OSDN Git Service

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