Supporters update.
[dcpomatic.git] / src / lib / audio_decoder.cc
index ca1faa0100492b5e76363cde68b0aa4dbed1e9ab..61ff5d265c526e6de31e44d5bfb7eb6972883fba 100644 (file)
@@ -52,14 +52,14 @@ AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> cont
 
 /** @param time_already_delayed true if the delay should not be added to time */
 void
-AudioDecoder::emit (shared_ptr<const Film> film, AudioStreamPtr stream, shared_ptr<const AudioBuffers> data, ContentTime time, bool time_already_delayed)
+AudioDecoder::emit(shared_ptr<const Film> film, AudioStreamPtr stream, shared_ptr<const AudioBuffers> data, ContentTime time, bool flushing)
 {
        if (ignore ()) {
                return;
        }
 
        int const resampled_rate = _content->resampled_frame_rate(film);
-       if (!time_already_delayed) {
+       if (!flushing) {
                time += ContentTime::from_seconds (_content->delay() / 1000.0);
        }
 
@@ -119,12 +119,24 @@ AudioDecoder::emit (shared_ptr<const Film> film, AudioStreamPtr stream, shared_p
                }
        }
 
-       if (resampler) {
-               auto ro = resampler->run (data);
-               if (ro->frames() == 0) {
+       if (resampler && !flushing) {
+               /* It can be the the data here has a different number of channels than the stream
+                * it comes from (e.g. the files decoded by FFmpegDecoder sometimes have a random
+                * frame, often at the end, with more channels).  Insert silence or discard channels
+                * here.
+                */
+               if (resampler->channels() != data->channels()) {
+                       LOG_WARNING("Received audio data with an unexpected channel count of %1 instead of %2", data->channels(), resampler->channels());
+                       auto data_copy = data->clone();
+                       data_copy->set_channels(resampler->channels());
+                       data = resampler->run(data_copy);
+               } else {
+                       data = resampler->run(data);
+               }
+
+               if (data->frames() == 0) {
                        return;
                }
-               data = ro;
        }
 
        Data(stream, ContentAudio (data, _positions[stream]));