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 },
255 for (i = 0; compatible_versions[i].major >= 0; i++) {
256 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
257 compatible_versions[i].major,
258 compatible_versions[i].minor)) {
259 init_func = (VADriverInit)dlsym(handle, init_func_s);
261 va_infoMessage("Found init function %s\n", init_func_s);
267 if (compatible_versions[i].major < 0) {
268 va_errorMessage("%s has no function %s\n",
269 driver_path, init_func_s);
272 struct VADriverVTable *vtable = ctx->vtable;
273 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
275 vaStatus = VA_STATUS_SUCCESS;
277 vtable = calloc(1, sizeof(*vtable));
279 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
281 ctx->vtable = vtable;
284 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
286 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
288 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
290 ctx->vtable_vpp = vtable_vpp;
292 if (init_func && VA_STATUS_SUCCESS == vaStatus)
293 vaStatus = (*init_func)(ctx);
295 if (VA_STATUS_SUCCESS == vaStatus) {
296 CHECK_MAXIMUM(vaStatus, ctx, profiles);
297 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
298 CHECK_MAXIMUM(vaStatus, ctx, attributes);
299 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
300 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
301 CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
302 CHECK_STRING(vaStatus, ctx, vendor);
303 CHECK_VTABLE(vaStatus, ctx, Terminate);
304 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
305 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
306 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
307 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
308 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
309 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
310 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
311 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
312 CHECK_VTABLE(vaStatus, ctx, CreateContext);
313 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
314 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
315 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
316 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
317 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
318 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
319 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
320 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
321 CHECK_VTABLE(vaStatus, ctx, EndPicture);
322 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
323 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
324 CHECK_VTABLE(vaStatus, ctx, PutSurface);
325 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
326 CHECK_VTABLE(vaStatus, ctx, CreateImage);
327 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
328 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
329 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
330 CHECK_VTABLE(vaStatus, ctx, GetImage);
331 CHECK_VTABLE(vaStatus, ctx, PutImage);
332 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
333 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
334 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
335 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
336 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
337 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
338 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
339 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
340 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
341 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
342 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
344 if (VA_STATUS_SUCCESS != vaStatus) {
345 va_errorMessage("%s init failed\n", driver_path);
348 if (VA_STATUS_SUCCESS == vaStatus)
349 ctx->handle = handle;
356 driver_dir = strtok_r(NULL, ":", &saveptr);
364 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
366 VADriverContextP ctx;
367 if (!vaDisplayIsValid(dpy))
371 if (NULL == ctx->handle)
374 return (VAPrivFunc) dlsym(ctx->handle, func);
379 * Returns a short english description of error_status
381 const char *vaErrorStr(VAStatus error_status)
383 switch(error_status) {
384 case VA_STATUS_SUCCESS:
385 return "success (no error)";
386 case VA_STATUS_ERROR_OPERATION_FAILED:
387 return "operation failed";
388 case VA_STATUS_ERROR_ALLOCATION_FAILED:
389 return "resource allocation failed";
390 case VA_STATUS_ERROR_INVALID_DISPLAY:
391 return "invalid VADisplay";
392 case VA_STATUS_ERROR_INVALID_CONFIG:
393 return "invalid VAConfigID";
394 case VA_STATUS_ERROR_INVALID_CONTEXT:
395 return "invalid VAContextID";
396 case VA_STATUS_ERROR_INVALID_SURFACE:
397 return "invalid VASurfaceID";
398 case VA_STATUS_ERROR_INVALID_BUFFER:
399 return "invalid VABufferID";
400 case VA_STATUS_ERROR_INVALID_IMAGE:
401 return "invalid VAImageID";
402 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
403 return "invalid VASubpictureID";
404 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
405 return "attribute not supported";
406 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
407 return "list argument exceeds maximum number";
408 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
409 return "the requested VAProfile is not supported";
410 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
411 return "the requested VAEntryPoint is not supported";
412 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
413 return "the requested RT Format is not supported";
414 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
415 return "the requested VABufferType is not supported";
416 case VA_STATUS_ERROR_SURFACE_BUSY:
417 return "surface is in use";
418 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
419 return "flag not supported";
420 case VA_STATUS_ERROR_INVALID_PARAMETER:
421 return "invalid parameter";
422 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
423 return "resolution not supported";
424 case VA_STATUS_ERROR_UNIMPLEMENTED:
425 return "the requested function is not implemented";
426 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
427 return "surface is in displaying (may by overlay)" ;
428 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
429 return "invalid VAImageFormat";
430 case VA_STATUS_ERROR_INVALID_VALUE:
431 return "an invalid/unsupported value was supplied";
432 case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
433 return "the requested filter is not supported";
434 case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
435 return "an invalid filter chain was supplied";
436 case VA_STATUS_ERROR_UNKNOWN:
437 return "unknown libva error";
439 return "unknown libva error / description missing";
442 VAStatus vaInitialize (
444 int *major_version, /* out */
445 int *minor_version /* out */
448 const char *driver_name_env = NULL;
449 char *driver_name = NULL;
458 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
460 vaStatus = va_getDriverName(dpy, &driver_name);
461 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
463 driver_name_env = getenv("LIBVA_DRIVER_NAME");
464 if ((VA_STATUS_SUCCESS == vaStatus) &&
465 driver_name_env && (geteuid() == getuid())) {
466 /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
467 if (driver_name) /* memory is allocated in va_getDriverName */
470 driver_name = strdup(driver_name_env);
471 vaStatus = VA_STATUS_SUCCESS;
472 va_infoMessage("User requested driver '%s'\n", driver_name);
475 if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
476 vaStatus = va_openDriver(dpy, driver_name);
477 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
479 *major_version = VA_MAJOR_VERSION;
480 *minor_version = VA_MINOR_VERSION;
482 va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n",
483 vaErrorStr(vaStatus), driver_name);
488 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
495 * After this call, all library internal resources will be cleaned up
497 VAStatus vaTerminate (
501 VAStatus vaStatus = VA_STATUS_SUCCESS;
502 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
503 VADriverContextP old_ctx;
508 if (old_ctx->handle) {
509 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
510 dlclose(old_ctx->handle);
511 old_ctx->handle = NULL;
513 free(old_ctx->vtable);
514 old_ctx->vtable = NULL;
515 free(old_ctx->vtable_vpp);
516 old_ctx->vtable_vpp = NULL;
518 if (VA_STATUS_SUCCESS == vaStatus)
519 pDisplayContext->vaDestroy(pDisplayContext);
521 VA_TRACE_LOG(va_TraceTerminate, dpy);
531 * vaQueryVendorString returns a pointer to a zero-terminated string
532 * describing some aspects of the VA implemenation on a specific
533 * hardware accelerator. The format of the returned string is:
534 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
535 * e.g. for the Intel GMA500 implementation, an example would be:
536 * "IntelGMA500-1.0-0.2-patch3
538 const char *vaQueryVendorString (
542 if (!vaDisplayIsValid(dpy))
545 return CTX(dpy)->str_vendor;
549 /* Get maximum number of profiles supported by the implementation */
550 int vaMaxNumProfiles (
554 if (!vaDisplayIsValid(dpy))
557 return CTX(dpy)->max_profiles;
560 /* Get maximum number of entrypoints supported by the implementation */
561 int vaMaxNumEntrypoints (
565 if (!vaDisplayIsValid(dpy))
568 return CTX(dpy)->max_entrypoints;
572 /* Get maximum number of attributs supported by the implementation */
573 int vaMaxNumConfigAttributes (
577 if (!vaDisplayIsValid(dpy))
580 return CTX(dpy)->max_attributes;
583 VAStatus vaQueryConfigEntrypoints (
586 VAEntrypoint *entrypoints, /* out */
587 int *num_entrypoints /* out */
590 VADriverContextP ctx;
594 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
597 VAStatus vaGetConfigAttributes (
600 VAEntrypoint entrypoint,
601 VAConfigAttrib *attrib_list, /* in/out */
605 VADriverContextP ctx;
609 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
612 VAStatus vaQueryConfigProfiles (
614 VAProfile *profile_list, /* out */
615 int *num_profiles /* out */
618 VADriverContextP ctx;
622 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
625 VAStatus vaCreateConfig (
628 VAEntrypoint entrypoint,
629 VAConfigAttrib *attrib_list,
631 VAConfigID *config_id /* out */
634 VADriverContextP ctx;
635 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_LOG(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_LOG(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;
954 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
956 return VA_STATUS_SUCCESS;
958 vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
960 VA_TRACE_LOG(va_TraceCreateBuffer,
961 dpy, context, type, size, num_elements, data, buf_id);
966 VAStatus vaBufferSetNumElements (
968 VABufferID buf_id, /* in */
969 unsigned int num_elements /* in */
972 VADriverContextP ctx;
978 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
982 VAStatus vaMapBuffer (
984 VABufferID buf_id, /* in */
985 void **pbuf /* out */
988 VADriverContextP ctx;
995 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
997 return VA_STATUS_SUCCESS;
999 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
1001 VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
1006 VAStatus vaUnmapBuffer (
1008 VABufferID buf_id /* in */
1011 VADriverContextP ctx;
1016 VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
1018 return VA_STATUS_SUCCESS;
1020 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
1023 VAStatus vaDestroyBuffer (
1025 VABufferID buffer_id
1028 VADriverContextP ctx;
1034 VA_TRACE_LOG(va_TraceDestroyBuffer,
1037 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1040 VAStatus vaBufferInfo (
1042 VAContextID context, /* in */
1043 VABufferID buf_id, /* in */
1044 VABufferType *type, /* out */
1045 unsigned int *size, /* out */
1046 unsigned int *num_elements /* out */
1049 VADriverContextP ctx;
1055 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1057 return VA_STATUS_SUCCESS;
1059 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1062 VAStatus vaBeginPicture (
1064 VAContextID context,
1065 VASurfaceID render_target
1068 VADriverContextP ctx;
1074 VA_TRACE_LOG(va_TraceBeginPicture, dpy, context, render_target);
1077 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1082 VAStatus vaRenderPicture (
1084 VAContextID context,
1085 VABufferID *buffers,
1089 VADriverContextP ctx;
1094 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1097 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1100 VAStatus vaEndPicture (
1105 VAStatus va_status = VA_STATUS_SUCCESS;
1106 VADriverContextP ctx;
1111 if (fool_codec == 0)
1112 va_status = ctx->vtable->vaEndPicture( ctx, context );
1114 /* dump surface content */
1115 VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
1120 VAStatus vaSyncSurface (
1122 VASurfaceID render_target
1126 VADriverContextP ctx;
1131 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1132 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1137 VAStatus vaQuerySurfaceStatus (
1139 VASurfaceID render_target,
1140 VASurfaceStatus *status /* out */
1144 VADriverContextP ctx;
1148 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1150 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1155 VAStatus vaQuerySurfaceError (
1157 VASurfaceID surface,
1158 VAStatus error_status,
1159 void **error_info /*out*/
1163 VADriverContextP ctx;
1167 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1169 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1174 /* Get maximum number of image formats supported by the implementation */
1175 int vaMaxNumImageFormats (
1179 if (!vaDisplayIsValid(dpy))
1182 return CTX(dpy)->max_image_formats;
1185 VAStatus vaQueryImageFormats (
1187 VAImageFormat *format_list, /* out */
1188 int *num_formats /* out */
1191 VADriverContextP ctx;
1195 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1199 * The width and height fields returned in the VAImage structure may get
1200 * enlarged for some YUV formats. The size of the data buffer that needs
1201 * to be allocated will be given in the "data_size" field in VAImage.
1202 * Image data is not allocated by this function. The client should
1203 * allocate the memory and fill in the VAImage structure's data field
1204 * after looking at "data_size" returned from the library.
1206 VAStatus vaCreateImage (
1208 VAImageFormat *format,
1211 VAImage *image /* out */
1214 VADriverContextP ctx;
1218 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1222 * Should call DestroyImage before destroying the surface it is bound to
1224 VAStatus vaDestroyImage (
1229 VADriverContextP ctx;
1233 return ctx->vtable->vaDestroyImage ( ctx, image);
1236 VAStatus vaSetImagePalette (
1239 unsigned char *palette
1242 VADriverContextP ctx;
1246 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1250 * Retrieve surface data into a VAImage
1251 * Image must be in a format supported by the implementation
1253 VAStatus vaGetImage (
1255 VASurfaceID surface,
1256 int x, /* coordinates of the upper left source pixel */
1258 unsigned int width, /* width and height of the region */
1259 unsigned int height,
1263 VADriverContextP ctx;
1267 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1271 * Copy data from a VAImage to a surface
1272 * Image must be in a format supported by the implementation
1274 VAStatus vaPutImage (
1276 VASurfaceID surface,
1280 unsigned int src_width,
1281 unsigned int src_height,
1284 unsigned int dest_width,
1285 unsigned int dest_height
1288 VADriverContextP ctx;
1292 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1296 * Derive an VAImage from an existing surface.
1297 * This interface will derive a VAImage and corresponding image buffer from
1298 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1299 * direct CPU access. This operation is only possible on implementations with
1300 * direct rendering capabilities and internal surface formats that can be
1301 * represented with a VAImage. When the operation is not possible this interface
1302 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1303 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1306 * Implementations should only return success when the resulting image buffer
1307 * would be useable with vaMap/Unmap.
1309 * When directly accessing a surface special care must be taken to insure
1310 * proper synchronization with the graphics hardware. Clients should call
1311 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1312 * rendering or currently being displayed by an overlay.
1314 * Additionally nothing about the contents of a surface should be assumed
1315 * following a vaPutSurface. Implementations are free to modify the surface for
1316 * scaling or subpicture blending within a call to vaPutImage.
1318 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1319 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1320 * vaGetImage with other surfaces is supported.
1322 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1323 * image and image buffer structures will be destroyed; however, the underlying
1324 * surface will remain unchanged until freed with vaDestroySurfaces.
1326 VAStatus vaDeriveImage (
1328 VASurfaceID surface,
1329 VAImage *image /* out */
1332 VADriverContextP ctx;
1336 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1340 /* Get maximum number of subpicture formats supported by the implementation */
1341 int vaMaxNumSubpictureFormats (
1345 if (!vaDisplayIsValid(dpy))
1348 return CTX(dpy)->max_subpic_formats;
1352 * Query supported subpicture formats
1353 * The caller must provide a "format_list" array that can hold at
1354 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1355 * for each format to indicate additional capabilities for that format. The actual
1356 * number of formats returned in "format_list" is returned in "num_formats".
1358 VAStatus vaQuerySubpictureFormats (
1360 VAImageFormat *format_list, /* out */
1361 unsigned int *flags, /* out */
1362 unsigned int *num_formats /* out */
1365 VADriverContextP ctx;
1370 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1374 * Subpictures are created with an image associated.
1376 VAStatus vaCreateSubpicture (
1379 VASubpictureID *subpicture /* out */
1382 VADriverContextP ctx;
1386 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1390 * Destroy the subpicture before destroying the image it is assocated to
1392 VAStatus vaDestroySubpicture (
1394 VASubpictureID subpicture
1397 VADriverContextP ctx;
1401 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1404 VAStatus vaSetSubpictureImage (
1406 VASubpictureID subpicture,
1410 VADriverContextP ctx;
1414 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1419 * If chromakey is enabled, then the area where the source value falls within
1420 * the chromakey [min, max] range is transparent
1422 VAStatus vaSetSubpictureChromakey (
1424 VASubpictureID subpicture,
1425 unsigned int chromakey_min,
1426 unsigned int chromakey_max,
1427 unsigned int chromakey_mask
1430 VADriverContextP ctx;
1434 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1439 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1440 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1441 * the overall alpha is per-pixel alpha multiplied by the global alpha
1443 VAStatus vaSetSubpictureGlobalAlpha (
1445 VASubpictureID subpicture,
1449 VADriverContextP ctx;
1453 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1457 vaAssociateSubpicture associates the subpicture with the target_surface.
1458 It defines the region mapping between the subpicture and the target
1459 surface through source and destination rectangles (with the same width and height).
1460 Both will be displayed at the next call to vaPutSurface. Additional
1461 associations before the call to vaPutSurface simply overrides the association.
1463 VAStatus vaAssociateSubpicture (
1465 VASubpictureID subpicture,
1466 VASurfaceID *target_surfaces,
1468 short src_x, /* upper left offset in subpicture */
1470 unsigned short src_width,
1471 unsigned short src_height,
1472 short dest_x, /* upper left offset in surface */
1474 unsigned short dest_width,
1475 unsigned short dest_height,
1477 * whether to enable chroma-keying or global-alpha
1478 * see VA_SUBPICTURE_XXX values
1483 VADriverContextP ctx;
1487 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 );
1491 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1493 VAStatus vaDeassociateSubpicture (
1495 VASubpictureID subpicture,
1496 VASurfaceID *target_surfaces,
1500 VADriverContextP ctx;
1504 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1508 /* Get maximum number of display attributes supported by the implementation */
1509 int vaMaxNumDisplayAttributes (
1515 if (!vaDisplayIsValid(dpy))
1518 tmp = CTX(dpy)->max_display_attributes;
1520 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1526 * Query display attributes
1527 * The caller must provide a "attr_list" array that can hold at
1528 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1529 * returned in "attr_list" is returned in "num_attributes".
1531 VAStatus vaQueryDisplayAttributes (
1533 VADisplayAttribute *attr_list, /* out */
1534 int *num_attributes /* out */
1537 VADriverContextP ctx;
1542 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1544 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1551 * Get display attributes
1552 * This function returns the current attribute values in "attr_list".
1553 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1554 * from vaQueryDisplayAttributes() can have their values retrieved.
1556 VAStatus vaGetDisplayAttributes (
1558 VADisplayAttribute *attr_list, /* in/out */
1562 VADriverContextP ctx;
1567 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1569 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1575 * Set display attributes
1576 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1577 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1578 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1580 VAStatus vaSetDisplayAttributes (
1582 VADisplayAttribute *attr_list,
1586 VADriverContextP ctx;
1591 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1592 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1597 VAStatus vaLockSurface(VADisplay dpy,
1598 VASurfaceID surface,
1599 unsigned int *fourcc, /* following are output argument */
1600 unsigned int *luma_stride,
1601 unsigned int *chroma_u_stride,
1602 unsigned int *chroma_v_stride,
1603 unsigned int *luma_offset,
1604 unsigned int *chroma_u_offset,
1605 unsigned int *chroma_v_offset,
1606 unsigned int *buffer_name,
1610 VADriverContextP ctx;
1614 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);
1618 VAStatus vaUnlockSurface(VADisplay dpy,
1622 VADriverContextP ctx;
1626 return ctx->vtable->vaUnlockSurface( ctx, surface );
1629 /* Video Processing */
1630 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1631 CHECK_DISPLAY(dpy); \
1634 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1637 #define VA_VPP_INVOKE(dpy, func, args) do { \
1638 if (!ctx->vtable_vpp->va##func) \
1639 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1640 status = ctx->vtable_vpp->va##func args; \
1644 vaQueryVideoProcFilters(
1646 VAContextID context,
1647 VAProcFilterType *filters,
1648 unsigned int *num_filters
1651 VADriverContextP ctx;
1654 VA_VPP_INIT_CONTEXT(ctx, dpy);
1657 QueryVideoProcFilters,
1658 (ctx, context, filters, num_filters)
1664 vaQueryVideoProcFilterCaps(
1666 VAContextID context,
1667 VAProcFilterType type,
1669 unsigned int *num_filter_caps
1672 VADriverContextP ctx;
1675 VA_VPP_INIT_CONTEXT(ctx, dpy);
1678 QueryVideoProcFilterCaps,
1679 (ctx, context, type, filter_caps, num_filter_caps)
1685 vaQueryVideoProcPipelineCaps(
1687 VAContextID context,
1688 VABufferID *filters,
1689 unsigned int num_filters,
1690 VAProcPipelineCaps *pipeline_caps
1693 VADriverContextP ctx;
1696 VA_VPP_INIT_CONTEXT(ctx, dpy);
1699 QueryVideoProcPipelineCaps,
1700 (ctx, context, filters, num_filters, pipeline_caps)