OSDN Git Service

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