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 },
258 for (i = 0; compatible_versions[i].major >= 0; i++) {
259 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
260 compatible_versions[i].major,
261 compatible_versions[i].minor)) {
262 init_func = (VADriverInit)dlsym(handle, init_func_s);
264 va_infoMessage("Found init function %s\n", init_func_s);
270 if (compatible_versions[i].major < 0) {
271 va_errorMessage("%s has no function %s\n",
272 driver_path, init_func_s);
275 struct VADriverVTable *vtable = ctx->vtable;
276 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
278 vaStatus = VA_STATUS_SUCCESS;
280 vtable = calloc(1, sizeof(*vtable));
282 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
284 ctx->vtable = vtable;
287 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
289 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
291 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
293 ctx->vtable_vpp = vtable_vpp;
295 if (init_func && VA_STATUS_SUCCESS == vaStatus)
296 vaStatus = (*init_func)(ctx);
298 if (VA_STATUS_SUCCESS == vaStatus) {
299 CHECK_MAXIMUM(vaStatus, ctx, profiles);
300 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
301 CHECK_MAXIMUM(vaStatus, ctx, attributes);
302 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
303 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
304 CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
305 CHECK_STRING(vaStatus, ctx, vendor);
306 CHECK_VTABLE(vaStatus, ctx, Terminate);
307 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
308 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
309 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
310 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
311 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
312 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
313 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
314 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
315 CHECK_VTABLE(vaStatus, ctx, CreateContext);
316 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
317 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
318 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
319 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
320 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
321 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
322 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
323 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
324 CHECK_VTABLE(vaStatus, ctx, EndPicture);
325 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
326 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
327 CHECK_VTABLE(vaStatus, ctx, PutSurface);
328 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
329 CHECK_VTABLE(vaStatus, ctx, CreateImage);
330 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
331 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
332 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
333 CHECK_VTABLE(vaStatus, ctx, GetImage);
334 CHECK_VTABLE(vaStatus, ctx, PutImage);
335 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
336 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
337 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
338 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
339 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
340 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
341 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
342 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
343 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
344 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
345 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
347 if (VA_STATUS_SUCCESS != vaStatus) {
348 va_errorMessage("%s init failed\n", driver_path);
351 if (VA_STATUS_SUCCESS == vaStatus)
352 ctx->handle = handle;
359 driver_dir = strtok_r(NULL, ":", &saveptr);
367 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
369 VADriverContextP ctx;
370 if (!vaDisplayIsValid(dpy))
374 if (NULL == ctx->handle)
377 return (VAPrivFunc) dlsym(ctx->handle, func);
382 * Returns a short english description of error_status
384 const char *vaErrorStr(VAStatus error_status)
386 switch(error_status) {
387 case VA_STATUS_SUCCESS:
388 return "success (no error)";
389 case VA_STATUS_ERROR_OPERATION_FAILED:
390 return "operation failed";
391 case VA_STATUS_ERROR_ALLOCATION_FAILED:
392 return "resource allocation failed";
393 case VA_STATUS_ERROR_INVALID_DISPLAY:
394 return "invalid VADisplay";
395 case VA_STATUS_ERROR_INVALID_CONFIG:
396 return "invalid VAConfigID";
397 case VA_STATUS_ERROR_INVALID_CONTEXT:
398 return "invalid VAContextID";
399 case VA_STATUS_ERROR_INVALID_SURFACE:
400 return "invalid VASurfaceID";
401 case VA_STATUS_ERROR_INVALID_BUFFER:
402 return "invalid VABufferID";
403 case VA_STATUS_ERROR_INVALID_IMAGE:
404 return "invalid VAImageID";
405 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
406 return "invalid VASubpictureID";
407 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
408 return "attribute not supported";
409 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
410 return "list argument exceeds maximum number";
411 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
412 return "the requested VAProfile is not supported";
413 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
414 return "the requested VAEntryPoint is not supported";
415 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
416 return "the requested RT Format is not supported";
417 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
418 return "the requested VABufferType is not supported";
419 case VA_STATUS_ERROR_SURFACE_BUSY:
420 return "surface is in use";
421 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
422 return "flag not supported";
423 case VA_STATUS_ERROR_INVALID_PARAMETER:
424 return "invalid parameter";
425 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
426 return "resolution not supported";
427 case VA_STATUS_ERROR_UNIMPLEMENTED:
428 return "the requested function is not implemented";
429 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
430 return "surface is in displaying (may by overlay)" ;
431 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
432 return "invalid VAImageFormat";
433 case VA_STATUS_ERROR_INVALID_VALUE:
434 return "an invalid/unsupported value was supplied";
435 case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
436 return "the requested filter is not supported";
437 case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
438 return "an invalid filter chain was supplied";
439 case VA_STATUS_ERROR_UNKNOWN:
440 return "unknown libva error";
442 return "unknown libva error / description missing";
445 const static char *prefer_driver_list[4] = {
452 VAStatus vaSetDriverName(
457 VADriverContextP ctx;
458 VAStatus vaStatus = VA_STATUS_SUCCESS;
459 char *override_driver_name = NULL;
463 if (geteuid() != getuid()) {
464 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
465 va_errorMessage("no permission to vaSetDriverName\n");
469 if (strlen(driver_name) == 0 || strlen(driver_name) >=256) {
470 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
471 va_errorMessage("vaSetDriverName returns %s\n",
472 vaErrorStr(vaStatus));
477 for (i = 0; i < sizeof(prefer_driver_list) / sizeof(char *); i++) {
478 if (strlen(prefer_driver_list[i]) != strlen(driver_name))
480 if (!strncmp(prefer_driver_list[i], driver_name, strlen(driver_name))) {
487 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
488 va_errorMessage("vaSetDriverName returns %s. Incorrect parameter\n",
489 vaErrorStr(vaStatus));
493 override_driver_name = strdup(driver_name);
495 if (!override_driver_name) {
496 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
497 va_errorMessage("vaSetDriverName returns %s. Out of Memory\n",
498 vaErrorStr(vaStatus));
502 ctx->override_driver_name = override_driver_name;
503 return VA_STATUS_SUCCESS;
506 VAStatus vaInitialize (
508 int *major_version, /* out */
509 int *minor_version /* out */
512 const char *driver_name_env = NULL;
513 char *driver_name = NULL;
515 VADriverContextP ctx;
525 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
527 vaStatus = va_getDriverName(dpy, &driver_name);
529 if (!ctx->override_driver_name) {
530 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
532 driver_name_env = getenv("LIBVA_DRIVER_NAME");
533 } else if (vaStatus == VA_STATUS_SUCCESS) {
537 driver_name = strdup(ctx->override_driver_name);
539 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
540 va_errorMessage("vaInitialize() failed with %s, out of memory\n",
541 vaErrorStr(vaStatus));
544 va_infoMessage("User requested driver '%s'\n", driver_name);
547 if ((VA_STATUS_SUCCESS == vaStatus) &&
548 driver_name_env && (geteuid() == getuid())) {
549 /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
550 if (driver_name) /* memory is allocated in va_getDriverName */
553 driver_name = strdup(driver_name_env);
554 vaStatus = VA_STATUS_SUCCESS;
555 va_infoMessage("User requested driver '%s'\n", driver_name);
558 if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
559 vaStatus = va_openDriver(dpy, driver_name);
560 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
562 *major_version = VA_MAJOR_VERSION;
563 *minor_version = VA_MINOR_VERSION;
565 va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n",
566 vaErrorStr(vaStatus), driver_name);
571 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
578 * After this call, all library internal resources will be cleaned up
580 VAStatus vaTerminate (
584 VAStatus vaStatus = VA_STATUS_SUCCESS;
585 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
586 VADriverContextP old_ctx;
591 if (old_ctx->handle) {
592 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
593 dlclose(old_ctx->handle);
594 old_ctx->handle = NULL;
596 free(old_ctx->vtable);
597 old_ctx->vtable = NULL;
598 free(old_ctx->vtable_vpp);
599 old_ctx->vtable_vpp = NULL;
601 if (old_ctx->override_driver_name) {
602 free(old_ctx->override_driver_name);
603 old_ctx->override_driver_name = NULL;
606 VA_TRACE_LOG(va_TraceTerminate, dpy);
612 if (VA_STATUS_SUCCESS == vaStatus)
613 pDisplayContext->vaDestroy(pDisplayContext);
619 * vaQueryVendorString returns a pointer to a zero-terminated string
620 * describing some aspects of the VA implemenation on a specific
621 * hardware accelerator. The format of the returned string is:
622 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
623 * e.g. for the Intel GMA500 implementation, an example would be:
624 * "IntelGMA500-1.0-0.2-patch3
626 const char *vaQueryVendorString (
630 if (!vaDisplayIsValid(dpy))
633 return CTX(dpy)->str_vendor;
637 /* Get maximum number of profiles supported by the implementation */
638 int vaMaxNumProfiles (
642 if (!vaDisplayIsValid(dpy))
645 return CTX(dpy)->max_profiles;
648 /* Get maximum number of entrypoints supported by the implementation */
649 int vaMaxNumEntrypoints (
653 if (!vaDisplayIsValid(dpy))
656 return CTX(dpy)->max_entrypoints;
660 /* Get maximum number of attributs supported by the implementation */
661 int vaMaxNumConfigAttributes (
665 if (!vaDisplayIsValid(dpy))
668 return CTX(dpy)->max_attributes;
671 VAStatus vaQueryConfigEntrypoints (
674 VAEntrypoint *entrypoints, /* out */
675 int *num_entrypoints /* out */
678 VADriverContextP ctx;
682 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
685 VAStatus vaGetConfigAttributes (
688 VAEntrypoint entrypoint,
689 VAConfigAttrib *attrib_list, /* in/out */
693 VADriverContextP ctx;
697 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
700 VAStatus vaQueryConfigProfiles (
702 VAProfile *profile_list, /* out */
703 int *num_profiles /* out */
706 VADriverContextP ctx;
710 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
713 VAStatus vaCreateConfig (
716 VAEntrypoint entrypoint,
717 VAConfigAttrib *attrib_list,
719 VAConfigID *config_id /* out */
722 VADriverContextP ctx;
723 VAStatus vaStatus = VA_STATUS_SUCCESS;
728 vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
730 /* record the current entrypoint for further trace/fool determination */
731 VA_TRACE_ALL(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
732 VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
737 VAStatus vaDestroyConfig (
742 VADriverContextP ctx;
746 return ctx->vtable->vaDestroyConfig ( ctx, config_id );
749 VAStatus vaQueryConfigAttributes (
751 VAConfigID config_id,
752 VAProfile *profile, /* out */
753 VAEntrypoint *entrypoint, /* out */
754 VAConfigAttrib *attrib_list,/* out */
755 int *num_attribs /* out */
758 VADriverContextP ctx;
762 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
765 /* XXX: this is a slow implementation that will be removed */
767 va_impl_query_surface_attributes(
768 VADriverContextP ctx,
770 VASurfaceAttrib *out_attribs,
771 unsigned int *out_num_attribs_ptr
774 VASurfaceAttrib *attribs = NULL;
775 unsigned int num_attribs, n;
776 VASurfaceAttrib *out_attrib;
777 unsigned int out_num_attribs;
778 VAImageFormat *image_formats = NULL;
779 int num_image_formats, i;
782 /* List of surface attributes to query */
783 struct va_surface_attrib_map {
784 VASurfaceAttribType type;
785 VAGenericValueType value_type;
787 static const struct va_surface_attrib_map attribs_map[] = {
788 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
789 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
790 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
791 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
792 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
793 { VASurfaceAttribNone, }
796 if (!out_attribs || !out_num_attribs_ptr)
797 return VA_STATUS_ERROR_INVALID_PARAMETER;
798 if (!ctx->vtable->vaGetSurfaceAttributes)
799 return VA_STATUS_ERROR_UNIMPLEMENTED;
801 num_image_formats = ctx->max_image_formats;
802 image_formats = malloc(num_image_formats * sizeof(*image_formats));
803 if (!image_formats) {
804 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
808 va_status = ctx->vtable->vaQueryImageFormats(
809 ctx, image_formats, &num_image_formats);
810 if (va_status != VA_STATUS_SUCCESS)
813 num_attribs = VASurfaceAttribCount + num_image_formats;
814 attribs = malloc(num_attribs * sizeof(*attribs));
816 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
820 /* Initialize with base surface attributes, except pixel-formats */
821 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
822 VASurfaceAttrib * const attrib = &attribs[n];
823 attrib->type = attribs_map[n].type;
824 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
825 attrib->value.type = attribs_map[n].value_type;
828 /* Append image formats */
829 for (i = 0; i < num_image_formats; i++) {
830 VASurfaceAttrib * const attrib = &attribs[n];
831 attrib->type = VASurfaceAttribPixelFormat;
832 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
833 attrib->value.type = VAGenericValueTypeInteger;
834 attrib->value.value.i = image_formats[i].fourcc;
835 if (++n == num_attribs) {
836 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
842 va_status = ctx->vtable->vaGetSurfaceAttributes(
843 ctx, config, attribs, num_attribs);
844 if (va_status != VA_STATUS_SUCCESS)
847 /* Remove invalid entries */
849 for (n = 0; n < num_attribs; n++) {
850 VASurfaceAttrib * const attrib = &attribs[n];
852 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
855 // Accept all surface attributes that are not pixel-formats
856 if (attrib->type != VASurfaceAttribPixelFormat) {
861 // Drop invalid pixel-format attribute
862 if (!attrib->value.value.i) {
863 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
867 // Check for duplicates
868 int is_duplicate = 0;
869 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
870 const VASurfaceAttrib * const prev_attrib = &attribs[i];
871 if (prev_attrib->type != VASurfaceAttribPixelFormat)
873 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
876 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
881 if (*out_num_attribs_ptr < out_num_attribs) {
882 *out_num_attribs_ptr = out_num_attribs;
883 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
887 out_attrib = out_attribs;
888 for (n = 0; n < num_attribs; n++) {
889 const VASurfaceAttrib * const attrib = &attribs[n];
890 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
892 *out_attrib++ = *attrib;
902 vaQuerySurfaceAttributes(
905 VASurfaceAttrib *attrib_list,
906 unsigned int *num_attribs
909 VADriverContextP ctx;
915 return VA_STATUS_ERROR_INVALID_DISPLAY;
917 if (!ctx->vtable->vaQuerySurfaceAttributes)
918 vaStatus = va_impl_query_surface_attributes(ctx, config,
919 attrib_list, num_attribs);
921 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
922 attrib_list, num_attribs);
924 VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs);
935 VASurfaceID *surfaces,
936 unsigned int num_surfaces,
937 VASurfaceAttrib *attrib_list,
938 unsigned int num_attribs
941 VADriverContextP ctx;
947 return VA_STATUS_ERROR_INVALID_DISPLAY;
949 if (ctx->vtable->vaCreateSurfaces2)
950 vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
951 surfaces, num_surfaces,
952 attrib_list, num_attribs);
953 else if (attrib_list && num_attribs > 0)
954 vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
956 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
957 num_surfaces, surfaces);
958 VA_TRACE_LOG(va_TraceCreateSurfaces,
959 dpy, width, height, format, num_surfaces, surfaces,
960 attrib_list, num_attribs);
966 VAStatus vaDestroySurfaces (
968 VASurfaceID *surface_list,
972 VADriverContextP ctx;
978 VA_TRACE_LOG(va_TraceDestroySurfaces,
979 dpy, surface_list, num_surfaces);
981 vaStatus = ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
986 VAStatus vaCreateContext (
988 VAConfigID config_id,
992 VASurfaceID *render_targets,
993 int num_render_targets,
994 VAContextID *context /* out */
997 VADriverContextP ctx;
1003 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
1004 flag, render_targets, num_render_targets, context );
1006 /* keep current encode/decode resoluton */
1007 VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
1012 VAStatus vaDestroyContext (
1017 VADriverContextP ctx;
1021 return ctx->vtable->vaDestroyContext( ctx, context );
1024 VAStatus vaCreateBuffer (
1026 VAContextID context, /* in */
1027 VABufferType type, /* in */
1028 unsigned int size, /* in */
1029 unsigned int num_elements, /* in */
1030 void *data, /* in */
1031 VABufferID *buf_id /* out */
1034 VADriverContextP ctx;
1040 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
1042 vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
1044 VA_TRACE_LOG(va_TraceCreateBuffer,
1045 dpy, context, type, size, num_elements, data, buf_id);
1050 VAStatus vaBufferSetNumElements (
1052 VABufferID buf_id, /* in */
1053 unsigned int num_elements /* in */
1056 VADriverContextP ctx;
1060 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1062 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
1066 VAStatus vaMapBuffer (
1068 VABufferID buf_id, /* in */
1069 void **pbuf /* out */
1072 VADriverContextP ctx;
1078 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
1080 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
1082 VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf);
1087 VAStatus vaUnmapBuffer (
1089 VABufferID buf_id /* in */
1092 VADriverContextP ctx;
1096 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1098 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
1101 VAStatus vaDestroyBuffer (
1103 VABufferID buffer_id
1106 VADriverContextP ctx;
1110 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1112 VA_TRACE_LOG(va_TraceDestroyBuffer,
1115 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1118 VAStatus vaBufferInfo (
1120 VAContextID context, /* in */
1121 VABufferID buf_id, /* in */
1122 VABufferType *type, /* out */
1123 unsigned int *size, /* out */
1124 unsigned int *num_elements /* out */
1127 VADriverContextP ctx;
1132 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1134 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1137 /* Locks buffer for external API usage */
1139 vaAcquireBufferHandle(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info)
1141 VADriverContextP ctx;
1146 if (!ctx->vtable->vaAcquireBufferHandle)
1147 return VA_STATUS_ERROR_UNIMPLEMENTED;
1148 return ctx->vtable->vaAcquireBufferHandle(ctx, buf_id, buf_info);
1151 /* Unlocks buffer after usage from external API */
1153 vaReleaseBufferHandle(VADisplay dpy, VABufferID buf_id)
1155 VADriverContextP ctx;
1160 if (!ctx->vtable->vaReleaseBufferHandle)
1161 return VA_STATUS_ERROR_UNIMPLEMENTED;
1162 return ctx->vtable->vaReleaseBufferHandle(ctx, buf_id);
1165 VAStatus vaBeginPicture (
1167 VAContextID context,
1168 VASurfaceID render_target
1171 VADriverContextP ctx;
1177 VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target);
1178 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1180 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1185 VAStatus vaRenderPicture (
1187 VAContextID context,
1188 VABufferID *buffers,
1192 VADriverContextP ctx;
1197 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1198 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1200 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1203 VAStatus vaEndPicture (
1208 VAStatus va_status = VA_STATUS_SUCCESS;
1209 VADriverContextP ctx;
1214 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1216 va_status = ctx->vtable->vaEndPicture( ctx, context );
1218 /* dump surface content */
1219 VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 1);
1224 VAStatus vaSyncSurface (
1226 VASurfaceID render_target
1230 VADriverContextP ctx;
1235 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1236 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1241 VAStatus vaQuerySurfaceStatus (
1243 VASurfaceID render_target,
1244 VASurfaceStatus *status /* out */
1248 VADriverContextP ctx;
1252 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1254 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1259 VAStatus vaQuerySurfaceError (
1261 VASurfaceID surface,
1262 VAStatus error_status,
1263 void **error_info /*out*/
1267 VADriverContextP ctx;
1271 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1273 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1278 /* Get maximum number of image formats supported by the implementation */
1279 int vaMaxNumImageFormats (
1283 if (!vaDisplayIsValid(dpy))
1286 return CTX(dpy)->max_image_formats;
1289 VAStatus vaQueryImageFormats (
1291 VAImageFormat *format_list, /* out */
1292 int *num_formats /* out */
1295 VADriverContextP ctx;
1299 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1303 * The width and height fields returned in the VAImage structure may get
1304 * enlarged for some YUV formats. The size of the data buffer that needs
1305 * to be allocated will be given in the "data_size" field in VAImage.
1306 * Image data is not allocated by this function. The client should
1307 * allocate the memory and fill in the VAImage structure's data field
1308 * after looking at "data_size" returned from the library.
1310 VAStatus vaCreateImage (
1312 VAImageFormat *format,
1315 VAImage *image /* out */
1318 VADriverContextP ctx;
1322 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1326 * Should call DestroyImage before destroying the surface it is bound to
1328 VAStatus vaDestroyImage (
1333 VADriverContextP ctx;
1337 return ctx->vtable->vaDestroyImage ( ctx, image);
1340 VAStatus vaSetImagePalette (
1343 unsigned char *palette
1346 VADriverContextP ctx;
1350 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1354 * Retrieve surface data into a VAImage
1355 * Image must be in a format supported by the implementation
1357 VAStatus vaGetImage (
1359 VASurfaceID surface,
1360 int x, /* coordinates of the upper left source pixel */
1362 unsigned int width, /* width and height of the region */
1363 unsigned int height,
1367 VADriverContextP ctx;
1371 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1375 * Copy data from a VAImage to a surface
1376 * Image must be in a format supported by the implementation
1378 VAStatus vaPutImage (
1380 VASurfaceID surface,
1384 unsigned int src_width,
1385 unsigned int src_height,
1388 unsigned int dest_width,
1389 unsigned int dest_height
1392 VADriverContextP ctx;
1396 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1400 * Derive an VAImage from an existing surface.
1401 * This interface will derive a VAImage and corresponding image buffer from
1402 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1403 * direct CPU access. This operation is only possible on implementations with
1404 * direct rendering capabilities and internal surface formats that can be
1405 * represented with a VAImage. When the operation is not possible this interface
1406 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1407 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1410 * Implementations should only return success when the resulting image buffer
1411 * would be useable with vaMap/Unmap.
1413 * When directly accessing a surface special care must be taken to insure
1414 * proper synchronization with the graphics hardware. Clients should call
1415 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1416 * rendering or currently being displayed by an overlay.
1418 * Additionally nothing about the contents of a surface should be assumed
1419 * following a vaPutSurface. Implementations are free to modify the surface for
1420 * scaling or subpicture blending within a call to vaPutImage.
1422 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1423 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1424 * vaGetImage with other surfaces is supported.
1426 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1427 * image and image buffer structures will be destroyed; however, the underlying
1428 * surface will remain unchanged until freed with vaDestroySurfaces.
1430 VAStatus vaDeriveImage (
1432 VASurfaceID surface,
1433 VAImage *image /* out */
1436 VADriverContextP ctx;
1440 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1444 /* Get maximum number of subpicture formats supported by the implementation */
1445 int vaMaxNumSubpictureFormats (
1449 if (!vaDisplayIsValid(dpy))
1452 return CTX(dpy)->max_subpic_formats;
1456 * Query supported subpicture formats
1457 * The caller must provide a "format_list" array that can hold at
1458 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1459 * for each format to indicate additional capabilities for that format. The actual
1460 * number of formats returned in "format_list" is returned in "num_formats".
1462 VAStatus vaQuerySubpictureFormats (
1464 VAImageFormat *format_list, /* out */
1465 unsigned int *flags, /* out */
1466 unsigned int *num_formats /* out */
1469 VADriverContextP ctx;
1474 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1478 * Subpictures are created with an image associated.
1480 VAStatus vaCreateSubpicture (
1483 VASubpictureID *subpicture /* out */
1486 VADriverContextP ctx;
1490 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1494 * Destroy the subpicture before destroying the image it is assocated to
1496 VAStatus vaDestroySubpicture (
1498 VASubpictureID subpicture
1501 VADriverContextP ctx;
1505 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1508 VAStatus vaSetSubpictureImage (
1510 VASubpictureID subpicture,
1514 VADriverContextP ctx;
1518 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1523 * If chromakey is enabled, then the area where the source value falls within
1524 * the chromakey [min, max] range is transparent
1526 VAStatus vaSetSubpictureChromakey (
1528 VASubpictureID subpicture,
1529 unsigned int chromakey_min,
1530 unsigned int chromakey_max,
1531 unsigned int chromakey_mask
1534 VADriverContextP ctx;
1538 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1543 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1544 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1545 * the overall alpha is per-pixel alpha multiplied by the global alpha
1547 VAStatus vaSetSubpictureGlobalAlpha (
1549 VASubpictureID subpicture,
1553 VADriverContextP ctx;
1557 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1561 vaAssociateSubpicture associates the subpicture with the target_surface.
1562 It defines the region mapping between the subpicture and the target
1563 surface through source and destination rectangles (with the same width and height).
1564 Both will be displayed at the next call to vaPutSurface. Additional
1565 associations before the call to vaPutSurface simply overrides the association.
1567 VAStatus vaAssociateSubpicture (
1569 VASubpictureID subpicture,
1570 VASurfaceID *target_surfaces,
1572 short src_x, /* upper left offset in subpicture */
1574 unsigned short src_width,
1575 unsigned short src_height,
1576 short dest_x, /* upper left offset in surface */
1578 unsigned short dest_width,
1579 unsigned short dest_height,
1581 * whether to enable chroma-keying or global-alpha
1582 * see VA_SUBPICTURE_XXX values
1587 VADriverContextP ctx;
1591 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 );
1595 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1597 VAStatus vaDeassociateSubpicture (
1599 VASubpictureID subpicture,
1600 VASurfaceID *target_surfaces,
1604 VADriverContextP ctx;
1608 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1612 /* Get maximum number of display attributes supported by the implementation */
1613 int vaMaxNumDisplayAttributes (
1619 if (!vaDisplayIsValid(dpy))
1622 tmp = CTX(dpy)->max_display_attributes;
1624 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1630 * Query display attributes
1631 * The caller must provide a "attr_list" array that can hold at
1632 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1633 * returned in "attr_list" is returned in "num_attributes".
1635 VAStatus vaQueryDisplayAttributes (
1637 VADisplayAttribute *attr_list, /* out */
1638 int *num_attributes /* out */
1641 VADriverContextP ctx;
1646 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1648 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1655 * Get display attributes
1656 * This function returns the current attribute values in "attr_list".
1657 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1658 * from vaQueryDisplayAttributes() can have their values retrieved.
1660 VAStatus vaGetDisplayAttributes (
1662 VADisplayAttribute *attr_list, /* in/out */
1666 VADriverContextP ctx;
1671 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1673 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1679 * Set display attributes
1680 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1681 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1682 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1684 VAStatus vaSetDisplayAttributes (
1686 VADisplayAttribute *attr_list,
1690 VADriverContextP ctx;
1695 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1696 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1701 VAStatus vaLockSurface(VADisplay dpy,
1702 VASurfaceID surface,
1703 unsigned int *fourcc, /* following are output argument */
1704 unsigned int *luma_stride,
1705 unsigned int *chroma_u_stride,
1706 unsigned int *chroma_v_stride,
1707 unsigned int *luma_offset,
1708 unsigned int *chroma_u_offset,
1709 unsigned int *chroma_v_offset,
1710 unsigned int *buffer_name,
1714 VADriverContextP ctx;
1718 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);
1722 VAStatus vaUnlockSurface(VADisplay dpy,
1726 VADriverContextP ctx;
1730 return ctx->vtable->vaUnlockSurface( ctx, surface );
1733 /* Video Processing */
1734 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1735 CHECK_DISPLAY(dpy); \
1738 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1741 #define VA_VPP_INVOKE(dpy, func, args) do { \
1742 if (!ctx->vtable_vpp->va##func) \
1743 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1744 status = ctx->vtable_vpp->va##func args; \
1748 vaQueryVideoProcFilters(
1750 VAContextID context,
1751 VAProcFilterType *filters,
1752 unsigned int *num_filters
1755 VADriverContextP ctx;
1758 VA_VPP_INIT_CONTEXT(ctx, dpy);
1761 QueryVideoProcFilters,
1762 (ctx, context, filters, num_filters)
1768 vaQueryVideoProcFilterCaps(
1770 VAContextID context,
1771 VAProcFilterType type,
1773 unsigned int *num_filter_caps
1776 VADriverContextP ctx;
1779 VA_VPP_INIT_CONTEXT(ctx, dpy);
1782 QueryVideoProcFilterCaps,
1783 (ctx, context, type, filter_caps, num_filter_caps)
1789 vaQueryVideoProcPipelineCaps(
1791 VAContextID context,
1792 VABufferID *filters,
1793 unsigned int num_filters,
1794 VAProcPipelineCaps *pipeline_caps
1797 VADriverContextP ctx;
1800 VA_VPP_INIT_CONTEXT(ctx, dpy);
1803 QueryVideoProcPipelineCaps,
1804 (ctx, context, filters, num_filters, pipeline_caps)