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