xref: /aosp_15_r20/external/libva/va/va.c (revision 54e60f844a168e9a219354de272cd517ee8cd4b7)
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