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