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