//framework
#include <binder/ProcessState.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
//#include <media/MediaPlayerInterface.h>

//libmix
#include <va/va_tpi.h>
#include <va/va_android.h>
#include <VideoEncoderHost.h>
#include <stdio.h>
#include <getopt.h>
#include <IntelMetadataBuffer.h>

#include <private/gui/ComposerService.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/IGraphicBufferAlloc.h>

#include <ui/PixelFormat.h>
#include <hardware/gralloc.h>
#include <hal/hal_public.h>
#include "loadsurface.h"

#include <binder/IMemory.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryDealer.h>

using namespace android;

#define ENABLE_LOG   true

#if ENABLE_LOG
//#define LOG(x, ...) printf("%s:"x, __FUNCTION__, ##__VA_ARGS__)
#define LOG  printf
#else
#define LOG(...)
#endif

enum {
    kYUV420SP = 0,
    kYUV420P  = 1,
};

static const int BOX_WIDTH = 64;
static const int PRELOAD_FRAME_NUM = 16;
uint32_t gNumFramesOutput = 0;

#define CHECK_ENC_STATUS(FUNC)\
    if (ret < ENCODE_SUCCESS) { \
        printf(FUNC" Failed. ret = 0x%08x\n", ret); \
        return UNKNOWN_ERROR; \
    }

#define CHECK_STATUS(err)\
    if (err != OK) { \
        printf("%s:%d: Failed. ret = 0x%08x\n", __FUNCTION__, __LINE__, err); \
        return err; \
    }

class DummySource : public MediaSource {

public:
    DummySource(int width, int height, int stride, int nFrames, int fps,
						bool metadata, const char* yuv)
        : mWidth(width),
          mHeight(height),
          mStride(stride),
          mMaxNumFrames(nFrames),
          mFrameRate(fps),
          mMetadata(metadata),
          mYuvfile(yuv),
          mYuvhandle(NULL){

        if (mMetadata)
            mSize = 128;
        else
            mSize = mStride * mHeight * 3 /2;

        for(int i=0; i<PRELOAD_FRAME_NUM; i++)
            mGroup.add_buffer(new MediaBuffer(mSize));

    }

    virtual sp<MetaData> getFormat() {
        sp<MetaData> meta = new MetaData;
        meta->setInt32(kKeyWidth, mWidth);
        meta->setInt32(kKeyHeight, mHeight);
        meta->setInt32(kKeyStride, mStride);
        meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar);
        meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);

        return meta;
    }

    virtual status_t start(MetaData *params) {
//        LOG("begin\n");
        gNumFramesOutput = 0;
        createResource ();

        if (mYuvfile == NULL) {
            //upload src data
            LOG("Fill src picture width=%d, Height=%d\n", mStride, mHeight);
            for(int i=0; i<PRELOAD_FRAME_NUM; i++)
                YUV_generator_planar(mStride, mHeight, mUsrptr[i], mStride, mUsrptr[i] + mStride*mHeight, mStride, 0, 0, 1);
        }else{
            mYuvhandle = fopen(mYuvfile, "rb");
            if (mYuvhandle == NULL)
                return errno;
        }
   //     LOG("end ...\n");
        return OK;
    }

    virtual status_t stop() {
        gNumFramesOutput = 0;
        return OK;
    }

    virtual status_t read(MediaBuffer **buffer, const MediaSource::ReadOptions *options) {

        if (gNumFramesOutput == mMaxNumFrames) {
            return ERROR_END_OF_STREAM;
        }

        status_t err = mGroup.acquire_buffer(buffer);
        if (err != OK) {
            return err;
        }

        if (mYuvhandle) {
            //load from yuv file
            size_t readsize = mStride*mHeight*3/2;
            size_t ret = 0;

            while (readsize > 0) {
                ret = fread(mUsrptr[gNumFramesOutput % PRELOAD_FRAME_NUM] + mStride*mHeight*3/2 - readsize,  1, readsize, mYuvhandle);

                if (ret <= 0) {
                    (*buffer)->release();
                    if (feof(mYuvhandle)) {
                        printf("Read from YUV file EOS");
                        return ERROR_END_OF_STREAM;
                    }else
                        return ferror(mYuvhandle);
                }
                readsize -= ret;

               // LOG("loading from file, ret=%d, readsize=%d\n", ret, readsize);
            }
        }

        uint8_t * data;
        uint32_t size;

        if (mMetadata) {
            mIMB[gNumFramesOutput % PRELOAD_FRAME_NUM]->Serialize(data, size);
            //LOG("use metadata mode\n");
        }else {
            data = mUsrptr[gNumFramesOutput % PRELOAD_FRAME_NUM];
            size = mSize;
        }

        memcpy ((*buffer)->data(), data, size);
        (*buffer)->set_range(0, size);
        (*buffer)->meta_data()->clear();
        (*buffer)->meta_data()->setInt64(
                kKeyTime, (gNumFramesOutput * 1000000) / mFrameRate);

        ++gNumFramesOutput;
        if (gNumFramesOutput % 10 ==0)
            fprintf(stderr, ".");
        return OK;
    }

    virtual status_t createResource() {
        return OK;
    }

protected:
    virtual ~DummySource() {
        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
            delete mIMB[i];
    }

private:

    int YUV_generator_planar(int width, int height,
                      unsigned char *Y_start, int Y_pitch,
                      unsigned char *U_start, int U_pitch,
                      unsigned char *V_start, int V_pitch,
                      int UV_interleave)
    {
        static int row_shift = 0;
        int row;

        /* copy Y plane */
        for (row=0;row<height;row++) {
            unsigned char *Y_row = Y_start + row * Y_pitch;
            int jj, xpos, ypos;

            ypos = (row / BOX_WIDTH) & 0x1;

            for (jj=0; jj<width; jj++) {
                xpos = ((row_shift + jj) / BOX_WIDTH) & 0x1;

                if ((xpos == 0) && (ypos == 0))
                    Y_row[jj] = 0xeb;
                if ((xpos == 1) && (ypos == 1))
                    Y_row[jj] = 0xeb;

                if ((xpos == 1) && (ypos == 0))
                    Y_row[jj] = 0x10;
                if ((xpos == 0) && (ypos == 1))
                    Y_row[jj] = 0x10;
            }
        }

        /* copy UV data */
        for( row =0; row < height/2; row++) {
            if (UV_interleave) {
                unsigned char *UV_row = U_start + row * U_pitch;
                memset (UV_row,0x80,width);
            } else {
                unsigned char *U_row = U_start + row * U_pitch;
                unsigned char *V_row = V_start + row * V_pitch;

                memset (U_row,0x80,width/2);
                memset (V_row,0x80,width/2);
            }
        }

        row_shift += 8;
//        if (row_shift==BOX_WIDTH) row_shift = 0;

        YUV_blend_with_pic(width,height,
                           Y_start, Y_pitch,
                           U_start, U_pitch,
                           V_start, V_pitch,
                           1, 70);

        return 0;
    }

protected:

    bool mMetadata;
    const char* mYuvfile;
    FILE* mYuvhandle;
    MediaBufferGroup mGroup;
    int mWidth, mHeight, mStride;
    int mMaxNumFrames;
    int mFrameRate;
    int mColorFormat;
    size_t mSize;
//    int64_t mNumFramesOutput;

    DummySource(const DummySource &);
    DummySource &operator=(const DummySource &);

//    int mMode = 0; //0:Camera malloc , 1: WiDi clone, 2: WiDi ext, 3: WiDi user, 4: Raw, 5: SurfaceMediaSource

    //for uploading src pictures, also for Camera malloc, WiDi clone, raw mode usrptr storage
    uint8_t* mUsrptr[PRELOAD_FRAME_NUM];

    //for Metadatabuffer transfer
    IntelMetadataBuffer* mIMB[PRELOAD_FRAME_NUM];

};

class MallocSource : public DummySource {
public:

    MallocSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
    }

    ~MallocSource() {
        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
            delete mMallocPtr[i];
    }

    //malloc external memory, and not need to set into encoder before start()
    status_t createResource()
    {
        uint32_t size = mStride * mHeight * 3 /2;

        ValueInfo vinfo;
        vinfo.mode = MEM_MODE_MALLOC;
        vinfo.handle = 0;
        vinfo.size = size;
        vinfo.width = mWidth;
        vinfo.height = mHeight;
        vinfo.lumaStride = mStride;
        vinfo.chromStride = mStride;
        vinfo.format = STRING_TO_FOURCC("NV12");
        vinfo.s3dformat = 0xFFFFFFFF;

        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
        {
            mMallocPtr[i] = (uint8_t*) malloc(size + 4095);

            //keep address 4K aligned
            mUsrptr[i] = (uint8_t*)((((uint32_t )mMallocPtr[i] + 4095) / 4096 ) * 4096);

            mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeCameraSource, (int32_t) mUsrptr[i]);
            mIMB[i]->SetValueInfo(&vinfo);
//            LOG("Malloc address=%x\n", mUsrptr[i]);
        }

        return OK;
    }

private:
    uint8_t* mMallocPtr[PRELOAD_FRAME_NUM];

};


class MemHeapSource : public DummySource {
public:

    MemHeapSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
    }

    ~MemHeapSource() {
//        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
  //          delete mMallocPtr[i];
    }

    //malloc external memory, and not need to set into encoder before start()
    status_t createResource()
    {
        uint32_t size = mStride * mHeight * 3 /2;

        ValueInfo vinfo;
        vinfo.mode = MEM_MODE_MALLOC;
        vinfo.handle = 0;
        vinfo.size = size;
        vinfo.width = mWidth;
        vinfo.height = mHeight;
        vinfo.lumaStride = mStride;
        vinfo.chromStride = mStride;
        vinfo.format = STRING_TO_FOURCC("NV12");
        vinfo.s3dformat = 0xFFFFFFFF;

        mHeap = new MemoryHeapBase(PRELOAD_FRAME_NUM * size);

        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
        {
            mBuffers[i] = new MemoryBase(mHeap, i * size, size);

            mUsrptr[i] = (uint8_t*) mBuffers[i]->pointer();

            mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeCameraSource, (int32_t) mUsrptr[i]);
            mIMB[i]->SetValueInfo(&vinfo);
            LOG("MemHeap address=%x\n", mUsrptr[i]);
        }

        return OK;
    }

private:
    sp<MemoryHeapBase> mHeap;
    sp<MemoryBase> mBuffers[PRELOAD_FRAME_NUM];

};

extern "C" {
    VAStatus vaLockSurface(VADisplay dpy,
        VASurfaceID surface,
        unsigned int *fourcc,
        unsigned int *luma_stride,
        unsigned int *chroma_u_stride,
        unsigned int *chroma_v_stride,
        unsigned int *luma_offset,
        unsigned int *chroma_u_offset,
        unsigned int *chroma_v_offset,
        unsigned int *buffer_name,
        void **buffer
    );

    VAStatus vaUnlockSurface(VADisplay dpy,
        VASurfaceID surface
    );
}

class VASurfaceSource : public DummySource {
public:
    VASurfaceSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
        mMode = 1;
    }

    virtual ~VASurfaceSource() {
        vaDestroySurfaces(mVADisplay, mSurfaces, PRELOAD_FRAME_NUM);
    }

    status_t createResource()
    {
        unsigned int display = 0;
        int majorVersion = -1;
        int minorVersion = -1;
        VAStatus vaStatus;

        mVADisplay = vaGetDisplay(&display);

        if (mVADisplay == NULL) {
            LOG("vaGetDisplay failed.");
        }

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

        VASurfaceAttributeTPI attribute_tpi;

        attribute_tpi.size = mWidth * mHeight * 3 /2;
        attribute_tpi.luma_stride = mWidth;
        attribute_tpi.chroma_u_stride = mWidth;
        attribute_tpi.chroma_v_stride = mWidth;
        attribute_tpi.luma_offset = 0;
        attribute_tpi.chroma_u_offset = mWidth * mHeight;
        attribute_tpi.chroma_v_offset = mWidth * mHeight;
        attribute_tpi.pixel_format = VA_FOURCC_NV12;
        attribute_tpi.type = VAExternalMemoryNULL;

        vaStatus = vaCreateSurfacesWithAttribute(mVADisplay, mWidth, mHeight, VA_RT_FORMAT_YUV420,
                PRELOAD_FRAME_NUM, mSurfaces, &attribute_tpi);

        if (vaStatus != VA_STATUS_SUCCESS) {
            LOG( "Failed vaCreateSurfaces, vaStatus = %d\n", vaStatus);
        }

        if (mMode == 1){
            uint32_t fourCC = 0;
            uint32_t lumaStride = 0;
            uint32_t chromaUStride = 0;
            uint32_t chromaVStride = 0;
            uint32_t lumaOffset = 0;
            uint32_t chromaUOffset = 0;
            uint32_t chromaVOffset = 0;

            for(int i = 0; i < PRELOAD_FRAME_NUM; i++) {
                vaStatus = vaLockSurface(
                        mVADisplay, (VASurfaceID)mSurfaces[i],
                        &fourCC, &lumaStride, &chromaUStride, &chromaVStride,
                        &lumaOffset, &chromaUOffset, &chromaVOffset, &mKBufHandle[i], NULL);
                if (vaStatus != VA_STATUS_SUCCESS) {
                     LOG( "Failed vaLockSurface, vaStatus = %d\n", vaStatus);
                }
#if 0
                LOG("lumaStride = %d", lumaStride);
                LOG("chromaUStride = %d\n", chromaUStride);
                LOG("chromaVStride = %d\n", chromaVStride);
                LOG("lumaOffset = %d\n", lumaOffset);
                LOG("chromaUOffset = %d\n", chromaUOffset);
                LOG("chromaVOffset = %d\n", chromaVOffset);
                LOG("kBufHandle = 0x%08x\n", mKBufHandle[i]);
                LOG("fourCC = %d\n", fourCC);
#endif
                vaStatus = vaUnlockSurface(mVADisplay, (VASurfaceID)mSurfaces[i]);

            }
        }

        //get usrptr for uploading src pictures
        VAImage surface_image;
        ValueInfo vinfo;
        memset(&vinfo, 0, sizeof(ValueInfo));
        vinfo.mode = MEM_MODE_SURFACE;
        vinfo.handle = (uint32_t) mVADisplay;
        vinfo.size = 0;
        vinfo.width = mWidth;
        vinfo.height = mHeight;
        vinfo.lumaStride = mStride;
        vinfo.chromStride = mStride;
        vinfo.format = STRING_TO_FOURCC("NV12");
        vinfo.s3dformat = 0xFFFFFFFF;

        for (int i = 0; i < PRELOAD_FRAME_NUM; i++) {
            vaStatus = vaDeriveImage(mVADisplay, mSurfaces[i], &surface_image);
            if (vaStatus != VA_STATUS_SUCCESS) {
                LOG("Failed vaDeriveImage, vaStatus = %d\n", vaStatus);
            }

            vaMapBuffer(mVADisplay, surface_image.buf, (void**)&mUsrptr[i]);
            if (vaStatus != VA_STATUS_SUCCESS) {
                LOG("Failed vaMapBuffer, vaStatus = %d\n", vaStatus);
            }

            vaUnmapBuffer(mVADisplay, surface_image.buf);
            vaDestroyImage(mVADisplay, surface_image.image_id);



            if (mMode == 0)
                mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeUser, mSurfaces[i]);
            else {
                mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeUser, mKBufHandle[i]);
                vinfo.mode = MEM_MODE_KBUFHANDLE;
                vinfo.handle = 0;
            }

            mIMB[i]->SetValueInfo(&vinfo);
        }

        return OK;
    }

private:
    //for WiDi user mode
    VADisplay mVADisplay;
    VASurfaceID mSurfaces[PRELOAD_FRAME_NUM];

    //for WiDi ext mode
    uint32_t mKBufHandle[PRELOAD_FRAME_NUM];
    int mMode;
};


class GfxSource : public DummySource {

public:
    GfxSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
        mColor = 0;
        mWidth = ((mWidth + 15 ) / 16 ) * 16;
        mHeight = ((mHeight + 15 ) / 16 ) * 16;
        mStride = mWidth;
    }

    virtual ~GfxSource() {
  //      for(int i=0; i<PRELOAD_FRAME_NUM; i++)
      //      delete mGraphicBuffer[i];
    }

    status_t createResource()
    {
        sp<ISurfaceComposer> composer(ComposerService::getComposerService());
        mGraphicBufferAlloc = composer->createGraphicBufferAlloc();

        uint32_t usage = GraphicBuffer::USAGE_HW_TEXTURE;// | GraphicBuffer::USAGE_HW_COMPOSER;
        int format = HAL_PIXEL_FORMAT_NV12;
        if (mColor == 1)
            format = 0x7FA00E00; // = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar in OMX_IVCommon.h

        int32_t error;

        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
        {
            sp<GraphicBuffer> graphicBuffer(
                    mGraphicBufferAlloc->createGraphicBuffer(
                                    mWidth, mHeight, format, usage, &error));

            if (graphicBuffer.get() == NULL) {
                printf("GFX createGraphicBuffer failed\n");
                return UNKNOWN_ERROR;
            }
            mGraphicBuffer[i] = graphicBuffer;
            graphicBuffer->lock(usage | GraphicBuffer::USAGE_SW_WRITE_OFTEN |GraphicBuffer::USAGE_SW_READ_OFTEN, (void**)(&mUsrptr[i]));

            mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeGrallocSource, (int32_t)mGraphicBuffer[i]->handle);
            graphicBuffer->unlock();

            IMG_native_handle_t* h = (IMG_native_handle_t*) mGraphicBuffer[i]->handle;
            mStride = h->iWidth;
            mHeight = h->iHeight;

//printf("mStride=%d, height=%d, format=%x", mStride, mHeight, h->iFormat);
        }

        return OK;
    }

private:
    //for gfxhandle
    sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
    sp<GraphicBuffer> mGraphicBuffer[PRELOAD_FRAME_NUM];

    int mColor;
};

class GrallocSource : public DummySource {

public:
    GrallocSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
    }

    virtual ~GrallocSource () {
        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
            gfx_free(mHandle[i]);
    }

    status_t createResource()
    {
        int usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER;
        int format = HAL_PIXEL_FORMAT_NV12;
        if (mColor == 1)
            format = 0x7FA00E00; // = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar in OMX_IVCommon.h

        gfx_init();

        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
        {
            if (gfx_alloc(mWidth, mHeight, format, usage, &mHandle[i], (int32_t*)&mStride) != 0)
                return UNKNOWN_ERROR;
            if (gfx_lock(mHandle[i], usage | GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, mWidth, mHeight, (void**)(&mUsrptr[i])) != 0)
                return UNKNOWN_ERROR;
            mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeGrallocSource, (int32_t)mHandle[i]);
            gfx_unlock(mHandle[i]);
            IMG_native_handle_t* h = (IMG_native_handle_t*) mHandle[i];
            mHeight = h->iHeight;
        }

        return OK;
    }

private:
    void gfx_init()
    {
        int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mModule);
        if (err) {
            LOG("FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
            return;
        }

        mAllocMod = (gralloc_module_t const *)mModule;

        err = gralloc_open(mModule, &mAllocDev);
        if (err) {
            LOG("FATAL: gralloc open failed\n");
        }

    }

    int gfx_alloc(uint32_t w, uint32_t h, int format,
              int usage, buffer_handle_t* handle, int32_t* stride)
    {
        int err;

        err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);
        if (err) {
            LOG("alloc(%u, %u, %d, %08x, ...) failed %d (%s)\n",
                   w, h, format, usage, err, strerror(-err));
        }

        return err;
    }

    int gfx_free(buffer_handle_t handle)
    {
        int err;

        err = mAllocDev->free(mAllocDev, handle);
        if (err) {
            LOG("free(...) failed %d (%s)\n", err, strerror(-err));
        }

        return err;
    }

    int gfx_lock(buffer_handle_t handle,
                int usage, int left, int top, int width, int height,
                void** vaddr)
    {
        int err;

        err = mAllocMod->lock(mAllocMod, handle, usage,
                              left, top, width, height, vaddr);

        if (err){
            LOG("lock(...) failed %d (%s)", err, strerror(-err));
        }

        return err;
    }


    int gfx_unlock(buffer_handle_t handle)
    {
        int err;

        err = mAllocMod->unlock(mAllocMod, handle);
        if (err) {
            LOG("unlock(...) failed %d (%s)\n", err, strerror(-err));
        }

        return err;
    }

private:
    hw_module_t const *mModule;
    gralloc_module_t const *mAllocMod; /* get by force hw_module_t */
    alloc_device_t  *mAllocDev; /* get by gralloc_open */

    buffer_handle_t mHandle[PRELOAD_FRAME_NUM];
    int mColor;
};

static const char *AVC_MIME_TYPE = "video/h264";
static const char *MPEG4_MIME_TYPE = "video/mpeg4";
static const char *H263_MIME_TYPE = "video/h263";

class MixEncoder : public MediaSource {

public:
    MixEncoder(const sp<MediaSource> &source, const sp<MetaData> &meta, int rcmode, uint32_t flag) {
        mFirstFrame = false;
        mSrcEOS = false;
        mEncoderFlag = flag;
        mEncodeFrameCount = 0;
        mSource = source;

        const char *mime;
        bool success = meta->findCString(kKeyMIMEType, &mime);
        CHECK(success);

        mCodec = mime;
        if (strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) == 0) {
            mMixCodec = (char*) MPEG4_MIME_TYPE;
        } else if (strcmp(mime, MEDIA_MIMETYPE_VIDEO_H263) == 0) {
            mMixCodec = (char*) H263_MIME_TYPE;
        } else {
            mMixCodec = (char*) AVC_MIME_TYPE;
        }

        success = meta->findInt32(kKeyWidth, &mWidth);
        CHECK(success);

        success = meta->findInt32(kKeyHeight, &mHeight);
        CHECK(success);

        success = meta->findInt32(kKeyFrameRate, &mFPS);
        CHECK(success);

        success = meta->findInt32(kKeyBitRate, &mBitrate);
        CHECK(success);

        success = meta->findInt32('itqp', &mInitQP);
        CHECK(success);

        success = meta->findInt32('mnqp', &mMinQP);
        CHECK(success);

        success = meta->findInt32('iapd', &mIntraPeriod);
        CHECK(success);

        success = meta->findInt32('wsiz', &mWinSize);
        CHECK(success);

        success = meta->findInt32('idri', &mIdrInt);
        CHECK(success);

        success = meta->findInt32('difs', &mDisableFrameSkip);
        CHECK(success);

//    const char *RCMODE[] = {"VBR", "CBR", "VCM", "NO_RC", NULL};
        VideoRateControl RC_MODES[] = {RATE_CONTROL_VBR,
        							RATE_CONTROL_CBR,
        							RATE_CONTROL_VCM,
        							RATE_CONTROL_NONE};

        mRCMode = RC_MODES[rcmode];
    }

    virtual sp<MetaData> getFormat() {
        sp<MetaData> meta = new MetaData;
        meta->setInt32(kKeyWidth, mWidth);
        meta->setInt32(kKeyHeight, mHeight);
//        meta->setInt32(kKeyColorFormat, mColorFormat);
        meta->setCString(kKeyMIMEType, mCodec);
        return meta;
    }

    virtual status_t start(MetaData *params) {
        Encode_Status ret;
        status_t err;

        //create video encoder
        mVideoEncoder = createVideoEncoder(mMixCodec);
        if (!mVideoEncoder) {
            printf("MIX::createVideoEncoder failed\n");
            return UNKNOWN_ERROR;
        }

        //set parameter
        err = SetVideoEncoderParam();
        CHECK_STATUS(err);

        //start
        ret = mVideoEncoder->start();
        CHECK_ENC_STATUS("MIX::Start");

        uint32_t maxsize;
        mVideoEncoder->getMaxOutSize(&maxsize);
        mGroup.add_buffer(new MediaBuffer(maxsize));
        mGroup.add_buffer(new MediaBuffer(maxsize));
        mGroup.add_buffer(new MediaBuffer(maxsize));

        return mSource->start();
    }

    virtual status_t stop() {
        Encode_Status ret;

        ret = mVideoEncoder->stop();
        CHECK_ENC_STATUS("MIX::stop");

        return OK;
    }

    status_t encode(MediaBuffer* in) {
        status_t  err = OK;
        Encode_Status ret;

        VideoEncRawBuffer InBuf;
        InBuf.data = (uint8_t *) in->data() + in->range_offset();
        InBuf.size = in->range_length();
        InBuf.bufAvailable = true;
        InBuf.type = FTYPE_UNKNOWN;
        InBuf.flag = 0;
        in->meta_data()->findInt64(kKeyTime, &InBuf.timeStamp);
        InBuf.priv = (void*)in;

#if 0
        if (mEncodeFrameCount > 1 && mEncodeFrameCount % 60 == 0){
            VideoParamConfigSet configIDRRequest;
            configIDRRequest.type = VideoConfigTypeIDRRequest;
            mVideoEncoder->setConfig(&configIDRRequest);
            printf("MIX::encode request IDR\n");
        }
#endif
        ret = mVideoEncoder->encode(&InBuf);
        if (ret < ENCODE_SUCCESS) {
            printf("MIX::encode failed, ret=%d\n", ret);
            in->release();
            return UNKNOWN_ERROR;
        }

        mEncodeFrameCount ++;
        return err;
    }

    status_t getoutput(MediaBuffer* out, VideoOutputFormat format) {
        Encode_Status ret;

        VideoEncOutputBuffer OutBuf;
        OutBuf.bufferSize = out->size() ;
        OutBuf.dataSize = 0;
        OutBuf.data = (uint8_t *) out->data() + out->range_offset();
        OutBuf.format = format;
        OutBuf.flag = 0;
        OutBuf.timeStamp = 0;

        ret = mVideoEncoder->getOutput(&OutBuf);
        if (ret < ENCODE_SUCCESS) {
            if ((ret == ENCODE_NO_REQUEST_DATA) && (strcmp(mMixCodec, H263_MIME_TYPE) == 0)) {
                printf("H263 FrameSkip happens at Frame #%d\n", mEncodeFrameCount);
                OutBuf.dataSize = 0;
            } else {
                printf("MIX::getOutput failed, ret=%d\n", ret);
                out->release();
                return UNKNOWN_ERROR;
            }
        }

        out->set_range(0, OutBuf.dataSize);
        out->meta_data()->clear();
        out->meta_data()->setInt64(kKeyTime, OutBuf.timeStamp);
        out->meta_data()->setInt64(kKeyDecodingTime, OutBuf.timeStamp);

        bool isSync = (OutBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME);
        bool isCsd = (OutBuf.flag & ENCODE_BUFFERFLAG_CODECCONFIG);
        out->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
        out->meta_data()->setInt32(kKeyIsCodecConfig, isCsd);

        //for h263 frame skip case, ENCODE_NO_REQUEST_DATA is returned, but priv is not set.
        //to handle properly, need to change libmix to set priv in outbuf even in wrong case
        if (format != OUTPUT_CODEC_DATA && (ret != ENCODE_NO_REQUEST_DATA)) {
            MediaBuffer* in = (MediaBuffer*) OutBuf.priv;
            in->release();
        }

        return OK;
    }

    virtual status_t read(MediaBuffer **buffer, const MediaSource::ReadOptions *options) {

        status_t  err;
        Encode_Status ret;

        if (mSrcEOS)
            return ERROR_END_OF_STREAM;

        //write rest data of first frame after outputting csd, only for H264/MPEG4
        if (mFirstFrame) {
            err = mGroup.acquire_buffer(buffer);
            CHECK_STATUS(err);

            err = getoutput(*buffer, OUTPUT_EVERYTHING);
            CHECK_STATUS(err);

            mFirstFrame = false;
            return OK;
        }

        //input buffers
        int loop=1;
        if (mEncodeFrameCount == 0)
            loop = 2;

        for(int i=0; i<loop; i++) {
            MediaBuffer *src;

            err = mSource->read (&src);
            if (err == ERROR_END_OF_STREAM) {
                LOG ("\nReach Resource EOS, still need to get final frame encoded data\n");
                mSrcEOS = true;
            }else {
                CHECK_STATUS(err);

                err = encode(src);
                CHECK_STATUS(err);
            }
        }

        //output buffers
        err = mGroup.acquire_buffer(buffer);
        CHECK_STATUS(err);

        VideoOutputFormat format;
        if (mEncodeFrameCount == 2 && (strcasecmp(mMixCodec, H263_MIME_TYPE) != 0)) {
            format = OUTPUT_CODEC_DATA;
            mFirstFrame = true;
        }else
            format = OUTPUT_EVERYTHING;

        err = getoutput(*buffer, format);
        CHECK_STATUS(err);

        return OK;
    }

    virtual ~MixEncoder() {
        releaseVideoEncoder(mVideoEncoder);
    }

private:

    MixEncoder(const MixEncoder &);
    MixEncoder &operator=(const MixEncoder &);

    status_t SetVideoEncoderParam() {

        Encode_Status ret = ENCODE_SUCCESS;

        ret = mVideoEncoder->getParameters(&mEncoderParams);
        CHECK_ENC_STATUS("MIX::getParameters");

        LOG("Set Encoding Width=%d, Height=%d\n", mWidth, mHeight);
        mEncoderParams.resolution.height = mHeight;
        mEncoderParams.resolution.width = mWidth;
        mEncoderParams.frameRate.frameRateDenom = 1;
        mEncoderParams.frameRate.frameRateNum = mFPS;
        mEncoderParams.rcMode = mRCMode;

        if (strcmp(mMixCodec, MPEG4_MIME_TYPE) == 0) {
            mEncoderParams.profile = (VAProfile)VAProfileMPEG4Simple;
        } else if (strcmp(mMixCodec, H263_MIME_TYPE) == 0) {
            mEncoderParams.profile = (VAProfile)VAProfileH263Baseline;
        } else {
            mEncoderParams.profile = (VAProfile)VAProfileH264Baseline;
        }

        mEncoderParams.rcParams.bitRate = mBitrate;
        mEncoderParams.rcParams.initQP = mInitQP;
        mEncoderParams.rcParams.minQP = mMinQP;
        mEncoderParams.rcParams.windowSize = mWinSize;
        mEncoderParams.intraPeriod = mIntraPeriod;

        ret = mVideoEncoder->setParameters(&mEncoderParams);
        CHECK_ENC_STATUS("MIX::setParameters VideoParamsCommon");

        mStoreMetaDataInBuffers.isEnabled = (mEncoderFlag & OMXCodec::kStoreMetaDataInVideoBuffers);

        ret = mVideoEncoder->setParameters(&mStoreMetaDataInBuffers);
        CHECK_ENC_STATUS("MIX::setParameters StoreMetaDataInBuffers");

        if (strcmp(mMixCodec, MPEG4_MIME_TYPE) == 0) {
            VideoParamsAVC AVCParam;
            mVideoEncoder->getParameters(&AVCParam);
            AVCParam.idrInterval = mIdrInt;
            mVideoEncoder->setParameters(&AVCParam);
        }

#if 1
        VideoConfigBitRate configBitrate;
        mVideoEncoder->getConfig(&configBitrate);
        configBitrate.rcParams.disableBitsStuffing = 0;
        configBitrate.rcParams.disableFrameSkip = mDisableFrameSkip;
        mVideoEncoder->setConfig(&configBitrate);
#endif
        return OK;
    }

private:

    const char* mMixCodec;
    const char* mCodec;
    int mBitrate;
    int mWidth;
    int mHeight;
    int mFPS;
    int mIntraPeriod;
    int mEncodeFrameCount;
    uint32_t mEncoderFlag;
    int mInitQP;
    int mMinQP;
    int mWinSize;
    int mIdrInt;
    int mDisableFrameSkip;

//    int mSyncMode;
    bool mFirstFrame;
    bool mSrcEOS;

    IVideoEncoder *mVideoEncoder;
    VideoParamsCommon mEncoderParams;
    VideoParamsAVC mVideoParamsAVC;
    VideoParamsStoreMetaDataInBuffers mStoreMetaDataInBuffers;
    VideoRateControl mRCMode;

    sp<MediaSource> mSource;
    MediaBufferGroup mGroup;

};

class RawWriter : public MediaWriter {
public:
    RawWriter(char* file) {
        mFile = file;
        mRunning = false;
    }

    status_t addSource(const sp<MediaSource> &source) {
        mSource = source;
        return OK;
    }

    bool reachedEOS() {
        return mEOS;
    }

    status_t start(MetaData *params = NULL) {

        mSource->start();

        mRunning = true;
        mEOS = false;

        mFilehandle = fopen(mFile, "w+");
        if (mFilehandle == NULL)
            return errno;

        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

        pthread_create(&mThread, &attr, RawWriter::ThreadFunc, this);
        pthread_attr_destroy(&attr);

        return OK;
    }

    status_t stop() {
        mRunning = false;
        void *dummy;
        pthread_join(mThread, &dummy);
        fclose(mFilehandle);
        return OK;
    }

    status_t pause() {
        return OK;
    }

private:
    static void *ThreadFunc(void *me) {
        RawWriter *writer = static_cast<RawWriter *>(me);

        status_t err = OK;

        while (writer->mRunning) {
            MediaBuffer* buffer;
            err = writer->mSource->read(&buffer, NULL);

            if (err == OK) {
                fwrite(buffer->data()+buffer->range_offset(), 1, buffer->range_length(), writer->mFilehandle);
//                LOG("RawWriter::threadfunc fwrite size=%d\n", buffer->range_length());
                buffer->release();
                continue;
            }else {
                if (err != ERROR_END_OF_STREAM)
                    LOG("RawWriter::threadfunc err=%d\n", err);
                writer->mEOS = true;
                writer->mRunning = false;
                fflush(writer->mFilehandle);
                return NULL;
            }
        }

        return NULL;
    }

public:

    const char* mFile;
    FILE* mFilehandle;
    sp<MediaSource> mSource;
    pthread_t mThread;
    bool mRunning;
    bool mEOS;
};


void usage() {
    printf("2nd generation Mix_encoder\n");
    printf("Usage: mix_encoder2 [options]\n\n");
    printf(" -a/--initQP <qp>					set initQP, default 0\n");
    printf(" -b/--bitrate <Bitrate>				set bitrate bps, default 10M\n");
    printf(" -c/--codec <Codec>				select codec, like H264(default), MPEG4, H263\n");
    printf(" -d/--intraPeriod <period>			set IntraPeriod, default 30\n");
    printf(" -e/--encoder	 <encoder>			select encoder, like MIX(default), OMXCODEC\n");
    printf(" -f <output file>				set output file name\n");
    printf(" -i/--yuv <yuvfile>				select yuv generate method, AUTO(default) or from yuv file\n");
    printf(" -j/--winSize						set window size, default 1000\n");
    printf(" -k/--encWidth <Width> -g/--encHeight <Hight>	set encoder width/height, default 1280*720\n");
    printf(" -l/--idrInterval					set IdrInterval, default 1\n");
    printf(" -m/--disableMetadata				disable Metadata Mode(default enabled)\n");
    printf(" -n/--count <number>				set source frame number, default 30\n");
    printf(" -o/--outputformat <format>			set output file format, like MP4(default), RAW\n");
    printf(" -p/--fps <Bitrate>				set frame rate, default 30\n");
    printf(" -q/--minQP <qp>					set minQP, default 0\n");
    printf(" -r/--rcMode <Mode>				set rc mode, like VBR(default), CBR, VCM, NO_RC\n");
    printf(" -s/--src <source>				select source, like MALLOC(default), VASURFACE, GFX, GRALLOC, CAMERASOURCE, MEMHEAP\n");
    printf(" -w <Width> -h <Height>				set source width /height, default 1280*720\n");
    printf(" -t/--disableFrameSkip				disable frame skip, default is false\n");
    printf("\n");

}

int main(int argc, char* argv[])
{
    int SrcType = 0;
    int SrcWidth = 1280;
    int SrcHeight = 720;
    int SrcStride = 1280;
    int SrcFrameNum = 30;
    bool MetadataMode = true;
    bool SoftCodec = false;
    int SrcFps = 30;
    int EncType = 0;
    int EncCodec = 0;
    int EncRCMode = 0;
    int EncBitrate = 10000000;
    int EncWidth = 1280;
    int EncHeight = 720;
    int InitQP = 0;
    int MinQP = 0;
    int WinSize = 1000;
    int IdrInt = 1;
    int IntraPeriod = 30;
    int DisableFrameSkip = 0;
    int OutFormat = 0;
//    bool SyncMode = false;
    char* OutFileName = "out.264";
    const char* Yuvfile = NULL;

    android::ProcessState::self()->startThreadPool();

    const char *short_opts = "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:q:u:v:w:x:y:z:?";
    const struct option long_opts[] = {
						{"help", no_argument, NULL, '?'},
						{"file", required_argument, NULL, 'f'},
						{"src", required_argument, NULL, 's'},
						{"yuv", required_argument, NULL, 'i'},
						{"srcWidth", required_argument, NULL, 'w'},
						{"srcHeight", required_argument, NULL, 'h'},
						{"disableMetadata", no_argument, NULL, 'm'},
						{"count", required_argument, NULL, 'n'},
						{"encoder", required_argument, NULL, 'e'},
						{"codec", required_argument, NULL, 'c'},
						{"bitrate", required_argument, NULL, 'b'},
						{"output", required_argument, NULL, 'o'},
						{"fps", required_argument, NULL, 'p'},
						{"rcMode", required_argument, NULL, 'r'},
						{"encWidth", required_argument, NULL, 'k'},
						{"encHeight", required_argument, NULL, 'g'},
						{"initQP", required_argument, NULL, 'a'},
						{"minQP", required_argument, NULL, 'q'},
						{"intraPeriod", required_argument, NULL, 'd'},
						{"winSize", required_argument, NULL, 'j'},
						{"idrInt", required_argument, NULL, 'l'},
						{"disableFrameSkip", no_argument, NULL, 't'},
						{0, 0, 0, 0}
    };

    char c;

    const char *SRCTYPE[] = {"MALLOC", "VASURFACE", "GFX", "GRALLOC",
						"CAMERASOURCE", "SURFACEMEDIASOURCE", "MEMHEAP", NULL};
    const char *ENCTYPE[] = {"MIX", "OMXCODEC", NULL};
    const char *CODEC[] = {"H264", "MPEG4", "H263", NULL};
    const char *RCMODE[] = {"VBR", "CBR", "VCM", "NO_RC", NULL};
    const char *OUTFORMAT[] = {"MP4", "RAW", NULL};

    while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL) ) != EOF) {
        switch (c) {
                case 'a':
                    InitQP = atoi(optarg);
                    break;

                case 'b':
                    EncBitrate = atoi(optarg);
                    break;

                case 'c':
                    for (int i = 0; CODEC[i] != NULL; i++) {
                        if (strcasecmp (optarg, CODEC[i]) == 0) {
                            EncCodec = i;
                            break;
                        }else
                            continue;
                    }

                    break;

                case 'd':
                    IntraPeriod = atoi(optarg);
                    break;

                case 'e':
                    for (int i = 0; ENCTYPE[i] != NULL; i++) {
                        if (strcasecmp (optarg, ENCTYPE[i]) == 0) {
                            EncType = i;
                            break;
                        }else
                            continue;
                    }

                    break;

                case 'f':
                    OutFileName = optarg;
                    break;

                case 'g':
                    EncHeight = atoi(optarg);
                    break;

                case 'h':
                    SrcHeight = atoi(optarg);
                    EncHeight = SrcHeight;
                    break;

                case 'i':
                    if (strcasecmp (optarg, "AUTO") == 0)
                        Yuvfile = NULL;
                    else
                        Yuvfile = optarg;

                    break;

                case 'j':
                    WinSize = atoi(optarg);
                    break;

                case 'k':
                    EncWidth = atoi(optarg);
                    break;

                case 'l':
                    IdrInt = atoi(optarg);
                    break;

                case 'm':
                    MetadataMode = false;
                    break;

                case 'n':
                    SrcFrameNum = atoi(optarg);
                    break;

                case 'o':
                    for (int i = 0; OUTFORMAT[i] != NULL; i++) {
                        if (strcasecmp (optarg, OUTFORMAT[i]) == 0) {
                            OutFormat = i;
                            break;
                        }else
                            continue;
                    }

                    break;

                case 'p':
                    SrcFps = atoi(optarg);
                    break;

                case 'q':
                    MinQP = atoi(optarg);
                    break;

                case 'r':
                    for (int i = 0; RCMODE[i] != NULL; i++) {
                        if (strcasecmp (optarg, RCMODE[i]) == 0) {
                            EncRCMode = i;
                            break;
                        }else
                            continue;
                    }

                    break;

                case 's':
                    for (int i = 0; SRCTYPE[i] != NULL; i++) {
                        if (strcasecmp (optarg, SRCTYPE[i]) == 0) {
                            SrcType = i;
                            break;
                        }else
                            continue;
                    }

                    break;

                case 't':
                    DisableFrameSkip = 1;
                    break;

                case 'w':
                    SrcWidth = atoi(optarg);
                    SrcStride = SrcWidth;
                    EncWidth = SrcWidth;
                    break;

                case '?':
                default:
                    usage();
                    exit(0);
        }
    }

    //export encoding parameters summary
    printf("=========================================\n");
    printf("Source:\n");
    printf("Type: %s, Width: %d, Height: %d, Stride: %d\n", SRCTYPE[SrcType], SrcWidth, SrcHeight, SrcStride);
    printf("FPS: %d, YUV: %s, Metadata: %d\n", SrcFps, Yuvfile, MetadataMode);

    printf("\nEncoder:\n");
    printf("Type: %s, Codec: %s, Width: %d, Height: %d\n", ENCTYPE[EncType], CODEC[EncCodec], EncWidth, EncHeight);
    printf("RC: %s, Bitrate: %d bps, initQP: %d, minQP: %d\n", RCMODE[EncRCMode], EncBitrate, InitQP, MinQP);
    printf("winSize: %d, IdrInterval: %d, IntraPeriod: %d, FPS: %d \n", WinSize, IdrInt, IntraPeriod, SrcFps);
    printf("Frameskip: %d\n", !DisableFrameSkip);

    printf("\nOut:\n");
    printf("Type: %s, File: %s\n", OUTFORMAT[OutFormat], OutFileName);
    printf("=========================================\n");

    sp<MediaSource> source;
    sp<MediaSource> encoder;
    sp<MediaWriter> writer;

    //setup source
    if (SrcType == 0) {
        source = new MallocSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
			SrcFps, MetadataMode, Yuvfile);
    } else if (SrcType == 1) {
        source = new VASurfaceSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
			SrcFps, MetadataMode, Yuvfile);
    } else if (SrcType == 2) {
        source = new GfxSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
			SrcFps, MetadataMode, Yuvfile);
    } else if (SrcType == 3) {
        source = new GrallocSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
			SrcFps, MetadataMode, Yuvfile);
    } else if (SrcType == 4) {
//        source = new CameraSource();
    } else if (SrcType == 5) {
 //       source = new SurfaceMediaSource();
    } else if (SrcType == 6) {
        source = new MemHeapSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
			SrcFps, MetadataMode, Yuvfile);
    }

    printf("Setup Encoder\n");
    //setup encoder
    sp<MetaData> enc_meta = new MetaData;
    switch (EncCodec) {
        case 1:
            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
            break;
        case 2:
            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
            break;
        default:
            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
            break;
    }

    enc_meta->setInt32(kKeyWidth, EncWidth);
    enc_meta->setInt32(kKeyHeight, EncHeight);
    enc_meta->setInt32(kKeyFrameRate, SrcFps);
    enc_meta->setInt32(kKeyBitRate, EncBitrate);
    enc_meta->setInt32(kKeyStride, EncWidth);
    enc_meta->setInt32(kKeySliceHeight, EncHeight);
    enc_meta->setInt32(kKeyIFramesInterval, 1);
    enc_meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar);

    //only valid for MIX encoder
    enc_meta->setInt32('itqp', InitQP);
    enc_meta->setInt32('mnqp', MinQP);
    enc_meta->setInt32('iapd', IntraPeriod);
    enc_meta->setInt32('wsiz', WinSize);
    enc_meta->setInt32('idri', WinSize);
    enc_meta->setInt32('difs', DisableFrameSkip);

    uint32_t encoder_flags = 0;
    if (MetadataMode)
        encoder_flags |= OMXCodec::kStoreMetaDataInVideoBuffers;
    if (SoftCodec)
        encoder_flags |= OMXCodec::kPreferSoftwareCodecs;

    OMXClient client;

    if (EncType == 1) {
        CHECK_EQ(client.connect(), (status_t)OK);

        encoder = OMXCodec::Create(
                client.interface(), enc_meta, true /* createEncoder */, source,
                0, encoder_flags);
    } else {
        encoder = new MixEncoder(source, enc_meta, EncRCMode, encoder_flags);
    }

    //setup output
    printf("Setup Writer\n");

    if (OutFormat == 0)
        writer = new MPEG4Writer(OutFileName);
    else
        writer = new RawWriter(OutFileName);

    writer->addSource(encoder);

    printf("Start encoding\n");

    int64_t start = systemTime();
    CHECK_EQ((status_t)OK, writer->start());
    while (!writer->reachedEOS()) {
        usleep(100000);
    }
    status_t err = writer->stop();
    int64_t end = systemTime();

    if (EncType == 1) {
        client.disconnect();
    }

    printf("Stop Encoding\n");

    if (err != OK && err != ERROR_END_OF_STREAM) {
        LOG("record failed: %d\n", err);
        return 1;
    }

    enc_meta.clear();

    printf("encoding %d frames in %lld us\n", gNumFramesOutput, (end-start)/1000);
    printf("encoding speed is: %.2f fps\n", (gNumFramesOutput * 1E9) / (end-start));

    return 1;
}

