OSDN Git Service

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