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