OSDN Git Service

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