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