OSDN Git Service

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