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__);
220 return VA_STATUS_ERROR_ALLOCATION_FAILED;
223 strncpy( driver_path, driver_dir, strlen(driver_dir) + 1);
224 strncat( driver_path, "/", strlen("/") );
225 strncat( driver_path, driver_name, strlen(driver_name) );
226 strncat( driver_path, DRIVER_EXTENSION, strlen(DRIVER_EXTENSION) );
228 va_infoMessage("Trying to open %s\n", driver_path);
230 handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE );
232 handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL);
235 /* Don't give errors for non-existing files */
236 if (0 == access( driver_path, F_OK))
237 va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
239 VADriverInit init_func = NULL;
240 char init_func_s[256];
243 static const struct {
246 } compatible_versions[] = {
247 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
253 for (i = 0; compatible_versions[i].major >= 0; i++) {
254 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
255 compatible_versions[i].major,
256 compatible_versions[i].minor)) {
257 init_func = (VADriverInit)dlsym(handle, init_func_s);
259 va_infoMessage("Found init function %s\n", init_func_s);
265 if (compatible_versions[i].major < 0) {
266 va_errorMessage("%s has no function %s\n",
267 driver_path, init_func_s);
270 struct VADriverVTable *vtable = ctx->vtable;
271 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
273 vaStatus = VA_STATUS_SUCCESS;
275 vtable = calloc(1, sizeof(*vtable));
277 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
279 ctx->vtable = vtable;
282 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
284 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
286 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
288 ctx->vtable_vpp = vtable_vpp;
290 if (VA_STATUS_SUCCESS == vaStatus)
291 vaStatus = (*init_func)(ctx);
293 if (VA_STATUS_SUCCESS == vaStatus) {
294 CHECK_MAXIMUM(vaStatus, ctx, profiles);
295 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
296 CHECK_MAXIMUM(vaStatus, ctx, attributes);
297 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
298 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
299 CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
300 CHECK_STRING(vaStatus, ctx, vendor);
301 CHECK_VTABLE(vaStatus, ctx, Terminate);
302 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
303 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
304 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
305 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
306 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
307 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
308 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
309 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
310 CHECK_VTABLE(vaStatus, ctx, CreateContext);
311 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
312 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
313 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
314 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
315 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
316 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
317 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
318 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
319 CHECK_VTABLE(vaStatus, ctx, EndPicture);
320 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
321 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
322 CHECK_VTABLE(vaStatus, ctx, PutSurface);
323 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
324 CHECK_VTABLE(vaStatus, ctx, CreateImage);
325 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
326 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
327 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
328 CHECK_VTABLE(vaStatus, ctx, GetImage);
329 CHECK_VTABLE(vaStatus, ctx, PutImage);
330 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
331 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
332 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
333 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
334 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
335 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
336 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
337 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
338 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
339 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
340 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
342 if (VA_STATUS_SUCCESS != vaStatus) {
343 va_errorMessage("%s init failed\n", driver_path);
346 if (VA_STATUS_SUCCESS == vaStatus)
347 ctx->handle = handle;
354 driver_dir = strtok_r(NULL, ":", &saveptr);
362 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
364 VADriverContextP ctx;
365 if (!vaDisplayIsValid(dpy))
369 if (NULL == ctx->handle)
372 return (VAPrivFunc) dlsym(ctx->handle, func);
377 * Returns a short english description of error_status
379 const char *vaErrorStr(VAStatus error_status)
381 switch(error_status) {
382 case VA_STATUS_SUCCESS:
383 return "success (no error)";
384 case VA_STATUS_ERROR_OPERATION_FAILED:
385 return "operation failed";
386 case VA_STATUS_ERROR_ALLOCATION_FAILED:
387 return "resource allocation failed";
388 case VA_STATUS_ERROR_INVALID_DISPLAY:
389 return "invalid VADisplay";
390 case VA_STATUS_ERROR_INVALID_CONFIG:
391 return "invalid VAConfigID";
392 case VA_STATUS_ERROR_INVALID_CONTEXT:
393 return "invalid VAContextID";
394 case VA_STATUS_ERROR_INVALID_SURFACE:
395 return "invalid VASurfaceID";
396 case VA_STATUS_ERROR_INVALID_BUFFER:
397 return "invalid VABufferID";
398 case VA_STATUS_ERROR_INVALID_IMAGE:
399 return "invalid VAImageID";
400 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
401 return "invalid VASubpictureID";
402 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
403 return "attribute not supported";
404 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
405 return "list argument exceeds maximum number";
406 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
407 return "the requested VAProfile is not supported";
408 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
409 return "the requested VAEntryPoint is not supported";
410 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
411 return "the requested RT Format is not supported";
412 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
413 return "the requested VABufferType is not supported";
414 case VA_STATUS_ERROR_SURFACE_BUSY:
415 return "surface is in use";
416 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
417 return "flag not supported";
418 case VA_STATUS_ERROR_INVALID_PARAMETER:
419 return "invalid parameter";
420 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
421 return "resolution not supported";
422 case VA_STATUS_ERROR_UNIMPLEMENTED:
423 return "the requested function is not implemented";
424 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
425 return "surface is in displaying (may by overlay)" ;
426 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
427 return "invalid VAImageFormat";
428 case VA_STATUS_ERROR_INVALID_VALUE:
429 return "an invalid/unsupported value was supplied";
430 case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
431 return "the requested filter is not supported";
432 case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
433 return "an invalid filter chain was supplied";
434 case VA_STATUS_ERROR_UNKNOWN:
435 return "unknown libva error";
437 return "unknown libva error / description missing";
440 VAStatus vaInitialize (
442 int *major_version, /* out */
443 int *minor_version /* out */
446 const char *driver_name_env = NULL;
447 char *driver_name = NULL;
456 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
458 vaStatus = va_getDriverName(dpy, &driver_name);
459 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
461 driver_name_env = getenv("LIBVA_DRIVER_NAME");
462 if ((VA_STATUS_SUCCESS == vaStatus) &&
463 driver_name_env && (geteuid() == getuid())) {
464 /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
465 if (driver_name) /* memory is allocated in va_getDriverName */
468 driver_name = strdup(driver_name_env);
469 vaStatus = VA_STATUS_SUCCESS;
470 va_infoMessage("User requested driver '%s'\n", driver_name);
473 if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
474 vaStatus = va_openDriver(dpy, driver_name);
475 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
477 *major_version = VA_MAJOR_VERSION;
478 *minor_version = VA_MINOR_VERSION;
480 va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n",
481 vaErrorStr(vaStatus), driver_name);
486 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
493 * After this call, all library internal resources will be cleaned up
495 VAStatus vaTerminate (
499 VAStatus vaStatus = VA_STATUS_SUCCESS;
500 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
501 VADriverContextP old_ctx;
506 if (old_ctx->handle) {
507 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
508 dlclose(old_ctx->handle);
509 old_ctx->handle = NULL;
511 free(old_ctx->vtable);
512 old_ctx->vtable = NULL;
513 free(old_ctx->vtable_vpp);
514 old_ctx->vtable_vpp = NULL;
516 if (VA_STATUS_SUCCESS == vaStatus)
517 pDisplayContext->vaDestroy(pDisplayContext);
519 VA_TRACE_LOG(va_TraceTerminate, dpy);
529 * vaQueryVendorString returns a pointer to a zero-terminated string
530 * describing some aspects of the VA implemenation on a specific
531 * hardware accelerator. The format of the returned string is:
532 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
533 * e.g. for the Intel GMA500 implementation, an example would be:
534 * "IntelGMA500-1.0-0.2-patch3
536 const char *vaQueryVendorString (
540 if (!vaDisplayIsValid(dpy))
543 return CTX(dpy)->str_vendor;
547 /* Get maximum number of profiles supported by the implementation */
548 int vaMaxNumProfiles (
552 if (!vaDisplayIsValid(dpy))
555 return CTX(dpy)->max_profiles;
558 /* Get maximum number of entrypoints supported by the implementation */
559 int vaMaxNumEntrypoints (
563 if (!vaDisplayIsValid(dpy))
566 return CTX(dpy)->max_entrypoints;
570 /* Get maximum number of attributs supported by the implementation */
571 int vaMaxNumConfigAttributes (
575 if (!vaDisplayIsValid(dpy))
578 return CTX(dpy)->max_attributes;
581 VAStatus vaQueryConfigEntrypoints (
584 VAEntrypoint *entrypoints, /* out */
585 int *num_entrypoints /* out */
588 VADriverContextP ctx;
592 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
595 VAStatus vaGetConfigAttributes (
598 VAEntrypoint entrypoint,
599 VAConfigAttrib *attrib_list, /* in/out */
603 VADriverContextP ctx;
607 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
610 VAStatus vaQueryConfigProfiles (
612 VAProfile *profile_list, /* out */
613 int *num_profiles /* out */
616 VADriverContextP ctx;
620 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
623 VAStatus vaCreateConfig (
626 VAEntrypoint entrypoint,
627 VAConfigAttrib *attrib_list,
629 VAConfigID *config_id /* out */
632 VADriverContextP ctx;
633 VAStatus vaStatus = VA_STATUS_SUCCESS;
639 vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
641 /* record the current entrypoint for further trace/fool determination */
642 VA_TRACE_LOG(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
643 VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
648 VAStatus vaDestroyConfig (
653 VADriverContextP ctx;
657 return ctx->vtable->vaDestroyConfig ( ctx, config_id );
660 VAStatus vaQueryConfigAttributes (
662 VAConfigID config_id,
663 VAProfile *profile, /* out */
664 VAEntrypoint *entrypoint, /* out */
665 VAConfigAttrib *attrib_list,/* out */
666 int *num_attribs /* out */
669 VADriverContextP ctx;
673 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
676 /* XXX: this is a slow implementation that will be removed */
678 va_impl_query_surface_attributes(
679 VADriverContextP ctx,
681 VASurfaceAttrib *out_attribs,
682 unsigned int *out_num_attribs_ptr
685 VASurfaceAttrib *attribs = NULL;
686 unsigned int num_attribs, n;
687 VASurfaceAttrib *out_attrib;
688 unsigned int out_num_attribs;
689 VAImageFormat *image_formats = NULL;
690 int num_image_formats, i;
693 /* List of surface attributes to query */
694 struct va_surface_attrib_map {
695 VASurfaceAttribType type;
696 VAGenericValueType value_type;
698 static const struct va_surface_attrib_map attribs_map[] = {
699 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
700 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
701 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
702 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
703 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
704 { VASurfaceAttribNone, }
707 if (!out_attribs || !out_num_attribs_ptr)
708 return VA_STATUS_ERROR_INVALID_PARAMETER;
709 if (!ctx->vtable->vaGetSurfaceAttributes)
710 return VA_STATUS_ERROR_UNIMPLEMENTED;
712 num_image_formats = ctx->max_image_formats;
713 image_formats = malloc(num_image_formats * sizeof(*image_formats));
714 if (!image_formats) {
715 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
719 va_status = ctx->vtable->vaQueryImageFormats(
720 ctx, image_formats, &num_image_formats);
721 if (va_status != VA_STATUS_SUCCESS)
724 num_attribs = VASurfaceAttribCount + num_image_formats;
725 attribs = malloc(num_attribs * sizeof(*attribs));
727 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
731 /* Initialize with base surface attributes, except pixel-formats */
732 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
733 VASurfaceAttrib * const attrib = &attribs[n];
734 attrib->type = attribs_map[n].type;
735 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
736 attrib->value.type = attribs_map[n].value_type;
739 /* Append image formats */
740 for (i = 0; i < num_image_formats; i++) {
741 VASurfaceAttrib * const attrib = &attribs[n];
742 attrib->type = VASurfaceAttribPixelFormat;
743 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
744 attrib->value.type = VAGenericValueTypeInteger;
745 attrib->value.value.i = image_formats[i].fourcc;
746 if (++n == num_attribs) {
747 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
753 va_status = ctx->vtable->vaGetSurfaceAttributes(
754 ctx, config, attribs, num_attribs);
755 if (va_status != VA_STATUS_SUCCESS)
758 /* Remove invalid entries */
760 for (n = 0; n < num_attribs; n++) {
761 VASurfaceAttrib * const attrib = &attribs[n];
763 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
766 // Accept all surface attributes that are not pixel-formats
767 if (attrib->type != VASurfaceAttribPixelFormat) {
772 // Drop invalid pixel-format attribute
773 if (!attrib->value.value.i) {
774 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
778 // Check for duplicates
779 int is_duplicate = 0;
780 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
781 const VASurfaceAttrib * const prev_attrib = &attribs[i];
782 if (prev_attrib->type != VASurfaceAttribPixelFormat)
784 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
787 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
792 if (*out_num_attribs_ptr < out_num_attribs) {
793 *out_num_attribs_ptr = out_num_attribs;
794 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
798 out_attrib = out_attribs;
799 for (n = 0; n < num_attribs; n++) {
800 const VASurfaceAttrib * const attrib = &attribs[n];
801 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
803 *out_attrib++ = *attrib;
813 vaQuerySurfaceAttributes(
816 VASurfaceAttrib *attrib_list,
817 unsigned int *num_attribs
820 VADriverContextP ctx;
826 return VA_STATUS_ERROR_INVALID_DISPLAY;
828 if (!ctx->vtable->vaQuerySurfaceAttributes)
829 return va_impl_query_surface_attributes(ctx, config,
830 attrib_list, num_attribs);
832 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
833 attrib_list, num_attribs);
843 VASurfaceID *surfaces,
844 unsigned int num_surfaces,
845 VASurfaceAttrib *attrib_list,
846 unsigned int num_attribs
849 VADriverContextP ctx;
855 return VA_STATUS_ERROR_INVALID_DISPLAY;
857 if (ctx->vtable->vaCreateSurfaces2)
858 return ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
859 surfaces, num_surfaces,
860 attrib_list, num_attribs);
862 if (attrib_list && num_attribs > 0)
863 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
865 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
866 num_surfaces, surfaces);
868 VA_TRACE_LOG(va_TraceCreateSurfaces,
869 dpy, width, height, format, num_surfaces, surfaces,
870 attrib_list, num_attribs);
876 VAStatus vaDestroySurfaces (
878 VASurfaceID *surface_list,
882 VADriverContextP ctx;
886 return ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
889 VAStatus vaCreateContext (
891 VAConfigID config_id,
895 VASurfaceID *render_targets,
896 int num_render_targets,
897 VAContextID *context /* out */
900 VADriverContextP ctx;
906 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
907 flag, render_targets, num_render_targets, context );
909 /* keep current encode/decode resoluton */
910 VA_TRACE_LOG(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
915 VAStatus vaDestroyContext (
920 VADriverContextP ctx;
924 return ctx->vtable->vaDestroyContext( ctx, context );
927 VAStatus vaCreateBuffer (
929 VAContextID context, /* in */
930 VABufferType type, /* in */
931 unsigned int size, /* in */
932 unsigned int num_elements, /* in */
934 VABufferID *buf_id /* out */
937 VADriverContextP ctx;
944 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
946 return VA_STATUS_SUCCESS;
948 vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
950 VA_TRACE_LOG(va_TraceCreateBuffer,
951 dpy, context, type, size, num_elements, data, buf_id);
956 VAStatus vaBufferSetNumElements (
958 VABufferID buf_id, /* in */
959 unsigned int num_elements /* in */
962 VADriverContextP ctx;
968 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
972 VAStatus vaMapBuffer (
974 VABufferID buf_id, /* in */
975 void **pbuf /* out */
978 VADriverContextP ctx;
985 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
987 return VA_STATUS_SUCCESS;
989 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
991 VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
996 VAStatus vaUnmapBuffer (
998 VABufferID buf_id /* in */
1001 VADriverContextP ctx;
1006 VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
1008 return VA_STATUS_SUCCESS;
1010 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
1013 VAStatus vaDestroyBuffer (
1015 VABufferID buffer_id
1018 VADriverContextP ctx;
1024 VA_TRACE_LOG(va_TraceDestroyBuffer,
1027 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1030 VAStatus vaBufferInfo (
1032 VAContextID context, /* in */
1033 VABufferID buf_id, /* in */
1034 VABufferType *type, /* out */
1035 unsigned int *size, /* out */
1036 unsigned int *num_elements /* out */
1039 VADriverContextP ctx;
1045 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1047 return VA_STATUS_SUCCESS;
1049 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1052 VAStatus vaBeginPicture (
1054 VAContextID context,
1055 VASurfaceID render_target
1058 VADriverContextP ctx;
1064 VA_TRACE_LOG(va_TraceBeginPicture, dpy, context, render_target);
1067 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1072 VAStatus vaRenderPicture (
1074 VAContextID context,
1075 VABufferID *buffers,
1079 VADriverContextP ctx;
1084 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1087 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1090 VAStatus vaEndPicture (
1095 VAStatus va_status = VA_STATUS_SUCCESS;
1096 VADriverContextP ctx;
1101 if (fool_codec == 0)
1102 va_status = ctx->vtable->vaEndPicture( ctx, context );
1104 /* dump surface content */
1105 VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
1110 VAStatus vaSyncSurface (
1112 VASurfaceID render_target
1116 VADriverContextP ctx;
1121 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1122 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1127 VAStatus vaQuerySurfaceStatus (
1129 VASurfaceID render_target,
1130 VASurfaceStatus *status /* out */
1134 VADriverContextP ctx;
1138 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1140 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1145 VAStatus vaQuerySurfaceError (
1147 VASurfaceID surface,
1148 VAStatus error_status,
1149 void **error_info /*out*/
1153 VADriverContextP ctx;
1157 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1159 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1164 /* Get maximum number of image formats supported by the implementation */
1165 int vaMaxNumImageFormats (
1169 if (!vaDisplayIsValid(dpy))
1172 return CTX(dpy)->max_image_formats;
1175 VAStatus vaQueryImageFormats (
1177 VAImageFormat *format_list, /* out */
1178 int *num_formats /* out */
1181 VADriverContextP ctx;
1185 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1189 * The width and height fields returned in the VAImage structure may get
1190 * enlarged for some YUV formats. The size of the data buffer that needs
1191 * to be allocated will be given in the "data_size" field in VAImage.
1192 * Image data is not allocated by this function. The client should
1193 * allocate the memory and fill in the VAImage structure's data field
1194 * after looking at "data_size" returned from the library.
1196 VAStatus vaCreateImage (
1198 VAImageFormat *format,
1201 VAImage *image /* out */
1204 VADriverContextP ctx;
1208 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1212 * Should call DestroyImage before destroying the surface it is bound to
1214 VAStatus vaDestroyImage (
1219 VADriverContextP ctx;
1223 return ctx->vtable->vaDestroyImage ( ctx, image);
1226 VAStatus vaSetImagePalette (
1229 unsigned char *palette
1232 VADriverContextP ctx;
1236 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1240 * Retrieve surface data into a VAImage
1241 * Image must be in a format supported by the implementation
1243 VAStatus vaGetImage (
1245 VASurfaceID surface,
1246 int x, /* coordinates of the upper left source pixel */
1248 unsigned int width, /* width and height of the region */
1249 unsigned int height,
1253 VADriverContextP ctx;
1257 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1261 * Copy data from a VAImage to a surface
1262 * Image must be in a format supported by the implementation
1264 VAStatus vaPutImage (
1266 VASurfaceID surface,
1270 unsigned int src_width,
1271 unsigned int src_height,
1274 unsigned int dest_width,
1275 unsigned int dest_height
1278 VADriverContextP ctx;
1282 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1286 * Derive an VAImage from an existing surface.
1287 * This interface will derive a VAImage and corresponding image buffer from
1288 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1289 * direct CPU access. This operation is only possible on implementations with
1290 * direct rendering capabilities and internal surface formats that can be
1291 * represented with a VAImage. When the operation is not possible this interface
1292 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1293 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1296 * Implementations should only return success when the resulting image buffer
1297 * would be useable with vaMap/Unmap.
1299 * When directly accessing a surface special care must be taken to insure
1300 * proper synchronization with the graphics hardware. Clients should call
1301 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1302 * rendering or currently being displayed by an overlay.
1304 * Additionally nothing about the contents of a surface should be assumed
1305 * following a vaPutSurface. Implementations are free to modify the surface for
1306 * scaling or subpicture blending within a call to vaPutImage.
1308 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1309 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1310 * vaGetImage with other surfaces is supported.
1312 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1313 * image and image buffer structures will be destroyed; however, the underlying
1314 * surface will remain unchanged until freed with vaDestroySurfaces.
1316 VAStatus vaDeriveImage (
1318 VASurfaceID surface,
1319 VAImage *image /* out */
1322 VADriverContextP ctx;
1326 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1330 /* Get maximum number of subpicture formats supported by the implementation */
1331 int vaMaxNumSubpictureFormats (
1335 if (!vaDisplayIsValid(dpy))
1338 return CTX(dpy)->max_subpic_formats;
1342 * Query supported subpicture formats
1343 * The caller must provide a "format_list" array that can hold at
1344 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1345 * for each format to indicate additional capabilities for that format. The actual
1346 * number of formats returned in "format_list" is returned in "num_formats".
1348 VAStatus vaQuerySubpictureFormats (
1350 VAImageFormat *format_list, /* out */
1351 unsigned int *flags, /* out */
1352 unsigned int *num_formats /* out */
1355 VADriverContextP ctx;
1360 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1364 * Subpictures are created with an image associated.
1366 VAStatus vaCreateSubpicture (
1369 VASubpictureID *subpicture /* out */
1372 VADriverContextP ctx;
1376 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1380 * Destroy the subpicture before destroying the image it is assocated to
1382 VAStatus vaDestroySubpicture (
1384 VASubpictureID subpicture
1387 VADriverContextP ctx;
1391 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1394 VAStatus vaSetSubpictureImage (
1396 VASubpictureID subpicture,
1400 VADriverContextP ctx;
1404 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1409 * If chromakey is enabled, then the area where the source value falls within
1410 * the chromakey [min, max] range is transparent
1412 VAStatus vaSetSubpictureChromakey (
1414 VASubpictureID subpicture,
1415 unsigned int chromakey_min,
1416 unsigned int chromakey_max,
1417 unsigned int chromakey_mask
1420 VADriverContextP ctx;
1424 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1429 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1430 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1431 * the overall alpha is per-pixel alpha multiplied by the global alpha
1433 VAStatus vaSetSubpictureGlobalAlpha (
1435 VASubpictureID subpicture,
1439 VADriverContextP ctx;
1443 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1447 vaAssociateSubpicture associates the subpicture with the target_surface.
1448 It defines the region mapping between the subpicture and the target
1449 surface through source and destination rectangles (with the same width and height).
1450 Both will be displayed at the next call to vaPutSurface. Additional
1451 associations before the call to vaPutSurface simply overrides the association.
1453 VAStatus vaAssociateSubpicture (
1455 VASubpictureID subpicture,
1456 VASurfaceID *target_surfaces,
1458 short src_x, /* upper left offset in subpicture */
1460 unsigned short src_width,
1461 unsigned short src_height,
1462 short dest_x, /* upper left offset in surface */
1464 unsigned short dest_width,
1465 unsigned short dest_height,
1467 * whether to enable chroma-keying or global-alpha
1468 * see VA_SUBPICTURE_XXX values
1473 VADriverContextP ctx;
1477 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 );
1481 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1483 VAStatus vaDeassociateSubpicture (
1485 VASubpictureID subpicture,
1486 VASurfaceID *target_surfaces,
1490 VADriverContextP ctx;
1494 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1498 /* Get maximum number of display attributes supported by the implementation */
1499 int vaMaxNumDisplayAttributes (
1505 if (!vaDisplayIsValid(dpy))
1508 tmp = CTX(dpy)->max_display_attributes;
1510 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1516 * Query display attributes
1517 * The caller must provide a "attr_list" array that can hold at
1518 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1519 * returned in "attr_list" is returned in "num_attributes".
1521 VAStatus vaQueryDisplayAttributes (
1523 VADisplayAttribute *attr_list, /* out */
1524 int *num_attributes /* out */
1527 VADriverContextP ctx;
1532 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1534 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1541 * Get display attributes
1542 * This function returns the current attribute values in "attr_list".
1543 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1544 * from vaQueryDisplayAttributes() can have their values retrieved.
1546 VAStatus vaGetDisplayAttributes (
1548 VADisplayAttribute *attr_list, /* in/out */
1552 VADriverContextP ctx;
1557 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1559 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1565 * Set display attributes
1566 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1567 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1568 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1570 VAStatus vaSetDisplayAttributes (
1572 VADisplayAttribute *attr_list,
1576 VADriverContextP ctx;
1581 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1582 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1587 VAStatus vaLockSurface(VADisplay dpy,
1588 VASurfaceID surface,
1589 unsigned int *fourcc, /* following are output argument */
1590 unsigned int *luma_stride,
1591 unsigned int *chroma_u_stride,
1592 unsigned int *chroma_v_stride,
1593 unsigned int *luma_offset,
1594 unsigned int *chroma_u_offset,
1595 unsigned int *chroma_v_offset,
1596 unsigned int *buffer_name,
1600 VADriverContextP ctx;
1604 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);
1608 VAStatus vaUnlockSurface(VADisplay dpy,
1612 VADriverContextP ctx;
1616 return ctx->vtable->vaUnlockSurface( ctx, surface );
1619 /* Video Processing */
1620 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1621 CHECK_DISPLAY(dpy); \
1624 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1627 #define VA_VPP_INVOKE(dpy, func, args) do { \
1628 if (!ctx->vtable_vpp->va##func) \
1629 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1630 status = ctx->vtable_vpp->va##func args; \
1634 vaQueryVideoProcFilters(
1636 VAContextID context,
1637 VAProcFilterType *filters,
1638 unsigned int *num_filters
1641 VADriverContextP ctx;
1644 VA_VPP_INIT_CONTEXT(ctx, dpy);
1647 QueryVideoProcFilters,
1648 (ctx, context, filters, num_filters)
1654 vaQueryVideoProcFilterCaps(
1656 VAContextID context,
1657 VAProcFilterType type,
1659 unsigned int *num_filter_caps
1662 VADriverContextP ctx;
1665 VA_VPP_INIT_CONTEXT(ctx, dpy);
1668 QueryVideoProcFilterCaps,
1669 (ctx, context, type, filter_caps, num_filter_caps)
1675 vaQueryVideoProcPipelineCaps(
1677 VAContextID context,
1678 VABufferID *filters,
1679 unsigned int num_filters,
1680 VAProcPipelineCaps *pipeline_caps
1683 VADriverContextP ctx;
1686 VA_VPP_INIT_CONTEXT(ctx, dpy);
1689 QueryVideoProcPipelineCaps,
1690 (ctx, context, filters, num_filters, pipeline_caps)