OSDN Git Service

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