summaryrefslogtreecommitdiff
path: root/mozilla-1619882-2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'mozilla-1619882-2.patch')
-rw-r--r--mozilla-1619882-2.patch123
1 files changed, 79 insertions, 44 deletions
diff --git a/mozilla-1619882-2.patch b/mozilla-1619882-2.patch
index 2733186..dc3ab77 100644
--- a/mozilla-1619882-2.patch
+++ b/mozilla-1619882-2.patch
@@ -1,7 +1,7 @@
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
-@@ -10,17 +10,26 @@
+@@ -10,21 +10,45 @@
#include "FFmpegLibWrapper.h"
#include "FFmpegDataDecoder.h"
#include "SimpleMap.h"
@@ -13,31 +13,56 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platfor
namespace mozilla {
#ifdef MOZ_WAYLAND_USE_VAAPI
+-class VAAPIFrameHolder {
++// When VA-API decoding is running, ffmpeg allocates AVHWFramesContext - a pool
++// of "hardware" frames. Every "hardware" frame (VASurface) is backed
++// by actual piece of GPU memory which holds the decoded image data.
++//
++// The VASurface is wrapped by WaylandDMABufSurface and transferred to
++// rendering queue by WaylandDMABUFSurfaceImage, where TextureClient is
++// created and VASurface is used as a texture there.
++//
++// As there's a limited number of VASurfaces, ffmpeg reuses them to decode
++// next frames ASAP even if they are still attached to WaylandDMABufSurface
++// and used as a texture in our rendering engine.
++//
++// Unfortunately there isn't any obvious way how to mark particular VASurface
++// as used. The best we can do is to hold a reference to particular AVBuffer
++// from decoded AVFrame and AVHWFramesContext which owns the AVBuffer.
+
- class VAAPIFrameHolder {
++class VAAPIFrameHolder final {
public:
- VAAPIFrameHolder(FFmpegLibWrapper* aLib, AVBufferRef* aVAAPIDeviceContext,
-+ VAAPIFrameHolder(RefPtr<WaylandDMABufSurface> aSurface,
-+ FFmpegLibWrapper* aLib, AVBufferRef* aVAAPIDeviceContext,
- AVBufferRef* aAVHWFramesContext, AVBufferRef* aHWFrame);
+- AVBufferRef* aAVHWFramesContext, AVBufferRef* aHWFrame);
++ VAAPIFrameHolder(FFmpegLibWrapper* aLib, WaylandDMABufSurface* aSurface,
++ AVCodecContext* aAVCodecContext, AVFrame* aAVFrame);
~VAAPIFrameHolder();
-+ bool IsUsed() { return mSurface->IsGlobalRefSet(); }
++ // Check if WaylandDMABufSurface is used by any gecko rendering process
++ // (WebRender or GL compositor) or by WaylandDMABUFSurfaceImage/VideoData.
++ bool IsUsed() const { return mSurface->IsGlobalRefSet(); }
+
private:
-+ RefPtr<WaylandDMABufSurface> mSurface;
- FFmpegLibWrapper* mLib;
- AVBufferRef* mVAAPIDeviceContext;
+- FFmpegLibWrapper* mLib;
+- AVBufferRef* mVAAPIDeviceContext;
++ const FFmpegLibWrapper* mLib;
++ const RefPtr<WaylandDMABufSurface> mSurface;
AVBufferRef* mAVHWFramesContext;
-@@ -97,6 +106,7 @@
+- AVBufferRef* mHWFrame;
++ AVBufferRef* mHWAVBuffer;
+ };
+ #endif
+
+@@ -97,6 +121,8 @@
MediaResult CreateImageVAAPI(int64_t aOffset, int64_t aPts, int64_t aDuration,
MediaDataDecoder::DecodedData& aResults);
+ void ReleaseUnusedVAAPIFrames();
++ void ReleaseAllVAAPIFrames();
#endif
/**
-@@ -112,6 +122,7 @@
+@@ -112,6 +138,7 @@
AVBufferRef* mVAAPIDeviceContext;
const bool mDisableHardwareDecoding;
VADisplay mDisplay;
@@ -48,41 +73,43 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platfor
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
-@@ -122,19 +122,30 @@
- return AV_PIX_FMT_NONE;
+@@ -123,18 +123,27 @@
}
--VAAPIFrameHolder::VAAPIFrameHolder(FFmpegLibWrapper* aLib,
-+VAAPIFrameHolder::VAAPIFrameHolder(RefPtr<WaylandDMABufSurface> aSurface,
-+ FFmpegLibWrapper* aLib,
- AVBufferRef* aVAAPIDeviceContext,
- AVBufferRef* aAVHWFramesContext,
- AVBufferRef* aHWFrame)
-- : mLib(aLib),
-+ : mSurface(aSurface),
-+ mLib(aLib),
- mVAAPIDeviceContext(mLib->av_buffer_ref(aVAAPIDeviceContext)),
- mAVHWFramesContext(mLib->av_buffer_ref(aAVHWFramesContext)),
+ VAAPIFrameHolder::VAAPIFrameHolder(FFmpegLibWrapper* aLib,
+- AVBufferRef* aVAAPIDeviceContext,
+- AVBufferRef* aAVHWFramesContext,
+- AVBufferRef* aHWFrame)
++ WaylandDMABufSurface* aSurface,
++ AVCodecContext* aAVCodecContext,
++ AVFrame* aAVFrame)
+ : mLib(aLib),
+- mVAAPIDeviceContext(mLib->av_buffer_ref(aVAAPIDeviceContext)),
+- mAVHWFramesContext(mLib->av_buffer_ref(aAVHWFramesContext)),
- mHWFrame(mLib->av_buffer_ref(aHWFrame)){};
-+ mHWFrame(mLib->av_buffer_ref(aHWFrame)) {
++ mSurface(aSurface),
++ mAVHWFramesContext(mLib->av_buffer_ref(aAVCodecContext->hw_frames_ctx)),
++ mHWAVBuffer(mLib->av_buffer_ref(aAVFrame->buf[0])) {
+ FFMPEG_LOG("VAAPIFrameHolder is adding dmabuf surface UID = %d\n",
+ mSurface->GetUID());
++
+ // Create global refcount object to track mSurface usage over
-+ // processes.
++ // gects rendering engine. We can't release it until it's used
++ // by GL compositor / WebRender.
+ mSurface->GlobalRefCountCreate();
+}
VAAPIFrameHolder::~VAAPIFrameHolder() {
+- mLib->av_buffer_unref(&mHWFrame);
+ FFMPEG_LOG("VAAPIFrameHolder is releasing dmabuf surface UID = %d\n",
+ mSurface->GetUID());
- mLib->av_buffer_unref(&mHWFrame);
++ mLib->av_buffer_unref(&mHWAVBuffer);
mLib->av_buffer_unref(&mAVHWFramesContext);
- mLib->av_buffer_unref(&mVAAPIDeviceContext);
-+ mSurface = nullptr;
+- mLib->av_buffer_unref(&mVAAPIDeviceContext);
}
AVCodec* FFmpegVideoDecoder<LIBAV_VER>::FindVAAPICodec() {
-@@ -418,6 +428,13 @@
+@@ -422,6 +431,13 @@
NS_WARNING("FFmpeg h264 decoder failed to allocate frame.");
return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
}
@@ -96,7 +123,7 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
res = mLib->avcodec_receive_frame(mCodecContext, mFrame);
if (res == int(AVERROR_EOF)) {
return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
-@@ -624,9 +641,16 @@
+@@ -628,9 +644,20 @@
}
#ifdef MOZ_WAYLAND_USE_VAAPI
@@ -113,10 +140,14 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
+ holder++;
+ }
+ }
++}
++
++void FFmpegVideoDecoder<LIBAV_VER>::ReleaseAllVAAPIFrames() {
++ mFrameHolders.clear();
}
MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI(
-@@ -663,20 +687,28 @@
+@@ -667,20 +694,20 @@
RESULT_DETAIL("Unable to allocate WaylandDMABufSurfaceNV12."));
}
@@ -128,28 +159,32 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
+
surface->SetYUVColorSpace(GetFrameColorSpace());
- // mFrame->buf[0] is a reference to H264 VASurface for this mFrame.
+- // mFrame->buf[0] is a reference to H264 VASurface for this mFrame.
- // We need create WaylandDMABUFSurfaceImage on top of it,
-+ // We need create WaylandDMABUFSurface on top of it,
- // create EGLImage/Texture on top of it and render it by GL.
+- // create EGLImage/Texture on top of it and render it by GL.
++ // Store reference to the decoded HW buffer, see VAAPIFrameHolder struct.
++ auto holder =
++ MakeUnique<VAAPIFrameHolder>(mLib, surface, mCodecContext, mFrame);
++ mFrameHolders.push_back(std::move(holder));
- // FFmpeg tends to reuse the particual VASurface for another frame
- // even when the mFrame is not released. To keep VASurface as is
+- // FFmpeg tends to reuse the particual VASurface for another frame
+- // even when the mFrame is not released. To keep VASurface as is
- // we explicitly reference it and keep until WaylandDMABUFSurfaceImage
- // is live.
- RefPtr<layers::Image> im = new layers::WaylandDMABUFSurfaceImage(
- surface, VAAPIFrameReleaseCallback,
- new VAAPIFrameHolder(mLib, mVAAPIDeviceContext,
- mCodecContext->hw_frames_ctx, mFrame->buf[0]));
-+ // we explicitly reference it and keep until there's any reference to
-+ // attached WaylandDMABUFSurface.
-+ auto holder = MakeUnique<VAAPIFrameHolder>(surface, mLib, mVAAPIDeviceContext,
-+ mCodecContext->hw_frames_ctx,
-+ mFrame->buf[0]);
-+ mFrameHolders.push_back(std::move(holder));
-+
+ RefPtr<layers::Image> im = new layers::WaylandDMABUFSurfaceImage(surface);
RefPtr<VideoData> vp = VideoData::CreateFromImage(
mInfo.mDisplay, aOffset, TimeUnit::FromMicroseconds(aPts),
+@@ -732,6 +759,7 @@
+ void FFmpegVideoDecoder<LIBAV_VER>::ProcessShutdown() {
+ #ifdef MOZ_WAYLAND_USE_VAAPI
+ if (mVAAPIDeviceContext) {
++ ReleaseAllVAAPIFrames();
+ mLib->av_buffer_unref(&mVAAPIDeviceContext);
+ }
+ #endif
bgstack15