int PreviewStream::freeBuffers()
{
    status_t ret = NO_ERROR;

    GraphicBufferMapper& mapper = GraphicBufferMapper::get();

    // Give the buffers back to display here -  sort of free it
    if (mNativeWindow) {
        for (int i = 0; i < mTotalBuffers; i++) {
            mapper.unlock(mCameraBuffer[i].mBufHandle);
            ret = mNativeWindow->cancel_buffer(mNativeWindow,
                                               &mCameraBuffer[i].mBufHandle);
            if (ENODEV == ret) {
                FLOGE("Preview surface abandoned!");
                mNativeWindow = NULL;
                return -ret;
            }
            else if (NO_ERROR != ret) {
                FLOGE("cancel_buffer() failed: %s (%d)", strerror(-ret), -ret);
                return -ret;
            }
        }
    }
    else {
        FLOGE("mNativeWindow is NULL");
    }

    // /Clear the frames with camera adapter map
    dispatchBuffers(NULL, 0, BUFFER_DESTROY);

    return ret;
}
int PhysMemAdapter::freeBuffer()
{
    if (mIonFd <= 0) {
        FLOGE("try to free buffer from ion in preview or ion invalid");
        return BAD_VALUE;
    }

    FLOGI("freeBufferToIon buffer num:%d", mBufferCount);
    for (int i = 0; i < mBufferCount; i++) {
        struct ion_handle *ionHandle =
            (struct ion_handle *)mCameraBuffer[i].mBufHandle;
        ion_free(mIonFd, ionHandle);
        munmap(mCameraBuffer[i].mVirtAddr, mCameraBuffer[i].mSize);
    }

    memset(mCameraBuffer, 0, sizeof(mCameraBuffer));
    dispatchBuffers(NULL, 0, BUFFER_DESTROY);
    return NO_ERROR;
}
int PhysMemAdapter::allocatePictureBuffer(int width,
                                          int height,
                                          int format,
                                          int numBufs)
{
    if (mIonFd <= 0) {
        FLOGE("try to allocate buffer from ion in preview or ion invalid");
        return BAD_VALUE;
    }

    int size = 0;
    if ((width == 0) || (height == 0)) {
        FLOGE("allocateBufferFromIon: width or height = 0");
        return BAD_VALUE;
    }
    switch (format) {
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
            size = width * ((height + 16) & (~15)) * 3 / 2;
            break;

        case HAL_PIXEL_FORMAT_YCbCr_420_P:
            size = width * height * 3 / 2;
            break;

        case HAL_PIXEL_FORMAT_YCbCr_422_I:
            size = width * height * 2;
            break;

        default:
            FLOGE("Error: format not supported int ion alloc");
            return BAD_VALUE;
    }

    unsigned char *ptr = NULL;
    int sharedFd;
    int phyAddr;
    struct ion_handle *ionHandle;
    size = (size + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));

    FLOGI("allocateBufferFromIon buffer num:%d", numBufs);
    for (int i = 0; i < numBufs; i++) {
        ionHandle = NULL;
        int err = ion_alloc(mIonFd, size, 8, 1, &ionHandle);
        if (err) {
            FLOGE("ion_alloc failed.");
            return BAD_VALUE;
        }

        err = ion_map(mIonFd,
                      ionHandle,
                      size,
                      PROT_READ | PROT_WRITE,
                      MAP_SHARED,
                      0,
                      &ptr,
                      &sharedFd);
        if (err) {
            FLOGE("ion_map failed.");
            return BAD_VALUE;
        }
        phyAddr = ion_phys(mIonFd, ionHandle);
        if (phyAddr == 0) {
            FLOGE("ion_phys failed.");
            return BAD_VALUE;
        }
        FLOG_RUNTIME("phyalloc ptr:0x%x, phy:0x%x, size:%d",
                     (int)ptr,
                     phyAddr,
                     size);
        mCameraBuffer[i].reset();
        mCameraBuffer[i].mIndex     = i;
        mCameraBuffer[i].mWidth     = width;
        mCameraBuffer[i].mHeight    = height;
        mCameraBuffer[i].mFormat    = format;
        mCameraBuffer[i].mVirtAddr  = ptr;
        mCameraBuffer[i].mPhyAddr   = phyAddr;
        mCameraBuffer[i].mSize      =  size;
        mCameraBuffer[i].mBufHandle = (buffer_handle_t *)ionHandle;
        close(sharedFd);
    }

    mBufferCount    = numBufs;
    mQueueableCount = numBufs;
    mFormat         = format;
    mBufferSize     = mCameraBuffer[0].mSize;
    mFrameWidth     = width;
    mFrameHeight    = height;

    dispatchBuffers(&mCameraBuffer[0], numBufs, BUFFER_CREATE);

    return NO_ERROR;
}
int PreviewStream::allocateBuffers(int /*width*/, int /*height*/,
                        int /*format*/, int /*numBufs*/ )
{
    int index = -1;
    int ret = NO_ERROR;

    //In DeviceAdapter::handleFrameRelease, if mPreviewing is false,
    //will not dec mRefCount. This will happen when performance is low.
    //So need zero ref count.
    for (int i = 0; i < mTotalBuffers; i++) {
       // FLOGI("==== PreviewStream::allocateBuffers, i %d, state %d, ref %d",
         //   i, mCameraBuffer[i].getState(), mCameraBuffer[i].getRefCount());

        mCameraBuffer[i].ZeroRefCount();
    }

    for (int i = 0; i < mMaxProducerBuffers; i++) {
        buffer_handle_t *buf_h = NULL;
        ret = mNativeWindow->dequeue_buffer(mNativeWindow, &buf_h);
        if (ret != 0) {
            FLOGE("dequeueBuffer failed: %s (%d)", strerror(-ret), -ret);
            if (ENODEV == ret) {
                FLOGE("Preview surface abandoned!");
                mNativeWindow = NULL;
            }
            return ret;
        }

        index = getBufferIdx(buf_h);
        if (index < 0 || index >= mTotalBuffers) {
            FLOGE("%s dequeue invalid buffer", __FUNCTION__);
            return BAD_VALUE;
        }
        mCameraBuffer[index].setState(CameraFrame::BUFS_FREE);
		if(mDeviceAdapter.get() && mDeviceAdapter->UseMJPG()) {
			mDeviceAdapter.get()->mVPUPhyAddr[i] = (unsigned char*)mCameraBuffer[index].mPhyAddr;
            mDeviceAdapter.get()->mVPUVirtAddr[i] = (unsigned char*)mCameraBuffer[index].mVirtAddr;
            FLOGI("allocateBuffers, index %d, phyAddr 0x%x", index, mCameraBuffer[index].mPhyAddr);
		}
    }

    for (int i = 0; i < mTotalBuffers; i++) {
        int state = mCameraBuffer[i].getState();
        if (state != CameraFrame::BUFS_FREE) {
            mCameraBuffer[i].setState(CameraFrame::BUFS_IN_SERVICE);

            // The frame held in service.
            // Make sure we dont add one more reference
            // count for it
            if(!mCameraBuffer[i].getRefCount())
                mCameraBuffer[i].addReference();
        }

        if(mDeviceAdapter.get() && mDeviceAdapter->UseMJPG()) {
            mCameraBuffer[i].mBindUVCBufIdx = -1;
            mCameraBuffer[i].mpFrameBuf = NULL;
        }
    }

    dispatchBuffers(&mCameraBuffer[0], mTotalBuffers, BUFFER_CREATE);

    return ret;
}