1 /* 2 * Copyright (C) 2012 Intel Corporation. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 #include <inttypes.h> 19 20 #include <OMX_Component.h> 21 #include "isv_omxcomponent.h" 22 #include <media/hardware/HardwareAPI.h> 23 #include "isv_profile.h" 24 #include <OMX_IndexExt.h> 25 #include <hal_public.h> 26 27 #include "OMX_adaptor.h" 28 29 //#define LOG_NDEBUG 0 30 #undef LOG_TAG 31 #define LOG_TAG "isv-omxil" 32 33 #define OUTPUT_STARTUP_DEC_BUF_NUM (38) 34 #define FLUSH_WIDTH 352 35 #define FLUSH_HEIGHT 288 36 37 using namespace android; 38 39 /********************************************************************************** 40 * component methods & helpers 41 */ 42 #define GET_ISVOMX_COMPONENT(hComponent) \ 43 ISVComponent *pComp = static_cast<ISVComponent*> \ 44 ((static_cast<OMX_COMPONENTTYPE*>(hComponent))->pComponentPrivate); \ 45 if (!pComp) \ 46 return OMX_ErrorBadParameter; 47 48 Vector<ISVComponent*> ISVComponent::g_isv_components; 49 50 extern MRM_OMX_Adaptor* g_mrm_omx_adaptor; 51 52 #ifndef TARGET_VPP_USE_GEN 53 //global, static 54 sp<ISVProcessor> ISVComponent::mProcThread = NULL; 55 #endif 56 57 //global, static 58 pthread_mutex_t ISVComponent::ProcThreadInstanceLock = PTHREAD_MUTEX_INITIALIZER; 59 60 ISVComponent::ISVComponent( 61 OMX_PTR pAppData) 62 : mComponent(NULL), 63 mpCallBacks(NULL), 64 mCore(NULL), 65 mpISVCallBacks(NULL), 66 mISVBufferManager(NULL), 67 mThreadRunning(false), 68 mProcThreadObserver(NULL), 69 mNumISVBuffers(MIN_ISV_BUFFER_NUM), 70 mNumDecoderBuffers(0), 71 mNumDecoderBuffersBak(0), 72 mOutputDecoderBufferNum(0), 73 mWidth(0), 74 mHeight(0), 75 mUseAndroidNativeBufferIndex(0), 76 mStoreMetaDataInBuffersIndex(0), 77 mHackFormat(0), 78 mUseAndroidNativeBuffer(false), 79 mUseAndroidNativeBuffer2(false), 80 mVPPEnabled(false), 81 mVPPFlushing(false), 82 mOutputCropChanged(false), 83 mInitialized(false), 84 #ifdef TARGET_VPP_USE_GEN 85 mProcThread(NULL), 86 #endif 87 mOwnProcessor(false) 88 { 89 memset(&mBaseComponent, 0, sizeof(OMX_COMPONENTTYPE)); 90 /* handle initialization */ 91 SetTypeHeader(&mBaseComponent, sizeof(mBaseComponent)); 92 mBaseComponent.pApplicationPrivate = pAppData; 93 mBaseComponent.pComponentPrivate = static_cast<OMX_PTR>(this); 94 95 /* connect handle's functions */ 96 mBaseComponent.GetComponentVersion = NULL; 97 mBaseComponent.SendCommand = SendCommand; 98 mBaseComponent.GetParameter = GetParameter; 99 mBaseComponent.SetParameter = SetParameter; 100 mBaseComponent.GetConfig = GetConfig; 101 mBaseComponent.SetConfig = SetConfig; 102 mBaseComponent.GetExtensionIndex = GetExtensionIndex; 103 mBaseComponent.GetState = GetState; 104 mBaseComponent.ComponentTunnelRequest = NULL; 105 mBaseComponent.UseBuffer = UseBuffer; 106 mBaseComponent.AllocateBuffer = AllocateBuffer; 107 mBaseComponent.FreeBuffer = FreeBuffer; 108 mBaseComponent.EmptyThisBuffer = EmptyThisBuffer; 109 mBaseComponent.FillThisBuffer = FillThisBuffer; 110 mBaseComponent.SetCallbacks = SetCallbacks; 111 mBaseComponent.ComponentDeInit = NULL; 112 mBaseComponent.UseEGLImage = NULL; 113 mBaseComponent.ComponentRoleEnum = ComponentRoleEnum; 114 g_isv_components.push_back(static_cast<ISVComponent*>(this)); 115 116 mVPPOn = ISVProfile::isFRCOn() || ISVProfile::isVPPOn(); 117 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPPOn %d", __func__, mVPPOn); 118 119 if (mISVBufferManager == NULL) { 120 mISVBufferManager = new ISVBufferManager(); 121 } 122 123 } 124 125 ISVComponent::~ISVComponent() 126 { 127 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__); 128 if (mpISVCallBacks) { 129 free(mpISVCallBacks); 130 mpISVCallBacks = NULL; 131 } 132 133 for (OMX_U32 i = 0; i < g_isv_components.size(); i++) { 134 if (g_isv_components.itemAt(i) == static_cast<ISVComponent*>(this)) { 135 g_isv_components.removeAt(i); 136 } 137 } 138 139 memset(&mBaseComponent, 0, sizeof(OMX_COMPONENTTYPE)); 140 deinit(); 141 mVPPOn = false; 142 mISVBufferManager = NULL; 143 } 144 145 status_t ISVComponent::init(int32_t width, int32_t height) 146 { 147 if (mInitialized) 148 return STATUS_OK; 149 150 bool frcOn = false; 151 if (mProcThreadObserver == NULL) 152 mProcThreadObserver = new ISVProcThreadObserver(&mBaseComponent, mComponent, mpCallBacks, mISVBufferManager); 153 154 pthread_mutex_lock(&ProcThreadInstanceLock); 155 if (mProcThread == NULL) { 156 mProcThread = new ISVProcessor(false, mISVBufferManager, mProcThreadObserver, width, height); 157 mOwnProcessor = true; 158 mProcThread->start(); 159 } 160 #ifndef TARGET_VPP_USE_GEN 161 else { 162 mVPPEnabled = false; 163 mOwnProcessor = false; 164 ALOGI("%s: failed to alloc isv processor", __func__); 165 pthread_mutex_unlock(&ProcThreadInstanceLock); 166 return STATUS_ERROR; 167 } 168 #endif 169 pthread_mutex_unlock(&ProcThreadInstanceLock); 170 171 mInitialized = true; 172 return STATUS_OK; 173 } 174 175 void ISVComponent::deinit() 176 { 177 pthread_mutex_lock(&ProcThreadInstanceLock); 178 if (mOwnProcessor) { 179 if (mProcThread != NULL) { 180 mProcThread->stop(); 181 mProcThread = NULL; 182 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: delete ISV processor ", __func__); 183 } 184 } 185 pthread_mutex_unlock(&ProcThreadInstanceLock); 186 187 mProcThreadObserver = NULL; 188 189 mInitialized = false; 190 } 191 192 OMX_CALLBACKTYPE* ISVComponent::getCallBacks(OMX_CALLBACKTYPE* pCallBacks) 193 { 194 //reset component callback functions 195 mpCallBacks = pCallBacks; 196 if (mpISVCallBacks) { 197 free(mpISVCallBacks); 198 mpISVCallBacks = NULL; 199 } 200 201 mpISVCallBacks = (OMX_CALLBACKTYPE *)calloc(1, sizeof(OMX_CALLBACKTYPE)); 202 if (!mpISVCallBacks) { 203 ALOGE("%s: failed to alloc isv callbacks", __func__); 204 return NULL; 205 } 206 mpISVCallBacks->EventHandler = EventHandler; 207 mpISVCallBacks->EmptyBufferDone = pCallBacks->EmptyBufferDone; 208 mpISVCallBacks->FillBufferDone = FillBufferDone; 209 return mpISVCallBacks; 210 } 211 212 OMX_ERRORTYPE ISVComponent::SendCommand( 213 OMX_IN OMX_HANDLETYPE hComponent, 214 OMX_IN OMX_COMMANDTYPE Cmd, 215 OMX_IN OMX_U32 nParam1, 216 OMX_IN OMX_PTR pCmdData) 217 { 218 GET_ISVOMX_COMPONENT(hComponent); 219 220 return pComp->ISV_SendCommand(Cmd, nParam1, pCmdData); 221 } 222 223 OMX_ERRORTYPE ISVComponent::ISV_SendCommand( 224 OMX_IN OMX_COMMANDTYPE Cmd, 225 OMX_IN OMX_U32 nParam1, 226 OMX_IN OMX_PTR pCmdData) 227 { 228 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: Cmd index 0x%08x, nParam1 %d", __func__, Cmd, nParam1); 229 230 if (mVPPEnabled && mVPPOn) { 231 if ((Cmd == OMX_CommandFlush && (nParam1 == kPortIndexOutput || nParam1 == OMX_ALL)) 232 || (Cmd == OMX_CommandStateSet && nParam1 == OMX_StateIdle) 233 || (Cmd == OMX_CommandPortDisable && nParam1 == 1)) { 234 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: receive flush command, notify vpp thread to flush(Seek begin)", __func__); 235 mVPPFlushing = true; 236 mProcThread->notifyFlush(); 237 } 238 } 239 240 return OMX_SendCommand(mComponent, Cmd, nParam1, pCmdData); 241 } 242 243 OMX_ERRORTYPE ISVComponent::GetParameter( 244 OMX_IN OMX_HANDLETYPE hComponent, 245 OMX_IN OMX_INDEXTYPE nParamIndex, 246 OMX_INOUT OMX_PTR pComponentParameterStructure) 247 { 248 GET_ISVOMX_COMPONENT(hComponent); 249 250 return pComp->ISV_GetParameter(nParamIndex, pComponentParameterStructure); 251 } 252 253 OMX_ERRORTYPE ISVComponent::ISV_GetParameter( 254 OMX_IN OMX_INDEXTYPE nParamIndex, 255 OMX_INOUT OMX_PTR pComponentParameterStructure) 256 { 257 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nParamIndex); 258 259 OMX_ERRORTYPE err = OMX_GetParameter(mComponent, nParamIndex, pComponentParameterStructure); 260 261 if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) { 262 OMX_PARAM_PORTDEFINITIONTYPE *def = 263 static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure); 264 265 if (nParamIndex == OMX_IndexParamPortDefinition 266 && def->nPortIndex == kPortIndexOutput) { 267 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: orignal bufferCountActual %d, bufferCountMin %d", __func__, def->nBufferCountActual, def->nBufferCountMin); 268 #ifndef TARGET_VPP_USE_GEN 269 //FIXME: THIS IS A HACK!! Request NV12 buffer for YV12 format 270 //because VSP only support NV12 output 271 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video; 272 if ((video_def->eColorFormat == VA_FOURCC_YV12) || 273 (video_def->eColorFormat == HAL_PIXEL_FORMAT_INTEL_YV12)) { 274 //FIXME workaround Disable ISV for YV12 input 275 mVPPEnabled = false; 276 ALOGI("%s: Disable ISV for YV12 input. mVPPEnabled %d", __func__, mVPPEnabled); 277 } else { 278 //FIXME workaround avc low resolution playback 279 def->nBufferCountActual += mNumISVBuffers + 9; 280 def->nBufferCountMin += mNumISVBuffers + 9; 281 } 282 #endif 283 } 284 } 285 286 return err; 287 } 288 289 OMX_ERRORTYPE ISVComponent::SetParameter( 290 OMX_IN OMX_HANDLETYPE hComponent, 291 OMX_IN OMX_INDEXTYPE nIndex, 292 OMX_IN OMX_PTR pComponentParameterStructure) 293 { 294 GET_ISVOMX_COMPONENT(hComponent); 295 296 return pComp->ISV_SetParameter(nIndex, pComponentParameterStructure); 297 } 298 299 OMX_ERRORTYPE ISVComponent::ISV_SetParameter( 300 OMX_IN OMX_INDEXTYPE nIndex, 301 OMX_IN OMX_PTR pComponentParameterStructure) 302 { 303 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex); 304 305 if (nIndex == static_cast<OMX_INDEXTYPE>(OMX_IndexExtSetISVMode)) { 306 ISV_MODE* def = static_cast<ISV_MODE*>(pComponentParameterStructure); 307 308 if (*def == ISV_AUTO) { 309 mVPPEnabled = true; 310 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPPEnabled -->true", __func__); 311 #ifndef TARGET_VPP_USE_GEN 312 if (mVPPOn) { 313 uint32_t number = MIN_INPUT_NUM + MIN_OUTPUT_NUM; 314 OMX_INDEXTYPE index; 315 status_t error = 316 OMX_GetExtensionIndex( 317 mComponent, 318 (OMX_STRING)"OMX.Intel.index.vppBufferNum", 319 &index); 320 if (error == OK) { 321 error = OMX_SetParameter(mComponent, index, (OMX_PTR)&number); 322 } else { 323 // ingore this error 324 ALOGW("Get vpp number index failed"); 325 } 326 } 327 #endif 328 } else if (*def == ISV_DISABLE) 329 mVPPEnabled = false; 330 return OMX_ErrorNone; 331 } 332 333 // before setting param to real omx component, firstly set to media resource manager 334 OMX_ERRORTYPE err = g_mrm_omx_adaptor->MRM_OMX_SetParameter(mComponent, 335 nIndex, 336 pComponentParameterStructure); 337 if (err == OMX_ErrorInsufficientResources) { 338 return OMX_ErrorInsufficientResources; 339 } 340 341 err = OMX_SetParameter(mComponent, nIndex, pComponentParameterStructure); 342 if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) { 343 if (nIndex == OMX_IndexParamPortDefinition) { 344 OMX_PARAM_PORTDEFINITIONTYPE *def = 345 static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure); 346 347 if (def->nPortIndex == kPortIndexOutput) { 348 //set the buffer count we should fill to decoder before feed buffer to VPP 349 mNumDecoderBuffersBak = mNumDecoderBuffers = def->nBufferCountActual - MIN_OUTPUT_NUM - UNDEQUEUED_NUM; 350 mOutputDecoderBufferNum = 0; 351 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video; 352 353 //FIXME: init itself here 354 if (mWidth != video_def->nFrameWidth 355 || mHeight != video_def->nFrameHeight) { 356 deinit(); 357 if (STATUS_OK == init(video_def->nFrameWidth, video_def->nFrameHeight)) { 358 mWidth = video_def->nFrameWidth; 359 mHeight = video_def->nFrameHeight; 360 } 361 } 362 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: def->nBufferCountActual %d, mNumDecoderBuffersBak %d", __func__, 363 def->nBufferCountActual, mNumDecoderBuffersBak); 364 if (mISVBufferManager != NULL && OK != mISVBufferManager->setBufferCount(def->nBufferCountActual)) { 365 ALOGE("%s: failed to set ISV buffer count, set VPPEnabled -->false", __func__); 366 mVPPEnabled = false; 367 } 368 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: video frame width %d, height %d", __func__, 369 video_def->nFrameWidth, video_def->nFrameHeight); 370 } 371 372 if (def->nPortIndex == kPortIndexInput) { 373 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video; 374 375 if (mProcThread != NULL) 376 mProcThread->configFRC(video_def->xFramerate); 377 } 378 } 379 380 if (mUseAndroidNativeBuffer 381 && nIndex == static_cast<OMX_INDEXTYPE>(mUseAndroidNativeBufferIndex)) { 382 UseAndroidNativeBufferParams *def = 383 static_cast<UseAndroidNativeBufferParams*>(pComponentParameterStructure); 384 385 if (mISVBufferManager != NULL && OK != mISVBufferManager->useBuffer(def->nativeBuffer)) { 386 ALOGE("%s: failed to register graphic buffers to ISV, set mVPPEnabled -->false", __func__); 387 mVPPEnabled = false; 388 } 389 } 390 391 if (nIndex == static_cast<OMX_INDEXTYPE>(mStoreMetaDataInBuffersIndex)) { 392 StoreMetaDataInBuffersParams *params = static_cast<StoreMetaDataInBuffersParams*>(pComponentParameterStructure); 393 if (params->nPortIndex == kPortIndexOutput) { 394 if (mISVBufferManager != NULL) { 395 bool bMetaDataMode = params->bStoreMetaData == OMX_TRUE; 396 mISVBufferManager->setMetaDataMode(bMetaDataMode); 397 } else { 398 ALOGE("%s: falied to set Meta Data Mode ", __func__); 399 } 400 } 401 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: receive ISVStoreMetaDataInBuffers mISVWorkMode %d", __func__, (params->bStoreMetaData == OMX_TRUE)); 402 } 403 } 404 return err; 405 } 406 407 OMX_ERRORTYPE ISVComponent::GetConfig( 408 OMX_IN OMX_HANDLETYPE hComponent, 409 OMX_IN OMX_INDEXTYPE nIndex, 410 OMX_INOUT OMX_PTR pComponentConfigStructure) 411 { 412 GET_ISVOMX_COMPONENT(hComponent); 413 414 return pComp->ISV_GetConfig(nIndex, pComponentConfigStructure); 415 } 416 417 OMX_ERRORTYPE ISVComponent::ISV_GetConfig( 418 OMX_IN OMX_INDEXTYPE nIndex, 419 OMX_INOUT OMX_PTR pComponentConfigStructure) 420 { 421 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex); 422 423 OMX_ERRORTYPE err = OMX_GetConfig(mComponent, nIndex, pComponentConfigStructure); 424 if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) { 425 if (nIndex == OMX_IndexConfigCommonOutputCrop) { 426 OMX_CONFIG_RECTTYPE *rect = static_cast<OMX_CONFIG_RECTTYPE*>(pComponentConfigStructure); 427 if (rect->nPortIndex == kPortIndexOutput && 428 rect->nWidth < mWidth && 429 rect->nHeight < mHeight) { 430 mISVBufferManager->setBuffersFlag(ISVBuffer::ISV_BUFFER_NEED_CLEAR); 431 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mark all buffers need clear", __func__); 432 } 433 } 434 } 435 return err; 436 } 437 438 OMX_ERRORTYPE ISVComponent::SetConfig( 439 OMX_IN OMX_HANDLETYPE hComponent, 440 OMX_IN OMX_INDEXTYPE nIndex, 441 OMX_IN OMX_PTR pComponentConfigStructure) 442 { 443 GET_ISVOMX_COMPONENT(hComponent); 444 445 return pComp->ISV_SetConfig(nIndex, pComponentConfigStructure); 446 } 447 448 OMX_ERRORTYPE ISVComponent::ISV_SetConfig( 449 OMX_IN OMX_INDEXTYPE nIndex, 450 OMX_IN OMX_PTR pComponentConfigStructure) 451 { 452 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex); 453 454 if (nIndex == static_cast<OMX_INDEXTYPE>(OMX_IndexConfigAutoFramerateConversion)) { 455 OMX_CONFIG_BOOLEANTYPE *config = static_cast<OMX_CONFIG_BOOLEANTYPE*>(pComponentConfigStructure); 456 if (config->bEnabled) { 457 mVPPEnabled = true; 458 ALOGI("%s: mVPPEnabled=true", __func__); 459 } else { 460 mVPPEnabled = false; 461 ALOGI("%s: mVPPEnabled=false", __func__); 462 } 463 return OMX_ErrorNone; 464 } 465 466 return OMX_SetConfig(mComponent, nIndex, pComponentConfigStructure); 467 } 468 469 OMX_ERRORTYPE ISVComponent::GetExtensionIndex( 470 OMX_IN OMX_HANDLETYPE hComponent, 471 OMX_IN OMX_STRING cParameterName, 472 OMX_OUT OMX_INDEXTYPE* pIndexType) 473 { 474 GET_ISVOMX_COMPONENT(hComponent); 475 476 return pComp->ISV_GetExtensionIndex(cParameterName, pIndexType); 477 } 478 479 OMX_ERRORTYPE ISVComponent::ISV_GetExtensionIndex( 480 OMX_IN OMX_STRING cParameterName, 481 OMX_OUT OMX_INDEXTYPE* pIndexType) 482 { 483 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: cParameterName %s", __func__, cParameterName); 484 if(!strncmp(cParameterName, "OMX.intel.index.SetISVMode", strlen(cParameterName))) { 485 *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtSetISVMode); 486 return OMX_ErrorNone; 487 } 488 489 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mComponent, cParameterName, pIndexType); 490 491 if(err == OMX_ErrorNone && 492 !strncmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer2", strlen(cParameterName))) 493 mUseAndroidNativeBuffer2 = true; 494 495 if(err == OMX_ErrorNone && 496 !strncmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer", strlen(cParameterName))) { 497 mUseAndroidNativeBuffer = true; 498 mUseAndroidNativeBufferIndex = static_cast<uint32_t>(*pIndexType); 499 } 500 501 if(err == OMX_ErrorNone && 502 !strncmp(cParameterName, "OMX.google.android.index.storeMetaDataInBuffers", strlen(cParameterName))) { 503 mStoreMetaDataInBuffersIndex = static_cast<uint32_t>(*pIndexType); 504 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: storeMetaDataInBuffersIndex 0x%08x return %d", __func__, mStoreMetaDataInBuffersIndex, err); 505 } 506 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: cParameterName %s, nIndex 0x%08x", __func__, 507 cParameterName, *pIndexType); 508 return err; 509 } 510 511 OMX_ERRORTYPE ISVComponent::GetState( 512 OMX_IN OMX_HANDLETYPE hComponent, 513 OMX_OUT OMX_STATETYPE* pState) 514 { 515 GET_ISVOMX_COMPONENT(hComponent); 516 517 return pComp->ISV_GetState(pState); 518 } 519 520 OMX_ERRORTYPE ISVComponent::ISV_GetState( 521 OMX_OUT OMX_STATETYPE* pState) 522 { 523 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__); 524 525 return OMX_GetState(mComponent, pState); 526 } 527 528 OMX_ERRORTYPE ISVComponent::UseBuffer( 529 OMX_IN OMX_HANDLETYPE hComponent, 530 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 531 OMX_IN OMX_U32 nPortIndex, 532 OMX_IN OMX_PTR pAppPrivate, 533 OMX_IN OMX_U32 nSizeBytes, 534 OMX_IN OMX_U8 *pBuffer) 535 { 536 GET_ISVOMX_COMPONENT(hComponent); 537 538 return pComp->ISV_UseBuffer(ppBufferHdr, nPortIndex, 539 pAppPrivate, nSizeBytes, pBuffer); 540 } 541 542 OMX_ERRORTYPE ISVComponent::ISV_UseBuffer( 543 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 544 OMX_IN OMX_U32 nPortIndex, 545 OMX_IN OMX_PTR pAppPrivate, 546 OMX_IN OMX_U32 nSizeBytes, 547 OMX_IN OMX_U8 *pBuffer) 548 { 549 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__); 550 551 OMX_ERRORTYPE err = OMX_UseBuffer(mComponent, ppBufferHdr, nPortIndex, 552 pAppPrivate, nSizeBytes, pBuffer); 553 #ifndef USE_IVP 554 if(err == OMX_ErrorNone 555 && mVPPEnabled 556 && mVPPOn 557 && nPortIndex == kPortIndexOutput 558 /*&& mUseAndroidNativeBuffer2*/) { 559 if (mISVBufferManager != NULL) { 560 if (OK != mISVBufferManager->useBuffer(reinterpret_cast<unsigned long>(pBuffer))) { 561 ALOGE("%s: failed to register graphic buffers to ISV, set mVPPEnabled -->false", __func__); 562 mVPPEnabled = false; 563 } else 564 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPP useBuffer success. buffer handle %p", __func__, pBuffer); 565 } 566 } 567 #endif 568 return err; 569 } 570 571 OMX_ERRORTYPE ISVComponent::AllocateBuffer( 572 OMX_IN OMX_HANDLETYPE hComponent, 573 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 574 OMX_IN OMX_U32 nPortIndex, 575 OMX_IN OMX_PTR pAppPrivate, 576 OMX_IN OMX_U32 nSizeBytes) 577 { 578 GET_ISVOMX_COMPONENT(hComponent); 579 580 return pComp->ISV_AllocateBuffer(ppBuffer, nPortIndex, 581 pAppPrivate, nSizeBytes); 582 } 583 584 OMX_ERRORTYPE ISVComponent::ISV_AllocateBuffer( 585 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 586 OMX_IN OMX_U32 nPortIndex, 587 OMX_IN OMX_PTR pAppPrivate, 588 OMX_IN OMX_U32 nSizeBytes) 589 { 590 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__); 591 592 return OMX_AllocateBuffer(mComponent, ppBuffer, nPortIndex, 593 pAppPrivate, nSizeBytes); 594 } 595 596 OMX_ERRORTYPE ISVComponent::FreeBuffer( 597 OMX_IN OMX_HANDLETYPE hComponent, 598 OMX_IN OMX_U32 nPortIndex, 599 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 600 { 601 GET_ISVOMX_COMPONENT(hComponent); 602 603 return pComp->ISV_FreeBuffer(nPortIndex, pBuffer); 604 } 605 606 OMX_ERRORTYPE ISVComponent::ISV_FreeBuffer( 607 OMX_IN OMX_U32 nPortIndex, 608 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 609 { 610 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: pBuffer %p", __func__, pBuffer); 611 612 if(mVPPEnabled && mVPPOn 613 && nPortIndex == kPortIndexOutput) { 614 if (mISVBufferManager != NULL && OK != mISVBufferManager->freeBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer))) 615 ALOGW("%s: pBuffer %p has not been registered into ISV", __func__, pBuffer); 616 } 617 return OMX_FreeBuffer(mComponent, nPortIndex, pBuffer); 618 } 619 620 OMX_ERRORTYPE ISVComponent::EmptyThisBuffer( 621 OMX_IN OMX_HANDLETYPE hComponent, 622 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 623 { 624 GET_ISVOMX_COMPONENT(hComponent); 625 626 return pComp->ISV_EmptyThisBuffer(pBuffer); 627 } 628 629 OMX_ERRORTYPE ISVComponent::ISV_EmptyThisBuffer( 630 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 631 { 632 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: pBuffer %p", __func__, pBuffer); 633 634 return OMX_EmptyThisBuffer(mComponent, pBuffer); 635 } 636 637 OMX_ERRORTYPE ISVComponent::FillThisBuffer( 638 OMX_IN OMX_HANDLETYPE hComponent, 639 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 640 { 641 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry.", __func__); 642 GET_ISVOMX_COMPONENT(hComponent); 643 644 return pComp->ISV_FillThisBuffer(pBuffer); 645 } 646 647 OMX_ERRORTYPE ISVComponent::ISV_FillThisBuffer( 648 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 649 { 650 if(!mVPPEnabled || !mVPPOn) 651 return OMX_FillThisBuffer(mComponent, pBuffer); 652 653 ISVBuffer* isvBuffer = NULL; 654 655 if (mISVBufferManager != NULL) { 656 isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer)); 657 if (isvBuffer == NULL) { 658 ALOGE("%s: failed to map ISVBuffer, set mVPPEnabled -->false", __func__); 659 mVPPEnabled = false; 660 return OMX_FillThisBuffer(mComponent, pBuffer); 661 } 662 663 if (OK != isvBuffer->initBufferInfo(mHackFormat)) { 664 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: isvBuffer %p failed to initBufferInfo", __func__, isvBuffer); 665 mVPPEnabled = false; 666 return OMX_FillThisBuffer(mComponent, pBuffer); 667 } 668 } 669 670 if (mNumDecoderBuffers > 0) { 671 Mutex::Autolock autoLock(mDecoderBufLock); 672 mNumDecoderBuffers--; 673 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: fill pBuffer %p to the decoder, decoder still need extra %d buffers", __func__, 674 pBuffer, mNumDecoderBuffers); 675 676 if (isvBuffer != NULL) 677 isvBuffer->clearIfNeed(); 678 679 return OMX_FillThisBuffer(mComponent, pBuffer); 680 } 681 mProcThread->addOutput(pBuffer); 682 683 return OMX_ErrorNone; 684 } 685 686 OMX_ERRORTYPE ISVComponent::FillBufferDone( 687 OMX_OUT OMX_HANDLETYPE hComponent, 688 OMX_OUT OMX_PTR pAppData, 689 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) 690 { 691 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry. ISV component num %d, component handle %p on index 0", __func__, 692 g_isv_components.size(), 693 g_isv_components.itemAt(0)); 694 for (OMX_U32 i = 0; i < g_isv_components.size(); i++) { 695 if (static_cast<OMX_HANDLETYPE>(g_isv_components.itemAt(i)->mComponent) == hComponent) 696 return g_isv_components.itemAt(i)->ISV_FillBufferDone(hComponent, pAppData, pBuffer); 697 } 698 return OMX_ErrorUndefined; 699 } 700 701 OMX_ERRORTYPE ISVComponent::ISV_FillBufferDone( 702 OMX_OUT OMX_HANDLETYPE __maybe_unused hComponent, 703 OMX_OUT OMX_PTR pAppData, 704 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) 705 { 706 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: %p <== buffer_handle_t %p. mVPPEnabled %d, mVPPOn %d", __func__, 707 pBuffer, pBuffer->pBuffer, mVPPEnabled, mVPPOn); 708 if (!mpCallBacks) { 709 ALOGE("%s: no call back functions were registered.", __func__); 710 return OMX_ErrorUndefined; 711 } 712 713 if(!mVPPEnabled || !mVPPOn || mVPPFlushing || pBuffer->nFilledLen == 0) { 714 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3); 715 return mpCallBacks->FillBufferDone(&mBaseComponent, pAppData, pBuffer); 716 } 717 718 if (mOutputCropChanged && mISVBufferManager != NULL) { 719 ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer)); 720 if (isvBuffer != NULL) 721 isvBuffer->setFlag(ISVBuffer::ISV_BUFFER_CROP_CHANGED); 722 mOutputCropChanged = false; 723 } 724 725 if ((mWidth > FLUSH_WIDTH) && (mHeight > FLUSH_HEIGHT) && 726 (pBuffer->nFilledLen != 0) && (mOutputDecoderBufferNum < OUTPUT_STARTUP_DEC_BUF_NUM)) { 727 Mutex::Autolock autoLock(mDecoderBufLock); 728 // take one buffer from decoder loop here. Fill one buffer to the loop by mNumDecoderBuffers++ 729 mNumDecoderBuffers++; 730 mOutputDecoderBufferNum++; 731 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: return %d decoder output Buffer, mNumDecoderBuffers get %d input buffer", 732 __func__, mOutputDecoderBufferNum, mNumDecoderBuffers); 733 return mpCallBacks->FillBufferDone(&mBaseComponent, pAppData, pBuffer); 734 } 735 736 mProcThread->addInput(pBuffer); 737 738 return OMX_ErrorNone; 739 } 740 741 OMX_ERRORTYPE ISVComponent::EventHandler( 742 OMX_IN OMX_HANDLETYPE hComponent, 743 OMX_IN OMX_PTR pAppData, 744 OMX_IN OMX_EVENTTYPE eEvent, 745 OMX_IN OMX_U32 nData1, 746 OMX_IN OMX_U32 nData2, 747 OMX_IN OMX_PTR pEventData) 748 { 749 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry. ISV component num %d, component handle %p on index 0", __func__, 750 g_isv_components.size(), 751 g_isv_components.itemAt(0)); 752 for (OMX_U32 i = 0; i < g_isv_components.size(); i++) { 753 if (static_cast<OMX_HANDLETYPE>(g_isv_components.itemAt(i)->mComponent) == hComponent) 754 return g_isv_components.itemAt(i)->ISV_EventHandler(hComponent, pAppData, eEvent, nData1, nData2, pEventData); 755 } 756 return OMX_ErrorUndefined; 757 } 758 759 OMX_ERRORTYPE ISVComponent::ISV_EventHandler( 760 OMX_IN OMX_HANDLETYPE __maybe_unused hComponent, 761 OMX_IN OMX_PTR pAppData, 762 OMX_IN OMX_EVENTTYPE eEvent, 763 OMX_IN OMX_U32 nData1, 764 OMX_IN OMX_U32 nData2, 765 OMX_IN OMX_PTR pEventData) 766 { 767 if (!mpCallBacks) { 768 ALOGE("%s: no call back functions were registered.", __func__); 769 return OMX_ErrorUndefined; 770 } 771 772 if(!mVPPEnabled || !mVPPOn) 773 return mpCallBacks->EventHandler(&mBaseComponent, pAppData, eEvent, nData1, nData2, pEventData); 774 775 switch (eEvent) { 776 case OMX_EventCmdComplete: 777 { 778 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: OMX_EventCmdComplete Cmd type 0x%08x, data2 %d", __func__, 779 nData1, nData2); 780 if (((OMX_COMMANDTYPE)nData1 == OMX_CommandFlush && (nData2 == kPortIndexOutput || nData2 == OMX_ALL)) 781 || ((OMX_COMMANDTYPE)nData1 == OMX_CommandStateSet && nData2 == OMX_StateIdle) 782 || ((OMX_COMMANDTYPE)nData1 == OMX_CommandPortDisable && nData2 == 1)) { 783 mProcThread->waitFlushFinished(); 784 mVPPFlushing = false; 785 mNumDecoderBuffers = mNumDecoderBuffersBak; 786 mOutputDecoderBufferNum = 0; 787 } 788 break; 789 } 790 791 case OMX_EventError: 792 { 793 //do we need do anything here? 794 ALOGE("%s: ERROR(0x%08x, %d)", __func__, nData1, nData2); 795 //mProcThread->flush(); 796 break; 797 } 798 799 case OMX_EventPortSettingsChanged: 800 { 801 if (nData1 == kPortIndexOutput && nData2 == OMX_IndexConfigCommonOutputCrop) { 802 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: output crop changed", __func__); 803 mOutputCropChanged = true; 804 return OMX_ErrorNone; 805 } else if (nData1 == kPortIndexOutput && nData2 == OMX_IndexParamPortDefinition) { 806 ALOGI("%s: output format changed. ISV flush buffers", __func__); 807 mProcThread->notifyFlush(); 808 } 809 break; 810 } 811 812 default: 813 { 814 ALOGD_IF( 815 ISV_COMPONENT_DEBUG, "%s: EVENT(%d, %" PRId32 ", %" PRId32 ")", 816 __func__, eEvent, nData1, nData2); 817 break; 818 } 819 } 820 return mpCallBacks->EventHandler(&mBaseComponent, pAppData, eEvent, nData1, nData2, pEventData); 821 } 822 823 OMX_ERRORTYPE ISVComponent::SetCallbacks( 824 OMX_IN OMX_HANDLETYPE hComponent, 825 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 826 OMX_IN OMX_PTR pAppData) 827 { 828 GET_ISVOMX_COMPONENT(hComponent); 829 830 return pComp->ISV_SetCallbacks(pCallbacks, pAppData); 831 } 832 833 OMX_ERRORTYPE ISVComponent::ISV_SetCallbacks( 834 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 835 OMX_IN OMX_PTR pAppData) 836 { 837 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__); 838 839 if (mVPPEnabled && mVPPOn) { 840 if (mpISVCallBacks == NULL) { 841 mpISVCallBacks = (OMX_CALLBACKTYPE *)calloc(1, sizeof(OMX_CALLBACKTYPE)); 842 if (!mpISVCallBacks) { 843 ALOGE("%s: failed to alloc isv callbacks", __func__); 844 return OMX_ErrorUndefined; 845 } 846 } 847 mpISVCallBacks->EventHandler = EventHandler; 848 mpISVCallBacks->EmptyBufferDone = pCallbacks->EmptyBufferDone; 849 mpISVCallBacks->FillBufferDone = FillBufferDone; 850 mpCallBacks = pCallbacks; 851 return mComponent->SetCallbacks(mComponent, mpISVCallBacks, pAppData); 852 } 853 return mComponent->SetCallbacks(mComponent, pCallbacks, pAppData); 854 } 855 856 OMX_ERRORTYPE ISVComponent::ComponentRoleEnum( 857 OMX_IN OMX_HANDLETYPE hComponent, 858 OMX_OUT OMX_U8 *cRole, 859 OMX_IN OMX_U32 nIndex) 860 { 861 GET_ISVOMX_COMPONENT(hComponent); 862 863 return pComp->ISV_ComponentRoleEnum(cRole, nIndex); 864 } 865 866 OMX_ERRORTYPE ISVComponent::ISV_ComponentRoleEnum( 867 OMX_OUT OMX_U8 *cRole, 868 OMX_IN OMX_U32 nIndex) 869 { 870 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__); 871 872 return mComponent->ComponentRoleEnum(mComponent, cRole, nIndex); 873 } 874 875 876 void ISVComponent::SetTypeHeader(OMX_PTR type, OMX_U32 size) 877 { 878 OMX_U32 *nsize; 879 OMX_VERSIONTYPE *nversion; 880 881 if (!type) 882 return; 883 884 nsize = (OMX_U32 *)type; 885 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 886 887 *nsize = size; 888 nversion->nVersion = OMX_SPEC_VERSION; 889 } 890 891 892 ISVProcThreadObserver::ISVProcThreadObserver( 893 OMX_COMPONENTTYPE *pBaseComponent, 894 OMX_COMPONENTTYPE *pComponent, 895 OMX_CALLBACKTYPE *pCallBacks, 896 sp<ISVBufferManager> bufferManager) 897 : mBaseComponent(pBaseComponent), 898 mComponent(pComponent), 899 mpCallBacks(pCallBacks), 900 mISVBufferManager(bufferManager) 901 { 902 ALOGV("VPPProcThreadObserver!"); 903 } 904 905 ISVProcThreadObserver::~ISVProcThreadObserver() 906 { 907 ALOGV("~VPPProcThreadObserver!"); 908 mBaseComponent = NULL; 909 mComponent = NULL; 910 mpCallBacks = NULL; 911 } 912 913 OMX_ERRORTYPE ISVProcThreadObserver::releaseBuffer(PORT_INDEX index, OMX_BUFFERHEADERTYPE* pBuffer, bool bFLush) 914 { 915 if (!mBaseComponent || !mComponent || !mpCallBacks) 916 return OMX_ErrorUndefined; 917 918 OMX_ERRORTYPE err = OMX_ErrorNone; 919 if (bFLush) { 920 if(index == kPortIndexOutput) { 921 pBuffer->nFilledLen = 0; 922 pBuffer->nOffset = 0; 923 pBuffer->nTimeStamp = 0; 924 pBuffer->nFlags = 0; 925 } 926 err = mpCallBacks->FillBufferDone(&mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer); 927 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: flush pBuffer %p", __func__, pBuffer); 928 return err; 929 } 930 931 if (index == kPortIndexInput) { 932 pBuffer->nFilledLen = 0; 933 pBuffer->nOffset = 0; 934 pBuffer->nFlags = 0; 935 pBuffer->nTimeStamp = 0; 936 937 if (mISVBufferManager != NULL) { 938 ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer)); 939 if (isvBuffer != NULL) 940 isvBuffer->clearIfNeed(); 941 } 942 943 err = OMX_FillThisBuffer(mComponent, pBuffer); 944 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBuffer pBuffer %p", __func__, pBuffer); 945 } else { 946 err = mpCallBacks->FillBufferDone(&mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer); 947 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3); 948 } 949 950 return err; 951 } 952 953 OMX_ERRORTYPE ISVProcThreadObserver::reportOutputCrop() 954 { 955 if (!mBaseComponent || !mComponent || !mpCallBacks) 956 return OMX_ErrorUndefined; 957 958 OMX_ERRORTYPE err = OMX_ErrorNone; 959 err = mpCallBacks->EventHandler(&mBaseComponent, mBaseComponent->pApplicationPrivate, 960 OMX_EventPortSettingsChanged, 961 kPortIndexOutput, OMX_IndexConfigCommonOutputCrop, NULL); 962 return err; 963 } 964