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