OSDN Git Service

Remove and redifine some Xlib Macros, use void* instead of Surface* for VAStatus...
[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 static 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   if (ctx->vtable.vaBufferInfo)
683       return ctx->vtable.vaBufferInfo( ctx, context, buf_id, type, size, num_elements );
684   else
685       return VA_STATUS_ERROR_UNIMPLEMENTED;
686 }
687
688 VAStatus vaBeginPicture (
689     VADisplay dpy,
690     VAContextID context,
691     VASurfaceID render_target
692 )
693 {
694   VADriverContextP ctx;
695   CHECK_DISPLAY(dpy);
696   ctx = CTX(dpy);
697
698   VA_TRACE(va_TraceBeginPicture, ctx, context, render_target);
699   return ctx->vtable.vaBeginPicture( ctx, context, render_target );
700 }
701
702 VAStatus vaRenderPicture (
703     VADisplay dpy,
704     VAContextID context,
705     VABufferID *buffers,
706     int num_buffers
707 )
708 {
709   VADriverContextP ctx;
710   CHECK_DISPLAY(dpy);
711   ctx = CTX(dpy);
712
713   VA_TRACE(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
714   return ctx->vtable.vaRenderPicture( ctx, context, buffers, num_buffers );
715 }
716
717 VAStatus vaEndPicture (
718     VADisplay dpy,
719     VAContextID context
720 )
721 {
722   VADriverContextP ctx;
723   CHECK_DISPLAY(dpy);
724   ctx = CTX(dpy);
725
726   VA_TRACE(va_TraceEndPicture, dpy, context);
727   return ctx->vtable.vaEndPicture( ctx, context );
728 }
729
730 VAStatus vaSyncSurface (
731     VADisplay dpy,
732     VASurfaceID render_target
733 )
734 {
735   VADriverContextP ctx;
736   CHECK_DISPLAY(dpy);
737   ctx = CTX(dpy);
738
739   return ctx->vtable.vaSyncSurface( ctx, render_target );
740 }
741
742 VAStatus vaQuerySurfaceStatus (
743     VADisplay dpy,
744     VASurfaceID render_target,
745     VASurfaceStatus *status     /* out */
746 )
747 {
748   VADriverContextP ctx;
749   CHECK_DISPLAY(dpy);
750   ctx = CTX(dpy);
751
752   return ctx->vtable.vaQuerySurfaceStatus( ctx, render_target, status );
753 }
754
755 /* Get maximum number of image formats supported by the implementation */
756 int vaMaxNumImageFormats (
757     VADisplay dpy
758 )
759 {
760   if( !vaDisplayIsValid(dpy) )
761       return 0;
762   
763   return CTX(dpy)->max_image_formats;
764 }
765
766 VAStatus vaQueryImageFormats (
767     VADisplay dpy,
768     VAImageFormat *format_list, /* out */
769     int *num_formats            /* out */
770 )
771 {
772   VADriverContextP ctx;
773   CHECK_DISPLAY(dpy);
774   ctx = CTX(dpy);
775
776   return ctx->vtable.vaQueryImageFormats ( ctx, format_list, num_formats);
777 }
778
779 /* 
780  * The width and height fields returned in the VAImage structure may get 
781  * enlarged for some YUV formats. The size of the data buffer that needs
782  * to be allocated will be given in the "data_size" field in VAImage.
783  * Image data is not allocated by this function.  The client should
784  * allocate the memory and fill in the VAImage structure's data field
785  * after looking at "data_size" returned from the library.
786  */
787 VAStatus vaCreateImage (
788     VADisplay dpy,
789     VAImageFormat *format,
790     int width,
791     int height,
792     VAImage *image      /* out */
793 )
794 {
795   VADriverContextP ctx;
796   CHECK_DISPLAY(dpy);
797   ctx = CTX(dpy);
798
799   return ctx->vtable.vaCreateImage ( ctx, format, width, height, image);
800 }
801
802 /*
803  * Should call DestroyImage before destroying the surface it is bound to
804  */
805 VAStatus vaDestroyImage (
806     VADisplay dpy,
807     VAImageID image
808 )
809 {
810   VADriverContextP ctx;
811   CHECK_DISPLAY(dpy);
812   ctx = CTX(dpy);
813
814   return ctx->vtable.vaDestroyImage ( ctx, image);
815 }
816
817 VAStatus vaSetImagePalette (
818     VADisplay dpy,
819     VAImageID image,
820     unsigned char *palette
821 )
822 {
823   VADriverContextP ctx;
824   CHECK_DISPLAY(dpy);
825   ctx = CTX(dpy);
826
827   return ctx->vtable.vaSetImagePalette ( ctx, image, palette);
828 }
829
830 /*
831  * Retrieve surface data into a VAImage
832  * Image must be in a format supported by the implementation
833  */
834 VAStatus vaGetImage (
835     VADisplay dpy,
836     VASurfaceID surface,
837     int x,      /* coordinates of the upper left source pixel */
838     int y,
839     unsigned int width, /* width and height of the region */
840     unsigned int height,
841     VAImageID image
842 )
843 {
844   VADriverContextP ctx;
845   CHECK_DISPLAY(dpy);
846   ctx = CTX(dpy);
847
848   return ctx->vtable.vaGetImage ( ctx, surface, x, y, width, height, image);
849 }
850
851 /*
852  * Copy data from a VAImage to a surface
853  * Image must be in a format supported by the implementation
854  */
855 VAStatus vaPutImage (
856     VADisplay dpy,
857     VASurfaceID surface,
858     VAImageID image,
859     int src_x,
860     int src_y,
861     unsigned int src_width,
862     unsigned int src_height,
863     int dest_x,
864     int dest_y,
865     unsigned int dest_width,
866     unsigned int dest_height
867 )
868 {
869   VADriverContextP ctx;
870   CHECK_DISPLAY(dpy);
871   ctx = CTX(dpy);
872
873   return ctx->vtable.vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
874 }
875
876 /*
877  * Derive an VAImage from an existing surface.
878  * This interface will derive a VAImage and corresponding image buffer from
879  * an existing VA Surface. The image buffer can then be mapped/unmapped for
880  * direct CPU access. This operation is only possible on implementations with
881  * direct rendering capabilities and internal surface formats that can be
882  * represented with a VAImage. When the operation is not possible this interface
883  * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
884  * to using vaCreateImage + vaPutImage to accomplish the same task in an
885  * indirect manner.
886  *
887  * Implementations should only return success when the resulting image buffer
888  * would be useable with vaMap/Unmap.
889  *
890  * When directly accessing a surface special care must be taken to insure
891  * proper synchronization with the graphics hardware. Clients should call
892  * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
893  * rendering or currently being displayed by an overlay.
894  *
895  * Additionally nothing about the contents of a surface should be assumed
896  * following a vaPutSurface. Implementations are free to modify the surface for
897  * scaling or subpicture blending within a call to vaPutImage.
898  *
899  * Calls to vaPutImage or vaGetImage using the same surface from which the image
900  * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
901  * vaGetImage with other surfaces is supported.
902  *
903  * An image created with vaDeriveImage should be freed with vaDestroyImage. The
904  * image and image buffer structures will be destroyed; however, the underlying
905  * surface will remain unchanged until freed with vaDestroySurfaces.
906  */
907 VAStatus vaDeriveImage (
908     VADisplay dpy,
909     VASurfaceID surface,
910     VAImage *image      /* out */
911 )
912 {
913   VADriverContextP ctx;
914   CHECK_DISPLAY(dpy);
915   ctx = CTX(dpy);
916
917   return ctx->vtable.vaDeriveImage ( ctx, surface, image );
918 }
919
920
921 /* Get maximum number of subpicture formats supported by the implementation */
922 int vaMaxNumSubpictureFormats (
923     VADisplay dpy
924 )
925 {
926   if( !vaDisplayIsValid(dpy) )
927       return 0;
928   
929   return CTX(dpy)->max_subpic_formats;
930 }
931
932 /* 
933  * Query supported subpicture formats 
934  * The caller must provide a "format_list" array that can hold at
935  * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag 
936  * for each format to indicate additional capabilities for that format. The actual 
937  * number of formats returned in "format_list" is returned in "num_formats".
938  */
939 VAStatus vaQuerySubpictureFormats (
940     VADisplay dpy,
941     VAImageFormat *format_list, /* out */
942     unsigned int *flags,        /* out */
943     unsigned int *num_formats   /* out */
944 )
945 {
946   VADriverContextP ctx;
947   CHECK_DISPLAY(dpy);
948   ctx = CTX(dpy);
949
950   return ctx->vtable.vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
951 }
952
953 /* 
954  * Subpictures are created with an image associated. 
955  */
956 VAStatus vaCreateSubpicture (
957     VADisplay dpy,
958     VAImageID image,
959     VASubpictureID *subpicture  /* out */
960 )
961 {
962   VADriverContextP ctx;
963   CHECK_DISPLAY(dpy);
964   ctx = CTX(dpy);
965
966   return ctx->vtable.vaCreateSubpicture ( ctx, image, subpicture );
967 }
968
969 /*
970  * Destroy the subpicture before destroying the image it is assocated to
971  */
972 VAStatus vaDestroySubpicture (
973     VADisplay dpy,
974     VASubpictureID subpicture
975 )
976 {
977   VADriverContextP ctx;
978   CHECK_DISPLAY(dpy);
979   ctx = CTX(dpy);
980
981   return ctx->vtable.vaDestroySubpicture ( ctx, subpicture);
982 }
983
984 VAStatus vaSetSubpictureImage (
985     VADisplay dpy,
986     VASubpictureID subpicture,
987     VAImageID image
988 )
989 {
990   VADriverContextP ctx;
991   CHECK_DISPLAY(dpy);
992   ctx = CTX(dpy);
993
994   return ctx->vtable.vaSetSubpictureImage ( ctx, subpicture, image);
995 }
996
997
998 /*
999  * If chromakey is enabled, then the area where the source value falls within
1000  * the chromakey [min, max] range is transparent
1001  */
1002 VAStatus vaSetSubpictureChromakey (
1003     VADisplay dpy,
1004     VASubpictureID subpicture,
1005     unsigned int chromakey_min,
1006     unsigned int chromakey_max,
1007     unsigned int chromakey_mask
1008 )
1009 {
1010   VADriverContextP ctx;
1011   CHECK_DISPLAY(dpy);
1012   ctx = CTX(dpy);
1013
1014   return ctx->vtable.vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1015 }
1016
1017
1018 /*
1019  * Global alpha value is between 0 and 1. A value of 1 means fully opaque and 
1020  * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1021  * the overall alpha is per-pixel alpha multiplied by the global alpha
1022  */
1023 VAStatus vaSetSubpictureGlobalAlpha (
1024     VADisplay dpy,
1025     VASubpictureID subpicture,
1026     float global_alpha 
1027 )
1028 {
1029   VADriverContextP ctx;
1030   CHECK_DISPLAY(dpy);
1031   ctx = CTX(dpy);
1032
1033   return ctx->vtable.vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1034 }
1035
1036 /*
1037   vaAssociateSubpicture associates the subpicture with the target_surface.
1038   It defines the region mapping between the subpicture and the target 
1039   surface through source and destination rectangles (with the same width and height).
1040   Both will be displayed at the next call to vaPutSurface.  Additional
1041   associations before the call to vaPutSurface simply overrides the association.
1042 */
1043 VAStatus vaAssociateSubpicture (
1044     VADisplay dpy,
1045     VASubpictureID subpicture,
1046     VASurfaceID *target_surfaces,
1047     int num_surfaces,
1048     short src_x, /* upper left offset in subpicture */
1049     short src_y,
1050     unsigned short src_width,
1051     unsigned short src_height,
1052     short dest_x, /* upper left offset in surface */
1053     short dest_y,
1054     unsigned short dest_width,
1055     unsigned short dest_height,
1056     /*
1057      * whether to enable chroma-keying or global-alpha
1058      * see VA_SUBPICTURE_XXX values
1059      */
1060     unsigned int flags
1061 )
1062 {
1063   VADriverContextP ctx;
1064   CHECK_DISPLAY(dpy);
1065   ctx = CTX(dpy);
1066
1067   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 );
1068 }
1069
1070 /*
1071  * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1072  */
1073 VAStatus vaDeassociateSubpicture (
1074     VADisplay dpy,
1075     VASubpictureID subpicture,
1076     VASurfaceID *target_surfaces,
1077     int num_surfaces
1078 )
1079 {
1080   VADriverContextP ctx;
1081   CHECK_DISPLAY(dpy);
1082   ctx = CTX(dpy);
1083
1084   return ctx->vtable.vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1085 }
1086
1087
1088 /* Get maximum number of display attributes supported by the implementation */
1089 int vaMaxNumDisplayAttributes (
1090     VADisplay dpy
1091 )
1092 {
1093   if( !vaDisplayIsValid(dpy) )
1094       return 0;
1095   
1096   return CTX(dpy)->max_display_attributes;
1097 }
1098
1099 /* 
1100  * Query display attributes 
1101  * The caller must provide a "attr_list" array that can hold at
1102  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1103  * returned in "attr_list" is returned in "num_attributes".
1104  */
1105 VAStatus vaQueryDisplayAttributes (
1106     VADisplay dpy,
1107     VADisplayAttribute *attr_list,      /* out */
1108     int *num_attributes                 /* out */
1109 )
1110 {
1111   VADriverContextP ctx;
1112   CHECK_DISPLAY(dpy);
1113   ctx = CTX(dpy);
1114
1115   return ctx->vtable.vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1116 }
1117
1118 /* 
1119  * Get display attributes 
1120  * This function returns the current attribute values in "attr_list".
1121  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1122  * from vaQueryDisplayAttributes() can have their values retrieved.  
1123  */
1124 VAStatus vaGetDisplayAttributes (
1125     VADisplay dpy,
1126     VADisplayAttribute *attr_list,      /* in/out */
1127     int num_attributes
1128 )
1129 {
1130   VADriverContextP ctx;
1131   CHECK_DISPLAY(dpy);
1132   ctx = CTX(dpy);
1133
1134   return ctx->vtable.vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1135 }
1136
1137 /* 
1138  * Set display attributes 
1139  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1140  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1141  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1142  */
1143 VAStatus vaSetDisplayAttributes (
1144     VADisplay dpy,
1145     VADisplayAttribute *attr_list,
1146     int num_attributes
1147 )
1148 {
1149   VADriverContextP ctx;
1150   CHECK_DISPLAY(dpy);
1151   ctx = CTX(dpy);
1152
1153   return ctx->vtable.vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1154 }
1155
1156 /* Wrap a CI (camera imaging) frame as a VA surface to share captured video between camear
1157  * and VA encode. With frame_id, VA driver need to call CI interfaces to get the information
1158  * of the frame, and to determine if the frame can be wrapped as a VA surface
1159  *
1160  * Application should make sure the frame is idle before the frame is passed into VA stack
1161  * and also a vaSyncSurface should be called before application tries to access the frame
1162  * from CI stack
1163  */
1164 VAStatus vaCreateSurfaceFromCIFrame (
1165     VADisplay dpy,
1166     unsigned long frame_id,
1167     VASurfaceID *surface        /* out */
1168 )
1169 {
1170   VADriverContextP ctx;
1171   CHECK_DISPLAY(dpy);
1172   ctx = CTX(dpy);
1173
1174   if (ctx->vtable.vaCreateSurfaceFromCIFrame)
1175       return ctx->vtable.vaCreateSurfaceFromCIFrame( ctx, frame_id, surface );
1176   else
1177       return VA_STATUS_ERROR_UNIMPLEMENTED;
1178 }
1179
1180
1181 /* Wrap a V4L2 buffer as a VA surface, so that V4L2 camera, VA encode
1182  * can share the data without copy
1183  * The VA driver should query the camera device from v4l2_fd to see
1184  * if camera device memory/buffer can be wrapped into a VA surface
1185  * Buffer information is passed in by v4l2_fmt and v4l2_buf structure,
1186  * VA driver also needs do further check if the buffer can meet encode
1187  * hardware requirement, such as dimension, fourcc, stride, etc
1188  *
1189  * Application should make sure the buffer is idle before the frame into VA stack
1190  * and also a vaSyncSurface should be called before application tries to access the frame
1191  * from V4L2 stack
1192  */
1193 VAStatus vaCreateSurfaceFromV4L2Buf(
1194     VADisplay dpy,
1195     int v4l2_fd,         /* file descriptor of V4L2 device */
1196     struct v4l2_format *v4l2_fmt,       /* format of V4L2 */
1197     struct v4l2_buffer *v4l2_buf,       /* V4L2 buffer */
1198     VASurfaceID *surface               /* out */
1199 )
1200 {
1201   VADriverContextP ctx;
1202   CHECK_DISPLAY(dpy);
1203   ctx = CTX(dpy);
1204
1205   if (ctx->vtable.vaCreateSurfaceFromV4L2Buf) 
1206       return ctx->vtable.vaCreateSurfaceFromV4L2Buf( ctx, v4l2_fd, v4l2_fmt, v4l2_buf, surface );
1207   else
1208       return VA_STATUS_ERROR_UNKNOWN;
1209 }
1210
1211 /* It is a debug interface, and isn't exported in core VAAPI
1212  * It is used to dump surface data into system memory
1213  * Application should explicitly call free to release the buffer memory
1214  */
1215
1216 VAStatus vaCopySurfaceToBuffer(VADisplay dpy,
1217     VASurfaceID surface,
1218     unsigned int *fourcc, /* following are output argument */
1219     unsigned int *luma_stride,
1220     unsigned int *chroma_u_stride,
1221     unsigned int *chroma_v_stride,
1222     unsigned int *luma_offset,
1223     unsigned int *chroma_u_offset,
1224     unsigned int *chroma_v_offset,
1225     void **buffer 
1226 )
1227 {
1228   VADriverContextP ctx;
1229   CHECK_DISPLAY(dpy);
1230   ctx = CTX(dpy);
1231
1232   if (ctx->vtable.vaCopySurfaceToBuffer)
1233       return ctx->vtable.vaCopySurfaceToBuffer( ctx, surface, fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset, chroma_v_offset, buffer);
1234   else
1235       return VA_STATUS_ERROR_UNIMPLEMENTED;
1236 }