OSDN Git Service

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