1 /*
2 * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
3 *
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:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
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.
23 */
24
25 #define _GNU_SOURCE 1
26 #include "sysdeps.h"
27 #include "va.h"
28 #include "va_backend.h"
29 #include "va_backend_vpp.h"
30 #include "va_trace.h"
31 #include "va_fool.h"
32
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <dlfcn.h>
39 #include <unistd.h>
40
41 #define DRIVER_EXTENSION "_drv_video.so"
42
43 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
44 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
45
46 #define ASSERT assert
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;
50
51
52 /*
53 * read a config "env" for libva.conf or from environment setting
54 * liva.conf has higher priority
55 * return 0: the "env" is set, and the value is copied into env_value
56 * 1: the env is not set
57 */
va_parseConfig(char * env,char * env_value)58 int va_parseConfig(char *env, char *env_value)
59 {
60 char *token, *value, *saveptr;
61 char oneline[1024];
62 FILE *fp=NULL;
63
64 if (env == NULL)
65 return 1;
66
67 fp = fopen("/etc/libva.conf", "r");
68 while (fp && (fgets(oneline, 1024, fp) != NULL)) {
69 if (strlen(oneline) == 1)
70 continue;
71 token = strtok_r(oneline, "=\n", &saveptr);
72 value = strtok_r(NULL, "=\n", &saveptr);
73
74 if (NULL == token || NULL == value)
75 continue;
76
77 if (strcmp(token, env) == 0) {
78 if (env_value)
79 strncpy(env_value,value, 1024);
80
81 fclose(fp);
82
83 return 0;
84 }
85 }
86 if (fp)
87 fclose(fp);
88
89 /* no setting in config file, use env setting */
90 value = getenv(env);
91 if (value) {
92 if (env_value)
93 strncpy(env_value, value, 1024);
94 return 0;
95 }
96
97 return 1;
98 }
99
vaDisplayIsValid(VADisplay dpy)100 int vaDisplayIsValid(VADisplay dpy)
101 {
102 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
103 return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext);
104 }
105
va_errorMessage(const char * msg,...)106 void va_errorMessage(const char *msg, ...)
107 {
108 char buf[512], *dynbuf;
109 va_list args;
110 int n, len;
111
112 va_start(args, msg);
113 len = vsnprintf(buf, sizeof(buf), msg, args);
114 va_end(args);
115
116 if (len >= (int)sizeof(buf)) {
117 dynbuf = malloc(len + 1);
118 if (!dynbuf)
119 return;
120 va_start(args, msg);
121 n = vsnprintf(dynbuf, len + 1, msg, args);
122 va_end(args);
123 if (n == len)
124 va_log_error(dynbuf);
125 free(dynbuf);
126 }
127 else if (len > 0)
128 va_log_error(buf);
129 }
130
va_infoMessage(const char * msg,...)131 void va_infoMessage(const char *msg, ...)
132 {
133 char buf[512], *dynbuf;
134 va_list args;
135 int n, len;
136
137 va_start(args, msg);
138 len = vsnprintf(buf, sizeof(buf), msg, args);
139 va_end(args);
140
141 if (len >= (int)sizeof(buf)) {
142 dynbuf = malloc(len + 1);
143 if (!dynbuf)
144 return;
145 va_start(args, msg);
146 n = vsnprintf(dynbuf, len + 1, msg, args);
147 va_end(args);
148 if (n == len)
149 va_log_info(dynbuf);
150 free(dynbuf);
151 }
152 else if (len > 0)
153 va_log_info(buf);
154 }
155
va_checkVtable(void * ptr,char * function)156 static bool va_checkVtable(void *ptr, char *function)
157 {
158 if (!ptr) {
159 va_errorMessage("No valid vtable entry for va%s\n", function);
160 return false;
161 }
162 return true;
163 }
164
va_checkMaximum(int value,char * variable)165 static bool va_checkMaximum(int value, char *variable)
166 {
167 if (!value) {
168 va_errorMessage("Failed to define max_%s in init\n", variable);
169 return false;
170 }
171 return true;
172 }
173
va_checkString(const char * value,char * variable)174 static bool va_checkString(const char* value, char *variable)
175 {
176 if (!value) {
177 va_errorMessage("Failed to define str_%s in init\n", variable);
178 return false;
179 }
180 return true;
181 }
182
183 static inline int
va_getDriverInitName(char * name,int namelen,int major,int minor)184 va_getDriverInitName(char *name, int namelen, int major, int minor)
185 {
186 int ret = snprintf(name, namelen, "__vaDriverInit_%d_%d", major, minor);
187 return ret > 0 && ret < namelen;
188 }
189
va_getDriverName(VADisplay dpy,char ** driver_name)190 static VAStatus va_getDriverName(VADisplay dpy, char **driver_name)
191 {
192 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
193
194 return pDisplayContext->vaGetDriverName(pDisplayContext, driver_name);
195 }
196
va_openDriver(VADisplay dpy,char * driver_name)197 static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
198 {
199 VADriverContextP ctx = CTX(dpy);
200 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
201 char *search_path = NULL;
202 char *saveptr;
203 char *driver_dir;
204
205 if (geteuid() == getuid())
206 /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
207 search_path = getenv("LIBVA_DRIVERS_PATH");
208 if (!search_path)
209 search_path = VA_DRIVERS_PATH;
210
211 search_path = strdup((const char *)search_path);
212 driver_dir = strtok_r(search_path, ":", &saveptr);
213 while (driver_dir) {
214 void *handle = NULL;
215 char *driver_path = (char *) malloc( strlen(driver_dir) +
216 strlen(driver_name) +
217 strlen(DRIVER_EXTENSION) + 2 );
218 if (!driver_path) {
219 va_errorMessage("%s L%d Out of memory!n",
220 __FUNCTION__, __LINE__);
221 free(search_path);
222 return VA_STATUS_ERROR_ALLOCATION_FAILED;
223 }
224
225 strncpy( driver_path, driver_dir, strlen(driver_dir) + 1);
226 strncat( driver_path, "/", strlen("/") );
227 strncat( driver_path, driver_name, strlen(driver_name) );
228 strncat( driver_path, DRIVER_EXTENSION, strlen(DRIVER_EXTENSION) );
229
230 va_infoMessage("Trying to open %s\n", driver_path);
231 #ifndef ANDROID
232 handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE );
233 #else
234 handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL);
235 #endif
236 if (!handle) {
237 /* Don't give errors for non-existing files */
238 if (0 == access( driver_path, F_OK))
239 va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
240 } else {
241 VADriverInit init_func = NULL;
242 char init_func_s[256];
243 int i;
244
245 static const struct {
246 int major;
247 int minor;
248 } compatible_versions[] = {
249 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
250 { 0, 33 },
251 { 0, 32 },
252 { -1, 0}
253 };
254
255 for (i = 0; compatible_versions[i].major >= 0; i++) {
256 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
257 compatible_versions[i].major,
258 compatible_versions[i].minor)) {
259 init_func = (VADriverInit)dlsym(handle, init_func_s);
260 if (init_func) {
261 va_infoMessage("Found init function %s\n", init_func_s);
262 break;
263 }
264 }
265 }
266
267 if (compatible_versions[i].major < 0) {
268 va_errorMessage("%s has no function %s\n",
269 driver_path, init_func_s);
270 dlclose(handle);
271 } else {
272 struct VADriverVTable *vtable = ctx->vtable;
273 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
274
275 vaStatus = VA_STATUS_SUCCESS;
276 if (!vtable) {
277 vtable = calloc(1, sizeof(*vtable));
278 if (!vtable)
279 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
280 }
281 ctx->vtable = vtable;
282
283 if (!vtable_vpp) {
284 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
285 if (vtable_vpp)
286 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
287 else
288 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
289 }
290 ctx->vtable_vpp = vtable_vpp;
291
292 if (init_func && VA_STATUS_SUCCESS == vaStatus)
293 vaStatus = (*init_func)(ctx);
294
295 if (VA_STATUS_SUCCESS == vaStatus) {
296 CHECK_MAXIMUM(vaStatus, ctx, profiles);
297 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
298 CHECK_MAXIMUM(vaStatus, ctx, attributes);
299 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
300 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
301 CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
302 CHECK_STRING(vaStatus, ctx, vendor);
303 CHECK_VTABLE(vaStatus, ctx, Terminate);
304 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
305 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
306 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
307 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
308 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
309 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
310 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
311 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
312 CHECK_VTABLE(vaStatus, ctx, CreateContext);
313 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
314 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
315 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
316 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
317 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
318 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
319 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
320 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
321 CHECK_VTABLE(vaStatus, ctx, EndPicture);
322 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
323 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
324 CHECK_VTABLE(vaStatus, ctx, PutSurface);
325 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
326 CHECK_VTABLE(vaStatus, ctx, CreateImage);
327 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
328 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
329 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
330 CHECK_VTABLE(vaStatus, ctx, GetImage);
331 CHECK_VTABLE(vaStatus, ctx, PutImage);
332 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
333 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
334 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
335 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
336 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
337 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
338 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
339 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
340 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
341 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
342 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
343 }
344 if (VA_STATUS_SUCCESS != vaStatus) {
345 va_errorMessage("%s init failed\n", driver_path);
346 dlclose(handle);
347 }
348 if (VA_STATUS_SUCCESS == vaStatus)
349 ctx->handle = handle;
350 free(driver_path);
351 break;
352 }
353 }
354 free(driver_path);
355
356 driver_dir = strtok_r(NULL, ":", &saveptr);
357 }
358
359 free(search_path);
360
361 return vaStatus;
362 }
363
vaGetLibFunc(VADisplay dpy,const char * func)364 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
365 {
366 VADriverContextP ctx;
367 if (!vaDisplayIsValid(dpy))
368 return NULL;
369 ctx = CTX(dpy);
370
371 if (NULL == ctx->handle)
372 return NULL;
373
374 return (VAPrivFunc) dlsym(ctx->handle, func);
375 }
376
377
378 /*
379 * Returns a short english description of error_status
380 */
vaErrorStr(VAStatus error_status)381 const char *vaErrorStr(VAStatus error_status)
382 {
383 switch(error_status) {
384 case VA_STATUS_SUCCESS:
385 return "success (no error)";
386 case VA_STATUS_ERROR_OPERATION_FAILED:
387 return "operation failed";
388 case VA_STATUS_ERROR_ALLOCATION_FAILED:
389 return "resource allocation failed";
390 case VA_STATUS_ERROR_INVALID_DISPLAY:
391 return "invalid VADisplay";
392 case VA_STATUS_ERROR_INVALID_CONFIG:
393 return "invalid VAConfigID";
394 case VA_STATUS_ERROR_INVALID_CONTEXT:
395 return "invalid VAContextID";
396 case VA_STATUS_ERROR_INVALID_SURFACE:
397 return "invalid VASurfaceID";
398 case VA_STATUS_ERROR_INVALID_BUFFER:
399 return "invalid VABufferID";
400 case VA_STATUS_ERROR_INVALID_IMAGE:
401 return "invalid VAImageID";
402 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
403 return "invalid VASubpictureID";
404 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
405 return "attribute not supported";
406 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
407 return "list argument exceeds maximum number";
408 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
409 return "the requested VAProfile is not supported";
410 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
411 return "the requested VAEntryPoint is not supported";
412 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
413 return "the requested RT Format is not supported";
414 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
415 return "the requested VABufferType is not supported";
416 case VA_STATUS_ERROR_SURFACE_BUSY:
417 return "surface is in use";
418 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
419 return "flag not supported";
420 case VA_STATUS_ERROR_INVALID_PARAMETER:
421 return "invalid parameter";
422 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
423 return "resolution not supported";
424 case VA_STATUS_ERROR_UNIMPLEMENTED:
425 return "the requested function is not implemented";
426 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
427 return "surface is in displaying (may by overlay)" ;
428 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
429 return "invalid VAImageFormat";
430 case VA_STATUS_ERROR_INVALID_VALUE:
431 return "an invalid/unsupported value was supplied";
432 case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
433 return "the requested filter is not supported";
434 case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
435 return "an invalid filter chain was supplied";
436 case VA_STATUS_ERROR_UNKNOWN:
437 return "unknown libva error";
438 }
439 return "unknown libva error / description missing";
440 }
441
vaInitialize(VADisplay dpy,int * major_version,int * minor_version)442 VAStatus vaInitialize (
443 VADisplay dpy,
444 int *major_version, /* out */
445 int *minor_version /* out */
446 )
447 {
448 const char *driver_name_env = NULL;
449 char *driver_name = NULL;
450 VAStatus vaStatus;
451
452 CHECK_DISPLAY(dpy);
453
454 va_TraceInit(dpy);
455
456 va_FoolInit(dpy);
457
458 va_infoMessage("VA-API version %s\n", VA_VERSION_S);
459
460 vaStatus = va_getDriverName(dpy, &driver_name);
461 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
462
463 driver_name_env = getenv("LIBVA_DRIVER_NAME");
464 if ((VA_STATUS_SUCCESS == vaStatus) &&
465 driver_name_env && (geteuid() == getuid())) {
466 /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
467 if (driver_name) /* memory is allocated in va_getDriverName */
468 free(driver_name);
469
470 driver_name = strdup(driver_name_env);
471 vaStatus = VA_STATUS_SUCCESS;
472 va_infoMessage("User requested driver '%s'\n", driver_name);
473 }
474
475 if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
476 vaStatus = va_openDriver(dpy, driver_name);
477 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
478
479 *major_version = VA_MAJOR_VERSION;
480 *minor_version = VA_MINOR_VERSION;
481 } else
482 va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n",
483 vaErrorStr(vaStatus), driver_name);
484
485 if (driver_name)
486 free(driver_name);
487
488 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
489
490 return vaStatus;
491 }
492
493
494 /*
495 * After this call, all library internal resources will be cleaned up
496 */
vaTerminate(VADisplay dpy)497 VAStatus vaTerminate (
498 VADisplay dpy
499 )
500 {
501 VAStatus vaStatus = VA_STATUS_SUCCESS;
502 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
503 VADriverContextP old_ctx;
504
505 CHECK_DISPLAY(dpy);
506 old_ctx = CTX(dpy);
507
508 if (old_ctx->handle) {
509 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
510 dlclose(old_ctx->handle);
511 old_ctx->handle = NULL;
512 }
513 free(old_ctx->vtable);
514 old_ctx->vtable = NULL;
515 free(old_ctx->vtable_vpp);
516 old_ctx->vtable_vpp = NULL;
517
518 VA_TRACE_LOG(va_TraceTerminate, dpy);
519
520 va_TraceEnd(dpy);
521
522 va_FoolEnd(dpy);
523
524 if (VA_STATUS_SUCCESS == vaStatus)
525 pDisplayContext->vaDestroy(pDisplayContext);
526
527 return vaStatus;
528 }
529
530 /*
531 * vaQueryVendorString returns a pointer to a zero-terminated string
532 * describing some aspects of the VA implemenation on a specific
533 * hardware accelerator. The format of the returned string is:
534 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
535 * e.g. for the Intel GMA500 implementation, an example would be:
536 * "IntelGMA500-1.0-0.2-patch3
537 */
vaQueryVendorString(VADisplay dpy)538 const char *vaQueryVendorString (
539 VADisplay dpy
540 )
541 {
542 if (!vaDisplayIsValid(dpy))
543 return NULL;
544
545 return CTX(dpy)->str_vendor;
546 }
547
548
549 /* Get maximum number of profiles supported by the implementation */
vaMaxNumProfiles(VADisplay dpy)550 int vaMaxNumProfiles (
551 VADisplay dpy
552 )
553 {
554 if (!vaDisplayIsValid(dpy))
555 return 0;
556
557 return CTX(dpy)->max_profiles;
558 }
559
560 /* Get maximum number of entrypoints supported by the implementation */
vaMaxNumEntrypoints(VADisplay dpy)561 int vaMaxNumEntrypoints (
562 VADisplay dpy
563 )
564 {
565 if (!vaDisplayIsValid(dpy))
566 return 0;
567
568 return CTX(dpy)->max_entrypoints;
569 }
570
571
572 /* Get maximum number of attributs supported by the implementation */
vaMaxNumConfigAttributes(VADisplay dpy)573 int vaMaxNumConfigAttributes (
574 VADisplay dpy
575 )
576 {
577 if (!vaDisplayIsValid(dpy))
578 return 0;
579
580 return CTX(dpy)->max_attributes;
581 }
582
vaQueryConfigEntrypoints(VADisplay dpy,VAProfile profile,VAEntrypoint * entrypoints,int * num_entrypoints)583 VAStatus vaQueryConfigEntrypoints (
584 VADisplay dpy,
585 VAProfile profile,
586 VAEntrypoint *entrypoints, /* out */
587 int *num_entrypoints /* out */
588 )
589 {
590 VADriverContextP ctx;
591 CHECK_DISPLAY(dpy);
592 ctx = CTX(dpy);
593
594 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
595 }
596
vaGetConfigAttributes(VADisplay dpy,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs)597 VAStatus vaGetConfigAttributes (
598 VADisplay dpy,
599 VAProfile profile,
600 VAEntrypoint entrypoint,
601 VAConfigAttrib *attrib_list, /* in/out */
602 int num_attribs
603 )
604 {
605 VADriverContextP ctx;
606 CHECK_DISPLAY(dpy);
607 ctx = CTX(dpy);
608
609 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
610 }
611
vaQueryConfigProfiles(VADisplay dpy,VAProfile * profile_list,int * num_profiles)612 VAStatus vaQueryConfigProfiles (
613 VADisplay dpy,
614 VAProfile *profile_list, /* out */
615 int *num_profiles /* out */
616 )
617 {
618 VADriverContextP ctx;
619 CHECK_DISPLAY(dpy);
620 ctx = CTX(dpy);
621
622 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
623 }
624
vaCreateConfig(VADisplay dpy,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs,VAConfigID * config_id)625 VAStatus vaCreateConfig (
626 VADisplay dpy,
627 VAProfile profile,
628 VAEntrypoint entrypoint,
629 VAConfigAttrib *attrib_list,
630 int num_attribs,
631 VAConfigID *config_id /* out */
632 )
633 {
634 VADriverContextP ctx;
635 VAStatus vaStatus = VA_STATUS_SUCCESS;
636
637 CHECK_DISPLAY(dpy);
638 ctx = CTX(dpy);
639
640 vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
641
642 /* record the current entrypoint for further trace/fool determination */
643 VA_TRACE_ALL(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
644 VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
645
646 return vaStatus;
647 }
648
vaDestroyConfig(VADisplay dpy,VAConfigID config_id)649 VAStatus vaDestroyConfig (
650 VADisplay dpy,
651 VAConfigID config_id
652 )
653 {
654 VADriverContextP ctx;
655 CHECK_DISPLAY(dpy);
656 ctx = CTX(dpy);
657
658 return ctx->vtable->vaDestroyConfig ( ctx, config_id );
659 }
660
vaQueryConfigAttributes(VADisplay dpy,VAConfigID config_id,VAProfile * profile,VAEntrypoint * entrypoint,VAConfigAttrib * attrib_list,int * num_attribs)661 VAStatus vaQueryConfigAttributes (
662 VADisplay dpy,
663 VAConfigID config_id,
664 VAProfile *profile, /* out */
665 VAEntrypoint *entrypoint, /* out */
666 VAConfigAttrib *attrib_list,/* out */
667 int *num_attribs /* out */
668 )
669 {
670 VADriverContextP ctx;
671 CHECK_DISPLAY(dpy);
672 ctx = CTX(dpy);
673
674 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
675 }
676
677 /* XXX: this is a slow implementation that will be removed */
678 static VAStatus
va_impl_query_surface_attributes(VADriverContextP ctx,VAConfigID config,VASurfaceAttrib * out_attribs,unsigned int * out_num_attribs_ptr)679 va_impl_query_surface_attributes(
680 VADriverContextP ctx,
681 VAConfigID config,
682 VASurfaceAttrib *out_attribs,
683 unsigned int *out_num_attribs_ptr
684 )
685 {
686 VASurfaceAttrib *attribs = NULL;
687 unsigned int num_attribs, n;
688 VASurfaceAttrib *out_attrib;
689 unsigned int out_num_attribs;
690 VAImageFormat *image_formats = NULL;
691 int num_image_formats, i;
692 VAStatus va_status;
693
694 /* List of surface attributes to query */
695 struct va_surface_attrib_map {
696 VASurfaceAttribType type;
697 VAGenericValueType value_type;
698 };
699 static const struct va_surface_attrib_map attribs_map[] = {
700 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
701 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
702 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
703 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
704 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
705 { VASurfaceAttribNone, }
706 };
707
708 if (!out_attribs || !out_num_attribs_ptr)
709 return VA_STATUS_ERROR_INVALID_PARAMETER;
710 if (!ctx->vtable->vaGetSurfaceAttributes)
711 return VA_STATUS_ERROR_UNIMPLEMENTED;
712
713 num_image_formats = ctx->max_image_formats;
714 image_formats = malloc(num_image_formats * sizeof(*image_formats));
715 if (!image_formats) {
716 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
717 goto end;
718 }
719
720 va_status = ctx->vtable->vaQueryImageFormats(
721 ctx, image_formats, &num_image_formats);
722 if (va_status != VA_STATUS_SUCCESS)
723 goto end;
724
725 num_attribs = VASurfaceAttribCount + num_image_formats;
726 attribs = malloc(num_attribs * sizeof(*attribs));
727 if (!attribs) {
728 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
729 goto end;
730 }
731
732 /* Initialize with base surface attributes, except pixel-formats */
733 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
734 VASurfaceAttrib * const attrib = &attribs[n];
735 attrib->type = attribs_map[n].type;
736 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
737 attrib->value.type = attribs_map[n].value_type;
738 }
739
740 /* Append image formats */
741 for (i = 0; i < num_image_formats; i++) {
742 VASurfaceAttrib * const attrib = &attribs[n];
743 attrib->type = VASurfaceAttribPixelFormat;
744 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
745 attrib->value.type = VAGenericValueTypeInteger;
746 attrib->value.value.i = image_formats[i].fourcc;
747 if (++n == num_attribs) {
748 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
749 goto end;
750 }
751 }
752 num_attribs = n;
753
754 va_status = ctx->vtable->vaGetSurfaceAttributes(
755 ctx, config, attribs, num_attribs);
756 if (va_status != VA_STATUS_SUCCESS)
757 goto end;
758
759 /* Remove invalid entries */
760 out_num_attribs = 0;
761 for (n = 0; n < num_attribs; n++) {
762 VASurfaceAttrib * const attrib = &attribs[n];
763
764 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
765 continue;
766
767 // Accept all surface attributes that are not pixel-formats
768 if (attrib->type != VASurfaceAttribPixelFormat) {
769 out_num_attribs++;
770 continue;
771 }
772
773 // Drop invalid pixel-format attribute
774 if (!attrib->value.value.i) {
775 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
776 continue;
777 }
778
779 // Check for duplicates
780 int is_duplicate = 0;
781 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
782 const VASurfaceAttrib * const prev_attrib = &attribs[i];
783 if (prev_attrib->type != VASurfaceAttribPixelFormat)
784 break;
785 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
786 }
787 if (is_duplicate)
788 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
789 else
790 out_num_attribs++;
791 }
792
793 if (*out_num_attribs_ptr < out_num_attribs) {
794 *out_num_attribs_ptr = out_num_attribs;
795 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
796 goto end;
797 }
798
799 out_attrib = out_attribs;
800 for (n = 0; n < num_attribs; n++) {
801 const VASurfaceAttrib * const attrib = &attribs[n];
802 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
803 continue;
804 *out_attrib++ = *attrib;
805 }
806
807 end:
808 free(attribs);
809 free(image_formats);
810 return va_status;
811 }
812
813 VAStatus
vaQuerySurfaceAttributes(VADisplay dpy,VAConfigID config,VASurfaceAttrib * attrib_list,unsigned int * num_attribs)814 vaQuerySurfaceAttributes(
815 VADisplay dpy,
816 VAConfigID config,
817 VASurfaceAttrib *attrib_list,
818 unsigned int *num_attribs
819 )
820 {
821 VADriverContextP ctx;
822 VAStatus vaStatus;
823
824 CHECK_DISPLAY(dpy);
825 ctx = CTX(dpy);
826 if (!ctx)
827 return VA_STATUS_ERROR_INVALID_DISPLAY;
828
829 if (!ctx->vtable->vaQuerySurfaceAttributes)
830 vaStatus = va_impl_query_surface_attributes(ctx, config,
831 attrib_list, num_attribs);
832 else
833 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
834 attrib_list, num_attribs);
835
836 VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs);
837
838 return vaStatus;
839 }
840
841 VAStatus
vaCreateSurfaces(VADisplay dpy,unsigned int format,unsigned int width,unsigned int height,VASurfaceID * surfaces,unsigned int num_surfaces,VASurfaceAttrib * attrib_list,unsigned int num_attribs)842 vaCreateSurfaces(
843 VADisplay dpy,
844 unsigned int format,
845 unsigned int width,
846 unsigned int height,
847 VASurfaceID *surfaces,
848 unsigned int num_surfaces,
849 VASurfaceAttrib *attrib_list,
850 unsigned int num_attribs
851 )
852 {
853 VADriverContextP ctx;
854 VAStatus vaStatus;
855
856 CHECK_DISPLAY(dpy);
857 ctx = CTX(dpy);
858 if (!ctx)
859 return VA_STATUS_ERROR_INVALID_DISPLAY;
860
861 if (ctx->vtable->vaCreateSurfaces2)
862 vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
863 surfaces, num_surfaces,
864 attrib_list, num_attribs);
865 else if (attrib_list && num_attribs > 0)
866 vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
867 else
868 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
869 num_surfaces, surfaces);
870 VA_TRACE_LOG(va_TraceCreateSurfaces,
871 dpy, width, height, format, num_surfaces, surfaces,
872 attrib_list, num_attribs);
873
874 return vaStatus;
875 }
876
877
vaDestroySurfaces(VADisplay dpy,VASurfaceID * surface_list,int num_surfaces)878 VAStatus vaDestroySurfaces (
879 VADisplay dpy,
880 VASurfaceID *surface_list,
881 int num_surfaces
882 )
883 {
884 VADriverContextP ctx;
885 VAStatus vaStatus;
886
887 CHECK_DISPLAY(dpy);
888 ctx = CTX(dpy);
889
890 VA_TRACE_LOG(va_TraceDestroySurfaces,
891 dpy, surface_list, num_surfaces);
892
893 vaStatus = ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
894
895 return vaStatus;
896 }
897
vaCreateContext(VADisplay dpy,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID * render_targets,int num_render_targets,VAContextID * context)898 VAStatus vaCreateContext (
899 VADisplay dpy,
900 VAConfigID config_id,
901 int picture_width,
902 int picture_height,
903 int flag,
904 VASurfaceID *render_targets,
905 int num_render_targets,
906 VAContextID *context /* out */
907 )
908 {
909 VADriverContextP ctx;
910 VAStatus vaStatus;
911
912 CHECK_DISPLAY(dpy);
913 ctx = CTX(dpy);
914
915 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
916 flag, render_targets, num_render_targets, context );
917
918 /* keep current encode/decode resoluton */
919 VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
920
921 return vaStatus;
922 }
923
vaDestroyContext(VADisplay dpy,VAContextID context)924 VAStatus vaDestroyContext (
925 VADisplay dpy,
926 VAContextID context
927 )
928 {
929 VADriverContextP ctx;
930 CHECK_DISPLAY(dpy);
931 ctx = CTX(dpy);
932
933 return ctx->vtable->vaDestroyContext( ctx, context );
934 }
935
vaCreateBuffer(VADisplay dpy,VAContextID context,VABufferType type,unsigned int size,unsigned int num_elements,void * data,VABufferID * buf_id)936 VAStatus vaCreateBuffer (
937 VADisplay dpy,
938 VAContextID context, /* in */
939 VABufferType type, /* in */
940 unsigned int size, /* in */
941 unsigned int num_elements, /* in */
942 void *data, /* in */
943 VABufferID *buf_id /* out */
944 )
945 {
946 VADriverContextP ctx;
947 VAStatus vaStatus;
948
949 CHECK_DISPLAY(dpy);
950 ctx = CTX(dpy);
951
952 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
953
954 vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
955
956 VA_TRACE_LOG(va_TraceCreateBuffer,
957 dpy, context, type, size, num_elements, data, buf_id);
958
959 return vaStatus;
960 }
961
vaBufferSetNumElements(VADisplay dpy,VABufferID buf_id,unsigned int num_elements)962 VAStatus vaBufferSetNumElements (
963 VADisplay dpy,
964 VABufferID buf_id, /* in */
965 unsigned int num_elements /* in */
966 )
967 {
968 VADriverContextP ctx;
969 CHECK_DISPLAY(dpy);
970 ctx = CTX(dpy);
971
972 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
973
974 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
975 }
976
977
vaMapBuffer(VADisplay dpy,VABufferID buf_id,void ** pbuf)978 VAStatus vaMapBuffer (
979 VADisplay dpy,
980 VABufferID buf_id, /* in */
981 void **pbuf /* out */
982 )
983 {
984 VADriverContextP ctx;
985 VAStatus va_status;
986
987 CHECK_DISPLAY(dpy);
988 ctx = CTX(dpy);
989
990 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
991
992 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
993
994 VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf);
995
996 return va_status;
997 }
998
vaUnmapBuffer(VADisplay dpy,VABufferID buf_id)999 VAStatus vaUnmapBuffer (
1000 VADisplay dpy,
1001 VABufferID buf_id /* in */
1002 )
1003 {
1004 VADriverContextP ctx;
1005 CHECK_DISPLAY(dpy);
1006 ctx = CTX(dpy);
1007
1008 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1009
1010 return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
1011 }
1012
vaDestroyBuffer(VADisplay dpy,VABufferID buffer_id)1013 VAStatus vaDestroyBuffer (
1014 VADisplay dpy,
1015 VABufferID buffer_id
1016 )
1017 {
1018 VADriverContextP ctx;
1019 CHECK_DISPLAY(dpy);
1020 ctx = CTX(dpy);
1021
1022 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1023
1024 VA_TRACE_LOG(va_TraceDestroyBuffer,
1025 dpy, buffer_id);
1026
1027 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1028 }
1029
vaBufferInfo(VADisplay dpy,VAContextID __maybe_unused context,VABufferID buf_id,VABufferType * type,unsigned int * size,unsigned int * num_elements)1030 VAStatus vaBufferInfo (
1031 VADisplay dpy,
1032 VAContextID __maybe_unused context, /* in */
1033 VABufferID buf_id, /* in */
1034 VABufferType *type, /* out */
1035 unsigned int *size, /* out */
1036 unsigned int *num_elements /* out */
1037 )
1038 {
1039 VADriverContextP ctx;
1040
1041 CHECK_DISPLAY(dpy);
1042 ctx = CTX(dpy);
1043
1044 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1045
1046 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1047 }
1048
vaBeginPicture(VADisplay dpy,VAContextID context,VASurfaceID render_target)1049 VAStatus vaBeginPicture (
1050 VADisplay dpy,
1051 VAContextID context,
1052 VASurfaceID render_target
1053 )
1054 {
1055 VADriverContextP ctx;
1056 VAStatus va_status;
1057
1058 CHECK_DISPLAY(dpy);
1059 ctx = CTX(dpy);
1060
1061 VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target);
1062 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1063
1064 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1065
1066 return va_status;
1067 }
1068
vaRenderPicture(VADisplay dpy,VAContextID context,VABufferID * buffers,int num_buffers)1069 VAStatus vaRenderPicture (
1070 VADisplay dpy,
1071 VAContextID context,
1072 VABufferID *buffers,
1073 int num_buffers
1074 )
1075 {
1076 VADriverContextP ctx;
1077
1078 CHECK_DISPLAY(dpy);
1079 ctx = CTX(dpy);
1080
1081 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1082 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1083
1084 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1085 }
1086
vaEndPicture(VADisplay dpy,VAContextID context)1087 VAStatus vaEndPicture (
1088 VADisplay dpy,
1089 VAContextID context
1090 )
1091 {
1092 VAStatus va_status = VA_STATUS_SUCCESS;
1093 VADriverContextP ctx;
1094
1095 CHECK_DISPLAY(dpy);
1096 ctx = CTX(dpy);
1097
1098 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1099
1100 va_status = ctx->vtable->vaEndPicture( ctx, context );
1101
1102 /* dump surface content */
1103 VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 1);
1104
1105 return va_status;
1106 }
1107
vaSyncSurface(VADisplay dpy,VASurfaceID render_target)1108 VAStatus vaSyncSurface (
1109 VADisplay dpy,
1110 VASurfaceID render_target
1111 )
1112 {
1113 VAStatus va_status;
1114 VADriverContextP ctx;
1115
1116 CHECK_DISPLAY(dpy);
1117 ctx = CTX(dpy);
1118
1119 va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1120 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1121
1122 return va_status;
1123 }
1124
vaQuerySurfaceStatus(VADisplay dpy,VASurfaceID render_target,VASurfaceStatus * status)1125 VAStatus vaQuerySurfaceStatus (
1126 VADisplay dpy,
1127 VASurfaceID render_target,
1128 VASurfaceStatus *status /* out */
1129 )
1130 {
1131 VAStatus va_status;
1132 VADriverContextP ctx;
1133 CHECK_DISPLAY(dpy);
1134 ctx = CTX(dpy);
1135
1136 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1137
1138 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1139
1140 return va_status;
1141 }
1142
vaQuerySurfaceError(VADisplay dpy,VASurfaceID surface,VAStatus error_status,void ** error_info)1143 VAStatus vaQuerySurfaceError (
1144 VADisplay dpy,
1145 VASurfaceID surface,
1146 VAStatus error_status,
1147 void **error_info /*out*/
1148 )
1149 {
1150 VAStatus va_status;
1151 VADriverContextP ctx;
1152 CHECK_DISPLAY(dpy);
1153 ctx = CTX(dpy);
1154
1155 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1156
1157 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1158
1159 return va_status;
1160 }
1161
1162 /* Get maximum number of image formats supported by the implementation */
vaMaxNumImageFormats(VADisplay dpy)1163 int vaMaxNumImageFormats (
1164 VADisplay dpy
1165 )
1166 {
1167 if (!vaDisplayIsValid(dpy))
1168 return 0;
1169
1170 return CTX(dpy)->max_image_formats;
1171 }
1172
vaQueryImageFormats(VADisplay dpy,VAImageFormat * format_list,int * num_formats)1173 VAStatus vaQueryImageFormats (
1174 VADisplay dpy,
1175 VAImageFormat *format_list, /* out */
1176 int *num_formats /* out */
1177 )
1178 {
1179 VADriverContextP ctx;
1180 CHECK_DISPLAY(dpy);
1181 ctx = CTX(dpy);
1182
1183 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1184 }
1185
1186 /*
1187 * The width and height fields returned in the VAImage structure may get
1188 * enlarged for some YUV formats. The size of the data buffer that needs
1189 * to be allocated will be given in the "data_size" field in VAImage.
1190 * Image data is not allocated by this function. The client should
1191 * allocate the memory and fill in the VAImage structure's data field
1192 * after looking at "data_size" returned from the library.
1193 */
vaCreateImage(VADisplay dpy,VAImageFormat * format,int width,int height,VAImage * image)1194 VAStatus vaCreateImage (
1195 VADisplay dpy,
1196 VAImageFormat *format,
1197 int width,
1198 int height,
1199 VAImage *image /* out */
1200 )
1201 {
1202 VADriverContextP ctx;
1203 CHECK_DISPLAY(dpy);
1204 ctx = CTX(dpy);
1205
1206 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1207 }
1208
1209 /*
1210 * Should call DestroyImage before destroying the surface it is bound to
1211 */
vaDestroyImage(VADisplay dpy,VAImageID image)1212 VAStatus vaDestroyImage (
1213 VADisplay dpy,
1214 VAImageID image
1215 )
1216 {
1217 VADriverContextP ctx;
1218 CHECK_DISPLAY(dpy);
1219 ctx = CTX(dpy);
1220
1221 return ctx->vtable->vaDestroyImage ( ctx, image);
1222 }
1223
vaSetImagePalette(VADisplay dpy,VAImageID image,unsigned char * palette)1224 VAStatus vaSetImagePalette (
1225 VADisplay dpy,
1226 VAImageID image,
1227 unsigned char *palette
1228 )
1229 {
1230 VADriverContextP ctx;
1231 CHECK_DISPLAY(dpy);
1232 ctx = CTX(dpy);
1233
1234 return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1235 }
1236
1237 /*
1238 * Retrieve surface data into a VAImage
1239 * Image must be in a format supported by the implementation
1240 */
vaGetImage(VADisplay dpy,VASurfaceID surface,int x,int y,unsigned int width,unsigned int height,VAImageID image)1241 VAStatus vaGetImage (
1242 VADisplay dpy,
1243 VASurfaceID surface,
1244 int x, /* coordinates of the upper left source pixel */
1245 int y,
1246 unsigned int width, /* width and height of the region */
1247 unsigned int height,
1248 VAImageID image
1249 )
1250 {
1251 VADriverContextP ctx;
1252 CHECK_DISPLAY(dpy);
1253 ctx = CTX(dpy);
1254
1255 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1256 }
1257
1258 /*
1259 * Copy data from a VAImage to a surface
1260 * Image must be in a format supported by the implementation
1261 */
vaPutImage(VADisplay dpy,VASurfaceID surface,VAImageID image,int src_x,int src_y,unsigned int src_width,unsigned int src_height,int dest_x,int dest_y,unsigned int dest_width,unsigned int dest_height)1262 VAStatus vaPutImage (
1263 VADisplay dpy,
1264 VASurfaceID surface,
1265 VAImageID image,
1266 int src_x,
1267 int src_y,
1268 unsigned int src_width,
1269 unsigned int src_height,
1270 int dest_x,
1271 int dest_y,
1272 unsigned int dest_width,
1273 unsigned int dest_height
1274 )
1275 {
1276 VADriverContextP ctx;
1277 CHECK_DISPLAY(dpy);
1278 ctx = CTX(dpy);
1279
1280 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1281 }
1282
1283 /*
1284 * Derive an VAImage from an existing surface.
1285 * This interface will derive a VAImage and corresponding image buffer from
1286 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1287 * direct CPU access. This operation is only possible on implementations with
1288 * direct rendering capabilities and internal surface formats that can be
1289 * represented with a VAImage. When the operation is not possible this interface
1290 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1291 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1292 * indirect manner.
1293 *
1294 * Implementations should only return success when the resulting image buffer
1295 * would be useable with vaMap/Unmap.
1296 *
1297 * When directly accessing a surface special care must be taken to insure
1298 * proper synchronization with the graphics hardware. Clients should call
1299 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1300 * rendering or currently being displayed by an overlay.
1301 *
1302 * Additionally nothing about the contents of a surface should be assumed
1303 * following a vaPutSurface. Implementations are free to modify the surface for
1304 * scaling or subpicture blending within a call to vaPutImage.
1305 *
1306 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1307 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1308 * vaGetImage with other surfaces is supported.
1309 *
1310 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1311 * image and image buffer structures will be destroyed; however, the underlying
1312 * surface will remain unchanged until freed with vaDestroySurfaces.
1313 */
vaDeriveImage(VADisplay dpy,VASurfaceID surface,VAImage * image)1314 VAStatus vaDeriveImage (
1315 VADisplay dpy,
1316 VASurfaceID surface,
1317 VAImage *image /* out */
1318 )
1319 {
1320 VADriverContextP ctx;
1321 CHECK_DISPLAY(dpy);
1322 ctx = CTX(dpy);
1323
1324 return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1325 }
1326
1327
1328 /* Get maximum number of subpicture formats supported by the implementation */
vaMaxNumSubpictureFormats(VADisplay dpy)1329 int vaMaxNumSubpictureFormats (
1330 VADisplay dpy
1331 )
1332 {
1333 if (!vaDisplayIsValid(dpy))
1334 return 0;
1335
1336 return CTX(dpy)->max_subpic_formats;
1337 }
1338
1339 /*
1340 * Query supported subpicture formats
1341 * The caller must provide a "format_list" array that can hold at
1342 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1343 * for each format to indicate additional capabilities for that format. The actual
1344 * number of formats returned in "format_list" is returned in "num_formats".
1345 */
vaQuerySubpictureFormats(VADisplay dpy,VAImageFormat * format_list,unsigned int * flags,unsigned int * num_formats)1346 VAStatus vaQuerySubpictureFormats (
1347 VADisplay dpy,
1348 VAImageFormat *format_list, /* out */
1349 unsigned int *flags, /* out */
1350 unsigned int *num_formats /* out */
1351 )
1352 {
1353 VADriverContextP ctx;
1354
1355 CHECK_DISPLAY(dpy);
1356 ctx = CTX(dpy);
1357
1358 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1359 }
1360
1361 /*
1362 * Subpictures are created with an image associated.
1363 */
vaCreateSubpicture(VADisplay dpy,VAImageID image,VASubpictureID * subpicture)1364 VAStatus vaCreateSubpicture (
1365 VADisplay dpy,
1366 VAImageID image,
1367 VASubpictureID *subpicture /* out */
1368 )
1369 {
1370 VADriverContextP ctx;
1371 CHECK_DISPLAY(dpy);
1372 ctx = CTX(dpy);
1373
1374 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1375 }
1376
1377 /*
1378 * Destroy the subpicture before destroying the image it is assocated to
1379 */
vaDestroySubpicture(VADisplay dpy,VASubpictureID subpicture)1380 VAStatus vaDestroySubpicture (
1381 VADisplay dpy,
1382 VASubpictureID subpicture
1383 )
1384 {
1385 VADriverContextP ctx;
1386 CHECK_DISPLAY(dpy);
1387 ctx = CTX(dpy);
1388
1389 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1390 }
1391
vaSetSubpictureImage(VADisplay dpy,VASubpictureID subpicture,VAImageID image)1392 VAStatus vaSetSubpictureImage (
1393 VADisplay dpy,
1394 VASubpictureID subpicture,
1395 VAImageID image
1396 )
1397 {
1398 VADriverContextP ctx;
1399 CHECK_DISPLAY(dpy);
1400 ctx = CTX(dpy);
1401
1402 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1403 }
1404
1405
1406 /*
1407 * If chromakey is enabled, then the area where the source value falls within
1408 * the chromakey [min, max] range is transparent
1409 */
vaSetSubpictureChromakey(VADisplay dpy,VASubpictureID subpicture,unsigned int chromakey_min,unsigned int chromakey_max,unsigned int chromakey_mask)1410 VAStatus vaSetSubpictureChromakey (
1411 VADisplay dpy,
1412 VASubpictureID subpicture,
1413 unsigned int chromakey_min,
1414 unsigned int chromakey_max,
1415 unsigned int chromakey_mask
1416 )
1417 {
1418 VADriverContextP ctx;
1419 CHECK_DISPLAY(dpy);
1420 ctx = CTX(dpy);
1421
1422 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1423 }
1424
1425
1426 /*
1427 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
1428 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1429 * the overall alpha is per-pixel alpha multiplied by the global alpha
1430 */
vaSetSubpictureGlobalAlpha(VADisplay dpy,VASubpictureID subpicture,float global_alpha)1431 VAStatus vaSetSubpictureGlobalAlpha (
1432 VADisplay dpy,
1433 VASubpictureID subpicture,
1434 float global_alpha
1435 )
1436 {
1437 VADriverContextP ctx;
1438 CHECK_DISPLAY(dpy);
1439 ctx = CTX(dpy);
1440
1441 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1442 }
1443
1444 /*
1445 vaAssociateSubpicture associates the subpicture with the target_surface.
1446 It defines the region mapping between the subpicture and the target
1447 surface through source and destination rectangles (with the same width and height).
1448 Both will be displayed at the next call to vaPutSurface. Additional
1449 associations before the call to vaPutSurface simply overrides the association.
1450 */
vaAssociateSubpicture(VADisplay dpy,VASubpictureID subpicture,VASurfaceID * target_surfaces,int num_surfaces,short src_x,short src_y,unsigned short src_width,unsigned short src_height,short dest_x,short dest_y,unsigned short dest_width,unsigned short dest_height,unsigned int flags)1451 VAStatus vaAssociateSubpicture (
1452 VADisplay dpy,
1453 VASubpictureID subpicture,
1454 VASurfaceID *target_surfaces,
1455 int num_surfaces,
1456 short src_x, /* upper left offset in subpicture */
1457 short src_y,
1458 unsigned short src_width,
1459 unsigned short src_height,
1460 short dest_x, /* upper left offset in surface */
1461 short dest_y,
1462 unsigned short dest_width,
1463 unsigned short dest_height,
1464 /*
1465 * whether to enable chroma-keying or global-alpha
1466 * see VA_SUBPICTURE_XXX values
1467 */
1468 unsigned int flags
1469 )
1470 {
1471 VADriverContextP ctx;
1472 CHECK_DISPLAY(dpy);
1473 ctx = CTX(dpy);
1474
1475 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 );
1476 }
1477
1478 /*
1479 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1480 */
vaDeassociateSubpicture(VADisplay dpy,VASubpictureID subpicture,VASurfaceID * target_surfaces,int num_surfaces)1481 VAStatus vaDeassociateSubpicture (
1482 VADisplay dpy,
1483 VASubpictureID subpicture,
1484 VASurfaceID *target_surfaces,
1485 int num_surfaces
1486 )
1487 {
1488 VADriverContextP ctx;
1489 CHECK_DISPLAY(dpy);
1490 ctx = CTX(dpy);
1491
1492 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1493 }
1494
1495
1496 /* Get maximum number of display attributes supported by the implementation */
vaMaxNumDisplayAttributes(VADisplay dpy)1497 int vaMaxNumDisplayAttributes (
1498 VADisplay dpy
1499 )
1500 {
1501 int tmp;
1502
1503 if (!vaDisplayIsValid(dpy))
1504 return 0;
1505
1506 tmp = CTX(dpy)->max_display_attributes;
1507
1508 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1509
1510 return tmp;
1511 }
1512
1513 /*
1514 * Query display attributes
1515 * The caller must provide a "attr_list" array that can hold at
1516 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1517 * returned in "attr_list" is returned in "num_attributes".
1518 */
vaQueryDisplayAttributes(VADisplay dpy,VADisplayAttribute * attr_list,int * num_attributes)1519 VAStatus vaQueryDisplayAttributes (
1520 VADisplay dpy,
1521 VADisplayAttribute *attr_list, /* out */
1522 int *num_attributes /* out */
1523 )
1524 {
1525 VADriverContextP ctx;
1526 VAStatus va_status;
1527
1528 CHECK_DISPLAY(dpy);
1529 ctx = CTX(dpy);
1530 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1531
1532 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1533
1534 return va_status;
1535
1536 }
1537
1538 /*
1539 * Get display attributes
1540 * This function returns the current attribute values in "attr_list".
1541 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1542 * from vaQueryDisplayAttributes() can have their values retrieved.
1543 */
vaGetDisplayAttributes(VADisplay dpy,VADisplayAttribute * attr_list,int num_attributes)1544 VAStatus vaGetDisplayAttributes (
1545 VADisplay dpy,
1546 VADisplayAttribute *attr_list, /* in/out */
1547 int num_attributes
1548 )
1549 {
1550 VADriverContextP ctx;
1551 VAStatus va_status;
1552
1553 CHECK_DISPLAY(dpy);
1554 ctx = CTX(dpy);
1555 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1556
1557 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1558
1559 return va_status;
1560 }
1561
1562 /*
1563 * Set display attributes
1564 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1565 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1566 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1567 */
vaSetDisplayAttributes(VADisplay dpy,VADisplayAttribute * attr_list,int num_attributes)1568 VAStatus vaSetDisplayAttributes (
1569 VADisplay dpy,
1570 VADisplayAttribute *attr_list,
1571 int num_attributes
1572 )
1573 {
1574 VADriverContextP ctx;
1575 VAStatus va_status;
1576 CHECK_DISPLAY(dpy);
1577 ctx = CTX(dpy);
1578
1579 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1580 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1581
1582 return va_status;
1583 }
1584
vaLockSurface(VADisplay dpy,VASurfaceID surface,unsigned int * fourcc,unsigned int * luma_stride,unsigned int * chroma_u_stride,unsigned int * chroma_v_stride,unsigned int * luma_offset,unsigned int * chroma_u_offset,unsigned int * chroma_v_offset,unsigned int * buffer_name,void ** buffer)1585 VAStatus vaLockSurface(VADisplay dpy,
1586 VASurfaceID surface,
1587 unsigned int *fourcc, /* following are output argument */
1588 unsigned int *luma_stride,
1589 unsigned int *chroma_u_stride,
1590 unsigned int *chroma_v_stride,
1591 unsigned int *luma_offset,
1592 unsigned int *chroma_u_offset,
1593 unsigned int *chroma_v_offset,
1594 unsigned int *buffer_name,
1595 void **buffer
1596 )
1597 {
1598 VADriverContextP ctx;
1599 CHECK_DISPLAY(dpy);
1600 ctx = CTX(dpy);
1601
1602 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);
1603 }
1604
1605
vaUnlockSurface(VADisplay dpy,VASurfaceID surface)1606 VAStatus vaUnlockSurface(VADisplay dpy,
1607 VASurfaceID surface
1608 )
1609 {
1610 VADriverContextP ctx;
1611 CHECK_DISPLAY(dpy);
1612 ctx = CTX(dpy);
1613
1614 return ctx->vtable->vaUnlockSurface( ctx, surface );
1615 }
1616
1617 /* Video Processing */
1618 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
1619 CHECK_DISPLAY(dpy); \
1620 ctx = CTX(dpy); \
1621 if (!ctx) \
1622 return VA_STATUS_ERROR_INVALID_DISPLAY; \
1623 } while (0)
1624
1625 #define VA_VPP_INVOKE(dpy, func, args) do { \
1626 if (!ctx->vtable_vpp->va##func) \
1627 return VA_STATUS_ERROR_UNIMPLEMENTED; \
1628 status = ctx->vtable_vpp->va##func args; \
1629 } while (0)
1630
1631 VAStatus
vaQueryVideoProcFilters(VADisplay dpy,VAContextID context,VAProcFilterType * filters,unsigned int * num_filters)1632 vaQueryVideoProcFilters(
1633 VADisplay dpy,
1634 VAContextID context,
1635 VAProcFilterType *filters,
1636 unsigned int *num_filters
1637 )
1638 {
1639 VADriverContextP ctx;
1640 VAStatus status;
1641
1642 VA_VPP_INIT_CONTEXT(ctx, dpy);
1643 VA_VPP_INVOKE(
1644 ctx,
1645 QueryVideoProcFilters,
1646 (ctx, context, filters, num_filters)
1647 );
1648 return status;
1649 }
1650
1651 VAStatus
vaQueryVideoProcFilterCaps(VADisplay dpy,VAContextID context,VAProcFilterType type,void * filter_caps,unsigned int * num_filter_caps)1652 vaQueryVideoProcFilterCaps(
1653 VADisplay dpy,
1654 VAContextID context,
1655 VAProcFilterType type,
1656 void *filter_caps,
1657 unsigned int *num_filter_caps
1658 )
1659 {
1660 VADriverContextP ctx;
1661 VAStatus status;
1662
1663 VA_VPP_INIT_CONTEXT(ctx, dpy);
1664 VA_VPP_INVOKE(
1665 ctx,
1666 QueryVideoProcFilterCaps,
1667 (ctx, context, type, filter_caps, num_filter_caps)
1668 );
1669 return status;
1670 }
1671
1672 VAStatus
vaQueryVideoProcPipelineCaps(VADisplay dpy,VAContextID context,VABufferID * filters,unsigned int num_filters,VAProcPipelineCaps * pipeline_caps)1673 vaQueryVideoProcPipelineCaps(
1674 VADisplay dpy,
1675 VAContextID context,
1676 VABufferID *filters,
1677 unsigned int num_filters,
1678 VAProcPipelineCaps *pipeline_caps
1679 )
1680 {
1681 VADriverContextP ctx;
1682 VAStatus status;
1683
1684 VA_VPP_INIT_CONTEXT(ctx, dpy);
1685 VA_VPP_INVOKE(
1686 ctx,
1687 QueryVideoProcPipelineCaps,
1688 (ctx, context, filters, num_filters, pipeline_caps)
1689 );
1690 return status;
1691 }
1692