/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above
*       copyright notice, this list of conditions and the following
*       disclaimer in the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of The Linux Foundation nor the names of its
*       contributors may be used to endorse or promote products derived
*       from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

#define LOG_TAG "QCamera3Stream"

// Camera dependencies
#include "QCamera3HWI.h"
#include "QCamera3Stream.h"

extern "C" {
#include "mm_camera_dbg.h"
}

using namespace android;

namespace qcamera {
#define MAX_BATCH_SIZE   32

const char* QCamera3Stream::mStreamNames[] = {
        "CAM_DEFAULT",
        "CAM_PREVIEW",
        "CAM_POSTVIEW",
        "CAM_SNAPSHOT",
        "CAM_VIDEO",
        "CAM_CALLBACK",
        "CAM_IMPL_DEFINED",
        "CAM_METADATA",
        "CAM_RAW",
        "CAM_OFFLINE_PROC",
        "CAM_PARM",
        "CAM_ANALYSIS"
        "CAM_MAX" };

/*===========================================================================
 * FUNCTION   : get_bufs
 *
 * DESCRIPTION: static function entry to allocate stream buffers
 *
 * PARAMETERS :
 *   @offset     : offset info of stream buffers
 *   @num_bufs   : number of buffers allocated
 *   @initial_reg_flag: flag to indicate if buffer needs to be registered
 *                      at kernel initially
 *   @bufs       : output of allocated buffers
 *   @ops_tbl    : ptr to buf mapping/unmapping ops
 *   @user_data  : user data ptr of ops_tbl
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::get_bufs(
                     cam_frame_len_offset_t *offset,
                     uint8_t *num_bufs,
                     uint8_t **initial_reg_flag,
                     mm_camera_buf_def_t **bufs,
                     mm_camera_map_unmap_ops_tbl_t *ops_tbl,
                     void *user_data)
{
    int32_t rc = NO_ERROR;
    QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
    if (!stream) {
        LOGE("getBufs invalid stream pointer");
        return NO_MEMORY;
    }
    rc = stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
    if (NO_ERROR != rc) {
        LOGE("stream->getBufs failed");
        return NO_MEMORY;
    }
    if (stream->mBatchSize) {
        //Allocate batch buffers if mBatchSize is non-zero. All the output
        //arguments correspond to batch containers and not image buffers
        rc = stream->getBatchBufs(num_bufs, initial_reg_flag,
                bufs, ops_tbl);
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : put_bufs
 *
 * DESCRIPTION: static function entry to deallocate stream buffers
 *
 * PARAMETERS :
 *   @ops_tbl    : ptr to buf mapping/unmapping ops
 *   @user_data  : user data ptr of ops_tbl
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::put_bufs(
                     mm_camera_map_unmap_ops_tbl_t *ops_tbl,
                     void *user_data)
{
    int32_t rc = NO_ERROR;
    QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
    if (!stream) {
        LOGE("putBufs invalid stream pointer");
        return NO_MEMORY;
    }

    if (stream->mBatchSize) {
        rc = stream->putBatchBufs(ops_tbl);
        if (NO_ERROR != rc) {
            LOGE("stream->putBatchBufs failed");
        }
    }
    rc = stream->putBufs(ops_tbl);
    return rc;
}

/*===========================================================================
 * FUNCTION   : invalidate_buf
 *
 * DESCRIPTION: static function entry to invalidate a specific stream buffer
 *
 * PARAMETERS :
 *   @index      : index of the stream buffer to invalidate
 *   @user_data  : user data ptr of ops_tbl
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::invalidate_buf(uint32_t index, void *user_data)
{
    int32_t rc = NO_ERROR;

    QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
    if (!stream) {
        LOGE("invalid stream pointer");
        return NO_MEMORY;
    }
    if (stream->mBatchSize) {
        int32_t retVal = NO_ERROR;
        for (size_t i = 0;
                i < stream->mBatchBufDefs[index].user_buf.bufs_used; i++) {
            uint32_t buf_idx = stream->mBatchBufDefs[index].user_buf.buf_idx[i];
            retVal = stream->invalidateBuf(buf_idx);
            if (NO_ERROR != retVal) {
                LOGE("invalidateBuf failed for buf_idx: %d err: %d",
                         buf_idx, retVal);
            }
            rc |= retVal;
        }
    } else {
        rc = stream->invalidateBuf(index);
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : clean_invalidate_buf
 *
 * DESCRIPTION: static function entry to clean and invalidate a specific stream buffer
 *
 * PARAMETERS :
 *   @index      : index of the stream buffer to invalidate
 *   @user_data  : user data ptr of ops_tbl
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::clean_invalidate_buf(uint32_t index, void *user_data)
{
    int32_t rc = NO_ERROR;

    QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
    if (!stream) {
        LOGE("invalid stream pointer");
        return NO_MEMORY;
    }
    if (stream->mBatchSize) {
        int32_t retVal = NO_ERROR;
        for (size_t i = 0;
                i < stream->mBatchBufDefs[index].user_buf.bufs_used; i++) {
            uint32_t buf_idx = stream->mBatchBufDefs[index].user_buf.buf_idx[i];
            retVal = stream->cleanInvalidateBuf(buf_idx);
            if (NO_ERROR != retVal) {
                LOGE("invalidateBuf failed for buf_idx: %d err: %d",
                         buf_idx, retVal);
            }
            rc |= retVal;
        }
    } else {
        rc = stream->cleanInvalidateBuf(index);
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : QCamera3Stream
 *
 * DESCRIPTION: constructor of QCamera3Stream
 *
 * PARAMETERS :
 *   @allocator  : memory allocator obj
 *   @camHandle  : camera handle
 *   @chId       : channel handle
 *   @camOps     : ptr to camera ops table
 *   @paddingInfo: ptr to padding info
 *
 * RETURN     : None
 *==========================================================================*/
QCamera3Stream::QCamera3Stream(uint32_t camHandle,
                             uint32_t chId,
                             mm_camera_ops_t *camOps,
                             cam_padding_info_t *paddingInfo,
                             QCamera3Channel *channel) :
        mCamHandle(camHandle),
        mChannelHandle(chId),
        mHandle(0),
        mCamOps(camOps),
        mStreamInfo(NULL),
        mMemOps(NULL),
        mNumBufs(0),
        mDataCB(NULL),
        mUserData(NULL),
        mDataQ(releaseFrameData, this),
        mStreamInfoBuf(NULL),
        mStreamBufs(NULL),
        mBufDefs(NULL),
        mChannel(channel),
        mBatchSize(0),
        mNumBatchBufs(0),
        mStreamBatchBufs(NULL),
        mBatchBufDefs(NULL),
        mCurrentBatchBufDef(NULL),
        mBufsStaged(0),
        mFreeBatchBufQ(NULL, this)
{
    mMemVtbl.user_data = this;
    mMemVtbl.get_bufs = get_bufs;
    mMemVtbl.put_bufs = put_bufs;
    mMemVtbl.invalidate_buf = invalidate_buf;
    mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
    mMemVtbl.set_config_ops = NULL;
    memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
}

/*===========================================================================
 * FUNCTION   : ~QCamera3Stream
 *
 * DESCRIPTION: deconstructor of QCamera3Stream
 *
 * PARAMETERS : None
 *
 * RETURN     : None
 *==========================================================================*/
QCamera3Stream::~QCamera3Stream()
{
    if (mStreamInfoBuf != NULL) {
        int rc = mCamOps->unmap_stream_buf(mCamHandle,
                    mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
        if (rc < 0) {
            LOGE("Failed to un-map stream info buffer");
        }
        mStreamInfoBuf->deallocate();
        delete mStreamInfoBuf;
        mStreamInfoBuf = NULL;
    }
    // delete stream
    if (mHandle > 0) {
        mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
        mHandle = 0;
    }
}

/*===========================================================================
 * FUNCTION   : init
 *
 * DESCRIPTION: initialize stream obj
 *
 * PARAMETERS :
 *   @streamType     : stream type
 *   @streamFormat   : stream format
 *   @streamDim      : stream dimension
 *   @reprocess_config: reprocess stream input configuration
 *   @minNumBuffers  : minimal buffer count for particular stream type
 *   @postprocess_mask: PP mask
 *   @is_type  : Image stabilization type, cam_is_type_t
 *   @batchSize  : Number of image buffers in a batch.
 *                 0: No batch. N: container with N image buffers
 *   @stream_cb      : callback handle
 *   @userdata       : user data
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::init(cam_stream_type_t streamType,
                            cam_format_t streamFormat,
                            cam_dimension_t streamDim,
                            cam_rotation_t streamRotation,
                            cam_stream_reproc_config_t* reprocess_config,
                            uint8_t minNumBuffers,
                            uint32_t postprocess_mask,
                            cam_is_type_t is_type,
                            uint32_t batchSize,
                            hal3_stream_cb_routine stream_cb,
                            void *userdata)
{
    int32_t rc = OK;
    ssize_t bufSize = BAD_INDEX;
    mm_camera_stream_config_t stream_config;
    LOGD("batch size is %d", batchSize);

    mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
    if (!mHandle) {
        LOGE("add_stream failed");
        rc = UNKNOWN_ERROR;
        goto done;
    }

    // allocate and map stream info memory
    mStreamInfoBuf = new QCamera3HeapMemory(1);
    if (mStreamInfoBuf == NULL) {
        LOGE("no memory for stream info buf obj");
        rc = -ENOMEM;
        goto err1;
    }
    rc = mStreamInfoBuf->allocate(sizeof(cam_stream_info_t));
    if (rc < 0) {
        LOGE("no memory for stream info");
        rc = -ENOMEM;
        goto err2;
    }

    mStreamInfo =
        reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
    memset(mStreamInfo, 0, sizeof(cam_stream_info_t));
    mStreamInfo->stream_type = streamType;
    mStreamInfo->fmt = streamFormat;
    mStreamInfo->dim = streamDim;
    mStreamInfo->num_bufs = minNumBuffers;
    mStreamInfo->pp_config.feature_mask = postprocess_mask;
    mStreamInfo->is_type = is_type;
    mStreamInfo->pp_config.rotation = streamRotation;
    LOGD("stream_type is %d, feature_mask is %d",
           mStreamInfo->stream_type, mStreamInfo->pp_config.feature_mask);

    bufSize = mStreamInfoBuf->getSize(0);
    if (BAD_INDEX != bufSize) {
        rc = mCamOps->map_stream_buf(mCamHandle,
                mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
                0, -1, mStreamInfoBuf->getFd(0), (size_t)bufSize);
        if (rc < 0) {
            LOGE("Failed to map stream info buffer");
            goto err3;
        }
    } else {
        LOGE("Failed to retrieve buffer size (bad index)");
        goto err3;
    }

    mNumBufs = minNumBuffers;
    if (reprocess_config != NULL) {
        mStreamInfo->reprocess_config = *reprocess_config;
        mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
        //mStreamInfo->num_of_burst = reprocess_config->offline.num_of_bufs;
        mStreamInfo->num_of_burst = 1;
    } else if (batchSize) {
        if (batchSize > MAX_BATCH_SIZE) {
            LOGE("batchSize:%d is very large", batchSize);
            rc = BAD_VALUE;
            goto err4;
        }
        else {
            mNumBatchBufs = MAX_INFLIGHT_HFR_REQUESTS / batchSize;
            mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
            mStreamInfo->user_buf_info.frame_buf_cnt = batchSize;
            mStreamInfo->user_buf_info.size =
                    (uint32_t)(sizeof(msm_camera_user_buf_cont_t));
            mStreamInfo->num_bufs = mNumBatchBufs;
            //Frame interval is irrelavent since time stamp calculation is not
            //required from the mCamOps
            mStreamInfo->user_buf_info.frameInterval = 0;
            LOGD("batch size is %d", batchSize);
        }
    } else {
        mStreamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    }

    // Configure the stream
    stream_config.stream_info = mStreamInfo;
    stream_config.mem_vtbl = mMemVtbl;
    stream_config.padding_info = mPaddingInfo;
    stream_config.userdata = this;
    stream_config.stream_cb = dataNotifyCB;
    stream_config.stream_cb_sync = NULL;

    rc = mCamOps->config_stream(mCamHandle,
            mChannelHandle, mHandle, &stream_config);
    if (rc < 0) {
        LOGE("Failed to config stream, rc = %d", rc);
        goto err4;
    }

    mDataCB = stream_cb;
    mUserData = userdata;
    mBatchSize = batchSize;
    return 0;

err4:
    mCamOps->unmap_stream_buf(mCamHandle,
            mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
err3:
    mStreamInfoBuf->deallocate();
err2:
    delete mStreamInfoBuf;
    mStreamInfoBuf = NULL;
    mStreamInfo = NULL;
err1:
    mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    mHandle = 0;
    mNumBufs = 0;
done:
    return rc;
}

/*===========================================================================
 * FUNCTION   : start
 *
 * DESCRIPTION: start stream. Will start main stream thread to handle stream
 *              related ops.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::start()
{
    int32_t rc = 0;

    mDataQ.init();
    if (mBatchSize)
        mFreeBatchBufQ.init();
    rc = mProcTh.launch(dataProcRoutine, this);
    return rc;
}

/*===========================================================================
 * FUNCTION   : stop
 *
 * DESCRIPTION: stop stream. Will stop main stream thread
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::stop()
{
    int32_t rc = 0;
    rc = mProcTh.exit();
    return rc;
}

/*===========================================================================
 * FUNCTION   : processDataNotify
 *
 * DESCRIPTION: process stream data notify
 *
 * PARAMETERS :
 *   @frame   : stream frame received
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::processDataNotify(mm_camera_super_buf_t *frame)
{
    LOGD("E\n");
    int32_t rc;
    if (mDataQ.enqueue((void *)frame)) {
        rc = mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
    } else {
        LOGD("Stream thread is not active, no ops here");
        bufDone(frame->bufs[0]->buf_idx);
        free(frame);
        rc = NO_ERROR;
    }
    LOGD("X\n");
    return rc;
}

/*===========================================================================
 * FUNCTION   : dataNotifyCB
 *
 * DESCRIPTION: callback for data notify. This function is registered with
 *              mm-camera-interface to handle data notify
 *
 * PARAMETERS :
 *   @recvd_frame   : stream frame received
 *   userdata       : user data ptr
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera3Stream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
                                 void *userdata)
{
    LOGD("E\n");
    QCamera3Stream* stream = (QCamera3Stream *)userdata;
    if (stream == NULL ||
        recvd_frame == NULL ||
        recvd_frame->bufs[0] == NULL ||
        recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
        LOGE("Not a valid stream to handle buf");
        return;
    }

    mm_camera_super_buf_t *frame =
        (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
    if (frame == NULL) {
        LOGE("No mem for mm_camera_buf_def_t");
        stream->bufDone(recvd_frame->bufs[0]->buf_idx);
        return;
    }
    *frame = *recvd_frame;
    stream->processDataNotify(frame);
    return;
}

/*===========================================================================
 * FUNCTION   : dataProcRoutine
 *
 * DESCRIPTION: function to process data in the main stream thread
 *
 * PARAMETERS :
 *   @data    : user data ptr
 *
 * RETURN     : none
 *==========================================================================*/
void *QCamera3Stream::dataProcRoutine(void *data)
{
    int running = 1;
    int ret;
    QCamera3Stream *pme = (QCamera3Stream *)data;
    QCameraCmdThread *cmdThread = &pme->mProcTh;

    cmdThread->setName(mStreamNames[pme->mStreamInfo->stream_type]);

    LOGD("E");
    do {
        do {
            ret = cam_sem_wait(&cmdThread->cmd_sem);
            if (ret != 0 && errno != EINVAL) {
                LOGE("cam_sem_wait error (%s)",
                       strerror(errno));
                return NULL;
            }
        } while (ret != 0);

        // we got notified about new cmd avail in cmd queue
        camera_cmd_type_t cmd = cmdThread->getCmd();
        switch (cmd) {
        case CAMERA_CMD_TYPE_DO_NEXT_JOB:
            {
                LOGD("Do next job");
                mm_camera_super_buf_t *frame =
                    (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
                if (NULL != frame) {
                    if (UNLIKELY(frame->bufs[0]->buf_type ==
                            CAM_STREAM_BUF_TYPE_USERPTR)) {
                        pme->handleBatchBuffer(frame);
                    } else if (pme->mDataCB != NULL) {
                        pme->mDataCB(frame, pme, pme->mUserData);
                    } else {
                        // no data cb routine, return buf here
                        pme->bufDone(frame->bufs[0]->buf_idx);
                    }
                }
            }
            break;
        case CAMERA_CMD_TYPE_EXIT:
            LOGH("Exit");
            /* flush data buf queue */
            pme->mDataQ.flush();
            pme->flushFreeBatchBufQ();
            running = 0;
            break;
        default:
            break;
        }
    } while (running);
    LOGD("X");
    return NULL;
}

/*===========================================================================
 * FUNCTION   : bufDone
 *
 * DESCRIPTION: return stream buffer to kernel
 *
 * PARAMETERS :
 *   @index   : index of buffer to be returned
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::bufDone(uint32_t index)
{
    int32_t rc = NO_ERROR;
    Mutex::Autolock lock(mLock);

    if ((index >= mNumBufs) || (mBufDefs == NULL)) {
        LOGE("index; %d, mNumBufs: %d", index, mNumBufs);
        return BAD_INDEX;
    }
    if (mStreamBufs == NULL)
    {
        LOGE("putBufs already called");
        return INVALID_OPERATION;
    }

    if( NULL == mBufDefs[index].mem_info) {
        if (NULL == mMemOps) {
            LOGE("Camera operations not initialized");
            return NO_INIT;
        }

        ssize_t bufSize = mStreamBufs->getSize(index);

        if (BAD_INDEX != bufSize) {
            LOGD("Map streamBufIdx: %d", index);
            rc = mMemOps->map_ops(index, -1, mStreamBufs->getFd(index),
                    (size_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF, mMemOps->userdata);
            if (rc < 0) {
                LOGE("Failed to map camera buffer %d", index);
                return rc;
            }

            rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
            if (NO_ERROR != rc) {
                LOGE("Couldn't find camera buffer definition");
                mMemOps->unmap_ops(index, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, mMemOps->userdata);
                return rc;
            }
        } else {
            LOGE("Failed to retrieve buffer size (bad index)");
            return INVALID_OPERATION;
        }
    }

    if (UNLIKELY(mBatchSize)) {
        rc = aggregateBufToBatch(mBufDefs[index]);
    } else {
        rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
        if (rc < 0) {
            return FAILED_TRANSACTION;
        }
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : bufRelease
 *
 * DESCRIPTION: release all resources associated with this buffer
 *
 * PARAMETERS :
 *   @index   : index of buffer to be released
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::bufRelease(int32_t index)
{
    int32_t rc = NO_ERROR;
    Mutex::Autolock lock(mLock);

    if ((index >= mNumBufs) || (mBufDefs == NULL)) {
        return BAD_INDEX;
    }

    if (NULL != mBufDefs[index].mem_info) {
        if (NULL == mMemOps) {
            LOGE("Camera operations not initialized");
            return NO_INIT;
        }

        rc = mMemOps->unmap_ops(index, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF,
                mMemOps->userdata);
        if (rc < 0) {
            LOGE("Failed to un-map camera buffer %d", index);
            return rc;
        }

        mBufDefs[index].mem_info = NULL;
    } else {
        LOGE("Buffer at index %d not registered");
        return BAD_INDEX;
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : getBufs
 *
 * DESCRIPTION: allocate stream buffers
 *
 * PARAMETERS :
 *   @offset     : offset info of stream buffers
 *   @num_bufs   : number of buffers allocated
 *   @initial_reg_flag: flag to indicate if buffer needs to be registered
 *                      at kernel initially
 *   @bufs       : output of allocated buffers
 *   @ops_tbl    : ptr to buf mapping/unmapping ops
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
                     uint8_t *num_bufs,
                     uint8_t **initial_reg_flag,
                     mm_camera_buf_def_t **bufs,
                     mm_camera_map_unmap_ops_tbl_t *ops_tbl)
{
    int rc = NO_ERROR;
    uint8_t *regFlags;
    Mutex::Autolock lock(mLock);

    if (!ops_tbl) {
        LOGE("ops_tbl is NULL");
        return INVALID_OPERATION;
    }

    mFrameLenOffset = *offset;
    mMemOps = ops_tbl;

    if (mStreamBufs != NULL) {
       LOGE("Failed getBufs being called twice in a row without a putBufs call");
       return INVALID_OPERATION;
    }
    mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len);
    if (!mStreamBufs) {
        LOGE("Failed to allocate stream buffers");
        return NO_MEMORY;
    }

    for (uint32_t i = 0; i < mNumBufs; i++) {
        if (mStreamBufs->valid(i)) {
            ssize_t bufSize = mStreamBufs->getSize(i);
            if (BAD_INDEX != bufSize) {
                rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
                        (size_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF,
                        ops_tbl->userdata);
                if (rc < 0) {
                    LOGE("map_stream_buf failed: %d", rc);
                    for (uint32_t j = 0; j < i; j++) {
                        if (mStreamBufs->valid(j)) {
                            ops_tbl->unmap_ops(j, -1,
                                    CAM_MAPPING_BUF_TYPE_STREAM_BUF,
                                    ops_tbl->userdata);
                        }
                    }
                    return INVALID_OPERATION;
                }
            } else {
                LOGE("Failed to retrieve buffer size (bad index)");
                return INVALID_OPERATION;
            }
        }
    }

    //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
    regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
    if (!regFlags) {
        LOGE("Out of memory");
        for (uint32_t i = 0; i < mNumBufs; i++) {
            if (mStreamBufs->valid(i)) {
                ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF,
                        ops_tbl->userdata);
            }
        }
        return NO_MEMORY;
    }
    memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);

    mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
    if (mBufDefs == NULL) {
        LOGE("Failed to allocate mm_camera_buf_def_t %d", rc);
        for (uint32_t i = 0; i < mNumBufs; i++) {
            if (mStreamBufs->valid(i)) {
                ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF,
                        ops_tbl->userdata);
            }
        }
        free(regFlags);
        regFlags = NULL;
        return INVALID_OPERATION;
    }
    memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
    for (uint32_t i = 0; i < mNumBufs; i++) {
        if (mStreamBufs->valid(i)) {
            mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
        }
    }

    rc = mStreamBufs->getRegFlags(regFlags);
    if (rc < 0) {
        LOGE("getRegFlags failed %d", rc);
        for (uint32_t i = 0; i < mNumBufs; i++) {
            if (mStreamBufs->valid(i)) {
                ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF,
                        ops_tbl->userdata);
            }
        }
        free(mBufDefs);
        mBufDefs = NULL;
        free(regFlags);
        regFlags = NULL;
        return INVALID_OPERATION;
    }

    *num_bufs = mNumBufs;
    *initial_reg_flag = regFlags;
    *bufs = mBufDefs;
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : putBufs
 *
 * DESCRIPTION: deallocate stream buffers
 *
 * PARAMETERS :
 *   @ops_tbl    : ptr to buf mapping/unmapping ops
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
{
    int rc = NO_ERROR;
    Mutex::Autolock lock(mLock);

    for (uint32_t i = 0; i < mNumBufs; i++) {
        if (mStreamBufs->valid(i) && NULL != mBufDefs[i].mem_info) {
            rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
            if (rc < 0) {
                LOGE("un-map stream buf failed: %d", rc);
            }
        }
    }
    mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
                     // mm-camera-interface own the buffer, so no need to free
    memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));

    if (mStreamBufs == NULL) {
        LOGE("getBuf failed previously, or calling putBufs twice");
    }

    mChannel->putStreamBufs();

    //need to set mStreamBufs to null because putStreamBufs deletes that memory
    mStreamBufs = NULL;

    return rc;
}

/*===========================================================================
 * FUNCTION   : invalidateBuf
 *
 * DESCRIPTION: invalidate a specific stream buffer
 *
 * PARAMETERS :
 *   @index   : index of the buffer to invalidate
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::invalidateBuf(uint32_t index)
{
    if (mStreamBufs == NULL) {
       LOGE("putBufs already called");
       return INVALID_OPERATION;
    } else
       return mStreamBufs->invalidateCache(index);
}

/*===========================================================================
 * FUNCTION   : cleanInvalidateBuf
 *
 * DESCRIPTION: clean and invalidate a specific stream buffer
 *
 * PARAMETERS :
 *   @index   : index of the buffer to invalidate
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::cleanInvalidateBuf(uint32_t index)
{
    if (mStreamBufs == NULL) {
        LOGE("putBufs already called");
        return INVALID_OPERATION;
    } else
        return mStreamBufs->cleanInvalidateCache(index);
}

/*===========================================================================
 * FUNCTION   : getFrameOffset
 *
 * DESCRIPTION: query stream buffer frame offset info
 *
 * PARAMETERS :
 *   @offset  : reference to struct to store the queried frame offset info
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::getFrameOffset(cam_frame_len_offset_t &offset)
{
    offset = mFrameLenOffset;
    return 0;
}

/*===========================================================================
 * FUNCTION   : getFrameDimension
 *
 * DESCRIPTION: query stream frame dimension info
 *
 * PARAMETERS :
 *   @dim     : reference to struct to store the queried frame dimension
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::getFrameDimension(cam_dimension_t &dim)
{
    if (mStreamInfo != NULL) {
        dim = mStreamInfo->dim;
        return 0;
    }
    return -1;
}

/*===========================================================================
 * FUNCTION   : getFormat
 *
 * DESCRIPTION: query stream format
 *
 * PARAMETERS :
 *   @fmt     : reference to stream format
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::getFormat(cam_format_t &fmt)
{
    if (mStreamInfo != NULL) {
        fmt = mStreamInfo->fmt;
        return 0;
    }
    return -1;
}

/*===========================================================================
 * FUNCTION   : getMyServerID
 *
 * DESCRIPTION: query server stream ID
 *
 * PARAMETERS : None
 *
 * RETURN     : stream ID from server
 *==========================================================================*/
uint32_t QCamera3Stream::getMyServerID() {
    if (mStreamInfo != NULL) {
        return mStreamInfo->stream_svr_id;
    } else {
        return 0;
    }
}

/*===========================================================================
 * FUNCTION   : getMyType
 *
 * DESCRIPTION: query stream type
 *
 * PARAMETERS : None
 *
 * RETURN     : type of stream
 *==========================================================================*/
cam_stream_type_t QCamera3Stream::getMyType() const
{
    if (mStreamInfo != NULL) {
        return mStreamInfo->stream_type;
    } else {
        return CAM_STREAM_TYPE_MAX;
    }
}

/*===========================================================================
 * FUNCTION   : mapBuf
 *
 * DESCRIPTION: map stream related buffer to backend server
 *
 * PARAMETERS :
 *   @buf_type : mapping type of buffer
 *   @buf_idx  : index of buffer
 *   @plane_idx: plane index
 *   @fd       : fd of the buffer
 *   @size     : lenght of the buffer
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::mapBuf(uint8_t buf_type, uint32_t buf_idx,
        int32_t plane_idx, int fd, size_t size)
{
    return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
                                   mHandle, buf_type,
                                   buf_idx, plane_idx,
                                   fd, size);

}

/*===========================================================================
 * FUNCTION   : unmapBuf
 *
 * DESCRIPTION: unmap stream related buffer to backend server
 *
 * PARAMETERS :
 *   @buf_type : mapping type of buffer
 *   @buf_idx  : index of buffer
 *   @plane_idx: plane index
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
{
    return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
                                     mHandle, buf_type,
                                     buf_idx, plane_idx);
}

/*===========================================================================
 * FUNCTION   : setParameter
 *
 * DESCRIPTION: set stream based parameters
 *
 * PARAMETERS :
 *   @param   : ptr to parameters to be set
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::setParameter(cam_stream_parm_buffer_t &param)
{
    int32_t rc = NO_ERROR;
    mStreamInfo->parm_buf = param;
    rc = mCamOps->set_stream_parms(mCamHandle,
                                   mChannelHandle,
                                   mHandle,
                                   &mStreamInfo->parm_buf);
    if (rc == NO_ERROR) {
        param = mStreamInfo->parm_buf;
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : releaseFrameData
 *
 * DESCRIPTION: callback function to release frame data node
 *
 * PARAMETERS :
 *   @data      : ptr to post process input data
 *   @user_data : user data ptr (QCameraReprocessor)
 *
 * RETURN     : None
 *==========================================================================*/
void QCamera3Stream::releaseFrameData(void *data, void *user_data)
{
    QCamera3Stream *pme = (QCamera3Stream *)user_data;
    mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
    if (NULL != pme) {
        if (UNLIKELY(pme->mBatchSize)) {
            /* For batch mode, the batch buffer is added to empty list */
            if(!pme->mFreeBatchBufQ.enqueue((void*) frame->bufs[0])) {
                LOGE("batchBuf.buf_idx: %d enqueue failed",
                        frame->bufs[0]->buf_idx);
            }
        } else {
            pme->bufDone(frame->bufs[0]->buf_idx);
        }
    }
}

/*===========================================================================
 * FUNCTION   : getBatchBufs
 *
 * DESCRIPTION: allocate batch containers for the stream
 *
 * PARAMETERS :
 *   @num_bufs   : number of buffers allocated
 *   @initial_reg_flag: flag to indicate if buffer needs to be registered
 *                      at kernel initially
 *   @bufs       : output of allocated buffers
  *  @ops_tbl    : ptr to buf mapping/unmapping ops
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::getBatchBufs(
        uint8_t *num_bufs, uint8_t **initial_reg_flag,
        mm_camera_buf_def_t **bufs,
        mm_camera_map_unmap_ops_tbl_t *ops_tbl)
{
    int rc = NO_ERROR;
    uint8_t *regFlags;

    if (!ops_tbl || !num_bufs || !initial_reg_flag || !bufs) {
        LOGE("input args NULL");
        return INVALID_OPERATION;
    }
    LOGH("Batch container allocation stream type = %d",
             getMyType());

    Mutex::Autolock lock(mLock);

    mMemOps = ops_tbl;

    //Allocate batch containers
    mStreamBatchBufs = new QCamera3HeapMemory(1);
    if (!mStreamBatchBufs) {
        LOGE("unable to create batch container memory");
        return NO_MEMORY;
    }
    // Allocating single buffer file-descriptor for all batch containers,
    // mStreamBatchBufs considers all the container bufs as a single buffer. But
    // QCamera3Stream manages that single buffer as multiple batch buffers
    LOGD("Allocating batch container memory. numBatch: %d size: %d",
             mNumBatchBufs, mStreamInfo->user_buf_info.size);
    rc = mStreamBatchBufs->allocate(
            mNumBatchBufs * mStreamInfo->user_buf_info.size);
    if (rc < 0) {
        LOGE("unable to allocate batch container memory");
        rc = NO_MEMORY;
        goto err1;
    }

    /* map batch buffers. getCnt here returns 1 because of single FD across
     * batch bufs */
    for (uint32_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
        if (mNumBatchBufs) {
            //For USER_BUF, size = number_of_container bufs instead of the total
            //buf size
            rc = ops_tbl->map_ops(i, -1, mStreamBatchBufs->getFd(i),
                    (size_t)mNumBatchBufs, CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
                    ops_tbl->userdata);
            if (rc < 0) {
                LOGE("Failed to map stream container buffer: %d",
                         rc);
                //Unmap all the buffers that were successfully mapped before
                //this buffer mapping failed
                for (size_t j = 0; j < i; j++) {
                    ops_tbl->unmap_ops(j, -1,
                            CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
                            ops_tbl->userdata);
                }
                goto err2;
            }
        } else {
            LOGE("Failed to retrieve buffer size (bad index)");
            return INVALID_OPERATION;
        }
    }

    LOGD("batch bufs successfully mmapped = %d",
             mNumBatchBufs);

    /* regFlags array is allocated here, but consumed and freed by
     * mm-camera-interface */
    regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBatchBufs);
    if (!regFlags) {
        LOGE("Out of memory");
        rc = NO_MEMORY;
        goto err3;
    }
    memset(regFlags, 0, sizeof(uint8_t) * mNumBatchBufs);
    /* Do not queue the container buffers as the image buffers are not yet
     * queued. mStreamBatchBufs->getRegFlags is not called as mStreamBatchBufs
     * considers single buffer is allocated */
    for (uint32_t i = 0; i < mNumBatchBufs; i++) {
        regFlags[i] = 0;
    }

    mBatchBufDefs = (mm_camera_buf_def_t *)
            malloc(mNumBatchBufs * sizeof(mm_camera_buf_def_t));
    if (mBatchBufDefs == NULL) {
        LOGE("mBatchBufDefs memory allocation failed");
        rc = INVALID_OPERATION;
        goto err4;
    }
    memset(mBatchBufDefs, 0, mNumBatchBufs * sizeof(mm_camera_buf_def_t));

    //Populate bufDef and queue to free batchBufQ
    for (uint32_t i = 0; i < mNumBatchBufs; i++) {
        getBatchBufDef(mBatchBufDefs[i], i);
        if(mFreeBatchBufQ.enqueue((void*) &mBatchBufDefs[i])) {
            LOGD("mBatchBufDefs[%d]: 0x%p", i, &mBatchBufDefs[i]);
        } else {
            LOGE("enqueue mBatchBufDefs[%d] failed", i);
        }
    }

    *num_bufs = mNumBatchBufs;
    *initial_reg_flag = regFlags;
    *bufs = mBatchBufDefs;
    LOGH("stream type: %d, numBufs(batch): %d",
             mStreamInfo->stream_type, mNumBatchBufs);

    return NO_ERROR;
err4:
    free(regFlags);
err3:
    for (size_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
        ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
                ops_tbl->userdata);
    }
err2:
    mStreamBatchBufs->deallocate();
err1:
    delete mStreamBatchBufs;
    mStreamBatchBufs = NULL;
    return rc;
}

/*===========================================================================
 * FUNCTION   : putBatchBufs
 *
 * DESCRIPTION: deallocate stream batch buffers
 *
 * PARAMETERS :
 *   @ops_tbl    : ptr to buf mapping/unmapping ops
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::putBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
{
    int rc = NO_ERROR;
    Mutex::Autolock lock(mLock);

    if (mStreamBatchBufs) {
        for (uint32_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
            rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
                    ops_tbl->userdata);
            if (rc < 0) {
                LOGE("un-map batch buf failed: %d", rc);
            }
        }
        mStreamBatchBufs->deallocate();
        delete mStreamBatchBufs;
        mStreamBatchBufs = NULL;
    }
    // mm-camera-interface frees bufDefs even though bufDefs are allocated by
    // QCamera3Stream. Don't free here
    mBatchBufDefs = NULL;

    return rc;
}

/*===========================================================================
 * FUNCTION   : getBatchBufDef
 *
 * DESCRIPTION: query detailed buffer information of batch buffer
 *
 * PARAMETERS :
 *   @bufDef  : [output] reference to struct to store buffer definition
 *   @@index  : [input] index of the buffer
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::getBatchBufDef(mm_camera_buf_def_t& batchBufDef,
        int32_t index)
{
    int rc = NO_ERROR;
    memset(&batchBufDef, 0, sizeof(mm_camera_buf_def_t));
    if (mStreamBatchBufs) {
        //Single file descriptor for all batch buffers
        batchBufDef.fd          = mStreamBatchBufs->getFd(0);
        batchBufDef.buf_type    = CAM_STREAM_BUF_TYPE_USERPTR;
        batchBufDef.frame_len   = mStreamInfo->user_buf_info.size;
        batchBufDef.mem_info    = mStreamBatchBufs;
        batchBufDef.buffer      = (uint8_t *)mStreamBatchBufs->getPtr(0) +
                                    (index * mStreamInfo->user_buf_info.size);
        batchBufDef.buf_idx     = index;
        batchBufDef.user_buf.num_buffers = mBatchSize;
        batchBufDef.user_buf.bufs_used = 0;
        batchBufDef.user_buf.plane_buf = mBufDefs;
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : aggregateBufToBatch
 *
 * DESCRIPTION: queue batch container to downstream.
 *
 * PARAMETERS :
 *   @bufDef : image buffer to be aggregated into batch
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success always
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::aggregateBufToBatch(mm_camera_buf_def_t& bufDef)
{
    int32_t rc = NO_ERROR;

    if (UNLIKELY(!mBatchSize)) {
        LOGE("Batch mod is not enabled");
        return INVALID_OPERATION;
    }
    if (!mCurrentBatchBufDef) {
        mCurrentBatchBufDef = (mm_camera_buf_def_t *)mFreeBatchBufQ.dequeue();
        if (!mCurrentBatchBufDef) {
            LOGE("No empty batch buffers is available");
            return NO_MEMORY;
        }
        LOGD("batch buffer: %d dequeued from empty buffer list",
                mCurrentBatchBufDef->buf_idx);
    }
    if (mBufsStaged == mCurrentBatchBufDef->user_buf.num_buffers) {
        LOGE("batch buffer is already full");
        return NO_MEMORY;
    }

    mCurrentBatchBufDef->user_buf.buf_idx[mBufsStaged] = bufDef.buf_idx;
    mBufsStaged++;
    LOGD("buffer id: %d aggregated into batch buffer id: %d",
             bufDef.buf_idx, mCurrentBatchBufDef->buf_idx);
    return rc;
}

/*===========================================================================
 * FUNCTION   : queueBatchBuf
 *
 * DESCRIPTION: queue batch container to downstream.
 *
 * PARAMETERS : None
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success always
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::queueBatchBuf()
{
    int32_t rc = NO_ERROR;

    if (!mCurrentBatchBufDef) {
        LOGE("No buffers were queued into batch");
        return INVALID_OPERATION;
    }
    //bufs_used: number of valid buffers in the batch buffers
    mCurrentBatchBufDef->user_buf.bufs_used = mBufsStaged;

    //if mBufsStaged < num_buffers, initialize the buf_idx to -1 for rest of the
    //buffers
    for (size_t i = mBufsStaged; i < mCurrentBatchBufDef->user_buf.num_buffers;
            i++) {
        mCurrentBatchBufDef->user_buf.buf_idx[i] = -1;
    }

    rc = mCamOps->qbuf(mCamHandle, mChannelHandle, mCurrentBatchBufDef);
    if (rc < 0) {
        LOGE("queueing of batch buffer: %d failed with err: %d",
                mCurrentBatchBufDef->buf_idx, rc);
        return FAILED_TRANSACTION;
    }
    LOGD("Batch buf id: %d queued. bufs_used: %d",
            mCurrentBatchBufDef->buf_idx,
            mCurrentBatchBufDef->user_buf.bufs_used);

    mCurrentBatchBufDef = NULL;
    mBufsStaged = 0;

    return rc;
}

/*===========================================================================
 * FUNCTION   : handleBatchBuffer
 *
 * DESCRIPTION: separate individual buffers from the batch and issue callback
 *
 * PARAMETERS :
 *   @superBuf : Received superbuf containing batch buffer
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success always
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera3Stream::handleBatchBuffer(mm_camera_super_buf_t *superBuf)
{
    int32_t rc = NO_ERROR;
    mm_camera_super_buf_t *frame;
    mm_camera_buf_def_t batchBuf;

    if (LIKELY(!mBatchSize)) {
        LOGE("Stream: %d not in batch mode, but batch buffer received",
                 getMyType());
        return INVALID_OPERATION;
    }
    if (!mDataCB) {
        LOGE("Data callback not set for batch mode");
        return BAD_VALUE;
    }
    if (!superBuf->bufs[0]) {
        LOGE("superBuf->bufs[0] is NULL!!");
        return BAD_VALUE;
    }

    /* Copy the batch buffer to local and queue the batch buffer to  empty queue
     * to handle the new requests received while callbacks are in progress */
    batchBuf = *superBuf->bufs[0];
    if (!mFreeBatchBufQ.enqueue((void*) superBuf->bufs[0])) {
        LOGE("batchBuf.buf_idx: %d enqueue failed",
                batchBuf.buf_idx);
        free(superBuf);
        return NO_MEMORY;
    }
    LOGD("Received batch buffer: %d bufs_used: %d",
            batchBuf.buf_idx, batchBuf.user_buf.bufs_used);
    //dummy local bufDef to issue multiple callbacks
    mm_camera_buf_def_t buf;
    memset(&buf, 0, sizeof(mm_camera_buf_def_t));

    for (size_t i = 0; i < batchBuf.user_buf.bufs_used; i++) {
        int32_t buf_idx = batchBuf.user_buf.buf_idx[i];
        buf = mBufDefs[buf_idx];

        /* this memory is freed inside dataCB. Should not be freed here */
        frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
        if (!frame) {
            LOGE("malloc failed. Buffers will be dropped");
            break;
        } else {
            memcpy(frame, superBuf, sizeof(mm_camera_super_buf_t));
            frame->bufs[0] = &buf;

            mDataCB(frame, this, mUserData);
        }
    }
    LOGD("batch buffer: %d callbacks done",
            batchBuf.buf_idx);

    free(superBuf);
    return rc;
}

/*===========================================================================
 * FUNCTION   : flushFreeBatchBufQ
 *
 * DESCRIPTION: dequeue all the entries of mFreeBatchBufQ and call flush.
 *              QCameraQueue::flush calls 'free(node->data)' which should be
 *              avoided for mFreeBatchBufQ as the entries are not allocated
 *              during each enqueue
 *
 * PARAMETERS : None
 *
 * RETURN     : None
 *==========================================================================*/
void QCamera3Stream::flushFreeBatchBufQ()
{
    while (!mFreeBatchBufQ.isEmpty()) {
        mFreeBatchBufQ.dequeue();
    }
    mFreeBatchBufQ.flush();
}

}; // namespace qcamera
