2 * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include "va_backend.h"
29 #include "va_backend_vpp.h"
41 #define DRIVER_EXTENSION "_drv_video.so"
43 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
44 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
47 #define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(ctx->vtable->va##func, #func)) s = VA_STATUS_ERROR_UNKNOWN;
48 #define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
49 #define CHECK_STRING(s, ctx, var) if (!va_checkString(ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
52 * read a config "env" for libva.conf or from environment setting
53 * liva.conf has higher priority
54 * return 0: the "env" is set, and the value is copied into env_value
55 * 1: the env is not set
57 int va_parseConfig(char *env, char *env_value)
59 char *token, *value, *saveptr;
66 fp = fopen("/etc/libva.conf", "r");
67 while (fp && (fgets(oneline, 1024, fp) != NULL)) {
68 if (strlen(oneline) == 1)
70 token = strtok_r(oneline, "=\n", &saveptr);
71 value = strtok_r(NULL, "=\n", &saveptr);
73 if (NULL == token || NULL == value)
76 if (strcmp(token, env) == 0) {
78 strncpy(env_value,value, 1024);
88 /* no setting in config file, use env setting */
91 strncpy(env_value, getenv(env), 1024);
99 int vaDisplayIsValid(VADisplay dpy)
101 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
102 return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext);
105 void va_errorMessage(const char *msg, ...)
107 char buf[512], *dynbuf;
112 len = vsnprintf(buf, sizeof(buf), msg, args);
115 if (len >= (int)sizeof(buf)) {
116 dynbuf = malloc(len + 1);
120 n = vsnprintf(dynbuf, len + 1, msg, args);
123 va_log_error(dynbuf);
130 void va_infoMessage(const char *msg, ...)
132 char buf[512], *dynbuf;
137 len = vsnprintf(buf, sizeof(buf), msg, args);
140 if (len >= (int)sizeof(buf)) {
141 dynbuf = malloc(len + 1);
145 n = vsnprintf(dynbuf, len + 1, msg, args);
155 static bool va_checkVtable(void *ptr, char *function)
158 va_errorMessage("No valid vtable entry for va%s\n", function);
164 static bool va_checkMaximum(int value, char *variable)
167 va_errorMessage("Failed to define max_%s in init\n", variable);
173 static bool va_checkString(const char* value, char *variable)
176 va_errorMessage("Failed to define str_%s in init\n", variable);
183 va_getDriverInitName(char *name, int namelen, int major, int minor)
185 int ret = snprintf(name, namelen, "__vaDriverInit_%d_%d", major, minor);
186 return ret > 0 && ret < namelen;
189 static VAStatus va_getDriverName(VADisplay dpy, char **driver_name)
191 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
193 return pDisplayContext->vaGetDriverName(pDisplayContext, driver_name);
196 static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
198 VADriverContextP ctx = CTX(dpy);
199 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
200 char *search_path = NULL;
204 if (geteuid() == getuid())
205 /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
206 search_path = getenv("LIBVA_DRIVERS_PATH");
208 search_path = VA_DRIVERS_PATH;
210 search_path = strdup((const char *)search_path);
211 driver_dir = strtok_r(search_path, ":", &saveptr);
214 char *driver_path = (char *) malloc( strlen(driver_dir) +
215 strlen(driver_name) +
216 strlen(DRIVER_EXTENSION) + 2 );
217 strncpy( driver_path, driver_dir, strlen(driver_dir) + 1);
218 strncat( driver_path, "/", strlen("/") );
219 strncat( driver_path, driver_name, strlen(driver_name) );
220 strncat( driver_path, DRIVER_EXTENSION, strlen(DRIVER_EXTENSION) );
222 va_infoMessage("Trying to open %s\n", driver_path);
224 handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE );
226 handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL);
229 /* Don't give errors for non-existing files */
230 if (0 == access( driver_path, F_OK))
231 va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
233 VADriverInit init_func = NULL;
234 char init_func_s[256];
237 static const struct {
240 } compatible_versions[] = {
241 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
247 for (i = 0; compatible_versions[i].major >= 0; i++) {
248 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
249 compatible_versions[i].major,
250 compatible_versions[i].minor)) {
251 init_func = (VADriverInit)dlsym(handle, init_func_s);
253 va_infoMessage("Found init function %s\n", init_func_s);
259 if (compatible_versions[i].major < 0) {
260 va_errorMessage("%s has no function %s\n",
261 driver_path, init_func_s);
264 struct VADriverVTable *vtable = ctx->vtable;
265 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
267 vaStatus = VA_STATUS_SUCCESS;
269 vtable = calloc(1, sizeof(*vtable));
271 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
273 ctx->vtable = vtable;
276 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
278 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
280 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
282 ctx->vtable_vpp = vtable_vpp;
284 if (VA_STATUS_SUCCESS == vaStatus)
285 vaStatus = (*init_func)(ctx);
287 if (VA_STATUS_SUCCESS == vaStatus) {
288 CHECK_MAXIMUM(vaStatus, ctx, profiles);
289 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
290 CHECK_MAXIMUM(vaStatus, ctx, attributes);
291 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
292 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
293 CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
294 CHECK_STRING(vaStatus, ctx, vendor);
295 CHECK_VTABLE(vaStatus, ctx, Terminate);
296 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
297 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
298 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
299 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
300 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
301 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
302 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
303 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
304 CHECK_VTABLE(vaStatus, ctx, CreateContext);
305 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
306 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
307 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
308 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
309 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
310 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
311 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
312 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
313 CHECK_VTABLE(vaStatus, ctx, EndPicture);
314 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
315 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
316 CHECK_VTABLE(vaStatus, ctx, PutSurface);
317 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
318 CHECK_VTABLE(vaStatus, ctx, CreateImage);
319 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
320 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
321 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
322 CHECK_VTABLE(vaStatus, ctx, GetImage);
323 CHECK_VTABLE(vaStatus, ctx, PutImage);
324 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
325 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
326 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
327 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
328 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
329 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
330 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
331 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
332 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
333 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
334 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
336 if (VA_STATUS_SUCCESS != vaStatus) {
337 va_errorMessage("%s init failed\n", driver_path);
340 if (VA_STATUS_SUCCESS == vaStatus)
341 ctx->handle = handle;
348 driver_dir = strtok_r(NULL, ":", &saveptr);
356 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
358 VADriverContextP ctx;
359 if (!vaDisplayIsValid(dpy))
363 if (NULL == ctx->handle)
366 return (VAPrivFunc) dlsym(ctx->handle, func);
371 * Returns a short english description of error_status
373 const char *vaErrorStr(VAStatus error_status)
375 switch(error_status) {
376 case VA_STATUS_SUCCESS:
377 return "success (no error)";
378 case VA_STATUS_ERROR_OPERATION_FAILED:
379 return "operation failed";
380 case VA_STATUS_ERROR_ALLOCATION_FAILED:
381 return "resource allocation failed";
382 case VA_STATUS_ERROR_INVALID_DISPLAY:
383 return "invalid VADisplay";
384 case VA_STATUS_ERROR_INVALID_CONFIG:
385 return "invalid VAConfigID";
386 case VA_STATUS_ERROR_INVALID_CONTEXT:
387 return "invalid VAContextID";
388 case VA_STATUS_ERROR_INVALID_SURFACE:
389 return "invalid VASurfaceID";
390 case VA_STATUS_ERROR_INVALID_BUFFER:
391 return "invalid VABufferID";
392 case VA_STATUS_ERROR_INVALID_IMAGE:
393 return "invalid VAImageID";
394 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
395 return "invalid VASubpictureID";
396 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
397 return "attribute not supported";
398 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
399 return "list argument exceeds maximum number";
400 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
401 return "the requested VAProfile is not supported";
402 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
403 return "the requested VAEntryPoint is not supported";
404 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
405 return "the requested RT Format is not supported";
406 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
407 return "the requested VABufferType is not supported";
408 case VA_STATUS_ERROR_SURFACE_BUSY:
409 return "surface is in use";
410 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
411 return "flag not supported";
412 case VA_STATUS_ERROR_INVALID_PARAMETER:
413 return "invalid parameter";
414 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
415 return "resolution not supported";
416 case VA_STATUS_ERROR_UNIMPLEMENTED:
417 return "the requested function is not implemented";
418 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
419 return "surface is in displaying (may by overlay)" ;
420 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
421 return "invalid VAImageFormat";
422 case VA_STATUS_ERROR_UNKNOWN:
423 return "unknown libva error";
425 return "unknown libva error / description missing";
428 VAStatus vaInitialize (
430 int *major_version, /* out */
431 int *minor_version /* out */
434 const char *driver_name_env = NULL;
435 char *driver_name = NULL;
444 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
446 driver_name_env = getenv("LIBVA_DRIVER_NAME");
447 if (driver_name_env && geteuid() == getuid()) {
448 /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
449 driver_name = strdup(driver_name_env);
450 vaStatus = VA_STATUS_SUCCESS;
451 va_infoMessage("User requested driver '%s'\n", driver_name);
453 vaStatus = va_getDriverName(dpy, &driver_name);
454 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
457 if (VA_STATUS_SUCCESS == vaStatus) {
458 vaStatus = va_openDriver(dpy, driver_name);
459 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
461 *major_version = VA_MAJOR_VERSION;
462 *minor_version = VA_MINOR_VERSION;
468 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
475 * After this call, all library internal resources will be cleaned up
477 VAStatus vaTerminate (
481 VAStatus vaStatus = VA_STATUS_SUCCESS;
482 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
483 VADriverContextP old_ctx;
488 if (old_ctx->handle) {
489 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
490 dlclose(old_ctx->handle);
491 old_ctx->handle = NULL;
493 free(old_ctx->vtable);
494 old_ctx->vtable = NULL;
495 free(old_ctx->vtable_vpp);
496 old_ctx->vtable_vpp = NULL;
498 if (VA_STATUS_SUCCESS == vaStatus)
499 pDisplayContext->vaDestroy(pDisplayContext);
501 VA_TRACE_LOG(va_TraceTerminate, dpy);
511 * vaQueryVendorString returns a pointer to a zero-terminated string
512 * describing some aspects of the VA implemenation on a specific
513 * hardware accelerator. The format of the returned string is:
514 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
515 * e.g. for the Intel GMA500 implementation, an example would be:
516 * "IntelGMA500-1.0-0.2-patch3
518 const char *vaQueryVendorString (
522 if (!vaDisplayIsValid(dpy))
525 return CTX(dpy)->str_vendor;
529 /* Get maximum number of profiles supported by the implementation */
530 int vaMaxNumProfiles (
534 if (!vaDisplayIsValid(dpy))
537 return CTX(dpy)->max_profiles;
540 /* Get maximum number of entrypoints supported by the implementation */
541 int vaMaxNumEntrypoints (
545 if (!vaDisplayIsValid(dpy))
548 return CTX(dpy)->max_entrypoints;
552 /* Get maximum number of attributs supported by the implementation */
553 int vaMaxNumConfigAttributes (
557 if (!vaDisplayIsValid(dpy))
560 return CTX(dpy)->max_attributes;
563 VAStatus vaQueryConfigEntrypoints (
566 VAEntrypoint *entrypoints, /* out */
567 int *num_entrypoints /* out */
570 VADriverContextP ctx;
574 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
577 VAStatus vaGetConfigAttributes (
580 VAEntrypoint entrypoint,
581 VAConfigAttrib *attrib_list, /* in/out */
585 VADriverContextP ctx;
589 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
592 VAStatus vaQueryConfigProfiles (
594 VAProfile *profile_list, /* out */
595 int *num_profiles /* out */
598 VADriverContextP ctx;
602 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
605 VAStatus vaCreateConfig (
608 VAEntrypoint entrypoint,
609 VAConfigAttrib *attrib_list,
611 VAConfigID *config_id /* out */
614 VADriverContextP ctx;
615 VAStatus vaStatus = VA_STATUS_SUCCESS;
621 vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
623 /* record the current entrypoint for further trace/fool determination */
624 VA_TRACE_FUNC(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
625 VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
630 VAStatus vaDestroyConfig (
635 VADriverContextP ctx;
639 return ctx->vtable->vaDestroyConfig ( ctx, config_id );
642 VAStatus vaQueryConfigAttributes (
644 VAConfigID config_id,
645 VAProfile *profile, /* out */
646 VAEntrypoint *entrypoint, /* out */
647 VAConfigAttrib *attrib_list,/* out */
648 int *num_attribs /* out */
651 VADriverContextP ctx;
655 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
658 /* XXX: this is a slow implementation that will be removed */
660 va_impl_query_surface_attributes(
661 VADriverContextP ctx,
663 VASurfaceAttrib *out_attribs,
664 unsigned int *out_num_attribs_ptr
667 VASurfaceAttrib *attribs = NULL;
668 unsigned int num_attribs, n;
669 VASurfaceAttrib *out_attrib;
670 unsigned int out_num_attribs;
671 VAImageFormat *image_formats = NULL;
672 int num_image_formats, i;
675 /* List of surface attributes to query */
676 struct va_surface_attrib_map {
677 VASurfaceAttribType type;
678 VAGenericValueType value_type;
680 static const struct va_surface_attrib_map attribs_map[] = {
681 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
682 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
683 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
684 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
685 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
686 { VASurfaceAttribNone, }
689 if (!out_attribs || !out_num_attribs_ptr)
690 return VA_STATUS_ERROR_INVALID_PARAMETER;
691 if (!ctx->vtable->vaGetSurfaceAttributes)
692 return VA_STATUS_ERROR_UNIMPLEMENTED;
694 num_image_formats = ctx->max_image_formats;
695 image_formats = malloc(num_image_formats * sizeof(*image_formats));
696 if (!image_formats) {
697 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
701 va_status = ctx->vtable->vaQueryImageFormats(
702 ctx, image_formats, &num_image_formats);
703 if (va_status != VA_STATUS_SUCCESS)
706 num_attribs = VASurfaceAttribCount + num_image_formats;
707 attribs = malloc(num_attribs * sizeof(*attribs));
709 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
713 /* Initialize with base surface attributes, except pixel-formats */
714 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
715 VASurfaceAttrib * const attrib = &attribs[n];
716 attrib->type = attribs_map[n].type;
717 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
718 attrib->value.type = attribs_map[n].value_type;
721 /* Append image formats */
722 for (i = 0; i < num_image_formats; i++) {
723 VASurfaceAttrib * const attrib = &attribs[n];
724 attrib->type = VASurfaceAttribPixelFormat;
725 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
726 attrib->value.type = VAGenericValueTypeInteger;
727 attrib->value.value.i = image_formats[i].fourcc;
728 if (++n == num_attribs) {
729 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
735 va_status = ctx->vtable->vaGetSurfaceAttributes(
736 ctx, config, attribs, num_attribs);
737 if (va_status != VA_STATUS_SUCCESS)
740 /* Remove invalid entries */
742 for (n = 0; n < num_attribs; n++) {
743 VASurfaceAttrib * const attrib = &attribs[n];
745 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
748 // Accept all surface attributes that are not pixel-formats
749 if (attrib->type != VASurfaceAttribPixelFormat) {
754 // Drop invalid pixel-format attribute
755 if (!attrib->value.value.i) {
756 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
760 // Check for duplicates
761 int is_duplicate = 0;
762 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
763 const VASurfaceAttrib * const prev_attrib = &attribs[i];
764 if (prev_attrib->type != VASurfaceAttribPixelFormat)
766 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
769 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
774 if (*out_num_attribs_ptr < out_num_attribs) {
775 *out_num_attribs_ptr = out_num_attribs;
776 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
780 out_attrib = out_attribs;
781 for (n = 0; n < num_attribs; n++) {
782 const VASurfaceAttrib * const attrib = &attribs[n];
783 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
785 *out_attrib++ = *attrib;
795 vaQuerySurfaceAttributes(
798 VASurfaceAttrib *attrib_list,
799 unsigned int *num_attribs
802 VADriverContextP ctx;
808 return VA_STATUS_ERROR_INVALID_DISPLAY;
810 if (!ctx->vtable->vaQuerySurfaceAttributes)
811 return va_impl_query_surface_attributes(ctx, config,
812 attrib_list, num_attribs);
814 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
815 attrib_list, num_attribs);
825 VASurfaceID *surfaces,
826 unsigned int num_surfaces,
827 VASurfaceAttrib *attrib_list,
828 unsigned int num_attribs
831 VADriverContextP ctx;
837 return VA_STATUS_ERROR_INVALID_DISPLAY;
839 if (ctx->vtable->vaCreateSurfaces2)
840 return ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
841 surfaces, num_surfaces,
842 attrib_list, num_attribs);
844 if (attrib_list && num_attribs > 0)
845 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
847 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
848 num_surfaces, surfaces);
850 VA_TRACE_LOG(va_TraceCreateSurfaces,
851 dpy, width, height, format, num_surfaces, surfaces,
852 attrib_list, num_attribs);
858 VAStatus vaDestroySurfaces (
860 VASurfaceID *surface_list,
864 VADriverContextP ctx;
868 return ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
871 VAStatus vaCreateContext (
873 VAConfigID config_id,
877 VASurfaceID *render_targets,
878 int num_render_targets,
879 VAContextID *context /* out */
882 VADriverContextP ctx;
888 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
889 flag, render_targets, num_render_targets, context );
891 /* keep current encode/decode resoluton */
892 VA_TRACE_FUNC(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
897 VAStatus vaDestroyContext (
902 VADriverContextP ctx;
906 return ctx->vtable->vaDestroyContext( ctx, context );
909 VAStatus vaCreateBuffer (
911 VAContextID context, /* in */
912 VABufferType type, /* in */
913 unsigned int size, /* in */
914 unsigned int num_elements, /* in */
916 VABufferID *buf_id /* out */
919 VADriverContextP ctx;
924 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
926 return VA_STATUS_SUCCESS;
928 return ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
931 VAStatus vaBufferSetNumElements (
933 VABufferID buf_id, /* in */
934 unsigned int num_elements /* in */
937 VADriverContextP ctx;
943 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
947 VAStatus vaMapBuffer (
949 VABufferID buf_id, /* in */
950 void **pbuf /* out */
953 VADriverContextP ctx;
960 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
962 return VA_STATUS_SUCCESS;
964 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
966 VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
971 VAStatus vaUnmapBuffer (
973 VABufferID buf_id /* in */
976 VADriverContextP ctx;
981 VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
983 return VA_STATUS_SUCCESS;
985 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
988 VAStatus vaDestroyBuffer (
993 VADriverContextP ctx;
999 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1002 VAStatus vaBufferInfo (
1004 VAContextID context, /* in */
1005 VABufferID buf_id, /* in */
1006 VABufferType *type, /* out */
1007 unsigned int *size, /* out */
1008 unsigned int *num_elements /* out */
1011 VADriverContextP ctx;
1017 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1019 return VA_STATUS_SUCCESS;
1021 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1024 VAStatus vaBeginPicture (
1026 VAContextID context,
1027 VASurfaceID render_target
1030 VADriverContextP ctx;
1036 VA_TRACE_FUNC(va_TraceBeginPicture, dpy, context, render_target);
1039 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1044 VAStatus vaRenderPicture (
1046 VAContextID context,
1047 VABufferID *buffers,
1051 VADriverContextP ctx;
1056 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1059 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1062 VAStatus vaEndPicture (
1068 VADriverContextP ctx;
1073 /* dump encode source surface */
1074 VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 0);
1075 /* return directly if do dummy operation */
1078 va_status = ctx->vtable->vaEndPicture( ctx, context );
1079 /* dump decode dest surface */
1080 VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
1085 VAStatus vaSyncSurface (
1087 VASurfaceID render_target
1091 VADriverContextP ctx;
1096 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1097 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1102 VAStatus vaQuerySurfaceStatus (
1104 VASurfaceID render_target,
1105 VASurfaceStatus *status /* out */
1109 VADriverContextP ctx;
1113 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1115 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1120 VAStatus vaQuerySurfaceError (
1122 VASurfaceID surface,
1123 VAStatus error_status,
1124 void **error_info /*out*/
1128 VADriverContextP ctx;
1132 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1134 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1139 /* Get maximum number of image formats supported by the implementation */
1140 int vaMaxNumImageFormats (
1144 if (!vaDisplayIsValid(dpy))
1147 return CTX(dpy)->max_image_formats;
1150 VAStatus vaQueryImageFormats (
1152 VAImageFormat *format_list, /* out */
1153 int *num_formats /* out */
1156 VADriverContextP ctx;
1160 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1164 * The width and height fields returned in the VAImage structure may get
1165 * enlarged for some YUV formats. The size of the data buffer that needs
1166 * to be allocated will be given in the "data_size" field in VAImage.
1167 * Image data is not allocated by this function. The client should
1168 * allocate the memory and fill in the VAImage structure's data field
1169 * after looking at "data_size" returned from the library.
1171 VAStatus vaCreateImage (
1173 VAImageFormat *format,
1176 VAImage *image /* out */
1179 VADriverContextP ctx;
1183 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1187 * Should call DestroyImage before destroying the surface it is bound to
1189 VAStatus vaDestroyImage (
1194 VADriverContextP ctx;
1198 return ctx->vtable->vaDestroyImage ( ctx, image);
1201 VAStatus vaSetImagePalette (
1204 unsigned char *palette
1207 VADriverContextP ctx;
1211 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1215 * Retrieve surface data into a VAImage
1216 * Image must be in a format supported by the implementation
1218 VAStatus vaGetImage (
1220 VASurfaceID surface,
1221 int x, /* coordinates of the upper left source pixel */
1223 unsigned int width, /* width and height of the region */
1224 unsigned int height,
1228 VADriverContextP ctx;
1232 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1236 * Copy data from a VAImage to a surface
1237 * Image must be in a format supported by the implementation
1239 VAStatus vaPutImage (
1241 VASurfaceID surface,
1245 unsigned int src_width,
1246 unsigned int src_height,
1249 unsigned int dest_width,
1250 unsigned int dest_height
1253 VADriverContextP ctx;
1257 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1261 * Derive an VAImage from an existing surface.
1262 * This interface will derive a VAImage and corresponding image buffer from
1263 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1264 * direct CPU access. This operation is only possible on implementations with
1265 * direct rendering capabilities and internal surface formats that can be
1266 * represented with a VAImage. When the operation is not possible this interface
1267 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1268 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1271 * Implementations should only return success when the resulting image buffer
1272 * would be useable with vaMap/Unmap.
1274 * When directly accessing a surface special care must be taken to insure
1275 * proper synchronization with the graphics hardware. Clients should call
1276 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1277 * rendering or currently being displayed by an overlay.
1279 * Additionally nothing about the contents of a surface should be assumed
1280 * following a vaPutSurface. Implementations are free to modify the surface for
1281 * scaling or subpicture blending within a call to vaPutImage.
1283 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1284 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1285 * vaGetImage with other surfaces is supported.
1287 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1288 * image and image buffer structures will be destroyed; however, the underlying
1289 * surface will remain unchanged until freed with vaDestroySurfaces.
1291 VAStatus vaDeriveImage (
1293 VASurfaceID surface,
1294 VAImage *image /* out */
1297 VADriverContextP ctx;
1301 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1305 /* Get maximum number of subpicture formats supported by the implementation */
1306 int vaMaxNumSubpictureFormats (
1310 if (!vaDisplayIsValid(dpy))
1313 return CTX(dpy)->max_subpic_formats;
1317 * Query supported subpicture formats
1318 * The caller must provide a "format_list" array that can hold at
1319 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1320 * for each format to indicate additional capabilities for that format. The actual
1321 * number of formats returned in "format_list" is returned in "num_formats".
1323 VAStatus vaQuerySubpictureFormats (
1325 VAImageFormat *format_list, /* out */
1326 unsigned int *flags, /* out */
1327 unsigned int *num_formats /* out */
1330 VADriverContextP ctx;
1335 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1339 * Subpictures are created with an image associated.
1341 VAStatus vaCreateSubpicture (
1344 VASubpictureID *subpicture /* out */
1347 VADriverContextP ctx;
1351 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1355 * Destroy the subpicture before destroying the image it is assocated to
1357 VAStatus vaDestroySubpicture (
1359 VASubpictureID subpicture
1362 VADriverContextP ctx;
1366 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1369 VAStatus vaSetSubpictureImage (
1371 VASubpictureID subpicture,
1375 VADriverContextP ctx;
1379 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1384 * If chromakey is enabled, then the area where the source value falls within
1385 * the chromakey [min, max] range is transparent
1387 VAStatus vaSetSubpictureChromakey (
1389 VASubpictureID subpicture,
1390 unsigned int chromakey_min,
1391 unsigned int chromakey_max,
1392 unsigned int chromakey_mask
1395 VADriverContextP ctx;
1399 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1404 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1405 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1406 * the overall alpha is per-pixel alpha multiplied by the global alpha
1408 VAStatus vaSetSubpictureGlobalAlpha (
1410 VASubpictureID subpicture,
1414 VADriverContextP ctx;
1418 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1422 vaAssociateSubpicture associates the subpicture with the target_surface.
1423 It defines the region mapping between the subpicture and the target
1424 surface through source and destination rectangles (with the same width and height).
1425 Both will be displayed at the next call to vaPutSurface. Additional
1426 associations before the call to vaPutSurface simply overrides the association.
1428 VAStatus vaAssociateSubpicture (
1430 VASubpictureID subpicture,
1431 VASurfaceID *target_surfaces,
1433 short src_x, /* upper left offset in subpicture */
1435 unsigned short src_width,
1436 unsigned short src_height,
1437 short dest_x, /* upper left offset in surface */
1439 unsigned short dest_width,
1440 unsigned short dest_height,
1442 * whether to enable chroma-keying or global-alpha
1443 * see VA_SUBPICTURE_XXX values
1448 VADriverContextP ctx;
1452 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 );
1456 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1458 VAStatus vaDeassociateSubpicture (
1460 VASubpictureID subpicture,
1461 VASurfaceID *target_surfaces,
1465 VADriverContextP ctx;
1469 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1473 /* Get maximum number of display attributes supported by the implementation */
1474 int vaMaxNumDisplayAttributes (
1480 if (!vaDisplayIsValid(dpy))
1483 tmp = CTX(dpy)->max_display_attributes;
1485 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1491 * Query display attributes
1492 * The caller must provide a "attr_list" array that can hold at
1493 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1494 * returned in "attr_list" is returned in "num_attributes".
1496 VAStatus vaQueryDisplayAttributes (
1498 VADisplayAttribute *attr_list, /* out */
1499 int *num_attributes /* out */
1502 VADriverContextP ctx;
1507 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1509 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1516 * Get display attributes
1517 * This function returns the current attribute values in "attr_list".
1518 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1519 * from vaQueryDisplayAttributes() can have their values retrieved.
1521 VAStatus vaGetDisplayAttributes (
1523 VADisplayAttribute *attr_list, /* in/out */
1527 VADriverContextP ctx;
1532 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1534 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1540 * Set display attributes
1541 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1542 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1543 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1545 VAStatus vaSetDisplayAttributes (
1547 VADisplayAttribute *attr_list,
1551 VADriverContextP ctx;
1556 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1557 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1562 VAStatus vaLockSurface(VADisplay dpy,
1563 VASurfaceID surface,
1564 unsigned int *fourcc, /* following are output argument */
1565 unsigned int *luma_stride,
1566 unsigned int *chroma_u_stride,
1567 unsigned int *chroma_v_stride,
1568 unsigned int *luma_offset,
1569 unsigned int *chroma_u_offset,
1570 unsigned int *chroma_v_offset,
1571 unsigned int *buffer_name,
1575 VADriverContextP ctx;
1579 return ctx->vtable->vaLockSurface( ctx, surface, fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset, chroma_v_offset, buffer_name, buffer);
1583 VAStatus vaUnlockSurface(VADisplay dpy,
1587 VADriverContextP ctx;
1591 return ctx->vtable->vaUnlockSurface( ctx, surface );
1594 /* Video Processing */
1595 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1596 CHECK_DISPLAY(dpy); \
1599 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1602 #define VA_VPP_INVOKE(dpy, func, args) do { \
1603 if (!ctx->vtable_vpp->va##func) \
1604 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1605 status = ctx->vtable_vpp->va##func args; \
1609 vaQueryVideoProcFilters(
1611 VAContextID context,
1612 VAProcFilterType *filters,
1613 unsigned int *num_filters
1616 VADriverContextP ctx;
1619 VA_VPP_INIT_CONTEXT(ctx, dpy);
1622 QueryVideoProcFilters,
1623 (ctx, context, filters, num_filters)
1629 vaQueryVideoProcFilterCaps(
1631 VAContextID context,
1632 VAProcFilterType type,
1634 unsigned int *num_filter_caps
1637 VADriverContextP ctx;
1640 VA_VPP_INIT_CONTEXT(ctx, dpy);
1643 QueryVideoProcFilterCaps,
1644 (ctx, context, type, filter_caps, num_filter_caps)
1650 vaQueryVideoProcPipelineCaps(
1652 VAContextID context,
1653 VABufferID *filters,
1654 unsigned int num_filters,
1655 VAProcPipelineCaps *pipeline_caps
1658 VADriverContextP ctx;
1661 VA_VPP_INIT_CONTEXT(ctx, dpy);
1664 QueryVideoProcPipelineCaps,
1665 (ctx, context, filters, num_filters, pipeline_caps)