firefox/mozilla-1619882-2.patch

156 lines
5.7 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
@@ -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),