Bug 1660336 Provide libva wrapper to run Firefox on systems without libva installed, r=jya

Differential Revision: https://phabricator.services.mozilla.com/D94650
This commit is contained in:
stransky 2020-11-26 21:25:59 +00:00
parent 24a4ddcc49
commit c3c0341407
6 changed files with 498 additions and 0 deletions

View File

@ -1344,6 +1344,9 @@ if CONFIG['MOZ_WAYLAND']:
'wayland-client.h',
'wayland-egl.h',
'wayland-util.h',
'va/va.h',
'va/va_dec_vp9.h',
'va/va_dec_vp8.h',
]
if CONFIG['OS_TARGET'] in ('Android', 'Linux', 'FreeBSD'):

View File

@ -102,6 +102,7 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
'vaapi_vp8.c',
'vaapi_vp9.c',
]
USE_LIBS += ['mozva']
if CONFIG['MOZ_LIBAV_FFT']:
SOURCES += [

View File

@ -62,6 +62,7 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
SOURCES += [
'hwcontext_vaapi.c',
]
USE_LIBS += ['mozva']
SYMBOLS_FILE = 'avutil.symbols'
NoVisibilityFlags()

View File

@ -11,3 +11,8 @@ DIRS += [
'libavutil',
'libavcodec'
]
if CONFIG['MOZ_WAYLAND']:
DIRS += [
'mozva',
]

View File

@ -0,0 +1,11 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
SOURCES += [
'mozva.cpp',
]
SharedLibrary('mozva')

477
media/ffvpx/mozva/mozva.cpp Normal file
View File

@ -0,0 +1,477 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* 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/. */
#pragma GCC visibility push(default)
#include <va/va.h>
#pragma GCC visibility pop
#include "mozilla/Types.h"
#include "mozilla/ScopeExit.h"
#include <dlfcn.h>
#include <pthread.h>
#include <stdlib.h>
#define GET_FUNC(func, lib) \
func##Fn = \
(decltype(func##Fn))dlsym(lib, #func) \
#define IS_FUNC_LOADED(func) \
(func##Fn != nullptr) \
static VAStatus (*vaDestroyBufferFn)(VADisplay dpy, VABufferID buffer_id);
static VAStatus (*vaBeginPictureFn)(VADisplay dpy, VAContextID context,
VASurfaceID render_target);
static VAStatus (*vaEndPictureFn)(VADisplay dpy, VAContextID context);
static VAStatus (*vaRenderPictureFn)(VADisplay dpy, VAContextID context,
VABufferID *buffers, int num_buffers);
static int (*vaMaxNumProfilesFn)(VADisplay dpy);
static VAStatus (*vaCreateContextFn)(VADisplay dpy, VAConfigID config_id,
int picture_width, int picture_height,
int flag, VASurfaceID *render_targets,
int num_render_targets,
VAContextID *context /* out */);
static VAStatus (*vaDestroyContextFn)( VADisplay dpy, VAContextID context);
static VAStatus (*vaCreateBufferFn)(VADisplay dpy, VAContextID context,
VABufferType type, /* in */
unsigned int size, /* in */
unsigned int num_elements, /* in */
void *data, /* in */
VABufferID *buf_id /* out */);
static VAStatus (*vaQuerySurfaceAttributesFn)(VADisplay dpy,
VAConfigID config,
VASurfaceAttrib *attrib_list,
unsigned int *num_attribs);
static VAStatus (*vaQueryConfigProfilesFn)(VADisplay dpy,
VAProfile *profile_list, /* out */
int *num_profiles /* out */);
static const char* (*vaErrorStrFn)(VAStatus error_status);
static VAStatus (*vaCreateConfigFn)(VADisplay dpy, VAProfile profile,
VAEntrypoint entrypoint,
VAConfigAttrib *attrib_list,
int num_attribs,
VAConfigID *config_id /* out */);
static VAStatus (*vaDestroyConfigFn)(VADisplay dpy, VAConfigID config_id);
static int (*vaMaxNumImageFormatsFn)(VADisplay dpy);
static VAStatus (*vaQueryImageFormatsFn)(VADisplay dpy,
VAImageFormat *format_list, /* out */
int *num_formats /* out */);
static const char * (*vaQueryVendorStringFn)(VADisplay dpy);
static VAStatus (*vaDestroySurfacesFn)(VADisplay dpy, VASurfaceID *surfaces,
int num_surfaces);
static VAStatus (*vaCreateSurfacesFn)(VADisplay dpy,
unsigned int format,
unsigned int width,
unsigned int height,
VASurfaceID *surfaces,
unsigned int num_surfaces,
VASurfaceAttrib *attrib_list,
unsigned int num_attribs);
static VAStatus (*vaDeriveImageFn)(VADisplay dpy, VASurfaceID surface,
VAImage *image /* out */);
static VAStatus (*vaDestroyImageFn)(VADisplay dpy, VAImageID image);
static VAStatus (*vaPutImageFn)(VADisplay dpy,
VASurfaceID surface,
VAImageID image,
int src_x,
int src_y,
unsigned int src_width,
unsigned int src_height,
int dest_x,
int dest_y,
unsigned int dest_width,
unsigned int dest_height);
static VAStatus (*vaSyncSurfaceFn)(VADisplay dpy, VASurfaceID render_target);
static VAStatus (*vaCreateImageFn)(VADisplay dpy,
VAImageFormat *format,
int width,
int height,
VAImage *image /* out */);
static VAStatus (*vaGetImageFn)(VADisplay dpy,
VASurfaceID surface,
int x, /* coordinates of the upper left source pixel */
int y,
unsigned int width, /* width and height of the region */
unsigned int height,
VAImageID image);
static VAStatus (*vaMapBufferFn)(VADisplay dpy,
VABufferID buf_id, /* in */
void **pbuf /* out */);
static VAStatus (*vaUnmapBufferFn)(VADisplay dpy,
VABufferID buf_id /* in */);
static VAStatus (*vaTerminateFn)(VADisplay dpy);
static VAStatus (*vaInitializeFn)(VADisplay dpy,
int *major_version, /* out */
int *minor_version /* out */);
static VAStatus (*vaSetDriverNameFn)(VADisplay dpy, char *driver_name);
bool LoadVALibrary() {
static bool vaLibraryLoaded = []() {
static void* sVALib = dlopen("libva.so.2", RTLD_LAZY);
if (!sVALib) {
return false;
}
GET_FUNC(vaDestroyBuffer, sVALib);
GET_FUNC(vaBeginPicture, sVALib);
GET_FUNC(vaEndPicture, sVALib);
GET_FUNC(vaRenderPicture, sVALib);
GET_FUNC(vaMaxNumProfiles, sVALib);
GET_FUNC(vaCreateContext, sVALib);
GET_FUNC(vaDestroyContext, sVALib);
GET_FUNC(vaCreateBuffer, sVALib);
GET_FUNC(vaQuerySurfaceAttributes, sVALib);
GET_FUNC(vaQueryConfigProfiles, sVALib);
GET_FUNC(vaErrorStr, sVALib);
GET_FUNC(vaCreateConfig, sVALib);
GET_FUNC(vaDestroyConfig, sVALib);
GET_FUNC(vaMaxNumImageFormats, sVALib);
GET_FUNC(vaQueryImageFormats, sVALib);
GET_FUNC(vaQueryVendorString, sVALib);
GET_FUNC(vaDestroySurfaces, sVALib);
GET_FUNC(vaCreateSurfaces, sVALib);
GET_FUNC(vaDeriveImage, sVALib);
GET_FUNC(vaDestroyImage, sVALib);
GET_FUNC(vaPutImage, sVALib);
GET_FUNC(vaSyncSurface, sVALib);
GET_FUNC(vaCreateImage, sVALib);
GET_FUNC(vaGetImage, sVALib);
GET_FUNC(vaMapBuffer, sVALib);
GET_FUNC(vaUnmapBuffer, sVALib);
GET_FUNC(vaTerminate, sVALib);
GET_FUNC(vaInitialize, sVALib);
GET_FUNC(vaSetDriverName, sVALib);
return (IS_FUNC_LOADED(vaDestroyBuffer) &&
IS_FUNC_LOADED(vaBeginPicture) &&
IS_FUNC_LOADED(vaEndPicture) &&
IS_FUNC_LOADED(vaRenderPicture) &&
IS_FUNC_LOADED(vaMaxNumProfiles) &&
IS_FUNC_LOADED(vaCreateContext) &&
IS_FUNC_LOADED(vaDestroyContext) &&
IS_FUNC_LOADED(vaCreateBuffer) &&
IS_FUNC_LOADED(vaQuerySurfaceAttributes) &&
IS_FUNC_LOADED(vaQueryConfigProfiles) &&
IS_FUNC_LOADED(vaErrorStr) &&
IS_FUNC_LOADED(vaCreateConfig) &&
IS_FUNC_LOADED(vaDestroyConfig) &&
IS_FUNC_LOADED(vaMaxNumImageFormats) &&
IS_FUNC_LOADED(vaQueryImageFormats) &&
IS_FUNC_LOADED(vaQueryVendorString) &&
IS_FUNC_LOADED(vaDestroySurfaces) &&
IS_FUNC_LOADED(vaCreateSurfaces) &&
IS_FUNC_LOADED(vaDeriveImage) &&
IS_FUNC_LOADED(vaDestroyImage) &&
IS_FUNC_LOADED(vaPutImage) &&
IS_FUNC_LOADED(vaSyncSurface) &&
IS_FUNC_LOADED(vaCreateImage) &&
IS_FUNC_LOADED(vaGetImage) &&
IS_FUNC_LOADED(vaMapBuffer) &&
IS_FUNC_LOADED(vaUnmapBuffer) &&
IS_FUNC_LOADED(vaTerminate) &&
IS_FUNC_LOADED(vaInitialize) &&
IS_FUNC_LOADED(vaSetDriverName));
}();
return vaLibraryLoaded;
}
#pragma GCC visibility push(default)
VAStatus vaDestroyBuffer(VADisplay dpy, VABufferID buffer_id)
{
if (LoadVALibrary()) {
return vaDestroyBufferFn(dpy, buffer_id);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaBeginPicture(VADisplay dpy, VAContextID context,
VASurfaceID render_target)
{
if (LoadVALibrary()) {
return vaBeginPictureFn(dpy, context, render_target);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaEndPicture(VADisplay dpy, VAContextID context)
{
if (LoadVALibrary()) {
return vaEndPictureFn(dpy, context);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaRenderPicture(VADisplay dpy, VAContextID context,
VABufferID *buffers, int num_buffers)
{
if (LoadVALibrary()) {
return vaRenderPictureFn(dpy, context, buffers, num_buffers);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
int vaMaxNumProfiles(VADisplay dpy)
{
if (LoadVALibrary()) {
return vaMaxNumProfilesFn(dpy);
}
return 0;
}
VAStatus vaCreateContext(VADisplay dpy, VAConfigID config_id,
int picture_width, int picture_height,
int flag, VASurfaceID *render_targets,
int num_render_targets,
VAContextID *context /* out */)
{
if (LoadVALibrary()) {
return vaCreateContextFn(dpy, config_id, picture_width, picture_height,
flag, render_targets, num_render_targets,
context);
}
*context = 0;
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaDestroyContext( VADisplay dpy, VAContextID context)
{
if (LoadVALibrary()) {
return vaDestroyContextFn(dpy, context);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaCreateBuffer(VADisplay dpy, VAContextID context,
VABufferType type, /* in */
unsigned int size, /* in */
unsigned int num_elements, /* in */
void *data, /* in */
VABufferID *buf_id /* out */)
{
if (LoadVALibrary()) {
return vaCreateBufferFn(dpy, context, type, size, num_elements,
data, buf_id);
}
*buf_id = 0;
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaQuerySurfaceAttributes(VADisplay dpy,
VAConfigID config,
VASurfaceAttrib *attrib_list,
unsigned int *num_attribs)
{
if (LoadVALibrary()) {
return vaQuerySurfaceAttributesFn(dpy, config, attrib_list, num_attribs);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaQueryConfigProfiles(VADisplay dpy,
VAProfile *profile_list, /* out */
int *num_profiles /* out */)
{
if (LoadVALibrary()) {
return vaQueryConfigProfilesFn(dpy, profile_list, num_profiles);
}
*num_profiles = 0;
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
const char *vaErrorStr(VAStatus error_status)
{
if (LoadVALibrary()) {
return vaErrorStrFn(error_status);
}
static char tmp[] = "Unimplemented";
return tmp;
}
VAStatus vaCreateConfig(VADisplay dpy, VAProfile profile,
VAEntrypoint entrypoint,
VAConfigAttrib *attrib_list,
int num_attribs,
VAConfigID *config_id /* out */)
{
if (LoadVALibrary()) {
return vaCreateConfigFn(dpy, profile, entrypoint, attrib_list, num_attribs,
config_id);
}
*config_id = 0;
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaDestroyConfig(VADisplay dpy, VAConfigID config_id)
{
if (LoadVALibrary()) {
return vaDestroyConfigFn(dpy, config_id);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
int vaMaxNumImageFormats(VADisplay dpy)
{
if (LoadVALibrary()) {
return vaMaxNumImageFormatsFn(dpy);
}
return 0;
}
VAStatus vaQueryImageFormats(VADisplay dpy,
VAImageFormat *format_list,
int *num_formats)
{
if (LoadVALibrary()) {
return vaQueryImageFormatsFn(dpy, format_list, num_formats);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
const char * vaQueryVendorString(VADisplay dpy)
{
if (LoadVALibrary()) {
return vaQueryVendorStringFn(dpy);
}
return nullptr;
}
VAStatus vaDestroySurfaces(VADisplay dpy, VASurfaceID *surfaces,
int num_surfaces)
{
if (LoadVALibrary()) {
return vaDestroySurfacesFn(dpy, surfaces, num_surfaces);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaCreateSurfaces(VADisplay dpy,
unsigned int format,
unsigned int width,
unsigned int height,
VASurfaceID *surfaces,
unsigned int num_surfaces,
VASurfaceAttrib *attrib_list,
unsigned int num_attribs)
{
if (LoadVALibrary()) {
return vaCreateSurfacesFn(dpy, format, width, height,
surfaces, num_surfaces, attrib_list, num_attribs);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaDeriveImage(VADisplay dpy, VASurfaceID surface,
VAImage *image /* out */)
{
if (LoadVALibrary()) {
return vaDeriveImageFn(dpy, surface, image);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaDestroyImage(VADisplay dpy, VAImageID image)
{
if (LoadVALibrary()) {
return vaDestroyImageFn(dpy, image);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaPutImage(VADisplay dpy,
VASurfaceID surface,
VAImageID image,
int src_x,
int src_y,
unsigned int src_width,
unsigned int src_height,
int dest_x,
int dest_y,
unsigned int dest_width,
unsigned int dest_height)
{
if (LoadVALibrary()) {
return vaPutImageFn(dpy, surface, image, src_x, src_y, src_width, src_height,
dest_x, dest_y, dest_width, dest_height);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaSyncSurface(VADisplay dpy, VASurfaceID render_target)
{
if (LoadVALibrary()) {
return vaSyncSurfaceFn(dpy, render_target);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaCreateImage(VADisplay dpy, VAImageFormat *format,
int width, int height, VAImage *image /* out */)
{
if (LoadVALibrary()) {
return vaCreateImageFn(dpy, format, width, height, image);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaGetImage(VADisplay dpy,
VASurfaceID surface,
int x, /* coordinates of the upper left source pixel */
int y,
unsigned int width, /* width and height of the region */
unsigned int height,
VAImageID image)
{
if (LoadVALibrary()) {
return vaGetImageFn(dpy, surface, x, y, width, height, image);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaMapBuffer(VADisplay dpy,
VABufferID buf_id, /* in */
void **pbuf /* out */)
{
if (LoadVALibrary()) {
return vaMapBufferFn(dpy, buf_id, pbuf);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaUnmapBuffer(VADisplay dpy, VABufferID buf_id /* in */)
{
if (LoadVALibrary()) {
return vaUnmapBufferFn(dpy, buf_id);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaTerminate(VADisplay dpy)
{
if (LoadVALibrary()) {
return vaTerminateFn(dpy);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaInitialize(VADisplay dpy,
int *major_version, /* out */
int *minor_version /* out */)
{
if (LoadVALibrary()) {
return vaInitializeFn(dpy, major_version, minor_version);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus vaSetDriverName(VADisplay dpy, char *driver_name)
{
if (LoadVALibrary()) {
return vaSetDriverNameFn(dpy, driver_name);
}
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
#pragma GCC visibility pop