OSDN Git Service

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