OSDN Git Service

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