OSDN Git Service

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