OSDN Git Service

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