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 */
92 strncpy(env_value, value, 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 );
218 va_errorMessage("%s L%d Out of memory!n",
219 __FUNCTION__, __LINE__);
221 return VA_STATUS_ERROR_ALLOCATION_FAILED;
224 strncpy( driver_path, driver_dir, strlen(driver_dir) + 1);
225 strncat( driver_path, "/", strlen("/") );
226 strncat( driver_path, driver_name, strlen(driver_name) );
227 strncat( driver_path, DRIVER_EXTENSION, strlen(DRIVER_EXTENSION) );
229 va_infoMessage("Trying to open %s\n", driver_path);
231 handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE );
233 handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL);
236 /* Don't give errors for non-existing files */
237 if (0 == access( driver_path, F_OK))
238 va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
240 VADriverInit init_func = NULL;
241 char init_func_s[256];
244 static const struct {
247 } compatible_versions[] = {
248 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
256 for (i = 0; compatible_versions[i].major >= 0; i++) {
257 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
258 compatible_versions[i].major,
259 compatible_versions[i].minor)) {
260 init_func = (VADriverInit)dlsym(handle, init_func_s);
262 va_infoMessage("Found init function %s\n", init_func_s);
268 if (compatible_versions[i].major < 0) {
269 va_errorMessage("%s has no function %s\n",
270 driver_path, init_func_s);
273 struct VADriverVTable *vtable = ctx->vtable;
274 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
276 vaStatus = VA_STATUS_SUCCESS;
278 vtable = calloc(1, sizeof(*vtable));
280 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
282 ctx->vtable = vtable;
285 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
287 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
289 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
291 ctx->vtable_vpp = vtable_vpp;
293 if (init_func && VA_STATUS_SUCCESS == vaStatus)
294 vaStatus = (*init_func)(ctx);
296 if (VA_STATUS_SUCCESS == vaStatus) {
297 CHECK_MAXIMUM(vaStatus, ctx, profiles);
298 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
299 CHECK_MAXIMUM(vaStatus, ctx, attributes);
300 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
301 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
302 CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
303 CHECK_STRING(vaStatus, ctx, vendor);
304 CHECK_VTABLE(vaStatus, ctx, Terminate);
305 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
306 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
307 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
308 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
309 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
310 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
311 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
312 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
313 CHECK_VTABLE(vaStatus, ctx, CreateContext);
314 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
315 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
316 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
317 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
318 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
319 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
320 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
321 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
322 CHECK_VTABLE(vaStatus, ctx, EndPicture);
323 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
324 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
325 CHECK_VTABLE(vaStatus, ctx, PutSurface);
326 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
327 CHECK_VTABLE(vaStatus, ctx, CreateImage);
328 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
329 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
330 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
331 CHECK_VTABLE(vaStatus, ctx, GetImage);
332 CHECK_VTABLE(vaStatus, ctx, PutImage);
333 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
334 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
335 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
336 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
337 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
338 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
339 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
340 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
341 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
342 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
343 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
345 if (VA_STATUS_SUCCESS != vaStatus) {
346 va_errorMessage("%s init failed\n", driver_path);
349 if (VA_STATUS_SUCCESS == vaStatus)
350 ctx->handle = handle;
357 driver_dir = strtok_r(NULL, ":", &saveptr);
365 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
367 VADriverContextP ctx;
368 if (!vaDisplayIsValid(dpy))
372 if (NULL == ctx->handle)
375 return (VAPrivFunc) dlsym(ctx->handle, func);
380 * Returns a short english description of error_status
382 const char *vaErrorStr(VAStatus error_status)
384 switch(error_status) {
385 case VA_STATUS_SUCCESS:
386 return "success (no error)";
387 case VA_STATUS_ERROR_OPERATION_FAILED:
388 return "operation failed";
389 case VA_STATUS_ERROR_ALLOCATION_FAILED:
390 return "resource allocation failed";
391 case VA_STATUS_ERROR_INVALID_DISPLAY:
392 return "invalid VADisplay";
393 case VA_STATUS_ERROR_INVALID_CONFIG:
394 return "invalid VAConfigID";
395 case VA_STATUS_ERROR_INVALID_CONTEXT:
396 return "invalid VAContextID";
397 case VA_STATUS_ERROR_INVALID_SURFACE:
398 return "invalid VASurfaceID";
399 case VA_STATUS_ERROR_INVALID_BUFFER:
400 return "invalid VABufferID";
401 case VA_STATUS_ERROR_INVALID_IMAGE:
402 return "invalid VAImageID";
403 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
404 return "invalid VASubpictureID";
405 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
406 return "attribute not supported";
407 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
408 return "list argument exceeds maximum number";
409 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
410 return "the requested VAProfile is not supported";
411 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
412 return "the requested VAEntryPoint is not supported";
413 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
414 return "the requested RT Format is not supported";
415 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
416 return "the requested VABufferType is not supported";
417 case VA_STATUS_ERROR_SURFACE_BUSY:
418 return "surface is in use";
419 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
420 return "flag not supported";
421 case VA_STATUS_ERROR_INVALID_PARAMETER:
422 return "invalid parameter";
423 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
424 return "resolution not supported";
425 case VA_STATUS_ERROR_UNIMPLEMENTED:
426 return "the requested function is not implemented";
427 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
428 return "surface is in displaying (may by overlay)" ;
429 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
430 return "invalid VAImageFormat";
431 case VA_STATUS_ERROR_INVALID_VALUE:
432 return "an invalid/unsupported value was supplied";
433 case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
434 return "the requested filter is not supported";
435 case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
436 return "an invalid filter chain was supplied";
437 case VA_STATUS_ERROR_UNKNOWN:
438 return "unknown libva error";
440 return "unknown libva error / description missing";
443 VAStatus vaInitialize (
445 int *major_version, /* out */
446 int *minor_version /* out */
449 const char *driver_name_env = NULL;
450 char *driver_name = NULL;
459 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
461 vaStatus = va_getDriverName(dpy, &driver_name);
462 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
464 driver_name_env = getenv("LIBVA_DRIVER_NAME");
465 if ((VA_STATUS_SUCCESS == vaStatus) &&
466 driver_name_env && (geteuid() == getuid())) {
467 /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
468 if (driver_name) /* memory is allocated in va_getDriverName */
471 driver_name = strdup(driver_name_env);
472 vaStatus = VA_STATUS_SUCCESS;
473 va_infoMessage("User requested driver '%s'\n", driver_name);
476 if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
477 vaStatus = va_openDriver(dpy, driver_name);
478 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
480 *major_version = VA_MAJOR_VERSION;
481 *minor_version = VA_MINOR_VERSION;
483 va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n",
484 vaErrorStr(vaStatus), driver_name);
489 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
496 * After this call, all library internal resources will be cleaned up
498 VAStatus vaTerminate (
502 VAStatus vaStatus = VA_STATUS_SUCCESS;
503 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
504 VADriverContextP old_ctx;
509 if (old_ctx->handle) {
510 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
511 dlclose(old_ctx->handle);
512 old_ctx->handle = NULL;
514 free(old_ctx->vtable);
515 old_ctx->vtable = NULL;
516 free(old_ctx->vtable_vpp);
517 old_ctx->vtable_vpp = NULL;
519 VA_TRACE_LOG(va_TraceTerminate, dpy);
525 if (VA_STATUS_SUCCESS == vaStatus)
526 pDisplayContext->vaDestroy(pDisplayContext);
532 * vaQueryVendorString returns a pointer to a zero-terminated string
533 * describing some aspects of the VA implemenation on a specific
534 * hardware accelerator. The format of the returned string is:
535 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
536 * e.g. for the Intel GMA500 implementation, an example would be:
537 * "IntelGMA500-1.0-0.2-patch3
539 const char *vaQueryVendorString (
543 if (!vaDisplayIsValid(dpy))
546 return CTX(dpy)->str_vendor;
550 /* Get maximum number of profiles supported by the implementation */
551 int vaMaxNumProfiles (
555 if (!vaDisplayIsValid(dpy))
558 return CTX(dpy)->max_profiles;
561 /* Get maximum number of entrypoints supported by the implementation */
562 int vaMaxNumEntrypoints (
566 if (!vaDisplayIsValid(dpy))
569 return CTX(dpy)->max_entrypoints;
573 /* Get maximum number of attributs supported by the implementation */
574 int vaMaxNumConfigAttributes (
578 if (!vaDisplayIsValid(dpy))
581 return CTX(dpy)->max_attributes;
584 VAStatus vaQueryConfigEntrypoints (
587 VAEntrypoint *entrypoints, /* out */
588 int *num_entrypoints /* out */
591 VADriverContextP ctx;
595 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
598 VAStatus vaGetConfigAttributes (
601 VAEntrypoint entrypoint,
602 VAConfigAttrib *attrib_list, /* in/out */
606 VADriverContextP ctx;
610 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
613 VAStatus vaQueryConfigProfiles (
615 VAProfile *profile_list, /* out */
616 int *num_profiles /* out */
619 VADriverContextP ctx;
623 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
626 VAStatus vaCreateConfig (
629 VAEntrypoint entrypoint,
630 VAConfigAttrib *attrib_list,
632 VAConfigID *config_id /* out */
635 VADriverContextP ctx;
636 VAStatus vaStatus = VA_STATUS_SUCCESS;
641 vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
643 /* record the current entrypoint for further trace/fool determination */
644 VA_TRACE_ALL(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
645 VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
650 VAStatus vaDestroyConfig (
655 VADriverContextP ctx;
659 return ctx->vtable->vaDestroyConfig ( ctx, config_id );
662 VAStatus vaQueryConfigAttributes (
664 VAConfigID config_id,
665 VAProfile *profile, /* out */
666 VAEntrypoint *entrypoint, /* out */
667 VAConfigAttrib *attrib_list,/* out */
668 int *num_attribs /* out */
671 VADriverContextP ctx;
675 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
678 /* XXX: this is a slow implementation that will be removed */
680 va_impl_query_surface_attributes(
681 VADriverContextP ctx,
683 VASurfaceAttrib *out_attribs,
684 unsigned int *out_num_attribs_ptr
687 VASurfaceAttrib *attribs = NULL;
688 unsigned int num_attribs, n;
689 VASurfaceAttrib *out_attrib;
690 unsigned int out_num_attribs;
691 VAImageFormat *image_formats = NULL;
692 int num_image_formats, i;
695 /* List of surface attributes to query */
696 struct va_surface_attrib_map {
697 VASurfaceAttribType type;
698 VAGenericValueType value_type;
700 static const struct va_surface_attrib_map attribs_map[] = {
701 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
702 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
703 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
704 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
705 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
706 { VASurfaceAttribNone, }
709 if (!out_attribs || !out_num_attribs_ptr)
710 return VA_STATUS_ERROR_INVALID_PARAMETER;
711 if (!ctx->vtable->vaGetSurfaceAttributes)
712 return VA_STATUS_ERROR_UNIMPLEMENTED;
714 num_image_formats = ctx->max_image_formats;
715 image_formats = malloc(num_image_formats * sizeof(*image_formats));
716 if (!image_formats) {
717 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
721 va_status = ctx->vtable->vaQueryImageFormats(
722 ctx, image_formats, &num_image_formats);
723 if (va_status != VA_STATUS_SUCCESS)
726 num_attribs = VASurfaceAttribCount + num_image_formats;
727 attribs = malloc(num_attribs * sizeof(*attribs));
729 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
733 /* Initialize with base surface attributes, except pixel-formats */
734 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
735 VASurfaceAttrib * const attrib = &attribs[n];
736 attrib->type = attribs_map[n].type;
737 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
738 attrib->value.type = attribs_map[n].value_type;
741 /* Append image formats */
742 for (i = 0; i < num_image_formats; i++) {
743 VASurfaceAttrib * const attrib = &attribs[n];
744 attrib->type = VASurfaceAttribPixelFormat;
745 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
746 attrib->value.type = VAGenericValueTypeInteger;
747 attrib->value.value.i = image_formats[i].fourcc;
748 if (++n == num_attribs) {
749 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
755 va_status = ctx->vtable->vaGetSurfaceAttributes(
756 ctx, config, attribs, num_attribs);
757 if (va_status != VA_STATUS_SUCCESS)
760 /* Remove invalid entries */
762 for (n = 0; n < num_attribs; n++) {
763 VASurfaceAttrib * const attrib = &attribs[n];
765 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
768 // Accept all surface attributes that are not pixel-formats
769 if (attrib->type != VASurfaceAttribPixelFormat) {
774 // Drop invalid pixel-format attribute
775 if (!attrib->value.value.i) {
776 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
780 // Check for duplicates
781 int is_duplicate = 0;
782 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
783 const VASurfaceAttrib * const prev_attrib = &attribs[i];
784 if (prev_attrib->type != VASurfaceAttribPixelFormat)
786 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
789 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
794 if (*out_num_attribs_ptr < out_num_attribs) {
795 *out_num_attribs_ptr = out_num_attribs;
796 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
800 out_attrib = out_attribs;
801 for (n = 0; n < num_attribs; n++) {
802 const VASurfaceAttrib * const attrib = &attribs[n];
803 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
805 *out_attrib++ = *attrib;
815 vaQuerySurfaceAttributes(
818 VASurfaceAttrib *attrib_list,
819 unsigned int *num_attribs
822 VADriverContextP ctx;
828 return VA_STATUS_ERROR_INVALID_DISPLAY;
830 if (!ctx->vtable->vaQuerySurfaceAttributes)
831 vaStatus = va_impl_query_surface_attributes(ctx, config,
832 attrib_list, num_attribs);
834 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
835 attrib_list, num_attribs);
837 VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs);
848 VASurfaceID *surfaces,
849 unsigned int num_surfaces,
850 VASurfaceAttrib *attrib_list,
851 unsigned int num_attribs
854 VADriverContextP ctx;
860 return VA_STATUS_ERROR_INVALID_DISPLAY;
862 if (ctx->vtable->vaCreateSurfaces2)
863 vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
864 surfaces, num_surfaces,
865 attrib_list, num_attribs);
866 else if (attrib_list && num_attribs > 0)
867 vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
869 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
870 num_surfaces, surfaces);
871 VA_TRACE_LOG(va_TraceCreateSurfaces,
872 dpy, width, height, format, num_surfaces, surfaces,
873 attrib_list, num_attribs);
879 VAStatus vaDestroySurfaces (
881 VASurfaceID *surface_list,
885 VADriverContextP ctx;
891 VA_TRACE_LOG(va_TraceDestroySurfaces,
892 dpy, surface_list, num_surfaces);
894 vaStatus = ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
899 VAStatus vaCreateContext (
901 VAConfigID config_id,
905 VASurfaceID *render_targets,
906 int num_render_targets,
907 VAContextID *context /* out */
910 VADriverContextP ctx;
916 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
917 flag, render_targets, num_render_targets, context );
919 /* keep current encode/decode resoluton */
920 VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
925 VAStatus vaDestroyContext (
930 VADriverContextP ctx;
934 return ctx->vtable->vaDestroyContext( ctx, context );
937 VAStatus vaCreateBuffer (
939 VAContextID context, /* in */
940 VABufferType type, /* in */
941 unsigned int size, /* in */
942 unsigned int num_elements, /* in */
944 VABufferID *buf_id /* out */
947 VADriverContextP ctx;
953 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
955 vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
957 VA_TRACE_LOG(va_TraceCreateBuffer,
958 dpy, context, type, size, num_elements, data, buf_id);
963 VAStatus vaBufferSetNumElements (
965 VABufferID buf_id, /* in */
966 unsigned int num_elements /* in */
969 VADriverContextP ctx;
973 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
975 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
979 VAStatus vaMapBuffer (
981 VABufferID buf_id, /* in */
982 void **pbuf /* out */
985 VADriverContextP ctx;
991 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
993 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
995 VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf);
1000 VAStatus vaUnmapBuffer (
1002 VABufferID buf_id /* in */
1005 VADriverContextP ctx;
1009 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1011 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
1014 VAStatus vaDestroyBuffer (
1016 VABufferID buffer_id
1019 VADriverContextP ctx;
1023 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1025 VA_TRACE_LOG(va_TraceDestroyBuffer,
1028 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1031 VAStatus vaBufferInfo (
1033 VAContextID context, /* in */
1034 VABufferID buf_id, /* in */
1035 VABufferType *type, /* out */
1036 unsigned int *size, /* out */
1037 unsigned int *num_elements /* out */
1040 VADriverContextP ctx;
1045 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1047 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1050 /* Locks buffer for external API usage */
1052 vaAcquireBufferHandle(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info)
1054 VADriverContextP ctx;
1059 if (!ctx->vtable->vaAcquireBufferHandle)
1060 return VA_STATUS_ERROR_UNIMPLEMENTED;
1061 return ctx->vtable->vaAcquireBufferHandle(ctx, buf_id, buf_info);
1064 /* Unlocks buffer after usage from external API */
1066 vaReleaseBufferHandle(VADisplay dpy, VABufferID buf_id)
1068 VADriverContextP ctx;
1073 if (!ctx->vtable->vaReleaseBufferHandle)
1074 return VA_STATUS_ERROR_UNIMPLEMENTED;
1075 return ctx->vtable->vaReleaseBufferHandle(ctx, buf_id);
1078 VAStatus vaBeginPicture (
1080 VAContextID context,
1081 VASurfaceID render_target
1084 VADriverContextP ctx;
1090 VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target);
1091 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1093 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1098 VAStatus vaRenderPicture (
1100 VAContextID context,
1101 VABufferID *buffers,
1105 VADriverContextP ctx;
1110 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1111 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1113 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1116 VAStatus vaEndPicture (
1121 VAStatus va_status = VA_STATUS_SUCCESS;
1122 VADriverContextP ctx;
1127 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1129 va_status = ctx->vtable->vaEndPicture( ctx, context );
1131 /* dump surface content */
1132 VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 1);
1137 VAStatus vaSyncSurface (
1139 VASurfaceID render_target
1143 VADriverContextP ctx;
1148 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1149 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1154 VAStatus vaQuerySurfaceStatus (
1156 VASurfaceID render_target,
1157 VASurfaceStatus *status /* out */
1161 VADriverContextP ctx;
1165 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1167 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1172 VAStatus vaQuerySurfaceError (
1174 VASurfaceID surface,
1175 VAStatus error_status,
1176 void **error_info /*out*/
1180 VADriverContextP ctx;
1184 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1186 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1191 /* Get maximum number of image formats supported by the implementation */
1192 int vaMaxNumImageFormats (
1196 if (!vaDisplayIsValid(dpy))
1199 return CTX(dpy)->max_image_formats;
1202 VAStatus vaQueryImageFormats (
1204 VAImageFormat *format_list, /* out */
1205 int *num_formats /* out */
1208 VADriverContextP ctx;
1212 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1216 * The width and height fields returned in the VAImage structure may get
1217 * enlarged for some YUV formats. The size of the data buffer that needs
1218 * to be allocated will be given in the "data_size" field in VAImage.
1219 * Image data is not allocated by this function. The client should
1220 * allocate the memory and fill in the VAImage structure's data field
1221 * after looking at "data_size" returned from the library.
1223 VAStatus vaCreateImage (
1225 VAImageFormat *format,
1228 VAImage *image /* out */
1231 VADriverContextP ctx;
1235 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1239 * Should call DestroyImage before destroying the surface it is bound to
1241 VAStatus vaDestroyImage (
1246 VADriverContextP ctx;
1250 return ctx->vtable->vaDestroyImage ( ctx, image);
1253 VAStatus vaSetImagePalette (
1256 unsigned char *palette
1259 VADriverContextP ctx;
1263 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1267 * Retrieve surface data into a VAImage
1268 * Image must be in a format supported by the implementation
1270 VAStatus vaGetImage (
1272 VASurfaceID surface,
1273 int x, /* coordinates of the upper left source pixel */
1275 unsigned int width, /* width and height of the region */
1276 unsigned int height,
1280 VADriverContextP ctx;
1284 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1288 * Copy data from a VAImage to a surface
1289 * Image must be in a format supported by the implementation
1291 VAStatus vaPutImage (
1293 VASurfaceID surface,
1297 unsigned int src_width,
1298 unsigned int src_height,
1301 unsigned int dest_width,
1302 unsigned int dest_height
1305 VADriverContextP ctx;
1309 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1313 * Derive an VAImage from an existing surface.
1314 * This interface will derive a VAImage and corresponding image buffer from
1315 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1316 * direct CPU access. This operation is only possible on implementations with
1317 * direct rendering capabilities and internal surface formats that can be
1318 * represented with a VAImage. When the operation is not possible this interface
1319 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1320 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1323 * Implementations should only return success when the resulting image buffer
1324 * would be useable with vaMap/Unmap.
1326 * When directly accessing a surface special care must be taken to insure
1327 * proper synchronization with the graphics hardware. Clients should call
1328 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1329 * rendering or currently being displayed by an overlay.
1331 * Additionally nothing about the contents of a surface should be assumed
1332 * following a vaPutSurface. Implementations are free to modify the surface for
1333 * scaling or subpicture blending within a call to vaPutImage.
1335 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1336 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1337 * vaGetImage with other surfaces is supported.
1339 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1340 * image and image buffer structures will be destroyed; however, the underlying
1341 * surface will remain unchanged until freed with vaDestroySurfaces.
1343 VAStatus vaDeriveImage (
1345 VASurfaceID surface,
1346 VAImage *image /* out */
1349 VADriverContextP ctx;
1353 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1357 /* Get maximum number of subpicture formats supported by the implementation */
1358 int vaMaxNumSubpictureFormats (
1362 if (!vaDisplayIsValid(dpy))
1365 return CTX(dpy)->max_subpic_formats;
1369 * Query supported subpicture formats
1370 * The caller must provide a "format_list" array that can hold at
1371 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1372 * for each format to indicate additional capabilities for that format. The actual
1373 * number of formats returned in "format_list" is returned in "num_formats".
1375 VAStatus vaQuerySubpictureFormats (
1377 VAImageFormat *format_list, /* out */
1378 unsigned int *flags, /* out */
1379 unsigned int *num_formats /* out */
1382 VADriverContextP ctx;
1387 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1391 * Subpictures are created with an image associated.
1393 VAStatus vaCreateSubpicture (
1396 VASubpictureID *subpicture /* out */
1399 VADriverContextP ctx;
1403 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1407 * Destroy the subpicture before destroying the image it is assocated to
1409 VAStatus vaDestroySubpicture (
1411 VASubpictureID subpicture
1414 VADriverContextP ctx;
1418 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1421 VAStatus vaSetSubpictureImage (
1423 VASubpictureID subpicture,
1427 VADriverContextP ctx;
1431 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1436 * If chromakey is enabled, then the area where the source value falls within
1437 * the chromakey [min, max] range is transparent
1439 VAStatus vaSetSubpictureChromakey (
1441 VASubpictureID subpicture,
1442 unsigned int chromakey_min,
1443 unsigned int chromakey_max,
1444 unsigned int chromakey_mask
1447 VADriverContextP ctx;
1451 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1456 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1457 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1458 * the overall alpha is per-pixel alpha multiplied by the global alpha
1460 VAStatus vaSetSubpictureGlobalAlpha (
1462 VASubpictureID subpicture,
1466 VADriverContextP ctx;
1470 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1474 vaAssociateSubpicture associates the subpicture with the target_surface.
1475 It defines the region mapping between the subpicture and the target
1476 surface through source and destination rectangles (with the same width and height).
1477 Both will be displayed at the next call to vaPutSurface. Additional
1478 associations before the call to vaPutSurface simply overrides the association.
1480 VAStatus vaAssociateSubpicture (
1482 VASubpictureID subpicture,
1483 VASurfaceID *target_surfaces,
1485 short src_x, /* upper left offset in subpicture */
1487 unsigned short src_width,
1488 unsigned short src_height,
1489 short dest_x, /* upper left offset in surface */
1491 unsigned short dest_width,
1492 unsigned short dest_height,
1494 * whether to enable chroma-keying or global-alpha
1495 * see VA_SUBPICTURE_XXX values
1500 VADriverContextP ctx;
1504 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 );
1508 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1510 VAStatus vaDeassociateSubpicture (
1512 VASubpictureID subpicture,
1513 VASurfaceID *target_surfaces,
1517 VADriverContextP ctx;
1521 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1525 /* Get maximum number of display attributes supported by the implementation */
1526 int vaMaxNumDisplayAttributes (
1532 if (!vaDisplayIsValid(dpy))
1535 tmp = CTX(dpy)->max_display_attributes;
1537 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1543 * Query display attributes
1544 * The caller must provide a "attr_list" array that can hold at
1545 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1546 * returned in "attr_list" is returned in "num_attributes".
1548 VAStatus vaQueryDisplayAttributes (
1550 VADisplayAttribute *attr_list, /* out */
1551 int *num_attributes /* out */
1554 VADriverContextP ctx;
1559 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1561 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1568 * Get display attributes
1569 * This function returns the current attribute values in "attr_list".
1570 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1571 * from vaQueryDisplayAttributes() can have their values retrieved.
1573 VAStatus vaGetDisplayAttributes (
1575 VADisplayAttribute *attr_list, /* in/out */
1579 VADriverContextP ctx;
1584 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1586 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1592 * Set display attributes
1593 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1594 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1595 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1597 VAStatus vaSetDisplayAttributes (
1599 VADisplayAttribute *attr_list,
1603 VADriverContextP ctx;
1608 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1609 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1614 VAStatus vaLockSurface(VADisplay dpy,
1615 VASurfaceID surface,
1616 unsigned int *fourcc, /* following are output argument */
1617 unsigned int *luma_stride,
1618 unsigned int *chroma_u_stride,
1619 unsigned int *chroma_v_stride,
1620 unsigned int *luma_offset,
1621 unsigned int *chroma_u_offset,
1622 unsigned int *chroma_v_offset,
1623 unsigned int *buffer_name,
1627 VADriverContextP ctx;
1631 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);
1635 VAStatus vaUnlockSurface(VADisplay dpy,
1639 VADriverContextP ctx;
1643 return ctx->vtable->vaUnlockSurface( ctx, surface );
1646 /* Video Processing */
1647 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1648 CHECK_DISPLAY(dpy); \
1651 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1654 #define VA_VPP_INVOKE(dpy, func, args) do { \
1655 if (!ctx->vtable_vpp->va##func) \
1656 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1657 status = ctx->vtable_vpp->va##func args; \
1661 vaQueryVideoProcFilters(
1663 VAContextID context,
1664 VAProcFilterType *filters,
1665 unsigned int *num_filters
1668 VADriverContextP ctx;
1671 VA_VPP_INIT_CONTEXT(ctx, dpy);
1674 QueryVideoProcFilters,
1675 (ctx, context, filters, num_filters)
1681 vaQueryVideoProcFilterCaps(
1683 VAContextID context,
1684 VAProcFilterType type,
1686 unsigned int *num_filter_caps
1689 VADriverContextP ctx;
1692 VA_VPP_INIT_CONTEXT(ctx, dpy);
1695 QueryVideoProcFilterCaps,
1696 (ctx, context, type, filter_caps, num_filter_caps)
1702 vaQueryVideoProcPipelineCaps(
1704 VAContextID context,
1705 VABufferID *filters,
1706 unsigned int num_filters,
1707 VAProcPipelineCaps *pipeline_caps
1710 VADriverContextP ctx;
1713 VA_VPP_INIT_CONTEXT(ctx, dpy);
1716 QueryVideoProcPipelineCaps,
1717 (ctx, context, filters, num_filters, pipeline_caps)