forked from mirrors/gecko-dev
Bug 1850615 Share the same libva handle across all FFmpegVideoDecoders a=pascalc
Rebased from https://hg.mozilla.org/mozilla-central/rev/b34601c7751d Differential Revision: https://phabricator.services.mozilla.com/D241144
This commit is contained in:
parent
24846b1e35
commit
c7ed87060f
8 changed files with 158 additions and 98 deletions
|
|
@ -14,6 +14,7 @@
|
|||
#ifdef MOZ_WIDGET_GTK
|
||||
# include "mozilla/gfx/gfxVars.h"
|
||||
# include "mozilla/widget/DMABufLibWrapper.h"
|
||||
# include "VALibWrapper.h"
|
||||
#endif
|
||||
|
||||
#define AV_LOG_INFO 32
|
||||
|
|
@ -288,33 +289,6 @@ FFmpegLibWrapper::LinkResult FFmpegLibWrapper::Link() {
|
|||
#undef AV_FUNC
|
||||
#undef AV_FUNC_OPTION
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
# define VA_FUNC_OPTION_SILENT(func) \
|
||||
if (!((func) = (decltype(func))PR_FindSymbol(mVALib, #func))) { \
|
||||
(func) = (decltype(func))nullptr; \
|
||||
}
|
||||
|
||||
// mVALib is optional and may not be present.
|
||||
if (mVALib) {
|
||||
VA_FUNC_OPTION_SILENT(vaExportSurfaceHandle)
|
||||
VA_FUNC_OPTION_SILENT(vaSyncSurface)
|
||||
VA_FUNC_OPTION_SILENT(vaInitialize)
|
||||
VA_FUNC_OPTION_SILENT(vaTerminate)
|
||||
}
|
||||
# undef VA_FUNC_OPTION_SILENT
|
||||
|
||||
# define VAD_FUNC_OPTION_SILENT(func) \
|
||||
if (!((func) = (decltype(func))PR_FindSymbol(mVALibDrm, #func))) { \
|
||||
FFMPEGP_LOG("Couldn't load function " #func); \
|
||||
}
|
||||
|
||||
// mVALibDrm is optional and may not be present.
|
||||
if (mVALibDrm) {
|
||||
VAD_FUNC_OPTION_SILENT(vaGetDisplayDRM)
|
||||
}
|
||||
# undef VAD_FUNC_OPTION_SILENT
|
||||
#endif
|
||||
|
||||
if (avcodec_register_all) {
|
||||
avcodec_register_all();
|
||||
}
|
||||
|
|
@ -350,48 +324,10 @@ void FFmpegLibWrapper::Unlink() {
|
|||
if (mAVCodecLib) {
|
||||
PR_UnloadLibrary(mAVCodecLib);
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
if (mVALib) {
|
||||
PR_UnloadLibrary(mVALib);
|
||||
}
|
||||
if (mVALibDrm) {
|
||||
PR_UnloadLibrary(mVALibDrm);
|
||||
}
|
||||
#endif
|
||||
PodZero(this);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
void FFmpegLibWrapper::LinkVAAPILibs() {
|
||||
if (!gfx::gfxVars::CanUseHardwareVideoDecoding() || !XRE_IsRDDProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRLibSpec lspec;
|
||||
lspec.type = PR_LibSpec_Pathname;
|
||||
const char* libDrm = "libva-drm.so.2";
|
||||
lspec.value.pathname = libDrm;
|
||||
mVALibDrm = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
|
||||
if (!mVALibDrm) {
|
||||
FFMPEGP_LOG("VA-API support: Missing or old %s library.\n", libDrm);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* lib = "libva.so.2";
|
||||
lspec.value.pathname = lib;
|
||||
mVALib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
|
||||
// Don't use libva when it's missing vaExportSurfaceHandle.
|
||||
if (mVALib && !PR_FindSymbol(mVALib, "vaExportSurfaceHandle")) {
|
||||
PR_UnloadLibrary(mVALib);
|
||||
mVALib = nullptr;
|
||||
}
|
||||
if (!mVALib) {
|
||||
FFMPEGP_LOG("VA-API support: Missing or old %s library.\n", lib);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
bool FFmpegLibWrapper::IsVAAPIAvailable() {
|
||||
# define VA_FUNC_LOADED(func) ((func) != nullptr)
|
||||
|
|
@ -407,9 +343,7 @@ bool FFmpegLibWrapper::IsVAAPIAvailable() {
|
|||
VA_FUNC_LOADED(av_hwframe_ctx_alloc) && VA_FUNC_LOADED(av_dict_set) &&
|
||||
VA_FUNC_LOADED(av_dict_free) && VA_FUNC_LOADED(avcodec_get_name) &&
|
||||
VA_FUNC_LOADED(av_get_pix_fmt_string) &&
|
||||
VA_FUNC_LOADED(vaExportSurfaceHandle) &&
|
||||
VA_FUNC_LOADED(vaSyncSurface) && VA_FUNC_LOADED(vaInitialize) &&
|
||||
VA_FUNC_LOADED(vaTerminate) && VA_FUNC_LOADED(vaGetDisplayDRM);
|
||||
VALibWrapper::IsVAAPIAvailable();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
// Examine mAVCodecLib, mAVUtilLib and mVALib, and attempt to resolve
|
||||
// Examine mAVCodecLib and mAVUtilLib, and attempt to resolve
|
||||
// all symbols.
|
||||
// Upon failure, the entire object will be reset and any attached libraries
|
||||
// will be unlinked.
|
||||
|
|
@ -87,9 +87,8 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
|
|||
void Unlink();
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
// Check if mVALib are available and we can use HW decode.
|
||||
// Check if libva and libva-drm are available and we can use HW decode.
|
||||
bool IsVAAPIAvailable();
|
||||
void LinkVAAPILibs();
|
||||
#endif
|
||||
|
||||
// indicate the version of libavcodec linked to.
|
||||
|
|
@ -210,12 +209,6 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
|
|||
AVBufferRef* (*av_hwframe_ctx_alloc)(AVBufferRef* device_ctx);
|
||||
const char* (*avcodec_get_name)(int id);
|
||||
char* (*av_get_pix_fmt_string)(char* buf, int buf_size, int pix_fmt);
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
// Only ever used with ffvpx
|
||||
|
|
@ -224,10 +217,6 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
|
|||
|
||||
PRLibrary* mAVCodecLib;
|
||||
PRLibrary* mAVUtilLib;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
PRLibrary* mVALib;
|
||||
PRLibrary* mVALibDrm;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
|
|
@ -68,10 +68,6 @@ bool FFmpegRuntimeLinker::Init() {
|
|||
return sLinkStatus == LinkStatus_SUCCEEDED;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
sLibAV.LinkVAAPILibs();
|
||||
#endif
|
||||
|
||||
// While going through all possible libs, this status will be updated with a
|
||||
// more precise error if possible.
|
||||
sLinkStatus = LinkStatus_NOT_FOUND;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "ImageContainer.h"
|
||||
#include "MP4Decoder.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "VALibWrapper.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "VPXDecoder.h"
|
||||
#include "mozilla/layers/KnowsCompositor.h"
|
||||
|
|
@ -213,15 +214,14 @@ class VAAPIDisplayHolder<LIBAV_VER>;
|
|||
template <>
|
||||
class VAAPIDisplayHolder<LIBAV_VER> {
|
||||
public:
|
||||
VAAPIDisplayHolder(FFmpegLibWrapper* aLib, VADisplay aDisplay, int aDRMFd)
|
||||
: mLib(aLib), mDisplay(aDisplay), mDRMFd(aDRMFd) {};
|
||||
VAAPIDisplayHolder(VADisplay aDisplay, int aDRMFd)
|
||||
: mDisplay(aDisplay), mDRMFd(aDRMFd) {};
|
||||
~VAAPIDisplayHolder() {
|
||||
mLib->vaTerminate(mDisplay);
|
||||
VALibWrapper::sFuncs.vaTerminate(mDisplay);
|
||||
close(mDRMFd);
|
||||
}
|
||||
|
||||
private:
|
||||
FFmpegLibWrapper* mLib;
|
||||
VADisplay mDisplay;
|
||||
int mDRMFd;
|
||||
};
|
||||
|
|
@ -246,17 +246,17 @@ bool FFmpegVideoDecoder<LIBAV_VER>::CreateVAAPIDeviceContext() {
|
|||
AVVAAPIDeviceContext* vactx = (AVVAAPIDeviceContext*)hwctx->hwctx;
|
||||
|
||||
int drmFd = widget::GetDMABufDevice()->OpenDRMFd();
|
||||
mDisplay = mLib->vaGetDisplayDRM(drmFd);
|
||||
mDisplay = VALibWrapper::sFuncs.vaGetDisplayDRM(drmFd);
|
||||
if (!mDisplay) {
|
||||
FFMPEG_LOG(" Can't get DRM VA-API display.");
|
||||
return false;
|
||||
}
|
||||
|
||||
hwctx->user_opaque = new VAAPIDisplayHolder<LIBAV_VER>(mLib, mDisplay, drmFd);
|
||||
hwctx->user_opaque = new VAAPIDisplayHolder<LIBAV_VER>(mDisplay, drmFd);
|
||||
hwctx->free = VAAPIDisplayReleaseCallback;
|
||||
|
||||
int major, minor;
|
||||
int status = mLib->vaInitialize(mDisplay, &major, &minor);
|
||||
int status = VALibWrapper::sFuncs.vaInitialize(mDisplay, &major, &minor);
|
||||
if (status != VA_STATUS_SUCCESS) {
|
||||
FFMPEG_LOG(" vaInitialize failed.");
|
||||
return false;
|
||||
|
|
@ -1516,13 +1516,13 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImage(
|
|||
bool FFmpegVideoDecoder<LIBAV_VER>::GetVAAPISurfaceDescriptor(
|
||||
VADRMPRIMESurfaceDescriptor* aVaDesc) {
|
||||
VASurfaceID surface_id = (VASurfaceID)(uintptr_t)mFrame->data[3];
|
||||
VAStatus vas = mLib->vaExportSurfaceHandle(
|
||||
VAStatus vas = VALibWrapper::sFuncs.vaExportSurfaceHandle(
|
||||
mDisplay, surface_id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
|
||||
VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS, aVaDesc);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
vas = mLib->vaSyncSurface(mDisplay, surface_id);
|
||||
vas = VALibWrapper::sFuncs.vaSyncSurface(mDisplay, surface_id);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
NS_WARNING("vaSyncSurface() failed.");
|
||||
}
|
||||
|
|
|
|||
90
dom/media/platforms/ffmpeg/VALibWrapper.cpp
Normal file
90
dom/media/platforms/ffmpeg/VALibWrapper.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VALibWrapper.h"
|
||||
|
||||
#include "FFmpegLog.h"
|
||||
#include "PlatformDecoderModule.h"
|
||||
#include "prlink.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
VALibWrapper VALibWrapper::sFuncs;
|
||||
|
||||
void VALibWrapper::Link() {
|
||||
#define VA_FUNC_OPTION_SILENT(func) \
|
||||
if (!((func) = (decltype(func))PR_FindSymbol(mVALib, #func))) { \
|
||||
(func) = (decltype(func))nullptr; \
|
||||
}
|
||||
|
||||
// mVALib is optional and may not be present.
|
||||
if (mVALib) {
|
||||
VA_FUNC_OPTION_SILENT(vaExportSurfaceHandle)
|
||||
VA_FUNC_OPTION_SILENT(vaSyncSurface)
|
||||
VA_FUNC_OPTION_SILENT(vaInitialize)
|
||||
VA_FUNC_OPTION_SILENT(vaTerminate)
|
||||
}
|
||||
#undef VA_FUNC_OPTION_SILENT
|
||||
|
||||
#define VAD_FUNC_OPTION_SILENT(func) \
|
||||
if (!((func) = (decltype(func))PR_FindSymbol(mVALibDrm, #func))) { \
|
||||
FFMPEGP_LOG("Couldn't load function " #func); \
|
||||
}
|
||||
|
||||
// mVALibDrm is optional and may not be present.
|
||||
if (mVALibDrm) {
|
||||
VAD_FUNC_OPTION_SILENT(vaGetDisplayDRM)
|
||||
}
|
||||
#undef VAD_FUNC_OPTION_SILENT
|
||||
}
|
||||
|
||||
bool VALibWrapper::LinkVAAPILibs() {
|
||||
if (!gfx::gfxVars::CanUseHardwareVideoDecoding() || !XRE_IsRDDProcess()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PRLibSpec lspec;
|
||||
lspec.type = PR_LibSpec_Pathname;
|
||||
const char* libDrm = "libva-drm.so.2";
|
||||
lspec.value.pathname = libDrm;
|
||||
mVALibDrm = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
|
||||
if (!mVALibDrm) {
|
||||
FFMPEGP_LOG("VA-API support: Missing or old %s library.\n", libDrm);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* lib = "libva.so.2";
|
||||
lspec.value.pathname = lib;
|
||||
mVALib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
|
||||
// Don't use libva when it's missing vaExportSurfaceHandle.
|
||||
if (mVALib && !PR_FindSymbol(mVALib, "vaExportSurfaceHandle")) {
|
||||
PR_UnloadLibrary(mVALib);
|
||||
mVALib = nullptr;
|
||||
}
|
||||
if (!mVALib) {
|
||||
FFMPEGP_LOG("VA-API support: Missing or old %s library.\n", lib);
|
||||
return false;
|
||||
}
|
||||
|
||||
Link();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VALibWrapper::AreVAAPIFuncsAvailable() {
|
||||
#define VA_FUNC_LOADED(func) ((func) != nullptr)
|
||||
return VA_FUNC_LOADED(vaExportSurfaceHandle) &&
|
||||
VA_FUNC_LOADED(vaSyncSurface) && VA_FUNC_LOADED(vaInitialize) &&
|
||||
VA_FUNC_LOADED(vaTerminate) && VA_FUNC_LOADED(vaGetDisplayDRM);
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool VALibWrapper::IsVAAPIAvailable() {
|
||||
static bool once = sFuncs.LinkVAAPILibs();
|
||||
(void)once;
|
||||
|
||||
return sFuncs.AreVAAPIFuncsAvailable();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
54
dom/media/platforms/ffmpeg/VALibWrapper.h
Normal file
54
dom/media/platforms/ffmpeg/VALibWrapper.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef DOM_MEDIA_PLATFORMS_FFMPEG_VALIBWRAPPER_H_
|
||||
#define DOM_MEDIA_PLATFORMS_FFMPEG_VALIBWRAPPER_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
struct PRLibrary;
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
namespace mozilla {
|
||||
|
||||
class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS VALibWrapper {
|
||||
public:
|
||||
// The class is used only in static storage and so is zero initialized.
|
||||
VALibWrapper() = default;
|
||||
// The libraries are not unloaded in the destructor, because doing so would
|
||||
// require a static constructor to register the static destructor. As the
|
||||
// class is in static storage, the destructor would only run on shutdown
|
||||
// anyway.
|
||||
~VALibWrapper() = default;
|
||||
|
||||
// Check if sVALib and sVALibDrm are available with necessary symbols and
|
||||
// initialize sFuncs;
|
||||
static bool IsVAAPIAvailable();
|
||||
static VALibWrapper sFuncs;
|
||||
|
||||
private:
|
||||
void Link();
|
||||
bool AreVAAPIFuncsAvailable();
|
||||
// Attempt to load libva-drm and libva and resolve necessary symbols.
|
||||
// Upon failure, the entire object will be reset and any attached libraries
|
||||
// will be unlinked. Do not invoke more than once.
|
||||
bool LinkVAAPILibs();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
#endif // MOZ_WIDGET_GTK
|
||||
|
||||
#endif // DOM_MEDIA_PLATFORMS_FFMPEG_VALIBWRAPPER_H_
|
||||
|
|
@ -76,10 +76,6 @@ bool FFVPXRuntimeLinker::Init() {
|
|||
|
||||
sLinkStatus = LinkStatus_FAILED;
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
sFFVPXLib.LinkVAAPILibs();
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
PathString path =
|
||||
GetLibraryFilePathname(LXUL_DLL, (PRFuncPtr)&FFVPXRuntimeLinker::Init);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ UNIFIED_SOURCES += ["FFmpegRuntimeLinker.cpp"]
|
|||
|
||||
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
UNIFIED_SOURCES += ["VALibWrapper.cpp"]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
"/media/libyuv/libyuv/include",
|
||||
|
|
|
|||
Loading…
Reference in a new issue