OSDN Git Service

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