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 
     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 
     30 using 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 
     41 Vector<ISVComponent*> ISVComponent::g_isv_components;
     42 
     43 #ifndef TARGET_VPP_USE_GEN
     44 //global, static
     45 sp<ISVProcessor> ISVComponent::mProcThread = NULL;
     46 #endif
     47 
     48 //global, static
     49 pthread_mutex_t ISVComponent::ProcThreadInstanceLock = PTHREAD_MUTEX_INITIALIZER;
     50 
     51 ISVComponent::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 
    115 ISVComponent::~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 
    135 status_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 
    165 void 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 
    182 OMX_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 
    202 OMX_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 
    213 OMX_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 
    233 OMX_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 
    243 OMX_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 
    278 OMX_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 
    288 OMX_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 
    387 OMX_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 
    397 OMX_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 
    418 OMX_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 
    428 OMX_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 
    449 OMX_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 
    459 OMX_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 
    491 OMX_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 
    500 OMX_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 
    508 OMX_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 
    522 OMX_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 
    551 OMX_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 
    564 OMX_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 
    576 OMX_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 
    586 OMX_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 
    600 OMX_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 
    609 OMX_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 
    617 OMX_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 
    627 OMX_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 
    665 OMX_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 
    680 OMX_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 
    709 OMX_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 
    727 OMX_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 
    785 OMX_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 
    795 OMX_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 
    818 OMX_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 
    828 OMX_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 
    838 void 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 
    854 ISVProcThreadObserver::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 
    867 ISVProcThreadObserver::~ISVProcThreadObserver()
    868 {
    869     ALOGV("~VPPProcThreadObserver!");
    870     mBaseComponent = NULL;
    871     mComponent = NULL;
    872     mpCallBacks = NULL;
    873 }
    874 
    875 OMX_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 
    910 OMX_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