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_UNKNOWN:
429 return "unknown libva error";
431 return "unknown libva error / description missing";
434 VAStatus vaInitialize (
436 int *major_version, /* out */
437 int *minor_version /* out */
440 const char *driver_name_env = NULL;
441 char *driver_name = NULL;
450 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
452 driver_name_env = getenv("LIBVA_DRIVER_NAME");
453 if (driver_name_env && geteuid() == getuid()) {
454 /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
455 driver_name = strdup(driver_name_env);
456 vaStatus = VA_STATUS_SUCCESS;
457 va_infoMessage("User requested driver '%s'\n", driver_name);
459 vaStatus = va_getDriverName(dpy, &driver_name);
460 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
463 if (VA_STATUS_SUCCESS == vaStatus) {
464 vaStatus = va_openDriver(dpy, driver_name);
465 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
467 *major_version = VA_MAJOR_VERSION;
468 *minor_version = VA_MINOR_VERSION;
474 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
481 * After this call, all library internal resources will be cleaned up
483 VAStatus vaTerminate (
487 VAStatus vaStatus = VA_STATUS_SUCCESS;
488 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
489 VADriverContextP old_ctx;
494 if (old_ctx->handle) {
495 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
496 dlclose(old_ctx->handle);
497 old_ctx->handle = NULL;
499 free(old_ctx->vtable);
500 old_ctx->vtable = NULL;
501 free(old_ctx->vtable_vpp);
502 old_ctx->vtable_vpp = NULL;
504 if (VA_STATUS_SUCCESS == vaStatus)
505 pDisplayContext->vaDestroy(pDisplayContext);
507 VA_TRACE_LOG(va_TraceTerminate, dpy);
517 * vaQueryVendorString returns a pointer to a zero-terminated string
518 * describing some aspects of the VA implemenation on a specific
519 * hardware accelerator. The format of the returned string is:
520 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
521 * e.g. for the Intel GMA500 implementation, an example would be:
522 * "IntelGMA500-1.0-0.2-patch3
524 const char *vaQueryVendorString (
528 if (!vaDisplayIsValid(dpy))
531 return CTX(dpy)->str_vendor;
535 /* Get maximum number of profiles supported by the implementation */
536 int vaMaxNumProfiles (
540 if (!vaDisplayIsValid(dpy))
543 return CTX(dpy)->max_profiles;
546 /* Get maximum number of entrypoints supported by the implementation */
547 int vaMaxNumEntrypoints (
551 if (!vaDisplayIsValid(dpy))
554 return CTX(dpy)->max_entrypoints;
558 /* Get maximum number of attributs supported by the implementation */
559 int vaMaxNumConfigAttributes (
563 if (!vaDisplayIsValid(dpy))
566 return CTX(dpy)->max_attributes;
569 VAStatus vaQueryConfigEntrypoints (
572 VAEntrypoint *entrypoints, /* out */
573 int *num_entrypoints /* out */
576 VADriverContextP ctx;
580 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
583 VAStatus vaGetConfigAttributes (
586 VAEntrypoint entrypoint,
587 VAConfigAttrib *attrib_list, /* in/out */
591 VADriverContextP ctx;
595 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
598 VAStatus vaQueryConfigProfiles (
600 VAProfile *profile_list, /* out */
601 int *num_profiles /* out */
604 VADriverContextP ctx;
608 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
611 VAStatus vaCreateConfig (
614 VAEntrypoint entrypoint,
615 VAConfigAttrib *attrib_list,
617 VAConfigID *config_id /* out */
620 VADriverContextP ctx;
621 VAStatus vaStatus = VA_STATUS_SUCCESS;
627 vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
629 /* record the current entrypoint for further trace/fool determination */
630 VA_TRACE_LOG(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
631 VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
636 VAStatus vaDestroyConfig (
641 VADriverContextP ctx;
645 return ctx->vtable->vaDestroyConfig ( ctx, config_id );
648 VAStatus vaQueryConfigAttributes (
650 VAConfigID config_id,
651 VAProfile *profile, /* out */
652 VAEntrypoint *entrypoint, /* out */
653 VAConfigAttrib *attrib_list,/* out */
654 int *num_attribs /* out */
657 VADriverContextP ctx;
661 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
664 /* XXX: this is a slow implementation that will be removed */
666 va_impl_query_surface_attributes(
667 VADriverContextP ctx,
669 VASurfaceAttrib *out_attribs,
670 unsigned int *out_num_attribs_ptr
673 VASurfaceAttrib *attribs = NULL;
674 unsigned int num_attribs, n;
675 VASurfaceAttrib *out_attrib;
676 unsigned int out_num_attribs;
677 VAImageFormat *image_formats = NULL;
678 int num_image_formats, i;
681 /* List of surface attributes to query */
682 struct va_surface_attrib_map {
683 VASurfaceAttribType type;
684 VAGenericValueType value_type;
686 static const struct va_surface_attrib_map attribs_map[] = {
687 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
688 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
689 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
690 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
691 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
692 { VASurfaceAttribNone, }
695 if (!out_attribs || !out_num_attribs_ptr)
696 return VA_STATUS_ERROR_INVALID_PARAMETER;
697 if (!ctx->vtable->vaGetSurfaceAttributes)
698 return VA_STATUS_ERROR_UNIMPLEMENTED;
700 num_image_formats = ctx->max_image_formats;
701 image_formats = malloc(num_image_formats * sizeof(*image_formats));
702 if (!image_formats) {
703 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
707 va_status = ctx->vtable->vaQueryImageFormats(
708 ctx, image_formats, &num_image_formats);
709 if (va_status != VA_STATUS_SUCCESS)
712 num_attribs = VASurfaceAttribCount + num_image_formats;
713 attribs = malloc(num_attribs * sizeof(*attribs));
715 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
719 /* Initialize with base surface attributes, except pixel-formats */
720 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
721 VASurfaceAttrib * const attrib = &attribs[n];
722 attrib->type = attribs_map[n].type;
723 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
724 attrib->value.type = attribs_map[n].value_type;
727 /* Append image formats */
728 for (i = 0; i < num_image_formats; i++) {
729 VASurfaceAttrib * const attrib = &attribs[n];
730 attrib->type = VASurfaceAttribPixelFormat;
731 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
732 attrib->value.type = VAGenericValueTypeInteger;
733 attrib->value.value.i = image_formats[i].fourcc;
734 if (++n == num_attribs) {
735 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
741 va_status = ctx->vtable->vaGetSurfaceAttributes(
742 ctx, config, attribs, num_attribs);
743 if (va_status != VA_STATUS_SUCCESS)
746 /* Remove invalid entries */
748 for (n = 0; n < num_attribs; n++) {
749 VASurfaceAttrib * const attrib = &attribs[n];
751 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
754 // Accept all surface attributes that are not pixel-formats
755 if (attrib->type != VASurfaceAttribPixelFormat) {
760 // Drop invalid pixel-format attribute
761 if (!attrib->value.value.i) {
762 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
766 // Check for duplicates
767 int is_duplicate = 0;
768 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
769 const VASurfaceAttrib * const prev_attrib = &attribs[i];
770 if (prev_attrib->type != VASurfaceAttribPixelFormat)
772 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
775 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
780 if (*out_num_attribs_ptr < out_num_attribs) {
781 *out_num_attribs_ptr = out_num_attribs;
782 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
786 out_attrib = out_attribs;
787 for (n = 0; n < num_attribs; n++) {
788 const VASurfaceAttrib * const attrib = &attribs[n];
789 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
791 *out_attrib++ = *attrib;
801 vaQuerySurfaceAttributes(
804 VASurfaceAttrib *attrib_list,
805 unsigned int *num_attribs
808 VADriverContextP ctx;
814 return VA_STATUS_ERROR_INVALID_DISPLAY;
816 if (!ctx->vtable->vaQuerySurfaceAttributes)
817 return va_impl_query_surface_attributes(ctx, config,
818 attrib_list, num_attribs);
820 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
821 attrib_list, num_attribs);
831 VASurfaceID *surfaces,
832 unsigned int num_surfaces,
833 VASurfaceAttrib *attrib_list,
834 unsigned int num_attribs
837 VADriverContextP ctx;
843 return VA_STATUS_ERROR_INVALID_DISPLAY;
845 if (ctx->vtable->vaCreateSurfaces2)
846 return ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
847 surfaces, num_surfaces,
848 attrib_list, num_attribs);
850 if (attrib_list && num_attribs > 0)
851 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
853 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
854 num_surfaces, surfaces);
856 VA_TRACE_LOG(va_TraceCreateSurfaces,
857 dpy, width, height, format, num_surfaces, surfaces,
858 attrib_list, num_attribs);
864 VAStatus vaDestroySurfaces (
866 VASurfaceID *surface_list,
870 VADriverContextP ctx;
874 return ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
877 VAStatus vaCreateContext (
879 VAConfigID config_id,
883 VASurfaceID *render_targets,
884 int num_render_targets,
885 VAContextID *context /* out */
888 VADriverContextP ctx;
894 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
895 flag, render_targets, num_render_targets, context );
897 /* keep current encode/decode resoluton */
898 VA_TRACE_LOG(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
903 VAStatus vaDestroyContext (
908 VADriverContextP ctx;
912 return ctx->vtable->vaDestroyContext( ctx, context );
915 VAStatus vaCreateBuffer (
917 VAContextID context, /* in */
918 VABufferType type, /* in */
919 unsigned int size, /* in */
920 unsigned int num_elements, /* in */
922 VABufferID *buf_id /* out */
925 VADriverContextP ctx;
930 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
932 return VA_STATUS_SUCCESS;
934 return ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
937 VAStatus vaBufferSetNumElements (
939 VABufferID buf_id, /* in */
940 unsigned int num_elements /* in */
943 VADriverContextP ctx;
949 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
953 VAStatus vaMapBuffer (
955 VABufferID buf_id, /* in */
956 void **pbuf /* out */
959 VADriverContextP ctx;
966 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
968 return VA_STATUS_SUCCESS;
970 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
972 VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
977 VAStatus vaUnmapBuffer (
979 VABufferID buf_id /* in */
982 VADriverContextP ctx;
987 VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
989 return VA_STATUS_SUCCESS;
991 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
994 VAStatus vaDestroyBuffer (
999 VADriverContextP ctx;
1005 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1008 VAStatus vaBufferInfo (
1010 VAContextID context, /* in */
1011 VABufferID buf_id, /* in */
1012 VABufferType *type, /* out */
1013 unsigned int *size, /* out */
1014 unsigned int *num_elements /* out */
1017 VADriverContextP ctx;
1023 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1025 return VA_STATUS_SUCCESS;
1027 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1030 VAStatus vaBeginPicture (
1032 VAContextID context,
1033 VASurfaceID render_target
1036 VADriverContextP ctx;
1042 VA_TRACE_LOG(va_TraceBeginPicture, dpy, context, render_target);
1045 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1050 VAStatus vaRenderPicture (
1052 VAContextID context,
1053 VABufferID *buffers,
1057 VADriverContextP ctx;
1062 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1065 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1068 VAStatus vaEndPicture (
1073 VAStatus va_status = VA_STATUS_SUCCESS;
1074 VADriverContextP ctx;
1079 if (fool_codec == 0)
1080 va_status = ctx->vtable->vaEndPicture( ctx, context );
1082 /* dump surface content */
1083 VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
1088 VAStatus vaSyncSurface (
1090 VASurfaceID render_target
1094 VADriverContextP ctx;
1099 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1100 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1105 VAStatus vaQuerySurfaceStatus (
1107 VASurfaceID render_target,
1108 VASurfaceStatus *status /* out */
1112 VADriverContextP ctx;
1116 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1118 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1123 VAStatus vaQuerySurfaceError (
1125 VASurfaceID surface,
1126 VAStatus error_status,
1127 void **error_info /*out*/
1131 VADriverContextP ctx;
1135 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1137 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1142 /* Get maximum number of image formats supported by the implementation */
1143 int vaMaxNumImageFormats (
1147 if (!vaDisplayIsValid(dpy))
1150 return CTX(dpy)->max_image_formats;
1153 VAStatus vaQueryImageFormats (
1155 VAImageFormat *format_list, /* out */
1156 int *num_formats /* out */
1159 VADriverContextP ctx;
1163 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1167 * The width and height fields returned in the VAImage structure may get
1168 * enlarged for some YUV formats. The size of the data buffer that needs
1169 * to be allocated will be given in the "data_size" field in VAImage.
1170 * Image data is not allocated by this function. The client should
1171 * allocate the memory and fill in the VAImage structure's data field
1172 * after looking at "data_size" returned from the library.
1174 VAStatus vaCreateImage (
1176 VAImageFormat *format,
1179 VAImage *image /* out */
1182 VADriverContextP ctx;
1186 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1190 * Should call DestroyImage before destroying the surface it is bound to
1192 VAStatus vaDestroyImage (
1197 VADriverContextP ctx;
1201 return ctx->vtable->vaDestroyImage ( ctx, image);
1204 VAStatus vaSetImagePalette (
1207 unsigned char *palette
1210 VADriverContextP ctx;
1214 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1218 * Retrieve surface data into a VAImage
1219 * Image must be in a format supported by the implementation
1221 VAStatus vaGetImage (
1223 VASurfaceID surface,
1224 int x, /* coordinates of the upper left source pixel */
1226 unsigned int width, /* width and height of the region */
1227 unsigned int height,
1231 VADriverContextP ctx;
1235 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1239 * Copy data from a VAImage to a surface
1240 * Image must be in a format supported by the implementation
1242 VAStatus vaPutImage (
1244 VASurfaceID surface,
1248 unsigned int src_width,
1249 unsigned int src_height,
1252 unsigned int dest_width,
1253 unsigned int dest_height
1256 VADriverContextP ctx;
1260 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1264 * Derive an VAImage from an existing surface.
1265 * This interface will derive a VAImage and corresponding image buffer from
1266 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1267 * direct CPU access. This operation is only possible on implementations with
1268 * direct rendering capabilities and internal surface formats that can be
1269 * represented with a VAImage. When the operation is not possible this interface
1270 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1271 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1274 * Implementations should only return success when the resulting image buffer
1275 * would be useable with vaMap/Unmap.
1277 * When directly accessing a surface special care must be taken to insure
1278 * proper synchronization with the graphics hardware. Clients should call
1279 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1280 * rendering or currently being displayed by an overlay.
1282 * Additionally nothing about the contents of a surface should be assumed
1283 * following a vaPutSurface. Implementations are free to modify the surface for
1284 * scaling or subpicture blending within a call to vaPutImage.
1286 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1287 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1288 * vaGetImage with other surfaces is supported.
1290 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1291 * image and image buffer structures will be destroyed; however, the underlying
1292 * surface will remain unchanged until freed with vaDestroySurfaces.
1294 VAStatus vaDeriveImage (
1296 VASurfaceID surface,
1297 VAImage *image /* out */
1300 VADriverContextP ctx;
1304 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1308 /* Get maximum number of subpicture formats supported by the implementation */
1309 int vaMaxNumSubpictureFormats (
1313 if (!vaDisplayIsValid(dpy))
1316 return CTX(dpy)->max_subpic_formats;
1320 * Query supported subpicture formats
1321 * The caller must provide a "format_list" array that can hold at
1322 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1323 * for each format to indicate additional capabilities for that format. The actual
1324 * number of formats returned in "format_list" is returned in "num_formats".
1326 VAStatus vaQuerySubpictureFormats (
1328 VAImageFormat *format_list, /* out */
1329 unsigned int *flags, /* out */
1330 unsigned int *num_formats /* out */
1333 VADriverContextP ctx;
1338 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1342 * Subpictures are created with an image associated.
1344 VAStatus vaCreateSubpicture (
1347 VASubpictureID *subpicture /* out */
1350 VADriverContextP ctx;
1354 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1358 * Destroy the subpicture before destroying the image it is assocated to
1360 VAStatus vaDestroySubpicture (
1362 VASubpictureID subpicture
1365 VADriverContextP ctx;
1369 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1372 VAStatus vaSetSubpictureImage (
1374 VASubpictureID subpicture,
1378 VADriverContextP ctx;
1382 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1387 * If chromakey is enabled, then the area where the source value falls within
1388 * the chromakey [min, max] range is transparent
1390 VAStatus vaSetSubpictureChromakey (
1392 VASubpictureID subpicture,
1393 unsigned int chromakey_min,
1394 unsigned int chromakey_max,
1395 unsigned int chromakey_mask
1398 VADriverContextP ctx;
1402 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1407 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1408 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1409 * the overall alpha is per-pixel alpha multiplied by the global alpha
1411 VAStatus vaSetSubpictureGlobalAlpha (
1413 VASubpictureID subpicture,
1417 VADriverContextP ctx;
1421 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1425 vaAssociateSubpicture associates the subpicture with the target_surface.
1426 It defines the region mapping between the subpicture and the target
1427 surface through source and destination rectangles (with the same width and height).
1428 Both will be displayed at the next call to vaPutSurface. Additional
1429 associations before the call to vaPutSurface simply overrides the association.
1431 VAStatus vaAssociateSubpicture (
1433 VASubpictureID subpicture,
1434 VASurfaceID *target_surfaces,
1436 short src_x, /* upper left offset in subpicture */
1438 unsigned short src_width,
1439 unsigned short src_height,
1440 short dest_x, /* upper left offset in surface */
1442 unsigned short dest_width,
1443 unsigned short dest_height,
1445 * whether to enable chroma-keying or global-alpha
1446 * see VA_SUBPICTURE_XXX values
1451 VADriverContextP ctx;
1455 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 );
1459 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1461 VAStatus vaDeassociateSubpicture (
1463 VASubpictureID subpicture,
1464 VASurfaceID *target_surfaces,
1468 VADriverContextP ctx;
1472 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1476 /* Get maximum number of display attributes supported by the implementation */
1477 int vaMaxNumDisplayAttributes (
1483 if (!vaDisplayIsValid(dpy))
1486 tmp = CTX(dpy)->max_display_attributes;
1488 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1494 * Query display attributes
1495 * The caller must provide a "attr_list" array that can hold at
1496 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1497 * returned in "attr_list" is returned in "num_attributes".
1499 VAStatus vaQueryDisplayAttributes (
1501 VADisplayAttribute *attr_list, /* out */
1502 int *num_attributes /* out */
1505 VADriverContextP ctx;
1510 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1512 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1519 * Get display attributes
1520 * This function returns the current attribute values in "attr_list".
1521 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1522 * from vaQueryDisplayAttributes() can have their values retrieved.
1524 VAStatus vaGetDisplayAttributes (
1526 VADisplayAttribute *attr_list, /* in/out */
1530 VADriverContextP ctx;
1535 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1537 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1543 * Set display attributes
1544 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1545 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1546 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1548 VAStatus vaSetDisplayAttributes (
1550 VADisplayAttribute *attr_list,
1554 VADriverContextP ctx;
1559 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1560 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1565 VAStatus vaLockSurface(VADisplay dpy,
1566 VASurfaceID surface,
1567 unsigned int *fourcc, /* following are output argument */
1568 unsigned int *luma_stride,
1569 unsigned int *chroma_u_stride,
1570 unsigned int *chroma_v_stride,
1571 unsigned int *luma_offset,
1572 unsigned int *chroma_u_offset,
1573 unsigned int *chroma_v_offset,
1574 unsigned int *buffer_name,
1578 VADriverContextP ctx;
1582 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);
1586 VAStatus vaUnlockSurface(VADisplay dpy,
1590 VADriverContextP ctx;
1594 return ctx->vtable->vaUnlockSurface( ctx, surface );
1597 /* Video Processing */
1598 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1599 CHECK_DISPLAY(dpy); \
1602 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1605 #define VA_VPP_INVOKE(dpy, func, args) do { \
1606 if (!ctx->vtable_vpp->va##func) \
1607 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1608 status = ctx->vtable_vpp->va##func args; \
1612 vaQueryVideoProcFilters(
1614 VAContextID context,
1615 VAProcFilterType *filters,
1616 unsigned int *num_filters
1619 VADriverContextP ctx;
1622 VA_VPP_INIT_CONTEXT(ctx, dpy);
1625 QueryVideoProcFilters,
1626 (ctx, context, filters, num_filters)
1632 vaQueryVideoProcFilterCaps(
1634 VAContextID context,
1635 VAProcFilterType type,
1637 unsigned int *num_filter_caps
1640 VADriverContextP ctx;
1643 VA_VPP_INIT_CONTEXT(ctx, dpy);
1646 QueryVideoProcFilterCaps,
1647 (ctx, context, type, filter_caps, num_filter_caps)
1653 vaQueryVideoProcPipelineCaps(
1655 VAContextID context,
1656 VABufferID *filters,
1657 unsigned int num_filters,
1658 VAProcPipelineCaps *pipeline_caps
1661 VADriverContextP ctx;
1664 VA_VPP_INIT_CONTEXT(ctx, dpy);
1667 QueryVideoProcPipelineCaps,
1668 (ctx, context, filters, num_filters, pipeline_caps)