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