80025a38fc566dcbd792e0727592f3d8d892f196
[platform/upstream/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_TraceCreateSurface,
714                  dpy, width, height, format, num_surfaces, surfaces);
715
716     return vaStatus;
717 }
718
719
720 VAStatus vaDestroySurfaces (
721     VADisplay dpy,
722     VASurfaceID *surface_list,
723     int num_surfaces
724 )
725 {
726   VADriverContextP ctx;
727   CHECK_DISPLAY(dpy);
728   ctx = CTX(dpy);
729
730   return ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
731 }
732
733 VAStatus vaCreateContext (
734     VADisplay dpy,
735     VAConfigID config_id,
736     int picture_width,
737     int picture_height,
738     int flag,
739     VASurfaceID *render_targets,
740     int num_render_targets,
741     VAContextID *context                /* out */
742 )
743 {
744   VADriverContextP ctx;
745   VAStatus vaStatus;
746   
747   CHECK_DISPLAY(dpy);
748   ctx = CTX(dpy);
749
750   vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
751                                       flag, render_targets, num_render_targets, context );
752
753   /* keep current encode/decode resoluton */
754   VA_TRACE_FUNC(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
755
756   return vaStatus;
757 }
758
759 VAStatus vaDestroyContext (
760     VADisplay dpy,
761     VAContextID context
762 )
763 {
764   VADriverContextP ctx;
765   CHECK_DISPLAY(dpy);
766   ctx = CTX(dpy);
767
768   return ctx->vtable->vaDestroyContext( ctx, context );
769 }
770
771 VAStatus vaCreateBuffer (
772     VADisplay dpy,
773     VAContextID context,        /* in */
774     VABufferType type,          /* in */
775     unsigned int size,          /* in */
776     unsigned int num_elements,  /* in */
777     void *data,                 /* in */
778     VABufferID *buf_id          /* out */
779 )
780 {
781   VADriverContextP ctx;
782   CHECK_DISPLAY(dpy);
783   ctx = CTX(dpy);
784   int ret = 0;
785
786   VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
787   if (ret)
788       return VA_STATUS_SUCCESS;
789
790   return ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
791 }
792
793 VAStatus vaBufferSetNumElements (
794     VADisplay dpy,
795     VABufferID buf_id,  /* in */
796     unsigned int num_elements /* in */
797 )
798 {
799   VADriverContextP ctx;
800   CHECK_DISPLAY(dpy);
801   ctx = CTX(dpy);
802   
803   VA_FOOL_RETURN();
804   
805   return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
806 }
807
808
809 VAStatus vaMapBuffer (
810     VADisplay dpy,
811     VABufferID buf_id,  /* in */
812     void **pbuf         /* out */
813 )
814 {
815   VADriverContextP ctx;
816   VAStatus va_status;
817   int ret = 0;
818   
819   CHECK_DISPLAY(dpy);
820   ctx = CTX(dpy);
821
822   VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
823   if (ret)
824       return VA_STATUS_SUCCESS;
825   
826   va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
827
828   VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
829   
830   return va_status;
831 }
832
833 VAStatus vaUnmapBuffer (
834     VADisplay dpy,
835     VABufferID buf_id   /* in */
836 )
837 {
838   VADriverContextP ctx;
839   CHECK_DISPLAY(dpy);
840   ctx = CTX(dpy);
841   int ret = 0;
842
843   VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
844   if (ret)
845       return VA_STATUS_SUCCESS;
846
847   return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
848 }
849
850 VAStatus vaDestroyBuffer (
851     VADisplay dpy,
852     VABufferID buffer_id
853 )
854 {
855   VADriverContextP ctx;
856   CHECK_DISPLAY(dpy);
857   ctx = CTX(dpy);
858
859   VA_FOOL_RETURN();
860   
861   return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
862 }
863
864 VAStatus vaBufferInfo (
865     VADisplay dpy,
866     VAContextID context,        /* in */
867     VABufferID buf_id,          /* in */
868     VABufferType *type,         /* out */
869     unsigned int *size,         /* out */
870     unsigned int *num_elements  /* out */
871 )
872 {
873   VADriverContextP ctx;
874   int ret = 0;
875   
876   CHECK_DISPLAY(dpy);
877   ctx = CTX(dpy);
878
879   VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
880   if (ret)
881       return VA_STATUS_SUCCESS;
882   
883   return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
884 }
885
886 VAStatus vaBeginPicture (
887     VADisplay dpy,
888     VAContextID context,
889     VASurfaceID render_target
890 )
891 {
892   VADriverContextP ctx;
893   VAStatus va_status;
894
895   CHECK_DISPLAY(dpy);
896   ctx = CTX(dpy);
897
898   VA_TRACE_FUNC(va_TraceBeginPicture, dpy, context, render_target);
899   VA_FOOL_RETURN();
900   
901   va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
902   
903   return va_status;
904 }
905
906 VAStatus vaRenderPicture (
907     VADisplay dpy,
908     VAContextID context,
909     VABufferID *buffers,
910     int num_buffers
911 )
912 {
913   VADriverContextP ctx;
914
915   CHECK_DISPLAY(dpy);
916   ctx = CTX(dpy);
917
918   VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
919   VA_FOOL_RETURN();
920
921   return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
922 }
923
924 VAStatus vaEndPicture (
925     VADisplay dpy,
926     VAContextID context
927 )
928 {
929   VAStatus va_status;
930   VADriverContextP ctx;
931
932   CHECK_DISPLAY(dpy);
933   ctx = CTX(dpy);
934
935   /* dump encode source surface */
936   VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 0);
937   /* return directly if do dummy operation */
938   VA_FOOL_RETURN();
939   
940   va_status = ctx->vtable->vaEndPicture( ctx, context );
941   /* dump decode dest surface */
942   VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
943
944   return va_status;
945 }
946
947 VAStatus vaSyncSurface (
948     VADisplay dpy,
949     VASurfaceID render_target
950 )
951 {
952   VAStatus va_status;
953   VADriverContextP ctx;
954
955   CHECK_DISPLAY(dpy);
956   ctx = CTX(dpy);
957
958   va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
959   VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
960
961   return va_status;
962 }
963
964 VAStatus vaQuerySurfaceStatus (
965     VADisplay dpy,
966     VASurfaceID render_target,
967     VASurfaceStatus *status     /* out */
968 )
969 {
970   VAStatus va_status;
971   VADriverContextP ctx;
972   CHECK_DISPLAY(dpy);
973   ctx = CTX(dpy);
974
975   va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
976
977   VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
978
979   return va_status;
980 }
981
982 VAStatus vaQuerySurfaceError (
983         VADisplay dpy,
984         VASurfaceID surface,
985         VAStatus error_status,
986         void **error_info /*out*/
987 )
988 {
989   VAStatus va_status;
990   VADriverContextP ctx;
991   CHECK_DISPLAY(dpy);
992   ctx = CTX(dpy);
993
994   va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
995
996   VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
997
998   return va_status;
999 }
1000
1001 /* Get maximum number of image formats supported by the implementation */
1002 int vaMaxNumImageFormats (
1003     VADisplay dpy
1004 )
1005 {
1006   if (!vaDisplayIsValid(dpy))
1007       return 0;
1008   
1009   return CTX(dpy)->max_image_formats;
1010 }
1011
1012 VAStatus vaQueryImageFormats (
1013     VADisplay dpy,
1014     VAImageFormat *format_list, /* out */
1015     int *num_formats            /* out */
1016 )
1017 {
1018   VADriverContextP ctx;
1019   CHECK_DISPLAY(dpy);
1020   ctx = CTX(dpy);
1021
1022   return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
1023 }
1024
1025 /* 
1026  * The width and height fields returned in the VAImage structure may get 
1027  * enlarged for some YUV formats. The size of the data buffer that needs
1028  * to be allocated will be given in the "data_size" field in VAImage.
1029  * Image data is not allocated by this function.  The client should
1030  * allocate the memory and fill in the VAImage structure's data field
1031  * after looking at "data_size" returned from the library.
1032  */
1033 VAStatus vaCreateImage (
1034     VADisplay dpy,
1035     VAImageFormat *format,
1036     int width,
1037     int height,
1038     VAImage *image      /* out */
1039 )
1040 {
1041   VADriverContextP ctx;
1042   CHECK_DISPLAY(dpy);
1043   ctx = CTX(dpy);
1044
1045   return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
1046 }
1047
1048 /*
1049  * Should call DestroyImage before destroying the surface it is bound to
1050  */
1051 VAStatus vaDestroyImage (
1052     VADisplay dpy,
1053     VAImageID image
1054 )
1055 {
1056   VADriverContextP ctx;
1057   CHECK_DISPLAY(dpy);
1058   ctx = CTX(dpy);
1059
1060   return ctx->vtable->vaDestroyImage ( ctx, image);
1061 }
1062
1063 VAStatus vaSetImagePalette (
1064     VADisplay dpy,
1065     VAImageID image,
1066     unsigned char *palette
1067 )
1068 {
1069   VADriverContextP ctx;
1070   CHECK_DISPLAY(dpy);
1071   ctx = CTX(dpy);
1072
1073   return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
1074 }
1075
1076 /*
1077  * Retrieve surface data into a VAImage
1078  * Image must be in a format supported by the implementation
1079  */
1080 VAStatus vaGetImage (
1081     VADisplay dpy,
1082     VASurfaceID surface,
1083     int x,      /* coordinates of the upper left source pixel */
1084     int y,
1085     unsigned int width, /* width and height of the region */
1086     unsigned int height,
1087     VAImageID image
1088 )
1089 {
1090   VADriverContextP ctx;
1091   CHECK_DISPLAY(dpy);
1092   ctx = CTX(dpy);
1093
1094   return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
1095 }
1096
1097 /*
1098  * Copy data from a VAImage to a surface
1099  * Image must be in a format supported by the implementation
1100  */
1101 VAStatus vaPutImage (
1102     VADisplay dpy,
1103     VASurfaceID surface,
1104     VAImageID image,
1105     int src_x,
1106     int src_y,
1107     unsigned int src_width,
1108     unsigned int src_height,
1109     int dest_x,
1110     int dest_y,
1111     unsigned int dest_width,
1112     unsigned int dest_height
1113 )
1114 {
1115   VADriverContextP ctx;
1116   CHECK_DISPLAY(dpy);
1117   ctx = CTX(dpy);
1118
1119   return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
1120 }
1121
1122 /*
1123  * Derive an VAImage from an existing surface.
1124  * This interface will derive a VAImage and corresponding image buffer from
1125  * an existing VA Surface. The image buffer can then be mapped/unmapped for
1126  * direct CPU access. This operation is only possible on implementations with
1127  * direct rendering capabilities and internal surface formats that can be
1128  * represented with a VAImage. When the operation is not possible this interface
1129  * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
1130  * to using vaCreateImage + vaPutImage to accomplish the same task in an
1131  * indirect manner.
1132  *
1133  * Implementations should only return success when the resulting image buffer
1134  * would be useable with vaMap/Unmap.
1135  *
1136  * When directly accessing a surface special care must be taken to insure
1137  * proper synchronization with the graphics hardware. Clients should call
1138  * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1139  * rendering or currently being displayed by an overlay.
1140  *
1141  * Additionally nothing about the contents of a surface should be assumed
1142  * following a vaPutSurface. Implementations are free to modify the surface for
1143  * scaling or subpicture blending within a call to vaPutImage.
1144  *
1145  * Calls to vaPutImage or vaGetImage using the same surface from which the image
1146  * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1147  * vaGetImage with other surfaces is supported.
1148  *
1149  * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1150  * image and image buffer structures will be destroyed; however, the underlying
1151  * surface will remain unchanged until freed with vaDestroySurfaces.
1152  */
1153 VAStatus vaDeriveImage (
1154     VADisplay dpy,
1155     VASurfaceID surface,
1156     VAImage *image      /* out */
1157 )
1158 {
1159   VADriverContextP ctx;
1160   CHECK_DISPLAY(dpy);
1161   ctx = CTX(dpy);
1162
1163   return ctx->vtable->vaDeriveImage ( ctx, surface, image );
1164 }
1165
1166
1167 /* Get maximum number of subpicture formats supported by the implementation */
1168 int vaMaxNumSubpictureFormats (
1169     VADisplay dpy
1170 )
1171 {
1172   if (!vaDisplayIsValid(dpy))
1173       return 0;
1174   
1175   return CTX(dpy)->max_subpic_formats;
1176 }
1177
1178 /* 
1179  * Query supported subpicture formats 
1180  * The caller must provide a "format_list" array that can hold at
1181  * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag 
1182  * for each format to indicate additional capabilities for that format. The actual 
1183  * number of formats returned in "format_list" is returned in "num_formats".
1184  */
1185 VAStatus vaQuerySubpictureFormats (
1186     VADisplay dpy,
1187     VAImageFormat *format_list, /* out */
1188     unsigned int *flags,        /* out */
1189     unsigned int *num_formats   /* out */
1190 )
1191 {
1192   VADriverContextP ctx;
1193
1194   CHECK_DISPLAY(dpy);
1195   ctx = CTX(dpy);
1196
1197   return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1198 }
1199
1200 /* 
1201  * Subpictures are created with an image associated. 
1202  */
1203 VAStatus vaCreateSubpicture (
1204     VADisplay dpy,
1205     VAImageID image,
1206     VASubpictureID *subpicture  /* out */
1207 )
1208 {
1209   VADriverContextP ctx;
1210   CHECK_DISPLAY(dpy);
1211   ctx = CTX(dpy);
1212
1213   return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
1214 }
1215
1216 /*
1217  * Destroy the subpicture before destroying the image it is assocated to
1218  */
1219 VAStatus vaDestroySubpicture (
1220     VADisplay dpy,
1221     VASubpictureID subpicture
1222 )
1223 {
1224   VADriverContextP ctx;
1225   CHECK_DISPLAY(dpy);
1226   ctx = CTX(dpy);
1227
1228   return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
1229 }
1230
1231 VAStatus vaSetSubpictureImage (
1232     VADisplay dpy,
1233     VASubpictureID subpicture,
1234     VAImageID image
1235 )
1236 {
1237   VADriverContextP ctx;
1238   CHECK_DISPLAY(dpy);
1239   ctx = CTX(dpy);
1240
1241   return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
1242 }
1243
1244
1245 /*
1246  * If chromakey is enabled, then the area where the source value falls within
1247  * the chromakey [min, max] range is transparent
1248  */
1249 VAStatus vaSetSubpictureChromakey (
1250     VADisplay dpy,
1251     VASubpictureID subpicture,
1252     unsigned int chromakey_min,
1253     unsigned int chromakey_max,
1254     unsigned int chromakey_mask
1255 )
1256 {
1257   VADriverContextP ctx;
1258   CHECK_DISPLAY(dpy);
1259   ctx = CTX(dpy);
1260
1261   return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1262 }
1263
1264
1265 /*
1266  * Global alpha value is between 0 and 1. A value of 1 means fully opaque and 
1267  * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1268  * the overall alpha is per-pixel alpha multiplied by the global alpha
1269  */
1270 VAStatus vaSetSubpictureGlobalAlpha (
1271     VADisplay dpy,
1272     VASubpictureID subpicture,
1273     float global_alpha 
1274 )
1275 {
1276   VADriverContextP ctx;
1277   CHECK_DISPLAY(dpy);
1278   ctx = CTX(dpy);
1279
1280   return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1281 }
1282
1283 /*
1284   vaAssociateSubpicture associates the subpicture with the target_surface.
1285   It defines the region mapping between the subpicture and the target 
1286   surface through source and destination rectangles (with the same width and height).
1287   Both will be displayed at the next call to vaPutSurface.  Additional
1288   associations before the call to vaPutSurface simply overrides the association.
1289 */
1290 VAStatus vaAssociateSubpicture (
1291     VADisplay dpy,
1292     VASubpictureID subpicture,
1293     VASurfaceID *target_surfaces,
1294     int num_surfaces,
1295     short src_x, /* upper left offset in subpicture */
1296     short src_y,
1297     unsigned short src_width,
1298     unsigned short src_height,
1299     short dest_x, /* upper left offset in surface */
1300     short dest_y,
1301     unsigned short dest_width,
1302     unsigned short dest_height,
1303     /*
1304      * whether to enable chroma-keying or global-alpha
1305      * see VA_SUBPICTURE_XXX values
1306      */
1307     unsigned int flags
1308 )
1309 {
1310   VADriverContextP ctx;
1311   CHECK_DISPLAY(dpy);
1312   ctx = CTX(dpy);
1313
1314   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 );
1315 }
1316
1317 /*
1318  * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1319  */
1320 VAStatus vaDeassociateSubpicture (
1321     VADisplay dpy,
1322     VASubpictureID subpicture,
1323     VASurfaceID *target_surfaces,
1324     int num_surfaces
1325 )
1326 {
1327   VADriverContextP ctx;
1328   CHECK_DISPLAY(dpy);
1329   ctx = CTX(dpy);
1330
1331   return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1332 }
1333
1334
1335 /* Get maximum number of display attributes supported by the implementation */
1336 int vaMaxNumDisplayAttributes (
1337     VADisplay dpy
1338 )
1339 {
1340   int tmp;
1341     
1342   if (!vaDisplayIsValid(dpy))
1343       return 0;
1344   
1345   tmp = CTX(dpy)->max_display_attributes;
1346
1347   VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
1348   
1349   return tmp;
1350 }
1351
1352 /* 
1353  * Query display attributes 
1354  * The caller must provide a "attr_list" array that can hold at
1355  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1356  * returned in "attr_list" is returned in "num_attributes".
1357  */
1358 VAStatus vaQueryDisplayAttributes (
1359     VADisplay dpy,
1360     VADisplayAttribute *attr_list,      /* out */
1361     int *num_attributes                 /* out */
1362 )
1363 {
1364   VADriverContextP ctx;
1365   VAStatus va_status;
1366   
1367   CHECK_DISPLAY(dpy);
1368   ctx = CTX(dpy);
1369   va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1370
1371   VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
1372
1373   return va_status;
1374   
1375 }
1376
1377 /* 
1378  * Get display attributes 
1379  * This function returns the current attribute values in "attr_list".
1380  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1381  * from vaQueryDisplayAttributes() can have their values retrieved.  
1382  */
1383 VAStatus vaGetDisplayAttributes (
1384     VADisplay dpy,
1385     VADisplayAttribute *attr_list,      /* in/out */
1386     int num_attributes
1387 )
1388 {
1389   VADriverContextP ctx;
1390   VAStatus va_status;
1391
1392   CHECK_DISPLAY(dpy);
1393   ctx = CTX(dpy);
1394   va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1395
1396   VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
1397   
1398   return va_status;
1399 }
1400
1401 /* 
1402  * Set display attributes 
1403  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1404  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1405  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1406  */
1407 VAStatus vaSetDisplayAttributes (
1408     VADisplay dpy,
1409     VADisplayAttribute *attr_list,
1410     int num_attributes
1411 )
1412 {
1413   VADriverContextP ctx;
1414   VAStatus va_status;
1415   CHECK_DISPLAY(dpy);
1416   ctx = CTX(dpy);
1417
1418   va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1419   VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
1420   
1421   return va_status;
1422 }
1423
1424 VAStatus vaLockSurface(VADisplay dpy,
1425     VASurfaceID surface,
1426     unsigned int *fourcc, /* following are output argument */
1427     unsigned int *luma_stride,
1428     unsigned int *chroma_u_stride,
1429     unsigned int *chroma_v_stride,
1430     unsigned int *luma_offset,
1431     unsigned int *chroma_u_offset,
1432     unsigned int *chroma_v_offset,
1433     unsigned int *buffer_name,
1434     void **buffer 
1435 )
1436 {
1437   VADriverContextP ctx;
1438   CHECK_DISPLAY(dpy);
1439   ctx = CTX(dpy);
1440
1441   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);
1442 }
1443
1444
1445 VAStatus vaUnlockSurface(VADisplay dpy,
1446     VASurfaceID surface
1447 )
1448 {
1449   VADriverContextP ctx;
1450   CHECK_DISPLAY(dpy);
1451   ctx = CTX(dpy);
1452
1453   return ctx->vtable->vaUnlockSurface( ctx, surface );
1454 }
1455
1456 /* Video Processing */
1457 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do {              \
1458         CHECK_DISPLAY(dpy);                             \
1459         ctx = CTX(dpy);                                 \
1460         if (!ctx)                                       \
1461             return VA_STATUS_ERROR_INVALID_DISPLAY;     \
1462     } while (0)
1463
1464 #define VA_VPP_INVOKE(dpy, func, args) do {             \
1465         if (!ctx->vtable_vpp->va##func)                 \
1466             return VA_STATUS_ERROR_UNIMPLEMENTED;       \
1467         status = ctx->vtable_vpp->va##func args;        \
1468     } while (0)
1469
1470 VAStatus
1471 vaQueryVideoProcFilters(
1472     VADisplay           dpy,
1473     VAContextID         context,
1474     VAProcFilterType   *filters,
1475     unsigned int       *num_filters
1476 )
1477 {
1478     VADriverContextP ctx;
1479     VAStatus status;
1480
1481     VA_VPP_INIT_CONTEXT(ctx, dpy);
1482     VA_VPP_INVOKE(
1483         ctx,
1484         QueryVideoProcFilters,
1485         (ctx, context, filters, num_filters)
1486     );
1487     return status;
1488 }
1489
1490 VAStatus
1491 vaQueryVideoProcFilterCaps(
1492     VADisplay           dpy,
1493     VAContextID         context,
1494     VAProcFilterType    type,
1495     void               *filter_caps,
1496     unsigned int       *num_filter_caps
1497 )
1498 {
1499     VADriverContextP ctx;
1500     VAStatus status;
1501
1502     VA_VPP_INIT_CONTEXT(ctx, dpy);
1503     VA_VPP_INVOKE(
1504         ctx,
1505         QueryVideoProcFilterCaps,
1506         (ctx, context, type, filter_caps, num_filter_caps)
1507     );
1508     return status;
1509 }
1510
1511 VAStatus
1512 vaQueryVideoProcPipelineCaps(
1513     VADisplay           dpy,
1514     VAContextID         context,
1515     VABufferID         *filters,
1516     unsigned int        num_filters,
1517     VAProcPipelineCaps *pipeline_caps
1518 )
1519 {
1520     VADriverContextP ctx;
1521     VAStatus status;
1522
1523     VA_VPP_INIT_CONTEXT(ctx, dpy);
1524     VA_VPP_INVOKE(
1525         ctx,
1526         QueryVideoProcPipelineCaps,
1527         (ctx, context, filters, num_filters, pipeline_caps)
1528     );
1529     return status;
1530 }