/*
 * Copyright (C) 2012 Intel Corporation.  All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <inttypes.h>

#include <OMX_Component.h>
#include "isv_omxcomponent.h"
#include <media/hardware/HardwareAPI.h>
#include "isv_profile.h"
#include <OMX_IndexExt.h>
#include <hal_public.h>

#include "OMX_adaptor.h"

//#define LOG_NDEBUG 0
#undef LOG_TAG
#define LOG_TAG "isv-omxil"

#define OUTPUT_STARTUP_DEC_BUF_NUM (38)
#define FLUSH_WIDTH  352
#define FLUSH_HEIGHT 288

using namespace android;

/**********************************************************************************
 * component methods & helpers
 */
#define GET_ISVOMX_COMPONENT(hComponent)                                    \
    ISVComponent *pComp = static_cast<ISVComponent*>                        \
        ((static_cast<OMX_COMPONENTTYPE*>(hComponent))->pComponentPrivate); \
    if (!pComp)                                                             \
        return OMX_ErrorBadParameter;

Vector<ISVComponent*> ISVComponent::g_isv_components;

extern MRM_OMX_Adaptor* g_mrm_omx_adaptor;

#ifndef TARGET_VPP_USE_GEN
//global, static
sp<ISVProcessor> ISVComponent::mProcThread = NULL;
#endif

//global, static
pthread_mutex_t ISVComponent::ProcThreadInstanceLock = PTHREAD_MUTEX_INITIALIZER;

ISVComponent::ISVComponent(
        OMX_PTR pAppData)
    :   mComponent(NULL),
        mpCallBacks(NULL),
        mCore(NULL),
        mpISVCallBacks(NULL),
        mISVBufferManager(NULL),
        mThreadRunning(false),
        mProcThreadObserver(NULL),
        mNumISVBuffers(MIN_ISV_BUFFER_NUM),
        mNumDecoderBuffers(0),
        mNumDecoderBuffersBak(0),
        mOutputDecoderBufferNum(0),
        mWidth(0),
        mHeight(0),
        mUseAndroidNativeBufferIndex(0),
        mStoreMetaDataInBuffersIndex(0),
        mHackFormat(0),
        mUseAndroidNativeBuffer(false),
        mUseAndroidNativeBuffer2(false),
        mVPPEnabled(false),
        mVPPFlushing(false),
        mOutputCropChanged(false),
        mInitialized(false),
#ifdef TARGET_VPP_USE_GEN
        mProcThread(NULL),
#endif
        mOwnProcessor(false)
{
    memset(&mBaseComponent, 0, sizeof(OMX_COMPONENTTYPE));
    /* handle initialization */
    SetTypeHeader(&mBaseComponent, sizeof(mBaseComponent));
    mBaseComponent.pApplicationPrivate = pAppData;
    mBaseComponent.pComponentPrivate = static_cast<OMX_PTR>(this);

    /* connect handle's functions */
    mBaseComponent.GetComponentVersion = NULL;
    mBaseComponent.SendCommand = SendCommand;
    mBaseComponent.GetParameter = GetParameter;
    mBaseComponent.SetParameter = SetParameter;
    mBaseComponent.GetConfig = GetConfig;
    mBaseComponent.SetConfig = SetConfig;
    mBaseComponent.GetExtensionIndex = GetExtensionIndex;
    mBaseComponent.GetState = GetState;
    mBaseComponent.ComponentTunnelRequest = NULL;
    mBaseComponent.UseBuffer = UseBuffer;
    mBaseComponent.AllocateBuffer = AllocateBuffer;
    mBaseComponent.FreeBuffer = FreeBuffer;
    mBaseComponent.EmptyThisBuffer = EmptyThisBuffer;
    mBaseComponent.FillThisBuffer = FillThisBuffer;
    mBaseComponent.SetCallbacks = SetCallbacks;
    mBaseComponent.ComponentDeInit = NULL;
    mBaseComponent.UseEGLImage = NULL;
    mBaseComponent.ComponentRoleEnum = ComponentRoleEnum;
    g_isv_components.push_back(static_cast<ISVComponent*>(this));

    mVPPOn = ISVProfile::isFRCOn() || ISVProfile::isVPPOn();
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPPOn %d", __func__, mVPPOn);

    if (mISVBufferManager == NULL) {
        mISVBufferManager = new ISVBufferManager();
    }

}

ISVComponent::~ISVComponent()
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
    if (mpISVCallBacks) {
        free(mpISVCallBacks);
        mpISVCallBacks = NULL;
    }

    for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
        if (g_isv_components.itemAt(i) == static_cast<ISVComponent*>(this)) {
            g_isv_components.removeAt(i);
        }
    }

    memset(&mBaseComponent, 0, sizeof(OMX_COMPONENTTYPE));
    deinit();
    mVPPOn = false;
    mISVBufferManager = NULL;
}

status_t ISVComponent::init(int32_t width, int32_t height)
{
    if (mInitialized)
        return STATUS_OK;

    bool frcOn = false;
    if (mProcThreadObserver == NULL)
        mProcThreadObserver = new ISVProcThreadObserver(&mBaseComponent, mComponent, mpCallBacks, mISVBufferManager);

    pthread_mutex_lock(&ProcThreadInstanceLock);
    if (mProcThread == NULL) {
        mProcThread = new ISVProcessor(false, mISVBufferManager, mProcThreadObserver, width, height);
        mOwnProcessor = true;
        mProcThread->start();
    }
#ifndef TARGET_VPP_USE_GEN
    else {
        mVPPEnabled = false;
        mOwnProcessor = false;
        ALOGI("%s: failed to alloc isv processor", __func__);
        pthread_mutex_unlock(&ProcThreadInstanceLock);
        return STATUS_ERROR;
    }
#endif
    pthread_mutex_unlock(&ProcThreadInstanceLock);

    mInitialized = true;
    return STATUS_OK;
}

void ISVComponent::deinit()
{
    pthread_mutex_lock(&ProcThreadInstanceLock);
    if (mOwnProcessor) {
        if (mProcThread != NULL) {
            mProcThread->stop();
            mProcThread = NULL;
            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: delete ISV processor ", __func__);
        }
    }
    pthread_mutex_unlock(&ProcThreadInstanceLock);

    mProcThreadObserver = NULL;

    mInitialized = false;
}

OMX_CALLBACKTYPE* ISVComponent::getCallBacks(OMX_CALLBACKTYPE* pCallBacks)
{
    //reset component callback functions
    mpCallBacks = pCallBacks;
    if (mpISVCallBacks) {
        free(mpISVCallBacks);
        mpISVCallBacks = NULL;
    }

    mpISVCallBacks = (OMX_CALLBACKTYPE *)calloc(1, sizeof(OMX_CALLBACKTYPE));
    if (!mpISVCallBacks) {
        ALOGE("%s: failed to alloc isv callbacks", __func__);
        return NULL;
    }
    mpISVCallBacks->EventHandler = EventHandler;
    mpISVCallBacks->EmptyBufferDone = pCallBacks->EmptyBufferDone;
    mpISVCallBacks->FillBufferDone = FillBufferDone;
    return mpISVCallBacks;
}

OMX_ERRORTYPE ISVComponent::SendCommand(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_COMMANDTYPE Cmd,
    OMX_IN  OMX_U32 nParam1,
    OMX_IN  OMX_PTR pCmdData)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_SendCommand(Cmd, nParam1, pCmdData);
}

OMX_ERRORTYPE ISVComponent::ISV_SendCommand(
    OMX_IN  OMX_COMMANDTYPE Cmd,
    OMX_IN  OMX_U32 nParam1,
    OMX_IN  OMX_PTR pCmdData)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: Cmd index 0x%08x, nParam1 %d", __func__, Cmd, nParam1);

    if (mVPPEnabled && mVPPOn) {
        if ((Cmd == OMX_CommandFlush && (nParam1 == kPortIndexOutput || nParam1 == OMX_ALL))
                || (Cmd == OMX_CommandStateSet && nParam1 == OMX_StateIdle)
                || (Cmd == OMX_CommandPortDisable && nParam1 == 1)) {
            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: receive flush command, notify vpp thread to flush(Seek begin)", __func__);
            mVPPFlushing = true;
            mProcThread->notifyFlush();
        }
    }

    return OMX_SendCommand(mComponent, Cmd, nParam1, pCmdData);
}

OMX_ERRORTYPE ISVComponent::GetParameter(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nParamIndex,
    OMX_INOUT OMX_PTR pComponentParameterStructure)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_GetParameter(nParamIndex, pComponentParameterStructure);
}

OMX_ERRORTYPE ISVComponent::ISV_GetParameter(
    OMX_IN  OMX_INDEXTYPE nParamIndex,
    OMX_INOUT OMX_PTR pComponentParameterStructure)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nParamIndex);

    OMX_ERRORTYPE err = OMX_GetParameter(mComponent, nParamIndex, pComponentParameterStructure);

    if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) {
        OMX_PARAM_PORTDEFINITIONTYPE *def =
            static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure);

        if (nParamIndex == OMX_IndexParamPortDefinition
                && def->nPortIndex == kPortIndexOutput) {
            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: orignal bufferCountActual %d, bufferCountMin %d",  __func__, def->nBufferCountActual, def->nBufferCountMin);
#ifndef TARGET_VPP_USE_GEN
            //FIXME: THIS IS A HACK!! Request NV12 buffer for YV12 format
            //because VSP only support NV12 output
            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;
            if ((video_def->eColorFormat == VA_FOURCC_YV12) ||
                (video_def->eColorFormat == HAL_PIXEL_FORMAT_INTEL_YV12)) {
                //FIXME workaround Disable ISV for YV12 input
                mVPPEnabled = false;
                ALOGI("%s: Disable ISV for YV12 input. mVPPEnabled %d", __func__, mVPPEnabled);
            } else {
                //FIXME workaround avc low resolution playback
                def->nBufferCountActual += mNumISVBuffers + 9;
                def->nBufferCountMin += mNumISVBuffers + 9;
            }
#endif
        }
    }

    return err;
}

OMX_ERRORTYPE ISVComponent::SetParameter(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_IN  OMX_PTR pComponentParameterStructure)
{
    GET_ISVOMX_COMPONENT(hComponent);
 
    return pComp->ISV_SetParameter(nIndex, pComponentParameterStructure);
}

OMX_ERRORTYPE ISVComponent::ISV_SetParameter(
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_IN  OMX_PTR pComponentParameterStructure)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);

    if (nIndex == static_cast<OMX_INDEXTYPE>(OMX_IndexExtSetISVMode)) {
        ISV_MODE* def = static_cast<ISV_MODE*>(pComponentParameterStructure);

        if (*def == ISV_AUTO) {
            mVPPEnabled = true;
            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPPEnabled -->true", __func__);
#ifndef TARGET_VPP_USE_GEN
            if (mVPPOn) {
                uint32_t number = MIN_INPUT_NUM + MIN_OUTPUT_NUM;
                OMX_INDEXTYPE index;
                status_t error =
                    OMX_GetExtensionIndex(
                            mComponent,
                            (OMX_STRING)"OMX.Intel.index.vppBufferNum",
                            &index);
                if (error == OK) {
                    error = OMX_SetParameter(mComponent, index, (OMX_PTR)&number);
                } else {
                    // ingore this error
                    ALOGW("Get vpp number index failed");
                }
            }
#endif
        } else if (*def == ISV_DISABLE)
            mVPPEnabled = false;
        return OMX_ErrorNone;
    }

    // before setting param to real omx component, firstly set to media resource manager
    OMX_ERRORTYPE err = g_mrm_omx_adaptor->MRM_OMX_SetParameter(mComponent,
                                                                nIndex,
                                                                pComponentParameterStructure); 
    if (err == OMX_ErrorInsufficientResources) {
        return OMX_ErrorInsufficientResources;
    }

    err = OMX_SetParameter(mComponent, nIndex, pComponentParameterStructure);
    if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) {
        if (nIndex == OMX_IndexParamPortDefinition) {
            OMX_PARAM_PORTDEFINITIONTYPE *def =
                static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure);

            if (def->nPortIndex == kPortIndexOutput) {
                //set the buffer count we should fill to decoder before feed buffer to VPP
                mNumDecoderBuffersBak = mNumDecoderBuffers = def->nBufferCountActual - MIN_OUTPUT_NUM - UNDEQUEUED_NUM;
                mOutputDecoderBufferNum = 0;
                OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;

                //FIXME: init itself here
                if (mWidth != video_def->nFrameWidth
                        || mHeight != video_def->nFrameHeight) {
                    deinit();
                    if (STATUS_OK == init(video_def->nFrameWidth, video_def->nFrameHeight)) {
                        mWidth = video_def->nFrameWidth;
                        mHeight = video_def->nFrameHeight;
                    }
                }
                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: def->nBufferCountActual %d, mNumDecoderBuffersBak %d", __func__,
                        def->nBufferCountActual, mNumDecoderBuffersBak);
                if (mISVBufferManager != NULL && OK != mISVBufferManager->setBufferCount(def->nBufferCountActual)) {
                    ALOGE("%s: failed to set ISV buffer count, set VPPEnabled -->false", __func__);
                    mVPPEnabled = false;
                }
                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: video frame width %d, height %d",  __func__, 
                        video_def->nFrameWidth, video_def->nFrameHeight);
            }

            if (def->nPortIndex == kPortIndexInput) {
                OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;

                if (mProcThread != NULL)
                    mProcThread->configFRC(video_def->xFramerate);
            }
        }

        if (mUseAndroidNativeBuffer
                && nIndex == static_cast<OMX_INDEXTYPE>(mUseAndroidNativeBufferIndex)) {
            UseAndroidNativeBufferParams *def =
                static_cast<UseAndroidNativeBufferParams*>(pComponentParameterStructure);

            if (mISVBufferManager != NULL && OK != mISVBufferManager->useBuffer(def->nativeBuffer)) {
                    ALOGE("%s: failed to register graphic buffers to ISV, set mVPPEnabled -->false", __func__);
                    mVPPEnabled = false;
            }
        }

        if (nIndex == static_cast<OMX_INDEXTYPE>(mStoreMetaDataInBuffersIndex)) {
            StoreMetaDataInBuffersParams *params = static_cast<StoreMetaDataInBuffersParams*>(pComponentParameterStructure);
            if (params->nPortIndex == kPortIndexOutput) {
                if (mISVBufferManager != NULL) {
                    bool bMetaDataMode = params->bStoreMetaData == OMX_TRUE;
                    mISVBufferManager->setMetaDataMode(bMetaDataMode);
                } else {
                    ALOGE("%s: falied to set Meta Data Mode ", __func__);
                }
            }
            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: receive ISVStoreMetaDataInBuffers mISVWorkMode %d", __func__, (params->bStoreMetaData == OMX_TRUE));
        }
    }
    return err;
}

OMX_ERRORTYPE ISVComponent::GetConfig(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_INOUT OMX_PTR pComponentConfigStructure)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_GetConfig(nIndex, pComponentConfigStructure);
}

OMX_ERRORTYPE ISVComponent::ISV_GetConfig(
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_INOUT OMX_PTR pComponentConfigStructure)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);

    OMX_ERRORTYPE err = OMX_GetConfig(mComponent, nIndex, pComponentConfigStructure);
    if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) {
        if (nIndex == OMX_IndexConfigCommonOutputCrop) {
            OMX_CONFIG_RECTTYPE *rect = static_cast<OMX_CONFIG_RECTTYPE*>(pComponentConfigStructure);
            if (rect->nPortIndex == kPortIndexOutput &&
                    rect->nWidth < mWidth &&
                    rect->nHeight < mHeight) {
                mISVBufferManager->setBuffersFlag(ISVBuffer::ISV_BUFFER_NEED_CLEAR);
                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mark all buffers need clear", __func__);
            }
        }
    }
    return err;
}

OMX_ERRORTYPE ISVComponent::SetConfig(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_IN  OMX_PTR pComponentConfigStructure)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_SetConfig(nIndex, pComponentConfigStructure);
}

OMX_ERRORTYPE ISVComponent::ISV_SetConfig(
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_IN  OMX_PTR pComponentConfigStructure)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);

    if (nIndex == static_cast<OMX_INDEXTYPE>(OMX_IndexConfigAutoFramerateConversion)) {
        OMX_CONFIG_BOOLEANTYPE *config = static_cast<OMX_CONFIG_BOOLEANTYPE*>(pComponentConfigStructure);
        if (config->bEnabled) {
            mVPPEnabled = true;
            ALOGI("%s: mVPPEnabled=true", __func__);
        } else {
            mVPPEnabled = false;
            ALOGI("%s: mVPPEnabled=false", __func__);
        }
        return OMX_ErrorNone;
    }

    return OMX_SetConfig(mComponent, nIndex, pComponentConfigStructure);
}

OMX_ERRORTYPE ISVComponent::GetExtensionIndex(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_STRING cParameterName,
    OMX_OUT OMX_INDEXTYPE* pIndexType)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_GetExtensionIndex(cParameterName, pIndexType);
}

OMX_ERRORTYPE ISVComponent::ISV_GetExtensionIndex(
    OMX_IN  OMX_STRING cParameterName,
    OMX_OUT OMX_INDEXTYPE* pIndexType)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: cParameterName %s", __func__, cParameterName);
    if(!strncmp(cParameterName, "OMX.intel.index.SetISVMode", strlen(cParameterName))) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtSetISVMode);
        return OMX_ErrorNone;
    }

    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mComponent, cParameterName, pIndexType);

    if(err == OMX_ErrorNone &&
            !strncmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer2", strlen(cParameterName)))
        mUseAndroidNativeBuffer2 = true;

    if(err == OMX_ErrorNone &&
            !strncmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer", strlen(cParameterName))) {
        mUseAndroidNativeBuffer = true;
        mUseAndroidNativeBufferIndex = static_cast<uint32_t>(*pIndexType);
    }

    if(err == OMX_ErrorNone &&
            !strncmp(cParameterName, "OMX.google.android.index.storeMetaDataInBuffers", strlen(cParameterName))) {
        mStoreMetaDataInBuffersIndex = static_cast<uint32_t>(*pIndexType);
        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: storeMetaDataInBuffersIndex 0x%08x return %d", __func__, mStoreMetaDataInBuffersIndex, err);
    }
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: cParameterName %s, nIndex 0x%08x", __func__,
            cParameterName, *pIndexType);
    return err;
}

OMX_ERRORTYPE ISVComponent::GetState(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_OUT OMX_STATETYPE* pState)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_GetState(pState);
}

OMX_ERRORTYPE ISVComponent::ISV_GetState(
    OMX_OUT OMX_STATETYPE* pState)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);

    return OMX_GetState(mComponent, pState);
}

OMX_ERRORTYPE ISVComponent::UseBuffer(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
    OMX_IN OMX_U32 nPortIndex,
    OMX_IN OMX_PTR pAppPrivate,
    OMX_IN OMX_U32 nSizeBytes,
    OMX_IN OMX_U8 *pBuffer)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_UseBuffer(ppBufferHdr, nPortIndex,
                                 pAppPrivate, nSizeBytes, pBuffer);
}

OMX_ERRORTYPE ISVComponent::ISV_UseBuffer(
    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
    OMX_IN OMX_U32 nPortIndex,
    OMX_IN OMX_PTR pAppPrivate,
    OMX_IN OMX_U32 nSizeBytes,
    OMX_IN OMX_U8 *pBuffer)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);

    OMX_ERRORTYPE err = OMX_UseBuffer(mComponent, ppBufferHdr, nPortIndex,
            pAppPrivate, nSizeBytes, pBuffer);
#ifndef USE_IVP
    if(err == OMX_ErrorNone
            && mVPPEnabled
            && mVPPOn
            && nPortIndex == kPortIndexOutput
            /*&& mUseAndroidNativeBuffer2*/) {
        if (mISVBufferManager != NULL) {
            if (OK != mISVBufferManager->useBuffer(reinterpret_cast<unsigned long>(pBuffer))) {
                ALOGE("%s: failed to register graphic buffers to ISV, set mVPPEnabled -->false", __func__);
                mVPPEnabled = false;
            } else
                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPP useBuffer success. buffer handle %p", __func__, pBuffer);
        }
    }
#endif
    return err;
}

OMX_ERRORTYPE ISVComponent::AllocateBuffer(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
    OMX_IN OMX_U32 nPortIndex,
    OMX_IN OMX_PTR pAppPrivate,
    OMX_IN OMX_U32 nSizeBytes)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_AllocateBuffer(ppBuffer, nPortIndex,
                                      pAppPrivate, nSizeBytes);
}

OMX_ERRORTYPE ISVComponent::ISV_AllocateBuffer(
    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
    OMX_IN OMX_U32 nPortIndex,
    OMX_IN OMX_PTR pAppPrivate,
    OMX_IN OMX_U32 nSizeBytes)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);

    return OMX_AllocateBuffer(mComponent, ppBuffer, nPortIndex,
                                      pAppPrivate, nSizeBytes);
}

OMX_ERRORTYPE ISVComponent::FreeBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_U32 nPortIndex,
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_FreeBuffer(nPortIndex, pBuffer);
}

OMX_ERRORTYPE ISVComponent::ISV_FreeBuffer(
    OMX_IN  OMX_U32 nPortIndex,
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: pBuffer %p", __func__, pBuffer);

    if(mVPPEnabled && mVPPOn
            && nPortIndex == kPortIndexOutput) {
        if (mISVBufferManager != NULL && OK != mISVBufferManager->freeBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer)))
            ALOGW("%s: pBuffer %p has not been registered into ISV", __func__, pBuffer);
    }
    return OMX_FreeBuffer(mComponent, nPortIndex, pBuffer);
}

OMX_ERRORTYPE ISVComponent::EmptyThisBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_EmptyThisBuffer(pBuffer);
}

OMX_ERRORTYPE ISVComponent::ISV_EmptyThisBuffer(
    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: pBuffer %p", __func__, pBuffer);

    return OMX_EmptyThisBuffer(mComponent, pBuffer);
}

OMX_ERRORTYPE ISVComponent::FillThisBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry.", __func__);
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_FillThisBuffer(pBuffer);
}

OMX_ERRORTYPE ISVComponent::ISV_FillThisBuffer(
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    if(!mVPPEnabled || !mVPPOn)
        return OMX_FillThisBuffer(mComponent, pBuffer);

    ISVBuffer* isvBuffer = NULL;

    if (mISVBufferManager != NULL) {
        isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer));
        if (isvBuffer == NULL) {
            ALOGE("%s: failed to map ISVBuffer, set mVPPEnabled -->false", __func__);
            mVPPEnabled = false;
            return OMX_FillThisBuffer(mComponent, pBuffer);
        }

        if (OK != isvBuffer->initBufferInfo(mHackFormat)) {
            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: isvBuffer %p failed to initBufferInfo", __func__, isvBuffer);
            mVPPEnabled = false;
            return OMX_FillThisBuffer(mComponent, pBuffer);
        }
    }

    if (mNumDecoderBuffers > 0) {
        Mutex::Autolock autoLock(mDecoderBufLock);
        mNumDecoderBuffers--;
        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: fill pBuffer %p to the decoder, decoder still need extra %d buffers", __func__,
                pBuffer, mNumDecoderBuffers);

        if (isvBuffer != NULL)
            isvBuffer->clearIfNeed();

        return OMX_FillThisBuffer(mComponent, pBuffer);
    }
    mProcThread->addOutput(pBuffer);

    return OMX_ErrorNone;
}

OMX_ERRORTYPE ISVComponent::FillBufferDone(
        OMX_OUT OMX_HANDLETYPE hComponent,
        OMX_OUT OMX_PTR pAppData,
        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry. ISV component num %d, component handle %p on index 0", __func__,
            g_isv_components.size(),
            g_isv_components.itemAt(0));
    for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
        if (static_cast<OMX_HANDLETYPE>(g_isv_components.itemAt(i)->mComponent) == hComponent)
            return g_isv_components.itemAt(i)->ISV_FillBufferDone(hComponent, pAppData, pBuffer);
    }
    return OMX_ErrorUndefined;
}

OMX_ERRORTYPE ISVComponent::ISV_FillBufferDone(
        OMX_OUT OMX_HANDLETYPE __maybe_unused hComponent,
        OMX_OUT OMX_PTR pAppData,
        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: %p <== buffer_handle_t %p. mVPPEnabled %d, mVPPOn %d", __func__,
            pBuffer, pBuffer->pBuffer, mVPPEnabled, mVPPOn);
    if (!mpCallBacks) {
        ALOGE("%s: no call back functions were registered.", __func__);
        return OMX_ErrorUndefined;
    }

    if(!mVPPEnabled || !mVPPOn || mVPPFlushing || (pBuffer->nFilledLen == 0 && !(pBuffer->nFlags & OMX_BUFFERFLAG_EOS))) {
        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3);
        return mpCallBacks->FillBufferDone(&mBaseComponent, pAppData, pBuffer);
    }

    if (mOutputCropChanged && mISVBufferManager != NULL) {
        ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer));
        if (isvBuffer != NULL)
            isvBuffer->setFlag(ISVBuffer::ISV_BUFFER_CROP_CHANGED);
        mOutputCropChanged = false;
    }

    if ((mWidth > FLUSH_WIDTH) && (mHeight > FLUSH_HEIGHT) &&
        (pBuffer->nFilledLen != 0) && (mOutputDecoderBufferNum < OUTPUT_STARTUP_DEC_BUF_NUM)) {
        Mutex::Autolock autoLock(mDecoderBufLock);
        // take one buffer from decoder loop here. Fill one buffer to the loop by mNumDecoderBuffers++
        mNumDecoderBuffers++;
        mOutputDecoderBufferNum++;
        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: return %d decoder output Buffer, mNumDecoderBuffers get %d input buffer",
                __func__, mOutputDecoderBufferNum, mNumDecoderBuffers);
        return mpCallBacks->FillBufferDone(&mBaseComponent, pAppData, pBuffer);
    }

    mProcThread->addInput(pBuffer);

    return OMX_ErrorNone;
}

OMX_ERRORTYPE ISVComponent::EventHandler(
        OMX_IN OMX_HANDLETYPE hComponent,
        OMX_IN OMX_PTR pAppData,
        OMX_IN OMX_EVENTTYPE eEvent,
        OMX_IN OMX_U32 nData1,
        OMX_IN OMX_U32 nData2,
        OMX_IN OMX_PTR pEventData)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry. ISV component num %d, component handle %p on index 0", __func__,
            g_isv_components.size(),
            g_isv_components.itemAt(0));
    for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
        if (static_cast<OMX_HANDLETYPE>(g_isv_components.itemAt(i)->mComponent) == hComponent)
            return g_isv_components.itemAt(i)->ISV_EventHandler(hComponent, pAppData, eEvent, nData1, nData2, pEventData);
    }
    return OMX_ErrorUndefined;
}

OMX_ERRORTYPE ISVComponent::ISV_EventHandler(
        OMX_IN OMX_HANDLETYPE __maybe_unused hComponent,
        OMX_IN OMX_PTR pAppData,
        OMX_IN OMX_EVENTTYPE eEvent,
        OMX_IN OMX_U32 nData1,
        OMX_IN OMX_U32 nData2,
        OMX_IN OMX_PTR pEventData)
{
    if (!mpCallBacks) {
        ALOGE("%s: no call back functions were registered.", __func__);
        return OMX_ErrorUndefined;
    }

    if(!mVPPEnabled || !mVPPOn)
        return mpCallBacks->EventHandler(&mBaseComponent, pAppData, eEvent, nData1, nData2, pEventData);

    switch (eEvent) {
        case OMX_EventCmdComplete:
        {
            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: OMX_EventCmdComplete Cmd type 0x%08x, data2 %d", __func__,
                    nData1, nData2);
            if (((OMX_COMMANDTYPE)nData1 == OMX_CommandFlush && (nData2 == kPortIndexOutput || nData2 == OMX_ALL))
                || ((OMX_COMMANDTYPE)nData1 == OMX_CommandStateSet && nData2 == OMX_StateIdle)
                || ((OMX_COMMANDTYPE)nData1 == OMX_CommandPortDisable && nData2 == 1)) {
                mProcThread->waitFlushFinished();
                mVPPFlushing = false;
                mNumDecoderBuffers = mNumDecoderBuffersBak;
                mOutputDecoderBufferNum = 0;
            }
            break;
        }

        case OMX_EventError:
        {
            //do we need do anything here?
            ALOGE("%s: ERROR(0x%08x, %d)", __func__, nData1, nData2);
            //mProcThread->flush();
            break;
        }

        case OMX_EventPortSettingsChanged:
        {
            if (nData1 == kPortIndexOutput && nData2 == OMX_IndexConfigCommonOutputCrop) {
                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: output crop changed", __func__);
                mOutputCropChanged = true;
                return OMX_ErrorNone;
            } else if (nData1 == kPortIndexOutput && nData2 == OMX_IndexParamPortDefinition) {
                ALOGI("%s: output format changed. ISV flush buffers", __func__);
                mProcThread->notifyFlush();
            }
            break;
        }

        default:
        {
            ALOGD_IF(
                ISV_COMPONENT_DEBUG, "%s: EVENT(%d, %" PRId32 ", %" PRId32 ")",
                __func__, eEvent, nData1, nData2);
            break;
        }
    }
    return mpCallBacks->EventHandler(&mBaseComponent, pAppData, eEvent, nData1, nData2, pEventData);
}

OMX_ERRORTYPE ISVComponent::SetCallbacks(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
    OMX_IN  OMX_PTR pAppData)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_SetCallbacks(pCallbacks, pAppData);
}

OMX_ERRORTYPE ISVComponent::ISV_SetCallbacks(
    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
    OMX_IN  OMX_PTR pAppData)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);

    if (mVPPEnabled && mVPPOn) {
        if (mpISVCallBacks == NULL) {
            mpISVCallBacks = (OMX_CALLBACKTYPE *)calloc(1, sizeof(OMX_CALLBACKTYPE));
            if (!mpISVCallBacks) {
                ALOGE("%s: failed to alloc isv callbacks", __func__);
                return OMX_ErrorUndefined;
            }
        }
        mpISVCallBacks->EventHandler = EventHandler;
        mpISVCallBacks->EmptyBufferDone = pCallbacks->EmptyBufferDone;
        mpISVCallBacks->FillBufferDone = FillBufferDone;
        mpCallBacks = pCallbacks;
        return mComponent->SetCallbacks(mComponent, mpISVCallBacks, pAppData);
    }
    return mComponent->SetCallbacks(mComponent, pCallbacks, pAppData);
}

OMX_ERRORTYPE ISVComponent::ComponentRoleEnum(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_OUT OMX_U8 *cRole,
    OMX_IN OMX_U32 nIndex)
{
    GET_ISVOMX_COMPONENT(hComponent);

    return pComp->ISV_ComponentRoleEnum(cRole, nIndex);
}

OMX_ERRORTYPE ISVComponent::ISV_ComponentRoleEnum(
    OMX_OUT OMX_U8 *cRole,
    OMX_IN OMX_U32 nIndex)
{
    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);

    return mComponent->ComponentRoleEnum(mComponent, cRole, nIndex);
}


void ISVComponent::SetTypeHeader(OMX_PTR type, OMX_U32 size)
{
    OMX_U32 *nsize;
    OMX_VERSIONTYPE *nversion;

    if (!type)
        return;

    nsize = (OMX_U32 *)type;
    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));

    *nsize = size;
    nversion->nVersion = OMX_SPEC_VERSION;
}


ISVProcThreadObserver::ISVProcThreadObserver(
        OMX_COMPONENTTYPE *pBaseComponent,
        OMX_COMPONENTTYPE *pComponent,
        OMX_CALLBACKTYPE *pCallBacks,
        sp<ISVBufferManager> bufferManager)
    :   mBaseComponent(pBaseComponent),
        mComponent(pComponent),
        mpCallBacks(pCallBacks),
        mISVBufferManager(bufferManager)
{
    ALOGV("VPPProcThreadObserver!");
}

ISVProcThreadObserver::~ISVProcThreadObserver()
{
    ALOGV("~VPPProcThreadObserver!");
    mBaseComponent = NULL;
    mComponent = NULL;
    mpCallBacks = NULL;
}

OMX_ERRORTYPE ISVProcThreadObserver::releaseBuffer(PORT_INDEX index, OMX_BUFFERHEADERTYPE* pBuffer, bool bFLush)
{
    if (!mBaseComponent || !mComponent || !mpCallBacks)
        return OMX_ErrorUndefined;

    OMX_ERRORTYPE err = OMX_ErrorNone;
    if (bFLush) {
        if(index == kPortIndexOutput) {
            pBuffer->nFilledLen = 0;
            pBuffer->nOffset = 0;
            pBuffer->nTimeStamp = 0;
            pBuffer->nFlags = 0;
        }
        err = mpCallBacks->FillBufferDone(&mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer);
        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: flush pBuffer %p", __func__, pBuffer);
        return err;
    }

    if (index == kPortIndexInput) {
        pBuffer->nFilledLen = 0;
        pBuffer->nOffset = 0;
        pBuffer->nFlags = 0;
        pBuffer->nTimeStamp = 0;

        if (mISVBufferManager != NULL) {
            ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer));
            if (isvBuffer != NULL)
                isvBuffer->clearIfNeed();
        }

        err = OMX_FillThisBuffer(mComponent, pBuffer);
        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBuffer pBuffer %p", __func__, pBuffer);
    } else {
        err = mpCallBacks->FillBufferDone(&mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer);
        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3);
    }

    return err;
}

OMX_ERRORTYPE ISVProcThreadObserver::reportOutputCrop()
{
    if (!mBaseComponent || !mComponent || !mpCallBacks)
        return OMX_ErrorUndefined;

    OMX_ERRORTYPE err = OMX_ErrorNone;
    err = mpCallBacks->EventHandler(&mBaseComponent, mBaseComponent->pApplicationPrivate,
                                    OMX_EventPortSettingsChanged,
                                    kPortIndexOutput, OMX_IndexConfigCommonOutputCrop, NULL);
    return err;
}
