Home | History | Annotate | Download | only in omx
      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