OSDN Git Service

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