OSDN Git Service

96168ae35b103715262948282254620aab634751
[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_trace.h"
31 #include "va_fool.h"
32
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <dlfcn.h>
39 #include <unistd.h>
40
41 #define DRIVER_EXTENSION        "_drv_video.so"
42
43 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
44 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
45
46 #define ASSERT          assert
47 #define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(ctx->vtable->va##func, #func)) s = VA_STATUS_ERROR_UNKNOWN;
48 #define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
49 #define CHECK_STRING(s, ctx, var) if (!va_checkString(ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
50
51 /*
52  * read a config "env" for libva.conf or from environment setting
53  * liva.conf has higher priority
54  * return 0: the "env" is set, and the value is copied into env_value
55  *        1: the env is not set
56  */
57 int va_parseConfig(char *env, char *env_value)
58 {
59     char *token, *value, *saveptr;
60     char oneline[1024];
61     FILE *fp=NULL;
62
63     if (env == NULL)
64         return 1;
65     
66     fp = fopen("/etc/libva.conf", "r");
67     while (fp && (fgets(oneline, 1024, fp) != NULL)) {
68         if (strlen(oneline) == 1)
69             continue;
70         token = strtok_r(oneline, "=\n", &saveptr);
71         value = strtok_r(NULL, "=\n", &saveptr);
72
73         if (NULL == token || NULL == value)
74             continue;
75
76         if (strcmp(token, env) == 0) {
77             if (env_value)
78                 strncpy(env_value,value, 1024);
79
80             fclose(fp);
81
82             return 0;
83         }
84     }
85     if (fp)
86         fclose(fp);
87
88     /* no setting in config file, use env setting */
89     if (getenv(env)) {
90         if (env_value)
91             strncpy(env_value, getenv(env), 1024);
92
93         return 0;
94     }
95     
96     return 1;
97 }
98
99 int vaDisplayIsValid(VADisplay dpy)
100 {
101     VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
102     return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext);
103 }
104
105 void va_errorMessage(const char *msg, ...)
106 {
107     char buf[512], *dynbuf;
108     va_list args;
109     int n, len;
110
111     va_start(args, msg);
112     len = vsnprintf(buf, sizeof(buf), msg, args);
113     va_end(args);
114
115     if (len >= (int)sizeof(buf)) {
116         dynbuf = malloc(len + 1);
117         if (!dynbuf)
118             return;
119         va_start(args, msg);
120         n = vsnprintf(dynbuf, len + 1, msg, args);
121         va_end(args);
122         if (n == len)
123             va_log_error(dynbuf);
124         free(dynbuf);
125     }
126     else if (len > 0)
127         va_log_error(buf);
128 }
129
130 void va_infoMessage(const char *msg, ...)
131 {
132     char buf[512], *dynbuf;
133     va_list args;
134     int n, len;
135
136     va_start(args, msg);
137     len = vsnprintf(buf, sizeof(buf), msg, args);
138     va_end(args);
139
140     if (len >= (int)sizeof(buf)) {
141         dynbuf = malloc(len + 1);
142         if (!dynbuf)
143             return;
144         va_start(args, msg);
145         n = vsnprintf(dynbuf, len + 1, msg, args);
146         va_end(args);
147         if (n == len)
148             va_log_info(dynbuf);
149         free(dynbuf);
150     }
151     else if (len > 0)
152         va_log_info(buf);
153 }
154
155 static bool va_checkVtable(void *ptr, char *function)
156 {
157     if (!ptr) {
158         va_errorMessage("No valid vtable entry for va%s\n", function);
159         return false;
160     }
161     return true;
162 }
163
164 static bool va_checkMaximum(int value, char *variable)
165 {
166     if (!value) {
167         va_errorMessage("Failed to define max_%s in init\n", variable);
168         return false;
169     }
170     return true;
171 }
172
173 static bool va_checkString(const char* value, char *variable)
174 {
175     if (!value) {
176         va_errorMessage("Failed to define str_%s in init\n", variable);
177         return false;
178     }
179     return true;
180 }
181
182 static inline int
183 va_getDriverInitName(char *name, int namelen, int major, int minor)
184 {
185     int ret = snprintf(name, namelen, "__vaDriverInit_%d_%d", major, minor);
186     return ret > 0 && ret < namelen;
187 }
188
189 static VAStatus va_getDriverName(VADisplay dpy, char **driver_name)
190 {
191     VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
192
193     return pDisplayContext->vaGetDriverName(pDisplayContext, driver_name);
194 }
195
196 static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
197 {
198     VADriverContextP ctx = CTX(dpy);
199     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
200     char *search_path = NULL;
201     char *saveptr;
202     char *driver_dir;
203     
204     if (geteuid() == getuid())
205         /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
206         search_path = getenv("LIBVA_DRIVERS_PATH");
207     if (!search_path)
208         search_path = VA_DRIVERS_PATH;
209
210     search_path = strdup((const char *)search_path);
211     driver_dir = strtok_r(search_path, ":", &saveptr);
212     while (driver_dir) {
213         void *handle = NULL;
214         char *driver_path = (char *) malloc( strlen(driver_dir) +
215                                              strlen(driver_name) +
216                                              strlen(DRIVER_EXTENSION) + 2 );
217         strncpy( driver_path, driver_dir, strlen(driver_dir) + 1);
218         strncat( driver_path, "/", strlen("/") );
219         strncat( driver_path, driver_name, strlen(driver_name) );
220         strncat( driver_path, DRIVER_EXTENSION, strlen(DRIVER_EXTENSION) );
221         
222         va_infoMessage("Trying to open %s\n", driver_path);
223 #ifndef ANDROID
224         handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE );
225 #else
226         handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL);
227 #endif
228         if (!handle) {
229             /* Don't give errors for non-existing files */
230             if (0 == access( driver_path, F_OK))
231                 va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
232         } else {
233             VADriverInit init_func = NULL;
234             char init_func_s[256];
235             int i;
236
237             static const struct {
238                 int major;
239                 int minor;
240             } compatible_versions[] = {
241                 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
242                 { 0, 33 },
243                 { 0, 32 },
244                 { -1, }
245             };
246
247             for (i = 0; compatible_versions[i].major >= 0; i++) {
248                 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
249                                          compatible_versions[i].major,
250                                          compatible_versions[i].minor)) {
251                     init_func = (VADriverInit)dlsym(handle, init_func_s);
252                     if (init_func) {
253                         va_infoMessage("Found init function %s\n", init_func_s);
254                         break;
255                     }
256                 }
257             }
258
259             if (compatible_versions[i].major < 0) {
260                 va_errorMessage("%s has no function %s\n",
261                                 driver_path, init_func_s);
262                 dlclose(handle);
263             } else {
264                 struct VADriverVTable *vtable = ctx->vtable;
265                 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
266
267                 vaStatus = VA_STATUS_SUCCESS;
268                 if (!vtable) {
269                     vtable = calloc(1, sizeof(*vtable));
270                     if (!vtable)
271                         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
272                 }
273                 ctx->vtable = vtable;
274
275                 if (!vtable_vpp) {
276                     vtable_vpp = calloc(1, sizeof(*vtable_vpp));
277                     if (vtable_vpp)
278                         vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
279                     else
280                         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
281                 }
282                 ctx->vtable_vpp = vtable_vpp;
283
284                 if (VA_STATUS_SUCCESS == vaStatus)
285                     vaStatus = (*init_func)(ctx);
286
287                 if (VA_STATUS_SUCCESS == vaStatus) {
288                     CHECK_MAXIMUM(vaStatus, ctx, profiles);
289                     CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
290                     CHECK_MAXIMUM(vaStatus, ctx, attributes);
291                     CHECK_MAXIMUM(vaStatus, ctx, image_formats);
292                     CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
293                     CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
294                     CHECK_STRING(vaStatus, ctx, vendor);
295                     CHECK_VTABLE(vaStatus, ctx, Terminate);
296                     CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
297                     CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
298                     CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
299                     CHECK_VTABLE(vaStatus, ctx, CreateConfig);
300                     CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
301                     CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
302                     CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
303                     CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
304                     CHECK_VTABLE(vaStatus, ctx, CreateContext);
305                     CHECK_VTABLE(vaStatus, ctx, DestroyContext);
306                     CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
307                     CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
308                     CHECK_VTABLE(vaStatus, ctx, MapBuffer);
309                     CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
310                     CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
311                     CHECK_VTABLE(vaStatus, ctx, BeginPicture);
312                     CHECK_VTABLE(vaStatus, ctx, RenderPicture);
313                     CHECK_VTABLE(vaStatus, ctx, EndPicture);
314                     CHECK_VTABLE(vaStatus, ctx, SyncSurface);
315                     CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
316                     CHECK_VTABLE(vaStatus, ctx, PutSurface);
317                     CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
318                     CHECK_VTABLE(vaStatus, ctx, CreateImage);
319                     CHECK_VTABLE(vaStatus, ctx, DeriveImage);
320                     CHECK_VTABLE(vaStatus, ctx, DestroyImage);
321                     CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
322                     CHECK_VTABLE(vaStatus, ctx, GetImage);
323                     CHECK_VTABLE(vaStatus, ctx, PutImage);
324                     CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
325                     CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
326                     CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
327                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
328                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
329                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
330                     CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
331                     CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
332                     CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
333                     CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
334                     CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
335                 }
336                 if (VA_STATUS_SUCCESS != vaStatus) {
337                     va_errorMessage("%s init failed\n", driver_path);
338                     dlclose(handle);
339                 }
340                 if (VA_STATUS_SUCCESS == vaStatus)
341                     ctx->handle = handle;
342                 free(driver_path);
343                 break;
344             }
345         }
346         free(driver_path);
347         
348         driver_dir = strtok_r(NULL, ":", &saveptr);
349     }
350     
351     free(search_path);    
352     
353     return vaStatus;
354 }
355
356 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
357 {
358     VADriverContextP ctx;
359     if (!vaDisplayIsValid(dpy))
360         return NULL;
361     ctx = CTX(dpy);
362
363     if (NULL == ctx->handle)
364         return NULL;
365         
366     return (VAPrivFunc) dlsym(ctx->handle, func);
367 }
368
369
370 /*
371  * Returns a short english description of error_status
372  */
373 const char *vaErrorStr(VAStatus error_status)
374 {
375     switch(error_status) {
376         case VA_STATUS_SUCCESS:
377             return "success (no error)";
378         case VA_STATUS_ERROR_OPERATION_FAILED:
379             return "operation failed";
380         case VA_STATUS_ERROR_ALLOCATION_FAILED:
381             return "resource allocation failed";
382         case VA_STATUS_ERROR_INVALID_DISPLAY:
383             return "invalid VADisplay";
384         case VA_STATUS_ERROR_INVALID_CONFIG:
385             return "invalid VAConfigID";
386         case VA_STATUS_ERROR_INVALID_CONTEXT:
387             return "invalid VAContextID";
388         case VA_STATUS_ERROR_INVALID_SURFACE:
389             return "invalid VASurfaceID";
390         case VA_STATUS_ERROR_INVALID_BUFFER:
391             return "invalid VABufferID";
392         case VA_STATUS_ERROR_INVALID_IMAGE:
393             return "invalid VAImageID";
394         case VA_STATUS_ERROR_INVALID_SUBPICTURE:
395             return "invalid VASubpictureID";
396         case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
397             return "attribute not supported";
398         case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
399             return "list argument exceeds maximum number";
400         case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
401             return "the requested VAProfile is not supported";
402         case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
403             return "the requested VAEntryPoint is not supported";
404         case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
405             return "the requested RT Format is not supported";
406         case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
407             return "the requested VABufferType is not supported";
408         case VA_STATUS_ERROR_SURFACE_BUSY:
409             return "surface is in use";
410         case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
411             return "flag not supported";
412         case VA_STATUS_ERROR_INVALID_PARAMETER:
413             return "invalid parameter";
414         case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
415             return "resolution not supported";
416         case VA_STATUS_ERROR_UNIMPLEMENTED:
417             return "the requested function is not implemented";
418         case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
419             return "surface is in displaying (may by overlay)" ;
420         case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
421             return "invalid VAImageFormat";
422         case VA_STATUS_ERROR_UNKNOWN:
423             return "unknown libva error";
424     }
425     return "unknown libva error / description missing";
426 }
427       
428 VAStatus vaInitialize (
429     VADisplay dpy,
430     int *major_version,  /* out */
431     int *minor_version   /* out */
432 )
433 {
434     const char *driver_name_env = NULL;
435     char *driver_name = NULL;
436     VAStatus vaStatus;
437
438     CHECK_DISPLAY(dpy);
439
440     va_TraceInit(dpy);
441
442     va_FoolInit(dpy);
443
444     va_infoMessage("VA-API version %s\n", VA_VERSION_S);
445
446     driver_name_env = getenv("LIBVA_DRIVER_NAME");
447     if (driver_name_env && geteuid() == getuid()) {
448         /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
449         driver_name = strdup(driver_name_env);
450         vaStatus = VA_STATUS_SUCCESS;
451         va_infoMessage("User requested driver '%s'\n", driver_name);
452     } else {
453         vaStatus = va_getDriverName(dpy, &driver_name);
454         va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
455     }
456
457     if (VA_STATUS_SUCCESS == vaStatus) {
458         vaStatus = va_openDriver(dpy, driver_name);
459         va_infoMessage("va_openDriver() returns %d\n", vaStatus);
460
461         *major_version = VA_MAJOR_VERSION;
462         *minor_version = VA_MINOR_VERSION;
463     }
464
465     if (driver_name)
466         free(driver_name);
467     
468     VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
469
470     return vaStatus;
471 }
472
473
474 /*
475  * After this call, all library internal resources will be cleaned up
476  */ 
477 VAStatus vaTerminate (
478     VADisplay dpy
479 )
480 {
481   VAStatus vaStatus = VA_STATUS_SUCCESS;
482   VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
483   VADriverContextP old_ctx;
484
485   CHECK_DISPLAY(dpy);
486   old_ctx = CTX(dpy);
487
488   if (old_ctx->handle) {
489       vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
490       dlclose(old_ctx->handle);
491       old_ctx->handle = NULL;
492   }
493   free(old_ctx->vtable);
494   old_ctx->vtable = NULL;
495   free(old_ctx->vtable_vpp);
496   old_ctx->vtable_vpp = NULL;
497
498   if (VA_STATUS_SUCCESS == vaStatus)
499       pDisplayContext->vaDestroy(pDisplayContext);
500
501   VA_TRACE_LOG(va_TraceTerminate, dpy);
502
503   va_TraceEnd(dpy);
504
505   va_FoolEnd(dpy);
506
507   return vaStatus;
508 }
509
510 /*
511  * vaQueryVendorString returns a pointer to a zero-terminated string
512  * describing some aspects of the VA implemenation on a specific
513  * hardware accelerator. The format of the returned string is:
514  * <vendorname>-<major_version>-<minor_version>-<addtional_info>
515  * e.g. for the Intel GMA500 implementation, an example would be:
516  * "IntelGMA500-1.0-0.2-patch3
517  */
518 const char *vaQueryVendorString (
519     VADisplay dpy
520 )
521 {
522   if (!vaDisplayIsValid(dpy))
523       return NULL;
524   
525   return CTX(dpy)->str_vendor;
526 }
527
528
529 /* Get maximum number of profiles supported by the implementation */
530 int vaMaxNumProfiles (
531     VADisplay dpy
532 )
533 {
534   if (!vaDisplayIsValid(dpy))
535       return 0;
536   
537   return CTX(dpy)->max_profiles;
538 }
539
540 /* Get maximum number of entrypoints supported by the implementation */
541 int vaMaxNumEntrypoints (
542     VADisplay dpy
543 )
544 {
545   if (!vaDisplayIsValid(dpy))
546       return 0;
547   
548   return CTX(dpy)->max_entrypoints;
549 }
550
551
552 /* Get maximum number of attributs supported by the implementation */
553 int vaMaxNumConfigAttributes (
554     VADisplay dpy
555 )
556 {
557   if (!vaDisplayIsValid(dpy))
558       return 0;
559   
560   return CTX(dpy)->max_attributes;
561 }
562
563 VAStatus vaQueryConfigEntrypoints (
564     VADisplay dpy,
565     VAProfile profile,
566     VAEntrypoint *entrypoints,  /* out */
567     int *num_entrypoints        /* out */
568 )
569 {
570   VADriverContextP ctx;
571   CHECK_DISPLAY(dpy);
572   ctx = CTX(dpy);
573
574   return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
575 }
576
577 VAStatus vaGetConfigAttributes (
578     VADisplay dpy,
579     VAProfile profile,
580     VAEntrypoint entrypoint,
581     VAConfigAttrib *attrib_list, /* in/out */
582     int num_attribs
583 )
584 {
585   VADriverContextP ctx;
586   CHECK_DISPLAY(dpy);
587   ctx = CTX(dpy);
588
589   return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
590 }
591
592 VAStatus vaQueryConfigProfiles (
593     VADisplay dpy,
594     VAProfile *profile_list,    /* out */
595     int *num_profiles           /* out */
596 )
597 {
598   VADriverContextP ctx;
599   CHECK_DISPLAY(dpy);
600   ctx = CTX(dpy);
601
602   return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
603 }
604
605 VAStatus vaCreateConfig (
606     VADisplay dpy,
607     VAProfile profile, 
608     VAEntrypoint entrypoint, 
609     VAConfigAttrib *attrib_list,
610     int num_attribs,
611     VAConfigID *config_id /* out */
612 )
613 {
614   VADriverContextP ctx;
615   VAStatus vaStatus = VA_STATUS_SUCCESS;
616   int ret = 0;
617   
618   CHECK_DISPLAY(dpy);
619   ctx = CTX(dpy);
620
621   vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
622
623   /* record the current entrypoint for further trace/fool determination */
624   VA_TRACE_FUNC(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
625   VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
626   
627   return vaStatus;
628 }
629
630 VAStatus vaDestroyConfig (
631     VADisplay dpy,
632     VAConfigID config_id
633 )
634 {
635   VADriverContextP ctx;
636   CHECK_DISPLAY(dpy);
637   ctx = CTX(dpy);
638
639   return ctx->vtable->vaDestroyConfig ( ctx, config_id );
640 }
641
642 VAStatus vaQueryConfigAttributes (
643     VADisplay dpy,
644     VAConfigID config_id, 
645     VAProfile *profile,         /* out */
646     VAEntrypoint *entrypoint,   /* out */
647     VAConfigAttrib *attrib_list,/* out */
648     int *num_attribs            /* out */
649 )
650 {
651   VADriverContextP ctx;
652   CHECK_DISPLAY(dpy);
653   ctx = CTX(dpy);
654
655   return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
656 }
657
658 VAStatus
659 vaGetSurfaceAttributes(
660     VADisplay           dpy,
661     VAConfigID          config,
662     VASurfaceAttrib    *attrib_list,
663     unsigned int        num_attribs
664 )
665 {
666     VADriverContextP ctx;
667     VAStatus vaStatus;
668
669     CHECK_DISPLAY(dpy);
670     ctx = CTX(dpy);
671     if (!ctx)
672         return VA_STATUS_ERROR_INVALID_DISPLAY;
673
674     if (!ctx->vtable->vaGetSurfaceAttributes)
675         return VA_STATUS_ERROR_UNIMPLEMENTED;
676
677     vaStatus = ctx->vtable->vaGetSurfaceAttributes(ctx, config,
678                                                    attrib_list, num_attribs);
679     return vaStatus;
680 }
681
682 VAStatus
683 vaCreateSurfaces(
684     VADisplay           dpy,
685     unsigned int        format,
686     unsigned int        width,
687     unsigned int        height,
688     VASurfaceID        *surfaces,
689     unsigned int        num_surfaces,
690     VASurfaceAttrib    *attrib_list,
691     unsigned int        num_attribs
692 )
693 {
694     VADriverContextP ctx;
695     VAStatus vaStatus;
696
697     CHECK_DISPLAY(dpy);
698     ctx = CTX(dpy);
699     if (!ctx)
700         return VA_STATUS_ERROR_INVALID_DISPLAY;
701
702     if (ctx->vtable->vaCreateSurfaces2)
703         return ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
704                                               surfaces, num_surfaces,
705                                               attrib_list, num_attribs);
706
707     if (attrib_list && num_attribs > 0)
708         return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
709
710     vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
711                                              num_surfaces, surfaces);
712
713     VA_TRACE_LOG(va_TraceCreateSurfaces,
714                  dpy, width, height, format, num_surfaces, surfaces,
715                  attrib_list, num_attribs);
716
717     return vaStatus;
718 }
719
720
721 VAStatus vaDestroySurfaces (
722     VADisplay dpy,
723     VASurfaceID *surface_list,
724     int num_surfaces
725 )
726 {
727   VADriverContextP ctx;
728   CHECK_DISPLAY(dpy);
729   ctx = CTX(dpy);
730
731   return ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
732 }
733
734 VAStatus vaCreateContext (
735     VADisplay dpy,
736     VAConfigID config_id,
737     int picture_width,
738     int picture_height,
739     int flag,
740     VASurfaceID *render_targets,
741     int num_render_targets,
742     VAContextID *context                /* out */
743 )
744 {
745   VADriverContextP ctx;
746   VAStatus vaStatus;
747   
748   CHECK_DISPLAY(dpy);
749   ctx = CTX(dpy);
750
751   vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
752                                       flag, render_targets, num_render_targets, context );
753
754   /* keep current encode/decode resoluton */
755   VA_TRACE_FUNC(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
756
757   return vaStatus;
758 }
759
760 VAStatus vaDestroyContext (
761     VADisplay dpy,
762     VAContextID context
763 )
764 {
765   VADriverContextP ctx;
766   CHECK_DISPLAY(dpy);
767   ctx = CTX(dpy);
768
769   return ctx->vtable->vaDestroyContext( ctx, context );
770 }
771
772 VAStatus vaCreateBuffer (
773     VADisplay dpy,
774     VAContextID context,        /* in */
775     VABufferType type,          /* in */
776     unsigned int size,          /* in */
777     unsigned int num_elements,  /* in */
778     void *data,                 /* in */
779     VABufferID *buf_id          /* out */
780 )
781 {
782   VADriverContextP ctx;
783   CHECK_DISPLAY(dpy);
784   ctx = CTX(dpy);
785   int ret = 0;
786
787   VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
788   if (ret)
789       return VA_STATUS_SUCCESS;
790
791   return ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
792 }
793
794 VAStatus vaBufferSetNumElements (
795     VADisplay dpy,
796     VABufferID buf_id,  /* in */
797     unsigned int num_elements /* in */
798 )
799 {
800   VADriverContextP ctx;
801   CHECK_DISPLAY(dpy);
802   ctx = CTX(dpy);
803   
804   VA_FOOL_RETURN();
805   
806   return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
807 }
808
809
810 VAStatus vaMapBuffer (
811     VADisplay dpy,
812     VABufferID buf_id,  /* in */
813     void **pbuf         /* out */
814 )
815 {
816   VADriverContextP ctx;
817   VAStatus va_status;
818   int ret = 0;
819   
820   CHECK_DISPLAY(dpy);
821   ctx = CTX(dpy);
822
823   VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
824   if (ret)
825       return VA_STATUS_SUCCESS;
826   
827   va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
828
829   VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
830   
831   return va_status;
832 }
833
834 VAStatus vaUnmapBuffer (
835     VADisplay dpy,
836     VABufferID buf_id   /* in */
837 )
838 {
839   VADriverContextP ctx;
840   CHECK_DISPLAY(dpy);
841   ctx = CTX(dpy);
842   int ret = 0;
843
844   VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
845   if (ret)
846       return VA_STATUS_SUCCESS;
847
848   return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
849 }
850
851 VAStatus vaDestroyBuffer (
852     VADisplay dpy,
853     VABufferID buffer_id
854 )
855 {
856   VADriverContextP ctx;
857   CHECK_DISPLAY(dpy);
858   ctx = CTX(dpy);
859
860   VA_FOOL_RETURN();
861   
862   return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
863 }
864
865 VAStatus vaBufferInfo (
866     VADisplay dpy,
867     VAContextID context,        /* in */
868     VABufferID buf_id,          /* in */
869     VABufferType *type,         /* out */
870     unsigned int *size,         /* out */
871     unsigned int *num_elements  /* out */
872 )
873 {
874   VADriverContextP ctx;
875   int ret = 0;
876   
877   CHECK_DISPLAY(dpy);
878   ctx = CTX(dpy);
879
880   VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
881   if (ret)
882       return VA_STATUS_SUCCESS;
883   
884   return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
885 }
886
887 VAStatus vaBeginPicture (
888     VADisplay dpy,
889     VAContextID context,
890     VASurfaceID render_target
891 )
892 {
893   VADriverContextP ctx;
894   VAStatus va_status;
895
896   CHECK_DISPLAY(dpy);
897   ctx = CTX(dpy);
898
899   VA_TRACE_FUNC(va_TraceBeginPicture, dpy, context, render_target);
900   VA_FOOL_RETURN();
901   
902   va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
903   
904   return va_status;
905 }
906
907 VAStatus vaRenderPicture (
908     VADisplay dpy,
909     VAContextID context,
910     VABufferID *buffers,
911     int num_buffers
912 )
913 {
914   VADriverContextP ctx;
915
916   CHECK_DISPLAY(dpy);
917   ctx = CTX(dpy);
918
919   VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
920   VA_FOOL_RETURN();
921
922   return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
923 }
924
925 VAStatus vaEndPicture (
926     VADisplay dpy,
927     VAContextID context
928 )
929 {
930   VAStatus va_status;
931   VADriverContextP ctx;
932
933   CHECK_DISPLAY(dpy);
934   ctx = CTX(dpy);
935
936   /* dump encode source surface */
937   VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 0);
938   /* return directly if do dummy operation */
939   VA_FOOL_RETURN();
940   
941   va_status = ctx->vtable->vaEndPicture( ctx, context );
942   /* dump decode dest surface */
943   VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
944
945   return va_status;
946 }
947
948 VAStatus vaSyncSurface (
949     VADisplay dpy,
950     VASurfaceID render_target
951 )
952 {
953   VAStatus va_status;
954   VADriverContextP ctx;
955
956   CHECK_DISPLAY(dpy);
957   ctx = CTX(dpy);
958
959   va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
960   VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
961
962   return va_status;
963 }
964
965 VAStatus vaQuerySurfaceStatus (
966     VADisplay dpy,
967     VASurfaceID render_target,
968     VASurfaceStatus *status     /* out */
969 )
970 {
971   VAStatus va_status;
972   VADriverContextP ctx;
973   CHECK_DISPLAY(dpy);
974   ctx = CTX(dpy);
975
976   va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
977
978   VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
979
980   return va_status;
981 }
982
983 VAStatus vaQuerySurfaceError (
984         VADisplay dpy,
985         VASurfaceID surface,
986         VAStatus error_status,
987         void **error_info /*out*/
988 )
989 {
990   VAStatus va_status;
991   VADriverContextP ctx;
992   CHECK_DISPLAY(dpy);
993   ctx = CTX(dpy);
994
995   va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
996
997   VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
998
999   return va_status;
1000 }
1001
1002 /* Get maximum number of image formats supported by the implementation */
1003 int vaMaxNumImageFormats (
1004     VADisplay dpy
1005 )
1006 {
1007   if (!vaDisplayIsValid(dpy))
1008       return 0;
1009   
1010   return CTX(dpy)->max_image_formats;
1011 }
1012
1013 VAStatus vaQueryImageFormats (
1014     VADisplay dpy,
1015     VAImageFormat *format_list, /* out */
1016     int *num_formats            /* out */
1017 )
1018 {
1019   VADriverContextP ctx;
1020   CHECK_DISPLAY(dpy);
1021   ctx = CTX(dpy);
1022
1023   return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1024 }
1025
1026 /* 
1027  * The width and height fields returned in the VAImage structure may get 
1028  * enlarged for some YUV formats. The size of the data buffer that needs
1029  * to be allocated will be given in the "data_size" field in VAImage.
1030  * Image data is not allocated by this function.  The client should
1031  * allocate the memory and fill in the VAImage structure's data field
1032  * after looking at "data_size" returned from the library.
1033  */
1034 VAStatus vaCreateImage (
1035     VADisplay dpy,
1036     VAImageFormat *format,
1037     int width,
1038     int height,
1039     VAImage *image      /* out */
1040 )
1041 {
1042   VADriverContextP ctx;
1043   CHECK_DISPLAY(dpy);
1044   ctx = CTX(dpy);
1045
1046   return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1047 }
1048
1049 /*
1050  * Should call DestroyImage before destroying the surface it is bound to
1051  */
1052 VAStatus vaDestroyImage (
1053     VADisplay dpy,
1054     VAImageID image
1055 )
1056 {
1057   VADriverContextP ctx;
1058   CHECK_DISPLAY(dpy);
1059   ctx = CTX(dpy);
1060
1061   return ctx->vtable->vaDestroyImage ( ctx, image);
1062 }
1063
1064 VAStatus vaSetImagePalette (
1065     VADisplay dpy,
1066     VAImageID image,
1067     unsigned char *palette
1068 )
1069 {
1070   VADriverContextP ctx;
1071   CHECK_DISPLAY(dpy);
1072   ctx = CTX(dpy);
1073
1074   return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1075 }
1076
1077 /*
1078  * Retrieve surface data into a VAImage
1079  * Image must be in a format supported by the implementation
1080  */
1081 VAStatus vaGetImage (
1082     VADisplay dpy,
1083     VASurfaceID surface,
1084     int x,      /* coordinates of the upper left source pixel */
1085     int y,
1086     unsigned int width, /* width and height of the region */
1087     unsigned int height,
1088     VAImageID image
1089 )
1090 {
1091   VADriverContextP ctx;
1092   CHECK_DISPLAY(dpy);
1093   ctx = CTX(dpy);
1094
1095   return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1096 }
1097
1098 /*
1099  * Copy data from a VAImage to a surface
1100  * Image must be in a format supported by the implementation
1101  */
1102 VAStatus vaPutImage (
1103     VADisplay dpy,
1104     VASurfaceID surface,
1105     VAImageID image,
1106     int src_x,
1107     int src_y,
1108     unsigned int src_width,
1109     unsigned int src_height,
1110     int dest_x,
1111     int dest_y,
1112     unsigned int dest_width,
1113     unsigned int dest_height
1114 )
1115 {
1116   VADriverContextP ctx;
1117   CHECK_DISPLAY(dpy);
1118   ctx = CTX(dpy);
1119
1120   return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1121 }
1122
1123 /*
1124  * Derive an VAImage from an existing surface.
1125  * This interface will derive a VAImage and corresponding image buffer from
1126  * an existing VA Surface. The image buffer can then be mapped/unmapped for
1127  * direct CPU access. This operation is only possible on implementations with
1128  * direct rendering capabilities and internal surface formats that can be
1129  * represented with a VAImage. When the operation is not possible this interface
1130  * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1131  * to using vaCreateImage + vaPutImage to accomplish the same task in an
1132  * indirect manner.
1133  *
1134  * Implementations should only return success when the resulting image buffer
1135  * would be useable with vaMap/Unmap.
1136  *
1137  * When directly accessing a surface special care must be taken to insure
1138  * proper synchronization with the graphics hardware. Clients should call
1139  * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1140  * rendering or currently being displayed by an overlay.
1141  *
1142  * Additionally nothing about the contents of a surface should be assumed
1143  * following a vaPutSurface. Implementations are free to modify the surface for
1144  * scaling or subpicture blending within a call to vaPutImage.
1145  *
1146  * Calls to vaPutImage or vaGetImage using the same surface from which the image
1147  * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1148  * vaGetImage with other surfaces is supported.
1149  *
1150  * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1151  * image and image buffer structures will be destroyed; however, the underlying
1152  * surface will remain unchanged until freed with vaDestroySurfaces.
1153  */
1154 VAStatus vaDeriveImage (
1155     VADisplay dpy,
1156     VASurfaceID surface,
1157     VAImage *image      /* out */
1158 )
1159 {
1160   VADriverContextP ctx;
1161   CHECK_DISPLAY(dpy);
1162   ctx = CTX(dpy);
1163
1164   return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1165 }
1166
1167
1168 /* Get maximum number of subpicture formats supported by the implementation */
1169 int vaMaxNumSubpictureFormats (
1170     VADisplay dpy
1171 )
1172 {
1173   if (!vaDisplayIsValid(dpy))
1174       return 0;
1175   
1176   return CTX(dpy)->max_subpic_formats;
1177 }
1178
1179 /* 
1180  * Query supported subpicture formats 
1181  * The caller must provide a "format_list" array that can hold at
1182  * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag 
1183  * for each format to indicate additional capabilities for that format. The actual 
1184  * number of formats returned in "format_list" is returned in "num_formats".
1185  */
1186 VAStatus vaQuerySubpictureFormats (
1187     VADisplay dpy,
1188     VAImageFormat *format_list, /* out */
1189     unsigned int *flags,        /* out */
1190     unsigned int *num_formats   /* out */
1191 )
1192 {
1193   VADriverContextP ctx;
1194
1195   CHECK_DISPLAY(dpy);
1196   ctx = CTX(dpy);
1197
1198   return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1199 }
1200
1201 /* 
1202  * Subpictures are created with an image associated. 
1203  */
1204 VAStatus vaCreateSubpicture (
1205     VADisplay dpy,
1206     VAImageID image,
1207     VASubpictureID *subpicture  /* out */
1208 )
1209 {
1210   VADriverContextP ctx;
1211   CHECK_DISPLAY(dpy);
1212   ctx = CTX(dpy);
1213
1214   return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1215 }
1216
1217 /*
1218  * Destroy the subpicture before destroying the image it is assocated to
1219  */
1220 VAStatus vaDestroySubpicture (
1221     VADisplay dpy,
1222     VASubpictureID subpicture
1223 )
1224 {
1225   VADriverContextP ctx;
1226   CHECK_DISPLAY(dpy);
1227   ctx = CTX(dpy);
1228
1229   return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1230 }
1231
1232 VAStatus vaSetSubpictureImage (
1233     VADisplay dpy,
1234     VASubpictureID subpicture,
1235     VAImageID image
1236 )
1237 {
1238   VADriverContextP ctx;
1239   CHECK_DISPLAY(dpy);
1240   ctx = CTX(dpy);
1241
1242   return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1243 }
1244
1245
1246 /*
1247  * If chromakey is enabled, then the area where the source value falls within
1248  * the chromakey [min, max] range is transparent
1249  */
1250 VAStatus vaSetSubpictureChromakey (
1251     VADisplay dpy,
1252     VASubpictureID subpicture,
1253     unsigned int chromakey_min,
1254     unsigned int chromakey_max,
1255     unsigned int chromakey_mask
1256 )
1257 {
1258   VADriverContextP ctx;
1259   CHECK_DISPLAY(dpy);
1260   ctx = CTX(dpy);
1261
1262   return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1263 }
1264
1265
1266 /*
1267  * Global alpha value is between 0 and 1. A value of 1 means fully opaque and 
1268  * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1269  * the overall alpha is per-pixel alpha multiplied by the global alpha
1270  */
1271 VAStatus vaSetSubpictureGlobalAlpha (
1272     VADisplay dpy,
1273     VASubpictureID subpicture,
1274     float global_alpha 
1275 )
1276 {
1277   VADriverContextP ctx;
1278   CHECK_DISPLAY(dpy);
1279   ctx = CTX(dpy);
1280
1281   return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1282 }
1283
1284 /*
1285   vaAssociateSubpicture associates the subpicture with the target_surface.
1286   It defines the region mapping between the subpicture and the target 
1287   surface through source and destination rectangles (with the same width and height).
1288   Both will be displayed at the next call to vaPutSurface.  Additional
1289   associations before the call to vaPutSurface simply overrides the association.
1290 */
1291 VAStatus vaAssociateSubpicture (
1292     VADisplay dpy,
1293     VASubpictureID subpicture,
1294     VASurfaceID *target_surfaces,
1295     int num_surfaces,
1296     short src_x, /* upper left offset in subpicture */
1297     short src_y,
1298     unsigned short src_width,
1299     unsigned short src_height,
1300     short dest_x, /* upper left offset in surface */
1301     short dest_y,
1302     unsigned short dest_width,
1303     unsigned short dest_height,
1304     /*
1305      * whether to enable chroma-keying or global-alpha
1306      * see VA_SUBPICTURE_XXX values
1307      */
1308     unsigned int flags
1309 )
1310 {
1311   VADriverContextP ctx;
1312   CHECK_DISPLAY(dpy);
1313   ctx = CTX(dpy);
1314
1315   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 );
1316 }
1317
1318 /*
1319  * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1320  */
1321 VAStatus vaDeassociateSubpicture (
1322     VADisplay dpy,
1323     VASubpictureID subpicture,
1324     VASurfaceID *target_surfaces,
1325     int num_surfaces
1326 )
1327 {
1328   VADriverContextP ctx;
1329   CHECK_DISPLAY(dpy);
1330   ctx = CTX(dpy);
1331
1332   return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1333 }
1334
1335
1336 /* Get maximum number of display attributes supported by the implementation */
1337 int vaMaxNumDisplayAttributes (
1338     VADisplay dpy
1339 )
1340 {
1341   int tmp;
1342     
1343   if (!vaDisplayIsValid(dpy))
1344       return 0;
1345   
1346   tmp = CTX(dpy)->max_display_attributes;
1347
1348   VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1349   
1350   return tmp;
1351 }
1352
1353 /* 
1354  * Query display attributes 
1355  * The caller must provide a "attr_list" array that can hold at
1356  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1357  * returned in "attr_list" is returned in "num_attributes".
1358  */
1359 VAStatus vaQueryDisplayAttributes (
1360     VADisplay dpy,
1361     VADisplayAttribute *attr_list,      /* out */
1362     int *num_attributes                 /* out */
1363 )
1364 {
1365   VADriverContextP ctx;
1366   VAStatus va_status;
1367   
1368   CHECK_DISPLAY(dpy);
1369   ctx = CTX(dpy);
1370   va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1371
1372   VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1373
1374   return va_status;
1375   
1376 }
1377
1378 /* 
1379  * Get display attributes 
1380  * This function returns the current attribute values in "attr_list".
1381  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1382  * from vaQueryDisplayAttributes() can have their values retrieved.  
1383  */
1384 VAStatus vaGetDisplayAttributes (
1385     VADisplay dpy,
1386     VADisplayAttribute *attr_list,      /* in/out */
1387     int num_attributes
1388 )
1389 {
1390   VADriverContextP ctx;
1391   VAStatus va_status;
1392
1393   CHECK_DISPLAY(dpy);
1394   ctx = CTX(dpy);
1395   va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1396
1397   VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1398   
1399   return va_status;
1400 }
1401
1402 /* 
1403  * Set display attributes 
1404  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1405  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1406  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1407  */
1408 VAStatus vaSetDisplayAttributes (
1409     VADisplay dpy,
1410     VADisplayAttribute *attr_list,
1411     int num_attributes
1412 )
1413 {
1414   VADriverContextP ctx;
1415   VAStatus va_status;
1416   CHECK_DISPLAY(dpy);
1417   ctx = CTX(dpy);
1418
1419   va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1420   VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1421   
1422   return va_status;
1423 }
1424
1425 VAStatus vaLockSurface(VADisplay dpy,
1426     VASurfaceID surface,
1427     unsigned int *fourcc, /* following are output argument */
1428     unsigned int *luma_stride,
1429     unsigned int *chroma_u_stride,
1430     unsigned int *chroma_v_stride,
1431     unsigned int *luma_offset,
1432     unsigned int *chroma_u_offset,
1433     unsigned int *chroma_v_offset,
1434     unsigned int *buffer_name,
1435     void **buffer 
1436 )
1437 {
1438   VADriverContextP ctx;
1439   CHECK_DISPLAY(dpy);
1440   ctx = CTX(dpy);
1441
1442   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);
1443 }
1444
1445
1446 VAStatus vaUnlockSurface(VADisplay dpy,
1447     VASurfaceID surface
1448 )
1449 {
1450   VADriverContextP ctx;
1451   CHECK_DISPLAY(dpy);
1452   ctx = CTX(dpy);
1453
1454   return ctx->vtable->vaUnlockSurface( ctx, surface );
1455 }
1456
1457 /* Video Processing */
1458 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do {              \
1459         CHECK_DISPLAY(dpy);                             \
1460         ctx = CTX(dpy);                                 \
1461         if (!ctx)                                       \
1462             return VA_STATUS_ERROR_INVALID_DISPLAY;     \
1463     } while (0)
1464
1465 #define VA_VPP_INVOKE(dpy, func, args) do {             \
1466         if (!ctx->vtable_vpp->va##func)                 \
1467             return VA_STATUS_ERROR_UNIMPLEMENTED;       \
1468         status = ctx->vtable_vpp->va##func args;        \
1469     } while (0)
1470
1471 VAStatus
1472 vaQueryVideoProcFilters(
1473     VADisplay           dpy,
1474     VAContextID         context,
1475     VAProcFilterType   *filters,
1476     unsigned int       *num_filters
1477 )
1478 {
1479     VADriverContextP ctx;
1480     VAStatus status;
1481
1482     VA_VPP_INIT_CONTEXT(ctx, dpy);
1483     VA_VPP_INVOKE(
1484         ctx,
1485         QueryVideoProcFilters,
1486         (ctx, context, filters, num_filters)
1487     );
1488     return status;
1489 }
1490
1491 VAStatus
1492 vaQueryVideoProcFilterCaps(
1493     VADisplay           dpy,
1494     VAContextID         context,
1495     VAProcFilterType    type,
1496     void               *filter_caps,
1497     unsigned int       *num_filter_caps
1498 )
1499 {
1500     VADriverContextP ctx;
1501     VAStatus status;
1502
1503     VA_VPP_INIT_CONTEXT(ctx, dpy);
1504     VA_VPP_INVOKE(
1505         ctx,
1506         QueryVideoProcFilterCaps,
1507         (ctx, context, type, filter_caps, num_filter_caps)
1508     );
1509     return status;
1510 }
1511
1512 VAStatus
1513 vaQueryVideoProcPipelineCaps(
1514     VADisplay           dpy,
1515     VAContextID         context,
1516     VABufferID         *filters,
1517     unsigned int        num_filters,
1518     VAProcPipelineCaps *pipeline_caps
1519 )
1520 {
1521     VADriverContextP ctx;
1522     VAStatus status;
1523
1524     VA_VPP_INIT_CONTEXT(ctx, dpy);
1525     VA_VPP_INVOKE(
1526         ctx,
1527         QueryVideoProcPipelineCaps,
1528         (ctx, context, filters, num_filters, pipeline_caps)
1529     );
1530     return status;
1531 }