diff --git a/dom/media/fmp4/apple/AppleVDADecoder.cpp b/dom/media/fmp4/apple/AppleVDADecoder.cpp index 899c5a75f868..cd5e3bfee9a8 100644 --- a/dom/media/fmp4/apple/AppleVDADecoder.cpp +++ b/dom/media/fmp4/apple/AppleVDADecoder.cpp @@ -48,11 +48,19 @@ AppleVDADecoder::AppleVDADecoder(const mp4_demuxer::VideoDecoderConfig& aConfig, // Retrieve video dimensions from H264 SPS NAL. mPictureWidth = mConfig.image_width; mPictureHeight = mConfig.image_height; + mMaxRefFrames = 4; mp4_demuxer::SPSData spsdata; if (mp4_demuxer::H264::DecodeSPSFromExtraData(mConfig.extra_data, spsdata) && spsdata.pic_width && spsdata.pic_height) { mPictureWidth = spsdata.pic_width; mPictureHeight = spsdata.pic_height; + // max_num_ref_frames determines the size of the sliding window + // we need to queue that many frames in order to guarantee proper + // pts frames ordering. Use a minimum of 4 to ensure proper playback of + // non compliant videos. + mMaxRefFrames = + (spsdata.max_num_ref_frames + 1) > mMaxRefFrames ? + spsdata.max_num_ref_frames + 1 : mMaxRefFrames; } LOG("Creating AppleVDADecoder for %dx%d h.264 video", @@ -282,17 +290,9 @@ AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage, // in composition order. mReorderQueue.Push(data); // Assume a frame with a PTS <= current DTS is ready. - while (mReorderQueue.Length() > 0) { + while (mReorderQueue.Length() > mMaxRefFrames) { nsRefPtr readyData = mReorderQueue.Pop(); - if (readyData->mTime <= aFrameRef->decode_timestamp) { - LOG("returning queued frame with pts %lld", readyData->mTime); mCallback->Output(readyData); - } else { - LOG("requeued frame with pts %lld > %lld", - readyData->mTime, aFrameRef->decode_timestamp); - mReorderQueue.Push(readyData); - break; - } } LOG("%llu decoded frames queued", static_cast(mReorderQueue.Length())); diff --git a/dom/media/fmp4/apple/AppleVDADecoder.h b/dom/media/fmp4/apple/AppleVDADecoder.h index 82084a609ba3..785721bbf90c 100644 --- a/dom/media/fmp4/apple/AppleVDADecoder.h +++ b/dom/media/fmp4/apple/AppleVDADecoder.h @@ -92,6 +92,7 @@ public: ReorderQueue mReorderQueue; uint32_t mPictureWidth; uint32_t mPictureHeight; + uint32_t mMaxRefFrames; private: VDADecoder mDecoder;