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 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 */ 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 */ 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 */ 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 */ 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 */ 567 int vaMaxNumConfigAttributes ( 568 VADisplay dpy 569 ) 570 { 571 if (!vaDisplayIsValid(dpy)) 572 return 0; 573 574 return CTX(dpy)->max_attributes; 575 } 576 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 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 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 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