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 */ 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 if (driver_name) /* memory is allocated in va_getDriverName */ 468 free(driver_name); 469 470 driver_name = strdup(driver_name_env); 471 vaStatus = VA_STATUS_SUCCESS; 472 va_infoMessage("User requested driver '%s'\n", driver_name); 473 } 474 475 if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) { 476 vaStatus = va_openDriver(dpy, driver_name); 477 va_infoMessage("va_openDriver() returns %d\n", vaStatus); 478 479 *major_version = VA_MAJOR_VERSION; 480 *minor_version = VA_MINOR_VERSION; 481 } else 482 va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n", 483 vaErrorStr(vaStatus), driver_name); 484 485 if (driver_name) 486 free(driver_name); 487 488 VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version); 489 490 return vaStatus; 491 } 492 493 494 /* 495 * After this call, all library internal resources will be cleaned up 496 */ 497 VAStatus vaTerminate ( 498 VADisplay dpy 499 ) 500 { 501 VAStatus vaStatus = VA_STATUS_SUCCESS; 502 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy; 503 VADriverContextP old_ctx; 504 505 CHECK_DISPLAY(dpy); 506 old_ctx = CTX(dpy); 507 508 if (old_ctx->handle) { 509 vaStatus = old_ctx->vtable->vaTerminate(old_ctx); 510 dlclose(old_ctx->handle); 511 old_ctx->handle = NULL; 512 } 513 free(old_ctx->vtable); 514 old_ctx->vtable = NULL; 515 free(old_ctx->vtable_vpp); 516 old_ctx->vtable_vpp = NULL; 517 518 VA_TRACE_LOG(va_TraceTerminate, dpy); 519 520 va_TraceEnd(dpy); 521 522 va_FoolEnd(dpy); 523 524 if (VA_STATUS_SUCCESS == vaStatus) 525 pDisplayContext->vaDestroy(pDisplayContext); 526 527 return vaStatus; 528 } 529 530 /* 531 * vaQueryVendorString returns a pointer to a zero-terminated string 532 * describing some aspects of the VA implemenation on a specific 533 * hardware accelerator. The format of the returned string is: 534 * <vendorname>-<major_version>-<minor_version>-<addtional_info> 535 * e.g. for the Intel GMA500 implementation, an example would be: 536 * "IntelGMA500-1.0-0.2-patch3 537 */ 538 const char *vaQueryVendorString ( 539 VADisplay dpy 540 ) 541 { 542 if (!vaDisplayIsValid(dpy)) 543 return NULL; 544 545 return CTX(dpy)->str_vendor; 546 } 547 548 549 /* Get maximum number of profiles supported by the implementation */ 550 int vaMaxNumProfiles ( 551 VADisplay dpy 552 ) 553 { 554 if (!vaDisplayIsValid(dpy)) 555 return 0; 556 557 return CTX(dpy)->max_profiles; 558 } 559 560 /* Get maximum number of entrypoints supported by the implementation */ 561 int vaMaxNumEntrypoints ( 562 VADisplay dpy 563 ) 564 { 565 if (!vaDisplayIsValid(dpy)) 566 return 0; 567 568 return CTX(dpy)->max_entrypoints; 569 } 570 571 572 /* Get maximum number of attributs supported by the implementation */ 573 int vaMaxNumConfigAttributes ( 574 VADisplay dpy 575 ) 576 { 577 if (!vaDisplayIsValid(dpy)) 578 return 0; 579 580 return CTX(dpy)->max_attributes; 581 } 582 583 VAStatus vaQueryConfigEntrypoints ( 584 VADisplay dpy, 585 VAProfile profile, 586 VAEntrypoint *entrypoints, /* out */ 587 int *num_entrypoints /* out */ 588 ) 589 { 590 VADriverContextP ctx; 591 CHECK_DISPLAY(dpy); 592 ctx = CTX(dpy); 593 594 return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints); 595 } 596 597 VAStatus vaGetConfigAttributes ( 598 VADisplay dpy, 599 VAProfile profile, 600 VAEntrypoint entrypoint, 601 VAConfigAttrib *attrib_list, /* in/out */ 602 int num_attribs 603 ) 604 { 605 VADriverContextP ctx; 606 CHECK_DISPLAY(dpy); 607 ctx = CTX(dpy); 608 609 return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs ); 610 } 611 612 VAStatus vaQueryConfigProfiles ( 613 VADisplay dpy, 614 VAProfile *profile_list, /* out */ 615 int *num_profiles /* out */ 616 ) 617 { 618 VADriverContextP ctx; 619 CHECK_DISPLAY(dpy); 620 ctx = CTX(dpy); 621 622 return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles ); 623 } 624 625 VAStatus vaCreateConfig ( 626 VADisplay dpy, 627 VAProfile profile, 628 VAEntrypoint entrypoint, 629 VAConfigAttrib *attrib_list, 630 int num_attribs, 631 VAConfigID *config_id /* out */ 632 ) 633 { 634 VADriverContextP ctx; 635 VAStatus vaStatus = VA_STATUS_SUCCESS; 636 637 CHECK_DISPLAY(dpy); 638 ctx = CTX(dpy); 639 640 vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id ); 641 642 /* record the current entrypoint for further trace/fool determination */ 643 VA_TRACE_ALL(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id); 644 VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id); 645 646 return vaStatus; 647 } 648 649 VAStatus vaDestroyConfig ( 650 VADisplay dpy, 651 VAConfigID config_id 652 ) 653 { 654 VADriverContextP ctx; 655 CHECK_DISPLAY(dpy); 656 ctx = CTX(dpy); 657 658 return ctx->vtable->vaDestroyConfig ( ctx, config_id ); 659 } 660 661 VAStatus vaQueryConfigAttributes ( 662 VADisplay dpy, 663 VAConfigID config_id, 664 VAProfile *profile, /* out */ 665 VAEntrypoint *entrypoint, /* out */ 666 VAConfigAttrib *attrib_list,/* out */ 667 int *num_attribs /* out */ 668 ) 669 { 670 VADriverContextP ctx; 671 CHECK_DISPLAY(dpy); 672 ctx = CTX(dpy); 673 674 return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs); 675 } 676 677 /* XXX: this is a slow implementation that will be removed */ 678 static VAStatus 679 va_impl_query_surface_attributes( 680 VADriverContextP ctx, 681 VAConfigID config, 682 VASurfaceAttrib *out_attribs, 683 unsigned int *out_num_attribs_ptr 684 ) 685 { 686 VASurfaceAttrib *attribs = NULL; 687 unsigned int num_attribs, n; 688 VASurfaceAttrib *out_attrib; 689 unsigned int out_num_attribs; 690 VAImageFormat *image_formats = NULL; 691 int num_image_formats, i; 692 VAStatus va_status; 693 694 /* List of surface attributes to query */ 695 struct va_surface_attrib_map { 696 VASurfaceAttribType type; 697 VAGenericValueType value_type; 698 }; 699 static const struct va_surface_attrib_map attribs_map[] = { 700 { VASurfaceAttribMinWidth, VAGenericValueTypeInteger }, 701 { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger }, 702 { VASurfaceAttribMinHeight, VAGenericValueTypeInteger }, 703 { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger }, 704 { VASurfaceAttribMemoryType, VAGenericValueTypeInteger }, 705 { VASurfaceAttribNone, } 706 }; 707 708 if (!out_attribs || !out_num_attribs_ptr) 709 return VA_STATUS_ERROR_INVALID_PARAMETER; 710 if (!ctx->vtable->vaGetSurfaceAttributes) 711 return VA_STATUS_ERROR_UNIMPLEMENTED; 712 713 num_image_formats = ctx->max_image_formats; 714 image_formats = malloc(num_image_formats * sizeof(*image_formats)); 715 if (!image_formats) { 716 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED; 717 goto end; 718 } 719 720 va_status = ctx->vtable->vaQueryImageFormats( 721 ctx, image_formats, &num_image_formats); 722 if (va_status != VA_STATUS_SUCCESS) 723 goto end; 724 725 num_attribs = VASurfaceAttribCount + num_image_formats; 726 attribs = malloc(num_attribs * sizeof(*attribs)); 727 if (!attribs) { 728 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED; 729 goto end; 730 } 731 732 /* Initialize with base surface attributes, except pixel-formats */ 733 for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) { 734 VASurfaceAttrib * const attrib = &attribs[n]; 735 attrib->type = attribs_map[n].type; 736 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE; 737 attrib->value.type = attribs_map[n].value_type; 738 } 739 740 /* Append image formats */ 741 for (i = 0; i < num_image_formats; i++) { 742 VASurfaceAttrib * const attrib = &attribs[n]; 743 attrib->type = VASurfaceAttribPixelFormat; 744 attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE; 745 attrib->value.type = VAGenericValueTypeInteger; 746 attrib->value.value.i = image_formats[i].fourcc; 747 if (++n == num_attribs) { 748 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED; 749 goto end; 750 } 751 } 752 num_attribs = n; 753 754 va_status = ctx->vtable->vaGetSurfaceAttributes( 755 ctx, config, attribs, num_attribs); 756 if (va_status != VA_STATUS_SUCCESS) 757 goto end; 758 759 /* Remove invalid entries */ 760 out_num_attribs = 0; 761 for (n = 0; n < num_attribs; n++) { 762 VASurfaceAttrib * const attrib = &attribs[n]; 763 764 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED) 765 continue; 766 767 // Accept all surface attributes that are not pixel-formats 768 if (attrib->type != VASurfaceAttribPixelFormat) { 769 out_num_attribs++; 770 continue; 771 } 772 773 // Drop invalid pixel-format attribute 774 if (!attrib->value.value.i) { 775 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED; 776 continue; 777 } 778 779 // Check for duplicates 780 int is_duplicate = 0; 781 for (i = n - 1; i >= 0 && !is_duplicate; i--) { 782 const VASurfaceAttrib * const prev_attrib = &attribs[i]; 783 if (prev_attrib->type != VASurfaceAttribPixelFormat) 784 break; 785 is_duplicate = prev_attrib->value.value.i == attrib->value.value.i; 786 } 787 if (is_duplicate) 788 attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED; 789 else 790 out_num_attribs++; 791 } 792 793 if (*out_num_attribs_ptr < out_num_attribs) { 794 *out_num_attribs_ptr = out_num_attribs; 795 va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED; 796 goto end; 797 } 798 799 out_attrib = out_attribs; 800 for (n = 0; n < num_attribs; n++) { 801 const VASurfaceAttrib * const attrib = &attribs[n]; 802 if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED) 803 continue; 804 *out_attrib++ = *attrib; 805 } 806 807 end: 808 free(attribs); 809 free(image_formats); 810 return va_status; 811 } 812 813 VAStatus 814 vaQuerySurfaceAttributes( 815 VADisplay dpy, 816 VAConfigID config, 817 VASurfaceAttrib *attrib_list, 818 unsigned int *num_attribs 819 ) 820 { 821 VADriverContextP ctx; 822 VAStatus vaStatus; 823 824 CHECK_DISPLAY(dpy); 825 ctx = CTX(dpy); 826 if (!ctx) 827 return VA_STATUS_ERROR_INVALID_DISPLAY; 828 829 if (!ctx->vtable->vaQuerySurfaceAttributes) 830 vaStatus = va_impl_query_surface_attributes(ctx, config, 831 attrib_list, num_attribs); 832 else 833 vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config, 834 attrib_list, num_attribs); 835 836 VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs); 837 838 return vaStatus; 839 } 840 841 VAStatus 842 vaCreateSurfaces( 843 VADisplay dpy, 844 unsigned int format, 845 unsigned int width, 846 unsigned int height, 847 VASurfaceID *surfaces, 848 unsigned int num_surfaces, 849 VASurfaceAttrib *attrib_list, 850 unsigned int num_attribs 851 ) 852 { 853 VADriverContextP ctx; 854 VAStatus vaStatus; 855 856 CHECK_DISPLAY(dpy); 857 ctx = CTX(dpy); 858 if (!ctx) 859 return VA_STATUS_ERROR_INVALID_DISPLAY; 860 861 if (ctx->vtable->vaCreateSurfaces2) 862 vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height, 863 surfaces, num_surfaces, 864 attrib_list, num_attribs); 865 else if (attrib_list && num_attribs > 0) 866 vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 867 else 868 vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format, 869 num_surfaces, surfaces); 870 VA_TRACE_LOG(va_TraceCreateSurfaces, 871 dpy, width, height, format, num_surfaces, surfaces, 872 attrib_list, num_attribs); 873 874 return vaStatus; 875 } 876 877 878 VAStatus vaDestroySurfaces ( 879 VADisplay dpy, 880 VASurfaceID *surface_list, 881 int num_surfaces 882 ) 883 { 884 VADriverContextP ctx; 885 VAStatus vaStatus; 886 887 CHECK_DISPLAY(dpy); 888 ctx = CTX(dpy); 889 890 VA_TRACE_LOG(va_TraceDestroySurfaces, 891 dpy, surface_list, num_surfaces); 892 893 vaStatus = ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces ); 894 895 return vaStatus; 896 } 897 898 VAStatus vaCreateContext ( 899 VADisplay dpy, 900 VAConfigID config_id, 901 int picture_width, 902 int picture_height, 903 int flag, 904 VASurfaceID *render_targets, 905 int num_render_targets, 906 VAContextID *context /* out */ 907 ) 908 { 909 VADriverContextP ctx; 910 VAStatus vaStatus; 911 912 CHECK_DISPLAY(dpy); 913 ctx = CTX(dpy); 914 915 vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height, 916 flag, render_targets, num_render_targets, context ); 917 918 /* keep current encode/decode resoluton */ 919 VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context); 920 921 return vaStatus; 922 } 923 924 VAStatus vaDestroyContext ( 925 VADisplay dpy, 926 VAContextID context 927 ) 928 { 929 VADriverContextP ctx; 930 CHECK_DISPLAY(dpy); 931 ctx = CTX(dpy); 932 933 return ctx->vtable->vaDestroyContext( ctx, context ); 934 } 935 936 VAStatus vaCreateBuffer ( 937 VADisplay dpy, 938 VAContextID context, /* in */ 939 VABufferType type, /* in */ 940 unsigned int size, /* in */ 941 unsigned int num_elements, /* in */ 942 void *data, /* in */ 943 VABufferID *buf_id /* out */ 944 ) 945 { 946 VADriverContextP ctx; 947 VAStatus vaStatus; 948 949 CHECK_DISPLAY(dpy); 950 ctx = CTX(dpy); 951 952 VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id); 953 954 vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id); 955 956 VA_TRACE_LOG(va_TraceCreateBuffer, 957 dpy, context, type, size, num_elements, data, buf_id); 958 959 return vaStatus; 960 } 961 962 VAStatus vaBufferSetNumElements ( 963 VADisplay dpy, 964 VABufferID buf_id, /* in */ 965 unsigned int num_elements /* in */ 966 ) 967 { 968 VADriverContextP ctx; 969 CHECK_DISPLAY(dpy); 970 ctx = CTX(dpy); 971 972 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy); 973 974 return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements ); 975 } 976 977 978 VAStatus vaMapBuffer ( 979 VADisplay dpy, 980 VABufferID buf_id, /* in */ 981 void **pbuf /* out */ 982 ) 983 { 984 VADriverContextP ctx; 985 VAStatus va_status; 986 987 CHECK_DISPLAY(dpy); 988 ctx = CTX(dpy); 989 990 VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf); 991 992 va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf ); 993 994 VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf); 995 996 return va_status; 997 } 998 999 VAStatus vaUnmapBuffer ( 1000 VADisplay dpy, 1001 VABufferID buf_id /* in */ 1002 ) 1003 { 1004 VADriverContextP ctx; 1005 CHECK_DISPLAY(dpy); 1006 ctx = CTX(dpy); 1007 1008 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy); 1009 1010 return ctx->vtable->vaUnmapBuffer( ctx, buf_id ); 1011 } 1012 1013 VAStatus vaDestroyBuffer ( 1014 VADisplay dpy, 1015 VABufferID buffer_id 1016 ) 1017 { 1018 VADriverContextP ctx; 1019 CHECK_DISPLAY(dpy); 1020 ctx = CTX(dpy); 1021 1022 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy); 1023 1024 VA_TRACE_LOG(va_TraceDestroyBuffer, 1025 dpy, buffer_id); 1026 1027 return ctx->vtable->vaDestroyBuffer( ctx, buffer_id ); 1028 } 1029 1030 VAStatus vaBufferInfo ( 1031 VADisplay dpy, 1032 VAContextID __maybe_unused context, /* in */ 1033 VABufferID buf_id, /* in */ 1034 VABufferType *type, /* out */ 1035 unsigned int *size, /* out */ 1036 unsigned int *num_elements /* out */ 1037 ) 1038 { 1039 VADriverContextP ctx; 1040 1041 CHECK_DISPLAY(dpy); 1042 ctx = CTX(dpy); 1043 1044 VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements); 1045 1046 return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements ); 1047 } 1048 1049 VAStatus vaBeginPicture ( 1050 VADisplay dpy, 1051 VAContextID context, 1052 VASurfaceID render_target 1053 ) 1054 { 1055 VADriverContextP ctx; 1056 VAStatus va_status; 1057 1058 CHECK_DISPLAY(dpy); 1059 ctx = CTX(dpy); 1060 1061 VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target); 1062 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy); 1063 1064 va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target ); 1065 1066 return va_status; 1067 } 1068 1069 VAStatus vaRenderPicture ( 1070 VADisplay dpy, 1071 VAContextID context, 1072 VABufferID *buffers, 1073 int num_buffers 1074 ) 1075 { 1076 VADriverContextP ctx; 1077 1078 CHECK_DISPLAY(dpy); 1079 ctx = CTX(dpy); 1080 1081 VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers); 1082 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy); 1083 1084 return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers ); 1085 } 1086 1087 VAStatus vaEndPicture ( 1088 VADisplay dpy, 1089 VAContextID context 1090 ) 1091 { 1092 VAStatus va_status = VA_STATUS_SUCCESS; 1093 VADriverContextP ctx; 1094 1095 CHECK_DISPLAY(dpy); 1096 ctx = CTX(dpy); 1097 1098 VA_FOOL_FUNC(va_FoolCheckContinuity, dpy); 1099 1100 va_status = ctx->vtable->vaEndPicture( ctx, context ); 1101 1102 /* dump surface content */ 1103 VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 1); 1104 1105 return va_status; 1106 } 1107 1108 VAStatus vaSyncSurface ( 1109 VADisplay dpy, 1110 VASurfaceID render_target 1111 ) 1112 { 1113 VAStatus va_status; 1114 VADriverContextP ctx; 1115 1116 CHECK_DISPLAY(dpy); 1117 ctx = CTX(dpy); 1118 1119 va_status = ctx->vtable->vaSyncSurface( ctx, render_target ); 1120 VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target); 1121 1122 return va_status; 1123 } 1124 1125 VAStatus vaQuerySurfaceStatus ( 1126 VADisplay dpy, 1127 VASurfaceID render_target, 1128 VASurfaceStatus *status /* out */ 1129 ) 1130 { 1131 VAStatus va_status; 1132 VADriverContextP ctx; 1133 CHECK_DISPLAY(dpy); 1134 ctx = CTX(dpy); 1135 1136 va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status ); 1137 1138 VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status); 1139 1140 return va_status; 1141 } 1142 1143 VAStatus vaQuerySurfaceError ( 1144 VADisplay dpy, 1145 VASurfaceID surface, 1146 VAStatus error_status, 1147 void **error_info /*out*/ 1148 ) 1149 { 1150 VAStatus va_status; 1151 VADriverContextP ctx; 1152 CHECK_DISPLAY(dpy); 1153 ctx = CTX(dpy); 1154 1155 va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info ); 1156 1157 VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info); 1158 1159 return va_status; 1160 } 1161 1162 /* Get maximum number of image formats supported by the implementation */ 1163 int vaMaxNumImageFormats ( 1164 VADisplay dpy 1165 ) 1166 { 1167 if (!vaDisplayIsValid(dpy)) 1168 return 0; 1169 1170 return CTX(dpy)->max_image_formats; 1171 } 1172 1173 VAStatus vaQueryImageFormats ( 1174 VADisplay dpy, 1175 VAImageFormat *format_list, /* out */ 1176 int *num_formats /* out */ 1177 ) 1178 { 1179 VADriverContextP ctx; 1180 CHECK_DISPLAY(dpy); 1181 ctx = CTX(dpy); 1182 1183 return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats); 1184 } 1185 1186 /* 1187 * The width and height fields returned in the VAImage structure may get 1188 * enlarged for some YUV formats. The size of the data buffer that needs 1189 * to be allocated will be given in the "data_size" field in VAImage. 1190 * Image data is not allocated by this function. The client should 1191 * allocate the memory and fill in the VAImage structure's data field 1192 * after looking at "data_size" returned from the library. 1193 */ 1194 VAStatus vaCreateImage ( 1195 VADisplay dpy, 1196 VAImageFormat *format, 1197 int width, 1198 int height, 1199 VAImage *image /* out */ 1200 ) 1201 { 1202 VADriverContextP ctx; 1203 CHECK_DISPLAY(dpy); 1204 ctx = CTX(dpy); 1205 1206 return ctx->vtable->vaCreateImage ( ctx, format, width, height, image); 1207 } 1208 1209 /* 1210 * Should call DestroyImage before destroying the surface it is bound to 1211 */ 1212 VAStatus vaDestroyImage ( 1213 VADisplay dpy, 1214 VAImageID image 1215 ) 1216 { 1217 VADriverContextP ctx; 1218 CHECK_DISPLAY(dpy); 1219 ctx = CTX(dpy); 1220 1221 return ctx->vtable->vaDestroyImage ( ctx, image); 1222 } 1223 1224 VAStatus vaSetImagePalette ( 1225 VADisplay dpy, 1226 VAImageID image, 1227 unsigned char *palette 1228 ) 1229 { 1230 VADriverContextP ctx; 1231 CHECK_DISPLAY(dpy); 1232 ctx = CTX(dpy); 1233 1234 return ctx->vtable->vaSetImagePalette ( ctx, image, palette); 1235 } 1236 1237 /* 1238 * Retrieve surface data into a VAImage 1239 * Image must be in a format supported by the implementation 1240 */ 1241 VAStatus vaGetImage ( 1242 VADisplay dpy, 1243 VASurfaceID surface, 1244 int x, /* coordinates of the upper left source pixel */ 1245 int y, 1246 unsigned int width, /* width and height of the region */ 1247 unsigned int height, 1248 VAImageID image 1249 ) 1250 { 1251 VADriverContextP ctx; 1252 CHECK_DISPLAY(dpy); 1253 ctx = CTX(dpy); 1254 1255 return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image); 1256 } 1257 1258 /* 1259 * Copy data from a VAImage to a surface 1260 * Image must be in a format supported by the implementation 1261 */ 1262 VAStatus vaPutImage ( 1263 VADisplay dpy, 1264 VASurfaceID surface, 1265 VAImageID image, 1266 int src_x, 1267 int src_y, 1268 unsigned int src_width, 1269 unsigned int src_height, 1270 int dest_x, 1271 int dest_y, 1272 unsigned int dest_width, 1273 unsigned int dest_height 1274 ) 1275 { 1276 VADriverContextP ctx; 1277 CHECK_DISPLAY(dpy); 1278 ctx = CTX(dpy); 1279 1280 return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height ); 1281 } 1282 1283 /* 1284 * Derive an VAImage from an existing surface. 1285 * This interface will derive a VAImage and corresponding image buffer from 1286 * an existing VA Surface. The image buffer can then be mapped/unmapped for 1287 * direct CPU access. This operation is only possible on implementations with 1288 * direct rendering capabilities and internal surface formats that can be 1289 * represented with a VAImage. When the operation is not possible this interface 1290 * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back 1291 * to using vaCreateImage + vaPutImage to accomplish the same task in an 1292 * indirect manner. 1293 * 1294 * Implementations should only return success when the resulting image buffer 1295 * would be useable with vaMap/Unmap. 1296 * 1297 * When directly accessing a surface special care must be taken to insure 1298 * proper synchronization with the graphics hardware. Clients should call 1299 * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent 1300 * rendering or currently being displayed by an overlay. 1301 * 1302 * Additionally nothing about the contents of a surface should be assumed 1303 * following a vaPutSurface. Implementations are free to modify the surface for 1304 * scaling or subpicture blending within a call to vaPutImage. 1305 * 1306 * Calls to vaPutImage or vaGetImage using the same surface from which the image 1307 * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or 1308 * vaGetImage with other surfaces is supported. 1309 * 1310 * An image created with vaDeriveImage should be freed with vaDestroyImage. The 1311 * image and image buffer structures will be destroyed; however, the underlying 1312 * surface will remain unchanged until freed with vaDestroySurfaces. 1313 */ 1314 VAStatus vaDeriveImage ( 1315 VADisplay dpy, 1316 VASurfaceID surface, 1317 VAImage *image /* out */ 1318 ) 1319 { 1320 VADriverContextP ctx; 1321 CHECK_DISPLAY(dpy); 1322 ctx = CTX(dpy); 1323 1324 return ctx->vtable->vaDeriveImage ( ctx, surface, image ); 1325 } 1326 1327 1328 /* Get maximum number of subpicture formats supported by the implementation */ 1329 int vaMaxNumSubpictureFormats ( 1330 VADisplay dpy 1331 ) 1332 { 1333 if (!vaDisplayIsValid(dpy)) 1334 return 0; 1335 1336 return CTX(dpy)->max_subpic_formats; 1337 } 1338 1339 /* 1340 * Query supported subpicture formats 1341 * The caller must provide a "format_list" array that can hold at 1342 * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag 1343 * for each format to indicate additional capabilities for that format. The actual 1344 * number of formats returned in "format_list" is returned in "num_formats". 1345 */ 1346 VAStatus vaQuerySubpictureFormats ( 1347 VADisplay dpy, 1348 VAImageFormat *format_list, /* out */ 1349 unsigned int *flags, /* out */ 1350 unsigned int *num_formats /* out */ 1351 ) 1352 { 1353 VADriverContextP ctx; 1354 1355 CHECK_DISPLAY(dpy); 1356 ctx = CTX(dpy); 1357 1358 return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats); 1359 } 1360 1361 /* 1362 * Subpictures are created with an image associated. 1363 */ 1364 VAStatus vaCreateSubpicture ( 1365 VADisplay dpy, 1366 VAImageID image, 1367 VASubpictureID *subpicture /* out */ 1368 ) 1369 { 1370 VADriverContextP ctx; 1371 CHECK_DISPLAY(dpy); 1372 ctx = CTX(dpy); 1373 1374 return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture ); 1375 } 1376 1377 /* 1378 * Destroy the subpicture before destroying the image it is assocated to 1379 */ 1380 VAStatus vaDestroySubpicture ( 1381 VADisplay dpy, 1382 VASubpictureID subpicture 1383 ) 1384 { 1385 VADriverContextP ctx; 1386 CHECK_DISPLAY(dpy); 1387 ctx = CTX(dpy); 1388 1389 return ctx->vtable->vaDestroySubpicture ( ctx, subpicture); 1390 } 1391 1392 VAStatus vaSetSubpictureImage ( 1393 VADisplay dpy, 1394 VASubpictureID subpicture, 1395 VAImageID image 1396 ) 1397 { 1398 VADriverContextP ctx; 1399 CHECK_DISPLAY(dpy); 1400 ctx = CTX(dpy); 1401 1402 return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image); 1403 } 1404 1405 1406 /* 1407 * If chromakey is enabled, then the area where the source value falls within 1408 * the chromakey [min, max] range is transparent 1409 */ 1410 VAStatus vaSetSubpictureChromakey ( 1411 VADisplay dpy, 1412 VASubpictureID subpicture, 1413 unsigned int chromakey_min, 1414 unsigned int chromakey_max, 1415 unsigned int chromakey_mask 1416 ) 1417 { 1418 VADriverContextP ctx; 1419 CHECK_DISPLAY(dpy); 1420 ctx = CTX(dpy); 1421 1422 return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask ); 1423 } 1424 1425 1426 /* 1427 * Global alpha value is between 0 and 1. A value of 1 means fully opaque and 1428 * a value of 0 means fully transparent. If per-pixel alpha is also specified then 1429 * the overall alpha is per-pixel alpha multiplied by the global alpha 1430 */ 1431 VAStatus vaSetSubpictureGlobalAlpha ( 1432 VADisplay dpy, 1433 VASubpictureID subpicture, 1434 float global_alpha 1435 ) 1436 { 1437 VADriverContextP ctx; 1438 CHECK_DISPLAY(dpy); 1439 ctx = CTX(dpy); 1440 1441 return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha ); 1442 } 1443 1444 /* 1445 vaAssociateSubpicture associates the subpicture with the target_surface. 1446 It defines the region mapping between the subpicture and the target 1447 surface through source and destination rectangles (with the same width and height). 1448 Both will be displayed at the next call to vaPutSurface. Additional 1449 associations before the call to vaPutSurface simply overrides the association. 1450 */ 1451 VAStatus vaAssociateSubpicture ( 1452 VADisplay dpy, 1453 VASubpictureID subpicture, 1454 VASurfaceID *target_surfaces, 1455 int num_surfaces, 1456 short src_x, /* upper left offset in subpicture */ 1457 short src_y, 1458 unsigned short src_width, 1459 unsigned short src_height, 1460 short dest_x, /* upper left offset in surface */ 1461 short dest_y, 1462 unsigned short dest_width, 1463 unsigned short dest_height, 1464 /* 1465 * whether to enable chroma-keying or global-alpha 1466 * see VA_SUBPICTURE_XXX values 1467 */ 1468 unsigned int flags 1469 ) 1470 { 1471 VADriverContextP ctx; 1472 CHECK_DISPLAY(dpy); 1473 ctx = CTX(dpy); 1474 1475 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 ); 1476 } 1477 1478 /* 1479 * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces. 1480 */ 1481 VAStatus vaDeassociateSubpicture ( 1482 VADisplay dpy, 1483 VASubpictureID subpicture, 1484 VASurfaceID *target_surfaces, 1485 int num_surfaces 1486 ) 1487 { 1488 VADriverContextP ctx; 1489 CHECK_DISPLAY(dpy); 1490 ctx = CTX(dpy); 1491 1492 return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces ); 1493 } 1494 1495 1496 /* Get maximum number of display attributes supported by the implementation */ 1497 int vaMaxNumDisplayAttributes ( 1498 VADisplay dpy 1499 ) 1500 { 1501 int tmp; 1502 1503 if (!vaDisplayIsValid(dpy)) 1504 return 0; 1505 1506 tmp = CTX(dpy)->max_display_attributes; 1507 1508 VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp); 1509 1510 return tmp; 1511 } 1512 1513 /* 1514 * Query display attributes 1515 * The caller must provide a "attr_list" array that can hold at 1516 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes 1517 * returned in "attr_list" is returned in "num_attributes". 1518 */ 1519 VAStatus vaQueryDisplayAttributes ( 1520 VADisplay dpy, 1521 VADisplayAttribute *attr_list, /* out */ 1522 int *num_attributes /* out */ 1523 ) 1524 { 1525 VADriverContextP ctx; 1526 VAStatus va_status; 1527 1528 CHECK_DISPLAY(dpy); 1529 ctx = CTX(dpy); 1530 va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes ); 1531 1532 VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes); 1533 1534 return va_status; 1535 1536 } 1537 1538 /* 1539 * Get display attributes 1540 * This function returns the current attribute values in "attr_list". 1541 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field 1542 * from vaQueryDisplayAttributes() can have their values retrieved. 1543 */ 1544 VAStatus vaGetDisplayAttributes ( 1545 VADisplay dpy, 1546 VADisplayAttribute *attr_list, /* in/out */ 1547 int num_attributes 1548 ) 1549 { 1550 VADriverContextP ctx; 1551 VAStatus va_status; 1552 1553 CHECK_DISPLAY(dpy); 1554 ctx = CTX(dpy); 1555 va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes ); 1556 1557 VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes); 1558 1559 return va_status; 1560 } 1561 1562 /* 1563 * Set display attributes 1564 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field 1565 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or 1566 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED 1567 */ 1568 VAStatus vaSetDisplayAttributes ( 1569 VADisplay dpy, 1570 VADisplayAttribute *attr_list, 1571 int num_attributes 1572 ) 1573 { 1574 VADriverContextP ctx; 1575 VAStatus va_status; 1576 CHECK_DISPLAY(dpy); 1577 ctx = CTX(dpy); 1578 1579 va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes ); 1580 VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes); 1581 1582 return va_status; 1583 } 1584 1585 VAStatus vaLockSurface(VADisplay dpy, 1586 VASurfaceID surface, 1587 unsigned int *fourcc, /* following are output argument */ 1588 unsigned int *luma_stride, 1589 unsigned int *chroma_u_stride, 1590 unsigned int *chroma_v_stride, 1591 unsigned int *luma_offset, 1592 unsigned int *chroma_u_offset, 1593 unsigned int *chroma_v_offset, 1594 unsigned int *buffer_name, 1595 void **buffer 1596 ) 1597 { 1598 VADriverContextP ctx; 1599 CHECK_DISPLAY(dpy); 1600 ctx = CTX(dpy); 1601 1602 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); 1603 } 1604 1605 1606 VAStatus vaUnlockSurface(VADisplay dpy, 1607 VASurfaceID surface 1608 ) 1609 { 1610 VADriverContextP ctx; 1611 CHECK_DISPLAY(dpy); 1612 ctx = CTX(dpy); 1613 1614 return ctx->vtable->vaUnlockSurface( ctx, surface ); 1615 } 1616 1617 /* Video Processing */ 1618 #define VA_VPP_INIT_CONTEXT(ctx, dpy) do { \ 1619 CHECK_DISPLAY(dpy); \ 1620 ctx = CTX(dpy); \ 1621 if (!ctx) \ 1622 return VA_STATUS_ERROR_INVALID_DISPLAY; \ 1623 } while (0) 1624 1625 #define VA_VPP_INVOKE(dpy, func, args) do { \ 1626 if (!ctx->vtable_vpp->va##func) \ 1627 return VA_STATUS_ERROR_UNIMPLEMENTED; \ 1628 status = ctx->vtable_vpp->va##func args; \ 1629 } while (0) 1630 1631 VAStatus 1632 vaQueryVideoProcFilters( 1633 VADisplay dpy, 1634 VAContextID context, 1635 VAProcFilterType *filters, 1636 unsigned int *num_filters 1637 ) 1638 { 1639 VADriverContextP ctx; 1640 VAStatus status; 1641 1642 VA_VPP_INIT_CONTEXT(ctx, dpy); 1643 VA_VPP_INVOKE( 1644 ctx, 1645 QueryVideoProcFilters, 1646 (ctx, context, filters, num_filters) 1647 ); 1648 return status; 1649 } 1650 1651 VAStatus 1652 vaQueryVideoProcFilterCaps( 1653 VADisplay dpy, 1654 VAContextID context, 1655 VAProcFilterType type, 1656 void *filter_caps, 1657 unsigned int *num_filter_caps 1658 ) 1659 { 1660 VADriverContextP ctx; 1661 VAStatus status; 1662 1663 VA_VPP_INIT_CONTEXT(ctx, dpy); 1664 VA_VPP_INVOKE( 1665 ctx, 1666 QueryVideoProcFilterCaps, 1667 (ctx, context, type, filter_caps, num_filter_caps) 1668 ); 1669 return status; 1670 } 1671 1672 VAStatus 1673 vaQueryVideoProcPipelineCaps( 1674 VADisplay dpy, 1675 VAContextID context, 1676 VABufferID *filters, 1677 unsigned int num_filters, 1678 VAProcPipelineCaps *pipeline_caps 1679 ) 1680 { 1681 VADriverContextP ctx; 1682 VAStatus status; 1683 1684 VA_VPP_INIT_CONTEXT(ctx, dpy); 1685 VA_VPP_INVOKE( 1686 ctx, 1687 QueryVideoProcPipelineCaps, 1688 (ctx, context, filters, num_filters, pipeline_caps) 1689 ); 1690 return status; 1691 } 1692