diff options
Diffstat (limited to 'D145871.diff')
-rw-r--r-- | D145871.diff | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/D145871.diff b/D145871.diff new file mode 100644 index 0000000..33a2e61 --- /dev/null +++ b/D145871.diff @@ -0,0 +1,140 @@ +diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h +--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h ++++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h +@@ -146,10 +146,15 @@ + RefPtr<ImageContainer> mImageContainer; + VideoInfo mInfo; + int mDecodedFrames; + #if LIBAVCODEC_VERSION_MAJOR >= 58 + int mDecodedFramesLate; ++ // Tracks when decode time of recent frame and averange decode time of ++ // previous frames is bigger than frame interval, ++ // i.e. we fail to decode in time. ++ // We switch to SW decode when we hit HW_DECODE_LATE_FRAMES treshold. ++ int mMissedDecodeInAverangeTime; + #endif + float mAverangeDecodeTime; + + class PtsCorrectionContext { + public: +diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp +--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp ++++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp +@@ -14,10 +14,13 @@ + #include "VPXDecoder.h" + #include "mozilla/layers/KnowsCompositor.h" + #if LIBAVCODEC_VERSION_MAJOR >= 57 + # include "mozilla/layers/TextureClient.h" + #endif ++#if LIBAVCODEC_VERSION_MAJOR >= 58 ++# include "mozilla/ProfilerMarkers.h" ++#endif + #ifdef MOZ_WAYLAND_USE_VAAPI + # include "H264.h" + # include "mozilla/layers/DMABUFSurfaceImage.h" + # include "mozilla/widget/DMABufLibWrapper.h" + # include "FFmpegVideoFramePool.h" +@@ -56,13 +59,14 @@ + typedef int VAStatus; + # define VA_EXPORT_SURFACE_READ_ONLY 0x0001 + # define VA_EXPORT_SURFACE_SEPARATE_LAYERS 0x0004 + # define VA_STATUS_SUCCESS 0x00000000 + #endif +- + // Use some extra HW frames for potential rendering lags. + #define EXTRA_HW_FRAMES 6 ++// Defines number of delayed frames until we switch back to SW decode. ++#define HW_DECODE_LATE_FRAMES 15 + + #if LIBAVCODEC_VERSION_MAJOR >= 57 && LIBAVUTIL_VERSION_MAJOR >= 56 + # define CUSTOMIZED_BUFFER_ALLOCATION 1 + #endif + +@@ -386,10 +390,11 @@ + mImageContainer(aImageContainer), + mInfo(aConfig), + mDecodedFrames(0), + #if LIBAVCODEC_VERSION_MAJOR >= 58 + mDecodedFramesLate(0), ++ mMissedDecodeInAverangeTime(0), + #endif + mAverangeDecodeTime(0), + mLowLatency(aLowLatency) { + FFMPEG_LOG("FFmpegVideoDecoder::FFmpegVideoDecoder MIME %s Codec ID %d", + aConfig.mMimeType.get(), mCodecID); +@@ -781,22 +786,32 @@ + float decodeTime = (TimeStamp::Now() - aDecodeStart).ToMilliseconds(); + mAverangeDecodeTime = + (mAverangeDecodeTime * (mDecodedFrames - 1) + decodeTime) / + mDecodedFrames; + FFMPEG_LOG( +- " decode time %.2f ms averange decode time %.2f ms decoded frames %d\n", ++ "Frame decode finished, time %.2f ms averange decode time %.2f ms " ++ "decoded %d frames\n", + decodeTime, mAverangeDecodeTime, mDecodedFrames); + #if LIBAVCODEC_VERSION_MAJOR >= 58 +- int frameDuration = mFrame->pkt_duration; +- if (frameDuration > 0 && frameDuration / 1000.0 < decodeTime) { +- mDecodedFramesLate++; +- FFMPEG_LOG( +- " slow decode: failed to decode in time, frame duration %.2f ms, " +- "decode time %.2f\n", +- frameDuration / 1000.0, decodeTime); +- FFMPEG_LOG(" all decoded frames / late decoded frames %d/%d\n", +- mDecodedFrames, mDecodedFramesLate); ++ if (mFrame->pkt_duration > 0) { ++ // Switch frame duration to ms ++ float frameDuration = mFrame->pkt_duration / 1000.0f; ++ if (frameDuration < decodeTime) { ++ PROFILER_MARKER_TEXT("FFmpegVideoDecoder::DoDecode", MEDIA_PLAYBACK, {}, ++ "frame decode takes too long"); ++ mDecodedFramesLate++; ++ if (frameDuration < mAverangeDecodeTime) { ++ mMissedDecodeInAverangeTime++; ++ } ++ FFMPEG_LOG( ++ " slow decode: failed to decode in time, frame duration %.2f ms, " ++ "decode time %.2f\n", ++ frameDuration, decodeTime); ++ FFMPEG_LOG(" frames: all decoded %d late decoded %d over averange %d\n", ++ mDecodedFrames, mDecodedFramesLate, ++ mMissedDecodeInAverangeTime); ++ } + } + #endif + } + + MediaResult FFmpegVideoDecoder<LIBAV_VER>::DoDecode( +@@ -866,10 +881,18 @@ + decodeStart = TimeStamp::Now(); + + MediaResult rv; + # ifdef MOZ_WAYLAND_USE_VAAPI + if (IsHardwareAccelerated()) { ++ if (mMissedDecodeInAverangeTime > HW_DECODE_LATE_FRAMES) { ++ PROFILER_MARKER_TEXT("FFmpegVideoDecoder::DoDecode", MEDIA_PLAYBACK, {}, ++ "Fallback to SW decode"); ++ FFMPEG_LOG(" HW decoding is slow, switch back to SW decode"); ++ return MediaResult( ++ NS_ERROR_DOM_MEDIA_DECODE_ERR, ++ RESULT_DETAIL("HW decoding is slow, switch back to SW decode")); ++ } + rv = CreateImageVAAPI(mFrame->pkt_pos, GetFramePts(mFrame), + mFrame->pkt_duration, aResults); + // If VA-API playback failed, just quit. Decoder is going to be restarted + // without VA-API. + if (NS_FAILED(rv)) { +@@ -1129,11 +1152,11 @@ + } + + MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI( + int64_t aOffset, int64_t aPts, int64_t aDuration, + MediaDataDecoder::DecodedData& aResults) { +- FFMPEG_LOG("VA-API Got one frame output with pts=%" PRId64 "dts=%" PRId64 ++ FFMPEG_LOG("VA-API Got one frame output with pts=%" PRId64 " dts=%" PRId64 + " duration=%" PRId64 " opaque=%" PRId64, + aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque); + + VADRMPRIMESurfaceDescriptor vaDesc; + if (!GetVAAPISurfaceDescriptor(&vaDesc)) { + |