/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.
 */
/**
*************************************************************************
* @file   VideoEditorVideoEncoder.cpp
* @brief  StageFright shell video encoder
*************************************************************************
*/
#define LOG_NDEBUG 1
#define LOG_TAG "VIDEOEDITOR_VIDEOENCODER"

/*******************
 *     HEADERS     *
 *******************/
#include "M4OSA_Debug.h"
#include "M4SYS_AccessUnit.h"
#include "VideoEditorVideoEncoder.h"
#include "MediaBufferPuller.h"
#include <I420ColorConverter.h>

#include <unistd.h>
#include "utils/Log.h"
#include "utils/Vector.h"
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <media/MediaProfiles.h>
#include "OMX_Video.h"

#include "IntelVideoEditorEncoderSource.h"
#include "IntelVideoEditorAVCEncoder.h"
#include "IntelVideoEditorH263Encoder.h"
#include "IntelVideoEditorUtils.h"

/********************
 *   DEFINITIONS    *
 ********************/

// Force using hardware encoder
#define VIDEOEDITOR_FORCECODEC kHardwareCodecsOnly

#if !defined(VIDEOEDITOR_FORCECODEC)
    #error "Cannot force DSI retrieval if codec type is not fixed"
#endif

/********************
 *   SOURCE CLASS   *
 ********************/

namespace android {

struct VideoEditorVideoEncoderSource : public MediaSource {
    public:
        static sp<VideoEditorVideoEncoderSource> Create(
            const sp<MetaData> &format);
        virtual status_t start(MetaData *params = NULL);
        virtual status_t stop();
        virtual sp<MetaData> getFormat();
        virtual status_t read(MediaBuffer **buffer,
            const ReadOptions *options = NULL);
        virtual int32_t storeBuffer(MediaBuffer *buffer);
        virtual int32_t getNumberOfBuffersInQueue();

    protected:
        virtual ~VideoEditorVideoEncoderSource();

    private:
        struct MediaBufferChain {
            MediaBuffer* buffer;
            MediaBufferChain* nextLink;
        };
        enum State {
            CREATED,
            STARTED,
            ERROR
        };
        VideoEditorVideoEncoderSource(const sp<MetaData> &format);

        // Don't call me
        VideoEditorVideoEncoderSource(const VideoEditorVideoEncoderSource &);
        VideoEditorVideoEncoderSource &operator=(
                const VideoEditorVideoEncoderSource &);

        MediaBufferChain* mFirstBufferLink;
        MediaBufferChain* mLastBufferLink;
        int32_t           mNbBuffer;
        bool              mIsEOS;
        State             mState;
        sp<MetaData>      mEncFormat;
        Mutex             mLock;
        Condition         mBufferCond;
};

sp<VideoEditorVideoEncoderSource> VideoEditorVideoEncoderSource::Create(
    const sp<MetaData> &format) {

    sp<VideoEditorVideoEncoderSource> aSource =
        new VideoEditorVideoEncoderSource(format);
    return aSource;
}

VideoEditorVideoEncoderSource::VideoEditorVideoEncoderSource(
    const sp<MetaData> &format):
        mFirstBufferLink(NULL),
        mLastBufferLink(NULL),
        mNbBuffer(0),
        mIsEOS(false),
        mState(CREATED),
        mEncFormat(format) {
    ALOGV("VideoEditorVideoEncoderSource::VideoEditorVideoEncoderSource");
}

VideoEditorVideoEncoderSource::~VideoEditorVideoEncoderSource() {

    // Safety clean up
    if( STARTED == mState ) {
        stop();
    }
}

status_t VideoEditorVideoEncoderSource::start(MetaData *meta) {
    status_t err = OK;

    ALOGV("VideoEditorVideoEncoderSource::start() begin");

    if( CREATED != mState ) {
        ALOGV("VideoEditorVideoEncoderSource::start: invalid state %d", mState);
        return UNKNOWN_ERROR;
    }
    mState = STARTED;

    ALOGV("VideoEditorVideoEncoderSource::start() END (0x%x)", err);
    return err;
}

status_t VideoEditorVideoEncoderSource::stop() {
    status_t err = OK;

    ALOGV("VideoEditorVideoEncoderSource::stop() begin");

    if( STARTED != mState ) {
        ALOGV("VideoEditorVideoEncoderSource::stop: invalid state %d", mState);
        return UNKNOWN_ERROR;
    }

    // Release the buffer chain
    int32_t i = 0;
    MediaBufferChain* tmpLink = NULL;
    while( mFirstBufferLink ) {
        i++;
        tmpLink = mFirstBufferLink;
        mFirstBufferLink = mFirstBufferLink->nextLink;
        delete tmpLink;
    }
    ALOGV("VideoEditorVideoEncoderSource::stop : %d buffer remained", i);
    mFirstBufferLink = NULL;
    mLastBufferLink = NULL;

    mState = CREATED;

    ALOGV("VideoEditorVideoEncoderSource::stop() END (0x%x)", err);
    return err;
}

sp<MetaData> VideoEditorVideoEncoderSource::getFormat() {

    ALOGV("VideoEditorVideoEncoderSource::getFormat");
    return mEncFormat;
}

status_t VideoEditorVideoEncoderSource::read(MediaBuffer **buffer,
        const ReadOptions *options) {
    Mutex::Autolock autolock(mLock);
    MediaSource::ReadOptions readOptions;
    status_t err = OK;
    MediaBufferChain* tmpLink = NULL;

    ALOGV("VideoEditorVideoEncoderSource::read() begin");

    if ( STARTED != mState ) {
        ALOGV("VideoEditorVideoEncoderSource::read: invalid state %d", mState);
        return UNKNOWN_ERROR;
    }

    while (mFirstBufferLink == NULL && !mIsEOS) {
        mBufferCond.wait(mLock);
    }

    // End of stream?
    if (mFirstBufferLink == NULL) {
        *buffer = NULL;
        ALOGV("VideoEditorVideoEncoderSource::read : EOS");
        return ERROR_END_OF_STREAM;
    }

    // Get a buffer from the chain
    *buffer = mFirstBufferLink->buffer;
    tmpLink = mFirstBufferLink;
    mFirstBufferLink = mFirstBufferLink->nextLink;

    if ( NULL == mFirstBufferLink ) {
        mLastBufferLink = NULL;
    }
    delete tmpLink;
    mNbBuffer--;

    ALOGV("VideoEditorVideoEncoderSource::read() END (0x%x)", err);
    return err;
}

int32_t VideoEditorVideoEncoderSource::storeBuffer(MediaBuffer *buffer) {
    Mutex::Autolock autolock(mLock);
    status_t err = OK;

    ALOGV("VideoEditorVideoEncoderSource::storeBuffer() begin");

    if( NULL == buffer ) {
        ALOGV("VideoEditorVideoEncoderSource::storeBuffer : reached EOS");
        mIsEOS = true;
    } else {
        MediaBufferChain* newLink = new MediaBufferChain;
        newLink->buffer = buffer;
        newLink->nextLink = NULL;
        if( NULL != mLastBufferLink ) {
            mLastBufferLink->nextLink = newLink;
        } else {
            mFirstBufferLink = newLink;
        }
        mLastBufferLink = newLink;
        mNbBuffer++;
    }
    mBufferCond.signal();
    ALOGV("VideoEditorVideoEncoderSource::storeBuffer() end");
    return mNbBuffer;
}

int32_t VideoEditorVideoEncoderSource::getNumberOfBuffersInQueue() {
    Mutex::Autolock autolock(mLock);
    return mNbBuffer;
}

/**
 ******************************************************************************
 * structure VideoEditorVideoEncoder_Context
 * @brief    This structure defines the context of the StageFright video encoder
 *           shell
 ******************************************************************************
*/
typedef enum {
    CREATED   = 0x1,
    OPENED    = 0x2,
    STARTED   = 0x4,
    BUFFERING = 0x8,
    READING   = 0x10
} VideoEditorVideoEncoder_State;

typedef struct {
    VideoEditorVideoEncoder_State     mState;
    M4ENCODER_Format                  mFormat;
    M4WRITER_DataInterface*           mWriterDataInterface;
    M4VPP_apply_fct*                  mPreProcFunction;
    M4VPP_Context                     mPreProcContext;
    M4SYS_AccessUnit*                 mAccessUnit;
    M4ENCODER_Params*                 mCodecParams;
    M4ENCODER_Header                  mHeader;
    H264MCS_ProcessEncodedNALU_fct*   mH264NALUPostProcessFct;
    M4OSA_Context                     mH264NALUPostProcessCtx;
    M4OSA_UInt32                      mLastCTS;
    sp<IntelVideoEditorEncoderSource> mEncoderSource;
    OMXClient                         mClient;
    sp<MediaSource>                   mEncoder;
    OMX_COLOR_FORMATTYPE              mEncoderColorFormat;
    MediaBufferPuller*                mPuller;
    I420ColorConverter*               mI420ColorConverter;

    uint32_t                          mNbInputFrames;
    double                            mFirstInputCts;
    double                            mLastInputCts;
    uint32_t                          mNbOutputFrames;
    int64_t                           mFirstOutputCts;
    int64_t                           mLastOutputCts;

    MediaProfiles *mVideoEditorProfile;
    int32_t mMaxPrefetchFrames;
} VideoEditorVideoEncoder_Context;

/********************
 *      TOOLS       *
 ********************/

M4OSA_ERR VideoEditorVideoEncoder_getDSI(M4ENCODER_Context pContext,
        sp<MetaData> metaData) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context*  pEncoderContext = M4OSA_NULL;
    status_t result = OK;
    int32_t nbBuffer = 0;
    int32_t stride = 0;
    int32_t height = 0;
    int32_t framerate = 0;
    int32_t isCodecConfig = 0;
    size_t size = 0;
    uint32_t codecFlags = 0;
    MediaBuffer* inputBuffer = NULL;
    MediaBuffer* outputBuffer = NULL;
    sp<IntelVideoEditorEncoderSource> encoderSource = NULL;
    sp<MediaSource> encoder = NULL;;
    OMXClient client;

    ALOGV("VideoEditorVideoEncoder_getDSI begin");
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext,       M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(M4OSA_NULL != metaData.get(), M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
    VIDEOEDITOR_CHECK(CREATED == pEncoderContext->mState, M4ERR_STATE);

    // Create the encoder source
    encoderSource = IntelVideoEditorEncoderSource::Create(metaData);
    VIDEOEDITOR_CHECK(NULL != encoderSource.get(), M4ERR_STATE);

    // Create Hardware encoder

    encoder = new IntelVideoEditorAVCEncoder(encoderSource,metaData);
    VIDEOEDITOR_CHECK(NULL != encoder.get(), M4ERR_STATE);

    /**
     * Send fake frames and retrieve the DSI
     */
    // Send a fake frame to the source
    metaData->findInt32(kKeyStride,     &stride);
    metaData->findInt32(kKeyHeight,     &height);
    metaData->findInt32(kKeySampleRate, &framerate);

    result = encoder->start();
    VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);

    encoderSource->requestBuffer(&inputBuffer);

    inputBuffer->meta_data()->setInt64(kKeyTime, 0);
    nbBuffer = encoderSource->storeBuffer(inputBuffer);
    encoderSource->storeBuffer(NULL); // Signal EOS

    // Call read once to get the DSI
    result = encoder->read(&outputBuffer, NULL);
    VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
    VIDEOEDITOR_CHECK(outputBuffer->meta_data()->findInt32(
        kKeyIsCodecConfig, &isCodecConfig) && isCodecConfig, M4ERR_STATE);

    VIDEOEDITOR_CHECK(M4OSA_NULL == pEncoderContext->mHeader.pBuf, M4ERR_STATE);
    if ( M4ENCODER_kH264 == pEncoderContext->mFormat ) {
        // For H264, format the DSI
        LOGV("outputBuffer->range_offset() = %d, outputBuffer->range_length() = %d",
            outputBuffer->range_offset(), outputBuffer->range_length());
        result = buildAVCCodecSpecificData(
            (uint8_t**)(&(pEncoderContext->mHeader.pBuf)),
            (size_t*)(&(pEncoderContext->mHeader.Size)),
            (const uint8_t*)outputBuffer->data() + outputBuffer->range_offset(),
            outputBuffer->range_length(), encoder->getFormat().get());
        outputBuffer->release();
        VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
    } else {
        // For MPEG4, just copy the DSI
        pEncoderContext->mHeader.Size =
            (M4OSA_UInt32)outputBuffer->range_length();
        SAFE_MALLOC(pEncoderContext->mHeader.pBuf, M4OSA_Int8,
            pEncoderContext->mHeader.Size, "Encoder header");
        memcpy((void *)pEncoderContext->mHeader.pBuf,
            (void *)((M4OSA_MemAddr8)(outputBuffer->data())+outputBuffer->range_offset()),
            pEncoderContext->mHeader.Size);
        outputBuffer->release();
    }

    result = encoder->stop();
    VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);

cleanUp:
    // Destroy the graph
    if ( encoder != NULL ) { encoder.clear(); }
    //client.disconnect();
    if ( encoderSource != NULL ) { encoderSource.clear(); }
    if ( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_getDSI no error");
    } else {
        ALOGV("VideoEditorVideoEncoder_getDSI ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_getDSI end");
    return err;
}
/********************
 * ENGINE INTERFACE *
 ********************/

M4OSA_ERR VideoEditorVideoEncoder_cleanup(M4ENCODER_Context pContext) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;

    ALOGV("VideoEditorVideoEncoder_cleanup begin");
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
    VIDEOEDITOR_CHECK(CREATED == pEncoderContext->mState, M4ERR_STATE);

    // Release memory
    SAFE_FREE(pEncoderContext->mHeader.pBuf);
    SAFE_FREE(pEncoderContext);
    pContext = M4OSA_NULL;

cleanUp:
    if ( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_cleanup no error");
    } else {
        ALOGV("VideoEditorVideoEncoder_cleanup ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_cleanup end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_init(M4ENCODER_Format format,
        M4ENCODER_Context* pContext,
        M4WRITER_DataInterface* pWriterDataInterface,
        M4VPP_apply_fct* pVPPfct, M4VPP_Context pVPPctxt,
        M4OSA_Void* pExternalAPI, M4OSA_Void* pUserData) {

    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
    int encoderInput = OMX_COLOR_FormatYUV420Planar;

    ALOGV("VideoEditorVideoEncoder_init begin: format  %d", format);
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(M4OSA_NULL != pWriterDataInterface, M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(M4OSA_NULL != pVPPfct, M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(M4OSA_NULL != pVPPctxt, M4ERR_PARAMETER);

    // Context allocation & initialization
    SAFE_MALLOC(pEncoderContext, VideoEditorVideoEncoder_Context, 1,
        "VideoEditorVideoEncoder");
    pEncoderContext->mState = CREATED;
    pEncoderContext->mFormat = format;
    pEncoderContext->mWriterDataInterface = pWriterDataInterface;
    pEncoderContext->mPreProcFunction = pVPPfct;
    pEncoderContext->mPreProcContext = pVPPctxt;
    pEncoderContext->mPuller = NULL;

    // Get color converter and determine encoder input format
    pEncoderContext->mI420ColorConverter = new I420ColorConverter;
    if (pEncoderContext->mI420ColorConverter->isLoaded()) {
        encoderInput = pEncoderContext->mI420ColorConverter->getEncoderInputFormat();
    }
    if (encoderInput == OMX_COLOR_FormatYUV420Planar) {
        delete pEncoderContext->mI420ColorConverter;
        pEncoderContext->mI420ColorConverter = NULL;
    }
    pEncoderContext->mEncoderColorFormat = (OMX_COLOR_FORMATTYPE)encoderInput;
    ALOGI("encoder input format = 0x%X\n", encoderInput);

    *pContext = pEncoderContext;

cleanUp:
    if ( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_init no error");
    } else {
        VideoEditorVideoEncoder_cleanup(pEncoderContext);
        *pContext = M4OSA_NULL;
        ALOGV("VideoEditorVideoEncoder_init ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_init end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_init_H263(M4ENCODER_Context* pContext,
        M4WRITER_DataInterface* pWriterDataInterface, M4VPP_apply_fct* pVPPfct,
        M4VPP_Context pVPPctxt, M4OSA_Void* pExternalAPI, M4OSA_Void* pUserData)
        {

    return VideoEditorVideoEncoder_init(M4ENCODER_kH263, pContext,
        pWriterDataInterface, pVPPfct, pVPPctxt, pExternalAPI, pUserData);
}


M4OSA_ERR VideoEditorVideoEncoder_init_MPEG4(M4ENCODER_Context* pContext,
        M4WRITER_DataInterface* pWriterDataInterface, M4VPP_apply_fct* pVPPfct,
        M4VPP_Context pVPPctxt, M4OSA_Void* pExternalAPI, M4OSA_Void* pUserData)
        {

    return VideoEditorVideoEncoder_init(M4ENCODER_kMPEG4, pContext,
        pWriterDataInterface, pVPPfct, pVPPctxt, pExternalAPI, pUserData);
}


M4OSA_ERR VideoEditorVideoEncoder_init_H264(M4ENCODER_Context* pContext,
        M4WRITER_DataInterface* pWriterDataInterface, M4VPP_apply_fct* pVPPfct,
        M4VPP_Context pVPPctxt, M4OSA_Void* pExternalAPI, M4OSA_Void* pUserData)
        {

    return VideoEditorVideoEncoder_init(M4ENCODER_kH264, pContext,
        pWriterDataInterface, pVPPfct, pVPPctxt, pExternalAPI, pUserData);
}

M4OSA_ERR VideoEditorVideoEncoder_close(M4ENCODER_Context pContext) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;

    ALOGV("VideoEditorVideoEncoder_close begin");
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
    VIDEOEDITOR_CHECK(OPENED == pEncoderContext->mState, M4ERR_STATE);

    // Release memory
    SAFE_FREE(pEncoderContext->mCodecParams);

    // Destroy the graph
    pEncoderContext->mEncoder.clear();
   // pEncoderContext->mClient.disconnect();
    pEncoderContext->mEncoderSource.clear();

    delete pEncoderContext->mPuller;
    pEncoderContext->mPuller = NULL;

    delete pEncoderContext->mI420ColorConverter;
    pEncoderContext->mI420ColorConverter = NULL;

    // Set the new state
    pEncoderContext->mState = CREATED;

cleanUp:
    if( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_close no error");
    } else {
        ALOGV("VideoEditorVideoEncoder_close ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_close end");
    return err;
}


M4OSA_ERR VideoEditorVideoEncoder_open(M4ENCODER_Context pContext,
        M4SYS_AccessUnit* pAU, M4OSA_Void* pParams) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
    M4ENCODER_Params* pCodecParams = M4OSA_NULL;
    status_t result = OK;
    sp<MetaData> encoderMetadata = NULL;
    const char* mime = NULL;
    int32_t iProfile = 0;
    int32_t iLevel = 0;

    int32_t iFrameRate = 0;
    uint32_t codecFlags = 0;

    ALOGV(">>> VideoEditorVideoEncoder_open begin");
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(M4OSA_NULL != pAU,      M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(M4OSA_NULL != pParams,  M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
    pCodecParams = (M4ENCODER_Params*)pParams;
    VIDEOEDITOR_CHECK(CREATED == pEncoderContext->mState, M4ERR_STATE);

    // Context initialization
    pEncoderContext->mAccessUnit = pAU;
    pEncoderContext->mVideoEditorProfile = MediaProfiles::getInstance();
    pEncoderContext->mMaxPrefetchFrames =
        pEncoderContext->mVideoEditorProfile->getVideoEditorCapParamByName(
        "maxPrefetchYUVFrames");

    // Allocate & initialize the encoding parameters
    SAFE_MALLOC(pEncoderContext->mCodecParams, M4ENCODER_Params, 1,
        "VideoEditorVideoEncoder");


    pEncoderContext->mCodecParams->InputFormat = pCodecParams->InputFormat;
    pEncoderContext->mCodecParams->InputFrameWidth =
        pCodecParams->InputFrameWidth;
    pEncoderContext->mCodecParams->InputFrameHeight =
        pCodecParams->InputFrameHeight;
    pEncoderContext->mCodecParams->FrameWidth = pCodecParams->FrameWidth;
    pEncoderContext->mCodecParams->FrameHeight = pCodecParams->FrameHeight;
    pEncoderContext->mCodecParams->Bitrate = pCodecParams->Bitrate;
    pEncoderContext->mCodecParams->FrameRate = pCodecParams->FrameRate;
    pEncoderContext->mCodecParams->Format = pCodecParams->Format;
    pEncoderContext->mCodecParams->videoProfile = pCodecParams->videoProfile;
    pEncoderContext->mCodecParams->videoLevel= pCodecParams->videoLevel;

    // Check output format consistency and resolution
    VIDEOEDITOR_CHECK(
        pEncoderContext->mCodecParams->Format == pEncoderContext->mFormat,
        M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(0 == pEncoderContext->mCodecParams->FrameWidth  % 16,
        M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(0 == pEncoderContext->mCodecParams->FrameHeight % 16,
        M4ERR_PARAMETER);

    /**
     * StageFright graph building
     */

    // Create the meta data for the encoder
    encoderMetadata = new MetaData;
    switch( pEncoderContext->mCodecParams->Format ) {
        case M4ENCODER_kH263:
            mime     = MEDIA_MIMETYPE_VIDEO_H263;
            break;
        case M4ENCODER_kMPEG4:
            mime     = MEDIA_MIMETYPE_VIDEO_MPEG4;
            break;
        case M4ENCODER_kH264:
            mime     = MEDIA_MIMETYPE_VIDEO_AVC;
            break;
        default:
            VIDEOEDITOR_CHECK(!"VideoEncoder_open : incorrect input format",
                M4ERR_PARAMETER);
            break;
    }
    iProfile = pEncoderContext->mCodecParams->videoProfile;
    iLevel = pEncoderContext->mCodecParams->videoLevel;
    ALOGV("Encoder mime %s profile %d, level %d",
        mime,iProfile, iLevel);
    ALOGV("Encoder w %d, h %d, bitrate %d, fps %d",
        pEncoderContext->mCodecParams->FrameWidth,
        pEncoderContext->mCodecParams->FrameHeight,
        pEncoderContext->mCodecParams->Bitrate,
        pEncoderContext->mCodecParams->FrameRate);
    CHECK(iProfile != 0x7fffffff);
    CHECK(iLevel != 0x7fffffff);

    encoderMetadata->setCString(kKeyMIMEType, mime);
    encoderMetadata->setInt32(kKeyVideoProfile, iProfile);
    //FIXME:
    // Temp: Do not set the level for Mpeg4 / H.263 Enc
    // as OMX.Nvidia.mp4.encoder and OMX.Nvidia.h263.encoder
    // return 0x80001019
    if (pEncoderContext->mCodecParams->Format == M4ENCODER_kH264) {
        encoderMetadata->setInt32(kKeyVideoLevel, iLevel);
    }
    encoderMetadata->setInt32(kKeyWidth,
        (int32_t)pEncoderContext->mCodecParams->FrameWidth);
    encoderMetadata->setInt32(kKeyStride,
        (int32_t)pEncoderContext->mCodecParams->FrameWidth);
    encoderMetadata->setInt32(kKeyHeight,
        (int32_t)pEncoderContext->mCodecParams->FrameHeight);
    encoderMetadata->setInt32(kKeySliceHeight,
        (int32_t)pEncoderContext->mCodecParams->FrameHeight);

    switch( pEncoderContext->mCodecParams->FrameRate ) {
        case M4ENCODER_k5_FPS:    iFrameRate = 5;  break;
        case M4ENCODER_k7_5_FPS:  iFrameRate = 8;  break;
        case M4ENCODER_k10_FPS:   iFrameRate = 10; break;
        case M4ENCODER_k12_5_FPS: iFrameRate = 13; break;
        case M4ENCODER_k15_FPS:   iFrameRate = 15; break;
        case M4ENCODER_k20_FPS:   iFrameRate = 20; break;
        case M4ENCODER_k25_FPS:   iFrameRate = 25; break;
        case M4ENCODER_k30_FPS:   iFrameRate = 30; break;
        case M4ENCODER_kVARIABLE_FPS:
            iFrameRate = 30;
            ALOGI("Frame rate set to M4ENCODER_kVARIABLE_FPS: set to 30");
          break;
        case M4ENCODER_kUSE_TIMESCALE:
            iFrameRate = 30;
            ALOGI("Frame rate set to M4ENCODER_kUSE_TIMESCALE:  set to 30");
            break;

        default:
            VIDEOEDITOR_CHECK(!"VideoEncoder_open:incorrect framerate",
                M4ERR_STATE);
            break;
    }
    encoderMetadata->setInt32(kKeyFrameRate, iFrameRate);
    encoderMetadata->setInt32(kKeyBitRate,
        (int32_t)pEncoderContext->mCodecParams->Bitrate);
    encoderMetadata->setInt32(kKeyIFramesInterval, 1);

    encoderMetadata->setInt32(kKeyColorFormat,
        pEncoderContext->mEncoderColorFormat);

    if (pEncoderContext->mCodecParams->Format != M4ENCODER_kH263) {
        // Get the encoder DSI
        err = VideoEditorVideoEncoder_getDSI(pEncoderContext, encoderMetadata);
        VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
    }

    // Create the encoder source
    pEncoderContext->mEncoderSource = IntelVideoEditorEncoderSource::Create(
        encoderMetadata);
    VIDEOEDITOR_CHECK(
        NULL != pEncoderContext->mEncoderSource.get(), M4ERR_STATE);

    // Create the HW Encoder
    if (pEncoderContext->mCodecParams->Format == M4ENCODER_kH264) {
        pEncoderContext->mEncoder = new IntelVideoEditorAVCEncoder(
        pEncoderContext->mEncoderSource, encoderMetadata);
    } else if (pEncoderContext->mCodecParams->Format == M4ENCODER_kH263) {
        pEncoderContext->mEncoder = new IntelVideoEditorH263Encoder(
        pEncoderContext->mEncoderSource, encoderMetadata);
    }
    VIDEOEDITOR_CHECK(NULL != pEncoderContext->mEncoder.get(), M4ERR_STATE);
    ALOGV("VideoEditorVideoEncoder_open : DONE");
    pEncoderContext->mPuller = new MediaBufferPuller(
        pEncoderContext->mEncoder);

    // Set the new state
    pEncoderContext->mState = OPENED;

cleanUp:
    if( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_open no error");
    } else {
        VideoEditorVideoEncoder_close(pEncoderContext);
        ALOGV("VideoEditorVideoEncoder_open ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_open end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_processInputBuffer(
        M4ENCODER_Context pContext, M4OSA_Double Cts,
        M4OSA_Bool bReachedEOS) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
    M4VIFI_ImagePlane pOutPlane[3];
    MediaBuffer* buffer = NULL;
    int32_t nbBuffer = 0;

    ALOGV("VideoEditorVideoEncoder_processInputBuffer begin: cts  %f", Cts);
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
    pOutPlane[0].pac_data = M4OSA_NULL;
    pOutPlane[1].pac_data = M4OSA_NULL;
    pOutPlane[2].pac_data = M4OSA_NULL;

    if ( M4OSA_FALSE == bReachedEOS ) {
        M4OSA_UInt32 sizeY = pEncoderContext->mCodecParams->FrameWidth *
            pEncoderContext->mCodecParams->FrameHeight;
        M4OSA_UInt32 sizeU = sizeY >> 2;
        M4OSA_UInt32 size  = sizeY + 2*sizeU;
        M4OSA_UInt8* pData = M4OSA_NULL;
        buffer = new MediaBuffer((size_t)size);
        pData = (M4OSA_UInt8*)buffer->data() + buffer->range_offset();

        // Prepare the output image for pre-processing
        pOutPlane[0].u_width   = pEncoderContext->mCodecParams->FrameWidth;
        pOutPlane[0].u_height  = pEncoderContext->mCodecParams->FrameHeight;
        pOutPlane[0].u_topleft = 0;
        pOutPlane[0].u_stride  = pOutPlane[0].u_width;
        pOutPlane[1].u_width   = pOutPlane[0].u_width/2;
        pOutPlane[1].u_height  = pOutPlane[0].u_height/2;
        pOutPlane[1].u_topleft = 0;
        pOutPlane[1].u_stride  = pOutPlane[0].u_stride/2;
        pOutPlane[2].u_width   = pOutPlane[1].u_width;
        pOutPlane[2].u_height  = pOutPlane[1].u_height;
        pOutPlane[2].u_topleft = 0;
        pOutPlane[2].u_stride  = pOutPlane[1].u_stride;

        pOutPlane[0].pac_data = pData;
        pOutPlane[1].pac_data = pData + sizeY;
        pOutPlane[2].pac_data = pData + sizeY + sizeU;

        // Apply pre-processing
        err = pEncoderContext->mPreProcFunction(
            pEncoderContext->mPreProcContext, M4OSA_NULL, pOutPlane);
        VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);

        // Convert MediaBuffer to the encoder input format if necessary
        if (pEncoderContext->mI420ColorConverter) {
            I420ColorConverter* converter = pEncoderContext->mI420ColorConverter;
            int actualWidth = pEncoderContext->mCodecParams->FrameWidth;
            int actualHeight = pEncoderContext->mCodecParams->FrameHeight;

            int encoderWidth, encoderHeight;
            ARect encoderRect;
            int encoderBufferSize;

            if (converter->getEncoderInputBufferInfo(
                actualWidth, actualHeight,
                &encoderWidth, &encoderHeight,
                &encoderRect, &encoderBufferSize) == 0) {

                MediaBuffer* newBuffer;
                pEncoderContext->mEncoderSource->requestBuffer(&newBuffer);
                if (converter->convertI420ToEncoderInput(
                    pData,  // srcBits
                    actualWidth, actualHeight,
                    encoderWidth, encoderHeight,
                    encoderRect,
                    (uint8_t*)newBuffer->data() + newBuffer->range_offset()) < 0) {
                    ALOGE("convertI420ToEncoderInput failed");
                }

                // switch to new buffer
                buffer->release();
                buffer = newBuffer;
            }
        }

        // Set the metadata
        buffer->meta_data()->setInt64(kKeyTime, (int64_t)(Cts*1000));
    }

    // Push the buffer to the source, a NULL buffer, notifies the source of EOS
    nbBuffer = pEncoderContext->mEncoderSource->storeBuffer(buffer);

cleanUp:
    if ( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_processInputBuffer error 0x%X", err);
    } else {
        if( NULL != buffer ) {
            buffer->release();
        }
        ALOGV("VideoEditorVideoEncoder_processInputBuffer ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_processInputBuffer end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_processOutputBuffer(
        M4ENCODER_Context pContext, MediaBuffer* buffer) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
    M4OSA_UInt32 Cts = 0;
    uint8_t *data;
    uint32_t length;
    int32_t i32Tmp = 0;
    int64_t i64Tmp = 0;
    status_t result = OK;
    LOGV("VideoEditorVideoEncoder_processOutputBuffer begin");
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(M4OSA_NULL != buffer,   M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;

    // Process the returned AU
    if ( 0 == buffer->range_length() ) {
        // Encoder has no data yet, nothing unusual
        LOGV("VideoEditorVideoEncoder_processOutputBuffer : buffer is empty");
        goto cleanUp;
    }
    VIDEOEDITOR_CHECK(0 == ((M4OSA_UInt32)buffer->data())%4, M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(buffer->meta_data().get(), M4ERR_PARAMETER);
    if ( buffer->meta_data()->findInt32(kKeyIsCodecConfig, &i32Tmp) && i32Tmp ){
        LOGV("VideoEditorVideoEncoder_processOutputBuffer DSI %d",buffer->range_length());
        removeAVCCodecSpecificData(&data,&length,(const uint8_t*) buffer->data(),buffer->range_length(),NULL);
        buffer->set_range(buffer->range_offset() + length, buffer->range_length() - length);
    }

    // Check the CTS
    VIDEOEDITOR_CHECK(buffer->meta_data()->findInt64(kKeyTime, &i64Tmp),
        M4ERR_STATE);

    pEncoderContext->mNbOutputFrames++;
    if ( 0 > pEncoderContext->mFirstOutputCts ) {
        pEncoderContext->mFirstOutputCts = i64Tmp;
    }
    pEncoderContext->mLastOutputCts = i64Tmp;

    Cts = (M4OSA_Int32)(i64Tmp/1000);
    LOGV("[TS_CHECK] VI/ENC WRITE frame %d @ %lld -> %d (last %d)",
        pEncoderContext->mNbOutputFrames, i64Tmp, Cts,
        pEncoderContext->mLastCTS);
    if ( Cts < pEncoderContext->mLastCTS ) {
        LOGV("VideoEncoder_processOutputBuffer WARNING : Cts is going "
        "backwards %d < %d", Cts, pEncoderContext->mLastCTS);
        goto cleanUp;
    }
    LOGV("VideoEditorVideoEncoder_processOutputBuffer : %d %d",
        Cts, pEncoderContext->mLastCTS);

    // Retrieve the AU container
    err = pEncoderContext->mWriterDataInterface->pStartAU(
        pEncoderContext->mWriterDataInterface->pWriterContext,
        pEncoderContext->mAccessUnit->stream->streamID,
        pEncoderContext->mAccessUnit);
    VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);

    // Format the AU
    VIDEOEDITOR_CHECK(
        buffer->range_length() <= pEncoderContext->mAccessUnit->size,
        M4ERR_PARAMETER);
    // Remove H264 AU start code
    if ( M4ENCODER_kH264 == pEncoderContext->mFormat ) {
        if (!memcmp((const uint8_t *)buffer->data() + \
                buffer->range_offset(), "\x00\x00\x00\x01", 4) ) {
            buffer->set_range(buffer->range_offset() + 4,
                buffer->range_length() - 4);
        }
    }

    if ( (M4ENCODER_kH264 == pEncoderContext->mFormat) &&
        (M4OSA_NULL != pEncoderContext->mH264NALUPostProcessFct) ) {
    // H264 trimming case, NALU post processing is needed
        M4OSA_Int32 outputSize = pEncoderContext->mAccessUnit->size;
        err = pEncoderContext->mH264NALUPostProcessFct(
            pEncoderContext->mH264NALUPostProcessCtx,
            (M4OSA_UInt8*)buffer->data()+buffer->range_offset(),
            buffer->range_length(),
            (M4OSA_UInt8*)pEncoderContext->mAccessUnit->dataAddress,
            &outputSize);
        VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
        pEncoderContext->mAccessUnit->size = (M4OSA_UInt32)outputSize;
    } else {
        // The AU can just be copied
        memcpy((void *)pEncoderContext->mAccessUnit->\
            dataAddress, (void *)((M4OSA_MemAddr8)(buffer->data())+buffer->\
            range_offset()), buffer->range_length());
        pEncoderContext->mAccessUnit->size =
            (M4OSA_UInt32)buffer->range_length();
    }

    if ( buffer->meta_data()->findInt32(kKeyIsSyncFrame,&i32Tmp) && i32Tmp){
        pEncoderContext->mAccessUnit->attribute = AU_RAP;
    } else {
        pEncoderContext->mAccessUnit->attribute = AU_P_Frame;
    }
    pEncoderContext->mLastCTS = Cts;
    pEncoderContext->mAccessUnit->CTS = Cts;
    pEncoderContext->mAccessUnit->DTS = Cts;

    LOGV("VideoEditorVideoEncoder_processOutputBuffer: AU @ 0x%X 0x%X %d %d",
        pEncoderContext->mAccessUnit->dataAddress,
        *pEncoderContext->mAccessUnit->dataAddress,
        pEncoderContext->mAccessUnit->size,
        pEncoderContext->mAccessUnit->CTS);

    // Write the AU
    err = pEncoderContext->mWriterDataInterface->pProcessAU(
        pEncoderContext->mWriterDataInterface->pWriterContext,
        pEncoderContext->mAccessUnit->stream->streamID,
        pEncoderContext->mAccessUnit);
    VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);

cleanUp:
    if( M4NO_ERROR == err ) {
        LOGV("VideoEditorVideoEncoder_processOutputBuffer no error");
    } else {
        if (pEncoderContext != NULL) {
            SAFE_FREE(pEncoderContext->mHeader.pBuf);
            pEncoderContext->mHeader.Size = 0;
        }
        LOGV("VideoEditorVideoEncoder_processOutputBuffer ERROR 0x%X", err);
    }
    LOGV("VideoEditorVideoEncoder_processOutputBuffer end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_encode(M4ENCODER_Context pContext,
        M4VIFI_ImagePlane* pInPlane, M4OSA_Double Cts,
        M4ENCODER_FrameMode FrameMode) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
    status_t result = OK;
    MediaBuffer* outputBuffer = NULL;

    ALOGV("VideoEditorVideoEncoder_encode 0x%X %f %d", pInPlane, Cts, FrameMode);
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
    if ( STARTED == pEncoderContext->mState ) {
        pEncoderContext->mState = BUFFERING;
    }
    VIDEOEDITOR_CHECK(
        (BUFFERING | READING) & pEncoderContext->mState, M4ERR_STATE);

    pEncoderContext->mNbInputFrames++;
    if ( 0 > pEncoderContext->mFirstInputCts ) {
        pEncoderContext->mFirstInputCts = Cts;
    }
    pEncoderContext->mLastInputCts = Cts;

    ALOGV("VideoEditorVideoEncoder_encode 0x%X %d %f (%d)", pInPlane, FrameMode,
        Cts, pEncoderContext->mLastCTS);

    // Push the input buffer to the encoder source
    err = VideoEditorVideoEncoder_processInputBuffer(pEncoderContext, Cts,
        M4OSA_FALSE);
    VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);

    // Notify the source in case of EOS
    if ( M4ENCODER_kLastFrame == FrameMode ) {
        err = VideoEditorVideoEncoder_processInputBuffer(
            pEncoderContext, 0, M4OSA_TRUE);
        VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
    }

    if ( BUFFERING == pEncoderContext->mState ) {
        // Prefetch is complete, start reading
        pEncoderContext->mState = READING;
    }
    // Read
    while (1)  {
        MediaBuffer *outputBuffer =
                pEncoderContext->mPuller->getBufferNonBlocking();

        if (outputBuffer == NULL) {
            break;
        } else {
            // Provide the encoded AU to the writer
            err = VideoEditorVideoEncoder_processOutputBuffer(pEncoderContext,
                outputBuffer);
            VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);

            pEncoderContext->mPuller->putBuffer(outputBuffer);
        }
    }

cleanUp:
    if( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_encode no error");
    } else {
        ALOGV("VideoEditorVideoEncoder_encode ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_encode end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_start(M4ENCODER_Context pContext) {
    M4OSA_ERR                  err             = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
    status_t                   result          = OK;

    ALOGV("VideoEditorVideoEncoder_start begin");
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
    VIDEOEDITOR_CHECK(OPENED == pEncoderContext->mState, M4ERR_STATE);

    pEncoderContext->mNbInputFrames  = 0;
    pEncoderContext->mFirstInputCts  = -1.0;
    pEncoderContext->mLastInputCts   = -1.0;
    pEncoderContext->mNbOutputFrames = 0;
    pEncoderContext->mFirstOutputCts = -1;
    pEncoderContext->mLastOutputCts  = -1;

    result = pEncoderContext->mEncoder->start();
    VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);

    pEncoderContext->mPuller->start();

    // Set the new state
    pEncoderContext->mState = STARTED;

cleanUp:
    if ( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_start no error");
    } else {
        ALOGV("VideoEditorVideoEncoder_start ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_start end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_stop(M4ENCODER_Context pContext) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
    MediaBuffer* outputBuffer = NULL;
    status_t result = OK;

    ALOGV("VideoEditorVideoEncoder_stop begin");
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;

    // Send EOS again to make sure the source doesn't block.
    err = VideoEditorVideoEncoder_processInputBuffer(pEncoderContext, 0,
        M4OSA_TRUE);
    VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);

    // Process the remaining buffers if necessary
    if ( (BUFFERING | READING) & pEncoderContext->mState ) {
        while (1)  {
            MediaBuffer *outputBuffer =
                pEncoderContext->mPuller->getBufferBlocking();

            if (outputBuffer == NULL) break;

            err = VideoEditorVideoEncoder_processOutputBuffer(
                pEncoderContext, outputBuffer);
            VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);

            pEncoderContext->mPuller->putBuffer(outputBuffer);
        }

        pEncoderContext->mState = STARTED;
    }

    // Stop the graph module if necessary
    if ( STARTED == pEncoderContext->mState ) {
        pEncoderContext->mPuller->stop();
        pEncoderContext->mEncoder->stop();
        pEncoderContext->mState = OPENED;
    }

    if (pEncoderContext->mNbInputFrames != pEncoderContext->mNbOutputFrames) {
        ALOGW("Some frames were not encoded: input(%d) != output(%d)",
            pEncoderContext->mNbInputFrames, pEncoderContext->mNbOutputFrames);
    }

cleanUp:
    if ( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_stop no error");
    } else {
        ALOGV("VideoEditorVideoEncoder_stop ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_stop end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_regulBitRate(M4ENCODER_Context pContext) {
    ALOGW("regulBitRate is not implemented");
    return M4NO_ERROR;
}

M4OSA_ERR VideoEditorVideoEncoder_setOption(M4ENCODER_Context pContext,
        M4OSA_UInt32 optionID, M4OSA_DataOption optionValue) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;

    ALOGV("VideoEditorVideoEncoder_setOption start optionID 0x%X", optionID);
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);

    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;

    switch( optionID ) {
        case M4ENCODER_kOptionID_SetH264ProcessNALUfctsPtr:
            pEncoderContext->mH264NALUPostProcessFct =
                (H264MCS_ProcessEncodedNALU_fct*)optionValue;
            break;
        case M4ENCODER_kOptionID_H264ProcessNALUContext:
            pEncoderContext->mH264NALUPostProcessCtx =
                (M4OSA_Context)optionValue;
            break;
        default:
            ALOGV("VideoEditorVideoEncoder_setOption: unsupported optionId 0x%X",
                optionID);
            VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_BAD_OPTION_ID);
            break;
    }

cleanUp:
    if ( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_setOption no error");
    } else {
        ALOGV("VideoEditorVideoEncoder_setOption ERROR 0x%X", err);
    }
    ALOGV("VideoEditorVideoEncoder_setOption end");
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_getOption(M4ENCODER_Context pContext,
        M4OSA_UInt32 optionID, M4OSA_DataOption optionValue) {
    M4OSA_ERR err = M4NO_ERROR;
    VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;

    ALOGV("VideoEditorVideoEncoder_getOption begin optinId 0x%X", optionID);
    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
    pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;

    switch( optionID ) {
        case M4ENCODER_kOptionID_EncoderHeader:
            VIDEOEDITOR_CHECK(
                    M4OSA_NULL != pEncoderContext->mHeader.pBuf, M4ERR_STATE);
            *(M4ENCODER_Header**)optionValue = &(pEncoderContext->mHeader);
            break;
        default:
            ALOGV("VideoEditorVideoEncoder_getOption: unsupported optionId 0x%X",
                optionID);
            VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_BAD_OPTION_ID);
            break;
    }

cleanUp:
    if ( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_getOption no error");
    } else {
        ALOGV("VideoEditorVideoEncoder_getOption ERROR 0x%X", err);
    }
    return err;
}

M4OSA_ERR VideoEditorVideoEncoder_getInterface(M4ENCODER_Format format,
        M4ENCODER_Format* pFormat,
        M4ENCODER_GlobalInterface** pEncoderInterface, M4ENCODER_OpenMode mode){
    M4OSA_ERR err = M4NO_ERROR;

    // Input parameters check
    VIDEOEDITOR_CHECK(M4OSA_NULL != pFormat,           M4ERR_PARAMETER);
    VIDEOEDITOR_CHECK(M4OSA_NULL != pEncoderInterface, M4ERR_PARAMETER);

    ALOGV("VideoEditorVideoEncoder_getInterface begin 0x%x 0x%x %d", pFormat,
        pEncoderInterface, mode);

    SAFE_MALLOC(*pEncoderInterface, M4ENCODER_GlobalInterface, 1,
        "VideoEditorVideoEncoder");

    *pFormat = format;

    switch( format ) {
        case M4ENCODER_kH263:
            {
                (*pEncoderInterface)->pFctInit =
                    VideoEditorVideoEncoder_init_H263;
                break;
            }
        case M4ENCODER_kMPEG4:
            {
                (*pEncoderInterface)->pFctInit =
                    VideoEditorVideoEncoder_init_MPEG4;
                break;
            }
        case M4ENCODER_kH264:
            {
                (*pEncoderInterface)->pFctInit =
                    VideoEditorVideoEncoder_init_H264;
                break;
            }
        default:
            ALOGV("VideoEditorVideoEncoder_getInterface : unsupported format %d",
                format);
            VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_PARAMETER);
        break;
    }
    (*pEncoderInterface)->pFctOpen         = VideoEditorVideoEncoder_open;
    (*pEncoderInterface)->pFctStart        = VideoEditorVideoEncoder_start;
    (*pEncoderInterface)->pFctStop         = VideoEditorVideoEncoder_stop;
    (*pEncoderInterface)->pFctPause        = M4OSA_NULL;
    (*pEncoderInterface)->pFctResume       = M4OSA_NULL;
    (*pEncoderInterface)->pFctClose        = VideoEditorVideoEncoder_close;
    (*pEncoderInterface)->pFctCleanup      = VideoEditorVideoEncoder_cleanup;
    (*pEncoderInterface)->pFctRegulBitRate =
        VideoEditorVideoEncoder_regulBitRate;
    (*pEncoderInterface)->pFctEncode       = VideoEditorVideoEncoder_encode;
    (*pEncoderInterface)->pFctSetOption    = VideoEditorVideoEncoder_setOption;
    (*pEncoderInterface)->pFctGetOption    = VideoEditorVideoEncoder_getOption;

cleanUp:
    if( M4NO_ERROR == err ) {
        ALOGV("VideoEditorVideoEncoder_getInterface no error");
    } else {
        *pEncoderInterface = M4OSA_NULL;
        ALOGV("VideoEditorVideoEncoder_getInterface ERROR 0x%X", err);
    }
    return err;
}

extern "C" {

M4OSA_ERR VideoEditorVideoEncoder_getInterface_H263(M4ENCODER_Format* pFormat,
        M4ENCODER_GlobalInterface** pEncoderInterface, M4ENCODER_OpenMode mode){
    LOGI("VideoEditorVideoEncoder_getInterface_H263: Intel Version");
    return VideoEditorVideoEncoder_getInterface(M4ENCODER_kH263, pFormat,
            pEncoderInterface, mode);
}

M4OSA_ERR VideoEditorVideoEncoder_getInterface_MPEG4(M4ENCODER_Format* pFormat,
        M4ENCODER_GlobalInterface** pEncoderInterface, M4ENCODER_OpenMode mode){
    LOGI("VideoEditorVideoEncoder_getInterface_MPEG4: Intel Version");
    return VideoEditorVideoEncoder_getInterface(M4ENCODER_kMPEG4, pFormat,
           pEncoderInterface, mode);
}

M4OSA_ERR VideoEditorVideoEncoder_getInterface_H264(M4ENCODER_Format* pFormat,
        M4ENCODER_GlobalInterface** pEncoderInterface, M4ENCODER_OpenMode mode){
    LOGI("VideoEditorVideoEncoder_getInterface_H264: Intel Version");
    return VideoEditorVideoEncoder_getInterface(M4ENCODER_kH264, pFormat,
           pEncoderInterface, mode);

}

}  // extern "C"

}  // namespace android
