diff --git a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp index 236f979516c2..c38604e095bf 100644 --- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "FFmpegAudioDecoder.h" +#include "FFmpegLog.h" #include "TimeUnits.h" #include "VideoUtils.h" #include "BufferReader.h" @@ -21,9 +22,14 @@ FFmpegAudioDecoder::FFmpegAudioDecoder(FFmpegLibWrapper* aLib, if (aConfig.mCodecSpecificConfig && aConfig.mCodecSpecificConfig->Length()) { mExtraData = new MediaByteBuffer; mExtraData->AppendElements(*aConfig.mCodecSpecificConfig); - BufferReader reader(mExtraData->Elements(), mExtraData->Length()); - mEncoderDelay = reader.ReadU32().unwrapOr(0); - mEncoderPadding = reader.ReadU32().unwrapOr(0); + if (mCodecID == AV_CODEC_ID_MP3) { + BufferReader reader(mExtraData->Elements(), mExtraData->Length()); + mEncoderDelay = reader.ReadU32().unwrapOr(0); + mEncoderPadding = reader.ReadU32().unwrapOr(0); + FFMPEG_LOG("FFmpegAudioDecoder, found encoder delay (%" PRIu32 + ") and padding values (%" PRIu32 ") in extra data", + mEncoderDelay, mEncoderPadding); + } } } @@ -231,6 +237,24 @@ MediaResult FFmpegAudioDecoder::DoDecode(MediaRawData* aSample, return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__); } + bool trimmed = false; + if (mEncoderDelay) { + trimmed = true; + uint32_t toPop = std::min((uint32_t)mFrame->nb_samples, mEncoderDelay); + audio.PopFront(toPop * numChannels); + mFrame->nb_samples -= toPop; + mEncoderDelay -= toPop; + } + + if (aSample->mEOS && mEncoderPadding) { + trimmed = true; + uint32_t toTrim = + std::min((uint32_t)mFrame->nb_samples, mEncoderPadding); + mEncoderPadding -= toTrim; + audio.PopBack(toTrim * numChannels); + mFrame->nb_samples = audio.Length() / numChannels; + } + media::TimeUnit duration = FramesToTimeUnit(mFrame->nb_samples, samplingRate); if (!duration.IsValid()) { @@ -248,7 +272,8 @@ MediaResult FFmpegAudioDecoder::DoDecode(MediaRawData* aSample, RefPtr data = new AudioData(samplePosition, pts, std::move(audio), numChannels, samplingRate, mCodecContext->channel_layout); - MOZ_DIAGNOSTIC_ASSERT(duration == data->mDuration, "must be equal"); + MOZ_DIAGNOSTIC_ASSERT(duration == data->mDuration || trimmed, + "must be equal"); aResults.AppendElement(std::move(data)); pts = newpts;