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