OSDN Git Service

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