/** @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;
}
- /* Amount of error we will tolerate on audio timestamps; see comment below.
- * We'll use 1 24fps video frame at 48kHz as this seems to be roughly how
- * ffplay does it.
- */
- static Frame const slack_frames = 48000 / 24;
-
int const resampled_rate = _content->resampled_frame_rate(film);
- if (!time_already_delayed) {
+ if (!flushing) {
time += ContentTime::from_seconds (_content->delay() / 1000.0);
}
+ /* Amount of error we will tolerate on audio timestamps; see comment below.
+ * We'll use 1 24fps video frame as this seems to be roughly how ffplay does it.
+ */
+ Frame const slack_frames = resampled_rate / 24;
+
/* first_since_seek is set to true if this is the first data we have
received since initialisation or seek. We'll set the position based
on the ContentTime that was given. After this first time we just
}
}
- 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]));