OSDN Git Service

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