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 },
259 for (i = 0; compatible_versions[i].major >= 0; i++) {
260 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
261 compatible_versions[i].major,
262 compatible_versions[i].minor)) {
263 init_func = (VADriverInit)dlsym(handle, init_func_s);
265 va_infoMessage("Found init function %s\n", init_func_s);
271 if (compatible_versions[i].major < 0) {
272 va_errorMessage("%s has no function %s\n",
273 driver_path, init_func_s);
276 struct VADriverVTable *vtable = ctx->vtable;
277 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
279 vaStatus = VA_STATUS_SUCCESS;
281 vtable = calloc(1, sizeof(*vtable));
283 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
285 ctx->vtable = vtable;
288 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
290 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
292 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
294 ctx->vtable_vpp = vtable_vpp;
296 if (init_func && VA_STATUS_SUCCESS == vaStatus)
297 vaStatus = (*init_func)(ctx);
299 if (VA_STATUS_SUCCESS == vaStatus) {
300 CHECK_MAXIMUM(vaStatus, ctx, profiles);
301 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
302 CHECK_MAXIMUM(vaStatus, ctx, attributes);
303 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
304 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
305 CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
306 CHECK_STRING(vaStatus, ctx, vendor);
307 CHECK_VTABLE(vaStatus, ctx, Terminate);
308 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
309 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
310 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
311 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
312 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
313 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
314 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
315 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
316 CHECK_VTABLE(vaStatus, ctx, CreateContext);
317 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
318 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
319 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
320 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
321 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
322 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
323 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
324 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
325 CHECK_VTABLE(vaStatus, ctx, EndPicture);
326 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
327 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
328 CHECK_VTABLE(vaStatus, ctx, PutSurface);
329 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
330 CHECK_VTABLE(vaStatus, ctx, CreateImage);
331 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
332 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
333 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
334 CHECK_VTABLE(vaStatus, ctx, GetImage);
335 CHECK_VTABLE(vaStatus, ctx, PutImage);
336 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
337 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
338 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
339 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
340 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
341 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
342 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
343 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
344 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
345 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
346 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
348 if (VA_STATUS_SUCCESS != vaStatus) {
349 va_errorMessage("%s init failed\n", driver_path);
352 if (VA_STATUS_SUCCESS == vaStatus)
353 ctx->handle = handle;
360 driver_dir = strtok_r(NULL, ":", &saveptr);
368 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
370 VADriverContextP ctx;
371 if (!vaDisplayIsValid(dpy))
375 if (NULL == ctx->handle)
378 return (VAPrivFunc) dlsym(ctx->handle, func);
383 * Returns a short english description of error_status
385 const char *vaErrorStr(VAStatus error_status)
387 switch(error_status) {
388 case VA_STATUS_SUCCESS:
389 return "success (no error)";
390 case VA_STATUS_ERROR_OPERATION_FAILED:
391 return "operation failed";
392 case VA_STATUS_ERROR_ALLOCATION_FAILED:
393 return "resource allocation failed";
394 case VA_STATUS_ERROR_INVALID_DISPLAY:
395 return "invalid VADisplay";
396 case VA_STATUS_ERROR_INVALID_CONFIG:
397 return "invalid VAConfigID";
398 case VA_STATUS_ERROR_INVALID_CONTEXT:
399 return "invalid VAContextID";
400 case VA_STATUS_ERROR_INVALID_SURFACE:
401 return "invalid VASurfaceID";
402 case VA_STATUS_ERROR_INVALID_BUFFER:
403 return "invalid VABufferID";
404 case VA_STATUS_ERROR_INVALID_IMAGE:
405 return "invalid VAImageID";
406 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
407 return "invalid VASubpictureID";
408 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
409 return "attribute not supported";
410 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
411 return "list argument exceeds maximum number";
412 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
413 return "the requested VAProfile is not supported";
414 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
415 return "the requested VAEntryPoint is not supported";
416 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
417 return "the requested RT Format is not supported";
418 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
419 return "the requested VABufferType is not supported";
420 case VA_STATUS_ERROR_SURFACE_BUSY:
421 return "surface is in use";
422 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
423 return "flag not supported";
424 case VA_STATUS_ERROR_INVALID_PARAMETER:
425 return "invalid parameter";
426 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
427 return "resolution not supported";
428 case VA_STATUS_ERROR_UNIMPLEMENTED:
429 return "the requested function is not implemented";
430 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
431 return "surface is in displaying (may by overlay)" ;
432 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
433 return "invalid VAImageFormat";
434 case VA_STATUS_ERROR_INVALID_VALUE:
435 return "an invalid/unsupported value was supplied";
436 case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
437 return "the requested filter is not supported";
438 case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
439 return "an invalid filter chain was supplied";
440 case VA_STATUS_ERROR_UNKNOWN:
441 return "unknown libva error";
443 return "unknown libva error / description missing";
446 const static char *prefer_driver_list[4] = {
453 VAStatus vaSetDriverName(
458 VADriverContextP ctx;
459 VAStatus vaStatus = VA_STATUS_SUCCESS;
460 char *override_driver_name = NULL;
464 if (geteuid() != getuid()) {
465 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
466 va_errorMessage("no permission to vaSetDriverName\n");
470 if (strlen(driver_name) == 0 || strlen(driver_name) >=256) {
471 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
472 va_errorMessage("vaSetDriverName returns %s\n",
473 vaErrorStr(vaStatus));
478 for (i = 0; i < sizeof(prefer_driver_list) / sizeof(char *); i++) {
479 if (strlen(prefer_driver_list[i]) != strlen(driver_name))
481 if (!strncmp(prefer_driver_list[i], driver_name, strlen(driver_name))) {
488 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
489 va_errorMessage("vaSetDriverName returns %s. Incorrect parameter\n",
490 vaErrorStr(vaStatus));
494 override_driver_name = strdup(driver_name);
496 if (!override_driver_name) {
497 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
498 va_errorMessage("vaSetDriverName returns %s. Out of Memory\n",
499 vaErrorStr(vaStatus));
503 ctx->override_driver_name = override_driver_name;
504 return VA_STATUS_SUCCESS;
507 VAStatus vaInitialize (
509 int *major_version, /* out */
510 int *minor_version /* out */
513 const char *driver_name_env = NULL;
514 char *driver_name = NULL;
516 VADriverContextP ctx;
526 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
528 vaStatus = va_getDriverName(dpy, &driver_name);
530 if (!ctx->override_driver_name) {
531 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
533 driver_name_env = getenv("LIBVA_DRIVER_NAME");
534 } else if (vaStatus == VA_STATUS_SUCCESS) {
538 driver_name = strdup(ctx->override_driver_name);
540 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
541 va_errorMessage("vaInitialize() failed with %s, out of memory\n",
542 vaErrorStr(vaStatus));
545 va_infoMessage("User requested driver '%s'\n", driver_name);
548 if (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;
743 VAStatus vaStatus = VA_STATUS_SUCCESS;
748 vaStatus = ctx->vtable->vaDestroyConfig ( ctx, config_id );
750 VA_TRACE_ALL(va_TraceDestroyConfig, dpy, config_id);
755 VAStatus vaQueryConfigAttributes (
757 VAConfigID config_id,
758 VAProfile *profile, /* out */
759 VAEntrypoint *entrypoint, /* out */
760 VAConfigAttrib *attrib_list,/* out */
761 int *num_attribs /* out */
764 VADriverContextP ctx;
768 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
771 /* XXX: this is a slow implementation that will be removed */
773 va_impl_query_surface_attributes(
774 VADriverContextP ctx,
776 VASurfaceAttrib *out_attribs,
777 unsigned int *out_num_attribs_ptr
780 VASurfaceAttrib *attribs = NULL;
781 unsigned int num_attribs, n;
782 VASurfaceAttrib *out_attrib;
783 unsigned int out_num_attribs;
784 VAImageFormat *image_formats = NULL;
785 int num_image_formats, i;
788 /* List of surface attributes to query */
789 struct va_surface_attrib_map {
790 VASurfaceAttribType type;
791 VAGenericValueType value_type;
793 static const struct va_surface_attrib_map attribs_map[] = {
794 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
795 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
796 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
797 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
798 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
799 { VASurfaceAttribNone, }
802 if (!out_attribs || !out_num_attribs_ptr)
803 return VA_STATUS_ERROR_INVALID_PARAMETER;
804 if (!ctx->vtable->vaGetSurfaceAttributes)
805 return VA_STATUS_ERROR_UNIMPLEMENTED;
807 num_image_formats = ctx->max_image_formats;
808 image_formats = malloc(num_image_formats * sizeof(*image_formats));
809 if (!image_formats) {
810 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
814 va_status = ctx->vtable->vaQueryImageFormats(
815 ctx, image_formats, &num_image_formats);
816 if (va_status != VA_STATUS_SUCCESS)
819 num_attribs = VASurfaceAttribCount + num_image_formats;
820 attribs = malloc(num_attribs * sizeof(*attribs));
822 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
826 /* Initialize with base surface attributes, except pixel-formats */
827 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
828 VASurfaceAttrib * const attrib = &attribs[n];
829 attrib->type = attribs_map[n].type;
830 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
831 attrib->value.type = attribs_map[n].value_type;
834 /* Append image formats */
835 for (i = 0; i < num_image_formats; i++) {
836 VASurfaceAttrib * const attrib = &attribs[n];
837 attrib->type = VASurfaceAttribPixelFormat;
838 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
839 attrib->value.type = VAGenericValueTypeInteger;
840 attrib->value.value.i = image_formats[i].fourcc;
841 if (++n == num_attribs) {
842 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
848 va_status = ctx->vtable->vaGetSurfaceAttributes(
849 ctx, config, attribs, num_attribs);
850 if (va_status != VA_STATUS_SUCCESS)
853 /* Remove invalid entries */
855 for (n = 0; n < num_attribs; n++) {
856 VASurfaceAttrib * const attrib = &attribs[n];
858 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
861 // Accept all surface attributes that are not pixel-formats
862 if (attrib->type != VASurfaceAttribPixelFormat) {
867 // Drop invalid pixel-format attribute
868 if (!attrib->value.value.i) {
869 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
873 // Check for duplicates
874 int is_duplicate = 0;
875 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
876 const VASurfaceAttrib * const prev_attrib = &attribs[i];
877 if (prev_attrib->type != VASurfaceAttribPixelFormat)
879 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
882 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
887 if (*out_num_attribs_ptr < out_num_attribs) {
888 *out_num_attribs_ptr = out_num_attribs;
889 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
893 out_attrib = out_attribs;
894 for (n = 0; n < num_attribs; n++) {
895 const VASurfaceAttrib * const attrib = &attribs[n];
896 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
898 *out_attrib++ = *attrib;
908 vaQuerySurfaceAttributes(
911 VASurfaceAttrib *attrib_list,
912 unsigned int *num_attribs
915 VADriverContextP ctx;
921 return VA_STATUS_ERROR_INVALID_DISPLAY;
923 if (!ctx->vtable->vaQuerySurfaceAttributes)
924 vaStatus = va_impl_query_surface_attributes(ctx, config,
925 attrib_list, num_attribs);
927 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
928 attrib_list, num_attribs);
930 VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs);
941 VASurfaceID *surfaces,
942 unsigned int num_surfaces,
943 VASurfaceAttrib *attrib_list,
944 unsigned int num_attribs
947 VADriverContextP ctx;
953 return VA_STATUS_ERROR_INVALID_DISPLAY;
955 if (ctx->vtable->vaCreateSurfaces2)
956 vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
957 surfaces, num_surfaces,
958 attrib_list, num_attribs);
959 else if (attrib_list && num_attribs > 0)
960 vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
962 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
963 num_surfaces, surfaces);
964 VA_TRACE_LOG(va_TraceCreateSurfaces,
965 dpy, width, height, format, num_surfaces, surfaces,
966 attrib_list, num_attribs);
972 VAStatus vaDestroySurfaces (
974 VASurfaceID *surface_list,
978 VADriverContextP ctx;
984 VA_TRACE_LOG(va_TraceDestroySurfaces,
985 dpy, surface_list, num_surfaces);
987 vaStatus = ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
992 VAStatus vaCreateContext (
994 VAConfigID config_id,
998 VASurfaceID *render_targets,
999 int num_render_targets,
1000 VAContextID *context /* out */
1003 VADriverContextP ctx;
1009 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
1010 flag, render_targets, num_render_targets, context );
1012 /* keep current encode/decode resoluton */
1013 VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
1018 VAStatus vaDestroyContext (
1023 VADriverContextP ctx;
1029 vaStatus = ctx->vtable->vaDestroyContext( ctx, context );
1031 VA_TRACE_ALL(va_TraceDestroyContext, dpy, context);
1036 VAStatus vaCreateBuffer (
1038 VAContextID context, /* in */
1039 VABufferType type, /* in */
1040 unsigned int size, /* in */
1041 unsigned int num_elements, /* in */
1042 void *data, /* in */
1043 VABufferID *buf_id /* out */
1046 VADriverContextP ctx;
1052 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
1054 vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
1056 VA_TRACE_LOG(va_TraceCreateBuffer,
1057 dpy, context, type, size, num_elements, data, buf_id);
1062 VAStatus vaBufferSetNumElements (
1064 VABufferID buf_id, /* in */
1065 unsigned int num_elements /* in */
1068 VADriverContextP ctx;
1072 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1074 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
1078 VAStatus vaMapBuffer (
1080 VABufferID buf_id, /* in */
1081 void **pbuf /* out */
1084 VADriverContextP ctx;
1090 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
1092 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
1094 VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf);
1099 VAStatus vaUnmapBuffer (
1101 VABufferID buf_id /* in */
1104 VADriverContextP ctx;
1108 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1110 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
1113 VAStatus vaDestroyBuffer (
1115 VABufferID buffer_id
1118 VADriverContextP ctx;
1122 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1124 VA_TRACE_LOG(va_TraceDestroyBuffer,
1127 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1130 VAStatus vaBufferInfo (
1132 VAContextID context, /* in */
1133 VABufferID buf_id, /* in */
1134 VABufferType *type, /* out */
1135 unsigned int *size, /* out */
1136 unsigned int *num_elements /* out */
1139 VADriverContextP ctx;
1144 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1146 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1149 /* Locks buffer for external API usage */
1151 vaAcquireBufferHandle(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info)
1153 VADriverContextP ctx;
1158 if (!ctx->vtable->vaAcquireBufferHandle)
1159 return VA_STATUS_ERROR_UNIMPLEMENTED;
1160 return ctx->vtable->vaAcquireBufferHandle(ctx, buf_id, buf_info);
1163 /* Unlocks buffer after usage from external API */
1165 vaReleaseBufferHandle(VADisplay dpy, VABufferID buf_id)
1167 VADriverContextP ctx;
1172 if (!ctx->vtable->vaReleaseBufferHandle)
1173 return VA_STATUS_ERROR_UNIMPLEMENTED;
1174 return ctx->vtable->vaReleaseBufferHandle(ctx, buf_id);
1177 VAStatus vaBeginPicture (
1179 VAContextID context,
1180 VASurfaceID render_target
1183 VADriverContextP ctx;
1189 VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target);
1190 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1192 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1197 VAStatus vaRenderPicture (
1199 VAContextID context,
1200 VABufferID *buffers,
1204 VADriverContextP ctx;
1209 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1210 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1212 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1215 VAStatus vaEndPicture (
1220 VAStatus va_status = VA_STATUS_SUCCESS;
1221 VADriverContextP ctx;
1226 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1228 va_status = ctx->vtable->vaEndPicture( ctx, context );
1230 /* dump surface content */
1231 VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 1);
1236 VAStatus vaSyncSurface (
1238 VASurfaceID render_target
1242 VADriverContextP ctx;
1247 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1248 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1253 VAStatus vaQuerySurfaceStatus (
1255 VASurfaceID render_target,
1256 VASurfaceStatus *status /* out */
1260 VADriverContextP ctx;
1264 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1266 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1271 VAStatus vaQuerySurfaceError (
1273 VASurfaceID surface,
1274 VAStatus error_status,
1275 void **error_info /*out*/
1279 VADriverContextP ctx;
1283 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1285 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1290 /* Get maximum number of image formats supported by the implementation */
1291 int vaMaxNumImageFormats (
1295 if (!vaDisplayIsValid(dpy))
1298 return CTX(dpy)->max_image_formats;
1301 VAStatus vaQueryImageFormats (
1303 VAImageFormat *format_list, /* out */
1304 int *num_formats /* out */
1307 VADriverContextP ctx;
1311 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1315 * The width and height fields returned in the VAImage structure may get
1316 * enlarged for some YUV formats. The size of the data buffer that needs
1317 * to be allocated will be given in the "data_size" field in VAImage.
1318 * Image data is not allocated by this function. The client should
1319 * allocate the memory and fill in the VAImage structure's data field
1320 * after looking at "data_size" returned from the library.
1322 VAStatus vaCreateImage (
1324 VAImageFormat *format,
1327 VAImage *image /* out */
1330 VADriverContextP ctx;
1334 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1338 * Should call DestroyImage before destroying the surface it is bound to
1340 VAStatus vaDestroyImage (
1345 VADriverContextP ctx;
1349 return ctx->vtable->vaDestroyImage ( ctx, image);
1352 VAStatus vaSetImagePalette (
1355 unsigned char *palette
1358 VADriverContextP ctx;
1362 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1366 * Retrieve surface data into a VAImage
1367 * Image must be in a format supported by the implementation
1369 VAStatus vaGetImage (
1371 VASurfaceID surface,
1372 int x, /* coordinates of the upper left source pixel */
1374 unsigned int width, /* width and height of the region */
1375 unsigned int height,
1379 VADriverContextP ctx;
1383 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1387 * Copy data from a VAImage to a surface
1388 * Image must be in a format supported by the implementation
1390 VAStatus vaPutImage (
1392 VASurfaceID surface,
1396 unsigned int src_width,
1397 unsigned int src_height,
1400 unsigned int dest_width,
1401 unsigned int dest_height
1404 VADriverContextP ctx;
1408 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1412 * Derive an VAImage from an existing surface.
1413 * This interface will derive a VAImage and corresponding image buffer from
1414 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1415 * direct CPU access. This operation is only possible on implementations with
1416 * direct rendering capabilities and internal surface formats that can be
1417 * represented with a VAImage. When the operation is not possible this interface
1418 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1419 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1422 * Implementations should only return success when the resulting image buffer
1423 * would be useable with vaMap/Unmap.
1425 * When directly accessing a surface special care must be taken to insure
1426 * proper synchronization with the graphics hardware. Clients should call
1427 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1428 * rendering or currently being displayed by an overlay.
1430 * Additionally nothing about the contents of a surface should be assumed
1431 * following a vaPutSurface. Implementations are free to modify the surface for
1432 * scaling or subpicture blending within a call to vaPutImage.
1434 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1435 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1436 * vaGetImage with other surfaces is supported.
1438 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1439 * image and image buffer structures will be destroyed; however, the underlying
1440 * surface will remain unchanged until freed with vaDestroySurfaces.
1442 VAStatus vaDeriveImage (
1444 VASurfaceID surface,
1445 VAImage *image /* out */
1448 VADriverContextP ctx;
1452 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1456 /* Get maximum number of subpicture formats supported by the implementation */
1457 int vaMaxNumSubpictureFormats (
1461 if (!vaDisplayIsValid(dpy))
1464 return CTX(dpy)->max_subpic_formats;
1468 * Query supported subpicture formats
1469 * The caller must provide a "format_list" array that can hold at
1470 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1471 * for each format to indicate additional capabilities for that format. The actual
1472 * number of formats returned in "format_list" is returned in "num_formats".
1474 VAStatus vaQuerySubpictureFormats (
1476 VAImageFormat *format_list, /* out */
1477 unsigned int *flags, /* out */
1478 unsigned int *num_formats /* out */
1481 VADriverContextP ctx;
1486 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1490 * Subpictures are created with an image associated.
1492 VAStatus vaCreateSubpicture (
1495 VASubpictureID *subpicture /* out */
1498 VADriverContextP ctx;
1502 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1506 * Destroy the subpicture before destroying the image it is assocated to
1508 VAStatus vaDestroySubpicture (
1510 VASubpictureID subpicture
1513 VADriverContextP ctx;
1517 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1520 VAStatus vaSetSubpictureImage (
1522 VASubpictureID subpicture,
1526 VADriverContextP ctx;
1530 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1535 * If chromakey is enabled, then the area where the source value falls within
1536 * the chromakey [min, max] range is transparent
1538 VAStatus vaSetSubpictureChromakey (
1540 VASubpictureID subpicture,
1541 unsigned int chromakey_min,
1542 unsigned int chromakey_max,
1543 unsigned int chromakey_mask
1546 VADriverContextP ctx;
1550 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1555 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1556 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1557 * the overall alpha is per-pixel alpha multiplied by the global alpha
1559 VAStatus vaSetSubpictureGlobalAlpha (
1561 VASubpictureID subpicture,
1565 VADriverContextP ctx;
1569 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1573 vaAssociateSubpicture associates the subpicture with the target_surface.
1574 It defines the region mapping between the subpicture and the target
1575 surface through source and destination rectangles (with the same width and height).
1576 Both will be displayed at the next call to vaPutSurface. Additional
1577 associations before the call to vaPutSurface simply overrides the association.
1579 VAStatus vaAssociateSubpicture (
1581 VASubpictureID subpicture,
1582 VASurfaceID *target_surfaces,
1584 short src_x, /* upper left offset in subpicture */
1586 unsigned short src_width,
1587 unsigned short src_height,
1588 short dest_x, /* upper left offset in surface */
1590 unsigned short dest_width,
1591 unsigned short dest_height,
1593 * whether to enable chroma-keying or global-alpha
1594 * see VA_SUBPICTURE_XXX values
1599 VADriverContextP ctx;
1603 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 );
1607 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1609 VAStatus vaDeassociateSubpicture (
1611 VASubpictureID subpicture,
1612 VASurfaceID *target_surfaces,
1616 VADriverContextP ctx;
1620 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1624 /* Get maximum number of display attributes supported by the implementation */
1625 int vaMaxNumDisplayAttributes (
1631 if (!vaDisplayIsValid(dpy))
1634 tmp = CTX(dpy)->max_display_attributes;
1636 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1642 * Query display attributes
1643 * The caller must provide a "attr_list" array that can hold at
1644 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1645 * returned in "attr_list" is returned in "num_attributes".
1647 VAStatus vaQueryDisplayAttributes (
1649 VADisplayAttribute *attr_list, /* out */
1650 int *num_attributes /* out */
1653 VADriverContextP ctx;
1658 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1660 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1667 * Get display attributes
1668 * This function returns the current attribute values in "attr_list".
1669 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1670 * from vaQueryDisplayAttributes() can have their values retrieved.
1672 VAStatus vaGetDisplayAttributes (
1674 VADisplayAttribute *attr_list, /* in/out */
1678 VADriverContextP ctx;
1683 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1685 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1691 * Set display attributes
1692 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1693 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1694 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1696 VAStatus vaSetDisplayAttributes (
1698 VADisplayAttribute *attr_list,
1702 VADriverContextP ctx;
1707 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1708 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1713 VAStatus vaLockSurface(VADisplay dpy,
1714 VASurfaceID surface,
1715 unsigned int *fourcc, /* following are output argument */
1716 unsigned int *luma_stride,
1717 unsigned int *chroma_u_stride,
1718 unsigned int *chroma_v_stride,
1719 unsigned int *luma_offset,
1720 unsigned int *chroma_u_offset,
1721 unsigned int *chroma_v_offset,
1722 unsigned int *buffer_name,
1726 VADriverContextP ctx;
1730 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);
1734 VAStatus vaUnlockSurface(VADisplay dpy,
1738 VADriverContextP ctx;
1742 return ctx->vtable->vaUnlockSurface( ctx, surface );
1745 /* Video Processing */
1746 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1747 CHECK_DISPLAY(dpy); \
1750 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1753 #define VA_VPP_INVOKE(dpy, func, args) do { \
1754 if (!ctx->vtable_vpp->va##func) \
1755 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1756 status = ctx->vtable_vpp->va##func args; \
1760 vaQueryVideoProcFilters(
1762 VAContextID context,
1763 VAProcFilterType *filters,
1764 unsigned int *num_filters
1767 VADriverContextP ctx;
1770 VA_VPP_INIT_CONTEXT(ctx, dpy);
1773 QueryVideoProcFilters,
1774 (ctx, context, filters, num_filters)
1780 vaQueryVideoProcFilterCaps(
1782 VAContextID context,
1783 VAProcFilterType type,
1785 unsigned int *num_filter_caps
1788 VADriverContextP ctx;
1791 VA_VPP_INIT_CONTEXT(ctx, dpy);
1794 QueryVideoProcFilterCaps,
1795 (ctx, context, type, filter_caps, num_filter_caps)
1801 vaQueryVideoProcPipelineCaps(
1803 VAContextID context,
1804 VABufferID *filters,
1805 unsigned int num_filters,
1806 VAProcPipelineCaps *pipeline_caps
1809 VADriverContextP ctx;
1812 VA_VPP_INIT_CONTEXT(ctx, dpy);
1815 QueryVideoProcPipelineCaps,
1816 (ctx, context, filters, num_filters, pipeline_caps)