forked from mirrors/gecko-dev
Bug 1850615 Share the same VADisplay across all FFmpegVideoDecoders a=pascalc
Rebased from https://hg.mozilla.org/mozilla-central/rev/9d547b90a407 with https://hg.mozilla.org/mozilla-central/rev/47d823d94067 Differential Revision: https://phabricator.services.mozilla.com/D241145
This commit is contained in:
parent
c7ed87060f
commit
493943a59b
3 changed files with 85 additions and 47 deletions
|
|
@ -25,7 +25,6 @@
|
|||
# include "H264.h"
|
||||
# include "mozilla/gfx/gfxVars.h"
|
||||
# include "mozilla/layers/DMABUFSurfaceImage.h"
|
||||
# include "mozilla/widget/DMABufLibWrapper.h"
|
||||
# include "FFmpegVideoFramePool.h"
|
||||
# include "va/va.h"
|
||||
#endif
|
||||
|
|
@ -66,13 +65,6 @@
|
|||
# include "mozilla/gfx/gfxVars.h"
|
||||
#endif
|
||||
|
||||
// Forward declare from va.h
|
||||
#ifdef MOZ_USE_HWDECODE
|
||||
typedef int VAStatus;
|
||||
# define VA_EXPORT_SURFACE_READ_ONLY 0x0001
|
||||
# define VA_EXPORT_SURFACE_SEPARATE_LAYERS 0x0004
|
||||
# define VA_STATUS_SUCCESS 0x00000000
|
||||
#endif
|
||||
// Use some extra HW frames for potential rendering lags.
|
||||
#define EXTRA_HW_FRAMES 6
|
||||
|
||||
|
|
@ -205,31 +197,9 @@ AVCodec* FFmpegVideoDecoder<LIBAV_VER>::FindVAAPICodec() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
template <int V>
|
||||
class VAAPIDisplayHolder {};
|
||||
|
||||
template <>
|
||||
class VAAPIDisplayHolder<LIBAV_VER>;
|
||||
|
||||
template <>
|
||||
class VAAPIDisplayHolder<LIBAV_VER> {
|
||||
public:
|
||||
VAAPIDisplayHolder(VADisplay aDisplay, int aDRMFd)
|
||||
: mDisplay(aDisplay), mDRMFd(aDRMFd) {};
|
||||
~VAAPIDisplayHolder() {
|
||||
VALibWrapper::sFuncs.vaTerminate(mDisplay);
|
||||
close(mDRMFd);
|
||||
}
|
||||
|
||||
private:
|
||||
VADisplay mDisplay;
|
||||
int mDRMFd;
|
||||
};
|
||||
|
||||
static void VAAPIDisplayReleaseCallback(struct AVHWDeviceContext* hwctx) {
|
||||
auto displayHolder =
|
||||
static_cast<VAAPIDisplayHolder<LIBAV_VER>*>(hwctx->user_opaque);
|
||||
delete displayHolder;
|
||||
auto displayHolder = static_cast<VADisplayHolder*>(hwctx->user_opaque);
|
||||
displayHolder->Release();
|
||||
}
|
||||
|
||||
bool FFmpegVideoDecoder<LIBAV_VER>::CreateVAAPIDeviceContext() {
|
||||
|
|
@ -245,23 +215,15 @@ bool FFmpegVideoDecoder<LIBAV_VER>::CreateVAAPIDeviceContext() {
|
|||
AVHWDeviceContext* hwctx = (AVHWDeviceContext*)mVAAPIDeviceContext->data;
|
||||
AVVAAPIDeviceContext* vactx = (AVVAAPIDeviceContext*)hwctx->hwctx;
|
||||
|
||||
int drmFd = widget::GetDMABufDevice()->OpenDRMFd();
|
||||
mDisplay = VALibWrapper::sFuncs.vaGetDisplayDRM(drmFd);
|
||||
if (!mDisplay) {
|
||||
FFMPEG_LOG(" Can't get DRM VA-API display.");
|
||||
RefPtr displayHolder = VADisplayHolder::GetSingleton();
|
||||
if (!displayHolder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hwctx->user_opaque = new VAAPIDisplayHolder<LIBAV_VER>(mDisplay, drmFd);
|
||||
mDisplay = displayHolder->mDisplay;
|
||||
hwctx->user_opaque = displayHolder.forget().take();
|
||||
hwctx->free = VAAPIDisplayReleaseCallback;
|
||||
|
||||
int major, minor;
|
||||
int status = VALibWrapper::sFuncs.vaInitialize(mDisplay, &major, &minor);
|
||||
if (status != VA_STATUS_SUCCESS) {
|
||||
FFMPEG_LOG(" vaInitialize failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
vactx->display = mDisplay;
|
||||
if (mLib->av_hwdevice_ctx_init(mVAAPIDeviceContext) < 0) {
|
||||
FFMPEG_LOG(" av_hwdevice_ctx_init failed.");
|
||||
|
|
|
|||
|
|
@ -8,10 +8,17 @@
|
|||
#include "PlatformDecoderModule.h"
|
||||
#include "prlink.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/widget/DMABufLibWrapper.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
VALibWrapper VALibWrapper::sFuncs;
|
||||
static int (*vaInitialize)(void* dpy, int* major_version, int* minor_version);
|
||||
static int (*vaTerminate)(void* dpy);
|
||||
static void* (*vaGetDisplayDRM)(int fd);
|
||||
|
||||
static VADisplayHolder* sDisplayHolder;
|
||||
static StaticMutex sDisplayHolderMutex;
|
||||
|
||||
void VALibWrapper::Link() {
|
||||
#define VA_FUNC_OPTION_SILENT(func) \
|
||||
|
|
@ -87,4 +94,48 @@ bool VALibWrapper::IsVAAPIAvailable() {
|
|||
return sFuncs.AreVAAPIFuncsAvailable();
|
||||
}
|
||||
|
||||
/* static */
|
||||
RefPtr<VADisplayHolder> VADisplayHolder::GetSingleton() {
|
||||
StaticMutexAutoLock lock(sDisplayHolderMutex);
|
||||
|
||||
if (sDisplayHolder) {
|
||||
return RefPtr{sDisplayHolder};
|
||||
}
|
||||
|
||||
int drmFd = widget::GetDMABufDevice()->OpenDRMFd();
|
||||
VADisplay display = vaGetDisplayDRM(drmFd);
|
||||
if (!display) {
|
||||
FFMPEGP_LOG(" Can't get DRM VA-API display.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr displayHolder = new VADisplayHolder(display, drmFd);
|
||||
|
||||
int major, minor;
|
||||
VAStatus status = vaInitialize(display, &major, &minor);
|
||||
if (status != VA_STATUS_SUCCESS) {
|
||||
FFMPEGP_LOG(" vaInitialize failed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sDisplayHolder = displayHolder;
|
||||
|
||||
return displayHolder;
|
||||
}
|
||||
|
||||
void VADisplayHolder::MaybeDestroy() {
|
||||
StaticMutexAutoLock lock(sDisplayHolderMutex);
|
||||
MOZ_ASSERT(int32_t(mRefCnt) >= 0, "dup release");
|
||||
if (mRefCnt == 0) {
|
||||
// No new reference added before the lock was taken.
|
||||
sDisplayHolder = nullptr;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
VADisplayHolder::~VADisplayHolder() {
|
||||
vaTerminate(mDisplay);
|
||||
close(mDRMFd);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
|
|
@ -7,10 +7,19 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Types.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
struct PRLibrary;
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
|
||||
// Forward declare from va.h
|
||||
typedef void* VADisplay;
|
||||
typedef int VAStatus;
|
||||
# define VA_EXPORT_SURFACE_READ_ONLY 0x0001
|
||||
# define VA_EXPORT_SURFACE_SEPARATE_LAYERS 0x0004
|
||||
# define VA_STATUS_SUCCESS 0x00000000
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS VALibWrapper {
|
||||
|
|
@ -39,15 +48,31 @@ class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS VALibWrapper {
|
|||
public:
|
||||
int (*vaExportSurfaceHandle)(void*, unsigned int, uint32_t, uint32_t, void*);
|
||||
int (*vaSyncSurface)(void*, unsigned int);
|
||||
int (*vaInitialize)(void* dpy, int* major_version, int* minor_version);
|
||||
int (*vaTerminate)(void* dpy);
|
||||
void* (*vaGetDisplayDRM)(int fd);
|
||||
|
||||
private:
|
||||
PRLibrary* mVALib;
|
||||
PRLibrary* mVALibDrm;
|
||||
};
|
||||
|
||||
class VADisplayHolder {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DESTROY(VADisplayHolder,
|
||||
MaybeDestroy())
|
||||
|
||||
static RefPtr<VADisplayHolder> GetSingleton();
|
||||
|
||||
const VADisplay mDisplay;
|
||||
|
||||
private:
|
||||
VADisplayHolder(VADisplay aDisplay, int aDRMFd)
|
||||
: mDisplay(aDisplay), mDRMFd(aDRMFd) {};
|
||||
~VADisplayHolder();
|
||||
|
||||
void MaybeDestroy();
|
||||
|
||||
const int mDRMFd;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
#endif // MOZ_WIDGET_GTK
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue