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_prot.h"
30 #include "va_backend_vpp.h"
31 #include "va_internal.h"
32 #include "va_trace.h"
33
34 #include <assert.h>
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #if defined(_WIN32)
40 #include "compat_win32.h"
41 #define DRIVER_EXTENSION "_drv_video.dll"
42 #define DRIVER_PATH_STRING "%s\\%s%s"
43 #define ENV_VAR_SEPARATOR ";"
44 #else
45 #include <dlfcn.h>
46 #include <unistd.h>
47 #define DRIVER_EXTENSION "_drv_video.so"
48 #define DRIVER_PATH_STRING "%s/%s%s"
49 #define ENV_VAR_SEPARATOR ":"
50 #endif
51 #ifdef ANDROID
52 #include <log/log.h>
53 #endif
54
55 #define ASSERT assert
56 #define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(dpy, ctx->vtable->va##func, #func)) s = VA_STATUS_ERROR_UNIMPLEMENTED;
57 #define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(dpy, ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
58 #define CHECK_STRING(s, ctx, var) if (!va_checkString(dpy, ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
59
60 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
61
62 #ifndef HAVE_SECURE_GETENV
secure_getenv(const char * name)63 static char * secure_getenv(const char *name)
64 {
65 #if defined(__MINGW32__) || defined(__MINGW64__)
66 if (getuid() == geteuid())
67 #else
68 if (getuid() == geteuid() && getgid() == getegid())
69 #endif
70 return getenv(name);
71 else
72 return NULL;
73 }
74 #endif
75
76 /*
77 * read a config "env" for libva.conf or from environment setting
78 * libva.conf has higher priority
79 * return 0: the "env" is set, and the value is copied into env_value
80 * 1: the env is not set
81 */
va_parseConfig(char * env,char * env_value)82 int va_parseConfig(char *env, char *env_value)
83 {
84 char *token, *value, *saveptr;
85 char oneline[1024];
86 FILE *fp = NULL;
87
88 if (env == NULL)
89 return 1;
90
91 fp = fopen(SYSCONFDIR "/libva.conf", "r");
92 while (fp && (fgets(oneline, 1024, fp) != NULL)) {
93 if (strlen(oneline) == 1)
94 continue;
95 token = strtok_r(oneline, "=\n", &saveptr);
96 value = strtok_r(NULL, "=\n", &saveptr);
97
98 if (NULL == token || NULL == value)
99 continue;
100
101 if (strcmp(token, env) == 0) {
102 if (env_value) {
103 strncpy(env_value, value, 1024);
104 env_value[1023] = '\0';
105 }
106
107 fclose(fp);
108
109 return 0;
110 }
111 }
112 if (fp)
113 fclose(fp);
114
115 /* no setting in config file, use env setting */
116 value = secure_getenv(env);
117 if (value) {
118 if (env_value) {
119 strncpy(env_value, value, 1024);
120 env_value[1023] = '\0';
121 }
122 return 0;
123 }
124
125 return 1;
126 }
127
vaDisplayIsValid(VADisplay dpy)128 int vaDisplayIsValid(VADisplay dpy)
129 {
130 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
131 return pDisplayContext &&
132 pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC &&
133 pDisplayContext->pDriverContext;
134 }
135
136 /*
137 * Global log level configured from the config file or environment, which sets
138 * whether default logging appears or not (always overridden by explicitly
139 * user-configured logging).
140 */
141 static int default_log_level = 2;
142
default_log_error(void * user_context,const char * buffer)143 static void default_log_error(void *user_context, const char *buffer)
144 {
145 if (default_log_level < 1)
146 return;
147 # ifdef ANDROID
148 ALOGE("%s", buffer);
149 # else
150 fprintf(stderr, "libva error: %s", buffer);
151 # endif
152 }
153
default_log_info(void * user_context,const char * buffer)154 static void default_log_info(void *user_context, const char *buffer)
155 {
156 if (default_log_level < 2)
157 return;
158 # ifdef ANDROID
159 ALOGI("%s", buffer);
160 # else
161 fprintf(stderr, "libva info: %s", buffer);
162 # endif
163 }
164
165 /**
166 * Set the callback for error messages, or NULL for no logging.
167 * Returns the previous one, or NULL if it was disabled.
168 */
vaSetErrorCallback(VADisplay dpy,VAMessageCallback callback,void * user_context)169 VAMessageCallback vaSetErrorCallback(VADisplay dpy, VAMessageCallback callback, void *user_context)
170 {
171 VADisplayContextP dctx;
172 VAMessageCallback old_callback;
173
174 if (!vaDisplayIsValid(dpy))
175 return NULL;
176
177 dctx = (VADisplayContextP)dpy;
178 old_callback = dctx->error_callback;
179
180 dctx->error_callback = callback;
181 dctx->error_callback_user_context = user_context;
182
183 return old_callback;
184 }
185
186 /**
187 * Set the callback for info messages, or NULL for no logging.
188 * Returns the previous one, or NULL if it was disabled.
189 */
vaSetInfoCallback(VADisplay dpy,VAMessageCallback callback,void * user_context)190 VAMessageCallback vaSetInfoCallback(VADisplay dpy, VAMessageCallback callback, void *user_context)
191 {
192 VADisplayContextP dctx;
193 VAMessageCallback old_callback;
194
195 if (!vaDisplayIsValid(dpy))
196 return NULL;
197
198 dctx = (VADisplayContextP)dpy;
199 old_callback = dctx->info_callback;
200
201 dctx->info_callback = callback;
202 dctx->info_callback_user_context = user_context;
203
204 return old_callback;
205 }
206
va_MessagingInit()207 static void va_MessagingInit()
208 {
209 char env_value[1024];
210 int ret;
211
212 if (va_parseConfig("LIBVA_MESSAGING_LEVEL", &env_value[0]) == 0) {
213 ret = sscanf(env_value, "%d", &default_log_level);
214 if (ret < 1 || default_log_level < 0 || default_log_level > 2)
215 default_log_level = 2;
216 }
217 }
218
va_errorMessage(VADisplay dpy,const char * msg,...)219 void va_errorMessage(VADisplay dpy, const char *msg, ...)
220 {
221 VADisplayContextP dctx = (VADisplayContextP)dpy;
222 char buf[512], *dynbuf;
223 va_list args;
224 int n, len;
225
226 if (dctx->error_callback == NULL)
227 return;
228
229 va_start(args, msg);
230 len = vsnprintf(buf, sizeof(buf), msg, args);
231 va_end(args);
232
233 if (len >= (int)sizeof(buf)) {
234 dynbuf = malloc(len + 1);
235 if (!dynbuf)
236 return;
237 va_start(args, msg);
238 n = vsnprintf(dynbuf, len + 1, msg, args);
239 va_end(args);
240 if (n == len)
241 dctx->error_callback(dctx->error_callback_user_context, dynbuf);
242 free(dynbuf);
243 } else if (len > 0)
244 dctx->error_callback(dctx->error_callback_user_context, buf);
245 }
246
va_infoMessage(VADisplay dpy,const char * msg,...)247 void va_infoMessage(VADisplay dpy, const char *msg, ...)
248 {
249 VADisplayContextP dctx = (VADisplayContextP)dpy;
250 char buf[512], *dynbuf;
251 va_list args;
252 int n, len;
253
254 if (dctx->info_callback == NULL)
255 return;
256
257 va_start(args, msg);
258 len = vsnprintf(buf, sizeof(buf), msg, args);
259 va_end(args);
260
261 if (len >= (int)sizeof(buf)) {
262 dynbuf = malloc(len + 1);
263 if (!dynbuf)
264 return;
265 va_start(args, msg);
266 n = vsnprintf(dynbuf, len + 1, msg, args);
267 va_end(args);
268 if (n == len)
269 dctx->info_callback(dctx->info_callback_user_context, dynbuf);
270 free(dynbuf);
271 } else if (len > 0)
272 dctx->info_callback(dctx->info_callback_user_context, buf);
273 }
274
va_driverErrorCallback(VADriverContextP ctx,const char * message)275 static void va_driverErrorCallback(VADriverContextP ctx,
276 const char *message)
277 {
278 VADisplayContextP dctx = ctx->pDisplayContext;
279 if (!dctx)
280 return;
281 dctx->error_callback(dctx->error_callback_user_context, message);
282 }
283
va_driverInfoCallback(VADriverContextP ctx,const char * message)284 static void va_driverInfoCallback(VADriverContextP ctx,
285 const char *message)
286 {
287 VADisplayContextP dctx = ctx->pDisplayContext;
288 if (!dctx)
289 return;
290 dctx->info_callback(dctx->info_callback_user_context, message);
291 }
292
va_newDisplayContext(void)293 VADisplayContextP va_newDisplayContext(void)
294 {
295 VADisplayContextP dctx = calloc(1, sizeof(*dctx));
296 if (!dctx)
297 return NULL;
298
299 dctx->vadpy_magic = VA_DISPLAY_MAGIC;
300
301 dctx->error_callback = default_log_error;
302 dctx->info_callback = default_log_info;
303
304 return dctx;
305 }
306
va_newDriverContext(VADisplayContextP dctx)307 VADriverContextP va_newDriverContext(VADisplayContextP dctx)
308 {
309 VADriverContextP ctx = calloc(1, sizeof(*ctx));
310 if (!ctx)
311 return NULL;
312
313 dctx->pDriverContext = ctx;
314 ctx->pDisplayContext = dctx;
315
316 ctx->error_callback = va_driverErrorCallback;
317 ctx->info_callback = va_driverInfoCallback;
318
319 return ctx;
320 }
321
va_checkVtable(VADisplay dpy,void * ptr,char * function)322 static bool va_checkVtable(VADisplay dpy, void *ptr, char *function)
323 {
324 if (!ptr) {
325 va_errorMessage(dpy, "No valid vtable entry for va%s\n", function);
326 return false;
327 }
328 return true;
329 }
330
va_checkMaximum(VADisplay dpy,int value,char * variable)331 static bool va_checkMaximum(VADisplay dpy, int value, char *variable)
332 {
333 if (!value) {
334 va_errorMessage(dpy, "Failed to define max_%s in init\n", variable);
335 return false;
336 }
337 return true;
338 }
339
va_checkString(VADisplay dpy,const char * value,char * variable)340 static bool va_checkString(VADisplay dpy, const char* value, char *variable)
341 {
342 if (!value) {
343 va_errorMessage(dpy, "Failed to define str_%s in init\n", variable);
344 return false;
345 }
346 return true;
347 }
348
349 static inline int
va_getDriverInitName(char * name,int namelen,int major,int minor)350 va_getDriverInitName(char *name, int namelen, int major, int minor)
351 {
352 int ret = snprintf(name, namelen, "__vaDriverInit_%d_%d", major, minor);
353 return ret > 0 && ret < namelen;
354 }
355
va_getDriverPath(const char * driver_dir,const char * driver_name)356 static char *va_getDriverPath(const char *driver_dir, const char *driver_name)
357 {
358 int n = snprintf(0, 0, DRIVER_PATH_STRING, driver_dir, driver_name, DRIVER_EXTENSION);
359 if (n < 0)
360 return NULL;
361 char *driver_path = (char *) malloc(n + 1);
362 if (!driver_path)
363 return NULL;
364 n = snprintf(driver_path, n + 1, DRIVER_PATH_STRING,
365 driver_dir, driver_name, DRIVER_EXTENSION);
366 if (n < 0) {
367 free(driver_path);
368 return NULL;
369 }
370 return driver_path;
371 }
372
va_openDriver(VADisplay dpy,char * driver_name)373 static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
374 {
375 VADriverContextP ctx = CTX(dpy);
376 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
377 char *search_path = NULL;
378 char *saveptr;
379 char *driver_dir;
380
381 if (geteuid() == getuid())
382 /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
383 search_path = secure_getenv("LIBVA_DRIVERS_PATH");
384 if (!search_path)
385 search_path = VA_DRIVERS_PATH;
386
387 search_path = strdup((const char *)search_path);
388 if (!search_path) {
389 va_errorMessage(dpy, "%s L%d Out of memory\n",
390 __FUNCTION__, __LINE__);
391 return VA_STATUS_ERROR_ALLOCATION_FAILED;
392 }
393 driver_dir = strtok_r(search_path, ENV_VAR_SEPARATOR, &saveptr);
394 while (driver_dir) {
395 void *handle = NULL;
396 char *driver_path = va_getDriverPath(driver_dir, driver_name);
397 if (!driver_path) {
398 va_errorMessage(dpy, "%s L%d Out of memory\n",
399 __FUNCTION__, __LINE__);
400 free(search_path);
401 return VA_STATUS_ERROR_ALLOCATION_FAILED;
402 }
403
404 va_infoMessage(dpy, "Trying to open %s\n", driver_path);
405 #if defined(RTLD_NODELETE) && !defined(ANDROID)
406 handle = dlopen(driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
407 #else
408 handle = dlopen(driver_path, RTLD_NOW | RTLD_GLOBAL);
409 #endif
410 if (!handle) {
411 /* Don't give errors for non-existing files */
412 if (0 == access(driver_path, F_OK))
413 va_errorMessage(dpy, "dlopen of %s failed: %s\n", driver_path, dlerror());
414 } else {
415 VADriverInit init_func = NULL;
416 char init_func_s[256];
417 int i;
418
419 struct {
420 int major;
421 int minor;
422 } compatible_versions[VA_MINOR_VERSION + 2];
423 for (i = 0; i <= VA_MINOR_VERSION; i ++) {
424 compatible_versions[i].major = VA_MAJOR_VERSION;
425 compatible_versions[i].minor = VA_MINOR_VERSION - i;
426 }
427 compatible_versions[i].major = -1;
428 compatible_versions[i].minor = -1;
429
430 for (i = 0; compatible_versions[i].major >= 0; i++) {
431 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
432 compatible_versions[i].major,
433 compatible_versions[i].minor)) {
434 init_func = (VADriverInit)dlsym(handle, init_func_s);
435 if (init_func) {
436 va_infoMessage(dpy, "Found init function %s\n", init_func_s);
437 break;
438 }
439 }
440 }
441
442 if (compatible_versions[i].major < 0) {
443 va_errorMessage(dpy, "%s has no function %s\n",
444 driver_path, init_func_s);
445 dlclose(handle);
446 } else {
447 struct VADriverVTable *vtable = ctx->vtable;
448 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
449 struct VADriverVTableProt *vtable_prot = ctx->vtable_prot;
450
451 vaStatus = VA_STATUS_SUCCESS;
452 if (!vtable) {
453 vtable = calloc(1, sizeof(*vtable));
454 if (!vtable)
455 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
456 }
457 ctx->vtable = vtable;
458
459 if (!vtable_vpp) {
460 vtable_vpp = calloc(1, sizeof(*vtable_vpp));
461 if (vtable_vpp)
462 vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
463 else
464 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
465 }
466 ctx->vtable_vpp = vtable_vpp;
467
468 if (!vtable_prot) {
469 vtable_prot = calloc(1, sizeof(*vtable_prot));
470 if (vtable_prot)
471 vtable_prot->version = VA_DRIVER_VTABLE_PROT_VERSION;
472 else
473 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
474 }
475 ctx->vtable_prot = vtable_prot;
476
477 if (init_func && VA_STATUS_SUCCESS == vaStatus)
478 vaStatus = (*init_func)(ctx);
479
480 if (VA_STATUS_SUCCESS == vaStatus) {
481 CHECK_MAXIMUM(vaStatus, ctx, profiles);
482 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
483 CHECK_MAXIMUM(vaStatus, ctx, attributes);
484 CHECK_MAXIMUM(vaStatus, ctx, image_formats);
485 CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
486 CHECK_STRING(vaStatus, ctx, vendor);
487 CHECK_VTABLE(vaStatus, ctx, Terminate);
488 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
489 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
490 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
491 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
492 CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
493 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
494 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
495 CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
496 CHECK_VTABLE(vaStatus, ctx, CreateContext);
497 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
498 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
499 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
500 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
501 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
502 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
503 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
504 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
505 CHECK_VTABLE(vaStatus, ctx, EndPicture);
506 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
507 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
508 CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
509 CHECK_VTABLE(vaStatus, ctx, CreateImage);
510 CHECK_VTABLE(vaStatus, ctx, DeriveImage);
511 CHECK_VTABLE(vaStatus, ctx, DestroyImage);
512 CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
513 CHECK_VTABLE(vaStatus, ctx, GetImage);
514 CHECK_VTABLE(vaStatus, ctx, PutImage);
515 CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
516 CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
517 CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
518 CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
519 CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
520 CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
521 CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
522 CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
523 CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
524 CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
525 CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
526 }
527 if (VA_STATUS_SUCCESS != vaStatus) {
528 va_errorMessage(dpy, "%s init failed\n", driver_path);
529 dlclose(handle);
530 }
531 if (VA_STATUS_SUCCESS == vaStatus)
532 ctx->handle = handle;
533 free(driver_path);
534 break;
535 }
536 }
537 free(driver_path);
538
539 driver_dir = strtok_r(NULL, ENV_VAR_SEPARATOR, &saveptr);
540 }
541
542 free(search_path);
543
544 return vaStatus;
545 }
546
vaGetLibFunc(VADisplay dpy,const char * func)547 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
548 {
549 VADriverContextP ctx;
550 if (!vaDisplayIsValid(dpy))
551 return NULL;
552 ctx = CTX(dpy);
553
554 if (NULL == ctx->handle)
555 return NULL;
556
557 return (VAPrivFunc) dlsym(ctx->handle, func);
558 }
559
560
561 /*
562 * Returns a short english description of error_status
563 */
vaErrorStr(VAStatus error_status)564 const char *vaErrorStr(VAStatus error_status)
565 {
566 switch (error_status) {
567 case VA_STATUS_SUCCESS:
568 return "success (no error)";
569 case VA_STATUS_ERROR_OPERATION_FAILED:
570 return "operation failed";
571 case VA_STATUS_ERROR_ALLOCATION_FAILED:
572 return "resource allocation failed";
573 case VA_STATUS_ERROR_INVALID_DISPLAY:
574 return "invalid VADisplay";
575 case VA_STATUS_ERROR_INVALID_CONFIG:
576 return "invalid VAConfigID";
577 case VA_STATUS_ERROR_INVALID_CONTEXT:
578 return "invalid VAContextID";
579 case VA_STATUS_ERROR_INVALID_SURFACE:
580 return "invalid VASurfaceID";
581 case VA_STATUS_ERROR_INVALID_BUFFER:
582 return "invalid VABufferID";
583 case VA_STATUS_ERROR_INVALID_IMAGE:
584 return "invalid VAImageID";
585 case VA_STATUS_ERROR_INVALID_SUBPICTURE:
586 return "invalid VASubpictureID";
587 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
588 return "attribute not supported";
589 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
590 return "list argument exceeds maximum number";
591 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
592 return "the requested VAProfile is not supported";
593 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
594 return "the requested VAEntryPoint is not supported";
595 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
596 return "the requested RT Format is not supported";
597 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
598 return "the requested VABufferType is not supported";
599 case VA_STATUS_ERROR_SURFACE_BUSY:
600 return "surface is in use";
601 case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
602 return "flag not supported";
603 case VA_STATUS_ERROR_INVALID_PARAMETER:
604 return "invalid parameter";
605 case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
606 return "resolution not supported";
607 case VA_STATUS_ERROR_UNIMPLEMENTED:
608 return "the requested function is not implemented";
609 case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
610 return "surface is in displaying (may by overlay)" ;
611 case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
612 return "invalid VAImageFormat";
613 case VA_STATUS_ERROR_DECODING_ERROR:
614 return "internal decoding error";
615 case VA_STATUS_ERROR_ENCODING_ERROR:
616 return "internal encoding error";
617 case VA_STATUS_ERROR_INVALID_VALUE:
618 return "an invalid/unsupported value was supplied";
619 case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
620 return "the requested filter is not supported";
621 case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
622 return "an invalid filter chain was supplied";
623 case VA_STATUS_ERROR_HW_BUSY:
624 return "HW busy now";
625 case VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE:
626 return "an unsupported memory type was supplied";
627 case VA_STATUS_ERROR_NOT_ENOUGH_BUFFER:
628 return "allocated memory size is not enough for input or output";
629 case VA_STATUS_ERROR_UNKNOWN:
630 return "unknown libva error";
631 }
632 return "unknown libva error / description missing";
633 }
634
vaSetDriverName(VADisplay dpy,char * driver_name)635 VAStatus vaSetDriverName(
636 VADisplay dpy,
637 char *driver_name
638 )
639 {
640 VADriverContextP ctx;
641 VAStatus vaStatus = VA_STATUS_SUCCESS;
642 char *override_driver_name = NULL;
643 ctx = CTX(dpy);
644
645 if (strlen(driver_name) == 0 || strlen(driver_name) >= 256) {
646 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
647 va_errorMessage(dpy, "vaSetDriverName returns %s\n",
648 vaErrorStr(vaStatus));
649 return vaStatus;
650 }
651
652 override_driver_name = strdup(driver_name);
653 if (!override_driver_name) {
654 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
655 va_errorMessage(dpy, "vaSetDriverName returns %s. Out of Memory\n",
656 vaErrorStr(vaStatus));
657 return vaStatus;
658 }
659
660 ctx->override_driver_name = override_driver_name;
661 return VA_STATUS_SUCCESS;
662 }
663
va_new_opendriver(VADisplay dpy)664 static VAStatus va_new_opendriver(VADisplay dpy)
665 {
666 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
667 /* In the extreme case we can get up-to 5ish names. Pad that out to be on
668 * the safe side. In the worst case, the DRIVER BUG below will print and
669 * we'll be capped to the current selection.
670 */
671 char *drivers[20] = { 0, };
672 unsigned int num_drivers = ARRAY_SIZE(drivers);
673 VAStatus vaStatus;
674 const char *driver_name_env;
675 VADriverContextP ctx;
676
677 /* XXX: The order is bonkers - env var should take highest priority, then
678 * override (which ought to be nuked) than native. It's not possible atm,
679 * since the DPY connect/init happens during the GetDriverNames.
680 */
681 vaStatus = pDisplayContext->vaGetDriverNames(pDisplayContext, drivers, &num_drivers);
682 if (vaStatus != VA_STATUS_SUCCESS) {
683 /* Print and error yet continue, as per the above ordering note */
684 va_errorMessage(dpy, "vaGetDriverNames() failed with %s\n", vaErrorStr(vaStatus));
685 num_drivers = 0;
686 }
687
688 ctx = CTX(dpy);
689 driver_name_env = secure_getenv("LIBVA_DRIVER_NAME");
690
691 if ((ctx->override_driver_name) || (driver_name_env && (geteuid() == getuid()))) {
692 const char *driver = ctx->override_driver_name ?
693 ctx->override_driver_name : driver_name_env;
694
695 for (unsigned int i = 0; i < num_drivers; i++)
696 free(drivers[i]);
697
698 drivers[0] = strdup(driver);
699 num_drivers = 1;
700
701 va_infoMessage(dpy, "User %srequested driver '%s'\n",
702 ctx->override_driver_name ? "" : "environment variable ",
703 driver);
704 }
705
706 for (unsigned int i = 0; i < num_drivers; i++) {
707 /* The strdup() may have failed. Check here instead of a dozen+ places */
708 if (!drivers[i]) {
709 va_errorMessage(dpy, "%s:%d: Out of memory\n", __func__, __LINE__);
710 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
711 break;
712 }
713
714 vaStatus = va_openDriver(dpy, drivers[i]);
715 va_infoMessage(dpy, "va_openDriver() returns %d\n", vaStatus);
716
717 if (vaStatus == VA_STATUS_SUCCESS)
718 break;
719 }
720
721 for (unsigned int i = 0; i < num_drivers; i++)
722 free(drivers[i]);
723
724 return vaStatus;
725 }
726
vaInitialize(VADisplay dpy,int * major_version,int * minor_version)727 VAStatus vaInitialize(
728 VADisplay dpy,
729 int *major_version, /* out */
730 int *minor_version /* out */
731 )
732 {
733 VAStatus vaStatus;
734
735 CHECK_DISPLAY(dpy);
736
737 va_TraceInit(dpy);
738
739 va_MessagingInit();
740
741 va_infoMessage(dpy, "VA-API version %s\n", VA_VERSION_S);
742
743 vaStatus = va_new_opendriver(dpy);
744
745 *major_version = VA_MAJOR_VERSION;
746 *minor_version = VA_MINOR_VERSION;
747
748 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
749 VA_TRACE_RET(dpy, vaStatus);
750 return vaStatus;
751 }
752
753
754 /*
755 * After this call, all library internal resources will be cleaned up
756 */
vaTerminate(VADisplay dpy)757 VAStatus vaTerminate(
758 VADisplay dpy
759 )
760 {
761 VAStatus vaStatus = VA_STATUS_SUCCESS;
762 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
763 VADriverContextP old_ctx;
764
765 CHECK_DISPLAY(dpy);
766 old_ctx = CTX(dpy);
767
768 if (old_ctx->handle) {
769 vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
770 dlclose(old_ctx->handle);
771 old_ctx->handle = NULL;
772 }
773 free(old_ctx->vtable);
774 old_ctx->vtable = NULL;
775 free(old_ctx->vtable_vpp);
776 old_ctx->vtable_vpp = NULL;
777 free(old_ctx->vtable_prot);
778 old_ctx->vtable_prot = NULL;
779
780 if (old_ctx->override_driver_name) {
781 free(old_ctx->override_driver_name);
782 old_ctx->override_driver_name = NULL;
783 }
784
785 VA_TRACE_LOG(va_TraceTerminate, dpy);
786 VA_TRACE_RET(dpy, vaStatus);
787
788 va_TraceEnd(dpy);
789
790 if (VA_STATUS_SUCCESS == vaStatus)
791 pDisplayContext->vaDestroy(pDisplayContext);
792
793 return vaStatus;
794 }
795
796 /*
797 * vaQueryVendorString returns a pointer to a zero-terminated string
798 * describing some aspects of the VA implemenation on a specific
799 * hardware accelerator. The format of the returned string is:
800 * <vendorname>-<major_version>-<minor_version>-<addtional_info>
801 * e.g. for the Intel GMA500 implementation, an example would be:
802 * "IntelGMA500-1.0-0.2-patch3
803 */
vaQueryVendorString(VADisplay dpy)804 const char *vaQueryVendorString(
805 VADisplay dpy
806 )
807 {
808 if (!vaDisplayIsValid(dpy))
809 return NULL;
810
811 return CTX(dpy)->str_vendor;
812 }
813
814
815 /* Get maximum number of profiles supported by the implementation */
vaMaxNumProfiles(VADisplay dpy)816 int vaMaxNumProfiles(
817 VADisplay dpy
818 )
819 {
820 if (!vaDisplayIsValid(dpy))
821 return 0;
822
823 return CTX(dpy)->max_profiles;
824 }
825
826 /* Get maximum number of entrypoints supported by the implementation */
vaMaxNumEntrypoints(VADisplay dpy)827 int vaMaxNumEntrypoints(
828 VADisplay dpy
829 )
830 {
831 if (!vaDisplayIsValid(dpy))
832 return 0;
833
834 return CTX(dpy)->max_entrypoints;
835 }
836
837
838 /* Get maximum number of attributs supported by the implementation */
vaMaxNumConfigAttributes(VADisplay dpy)839 int vaMaxNumConfigAttributes(
840 VADisplay dpy
841 )
842 {
843 if (!vaDisplayIsValid(dpy))
844 return 0;
845
846 return CTX(dpy)->max_attributes;
847 }
848
vaQueryConfigEntrypoints(VADisplay dpy,VAProfile profile,VAEntrypoint * entrypoints,int * num_entrypoints)849 VAStatus vaQueryConfigEntrypoints(
850 VADisplay dpy,
851 VAProfile profile,
852 VAEntrypoint *entrypoints, /* out */
853 int *num_entrypoints /* out */
854 )
855 {
856 VADriverContextP ctx;
857 VAStatus vaStatus = VA_STATUS_SUCCESS;
858 CHECK_DISPLAY(dpy);
859 ctx = CTX(dpy);
860
861 vaStatus = ctx->vtable->vaQueryConfigEntrypoints(ctx, profile, entrypoints, num_entrypoints);
862 VA_TRACE_RET(dpy, vaStatus);
863 return vaStatus;
864 }
865
vaGetConfigAttributes(VADisplay dpy,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs)866 VAStatus vaGetConfigAttributes(
867 VADisplay dpy,
868 VAProfile profile,
869 VAEntrypoint entrypoint,
870 VAConfigAttrib *attrib_list, /* in/out */
871 int num_attribs
872 )
873 {
874 VADriverContextP ctx;
875 VAStatus vaStatus = VA_STATUS_SUCCESS;
876 CHECK_DISPLAY(dpy);
877 ctx = CTX(dpy);
878
879 vaStatus = ctx->vtable->vaGetConfigAttributes(ctx, profile, entrypoint, attrib_list, num_attribs);
880 VA_TRACE_RET(dpy, vaStatus);
881 return vaStatus;
882 }
883
vaQueryConfigProfiles(VADisplay dpy,VAProfile * profile_list,int * num_profiles)884 VAStatus vaQueryConfigProfiles(
885 VADisplay dpy,
886 VAProfile *profile_list, /* out */
887 int *num_profiles /* out */
888 )
889 {
890 VADriverContextP ctx;
891 VAStatus vaStatus = VA_STATUS_SUCCESS;
892 CHECK_DISPLAY(dpy);
893 ctx = CTX(dpy);
894
895 vaStatus = ctx->vtable->vaQueryConfigProfiles(ctx, profile_list, num_profiles);
896 VA_TRACE_RET(dpy, vaStatus);
897 return vaStatus;
898 }
899
vaCreateConfig(VADisplay dpy,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs,VAConfigID * config_id)900 VAStatus vaCreateConfig(
901 VADisplay dpy,
902 VAProfile profile,
903 VAEntrypoint entrypoint,
904 VAConfigAttrib *attrib_list,
905 int num_attribs,
906 VAConfigID *config_id /* out */
907 )
908 {
909 VADriverContextP ctx;
910 VAStatus vaStatus = VA_STATUS_SUCCESS;
911
912 CHECK_DISPLAY(dpy);
913 ctx = CTX(dpy);
914
915 VA_TRACE_VVVA(dpy, CREATE_CONFIG, TRACE_BEGIN, profile, entrypoint, num_attribs, attrib_list);
916 vaStatus = ctx->vtable->vaCreateConfig(ctx, profile, entrypoint, attrib_list, num_attribs, config_id);
917
918 /* record the current entrypoint for further trace/fool determination */
919 VA_TRACE_ALL(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
920 VA_TRACE_RET(dpy, vaStatus);
921 VA_TRACE_PV(dpy, CREATE_CONFIG, TRACE_END, config_id, vaStatus);
922 return vaStatus;
923 }
924
vaDestroyConfig(VADisplay dpy,VAConfigID config_id)925 VAStatus vaDestroyConfig(
926 VADisplay dpy,
927 VAConfigID config_id
928 )
929 {
930 VADriverContextP ctx;
931 VAStatus vaStatus = VA_STATUS_SUCCESS;
932
933 CHECK_DISPLAY(dpy);
934 ctx = CTX(dpy);
935
936 VA_TRACE_V(dpy, DESTROY_CONFIG, TRACE_BEGIN, config_id);
937 vaStatus = ctx->vtable->vaDestroyConfig(ctx, config_id);
938
939 VA_TRACE_ALL(va_TraceDestroyConfig, dpy, config_id);
940 VA_TRACE_RET(dpy, vaStatus);
941 VA_TRACE_V(dpy, DESTROY_CONFIG, TRACE_END, vaStatus);
942
943 return vaStatus;
944 }
945
vaQueryConfigAttributes(VADisplay dpy,VAConfigID config_id,VAProfile * profile,VAEntrypoint * entrypoint,VAConfigAttrib * attrib_list,int * num_attribs)946 VAStatus vaQueryConfigAttributes(
947 VADisplay dpy,
948 VAConfigID config_id,
949 VAProfile *profile, /* out */
950 VAEntrypoint *entrypoint, /* out */
951 VAConfigAttrib *attrib_list,/* out */
952 int *num_attribs /* out */
953 )
954 {
955 VADriverContextP ctx;
956 VAStatus vaStatus = VA_STATUS_SUCCESS;
957 CHECK_DISPLAY(dpy);
958 ctx = CTX(dpy);
959
960 vaStatus = ctx->vtable->vaQueryConfigAttributes(ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
961 VA_TRACE_RET(dpy, vaStatus);
962 return vaStatus;
963 }
964
vaQueryProcessingRate(VADisplay dpy,VAConfigID config_id,VAProcessingRateParameter * proc_buf,unsigned int * processing_rate)965 VAStatus vaQueryProcessingRate(
966 VADisplay dpy,
967 VAConfigID config_id,
968 VAProcessingRateParameter *proc_buf,
969 unsigned int *processing_rate /* out */
970 )
971 {
972 VADriverContextP ctx;
973 VAStatus vaStatus = VA_STATUS_SUCCESS;
974 CHECK_DISPLAY(dpy);
975 ctx = CTX(dpy);
976 if (!ctx->vtable->vaQueryProcessingRate)
977 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
978 else
979 vaStatus = ctx->vtable->vaQueryProcessingRate(ctx, config_id, proc_buf, processing_rate);
980 VA_TRACE_RET(dpy, vaStatus);
981 return vaStatus;
982 }
983
984 /* XXX: this is a slow implementation that will be removed */
985 static VAStatus
va_impl_query_surface_attributes(VADriverContextP ctx,VAConfigID config,VASurfaceAttrib * out_attribs,unsigned int * out_num_attribs_ptr)986 va_impl_query_surface_attributes(
987 VADriverContextP ctx,
988 VAConfigID config,
989 VASurfaceAttrib *out_attribs,
990 unsigned int *out_num_attribs_ptr
991 )
992 {
993 VASurfaceAttrib *attribs = NULL;
994 unsigned int num_attribs, n;
995 VASurfaceAttrib *out_attrib;
996 unsigned int out_num_attribs;
997 VAImageFormat *image_formats = NULL;
998 int num_image_formats, i;
999 VAStatus va_status;
1000
1001 /* List of surface attributes to query */
1002 struct va_surface_attrib_map {
1003 VASurfaceAttribType type;
1004 VAGenericValueType value_type;
1005 };
1006 static const struct va_surface_attrib_map attribs_map[] = {
1007 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
1008 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
1009 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
1010 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
1011 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
1012 { VASurfaceAttribNone, VAGenericValueTypeInteger }
1013 };
1014
1015 if (!out_attribs || !out_num_attribs_ptr)
1016 return VA_STATUS_ERROR_INVALID_PARAMETER;
1017 if (!ctx->vtable->vaGetSurfaceAttributes)
1018 return VA_STATUS_ERROR_UNIMPLEMENTED;
1019
1020 num_image_formats = ctx->max_image_formats;
1021 image_formats = malloc(num_image_formats * sizeof(*image_formats));
1022 if (!image_formats) {
1023 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1024 goto end;
1025 }
1026
1027 va_status = ctx->vtable->vaQueryImageFormats(
1028 ctx, image_formats, &num_image_formats);
1029 if (va_status != VA_STATUS_SUCCESS)
1030 goto end;
1031
1032 num_attribs = VASurfaceAttribCount + num_image_formats;
1033 attribs = malloc(num_attribs * sizeof(*attribs));
1034 if (!attribs) {
1035 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1036 goto end;
1037 }
1038
1039 /* Initialize with base surface attributes, except pixel-formats */
1040 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
1041 VASurfaceAttrib * const attrib = &attribs[n];
1042 attrib->type = attribs_map[n].type;
1043 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
1044 attrib->value.type = attribs_map[n].value_type;
1045 }
1046
1047 /* Append image formats */
1048 for (i = 0; i < num_image_formats; i++) {
1049 VASurfaceAttrib * const attrib = &attribs[n];
1050 attrib->type = VASurfaceAttribPixelFormat;
1051 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
1052 attrib->value.type = VAGenericValueTypeInteger;
1053 attrib->value.value.i = image_formats[i].fourcc;
1054 if (++n == num_attribs) {
1055 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1056 goto end;
1057 }
1058 }
1059 num_attribs = n;
1060
1061 va_status = ctx->vtable->vaGetSurfaceAttributes(
1062 ctx, config, attribs, num_attribs);
1063 if (va_status != VA_STATUS_SUCCESS)
1064 goto end;
1065
1066 /* Remove invalid entries */
1067 out_num_attribs = 0;
1068 for (n = 0; n < num_attribs; n++) {
1069 VASurfaceAttrib * const attrib = &attribs[n];
1070
1071 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
1072 continue;
1073
1074 // Accept all surface attributes that are not pixel-formats
1075 if (attrib->type != VASurfaceAttribPixelFormat) {
1076 out_num_attribs++;
1077 continue;
1078 }
1079
1080 // Drop invalid pixel-format attribute
1081 if (!attrib->value.value.i) {
1082 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
1083 continue;
1084 }
1085
1086 // Check for duplicates
1087 int is_duplicate = 0;
1088 for (i = n - 1; i >= 0 && !is_duplicate; i--) {
1089 const VASurfaceAttrib * const prev_attrib = &attribs[i];
1090 if (prev_attrib->type != VASurfaceAttribPixelFormat)
1091 break;
1092 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
1093 }
1094 if (is_duplicate)
1095 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
1096 else
1097 out_num_attribs++;
1098 }
1099
1100 if (*out_num_attribs_ptr < out_num_attribs) {
1101 *out_num_attribs_ptr = out_num_attribs;
1102 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1103 goto end;
1104 }
1105
1106 out_attrib = out_attribs;
1107 for (n = 0; n < num_attribs; n++) {
1108 const VASurfaceAttrib * const attrib = &attribs[n];
1109 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
1110 continue;
1111 *out_attrib++ = *attrib;
1112 }
1113
1114 end:
1115 free(attribs);
1116 free(image_formats);
1117 return va_status;
1118 }
1119
1120 VAStatus
vaQuerySurfaceAttributes(VADisplay dpy,VAConfigID config,VASurfaceAttrib * attrib_list,unsigned int * num_attribs)1121 vaQuerySurfaceAttributes(
1122 VADisplay dpy,
1123 VAConfigID config,
1124 VASurfaceAttrib *attrib_list,
1125 unsigned int *num_attribs
1126 )
1127 {
1128 VADriverContextP ctx;
1129 VAStatus vaStatus;
1130
1131 CHECK_DISPLAY(dpy);
1132 ctx = CTX(dpy);
1133 if (!ctx)
1134 return VA_STATUS_ERROR_INVALID_DISPLAY;
1135
1136 VA_TRACE_V(dpy, QUERY_SURFACE_ATTR, TRACE_BEGIN, config);
1137 if (!ctx->vtable->vaQuerySurfaceAttributes)
1138 vaStatus = va_impl_query_surface_attributes(ctx, config,
1139 attrib_list, num_attribs);
1140 else
1141 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
1142 attrib_list, num_attribs);
1143
1144 VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs);
1145 VA_TRACE_RET(dpy, vaStatus);
1146 VA_TRACE_PA(dpy, QUERY_SURFACE_ATTR, TRACE_END, num_attribs, attrib_list);
1147
1148 return vaStatus;
1149 }
1150
1151 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)1152 vaCreateSurfaces(
1153 VADisplay dpy,
1154 unsigned int format,
1155 unsigned int width,
1156 unsigned int height,
1157 VASurfaceID *surfaces,
1158 unsigned int num_surfaces,
1159 VASurfaceAttrib *attrib_list,
1160 unsigned int num_attribs
1161 )
1162 {
1163 VADriverContextP ctx;
1164 VAStatus vaStatus;
1165
1166 CHECK_DISPLAY(dpy);
1167 ctx = CTX(dpy);
1168 if (!ctx)
1169 return VA_STATUS_ERROR_INVALID_DISPLAY;
1170
1171 VA_TRACE_VVVVA(dpy, CREATE_SURFACE, TRACE_BEGIN, width, height, format, num_attribs, attrib_list);
1172 if (ctx->vtable->vaCreateSurfaces2)
1173 vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
1174 surfaces, num_surfaces,
1175 attrib_list, num_attribs);
1176 else if (attrib_list && num_attribs > 0)
1177 vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
1178 else
1179 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
1180 num_surfaces, surfaces);
1181 VA_TRACE_LOG(va_TraceCreateSurfaces,
1182 dpy, width, height, format, num_surfaces, surfaces,
1183 attrib_list, num_attribs);
1184 VA_TRACE_RET(dpy, vaStatus);
1185 VA_TRACE_VVA(dpy, CREATE_SURFACE, TRACE_END, vaStatus, num_surfaces, surfaces);
1186
1187 return vaStatus;
1188 }
1189
1190
vaDestroySurfaces(VADisplay dpy,VASurfaceID * surface_list,int num_surfaces)1191 VAStatus vaDestroySurfaces(
1192 VADisplay dpy,
1193 VASurfaceID *surface_list,
1194 int num_surfaces
1195 )
1196 {
1197 VADriverContextP ctx;
1198 VAStatus vaStatus;
1199
1200 CHECK_DISPLAY(dpy);
1201 ctx = CTX(dpy);
1202
1203 VA_TRACE_VA(dpy, DESTROY_SURFACE, TRACE_BEGIN, num_surfaces, surface_list);
1204 VA_TRACE_LOG(va_TraceDestroySurfaces,
1205 dpy, surface_list, num_surfaces);
1206
1207 vaStatus = ctx->vtable->vaDestroySurfaces(ctx, surface_list, num_surfaces);
1208 VA_TRACE_RET(dpy, vaStatus);
1209 VA_TRACE_V(dpy, DESTROY_SURFACE, TRACE_END, vaStatus);
1210
1211 return vaStatus;
1212 }
1213
vaCreateContext(VADisplay dpy,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID * render_targets,int num_render_targets,VAContextID * context)1214 VAStatus vaCreateContext(
1215 VADisplay dpy,
1216 VAConfigID config_id,
1217 int picture_width,
1218 int picture_height,
1219 int flag,
1220 VASurfaceID *render_targets,
1221 int num_render_targets,
1222 VAContextID *context /* out */
1223 )
1224 {
1225 VADriverContextP ctx;
1226 VAStatus vaStatus;
1227
1228 CHECK_DISPLAY(dpy);
1229 ctx = CTX(dpy);
1230
1231 VA_TRACE_VVVVVA(dpy, CREATE_CONTEXT, TRACE_BEGIN, config_id, picture_width, picture_height, flag, num_render_targets, render_targets);
1232 vaStatus = ctx->vtable->vaCreateContext(ctx, config_id, picture_width, picture_height,
1233 flag, render_targets, num_render_targets, context);
1234
1235 /* keep current encode/decode resoluton */
1236 VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
1237 VA_TRACE_RET(dpy, vaStatus);
1238 VA_TRACE_PV(dpy, CREATE_CONTEXT, TRACE_END, context, vaStatus);
1239
1240 return vaStatus;
1241 }
1242
vaDestroyContext(VADisplay dpy,VAContextID context)1243 VAStatus vaDestroyContext(
1244 VADisplay dpy,
1245 VAContextID context
1246 )
1247 {
1248 VADriverContextP ctx;
1249 VAStatus vaStatus;
1250
1251 CHECK_DISPLAY(dpy);
1252 ctx = CTX(dpy);
1253
1254 VA_TRACE_V(dpy, DESTROY_CONTEXT, TRACE_BEGIN, context);
1255 vaStatus = ctx->vtable->vaDestroyContext(ctx, context);
1256
1257 VA_TRACE_ALL(va_TraceDestroyContext, dpy, context);
1258 VA_TRACE_RET(dpy, vaStatus);
1259 VA_TRACE_V(dpy, DESTROY_CONTEXT, TRACE_END, vaStatus);
1260
1261 return vaStatus;
1262 }
1263
vaCreateMFContext(VADisplay dpy,VAMFContextID * mf_context)1264 VAStatus vaCreateMFContext(
1265 VADisplay dpy,
1266 VAMFContextID *mf_context /* out */
1267 )
1268 {
1269 VADriverContextP ctx;
1270 VAStatus vaStatus;
1271
1272 CHECK_DISPLAY(dpy);
1273 ctx = CTX(dpy);
1274 if (ctx->vtable->vaCreateMFContext == NULL)
1275 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1276 else {
1277 vaStatus = ctx->vtable->vaCreateMFContext(ctx, mf_context);
1278 VA_TRACE_ALL(va_TraceCreateMFContext, dpy, mf_context);
1279 }
1280
1281 VA_TRACE_RET(dpy, vaStatus);
1282 return vaStatus;
1283 }
1284
vaMFAddContext(VADisplay dpy,VAMFContextID mf_context,VAContextID context)1285 VAStatus vaMFAddContext(
1286 VADisplay dpy,
1287 VAMFContextID mf_context,
1288 VAContextID context
1289 )
1290 {
1291 VADriverContextP ctx;
1292 VAStatus vaStatus;
1293
1294 CHECK_DISPLAY(dpy);
1295 ctx = CTX(dpy);
1296
1297 if (ctx->vtable->vaMFAddContext == NULL)
1298 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1299 else {
1300 vaStatus = ctx->vtable->vaMFAddContext(ctx, context, mf_context);
1301 VA_TRACE_ALL(va_TraceMFAddContext, dpy, context, mf_context);
1302 }
1303
1304 VA_TRACE_RET(dpy, vaStatus);
1305 return vaStatus;
1306 }
1307
vaMFReleaseContext(VADisplay dpy,VAMFContextID mf_context,VAContextID context)1308 VAStatus vaMFReleaseContext(
1309 VADisplay dpy,
1310 VAMFContextID mf_context,
1311 VAContextID context
1312 )
1313 {
1314 VADriverContextP ctx;
1315 VAStatus vaStatus;
1316
1317 CHECK_DISPLAY(dpy);
1318 ctx = CTX(dpy);
1319 if (ctx->vtable->vaMFReleaseContext == NULL)
1320 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1321 else {
1322 vaStatus = ctx->vtable->vaMFReleaseContext(ctx, context, mf_context);
1323 VA_TRACE_ALL(va_TraceMFReleaseContext, dpy, context, mf_context);
1324 }
1325 VA_TRACE_RET(dpy, vaStatus);
1326
1327 return vaStatus;
1328 }
1329
vaMFSubmit(VADisplay dpy,VAMFContextID mf_context,VAContextID * contexts,int num_contexts)1330 VAStatus vaMFSubmit(
1331 VADisplay dpy,
1332 VAMFContextID mf_context,
1333 VAContextID *contexts,
1334 int num_contexts
1335 )
1336 {
1337 VADriverContextP ctx;
1338 VAStatus vaStatus;
1339
1340 CHECK_DISPLAY(dpy);
1341 ctx = CTX(dpy);
1342 CHECK_VTABLE(vaStatus, ctx, MFSubmit);
1343 if (ctx->vtable->vaMFSubmit == NULL)
1344 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1345 else {
1346 vaStatus = ctx->vtable->vaMFSubmit(ctx, mf_context, contexts, num_contexts);
1347 VA_TRACE_ALL(va_TraceMFSubmit, dpy, mf_context, contexts, num_contexts);
1348 }
1349 VA_TRACE_RET(dpy, vaStatus);
1350
1351 return vaStatus;
1352 }
1353
vaCreateBuffer(VADisplay dpy,VAContextID context,VABufferType type,unsigned int size,unsigned int num_elements,void * data,VABufferID * buf_id)1354 VAStatus vaCreateBuffer(
1355 VADisplay dpy,
1356 VAContextID context, /* in */
1357 VABufferType type, /* in */
1358 unsigned int size, /* in */
1359 unsigned int num_elements, /* in */
1360 void *data, /* in */
1361 VABufferID *buf_id /* out */
1362 )
1363 {
1364 VADriverContextP ctx;
1365 VAStatus vaStatus;
1366
1367 CHECK_DISPLAY(dpy);
1368 ctx = CTX(dpy);
1369
1370 VA_TRACE_VVVV(dpy, CREATE_BUFFER, TRACE_BEGIN, context, type, size, num_elements);
1371 vaStatus = ctx->vtable->vaCreateBuffer(ctx, context, type, size, num_elements, data, buf_id);
1372
1373 VA_TRACE_LOG(va_TraceCreateBuffer,
1374 dpy, context, type, size, num_elements, data, buf_id);
1375
1376 VA_TRACE_RET(dpy, vaStatus);
1377 VA_TRACE_PV(dpy, CREATE_BUFFER, TRACE_END, buf_id, vaStatus);
1378 return vaStatus;
1379 }
1380
vaCreateBuffer2(VADisplay dpy,VAContextID context,VABufferType type,unsigned int width,unsigned int height,unsigned int * unit_size,unsigned int * pitch,VABufferID * buf_id)1381 VAStatus vaCreateBuffer2(
1382 VADisplay dpy,
1383 VAContextID context,
1384 VABufferType type,
1385 unsigned int width,
1386 unsigned int height,
1387 unsigned int *unit_size,
1388 unsigned int *pitch,
1389 VABufferID *buf_id
1390 )
1391 {
1392 VADriverContextP ctx;
1393 VAStatus vaStatus;
1394
1395 CHECK_DISPLAY(dpy);
1396 ctx = CTX(dpy);
1397 if (!ctx->vtable->vaCreateBuffer2)
1398 return VA_STATUS_ERROR_UNIMPLEMENTED;
1399
1400 vaStatus = ctx->vtable->vaCreateBuffer2(ctx, context, type, width, height, unit_size, pitch, buf_id);
1401
1402 VA_TRACE_LOG(va_TraceCreateBuffer,
1403 dpy, context, type, *pitch, height, NULL, buf_id);
1404 VA_TRACE_RET(dpy, vaStatus);
1405
1406 return vaStatus;
1407 }
1408
vaBufferSetNumElements(VADisplay dpy,VABufferID buf_id,unsigned int num_elements)1409 VAStatus vaBufferSetNumElements(
1410 VADisplay dpy,
1411 VABufferID buf_id, /* in */
1412 unsigned int num_elements /* in */
1413 )
1414 {
1415 VADriverContextP ctx;
1416 VAStatus vaStatus = VA_STATUS_SUCCESS;
1417 CHECK_DISPLAY(dpy);
1418 ctx = CTX(dpy);
1419
1420 vaStatus = ctx->vtable->vaBufferSetNumElements(ctx, buf_id, num_elements);
1421 VA_TRACE_RET(dpy, vaStatus);
1422 return vaStatus;
1423 }
1424
1425
vaMapBuffer(VADisplay dpy,VABufferID buf_id,void ** pbuf)1426 VAStatus vaMapBuffer(
1427 VADisplay dpy,
1428 VABufferID buf_id, /* in */
1429 void **pbuf /* out */
1430 )
1431 {
1432 VADriverContextP ctx;
1433 VAStatus va_status = VA_STATUS_SUCCESS;
1434
1435 CHECK_DISPLAY(dpy);
1436 ctx = CTX(dpy);
1437
1438 if (ctx->vtable->vaMapBuffer2) {
1439 va_status = ctx->vtable->vaMapBuffer2(ctx, buf_id, pbuf, VA_MAPBUFFER_FLAG_DEFAULT);
1440 } else if (ctx->vtable->vaMapBuffer) {
1441 va_status = ctx->vtable->vaMapBuffer(ctx, buf_id, pbuf);
1442 }
1443
1444 VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf, VA_MAPBUFFER_FLAG_DEFAULT);
1445 VA_TRACE_RET(dpy, va_status);
1446
1447 return va_status;
1448 }
1449
vaMapBuffer2(VADisplay dpy,VABufferID buf_id,void ** pbuf,uint32_t flags)1450 VAStatus vaMapBuffer2(
1451 VADisplay dpy,
1452 VABufferID buf_id, /* in */
1453 void **pbuf, /* out */
1454 uint32_t flags /*in */
1455 )
1456 {
1457 VADriverContextP ctx;
1458 VAStatus va_status = VA_STATUS_SUCCESS;
1459
1460 CHECK_DISPLAY(dpy);
1461 ctx = CTX(dpy);
1462
1463 if (ctx->vtable->vaMapBuffer2) {
1464 va_status = ctx->vtable->vaMapBuffer2(ctx, buf_id, pbuf, flags);
1465 } else if (ctx->vtable->vaMapBuffer) {
1466 va_status = ctx->vtable->vaMapBuffer(ctx, buf_id, pbuf);
1467 }
1468
1469 VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf, flags);
1470 VA_TRACE_RET(dpy, va_status);
1471
1472 return va_status;
1473 }
1474
vaUnmapBuffer(VADisplay dpy,VABufferID buf_id)1475 VAStatus vaUnmapBuffer(
1476 VADisplay dpy,
1477 VABufferID buf_id /* in */
1478 )
1479 {
1480 VADriverContextP ctx;
1481 VAStatus vaStatus = VA_STATUS_SUCCESS;
1482 CHECK_DISPLAY(dpy);
1483 ctx = CTX(dpy);
1484
1485 vaStatus = ctx->vtable->vaUnmapBuffer(ctx, buf_id);
1486 VA_TRACE_RET(dpy, vaStatus);
1487 return vaStatus;
1488 }
1489
vaDestroyBuffer(VADisplay dpy,VABufferID buffer_id)1490 VAStatus vaDestroyBuffer(
1491 VADisplay dpy,
1492 VABufferID buffer_id
1493 )
1494 {
1495 VADriverContextP ctx;
1496 VAStatus vaStatus = VA_STATUS_SUCCESS;
1497 CHECK_DISPLAY(dpy);
1498 ctx = CTX(dpy);
1499
1500 VA_TRACE_V(dpy, DESTROY_BUFFER, TRACE_BEGIN, buffer_id);
1501 VA_TRACE_LOG(va_TraceDestroyBuffer,
1502 dpy, buffer_id);
1503
1504 vaStatus = ctx->vtable->vaDestroyBuffer(ctx, buffer_id);
1505 VA_TRACE_RET(dpy, vaStatus);
1506 VA_TRACE_V(dpy, DESTROY_BUFFER, TRACE_END, vaStatus);
1507 return vaStatus;
1508 }
1509
vaBufferInfo(VADisplay dpy,VAContextID context,VABufferID buf_id,VABufferType * type,unsigned int * size,unsigned int * num_elements)1510 VAStatus vaBufferInfo(
1511 VADisplay dpy,
1512 VAContextID context, /* in */
1513 VABufferID buf_id, /* in */
1514 VABufferType *type, /* out */
1515 unsigned int *size, /* out */
1516 unsigned int *num_elements /* out */
1517 )
1518 {
1519 VADriverContextP ctx;
1520 VAStatus vaStatus = VA_STATUS_SUCCESS;
1521
1522 CHECK_DISPLAY(dpy);
1523 ctx = CTX(dpy);
1524
1525 vaStatus = ctx->vtable->vaBufferInfo(ctx, buf_id, type, size, num_elements);
1526 VA_TRACE_RET(dpy, vaStatus);
1527 return vaStatus;
1528 }
1529
1530 /* Locks buffer for external API usage */
1531 VAStatus
vaAcquireBufferHandle(VADisplay dpy,VABufferID buf_id,VABufferInfo * buf_info)1532 vaAcquireBufferHandle(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info)
1533 {
1534 VADriverContextP ctx;
1535 VAStatus vaStatus = VA_STATUS_SUCCESS;
1536
1537 CHECK_DISPLAY(dpy);
1538 ctx = CTX(dpy);
1539
1540 if (!ctx->vtable->vaAcquireBufferHandle)
1541 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1542 else
1543 vaStatus = ctx->vtable->vaAcquireBufferHandle(ctx, buf_id, buf_info);
1544 VA_TRACE_RET(dpy, vaStatus);
1545 return vaStatus;
1546 }
1547
1548 /* Unlocks buffer after usage from external API */
1549 VAStatus
vaReleaseBufferHandle(VADisplay dpy,VABufferID buf_id)1550 vaReleaseBufferHandle(VADisplay dpy, VABufferID buf_id)
1551 {
1552 VADriverContextP ctx;
1553 VAStatus vaStatus = VA_STATUS_SUCCESS;
1554
1555 CHECK_DISPLAY(dpy);
1556 ctx = CTX(dpy);
1557
1558 if (!ctx->vtable->vaReleaseBufferHandle)
1559 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1560 else
1561 vaStatus = ctx->vtable->vaReleaseBufferHandle(ctx, buf_id);
1562 VA_TRACE_RET(dpy, vaStatus);
1563 return vaStatus;
1564 }
1565
1566 VAStatus
vaExportSurfaceHandle(VADisplay dpy,VASurfaceID surface_id,uint32_t mem_type,uint32_t flags,void * descriptor)1567 vaExportSurfaceHandle(VADisplay dpy, VASurfaceID surface_id,
1568 uint32_t mem_type, uint32_t flags,
1569 void *descriptor)
1570 {
1571 VADriverContextP ctx;
1572 VAStatus vaStatus = VA_STATUS_SUCCESS;
1573
1574 CHECK_DISPLAY(dpy);
1575 ctx = CTX(dpy);
1576
1577 if (!ctx->vtable->vaExportSurfaceHandle)
1578 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1579 else
1580 vaStatus = ctx->vtable->vaExportSurfaceHandle(ctx, surface_id,
1581 mem_type, flags,
1582 descriptor);
1583 VA_TRACE_LOG(va_TraceExportSurfaceHandle, dpy, surface_id, mem_type, flags, descriptor);
1584
1585 VA_TRACE_RET(dpy, vaStatus);
1586 return vaStatus;
1587 }
1588
vaBeginPicture(VADisplay dpy,VAContextID context,VASurfaceID render_target)1589 VAStatus vaBeginPicture(
1590 VADisplay dpy,
1591 VAContextID context,
1592 VASurfaceID render_target
1593 )
1594 {
1595 VADriverContextP ctx;
1596 VAStatus va_status;
1597
1598 CHECK_DISPLAY(dpy);
1599 ctx = CTX(dpy);
1600
1601 VA_TRACE_VV(dpy, BEGIN_PICTURE, TRACE_BEGIN, context, render_target);
1602 VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target);
1603
1604 va_status = ctx->vtable->vaBeginPicture(ctx, context, render_target);
1605 VA_TRACE_RET(dpy, va_status);
1606 VA_TRACE_V(dpy, BEGIN_PICTURE, TRACE_END, va_status);
1607
1608 return va_status;
1609 }
1610
vaRenderPicture(VADisplay dpy,VAContextID context,VABufferID * buffers,int num_buffers)1611 VAStatus vaRenderPicture(
1612 VADisplay dpy,
1613 VAContextID context,
1614 VABufferID *buffers,
1615 int num_buffers
1616 )
1617 {
1618 VADriverContextP ctx;
1619 VAStatus vaStatus = VA_STATUS_SUCCESS;
1620
1621 CHECK_DISPLAY(dpy);
1622 ctx = CTX(dpy);
1623
1624 VA_TRACE_VVA(dpy, RENDER_PICTURE, TRACE_BEGIN, context, num_buffers, buffers);
1625 VA_TRACE_BUFFERS(dpy, context, num_buffers, buffers);
1626 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1627
1628 vaStatus = ctx->vtable->vaRenderPicture(ctx, context, buffers, num_buffers);
1629 VA_TRACE_RET(dpy, vaStatus);
1630 VA_TRACE_V(dpy, RENDER_PICTURE, TRACE_END, vaStatus);
1631 return vaStatus;
1632 }
1633
vaEndPicture(VADisplay dpy,VAContextID context)1634 VAStatus vaEndPicture(
1635 VADisplay dpy,
1636 VAContextID context
1637 )
1638 {
1639 VAStatus va_status = VA_STATUS_SUCCESS;
1640 VADriverContextP ctx;
1641
1642 CHECK_DISPLAY(dpy);
1643 ctx = CTX(dpy);
1644
1645 VA_TRACE_V(dpy, END_PICTURE, TRACE_BEGIN, context);
1646 VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 0);
1647 va_status = ctx->vtable->vaEndPicture(ctx, context);
1648 VA_TRACE_RET(dpy, va_status);
1649 /* dump surface content */
1650 VA_TRACE_ALL(va_TraceEndPictureExt, dpy, context, 1);
1651 VA_TRACE_V(dpy, END_PICTURE, TRACE_END, va_status);
1652
1653 return va_status;
1654 }
1655
vaSyncSurface(VADisplay dpy,VASurfaceID render_target)1656 VAStatus vaSyncSurface(
1657 VADisplay dpy,
1658 VASurfaceID render_target
1659 )
1660 {
1661 VAStatus va_status;
1662 VADriverContextP ctx;
1663
1664 CHECK_DISPLAY(dpy);
1665 ctx = CTX(dpy);
1666
1667 VA_TRACE_V(dpy, SYNC_SURFACE, TRACE_BEGIN, render_target);
1668 va_status = ctx->vtable->vaSyncSurface(ctx, render_target);
1669 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1670 VA_TRACE_RET(dpy, va_status);
1671 VA_TRACE_V(dpy, SYNC_SURFACE, TRACE_END, va_status);
1672
1673 return va_status;
1674 }
1675
vaSyncSurface2(VADisplay dpy,VASurfaceID surface,uint64_t timeout_ns)1676 VAStatus vaSyncSurface2(
1677 VADisplay dpy,
1678 VASurfaceID surface,
1679 uint64_t timeout_ns
1680 )
1681 {
1682 VAStatus va_status;
1683 VADriverContextP ctx;
1684
1685 CHECK_DISPLAY(dpy);
1686 ctx = CTX(dpy);
1687
1688 VA_TRACE_VV(dpy, SYNC_SURFACE2, TRACE_BEGIN, surface, timeout_ns);
1689 if (ctx->vtable->vaSyncSurface2)
1690 va_status = ctx->vtable->vaSyncSurface2(ctx, surface, timeout_ns);
1691 else
1692 va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
1693 VA_TRACE_LOG(va_TraceSyncSurface2, dpy, surface, timeout_ns);
1694 VA_TRACE_RET(dpy, va_status);
1695 VA_TRACE_V(dpy, SYNC_SURFACE2, TRACE_END, va_status);
1696
1697 return va_status;
1698 }
1699
vaQuerySurfaceStatus(VADisplay dpy,VASurfaceID render_target,VASurfaceStatus * status)1700 VAStatus vaQuerySurfaceStatus(
1701 VADisplay dpy,
1702 VASurfaceID render_target,
1703 VASurfaceStatus *status /* out */
1704 )
1705 {
1706 VAStatus va_status;
1707 VADriverContextP ctx;
1708 CHECK_DISPLAY(dpy);
1709 ctx = CTX(dpy);
1710
1711 va_status = ctx->vtable->vaQuerySurfaceStatus(ctx, render_target, status);
1712
1713 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1714 VA_TRACE_RET(dpy, va_status);
1715
1716 return va_status;
1717 }
1718
vaQuerySurfaceError(VADisplay dpy,VASurfaceID surface,VAStatus error_status,void ** error_info)1719 VAStatus vaQuerySurfaceError(
1720 VADisplay dpy,
1721 VASurfaceID surface,
1722 VAStatus error_status,
1723 void **error_info /*out*/
1724 )
1725 {
1726 VAStatus va_status;
1727 VADriverContextP ctx;
1728 CHECK_DISPLAY(dpy);
1729 ctx = CTX(dpy);
1730
1731 va_status = ctx->vtable->vaQuerySurfaceError(ctx, surface, error_status, error_info);
1732
1733 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1734 VA_TRACE_RET(dpy, va_status);
1735
1736 return va_status;
1737 }
1738
vaSyncBuffer(VADisplay dpy,VABufferID buf_id,uint64_t timeout_ns)1739 VAStatus vaSyncBuffer(
1740 VADisplay dpy,
1741 VABufferID buf_id,
1742 uint64_t timeout_ns
1743 )
1744 {
1745 VAStatus va_status;
1746 VADriverContextP ctx;
1747
1748 CHECK_DISPLAY(dpy);
1749 ctx = CTX(dpy);
1750
1751 VA_TRACE_LOG(va_TraceSyncBuffer, dpy, buf_id, timeout_ns);
1752
1753 if (ctx->vtable->vaSyncBuffer)
1754 va_status = ctx->vtable->vaSyncBuffer(ctx, buf_id, timeout_ns);
1755 else
1756 va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
1757 VA_TRACE_RET(dpy, va_status);
1758
1759 return va_status;
1760 }
1761
1762 /* Get maximum number of image formats supported by the implementation */
vaMaxNumImageFormats(VADisplay dpy)1763 int vaMaxNumImageFormats(
1764 VADisplay dpy
1765 )
1766 {
1767 if (!vaDisplayIsValid(dpy))
1768 return 0;
1769
1770 return CTX(dpy)->max_image_formats;
1771 }
1772
vaQueryImageFormats(VADisplay dpy,VAImageFormat * format_list,int * num_formats)1773 VAStatus vaQueryImageFormats(
1774 VADisplay dpy,
1775 VAImageFormat *format_list, /* out */
1776 int *num_formats /* out */
1777 )
1778 {
1779 VADriverContextP ctx;
1780 CHECK_DISPLAY(dpy);
1781 ctx = CTX(dpy);
1782
1783 return ctx->vtable->vaQueryImageFormats(ctx, format_list, num_formats);
1784 }
1785
1786 /*
1787 * The width and height fields returned in the VAImage structure may get
1788 * enlarged for some YUV formats. The size of the data buffer that needs
1789 * to be allocated will be given in the "data_size" field in VAImage.
1790 * Image data is not allocated by this function. The client should
1791 * allocate the memory and fill in the VAImage structure's data field
1792 * after looking at "data_size" returned from the library.
1793 */
vaCreateImage(VADisplay dpy,VAImageFormat * format,int width,int height,VAImage * image)1794 VAStatus vaCreateImage(
1795 VADisplay dpy,
1796 VAImageFormat *format,
1797 int width,
1798 int height,
1799 VAImage *image /* out */
1800 )
1801 {
1802 VADriverContextP ctx;
1803 VAStatus va_status = VA_STATUS_SUCCESS;
1804 CHECK_DISPLAY(dpy);
1805 ctx = CTX(dpy);
1806
1807 va_status = ctx->vtable->vaCreateImage(ctx, format, width, height, image);
1808 VA_TRACE_RET(dpy, va_status);
1809 return va_status;
1810 }
1811
1812 /*
1813 * Should call DestroyImage before destroying the surface it is bound to
1814 */
vaDestroyImage(VADisplay dpy,VAImageID image)1815 VAStatus vaDestroyImage(
1816 VADisplay dpy,
1817 VAImageID image
1818 )
1819 {
1820 VADriverContextP ctx;
1821 VAStatus va_status = VA_STATUS_SUCCESS;
1822 CHECK_DISPLAY(dpy);
1823 ctx = CTX(dpy);
1824
1825 va_status = ctx->vtable->vaDestroyImage(ctx, image);
1826 VA_TRACE_RET(dpy, va_status);
1827 return va_status;
1828 }
1829
vaSetImagePalette(VADisplay dpy,VAImageID image,unsigned char * palette)1830 VAStatus vaSetImagePalette(
1831 VADisplay dpy,
1832 VAImageID image,
1833 unsigned char *palette
1834 )
1835 {
1836 VADriverContextP ctx;
1837 VAStatus va_status = VA_STATUS_SUCCESS;
1838 CHECK_DISPLAY(dpy);
1839 ctx = CTX(dpy);
1840
1841 va_status = ctx->vtable->vaSetImagePalette(ctx, image, palette);
1842 VA_TRACE_RET(dpy, va_status);
1843 return va_status;
1844 }
1845
1846 /*
1847 * Retrieve surface data into a VAImage
1848 * Image must be in a format supported by the implementation
1849 */
vaGetImage(VADisplay dpy,VASurfaceID surface,int x,int y,unsigned int width,unsigned int height,VAImageID image)1850 VAStatus vaGetImage(
1851 VADisplay dpy,
1852 VASurfaceID surface,
1853 int x, /* coordinates of the upper left source pixel */
1854 int y,
1855 unsigned int width, /* width and height of the region */
1856 unsigned int height,
1857 VAImageID image
1858 )
1859 {
1860 VADriverContextP ctx;
1861 VAStatus va_status = VA_STATUS_SUCCESS;
1862 CHECK_DISPLAY(dpy);
1863 ctx = CTX(dpy);
1864
1865 va_status = ctx->vtable->vaGetImage(ctx, surface, x, y, width, height, image);
1866 VA_TRACE_RET(dpy, va_status);
1867 return va_status;
1868 }
1869
1870 /*
1871 * Copy data from a VAImage to a surface
1872 * Image must be in a format supported by the implementation
1873 */
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)1874 VAStatus vaPutImage(
1875 VADisplay dpy,
1876 VASurfaceID surface,
1877 VAImageID image,
1878 int src_x,
1879 int src_y,
1880 unsigned int src_width,
1881 unsigned int src_height,
1882 int dest_x,
1883 int dest_y,
1884 unsigned int dest_width,
1885 unsigned int dest_height
1886 )
1887 {
1888 VADriverContextP ctx;
1889 VAStatus va_status = VA_STATUS_SUCCESS;
1890 CHECK_DISPLAY(dpy);
1891 ctx = CTX(dpy);
1892
1893 va_status = ctx->vtable->vaPutImage(ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height);
1894 VA_TRACE_RET(dpy, va_status);
1895 return va_status;
1896 }
1897
1898 /*
1899 * Derive an VAImage from an existing surface.
1900 * This interface will derive a VAImage and corresponding image buffer from
1901 * an existing VA Surface. The image buffer can then be mapped/unmapped for
1902 * direct CPU access. This operation is only possible on implementations with
1903 * direct rendering capabilities and internal surface formats that can be
1904 * represented with a VAImage. When the operation is not possible this interface
1905 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1906 * to using vaCreateImage + vaPutImage to accomplish the same task in an
1907 * indirect manner.
1908 *
1909 * Implementations should only return success when the resulting image buffer
1910 * would be useable with vaMap/Unmap.
1911 *
1912 * When directly accessing a surface special care must be taken to insure
1913 * proper synchronization with the graphics hardware. Clients should call
1914 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1915 * rendering or currently being displayed by an overlay.
1916 *
1917 * Additionally nothing about the contents of a surface should be assumed
1918 * following a vaPutSurface. Implementations are free to modify the surface for
1919 * scaling or subpicture blending within a call to vaPutImage.
1920 *
1921 * Calls to vaPutImage or vaGetImage using the same surface from which the image
1922 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1923 * vaGetImage with other surfaces is supported.
1924 *
1925 * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1926 * image and image buffer structures will be destroyed; however, the underlying
1927 * surface will remain unchanged until freed with vaDestroySurfaces.
1928 */
vaDeriveImage(VADisplay dpy,VASurfaceID surface,VAImage * image)1929 VAStatus vaDeriveImage(
1930 VADisplay dpy,
1931 VASurfaceID surface,
1932 VAImage *image /* out */
1933 )
1934 {
1935 VADriverContextP ctx;
1936 VAStatus va_status = VA_STATUS_SUCCESS;
1937 CHECK_DISPLAY(dpy);
1938 ctx = CTX(dpy);
1939
1940 va_status = ctx->vtable->vaDeriveImage(ctx, surface, image);
1941 VA_TRACE_RET(dpy, va_status);
1942 return va_status;
1943 }
1944
1945
1946 /* Get maximum number of subpicture formats supported by the implementation */
vaMaxNumSubpictureFormats(VADisplay dpy)1947 int vaMaxNumSubpictureFormats(
1948 VADisplay dpy
1949 )
1950 {
1951 if (!vaDisplayIsValid(dpy))
1952 return 0;
1953
1954 return CTX(dpy)->max_subpic_formats;
1955 }
1956
1957 /*
1958 * Query supported subpicture formats
1959 * The caller must provide a "format_list" array that can hold at
1960 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
1961 * for each format to indicate additional capabilities for that format. The actual
1962 * number of formats returned in "format_list" is returned in "num_formats".
1963 */
vaQuerySubpictureFormats(VADisplay dpy,VAImageFormat * format_list,unsigned int * flags,unsigned int * num_formats)1964 VAStatus vaQuerySubpictureFormats(
1965 VADisplay dpy,
1966 VAImageFormat *format_list, /* out */
1967 unsigned int *flags, /* out */
1968 unsigned int *num_formats /* out */
1969 )
1970 {
1971 VADriverContextP ctx;
1972
1973 CHECK_DISPLAY(dpy);
1974 ctx = CTX(dpy);
1975
1976 return ctx->vtable->vaQuerySubpictureFormats(ctx, format_list, flags, num_formats);
1977 }
1978
1979 /*
1980 * Subpictures are created with an image associated.
1981 */
vaCreateSubpicture(VADisplay dpy,VAImageID image,VASubpictureID * subpicture)1982 VAStatus vaCreateSubpicture(
1983 VADisplay dpy,
1984 VAImageID image,
1985 VASubpictureID *subpicture /* out */
1986 )
1987 {
1988 VADriverContextP ctx;
1989 CHECK_DISPLAY(dpy);
1990 ctx = CTX(dpy);
1991
1992 return ctx->vtable->vaCreateSubpicture(ctx, image, subpicture);
1993 }
1994
1995 /*
1996 * Destroy the subpicture before destroying the image it is assocated to
1997 */
vaDestroySubpicture(VADisplay dpy,VASubpictureID subpicture)1998 VAStatus vaDestroySubpicture(
1999 VADisplay dpy,
2000 VASubpictureID subpicture
2001 )
2002 {
2003 VADriverContextP ctx;
2004 CHECK_DISPLAY(dpy);
2005 ctx = CTX(dpy);
2006
2007 return ctx->vtable->vaDestroySubpicture(ctx, subpicture);
2008 }
2009
vaSetSubpictureImage(VADisplay dpy,VASubpictureID subpicture,VAImageID image)2010 VAStatus vaSetSubpictureImage(
2011 VADisplay dpy,
2012 VASubpictureID subpicture,
2013 VAImageID image
2014 )
2015 {
2016 VADriverContextP ctx;
2017 CHECK_DISPLAY(dpy);
2018 ctx = CTX(dpy);
2019
2020 return ctx->vtable->vaSetSubpictureImage(ctx, subpicture, image);
2021 }
2022
2023
2024 /*
2025 * If chromakey is enabled, then the area where the source value falls within
2026 * the chromakey [min, max] range is transparent
2027 */
vaSetSubpictureChromakey(VADisplay dpy,VASubpictureID subpicture,unsigned int chromakey_min,unsigned int chromakey_max,unsigned int chromakey_mask)2028 VAStatus vaSetSubpictureChromakey(
2029 VADisplay dpy,
2030 VASubpictureID subpicture,
2031 unsigned int chromakey_min,
2032 unsigned int chromakey_max,
2033 unsigned int chromakey_mask
2034 )
2035 {
2036 VADriverContextP ctx;
2037 CHECK_DISPLAY(dpy);
2038 ctx = CTX(dpy);
2039
2040 return ctx->vtable->vaSetSubpictureChromakey(ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask);
2041 }
2042
2043
2044 /*
2045 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
2046 * a value of 0 means fully transparent. If per-pixel alpha is also specified then
2047 * the overall alpha is per-pixel alpha multiplied by the global alpha
2048 */
vaSetSubpictureGlobalAlpha(VADisplay dpy,VASubpictureID subpicture,float global_alpha)2049 VAStatus vaSetSubpictureGlobalAlpha(
2050 VADisplay dpy,
2051 VASubpictureID subpicture,
2052 float global_alpha
2053 )
2054 {
2055 VADriverContextP ctx;
2056 CHECK_DISPLAY(dpy);
2057 ctx = CTX(dpy);
2058
2059 return ctx->vtable->vaSetSubpictureGlobalAlpha(ctx, subpicture, global_alpha);
2060 }
2061
2062 /*
2063 vaAssociateSubpicture associates the subpicture with the target_surface.
2064 It defines the region mapping between the subpicture and the target
2065 surface through source and destination rectangles (with the same width and height).
2066 Both will be displayed at the next call to vaPutSurface. Additional
2067 associations before the call to vaPutSurface simply overrides the association.
2068 */
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)2069 VAStatus vaAssociateSubpicture(
2070 VADisplay dpy,
2071 VASubpictureID subpicture,
2072 VASurfaceID *target_surfaces,
2073 int num_surfaces,
2074 short src_x, /* upper left offset in subpicture */
2075 short src_y,
2076 unsigned short src_width,
2077 unsigned short src_height,
2078 short dest_x, /* upper left offset in surface */
2079 short dest_y,
2080 unsigned short dest_width,
2081 unsigned short dest_height,
2082 /*
2083 * whether to enable chroma-keying or global-alpha
2084 * see VA_SUBPICTURE_XXX values
2085 */
2086 unsigned int flags
2087 )
2088 {
2089 VADriverContextP ctx;
2090 CHECK_DISPLAY(dpy);
2091 ctx = CTX(dpy);
2092
2093 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);
2094 }
2095
2096 /*
2097 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
2098 */
vaDeassociateSubpicture(VADisplay dpy,VASubpictureID subpicture,VASurfaceID * target_surfaces,int num_surfaces)2099 VAStatus vaDeassociateSubpicture(
2100 VADisplay dpy,
2101 VASubpictureID subpicture,
2102 VASurfaceID *target_surfaces,
2103 int num_surfaces
2104 )
2105 {
2106 VADriverContextP ctx;
2107 CHECK_DISPLAY(dpy);
2108 ctx = CTX(dpy);
2109
2110 return ctx->vtable->vaDeassociateSubpicture(ctx, subpicture, target_surfaces, num_surfaces);
2111 }
2112
2113
2114 /* Get maximum number of display attributes supported by the implementation */
vaMaxNumDisplayAttributes(VADisplay dpy)2115 int vaMaxNumDisplayAttributes(
2116 VADisplay dpy
2117 )
2118 {
2119 int tmp;
2120
2121 if (!vaDisplayIsValid(dpy))
2122 return 0;
2123
2124 tmp = CTX(dpy)->max_display_attributes;
2125
2126 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
2127
2128 return tmp;
2129 }
2130
2131 /*
2132 * Query display attributes
2133 * The caller must provide a "attr_list" array that can hold at
2134 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
2135 * returned in "attr_list" is returned in "num_attributes".
2136 */
vaQueryDisplayAttributes(VADisplay dpy,VADisplayAttribute * attr_list,int * num_attributes)2137 VAStatus vaQueryDisplayAttributes(
2138 VADisplay dpy,
2139 VADisplayAttribute *attr_list, /* out */
2140 int *num_attributes /* out */
2141 )
2142 {
2143 VADriverContextP ctx;
2144 VAStatus va_status;
2145
2146 CHECK_DISPLAY(dpy);
2147 ctx = CTX(dpy);
2148 va_status = ctx->vtable->vaQueryDisplayAttributes(ctx, attr_list, num_attributes);
2149
2150 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
2151 VA_TRACE_RET(dpy, va_status);
2152
2153 return va_status;
2154
2155 }
2156
2157 /*
2158 * Get display attributes
2159 * This function returns the current attribute values in "attr_list".
2160 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
2161 * from vaQueryDisplayAttributes() can have their values retrieved.
2162 */
vaGetDisplayAttributes(VADisplay dpy,VADisplayAttribute * attr_list,int num_attributes)2163 VAStatus vaGetDisplayAttributes(
2164 VADisplay dpy,
2165 VADisplayAttribute *attr_list, /* in/out */
2166 int num_attributes
2167 )
2168 {
2169 VADriverContextP ctx;
2170 VAStatus va_status;
2171
2172 CHECK_DISPLAY(dpy);
2173 ctx = CTX(dpy);
2174 va_status = ctx->vtable->vaGetDisplayAttributes(ctx, attr_list, num_attributes);
2175
2176 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
2177 VA_TRACE_RET(dpy, va_status);
2178
2179 return va_status;
2180 }
2181
2182 /*
2183 * Set display attributes
2184 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
2185 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
2186 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
2187 */
vaSetDisplayAttributes(VADisplay dpy,VADisplayAttribute * attr_list,int num_attributes)2188 VAStatus vaSetDisplayAttributes(
2189 VADisplay dpy,
2190 VADisplayAttribute *attr_list,
2191 int num_attributes
2192 )
2193 {
2194 VADriverContextP ctx;
2195 VAStatus va_status;
2196 CHECK_DISPLAY(dpy);
2197 ctx = CTX(dpy);
2198
2199 va_status = ctx->vtable->vaSetDisplayAttributes(ctx, attr_list, num_attributes);
2200 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
2201 VA_TRACE_RET(dpy, va_status);
2202
2203 return va_status;
2204 }
2205
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)2206 VAStatus vaLockSurface(VADisplay dpy,
2207 VASurfaceID surface,
2208 unsigned int *fourcc, /* following are output argument */
2209 unsigned int *luma_stride,
2210 unsigned int *chroma_u_stride,
2211 unsigned int *chroma_v_stride,
2212 unsigned int *luma_offset,
2213 unsigned int *chroma_u_offset,
2214 unsigned int *chroma_v_offset,
2215 unsigned int *buffer_name,
2216 void **buffer
2217 )
2218 {
2219 VADriverContextP ctx;
2220 VAStatus va_status = VA_STATUS_SUCCESS;
2221 CHECK_DISPLAY(dpy);
2222 ctx = CTX(dpy);
2223
2224 va_status = 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);
2225 VA_TRACE_RET(dpy, va_status);
2226
2227 return va_status;
2228 }
2229
2230
vaUnlockSurface(VADisplay dpy,VASurfaceID surface)2231 VAStatus vaUnlockSurface(VADisplay dpy,
2232 VASurfaceID surface
2233 )
2234 {
2235 VADriverContextP ctx;
2236 VAStatus va_status = VA_STATUS_SUCCESS;
2237 CHECK_DISPLAY(dpy);
2238 ctx = CTX(dpy);
2239
2240 va_status = ctx->vtable->vaUnlockSurface(ctx, surface);
2241 VA_TRACE_RET(dpy, va_status);
2242
2243 return va_status;
2244 }
2245
2246 /* Video Processing */
2247 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \
2248 CHECK_DISPLAY(dpy); \
2249 ctx = CTX(dpy); \
2250 if (!ctx) \
2251 return VA_STATUS_ERROR_INVALID_DISPLAY; \
2252 } while (0)
2253
2254 #define VA_VPP_INVOKE(dpy, func, args) do { \
2255 if (!ctx->vtable_vpp->va##func) \
2256 return VA_STATUS_ERROR_UNIMPLEMENTED; \
2257 status = ctx->vtable_vpp->va##func args; \
2258 } while (0)
2259
2260 VAStatus
vaQueryVideoProcFilters(VADisplay dpy,VAContextID context,VAProcFilterType * filters,unsigned int * num_filters)2261 vaQueryVideoProcFilters(
2262 VADisplay dpy,
2263 VAContextID context,
2264 VAProcFilterType *filters,
2265 unsigned int *num_filters
2266 )
2267 {
2268 VADriverContextP ctx;
2269 VAStatus status;
2270
2271 VA_VPP_INIT_CONTEXT(ctx, dpy);
2272 VA_VPP_INVOKE(
2273 ctx,
2274 QueryVideoProcFilters,
2275 (ctx, context, filters, num_filters)
2276 );
2277 VA_TRACE_RET(dpy, status);
2278
2279 return status;
2280 }
2281
2282 VAStatus
vaQueryVideoProcFilterCaps(VADisplay dpy,VAContextID context,VAProcFilterType type,void * filter_caps,unsigned int * num_filter_caps)2283 vaQueryVideoProcFilterCaps(
2284 VADisplay dpy,
2285 VAContextID context,
2286 VAProcFilterType type,
2287 void *filter_caps,
2288 unsigned int *num_filter_caps
2289 )
2290 {
2291 VADriverContextP ctx;
2292 VAStatus status;
2293
2294 VA_VPP_INIT_CONTEXT(ctx, dpy);
2295 VA_VPP_INVOKE(
2296 ctx,
2297 QueryVideoProcFilterCaps,
2298 (ctx, context, type, filter_caps, num_filter_caps)
2299 );
2300 VA_TRACE_RET(dpy, status);
2301 return status;
2302 }
2303
2304 VAStatus
vaQueryVideoProcPipelineCaps(VADisplay dpy,VAContextID context,VABufferID * filters,unsigned int num_filters,VAProcPipelineCaps * pipeline_caps)2305 vaQueryVideoProcPipelineCaps(
2306 VADisplay dpy,
2307 VAContextID context,
2308 VABufferID *filters,
2309 unsigned int num_filters,
2310 VAProcPipelineCaps *pipeline_caps
2311 )
2312 {
2313 VADriverContextP ctx;
2314 VAStatus status;
2315
2316 VA_VPP_INIT_CONTEXT(ctx, dpy);
2317 VA_VPP_INVOKE(
2318 ctx,
2319 QueryVideoProcPipelineCaps,
2320 (ctx, context, filters, num_filters, pipeline_caps)
2321 );
2322 VA_TRACE_RET(dpy, status);
2323 return status;
2324 }
2325
2326 VAStatus
vaCopy(VADisplay dpy,VACopyObject * dst,VACopyObject * src,VACopyOption option)2327 vaCopy(
2328 VADisplay dpy,
2329 VACopyObject *dst,
2330 VACopyObject *src,
2331 VACopyOption option
2332 )
2333 {
2334 VAStatus va_status;
2335 VADriverContextP ctx;
2336 CHECK_DISPLAY(dpy);
2337 ctx = CTX(dpy);
2338
2339 if (ctx->vtable->vaCopy == NULL)
2340 va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
2341 else
2342 va_status = ctx->vtable->vaCopy(ctx, dst, src, option);
2343 return va_status;
2344 }
2345
2346 /* Protected content */
2347 #define VA_PROT_INIT_CONTEXT(ctx, dpy) do { \
2348 CHECK_DISPLAY(dpy); \
2349 ctx = CTX(dpy); \
2350 if (!ctx) \
2351 return VA_STATUS_ERROR_INVALID_DISPLAY; \
2352 } while (0)
2353
2354 #define VA_PROT_INVOKE(dpy, func, args) do { \
2355 if (!ctx->vtable_prot->va##func) \
2356 return VA_STATUS_ERROR_UNIMPLEMENTED; \
2357 status = ctx->vtable_prot->va##func args; \
2358 } while (0)
2359
vaCreateProtectedSession(VADisplay dpy,VAConfigID config_id,VAProtectedSessionID * protected_session)2360 VAStatus vaCreateProtectedSession(
2361 VADisplay dpy,
2362 VAConfigID config_id,
2363 VAProtectedSessionID *protected_session
2364 )
2365 {
2366 VADriverContextP ctx;
2367 VAStatus status;
2368
2369 VA_PROT_INIT_CONTEXT(ctx, dpy);
2370 VA_PROT_INVOKE(
2371 ctx,
2372 CreateProtectedSession,
2373 (ctx, config_id, protected_session)
2374 );
2375 VA_TRACE_RET(dpy, status);
2376
2377 return status;
2378 }
2379
vaDestroyProtectedSession(VADisplay dpy,VAProtectedSessionID protected_session)2380 VAStatus vaDestroyProtectedSession(
2381 VADisplay dpy,
2382 VAProtectedSessionID protected_session
2383 )
2384 {
2385 VADriverContextP ctx;
2386 VAStatus status;
2387
2388 VA_PROT_INIT_CONTEXT(ctx, dpy);
2389 VA_PROT_INVOKE(
2390 ctx,
2391 DestroyProtectedSession,
2392 (ctx, protected_session)
2393 );
2394 VA_TRACE_RET(dpy, status);
2395
2396 return status;
2397 }
2398
vaAttachProtectedSession(VADisplay dpy,VAContextID context,VAProtectedSessionID protected_session)2399 VAStatus vaAttachProtectedSession(
2400 VADisplay dpy,
2401 VAContextID context,
2402 VAProtectedSessionID protected_session
2403 )
2404 {
2405 VADriverContextP ctx;
2406 VAStatus status;
2407
2408 VA_PROT_INIT_CONTEXT(ctx, dpy);
2409 VA_PROT_INVOKE(
2410 ctx,
2411 AttachProtectedSession,
2412 (ctx, context, protected_session)
2413 );
2414 VA_TRACE_RET(dpy, status);
2415
2416 return status;
2417 }
2418
vaDetachProtectedSession(VADisplay dpy,VAContextID context)2419 VAStatus vaDetachProtectedSession(
2420 VADisplay dpy,
2421 VAContextID context
2422 )
2423 {
2424 VADriverContextP ctx;
2425 VAStatus status;
2426
2427 VA_PROT_INIT_CONTEXT(ctx, dpy);
2428 VA_PROT_INVOKE(
2429 ctx,
2430 DetachProtectedSession,
2431 (ctx, context)
2432 );
2433 VA_TRACE_RET(dpy, status);
2434
2435 return status;
2436 }
2437
vaProtectedSessionExecute(VADisplay dpy,VAProtectedSessionID protected_session,VABufferID data)2438 VAStatus vaProtectedSessionExecute(
2439 VADisplay dpy,
2440 VAProtectedSessionID protected_session,
2441 VABufferID data
2442 )
2443 {
2444 VADriverContextP ctx;
2445 VAStatus status;
2446
2447 VA_PROT_INIT_CONTEXT(ctx, dpy);
2448 VA_PROT_INVOKE(
2449 ctx,
2450 ProtectedSessionExecute,
2451 (ctx, protected_session, data)
2452 );
2453 VA_TRACE_RET(dpy, status);
2454
2455 return status;
2456 }
2457
2458