summaryrefslogtreecommitdiff
path: root/va/va.c
diff options
context:
space:
mode:
Diffstat (limited to 'va/va.c')
-rw-r--r--va/va.c1263
1 files changed, 1263 insertions, 0 deletions
diff --git a/va/va.c b/va/va.c
new file mode 100644
index 0000000..c8e036e
--- /dev/null
+++ b/va/va.c
@@ -0,0 +1,1263 @@
+/*
+ * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define _GNU_SOURCE 1
+
+#include "va.h"
+#include "va_backend.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <unistd.h>
+
+
+#define DRIVER_INIT_FUNC "__vaDriverInit_0_31"
+
+#define DRIVER_EXTENSION "_drv_video.so"
+
+#define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
+#define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
+
+#define ASSERT assert
+#define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(ctx->vtable.va##func, #func)) s = VA_STATUS_ERROR_UNKNOWN;
+#define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
+#define CHECK_STRING(s, ctx, var) if (!va_checkString(ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
+
+#define TRACE(func) if (va_debug_trace) va_infoMessage("[TR] %s\n", #func);
+
+static int va_debug_trace = 0;
+
+static int vaDisplayIsValid(VADisplay dpy)
+{
+ VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
+ return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext);
+}
+
+static void va_errorMessage(const char *msg, ...)
+{
+ va_list args;
+
+ fprintf(stderr, "libva error: ");
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+}
+
+static void va_infoMessage(const char *msg, ...)
+{
+ va_list args;
+
+ fprintf(stderr, "libva: ");
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+}
+
+static Bool va_checkVtable(void *ptr, char *function)
+{
+ if (!ptr)
+ {
+ va_errorMessage("No valid vtable entry for va%s\n", function);
+ return False;
+ }
+ return True;
+}
+
+static Bool va_checkMaximum(int value, char *variable)
+{
+ if (!value)
+ {
+ va_errorMessage("Failed to define max_%s in init\n", variable);
+ return False;
+ }
+ return True;
+}
+
+static Bool va_checkString(const char* value, char *variable)
+{
+ if (!value)
+ {
+ va_errorMessage("Failed to define str_%s in init\n", variable);
+ return False;
+ }
+ return True;
+}
+
+static VAStatus va_getDriverName(VADisplay dpy, char **driver_name)
+{
+ VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
+
+ return pDisplayContext->vaGetDriverName(pDisplayContext, driver_name);
+}
+
+static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
+{
+ VADriverContextP ctx = CTX(dpy);
+ VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+ char *search_path = NULL;
+ char *saveptr;
+ char *driver_dir;
+
+ if (geteuid() == getuid())
+ {
+ /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
+ search_path = getenv("LIBVA_DRIVERS_PATH");
+ if (!search_path)
+ {
+ search_path = getenv("LIBGL_DRIVERS_PATH");
+ }
+ }
+ if (!search_path)
+ {
+ search_path = VA_DRIVERS_PATH;
+ }
+
+ search_path = strdup((const char *)search_path);
+ driver_dir = strtok_r((const char *)search_path, ":", &saveptr);
+ while(driver_dir)
+ {
+ void *handle = NULL;
+ char *driver_path = (char *) malloc( strlen(driver_dir) +
+ strlen(driver_name) +
+ strlen(DRIVER_EXTENSION) + 2 );
+ strncpy( driver_path, driver_dir, strlen(driver_dir) + 1);
+ strncat( driver_path, "/", strlen("/") );
+ strncat( driver_path, driver_name, strlen(driver_name) );
+ strncat( driver_path, DRIVER_EXTENSION, strlen(DRIVER_EXTENSION) );
+
+ va_infoMessage("Trying to open %s\n", driver_path);
+
+ handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE );
+ if (!handle)
+ {
+ /* Don't give errors for non-existing files */
+ if (0 == access( driver_path, F_OK))
+ {
+ va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
+ }
+ }
+ else
+ {
+ VADriverInit init_func;
+ init_func = (VADriverInit) dlsym(handle, DRIVER_INIT_FUNC);
+ if (!init_func)
+ {
+ va_errorMessage("%s has no function %s\n", driver_path, DRIVER_INIT_FUNC);
+ dlclose(handle);
+ }
+ else
+ {
+ vaStatus = (*init_func)(ctx);
+
+ if (VA_STATUS_SUCCESS == vaStatus)
+ {
+ CHECK_MAXIMUM(vaStatus, ctx, profiles);
+ CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
+ CHECK_MAXIMUM(vaStatus, ctx, attributes);
+ CHECK_MAXIMUM(vaStatus, ctx, image_formats);
+ CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
+ CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
+ CHECK_STRING(vaStatus, ctx, vendor);
+ CHECK_VTABLE(vaStatus, ctx, Terminate);
+ CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
+ CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
+ CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
+ CHECK_VTABLE(vaStatus, ctx, CreateConfig);
+ CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
+ CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
+ CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
+ CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
+ CHECK_VTABLE(vaStatus, ctx, CreateContext);
+ CHECK_VTABLE(vaStatus, ctx, DestroyContext);
+ CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
+ CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
+ CHECK_VTABLE(vaStatus, ctx, MapBuffer);
+ CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
+ CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
+ CHECK_VTABLE(vaStatus, ctx, BeginPicture);
+ CHECK_VTABLE(vaStatus, ctx, RenderPicture);
+ CHECK_VTABLE(vaStatus, ctx, EndPicture);
+ CHECK_VTABLE(vaStatus, ctx, SyncSurface);
+ CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
+ CHECK_VTABLE(vaStatus, ctx, PutSurface);
+ CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
+ CHECK_VTABLE(vaStatus, ctx, CreateImage);
+ CHECK_VTABLE(vaStatus, ctx, DeriveImage);
+ CHECK_VTABLE(vaStatus, ctx, DestroyImage);
+ CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
+ CHECK_VTABLE(vaStatus, ctx, GetImage);
+ CHECK_VTABLE(vaStatus, ctx, PutImage);
+ CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
+ CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
+ CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
+ CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
+ CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
+ CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
+ CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
+ CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
+ CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
+ CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
+ CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
+ }
+ if (VA_STATUS_SUCCESS != vaStatus)
+ {
+ va_errorMessage("%s init failed\n", driver_path);
+ dlclose(handle);
+ }
+ if (VA_STATUS_SUCCESS == vaStatus)
+ {
+ ctx->handle = handle;
+ }
+ free(driver_path);
+ break;
+ }
+ }
+ free(driver_path);
+
+ driver_dir = strtok_r(NULL, ":", &saveptr);
+ }
+
+ free(search_path);
+
+ return vaStatus;
+}
+
+VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
+{
+ VADriverContextP ctx;
+ if( !vaDisplayIsValid(dpy) )
+ return NULL;
+ ctx = CTX(dpy);
+
+ if (NULL == ctx->handle)
+ return NULL;
+
+ return (VAPrivFunc) dlsym(ctx->handle, func);
+}
+
+
+/*
+ * Returns a short english description of error_status
+ */
+const char *vaErrorStr(VAStatus error_status)
+{
+ switch(error_status)
+ {
+ case VA_STATUS_SUCCESS:
+ return "success (no error)";
+ case VA_STATUS_ERROR_OPERATION_FAILED:
+ return "operation failed";
+ case VA_STATUS_ERROR_ALLOCATION_FAILED:
+ return "resource allocation failed";
+ case VA_STATUS_ERROR_INVALID_DISPLAY:
+ return "invalid VADisplay";
+ case VA_STATUS_ERROR_INVALID_CONFIG:
+ return "invalid VAConfigID";
+ case VA_STATUS_ERROR_INVALID_CONTEXT:
+ return "invalid VAContextID";
+ case VA_STATUS_ERROR_INVALID_SURFACE:
+ return "invalid VASurfaceID";
+ case VA_STATUS_ERROR_INVALID_BUFFER:
+ return "invalid VABufferID";
+ case VA_STATUS_ERROR_INVALID_IMAGE:
+ return "invalid VAImageID";
+ case VA_STATUS_ERROR_INVALID_SUBPICTURE:
+ return "invalid VASubpictureID";
+ case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
+ return "attribute not supported";
+ case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
+ return "list argument exceeds maximum number";
+ case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
+ return "the requested VAProfile is not supported";
+ case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
+ return "the requested VAEntryPoint is not supported";
+ case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
+ return "the requested RT Format is not supported";
+ case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
+ return "the requested VABufferType is not supported";
+ case VA_STATUS_ERROR_SURFACE_BUSY:
+ return "surface is in use";
+ case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
+ return "flag not supported";
+ case VA_STATUS_ERROR_INVALID_PARAMETER:
+ return "invalid parameter";
+ case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
+ return "resolution not supported";
+ case VA_STATUS_ERROR_UNIMPLEMENTED:
+ return "the requested function is not implemented";
+ case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
+ return "surface is in displaying (may by overlay)" ;
+ case VA_STATUS_ERROR_UNKNOWN:
+ return "unknown libva error";
+ }
+ return "unknown libva error / description missing";
+}
+
+VAStatus vaInitialize (
+ VADisplay dpy,
+ int *major_version, /* out */
+ int *minor_version /* out */
+)
+{
+ char *driver_name = NULL;
+ VAStatus vaStatus;
+
+ CHECK_DISPLAY(dpy);
+
+ va_debug_trace = (getenv("LIBVA_DEBUG_TRACE") != NULL);
+
+ va_infoMessage("libva version %s\n", VA_VERSION_S);
+
+ vaStatus = va_getDriverName(dpy, &driver_name);
+ va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
+
+ if (VA_STATUS_SUCCESS == vaStatus)
+ {
+ vaStatus = va_openDriver(dpy, driver_name);
+ va_infoMessage("va_openDriver() returns %d\n", vaStatus);
+
+ *major_version = VA_MAJOR_VERSION;
+ *minor_version = VA_MINOR_VERSION;
+ }
+
+ if (driver_name)
+ free(driver_name);
+ return vaStatus;
+}
+
+
+/*
+ * After this call, all library internal resources will be cleaned up
+ */
+VAStatus vaTerminate (
+ VADisplay dpy
+)
+{
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
+ VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
+ VADriverContextP old_ctx;
+
+ CHECK_DISPLAY(dpy);
+ old_ctx = CTX(dpy);
+
+ if (old_ctx->handle)
+ {
+ vaStatus = old_ctx->vtable.vaTerminate(old_ctx);
+ dlclose(old_ctx->handle);
+ old_ctx->handle = NULL;
+ }
+
+ if (VA_STATUS_SUCCESS == vaStatus)
+ pDisplayContext->vaDestroy(pDisplayContext);
+ return vaStatus;
+}
+
+/*
+ * vaQueryVendorString returns a pointer to a zero-terminated string
+ * describing some aspects of the VA implemenation on a specific
+ * hardware accelerator. The format of the returned string is:
+ * <vendorname>-<major_version>-<minor_version>-<addtional_info>
+ * e.g. for the Intel GMA500 implementation, an example would be:
+ * "IntelGMA500-1.0-0.2-patch3
+ */
+const char *vaQueryVendorString (
+ VADisplay dpy
+)
+{
+ if( !vaDisplayIsValid(dpy) )
+ return NULL;
+
+ return CTX(dpy)->str_vendor;
+}
+
+
+/* Get maximum number of profiles supported by the implementation */
+int vaMaxNumProfiles (
+ VADisplay dpy
+)
+{
+ if( !vaDisplayIsValid(dpy) )
+ return 0;
+
+ return CTX(dpy)->max_profiles;
+}
+
+/* Get maximum number of entrypoints supported by the implementation */
+int vaMaxNumEntrypoints (
+ VADisplay dpy
+)
+{
+ if( !vaDisplayIsValid(dpy) )
+ return 0;
+
+ return CTX(dpy)->max_entrypoints;
+}
+
+
+/* Get maximum number of attributs supported by the implementation */
+int vaMaxNumConfigAttributes (
+ VADisplay dpy
+)
+{
+ if( !vaDisplayIsValid(dpy) )
+ return 0;
+
+ return CTX(dpy)->max_attributes;
+}
+
+VAStatus vaQueryConfigEntrypoints (
+ VADisplay dpy,
+ VAProfile profile,
+ VAEntrypoint *entrypoints, /* out */
+ int *num_entrypoints /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaQueryConfigEntrypoints);
+ return ctx->vtable.vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
+}
+
+VAStatus vaGetConfigAttributes (
+ VADisplay dpy,
+ VAProfile profile,
+ VAEntrypoint entrypoint,
+ VAConfigAttrib *attrib_list, /* in/out */
+ int num_attribs
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaGetConfigAttributes);
+ return ctx->vtable.vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
+}
+
+VAStatus vaQueryConfigProfiles (
+ VADisplay dpy,
+ VAProfile *profile_list, /* out */
+ int *num_profiles /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaQueryConfigProfiles);
+ return ctx->vtable.vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
+}
+
+VAStatus vaCreateConfig (
+ VADisplay dpy,
+ VAProfile profile,
+ VAEntrypoint entrypoint,
+ VAConfigAttrib *attrib_list,
+ int num_attribs,
+ VAConfigID *config_id /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaCreateConfig);
+ return ctx->vtable.vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
+}
+
+VAStatus vaDestroyConfig (
+ VADisplay dpy,
+ VAConfigID config_id
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaDestroyConfig);
+ return ctx->vtable.vaDestroyConfig ( ctx, config_id );
+}
+
+VAStatus vaQueryConfigAttributes (
+ VADisplay dpy,
+ VAConfigID config_id,
+ VAProfile *profile, /* out */
+ VAEntrypoint *entrypoint, /* out */
+ VAConfigAttrib *attrib_list,/* out */
+ int *num_attribs /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaQueryConfigAttributes);
+ return ctx->vtable.vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
+}
+
+VAStatus vaCreateSurfaces (
+ VADisplay dpy,
+ int width,
+ int height,
+ int format,
+ int num_surfaces,
+ VASurfaceID *surfaces /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaCreateSurfaces);
+ return ctx->vtable.vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces );
+}
+
+
+VAStatus vaDestroySurfaces (
+ VADisplay dpy,
+ VASurfaceID *surface_list,
+ int num_surfaces
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaDestroySurfaces);
+ return ctx->vtable.vaDestroySurfaces( ctx, surface_list, num_surfaces );
+}
+
+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 */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaCreateContext);
+ return ctx->vtable.vaCreateContext( ctx, config_id, picture_width, picture_height,
+ flag, render_targets, num_render_targets, context );
+}
+
+VAStatus vaDestroyContext (
+ VADisplay dpy,
+ VAContextID context
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaDestroyContext);
+ return ctx->vtable.vaDestroyContext( ctx, context );
+}
+
+VAStatus vaCreateBuffer (
+ VADisplay dpy,
+ VAContextID context, /* in */
+ VABufferType type, /* in */
+ unsigned int size, /* in */
+ unsigned int num_elements, /* in */
+ void *data, /* in */
+ VABufferID *buf_id /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaCreateBuffer);
+ return ctx->vtable.vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
+}
+
+VAStatus vaBufferSetNumElements (
+ VADisplay dpy,
+ VABufferID buf_id, /* in */
+ unsigned int num_elements /* in */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaBufferSetNumElements);
+ return ctx->vtable.vaBufferSetNumElements( ctx, buf_id, num_elements );
+}
+
+
+VAStatus vaMapBuffer (
+ VADisplay dpy,
+ VABufferID buf_id, /* in */
+ void **pbuf /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaMapBuffer);
+ return ctx->vtable.vaMapBuffer( ctx, buf_id, pbuf );
+}
+
+VAStatus vaUnmapBuffer (
+ VADisplay dpy,
+ VABufferID buf_id /* in */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaUnmapBuffer);
+ return ctx->vtable.vaUnmapBuffer( ctx, buf_id );
+}
+
+VAStatus vaDestroyBuffer (
+ VADisplay dpy,
+ VABufferID buffer_id
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaDestroyBuffer);
+ return ctx->vtable.vaDestroyBuffer( ctx, buffer_id );
+}
+
+VAStatus vaBeginPicture (
+ VADisplay dpy,
+ VAContextID context,
+ VASurfaceID render_target
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaBeginPicture);
+ return ctx->vtable.vaBeginPicture( ctx, context, render_target );
+}
+
+VAStatus vaRenderPicture (
+ VADisplay dpy,
+ VAContextID context,
+ VABufferID *buffers,
+ int num_buffers
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaRenderPicture);
+ return ctx->vtable.vaRenderPicture( ctx, context, buffers, num_buffers );
+}
+
+VAStatus vaEndPicture (
+ VADisplay dpy,
+ VAContextID context
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaEndPicture);
+ return ctx->vtable.vaEndPicture( ctx, context );
+}
+
+VAStatus vaSyncSurface (
+ VADisplay dpy,
+ VASurfaceID render_target
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaSyncSurface);
+ return ctx->vtable.vaSyncSurface( ctx, render_target );
+}
+
+VAStatus vaQuerySurfaceStatus (
+ VADisplay dpy,
+ VASurfaceID render_target,
+ VASurfaceStatus *status /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaQuerySurfaceStatus);
+ return ctx->vtable.vaQuerySurfaceStatus( ctx, render_target, status );
+}
+
+VAStatus vaPutSurface (
+ VADisplay dpy,
+ VASurfaceID surface,
+ Drawable draw, /* X Drawable */
+ short srcx,
+ short srcy,
+ unsigned short srcw,
+ unsigned short srch,
+ short destx,
+ short desty,
+ unsigned short destw,
+ unsigned short desth,
+ VARectangle *cliprects, /* client supplied clip list */
+ unsigned int number_cliprects, /* number of clip rects in the clip list */
+ unsigned int flags /* de-interlacing flags */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaPutSurface);
+ return ctx->vtable.vaPutSurface( ctx, surface, draw, srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
+ cliprects, number_cliprects, flags );
+}
+
+/* Get maximum number of image formats supported by the implementation */
+int vaMaxNumImageFormats (
+ VADisplay dpy
+)
+{
+ if( !vaDisplayIsValid(dpy) )
+ return 0;
+
+ return CTX(dpy)->max_image_formats;
+}
+
+VAStatus vaQueryImageFormats (
+ VADisplay dpy,
+ VAImageFormat *format_list, /* out */
+ int *num_formats /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaQueryImageFormats);
+ return ctx->vtable.vaQueryImageFormats ( ctx, format_list, num_formats);
+}
+
+/*
+ * The width and height fields returned in the VAImage structure may get
+ * enlarged for some YUV formats. The size of the data buffer that needs
+ * to be allocated will be given in the "data_size" field in VAImage.
+ * Image data is not allocated by this function. The client should
+ * allocate the memory and fill in the VAImage structure's data field
+ * after looking at "data_size" returned from the library.
+ */
+VAStatus vaCreateImage (
+ VADisplay dpy,
+ VAImageFormat *format,
+ int width,
+ int height,
+ VAImage *image /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaCreateImage);
+ return ctx->vtable.vaCreateImage ( ctx, format, width, height, image);
+}
+
+/*
+ * Should call DestroyImage before destroying the surface it is bound to
+ */
+VAStatus vaDestroyImage (
+ VADisplay dpy,
+ VAImageID image
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaDestroyImage);
+ return ctx->vtable.vaDestroyImage ( ctx, image);
+}
+
+VAStatus vaSetImagePalette (
+ VADisplay dpy,
+ VAImageID image,
+ unsigned char *palette
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaSetImagePalette);
+ return ctx->vtable.vaSetImagePalette ( ctx, image, palette);
+}
+
+/*
+ * Retrieve surface data into a VAImage
+ * Image must be in a format supported by the implementation
+ */
+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
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaGetImage);
+ return ctx->vtable.vaGetImage ( ctx, surface, x, y, width, height, image);
+}
+
+/*
+ * Copy data from a VAImage to a surface
+ * Image must be in a format supported by the implementation
+ */
+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
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaPutImage);
+ return ctx->vtable.vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
+}
+
+/*
+ * Derive an VAImage from an existing surface.
+ * This interface will derive a VAImage and corresponding image buffer from
+ * an existing VA Surface. The image buffer can then be mapped/unmapped for
+ * direct CPU access. This operation is only possible on implementations with
+ * direct rendering capabilities and internal surface formats that can be
+ * represented with a VAImage. When the operation is not possible this interface
+ * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
+ * to using vaCreateImage + vaPutImage to accomplish the same task in an
+ * indirect manner.
+ *
+ * Implementations should only return success when the resulting image buffer
+ * would be useable with vaMap/Unmap.
+ *
+ * When directly accessing a surface special care must be taken to insure
+ * proper synchronization with the graphics hardware. Clients should call
+ * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
+ * rendering or currently being displayed by an overlay.
+ *
+ * Additionally nothing about the contents of a surface should be assumed
+ * following a vaPutSurface. Implementations are free to modify the surface for
+ * scaling or subpicture blending within a call to vaPutImage.
+ *
+ * Calls to vaPutImage or vaGetImage using the same surface from which the image
+ * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
+ * vaGetImage with other surfaces is supported.
+ *
+ * An image created with vaDeriveImage should be freed with vaDestroyImage. The
+ * image and image buffer structures will be destroyed; however, the underlying
+ * surface will remain unchanged until freed with vaDestroySurfaces.
+ */
+VAStatus vaDeriveImage (
+ VADisplay dpy,
+ VASurfaceID surface,
+ VAImage *image /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaDeriveImage);
+ return ctx->vtable.vaDeriveImage ( ctx, surface, image );
+}
+
+
+/* Get maximum number of subpicture formats supported by the implementation */
+int vaMaxNumSubpictureFormats (
+ VADisplay dpy
+)
+{
+ if( !vaDisplayIsValid(dpy) )
+ return 0;
+
+ return CTX(dpy)->max_subpic_formats;
+}
+
+/*
+ * Query supported subpicture formats
+ * The caller must provide a "format_list" array that can hold at
+ * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
+ * for each format to indicate additional capabilities for that format. The actual
+ * number of formats returned in "format_list" is returned in "num_formats".
+ */
+VAStatus vaQuerySubpictureFormats (
+ VADisplay dpy,
+ VAImageFormat *format_list, /* out */
+ unsigned int *flags, /* out */
+ unsigned int *num_formats /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaQuerySubpictureFormats);
+ return ctx->vtable.vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
+}
+
+/*
+ * Subpictures are created with an image associated.
+ */
+VAStatus vaCreateSubpicture (
+ VADisplay dpy,
+ VAImageID image,
+ VASubpictureID *subpicture /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaCreateSubpicture);
+ return ctx->vtable.vaCreateSubpicture ( ctx, image, subpicture );
+}
+
+/*
+ * Destroy the subpicture before destroying the image it is assocated to
+ */
+VAStatus vaDestroySubpicture (
+ VADisplay dpy,
+ VASubpictureID subpicture
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaDestroySubpicture);
+ return ctx->vtable.vaDestroySubpicture ( ctx, subpicture);
+}
+
+VAStatus vaSetSubpictureImage (
+ VADisplay dpy,
+ VASubpictureID subpicture,
+ VAImageID image
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaSetSubpictureImage);
+ return ctx->vtable.vaSetSubpictureImage ( ctx, subpicture, image);
+}
+
+
+/*
+ * If chromakey is enabled, then the area where the source value falls within
+ * the chromakey [min, max] range is transparent
+ */
+VAStatus vaSetSubpictureChromakey (
+ VADisplay dpy,
+ VASubpictureID subpicture,
+ unsigned int chromakey_min,
+ unsigned int chromakey_max,
+ unsigned int chromakey_mask
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaSetSubpictureChromakey);
+ return ctx->vtable.vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
+}
+
+
+/*
+ * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
+ * a value of 0 means fully transparent. If per-pixel alpha is also specified then
+ * the overall alpha is per-pixel alpha multiplied by the global alpha
+ */
+VAStatus vaSetSubpictureGlobalAlpha (
+ VADisplay dpy,
+ VASubpictureID subpicture,
+ float global_alpha
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaSetSubpictureGlobalAlpha);
+ return ctx->vtable.vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
+}
+
+/*
+ vaAssociateSubpicture associates the subpicture with the target_surface.
+ It defines the region mapping between the subpicture and the target
+ surface through source and destination rectangles (with the same width and height).
+ Both will be displayed at the next call to vaPutSurface. Additional
+ associations before the call to vaPutSurface simply overrides the association.
+*/
+VAStatus vaAssociateSubpicture (
+ VADisplay dpy,
+ VASubpictureID subpicture,
+ VASurfaceID *target_surfaces,
+ int num_surfaces,
+ short src_x, /* upper left offset in subpicture */
+ short src_y,
+ unsigned short src_width,
+ unsigned short src_height,
+ short dest_x, /* upper left offset in surface */
+ short dest_y,
+ unsigned short dest_width,
+ unsigned short dest_height,
+ /*
+ * whether to enable chroma-keying or global-alpha
+ * see VA_SUBPICTURE_XXX values
+ */
+ unsigned int flags
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaAssociateSubpicture);
+ return ctx->vtable.vaAssociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height, flags );
+}
+
+/*
+ * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
+ */
+VAStatus vaDeassociateSubpicture (
+ VADisplay dpy,
+ VASubpictureID subpicture,
+ VASurfaceID *target_surfaces,
+ int num_surfaces
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaDeassociateSubpicture);
+ return ctx->vtable.vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
+}
+
+
+/* Get maximum number of display attributes supported by the implementation */
+int vaMaxNumDisplayAttributes (
+ VADisplay dpy
+)
+{
+ if( !vaDisplayIsValid(dpy) )
+ return 0;
+
+ return CTX(dpy)->max_display_attributes;
+}
+
+/*
+ * Query display attributes
+ * The caller must provide a "attr_list" array that can hold at
+ * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
+ * returned in "attr_list" is returned in "num_attributes".
+ */
+VAStatus vaQueryDisplayAttributes (
+ VADisplay dpy,
+ VADisplayAttribute *attr_list, /* out */
+ int *num_attributes /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaQueryDisplayAttributes);
+ return ctx->vtable.vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
+}
+
+/*
+ * Get display attributes
+ * This function returns the current attribute values in "attr_list".
+ * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
+ * from vaQueryDisplayAttributes() can have their values retrieved.
+ */
+VAStatus vaGetDisplayAttributes (
+ VADisplay dpy,
+ VADisplayAttribute *attr_list, /* in/out */
+ int num_attributes
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaGetDisplayAttributes);
+ return ctx->vtable.vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
+}
+
+/*
+ * Set display attributes
+ * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
+ * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
+ * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
+ */
+VAStatus vaSetDisplayAttributes (
+ VADisplay dpy,
+ VADisplayAttribute *attr_list,
+ int num_attributes
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaSetDisplayAttributes);
+ return ctx->vtable.vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
+}
+
+/* Wrap a CI (camera imaging) frame as a VA surface to share captured video between camear
+ * and VA encode. With frame_id, VA driver need to call CI interfaces to get the information
+ * of the frame, and to determine if the frame can be wrapped as a VA surface
+ *
+ * Application should make sure the frame is idle before the frame is passed into VA stack
+ * and also a vaSyncSurface should be called before application tries to access the frame
+ * from CI stack
+ */
+VAStatus vaCreateSurfaceFromCIFrame (
+ VADisplay dpy,
+ unsigned long frame_id,
+ VASurfaceID *surface /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaCreateSurfacesFromCIFrame);
+
+ if (ctx->vtable.vaCreateSurfaceFromCIFrame)
+ return ctx->vtable.vaCreateSurfaceFromCIFrame( ctx, frame_id, surface );
+ else
+ return VA_STATUS_ERROR_UNKNOWN;
+}
+
+
+/* Wrap a V4L2 buffer as a VA surface, so that V4L2 camera, VA encode
+ * can share the data without copy
+ * The VA driver should query the camera device from v4l2_fd to see
+ * if camera device memory/buffer can be wrapped into a VA surface
+ * Buffer information is passed in by v4l2_fmt and v4l2_buf structure,
+ * VA driver also needs do further check if the buffer can meet encode
+ * hardware requirement, such as dimension, fourcc, stride, etc
+ *
+ * Application should make sure the buffer is idle before the frame into VA stack
+ * and also a vaSyncSurface should be called before application tries to access the frame
+ * from V4L2 stack
+ */
+VAStatus vaCreateSurfaceFromV4L2Buf(
+ VADisplay dpy,
+ int v4l2_fd, /* file descriptor of V4L2 device */
+ struct v4l2_format *v4l2_fmt, /* format of V4L2 */
+ struct v4l2_buffer *v4l2_buf, /* V4L2 buffer */
+ VASurfaceID *surface /* out */
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vtable.vaCreateSurfaceFromV4L2Buf);
+
+ if (ctx->vtable.vaCreateSurfaceFromV4L2Buf)
+ return ctx->vtable.vaCreateSurfaceFromV4L2Buf( ctx, v4l2_fd, v4l2_fmt, v4l2_buf, surface );
+ else
+ return VA_STATUS_ERROR_UNKNOWN;
+}
+
+/* It is a debug interface, and isn't exported in core VAAPI
+ * It is used to dump surface data into system memory
+ * Application should explicitly call free to release the buffer memory
+ */
+
+VAStatus vaCopySurfaceToBuffer(VADisplay dpy,
+ VASurfaceID surface,
+ unsigned int *fourcc, /* following are output argument */
+ unsigned int *luma_stride,
+ unsigned int *chroma_u_stride,
+ unsigned int *chroma_v_stride,
+ unsigned int *luma_offset,
+ unsigned int *chroma_u_offset,
+ unsigned int *chroma_v_offset,
+ void **buffer
+)
+{
+ VADriverContextP ctx;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ TRACE(vaCopySurfaceToBuffer);
+ if (ctx->vtable.vaCopySurfaceToBuffer)
+ return ctx->vtable.vaCopySurfaceToBuffer( ctx, surface, fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset, chroma_v_offset, buffer);
+ else
+ return VA_STATUS_ERROR_UNKNOWN;
+}