095be0aae50e7aa0f1d4a16e2ab893691449bacb
[dcpomatic.git] / src / lib / audio_decoder.cc
1 /*
2     Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #include "audio_decoder.h"
22 #include "audio_buffers.h"
23 #include "audio_content.h"
24 #include "dcpomatic_log.h"
25 #include "log.h"
26 #include "resampler.h"
27 #include "compose.hpp"
28 #include <iostream>
29
30 #include "i18n.h"
31
32 using std::cout;
33 using std::map;
34 using std::pair;
35 using std::shared_ptr;
36 using boost::optional;
37 using namespace dcpomatic;
38
39 AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, bool fast)
40         : DecoderPart (parent)
41         , _content (content)
42         , _fast (fast)
43 {
44         /* Set up _positions so that we have one for each stream */
45         for (auto i: content->streams ()) {
46                 _positions[i] = 0;
47         }
48 }
49
50 /** @param time_already_delayed true if the delay should not be added to time */
51 void
52 AudioDecoder::emit (shared_ptr<const Film> film, AudioStreamPtr stream, shared_ptr<const AudioBuffers> data, ContentTime time, bool time_already_delayed)
53 {
54         if (ignore ()) {
55                 return;
56         }
57
58         /* Amount of error we will tolerate on audio timestamps; see comment below.
59          * We'll use 1 24fps video frame at 48kHz as this seems to be roughly how
60          * ffplay does it.
61          */
62         static Frame const slack_frames = 48000 / 24;
63
64         int const resampled_rate = _content->resampled_frame_rate(film);
65         if (!time_already_delayed) {
66                 time += ContentTime::from_seconds (_content->delay() / 1000.0);
67         }
68
69         bool reset = false;
70         if (_positions[stream] == 0) {
71                 /* This is the first data we have received since initialisation or seek.  Set
72                    the position based on the ContentTime that was given.  After this first time
73                    we just count samples unless the timestamp is more than slack_frames away
74                    from where we think it should be.  This is because ContentTimes seem to be
75                    slightly unreliable from FFmpegDecoder (i.e. not sample accurate), but we still
76                    need to obey them sometimes otherwise we get sync problems such as #1833.
77                 */
78                 if (_content->delay() > 0) {
79                         /* Insert silence to give the delay */
80                         silence (_content->delay ());
81                 }
82                 reset = true;
83         } else if (std::abs(_positions[stream] - time.frames_round(resampled_rate)) > slack_frames) {
84                 reset = true;
85                 LOG_GENERAL (
86                         "Reset audio position: was %1, new data at %2, slack: %3 frames",
87                         _positions[stream],
88                         time.frames_round(resampled_rate),
89                         std::abs(_positions[stream] - time.frames_round(resampled_rate))
90                         );
91         }
92
93         if (reset) {
94                 _positions[stream] = time.frames_round (resampled_rate);
95         }
96
97         shared_ptr<Resampler> resampler;
98         ResamplerMap::iterator i = _resamplers.find(stream);
99         if (i != _resamplers.end ()) {
100                 resampler = i->second;
101         } else {
102                 if (stream->frame_rate() != resampled_rate) {
103                         LOG_GENERAL (
104                                 "Creating new resampler from %1 to %2 with %3 channels",
105                                 stream->frame_rate(),
106                                 resampled_rate,
107                                 stream->channels()
108                                 );
109
110                         resampler.reset (new Resampler(stream->frame_rate(), resampled_rate, stream->channels()));
111                         if (_fast) {
112                                 resampler->set_fast ();
113                         }
114                         _resamplers[stream] = resampler;
115                 }
116         }
117
118         if (resampler) {
119                 shared_ptr<const AudioBuffers> ro = resampler->run (data);
120                 if (ro->frames() == 0) {
121                         return;
122                 }
123                 data = ro;
124         }
125
126         Data(stream, ContentAudio (data, _positions[stream]));
127         _positions[stream] += data->frames();
128 }
129
130 /** @return Time just after the last thing that was emitted from a given stream */
131 ContentTime
132 AudioDecoder::stream_position (shared_ptr<const Film> film, AudioStreamPtr stream) const
133 {
134         PositionMap::const_iterator i = _positions.find (stream);
135         DCPOMATIC_ASSERT (i != _positions.end ());
136         return ContentTime::from_frames (i->second, _content->resampled_frame_rate(film));
137 }
138
139 boost::optional<ContentTime>
140 AudioDecoder::position (shared_ptr<const Film> film) const
141 {
142         optional<ContentTime> p;
143         for (PositionMap::const_iterator i = _positions.begin(); i != _positions.end(); ++i) {
144                 ContentTime const ct = stream_position (film, i->first);
145                 if (!p || ct < *p) {
146                         p = ct;
147                 }
148         }
149
150         return p;
151 }
152
153 void
154 AudioDecoder::seek ()
155 {
156         for (ResamplerMap::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
157                 i->second->flush ();
158                 i->second->reset ();
159         }
160
161         for (PositionMap::iterator i = _positions.begin(); i != _positions.end(); ++i) {
162                 i->second = 0;
163         }
164 }
165
166 void
167 AudioDecoder::flush ()
168 {
169         for (ResamplerMap::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
170                 shared_ptr<const AudioBuffers> ro = i->second->flush ();
171                 if (ro->frames() > 0) {
172                         Data (i->first, ContentAudio (ro, _positions[i->first]));
173                         _positions[i->first] += ro->frames();
174                 }
175         }
176
177         if (_content->delay() < 0) {
178                 /* Finish off with the gap caused by the delay */
179                 silence (-_content->delay ());
180         }
181 }
182
183 void
184 AudioDecoder::silence (int milliseconds)
185 {
186         for (auto i: _content->streams()) {
187                 int const samples = ContentTime::from_seconds(milliseconds / 1000.0).frames_round(i->frame_rate());
188                 shared_ptr<AudioBuffers> silence (new AudioBuffers (i->channels(), samples));
189                 silence->make_silent ();
190                 Data (i, ContentAudio (silence, _positions[i]));
191         }
192 }