OSDN Git Service

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