summaryrefslogtreecommitdiff
path: root/mozilla-1619882-2.patch
diff options
context:
space:
mode:
authorMartin Stransky <stransky@redhat.com>2020-05-25 14:38:58 +0200
committerMartin Stransky <stransky@redhat.com>2020-05-25 14:38:58 +0200
commit1f2660d56b4c27145382cdb856e0914371a5bf3a (patch)
tree292c5d71692ba5961506db5831fc3c11f819b1ce /mozilla-1619882-2.patch
parentAdd support for PipeWire 0.3 (diff)
downloadlibrewolf-fedora-ff-1f2660d56b4c27145382cdb856e0914371a5bf3a.tar.gz
librewolf-fedora-ff-1f2660d56b4c27145382cdb856e0914371a5bf3a.tar.bz2
librewolf-fedora-ff-1f2660d56b4c27145382cdb856e0914371a5bf3a.zip
Added fix for mozbz#1619882 - video flickering when va-api is used.
Diffstat (limited to 'mozilla-1619882-2.patch')
-rw-r--r--mozilla-1619882-2.patch155
1 files changed, 155 insertions, 0 deletions
diff --git a/mozilla-1619882-2.patch b/mozilla-1619882-2.patch
new file mode 100644
index 0000000..2733186
--- /dev/null
+++ b/mozilla-1619882-2.patch
@@ -0,0 +1,155 @@
+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 @@
+ #include "FFmpegLibWrapper.h"
+ #include "FFmpegDataDecoder.h"
+ #include "SimpleMap.h"
++#ifdef MOZ_WAYLAND_USE_VAAPI
++# include "mozilla/widget/WaylandDMABufSurface.h"
++# include <list>
++#endif
+
+ namespace mozilla {
+
+ #ifdef MOZ_WAYLAND_USE_VAAPI
++
+ class VAAPIFrameHolder {
+ public:
+- VAAPIFrameHolder(FFmpegLibWrapper* aLib, AVBufferRef* aVAAPIDeviceContext,
++ VAAPIFrameHolder(RefPtr<WaylandDMABufSurface> aSurface,
++ FFmpegLibWrapper* aLib, AVBufferRef* aVAAPIDeviceContext,
+ AVBufferRef* aAVHWFramesContext, AVBufferRef* aHWFrame);
+ ~VAAPIFrameHolder();
+
++ bool IsUsed() { return mSurface->IsGlobalRefSet(); }
++
+ private:
++ RefPtr<WaylandDMABufSurface> mSurface;
+ FFmpegLibWrapper* mLib;
+ AVBufferRef* mVAAPIDeviceContext;
+ AVBufferRef* mAVHWFramesContext;
+@@ -97,6 +106,7 @@
+
+ MediaResult CreateImageVAAPI(int64_t aOffset, int64_t aPts, int64_t aDuration,
+ MediaDataDecoder::DecodedData& aResults);
++ void ReleaseUnusedVAAPIFrames();
+ #endif
+
+ /**
+@@ -112,6 +122,7 @@
+ AVBufferRef* mVAAPIDeviceContext;
+ const bool mDisableHardwareDecoding;
+ VADisplay mDisplay;
++ std::list<UniquePtr<VAAPIFrameHolder>> mFrameHolders;
+ #endif
+ RefPtr<KnowsCompositor> mImageAllocator;
+ RefPtr<ImageContainer> mImageContainer;
+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;
+ }
+
+-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)),
+- mHWFrame(mLib->av_buffer_ref(aHWFrame)){};
++ mHWFrame(mLib->av_buffer_ref(aHWFrame)) {
++ FFMPEG_LOG("VAAPIFrameHolder is adding dmabuf surface UID = %d\n",
++ mSurface->GetUID());
++ // Create global refcount object to track mSurface usage over
++ // processes.
++ mSurface->GlobalRefCountCreate();
++}
+
+ VAAPIFrameHolder::~VAAPIFrameHolder() {
++ FFMPEG_LOG("VAAPIFrameHolder is releasing dmabuf surface UID = %d\n",
++ mSurface->GetUID());
+ mLib->av_buffer_unref(&mHWFrame);
+ mLib->av_buffer_unref(&mAVHWFramesContext);
+ mLib->av_buffer_unref(&mVAAPIDeviceContext);
++ mSurface = nullptr;
+ }
+
+ AVCodec* FFmpegVideoDecoder<LIBAV_VER>::FindVAAPICodec() {
+@@ -418,6 +428,13 @@
+ NS_WARNING("FFmpeg h264 decoder failed to allocate frame.");
+ return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
+ }
++
++# ifdef MOZ_WAYLAND_USE_VAAPI
++ if (mVAAPIDeviceContext) {
++ ReleaseUnusedVAAPIFrames();
++ }
++# endif
++
+ res = mLib->avcodec_receive_frame(mCodecContext, mFrame);
+ if (res == int(AVERROR_EOF)) {
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
+@@ -624,9 +641,16 @@
+ }
+
+ #ifdef MOZ_WAYLAND_USE_VAAPI
+-static void VAAPIFrameReleaseCallback(VAAPIFrameHolder* aVAAPIFrameHolder) {
+- auto frameHolder = static_cast<VAAPIFrameHolder*>(aVAAPIFrameHolder);
+- delete frameHolder;
++void FFmpegVideoDecoder<LIBAV_VER>::ReleaseUnusedVAAPIFrames() {
++ std::list<UniquePtr<VAAPIFrameHolder>>::iterator holder =
++ mFrameHolders.begin();
++ while (holder != mFrameHolders.end()) {
++ if (!(*holder)->IsUsed()) {
++ holder = mFrameHolders.erase(holder);
++ } else {
++ holder++;
++ }
++ }
+ }
+
+ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI(
+@@ -663,20 +687,28 @@
+ RESULT_DETAIL("Unable to allocate WaylandDMABufSurfaceNV12."));
+ }
+
++# ifdef MOZ_LOGGING
++ static int uid = 0;
++ surface->SetUID(++uid);
++ FFMPEG_LOG("Created dmabuf UID = %d HW surface %x\n", uid, surface_id);
++# endif
++
+ surface->SetYUVColorSpace(GetFrameColorSpace());
+
+ // 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.
+
+ // 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),
+
bgstack15