diff -up firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp.D141827 firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp --- firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp.D141827 2022-03-31 01:24:44.000000000 +0200 +++ firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp 2022-04-07 10:10:11.608526890 +0200 @@ -6,7 +6,7 @@ #include "FFmpegVideoFramePool.h" #include "FFmpegLog.h" -#include "mozilla/widget/DMABufLibWrapper.h" +#include "mozilla/widget/DMABufLibWrapper.h" #include "libavutil/pixfmt.h" #undef FFMPEG_LOG @@ -15,11 +15,11 @@ namespace mozilla { -RefPtr VideoFrameSurfaceVAAPI::GetAsImage() { +RefPtr VideoFrameSurface::GetAsImage() { return new layers::DMABUFSurfaceImage(mSurface); } -VideoFrameSurfaceVAAPI::VideoFrameSurfaceVAAPI(DMABufSurface* aSurface) +VideoFrameSurface::VideoFrameSurface(DMABufSurface* aSurface) : mSurface(aSurface), mLib(nullptr), mAVHWFramesContext(nullptr), @@ -30,22 +30,22 @@ VideoFrameSurfaceVAAPI::VideoFrameSurfac MOZ_ASSERT(mSurface); MOZ_RELEASE_ASSERT(mSurface->GetAsDMABufSurfaceYUV()); mSurface->GlobalRefCountCreate(); - FFMPEG_LOG("VideoFrameSurfaceVAAPI: creating surface UID = %d", + FFMPEG_LOG("VideoFrameSurface: creating surface UID = %d", mSurface->GetUID()); } -void VideoFrameSurfaceVAAPI::LockVAAPIData(AVCodecContext* aAVCodecContext, +void VideoFrameSurface::LockVAAPIData(AVCodecContext* aAVCodecContext, AVFrame* aAVFrame, FFmpegLibWrapper* aLib) { - FFMPEG_LOG("VideoFrameSurfaceVAAPI: VAAPI locking dmabuf surface UID = %d", + FFMPEG_LOG("VideoFrameSurface: VAAPI locking dmabuf surface UID = %d", mSurface->GetUID()); mLib = aLib; mAVHWFramesContext = aLib->av_buffer_ref(aAVCodecContext->hw_frames_ctx); mHWAVBuffer = aLib->av_buffer_ref(aAVFrame->buf[0]); } -void VideoFrameSurfaceVAAPI::ReleaseVAAPIData(bool aForFrameRecycle) { - FFMPEG_LOG("VideoFrameSurfaceVAAPI: VAAPI releasing dmabuf surface UID = %d", +void VideoFrameSurface::ReleaseVAAPIData(bool aForFrameRecycle) { + FFMPEG_LOG("VideoFrameSurface: VAAPI releasing dmabuf surface UID = %d", mSurface->GetUID()); // It's possible to unref GPU data while IsUsed() is still set. @@ -67,8 +67,8 @@ void VideoFrameSurfaceVAAPI::ReleaseVAAP } } -VideoFrameSurfaceVAAPI::~VideoFrameSurfaceVAAPI() { - FFMPEG_LOG("VideoFrameSurfaceVAAPI: deleting dmabuf surface UID = %d", +VideoFrameSurface::~VideoFrameSurface() { + FFMPEG_LOG("VideoFrameSurface: deleting dmabuf surface UID = %d", mSurface->GetUID()); // We're about to quit, no need to recycle the frames. ReleaseVAAPIData(/* aForFrameRecycle */ false); @@ -84,9 +84,8 @@ VideoFramePool::~VideoFramePool() { void VideoFramePool::ReleaseUnusedVAAPIFrames() { MutexAutoLock lock(mSurfaceLock); for (const auto& surface : mDMABufSurfaces) { - auto* vaapiSurface = surface->AsVideoFrameSurfaceVAAPI(); - if (!vaapiSurface->IsUsed()) { - vaapiSurface->ReleaseVAAPIData(); + if (!surface->IsUsed()) { + surface->ReleaseVAAPIData(); } } } @@ -96,8 +95,7 @@ RefPtr VideoFramePool if (surface->IsUsed()) { continue; } - auto* vaapiSurface = surface->AsVideoFrameSurfaceVAAPI(); - vaapiSurface->ReleaseVAAPIData(); + surface->ReleaseVAAPIData(); return surface; } return nullptr; @@ -121,7 +119,7 @@ RefPtr VideoFramePool return nullptr; } FFMPEG_LOG("Created new VA-API DMABufSurface UID = %d", surface->GetUID()); - RefPtr surf = new VideoFrameSurfaceVAAPI(surface); + RefPtr surf = new VideoFrameSurface(surface); if (!mTextureCreationWorks) { mTextureCreationWorks = Some(surface->VerifyTextureCreation()); } @@ -138,11 +136,8 @@ RefPtr VideoFramePool } FFMPEG_LOG("Reusing VA-API DMABufSurface UID = %d", surface->GetUID()); } - - auto* vaapiSurface = videoSurface->AsVideoFrameSurfaceVAAPI(); - vaapiSurface->LockVAAPIData(aAVCodecContext, aAVFrame, aLib); - vaapiSurface->MarkAsUsed(); - + videoSurface->LockVAAPIData(aAVCodecContext, aAVFrame, aLib); + videoSurface->MarkAsUsed(); return videoSurface; } diff -up firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h.D141827 firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h --- firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h.D141827 2022-03-31 01:24:44.000000000 +0200 +++ firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h 2022-04-07 10:09:46.527708638 +0200 @@ -17,42 +17,17 @@ namespace mozilla { class VideoFramePool; -class VideoFrameSurfaceVAAPI; -class VideoFrameSurface { - public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameSurface) - - VideoFrameSurface() = default; - - virtual VideoFrameSurfaceVAAPI* AsVideoFrameSurfaceVAAPI() { return nullptr; } - - virtual void SetYUVColorSpace(gfx::YUVColorSpace aColorSpace) = 0; - virtual void SetColorRange(gfx::ColorRange aColorRange) = 0; - - virtual RefPtr GetDMABufSurface() { return nullptr; }; - virtual RefPtr GetAsImage() = 0; - - // Don't allow VideoFrameSurface plain copy as it leads to - // unexpected DMABufSurface/HW buffer releases and we don't want to - // deep copy them. - VideoFrameSurface(const VideoFrameSurface&) = delete; - const VideoFrameSurface& operator=(VideoFrameSurface const&) = delete; - - protected: - virtual ~VideoFrameSurface(){}; -}; - -// VideoFrameSurfaceVAAPI holds a reference to GPU data with a video frame. +// VideoFrameSurface holds a reference to GPU data with a video frame. // // Actual GPU pixel data are stored at DMABufSurface and // DMABufSurface is passed to gecko GL rendering pipeline via. // DMABUFSurfaceImage. // -// VideoFrameSurfaceVAAPI can optionally hold VA-API ffmpeg related data to keep +// VideoFrameSurface can optionally hold VA-API ffmpeg related data to keep // GPU data locked untill we need them. // -// VideoFrameSurfaceVAAPI is used for both HW accelerated video decoding +// VideoFrameSurface is used for both HW accelerated video decoding // (VA-API) and ffmpeg SW decoding. // // VA-API scenario @@ -72,13 +47,13 @@ class VideoFrameSurface { // 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 VideoFrameSurfaceVAAPI final : public VideoFrameSurface { +class VideoFrameSurface { friend class VideoFramePool; public: - explicit VideoFrameSurfaceVAAPI(DMABufSurface* aSurface); + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameSurface) - VideoFrameSurfaceVAAPI* AsVideoFrameSurfaceVAAPI() final { return this; } + explicit VideoFrameSurface(DMABufSurface* aSurface); void SetYUVColorSpace(mozilla::gfx::YUVColorSpace aColorSpace) { mSurface->GetAsDMABufSurfaceYUV()->SetYUVColorSpace(aColorSpace); @@ -93,6 +68,12 @@ class VideoFrameSurfaceVAAPI final : pub RefPtr GetAsImage(); + // Don't allow VideoFrameSurface plain copy as it leads to + // unexpected DMABufSurface/HW buffer releases and we don't want to + // deep copy them. + VideoFrameSurface(const VideoFrameSurface&) = delete; + const VideoFrameSurface& operator=(VideoFrameSurface const&) = delete; + protected: // Lock VAAPI related data void LockVAAPIData(AVCodecContext* aAVCodecContext, AVFrame* aAVFrame, @@ -107,7 +88,7 @@ class VideoFrameSurfaceVAAPI final : pub void MarkAsUsed() { mSurface->GlobalRefAdd(); } private: - virtual ~VideoFrameSurfaceVAAPI(); + virtual ~VideoFrameSurface(); const RefPtr mSurface; const FFmpegLibWrapper* mLib; @@ -132,7 +113,7 @@ class VideoFramePool final { private: // Protect mDMABufSurfaces pool access Mutex mSurfaceLock; - nsTArray> mDMABufSurfaces; + nsTArray> mDMABufSurfaces; // We may fail to create texture over DMABuf memory due to driver bugs so // check that before we export first DMABuf video frame. Maybe mTextureCreationWorks;