OSDN Git Service

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