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