firefox/D145871.diff

141 lines
5.4 KiB
Diff

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)) {