//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/stagefright/SurfaceMediaSource.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 <gui/Surface.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;
static unsigned int pts;


#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; \
    }

static 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;
}


class DummySource : public MediaSource {

public:
    DummySource(const sp<MetaData> &meta, uint32_t flag) {

        bool success;

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

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

        success = meta->findInt32(kKeyStride, &mStride);
        CHECK(success);

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

        success = meta->findInt32(kKeyColorFormat, &mColorFormat);
        CHECK(success);

        success = meta->findCString('yuvf', &mYuvfile);
        CHECK(success);

        success = meta->findInt32('fnum', &mMaxNumFrames);
        CHECK(success);

        success = meta->findInt32('sflg', (int32_t*)&mSessionFlag);
        CHECK(success);

        mYuvhandle = NULL;

        mMetadata = flag & OMXCodec::kStoreMetaDataInVideoBuffers;

        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 + 0x0FFF));

        mTAG = "Dummy";
    }

    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 0
        {
            int size= mStride * mHeight * 1.5;
            void* tmp = malloc(size);

            int64_t start = systemTime();

            for(int j=0; j<100; j++) {
                for(int i=0; i<PRELOAD_FRAME_NUM; i++)
                    memcpy(tmp, mUsrptr[i], size);
            }
            int64_t end = systemTime();
            printf("read from %s mem, write to cached malloc mem, per memcpy cost = %lld us\n", mTAG, (end-start) / (100000*PRELOAD_FRAME_NUM));

            for(int j=0; j<100; j++) {
                for(int i=0; i<PRELOAD_FRAME_NUM; i++)
                    memcpy(mUsrptr[i], tmp, size);
            }
            start = systemTime();

            printf("read from cached malloc mem, write to %s mem, per memcpy cost = %lld us\n", mTAG, (start - end)/ (100000*PRELOAD_FRAME_NUM));

        }
#endif
        if (mYuvfile == NULL || strlen(mYuvfile) == 0) {
            //upload src data
            LOG("Fill src pictures width=%d, Height=%d\n", mStride, mHeight);
            for(int i=0; i<PRELOAD_FRAME_NUM; i++) {
                preSourceWriting(i);
                if (mColorFormat == HAL_PIXEL_FORMAT_BGRA_8888) {
                    int color = 0x00FF00FF; //AA RR GG BB
                    for(int j=0; j<mStride*mHeight; j++)
                        memcpy(mUsrptr[i]+ j*4, &color, 4);
                }else
                    YUV_generator_planar(mStride, mHeight, mUsrptr[i], mStride, mUsrptr[i] + mStride*mHeight, mStride, 0, 0, 1);
                postSourceWriting(i);
            }
            LOG("Fill src pictures end\n");
        }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) {

        static int64_t lastTS = 0;

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

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

        preSourceWriting(gNumFramesOutput % PRELOAD_FRAME_NUM);

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

            size_t ret = 0;

            while (readsize > 0) {
                if (mColorFormat == HAL_PIXEL_FORMAT_BGRA_8888)
                    ret = fread(mUsrptr[gNumFramesOutput % PRELOAD_FRAME_NUM] + mStride*mHeight*4 - readsize,  1, readsize, mYuvhandle);
                else
                    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;
        }

        size_t offset = 0;
        if (mMetadata)
            memcpy ((*buffer)->data(), data, size);
        else {
            offset = ((int)((*buffer)->data() + 0x0FFF) & ~0x0FFF) - (int)(*buffer)->data();
            memcpy ((*buffer)->data() + offset, data, size);
        }
        (*buffer)->set_range(offset, size);
        (*buffer)->meta_data()->clear();
        (*buffer)->meta_data()->setInt64(
                kKeyTime, (gNumFramesOutput*100 / mFrameRate) * 10000);

        postSourceWriting(gNumFramesOutput % PRELOAD_FRAME_NUM);

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

        int64_t currTS = systemTime();
        if (lastTS > 0) {
            int32_t delayTS = (1000000 / mFrameRate) - (currTS - lastTS) / 1000;
			if (delayTS > 0)
                usleep(delayTS);
        }
        lastTS = systemTime();
        return OK;
    }

    virtual status_t createResource() {
        return OK;
    }

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

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

public:

    bool mMetadata;
    const char* mYuvfile;
    FILE* mYuvhandle;
    MediaBufferGroup mGroup;
    int mWidth, mHeight, mStride;
    int mMaxNumFrames;
    int mFrameRate;
    int mColorFormat;
    size_t mSize;
    unsigned int mSessionFlag;
    const char* mTAG;

//    int64_t mNumFramesOutput;

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

    //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(const sp<MetaData> &meta, uint32_t flag) :
			DummySource (meta, flag) {

        mTAG = "Malloc";
    }

    ~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(IntelMetadataBufferTypeCameraSource, (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(const sp<MetaData> &meta, uint32_t flag) :
			DummySource (meta, flag) {
        mTAG = "MemHeap";
    }

    ~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;
        size += 0x0FFF;

        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*) ((int) (mBuffers[i]->pointer() + 0x0FFF) & ~0x0FFF);

            mIMB[i] = new IntelMetadataBuffer();
            mIMB[i]->SetType(IntelMetadataBufferTypeCameraSource);
#ifdef INTEL_VIDEO_XPROC_SHARING
            mIMB[i]->SetSessionFlag(mSessionFlag);
            mIMB[i]->ShareValue(mBuffers[i]);
#else
            mIMB[i]->SetValue((int32_t)mUsrptr[i]);
#endif
            mIMB[i]->SetValueInfo(&vinfo);
            LOG("MemHeap local 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(const sp<MetaData> &meta, uint32_t flag, int mode) :
			DummySource (meta, flag) {
        mMode = mode;
        mTAG = "VASurface";
    }

    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(IntelMetadataBufferTypeUser, mSurfaces[i]);
            else {
                mIMB[i] = new IntelMetadataBuffer(IntelMetadataBufferTypeUser, 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(const sp<MetaData> &meta, uint32_t flag) :
			DummySource (meta, flag) {

        mWidth = ((mWidth + 15 ) / 16 ) * 16;
        mHeight = ((mHeight + 15 ) / 16 ) * 16;
        mStride = mWidth;
        mTAG = "Gfx";
    }

    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_RENDER | GraphicBuffer::USAGE_SW_WRITE_OFTEN;// | GraphicBuffer::USAGE_HW_COMPOSER;
        int32_t error;

        ValueInfo vinfo;
        memset(&vinfo, 0, sizeof(ValueInfo));
        vinfo.mode = MEM_MODE_GFXHANDLE;
        vinfo.size = 0;
        vinfo.width = mWidth;
        vinfo.height = mHeight;
        vinfo.lumaStride = mStride;
        vinfo.chromStride = mStride;
        vinfo.format = mColorFormat;
        vinfo.s3dformat = 0xFFFFFFFF;

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

            if (graphicBuffer.get() == NULL) {
                printf("GFX createGraphicBuffer failed\n");
                return UNKNOWN_ERROR;
            }
            mGraphicBuffer[i] = graphicBuffer;

            mIMB[i] = new IntelMetadataBuffer();
            mIMB[i]->SetType(IntelMetadataBufferTypeCameraSource);
#ifdef INTEL_VIDEO_XPROC_SHARING
            mIMB[i]->SetSessionFlag(mSessionFlag);
            mIMB[i]->ShareValue(mGraphicBuffer[i]);
#else
            mIMB[i]->SetValue((int32_t)mGraphicBuffer[i]->handle);
#endif
            mIMB[i]->SetValueInfo(&vinfo);

            IMG_native_handle_t* h = (IMG_native_handle_t*) mGraphicBuffer[i]->handle;
            mStride = graphicBuffer->getStride();
            mHeight = h->iHeight;
            printf("GfxSource handle iWidth=%d, iHeight=%d, stride=%d, color=0x%08x\n", h->iWidth, h->iHeight, mStride, h->iFormat);
        }
        printf("GfxSource1 width=%d, height=%d, stride=%d\n", mWidth, mHeight, mStride);

        return OK;
    }

    void preSourceWriting(int i) {
        uint32_t usage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_OFTEN;// | GraphicBuffer::USAGE_HW_COMPOSER;
        void* vaddr[3];
        if (mGraphicBuffer[i]->lock(usage, &vaddr[0]) != OK)
            printf("GfxSource lock failed\n");
        mUsrptr[i] = (uint8_t*)vaddr[0];
    }
    void postSourceWriting(int i) {
        mGraphicBuffer[i]->unlock();
    }

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

class GrallocSource : public DummySource {

public:
    GrallocSource(const sp<MetaData> &meta, uint32_t flag) :
			DummySource (meta, flag) {
        mTAG = "Gralloc";
    }

    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_SW_WRITE_OFTEN;

        gfx_init();

        for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
        {
            if (gfx_alloc(mWidth, mHeight, mColorFormat, usage, &mHandle[i], (int32_t*)&mStride) != 0)
                return UNKNOWN_ERROR;

            mIMB[i] = new IntelMetadataBuffer(IntelMetadataBufferTypeGrallocSource, (int32_t)mHandle[i]);
            IMG_native_handle_t* h = (IMG_native_handle_t*) mHandle[i];
//            mWidth = h->iWidth;
            mHeight = h->iHeight;
        printf("GrallocSource iWidth=%d, iHeight=%d, stride=%d, Color=0x%08x\n", h->iWidth, h->iHeight, mStride, h->iFormat);
        }
        printf("GrallocSource width=%d, height=%d, stride=%d\n", mWidth, mHeight, mStride);
        return OK;
    }

    void preSourceWriting(int i) {
        int usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_WRITE_OFTEN;
        void* vaddr[3];
        if (gfx_lock(mHandle[i], usage, 0, 0, mWidth, mHeight, &vaddr[0]) != 0)
            printf("GrallocSource lock failed\n");
        mUsrptr[i] = (uint8_t*)vaddr[0];
    }
    void postSourceWriting(int i) {
        gfx_unlock(mHandle[i]);
    }

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];
};

class MixSurfaceMediaSource : public SurfaceMediaSource {

public:
    MixSurfaceMediaSource(int width, int height, int nFrames, int fps)
                                 :SurfaceMediaSource(width, height){
        mMaxNumFrames = nFrames;
        mFPS = fps;
    }

    virtual ~MixSurfaceMediaSource() {        
    }

    status_t start(MetaData *params) {
		mSTC = new Surface(getBufferQueue());
		mANW = mSTC;
        mRunning = true;

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

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

        SurfaceMediaSource::start(params);

        return OK;
    }

    status_t stop() {
        mRunning = false;
//        void *dummy;
//        pthread_join(mThread, &dummy);		
        SurfaceMediaSource::stop();

        return OK;
    }

public:
    int mMaxNumFrames;
    int mFPS;

private:
    sp<Surface> mSTC;
    sp<ANativeWindow> mANW;
    pthread_t mThread;
    bool mRunning;

    static void *ThreadFunc(void *me) {
        MixSurfaceMediaSource *source = static_cast<MixSurfaceMediaSource *>(me);

        // get buffer directly from member
	    sp<GraphicBuffer> buf;
        
        for ( gNumFramesOutput = 0; gNumFramesOutput < source->mMaxNumFrames; gNumFramesOutput++) {
            ANativeWindowBuffer* anb;
            native_window_set_buffers_format(source->mANW.get(), HAL_PIXEL_FORMAT_NV12);
            native_window_dequeue_buffer_and_wait(source->mANW.get(), &anb);
            // We do not fill the buffer in. Just queue it back.
            sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
#if 1
            uint8_t* img[3];
            buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img[0]));
            IMG_native_handle_t* h = (IMG_native_handle_t*) buf->handle;
            YUV_generator_planar(h->iWidth, h->iHeight, img[0], h->iWidth, img[0] + h->iWidth*h->iHeight, h->iWidth, 0, 0, 1);
            buf->unlock();
#endif	
            if (NO_ERROR != source->mANW->queueBuffer(source->mANW.get(), buf->getNativeBuffer(), -1))
                return NULL;
//            else
//                usleep(1000000 / source->mFPS);
        }

        source->stop();
		
        return NULL;
    }
};

static const char *AVC_MIME_TYPE = "video/h264";
static const char *MPEG4_MIME_TYPE = "video/mpeg4";
static const char *H263_MIME_TYPE = "video/h263";
static const char *VP8_MIME_TYPE = "video/x-webm";


class MixEncoder : public MediaSource {

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

        mMeta = meta;
        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 if (strcmp(mime, MEDIA_MIMETYPE_VIDEO_VP8) == 0) {
            mMixCodec = (char*) VP8_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);

        success = meta->findInt32('rawc', &mRawColor);
        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];
    }

    sp<MetaData> getFormat() {
#if 0
        mMeta = new MetaData;
        mMeta->setInt32(kKeyWidth, mWidth);
        mMeta->setInt32(kKeyHeight, mHeight);
//        meta->setInt32(kKeyColorFormat, mColorFormat);
        mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
#endif
        return mMeta;
    }

    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));

        err = mSource->start();
        if (err != OK)
            return err;

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

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

        return OK;
    }

    status_t stop() {
        Encode_Status ret;

        mRunning = false;
        void *dummy;
        pthread_join(mThread, &dummy);

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

        mEOS = false;
        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) {
            VideoConfigBitRate configBitrate;
            mVideoEncoder->getConfig(&configBitrate);
            configBitrate.rcParams.minQP = 0;
            configBitrate.rcParams.maxQP = 0;
            mVideoEncoder->setConfig(&configBitrate);
        }

        if (mEncodeFrameCount == 40) {
            VideoConfigBitRate configBitrate;
            mVideoEncoder->getConfig(&configBitrate);
            configBitrate.rcParams.minQP = 0;
            configBitrate.rcParams.maxQP = 0;
            mVideoEncoder->setConfig(&configBitrate);
        }

        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, 500);
        if (ret < ENCODE_SUCCESS) {
            if (ret == ENCODE_NO_REQUEST_DATA) {
                if (mEOS) {
                    out->release();
                    return ERROR_END_OF_STREAM;
                }

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

        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;

        if (mFirstFrame && (strcasecmp(mMixCodec, H263_MIME_TYPE) != 0)
                        && (strcasecmp(mMixCodec, VP8_MIME_TYPE) != 0)) {
            err = mGroup.acquire_buffer(buffer);
            CHECK_STATUS(err);

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

            mFirstFrame = false;
            return OK;
        }

        mFirstFrame = false;

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

        err = getoutput(*buffer, OUTPUT_EVERYTHING);
        if (err == ERROR_END_OF_STREAM)
            return err;
        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 (mRawColor == 2)
            mEncoderParams.rawFormat = RAW_FORMAT_OPAQUE;
        else
            mEncoderParams.rawFormat = RAW_FORMAT_NV12;

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

        mEncoderParams.rcParams.bitRate = mBitrate;
        mEncoderParams.rcParams.initQP = mInitQP;
        mEncoderParams.rcParams.minQP = mMinQP;
        mEncoderParams.rcParams.maxQP = 0;
        mEncoderParams.rcParams.I_minQP = 0;
        mEncoderParams.rcParams.I_maxQP = 0;
        mEncoderParams.rcParams.windowSize = mWinSize;
        mEncoderParams.rcParams.disableBitsStuffing = 1;
        mEncoderParams.rcParams.enableIntraFrameQPControl = 0;  //change to 1 to enable I frame qp control
        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, AVC_MIME_TYPE) == 0) {
            VideoParamsAVC AVCParam;
            mVideoEncoder->getParameters(&AVCParam);
            AVCParam.idrInterval = mIdrInt;
            mVideoEncoder->setParameters(&AVCParam);
        }

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

private:
    //encoding thread
    static void *ThreadFunc(void *me) {
        MixEncoder *encoder = static_cast<MixEncoder *>(me);

        status_t err = OK;

        while (encoder->mRunning) {
            MediaBuffer* src = NULL;

            err = encoder->mSource->read(&src);

            if (err == ERROR_END_OF_STREAM) {
                encoder->mEOS = true;
                return NULL;
            }else {
                if (err == OK)
                    err = encoder->encode(src);
                if (err != OK) {
                    src->release();
                    return NULL;
                }
            }
        }

        return NULL;
    }

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 mRawColor;

    bool mFirstFrame;

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

    sp<MediaSource> mSource;
    MediaBufferGroup mGroup;
    sp<MetaData> mMeta;

public:
    pthread_t mThread;
    bool mRunning;
    bool mEOS;
};

class IVFWriter : public MediaWriter {

public:
    const char* mFile;
    FILE* mFilehandle;
    sp<MediaSource> mSource;
    pthread_t mThread;
    bool mRunning;
    bool mEOS;
	char vp8_file_header[32];
	
public:
    IVFWriter(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;

		write_ivf_file_header(params);

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

        pthread_create(&mThread, &attr, IVFWriter::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;
    }

	
	static void mem_put_le16(char *mem, unsigned int val)
	{
		mem[0] = val;
		mem[1] = val>>8;
	}
	
	static void mem_put_le32(char *mem, unsigned int val)
	{
		mem[0] = val;
		mem[1] = val>>8;
		mem[2] = val>>16;
		mem[3] = val>>24;
	}

	void write_ivf_file_header(MetaData *params)	{

    int width,height,framerate; 
	params->findInt32(kKeyWidth, &width);
    params->findInt32(kKeyHeight, &height);
    params->findInt32(kKeyFrameRate, &framerate);
     /* write ivf header */
    vp8_file_header[0] = 'D';
    vp8_file_header[1] = 'K';
    vp8_file_header[2] = 'I';
    vp8_file_header[3] = 'F';
    mem_put_le16(vp8_file_header+4,  0);                     /* version */
    mem_put_le16(vp8_file_header+6,  32);                    /* headersize */
    mem_put_le32(vp8_file_header+8,  0x30385056);            /* headersize */
    mem_put_le16(vp8_file_header+12, width);           /* width */
    mem_put_le16(vp8_file_header+14, height);          /* height */
    mem_put_le32(vp8_file_header+16, framerate);       /* rate default at 30 */
    mem_put_le32(vp8_file_header+20, 1);                     /* scale */
    mem_put_le32(vp8_file_header+24, 50);           /* length just hardcode to 50*/
    mem_put_le32(vp8_file_header+28, 0);                     /* unused */
    fwrite(vp8_file_header, 1, 32, mFilehandle);

	}

private:

    static void *ThreadFunc(void *me) {
        IVFWriter *writer = static_cast<IVFWriter *>(me);

        status_t err = OK;
		char vp8_frame_header[12];
		unsigned int vp8_frame_length;


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

            if (err == OK) {
				vp8_frame_length = buffer->range_length();
				mem_put_le32(vp8_frame_header, vp8_frame_length);
				mem_put_le32(vp8_frame_header+4, pts&0xFFFFFFFF);
				mem_put_le32(vp8_frame_header+8, pts >> 32);
				fwrite(vp8_frame_header, 1, 12, writer->mFilehandle);
				pts++;
                fwrite(buffer->data()+buffer->range_offset(), 1, buffer->range_length(), writer->mFilehandle);
				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;
    }

};


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, VP8\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, IVF(only for VP8)\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, KBUFHANDLE, GFX, GRALLOC, MEMHEAP, SURFACEMEDIASOURCE (CAMERASOURCE, not support yet) \n");
    printf(" -t/--sessionFlag	<sessionflag>	       	set sessionflag, default is 0\n");
    printf(" -u/--disableFrameSkip				disable frame skip, default is false\n");
    printf(" -v/--gfxColor					set gfx color, default is 0(HAL_PIXEL_FORMAT_NV12), 1(OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar), 2(HAL_PIXEL_FORMAT_BGRA_8888)\n");
    printf(" -w <Width> -h <Height>				set source width /height, default 1280*720\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 GfxColor = 0;
    int OutFormat = 0;
    char* OutFileName = "out.264";
    const char* Yuvfile = "";
    unsigned int SessionFlag = 0;

    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, 'u'},
						{"sessionFlag", required_argument, NULL, 't'},
						{"gfxColor", required_argument, NULL, 'v'},
						{0, 0, 0, 0}
    };

    char c;

    const char *SRCTYPE[] = {"MALLOC", "VASURFACE", "KBUFHANDLE", "GFX", "GRALLOC", "MEMHEAP", "CAMERASOURCE", "SURFACEMEDIASOURCE", NULL};
    const char *ENCTYPE[] = {"MIX", "OMXCODEC", NULL};
    const char *CODEC[] = {"H264", "MPEG4", "H263", "VP8",NULL};
    const char *RCMODE[] = {"VBR", "CBR", "VCM", "NO_RC", NULL};
    const char *OUTFORMAT[] = {"MP4", "RAW", "IVF", 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':
                    SessionFlag = atoi(optarg);
                    break;

                case 'u':
                    DisableFrameSkip = 1;
                    break;

                case 'v':
                    GfxColor = atoi(optarg);
                    break;

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

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

    //RGB is only valid in gfx/gralloc source mode
    if ( GfxColor > 2 && (SrcType != 3 || SrcType != 4) )
        GfxColor = 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, SessionFlag: 0x%08x\n", SrcFps, Yuvfile, MetadataMode, SessionFlag);

    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, GfxColor: %s\n", !DisableFrameSkip, GfxColor > 0 ? (GfxColor > 1? "HAL_PIXEL_FORMAT_BGRA_8888":"OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar"):"HAL_PIXEL_FORMAT_NV12");

    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
    sp<MetaData> src_meta = new MetaData;
    src_meta->setInt32(kKeyWidth, SrcWidth);
    src_meta->setInt32(kKeyHeight, SrcHeight);
    src_meta->setInt32(kKeyStride, SrcStride);
    src_meta->setInt32(kKeyFrameRate, SrcFps);
    if (GfxColor == 1)
        src_meta->setInt32(kKeyColorFormat, 0x7FA00E00); //OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar
    else if (GfxColor == 2)
        src_meta->setInt32(kKeyColorFormat, HAL_PIXEL_FORMAT_BGRA_8888);
    else
        src_meta->setInt32(kKeyColorFormat, HAL_PIXEL_FORMAT_NV12);

    src_meta->setCString('yuvf', Yuvfile);
    src_meta->setInt32('fnum', SrcFrameNum);
    src_meta->setInt32('sflg', SessionFlag);

    uint32_t src_flags = 0;
    if (MetadataMode)
        src_flags |= OMXCodec::kStoreMetaDataInVideoBuffers;

    if (SrcType == 0) {
        source = new MallocSource(src_meta, src_flags);
    } else if (SrcType == 1) {
        source = new VASurfaceSource(src_meta, src_flags, 0);
    } else if (SrcType == 2) {
        source = new VASurfaceSource(src_meta, src_flags, 1);
    } else if (SrcType == 3) {
        source = new GfxSource(src_meta, src_flags);
    } else if (SrcType == 4) {
        source = new GrallocSource(src_meta, src_flags);
    } else if (SrcType == 5) {
        source = new MemHeapSource(src_meta, src_flags);
    } else if (SrcType == 7) {
        source = new MixSurfaceMediaSource(SrcWidth, SrcHeight, SrcFrameNum, SrcFps);
    }else{
        printf("Source Type is not supported\n");
        return 0;
    }

    printf("Setup Encoder EncCodec is %d\n",EncCodec);
    //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;
		case 3: 
			enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8);
			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', IdrInt);
    enc_meta->setInt32('difs', DisableFrameSkip);
    enc_meta->setInt32('rawc', GfxColor);

    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 if (OutFormat == 1)
        writer = new RawWriter(OutFileName);
	else 
		writer = new IVFWriter(OutFileName);

    status_t err;
    err = writer->addSource(encoder);
    if (err != OK) {
        printf("Writer addSource failed %d\n", err);
        return 0;
    }

    err = writer->start(enc_meta.get());
    if (err != OK) {
        printf("Writer start failed %d\n", err);
        return 0;
    }

    printf("Start encoding\n");

    int64_t start = systemTime();

    while (!writer->reachedEOS()) {
        usleep(100000);
    }

    int64_t end = systemTime();
    err = writer->stop();


    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;
    }

    src_meta.clear();
    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;
}

