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