diff -up firefox-99.0/dom/media/platforms/ffmpeg/ffmpeg58/moz.build.D141828 firefox-99.0/dom/media/platforms/ffmpeg/ffmpeg58/moz.build --- firefox-99.0/dom/media/platforms/ffmpeg/ffmpeg58/moz.build.D141828 2022-03-31 01:24:44.000000000 +0200 +++ firefox-99.0/dom/media/platforms/ffmpeg/ffmpeg58/moz.build 2022-04-07 10:11:34.981246890 +0200 @@ -30,6 +30,9 @@ if CONFIG['MOZ_WAYLAND']: CXXFLAGS += CONFIG['MOZ_GTK3_CFLAGS'] DEFINES['MOZ_WAYLAND_USE_VAAPI'] = 1 USE_LIBS += ['mozva'] + UNIFIED_SOURCES += [ + '../FFmpegVideoFramePool.cpp', + ] include("/ipc/chromium/chromium-config.mozbuild") diff -up firefox-99.0/dom/media/platforms/ffmpeg/ffmpeg59/moz.build.D141828 firefox-99.0/dom/media/platforms/ffmpeg/ffmpeg59/moz.build --- firefox-99.0/dom/media/platforms/ffmpeg/ffmpeg59/moz.build.D141828 2022-03-31 01:24:44.000000000 +0200 +++ firefox-99.0/dom/media/platforms/ffmpeg/ffmpeg59/moz.build 2022-04-07 10:11:34.981246890 +0200 @@ -30,6 +30,9 @@ if CONFIG["MOZ_WAYLAND"]: CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"] DEFINES["MOZ_WAYLAND_USE_VAAPI"] = 1 USE_LIBS += ["mozva"] + UNIFIED_SOURCES += [ + "../FFmpegVideoFramePool.cpp", + ] include("/ipc/chromium/chromium-config.mozbuild") diff -up firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp.D141828 firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp --- firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp.D141828 2022-03-31 01:24:44.000000000 +0200 +++ firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2022-04-07 10:11:34.981246890 +0200 @@ -814,7 +814,7 @@ MediaResult FFmpegVideoDecoder(); + mVideoFramePool = MakeUnique>(); } // Release unused VA-API surfaces before avcodec_receive_frame() as diff -up firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h.D141828 firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h --- firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h.D141828 2022-03-31 01:24:44.000000000 +0200 +++ firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h 2022-04-07 10:11:34.981246890 +0200 @@ -16,6 +16,9 @@ #if LIBAVCODEC_VERSION_MAJOR >= 57 && LIBAVUTIL_VERSION_MAJOR >= 56 # include "mozilla/layers/TextureClient.h" #endif +#ifdef MOZ_WAYLAND_USE_VAAPI +# include "FFmpegVideoFramePool.h" +#endif struct _VADRMPRIMESurfaceDescriptor; typedef struct _VADRMPRIMESurfaceDescriptor VADRMPRIMESurfaceDescriptor; @@ -23,7 +26,6 @@ typedef struct _VADRMPRIMESurfaceDescrip namespace mozilla { class ImageBufferWrapper; -class VideoFramePool; template class FFmpegVideoDecoder : public FFmpegDataDecoder {}; @@ -138,7 +140,7 @@ class FFmpegVideoDecoder AVBufferRef* mVAAPIDeviceContext; bool mEnableHardwareDecoding; VADisplay mDisplay; - UniquePtr mVideoFramePool; + UniquePtr> mVideoFramePool; static nsTArray mAcceleratedFormats; #endif RefPtr mImageAllocator; diff -up firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp.D141828 firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp --- firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp.D141828 2022-04-07 10:11:34.980246857 +0200 +++ firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp 2022-04-07 10:16:02.390971008 +0200 @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "FFmpegVideoFramePool.h" +#include "PlatformDecoderModule.h" #include "FFmpegLog.h" #include "mozilla/widget/DMABufLibWrapper.h" #include "libavutil/pixfmt.h" @@ -15,11 +16,11 @@ namespace mozilla { -RefPtr VideoFrameSurface::GetAsImage() { +RefPtr VideoFrameSurface::GetAsImage() { return new layers::DMABUFSurfaceImage(mSurface); } -VideoFrameSurface::VideoFrameSurface(DMABufSurface* aSurface) +VideoFrameSurface::VideoFrameSurface(DMABufSurface* aSurface) : mSurface(aSurface), mLib(nullptr), mAVHWFramesContext(nullptr), @@ -34,7 +35,7 @@ VideoFrameSurface::VideoFrameSurface(DMA mSurface->GetUID()); } -void VideoFrameSurface::LockVAAPIData(AVCodecContext* aAVCodecContext, +void VideoFrameSurface::LockVAAPIData(AVCodecContext* aAVCodecContext, AVFrame* aAVFrame, FFmpegLibWrapper* aLib) { FFMPEG_LOG("VideoFrameSurface: VAAPI locking dmabuf surface UID = %d", @@ -44,7 +45,7 @@ void VideoFrameSurface::LockVAAPIData(AV mHWAVBuffer = aLib->av_buffer_ref(aAVFrame->buf[0]); } -void VideoFrameSurface::ReleaseVAAPIData(bool aForFrameRecycle) { +void VideoFrameSurface::ReleaseVAAPIData(bool aForFrameRecycle) { FFMPEG_LOG("VideoFrameSurface: VAAPI releasing dmabuf surface UID = %d", mSurface->GetUID()); @@ -67,21 +68,22 @@ void VideoFrameSurface::ReleaseVAAPIData } } -VideoFrameSurface::~VideoFrameSurface() { +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); } -VideoFramePool::VideoFramePool() : mSurfaceLock("VideoFramePoolSurfaceLock") {} +VideoFramePool::VideoFramePool() + : mSurfaceLock("VideoFramePoolSurfaceLock") {} -VideoFramePool::~VideoFramePool() { +VideoFramePool::~VideoFramePool() { MutexAutoLock lock(mSurfaceLock); mDMABufSurfaces.Clear(); } -void VideoFramePool::ReleaseUnusedVAAPIFrames() { +void VideoFramePool::ReleaseUnusedVAAPIFrames() { MutexAutoLock lock(mSurfaceLock); for (const auto& surface : mDMABufSurfaces) { if (!surface->IsUsed()) { @@ -90,7 +92,8 @@ void VideoFramePool::ReleaseUnusedVAAPIF } } -RefPtr VideoFramePool::GetFreeVideoFrameSurface() { +RefPtr> +VideoFramePool::GetFreeVideoFrameSurface() { for (auto& surface : mDMABufSurfaces) { if (surface->IsUsed()) { continue; @@ -101,7 +104,8 @@ RefPtr VideoFramePool return nullptr; } -RefPtr VideoFramePool::GetVideoFrameSurface( +RefPtr> +VideoFramePool::GetVideoFrameSurface( VADRMPRIMESurfaceDescriptor& aVaDesc, AVCodecContext* aAVCodecContext, AVFrame* aAVFrame, FFmpegLibWrapper* aLib) { if (aVaDesc.fourcc != VA_FOURCC_NV12 && aVaDesc.fourcc != VA_FOURCC_YV12 && @@ -111,7 +115,8 @@ RefPtr VideoFramePool } MutexAutoLock lock(mSurfaceLock); - RefPtr videoSurface = GetFreeVideoFrameSurface(); + RefPtr> videoSurface = + GetFreeVideoFrameSurface(); if (!videoSurface) { RefPtr surface = DMABufSurfaceYUV::CreateYUVSurface(aVaDesc); @@ -119,7 +124,8 @@ RefPtr VideoFramePool return nullptr; } FFMPEG_LOG("Created new VA-API DMABufSurface UID = %d", surface->GetUID()); - RefPtr surf = new VideoFrameSurface(surface); + RefPtr> surf = + new VideoFrameSurface(surface); if (!mTextureCreationWorks) { mTextureCreationWorks = Some(surface->VerifyTextureCreation()); } diff -up firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h.D141828 firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h --- firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h.D141828 2022-04-07 10:11:34.980246857 +0200 +++ firefox-99.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h 2022-04-07 10:14:54.478755409 +0200 @@ -7,8 +7,9 @@ #ifndef __FFmpegVideoFramePool_h__ #define __FFmpegVideoFramePool_h__ -#include "FFmpegVideoDecoder.h" #include "FFmpegLibWrapper.h" +#include "FFmpegLibs.h" +#include "FFmpegLog.h" #include "mozilla/layers/DMABUFSurfaceImage.h" #include "mozilla/widget/DMABufLibWrapper.h" @@ -16,8 +17,6 @@ namespace mozilla { -class VideoFramePool; - // VideoFrameSurface holds a reference to GPU data with a video frame. // // Actual GPU pixel data are stored at DMABufSurface and @@ -47,8 +46,19 @@ class VideoFramePool; // 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 VideoFrameSurface { - friend class VideoFramePool; +template +class VideoFrameSurface {}; +template <> +class VideoFrameSurface; + +template +class VideoFramePool {}; +template <> +class VideoFramePool; + +template <> +class VideoFrameSurface { + friend class VideoFramePool; public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameSurface) @@ -97,23 +107,24 @@ class VideoFrameSurface { }; // VideoFramePool class is thread-safe. -class VideoFramePool final { +template <> +class VideoFramePool { public: VideoFramePool(); ~VideoFramePool(); - RefPtr GetVideoFrameSurface( + RefPtr> GetVideoFrameSurface( VADRMPRIMESurfaceDescriptor& aVaDesc, AVCodecContext* aAVCodecContext, AVFrame* aAVFrame, FFmpegLibWrapper* aLib); void ReleaseUnusedVAAPIFrames(); private: - RefPtr GetFreeVideoFrameSurface(); + RefPtr> GetFreeVideoFrameSurface(); 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;