/*
 INTEL CONFIDENTIAL
 Copyright 2011 Intel Corporation All Rights Reserved.
 The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.

 No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
 */
#include <string.h>
#include "VideoEncoderLog.h"
#include "VideoEncoderBase.h"
#include "IntelMetadataBuffer.h"
#include <va/va_tpi.h>
#include <va/va_android.h>

VideoEncoderBase::VideoEncoderBase()
    :mInitialized(true)
    ,mStarted(false)
    ,mVADisplay(NULL)
    ,mVAContext(VA_INVALID_ID)
    ,mVAConfig(VA_INVALID_ID)
    ,mVAEntrypoint(VAEntrypointEncSlice)
    ,mCodedBufSize(0)
    ,mNewHeader(false)
    ,mRenderMaxSliceSize(false)
    ,mRenderQP (false)
    ,mRenderAIR(false)
    ,mRenderCIR(false)
    ,mRenderFrameRate(false)
    ,mRenderBitRate(false)
    ,mRenderHrd(false)
    ,mRenderMultiTemporal(false)
    ,mForceKFrame(false)
    ,mSeqParamBuf(0)
    ,mPicParamBuf(0)
    ,mSliceParamBuf(0)
    ,mRefSurface(VA_INVALID_SURFACE)
    ,mRecSurface(VA_INVALID_SURFACE)
    ,mAutoRefSurfaces(NULL)
    ,mFrameNum(0)
    ,mAutoReference(false)
    ,mAutoReferenceSurfaceNum(4)
    ,mSliceSizeOverflow(false)
    ,mCurOutputTask(NULL)
    ,mOutCodedBuffer(0)
    ,mOutCodedBufferPtr(NULL)
    ,mCurSegment(NULL)
    ,mOffsetInSeg(0)
    ,mTotalSize(0)
    ,mTotalSizeCopied(0)
    ,mFrameSkipped(false)
    ,mSupportedSurfaceMemType(0)
    ,mVASurfaceMappingAction(0)
    ,mEncPackedHeaders(VA_ATTRIB_NOT_SUPPORTED)
#ifdef INTEL_VIDEO_XPROC_SHARING
    ,mSessionFlag(0)
#endif
    {

    VAStatus vaStatus = VA_STATUS_SUCCESS;
    // here the display can be any value, use following one
    // just for consistence purpose, so don't define it
    unsigned int display = 0x18C34078;
    int majorVersion = -1;
    int minorVersion = -1;

    setDefaultParams();

    LOG_V("vaGetDisplay \n");
    mVADisplay = vaGetDisplay(&display);
    if (mVADisplay == NULL) {
        LOG_E("vaGetDisplay failed.");
    }

    vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion);
    LOG_V("vaInitialize \n");
    if (vaStatus != VA_STATUS_SUCCESS) {
        LOG_E( "Failed vaInitialize, vaStatus = %d\n", vaStatus);
        mInitialized = false;
    }
}

VideoEncoderBase::~VideoEncoderBase() {

    VAStatus vaStatus = VA_STATUS_SUCCESS;

    stop();

    vaStatus = vaTerminate(mVADisplay);
    LOG_V( "vaTerminate\n");
    if (vaStatus != VA_STATUS_SUCCESS) {
        LOG_W( "Failed vaTerminate, vaStatus = %d\n", vaStatus);
    } else {
        mVADisplay = NULL;
    }

#ifdef INTEL_VIDEO_XPROC_SHARING
    IntelMetadataBuffer::ClearContext(mSessionFlag, false);
#endif
}

Encode_Status VideoEncoderBase::start() {

    Encode_Status ret = ENCODE_SUCCESS;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    if (!mInitialized) {
        LOGE("Encoder Initialize fail can not start");
        return ENCODE_DRIVER_FAIL;
    }

    if (mStarted) {
        LOG_V("Encoder has been started\n");
        return ENCODE_ALREADY_INIT;
    }

    if (mComParams.rawFormat != RAW_FORMAT_NV12)
#ifdef IMG_GFX
        mVASurfaceMappingAction |= MAP_ACTION_COLORCONVERT;
#else
        return ENCODE_NOT_SUPPORTED;
#endif

    queryAutoReferenceConfig(mComParams.profile);

    VAConfigAttrib vaAttrib_tmp[6],vaAttrib[VAConfigAttribTypeMax];
    int vaAttribNumber = 0;
    vaAttrib_tmp[0].type = VAConfigAttribRTFormat;
    vaAttrib_tmp[1].type = VAConfigAttribRateControl;
    vaAttrib_tmp[2].type = VAConfigAttribEncAutoReference;
    vaAttrib_tmp[3].type = VAConfigAttribEncPackedHeaders;
    vaAttrib_tmp[4].type = VAConfigAttribEncMaxRefFrames;
    vaAttrib_tmp[5].type = VAConfigAttribEncRateControlExt;

    vaStatus = vaGetConfigAttributes(mVADisplay, mComParams.profile,
            VAEntrypointEncSlice, &vaAttrib_tmp[0], 6);
    CHECK_VA_STATUS_RETURN("vaGetConfigAttributes");

    if((vaAttrib_tmp[0].value & VA_RT_FORMAT_YUV420) != 0)
    {
        vaAttrib[vaAttribNumber].type = VAConfigAttribRTFormat;
        vaAttrib[vaAttribNumber].value = VA_RT_FORMAT_YUV420;
        vaAttribNumber++;
    }

    vaAttrib[vaAttribNumber].type = VAConfigAttribRateControl;
    vaAttrib[vaAttribNumber].value = mComParams.rcMode;
    vaAttribNumber++;

    vaAttrib[vaAttribNumber].type = VAConfigAttribEncAutoReference;
    vaAttrib[vaAttribNumber].value = mAutoReference ? 1 : VA_ATTRIB_NOT_SUPPORTED;
    vaAttribNumber++;

    if(vaAttrib_tmp[3].value != VA_ATTRIB_NOT_SUPPORTED)
    {
        vaAttrib[vaAttribNumber].type = VAConfigAttribEncPackedHeaders;
        vaAttrib[vaAttribNumber].value = vaAttrib[3].value;
        vaAttribNumber++;
        mEncPackedHeaders = vaAttrib[3].value;
    }

    if(vaAttrib_tmp[4].value != VA_ATTRIB_NOT_SUPPORTED)
    {
        vaAttrib[vaAttribNumber].type = VAConfigAttribEncMaxRefFrames;
        vaAttrib[vaAttribNumber].value = vaAttrib[4].value;
        vaAttribNumber++;
        mEncMaxRefFrames = vaAttrib[4].value;
    }

    if(vaAttrib_tmp[5].value != VA_ATTRIB_NOT_SUPPORTED)
    {
        vaAttrib[vaAttribNumber].type = VAConfigAttribEncRateControlExt;
        vaAttrib[vaAttribNumber].value = mComParams.numberOfLayer;
        vaAttribNumber++;
    }

    LOG_V( "======VA Configuration======\n");
    LOG_I( "profile = %d\n", mComParams.profile);
    LOG_I( "mVAEntrypoint = %d\n", mVAEntrypoint);
    LOG_I( "vaAttrib[0].type = %d\n", vaAttrib[0].type);
    LOG_I( "vaAttrib[1].type = %d\n", vaAttrib[1].type);
    LOG_I( "vaAttrib[2].type = %d\n", vaAttrib[2].type);
    LOG_I( "vaAttrib[0].value (Format) = %d\n", vaAttrib[0].value);
    LOG_I( "vaAttrib[1].value (RC mode) = %d\n", vaAttrib[1].value);
    LOG_I( "vaAttrib[2].value (AutoReference) = %d\n", vaAttrib[2].value);
    LOG_I( "vaAttribNumber is %d\n", vaAttribNumber);
    LOG_I( "mComParams.numberOfLayer is %d\n", mComParams.numberOfLayer);

    LOG_V( "vaCreateConfig\n");

    vaStatus = vaCreateConfig(
            mVADisplay, mComParams.profile, mVAEntrypoint,
            &vaAttrib[0], vaAttribNumber, &(mVAConfig));
//            &vaAttrib[0], 3, &(mVAConfig));  //uncomment this after psb_video supports
    CHECK_VA_STATUS_RETURN("vaCreateConfig");

    querySupportedSurfaceMemTypes();

    if (mComParams.rcMode == VA_RC_VCM) {
        // Following three features are only enabled in VCM mode
        mRenderMaxSliceSize = true;
        mRenderAIR = true;
        mRenderBitRate = true;
    }

    LOG_V( "======VA Create Surfaces for Rec/Ref frames ======\n");

    uint32_t stride_aligned, height_aligned;
    if(mAutoReference == false){
        stride_aligned = (mComParams.resolution.width + 15) & ~15;
        height_aligned = (mComParams.resolution.height + 15) & ~15;
    }else{
        // this alignment is used for AVC. For vp8 encode, driver will handle the alignment
        if(mComParams.profile == VAProfileVP8Version0_3)
        {
            stride_aligned = mComParams.resolution.width;
            height_aligned = mComParams.resolution.height;
            mVASurfaceMappingAction |= MAP_ACTION_COPY;
        }
        else
        {
            stride_aligned = (mComParams.resolution.width + 63) & ~63;  //on Merr, stride must be 64 aligned.
            height_aligned = (mComParams.resolution.height + 31) & ~31;
            mVASurfaceMappingAction |= MAP_ACTION_ALIGN64;
        }
    }

    if(mAutoReference == false){
        mRefSurface = CreateNewVASurface(mVADisplay, stride_aligned, height_aligned);
        mRecSurface = CreateNewVASurface(mVADisplay, stride_aligned, height_aligned);

    }else {
        mAutoRefSurfaces = new VASurfaceID [mAutoReferenceSurfaceNum];
        for(int i = 0; i < mAutoReferenceSurfaceNum; i ++)
            mAutoRefSurfaces[i] = CreateNewVASurface(mVADisplay, stride_aligned, height_aligned);
    }
    CHECK_VA_STATUS_RETURN("vaCreateSurfaces");

    //Prepare all Surfaces to be added into Context
    uint32_t contextSurfaceCnt;
    if(mAutoReference == false )
        contextSurfaceCnt = 2 + mSrcSurfaceMapList.size();
    else
        contextSurfaceCnt = mAutoReferenceSurfaceNum + mSrcSurfaceMapList.size();

    VASurfaceID *contextSurfaces = new VASurfaceID[contextSurfaceCnt];
    int32_t index = -1;
    android::List<VASurfaceMap *>::iterator map_node;

    for(map_node = mSrcSurfaceMapList.begin(); map_node !=  mSrcSurfaceMapList.end(); map_node++)
    {
        contextSurfaces[++index] = (*map_node)->getVASurface();
        (*map_node)->setTracked();
    }

    if(mAutoReference == false){
        contextSurfaces[++index] = mRefSurface;
        contextSurfaces[++index] = mRecSurface;
    } else {
        for (int i=0; i < mAutoReferenceSurfaceNum; i++)
            contextSurfaces[++index] = mAutoRefSurfaces[i];
    }

    //Initialize and save the VA context ID
    LOG_V( "vaCreateContext\n");
    vaStatus = vaCreateContext(mVADisplay, mVAConfig,
#ifdef IMG_GFX
            mComParams.resolution.width,
            mComParams.resolution.height,
#else
            stride_aligned,
            height_aligned,
#endif
            VA_PROGRESSIVE, contextSurfaces, contextSurfaceCnt,
            &(mVAContext));
    CHECK_VA_STATUS_RETURN("vaCreateContext");

    delete [] contextSurfaces;

    LOG_I("Success to create libva context width %d, height %d\n",
          mComParams.resolution.width, mComParams.resolution.height);

    uint32_t maxSize = 0;
    ret = getMaxOutSize(&maxSize);
    CHECK_ENCODE_STATUS_RETURN("getMaxOutSize");

    // Create CodedBuffer for output
    VABufferID VACodedBuffer;

    for(uint32_t i = 0; i <mComParams.codedBufNum; i++) {
            vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
                    VAEncCodedBufferType,
                    mCodedBufSize,
                    1, NULL,
                    &VACodedBuffer);
            CHECK_VA_STATUS_RETURN("vaCreateBuffer::VAEncCodedBufferType");

            mVACodedBufferList.push_back(VACodedBuffer);
    }

    if (ret == ENCODE_SUCCESS)
        mStarted = true;

    LOG_V( "end\n");
    return ret;
}

Encode_Status VideoEncoderBase::encode(VideoEncRawBuffer *inBuffer, uint32_t timeout) {

    Encode_Status ret = ENCODE_SUCCESS;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    if (!mStarted) {
        LOG_E("Encoder has not initialized yet\n");
        return ENCODE_NOT_INIT;
    }

    CHECK_NULL_RETURN_IFFAIL(inBuffer);

    //======Prepare all resources encoder needed=====.

    //Prepare encode vaSurface
    VASurfaceID sid = VA_INVALID_SURFACE;
    ret = manageSrcSurface(inBuffer, &sid);
    CHECK_ENCODE_STATUS_RETURN("manageSrcSurface");

    //Prepare CodedBuffer
    mCodedBuffer_Lock.lock();
    if(mVACodedBufferList.empty()){
        if(timeout == FUNC_BLOCK)
            mCodedBuffer_Cond.wait(mCodedBuffer_Lock);
        else if (timeout > 0)
            if(NO_ERROR != mEncodeTask_Cond.waitRelative(mCodedBuffer_Lock, 1000000*timeout)){
                mCodedBuffer_Lock.unlock();
                LOG_E("Time out wait for Coded buffer.\n");
                return ENCODE_DEVICE_BUSY;
            }
        else {//Nonblock
            mCodedBuffer_Lock.unlock();
            LOG_E("Coded buffer is not ready now.\n");
            return ENCODE_DEVICE_BUSY;
        }
    }

    if(mVACodedBufferList.empty()){
        mCodedBuffer_Lock.unlock();
        return ENCODE_DEVICE_BUSY;
    }
    VABufferID coded_buf = (VABufferID) *(mVACodedBufferList.begin());
    mVACodedBufferList.erase(mVACodedBufferList.begin());
    mCodedBuffer_Lock.unlock();

    LOG_V("CodedBuffer ID 0x%08x\n", coded_buf);

    //All resources are ready, start to assemble EncodeTask
    EncodeTask* task = new EncodeTask();

    task->completed = false;
    task->enc_surface = sid;
    task->coded_buffer = coded_buf;
    task->timestamp = inBuffer->timeStamp;
    task->priv = inBuffer->priv;

    //Setup frame info, like flag ( SYNCFRAME), frame number, type etc
    task->type = inBuffer->type;
    task->flag = inBuffer->flag;
    PrepareFrameInfo(task);

    if(mAutoReference == false){
        //Setup ref /rec frames
        //TODO: B frame support, temporary use same logic
        switch (inBuffer->type) {
            case FTYPE_UNKNOWN:
            case FTYPE_IDR:
            case FTYPE_I:
            case FTYPE_P:
            {
                if(!mFrameSkipped) {
                    VASurfaceID tmpSurface = mRecSurface;
                    mRecSurface = mRefSurface;
                    mRefSurface = tmpSurface;
                }

                task->ref_surface = mRefSurface;
                task->rec_surface = mRecSurface;

                break;
            }
            case FTYPE_B:
            default:
                LOG_V("Something wrong, B frame may not be supported in this mode\n");
                ret = ENCODE_NOT_SUPPORTED;
                goto CLEAN_UP;
        }
    }else {
        task->ref_surface = VA_INVALID_SURFACE;
        task->rec_surface = VA_INVALID_SURFACE;
    }
    //======Start Encoding, add task to list======
    LOG_V("Start Encoding vaSurface=0x%08x\n", task->enc_surface);

    vaStatus = vaBeginPicture(mVADisplay, mVAContext, task->enc_surface);
    CHECK_VA_STATUS_GOTO_CLEANUP("vaBeginPicture");

    ret = sendEncodeCommand(task);
    CHECK_ENCODE_STATUS_CLEANUP("sendEncodeCommand");

    vaStatus = vaEndPicture(mVADisplay, mVAContext);
    CHECK_VA_STATUS_GOTO_CLEANUP("vaEndPicture");

    LOG_V("Add Task %p into Encode Task list\n", task);
    mEncodeTask_Lock.lock();
    mEncodeTaskList.push_back(task);
    mEncodeTask_Cond.signal();
    mEncodeTask_Lock.unlock();

    mFrameNum ++;

    LOG_V("encode return Success\n");

    return ENCODE_SUCCESS;

CLEAN_UP:

    delete task;
    mCodedBuffer_Lock.lock();
    mVACodedBufferList.push_back(coded_buf); //push to CodedBuffer pool again since it is not used
    mCodedBuffer_Cond.signal();
    mCodedBuffer_Lock.unlock();

    LOG_V("encode return error=%x\n", ret);

    return ret;
}

/*
  1. Firstly check if one task is outputting data, if yes, continue outputting, if not try to get one from list.
  2. Due to block/non-block/block with timeout 3 modes, if task is not completed, then sync surface, if yes,
    start output data
  3. Use variable curoutputtask to record task which is getOutput() working on to avoid push again when get failure
    on non-block/block with timeout modes.
  4. if complete all output data, curoutputtask should be set NULL
*/
Encode_Status VideoEncoderBase::getOutput(VideoEncOutputBuffer *outBuffer, uint32_t timeout) {

    Encode_Status ret = ENCODE_SUCCESS;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    bool useLocalBuffer = false;

    CHECK_NULL_RETURN_IFFAIL(outBuffer);

    if (mCurOutputTask == NULL) {
        mEncodeTask_Lock.lock();
        if(mEncodeTaskList.empty()) {
            LOG_V("getOutput CurrentTask is NULL\n");
            if(timeout == FUNC_BLOCK) {
                LOG_V("waiting for task....\n");
                mEncodeTask_Cond.wait(mEncodeTask_Lock);
            } else if (timeout > 0) {
                LOG_V("waiting for task in % ms....\n", timeout);
                if(NO_ERROR != mEncodeTask_Cond.waitRelative(mEncodeTask_Lock, 1000000*timeout)) {
                    mEncodeTask_Lock.unlock();
                    LOG_E("Time out wait for encode task.\n");
                    return ENCODE_NO_REQUEST_DATA;
                }
            } else {//Nonblock
                mEncodeTask_Lock.unlock();
                return ENCODE_NO_REQUEST_DATA;
            }
        }

        if(mEncodeTaskList.empty()){
            mEncodeTask_Lock.unlock();
            return ENCODE_DATA_NOT_READY;
        }
        mCurOutputTask =  *(mEncodeTaskList.begin());
        mEncodeTaskList.erase(mEncodeTaskList.begin());
        mEncodeTask_Lock.unlock();
    }

    //sync/query/wait task if not completed
    if (mCurOutputTask->completed == false) {
        VASurfaceStatus vaSurfaceStatus;

        if (timeout == FUNC_BLOCK) {
            //block mode, direct sync surface to output data

            mOutCodedBuffer = mCurOutputTask->coded_buffer;

            // Check frame skip
            // Need encoding to be completed before calling query surface below to
            // get the right skip frame flag for current frame
            // It is a requirement of video driver
            // vaSyncSurface syncs the wrong frame when rendering the same surface multiple times,
            // so use vaMapbuffer instead
            LOG_I ("block mode, vaMapBuffer ID = 0x%08x\n", mOutCodedBuffer);
            if (mOutCodedBufferPtr == NULL) {
                vaStatus = vaMapBuffer (mVADisplay, mOutCodedBuffer, (void **)&mOutCodedBufferPtr);
                CHECK_VA_STATUS_GOTO_CLEANUP("vaMapBuffer");
                CHECK_NULL_RETURN_IFFAIL(mOutCodedBufferPtr);
            }

            vaStatus = vaQuerySurfaceStatus(mVADisplay, mCurOutputTask->enc_surface,  &vaSurfaceStatus);
            CHECK_VA_STATUS_RETURN("vaQuerySurfaceStatus");
            mFrameSkipped = vaSurfaceStatus & VASurfaceSkipped;

            mCurOutputTask->completed = true;

        } else {
            //For both block with timeout and non-block mode, query surface, if ready, output data
            LOG_I ("non-block mode, vaQuerySurfaceStatus ID = 0x%08x\n", mCurOutputTask->enc_surface);

            vaStatus = vaQuerySurfaceStatus(mVADisplay, mCurOutputTask->enc_surface,  &vaSurfaceStatus);
            if (vaSurfaceStatus & VASurfaceReady) {
                mOutCodedBuffer = mCurOutputTask->coded_buffer;
                mFrameSkipped = vaSurfaceStatus & VASurfaceSkipped;
                mCurOutputTask->completed = true;
                //if need to call SyncSurface again ?

            }  else {//not encode complet yet, but keep all context and return directly
                return ENCODE_DATA_NOT_READY;
            }

        }

    }

    //start to output data
    ret = prepareForOutput(outBuffer, &useLocalBuffer);
    CHECK_ENCODE_STATUS_CLEANUP("prepareForOutput");

    //copy all flags to outBuffer
    outBuffer->offset = 0;
    outBuffer->flag = mCurOutputTask->flag;
    outBuffer->type = mCurOutputTask->type;
    outBuffer->timeStamp = mCurOutputTask->timestamp;
    outBuffer->priv = mCurOutputTask->priv;

    if (outBuffer->format == OUTPUT_EVERYTHING || outBuffer->format == OUTPUT_FRAME_DATA) {
        ret = outputAllData(outBuffer);
        CHECK_ENCODE_STATUS_CLEANUP("outputAllData");
    }else {
        ret = getExtFormatOutput(outBuffer);
        CHECK_ENCODE_STATUS_CLEANUP("getExtFormatOutput");
    }

    LOG_I("out size for this getOutput call = %d\n", outBuffer->dataSize);

    ret = cleanupForOutput();
    CHECK_ENCODE_STATUS_CLEANUP("cleanupForOutput");

    LOG_V("getOutput return Success, Frame skip is %d\n", mFrameSkipped);

    return ENCODE_SUCCESS;

CLEAN_UP:

    if (outBuffer->data && (useLocalBuffer == true)) {
        delete[] outBuffer->data;
        outBuffer->data = NULL;
        useLocalBuffer = false;
    }

    if (mOutCodedBufferPtr != NULL) {
        vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
        mOutCodedBufferPtr = NULL;
        mCurSegment = NULL;
    }

    delete mCurOutputTask;
    mCurOutputTask = NULL;
    mCodedBuffer_Lock.lock();
    mVACodedBufferList.push_back(mOutCodedBuffer);
    mCodedBuffer_Cond.signal();
    mCodedBuffer_Lock.unlock();

    LOG_V("getOutput return error=%x\n", ret);
    return ret;
}

void VideoEncoderBase::flush() {

    LOG_V( "Begin\n");

    // reset the properities
    mFrameNum = 0;

    LOG_V( "end\n");
}

Encode_Status VideoEncoderBase::stop() {

    VAStatus vaStatus = VA_STATUS_SUCCESS;
    Encode_Status ret = ENCODE_SUCCESS;

    LOG_V( "Begin\n");

    // It is possible that above pointers have been allocated
    // before we set mStarted to true
    if (!mStarted) {
        LOG_V("Encoder has been stopped\n");
        return ENCODE_SUCCESS;
    }
    if (mAutoRefSurfaces) {
        delete[] mAutoRefSurfaces;
        mAutoRefSurfaces = NULL;
    }

    mCodedBuffer_Lock.lock();
    mVACodedBufferList.clear();
    mCodedBuffer_Lock.unlock();
    mCodedBuffer_Cond.broadcast();

    //Delete all uncompleted tasks
    mEncodeTask_Lock.lock();
    while(! mEncodeTaskList.empty())
    {
        delete *mEncodeTaskList.begin();
        mEncodeTaskList.erase(mEncodeTaskList.begin());
    }
    mEncodeTask_Lock.unlock();
    mEncodeTask_Cond.broadcast();

    //Release Src Surface Buffer Map, destroy surface manually since it is not added into context
    LOG_V( "Rlease Src Surface Map\n");
    while(! mSrcSurfaceMapList.empty())
    {
        delete (*mSrcSurfaceMapList.begin());
        mSrcSurfaceMapList.erase(mSrcSurfaceMapList.begin());
    }

    LOG_V( "vaDestroyContext\n");
    if (mVAContext != VA_INVALID_ID) {
        vaStatus = vaDestroyContext(mVADisplay, mVAContext);
        CHECK_VA_STATUS_GOTO_CLEANUP("vaDestroyContext");
    }

    LOG_V( "vaDestroyConfig\n");
    if (mVAConfig != VA_INVALID_ID) {
        vaStatus = vaDestroyConfig(mVADisplay, mVAConfig);
        CHECK_VA_STATUS_GOTO_CLEANUP("vaDestroyConfig");
    }

CLEAN_UP:

    mStarted = false;
    mSliceSizeOverflow = false;
    mCurOutputTask= NULL;
    mOutCodedBuffer = 0;
    mCurSegment = NULL;
    mOffsetInSeg =0;
    mTotalSize = 0;
    mTotalSizeCopied = 0;
    mFrameSkipped = false;
    mSupportedSurfaceMemType = 0;

    LOG_V( "end\n");
    return ret;
}

Encode_Status VideoEncoderBase::prepareForOutput(
        VideoEncOutputBuffer *outBuffer, bool *useLocalBuffer) {

    VAStatus vaStatus = VA_STATUS_SUCCESS;
    VACodedBufferSegment *vaCodedSeg = NULL;
    uint32_t status = 0;

    LOG_V( "begin\n");
    // Won't check parameters here as the caller already checked them
    // mCurSegment is NULL means it is first time to be here after finishing encoding a frame
    if (mCurSegment == NULL) {
        if (mOutCodedBufferPtr == NULL) {
            vaStatus = vaMapBuffer (mVADisplay, mOutCodedBuffer, (void **)&mOutCodedBufferPtr);
            CHECK_VA_STATUS_RETURN("vaMapBuffer");
            CHECK_NULL_RETURN_IFFAIL(mOutCodedBufferPtr);
        }

        LOG_I ("Coded Buffer ID been mapped = 0x%08x\n", mOutCodedBuffer);

        mTotalSize = 0;
        mOffsetInSeg = 0;
        mTotalSizeCopied = 0;
        vaCodedSeg = (VACodedBufferSegment *)mOutCodedBufferPtr;
        mCurSegment = (VACodedBufferSegment *)mOutCodedBufferPtr;

        while (1) {

            mTotalSize += vaCodedSeg->size;
            status = vaCodedSeg->status;
#ifndef IMG_GFX
            uint8_t *pTemp;
            uint32_t ii;
            pTemp = (uint8_t*)vaCodedSeg->buf;
            for(ii = 0; ii < 16;){
                if (*(pTemp + ii) == 0xFF)
                    ii++;
                else
                    break;
            }
            if (ii > 0) {
                mOffsetInSeg = ii;
            }
#endif
            if (!mSliceSizeOverflow) {
                mSliceSizeOverflow = status & VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
            }

            if (vaCodedSeg->next == NULL)
                break;

            vaCodedSeg = (VACodedBufferSegment *)vaCodedSeg->next;
        }
    }

    // We will support two buffer allocation mode,
    // one is application allocates the buffer and passes to encode,
    // the other is encode allocate memory

    //means  app doesn't allocate the buffer, so _encode will allocate it.
    if (outBuffer->data == NULL) {
        *useLocalBuffer = true;
        outBuffer->data = new  uint8_t[mTotalSize - mTotalSizeCopied + 100];
        if (outBuffer->data == NULL) {
            LOG_E( "outBuffer->data == NULL\n");
            return ENCODE_NO_MEMORY;
        }
        outBuffer->bufferSize = mTotalSize + 100;
        outBuffer->dataSize = 0;
    }

    // Clear all flag for every call
    outBuffer->flag = 0;
    if (mSliceSizeOverflow) outBuffer->flag |= ENCODE_BUFFERFLAG_SLICEOVERFOLOW;

    if (!mCurSegment)
        return ENCODE_FAIL;

    if (mCurSegment->size < mOffsetInSeg) {
        LOG_E("mCurSegment->size < mOffsetInSeg\n");
        return ENCODE_FAIL;
    }

    // Make sure we have data in current segment
    if (mCurSegment->size == mOffsetInSeg) {
        if (mCurSegment->next != NULL) {
            mCurSegment = (VACodedBufferSegment *)mCurSegment->next;
            mOffsetInSeg = 0;
        } else {
            LOG_V("No more data available\n");
            outBuffer->flag |= ENCODE_BUFFERFLAG_DATAINVALID;
            outBuffer->dataSize = 0;
            mCurSegment = NULL;
            return ENCODE_NO_REQUEST_DATA;
        }
    }

    LOG_V( "end\n");
    return ENCODE_SUCCESS;
}

Encode_Status VideoEncoderBase::cleanupForOutput() {

    VAStatus vaStatus = VA_STATUS_SUCCESS;

    //mCurSegment is NULL means all data has been copied out
    if (mCurSegment == NULL && mOutCodedBufferPtr) {
        vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
        CHECK_VA_STATUS_RETURN("vaUnmapBuffer");
        mOutCodedBufferPtr = NULL;
        mTotalSize = 0;
        mOffsetInSeg = 0;
        mTotalSizeCopied = 0;

        delete mCurOutputTask;
        mCurOutputTask = NULL;
        mCodedBuffer_Lock.lock();
        mVACodedBufferList.push_back(mOutCodedBuffer);
        mCodedBuffer_Cond.signal();
        mCodedBuffer_Lock.unlock();

        LOG_V("All data has been outputted, return CodedBuffer 0x%08x to pool\n", mOutCodedBuffer);
    }
    return ENCODE_SUCCESS;
}

Encode_Status VideoEncoderBase::queryProfileLevelConfig(VADisplay dpy, VAProfile profile) {

    VAStatus vaStatus = VA_STATUS_SUCCESS;
    VAEntrypoint entryPtr[8];
    int i, entryPtrNum;

    if(profile ==  VAProfileH264Main) //need to be fixed
        return ENCODE_NOT_SUPPORTED;

    vaStatus = vaQueryConfigEntrypoints(dpy, profile, entryPtr, &entryPtrNum);
    CHECK_VA_STATUS_RETURN("vaQueryConfigEntrypoints");

    for(i=0; i<entryPtrNum; i++){
        if(entryPtr[i] == VAEntrypointEncSlice)
            return ENCODE_SUCCESS;
    }

    return ENCODE_NOT_SUPPORTED;
}

Encode_Status VideoEncoderBase::queryAutoReferenceConfig(VAProfile profile) {

    VAStatus vaStatus = VA_STATUS_SUCCESS;
    VAConfigAttrib attrib_list;
    attrib_list.type = VAConfigAttribEncAutoReference;
    attrib_list.value = VA_ATTRIB_NOT_SUPPORTED;

    vaStatus = vaGetConfigAttributes(mVADisplay, profile, VAEntrypointEncSlice, &attrib_list, 1);
    if(attrib_list.value == VA_ATTRIB_NOT_SUPPORTED )
        mAutoReference = false;
    else
        mAutoReference = true;

    return ENCODE_SUCCESS;
}

Encode_Status VideoEncoderBase::querySupportedSurfaceMemTypes() {

    VAStatus vaStatus = VA_STATUS_SUCCESS;

    unsigned int num = 0;

    VASurfaceAttrib* attribs = NULL;

    //get attribs number
    vaStatus = vaQuerySurfaceAttributes(mVADisplay, mVAConfig, attribs, &num);
    CHECK_VA_STATUS_RETURN("vaGetSurfaceAttributes");

    if (num == 0)
        return ENCODE_SUCCESS;

    attribs = new VASurfaceAttrib[num];

    vaStatus = vaQuerySurfaceAttributes(mVADisplay, mVAConfig, attribs, &num);
    CHECK_VA_STATUS_RETURN("vaGetSurfaceAttributes");

    for(int i = 0; i < num; i ++) {
        if (attribs[i].type == VASurfaceAttribMemoryType) {
            mSupportedSurfaceMemType = attribs[i].value.value.i;
            break;
        }
        else
            continue;
    }

    delete attribs;

    return ENCODE_SUCCESS;
}

Encode_Status VideoEncoderBase::outputAllData(VideoEncOutputBuffer *outBuffer) {

    // Data size been copied for every single call
    uint32_t sizeCopiedHere = 0;
    uint32_t sizeToBeCopied = 0;

    CHECK_NULL_RETURN_IFFAIL(outBuffer->data);

    while (1) {

        LOG_I("mCurSegment->size = %d, mOffsetInSeg = %d\n", mCurSegment->size, mOffsetInSeg);
        LOG_I("outBuffer->bufferSize = %d, sizeCopiedHere = %d, mTotalSizeCopied = %d\n",
              outBuffer->bufferSize, sizeCopiedHere, mTotalSizeCopied);

        if (mCurSegment->size < mOffsetInSeg || outBuffer->bufferSize < sizeCopiedHere) {
            LOG_E("mCurSegment->size < mOffsetInSeg  || outBuffer->bufferSize < sizeCopiedHere\n");
            return ENCODE_FAIL;
        }

        if ((mCurSegment->size - mOffsetInSeg) <= outBuffer->bufferSize - sizeCopiedHere) {
            sizeToBeCopied = mCurSegment->size - mOffsetInSeg;
            memcpy(outBuffer->data + sizeCopiedHere,
                   (uint8_t *)mCurSegment->buf + mOffsetInSeg, sizeToBeCopied);
            sizeCopiedHere += sizeToBeCopied;
            mTotalSizeCopied += sizeToBeCopied;
            mOffsetInSeg = 0;
        } else {
            sizeToBeCopied = outBuffer->bufferSize - sizeCopiedHere;
            memcpy(outBuffer->data + sizeCopiedHere,
                   (uint8_t *)mCurSegment->buf + mOffsetInSeg, outBuffer->bufferSize - sizeCopiedHere);
            mTotalSizeCopied += sizeToBeCopied;
            mOffsetInSeg += sizeToBeCopied;
            outBuffer->dataSize = outBuffer->bufferSize;
            outBuffer->remainingSize = mTotalSize - mTotalSizeCopied;
            outBuffer->flag |= ENCODE_BUFFERFLAG_PARTIALFRAME;
            return ENCODE_BUFFER_TOO_SMALL;
        }

        if (mCurSegment->next == NULL) {
            outBuffer->dataSize = sizeCopiedHere;
            outBuffer->remainingSize = 0;
            outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
            mCurSegment = NULL;
            return ENCODE_SUCCESS;
        }

        mCurSegment = (VACodedBufferSegment *)mCurSegment->next;
        mOffsetInSeg = 0;
    }
}

void VideoEncoderBase::setDefaultParams() {

    // Set default value for input parameters
    mComParams.profile = VAProfileH264Baseline;
    mComParams.level = 41;
    mComParams.rawFormat = RAW_FORMAT_NV12;
    mComParams.frameRate.frameRateNum = 30;
    mComParams.frameRate.frameRateDenom = 1;
    mComParams.resolution.width = 0;
    mComParams.resolution.height = 0;
    mComParams.intraPeriod = 30;
    mComParams.rcMode = RATE_CONTROL_NONE;
    mComParams.rcParams.initQP = 15;
    mComParams.rcParams.minQP = 0;
    mComParams.rcParams.maxQP = 0;
    mComParams.rcParams.I_minQP = 0;
    mComParams.rcParams.I_maxQP = 0;
    mComParams.rcParams.bitRate = 640000;
    mComParams.rcParams.targetPercentage= 0;
    mComParams.rcParams.windowSize = 0;
    mComParams.rcParams.disableFrameSkip = 0;
    mComParams.rcParams.disableBitsStuffing = 1;
    mComParams.rcParams.enableIntraFrameQPControl = 0;
    mComParams.rcParams.temporalFrameRate = 0;
    mComParams.rcParams.temporalID = 0;
    mComParams.cyclicFrameInterval = 30;
    mComParams.refreshType = VIDEO_ENC_NONIR;
    mComParams.airParams.airMBs = 0;
    mComParams.airParams.airThreshold = 0;
    mComParams.airParams.airAuto = 1;
    mComParams.disableDeblocking = 2;
    mComParams.syncEncMode = false;
    mComParams.codedBufNum = 2;
    mComParams.numberOfLayer = 1;
    mComParams.nPeriodicity = 0;
    memset(mComParams.nLayerID,0,32*sizeof(uint32_t));

    mHrdParam.bufferSize = 0;
    mHrdParam.initBufferFullness = 0;

    mStoreMetaDataInBuffers.isEnabled = false;
}

Encode_Status VideoEncoderBase::setParameters(
        VideoParamConfigSet *videoEncParams) {

    Encode_Status ret = ENCODE_SUCCESS;
    CHECK_NULL_RETURN_IFFAIL(videoEncParams);
    LOG_I("Config type = %x\n", (int)videoEncParams->type);

    if (mStarted) {
        LOG_E("Encoder has been initialized, should use setConfig to change configurations\n");
        return ENCODE_ALREADY_INIT;
    }

    switch (videoEncParams->type) {
        case VideoParamsTypeCommon: {

            VideoParamsCommon *paramsCommon =
                    reinterpret_cast <VideoParamsCommon *> (videoEncParams);
            if (paramsCommon->size != sizeof (VideoParamsCommon)) {
                return ENCODE_INVALID_PARAMS;
            }
            if(paramsCommon->codedBufNum < 2)
                paramsCommon->codedBufNum =2;
            mComParams = *paramsCommon;
            break;
        }

        case VideoParamsTypeUpSteamBuffer: {

            VideoParamsUpstreamBuffer *upStreamBuffer =
                    reinterpret_cast <VideoParamsUpstreamBuffer *> (videoEncParams);

            if (upStreamBuffer->size != sizeof (VideoParamsUpstreamBuffer)) {
                return ENCODE_INVALID_PARAMS;
            }

            ret = setUpstreamBuffer(upStreamBuffer);
            break;
        }

        case VideoParamsTypeUsrptrBuffer: {

            // usrptr only can be get
            // this case should not happen
            break;
        }

        case VideoParamsTypeHRD: {
            VideoParamsHRD *hrd =
                    reinterpret_cast <VideoParamsHRD *> (videoEncParams);

            if (hrd->size != sizeof (VideoParamsHRD)) {
                return ENCODE_INVALID_PARAMS;
            }

            mHrdParam.bufferSize = hrd->bufferSize;
            mHrdParam.initBufferFullness = hrd->initBufferFullness;
            mRenderHrd = true;

            break;
        }

        case VideoParamsTypeStoreMetaDataInBuffers: {
            VideoParamsStoreMetaDataInBuffers *metadata =
                    reinterpret_cast <VideoParamsStoreMetaDataInBuffers *> (videoEncParams);

            if (metadata->size != sizeof (VideoParamsStoreMetaDataInBuffers)) {
                return ENCODE_INVALID_PARAMS;
            }

            mStoreMetaDataInBuffers.isEnabled = metadata->isEnabled;

            break;
        }

        case VideoParamsTypeTemporalLayer:{
            VideoParamsTemporalLayer *temporallayer =
                    reinterpret_cast <VideoParamsTemporalLayer *> (videoEncParams);

            if (temporallayer->size != sizeof(VideoParamsTemporalLayer)) {
                 return ENCODE_INVALID_PARAMS;
            }

            mComParams.numberOfLayer = temporallayer->numberOfLayer;
            mComParams.nPeriodicity = temporallayer->nPeriodicity;
            for(int i=0;i<temporallayer->nPeriodicity;i++)
                mComParams.nLayerID[i] = temporallayer->nLayerID[i];
            mRenderMultiTemporal = true;
            break;
        }

        case VideoParamsTypeAVC:
        case VideoParamsTypeH263:
        case VideoParamsTypeMP4:
        case VideoParamsTypeVC1:
        case VideoParamsTypeVP8: {
            ret = derivedSetParams(videoEncParams);
            break;
        }

        default: {
            LOG_E ("Wrong ParamType here\n");
            return ENCODE_INVALID_PARAMS;
        }
    }
    return ret;
}

Encode_Status VideoEncoderBase::getParameters(
        VideoParamConfigSet *videoEncParams) {

    Encode_Status ret = ENCODE_SUCCESS;
    CHECK_NULL_RETURN_IFFAIL(videoEncParams);
    LOG_I("Config type = %d\n", (int)videoEncParams->type);

    switch (videoEncParams->type) {
        case VideoParamsTypeCommon: {

            VideoParamsCommon *paramsCommon =
                    reinterpret_cast <VideoParamsCommon *> (videoEncParams);

            if (paramsCommon->size != sizeof (VideoParamsCommon)) {
                return ENCODE_INVALID_PARAMS;
            }
            *paramsCommon = mComParams;
            break;
        }

        case VideoParamsTypeUpSteamBuffer: {

            // Get upstream buffer could happen
            // but not meaningful a lot
            break;
        }

        case VideoParamsTypeUsrptrBuffer: {
            VideoParamsUsrptrBuffer *usrptrBuffer =
                    reinterpret_cast <VideoParamsUsrptrBuffer *> (videoEncParams);

            if (usrptrBuffer->size != sizeof (VideoParamsUsrptrBuffer)) {
                return ENCODE_INVALID_PARAMS;
            }

            ret = getNewUsrptrFromSurface(
                    usrptrBuffer->width, usrptrBuffer->height, usrptrBuffer->format,
                    usrptrBuffer->expectedSize, &(usrptrBuffer->actualSize),
                    &(usrptrBuffer->stride), &(usrptrBuffer->usrPtr));

            break;
        }

        case VideoParamsTypeHRD: {
            VideoParamsHRD *hrd =
                    reinterpret_cast <VideoParamsHRD *> (videoEncParams);

            if (hrd->size != sizeof (VideoParamsHRD)) {
                return ENCODE_INVALID_PARAMS;
            }

            hrd->bufferSize = mHrdParam.bufferSize;
            hrd->initBufferFullness = mHrdParam.initBufferFullness;

            break;
        }

        case VideoParamsTypeStoreMetaDataInBuffers: {
            VideoParamsStoreMetaDataInBuffers *metadata =
                    reinterpret_cast <VideoParamsStoreMetaDataInBuffers *> (videoEncParams);

            if (metadata->size != sizeof (VideoParamsStoreMetaDataInBuffers)) {
                return ENCODE_INVALID_PARAMS;
            }

            metadata->isEnabled = mStoreMetaDataInBuffers.isEnabled;

            break;
        }

        case VideoParamsTypeProfileLevel: {
            VideoParamsProfileLevel *profilelevel =
                reinterpret_cast <VideoParamsProfileLevel *> (videoEncParams);

            if (profilelevel->size != sizeof (VideoParamsProfileLevel)) {
                return ENCODE_INVALID_PARAMS;
            }

            profilelevel->level = 0;
            if(queryProfileLevelConfig(mVADisplay, profilelevel->profile) == ENCODE_SUCCESS){
                profilelevel->isSupported = true;
                if(profilelevel->profile == VAProfileH264High)
                    profilelevel->level = 42;
                else if(profilelevel->profile == VAProfileH264Main)
                     profilelevel->level = 42;
                else if(profilelevel->profile == VAProfileH264Baseline)
                     profilelevel->level = 41;
                else{
                    profilelevel->level = 0;
                    profilelevel->isSupported = false;
                }
            }
        }

        case VideoParamsTypeTemporalLayer:{
            VideoParamsTemporalLayer *temporallayer =
                reinterpret_cast <VideoParamsTemporalLayer *> (videoEncParams);

            if(temporallayer->size != sizeof(VideoParamsTemporalLayer)) {
                return ENCODE_INVALID_PARAMS;
            }

            temporallayer->numberOfLayer = mComParams.numberOfLayer;

            break;
        }

        case VideoParamsTypeAVC:
        case VideoParamsTypeH263:
        case VideoParamsTypeMP4:
        case VideoParamsTypeVC1:
        case VideoParamsTypeVP8: {
            derivedGetParams(videoEncParams);
            break;
        }

        default: {
            LOG_E ("Wrong ParamType here\n");
            break;
        }

    }
    return ENCODE_SUCCESS;
}

Encode_Status VideoEncoderBase::setConfig(VideoParamConfigSet *videoEncConfig) {

    Encode_Status ret = ENCODE_SUCCESS;
    CHECK_NULL_RETURN_IFFAIL(videoEncConfig);
    LOG_I("Config type = %d\n", (int)videoEncConfig->type);

   // workaround
#if 0
    if (!mStarted) {
        LOG_E("Encoder has not initialized yet, can't call setConfig\n");
        return ENCODE_NOT_INIT;
    }
#endif

    switch (videoEncConfig->type) {
        case VideoConfigTypeFrameRate: {
            VideoConfigFrameRate *configFrameRate =
                    reinterpret_cast <VideoConfigFrameRate *> (videoEncConfig);

            if (configFrameRate->size != sizeof (VideoConfigFrameRate)) {
                return ENCODE_INVALID_PARAMS;
            }
            mComParams.frameRate = configFrameRate->frameRate;
            mRenderFrameRate = true;
            break;
        }

        case VideoConfigTypeBitRate: {
            VideoConfigBitRate *configBitRate =
                    reinterpret_cast <VideoConfigBitRate *> (videoEncConfig);

            if (configBitRate->size != sizeof (VideoConfigBitRate)) {
                return ENCODE_INVALID_PARAMS;
            }

            if(mComParams.numberOfLayer == 1)
            {
                mComParams.rcParams = configBitRate->rcParams;
                mRenderBitRate = true;
            }
            else
            {
                mTemporalLayerBitrateFramerate[configBitRate->rcParams.temporalID].nLayerID = configBitRate->rcParams.temporalID;
                mTemporalLayerBitrateFramerate[configBitRate->rcParams.temporalID].bitRate = configBitRate->rcParams.bitRate;
                mTemporalLayerBitrateFramerate[configBitRate->rcParams.temporalID].frameRate = configBitRate->rcParams.temporalFrameRate;
            }
            break;
        }

        case VideoConfigTypeResolution: {

            // Not Implemented
            break;
        }
        case VideoConfigTypeIntraRefreshType: {

            VideoConfigIntraRefreshType *configIntraRefreshType =
                    reinterpret_cast <VideoConfigIntraRefreshType *> (videoEncConfig);

            if (configIntraRefreshType->size != sizeof (VideoConfigIntraRefreshType)) {
                return ENCODE_INVALID_PARAMS;
            }
            mComParams.refreshType = configIntraRefreshType->refreshType;
            break;
        }

        case VideoConfigTypeCyclicFrameInterval: {
            VideoConfigCyclicFrameInterval *configCyclicFrameInterval =
                    reinterpret_cast <VideoConfigCyclicFrameInterval *> (videoEncConfig);
            if (configCyclicFrameInterval->size != sizeof (VideoConfigCyclicFrameInterval)) {
                return ENCODE_INVALID_PARAMS;
            }

            mComParams.cyclicFrameInterval = configCyclicFrameInterval->cyclicFrameInterval;
            break;
        }

        case VideoConfigTypeAIR: {

            VideoConfigAIR *configAIR = reinterpret_cast <VideoConfigAIR *> (videoEncConfig);

            if (configAIR->size != sizeof (VideoConfigAIR)) {
                return ENCODE_INVALID_PARAMS;
            }

            mComParams.airParams = configAIR->airParams;
            mRenderAIR = true;
            break;
        }
        case VideoConfigTypeCIR: {

            VideoConfigCIR *configCIR = reinterpret_cast <VideoConfigCIR *> (videoEncConfig);

            if (configCIR->size != sizeof (VideoConfigCIR)) {
                return ENCODE_INVALID_PARAMS;
            }

            mComParams.cirParams = configCIR->cirParams;
            mRenderCIR = true;
            break;
        }
        case VideoConfigTypeAVCIntraPeriod:
        case VideoConfigTypeNALSize:
        case VideoConfigTypeIDRRequest:
        case VideoConfigTypeSliceNum:
        case VideoConfigTypeVP8:
        case VideoConfigTypeVP8ReferenceFrame:
        case VideoConfigTypeVP8MaxFrameSizeRatio:{
            ret = derivedSetConfig(videoEncConfig);
            break;
        }
        default: {
            LOG_E ("Wrong Config Type here\n");
            break;
        }
    }
    return ret;
}

Encode_Status VideoEncoderBase::getConfig(VideoParamConfigSet *videoEncConfig) {

    Encode_Status ret = ENCODE_SUCCESS;
    CHECK_NULL_RETURN_IFFAIL(videoEncConfig);
    LOG_I("Config type = %d\n", (int)videoEncConfig->type);

    switch (videoEncConfig->type) {
        case VideoConfigTypeFrameRate: {
            VideoConfigFrameRate *configFrameRate =
                    reinterpret_cast <VideoConfigFrameRate *> (videoEncConfig);

            if (configFrameRate->size != sizeof (VideoConfigFrameRate)) {
                return ENCODE_INVALID_PARAMS;
            }

            configFrameRate->frameRate = mComParams.frameRate;
            break;
        }

        case VideoConfigTypeBitRate: {
            VideoConfigBitRate *configBitRate =
                    reinterpret_cast <VideoConfigBitRate *> (videoEncConfig);

            if (configBitRate->size != sizeof (VideoConfigBitRate)) {
                return ENCODE_INVALID_PARAMS;
            }
            configBitRate->rcParams = mComParams.rcParams;


            break;
        }
        case VideoConfigTypeResolution: {
            // Not Implemented
            break;
        }
        case VideoConfigTypeIntraRefreshType: {

            VideoConfigIntraRefreshType *configIntraRefreshType =
                    reinterpret_cast <VideoConfigIntraRefreshType *> (videoEncConfig);

            if (configIntraRefreshType->size != sizeof (VideoConfigIntraRefreshType)) {
                return ENCODE_INVALID_PARAMS;
            }
            configIntraRefreshType->refreshType = mComParams.refreshType;
            break;
        }

        case VideoConfigTypeCyclicFrameInterval: {
            VideoConfigCyclicFrameInterval *configCyclicFrameInterval =
                    reinterpret_cast <VideoConfigCyclicFrameInterval *> (videoEncConfig);
            if (configCyclicFrameInterval->size != sizeof (VideoConfigCyclicFrameInterval)) {
                return ENCODE_INVALID_PARAMS;
            }

            configCyclicFrameInterval->cyclicFrameInterval = mComParams.cyclicFrameInterval;
            break;
        }

        case VideoConfigTypeAIR: {

            VideoConfigAIR *configAIR = reinterpret_cast <VideoConfigAIR *> (videoEncConfig);

            if (configAIR->size != sizeof (VideoConfigAIR)) {
                return ENCODE_INVALID_PARAMS;
            }

            configAIR->airParams = mComParams.airParams;
            break;
        }
        case VideoConfigTypeCIR: {

            VideoConfigCIR *configCIR = reinterpret_cast <VideoConfigCIR *> (videoEncConfig);

            if (configCIR->size != sizeof (VideoConfigCIR)) {
                return ENCODE_INVALID_PARAMS;
            }

            configCIR->cirParams = mComParams.cirParams;
            break;
        }
        case VideoConfigTypeAVCIntraPeriod:
        case VideoConfigTypeNALSize:
        case VideoConfigTypeIDRRequest:
        case VideoConfigTypeSliceNum:
        case VideoConfigTypeVP8: {

            ret = derivedGetConfig(videoEncConfig);
            break;
        }
        default: {
            LOG_E ("Wrong ParamType here\n");
            break;
        }
    }
    return ret;
}

void VideoEncoderBase:: PrepareFrameInfo (EncodeTask* task) {
    if (mNewHeader) mFrameNum = 0;
    LOG_I( "mFrameNum = %d   ", mFrameNum);

    updateFrameInfo(task) ;
}

Encode_Status VideoEncoderBase:: updateFrameInfo (EncodeTask* task) {

    task->type = FTYPE_P;

    // determine the picture type
    if (mFrameNum == 0)
        task->type = FTYPE_I;
    if (mComParams.intraPeriod != 0 && ((mFrameNum % mComParams.intraPeriod) == 0))
        task->type = FTYPE_I;

    if (task->type == FTYPE_I)
        task->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;

    return ENCODE_SUCCESS;
}

Encode_Status  VideoEncoderBase::getMaxOutSize (uint32_t *maxSize) {

    uint32_t size = mComParams.resolution.width * mComParams.resolution.height;

    if (maxSize == NULL) {
        LOG_E("maxSize == NULL\n");
        return ENCODE_NULL_PTR;
    }

    LOG_V( "Begin\n");

    if (mCodedBufSize > 0) {
        *maxSize = mCodedBufSize;
        LOG_V ("Already calculate the max encoded size, get the value directly");
        return ENCODE_SUCCESS;
    }

    // here, VP8 is different from AVC/H263
    if(mComParams.profile == VAProfileVP8Version0_3) // for VP8 encode
    {
        // According to VIED suggestions, in CBR mode, coded buffer should be the size of 3 bytes per luma pixel
        // in CBR_HRD mode, coded buffer size should be  5 * rc_buf_sz * rc_target_bitrate;
        // now we just hardcode mCodedBufSize as 2M to walk round coded buffer size issue;
        /*
        if(mComParams.rcMode == VA_RC_CBR) // CBR_HRD mode
            mCodedBufSize = 5 * mComParams.rcParams.bitRate * 6000;
        else // CBR mode
            mCodedBufSize = 3 * mComParams.resolution.width * mComParams.resolution.height;
        */
        mCodedBufSize = (2 * 1024 * 1024 + 31) & (~31);
    }
    else // for AVC/H263/MPEG4 encode
    {
        // base on the rate control mode to calculate the defaule encoded buffer size
        if (mComParams.rcMode == VA_RC_NONE) {
             mCodedBufSize = (size * 400) / (16 * 16);
             // set to value according to QP
        } else {
             mCodedBufSize = mComParams.rcParams.bitRate / 4;
        }

        mCodedBufSize = max (mCodedBufSize , (size * 400) / (16 * 16));

        // in case got a very large user input bit rate value
        mCodedBufSize = min(mCodedBufSize, (size * 1.5 * 8));
        mCodedBufSize =  (mCodedBufSize + 15) &(~15);
    }

    *maxSize = mCodedBufSize;
    return ENCODE_SUCCESS;
}

Encode_Status VideoEncoderBase::getNewUsrptrFromSurface(
    uint32_t width, uint32_t height, uint32_t format,
    uint32_t expectedSize, uint32_t *outsize, uint32_t *stride, uint8_t **usrptr) {

    Encode_Status ret = ENCODE_FAIL;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    VASurfaceID surface = VA_INVALID_SURFACE;
    VAImage image;
    uint32_t index = 0;

    LOG_V( "Begin\n");
    // If encode session has been configured, we can not request surface creation anymore
    if (mStarted) {
        LOG_E( "Already Initialized, can not request VA surface anymore\n");
        return ENCODE_WRONG_STATE;
    }
    if (width<=0 || height<=0 ||outsize == NULL ||stride == NULL || usrptr == NULL) {
        LOG_E("width<=0 || height<=0 || outsize == NULL || stride == NULL ||usrptr == NULL\n");
        return ENCODE_NULL_PTR;
    }

    // Current only NV12 is supported in VA API
    // Through format we can get known the number of planes
    if (format != STRING_TO_FOURCC("NV12")) {
        LOG_W ("Format is not supported\n");
        return ENCODE_NOT_SUPPORTED;
    }

    surface = CreateNewVASurface(mVADisplay, width, height);
    if (surface == VA_INVALID_SURFACE)
        return ENCODE_DRIVER_FAIL;

    vaStatus = vaDeriveImage(mVADisplay, surface, &image);
    CHECK_VA_STATUS_RETURN("vaDeriveImage");
    LOG_V( "vaDeriveImage Done\n");
    vaStatus = vaMapBuffer(mVADisplay, image.buf, (void **) usrptr);
    CHECK_VA_STATUS_RETURN("vaMapBuffer");

    // make sure the physical page been allocated
    for (index = 0; index < image.data_size; index = index + 4096) {
        unsigned char tmp =  *(*usrptr + index);
        if (tmp == 0)
            *(*usrptr + index) = 0;
    }

    *outsize = image.data_size;
    *stride = image.pitches[0];

    LOG_I( "surface = 0x%08x\n",(uint32_t)surface);
    LOG_I("image->pitches[0] = %d\n", image.pitches[0]);
    LOG_I("image->pitches[1] = %d\n", image.pitches[1]);
    LOG_I("image->offsets[0] = %d\n", image.offsets[0]);
    LOG_I("image->offsets[1] = %d\n", image.offsets[1]);
    LOG_I("image->num_planes = %d\n", image.num_planes);
    LOG_I("image->width = %d\n", image.width);
    LOG_I("image->height = %d\n", image.height);
    LOG_I ("data_size = %d\n", image.data_size);
    LOG_I ("usrptr = 0x%p\n", *usrptr);

    vaStatus = vaUnmapBuffer(mVADisplay, image.buf);
    CHECK_VA_STATUS_RETURN("vaUnmapBuffer");
    vaStatus = vaDestroyImage(mVADisplay, image.image_id);
    CHECK_VA_STATUS_RETURN("vaDestroyImage");

    if (*outsize < expectedSize) {
        LOG_E ("Allocated buffer size is small than the expected size, destroy the surface");
        LOG_I ("Allocated size is %d, expected size is %d\n", *outsize, expectedSize);
        vaStatus = vaDestroySurfaces(mVADisplay, &surface, 1);
        CHECK_VA_STATUS_RETURN("vaDestroySurfaces");
        return ENCODE_FAIL;
    }

    VASurfaceMap *map = new VASurfaceMap(mVADisplay, mSupportedSurfaceMemType);
    if (map == NULL) {
        LOG_E( "new VASurfaceMap failed\n");
        return ENCODE_NO_MEMORY;
    }

    map->setVASurface(surface);  //special case, vasuface is set, so nothing do in doMapping
//    map->setType(MetadataBufferTypeEncoder);
    map->setValue((intptr_t)*usrptr);
    ValueInfo vinfo;
    memset(&vinfo, 0, sizeof(ValueInfo));
    vinfo.mode = (MemMode)MEM_MODE_USRPTR;
    vinfo.handle = 0;
    vinfo.size = 0;
    vinfo.width = width;
    vinfo.height = height;
    vinfo.lumaStride = width;
    vinfo.chromStride = width;
    vinfo.format = VA_FOURCC_NV12;
    vinfo.s3dformat = 0xffffffff;
    map->setValueInfo(vinfo);
    map->doMapping();

    mSrcSurfaceMapList.push_back(map);

    ret = ENCODE_SUCCESS;

    return ret;
}

Encode_Status VideoEncoderBase::setUpstreamBuffer(VideoParamsUpstreamBuffer *upStreamBuffer) {

    Encode_Status status = ENCODE_SUCCESS;

    CHECK_NULL_RETURN_IFFAIL(upStreamBuffer);
    if (upStreamBuffer->bufCnt == 0) {
        LOG_E("bufCnt == 0\n");
        return ENCODE_FAIL;
    }

    for(unsigned int i=0; i < upStreamBuffer->bufCnt; i++) {
        if (findSurfaceMapByValue(upStreamBuffer->bufList[i]) != NULL)  //already mapped
            continue;

        //wrap upstream buffer into vaSurface
        VASurfaceMap *map = new VASurfaceMap(mVADisplay, mSupportedSurfaceMemType);

//        map->setType(MetadataBufferTypeUser);
        map->setValue(upStreamBuffer->bufList[i]);
        ValueInfo vinfo;
        memset(&vinfo, 0, sizeof(ValueInfo));
        vinfo.mode = (MemMode)upStreamBuffer->bufferMode;
        vinfo.handle = (intptr_t)upStreamBuffer->display;
        vinfo.size = 0;
        if (upStreamBuffer->bufAttrib) {
            vinfo.width = upStreamBuffer->bufAttrib->realWidth;
            vinfo.height = upStreamBuffer->bufAttrib->realHeight;
            vinfo.lumaStride = upStreamBuffer->bufAttrib->lumaStride;
            vinfo.chromStride = upStreamBuffer->bufAttrib->chromStride;
            vinfo.format = upStreamBuffer->bufAttrib->format;
        }
        vinfo.s3dformat = 0xFFFFFFFF;
        map->setValueInfo(vinfo);
        status = map->doMapping();

        if (status == ENCODE_SUCCESS)
            mSrcSurfaceMapList.push_back(map);
        else
           delete map;
    }

    return status;
}

Encode_Status VideoEncoderBase::manageSrcSurface(VideoEncRawBuffer *inBuffer, VASurfaceID *sid) {

    Encode_Status ret = ENCODE_SUCCESS;
    IntelMetadataBufferType type;
    intptr_t value;
    ValueInfo vinfo;
    ValueInfo *pvinfo = &vinfo;
    intptr_t *extravalues = NULL;
    unsigned int extravalues_count = 0;

    IntelMetadataBuffer imb;
    VASurfaceMap *map = NULL;

    memset(&vinfo, 0, sizeof(ValueInfo));
    if (mStoreMetaDataInBuffers.isEnabled) {
        //metadatabuffer mode
        LOG_I("in metadata mode, data=%p, size=%d\n", inBuffer->data, inBuffer->size);
        if (imb.UnSerialize(inBuffer->data, inBuffer->size) != IMB_SUCCESS) {
            //fail to parse buffer
            return ENCODE_NO_REQUEST_DATA;
        }

        imb.GetType(type);
        imb.GetValue(value);
    } else {
        //raw mode
        LOG_I("in raw mode, data=%p, size=%d\n", inBuffer->data, inBuffer->size);
        if (! inBuffer->data || inBuffer->size == 0) {
            return ENCODE_NULL_PTR;
        }

        type = IntelMetadataBufferTypeUser;
        value = (intptr_t)inBuffer->data;
    }

#ifdef INTEL_VIDEO_XPROC_SHARING
    uint32_t sflag = mSessionFlag;
    imb.GetSessionFlag(mSessionFlag);
    if (mSessionFlag != sflag) {
        //new sharing session, flush buffer sharing cache
        IntelMetadataBuffer::ClearContext(sflag, false);
        //flush surfacemap cache
        LOG_V( "Flush Src Surface Map\n");
        while(! mSrcSurfaceMapList.empty())
        {
            delete (*mSrcSurfaceMapList.begin());
            mSrcSurfaceMapList.erase(mSrcSurfaceMapList.begin());
        }
    }
#endif

    //find if mapped
    map = (VASurfaceMap*) findSurfaceMapByValue(value);

    if (map) {
        //has mapped, get surfaceID directly and do all necessary actions
        LOG_I("direct find surface %d from value %p\n", map->getVASurface(), value);
        *sid = map->getVASurface();
        map->doMapping();
        return ret;
    }

    //if no found from list, then try to map value with parameters
    LOG_I("not find surface from cache with value %p, start mapping if enough information\n", value);

    if (mStoreMetaDataInBuffers.isEnabled) {

        //if type is IntelMetadataBufferTypeGrallocSource, use default parameters since no ValueInfo
        if (type == IntelMetadataBufferTypeGrallocSource) {
            vinfo.mode = MEM_MODE_GFXHANDLE;
            vinfo.handle = 0;
            vinfo.size = 0;
            vinfo.width = mComParams.resolution.width;
            vinfo.height = mComParams.resolution.height;
            vinfo.lumaStride = mComParams.resolution.width;
            vinfo.chromStride = mComParams.resolution.width;
            vinfo.format = VA_FOURCC_NV12;
            vinfo.s3dformat = 0xFFFFFFFF;
        } else {
            //get all info mapping needs
            imb.GetValueInfo(pvinfo);
            imb.GetExtraValues(extravalues, extravalues_count);
        }

    } else {

        //raw mode
        vinfo.mode = MEM_MODE_MALLOC;
        vinfo.handle = 0;
        vinfo.size = inBuffer->size;
        vinfo.width = mComParams.resolution.width;
        vinfo.height = mComParams.resolution.height;
        vinfo.lumaStride = mComParams.resolution.width;
        vinfo.chromStride = mComParams.resolution.width;
        vinfo.format = VA_FOURCC_NV12;
        vinfo.s3dformat = 0xFFFFFFFF;
    }

    /*  Start mapping, if pvinfo is not NULL, then have enough info to map;
     *   if extravalues is not NULL, then need to do more times mapping
     */
    if (pvinfo){
        //map according info, and add to surfacemap list
        map = new VASurfaceMap(mVADisplay, mSupportedSurfaceMemType);
        map->setValue(value);
        map->setValueInfo(*pvinfo);
        map->setAction(mVASurfaceMappingAction);

        ret = map->doMapping();
        if (ret == ENCODE_SUCCESS) {
            LOG_I("surface mapping success, map value %p into surface %d\n", value, map->getVASurface());
            mSrcSurfaceMapList.push_back(map);
        } else {
            delete map;
            LOG_E("surface mapping failed, wrong info or meet serious error\n");
            return ret;
        }

        *sid = map->getVASurface();

    } else {
        //can't map due to no info
        LOG_E("surface mapping failed, missing information\n");
        return ENCODE_NO_REQUEST_DATA;
    }

    if (extravalues) {
        //map more using same ValueInfo
        for(unsigned int i=0; i<extravalues_count; i++) {
            map = new VASurfaceMap(mVADisplay, mSupportedSurfaceMemType);
            map->setValue(extravalues[i]);
            map->setValueInfo(vinfo);

            ret = map->doMapping();
            if (ret == ENCODE_SUCCESS) {
                LOG_I("surface mapping extravalue success, map value %p into surface %d\n", extravalues[i], map->getVASurface());
                mSrcSurfaceMapList.push_back(map);
            } else {
                delete map;
                map = NULL;
                LOG_E( "surface mapping extravalue failed, extravalue is %p\n", extravalues[i]);
            }
        }
    }

    return ret;
}

Encode_Status VideoEncoderBase::renderDynamicBitrate(EncodeTask* task) {
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    LOG_V( "Begin\n\n");
    // disable bits stuffing and skip frame apply to all rate control mode

    VAEncMiscParameterBuffer   *miscEncParamBuf;
    VAEncMiscParameterRateControl *bitrateControlParam;
    VABufferID miscParamBufferID;

    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
            VAEncMiscParameterBufferType,
            sizeof (VAEncMiscParameterBuffer) + sizeof (VAEncMiscParameterRateControl),
            1, NULL,
            &miscParamBufferID);

    CHECK_VA_STATUS_RETURN("vaCreateBuffer");

    vaStatus = vaMapBuffer(mVADisplay, miscParamBufferID, (void **)&miscEncParamBuf);
    CHECK_VA_STATUS_RETURN("vaMapBuffer");

    miscEncParamBuf->type = VAEncMiscParameterTypeRateControl;
    bitrateControlParam = (VAEncMiscParameterRateControl *)miscEncParamBuf->data;

    bitrateControlParam->bits_per_second = mComParams.rcParams.bitRate;
    bitrateControlParam->initial_qp = mComParams.rcParams.initQP;
    if(mComParams.rcParams.enableIntraFrameQPControl && (task->type == FTYPE_IDR || task->type == FTYPE_I)) {
        bitrateControlParam->min_qp = mComParams.rcParams.I_minQP;
        bitrateControlParam->max_qp = mComParams.rcParams.I_maxQP;
        mRenderBitRate = true;
        LOG_I("apply I min/max qp for IDR or I frame\n");
    } else {
        bitrateControlParam->min_qp = mComParams.rcParams.minQP;
        bitrateControlParam->max_qp = mComParams.rcParams.maxQP;
        mRenderBitRate = false;
        LOG_I("revert to original min/max qp after IDR or I frame\n");
    }
    bitrateControlParam->target_percentage = mComParams.rcParams.targetPercentage;
    bitrateControlParam->window_size = mComParams.rcParams.windowSize;
    bitrateControlParam->rc_flags.bits.disable_frame_skip = mComParams.rcParams.disableFrameSkip;
    bitrateControlParam->rc_flags.bits.disable_bit_stuffing = mComParams.rcParams.disableBitsStuffing;
    bitrateControlParam->basic_unit_size = 0;

    LOG_I("bits_per_second = %d\n", bitrateControlParam->bits_per_second);
    LOG_I("initial_qp = %d\n", bitrateControlParam->initial_qp);
    LOG_I("min_qp = %d\n", bitrateControlParam->min_qp);
    LOG_I("max_qp = %d\n", bitrateControlParam->max_qp);
    LOG_I("target_percentage = %d\n", bitrateControlParam->target_percentage);
    LOG_I("window_size = %d\n", bitrateControlParam->window_size);
    LOG_I("disable_frame_skip = %d\n", bitrateControlParam->rc_flags.bits.disable_frame_skip);
    LOG_I("disable_bit_stuffing = %d\n", bitrateControlParam->rc_flags.bits.disable_bit_stuffing);

    vaStatus = vaUnmapBuffer(mVADisplay, miscParamBufferID);
    CHECK_VA_STATUS_RETURN("vaUnmapBuffer");

    vaStatus = vaRenderPicture(mVADisplay, mVAContext,
            &miscParamBufferID, 1);
    CHECK_VA_STATUS_RETURN("vaRenderPicture");

    return ENCODE_SUCCESS;
}


Encode_Status VideoEncoderBase::renderDynamicFrameRate() {

    VAStatus vaStatus = VA_STATUS_SUCCESS;

    if (mComParams.rcMode != RATE_CONTROL_VCM) {

        LOG_W("Not in VCM mode, but call SendDynamicFramerate\n");
        return ENCODE_SUCCESS;
    }

    VAEncMiscParameterBuffer   *miscEncParamBuf;
    VAEncMiscParameterFrameRate *frameRateParam;
    VABufferID miscParamBufferID;

    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
            VAEncMiscParameterBufferType,
            sizeof(miscEncParamBuf) + sizeof(VAEncMiscParameterFrameRate),
            1, NULL, &miscParamBufferID);
    CHECK_VA_STATUS_RETURN("vaCreateBuffer");

    vaStatus = vaMapBuffer(mVADisplay, miscParamBufferID, (void **)&miscEncParamBuf);
    CHECK_VA_STATUS_RETURN("vaMapBuffer");

    miscEncParamBuf->type = VAEncMiscParameterTypeFrameRate;
    frameRateParam = (VAEncMiscParameterFrameRate *)miscEncParamBuf->data;
    frameRateParam->framerate =
            (unsigned int) (mComParams.frameRate.frameRateNum + mComParams.frameRate.frameRateDenom/2)
            / mComParams.frameRate.frameRateDenom;

    vaStatus = vaUnmapBuffer(mVADisplay, miscParamBufferID);
    CHECK_VA_STATUS_RETURN("vaUnmapBuffer");

    vaStatus = vaRenderPicture(mVADisplay, mVAContext, &miscParamBufferID, 1);
    CHECK_VA_STATUS_RETURN("vaRenderPicture");

    LOG_I( "frame rate = %d\n", frameRateParam->framerate);
    return ENCODE_SUCCESS;
}

Encode_Status VideoEncoderBase::renderHrd() {

    VAStatus vaStatus = VA_STATUS_SUCCESS;

    VAEncMiscParameterBuffer *miscEncParamBuf;
    VAEncMiscParameterHRD *hrdParam;
    VABufferID miscParamBufferID;

    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
            VAEncMiscParameterBufferType,
            sizeof(miscEncParamBuf) + sizeof(VAEncMiscParameterHRD),
            1, NULL, &miscParamBufferID);
    CHECK_VA_STATUS_RETURN("vaCreateBuffer");

    vaStatus = vaMapBuffer(mVADisplay, miscParamBufferID, (void **)&miscEncParamBuf);
    CHECK_VA_STATUS_RETURN("vaMapBuffer");

    miscEncParamBuf->type = VAEncMiscParameterTypeHRD;
    hrdParam = (VAEncMiscParameterHRD *)miscEncParamBuf->data;

    hrdParam->buffer_size = mHrdParam.bufferSize;
    hrdParam->initial_buffer_fullness = mHrdParam.initBufferFullness;

    vaStatus = vaUnmapBuffer(mVADisplay, miscParamBufferID);
    CHECK_VA_STATUS_RETURN("vaUnmapBuffer");

    vaStatus = vaRenderPicture(mVADisplay, mVAContext, &miscParamBufferID, 1);
    CHECK_VA_STATUS_RETURN("vaRenderPicture");

    return ENCODE_SUCCESS;
}

VASurfaceMap *VideoEncoderBase::findSurfaceMapByValue(intptr_t value) {
    android::List<VASurfaceMap *>::iterator node;

    for(node = mSrcSurfaceMapList.begin(); node !=  mSrcSurfaceMapList.end(); node++)
    {
        if ((*node)->getValue() == value)
            return *node;
        else
            continue;
    }

    return NULL;
}
