summaryrefslogtreecommitdiff
path: root/D145871.diff
blob: 33a2e615821504f4220d5b8eb3b02f92f580616c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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)) {

bgstack15