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