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 },
254 for (i = 0; compatible_versions[i].major >= 0; i++) {
255 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
256 compatible_versions[i].major,
257 compatible_versions[i].minor)) {
258 init_func = (VADriverInit)dlsym(handle, init_func_s);
260 va_infoMessage("Found init function %s\n", init_func_s);
266 if (compatible_versions[i].major < 0) {
267 va_errorMessage("%s has no function %s\n",
268 driver_path, init_func_s);
271 struct VADriverVTable *vtable = ctx->vtable;
272 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
274 vaStatus = VA_STATUS_SUCCESS;
276 vtable = calloc(1, sizeof(*vtable));
278 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
280 ctx->vtable = vtable;
283 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
285 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
287 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
289 ctx->vtable_vpp = vtable_vpp;
291 if (init_func && VA_STATUS_SUCCESS == vaStatus)
292 vaStatus = (*init_func)(ctx);
294 if (VA_STATUS_SUCCESS == vaStatus) {
295 CHECK_MAXIMUM(vaStatus, ctx, profiles);
296 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
297 CHECK_MAXIMUM(vaStatus, ctx, attributes);
298 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
299 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
300 CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
301 CHECK_STRING(vaStatus, ctx, vendor);
302 CHECK_VTABLE(vaStatus, ctx, Terminate);
303 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
304 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
305 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
306 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
307 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
308 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
309 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
310 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
311 CHECK_VTABLE(vaStatus, ctx, CreateContext);
312 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
313 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
314 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
315 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
316 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
317 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
318 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
319 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
320 CHECK_VTABLE(vaStatus, ctx, EndPicture);
321 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
322 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
323 CHECK_VTABLE(vaStatus, ctx, PutSurface);
324 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
325 CHECK_VTABLE(vaStatus, ctx, CreateImage);
326 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
327 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
328 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
329 CHECK_VTABLE(vaStatus, ctx, GetImage);
330 CHECK_VTABLE(vaStatus, ctx, PutImage);
331 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
332 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
333 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
334 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
335 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
336 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
337 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
338 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
339 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
340 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
341 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
343 if (VA_STATUS_SUCCESS != vaStatus) {
344 va_errorMessage("%s init failed\n", driver_path);
347 if (VA_STATUS_SUCCESS == vaStatus)
348 ctx->handle = handle;
355 driver_dir = strtok_r(NULL, ":", &saveptr);
363 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
365 VADriverContextP ctx;
366 if (!vaDisplayIsValid(dpy))
370 if (NULL == ctx->handle)
373 return (VAPrivFunc) dlsym(ctx->handle, func);
378 * Returns a short english description of error_status
380 const char *vaErrorStr(VAStatus error_status)
382 switch(error_status) {
383 case VA_STATUS_SUCCESS:
384 return "success (no error)";
385 case VA_STATUS_ERROR_OPERATION_FAILED:
386 return "operation failed";
387 case VA_STATUS_ERROR_ALLOCATION_FAILED:
388 return "resource allocation failed";
389 case VA_STATUS_ERROR_INVALID_DISPLAY:
390 return "invalid VADisplay";
391 case VA_STATUS_ERROR_INVALID_CONFIG:
392 return "invalid VAConfigID";
393 case VA_STATUS_ERROR_INVALID_CONTEXT:
394 return "invalid VAContextID";
395 case VA_STATUS_ERROR_INVALID_SURFACE:
396 return "invalid VASurfaceID";
397 case VA_STATUS_ERROR_INVALID_BUFFER:
398 return "invalid VABufferID";
399 case VA_STATUS_ERROR_INVALID_IMAGE:
400 return "invalid VAImageID";
401 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
402 return "invalid VASubpictureID";
403 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
404 return "attribute not supported";
405 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
406 return "list argument exceeds maximum number";
407 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
408 return "the requested VAProfile is not supported";
409 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
410 return "the requested VAEntryPoint is not supported";
411 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
412 return "the requested RT Format is not supported";
413 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
414 return "the requested VABufferType is not supported";
415 case VA_STATUS_ERROR_SURFACE_BUSY:
416 return "surface is in use";
417 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
418 return "flag not supported";
419 case VA_STATUS_ERROR_INVALID_PARAMETER:
420 return "invalid parameter";
421 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
422 return "resolution not supported";
423 case VA_STATUS_ERROR_UNIMPLEMENTED:
424 return "the requested function is not implemented";
425 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
426 return "surface is in displaying (may by overlay)" ;
427 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
428 return "invalid VAImageFormat";
429 case VA_STATUS_ERROR_INVALID_VALUE:
430 return "an invalid/unsupported value was supplied";
431 case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
432 return "the requested filter is not supported";
433 case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
434 return "an invalid filter chain was supplied";
435 case VA_STATUS_ERROR_UNKNOWN:
436 return "unknown libva error";
438 return "unknown libva error / description missing";
441 VAStatus vaInitialize (
443 int *major_version, /* out */
444 int *minor_version /* out */
447 const char *driver_name_env = NULL;
448 char *driver_name = NULL;
457 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
459 vaStatus = va_getDriverName(dpy, &driver_name);
460 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
462 driver_name_env = getenv("LIBVA_DRIVER_NAME");
463 if ((VA_STATUS_SUCCESS == vaStatus) &&
464 driver_name_env && (geteuid() == getuid())) {
465 /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
466 if (driver_name) /* memory is allocated in va_getDriverName */
469 driver_name = strdup(driver_name_env);
470 vaStatus = VA_STATUS_SUCCESS;
471 va_infoMessage("User requested driver '%s'\n", driver_name);
474 if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
475 vaStatus = va_openDriver(dpy, driver_name);
476 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
478 *major_version = VA_MAJOR_VERSION;
479 *minor_version = VA_MINOR_VERSION;
481 va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n",
482 vaErrorStr(vaStatus), driver_name);
487 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
494 * After this call, all library internal resources will be cleaned up
496 VAStatus vaTerminate (
500 VAStatus vaStatus = VA_STATUS_SUCCESS;
501 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
502 VADriverContextP old_ctx;
507 if (old_ctx->handle) {
508 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
509 dlclose(old_ctx->handle);
510 old_ctx->handle = NULL;
512 free(old_ctx->vtable);
513 old_ctx->vtable = NULL;
514 free(old_ctx->vtable_vpp);
515 old_ctx->vtable_vpp = NULL;
517 if (VA_STATUS_SUCCESS == vaStatus)
518 pDisplayContext->vaDestroy(pDisplayContext);
520 VA_TRACE_LOG(va_TraceTerminate, dpy);
530 * vaQueryVendorString returns a pointer to a zero-terminated string
531 * describing some aspects of the VA implemenation on a specific
532 * hardware accelerator. The format of the returned string is:
533 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
534 * e.g. for the Intel GMA500 implementation, an example would be:
535 * "IntelGMA500-1.0-0.2-patch3
537 const char *vaQueryVendorString (
541 if (!vaDisplayIsValid(dpy))
544 return CTX(dpy)->str_vendor;
548 /* Get maximum number of profiles supported by the implementation */
549 int vaMaxNumProfiles (
553 if (!vaDisplayIsValid(dpy))
556 return CTX(dpy)->max_profiles;
559 /* Get maximum number of entrypoints supported by the implementation */
560 int vaMaxNumEntrypoints (
564 if (!vaDisplayIsValid(dpy))
567 return CTX(dpy)->max_entrypoints;
571 /* Get maximum number of attributs supported by the implementation */
572 int vaMaxNumConfigAttributes (
576 if (!vaDisplayIsValid(dpy))
579 return CTX(dpy)->max_attributes;
582 VAStatus vaQueryConfigEntrypoints (
585 VAEntrypoint *entrypoints, /* out */
586 int *num_entrypoints /* out */
589 VADriverContextP ctx;
593 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
596 VAStatus vaGetConfigAttributes (
599 VAEntrypoint entrypoint,
600 VAConfigAttrib *attrib_list, /* in/out */
604 VADriverContextP ctx;
608 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
611 VAStatus vaQueryConfigProfiles (
613 VAProfile *profile_list, /* out */
614 int *num_profiles /* out */
617 VADriverContextP ctx;
621 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
624 VAStatus vaCreateConfig (
627 VAEntrypoint entrypoint,
628 VAConfigAttrib *attrib_list,
630 VAConfigID *config_id /* out */
633 VADriverContextP ctx;
634 VAStatus vaStatus = VA_STATUS_SUCCESS;
640 vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
642 /* record the current entrypoint for further trace/fool determination */
643 VA_TRACE_LOG(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
644 VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
649 VAStatus vaDestroyConfig (
654 VADriverContextP ctx;
658 return ctx->vtable->vaDestroyConfig ( ctx, config_id );
661 VAStatus vaQueryConfigAttributes (
663 VAConfigID config_id,
664 VAProfile *profile, /* out */
665 VAEntrypoint *entrypoint, /* out */
666 VAConfigAttrib *attrib_list,/* out */
667 int *num_attribs /* out */
670 VADriverContextP ctx;
674 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
677 /* XXX: this is a slow implementation that will be removed */
679 va_impl_query_surface_attributes(
680 VADriverContextP ctx,
682 VASurfaceAttrib *out_attribs,
683 unsigned int *out_num_attribs_ptr
686 VASurfaceAttrib *attribs = NULL;
687 unsigned int num_attribs, n;
688 VASurfaceAttrib *out_attrib;
689 unsigned int out_num_attribs;
690 VAImageFormat *image_formats = NULL;
691 int num_image_formats, i;
694 /* List of surface attributes to query */
695 struct va_surface_attrib_map {
696 VASurfaceAttribType type;
697 VAGenericValueType value_type;
699 static const struct va_surface_attrib_map attribs_map[] = {
700 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
701 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
702 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
703 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
704 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
705 { VASurfaceAttribNone, }
708 if (!out_attribs || !out_num_attribs_ptr)
709 return VA_STATUS_ERROR_INVALID_PARAMETER;
710 if (!ctx->vtable->vaGetSurfaceAttributes)
711 return VA_STATUS_ERROR_UNIMPLEMENTED;
713 num_image_formats = ctx->max_image_formats;
714 image_formats = malloc(num_image_formats * sizeof(*image_formats));
715 if (!image_formats) {
716 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
720 va_status = ctx->vtable->vaQueryImageFormats(
721 ctx, image_formats, &num_image_formats);
722 if (va_status != VA_STATUS_SUCCESS)
725 num_attribs = VASurfaceAttribCount + num_image_formats;
726 attribs = malloc(num_attribs * sizeof(*attribs));
728 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
732 /* Initialize with base surface attributes, except pixel-formats */
733 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
734 VASurfaceAttrib * const attrib = &attribs[n];
735 attrib->type = attribs_map[n].type;
736 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
737 attrib->value.type = attribs_map[n].value_type;
740 /* Append image formats */
741 for (i = 0; i < num_image_formats; i++) {
742 VASurfaceAttrib * const attrib = &attribs[n];
743 attrib->type = VASurfaceAttribPixelFormat;
744 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
745 attrib->value.type = VAGenericValueTypeInteger;
746 attrib->value.value.i = image_formats[i].fourcc;
747 if (++n == num_attribs) {
748 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
754 va_status = ctx->vtable->vaGetSurfaceAttributes(
755 ctx, config, attribs, num_attribs);
756 if (va_status != VA_STATUS_SUCCESS)
759 /* Remove invalid entries */
761 for (n = 0; n < num_attribs; n++) {
762 VASurfaceAttrib * const attrib = &attribs[n];
764 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
767 // Accept all surface attributes that are not pixel-formats
768 if (attrib->type != VASurfaceAttribPixelFormat) {
773 // Drop invalid pixel-format attribute
774 if (!attrib->value.value.i) {
775 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
779 // Check for duplicates
780 int is_duplicate = 0;
781 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
782 const VASurfaceAttrib * const prev_attrib = &attribs[i];
783 if (prev_attrib->type != VASurfaceAttribPixelFormat)
785 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
788 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
793 if (*out_num_attribs_ptr < out_num_attribs) {
794 *out_num_attribs_ptr = out_num_attribs;
795 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
799 out_attrib = out_attribs;
800 for (n = 0; n < num_attribs; n++) {
801 const VASurfaceAttrib * const attrib = &attribs[n];
802 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
804 *out_attrib++ = *attrib;
814 vaQuerySurfaceAttributes(
817 VASurfaceAttrib *attrib_list,
818 unsigned int *num_attribs
821 VADriverContextP ctx;
827 return VA_STATUS_ERROR_INVALID_DISPLAY;
829 if (!ctx->vtable->vaQuerySurfaceAttributes)
830 return va_impl_query_surface_attributes(ctx, config,
831 attrib_list, num_attribs);
833 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
834 attrib_list, num_attribs);
844 VASurfaceID *surfaces,
845 unsigned int num_surfaces,
846 VASurfaceAttrib *attrib_list,
847 unsigned int num_attribs
850 VADriverContextP ctx;
856 return VA_STATUS_ERROR_INVALID_DISPLAY;
858 if (ctx->vtable->vaCreateSurfaces2)
859 return ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
860 surfaces, num_surfaces,
861 attrib_list, num_attribs);
863 if (attrib_list && num_attribs > 0)
864 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
866 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
867 num_surfaces, surfaces);
869 VA_TRACE_LOG(va_TraceCreateSurfaces,
870 dpy, width, height, format, num_surfaces, surfaces,
871 attrib_list, num_attribs);
877 VAStatus vaDestroySurfaces (
879 VASurfaceID *surface_list,
883 VADriverContextP ctx;
887 return ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
890 VAStatus vaCreateContext (
892 VAConfigID config_id,
896 VASurfaceID *render_targets,
897 int num_render_targets,
898 VAContextID *context /* out */
901 VADriverContextP ctx;
907 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
908 flag, render_targets, num_render_targets, context );
910 /* keep current encode/decode resoluton */
911 VA_TRACE_LOG(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
916 VAStatus vaDestroyContext (
921 VADriverContextP ctx;
925 return ctx->vtable->vaDestroyContext( ctx, context );
928 VAStatus vaCreateBuffer (
930 VAContextID context, /* in */
931 VABufferType type, /* in */
932 unsigned int size, /* in */
933 unsigned int num_elements, /* in */
935 VABufferID *buf_id /* out */
938 VADriverContextP ctx;
945 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
947 return VA_STATUS_SUCCESS;
949 vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
951 VA_TRACE_LOG(va_TraceCreateBuffer,
952 dpy, context, type, size, num_elements, data, buf_id);
957 VAStatus vaBufferSetNumElements (
959 VABufferID buf_id, /* in */
960 unsigned int num_elements /* in */
963 VADriverContextP ctx;
969 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
973 VAStatus vaMapBuffer (
975 VABufferID buf_id, /* in */
976 void **pbuf /* out */
979 VADriverContextP ctx;
986 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
988 return VA_STATUS_SUCCESS;
990 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
992 VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
997 VAStatus vaUnmapBuffer (
999 VABufferID buf_id /* in */
1002 VADriverContextP ctx;
1007 VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
1009 return VA_STATUS_SUCCESS;
1011 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
1014 VAStatus vaDestroyBuffer (
1016 VABufferID buffer_id
1019 VADriverContextP ctx;
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;
1046 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1048 return VA_STATUS_SUCCESS;
1050 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1053 VAStatus vaBeginPicture (
1055 VAContextID context,
1056 VASurfaceID render_target
1059 VADriverContextP ctx;
1065 VA_TRACE_LOG(va_TraceBeginPicture, dpy, context, render_target);
1068 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1073 VAStatus vaRenderPicture (
1075 VAContextID context,
1076 VABufferID *buffers,
1080 VADriverContextP ctx;
1085 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1088 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1091 VAStatus vaEndPicture (
1096 VAStatus va_status = VA_STATUS_SUCCESS;
1097 VADriverContextP ctx;
1102 if (fool_codec == 0)
1103 va_status = ctx->vtable->vaEndPicture( ctx, context );
1105 /* dump surface content */
1106 VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
1111 VAStatus vaSyncSurface (
1113 VASurfaceID render_target
1117 VADriverContextP ctx;
1122 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1123 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1128 VAStatus vaQuerySurfaceStatus (
1130 VASurfaceID render_target,
1131 VASurfaceStatus *status /* out */
1135 VADriverContextP ctx;
1139 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1141 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1146 VAStatus vaQuerySurfaceError (
1148 VASurfaceID surface,
1149 VAStatus error_status,
1150 void **error_info /*out*/
1154 VADriverContextP ctx;
1158 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1160 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1165 /* Get maximum number of image formats supported by the implementation */
1166 int vaMaxNumImageFormats (
1170 if (!vaDisplayIsValid(dpy))
1173 return CTX(dpy)->max_image_formats;
1176 VAStatus vaQueryImageFormats (
1178 VAImageFormat *format_list, /* out */
1179 int *num_formats /* out */
1182 VADriverContextP ctx;
1186 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1190 * The width and height fields returned in the VAImage structure may get
1191 * enlarged for some YUV formats. The size of the data buffer that needs
1192 * to be allocated will be given in the "data_size" field in VAImage.
1193 * Image data is not allocated by this function. The client should
1194 * allocate the memory and fill in the VAImage structure's data field
1195 * after looking at "data_size" returned from the library.
1197 VAStatus vaCreateImage (
1199 VAImageFormat *format,
1202 VAImage *image /* out */
1205 VADriverContextP ctx;
1209 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1213 * Should call DestroyImage before destroying the surface it is bound to
1215 VAStatus vaDestroyImage (
1220 VADriverContextP ctx;
1224 return ctx->vtable->vaDestroyImage ( ctx, image);
1227 VAStatus vaSetImagePalette (
1230 unsigned char *palette
1233 VADriverContextP ctx;
1237 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1241 * Retrieve surface data into a VAImage
1242 * Image must be in a format supported by the implementation
1244 VAStatus vaGetImage (
1246 VASurfaceID surface,
1247 int x, /* coordinates of the upper left source pixel */
1249 unsigned int width, /* width and height of the region */
1250 unsigned int height,
1254 VADriverContextP ctx;
1258 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1262 * Copy data from a VAImage to a surface
1263 * Image must be in a format supported by the implementation
1265 VAStatus vaPutImage (
1267 VASurfaceID surface,
1271 unsigned int src_width,
1272 unsigned int src_height,
1275 unsigned int dest_width,
1276 unsigned int dest_height
1279 VADriverContextP ctx;
1283 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1287 * Derive an VAImage from an existing surface.
1288 * This interface will derive a VAImage and corresponding image buffer from
1289 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1290 * direct CPU access. This operation is only possible on implementations with
1291 * direct rendering capabilities and internal surface formats that can be
1292 * represented with a VAImage. When the operation is not possible this interface
1293 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1294 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1297 * Implementations should only return success when the resulting image buffer
1298 * would be useable with vaMap/Unmap.
1300 * When directly accessing a surface special care must be taken to insure
1301 * proper synchronization with the graphics hardware. Clients should call
1302 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1303 * rendering or currently being displayed by an overlay.
1305 * Additionally nothing about the contents of a surface should be assumed
1306 * following a vaPutSurface. Implementations are free to modify the surface for
1307 * scaling or subpicture blending within a call to vaPutImage.
1309 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1310 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1311 * vaGetImage with other surfaces is supported.
1313 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1314 * image and image buffer structures will be destroyed; however, the underlying
1315 * surface will remain unchanged until freed with vaDestroySurfaces.
1317 VAStatus vaDeriveImage (
1319 VASurfaceID surface,
1320 VAImage *image /* out */
1323 VADriverContextP ctx;
1327 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1331 /* Get maximum number of subpicture formats supported by the implementation */
1332 int vaMaxNumSubpictureFormats (
1336 if (!vaDisplayIsValid(dpy))
1339 return CTX(dpy)->max_subpic_formats;
1343 * Query supported subpicture formats
1344 * The caller must provide a "format_list" array that can hold at
1345 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1346 * for each format to indicate additional capabilities for that format. The actual
1347 * number of formats returned in "format_list" is returned in "num_formats".
1349 VAStatus vaQuerySubpictureFormats (
1351 VAImageFormat *format_list, /* out */
1352 unsigned int *flags, /* out */
1353 unsigned int *num_formats /* out */
1356 VADriverContextP ctx;
1361 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1365 * Subpictures are created with an image associated.
1367 VAStatus vaCreateSubpicture (
1370 VASubpictureID *subpicture /* out */
1373 VADriverContextP ctx;
1377 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1381 * Destroy the subpicture before destroying the image it is assocated to
1383 VAStatus vaDestroySubpicture (
1385 VASubpictureID subpicture
1388 VADriverContextP ctx;
1392 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1395 VAStatus vaSetSubpictureImage (
1397 VASubpictureID subpicture,
1401 VADriverContextP ctx;
1405 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1410 * If chromakey is enabled, then the area where the source value falls within
1411 * the chromakey [min, max] range is transparent
1413 VAStatus vaSetSubpictureChromakey (
1415 VASubpictureID subpicture,
1416 unsigned int chromakey_min,
1417 unsigned int chromakey_max,
1418 unsigned int chromakey_mask
1421 VADriverContextP ctx;
1425 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1430 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1431 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1432 * the overall alpha is per-pixel alpha multiplied by the global alpha
1434 VAStatus vaSetSubpictureGlobalAlpha (
1436 VASubpictureID subpicture,
1440 VADriverContextP ctx;
1444 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1448 vaAssociateSubpicture associates the subpicture with the target_surface.
1449 It defines the region mapping between the subpicture and the target
1450 surface through source and destination rectangles (with the same width and height).
1451 Both will be displayed at the next call to vaPutSurface. Additional
1452 associations before the call to vaPutSurface simply overrides the association.
1454 VAStatus vaAssociateSubpicture (
1456 VASubpictureID subpicture,
1457 VASurfaceID *target_surfaces,
1459 short src_x, /* upper left offset in subpicture */
1461 unsigned short src_width,
1462 unsigned short src_height,
1463 short dest_x, /* upper left offset in surface */
1465 unsigned short dest_width,
1466 unsigned short dest_height,
1468 * whether to enable chroma-keying or global-alpha
1469 * see VA_SUBPICTURE_XXX values
1474 VADriverContextP ctx;
1478 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 );
1482 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1484 VAStatus vaDeassociateSubpicture (
1486 VASubpictureID subpicture,
1487 VASurfaceID *target_surfaces,
1491 VADriverContextP ctx;
1495 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1499 /* Get maximum number of display attributes supported by the implementation */
1500 int vaMaxNumDisplayAttributes (
1506 if (!vaDisplayIsValid(dpy))
1509 tmp = CTX(dpy)->max_display_attributes;
1511 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1517 * Query display attributes
1518 * The caller must provide a "attr_list" array that can hold at
1519 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1520 * returned in "attr_list" is returned in "num_attributes".
1522 VAStatus vaQueryDisplayAttributes (
1524 VADisplayAttribute *attr_list, /* out */
1525 int *num_attributes /* out */
1528 VADriverContextP ctx;
1533 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1535 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1542 * Get display attributes
1543 * This function returns the current attribute values in "attr_list".
1544 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1545 * from vaQueryDisplayAttributes() can have their values retrieved.
1547 VAStatus vaGetDisplayAttributes (
1549 VADisplayAttribute *attr_list, /* in/out */
1553 VADriverContextP ctx;
1558 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1560 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1566 * Set display attributes
1567 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1568 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1569 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1571 VAStatus vaSetDisplayAttributes (
1573 VADisplayAttribute *attr_list,
1577 VADriverContextP ctx;
1582 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1583 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1588 VAStatus vaLockSurface(VADisplay dpy,
1589 VASurfaceID surface,
1590 unsigned int *fourcc, /* following are output argument */
1591 unsigned int *luma_stride,
1592 unsigned int *chroma_u_stride,
1593 unsigned int *chroma_v_stride,
1594 unsigned int *luma_offset,
1595 unsigned int *chroma_u_offset,
1596 unsigned int *chroma_v_offset,
1597 unsigned int *buffer_name,
1601 VADriverContextP ctx;
1605 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);
1609 VAStatus vaUnlockSurface(VADisplay dpy,
1613 VADriverContextP ctx;
1617 return ctx->vtable->vaUnlockSurface( ctx, surface );
1620 /* Video Processing */
1621 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1622 CHECK_DISPLAY(dpy); \
1625 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1628 #define VA_VPP_INVOKE(dpy, func, args) do { \
1629 if (!ctx->vtable_vpp->va##func) \
1630 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1631 status = ctx->vtable_vpp->va##func args; \
1635 vaQueryVideoProcFilters(
1637 VAContextID context,
1638 VAProcFilterType *filters,
1639 unsigned int *num_filters
1642 VADriverContextP ctx;
1645 VA_VPP_INIT_CONTEXT(ctx, dpy);
1648 QueryVideoProcFilters,
1649 (ctx, context, filters, num_filters)
1655 vaQueryVideoProcFilterCaps(
1657 VAContextID context,
1658 VAProcFilterType type,
1660 unsigned int *num_filter_caps
1663 VADriverContextP ctx;
1666 VA_VPP_INIT_CONTEXT(ctx, dpy);
1669 QueryVideoProcFilterCaps,
1670 (ctx, context, type, filter_caps, num_filter_caps)
1676 vaQueryVideoProcPipelineCaps(
1678 VAContextID context,
1679 VABufferID *filters,
1680 unsigned int num_filters,
1681 VAProcPipelineCaps *pipeline_caps
1684 VADriverContextP ctx;
1687 VA_VPP_INIT_CONTEXT(ctx, dpy);
1690 QueryVideoProcPipelineCaps,
1691 (ctx, context, filters, num_filters, pipeline_caps)