psb_drv_video.c revision c188aa00cc5a56361298b94be444d70bc148eb40
1/* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * Copyright (c) Imagination Technologies Limited, UK 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Waldo Bastian <waldo.bastian@intel.com> 27 * 28 */ 29 30#include <va/va_backend.h> 31#include <va/va_backend_tpi.h> 32#include <va/va_backend_egl.h> 33#ifdef PSBVIDEO_MRFL_VPP 34#include <va/va_backend_vpp.h> 35#endif 36#include <va/va_dricommon.h> 37 38#include "psb_drv_video.h" 39#include "psb_texture.h" 40#include "psb_cmdbuf.h" 41#include "lnc_cmdbuf.h" 42#include "pnw_cmdbuf.h" 43#include "tng_cmdbuf.h" 44#ifdef PSBVIDEO_MRFL_VPP 45#include "vsp_cmdbuf.h" 46#endif 47#include "psb_surface.h" 48 49#ifdef PSBVIDEO_MRST 50#include "psb_MPEG2.h" 51#include "psb_MPEG4.h" 52#include "psb_H264.h" 53#include "psb_VC1.h" 54#include "lnc_MPEG4ES.h" 55#include "lnc_H264ES.h" 56#include "lnc_H263ES.h" 57#endif 58#include "pnw_MPEG2.h" 59#include "pnw_MPEG4.h" 60#include "pnw_H264.h" 61#include "pnw_VC1.h" 62#include "tng_jpegdec.h" 63#include "tng_VP8.h" 64#ifdef PSBVIDEO_MFLD 65#include "pnw_MPEG4ES.h" 66#include "pnw_H264ES.h" 67#include "pnw_H263ES.h" 68#include "pnw_jpeg.h" 69#endif 70#ifdef PSBVIDEO_MRFL 71#include "tng_H264ES.h" 72#include "tng_H263ES.h" 73#include "tng_MPEG4ES.h" 74#include "tng_jpegES.h" 75#endif 76#ifdef PSBVIDEO_MRFL_VPP 77#include "vsp_VPP.h" 78#endif 79#include "psb_output.h" 80#include <stdio.h> 81#include <string.h> 82#include <stdarg.h> 83#include <time.h> 84#include <unistd.h> 85#include <wsbm/wsbm_pool.h> 86#include <wsbm/wsbm_manager.h> 87#include <wsbm/wsbm_util.h> 88#include <wsbm/wsbm_fencemgr.h> 89#include <linux/videodev2.h> 90#include <errno.h> 91 92#include "psb_def.h" 93#include "psb_drv_debug.h" 94#include "psb_ws_driver.h" 95#include "pnw_rotate.h" 96#include "psb_surface_attrib.h" 97 98#ifndef PSB_PACKAGE_VERSION 99#define PSB_PACKAGE_VERSION "Undefined" 100#endif 101 102#define PSB_DRV_VERSION PSB_PACKAGE_VERSION 103#define PSB_CHG_REVISION "(0X00000071)" 104 105#define PSB_STR_VENDOR_MRST "Intel GMA500-MRST-" PSB_DRV_VERSION " " PSB_CHG_REVISION 106#define PSB_STR_VENDOR_MFLD "Intel GMA500-MFLD-" PSB_DRV_VERSION " " PSB_CHG_REVISION 107#define PSB_STR_VENDOR_MRFL "Intel GMA500-MRFL-" PSB_DRV_VERSION " " PSB_CHG_REVISION 108#define PSB_STR_VENDOR_LEXINGTON "Intel GMA500-LEXINGTON-" PSB_DRV_VERSION " " PSB_CHG_REVISION 109 110#define MAX_UNUSED_BUFFERS 16 111 112#define PSB_MAX_FLIP_DELAY (1000/30/10) 113 114#include <signal.h> 115 116extern int force_texure_1080p_60fps; 117 118#define EXPORT __attribute__ ((visibility("default"))) 119 120#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 121 122#ifdef PSBVIDEO_MRFL_VPP 123#define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL; 124#else 125#define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? driver_data->profile2Format[profile][entrypoint] : NULL; 126#endif 127 128#define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id )) 129#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 130#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) 131#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 132 133#define CONFIG_ID_OFFSET 0x01000000 134#define CONTEXT_ID_OFFSET 0x02000000 135#define SURFACE_ID_OFFSET 0x03000000 136#define BUFFER_ID_OFFSET 0x04000000 137#define IMAGE_ID_OFFSET 0x05000000 138#define SUBPIC_ID_OFFSET 0x06000000 139 140static int psb_get_device_info(VADriverContextP ctx); 141 142 143void psb_init_surface_pvr2dbuf(psb_driver_data_p driver_data); 144void psb_free_surface_pvr2dbuf(psb_driver_data_p driver_data); 145 146VAStatus psb_QueryConfigProfiles( 147 VADriverContextP ctx, 148 VAProfile *profile_list, /* out */ 149 int *num_profiles /* out */ 150) 151{ 152 DEBUG_FUNC_ENTER 153 (void) ctx; /* unused */ 154 int i = 0; 155 VAStatus vaStatus = VA_STATUS_SUCCESS; 156 INIT_DRIVER_DATA 157 158 if (NULL == profile_list) { 159 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 160 DEBUG_FAILURE; 161 return vaStatus; 162 } 163 if (NULL == num_profiles) { 164 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 165 DEBUG_FAILURE; 166 return vaStatus; 167 } 168#ifdef PSBVIDEO_MRFL_VPP 169 profile_list[i++] = VAProfileNone; 170#endif 171// profile_list[i++] = VAProfileMPEG2Simple; 172 profile_list[i++] = VAProfileMPEG2Main; 173 profile_list[i++] = VAProfileMPEG4Simple; 174 profile_list[i++] = VAProfileMPEG4AdvancedSimple; 175// profile_list[i++] = VAProfileMPEG4Main; 176 profile_list[i++] = VAProfileH264Baseline; 177 profile_list[i++] = VAProfileH264Main; 178 profile_list[i++] = VAProfileH264High; 179 profile_list[i++] = VAProfileH264StereoHigh; 180 profile_list[i++] = VAProfileVC1Simple; 181 profile_list[i++] = VAProfileVC1Main; 182 profile_list[i++] = VAProfileVC1Advanced; 183 184 if (IS_MRFL(driver_data)) { 185 profile_list[i++] = VAProfileH263Baseline; 186 profile_list[i++] = VAProfileJPEGBaseline; 187 } else if (IS_MFLD(driver_data)) { 188 profile_list[i++] = VAProfileH263Baseline; 189 profile_list[i++] = VAProfileJPEGBaseline; 190 } else if (IS_MRST(driver_data)) 191 profile_list[i++] = VAProfileH263Baseline; 192 profile_list[i++] = VAProfileH264ConstrainedBaseline; 193 194 /* If the assert fails then PSB_MAX_PROFILES needs to be bigger */ 195 ASSERT(i <= PSB_MAX_PROFILES); 196 *num_profiles = i; 197 DEBUG_FUNC_EXIT 198 return VA_STATUS_SUCCESS; 199} 200 201VAStatus psb_QueryConfigEntrypoints( 202 VADriverContextP ctx, 203 VAProfile profile, 204 VAEntrypoint *entrypoint_list, /* out */ 205 int *num_entrypoints /* out */ 206) 207{ 208 DEBUG_FUNC_ENTER 209 INIT_DRIVER_DATA 210 VAStatus vaStatus = VA_STATUS_SUCCESS; 211 int entrypoints = 0; 212 int i; 213 214 if (NULL == entrypoint_list) { 215 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 216 DEBUG_FAILURE; 217 return vaStatus; 218 } 219 if (NULL == num_entrypoints || profile >= PSB_MAX_PROFILES) { 220 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 221 DEBUG_FAILURE; 222 return vaStatus; 223 } 224 225 for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) { 226#ifdef PSBVIDEO_MRFL_VPP 227 if (profile == VAProfileNone && driver_data->vpp_profile && 228 i == VAEntrypointVideoProc) { 229 entrypoints++; 230 *entrypoint_list++ = i; 231 } else if (profile != VAProfileNone && driver_data->profile2Format[profile][i]) { 232 entrypoints++; 233 *entrypoint_list++ = i; 234 } 235#else 236 if (driver_data->profile2Format[profile][i]) { 237 entrypoints++; 238 *entrypoint_list++ = i; 239 } 240#endif 241 } 242 243 /* If the assert fails then PSB_MAX_ENTRYPOINTS needs to be bigger */ 244 ASSERT(entrypoints <= PSB_MAX_ENTRYPOINTS); 245 246 if (0 == entrypoints) { 247 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 248 } 249 250 *num_entrypoints = entrypoints; 251 DEBUG_FUNC_EXIT 252 return VA_STATUS_SUCCESS; 253} 254 255/* 256 * Figure out if we should return VA_STATUS_ERROR_UNSUPPORTED_PROFILE 257 * or VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT 258 */ 259static VAStatus psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data, VAProfile profile, VAEntrypoint entrypoint) 260{ 261 /* Does the driver support _any_ entrypoint for this profile? */ 262 if (profile < PSB_MAX_PROFILES) { 263 int i; 264 265 /* Do the parameter check for MFLD and MRFLD */ 266 if (profile == VAProfileNone) 267 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; 268 269 for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) { 270 if (driver_data->profile2Format[profile][i]) { 271 /* There is an entrypoint, so the profile is supported */ 272 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; 273 } 274 } 275 } 276 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 277} 278 279VAStatus psb_GetConfigAttributes( 280 VADriverContextP ctx, 281 VAProfile profile, 282 VAEntrypoint entrypoint, 283 VAConfigAttrib *attrib_list, /* in/out */ 284 int num_attribs 285) 286{ 287 DEBUG_FUNC_ENTER 288 INIT_DRIVER_DATA 289 INIT_FORMAT_VTABLE 290 int i; 291 VAStatus vaStatus = VA_STATUS_SUCCESS; 292 if (NULL == format_vtable) { 293 return psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint); 294 } 295 if (NULL == attrib_list) { 296 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 297 DEBUG_FAILURE; 298 return vaStatus; 299 } 300 if (num_attribs <= 0) { 301 return VA_STATUS_ERROR_INVALID_PARAMETER; 302 } 303 304 /* Generic attributes */ 305 for (i = 0; i < num_attribs; i++) { 306 switch (attrib_list[i].type) { 307 case VAConfigAttribRTFormat: 308 attrib_list[i].value = VA_RT_FORMAT_YUV420; 309 if (entrypoint == VAEntrypointEncPicture) 310 attrib_list[i].value |= VA_RT_FORMAT_YUV422; 311 if ((profile == VAProfileJPEGBaseline) && (entrypoint == VAEntrypointVLD)) 312 attrib_list[i].value |= VA_RT_FORMAT_YUV444; 313 break; 314 315 default: 316 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; 317 break; 318 } 319 } 320 /* format specific attributes */ 321 format_vtable->queryConfigAttributes(profile, entrypoint, attrib_list, num_attribs); 322 DEBUG_FUNC_EXIT 323 return VA_STATUS_SUCCESS; 324} 325 326static VAStatus psb__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib) 327{ 328 int i; 329 /* Check existing attributes */ 330 for (i = 0; i < obj_config->attrib_count; i++) { 331 if (obj_config->attrib_list[i].type == attrib->type) { 332 /* Update existing attribute */ 333 obj_config->attrib_list[i].value = attrib->value; 334 return VA_STATUS_SUCCESS; 335 } 336 } 337 if (obj_config->attrib_count < PSB_MAX_CONFIG_ATTRIBUTES) { 338 i = obj_config->attrib_count; 339 obj_config->attrib_list[i].type = attrib->type; 340 obj_config->attrib_list[i].value = attrib->value; 341 obj_config->attrib_count++; 342 return VA_STATUS_SUCCESS; 343 } 344 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; 345} 346 347static VAStatus psb__validate_config(object_config_p obj_config) 348{ 349 int i; 350 /* Check all attributes */ 351 for (i = 0; i < obj_config->attrib_count; i++) { 352 switch (obj_config->attrib_list[i].type) { 353 case VAConfigAttribRTFormat: 354 if (!(obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV420 355 || (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 && 356 obj_config->entrypoint == VAEntrypointEncPicture) 357 || (obj_config->attrib_list[i].value == (VA_RT_FORMAT_YUV444 | VA_RT_FORMAT_YUV420 )))) { 358 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 359 } 360 break; 361 362 default: 363 /* 364 * Ignore unknown attributes here, it 365 * may be format specific. 366 */ 367 break; 368 } 369 } 370 return VA_STATUS_SUCCESS; 371} 372 373static int psb_get_active_entrypoint_number( 374 VADriverContextP ctx, 375 unsigned int entrypoint) 376{ 377 INIT_DRIVER_DATA; 378 struct drm_lnc_video_getparam_arg arg; 379 int count = 0; 380 int ret; 381 382 if (VAEntrypointVLD > entrypoint || 383 entrypoint > VAEntrypointEncPicture) { 384 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s :Invalid entrypoint %d.\n", 385 __FUNCTION__, entrypoint); 386 return -1; 387 } 388 389 arg.key = PNW_VIDEO_QUERY_ENTRY; 390 arg.value = (uint64_t)((unsigned long) &count); 391 arg.arg = (uint64_t)((unsigned int)&entrypoint); 392 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 393 &arg, sizeof(arg)); 394 if (ret) { 395 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s drmCommandWriteRead fails %d.\n", 396 __FUNCTION__, ret); 397 return -1; 398 } 399 400 return count; 401} 402 403VAStatus psb_CreateConfig( 404 VADriverContextP ctx, 405 VAProfile profile, 406 VAEntrypoint entrypoint, 407 VAConfigAttrib *attrib_list, 408 int num_attribs, 409 VAConfigID *config_id /* out */ 410) 411{ 412 DEBUG_FUNC_ENTER 413 INIT_DRIVER_DATA 414 INIT_FORMAT_VTABLE 415 VAStatus vaStatus = VA_STATUS_SUCCESS; 416 int configID; 417 object_config_p obj_config; 418 int i; 419 420 drv_debug_msg(VIDEO_DEBUG_INIT, "CreateConfig profile:%d, entrypoint:%d, num_attribs:%d.\n", 421 profile, entrypoint, num_attribs); 422 /*echo 8 > /sys/module/pvrsrvkm/parameters/no_ec will disable error concealment*/ 423 if ((profile == VAProfileH264ConstrainedBaseline) && (VAEntrypointVLD == entrypoint)) { 424 char ec_disable[2]; 425 FILE *ec_fp = fopen("/sys/module/pvrsrvkm/parameters/no_ec", "r"); 426 if (ec_fp) { 427 if (fgets(ec_disable, 2, ec_fp) != NULL) { 428 /* force profile to VAProfileH264High */ 429 if (strcmp(ec_disable, "8") == 0) { 430 drv_debug_msg(VIDEO_DEBUG_INIT, "disabled error concealment by setting profile to VAProfileH264High\n"); 431 profile = VAProfileH264High; 432 } 433 } 434 fclose(ec_fp); 435 } 436 } 437 438 if (NULL == config_id) { 439 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 440 return vaStatus; 441 } 442 443 if (num_attribs < 0) { 444 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 445 } 446 447 if (NULL == attrib_list) { 448 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 449 return vaStatus; 450 } 451 452 if (NULL == format_vtable) { 453 vaStatus = psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint); 454 } 455 456 if (VA_STATUS_SUCCESS != vaStatus) { 457 return vaStatus; 458 } 459 460 if ((IS_MFLD(driver_data)) && 461 ((VAEntrypointEncPicture == entrypoint) 462 || (VAEntrypointEncSlice == entrypoint))) { 463 int active_slc, active_pic; 464 /* Only allow one encoding entrypoint at the sametime. 465 * But if video encoding request comes when process JPEG encoding, 466 * it will wait until current JPEG picture encoding finish. 467 * Further JPEG encoding should fall back to software path.*/ 468 active_slc = psb_get_active_entrypoint_number(ctx, VAEntrypointEncSlice); 469 active_pic = psb_get_active_entrypoint_number(ctx, VAEntrypointEncPicture); 470 471 if (active_slc > 0) { 472 drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active video encoding entrypoint." 473 "Entrypoint %d isn't available.\n", entrypoint); 474 return VA_STATUS_ERROR_HW_BUSY; 475 } 476 else if (active_pic > 0 && VAEntrypointEncPicture == entrypoint) { 477 drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active picture encoding entrypoint." 478 "Entrypoint %d isn't available.\n", entrypoint); 479 return VA_STATUS_ERROR_HW_BUSY; 480 } 481 } 482 483 configID = object_heap_allocate(&driver_data->config_heap); 484 obj_config = CONFIG(configID); 485 if (NULL == obj_config) { 486 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 487 return vaStatus; 488 } 489 490 491 MEMSET_OBJECT(obj_config, struct object_config_s); 492 493 obj_config->profile = profile; 494 obj_config->format_vtable = format_vtable; 495 obj_config->entrypoint = entrypoint; 496 obj_config->attrib_list[0].type = VAConfigAttribRTFormat; 497 obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420; 498 obj_config->attrib_count = 1; 499 500 for (i = 0; i < num_attribs; i++) { 501 if (attrib_list[i].type > VAConfigAttribRateControl) 502 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 503 504 vaStatus = psb__update_attribute(obj_config, &(attrib_list[i])); 505 if (VA_STATUS_SUCCESS != vaStatus) { 506 break; 507 } 508 } 509 510 if (VA_STATUS_SUCCESS == vaStatus) { 511 vaStatus = psb__validate_config(obj_config); 512 } 513 514 if (VA_STATUS_SUCCESS == vaStatus) { 515 vaStatus = format_vtable->validateConfig(obj_config); 516 } 517 518 /* Error recovery */ 519 if (VA_STATUS_SUCCESS != vaStatus) { 520 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); 521 } else { 522 *config_id = configID; 523 } 524 525#ifdef PSBVIDEO_MSVDX_EC 526 if((getenv("PSB_VIDEO_NOEC") == NULL) 527 && (profile == VAProfileH264ConstrainedBaseline)) { 528 drv_debug_msg(VIDEO_DEBUG_INIT, "profile is VAProfileH264ConstrainedBaseline, error concealment is enabled. \n"); 529 driver_data->ec_enabled = 1; 530 } else { 531 driver_data->ec_enabled = 0; 532 } 533#else 534 driver_data->ec_enabled = 0; 535#endif 536 DEBUG_FUNC_EXIT 537 return vaStatus; 538} 539 540VAStatus psb_DestroyConfig( 541 VADriverContextP ctx, 542 VAConfigID config_id 543) 544{ 545 DEBUG_FUNC_ENTER 546 INIT_DRIVER_DATA 547 VAStatus vaStatus = VA_STATUS_SUCCESS; 548 object_config_p obj_config; 549 550 obj_config = CONFIG(config_id); 551 if (NULL == obj_config) { 552 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 553 DEBUG_FAILURE; 554 return vaStatus; 555 } 556 557 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); 558 DEBUG_FUNC_EXIT 559 return vaStatus; 560} 561 562VAStatus psb_QueryConfigAttributes( 563 VADriverContextP ctx, 564 VAConfigID config_id, 565 VAProfile *profile, /* out */ 566 VAEntrypoint *entrypoint, /* out */ 567 VAConfigAttrib *attrib_list, /* out */ 568 int *num_attribs /* out */ 569) 570{ 571 DEBUG_FUNC_ENTER 572 INIT_DRIVER_DATA 573 VAStatus vaStatus = VA_STATUS_SUCCESS; 574 object_config_p obj_config; 575 int i; 576 577 if (NULL == profile) { 578 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 579 DEBUG_FAILURE; 580 return vaStatus; 581 } 582 if (NULL == entrypoint) { 583 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 584 DEBUG_FAILURE; 585 return vaStatus; 586 } 587 if (NULL == attrib_list) { 588 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 589 DEBUG_FAILURE; 590 return vaStatus; 591 } 592 if (NULL == num_attribs) { 593 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 594 DEBUG_FAILURE; 595 return vaStatus; 596 } 597 obj_config = CONFIG(config_id); 598 if (NULL == obj_config) { 599 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 600 DEBUG_FAILURE; 601 return vaStatus; 602 } 603 604 *profile = obj_config->profile; 605 *entrypoint = obj_config->entrypoint; 606 *num_attribs = obj_config->attrib_count; 607 for (i = 0; i < obj_config->attrib_count; i++) { 608 attrib_list[i] = obj_config->attrib_list[i]; 609 } 610 611 DEBUG_FUNC_EXIT 612 return vaStatus; 613} 614 615void psb__destroy_surface(psb_driver_data_p driver_data, object_surface_p obj_surface) 616{ 617 if (NULL != obj_surface) { 618 /* delete subpicture association */ 619 psb_SurfaceDeassociateSubpict(driver_data, obj_surface); 620 621 psb_surface_sync(obj_surface->psb_surface); 622 psb_surface_destroy(obj_surface->psb_surface); 623 624 if (obj_surface->psb_surface_rotate) { 625 psb_surface_destroy(obj_surface->psb_surface_rotate); 626 } 627 628 free(obj_surface->psb_surface); 629 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 630 } 631} 632 633static 634VAStatus psb__checkSurfaceDimensions(psb_driver_data_p driver_data, int width, int height) 635{ 636 if (driver_data->video_sd_disabled) { 637 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 638 } 639 if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) { 640 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 641 } 642 if (driver_data->video_hd_disabled) { 643 if ((width > 1024) || (height > 576)) { 644 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 645 } 646 } 647 648 return VA_STATUS_SUCCESS; 649} 650 651 652VAStatus psb_CreateSurfaces2( 653 VADriverContextP ctx, 654 int format, 655 int width, 656 int height, 657 VASurfaceID *surface_list, /* out */ 658 int num_surfaces, 659 VASurfaceAttrib *attrib_list, 660 int num_attribs 661) 662{ 663 DEBUG_FUNC_ENTER 664 INIT_DRIVER_DATA 665 VAStatus vaStatus = VA_STATUS_SUCCESS; 666 int i, height_origin, buffer_stride = 0; 667 driver_data->protected = (VA_RT_FORMAT_PROTECTED & format); 668 unsigned long fourcc; 669 unsigned int flags = 0; 670 671 format = format & (~VA_RT_FORMAT_PROTECTED); 672 if (num_surfaces <= 0) { 673 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 674 DEBUG_FAILURE; 675 return vaStatus; 676 } 677 if (NULL == surface_list) { 678 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 679 DEBUG_FAILURE; 680 return vaStatus; 681 } 682 683 if ((attrib_list != NULL) && (num_attribs > 0)) { 684 for (i = 0; i < num_attribs; i++, attrib_list++) { 685 if (!attrib_list) 686 return VA_STATUS_ERROR_INVALID_PARAMETER; 687 switch (attrib_list->type) { 688 default: 689 drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported attribute.\n"); 690 return VA_STATUS_ERROR_INVALID_PARAMETER; 691 } 692 } 693 } 694 695 /* We only support one format */ 696 if ((VA_RT_FORMAT_YUV420 != format) 697 && (VA_RT_FORMAT_YUV422 != format) 698 && (VA_RT_FORMAT_YUV444 != format)) { 699 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 700 DEBUG_FAILURE; 701 return vaStatus; 702 } 703 704 vaStatus = psb__checkSurfaceDimensions(driver_data, width, height); 705 if (VA_STATUS_SUCCESS != vaStatus) { 706 DEBUG_FAILURE; 707 return vaStatus; 708 } 709 710 /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */ 711 height_origin = height; 712 height = (height + 0x1f) & ~0x1f; 713 714 715 for (i = 0; i < num_surfaces; i++) { 716 int surfaceID; 717 object_surface_p obj_surface; 718 psb_surface_p psb_surface; 719 720 surfaceID = object_heap_allocate(&driver_data->surface_heap); 721 obj_surface = SURFACE(surfaceID); 722 if (NULL == obj_surface) { 723 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 724 DEBUG_FAILURE; 725 break; 726 } 727 MEMSET_OBJECT(obj_surface, struct object_surface_s); 728 729 obj_surface->surface_id = surfaceID; 730 surface_list[i] = surfaceID; 731 obj_surface->context_id = -1; 732 obj_surface->width = width; 733 obj_surface->height = height; 734 obj_surface->width_r = width; 735 obj_surface->height_r = height; 736 obj_surface->height_origin = height_origin; 737 obj_surface->share_info = NULL; 738 739 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); 740 if (NULL == psb_surface) { 741 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 742 obj_surface->surface_id = VA_INVALID_SURFACE; 743 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 744 DEBUG_FAILURE; 745 break; 746 } 747 748 switch (format) { 749 case VA_RT_FORMAT_YUV444: 750 fourcc = VA_FOURCC_YV32; /* allocate 4 planar */ 751 break; 752 case VA_RT_FORMAT_YUV422: 753 fourcc = VA_FOURCC_YV16; 754 break; 755 case VA_RT_FORMAT_YUV420: 756 default: 757 fourcc = VA_FOURCC_NV12; 758 break; 759 } 760 761 flags |= driver_data->protected ? IS_PROTECTED : 0; 762 vaStatus = psb_surface_create(driver_data, width, height, fourcc, 763 flags, psb_surface); 764 765 if (VA_STATUS_SUCCESS != vaStatus) { 766 free(psb_surface); 767 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 768 obj_surface->surface_id = VA_INVALID_SURFACE; 769 DEBUG_FAILURE; 770 break; 771 } 772 buffer_stride = psb_surface->stride; 773 /* by default, surface fourcc is NV12 */ 774 psb_surface->extra_info[4] = fourcc; 775 obj_surface->psb_surface = psb_surface; 776 } 777 778 /* Error recovery */ 779 if (VA_STATUS_SUCCESS != vaStatus) { 780 /* surface_list[i-1] was the last successful allocation */ 781 for (; i--;) { 782 object_surface_p obj_surface = SURFACE(surface_list[i]); 783 psb__destroy_surface(driver_data, obj_surface); 784 surface_list[i] = VA_INVALID_SURFACE; 785 } 786 drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n"); 787 return vaStatus; 788 } 789 DEBUG_FUNC_EXIT 790 return vaStatus; 791} 792 793 794VAStatus psb_DestroySurfaces( 795 VADriverContextP ctx, 796 VASurfaceID *surface_list, 797 int num_surfaces 798) 799{ 800 INIT_DRIVER_DATA 801 int i; 802 803 if (num_surfaces <= 0) { 804 return VA_STATUS_ERROR_INVALID_PARAMETER; 805 } 806 807 /* Free PVR2D buffer wrapped from the surfaces */ 808 psb_free_surface_pvr2dbuf(driver_data); 809 810 /* Make validation happy */ 811 for (i = 0; i < num_surfaces; i++) { 812 object_surface_p obj_surface = SURFACE(surface_list[i]); 813 if (obj_surface == NULL) { 814 return VA_STATUS_ERROR_INVALID_SURFACE; 815 } 816 if (obj_surface->derived_imgcnt > 0) { 817 drv_debug_msg(VIDEO_DEBUG_ERROR, "Some surface is deriving by images\n"); 818 return VA_STATUS_ERROR_OPERATION_FAILED; 819 } 820 } 821 822 for (i = 0; i < num_surfaces; i++) { 823 object_surface_p obj_surface = SURFACE(surface_list[i]); 824 825 if (driver_data->cur_displaying_surface == surface_list[i]) { 826 /* Surface is being displaying. Need to stop overlay here */ 827 psb_coverlay_stop(ctx); 828 } 829 drv_debug_msg(VIDEO_DEBUG_INIT, "%s : obj_surface->surface_id = 0x%x\n",__FUNCTION__, obj_surface->surface_id); 830 if (obj_surface->share_info) { 831 psb_DestroySurfaceGralloc(obj_surface); 832 } 833 psb__destroy_surface(driver_data, obj_surface); 834 surface_list[i] = VA_INVALID_SURFACE; 835 } 836 837 DEBUG_FUNC_EXIT 838 return VA_STATUS_SUCCESS; 839} 840 841int psb_new_context(psb_driver_data_p driver_data, int ctx_type) 842{ 843 struct drm_lnc_video_getparam_arg arg; 844 int ret = 0; 845 846 arg.key = IMG_VIDEO_NEW_CONTEXT; 847 arg.value = (uint64_t)((unsigned long) & ctx_type); 848 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 849 &arg, sizeof(arg)); 850 if (ret != 0) 851 drv_debug_msg(VIDEO_DEBUG_ERROR, "Set context %d failed\n", ctx_type); 852 853 return ret; 854} 855 856#ifdef PSBVIDEO_MSVDX_DEC_TILING 857int psb_update_context(psb_driver_data_p driver_data, unsigned long ctx_type) 858{ 859 struct drm_lnc_video_getparam_arg arg; 860 int ret = 0; 861 862 arg.key = IMG_VIDEO_UPDATE_CONTEXT; 863 arg.value = (uint64_t)((unsigned long) & ctx_type); 864 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 865 &arg, sizeof(arg)); 866 if (ret != 0) 867 psb__error_message("Update context %d failed\n", ctx_type); 868 869 return ret; 870} 871#endif 872 873int psb_rm_context(psb_driver_data_p driver_data) 874{ 875 struct drm_lnc_video_getparam_arg arg; 876 int tmp; 877 int ret = 0; 878 879 arg.key = IMG_VIDEO_RM_CONTEXT; 880 arg.value = (uint64_t)((unsigned long) & tmp); /* value is ignored */ 881 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 882 &arg, sizeof(arg)); 883 if (ret != 0) 884 drv_debug_msg(VIDEO_DEBUG_ERROR, "Remove context failed\n"); 885 886 return ret; 887} 888 889unsigned long psb__tile_stride_log2_256(int w) 890{ 891 int stride_mode = 0; 892 893 if (512 >= w) 894 stride_mode = 1; 895 else if (1024 >= w) 896 stride_mode = 2; 897 else if (2048 >= w) 898 stride_mode = 3; 899 else if (4096 >= w) 900 stride_mode = 4; 901 902 return stride_mode; 903} 904 905VAStatus psb_CreateContext( 906 VADriverContextP ctx, 907 VAConfigID config_id, 908 int picture_width, 909 int picture_height, 910 int flag, 911 VASurfaceID *render_targets, 912 int num_render_targets, 913 VAContextID *context /* out */ 914) 915{ 916 DEBUG_FUNC_ENTER 917 INIT_DRIVER_DATA 918 VAStatus vaStatus = VA_STATUS_SUCCESS; 919 object_config_p obj_config; 920 int cmdbuf_num, encode = 0, proc = 0; 921 int i; 922 drv_debug_msg(VIDEO_DEBUG_INIT, "CreateContext config_id:%d, pic_w:%d, pic_h:%d, flag:%d, num_render_targets:%d.\n", 923 config_id, picture_width, picture_height, flag, num_render_targets); 924 925 if (num_render_targets <= 0) { 926 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 927 DEBUG_FAILURE; 928 return vaStatus; 929 } 930 931 if (NULL == render_targets) { 932 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 933 DEBUG_FAILURE; 934 return vaStatus; 935 } 936 if (NULL == context) { 937 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 938 DEBUG_FAILURE; 939 return vaStatus; 940 } 941 942 vaStatus = psb__checkSurfaceDimensions(driver_data, picture_width, picture_height); 943 if (VA_STATUS_SUCCESS != vaStatus) { 944 DEBUG_FAILURE; 945 return vaStatus; 946 } 947 948 obj_config = CONFIG(config_id); 949 if (NULL == obj_config) { 950 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 951 DEBUG_FAILURE; 952 return vaStatus; 953 } 954 955 int contextID = object_heap_allocate(&driver_data->context_heap); 956 object_context_p obj_context = CONTEXT(contextID); 957 if (NULL == obj_context) { 958 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 959 DEBUG_FAILURE; 960 return vaStatus; 961 } 962 963 *context = contextID; 964 965 MEMSET_OBJECT(obj_context, struct object_context_s); 966 967 obj_context->driver_data = driver_data; 968 obj_context->current_render_target = NULL; 969 obj_context->ec_target = NULL; 970 obj_context->ec_candidate = NULL; 971 obj_context->is_oold = driver_data->is_oold; 972 obj_context->context_id = contextID; 973 obj_context->config_id = config_id; 974 obj_context->picture_width = picture_width; 975 obj_context->picture_height = picture_height; 976 obj_context->num_render_targets = num_render_targets; 977 obj_context->render_targets = (VASurfaceID *) calloc(1, num_render_targets * sizeof(VASurfaceID)); 978 if (obj_context->render_targets == NULL) { 979 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 980 DEBUG_FAILURE; 981 982 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 983 984 return vaStatus; 985 } 986 987 /* allocate buffer points for vaRenderPicture */ 988 obj_context->num_buffers = 10; 989 obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * obj_context->num_buffers); 990 if (obj_context->buffer_list == NULL) { 991 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 992 DEBUG_FAILURE; 993 994 free(obj_context->render_targets); 995 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 996 997 return vaStatus; 998 } 999 1000 memset(obj_context->buffers_unused, 0, sizeof(obj_context->buffers_unused)); 1001 memset(obj_context->buffers_unused_count, 0, sizeof(obj_context->buffers_unused_count)); 1002 memset(obj_context->buffers_unused_tail, 0, sizeof(obj_context->buffers_unused_tail)); 1003 memset(obj_context->buffers_active, 0, sizeof(obj_context->buffers_active)); 1004 1005 if (obj_config->entrypoint == VAEntrypointEncSlice 1006 || obj_config->entrypoint == VAEntrypointEncPicture) { 1007 encode = 1; 1008 } 1009#ifdef PSBVIDEO_MRFL_VPP 1010 if (obj_config->entrypoint == VAEntrypointVideoProc) 1011 proc = 1; 1012#endif 1013 1014 if (encode) 1015 cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE; 1016 else if (proc) 1017 cmdbuf_num = VSP_MAX_CMDBUFS; 1018 else 1019 cmdbuf_num = PSB_MAX_CMDBUFS; 1020 1021 for (i = 0; i < num_render_targets; i++) { 1022 object_surface_p obj_surface = SURFACE(render_targets[i]); 1023 psb_surface_p psb_surface; 1024 1025 if (NULL == obj_surface) { 1026 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1027 DEBUG_FAILURE; 1028 break; 1029 } 1030 1031 psb_surface = obj_surface->psb_surface; 1032 1033 /* Clear format specific surface info */ 1034 obj_context->render_targets[i] = render_targets[i]; 1035 obj_surface->context_id = contextID; /* Claim ownership of surface */ 1036#ifdef PSBVIDEO_MSVDX_DEC_TILING 1037 if (GET_SURFACE_INFO_tiling(psb_surface)) 1038 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width); 1039#endif 1040#if 0 1041 /* for decode, move the surface into |TT */ 1042 if ((encode == 0) && /* decode */ 1043 ((psb_surface->buf.pl_flags & DRM_PSB_FLAG_MEM_RAR) == 0)) /* surface not in RAR */ 1044 psb_buffer_setstatus(&obj_surface->psb_surface->buf, 1045 WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED, DRM_PSB_FLAG_MEM_MMU); 1046#endif 1047 } 1048 1049 obj_context->va_flags = flag; 1050 obj_context->format_vtable = obj_config->format_vtable; 1051 obj_context->format_data = NULL; 1052 1053 if (VA_STATUS_SUCCESS == vaStatus) { 1054 vaStatus = obj_context->format_vtable->createContext(obj_context, obj_config); 1055 } 1056 1057 /* Error recovery */ 1058 if (VA_STATUS_SUCCESS != vaStatus) { 1059 obj_context->context_id = -1; 1060 obj_context->config_id = -1; 1061 obj_context->picture_width = 0; 1062 obj_context->picture_height = 0; 1063 free(obj_context->render_targets); 1064 free(obj_context->buffer_list); 1065 obj_context->num_buffers = 0; 1066 obj_context->render_targets = NULL; 1067 obj_context->num_render_targets = 0; 1068 obj_context->va_flags = 0; 1069 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 1070 1071 return vaStatus; 1072 } 1073 1074 /* initialize cmdbuf */ 1075 for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) { 1076 obj_context->lnc_cmdbuf_list[i] = NULL; 1077 } 1078 1079 for (i = 0; i < PNW_MAX_CMDBUFS_ENCODE; i++) { 1080 obj_context->pnw_cmdbuf_list[i] = NULL; 1081 } 1082 1083#ifdef PSBVIDEO_MRFL 1084 for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) { 1085 obj_context->tng_cmdbuf_list[i] = NULL; 1086 } 1087#endif 1088 1089#ifdef PSBVIDEO_MRFL_VPP 1090 for (i = 0; i < VSP_MAX_CMDBUFS; i++) { 1091 obj_context->vsp_cmdbuf_list[i] = NULL; 1092 } 1093#endif 1094 1095 for (i = 0; i < PSB_MAX_CMDBUFS; i++) { 1096 obj_context->cmdbuf_list[i] = NULL; 1097 } 1098 1099 for (i = 0; i < cmdbuf_num; i++) { 1100 void *cmdbuf = NULL; 1101 1102 if (encode) { /* Topaz encode context */ 1103#ifdef PSBVIDEO_MRFL 1104 if (IS_MRFL(obj_context->driver_data)) 1105 cmdbuf = calloc(1, sizeof(struct tng_cmdbuf_s)); 1106#endif 1107#ifdef PSBVIDEO_MFLD 1108 if (IS_MFLD(obj_context->driver_data)) 1109 cmdbuf = calloc(1, sizeof(struct pnw_cmdbuf_s)); 1110#endif 1111#ifdef PSBVIDEO_MRST 1112 if (IS_MRST(obj_context->driver_data)) 1113 cmdbuf = calloc(1, sizeof(struct lnc_cmdbuf_s)); 1114#endif 1115 } else if (proc) { /* VSP VPP context */ 1116#ifdef PSBVIDEO_MRFL_VPP 1117 if (IS_MRFL(obj_context->driver_data)) 1118 cmdbuf = calloc(1, sizeof(struct vsp_cmdbuf_s)); 1119#endif 1120 } else /* MSVDX decode context */ 1121 cmdbuf = calloc(1, sizeof(struct psb_cmdbuf_s)); 1122 1123 if (NULL == cmdbuf) { 1124 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1125 DEBUG_FAILURE; 1126 break; 1127 } 1128 1129 if (encode) { /* Topaz encode context */ 1130 1131#ifdef PSBVIDEO_MRFL 1132 if (IS_MRFL(obj_context->driver_data)) 1133 vaStatus = tng_cmdbuf_create(obj_context, driver_data, (tng_cmdbuf_p)cmdbuf); 1134#endif 1135#ifdef PSBVIDEO_MFLD 1136 if (IS_MFLD(obj_context->driver_data)) 1137 vaStatus = pnw_cmdbuf_create(obj_context, driver_data, (pnw_cmdbuf_p)cmdbuf); 1138#endif 1139#ifdef PSBVIDEO_MRST 1140 if (IS_MRST(obj_context->driver_data)) 1141 vaStatus = lnc_cmdbuf_create(obj_context, driver_data, (lnc_cmdbuf_p)cmdbuf); 1142#endif 1143 } else if (proc) { /* VSP VPP context */ 1144#ifdef PSBVIDEO_MRFL_VPP 1145 if (IS_MRFL(obj_context->driver_data)) 1146 vaStatus = vsp_cmdbuf_create(obj_context, driver_data, (vsp_cmdbuf_p)cmdbuf); 1147#endif 1148 } else /* MSVDX decode context */ 1149 vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf); 1150 1151 if (VA_STATUS_SUCCESS != vaStatus) { 1152 free(cmdbuf); 1153 DEBUG_FAILURE; 1154 break; 1155 } 1156 1157 if (encode) { /* Topaz encode context */ 1158 if (i >= LNC_MAX_CMDBUFS_ENCODE) { 1159 free(cmdbuf); 1160 DEBUG_FAILURE; 1161 break; 1162 } 1163 1164#ifdef PSBVIDEO_MRFL 1165 if (IS_MRFL(obj_context->driver_data)) 1166 obj_context->tng_cmdbuf_list[i] = (tng_cmdbuf_p)cmdbuf; 1167#endif 1168#ifdef PSBVIDEO_MFLD 1169 if (IS_MFLD(obj_context->driver_data)) 1170 obj_context->pnw_cmdbuf_list[i] = (pnw_cmdbuf_p)cmdbuf; 1171#endif 1172#ifdef PSBVIDEO_MRST 1173 if (IS_MRST(obj_context->driver_data)) 1174 obj_context->lnc_cmdbuf_list[i] = (lnc_cmdbuf_p)cmdbuf; 1175#endif 1176 } else if (proc) { /* VSP VPP context */ 1177#ifdef PSBVIDEO_MRFL_VPP 1178 if (IS_MRFL(obj_context->driver_data)) 1179 obj_context->vsp_cmdbuf_list[i] = (vsp_cmdbuf_p)cmdbuf; 1180#endif 1181 } else /* MSVDX decode context */ 1182 obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf; 1183 } 1184 1185 obj_context->cmdbuf_current = -1; 1186 obj_context->cmdbuf = NULL; 1187 obj_context->lnc_cmdbuf = NULL; 1188 obj_context->pnw_cmdbuf = NULL; 1189 obj_context->tng_cmdbuf = NULL; 1190#ifdef PSBVIDEO_MRFL_VPP 1191 obj_context->vsp_cmdbuf = NULL; 1192#endif 1193 obj_context->frame_count = 0; 1194 obj_context->slice_count = 0; 1195 obj_context->msvdx_context = ((driver_data->msvdx_context_base & 0xff0000) >> 16) | 1196 ((contextID & 0xff000000) >> 16); 1197#ifdef ANDROID 1198 obj_context->msvdx_context = ((driver_data->drm_fd & 0xf) << 4) | 1199 ((unsigned int)gettid() & 0xf); 1200#endif 1201 obj_context->profile = obj_config->profile; 1202 obj_context->entry_point = obj_config->entrypoint; 1203 1204 /* Error recovery */ 1205 if (VA_STATUS_SUCCESS != vaStatus) { 1206 if (cmdbuf_num > LNC_MAX_CMDBUFS_ENCODE) 1207 cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE; 1208 for (i = 0; i < cmdbuf_num; i++) { 1209 if (obj_context->lnc_cmdbuf_list[i]) { 1210 lnc_cmdbuf_destroy(obj_context->lnc_cmdbuf_list[i]); 1211 free(obj_context->lnc_cmdbuf_list[i]); 1212 obj_context->lnc_cmdbuf_list[i] = NULL; 1213 } 1214 if (obj_context->pnw_cmdbuf_list[i]) { 1215 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]); 1216 free(obj_context->pnw_cmdbuf_list[i]); 1217 obj_context->pnw_cmdbuf_list[i] = NULL; 1218 } 1219#ifdef PSBVIDEO_MRFL 1220 if (obj_context->tng_cmdbuf_list[i]) { 1221 tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]); 1222 free(obj_context->tng_cmdbuf_list[i]); 1223 obj_context->tng_cmdbuf_list[i] = NULL; 1224 } 1225#endif 1226 if (obj_context->cmdbuf_list[i]) { 1227 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]); 1228 free(obj_context->cmdbuf_list[i]); 1229 obj_context->cmdbuf_list[i] = NULL; 1230 } 1231#ifdef PSBVIDEO_MRFL_VPP 1232 if (obj_context->vsp_cmdbuf_list[i]) { 1233 vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]); 1234 free(obj_context->vsp_cmdbuf_list[i]); 1235 obj_context->vsp_cmdbuf_list[i] = NULL; 1236 } 1237#endif 1238 } 1239 1240 obj_context->cmdbuf = NULL; 1241 obj_context->lnc_cmdbuf = NULL; 1242#ifdef PSBVIDEO_MRFL_VPP 1243 obj_context->vsp_cmdbuf = NULL; 1244#endif 1245 1246 obj_context->context_id = -1; 1247 obj_context->config_id = -1; 1248 obj_context->picture_width = 0; 1249 obj_context->picture_height = 0; 1250 free(obj_context->render_targets); 1251 free(obj_context->buffer_list); 1252 obj_context->num_buffers = 0; 1253 obj_context->render_targets = NULL; 1254 obj_context->num_render_targets = 0; 1255 obj_context->va_flags = 0; 1256 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 1257 } 1258 obj_context->ctp_type = ((obj_config->profile << 8) | 1259 obj_config->entrypoint | driver_data->protected); 1260 1261 if (!encode) { 1262 obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16); 1263 } 1264 1265 psb_new_context(driver_data, obj_context->ctp_type | driver_data->protected); 1266 1267 DEBUG_FUNC_EXIT 1268 return vaStatus; 1269} 1270 1271static VAStatus psb__allocate_malloc_buffer(object_buffer_p obj_buffer, int size) 1272{ 1273 VAStatus vaStatus = VA_STATUS_SUCCESS; 1274 1275 obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size); 1276 if (NULL == obj_buffer->buffer_data) { 1277 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1278 DEBUG_FAILURE; 1279 } 1280 return vaStatus; 1281} 1282 1283static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer); 1284 1285static VAStatus psb__allocate_BO_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer, int size, unsigned char *data, VABufferType type) 1286{ 1287 VAStatus vaStatus = VA_STATUS_SUCCESS; 1288 1289 ASSERT(NULL == obj_buffer->buffer_data); 1290 1291 if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) { 1292 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Abandoning BO for buffer %08x type %s\n", obj_buffer->base.id, 1293 buffer_type_to_string(obj_buffer->type)); 1294 /* need to set psb_buffer aside and get another one */ 1295 obj_buffer->psb_buffer->status = psb_bs_abandoned; 1296 obj_buffer->psb_buffer = NULL; 1297 obj_buffer->size = 0; 1298 obj_buffer->alloc_size = 0; 1299 } 1300 1301 if (type == VAProtectedSliceDataBufferType) { 1302 if (obj_buffer->psb_buffer) { 1303 drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: old RAR slice buffer with RAR handle 0%08x, current RAR handle 0x%08x\n", 1304 obj_buffer->psb_buffer->rar_handle, (uint32_t)data); 1305 drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: force old RAR buffer destroy and new buffer re-allocation by set size=0\n"); 1306 obj_buffer->alloc_size = 0; 1307 } 1308 } 1309 1310 if (obj_buffer->alloc_size < (unsigned int)size) { 1311 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Buffer size mismatch: Need %d, currently have %d\n", size, obj_buffer->alloc_size); 1312 if (obj_buffer->psb_buffer) { 1313 if (obj_buffer->buffer_data) { 1314 psb__unmap_buffer(obj_buffer); 1315 } 1316 psb_buffer_destroy(obj_buffer->psb_buffer); 1317 obj_buffer->alloc_size = 0; 1318 } else { 1319 obj_buffer->psb_buffer = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s)); 1320 if (NULL == obj_buffer->psb_buffer) { 1321 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1322 DEBUG_FAILURE; 1323 } 1324 } 1325 if (VA_STATUS_SUCCESS == vaStatus) { 1326 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new GPU buffers for vaCreateBuffer:type=%s,size=%d.\n", 1327 buffer_type_to_string(obj_buffer->type), size); 1328 1329 size = (size + 0x7fff) & ~0x7fff; /* Round up */ 1330 if (obj_buffer->type == VAImageBufferType) /* Xserver side PutSurface, Image/subpicture buffer 1331 * should be shared between two process 1332 */ 1333 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_shared, obj_buffer->psb_buffer); 1334 else if (obj_buffer->type == VAProtectedSliceDataBufferType) { 1335 vaStatus = psb_buffer_reference_imr(driver_data, (uint32_t)data, obj_buffer->psb_buffer); 1336 } 1337 else if (obj_buffer->type == VAEncCodedBufferType) 1338#ifdef ANDROID 1339 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_cached, obj_buffer->psb_buffer); 1340#else 1341 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer); 1342#endif 1343 else 1344 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer); 1345 if (VA_STATUS_SUCCESS != vaStatus) { 1346 free(obj_buffer->psb_buffer); 1347 obj_buffer->psb_buffer = NULL; 1348 DEBUG_FAILURE; 1349 } else { 1350 obj_buffer->alloc_size = size; 1351 } 1352 } 1353 } 1354 return vaStatus; 1355} 1356 1357static VAStatus psb__map_buffer(object_buffer_p obj_buffer) 1358{ 1359 if (obj_buffer->psb_buffer) { 1360 return psb_buffer_map(obj_buffer->psb_buffer, &obj_buffer->buffer_data); 1361 } 1362 return VA_STATUS_SUCCESS; 1363} 1364 1365static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer) 1366{ 1367 if (obj_buffer->psb_buffer) { 1368 obj_buffer->buffer_data = NULL; 1369 return psb_buffer_unmap(obj_buffer->psb_buffer); 1370 } 1371 return VA_STATUS_SUCCESS; 1372} 1373 1374static void psb__destroy_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer) 1375{ 1376 if (obj_buffer->psb_buffer) { 1377 if (obj_buffer->buffer_data) { 1378 psb__unmap_buffer(obj_buffer); 1379 } 1380 psb_buffer_destroy(obj_buffer->psb_buffer); 1381 free(obj_buffer->psb_buffer); 1382 obj_buffer->psb_buffer = NULL; 1383 } 1384 1385 if (NULL != obj_buffer->buffer_data) { 1386 free(obj_buffer->buffer_data); 1387 obj_buffer->buffer_data = NULL; 1388 obj_buffer->size = 0; 1389 } 1390 1391 object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer); 1392} 1393 1394void psb__suspend_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer) 1395{ 1396 if (obj_buffer->context) { 1397 VABufferType type = obj_buffer->type; 1398 object_context_p obj_context = obj_buffer->context; 1399 1400 /* Remove buffer from active list */ 1401 *obj_buffer->pptr_prev_next = obj_buffer->ptr_next; 1402 1403 /* Add buffer to tail of unused list */ 1404 obj_buffer->ptr_next = NULL; 1405 obj_buffer->last_used = obj_context->frame_count; 1406 if (obj_context->buffers_unused_tail[type]) { 1407 obj_buffer->pptr_prev_next = &(obj_context->buffers_unused_tail[type]->ptr_next); 1408 } else { 1409 obj_buffer->pptr_prev_next = &(obj_context->buffers_unused[type]); 1410 } 1411 *obj_buffer->pptr_prev_next = obj_buffer; 1412 obj_context->buffers_unused_tail[type] = obj_buffer; 1413 obj_context->buffers_unused_count[type]++; 1414 1415 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Adding buffer %08x type %s to unused list. unused count = %d\n", obj_buffer->base.id, 1416 buffer_type_to_string(obj_buffer->type), obj_context->buffers_unused_count[type]); 1417 1418 object_heap_suspend_object((object_base_p) obj_buffer, 1); /* suspend */ 1419 return; 1420 } 1421 1422 if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) { 1423 /* need to set psb_buffer aside */ 1424 obj_buffer->psb_buffer->status = psb_bs_abandoned; 1425 obj_buffer->psb_buffer = NULL; 1426 } 1427 1428 psb__destroy_buffer(driver_data, obj_buffer); 1429} 1430 1431static void psb__destroy_context(psb_driver_data_p driver_data, object_context_p obj_context) 1432{ 1433 int encode, i; 1434 1435 if (obj_context->entry_point == VAEntrypointEncSlice) 1436 encode = 1; 1437 else 1438 encode = 0; 1439 1440 obj_context->format_vtable->destroyContext(obj_context); 1441 1442 for (i = 0; i < PSB_MAX_BUFFERTYPES; i++) { 1443 object_buffer_p obj_buffer; 1444 obj_buffer = obj_context->buffers_active[i]; 1445 for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) { 1446 drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying active buffer %08x\n", __FUNCTION__, obj_buffer->base.id); 1447 psb__destroy_buffer(driver_data, obj_buffer); 1448 } 1449 obj_buffer = obj_context->buffers_unused[i]; 1450 for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) { 1451 drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying unused buffer %08x\n", __FUNCTION__, obj_buffer->base.id); 1452 psb__destroy_buffer(driver_data, obj_buffer); 1453 } 1454 obj_context->buffers_unused_count[i] = 0; 1455 } 1456 1457 for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) { 1458 if (obj_context->lnc_cmdbuf_list[i]) { 1459 lnc_cmdbuf_destroy(obj_context->lnc_cmdbuf_list[i]); 1460 free(obj_context->lnc_cmdbuf_list[i]); 1461 obj_context->lnc_cmdbuf_list[i] = NULL; 1462 } 1463 } 1464 1465 for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) { 1466 if (obj_context->pnw_cmdbuf_list[i]) { 1467 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]); 1468 free(obj_context->pnw_cmdbuf_list[i]); 1469 obj_context->pnw_cmdbuf_list[i] = NULL; 1470 } 1471 } 1472#ifdef PSBVIDEO_MRFL 1473 for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) { 1474 if (obj_context->tng_cmdbuf_list[i]) { 1475 tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]); 1476 free(obj_context->tng_cmdbuf_list[i]); 1477 obj_context->tng_cmdbuf_list[i] = NULL; 1478 } 1479 } 1480#endif 1481#ifdef PSBVIDEO_MRFL_VPP 1482 for (i = 0; i < VSP_MAX_CMDBUFS; i++) { 1483 if (obj_context->vsp_cmdbuf_list[i]) { 1484 vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]); 1485 free(obj_context->vsp_cmdbuf_list[i]); 1486 obj_context->vsp_cmdbuf_list[i] = NULL; 1487 } 1488 } 1489#endif 1490 1491 for (i = 0; i < PSB_MAX_CMDBUFS; i++) { 1492 if (obj_context->cmdbuf_list[i]) { 1493 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]); 1494 free(obj_context->cmdbuf_list[i]); 1495 obj_context->cmdbuf_list[i] = NULL; 1496 } 1497 } 1498 obj_context->cmdbuf = NULL; 1499 obj_context->lnc_cmdbuf = NULL; 1500#ifdef PSBVIDEO_MRFL_VPP 1501 obj_context->vsp_cmdbuf = NULL; 1502#endif 1503 1504 obj_context->context_id = -1; 1505 obj_context->config_id = -1; 1506 obj_context->picture_width = 0; 1507 obj_context->picture_height = 0; 1508 if (obj_context->render_targets) 1509 free(obj_context->render_targets); 1510 obj_context->render_targets = NULL; 1511 obj_context->num_render_targets = 0; 1512 obj_context->va_flags = 0; 1513 1514 obj_context->current_render_target = NULL; 1515 obj_context->ec_target = NULL; 1516 obj_context->ec_candidate = NULL; 1517 if (obj_context->buffer_list) 1518 free(obj_context->buffer_list); 1519 obj_context->num_buffers = 0; 1520 1521 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 1522 1523 psb_rm_context(driver_data); 1524} 1525 1526VAStatus psb_DestroyContext( 1527 VADriverContextP ctx, 1528 VAContextID context 1529) 1530{ 1531 DEBUG_FUNC_ENTER 1532 INIT_DRIVER_DATA 1533 VAStatus vaStatus = VA_STATUS_SUCCESS; 1534 object_context_p obj_context = CONTEXT(context); 1535 if (NULL == obj_context) { 1536 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 1537 DEBUG_FAILURE; 1538 return vaStatus; 1539 } 1540 1541 psb__destroy_context(driver_data, obj_context); 1542 1543 DEBUG_FUNC_EXIT 1544 return vaStatus; 1545} 1546 1547VAStatus psb__CreateBuffer( 1548 psb_driver_data_p driver_data, 1549 object_context_p obj_context, /* in */ 1550 VABufferType type, /* in */ 1551 unsigned int size, /* in */ 1552 unsigned int num_elements, /* in */ 1553 unsigned char *data, /* in */ 1554 VABufferID *buf_desc /* out */ 1555) 1556{ 1557 DEBUG_FUNC_ENTER 1558 VAStatus vaStatus = VA_STATUS_SUCCESS; 1559 int bufferID; 1560 object_buffer_p obj_buffer = obj_context ? obj_context->buffers_unused[type] : NULL; 1561 int unused_count = obj_context ? obj_context->buffers_unused_count[type] : 0; 1562 1563 1564 /* 1565 * Buffer Management 1566 * For each buffer type, maintain 1567 * - a LRU sorted list of unused buffers 1568 * - a list of active buffers 1569 * We only create a new buffer when 1570 * - no unused buffers are available 1571 * - the last unused buffer is still queued 1572 * - the last unused buffer was used very recently and may still be fenced 1573 * - used recently is defined as within the current frame_count (subject to tweaks) 1574 * 1575 * The buffer that is returned will be moved to the list of active buffers 1576 * - vaDestroyBuffer and vaRenderPicture will move the active buffer back to the list of unused buffers 1577 */ 1578 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Requesting buffer creation, size=%d,elements=%d,type=%s\n", size, num_elements, 1579 buffer_type_to_string(type)); 1580 1581 /* on MFLD, data is IMR offset, and could be 0 */ 1582 /* 1583 if ((type == VAProtectedSliceDataBufferType) && (data == NULL)) { 1584 drv_debug_msg(VIDEO_DEBUG_ERROR, "RAR: Create protected slice buffer, but RAR handle is NULL\n"); 1585 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ; 1586 } 1587 */ 1588 1589 if (obj_buffer && obj_buffer->psb_buffer) { 1590 if (psb_bs_queued == obj_buffer->psb_buffer->status) { 1591 /* Buffer is still queued, allocate new buffer instead */ 1592 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, still queued\n", obj_buffer->base.id); 1593 obj_buffer = NULL; 1594 } else if ((obj_buffer->last_used == obj_context->frame_count) && (unused_count < MAX_UNUSED_BUFFERS)) { 1595 /* Buffer was used for this frame, allocate new buffer instead */ 1596 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, recently used. Unused = %d\n", obj_buffer->base.id, unused_count); 1597 obj_buffer = NULL; 1598 } else if (obj_context->frame_count - obj_buffer->last_used < 5) { 1599 /* Buffer was used for previous frame, allocate new buffer instead */ 1600 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x used by frame %d. Unused = %d\n", obj_buffer->base.id, obj_buffer->last_used, unused_count); 1601 obj_buffer = NULL; 1602 } 1603 } 1604 1605 if (obj_buffer) { 1606 bufferID = obj_buffer->base.id; 1607 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Reusing buffer %08x type %s from unused list. Unused = %d\n", bufferID, 1608 buffer_type_to_string(type), unused_count); 1609 1610 /* Remove from unused list */ 1611 obj_context->buffers_unused[type] = obj_buffer->ptr_next; 1612 if (obj_context->buffers_unused[type]) { 1613 obj_context->buffers_unused[type]->pptr_prev_next = &(obj_context->buffers_unused[type]); 1614 ASSERT(obj_context->buffers_unused_tail[type] != obj_buffer); 1615 } else { 1616 ASSERT(obj_context->buffers_unused_tail[type] == obj_buffer); 1617 obj_context->buffers_unused_tail[type] = 0; 1618 } 1619 obj_context->buffers_unused_count[type]--; 1620 1621 object_heap_suspend_object((object_base_p)obj_buffer, 0); /* Make BufferID valid again */ 1622 ASSERT(type == obj_buffer->type); 1623 ASSERT(obj_context == obj_buffer->context); 1624 } else { 1625 bufferID = object_heap_allocate(&driver_data->buffer_heap); 1626 obj_buffer = BUFFER(bufferID); 1627 if (NULL == obj_buffer) { 1628 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1629 DEBUG_FAILURE; 1630 return vaStatus; 1631 } 1632 1633 MEMSET_OBJECT(obj_buffer, struct object_buffer_s); 1634 1635 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating new buffer %08x type %s.\n", bufferID, buffer_type_to_string(type)); 1636 obj_buffer->type = type; 1637 obj_buffer->buffer_data = NULL; 1638 obj_buffer->psb_buffer = NULL; 1639 obj_buffer->size = 0; 1640 obj_buffer->max_num_elements = 0; 1641 obj_buffer->alloc_size = 0; 1642 obj_buffer->context = obj_context; 1643 } 1644 if (obj_context) { 1645 /* Add to front of active list */ 1646 obj_buffer->ptr_next = obj_context->buffers_active[type]; 1647 if (obj_buffer->ptr_next) { 1648 obj_buffer->ptr_next->pptr_prev_next = &(obj_buffer->ptr_next); 1649 } 1650 obj_buffer->pptr_prev_next = &(obj_context->buffers_active[type]); 1651 *obj_buffer->pptr_prev_next = obj_buffer; 1652 } 1653 1654 switch (obj_buffer->type) { 1655 case VABitPlaneBufferType: 1656 case VASliceDataBufferType: 1657 case VAResidualDataBufferType: 1658 case VAImageBufferType: 1659 case VASliceGroupMapBufferType: 1660 case VAEncCodedBufferType: 1661 case VAProtectedSliceDataBufferType: 1662 vaStatus = psb__allocate_BO_buffer(driver_data, obj_buffer, size * num_elements, data, obj_buffer->type); 1663 DEBUG_FAILURE; 1664 break; 1665 case VAPictureParameterBufferType: 1666 case VAIQMatrixBufferType: 1667 case VASliceParameterBufferType: 1668 case VAMacroblockParameterBufferType: 1669 case VADeblockingParameterBufferType: 1670 case VAEncPackedHeaderParameterBufferType: 1671 case VAEncPackedHeaderDataBufferType: 1672 case VAEncSequenceParameterBufferType: 1673 case VAEncPictureParameterBufferType: 1674 case VAEncSliceParameterBufferType: 1675 case VAQMatrixBufferType: 1676 case VAEncMiscParameterBufferType: 1677 case VAProbabilityBufferType: 1678 case VAHuffmanTableBufferType: 1679#ifdef PSBVIDEO_MRFL_VPP 1680 case VAProcPipelineParameterBufferType: 1681 case VAProcFilterParameterBufferType: 1682#endif 1683 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new malloc buffers for vaCreateBuffer:type=%s,size=%d, buffer_data=%p.\n", 1684 buffer_type_to_string(type), size, obj_buffer->buffer_data); 1685 vaStatus = psb__allocate_malloc_buffer(obj_buffer, size * num_elements); 1686 DEBUG_FAILURE; 1687 break; 1688 1689 default: 1690 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; 1691 DEBUG_FAILURE; 1692 break;; 1693 } 1694 1695 if (VA_STATUS_SUCCESS == vaStatus) { 1696 obj_buffer->size = size; 1697 obj_buffer->max_num_elements = num_elements; 1698 obj_buffer->num_elements = num_elements; 1699 if (data && (obj_buffer->type != VAProtectedSliceDataBufferType)) { 1700 vaStatus = psb__map_buffer(obj_buffer); 1701 if (VA_STATUS_SUCCESS == vaStatus) { 1702 memcpy(obj_buffer->buffer_data, data, size * num_elements); 1703 1704 psb__unmap_buffer(obj_buffer); 1705 } 1706 } 1707 } 1708 if (VA_STATUS_SUCCESS == vaStatus) { 1709 *buf_desc = bufferID; 1710 } else { 1711 psb__destroy_buffer(driver_data, obj_buffer); 1712 } 1713 1714 DEBUG_FUNC_EXIT 1715 return vaStatus; 1716} 1717 1718VAStatus psb_CreateBuffer( 1719 VADriverContextP ctx, 1720 VAContextID context, /* in */ 1721 VABufferType type, /* in */ 1722 unsigned int size, /* in */ 1723 unsigned int num_elements, /* in */ 1724 void *data, /* in */ 1725 VABufferID *buf_desc /* out */ 1726) 1727{ 1728 DEBUG_FUNC_ENTER 1729 INIT_DRIVER_DATA 1730 VAStatus vaStatus = VA_STATUS_SUCCESS; 1731 1732 if (num_elements <= 0) { 1733 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1734 DEBUG_FAILURE; 1735 return vaStatus; 1736 } 1737 1738 switch (type) { 1739 case VABitPlaneBufferType: 1740 case VASliceDataBufferType: 1741 case VAProtectedSliceDataBufferType: 1742 case VAResidualDataBufferType: 1743 case VASliceGroupMapBufferType: 1744 case VAPictureParameterBufferType: 1745 case VAIQMatrixBufferType: 1746 case VASliceParameterBufferType: 1747 case VAMacroblockParameterBufferType: 1748 case VADeblockingParameterBufferType: 1749 case VAEncCodedBufferType: 1750 case VAEncSequenceParameterBufferType: 1751 case VAEncPictureParameterBufferType: 1752 case VAEncSliceParameterBufferType: 1753 case VAEncPackedHeaderParameterBufferType: 1754 case VAEncPackedHeaderDataBufferType: 1755 case VAQMatrixBufferType: 1756 case VAEncMiscParameterBufferType: 1757 case VAProbabilityBufferType: 1758 case VAHuffmanTableBufferType: 1759#ifdef PSBVIDEO_MRFL_VPP 1760 case VAProcPipelineParameterBufferType: 1761 case VAProcFilterParameterBufferType: 1762#endif 1763 break; 1764 1765 default: 1766 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; 1767 DEBUG_FAILURE; 1768 return vaStatus; 1769 } 1770 1771 object_context_p obj_context = CONTEXT(context); 1772 if (NULL == obj_context) { 1773 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 1774 DEBUG_FAILURE; 1775 return vaStatus; 1776 } 1777 if (NULL == buf_desc) { 1778 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1779 DEBUG_FAILURE; 1780 return vaStatus; 1781 } 1782 1783 vaStatus = psb__CreateBuffer(driver_data, obj_context, type, size, num_elements, data, buf_desc); 1784 1785 DEBUG_FUNC_EXIT 1786 return vaStatus; 1787} 1788 1789 1790VAStatus psb_BufferInfo( 1791 VADriverContextP ctx, 1792 VABufferID buf_id, /* in */ 1793 VABufferType *type, /* out */ 1794 unsigned int *size, /* out */ 1795 unsigned int *num_elements /* out */ 1796) 1797{ 1798 DEBUG_FUNC_ENTER 1799 INIT_DRIVER_DATA 1800 VAStatus vaStatus = VA_STATUS_SUCCESS; 1801 1802 object_buffer_p obj_buffer = BUFFER(buf_id); 1803 if (NULL == obj_buffer) { 1804 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 1805 DEBUG_FAILURE; 1806 return vaStatus; 1807 } 1808 1809 *type = obj_buffer->type; 1810 *size = obj_buffer->size; 1811 *num_elements = obj_buffer->num_elements; 1812 DEBUG_FUNC_EXIT 1813 return VA_STATUS_SUCCESS; 1814} 1815 1816 1817VAStatus psb_BufferSetNumElements( 1818 VADriverContextP ctx, 1819 VABufferID buf_id, /* in */ 1820 unsigned int num_elements /* in */ 1821) 1822{ 1823 DEBUG_FUNC_ENTER 1824 INIT_DRIVER_DATA 1825 VAStatus vaStatus = VA_STATUS_SUCCESS; 1826 object_buffer_p obj_buffer = BUFFER(buf_id); 1827 if (NULL == obj_buffer) { 1828 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 1829 DEBUG_FAILURE; 1830 return vaStatus; 1831 } 1832 1833 if ((num_elements <= 0) || (num_elements > obj_buffer->max_num_elements)) { 1834 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1835 } 1836 if (VA_STATUS_SUCCESS == vaStatus) { 1837 obj_buffer->num_elements = num_elements; 1838 } 1839 1840 DEBUG_FUNC_EXIT 1841 return vaStatus; 1842} 1843 1844VAStatus psb_MapBuffer( 1845 VADriverContextP ctx, 1846 VABufferID buf_id, /* in */ 1847 void **pbuf /* out */ 1848) 1849{ 1850 DEBUG_FUNC_ENTER 1851 INIT_DRIVER_DATA 1852 VAStatus vaStatus = VA_STATUS_SUCCESS; 1853 object_buffer_p obj_buffer = BUFFER(buf_id); 1854 if (NULL == obj_buffer) { 1855 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 1856 DEBUG_FAILURE; 1857 return vaStatus; 1858 } 1859 1860 1861 if (NULL == pbuf) { 1862 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1863 DEBUG_FAILURE; 1864 return vaStatus; 1865 } 1866 1867 vaStatus = psb__map_buffer(obj_buffer); 1868 if (VA_STATUS_SUCCESS != vaStatus) { 1869 DEBUG_FAILURE; 1870 return vaStatus; 1871 } 1872 1873 if (NULL != obj_buffer->buffer_data) { 1874 *pbuf = obj_buffer->buffer_data; 1875 1876 /* specifically for Topaz encode 1877 * write validate coded data offset in CodedBuffer 1878 */ 1879 if (obj_buffer->type == VAEncCodedBufferType) 1880 psb_codedbuf_map_mangle(ctx, obj_buffer, pbuf); 1881 /* *(IMG_UINT32 *)((unsigned char *)obj_buffer->buffer_data + 4) = 16; */ 1882 } else { 1883 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1884 } 1885 DEBUG_FUNC_EXIT 1886 return vaStatus; 1887} 1888 1889VAStatus psb_UnmapBuffer( 1890 VADriverContextP ctx, 1891 VABufferID buf_id /* in */ 1892) 1893{ 1894 DEBUG_FUNC_ENTER 1895 INIT_DRIVER_DATA 1896 VAStatus vaStatus = VA_STATUS_SUCCESS; 1897 object_buffer_p obj_buffer = BUFFER(buf_id); 1898 if (NULL == obj_buffer) { 1899 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 1900 DEBUG_FAILURE; 1901 return vaStatus; 1902 } 1903 1904 vaStatus = psb__unmap_buffer(obj_buffer); 1905 DEBUG_FUNC_EXIT 1906 return vaStatus; 1907} 1908 1909 1910VAStatus psb_DestroyBuffer( 1911 VADriverContextP ctx, 1912 VABufferID buffer_id 1913) 1914{ 1915 DEBUG_FUNC_ENTER 1916 INIT_DRIVER_DATA 1917 VAStatus vaStatus = VA_STATUS_SUCCESS; 1918 object_buffer_p obj_buffer = BUFFER(buffer_id); 1919 1920 if (NULL == obj_buffer) { 1921 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 1922 DEBUG_FAILURE; 1923 return vaStatus; 1924 } 1925 1926 psb__suspend_buffer(driver_data, obj_buffer); 1927 DEBUG_FUNC_EXIT 1928 return vaStatus; 1929} 1930 1931 1932VAStatus psb_BeginPicture( 1933 VADriverContextP ctx, 1934 VAContextID context, 1935 VASurfaceID render_target 1936) 1937{ 1938 DEBUG_FUNC_ENTER 1939 INIT_DRIVER_DATA 1940 VAStatus vaStatus = VA_STATUS_SUCCESS; 1941 object_context_p obj_context; 1942 object_surface_p obj_surface; 1943 object_config_p obj_config; 1944 1945 obj_context = CONTEXT(context); 1946 if (NULL == obj_context) { 1947 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 1948 DEBUG_FAILURE; 1949 return vaStatus; 1950 } 1951 1952 /* Must not be within BeginPicture / EndPicture already */ 1953 ASSERT(obj_context->current_render_target == NULL); 1954 1955 obj_surface = SURFACE(render_target); 1956 if (NULL == obj_surface) { 1957 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1958 DEBUG_FAILURE; 1959 return vaStatus; 1960 } 1961 1962 obj_context->current_render_surface_id = render_target; 1963 obj_context->current_render_target = obj_surface; 1964 obj_context->slice_count = 0; 1965 1966 obj_config = CONFIG(obj_context->config_id); 1967 /* if the surface is decode render target, and in displaying */ 1968 if (obj_config && 1969 (obj_config->entrypoint != VAEntrypointEncSlice) && 1970 (driver_data->cur_displaying_surface == render_target)) 1971 drv_debug_msg(VIDEO_DEBUG_ERROR, "WARNING: rendering a displaying surface, may see tearing\n"); 1972 1973 if (VA_STATUS_SUCCESS == vaStatus) { 1974 vaStatus = obj_context->format_vtable->beginPicture(obj_context); 1975 } 1976 1977#ifdef ANDROID 1978 /* want msvdx to do rotate 1979 * but check per-context stream type: interlace or not 1980 */ 1981 if ((obj_config->entrypoint != VAEntrypointEncSlice) && 1982 (obj_config->entrypoint != VAEntrypointEncPicture) && 1983 driver_data->native_window) { 1984 psb_RecalcRotate(ctx, obj_context); 1985 } 1986#endif 1987 1988 if (obj_context->interlaced_stream || driver_data->disable_msvdx_rotate || 1989 (driver_data->render_mode == VA_RENDER_MODE_EXTERNAL_GPU && force_texure_1080p_60fps)) { 1990 int i; 1991 1992 obj_context->msvdx_rotate = 0; 1993 for (i = 0; i < obj_context->num_render_targets; i++) { 1994 object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]); 1995 /*we invalidate all surfaces's rotate buffer share info here.*/ 1996 if (obj_surface && obj_surface->share_info) { 1997 obj_surface->share_info->surface_rotate = 0; 1998 } 1999 } 2000 } 2001 else 2002 obj_context->msvdx_rotate = driver_data->msvdx_rotate_want; 2003 2004 /* the main surface track current rotate information 2005 * try to reuse the allocated rotate surfaces and don't destroy them 2006 * thus the rotation info in obj_surface->psb_surface_rotate may not be updated 2007 */ 2008 2009 SET_SURFACE_INFO_rotate(obj_surface->psb_surface, obj_context->msvdx_rotate); 2010 if (CONTEXT_ROTATE(obj_context)) { 2011 psb_CreateRotateSurface(ctx, obj_surface, obj_context->msvdx_rotate); 2012 /* for 1080p 60fps clip, need force to use surface texture to display video */ 2013 if (force_texure_1080p_60fps && driver_data->render_mode == VA_RENDER_MODE_EXTERNAL_GPU && 2014 obj_surface->share_info) 2015 obj_surface->share_info->force_output_method = 1; 2016 } 2017 2018 if (driver_data->is_oold && !obj_surface->psb_surface->in_loop_buf) { 2019 psb_surface_p psb_surface = obj_surface->psb_surface; 2020 2021 psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s)); 2022 if (NULL == psb_surface->in_loop_buf) { 2023 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 2024 DEBUG_FAILURE; 2025 return vaStatus; 2026 } 2027 2028 /* FIXME: For RAR surface, need allocate RAR buffer */ 2029 vaStatus = psb_buffer_create(obj_context->driver_data, 2030 psb_surface->size, 2031 psb_bt_surface, 2032 psb_surface->in_loop_buf); 2033 } else if (!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) { 2034 psb_surface_p psb_surface = obj_surface->psb_surface; 2035 2036 psb_buffer_destroy(psb_surface->in_loop_buf); 2037 free(psb_surface->in_loop_buf); 2038 psb_surface->in_loop_buf = NULL; 2039 } 2040 obj_context->is_oold = driver_data->is_oold; 2041 2042 drv_debug_msg(VIDEO_DEBUG_GENERAL, "---BeginPicture 0x%08x for frame %d --\n", 2043 render_target, obj_context->frame_count); 2044 psb__trace_message("------Trace frame %d------\n", obj_context->frame_count); 2045 2046 DEBUG_FUNC_EXIT 2047 return vaStatus; 2048} 2049 2050VAStatus psb_RenderPicture( 2051 VADriverContextP ctx, 2052 VAContextID context, 2053 VABufferID *buffers, 2054 int num_buffers 2055) 2056{ 2057 DEBUG_FUNC_ENTER 2058 INIT_DRIVER_DATA 2059 VAStatus vaStatus = VA_STATUS_SUCCESS; 2060 object_context_p obj_context; 2061 object_buffer_p *buffer_list; 2062 int i; 2063 2064 obj_context = CONTEXT(context); 2065 if (NULL == obj_context) { 2066 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 2067 DEBUG_FAILURE; 2068 return vaStatus; 2069 } 2070 2071 if (num_buffers <= 0) { 2072 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2073 DEBUG_FAILURE; 2074 return vaStatus; 2075 } 2076 2077 if (NULL == buffers) { 2078 /* Don't crash on NULL pointers */ 2079 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2080 DEBUG_FAILURE; 2081 return vaStatus; 2082 } 2083 /* Must be within BeginPicture / EndPicture */ 2084 ASSERT(obj_context->current_render_target != NULL); 2085 2086 if (num_buffers > obj_context->num_buffers) { 2087 free(obj_context->buffer_list); 2088 2089 obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * num_buffers); 2090 if (obj_context->buffer_list == NULL) { 2091 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 2092 obj_context->num_buffers = 0; 2093 } 2094 2095 obj_context->num_buffers = num_buffers; 2096 } 2097 buffer_list = obj_context->buffer_list; 2098 2099 if (VA_STATUS_SUCCESS == vaStatus) { 2100 /* Lookup buffer references */ 2101 for (i = 0; i < num_buffers; i++) { 2102 object_buffer_p obj_buffer = BUFFER(buffers[i]); 2103 if (NULL == obj_buffer) { 2104 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2105 DEBUG_FAILURE; 2106 return vaStatus; 2107 } 2108 buffer_list[i] = obj_buffer; 2109 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Render buffer %08x type %s\n", obj_buffer->base.id, 2110 buffer_type_to_string(obj_buffer->type)); 2111 } 2112 } 2113 2114 if (VA_STATUS_SUCCESS == vaStatus) { 2115 vaStatus = obj_context->format_vtable->renderPicture(obj_context, buffer_list, num_buffers); 2116 } 2117 2118 if (buffer_list) { 2119 /* Release buffers */ 2120 for (i = 0; i < num_buffers; i++) { 2121 if (buffer_list[i]) { 2122 psb__suspend_buffer(driver_data, buffer_list[i]); 2123 } 2124 } 2125 } 2126 2127 DEBUG_FUNC_EXIT 2128 return vaStatus; 2129} 2130 2131VAStatus psb_EndPicture( 2132 VADriverContextP ctx, 2133 VAContextID context 2134) 2135{ 2136 DEBUG_FUNC_ENTER 2137 INIT_DRIVER_DATA 2138 VAStatus vaStatus; 2139 object_context_p obj_context; 2140 2141 obj_context = CONTEXT(context); 2142 if (NULL == obj_context) { 2143 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 2144 DEBUG_FAILURE; 2145 return vaStatus; 2146 } 2147 2148 vaStatus = obj_context->format_vtable->endPicture(obj_context); 2149 2150 drv_debug_msg(VIDEO_DEBUG_GENERAL, "---EndPicture for frame %d --\n", obj_context->frame_count); 2151 2152 obj_context->current_render_target = NULL; 2153 obj_context->frame_count++; 2154 2155 psb__trace_message("FrameCount = %03d\n", obj_context->frame_count); 2156 drv_debug_msg(VIDEO_DEBUG_GENERAL, "FrameCount = %03d\n", obj_context->frame_count); 2157 psb__trace_message(NULL); 2158 2159 DEBUG_FUNC_EXIT 2160 return vaStatus; 2161} 2162 2163 2164static void psb__surface_usage( 2165 psb_driver_data_p driver_data, 2166 object_surface_p obj_surface, 2167 int *decode, int *encode, int *rc_enable, int *proc 2168) 2169{ 2170 object_context_p obj_context; 2171 object_config_p obj_config; 2172 VAEntrypoint tmp; 2173 unsigned int eRCmode; 2174 int i; 2175 2176 2177 *decode = 0; 2178 *encode = 0; 2179 *rc_enable = 0; 2180 *proc = 0; 2181 2182 obj_context = CONTEXT(obj_surface->context_id); 2183 if (NULL == obj_context) /* not associate with a context */ 2184 return; 2185 2186 obj_config = CONFIG(obj_context->config_id); 2187 if (NULL == obj_config) /* not have a validate context */ 2188 return; 2189 2190 tmp = obj_config->entrypoint; 2191 2192 *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture); 2193 *decode = (VAEntrypointVLD <= tmp) && (tmp <= VAEntrypointDeblocking); 2194#ifdef PSBVIDEO_MRFL_VPP 2195 *proc = (VAEntrypointVideoProc == tmp); 2196#endif 2197 2198 if (*encode) { 2199 for (i = 0; i < obj_config->attrib_count; i++) { 2200 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) 2201 break; 2202 } 2203 2204 if (i >= obj_config->attrib_count) 2205 eRCmode = VA_RC_NONE; 2206 else 2207 eRCmode = obj_config->attrib_list[i].value; 2208 2209 if (eRCmode == VA_RC_NONE) 2210 *rc_enable = 0; 2211 else 2212 *rc_enable = 1; 2213 } 2214} 2215 2216VAStatus psb_SyncSurface( 2217 VADriverContextP ctx, 2218 VASurfaceID render_target 2219) 2220{ 2221 DEBUG_FUNC_ENTER 2222 INIT_DRIVER_DATA 2223 VAStatus vaStatus = VA_STATUS_SUCCESS; 2224 object_surface_p obj_surface; 2225 int decode = 0, encode = 0, rc_enable = 0, proc = 0; 2226 2227 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_SyncSurface: 0x%08x\n", render_target); 2228 2229 obj_surface = SURFACE(render_target); 2230 if (NULL == obj_surface) { 2231 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2232 DEBUG_FAILURE; 2233 return vaStatus; 2234 } 2235 2236 /* The cur_displaying_surface indicates the surface being displayed by overlay. 2237 * The diaplay_timestamp records the time point of put surface, which would 2238 * be set to zero while using texture blit.*/ 2239 2240 /* don't use mutex here for performance concern... */ 2241 //pthread_mutex_lock(&output->output_mutex); 2242 if (render_target == driver_data->cur_displaying_surface) 2243 vaStatus = VA_STATUS_ERROR_SURFACE_IN_DISPLAYING; 2244 else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */ 2245 && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/ 2246 object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface); 2247 /* The flip operation on current displaying surface could be delayed to 2248 * next VBlank and hadn't been finished yet. Then, the last displaying 2249 * surface shouldn't be freed, because the hardware may not 2250 * complete loading data of it. Any change of the last surface could 2251 * have a impect on the scrren.*/ 2252 if (NULL != cur_obj_surface) { 2253 while ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY) 2254 usleep(PSB_MAX_FLIP_DELAY * 1000); 2255 } 2256 } 2257 //pthread_mutex_unlock(&output->output_mutex); 2258 2259 if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) 2260 vaStatus = psb_surface_sync(obj_surface->psb_surface); 2261 2262 /* report any error of decode for Android */ 2263 psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc); 2264 2265 if (decode && IS_MRST(driver_data)) { 2266 struct drm_lnc_video_getparam_arg arg; 2267 uint32_t ret, handle, fw_status = 0; 2268 handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf)); 2269 arg.key = IMG_VIDEO_DECODE_STATUS; 2270 arg.arg = (uint64_t)((unsigned long) & handle); 2271 arg.value = (uint64_t)((unsigned long) & fw_status); 2272 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 2273 &arg, sizeof(arg)); 2274 if (ret == 0) { 2275 if (fw_status != 0) 2276 vaStatus = VA_STATUS_ERROR_DECODING_ERROR; 2277 } else { 2278 drv_debug_msg(VIDEO_DEBUG_GENERAL, "IMG_VIDEO_DECODE_STATUS ioctl return failed.\n"); 2279 vaStatus = VA_STATUS_ERROR_UNKNOWN; 2280 } 2281 } else if (proc && IS_MRFL(driver_data)) { 2282 /* FIXME: does it need a new surface sync mechanism for FRC? */ 2283 } 2284// psb__dump_NV_buffers(obj_surface, 0, 0, obj_surface->width, obj_surface->height); 2285 DEBUG_FAILURE; 2286 DEBUG_FUNC_EXIT 2287 return vaStatus; 2288} 2289 2290 2291VAStatus psb_QuerySurfaceStatus( 2292 VADriverContextP ctx, 2293 VASurfaceID render_target, 2294 VASurfaceStatus *status /* out */ 2295) 2296{ 2297 DEBUG_FUNC_ENTER 2298 INIT_DRIVER_DATA 2299 VAStatus vaStatus = VA_STATUS_SUCCESS; 2300 object_surface_p obj_surface; 2301 VASurfaceStatus surface_status; 2302 int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0, proc = 0; 2303 2304 obj_surface = SURFACE(render_target); 2305 if (NULL == obj_surface) { 2306 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2307 DEBUG_FAILURE; 2308 return vaStatus; 2309 } 2310 if (NULL == status) { 2311 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2312 DEBUG_FAILURE; 2313 return vaStatus; 2314 } 2315 2316 vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status); 2317 2318 /* The cur_displaying_surface indicates the surface being displayed by overlay. 2319 * The diaplay_timestamp records the time point of put surface, which would 2320 * be set to zero while using texture blit.*/ 2321 pthread_mutex_lock(&driver_data->output_mutex); 2322 if (render_target == driver_data->cur_displaying_surface) 2323 surface_status = VASurfaceDisplaying; 2324 else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */ 2325 && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/ 2326 object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface); 2327 /*The flip operation on current displaying surface could be delayed to 2328 * next VBlank and hadn't been finished yet. Then, the last displaying 2329 * surface shouldn't be freed, because the hardware may not 2330 * complete loading data of it. Any change of the last surface could 2331 * have a impect on the scrren.*/ 2332 if ((NULL != cur_obj_surface) 2333 && ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)) { 2334 surface_status = VASurfaceDisplaying; 2335 } 2336 } 2337 pthread_mutex_unlock(&driver_data->output_mutex); 2338 2339 /* try to get frameskip flag for encode */ 2340 psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc); 2341 if (encode && rc_enable) { 2342 if (IS_MRST(driver_data)) 2343 lnc_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip); 2344 else 2345 pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip); 2346 2347 if (frame_skip == 1) { 2348 surface_status = surface_status | VASurfaceSkipped; 2349 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s next frame of 0x%08x is skipped", 2350 __FUNCTION__, render_target); 2351 } 2352 } else if (decode) { 2353 if (obj_surface->share_info) { 2354 if (obj_surface->share_info->renderStatus == 1) { 2355 surface_status = VASurfaceDisplaying; 2356 } else if (obj_surface->share_info->renderStatus == 0) { 2357 surface_status = VASurfaceReady; 2358 } 2359 } 2360 } else if (proc) { 2361 /* FIXME: does it need a new surface sync mechanism for FRC? */ 2362 } 2363 2364 *status = surface_status; 2365 DEBUG_FUNC_EXIT 2366 return vaStatus; 2367} 2368 2369VAStatus psb_QuerySurfaceError( 2370 VADriverContextP ctx, 2371 VASurfaceID render_target, 2372 VAStatus error_status, 2373 void **error_info /*out*/ 2374) 2375{ 2376 DEBUG_FUNC_ENTER 2377 INIT_DRIVER_DATA 2378 VAStatus vaStatus = VA_STATUS_SUCCESS; 2379 object_surface_p obj_surface; 2380 uint32_t i; 2381 2382 obj_surface = SURFACE(render_target); 2383 if (NULL == obj_surface) { 2384 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2385 DEBUG_FAILURE; 2386 return vaStatus; 2387 } 2388 2389#ifdef PSBVIDEO_MSVDX_EC 2390 if (driver_data->ec_enabled == 0) { 2391#else 2392 if (!IS_MRST(driver_data) || (driver_data->ec_enabled == 0)) { 2393#endif 2394 drv_debug_msg(VIDEO_DEBUG_GENERAL, "error concealment is not supported for this profile.\n"); 2395 error_info = NULL; 2396 return VA_STATUS_ERROR_UNKNOWN; 2397 } 2398 2399 if (error_status == VA_STATUS_ERROR_DECODING_ERROR) { 2400 drm_psb_msvdx_decode_status_t *decode_status = driver_data->msvdx_decode_status; 2401 struct drm_lnc_video_getparam_arg arg; 2402 uint32_t ret, handle; 2403 handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf)); 2404 2405 arg.key = IMG_VIDEO_MB_ERROR; 2406 arg.arg = (uint64_t)((unsigned long) & handle); 2407 arg.value = (uint64_t)((unsigned long)decode_status); 2408 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 2409 &arg, sizeof(arg)); 2410 2411#ifndef _FOR_FPGA_ 2412 if (decode_status->num_region > MAX_MB_ERRORS) { 2413 drv_debug_msg(VIDEO_DEBUG_GENERAL, "too much mb errors are reported.\n"); 2414 return VA_STATUS_ERROR_UNKNOWN; 2415 } 2416 i = 0; 2417 for (i = 0; i < decode_status->num_region; ++i) { 2418/* 2419 driver_data->surface_mb_error[i].status = 1; 2420 driver_data->surface_mb_error[i].start_mb = decode_status->start_error_mb_list[i]; 2421 driver_data->surface_mb_error[i].end_mb = decode_status->end_error_mb_list[i]; 2422 driver_data->surface_mb_error[i].decode_error_type = decode_status->slice_missing_or_error[i]; 2423*/ 2424 } 2425#endif 2426 driver_data->surface_mb_error[i].status = -1; 2427 *error_info = driver_data->surface_mb_error; 2428 } else { 2429 error_info = NULL; 2430 return VA_STATUS_ERROR_UNKNOWN; 2431 } 2432 DEBUG_FUNC_EXIT 2433 return vaStatus; 2434} 2435 2436VAStatus psb_LockSurface( 2437 VADriverContextP ctx, 2438 VASurfaceID surface, 2439 unsigned int *fourcc, /* following are output argument */ 2440 unsigned int *luma_stride, 2441 unsigned int *chroma_u_stride, 2442 unsigned int *chroma_v_stride, 2443 unsigned int *luma_offset, 2444 unsigned int *chroma_u_offset, 2445 unsigned int *chroma_v_offset, 2446 unsigned int *buffer_name, 2447 void **buffer 2448) 2449{ 2450 DEBUG_FUNC_ENTER 2451 INIT_DRIVER_DATA 2452 VAStatus vaStatus = VA_STATUS_SUCCESS; 2453 unsigned char *surface_data; 2454 int ret; 2455 2456 object_surface_p obj_surface = SURFACE(surface); 2457 psb_surface_p psb_surface; 2458 if (NULL == obj_surface) { 2459 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2460 DEBUG_FAILURE; 2461 return vaStatus; 2462 } 2463 2464 psb_surface = obj_surface->psb_surface; 2465 if (buffer_name) 2466 *buffer_name = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf))); 2467 2468 if (buffer) { /* map the surface buffer */ 2469 uint32_t srf_buf_ofs = 0; 2470 ret = psb_buffer_map(&psb_surface->buf, &surface_data); 2471 if (ret) { 2472 *buffer = NULL; 2473 vaStatus = VA_STATUS_ERROR_UNKNOWN; 2474 DEBUG_FAILURE; 2475 return vaStatus; 2476 } 2477 srf_buf_ofs = psb_surface->buf.buffer_ofs; 2478 *buffer = surface_data + srf_buf_ofs; 2479 } 2480 2481 *fourcc = VA_FOURCC_NV12; 2482 *luma_stride = psb_surface->stride; 2483 *chroma_u_stride = psb_surface->stride; 2484 *chroma_v_stride = psb_surface->stride; 2485 *luma_offset = 0; 2486 *chroma_u_offset = obj_surface->height * psb_surface->stride; 2487 *chroma_v_offset = obj_surface->height * psb_surface->stride + 1; 2488 DEBUG_FUNC_EXIT 2489 return vaStatus; 2490} 2491 2492 2493VAStatus psb_UnlockSurface( 2494 VADriverContextP ctx, 2495 VASurfaceID surface 2496) 2497{ 2498 DEBUG_FUNC_ENTER 2499 INIT_DRIVER_DATA 2500 VAStatus vaStatus = VA_STATUS_SUCCESS; 2501 2502 object_surface_p obj_surface = SURFACE(surface); 2503 if (NULL == obj_surface) { 2504 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2505 DEBUG_FAILURE; 2506 return vaStatus; 2507 } 2508 2509 psb_surface_p psb_surface = obj_surface->psb_surface; 2510 2511 psb_buffer_unmap(&psb_surface->buf); 2512 2513 DEBUG_FUNC_EXIT 2514 return VA_STATUS_SUCCESS; 2515} 2516 2517VAStatus psb_GetEGLClientBufferFromSurface( 2518 VADriverContextP ctx, 2519 VASurfaceID surface, 2520 void **buffer 2521) 2522{ 2523 DEBUG_FUNC_ENTER 2524 INIT_DRIVER_DATA 2525 VAStatus vaStatus = VA_STATUS_SUCCESS; 2526 2527 object_surface_p obj_surface = SURFACE(surface); 2528 if (NULL == obj_surface) { 2529 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2530 DEBUG_FAILURE; 2531 return vaStatus; 2532 } 2533 2534 psb_surface_p psb_surface = obj_surface->psb_surface; 2535 *buffer = (unsigned char *)psb_surface->bc_buffer; 2536 2537 DEBUG_FUNC_EXIT 2538 return vaStatus; 2539} 2540 2541 2542VAStatus psb_PutSurfaceBuf( 2543 VADriverContextP ctx, 2544 VASurfaceID surface, 2545 unsigned char* data, 2546 int* data_len, 2547 short srcx, 2548 short srcy, 2549 unsigned short srcw, 2550 unsigned short srch, 2551 short destx, 2552 short desty, 2553 unsigned short destw, 2554 unsigned short desth, 2555 VARectangle *cliprects, /* client supplied clip list */ 2556 unsigned int number_cliprects, /* number of clip rects in the clip list */ 2557 unsigned int flags /* de-interlacing flags */ 2558) 2559{ 2560 DEBUG_FUNC_ENTER 2561 INIT_DRIVER_DATA; 2562 object_surface_p obj_surface = SURFACE(surface); 2563 psb_surface_p psb_surface; 2564 2565 obj_surface = SURFACE(surface); 2566 psb_surface = obj_surface->psb_surface; 2567 2568 psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, /* check subpicture */ 2569 obj_surface->width, obj_surface->height, 2570 psb_surface->stride, psb_surface->buf.drm_buf, 2571 psb_surface->buf.pl_flags, 1 /* wrap dst */); 2572 2573 DEBUG_FUNC_EXIT 2574 return VA_STATUS_SUCCESS; 2575} 2576 2577VAStatus psb_SetTimestampForSurface( 2578 VADriverContextP ctx, 2579 VASurfaceID surface, 2580 long long timestamp 2581) 2582{ 2583 INIT_DRIVER_DATA; 2584 object_surface_p obj_surface = SURFACE(surface); 2585 2586 obj_surface = SURFACE(surface); 2587 2588 if (obj_surface->share_info) { 2589 obj_surface->share_info->timestamp = timestamp; 2590 return VA_STATUS_SUCCESS; 2591 } else { 2592 return VA_STATUS_ERROR_UNKNOWN; 2593 } 2594} 2595 2596 2597int LOCK_HARDWARE(psb_driver_data_p driver_data) 2598{ 2599 char ret = 0; 2600 2601 if (driver_data->dri2 || driver_data->dri_dummy) 2602 return 0; 2603 2604 pthread_mutex_lock(&driver_data->drm_mutex); 2605 DRM_CAS(driver_data->drm_lock, driver_data->drm_context, 2606 (DRM_LOCK_HELD | driver_data->drm_context), ret); 2607 if (ret) { 2608 ret = drmGetLock(driver_data->drm_fd, driver_data->drm_context, 0); 2609 /* driver_data->contended_lock=1; */ 2610 } 2611 2612 return ret; 2613} 2614 2615int UNLOCK_HARDWARE(psb_driver_data_p driver_data) 2616{ 2617 /* driver_data->contended_lock=0; */ 2618 if (driver_data->dri2 || driver_data->dri_dummy) 2619 return 0; 2620 2621 DRM_UNLOCK(driver_data->drm_fd, driver_data->drm_lock, driver_data->drm_context); 2622 pthread_mutex_unlock(&driver_data->drm_mutex); 2623 2624 return 0; 2625} 2626 2627 2628static void psb__deinitDRM(VADriverContextP ctx) 2629{ 2630 INIT_DRIVER_DATA 2631 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; 2632 2633 if (driver_data->main_pool) { 2634 driver_data->main_pool->takeDown(driver_data->main_pool); 2635 driver_data->main_pool = NULL; 2636 } 2637 if (driver_data->fence_mgr) { 2638 wsbmFenceMgrTTMTakedown(driver_data->fence_mgr); 2639 driver_data->fence_mgr = NULL; 2640 } 2641 2642 if (wsbmIsInitialized()) 2643 wsbmTakedown(); 2644 2645 close(driver_data->drm_fd); 2646 driver_data->drm_fd = dri_state->fd = -1; 2647} 2648 2649 2650static VAStatus psb__initDRI(VADriverContextP ctx) 2651{ 2652 INIT_DRIVER_DATA 2653 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; 2654 2655 assert(dri_state); 2656#ifdef _FOR_FPGA_ 2657 dri_state->driConnectedFlag = VA_DUMMY; 2658 /* ON FPGA machine, psb may co-exist with gfx's drm driver */ 2659 dri_state->fd = open("/dev/dri/card1", O_RDWR); 2660 if (dri_state->fd < 0) 2661 dri_state->fd = open("/dev/dri/card0", O_RDWR); 2662 assert(dri_state->fd >= 0); 2663#endif 2664 assert(dri_state->driConnectedFlag == VA_DRI2 || 2665 dri_state->driConnectedFlag == VA_DUMMY); 2666 2667 driver_data->drm_fd = dri_state->fd; 2668 driver_data->dri_dummy = (dri_state->driConnectedFlag == VA_DUMMY); 2669 driver_data->dri2 = (dri_state->driConnectedFlag == VA_DRI2); 2670 driver_data->ws_priv = NULL; 2671 driver_data->bus_id = NULL; 2672 2673 return VA_STATUS_SUCCESS; 2674} 2675 2676 2677static VAStatus psb__initTTM(VADriverContextP ctx) 2678{ 2679 INIT_DRIVER_DATA 2680 2681 const char drm_ext[] = "psb_ttm_placement_alphadrop"; 2682 union drm_psb_extension_arg arg; 2683 struct _WsbmBufferPool *pool; 2684 int ret; 2685 const char exec_ext[] = "psb_ttm_execbuf_alphadrop"; 2686 union drm_psb_extension_arg exec_arg; 2687 const char lncvideo_getparam_ext[] = "lnc_video_getparam"; 2688 union drm_psb_extension_arg lncvideo_getparam_arg; 2689 2690 /* init wsbm */ 2691 ret = wsbmInit(wsbmNullThreadFuncs(), psbVNodeFuncs()); 2692 if (ret) { 2693 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed initializing libwsbm.\n"); 2694 return VA_STATUS_ERROR_UNKNOWN; 2695 } 2696 2697 strncpy(arg.extension, drm_ext, sizeof(arg.extension)); 2698 /* FIXME: should check dri enabled? 2699 * it seems not init dri here at all 2700 */ 2701 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, 2702 &arg, sizeof(arg)); 2703 if (ret != 0 || !arg.rep.exists) { 2704 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n", 2705 drm_ext); 2706 driver_data->main_pool = NULL; 2707 return VA_STATUS_ERROR_UNKNOWN; 2708 } else { 2709 pool = wsbmTTMPoolInit(driver_data->drm_fd, 2710 arg.rep.driver_ioctl_offset); 2711 if (pool == NULL) { 2712 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get ttm pool\n"); 2713 return VA_STATUS_ERROR_UNKNOWN; 2714 } 2715 driver_data->main_pool = pool; 2716 } 2717 2718 strncpy(exec_arg.extension, exec_ext, sizeof(exec_arg.extension)); 2719 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &exec_arg, 2720 sizeof(exec_arg)); 2721 if (ret != 0 || !exec_arg.rep.exists) { 2722 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n", 2723 exec_ext); 2724 return FALSE; 2725 } 2726 driver_data->execIoctlOffset = exec_arg.rep.driver_ioctl_offset; 2727 2728 strncpy(lncvideo_getparam_arg.extension, lncvideo_getparam_ext, sizeof(lncvideo_getparam_arg.extension)); 2729 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &lncvideo_getparam_arg, 2730 sizeof(lncvideo_getparam_arg)); 2731 if (ret != 0 || !lncvideo_getparam_arg.rep.exists) { 2732 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n", 2733 lncvideo_getparam_ext); 2734 /* return FALSE; */ /* not reture FALSE, so it still can run */ 2735 } 2736 driver_data->getParamIoctlOffset = lncvideo_getparam_arg.rep.driver_ioctl_offset; 2737 return VA_STATUS_SUCCESS; 2738} 2739 2740static VAStatus psb__initDRM(VADriverContextP ctx) 2741{ 2742 VAStatus vaStatus; 2743 2744 vaStatus = psb__initDRI(ctx); 2745 2746 if (vaStatus == VA_STATUS_SUCCESS) 2747 return psb__initTTM(ctx); 2748 else 2749 return vaStatus; 2750} 2751 2752VAStatus psb_Terminate(VADriverContextP ctx) 2753{ 2754 DEBUG_FUNC_ENTER 2755 INIT_DRIVER_DATA 2756 object_subpic_p obj_subpic; 2757 object_image_p obj_image; 2758 object_buffer_p obj_buffer; 2759 object_surface_p obj_surface; 2760 object_context_p obj_context; 2761 object_config_p obj_config; 2762 object_heap_iterator iter; 2763 2764 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: begin to tear down\n"); 2765 2766 /* Clean up left over contexts */ 2767 obj_context = (object_context_p) object_heap_first(&driver_data->context_heap, &iter); 2768 while (obj_context) { 2769 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: contextID %08x still allocated, destroying\n", obj_context->base.id); 2770 psb__destroy_context(driver_data, obj_context); 2771 obj_context = (object_context_p) object_heap_next(&driver_data->context_heap, &iter); 2772 } 2773 object_heap_destroy(&driver_data->context_heap); 2774 2775 /* Clean up SubpicIDs */ 2776 obj_subpic = (object_subpic_p) object_heap_first(&driver_data->subpic_heap, &iter); 2777 while (obj_subpic) { 2778 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: subpictureID %08x still allocated, destroying\n", obj_subpic->base.id); 2779 psb__destroy_subpicture(driver_data, obj_subpic); 2780 obj_subpic = (object_subpic_p) object_heap_next(&driver_data->subpic_heap, &iter); 2781 } 2782 object_heap_destroy(&driver_data->subpic_heap); 2783 2784 /* Clean up ImageIDs */ 2785 obj_image = (object_image_p) object_heap_first(&driver_data->image_heap, &iter); 2786 while (obj_image) { 2787 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: imageID %08x still allocated, destroying\n", obj_image->base.id); 2788 psb__destroy_image(driver_data, obj_image); 2789 obj_image = (object_image_p) object_heap_next(&driver_data->image_heap, &iter); 2790 } 2791 object_heap_destroy(&driver_data->image_heap); 2792 2793 /* Clean up left over buffers */ 2794 obj_buffer = (object_buffer_p) object_heap_first(&driver_data->buffer_heap, &iter); 2795 while (obj_buffer) { 2796 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id); 2797 psb__destroy_buffer(driver_data, obj_buffer); 2798 obj_buffer = (object_buffer_p) object_heap_next(&driver_data->buffer_heap, &iter); 2799 } 2800 object_heap_destroy(&driver_data->buffer_heap); 2801 2802 /* Clean up left over surfaces */ 2803 2804 /* Free PVR2D buffer wrapped from the surfaces */ 2805 psb_free_surface_pvr2dbuf(driver_data); 2806 obj_surface = (object_surface_p) object_heap_first(&driver_data->surface_heap, &iter); 2807 while (obj_surface) { 2808 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: surfaceID %08x still allocated, destroying\n", obj_surface->base.id); 2809 psb__destroy_surface(driver_data, obj_surface); 2810 obj_surface = (object_surface_p) object_heap_next(&driver_data->surface_heap, &iter); 2811 } 2812 object_heap_destroy(&driver_data->surface_heap); 2813 2814 /* Clean up configIDs */ 2815 obj_config = (object_config_p) object_heap_first(&driver_data->config_heap, &iter); 2816 while (obj_config) { 2817 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); 2818 obj_config = (object_config_p) object_heap_next(&driver_data->config_heap, &iter); 2819 } 2820 object_heap_destroy(&driver_data->config_heap); 2821 2822 if (driver_data->camera_bo) { 2823 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup camera global BO\n"); 2824 2825 psb_buffer_destroy((psb_buffer_p)driver_data->camera_bo); 2826 free(driver_data->camera_bo); 2827 driver_data->camera_bo = NULL; 2828 } 2829 2830 if (driver_data->rar_bo) { 2831 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup RAR global BO\n"); 2832 2833 psb_buffer_destroy((psb_buffer_p)driver_data->rar_bo); 2834 free(driver_data->rar_bo); 2835 driver_data->rar_bo = NULL; 2836 } 2837 2838 if (driver_data->ws_priv) { 2839 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: tear down output portion\n"); 2840 2841 psb_deinitOutput(ctx); 2842 driver_data->ws_priv = NULL; 2843 } 2844 2845 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: de-initialized DRM\n"); 2846 2847 psb__deinitDRM(ctx); 2848 2849 if (driver_data->msvdx_decode_status) 2850 free(driver_data->msvdx_decode_status); 2851 2852 if (driver_data->surface_mb_error) 2853 free(driver_data->surface_mb_error); 2854 2855 free(ctx->pDriverData); 2856 free(ctx->vtable_egl); 2857 free(ctx->vtable_tpi); 2858 2859 ctx->pDriverData = NULL; 2860 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: goodbye\n\n"); 2861 2862 psb__close_log(); 2863 DEBUG_FUNC_EXIT 2864 return VA_STATUS_SUCCESS; 2865} 2866 2867EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx) 2868{ 2869 psb_driver_data_p driver_data; 2870 struct VADriverVTableTPI *tpi; 2871 struct VADriverVTableEGL *va_egl; 2872 int result; 2873 2874 if (psb_video_trace_fp) { 2875 /* make gdb always stop here */ 2876 signal(SIGUSR1, SIG_IGN); 2877 kill(getpid(), SIGUSR1); 2878 } 2879 2880 psb__open_log(); 2881 2882 drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: start the journey\n"); 2883 2884 ctx->version_major = 0; 2885 ctx->version_minor = 31; 2886 2887 ctx->max_profiles = PSB_MAX_PROFILES; 2888 ctx->max_entrypoints = PSB_MAX_ENTRYPOINTS; 2889 ctx->max_attributes = PSB_MAX_CONFIG_ATTRIBUTES; 2890 ctx->max_image_formats = PSB_MAX_IMAGE_FORMATS; 2891 ctx->max_subpic_formats = PSB_MAX_SUBPIC_FORMATS; 2892 ctx->max_display_attributes = PSB_MAX_DISPLAY_ATTRIBUTES; 2893 2894 ctx->vtable->vaTerminate = psb_Terminate; 2895 ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints; 2896 ctx->vtable->vaTerminate = psb_Terminate; 2897 ctx->vtable->vaQueryConfigProfiles = psb_QueryConfigProfiles; 2898 ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints; 2899 ctx->vtable->vaQueryConfigAttributes = psb_QueryConfigAttributes; 2900 ctx->vtable->vaCreateConfig = psb_CreateConfig; 2901 ctx->vtable->vaDestroyConfig = psb_DestroyConfig; 2902 ctx->vtable->vaGetConfigAttributes = psb_GetConfigAttributes; 2903 ctx->vtable->vaCreateSurfaces2 = psb_CreateSurfaces2; 2904 ctx->vtable->vaCreateSurfaces = NULL; 2905 ctx->vtable->vaDestroySurfaces = psb_DestroySurfaces; 2906 ctx->vtable->vaCreateContext = psb_CreateContext; 2907 ctx->vtable->vaDestroyContext = psb_DestroyContext; 2908 ctx->vtable->vaCreateBuffer = psb_CreateBuffer; 2909 ctx->vtable->vaBufferSetNumElements = psb_BufferSetNumElements; 2910 ctx->vtable->vaMapBuffer = psb_MapBuffer; 2911 ctx->vtable->vaUnmapBuffer = psb_UnmapBuffer; 2912 ctx->vtable->vaDestroyBuffer = psb_DestroyBuffer; 2913 ctx->vtable->vaBeginPicture = psb_BeginPicture; 2914 ctx->vtable->vaRenderPicture = psb_RenderPicture; 2915 ctx->vtable->vaEndPicture = psb_EndPicture; 2916 ctx->vtable->vaSyncSurface = psb_SyncSurface; 2917 ctx->vtable->vaQuerySurfaceStatus = psb_QuerySurfaceStatus; 2918 ctx->vtable->vaQuerySurfaceError = psb_QuerySurfaceError; 2919 ctx->vtable->vaPutSurface = psb_PutSurface; 2920 ctx->vtable->vaQueryImageFormats = psb_QueryImageFormats; 2921 ctx->vtable->vaCreateImage = psb_CreateImage; 2922 ctx->vtable->vaDeriveImage = psb_DeriveImage; 2923 ctx->vtable->vaDestroyImage = psb_DestroyImage; 2924 ctx->vtable->vaSetImagePalette = psb_SetImagePalette; 2925 ctx->vtable->vaGetImage = psb_GetImage; 2926 ctx->vtable->vaPutImage = psb_PutImage; 2927 ctx->vtable->vaQuerySubpictureFormats = psb_QuerySubpictureFormats; 2928 ctx->vtable->vaCreateSubpicture = psb_CreateSubpicture; 2929 ctx->vtable->vaDestroySubpicture = psb_DestroySubpicture; 2930 ctx->vtable->vaSetSubpictureImage = psb_SetSubpictureImage; 2931 ctx->vtable->vaSetSubpictureChromakey = psb_SetSubpictureChromakey; 2932 ctx->vtable->vaSetSubpictureGlobalAlpha = psb_SetSubpictureGlobalAlpha; 2933 ctx->vtable->vaAssociateSubpicture = psb_AssociateSubpicture; 2934 ctx->vtable->vaDeassociateSubpicture = psb_DeassociateSubpicture; 2935 ctx->vtable->vaQueryDisplayAttributes = psb_QueryDisplayAttributes; 2936 ctx->vtable->vaGetDisplayAttributes = psb_GetDisplayAttributes; 2937 ctx->vtable->vaSetDisplayAttributes = psb_SetDisplayAttributes; 2938 ctx->vtable->vaBufferInfo = psb_BufferInfo; 2939 ctx->vtable->vaLockSurface = psb_LockSurface; 2940 ctx->vtable->vaUnlockSurface = psb_UnlockSurface; 2941#ifdef PSBVIDEO_MRFL_VPP 2942 ctx->vtable_vpp->vaQueryVideoProcFilters = vsp_QueryVideoProcFilters; 2943 ctx->vtable_vpp->vaQueryVideoProcFilterCaps = vsp_QueryVideoProcFilterCaps; 2944 ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = vsp_QueryVideoProcPipelineCaps; 2945#endif 2946 ctx->vtable_tpi = calloc(1, sizeof(struct VADriverVTableTPI)); 2947 if (NULL == ctx->vtable_tpi) 2948 return VA_STATUS_ERROR_ALLOCATION_FAILED; 2949 2950 tpi = (struct VADriverVTableTPI *)ctx->vtable_tpi; 2951 tpi->vaCreateSurfacesWithAttribute = psb_CreateSurfacesWithAttribute; 2952 tpi->vaPutSurfaceBuf = psb_PutSurfaceBuf; 2953 tpi->vaSetTimestampForSurface = psb_SetTimestampForSurface; 2954 2955 ctx->vtable_egl = calloc(1, sizeof(struct VADriverVTableEGL)); 2956 if (NULL == ctx->vtable_egl) 2957 return VA_STATUS_ERROR_ALLOCATION_FAILED; 2958 2959 va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl; 2960 va_egl->vaGetEGLClientBufferFromSurface = psb_GetEGLClientBufferFromSurface; 2961 2962 driver_data = (psb_driver_data_p) calloc(1, sizeof(*driver_data)); 2963 ctx->pDriverData = (unsigned char *) driver_data; 2964 if (NULL == driver_data) { 2965 if (ctx->vtable_tpi) 2966 free(ctx->vtable_tpi); 2967 if (ctx->vtable_egl) 2968 free(ctx->vtable_egl); 2969 return VA_STATUS_ERROR_ALLOCATION_FAILED; 2970 } 2971 2972 if (VA_STATUS_SUCCESS != psb__initDRM(ctx)) { 2973 free(ctx->pDriverData); 2974 ctx->pDriverData = NULL; 2975 return VA_STATUS_ERROR_UNKNOWN; 2976 } 2977 2978 pthread_mutex_init(&driver_data->drm_mutex, NULL); 2979 2980 /* 2981 * To read PBO.MSR.CCF Mode and Status Register C-Spec -p112 2982 */ 2983#define PCI_PORT5_REG80_VIDEO_SD_DISABLE 0x0008 2984#define PCI_PORT5_REG80_VIDEO_HD_DISABLE 0x0010 2985 2986#if 0 2987 struct drm_psb_hw_info hw_info; 2988 do { 2989 result = drmCommandRead(driver_data->drm_fd, DRM_PSB_HW_INFO, &hw_info, sizeof(hw_info)); 2990 } while (result == EAGAIN); 2991 2992 if (result != 0) { 2993 psb__deinitDRM(ctx); 2994 free(ctx->pDriverData); 2995 ctx->pDriverData = NULL; 2996 return VA_STATUS_ERROR_UNKNOWN; 2997 } 2998 2999 driver_data->video_sd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_SD_DISABLE); 3000 driver_data->video_hd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_HD_DISABLE); 3001 drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: rev_id = %08x capabilities = %08x\n", hw_info.rev_id, hw_info.caps); 3002 drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: video_sd_disable=%d,video_hd_disable=%d\n", 3003 driver_data->video_sd_disabled, driver_data->video_hd_disabled); 3004 if (driver_data->video_sd_disabled != 0) { 3005 drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_sd_disable is true,fix it manually\n"); 3006 driver_data->video_sd_disabled = 0; 3007 } 3008 if (driver_data->video_hd_disabled != 0) { 3009 drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_hd_disable is true,fix it manually\n"); 3010 driver_data->video_hd_disabled = 0; 3011 } 3012#endif 3013 3014 if (0 != psb_get_device_info(ctx)) { 3015 drv_debug_msg(VIDEO_DEBUG_ERROR, "ERROR: failed to get video device info\n"); 3016 driver_data->encode_supported = 1; 3017 driver_data->decode_supported = 1; 3018 driver_data->hd_encode_supported = 1; 3019 driver_data->hd_decode_supported = 1; 3020 } 3021 3022 psb_init_surface_pvr2dbuf(driver_data); 3023 3024 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; 3025 if (dri_state->driConnectedFlag == VA_DRI1 || 3026 dri_state->driConnectedFlag == VA_DRI2 || 3027 dri_state->driConnectedFlag == VA_DUMMY) { 3028 if (VA_STATUS_SUCCESS != psb_initOutput(ctx)) { 3029 psb__deinitDRM(ctx); 3030 free(ctx->pDriverData); 3031 ctx->pDriverData = NULL; 3032 return VA_STATUS_ERROR_UNKNOWN; 3033 } 3034 } 3035 3036 driver_data->msvdx_context_base = (((unsigned int) getpid()) & 0xffff) << 16; 3037#ifdef PSBVIDEO_MRFL 3038 if (IS_MRFL(driver_data)) { 3039 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield topazhp encoder\n"); 3040 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &tng_H264ES_vtable; 3041 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &tng_H264ES_vtable; 3042 driver_data->profile2Format[VAProfileH264High][VAEntrypointEncSlice] = &tng_H264ES_vtable; 3043 driver_data->profile2Format[VAProfileH264StereoHigh][VAEntrypointEncSlice] = &tng_H264ES_vtable; 3044 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &tng_H263ES_vtable; 3045 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &tng_JPEGES_vtable; 3046 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable; 3047 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable; 3048 } 3049#endif 3050#ifdef PSBVIDEO_MRFL_VPP 3051 if (IS_MRFL(driver_data)) { 3052 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield vsp vpp\n"); 3053 driver_data->vpp_profile = &vsp_VPP_vtable; 3054 } 3055#endif 3056 3057#ifdef PSBVIDEO_MRFL_DEC 3058 if (IS_MRFL(driver_data)) { 3059 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield VXD392 decoder\n"); 3060 driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointVLD] = &tng_VP8_vtable; 3061 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointVLD] = &tng_JPEG_vtable; 3062 3063 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable; 3064 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable; 3065 3066 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable; 3067 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable; 3068 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable; 3069 3070 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable; 3071 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable; 3072 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable; 3073 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable; 3074 } 3075#endif 3076 3077#ifdef PSBVIDEO_MFLD 3078 if (IS_MFLD(driver_data)) { 3079 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &pnw_H263ES_vtable; 3080 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &pnw_H264ES_vtable; 3081 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &pnw_H264ES_vtable; 3082 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable; 3083 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable; 3084 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &pnw_JPEG_vtable; 3085 3086 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable; 3087 3088 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable; 3089 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable; 3090 3091 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable; 3092 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable; 3093 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable; 3094 3095 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable; 3096 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable; 3097 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable; 3098 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable; 3099 } 3100#endif 3101#ifdef PSBVIDEO_MRST 3102 if (IS_MRST(driver_data)) { 3103 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &psb_MPEG2_vtable; 3104 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointMoComp] = &psb_MPEG2MC_vtable; 3105 3106 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &psb_MPEG4_vtable; 3107 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &psb_MPEG4_vtable; 3108 3109 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &psb_H264_vtable; 3110 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &psb_H264_vtable; 3111 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &psb_H264_vtable; 3112 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &psb_H264_vtable; 3113 3114 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &psb_VC1_vtable; 3115 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &psb_VC1_vtable; 3116 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &psb_VC1_vtable; 3117 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &psb_H264_vtable; 3118 3119 if(driver_data->encode_supported) { 3120 3121 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &lnc_H263ES_vtable; 3122 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &lnc_H264ES_vtable; 3123 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &lnc_H264ES_vtable; 3124 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &lnc_MPEG4ES_vtable; 3125 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &lnc_MPEG4ES_vtable; 3126 } 3127} 3128#endif 3129 result = object_heap_init(&driver_data->config_heap, sizeof(struct object_config_s), CONFIG_ID_OFFSET); 3130 ASSERT(result == 0); 3131 3132 result = object_heap_init(&driver_data->context_heap, sizeof(struct object_context_s), CONTEXT_ID_OFFSET); 3133 ASSERT(result == 0); 3134 3135 result = object_heap_init(&driver_data->surface_heap, sizeof(struct object_surface_s), SURFACE_ID_OFFSET); 3136 ASSERT(result == 0); 3137 3138 result = object_heap_init(&driver_data->buffer_heap, sizeof(struct object_buffer_s), BUFFER_ID_OFFSET); 3139 ASSERT(result == 0); 3140 3141 result = object_heap_init(&driver_data->image_heap, sizeof(struct object_image_s), IMAGE_ID_OFFSET); 3142 ASSERT(result == 0); 3143 3144 result = object_heap_init(&driver_data->subpic_heap, sizeof(struct object_subpic_s), SUBPIC_ID_OFFSET); 3145 ASSERT(result == 0); 3146 3147 driver_data->cur_displaying_surface = VA_INVALID_SURFACE; 3148 driver_data->last_displaying_surface = VA_INVALID_SURFACE; 3149 3150 driver_data->clear_color = 0; 3151 driver_data->blend_color = 0; 3152 driver_data->blend_mode = 0; 3153 driver_data->overlay_auto_paint_color_key = 0; 3154 3155 if (IS_MRFL(driver_data)) 3156 ctx->str_vendor = PSB_STR_VENDOR_MRFL; 3157 else if (IS_MFLD(driver_data)) 3158 { 3159 if (IS_LEXINGTON(driver_data)) 3160 ctx->str_vendor = PSB_STR_VENDOR_LEXINGTON; 3161 else 3162 ctx->str_vendor = PSB_STR_VENDOR_MFLD; 3163 } 3164 else 3165 ctx->str_vendor = PSB_STR_VENDOR_MRST; 3166 3167 driver_data->msvdx_decode_status = calloc(1, sizeof(drm_psb_msvdx_decode_status_t)); 3168 if (NULL == driver_data->msvdx_decode_status) { 3169 return VA_STATUS_ERROR_ALLOCATION_FAILED; 3170 } 3171 driver_data->surface_mb_error = calloc(MAX_MB_ERRORS, sizeof(VASurfaceDecodeMBErrors)); 3172 if (NULL == driver_data->surface_mb_error) { 3173 return VA_STATUS_ERROR_ALLOCATION_FAILED; 3174 } 3175 3176 drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: succeeded!\n\n"); 3177 3178#ifdef ANDROID 3179#ifndef PSBVIDEO_MRFL 3180 gralloc_init(); 3181#endif 3182#endif 3183 return VA_STATUS_SUCCESS; 3184} 3185 3186 3187EXPORT VAStatus __vaDriverInit_0_32(VADriverContextP ctx) 3188{ 3189 return __vaDriverInit_0_31(ctx); 3190} 3191 3192 3193 3194static int psb_get_device_info(VADriverContextP ctx) 3195{ 3196 INIT_DRIVER_DATA; 3197 struct drm_lnc_video_getparam_arg arg; 3198 unsigned long device_info; 3199 int ret = 0; 3200 unsigned long video_capability; 3201 unsigned long pci_device; 3202 3203 driver_data->dev_id = 0x4100; /* by default MRST */ 3204 3205 arg.key = LNC_VIDEO_DEVICE_INFO; 3206 arg.value = (uint64_t)((unsigned long) & device_info); 3207 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 3208 &arg, sizeof(arg)); 3209 if (ret != 0) { 3210 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get video device info\n"); 3211 return ret; 3212 } 3213 3214 pci_device = (device_info >> 16) & 0xffff; 3215 video_capability = device_info & 0xffff; 3216 3217 driver_data->dev_id = pci_device; 3218 drv_debug_msg(VIDEO_DEBUG_INIT, "Retrieve Device ID 0x%08x\n", driver_data->dev_id); 3219 3220 if ((IS_MRST(driver_data) && (pci_device != 0x4101)) || 3221 IS_MFLD(driver_data) || IS_MRFL(driver_data)) 3222 driver_data->encode_supported = 1; 3223 else /* 0x4101 or other device hasn't encode support */ 3224 driver_data->encode_supported = 0; 3225 3226 if (IS_MRST(driver_data)) { 3227 driver_data->decode_supported = !(video_capability & 0x2); 3228 driver_data->hd_decode_supported = !(video_capability & 0x3); 3229 driver_data->hd_encode_supported = !(video_capability & 0x4); 3230 3231 drv_debug_msg(VIDEO_DEBUG_INIT, "video capability: decode %s, HD decode %s\n", 3232 driver_data->decode_supported ? "support" : "not support", 3233 driver_data->hd_decode_supported ? "support" : "not support"); 3234 3235 drv_debug_msg(VIDEO_DEBUG_INIT, "video capability: encode %s, HD encode %s\n", 3236 driver_data->encode_supported ? "support" : "not support", 3237 driver_data->hd_encode_supported ? "support" : "not support"); 3238 3239 } else { 3240 driver_data->decode_supported = 1; 3241 driver_data->hd_decode_supported = 1; 3242 driver_data->hd_encode_supported = 1; 3243 } 3244 3245 return ret; 3246} 3247