OSDN Git Service

remove max_display_attributes value check.
[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                 { -1, }
406             };
407
408             for (i = 0; compatible_versions[i].major >= 0; i++) {
409                 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
410                                          compatible_versions[i].major,
411                                          compatible_versions[i].minor)) {
412                     init_func = (VADriverInit)dlsym(handle, init_func_s);
413                     if (init_func) {
414                         va_infoMessage(dpy, "Found init function %s\n", init_func_s);
415                         break;
416                     }
417                 }
418             }
419
420             if (compatible_versions[i].major < 0) {
421                 va_errorMessage(dpy, "%s has no function %s\n",
422                                 driver_path, init_func_s);
423                 dlclose(handle);
424             } else {
425                 struct VADriverVTable *vtable = ctx->vtable;
426                 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
427
428                 vaStatus = VA_STATUS_SUCCESS;
429                 if (!vtable) {
430                     vtable = calloc(1, sizeof(*vtable));
431                     if (!vtable)
432                         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
433                 }
434                 ctx->vtable = vtable;
435
436                 if (!vtable_vpp) {
437                     vtable_vpp = calloc(1, sizeof(*vtable_vpp));
438                     if (vtable_vpp)
439                         vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
440                     else
441                         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
442                 }
443                 ctx->vtable_vpp = vtable_vpp;
444
445                 if (init_func && VA_STATUS_SUCCESS == vaStatus)
446                     vaStatus = (*init_func)(ctx);
447
448                 if (VA_STATUS_SUCCESS == vaStatus) {
449                     CHECK_MAXIMUM(vaStatus, ctx, profiles);
450                     CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
451                     CHECK_MAXIMUM(vaStatus, ctx, attributes);
452                     CHECK_MAXIMUM(vaStatus, ctx, image_formats);
453                     CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
454                     CHECK_STRING(vaStatus, ctx, vendor);
455                     CHECK_VTABLE(vaStatus, ctx, Terminate);
456                     CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
457                     CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
458                     CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
459                     CHECK_VTABLE(vaStatus, ctx, CreateConfig);
460                     CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
461                     CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
462                     CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
463                     CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
464                     CHECK_VTABLE(vaStatus, ctx, CreateContext);
465                     CHECK_VTABLE(vaStatus, ctx, DestroyContext);
466                     CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
467                     CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
468                     CHECK_VTABLE(vaStatus, ctx, MapBuffer);
469                     CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
470                     CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
471                     CHECK_VTABLE(vaStatus, ctx, BeginPicture);
472                     CHECK_VTABLE(vaStatus, ctx, RenderPicture);
473                     CHECK_VTABLE(vaStatus, ctx, EndPicture);
474                     CHECK_VTABLE(vaStatus, ctx, SyncSurface);
475                     CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
476                     CHECK_VTABLE(vaStatus, ctx, PutSurface);
477                     CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
478                     CHECK_VTABLE(vaStatus, ctx, CreateImage);
479                     CHECK_VTABLE(vaStatus, ctx, DeriveImage);
480                     CHECK_VTABLE(vaStatus, ctx, DestroyImage);
481                     CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
482                     CHECK_VTABLE(vaStatus, ctx, GetImage);
483                     CHECK_VTABLE(vaStatus, ctx, PutImage);
484                     CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
485                     CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
486                     CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
487                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
488                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
489                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
490                     CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
491                     CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
492                     CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
493                     CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
494                     CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
495                 }
496                 if (VA_STATUS_SUCCESS != vaStatus) {
497                     va_errorMessage(dpy, "%s init failed\n", driver_path);
498                     dlclose(handle);
499                 }
500                 if (VA_STATUS_SUCCESS == vaStatus)
501                     ctx->handle = handle;
502                 free(driver_path);
503                 break;
504             }
505         }
506         free(driver_path);
507         
508         driver_dir = strtok_r(NULL, ":", &saveptr);
509     }
510     
511     free(search_path);    
512     
513     return vaStatus;
514 }
515
516 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
517 {
518     VADriverContextP ctx;
519     if (!vaDisplayIsValid(dpy))
520         return NULL;
521     ctx = CTX(dpy);
522
523     if (NULL == ctx->handle)
524         return NULL;
525         
526     return (VAPrivFunc) dlsym(ctx->handle, func);
527 }
528
529
530 /*
531  * Returns a short english description of error_status
532  */
533 const char *vaErrorStr(VAStatus error_status)
534 {
535     switch(error_status) {
536         case VA_STATUS_SUCCESS:
537             return "success (no error)";
538         case VA_STATUS_ERROR_OPERATION_FAILED:
539             return "operation failed";
540         case VA_STATUS_ERROR_ALLOCATION_FAILED:
541             return "resource allocation failed";
542         case VA_STATUS_ERROR_INVALID_DISPLAY:
543             return "invalid VADisplay";
544         case VA_STATUS_ERROR_INVALID_CONFIG:
545             return "invalid VAConfigID";
546         case VA_STATUS_ERROR_INVALID_CONTEXT:
547             return "invalid VAContextID";
548         case VA_STATUS_ERROR_INVALID_SURFACE:
549             return "invalid VASurfaceID";
550         case VA_STATUS_ERROR_INVALID_BUFFER:
551             return "invalid VABufferID";
552         case VA_STATUS_ERROR_INVALID_IMAGE:
553             return "invalid VAImageID";
554         case VA_STATUS_ERROR_INVALID_SUBPICTURE:
555             return "invalid VASubpictureID";
556         case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
557             return "attribute not supported";
558         case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
559             return "list argument exceeds maximum number";
560         case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
561             return "the requested VAProfile is not supported";
562         case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
563             return "the requested VAEntryPoint is not supported";
564         case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
565             return "the requested RT Format is not supported";
566         case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
567             return "the requested VABufferType is not supported";
568         case VA_STATUS_ERROR_SURFACE_BUSY:
569             return "surface is in use";
570         case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
571             return "flag not supported";
572         case VA_STATUS_ERROR_INVALID_PARAMETER:
573             return "invalid parameter";
574         case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
575             return "resolution not supported";
576         case VA_STATUS_ERROR_UNIMPLEMENTED:
577             return "the requested function is not implemented";
578         case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
579             return "surface is in displaying (may by overlay)" ;
580         case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
581             return "invalid VAImageFormat";
582         case VA_STATUS_ERROR_INVALID_VALUE:
583             return "an invalid/unsupported value was supplied";
584         case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
585             return "the requested filter is not supported";
586         case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
587             return "an invalid filter chain was supplied";
588         case VA_STATUS_ERROR_UNKNOWN:
589             return "unknown libva error";
590     }
591     return "unknown libva error / description missing";
592 }
593
594 const static char *prefer_driver_list[4] = {
595     "i965",
596     "hybrid",
597     "pvr",
598     "iHD",
599 };
600
601 VAStatus vaSetDriverName(
602     VADisplay dpy,
603     char *driver_name
604 )
605 {
606     VADriverContextP ctx;
607     VAStatus vaStatus = VA_STATUS_SUCCESS;
608     char *override_driver_name = NULL;
609     int i, found;
610     ctx = CTX(dpy);
611
612     if (geteuid() != getuid()) {
613         vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
614         va_errorMessage(dpy, "no permission to vaSetDriverName\n");
615         return vaStatus;
616     }
617
618     if (strlen(driver_name) == 0 || strlen(driver_name) >=256) {
619         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
620         va_errorMessage(dpy, "vaSetDriverName returns %s\n",
621                          vaErrorStr(vaStatus));
622         return vaStatus;
623     }
624
625     found = 0;
626     for (i = 0; i < sizeof(prefer_driver_list) / sizeof(char *); i++) {
627         if (strlen(prefer_driver_list[i]) != strlen(driver_name))
628             continue;
629         if (!strncmp(prefer_driver_list[i], driver_name, strlen(driver_name))) {
630             found = 1;
631             break;
632         }
633     }
634
635     if (!found) {
636         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
637         va_errorMessage(dpy, "vaSetDriverName returns %s. Incorrect parameter\n",
638                          vaErrorStr(vaStatus));
639         return vaStatus;
640     }
641
642     override_driver_name = strdup(driver_name);
643
644     if (!override_driver_name) {
645         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
646         va_errorMessage(dpy, "vaSetDriverName returns %s. Out of Memory\n",
647                          vaErrorStr(vaStatus));
648         return vaStatus;
649     }
650
651     ctx->override_driver_name = override_driver_name;
652     return VA_STATUS_SUCCESS;
653 }
654
655 VAStatus vaInitialize (
656     VADisplay dpy,
657     int *major_version,  /* out */
658     int *minor_version   /* out */
659 )
660 {
661     const char *driver_name_env = NULL;
662     char *driver_name = NULL;
663     VAStatus vaStatus;
664     VADriverContextP ctx;
665
666     CHECK_DISPLAY(dpy);
667
668     ctx = CTX(dpy);
669
670     va_TraceInit(dpy);
671
672     va_FoolInit(dpy);
673
674     va_MessagingInit();
675
676     va_infoMessage(dpy, "VA-API version %s\n", VA_VERSION_S);
677
678     vaStatus = va_getDriverName(dpy, &driver_name);
679
680     if (!ctx->override_driver_name) {
681         va_infoMessage(dpy, "va_getDriverName() returns %d\n", vaStatus);
682
683         driver_name_env = getenv("LIBVA_DRIVER_NAME");
684     } else if (vaStatus == VA_STATUS_SUCCESS) {
685         if (driver_name)
686             free(driver_name);
687
688         driver_name = strdup(ctx->override_driver_name);
689         if (!driver_name) {
690             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
691             va_errorMessage(dpy, "vaInitialize() failed with %s, out of memory\n",
692                         vaErrorStr(vaStatus));
693             return vaStatus;
694         }
695         va_infoMessage(dpy, "User requested driver '%s'\n", driver_name);
696     }
697
698     if (driver_name_env && (geteuid() == getuid())) {
699         /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
700         if (driver_name) /* memory is allocated in va_getDriverName */
701             free(driver_name);
702         
703         driver_name = strdup(driver_name_env);
704         vaStatus = VA_STATUS_SUCCESS;
705         va_infoMessage(dpy, "User requested driver '%s'\n", driver_name);
706     }
707
708     if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
709         vaStatus = va_openDriver(dpy, driver_name);
710         va_infoMessage(dpy, "va_openDriver() returns %d\n", vaStatus);
711
712         *major_version = VA_MAJOR_VERSION;
713         *minor_version = VA_MINOR_VERSION;
714     } else
715         va_errorMessage(dpy, "va_getDriverName() failed with %s,driver_name=%s\n",
716                         vaErrorStr(vaStatus), driver_name);
717
718     if (driver_name)
719         free(driver_name);
720     
721     VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
722
723     return vaStatus;
724 }
725
726
727 /*
728  * After this call, all library internal resources will be cleaned up
729  */ 
730 VAStatus vaTerminate (
731     VADisplay dpy
732 )
733 {
734   VAStatus vaStatus = VA_STATUS_SUCCESS;
735   VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
736   VADriverContextP old_ctx;
737
738   CHECK_DISPLAY(dpy);
739   old_ctx = CTX(dpy);
740
741   if (old_ctx->handle) {
742       vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
743       dlclose(old_ctx->handle);
744       old_ctx->handle = NULL;
745   }
746   free(old_ctx->vtable);
747   old_ctx->vtable = NULL;
748   free(old_ctx->vtable_vpp);
749   old_ctx->vtable_vpp = NULL;
750
751   if (old_ctx->override_driver_name) {
752       free(old_ctx->override_driver_name);
753       old_ctx->override_driver_name = NULL;
754   }
755
756   VA_TRACE_LOG(va_TraceTerminate, dpy);
757
758   va_TraceEnd(dpy);
759
760   va_FoolEnd(dpy);
761
762   if (VA_STATUS_SUCCESS == vaStatus)
763       pDisplayContext->vaDestroy(pDisplayContext);
764
765   return vaStatus;
766 }
767
768 /*
769  * vaQueryVendorString returns a pointer to a zero-terminated string
770  * describing some aspects of the VA implemenation on a specific
771  * hardware accelerator. The format of the returned string is:
772  * <vendorname>-<major_version>-<minor_version>-<addtional_info>
773  * e.g. for the Intel GMA500 implementation, an example would be:
774  * "IntelGMA500-1.0-0.2-patch3
775  */
776 const char *vaQueryVendorString (
777     VADisplay dpy
778 )
779 {
780   if (!vaDisplayIsValid(dpy))
781       return NULL;
782   
783   return CTX(dpy)->str_vendor;
784 }
785
786
787 /* Get maximum number of profiles supported by the implementation */
788 int vaMaxNumProfiles (
789     VADisplay dpy
790 )
791 {
792   if (!vaDisplayIsValid(dpy))
793       return 0;
794   
795   return CTX(dpy)->max_profiles;
796 }
797
798 /* Get maximum number of entrypoints supported by the implementation */
799 int vaMaxNumEntrypoints (
800     VADisplay dpy
801 )
802 {
803   if (!vaDisplayIsValid(dpy))
804       return 0;
805   
806   return CTX(dpy)->max_entrypoints;
807 }
808
809
810 /* Get maximum number of attributs supported by the implementation */
811 int vaMaxNumConfigAttributes (
812     VADisplay dpy
813 )
814 {
815   if (!vaDisplayIsValid(dpy))
816       return 0;
817   
818   return CTX(dpy)->max_attributes;
819 }
820
821 VAStatus vaQueryConfigEntrypoints (
822     VADisplay dpy,
823     VAProfile profile,
824     VAEntrypoint *entrypoints,  /* out */
825     int *num_entrypoints        /* out */
826 )
827 {
828   VADriverContextP ctx;
829   CHECK_DISPLAY(dpy);
830   ctx = CTX(dpy);
831
832   return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
833 }
834
835 VAStatus vaGetConfigAttributes (
836     VADisplay dpy,
837     VAProfile profile,
838     VAEntrypoint entrypoint,
839     VAConfigAttrib *attrib_list, /* in/out */
840     int num_attribs
841 )
842 {
843   VADriverContextP ctx;
844   CHECK_DISPLAY(dpy);
845   ctx = CTX(dpy);
846
847   return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
848 }
849
850 VAStatus vaQueryConfigProfiles (
851     VADisplay dpy,
852     VAProfile *profile_list,    /* out */
853     int *num_profiles           /* out */
854 )
855 {
856   VADriverContextP ctx;
857   CHECK_DISPLAY(dpy);
858   ctx = CTX(dpy);
859
860   return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
861 }
862
863 VAStatus vaCreateConfig (
864     VADisplay dpy,
865     VAProfile profile, 
866     VAEntrypoint entrypoint, 
867     VAConfigAttrib *attrib_list,
868     int num_attribs,
869     VAConfigID *config_id /* out */
870 )
871 {
872   VADriverContextP ctx;
873   VAStatus vaStatus = VA_STATUS_SUCCESS;
874   
875   CHECK_DISPLAY(dpy);
876   ctx = CTX(dpy);
877
878   vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
879
880   /* record the current entrypoint for further trace/fool determination */
881   VA_TRACE_ALL(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
882   VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
883   
884   return vaStatus;
885 }
886
887 VAStatus vaDestroyConfig (
888     VADisplay dpy,
889     VAConfigID config_id
890 )
891 {
892   VADriverContextP ctx;
893   VAStatus vaStatus = VA_STATUS_SUCCESS;
894
895   CHECK_DISPLAY(dpy);
896   ctx = CTX(dpy);
897
898   vaStatus = ctx->vtable->vaDestroyConfig ( ctx, config_id );
899
900   VA_TRACE_ALL(va_TraceDestroyConfig, dpy, config_id);
901
902   return vaStatus;
903 }
904
905 VAStatus vaQueryConfigAttributes (
906     VADisplay dpy,
907     VAConfigID config_id, 
908     VAProfile *profile,         /* out */
909     VAEntrypoint *entrypoint,   /* out */
910     VAConfigAttrib *attrib_list,/* out */
911     int *num_attribs            /* out */
912 )
913 {
914   VADriverContextP ctx;
915   CHECK_DISPLAY(dpy);
916   ctx = CTX(dpy);
917
918   return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
919 }
920
921 VAStatus vaQueryProcessingRate (
922     VADisplay dpy,
923     VAConfigID config_id,
924     VAProcessingRateParameter *proc_buf,
925     unsigned int *processing_rate       /* out */
926 )
927 {
928   VADriverContextP ctx;
929   CHECK_DISPLAY(dpy);
930   ctx = CTX(dpy);
931   if(!ctx->vtable->vaQueryProcessingRate)
932       return VA_STATUS_ERROR_UNIMPLEMENTED;
933   return ctx->vtable->vaQueryProcessingRate( ctx, config_id, proc_buf, processing_rate);
934 }
935
936 /* XXX: this is a slow implementation that will be removed */
937 static VAStatus
938 va_impl_query_surface_attributes(
939     VADriverContextP    ctx,
940     VAConfigID          config,
941     VASurfaceAttrib    *out_attribs,
942     unsigned int       *out_num_attribs_ptr
943 )
944 {
945     VASurfaceAttrib *attribs = NULL;
946     unsigned int num_attribs, n;
947     VASurfaceAttrib *out_attrib;
948     unsigned int out_num_attribs;
949     VAImageFormat *image_formats = NULL;
950     int num_image_formats, i;
951     VAStatus va_status;
952
953     /* List of surface attributes to query */
954     struct va_surface_attrib_map {
955         VASurfaceAttribType type;
956         VAGenericValueType  value_type;
957     };
958     static const struct va_surface_attrib_map attribs_map[] = {
959         { VASurfaceAttribMinWidth,      VAGenericValueTypeInteger },
960         { VASurfaceAttribMaxWidth,      VAGenericValueTypeInteger },
961         { VASurfaceAttribMinHeight,     VAGenericValueTypeInteger },
962         { VASurfaceAttribMaxHeight,     VAGenericValueTypeInteger },
963         { VASurfaceAttribMemoryType,    VAGenericValueTypeInteger },
964         { VASurfaceAttribNone, }
965     };
966
967     if (!out_attribs || !out_num_attribs_ptr)
968         return VA_STATUS_ERROR_INVALID_PARAMETER;
969     if (!ctx->vtable->vaGetSurfaceAttributes)
970         return VA_STATUS_ERROR_UNIMPLEMENTED;
971
972     num_image_formats = ctx->max_image_formats;
973     image_formats = malloc(num_image_formats * sizeof(*image_formats));
974     if (!image_formats) {
975         va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
976         goto end;
977     }
978
979     va_status = ctx->vtable->vaQueryImageFormats(
980         ctx, image_formats, &num_image_formats);
981     if (va_status != VA_STATUS_SUCCESS)
982         goto end;
983
984     num_attribs = VASurfaceAttribCount + num_image_formats;
985     attribs = malloc(num_attribs * sizeof(*attribs));
986     if (!attribs) {
987         va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
988         goto end;
989     }
990
991     /* Initialize with base surface attributes, except pixel-formats */
992     for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
993         VASurfaceAttrib * const attrib = &attribs[n];
994         attrib->type = attribs_map[n].type;
995         attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
996         attrib->value.type = attribs_map[n].value_type;
997     }
998
999     /* Append image formats */
1000     for (i = 0; i < num_image_formats; i++) {
1001         VASurfaceAttrib * const attrib = &attribs[n];
1002         attrib->type = VASurfaceAttribPixelFormat;
1003         attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
1004         attrib->value.type = VAGenericValueTypeInteger;
1005         attrib->value.value.i = image_formats[i].fourcc;
1006         if (++n == num_attribs) {
1007             va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1008             goto end;
1009         }
1010     }
1011     num_attribs = n;
1012
1013     va_status = ctx->vtable->vaGetSurfaceAttributes(
1014         ctx, config, attribs, num_attribs);
1015     if (va_status != VA_STATUS_SUCCESS)
1016         goto end;
1017
1018     /* Remove invalid entries */
1019     out_num_attribs = 0;
1020     for (n = 0; n < num_attribs; n++) {
1021         VASurfaceAttrib * const attrib = &attribs[n];
1022
1023         if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
1024             continue;
1025
1026         // Accept all surface attributes that are not pixel-formats
1027         if (attrib->type != VASurfaceAttribPixelFormat) {
1028             out_num_attribs++;
1029             continue;
1030         }
1031
1032         // Drop invalid pixel-format attribute
1033         if (!attrib->value.value.i) {
1034             attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
1035             continue;
1036         }
1037
1038         // Check for duplicates
1039         int is_duplicate = 0;
1040         for (i = n - 1; i >= 0 && !is_duplicate; i--) {
1041             const VASurfaceAttrib * const prev_attrib = &attribs[i];
1042             if (prev_attrib->type != VASurfaceAttribPixelFormat)
1043                 break;
1044             is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
1045         }
1046         if (is_duplicate)
1047             attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
1048         else
1049             out_num_attribs++;
1050     }
1051
1052     if (*out_num_attribs_ptr < out_num_attribs) {
1053         *out_num_attribs_ptr = out_num_attribs;
1054         va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1055         goto end;
1056     }
1057
1058     out_attrib = out_attribs;
1059     for (n = 0; n < num_attribs; n++) {
1060         const VASurfaceAttrib * const attrib = &attribs[n];
1061         if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
1062             continue;
1063         *out_attrib++ = *attrib;
1064     }
1065
1066 end:
1067     free(attribs);
1068     free(image_formats);
1069     return va_status;
1070 }
1071
1072 VAStatus
1073 vaQuerySurfaceAttributes(
1074     VADisplay           dpy,
1075     VAConfigID          config,
1076     VASurfaceAttrib    *attrib_list,
1077     unsigned int       *num_attribs
1078 )
1079 {
1080     VADriverContextP ctx;
1081     VAStatus vaStatus;
1082
1083     CHECK_DISPLAY(dpy);
1084     ctx = CTX(dpy);
1085     if (!ctx)
1086         return VA_STATUS_ERROR_INVALID_DISPLAY;
1087
1088     if (!ctx->vtable->vaQuerySurfaceAttributes)
1089         vaStatus = va_impl_query_surface_attributes(ctx, config,
1090                                                     attrib_list, num_attribs);
1091     else
1092         vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
1093                                                          attrib_list, num_attribs);
1094
1095     VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs);
1096
1097     return vaStatus;
1098 }
1099
1100 VAStatus
1101 vaCreateSurfaces(
1102     VADisplay           dpy,
1103     unsigned int        format,
1104     unsigned int        width,
1105     unsigned int        height,
1106     VASurfaceID        *surfaces,
1107     unsigned int        num_surfaces,
1108     VASurfaceAttrib    *attrib_list,
1109     unsigned int        num_attribs
1110 )
1111 {
1112     VADriverContextP ctx;
1113     VAStatus vaStatus;
1114
1115     CHECK_DISPLAY(dpy);
1116     ctx = CTX(dpy);
1117     if (!ctx)
1118         return VA_STATUS_ERROR_INVALID_DISPLAY;
1119
1120     if (ctx->vtable->vaCreateSurfaces2)
1121         vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
1122                                               surfaces, num_surfaces,
1123                                               attrib_list, num_attribs);
1124     else if (attrib_list && num_attribs > 0)
1125         vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
1126     else
1127         vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
1128                                                  num_surfaces, surfaces);
1129     VA_TRACE_LOG(va_TraceCreateSurfaces,
1130                  dpy, width, height, format, num_surfaces, surfaces,
1131                  attrib_list, num_attribs);
1132
1133     return vaStatus;
1134 }
1135
1136
1137 VAStatus vaDestroySurfaces (
1138     VADisplay dpy,
1139     VASurfaceID *surface_list,
1140     int num_surfaces
1141 )
1142 {
1143   VADriverContextP ctx;
1144   VAStatus vaStatus;
1145   
1146   CHECK_DISPLAY(dpy);
1147   ctx = CTX(dpy);
1148
1149   VA_TRACE_LOG(va_TraceDestroySurfaces,
1150                dpy, surface_list, num_surfaces);
1151   
1152   vaStatus = ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
1153   
1154   return vaStatus;
1155 }
1156
1157 VAStatus vaCreateContext (
1158     VADisplay dpy,
1159     VAConfigID config_id,
1160     int picture_width,
1161     int picture_height,
1162     int flag,
1163     VASurfaceID *render_targets,
1164     int num_render_targets,
1165     VAContextID *context                /* out */
1166 )
1167 {
1168   VADriverContextP ctx;
1169   VAStatus vaStatus;
1170   
1171   CHECK_DISPLAY(dpy);
1172   ctx = CTX(dpy);
1173
1174   vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
1175                                       flag, render_targets, num_render_targets, context );
1176
1177   /* keep current encode/decode resoluton */
1178   VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
1179
1180   return vaStatus;
1181 }
1182
1183 VAStatus vaDestroyContext (
1184     VADisplay dpy,
1185     VAContextID context
1186 )
1187 {
1188   VADriverContextP ctx;
1189   VAStatus vaStatus;
1190
1191   CHECK_DISPLAY(dpy);
1192   ctx = CTX(dpy);
1193
1194   vaStatus = ctx->vtable->vaDestroyContext( ctx, context );
1195
1196   VA_TRACE_ALL(va_TraceDestroyContext, dpy, context);
1197
1198   return vaStatus;
1199 }
1200
1201 VAStatus vaCreateMFContext (
1202     VADisplay dpy,
1203     VAMFContextID *mf_context    /* out */
1204 )
1205 {
1206     VADriverContextP ctx;
1207     VAStatus vaStatus;
1208     
1209     CHECK_DISPLAY(dpy);
1210     ctx = CTX(dpy);
1211     if(ctx->vtable->vaCreateMFContext == NULL)
1212         vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1213     else
1214     {
1215         vaStatus = ctx->vtable->vaCreateMFContext( ctx, mf_context);
1216         VA_TRACE_ALL(va_TraceCreateMFContext, dpy, mf_context);
1217     }
1218
1219     return vaStatus;
1220 }
1221
1222 VAStatus vaMFAddContext (
1223     VADisplay dpy,
1224     VAMFContextID mf_context,
1225     VAContextID context
1226 )
1227 {
1228     VADriverContextP ctx;
1229     VAStatus vaStatus;
1230
1231     CHECK_DISPLAY(dpy);
1232     ctx = CTX(dpy);
1233     
1234     if(ctx->vtable->vaMFAddContext == NULL)
1235         vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1236     else
1237     {
1238         vaStatus = ctx->vtable->vaMFAddContext( ctx, context, mf_context);
1239         VA_TRACE_ALL(va_TraceMFAddContext, dpy, context, mf_context);
1240     }
1241
1242     return vaStatus;
1243 }
1244
1245 VAStatus vaMFReleaseContext (
1246     VADisplay dpy,
1247     VAMFContextID mf_context,
1248     VAContextID context
1249 )
1250 {
1251     VADriverContextP ctx;
1252     VAStatus vaStatus;
1253
1254     CHECK_DISPLAY(dpy);
1255     ctx = CTX(dpy);
1256     if(ctx->vtable->vaMFReleaseContext == NULL)
1257         vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1258     else
1259     {
1260         vaStatus = ctx->vtable->vaMFReleaseContext( ctx, context, mf_context);
1261         VA_TRACE_ALL(va_TraceMFReleaseContext, dpy, context, mf_context);
1262     }
1263
1264     return vaStatus;
1265 }
1266
1267 VAStatus vaMFSubmit (
1268     VADisplay dpy,
1269     VAMFContextID mf_context,
1270     VAContextID *contexts,
1271     int num_contexts
1272 )
1273 {
1274     VADriverContextP ctx;
1275     VAStatus vaStatus;
1276
1277     CHECK_DISPLAY(dpy);
1278     ctx = CTX(dpy);
1279     CHECK_VTABLE(vaStatus, ctx, MFSubmit);
1280     if(ctx->vtable->vaMFSubmit == NULL)
1281         vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1282     else
1283     {
1284         vaStatus = ctx->vtable->vaMFSubmit( ctx, mf_context, contexts, num_contexts);
1285         VA_TRACE_ALL(va_TraceMFSubmit, dpy, mf_context, contexts, num_contexts);
1286     }
1287
1288     return vaStatus;
1289 }
1290
1291 VAStatus vaCreateBuffer (
1292     VADisplay dpy,
1293     VAContextID context,        /* in */
1294     VABufferType type,          /* in */
1295     unsigned int size,          /* in */
1296     unsigned int num_elements,  /* in */
1297     void *data,                 /* in */
1298     VABufferID *buf_id          /* out */
1299 )
1300 {
1301   VADriverContextP ctx;
1302   VAStatus vaStatus;
1303   
1304   CHECK_DISPLAY(dpy);
1305   ctx = CTX(dpy);
1306
1307   VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
1308
1309   vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
1310
1311   VA_TRACE_LOG(va_TraceCreateBuffer,
1312                dpy, context, type, size, num_elements, data, buf_id);
1313   
1314   return vaStatus;
1315 }
1316
1317 VAStatus vaCreateBuffer2 (
1318     VADisplay dpy,
1319     VAContextID context,
1320     VABufferType type,
1321     unsigned int width,
1322     unsigned int height,
1323     unsigned int *unit_size,
1324     unsigned int *pitch,
1325     VABufferID *buf_id
1326 )
1327 {
1328   VADriverContextP ctx;
1329   VAStatus vaStatus;
1330
1331   CHECK_DISPLAY(dpy);
1332   ctx = CTX(dpy);
1333   if(!ctx->vtable->vaCreateBuffer2)
1334      return VA_STATUS_ERROR_UNIMPLEMENTED;
1335
1336   vaStatus = ctx->vtable->vaCreateBuffer2( ctx, context, type, width, height ,unit_size, pitch, buf_id);
1337
1338   VA_TRACE_LOG(va_TraceCreateBuffer,
1339                dpy, context, type, *pitch, height, NULL, buf_id);
1340
1341   return vaStatus;
1342 }
1343
1344 VAStatus vaBufferSetNumElements (
1345     VADisplay dpy,
1346     VABufferID buf_id,  /* in */
1347     unsigned int num_elements /* in */
1348 )
1349 {
1350   VADriverContextP ctx;
1351   CHECK_DISPLAY(dpy);
1352   ctx = CTX(dpy);
1353
1354   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1355   
1356   return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
1357 }
1358
1359
1360 VAStatus vaMapBuffer (
1361     VADisplay dpy,
1362     VABufferID buf_id,  /* in */
1363     void **pbuf         /* out */
1364 )
1365 {
1366   VADriverContextP ctx;
1367   VAStatus va_status;
1368   
1369   CHECK_DISPLAY(dpy);
1370   ctx = CTX(dpy);
1371   
1372   VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
1373   
1374   va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
1375
1376   VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf);
1377   
1378   return va_status;
1379 }
1380
1381 VAStatus vaUnmapBuffer (
1382     VADisplay dpy,
1383     VABufferID buf_id   /* in */
1384 )
1385 {
1386   VADriverContextP ctx;
1387   CHECK_DISPLAY(dpy);
1388   ctx = CTX(dpy);
1389
1390   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1391
1392   return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
1393 }
1394
1395 VAStatus vaDestroyBuffer (
1396     VADisplay dpy,
1397     VABufferID buffer_id
1398 )
1399 {
1400   VADriverContextP ctx;
1401   CHECK_DISPLAY(dpy);
1402   ctx = CTX(dpy);
1403
1404   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1405
1406   VA_TRACE_LOG(va_TraceDestroyBuffer,
1407                dpy, buffer_id);
1408   
1409   return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
1410 }
1411
1412 VAStatus vaBufferInfo (
1413     VADisplay dpy,
1414     VAContextID context,        /* in */
1415     VABufferID buf_id,          /* in */
1416     VABufferType *type,         /* out */
1417     unsigned int *size,         /* out */
1418     unsigned int *num_elements  /* out */
1419 )
1420 {
1421   VADriverContextP ctx;
1422   
1423   CHECK_DISPLAY(dpy);
1424   ctx = CTX(dpy);
1425
1426   VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
1427   
1428   return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
1429 }
1430
1431 /* Locks buffer for external API usage */
1432 VAStatus
1433 vaAcquireBufferHandle(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info)
1434 {
1435     VADriverContextP ctx;
1436
1437     CHECK_DISPLAY(dpy);
1438     ctx = CTX(dpy);
1439
1440     if (!ctx->vtable->vaAcquireBufferHandle)
1441         return VA_STATUS_ERROR_UNIMPLEMENTED;
1442     return ctx->vtable->vaAcquireBufferHandle(ctx, buf_id, buf_info);
1443 }
1444
1445 /* Unlocks buffer after usage from external API */
1446 VAStatus
1447 vaReleaseBufferHandle(VADisplay dpy, VABufferID buf_id)
1448 {
1449     VADriverContextP ctx;
1450
1451     CHECK_DISPLAY(dpy);
1452     ctx = CTX(dpy);
1453
1454     if (!ctx->vtable->vaReleaseBufferHandle)
1455         return VA_STATUS_ERROR_UNIMPLEMENTED;
1456     return ctx->vtable->vaReleaseBufferHandle(ctx, buf_id);
1457 }
1458
1459 VAStatus
1460 vaExportSurfaceHandle(VADisplay dpy, VASurfaceID surface_id,
1461                       uint32_t mem_type, uint32_t flags,
1462                       void *descriptor)
1463 {
1464     VADriverContextP ctx;
1465
1466     CHECK_DISPLAY(dpy);
1467     ctx = CTX(dpy);
1468
1469     if (!ctx->vtable->vaExportSurfaceHandle)
1470         return VA_STATUS_ERROR_UNIMPLEMENTED;
1471     return ctx->vtable->vaExportSurfaceHandle(ctx, surface_id,
1472                                               mem_type, flags,
1473                                               descriptor);
1474 }
1475
1476 VAStatus vaBeginPicture (
1477     VADisplay dpy,
1478     VAContextID context,
1479     VASurfaceID render_target
1480 )
1481 {
1482   VADriverContextP ctx;
1483   VAStatus va_status;
1484
1485   CHECK_DISPLAY(dpy);
1486   ctx = CTX(dpy);
1487
1488   VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target);
1489   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1490   
1491   va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
1492   
1493   return va_status;
1494 }
1495
1496 VAStatus vaRenderPicture (
1497     VADisplay dpy,
1498     VAContextID context,
1499     VABufferID *buffers,
1500     int num_buffers
1501 )
1502 {
1503   VADriverContextP ctx;
1504
1505   CHECK_DISPLAY(dpy);
1506   ctx = CTX(dpy);
1507
1508   VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
1509   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1510
1511   return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
1512 }
1513
1514 VAStatus vaEndPicture (
1515     VADisplay dpy,
1516     VAContextID context
1517 )
1518 {
1519   VAStatus va_status = VA_STATUS_SUCCESS;
1520   VADriverContextP ctx;
1521
1522   CHECK_DISPLAY(dpy);
1523   ctx = CTX(dpy);
1524
1525   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
1526
1527   va_status = ctx->vtable->vaEndPicture( ctx, context );
1528
1529   /* dump surface content */
1530   VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 1);
1531
1532   return va_status;
1533 }
1534
1535 VAStatus vaSyncSurface (
1536     VADisplay dpy,
1537     VASurfaceID render_target
1538 )
1539 {
1540   VAStatus va_status;
1541   VADriverContextP ctx;
1542
1543   CHECK_DISPLAY(dpy);
1544   ctx = CTX(dpy);
1545
1546   va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
1547   VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
1548
1549   return va_status;
1550 }
1551
1552 VAStatus vaQuerySurfaceStatus (
1553     VADisplay dpy,
1554     VASurfaceID render_target,
1555     VASurfaceStatus *status     /* out */
1556 )
1557 {
1558   VAStatus va_status;
1559   VADriverContextP ctx;
1560   CHECK_DISPLAY(dpy);
1561   ctx = CTX(dpy);
1562
1563   va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
1564
1565   VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
1566
1567   return va_status;
1568 }
1569
1570 VAStatus vaQuerySurfaceError (
1571         VADisplay dpy,
1572         VASurfaceID surface,
1573         VAStatus error_status,
1574         void **error_info /*out*/
1575 )
1576 {
1577   VAStatus va_status;
1578   VADriverContextP ctx;
1579   CHECK_DISPLAY(dpy);
1580   ctx = CTX(dpy);
1581
1582   va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
1583
1584   VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
1585
1586   return va_status;
1587 }
1588
1589 /* Get maximum number of image formats supported by the implementation */
1590 int vaMaxNumImageFormats (
1591     VADisplay dpy
1592 )
1593 {
1594   if (!vaDisplayIsValid(dpy))
1595       return 0;
1596   
1597   return CTX(dpy)->max_image_formats;
1598 }
1599
1600 VAStatus vaQueryImageFormats (
1601     VADisplay dpy,
1602     VAImageFormat *format_list, /* out */
1603     int *num_formats            /* out */
1604 )
1605 {
1606   VADriverContextP ctx;
1607   CHECK_DISPLAY(dpy);
1608   ctx = CTX(dpy);
1609
1610   return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1611 }
1612
1613 /* 
1614  * The width and height fields returned in the VAImage structure may get 
1615  * enlarged for some YUV formats. The size of the data buffer that needs
1616  * to be allocated will be given in the "data_size" field in VAImage.
1617  * Image data is not allocated by this function.  The client should
1618  * allocate the memory and fill in the VAImage structure's data field
1619  * after looking at "data_size" returned from the library.
1620  */
1621 VAStatus vaCreateImage (
1622     VADisplay dpy,
1623     VAImageFormat *format,
1624     int width,
1625     int height,
1626     VAImage *image      /* out */
1627 )
1628 {
1629   VADriverContextP ctx;
1630   CHECK_DISPLAY(dpy);
1631   ctx = CTX(dpy);
1632
1633   return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1634 }
1635
1636 /*
1637  * Should call DestroyImage before destroying the surface it is bound to
1638  */
1639 VAStatus vaDestroyImage (
1640     VADisplay dpy,
1641     VAImageID image
1642 )
1643 {
1644   VADriverContextP ctx;
1645   CHECK_DISPLAY(dpy);
1646   ctx = CTX(dpy);
1647
1648   return ctx->vtable->vaDestroyImage ( ctx, image);
1649 }
1650
1651 VAStatus vaSetImagePalette (
1652     VADisplay dpy,
1653     VAImageID image,
1654     unsigned char *palette
1655 )
1656 {
1657   VADriverContextP ctx;
1658   CHECK_DISPLAY(dpy);
1659   ctx = CTX(dpy);
1660
1661   return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1662 }
1663
1664 /*
1665  * Retrieve surface data into a VAImage
1666  * Image must be in a format supported by the implementation
1667  */
1668 VAStatus vaGetImage (
1669     VADisplay dpy,
1670     VASurfaceID surface,
1671     int x,      /* coordinates of the upper left source pixel */
1672     int y,
1673     unsigned int width, /* width and height of the region */
1674     unsigned int height,
1675     VAImageID image
1676 )
1677 {
1678   VADriverContextP ctx;
1679   CHECK_DISPLAY(dpy);
1680   ctx = CTX(dpy);
1681
1682   return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1683 }
1684
1685 /*
1686  * Copy data from a VAImage to a surface
1687  * Image must be in a format supported by the implementation
1688  */
1689 VAStatus vaPutImage (
1690     VADisplay dpy,
1691     VASurfaceID surface,
1692     VAImageID image,
1693     int src_x,
1694     int src_y,
1695     unsigned int src_width,
1696     unsigned int src_height,
1697     int dest_x,
1698     int dest_y,
1699     unsigned int dest_width,
1700     unsigned int dest_height
1701 )
1702 {
1703   VADriverContextP ctx;
1704   CHECK_DISPLAY(dpy);
1705   ctx = CTX(dpy);
1706
1707   return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1708 }
1709
1710 /*
1711  * Derive an VAImage from an existing surface.
1712  * This interface will derive a VAImage and corresponding image buffer from
1713  * an existing VA Surface. The image buffer can then be mapped/unmapped for
1714  * direct CPU access. This operation is only possible on implementations with
1715  * direct rendering capabilities and internal surface formats that can be
1716  * represented with a VAImage. When the operation is not possible this interface
1717  * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1718  * to using vaCreateImage + vaPutImage to accomplish the same task in an
1719  * indirect manner.
1720  *
1721  * Implementations should only return success when the resulting image buffer
1722  * would be useable with vaMap/Unmap.
1723  *
1724  * When directly accessing a surface special care must be taken to insure
1725  * proper synchronization with the graphics hardware. Clients should call
1726  * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1727  * rendering or currently being displayed by an overlay.
1728  *
1729  * Additionally nothing about the contents of a surface should be assumed
1730  * following a vaPutSurface. Implementations are free to modify the surface for
1731  * scaling or subpicture blending within a call to vaPutImage.
1732  *
1733  * Calls to vaPutImage or vaGetImage using the same surface from which the image
1734  * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1735  * vaGetImage with other surfaces is supported.
1736  *
1737  * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1738  * image and image buffer structures will be destroyed; however, the underlying
1739  * surface will remain unchanged until freed with vaDestroySurfaces.
1740  */
1741 VAStatus vaDeriveImage (
1742     VADisplay dpy,
1743     VASurfaceID surface,
1744     VAImage *image      /* out */
1745 )
1746 {
1747   VADriverContextP ctx;
1748   CHECK_DISPLAY(dpy);
1749   ctx = CTX(dpy);
1750
1751   return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1752 }
1753
1754
1755 /* Get maximum number of subpicture formats supported by the implementation */
1756 int vaMaxNumSubpictureFormats (
1757     VADisplay dpy
1758 )
1759 {
1760   if (!vaDisplayIsValid(dpy))
1761       return 0;
1762   
1763   return CTX(dpy)->max_subpic_formats;
1764 }
1765
1766 /* 
1767  * Query supported subpicture formats 
1768  * The caller must provide a "format_list" array that can hold at
1769  * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag 
1770  * for each format to indicate additional capabilities for that format. The actual 
1771  * number of formats returned in "format_list" is returned in "num_formats".
1772  */
1773 VAStatus vaQuerySubpictureFormats (
1774     VADisplay dpy,
1775     VAImageFormat *format_list, /* out */
1776     unsigned int *flags,        /* out */
1777     unsigned int *num_formats   /* out */
1778 )
1779 {
1780   VADriverContextP ctx;
1781
1782   CHECK_DISPLAY(dpy);
1783   ctx = CTX(dpy);
1784
1785   return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1786 }
1787
1788 /* 
1789  * Subpictures are created with an image associated. 
1790  */
1791 VAStatus vaCreateSubpicture (
1792     VADisplay dpy,
1793     VAImageID image,
1794     VASubpictureID *subpicture  /* out */
1795 )
1796 {
1797   VADriverContextP ctx;
1798   CHECK_DISPLAY(dpy);
1799   ctx = CTX(dpy);
1800
1801   return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1802 }
1803
1804 /*
1805  * Destroy the subpicture before destroying the image it is assocated to
1806  */
1807 VAStatus vaDestroySubpicture (
1808     VADisplay dpy,
1809     VASubpictureID subpicture
1810 )
1811 {
1812   VADriverContextP ctx;
1813   CHECK_DISPLAY(dpy);
1814   ctx = CTX(dpy);
1815
1816   return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1817 }
1818
1819 VAStatus vaSetSubpictureImage (
1820     VADisplay dpy,
1821     VASubpictureID subpicture,
1822     VAImageID image
1823 )
1824 {
1825   VADriverContextP ctx;
1826   CHECK_DISPLAY(dpy);
1827   ctx = CTX(dpy);
1828
1829   return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1830 }
1831
1832
1833 /*
1834  * If chromakey is enabled, then the area where the source value falls within
1835  * the chromakey [min, max] range is transparent
1836  */
1837 VAStatus vaSetSubpictureChromakey (
1838     VADisplay dpy,
1839     VASubpictureID subpicture,
1840     unsigned int chromakey_min,
1841     unsigned int chromakey_max,
1842     unsigned int chromakey_mask
1843 )
1844 {
1845   VADriverContextP ctx;
1846   CHECK_DISPLAY(dpy);
1847   ctx = CTX(dpy);
1848
1849   return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1850 }
1851
1852
1853 /*
1854  * Global alpha value is between 0 and 1. A value of 1 means fully opaque and 
1855  * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1856  * the overall alpha is per-pixel alpha multiplied by the global alpha
1857  */
1858 VAStatus vaSetSubpictureGlobalAlpha (
1859     VADisplay dpy,
1860     VASubpictureID subpicture,
1861     float global_alpha 
1862 )
1863 {
1864   VADriverContextP ctx;
1865   CHECK_DISPLAY(dpy);
1866   ctx = CTX(dpy);
1867
1868   return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1869 }
1870
1871 /*
1872   vaAssociateSubpicture associates the subpicture with the target_surface.
1873   It defines the region mapping between the subpicture and the target 
1874   surface through source and destination rectangles (with the same width and height).
1875   Both will be displayed at the next call to vaPutSurface.  Additional
1876   associations before the call to vaPutSurface simply overrides the association.
1877 */
1878 VAStatus vaAssociateSubpicture (
1879     VADisplay dpy,
1880     VASubpictureID subpicture,
1881     VASurfaceID *target_surfaces,
1882     int num_surfaces,
1883     short src_x, /* upper left offset in subpicture */
1884     short src_y,
1885     unsigned short src_width,
1886     unsigned short src_height,
1887     short dest_x, /* upper left offset in surface */
1888     short dest_y,
1889     unsigned short dest_width,
1890     unsigned short dest_height,
1891     /*
1892      * whether to enable chroma-keying or global-alpha
1893      * see VA_SUBPICTURE_XXX values
1894      */
1895     unsigned int flags
1896 )
1897 {
1898   VADriverContextP ctx;
1899   CHECK_DISPLAY(dpy);
1900   ctx = CTX(dpy);
1901
1902   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 );
1903 }
1904
1905 /*
1906  * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1907  */
1908 VAStatus vaDeassociateSubpicture (
1909     VADisplay dpy,
1910     VASubpictureID subpicture,
1911     VASurfaceID *target_surfaces,
1912     int num_surfaces
1913 )
1914 {
1915   VADriverContextP ctx;
1916   CHECK_DISPLAY(dpy);
1917   ctx = CTX(dpy);
1918
1919   return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1920 }
1921
1922
1923 /* Get maximum number of display attributes supported by the implementation */
1924 int vaMaxNumDisplayAttributes (
1925     VADisplay dpy
1926 )
1927 {
1928   int tmp;
1929     
1930   if (!vaDisplayIsValid(dpy))
1931       return 0;
1932   
1933   tmp = CTX(dpy)->max_display_attributes;
1934
1935   VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1936   
1937   return tmp;
1938 }
1939
1940 /* 
1941  * Query display attributes 
1942  * The caller must provide a "attr_list" array that can hold at
1943  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1944  * returned in "attr_list" is returned in "num_attributes".
1945  */
1946 VAStatus vaQueryDisplayAttributes (
1947     VADisplay dpy,
1948     VADisplayAttribute *attr_list,      /* out */
1949     int *num_attributes                 /* out */
1950 )
1951 {
1952   VADriverContextP ctx;
1953   VAStatus va_status;
1954   
1955   CHECK_DISPLAY(dpy);
1956   ctx = CTX(dpy);
1957   va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1958
1959   VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1960
1961   return va_status;
1962   
1963 }
1964
1965 /* 
1966  * Get display attributes 
1967  * This function returns the current attribute values in "attr_list".
1968  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1969  * from vaQueryDisplayAttributes() can have their values retrieved.  
1970  */
1971 VAStatus vaGetDisplayAttributes (
1972     VADisplay dpy,
1973     VADisplayAttribute *attr_list,      /* in/out */
1974     int num_attributes
1975 )
1976 {
1977   VADriverContextP ctx;
1978   VAStatus va_status;
1979
1980   CHECK_DISPLAY(dpy);
1981   ctx = CTX(dpy);
1982   va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1983
1984   VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1985   
1986   return va_status;
1987 }
1988
1989 /* 
1990  * Set display attributes 
1991  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1992  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1993  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1994  */
1995 VAStatus vaSetDisplayAttributes (
1996     VADisplay dpy,
1997     VADisplayAttribute *attr_list,
1998     int num_attributes
1999 )
2000 {
2001   VADriverContextP ctx;
2002   VAStatus va_status;
2003   CHECK_DISPLAY(dpy);
2004   ctx = CTX(dpy);
2005
2006   va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
2007   VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
2008   
2009   return va_status;
2010 }
2011
2012 VAStatus vaLockSurface(VADisplay dpy,
2013     VASurfaceID surface,
2014     unsigned int *fourcc, /* following are output argument */
2015     unsigned int *luma_stride,
2016     unsigned int *chroma_u_stride,
2017     unsigned int *chroma_v_stride,
2018     unsigned int *luma_offset,
2019     unsigned int *chroma_u_offset,
2020     unsigned int *chroma_v_offset,
2021     unsigned int *buffer_name,
2022     void **buffer 
2023 )
2024 {
2025   VADriverContextP ctx;
2026   CHECK_DISPLAY(dpy);
2027   ctx = CTX(dpy);
2028
2029   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);
2030 }
2031
2032
2033 VAStatus vaUnlockSurface(VADisplay dpy,
2034     VASurfaceID surface
2035 )
2036 {
2037   VADriverContextP ctx;
2038   CHECK_DISPLAY(dpy);
2039   ctx = CTX(dpy);
2040
2041   return ctx->vtable->vaUnlockSurface( ctx, surface );
2042 }
2043
2044 /* Video Processing */
2045 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do {              \
2046         CHECK_DISPLAY(dpy);                             \
2047         ctx = CTX(dpy);                                 \
2048         if (!ctx)                                       \
2049             return VA_STATUS_ERROR_INVALID_DISPLAY;     \
2050     } while (0)
2051
2052 #define VA_VPP_INVOKE(dpy, func, args) do {             \
2053         if (!ctx->vtable_vpp->va##func)                 \
2054             return VA_STATUS_ERROR_UNIMPLEMENTED;       \
2055         status = ctx->vtable_vpp->va##func args;        \
2056     } while (0)
2057
2058 VAStatus
2059 vaQueryVideoProcFilters(
2060     VADisplay           dpy,
2061     VAContextID         context,
2062     VAProcFilterType   *filters,
2063     unsigned int       *num_filters
2064 )
2065 {
2066     VADriverContextP ctx;
2067     VAStatus status;
2068
2069     VA_VPP_INIT_CONTEXT(ctx, dpy);
2070     VA_VPP_INVOKE(
2071         ctx,
2072         QueryVideoProcFilters,
2073         (ctx, context, filters, num_filters)
2074     );
2075     return status;
2076 }
2077
2078 VAStatus
2079 vaQueryVideoProcFilterCaps(
2080     VADisplay           dpy,
2081     VAContextID         context,
2082     VAProcFilterType    type,
2083     void               *filter_caps,
2084     unsigned int       *num_filter_caps
2085 )
2086 {
2087     VADriverContextP ctx;
2088     VAStatus status;
2089
2090     VA_VPP_INIT_CONTEXT(ctx, dpy);
2091     VA_VPP_INVOKE(
2092         ctx,
2093         QueryVideoProcFilterCaps,
2094         (ctx, context, type, filter_caps, num_filter_caps)
2095     );
2096     return status;
2097 }
2098
2099 VAStatus
2100 vaQueryVideoProcPipelineCaps(
2101     VADisplay           dpy,
2102     VAContextID         context,
2103     VABufferID         *filters,
2104     unsigned int        num_filters,
2105     VAProcPipelineCaps *pipeline_caps
2106 )
2107 {
2108     VADriverContextP ctx;
2109     VAStatus status;
2110
2111     VA_VPP_INIT_CONTEXT(ctx, dpy);
2112     VA_VPP_INVOKE(
2113         ctx,
2114         QueryVideoProcPipelineCaps,
2115         (ctx, context, filters, num_filters, pipeline_caps)
2116     );
2117     return status;
2118 }