зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1758610 [Linux] Implement VideoFramePool as template r=alwu
Depends on D141827 Differential Revision: https://phabricator.services.mozilla.com/D141828
This commit is contained in:
Родитель
39c0400669
Коммит
bf36926523
|
@ -805,7 +805,7 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
|
|||
# ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
// Create VideoFramePool in case we need it.
|
||||
if (!mVideoFramePool && mEnableHardwareDecoding) {
|
||||
mVideoFramePool = MakeUnique<VideoFramePool>();
|
||||
mVideoFramePool = MakeUnique<VideoFramePool<LIBAV_VER>>();
|
||||
}
|
||||
|
||||
// Release unused VA-API surfaces before avcodec_receive_frame() as
|
||||
|
|
|
@ -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 _VADRMPRIMESurfaceDescriptor VADRMPRIMESurfaceDescriptor;
|
|||
namespace mozilla {
|
||||
|
||||
class ImageBufferWrapper;
|
||||
class VideoFramePool;
|
||||
|
||||
template <int V>
|
||||
class FFmpegVideoDecoder : public FFmpegDataDecoder<V> {};
|
||||
|
@ -135,7 +137,7 @@ class FFmpegVideoDecoder<LIBAV_VER>
|
|||
AVBufferRef* mVAAPIDeviceContext;
|
||||
bool mEnableHardwareDecoding;
|
||||
VADisplay mDisplay;
|
||||
UniquePtr<VideoFramePool> mVideoFramePool;
|
||||
UniquePtr<VideoFramePool<LIBAV_VER>> mVideoFramePool;
|
||||
static nsTArray<AVCodecID> mAcceleratedFormats;
|
||||
#endif
|
||||
RefPtr<KnowsCompositor> mImageAllocator;
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
RefPtr<layers::Image> VideoFrameSurface::GetAsImage() {
|
||||
RefPtr<layers::Image> VideoFrameSurface<LIBAV_VER>::GetAsImage() {
|
||||
return new layers::DMABUFSurfaceImage(mSurface);
|
||||
}
|
||||
|
||||
VideoFrameSurface::VideoFrameSurface(DMABufSurface* aSurface)
|
||||
VideoFrameSurface<LIBAV_VER>::VideoFrameSurface(DMABufSurface* aSurface)
|
||||
: mSurface(aSurface),
|
||||
mLib(nullptr),
|
||||
mAVHWFramesContext(nullptr),
|
||||
|
@ -34,9 +34,9 @@ VideoFrameSurface::VideoFrameSurface(DMABufSurface* aSurface)
|
|||
mSurface->GetUID());
|
||||
}
|
||||
|
||||
void VideoFrameSurface::LockVAAPIData(AVCodecContext* aAVCodecContext,
|
||||
AVFrame* aAVFrame,
|
||||
FFmpegLibWrapper* aLib) {
|
||||
void VideoFrameSurface<LIBAV_VER>::LockVAAPIData(
|
||||
AVCodecContext* aAVCodecContext, AVFrame* aAVFrame,
|
||||
FFmpegLibWrapper* aLib) {
|
||||
FFMPEG_LOG("VideoFrameSurface: VAAPI locking dmabuf surface UID = %d",
|
||||
mSurface->GetUID());
|
||||
mLib = aLib;
|
||||
|
@ -44,7 +44,7 @@ void VideoFrameSurface::LockVAAPIData(AVCodecContext* aAVCodecContext,
|
|||
mHWAVBuffer = aLib->av_buffer_ref(aAVFrame->buf[0]);
|
||||
}
|
||||
|
||||
void VideoFrameSurface::ReleaseVAAPIData(bool aForFrameRecycle) {
|
||||
void VideoFrameSurface<LIBAV_VER>::ReleaseVAAPIData(bool aForFrameRecycle) {
|
||||
FFMPEG_LOG("VideoFrameSurface: VAAPI releasing dmabuf surface UID = %d",
|
||||
mSurface->GetUID());
|
||||
|
||||
|
@ -67,21 +67,22 @@ void VideoFrameSurface::ReleaseVAAPIData(bool aForFrameRecycle) {
|
|||
}
|
||||
}
|
||||
|
||||
VideoFrameSurface::~VideoFrameSurface() {
|
||||
VideoFrameSurface<LIBAV_VER>::~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<LIBAV_VER>::VideoFramePool()
|
||||
: mSurfaceLock("VideoFramePoolSurfaceLock") {}
|
||||
|
||||
VideoFramePool::~VideoFramePool() {
|
||||
VideoFramePool<LIBAV_VER>::~VideoFramePool() {
|
||||
MutexAutoLock lock(mSurfaceLock);
|
||||
mDMABufSurfaces.Clear();
|
||||
}
|
||||
|
||||
void VideoFramePool::ReleaseUnusedVAAPIFrames() {
|
||||
void VideoFramePool<LIBAV_VER>::ReleaseUnusedVAAPIFrames() {
|
||||
MutexAutoLock lock(mSurfaceLock);
|
||||
for (const auto& surface : mDMABufSurfaces) {
|
||||
if (!surface->IsUsed()) {
|
||||
|
@ -90,7 +91,8 @@ void VideoFramePool::ReleaseUnusedVAAPIFrames() {
|
|||
}
|
||||
}
|
||||
|
||||
RefPtr<VideoFrameSurface> VideoFramePool::GetFreeVideoFrameSurface() {
|
||||
RefPtr<VideoFrameSurface<LIBAV_VER>>
|
||||
VideoFramePool<LIBAV_VER>::GetFreeVideoFrameSurface() {
|
||||
for (auto& surface : mDMABufSurfaces) {
|
||||
if (surface->IsUsed()) {
|
||||
continue;
|
||||
|
@ -101,7 +103,8 @@ RefPtr<VideoFrameSurface> VideoFramePool::GetFreeVideoFrameSurface() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<VideoFrameSurface> VideoFramePool::GetVideoFrameSurface(
|
||||
RefPtr<VideoFrameSurface<LIBAV_VER>>
|
||||
VideoFramePool<LIBAV_VER>::GetVideoFrameSurface(
|
||||
VADRMPRIMESurfaceDescriptor& aVaDesc, AVCodecContext* aAVCodecContext,
|
||||
AVFrame* aAVFrame, FFmpegLibWrapper* aLib) {
|
||||
if (aVaDesc.fourcc != VA_FOURCC_NV12 && aVaDesc.fourcc != VA_FOURCC_YV12 &&
|
||||
|
@ -111,7 +114,8 @@ RefPtr<VideoFrameSurface> VideoFramePool::GetVideoFrameSurface(
|
|||
}
|
||||
|
||||
MutexAutoLock lock(mSurfaceLock);
|
||||
RefPtr<VideoFrameSurface> videoSurface = GetFreeVideoFrameSurface();
|
||||
RefPtr<VideoFrameSurface<LIBAV_VER>> videoSurface =
|
||||
GetFreeVideoFrameSurface();
|
||||
if (!videoSurface) {
|
||||
RefPtr<DMABufSurfaceYUV> surface =
|
||||
DMABufSurfaceYUV::CreateYUVSurface(aVaDesc);
|
||||
|
@ -119,7 +123,8 @@ RefPtr<VideoFrameSurface> VideoFramePool::GetVideoFrameSurface(
|
|||
return nullptr;
|
||||
}
|
||||
FFMPEG_LOG("Created new VA-API DMABufSurface UID = %d", surface->GetUID());
|
||||
RefPtr<VideoFrameSurface> surf = new VideoFrameSurface(surface);
|
||||
RefPtr<VideoFrameSurface<LIBAV_VER>> surf =
|
||||
new VideoFrameSurface<LIBAV_VER>(surface);
|
||||
if (!mTextureCreationWorks) {
|
||||
mTextureCreationWorks = Some(surface->VerifyTextureCreation());
|
||||
}
|
||||
|
|
|
@ -7,17 +7,12 @@
|
|||
#ifndef __FFmpegVideoFramePool_h__
|
||||
#define __FFmpegVideoFramePool_h__
|
||||
|
||||
#include "FFmpegVideoDecoder.h"
|
||||
#include "FFmpegLibWrapper.h"
|
||||
|
||||
#include "mozilla/layers/DMABUFSurfaceImage.h"
|
||||
#include "mozilla/widget/DMABufLibWrapper.h"
|
||||
#include "mozilla/widget/DMABufSurface.h"
|
||||
|
||||
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 +42,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 <int V>
|
||||
class VideoFrameSurface {};
|
||||
template <>
|
||||
class VideoFrameSurface<LIBAV_VER>;
|
||||
|
||||
template <int V>
|
||||
class VideoFramePool {};
|
||||
template <>
|
||||
class VideoFramePool<LIBAV_VER>;
|
||||
|
||||
template <>
|
||||
class VideoFrameSurface<LIBAV_VER> {
|
||||
friend class VideoFramePool<LIBAV_VER>;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameSurface)
|
||||
|
@ -97,23 +103,24 @@ class VideoFrameSurface {
|
|||
};
|
||||
|
||||
// VideoFramePool class is thread-safe.
|
||||
class VideoFramePool final {
|
||||
template <>
|
||||
class VideoFramePool<LIBAV_VER> {
|
||||
public:
|
||||
VideoFramePool();
|
||||
~VideoFramePool();
|
||||
|
||||
RefPtr<VideoFrameSurface> GetVideoFrameSurface(
|
||||
RefPtr<VideoFrameSurface<LIBAV_VER>> GetVideoFrameSurface(
|
||||
VADRMPRIMESurfaceDescriptor& aVaDesc, AVCodecContext* aAVCodecContext,
|
||||
AVFrame* aAVFrame, FFmpegLibWrapper* aLib);
|
||||
void ReleaseUnusedVAAPIFrames();
|
||||
|
||||
private:
|
||||
RefPtr<VideoFrameSurface> GetFreeVideoFrameSurface();
|
||||
RefPtr<VideoFrameSurface<LIBAV_VER>> GetFreeVideoFrameSurface();
|
||||
|
||||
private:
|
||||
// Protect mDMABufSurfaces pool access
|
||||
Mutex mSurfaceLock MOZ_UNANNOTATED;
|
||||
nsTArray<RefPtr<VideoFrameSurface>> mDMABufSurfaces;
|
||||
nsTArray<RefPtr<VideoFrameSurface<LIBAV_VER>>> 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<bool> mTextureCreationWorks;
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче