mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
457 lines
18 KiB
C
457 lines
18 KiB
C
/* -*- 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 <dlfcn.h>
|
|
#include <pthread.h>
|
|
#include <stdlib.h>
|
|
|
|
#define GET_FUNC(func, lib) (func##Fn = dlsym(lib, #func))
|
|
|
|
#define IS_FUNC_LOADED(func) (func##Fn != NULL)
|
|
|
|
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);
|
|
static int (*vaMaxNumEntrypointsFn)(VADisplay dpy);
|
|
static VAStatus (*vaQueryConfigEntrypointsFn)(VADisplay dpy, VAProfile profile,
|
|
VAEntrypoint* entrypoint_list,
|
|
int* num_entrypoints);
|
|
static VAMessageCallback (*vaSetErrorCallbackFn)(VADisplay dpy,
|
|
VAMessageCallback callback,
|
|
void* user_context);
|
|
static VAMessageCallback (*vaSetInfoCallbackFn)(VADisplay dpy,
|
|
VAMessageCallback callback,
|
|
void* user_context);
|
|
int LoadVALibrary() {
|
|
static pthread_mutex_t sVALock = PTHREAD_MUTEX_INITIALIZER;
|
|
static void* sVALib = NULL;
|
|
static int sVAInitialized = 0;
|
|
static int sVALoaded = 0;
|
|
|
|
pthread_mutex_lock(&sVALock);
|
|
|
|
if (!sVAInitialized) {
|
|
sVAInitialized = 1;
|
|
sVALib = dlopen("libva.so.2", RTLD_LAZY);
|
|
if (!sVALib) {
|
|
pthread_mutex_unlock(&sVALock);
|
|
return 0;
|
|
}
|
|
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);
|
|
GET_FUNC(vaMaxNumEntrypoints, sVALib);
|
|
GET_FUNC(vaQueryConfigEntrypoints, sVALib);
|
|
GET_FUNC(vaSetErrorCallback, sVALib);
|
|
GET_FUNC(vaSetInfoCallback, sVALib);
|
|
|
|
sVALoaded =
|
|
(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) &&
|
|
IS_FUNC_LOADED(vaMaxNumEntrypoints) &&
|
|
IS_FUNC_LOADED(vaQueryConfigEntrypoints) &&
|
|
IS_FUNC_LOADED(vaSetErrorCallback) &&
|
|
IS_FUNC_LOADED(vaSetInfoCallback));
|
|
}
|
|
pthread_mutex_unlock(&sVALock);
|
|
return sVALoaded;
|
|
}
|
|
|
|
#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 NULL;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
int vaMaxNumEntrypoints(VADisplay dpy) {
|
|
if (LoadVALibrary()) {
|
|
return vaMaxNumEntrypointsFn(dpy);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
VAStatus vaQueryConfigEntrypoints(VADisplay dpy, VAProfile profile,
|
|
VAEntrypoint* entrypoint_list,
|
|
int* num_entrypoints) {
|
|
if (LoadVALibrary()) {
|
|
return vaQueryConfigEntrypointsFn(dpy, profile, entrypoint_list,
|
|
num_entrypoints);
|
|
}
|
|
return VA_STATUS_ERROR_UNIMPLEMENTED;
|
|
}
|
|
|
|
VAMessageCallback vaSetErrorCallback(VADisplay dpy, VAMessageCallback callback,
|
|
void* user_context) {
|
|
if (LoadVALibrary()) {
|
|
return vaSetErrorCallbackFn(dpy, callback, user_context);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
VAMessageCallback vaSetInfoCallback(VADisplay dpy, VAMessageCallback callback,
|
|
void* user_context) {
|
|
if (LoadVALibrary()) {
|
|
return vaSetInfoCallbackFn(dpy, callback, user_context);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#pragma GCC visibility pop
|