/*
Copyright (c) 2011-2012, 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.
*/

#include <pthread.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include <semaphore.h>
#include <linux/msm_ion.h>

#include "mm_camera_dbg.h"
#include "mm_camera_interface.h"
#include "mm_camera.h"

extern mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler);
extern mm_channel_t * mm_camera_util_get_channel_by_handler(
                                    mm_camera_obj_t * cam_obj,
                                    uint32_t handler);
extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
                                       cam_ctrl_type type,
                                       uint32_t length,
                                       void *value);
extern int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj,
                                               cam_ctrl_type type,
                                               uint32_t length,
                                               void *value,
                                               int timeout);

/* internal function declare goes here */
int32_t mm_channel_qbuf(mm_channel_t *my_obj,
                        mm_camera_buf_def_t *buf);
int32_t mm_channel_init(mm_channel_t *my_obj);
void mm_channel_release(mm_channel_t *my_obj);
uint32_t mm_channel_add_stream(mm_channel_t *my_obj,
                                   mm_camera_buf_notify_t buf_cb, void *user_data,
                                   uint32_t ext_image_mode, uint32_t sensor_idx);
int32_t mm_channel_del_stream(mm_channel_t *my_obj,
                                   uint32_t stream_id);
int32_t mm_channel_config_stream(mm_channel_t *my_obj,
                                 uint32_t stream_id,
                                 mm_camera_stream_config_t *config);
int32_t mm_channel_bundle_stream(mm_channel_t *my_obj,
                                 mm_camera_buf_notify_t super_frame_notify_cb,
                                 void *user_data,
                                 mm_camera_bundle_attr_t *attr,
                                 uint8_t num_streams,
                                 uint32_t *stream_ids);
int32_t mm_channel_destroy_bundle(mm_channel_t *my_obj);
int32_t mm_channel_start_streams(mm_channel_t *my_obj,
                                 uint8_t num_streams,
                                 uint32_t *stream_ids);
int32_t mm_channel_stop_streams(mm_channel_t *my_obj,
                                uint8_t num_streams,
                                uint32_t *stream_ids,
                                uint8_t tear_down_flag);
int32_t mm_channel_request_super_buf(mm_channel_t *my_obj);
int32_t mm_channel_cancel_super_buf_request(mm_channel_t *my_obj);
int32_t mm_channel_start_focus(mm_channel_t *my_obj,
                               uint32_t sensor_idx,
                               uint32_t focus_mode);
int32_t mm_channel_abort_focus(mm_channel_t *my_obj,
                               uint32_t sensor_idx);
int32_t mm_channel_prepare_snapshot(mm_channel_t *my_obj,
                                    uint32_t sensor_idx);
int32_t mm_channel_set_stream_parm(mm_channel_t *my_obj,
                                   uint32_t s_id,
                                   void *value);
int32_t mm_channel_get_stream_parm(mm_channel_t *my_obj,
                                   uint32_t s_id,
                                   void *value);
uint8_t mm_channel_need_do_pp(mm_channel_t *my_obj,
                              mm_channel_queue_node_t *super_buf);
int32_t mm_channel_do_post_processing(mm_channel_t *my_obj,
                                      mm_channel_queue_node_t *super_buf);
int32_t mm_channel_cancel_post_processing(mm_channel_t *my_obj);
int32_t mm_channel_superbuf_bufdone_overflow(mm_channel_t* my_obj,
                                             mm_channel_queue_t * queue);
int32_t mm_channel_superbuf_skip(mm_channel_t* my_obj,
                                 mm_channel_queue_t * queue);

/* state machine function declare */
int32_t mm_channel_fsm_fn_notused(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val);
int32_t mm_channel_fsm_fn_stopped(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val);
int32_t mm_channel_fsm_fn_active(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val);
int32_t mm_channel_fsm_fn_paused(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val);

/* channel super queue functions */
int32_t mm_channel_superbuf_queue_init(mm_channel_queue_t * queue);
int32_t mm_channel_superbuf_queue_deinit(mm_channel_queue_t * queue);
int32_t mm_channel_superbuf_comp_and_enqueue(mm_channel_t *ch_obj,
                                             mm_channel_queue_t * queue,
                                             mm_camera_buf_info_t *buf);
mm_channel_queue_node_t* mm_channel_superbuf_dequeue(mm_channel_queue_t * queue);

/* channel utility function */
mm_stream_t * mm_channel_util_get_stream_by_handler(
                                    mm_channel_t * ch_obj,
                                    uint32_t handler)
{
    int i;
    mm_stream_t *s_obj = NULL;
    uint8_t ch_idx = mm_camera_util_get_index_by_handler(handler);

    for(i = 0; i < MM_CAMEAR_STRAEM_NUM_MAX; i++) {
        if (handler == ch_obj->streams[i].my_hdl) {
            s_obj = &ch_obj->streams[i];
            break;
        }
    }
    return s_obj;
}

/* CB for handling post processing result from ctrl evt */
static void mm_channel_pp_result_notify(uint32_t camera_handler,
                                        mm_camera_event_t *evt,
                                        void *user_data)
{
    uint32_t ch_hdl = (uint32_t)user_data;
    mm_camera_obj_t *cam_obj = NULL;
    mm_channel_t *ch_obj = NULL;
    mm_channel_queue_node_t * node = NULL;
    mm_channel_pp_info_t* pp_info = NULL;

    cam_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    if (NULL == cam_obj) {
        CDBG("%s: No matching camera handler", __func__);
        return;
    }

    ch_obj = mm_camera_util_get_channel_by_handler(cam_obj, ch_hdl);
    if (NULL == ch_obj) {
        CDBG("%s: No matching channel handler", __func__);
        return;
    }

    pthread_mutex_lock(&ch_obj->ch_lock);
    if (ch_obj->pending_pp_cnt > 0) {
        if (MM_CAMERA_EVT_TYPE_CTRL == evt->event_type) {
            /* PP result is sent as CTRL event
             * currently we only have WNR */
            if (MM_CAMERA_CTRL_EVT_WDN_DONE == evt->e.ctrl.evt) {
                /* WNR result */
                pp_info = (mm_channel_pp_info_t *)evt->e.ctrl.cookie;
                if (NULL != pp_info) {
                    node = pp_info->super_buf;
                }
            }
        }

        if (NULL != node) {
            uint8_t pp_done = 1;
            if (CAM_CTRL_SUCCESS == evt->e.ctrl.status) {
                uint8_t i;
                /* 1) update need_pp flag as action done */
                for (i=0; i<node->num_of_bufs; i++) {
                    if (node->super_buf[i].stream_id == pp_info->stream_hdl) {
                        /* stream pp is done, set the flag to 0*/
                        node->super_buf[i].need_pp = 0;
                        break;
                    }
                }

                /* 2) check if all bufs done with pp */
                for (i=0; i<node->num_of_bufs; i++) {
                    if (node->super_buf[i].need_pp) {
                        pp_done = 0;
                        break;
                    }
                }
            }

            if (pp_done) {
                /* send super buf to CB */
                if (NULL != ch_obj->bundle.super_buf_notify_cb) {
                    mm_camera_super_buf_t super_buf;
                    uint8_t i;

                    memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
                    super_buf.num_bufs = node->num_of_bufs;
                    for (i=0; i<node->num_of_bufs; i++) {
                        super_buf.bufs[i] = node->super_buf[i].buf;
                    }
                    super_buf.camera_handle = ch_obj->cam_obj->my_hdl;
                    super_buf.ch_id = ch_obj->my_hdl;

                    ch_obj->bundle.super_buf_notify_cb(&super_buf,
                                                       ch_obj->bundle.user_data);
                    ch_obj->pending_pp_cnt--;
                } else {
                    /* buf done with the nonuse super buf */
                    uint8_t i;
                    for (i=0; i<node->num_of_bufs; i++) {
                        mm_channel_qbuf(ch_obj, node->super_buf[i].buf);
                    }
                }

                /* done with node, free it */
                free(node);
            }
        }
    }
    pthread_mutex_unlock(&ch_obj->ch_lock);
}

/* CB for processing stream buffer */
static void mm_channel_process_stream_buf(mm_camera_cmdcb_t * cmd_cb,
                                          void *user_data)
{
    mm_camera_super_buf_notify_mode_t notify_mode;
    mm_channel_queue_node_t *node = NULL;
    mm_channel_t *ch_obj = (mm_channel_t *)user_data;
    if (NULL == ch_obj) {
        return;
    }

    if (MM_CAMERA_CMD_TYPE_DATA_CB  == cmd_cb->cmd_type) {
        /* comp_and_enqueue */
        mm_channel_superbuf_comp_and_enqueue(
                        ch_obj,
                        &ch_obj->bundle.superbuf_queue,
                        &cmd_cb->u.buf);
    }

    notify_mode = ch_obj->bundle.superbuf_queue.attr.notify_mode;

    /* bufdone for overflowed bufs */
    mm_channel_superbuf_bufdone_overflow(ch_obj, &ch_obj->bundle.superbuf_queue);

    /* lock ch_lock */
    pthread_mutex_lock(&ch_obj->ch_lock);

    /* dispatch frame if pending_cnt>0 or is in continuous streaming mode */
    while ( (ch_obj->pending_cnt > 0) ||
            (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == notify_mode) ) {

        /* skip frames if needed */
        mm_channel_superbuf_skip(ch_obj, &ch_obj->bundle.superbuf_queue);

        /* dequeue */
        node = mm_channel_superbuf_dequeue(&ch_obj->bundle.superbuf_queue);
        if (NULL != node) {
            /* decrease pending_cnt */
            CDBG("%s: Super Buffer received, Call client callback",__func__);
            if (MM_CAMERA_SUPER_BUF_NOTIFY_BURST == notify_mode) {
                ch_obj->pending_cnt--;
            }

            if (mm_channel_need_do_pp(ch_obj, node)) {
                /* do post processing */
                ch_obj->pending_pp_cnt++;
                mm_channel_do_post_processing(ch_obj, node);
                /* no need to free node here
                 * node will be as cookie sent to backend doing pp */
            } else {
                /* dispatch superbuf */
                if (NULL != ch_obj->bundle.super_buf_notify_cb) {
                    mm_camera_super_buf_t super_buf;
                    uint8_t i;

                    memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
                    super_buf.num_bufs = node->num_of_bufs;
                    for (i=0; i<node->num_of_bufs; i++) {
                        super_buf.bufs[i] = node->super_buf[i].buf;
                    }
                    super_buf.camera_handle = ch_obj->cam_obj->my_hdl;
                    super_buf.ch_id = ch_obj->my_hdl;

                    ch_obj->bundle.super_buf_notify_cb(&super_buf,
                                                       ch_obj->bundle.user_data);
                } else {
                    /* buf done with the nonuse super buf */
                    uint8_t i;
                    for (i=0; i<node->num_of_bufs; i++) {
                        mm_channel_qbuf(ch_obj, node->super_buf[i].buf);
                    }
                }
                free(node);
            }
        } else {
            /* no superbuf avail, break the loop */
            CDBG_ERROR("%s : Superbuffer not available",__func__);
            break;
        }
    }

    /* unlock ch_lock */
    pthread_mutex_unlock(&ch_obj->ch_lock);
}

/* state machine entry */
int32_t mm_channel_fsm_fn(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val)
{
    int32_t rc = -1;

    CDBG("%s : E state = %d",__func__,my_obj->state);
    switch (my_obj->state) {
    case MM_CHANNEL_STATE_NOTUSED:
        rc = mm_channel_fsm_fn_notused(my_obj, evt, in_val, out_val);
        break;
    case MM_CHANNEL_STATE_STOPPED:
        rc = mm_channel_fsm_fn_stopped(my_obj, evt, in_val, out_val);
        break;
    case MM_CHANNEL_STATE_ACTIVE:
        rc = mm_channel_fsm_fn_active(my_obj, evt, in_val, out_val);
        break;
    case MM_CHANNEL_STATE_PAUSED:
        rc = mm_channel_fsm_fn_paused(my_obj, evt, in_val, out_val);
        break;
    default:
        CDBG("%s: Not a valid state (%d)", __func__, my_obj->state);
        break;
    }

    /* unlock ch_lock */
    pthread_mutex_unlock(&my_obj->ch_lock);
    CDBG("%s : X rc = %d",__func__,rc);
    return rc;
}

int32_t mm_channel_fsm_fn_notused(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val)
{
    int32_t rc = -1;

    switch (evt) {
    default:
        CDBG_ERROR("%s: invalid state (%d) for evt (%d)",
                   __func__, my_obj->state, evt);
        break;
    }

    return rc;
}

int32_t mm_channel_fsm_fn_stopped(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val)
{
    int32_t rc = -1;
    CDBG("%s : E evt = %d",__func__,evt);
    switch (evt) {
    case MM_CHANNEL_EVT_ADD_STREAM:
        {
            uint32_t s_hdl = 0;
            mm_evt_paylod_add_stream_t *payload =
                (mm_evt_paylod_add_stream_t *)in_val;
            s_hdl = mm_channel_add_stream(my_obj,
                                          payload->buf_cb,
                                          payload->user_data,
                                          payload->ext_image_mode,
                                          payload->sensor_idx);
            *((uint32_t*)out_val) = s_hdl;
            rc = 0;
        }
        break;
    case MM_CHANNEL_EVT_DEL_STREAM:
        {
            uint32_t s_id = *((uint32_t *)in_val);
            rc = mm_channel_del_stream(my_obj, s_id);
        }
        break;
    case MM_CHANNEL_EVT_START_STREAM:
        {
            mm_evt_payload_start_stream_t *payload =
                (mm_evt_payload_start_stream_t *)in_val;
            rc = mm_channel_start_streams(my_obj,
                                          payload->num_streams,
                                          payload->stream_ids);
            /* first stream started in stopped state
             * move to active state */
            if (0 == rc) {
                my_obj->state = MM_CHANNEL_STATE_ACTIVE;
            }
        }
        break;
    case MM_CHANNEL_EVT_CONFIG_STREAM:
        {
            mm_evt_paylod_config_stream_t *payload =
                (mm_evt_paylod_config_stream_t *)in_val;
            rc = mm_channel_config_stream(my_obj,
                                          payload->stream_id,
                                          payload->config);
        }
        break;
    case MM_CHANNEL_EVT_INIT_BUNDLE:
        {
            mm_evt_payload_bundle_stream_t *payload =
                (mm_evt_payload_bundle_stream_t *)in_val;
            rc = mm_channel_bundle_stream(my_obj,
                                          payload->super_frame_notify_cb,
                                          payload->user_data,
                                          payload->attr,
                                          payload->num_streams,
                                          payload->stream_ids);
        }
        break;
    case MM_CHANNEL_EVT_DESTROY_BUNDLE:
        rc = mm_channel_destroy_bundle(my_obj);
        break;
    case MM_CHANNEL_EVT_PREPARE_SNAPSHOT:
        {
            uint32_t sensor_idx = (uint32_t)in_val;
            rc = mm_channel_prepare_snapshot(my_obj, sensor_idx);
        }
        break;
    case MM_CHANNEL_EVT_DELETE:
        mm_channel_release(my_obj);
        rc = 0;
        break;
    case MM_CHANNEL_EVT_SET_STREAM_PARM:
        {
            uint32_t s_id = (uint32_t)in_val;
            rc = mm_channel_set_stream_parm(my_obj, s_id, out_val);
        }
        break;
    case MM_CHANNEL_EVT_GET_STREAM_PARM:
        {
            uint32_t s_id = (uint32_t)in_val;
            rc = mm_channel_get_stream_parm(my_obj, s_id, out_val);
        }
        break;
    default:
        CDBG_ERROR("%s: invalid state (%d) for evt (%d)",
                   __func__, my_obj->state, evt);
        break;
    }
    CDBG("%s : E rc = %d",__func__,rc);
    return rc;
}

int32_t mm_channel_fsm_fn_active(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val)
{
    int32_t rc = -1;

    CDBG("%s : E evt = %d",__func__,evt);
    switch (evt) {
    case MM_CHANNEL_EVT_CONFIG_STREAM:
        {
            mm_evt_paylod_config_stream_t *payload =
                (mm_evt_paylod_config_stream_t *)in_val;
            rc = mm_channel_config_stream(my_obj,
                                          payload->stream_id,
                                          payload->config);
        }
        break;
    case MM_CHANNEL_EVT_START_STREAM:
        {
            mm_evt_payload_start_stream_t *payload =
                (mm_evt_payload_start_stream_t *)in_val;
            rc = mm_channel_start_streams(my_obj,
                                          payload->num_streams,
                                          payload->stream_ids);
        }
        break;
    case MM_CHANNEL_EVT_STOP_STREAM:
    case MM_CHANNEL_EVT_TEARDOWN_STREAM:
        {
            int i;
            uint8_t tear_down_flag = (MM_CHANNEL_EVT_TEARDOWN_STREAM == evt)? 1:0;
            uint8_t all_stopped = 1;
            mm_evt_payload_stop_stream_t *payload =
                (mm_evt_payload_stop_stream_t *)in_val;

            rc = mm_channel_stop_streams(my_obj,
                                         payload->num_streams,
                                         payload->stream_ids,
                                         tear_down_flag);

            /* check if all streams are stopped
             * then we move to stopped state */

            for (i=0; i<MM_CAMEAR_STRAEM_NUM_MAX; i++) {
                if (MM_STREAM_STATE_ACTIVE_STREAM_ON == my_obj->streams[i].state ||
                    MM_STREAM_STATE_ACTIVE_STREAM_OFF == my_obj->streams[i].state) {
                    all_stopped = 0;
                    break;
                }
            }
            if (all_stopped) {
                my_obj->state = MM_CHANNEL_STATE_STOPPED;
            }

        }
        break;
    case MM_CHANNEL_EVT_INIT_BUNDLE:
        {
            mm_evt_payload_bundle_stream_t *payload =
                (mm_evt_payload_bundle_stream_t *)in_val;
            rc = mm_channel_bundle_stream(my_obj,
                                          payload->super_frame_notify_cb,
                                          payload->user_data,
                                          payload->attr,
                                          payload->num_streams,
                                          payload->stream_ids);
        }
        break;
    case MM_CHANNEL_EVT_DESTROY_BUNDLE:
        rc = mm_channel_destroy_bundle(my_obj);
        break;
    case MM_CHANNEL_EVT_REQUEST_SUPER_BUF:
        rc = mm_channel_request_super_buf(my_obj);
        break;
    case MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF:
        rc = mm_channel_cancel_super_buf_request(my_obj);
        break;
    case MM_CHANNEL_EVT_START_FOCUS:
        {
            mm_evt_payload_start_focus_t* payload =
                (mm_evt_payload_start_focus_t *)in_val;
            rc = mm_channel_start_focus(my_obj,
                                        payload->sensor_idx,
                                        payload->focus_mode);
        }
        break;
    case MM_CHANNEL_EVT_ABORT_FOCUS:
        {
            uint32_t sensor_idx = (uint32_t)in_val;
            rc = mm_channel_abort_focus(my_obj, sensor_idx);
        }
        break;
    case MM_CHANNEL_EVT_PREPARE_SNAPSHOT:
        {
            uint32_t sensor_idx = (uint32_t)in_val;
            rc = mm_channel_prepare_snapshot(my_obj, sensor_idx);
        }
        break;
    case MM_CHANNEL_EVT_SET_STREAM_PARM:
        {
            uint32_t s_id = (uint32_t)in_val;
            rc = mm_channel_set_stream_parm(my_obj, s_id, out_val);
        }
        break;
    case MM_CHANNEL_EVT_GET_STREAM_PARM:
        {
            uint32_t s_id = (uint32_t)in_val;
            rc = mm_channel_get_stream_parm(my_obj, s_id, out_val);
        }
        break;

    case MM_CHANNEL_EVT_DEL_STREAM:
        {
            uint32_t s_id = *((uint32_t *)in_val);
            rc = mm_channel_del_stream(my_obj, s_id);
        }
        break;
    default:
        CDBG_ERROR("%s: invalid state (%d) for evt (%d)",
                   __func__, my_obj->state, evt);
        break;
    }
    CDBG("%s : X rc = %d",__func__,rc);
    return rc;
}

int32_t mm_channel_fsm_fn_paused(mm_channel_t *my_obj,
                          mm_channel_evt_type_t evt,
                          void * in_val,
                          void * out_val)
{
    int32_t rc = -1;

    /* currently we are not supporting pause/resume channel */
    CDBG_ERROR("%s: evt (%d) not supported in state (%d)",
               __func__, evt, my_obj->state);

    return rc;
}

int32_t mm_channel_init(mm_channel_t *my_obj)
{
    int32_t rc = 0;
    CDBG("%s : Launch data poll thread in channel open",__func__);
    mm_camera_poll_thread_launch(&my_obj->poll_thread[0],
                                 MM_CAMERA_POLL_TYPE_CH);

    /* change state to stopped state */
    my_obj->state = MM_CHANNEL_STATE_STOPPED;
    return rc;
}

void mm_channel_release(mm_channel_t *my_obj)
{
    /* stop data poll thread */
    mm_camera_poll_thread_release(&my_obj->poll_thread[0]);

    /* change state to notused state */
    my_obj->state = MM_CHANNEL_STATE_NOTUSED;
}

uint32_t mm_channel_add_stream(mm_channel_t *my_obj,
                              mm_camera_buf_notify_t buf_cb, void *user_data,
                              uint32_t ext_image_mode, uint32_t sensor_idx)
{
    int32_t rc = 0;
    uint8_t idx = 0;
    uint32_t s_hdl = 0;
    mm_stream_t *stream_obj = NULL;

    CDBG("%s : image mode = %d",__func__,ext_image_mode);
    /* check available stream */
    for (idx = 0; idx < MM_CAMEAR_STRAEM_NUM_MAX; idx++) {
        if (MM_STREAM_STATE_NOTUSED == my_obj->streams[idx].state) {
            stream_obj = &my_obj->streams[idx];
            break;
        }
    }
    if (NULL == stream_obj) {
        CDBG_ERROR("%s: streams reach max, no more stream allowed to add", __func__);
        return s_hdl;
    }

    /* initialize stream object */
    memset(stream_obj, 0, sizeof(mm_stream_t));
    stream_obj->my_hdl = mm_camera_util_generate_handler(idx);
    stream_obj->ch_obj = my_obj;
    /* cd through intf always palced at idx 0 of buf_cb */
    stream_obj->buf_cb[0].cb = buf_cb;
    stream_obj->buf_cb[0].user_data = user_data;
    stream_obj->buf_cb[0].cb_count = -1; /* infinite by default */
    stream_obj->ext_image_mode = ext_image_mode + 1;
    stream_obj->sensor_idx = sensor_idx;
    stream_obj->fd = -1;
    pthread_mutex_init(&stream_obj->buf_lock, NULL);
    pthread_mutex_init(&stream_obj->cb_lock, NULL);
    stream_obj->state = MM_STREAM_STATE_INITED;

    /* acquire stream */
    rc = mm_stream_fsm_fn(stream_obj, MM_STREAM_EVT_ACQUIRE, NULL, NULL);
    if (0 == rc) {
        s_hdl = stream_obj->my_hdl;
    } else {
        /* error during acquire, de-init */
        pthread_mutex_destroy(&stream_obj->buf_lock);
        pthread_mutex_destroy(&stream_obj->cb_lock);
        memset(stream_obj, 0, sizeof(mm_stream_t));
    }
    CDBG("%s : stream handle = %d",__func__,s_hdl);
    return s_hdl;
}

int32_t mm_channel_del_stream(mm_channel_t *my_obj,
                              uint32_t stream_id)
{
    int rc = -1;
    mm_stream_t * stream_obj = NULL;
    stream_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id);

    if (NULL == stream_obj) {
        CDBG_ERROR("%s :Invalid Stream Object",__func__);
        return rc;
    }

    rc = mm_stream_fsm_fn(stream_obj,
                          MM_STREAM_EVT_RELEASE,
                          NULL,
                          NULL);

    return rc;
}

int32_t mm_channel_config_stream(mm_channel_t *my_obj,
                                   uint32_t stream_id,
                                   mm_camera_stream_config_t *config)
{
    int rc = -1;
    mm_stream_t * stream_obj = NULL;
    CDBG("%s : E stream ID = %d",__func__,stream_id);
    stream_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id);

    if (NULL == stream_obj) {
        CDBG_ERROR("%s : X rc = %d",__func__,rc);
        return rc;
    }

    /* set stream fmt */
    rc = mm_stream_fsm_fn(stream_obj,
                          MM_STREAM_EVT_SET_FMT,
                          (void *)config,
                          NULL);
    CDBG("%s : X rc = %d",__func__,rc);
    return rc;
}

int32_t mm_channel_bundle_stream(mm_channel_t *my_obj,
                                 mm_camera_buf_notify_t super_frame_notify_cb,
                                 void *user_data,
                                 mm_camera_bundle_attr_t *attr,
                                 uint8_t num_streams,
                                 uint32_t *stream_ids)
{
    int32_t rc = 0;
    int i;
    mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL};

    /* first check if all streams to be bundled are valid */
    for (i=0; i < num_streams; i++) {
        s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, stream_ids[i]);
        if (NULL == s_objs[i]) {
            CDBG_ERROR("%s: invalid stream handler %d (idx=%d) to be bundled",
                       __func__, stream_ids[i], i);
            return -1;
        }
    }

    /* init superbuf queue */
    mm_channel_superbuf_queue_init(&my_obj->bundle.superbuf_queue);

    /* save bundle config */
    memcpy(&my_obj->bundle.superbuf_queue.attr, attr, sizeof(mm_camera_bundle_attr_t));
    my_obj->bundle.super_buf_notify_cb = super_frame_notify_cb;
    my_obj->bundle.user_data = user_data;
    my_obj->bundle.superbuf_queue.num_streams = num_streams;
    my_obj->bundle.superbuf_queue.expected_frame_id = 0;

    for (i=0; i < num_streams; i++) {
        /* set bundled flag to streams */
        s_objs[i]->is_bundled = 1;
        /* init bundled streams to invalid value -1 */
        //my_obj->bundle.superbuf_queue.bundled_streams[i] = -1;
        my_obj->bundle.superbuf_queue.bundled_streams[i] = stream_ids[i];
    }

    /* launch cmd thread for super buf dataCB */
    mm_camera_cmd_thread_launch(&my_obj->cmd_thread,
                                mm_channel_process_stream_buf,
                                (void*)my_obj);

    /* check if we need to do post-processing */
    if (my_obj->cam_obj->need_pp) {
        /* register postProcessingCB at camera evt polling thread
         * because pp result is coming from ctrl evt */
        mm_camera_register_event_notify_internal(my_obj->cam_obj,
                                                 mm_channel_pp_result_notify,
                                                 (void *)my_obj->my_hdl,
                                                 MM_CAMERA_EVT_TYPE_CTRL);
    }

    return rc;
}

/* bundled streams must all be stopped before bundle can be destroyed */
int32_t mm_channel_destroy_bundle(mm_channel_t *my_obj)
{

    mm_camera_cmd_thread_release(&my_obj->cmd_thread);

    /* deinit superbuf queue */
    mm_channel_superbuf_queue_deinit(&my_obj->bundle.superbuf_queue);

    /* memset bundle info */
    memset(&my_obj->bundle, 0, sizeof(mm_channel_bundle_t));
    return 0;
}

int32_t mm_channel_start_streams(mm_channel_t *my_obj,
                                 uint8_t num_streams,
                                 uint32_t *stream_ids)
{
    int32_t rc = 0;
    int i, j;
    mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL};
    uint8_t num_streams_to_start = num_streams;
    uint32_t streams_to_start[MM_CAMEAR_MAX_STRAEM_BUNDLE];
    uint8_t bundle_to_start = 0;

    /* check if any bundled stream to be start,
     * then all bundled stream should be started */
    memcpy(streams_to_start, stream_ids, sizeof(uint32_t) * num_streams);
    for (i=0; i < num_streams; i++) {
        for (j=0; j < my_obj->bundle.superbuf_queue.num_streams; j++) {
            if (stream_ids[i] == my_obj->bundle.superbuf_queue.bundled_streams[j]) {
                bundle_to_start = 1;
                break;
            }
        }
    }

    if (bundle_to_start) {
        uint8_t need_add;
        /* add bundled streams into the start list if not already added*/
        for (i=0; i<my_obj->bundle.superbuf_queue.num_streams; i++) {
            need_add = 1;
            for (j=0; j<num_streams; j++) {
                if (stream_ids[j] == my_obj->bundle.superbuf_queue.bundled_streams[i]) {
                    need_add = 0;
                    break;
                }
            }
            if (need_add) {
                streams_to_start[num_streams_to_start++] =
                    my_obj->bundle.superbuf_queue.bundled_streams[i];
            }
        }
    }

    /* check if all streams to be started are valid */
    for (i=0; i<num_streams_to_start; i++) {
        s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, streams_to_start[i]);

        if (NULL == s_objs[i]) {
            CDBG_ERROR("%s: invalid stream handler %d (idx=%d) to be started",
                       __func__, streams_to_start[i], i);
            return -1;
        }
    }

    for (i=0; i<num_streams_to_start; i++) {
        /* allocate buf */
        rc = mm_stream_fsm_fn(s_objs[i],
                              MM_STREAM_EVT_GET_BUF,
                              NULL,
                              NULL);
        if (0 != rc) {
            CDBG_ERROR("%s: get buf failed at idx(%d)", __func__, i);
            break;
        }

        /* reg buf */
        rc = mm_stream_fsm_fn(s_objs[i],
                              MM_STREAM_EVT_REG_BUF,
                              NULL,
                              NULL);
        if (0 != rc) {
            CDBG_ERROR("%s: reg buf failed at idx(%d)", __func__, i);
            break;
        }

        /* TODO */
        /* for now, hard-coded to 1 for main image stream */
        /* Query if stream need to do pp under current hardware configuration,
         * when camera has offline pp capability */
        if (my_obj->cam_obj->need_pp) {
            if (MSM_V4L2_EXT_CAPTURE_MODE_MAIN == s_objs[i]->ext_image_mode) {
                s_objs[i]->is_pp_needed = 1;
            } else {
                s_objs[i]->is_pp_needed = 0;
            }
        }

        /* start stream */
        rc = mm_stream_fsm_fn(s_objs[i],
                              MM_STREAM_EVT_START,
                              NULL,
                              NULL);
        if (0 != rc) {
            CDBG_ERROR("%s: start stream failed at idx(%d)", __func__, i);
            break;
        }
    }

    /* error handling */
    if (0 != rc) {
        for (j=0; j<=i; j++) {
            /* stop streams*/
            mm_stream_fsm_fn(s_objs[i],
                             MM_STREAM_EVT_STOP,
                             NULL,
                             NULL);

            /* unreg buf */
            mm_stream_fsm_fn(s_objs[i],
                             MM_STREAM_EVT_UNREG_BUF,
                             NULL,
                             NULL);

            /* put buf back */
            mm_stream_fsm_fn(s_objs[i],
                             MM_STREAM_EVT_PUT_BUF,
                             NULL,
                             NULL);
        }
    }

    return rc;
}

/* Required: bundled streams need to be stopped together */
int32_t mm_channel_stop_streams(mm_channel_t *my_obj,
                                uint8_t num_streams,
                                uint32_t *stream_ids,
                                uint8_t tear_down_flag)
{
    int32_t rc = 0;
    int i, j;
    mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL};
    uint8_t num_streams_to_stop = num_streams;
    uint32_t streams_to_stop[MM_CAMEAR_MAX_STRAEM_BUNDLE];
    uint8_t bundle_to_stop = 0;

    /* make sure bundled streams are stopped together */
    memcpy(streams_to_stop, stream_ids, sizeof(uint32_t) * num_streams);
    for (i=0; i<num_streams; i++) {
        for (j=0; j<my_obj->bundle.superbuf_queue.num_streams; j++) {
            if (stream_ids[i] == my_obj->bundle.superbuf_queue.bundled_streams[j]) {
                bundle_to_stop = 1;
                break;
            }
        }
    }
    if (bundle_to_stop) {
        uint8_t need_add;
        /* add bundled streams into the start list if not already added*/
        for (i=0; i<my_obj->bundle.superbuf_queue.num_streams; i++) {
            need_add = 1;
            for (j=0; j<num_streams; j++) {
                if (stream_ids[j] == my_obj->bundle.superbuf_queue.bundled_streams[i]) {
                    need_add = 0;
                    break;
                }
            }
            if (need_add) {
                streams_to_stop[num_streams_to_stop++] =
                    my_obj->bundle.superbuf_queue.bundled_streams[i];
            }
        }
    }

    for (i=0; i<num_streams_to_stop; i++) {
        s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, streams_to_stop[i]);

        if (NULL != s_objs[i]) {
            /* stream off */
            mm_stream_fsm_fn(s_objs[i],
                             MM_STREAM_EVT_STOP,
                             NULL,
                             NULL);

            /* unreg buf at kernel */
            mm_stream_fsm_fn(s_objs[i],
                             MM_STREAM_EVT_UNREG_BUF,
                             NULL,
                             NULL);
        }
    }

    /* since all streams are stopped, we are safe to
     * release all buffers allocated in stream */
    for (i=0; i<num_streams_to_stop; i++) {
        if (NULL != s_objs[i]) {
            /* put buf back */
            mm_stream_fsm_fn(s_objs[i],
                             MM_STREAM_EVT_PUT_BUF,
                             NULL,
                             NULL);

            if (tear_down_flag) {
                /* to tear down stream totally, stream needs to be released */
                mm_stream_fsm_fn(s_objs[i],
                                 MM_STREAM_EVT_RELEASE,
                                 NULL,
                                 NULL);
            }
        }
    }

    return rc;
}

int32_t mm_channel_request_super_buf(mm_channel_t *my_obj)
{
    int32_t rc = 0;
    mm_camera_cmdcb_t* node = NULL;

    /* set pending_cnt
     * will trigger dispatching super frames if pending_cnt > 0 */
    my_obj->pending_cnt = my_obj->bundle.superbuf_queue.attr.burst_num;

    /* send sem_post to wake up cmd thread to dispatch super buffer */
    node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    if (NULL != node) {
        memset(node, 0, sizeof(mm_camera_cmdcb_t));
        node->cmd_type = MM_CAMERA_CMD_TYPE_REQ_DATA_CB;

        /* enqueue to cmd thread */
        mm_camera_queue_enq(&(my_obj->cmd_thread.cmd_queue), node);

        /* wake up cmd thread */
        sem_post(&(my_obj->cmd_thread.cmd_sem));
    } else {
        CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
        rc = -1;
    }

    return rc;
}

int32_t mm_channel_cancel_super_buf_request(mm_channel_t *my_obj)
{
    int32_t rc = 0;
    /* reset pending_cnt */
    my_obj->pending_cnt = 0;

    if (my_obj->pending_pp_cnt > 0) {
        rc = mm_channel_cancel_post_processing(my_obj);
    }
    my_obj->pending_pp_cnt = 0;
    return rc;
}

int32_t mm_channel_qbuf(mm_channel_t *my_obj,
                        mm_camera_buf_def_t *buf)
{
    int32_t rc = -1;
    struct ion_flush_data cache_inv_data;
    int ion_fd;
    struct msm_frame *cache_frame;
    struct msm_frame *cache_frame1 = NULL;

    mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, buf->stream_id);

    if (NULL != s_obj) {
        rc = mm_stream_fsm_fn(s_obj,
                              MM_STREAM_EVT_QBUF,
                              (void *)buf,
                              NULL);
    }

#ifdef USE_ION
    cache_inv_data.vaddr = cache_frame->buffer;
    cache_inv_data.fd = cache_frame->fd;
    cache_inv_data.handle = cache_frame->fd_data.handle;
    cache_inv_data.length = cache_frame->ion_alloc.len;
    ion_fd = cache_frame->ion_dev_fd;
    if(ion_fd > 0) {
        if(ioctl(ion_fd, ION_IOC_INV_CACHES, &cache_inv_data) < 0)
            CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
        else {
            CDBG("%s: Successful cache invalidate\n", __func__);
            if(cache_frame1) {
                ion_fd = cache_frame1->ion_dev_fd;
                cache_inv_data.vaddr = cache_frame1->buffer;
                cache_inv_data.fd = cache_frame1->fd;
                cache_inv_data.handle = cache_frame1->fd_data.handle;
                cache_inv_data.length = cache_frame1->ion_alloc.len;
                if(ioctl(ion_fd, ION_IOC_INV_CACHES, &cache_inv_data) < 0)
                    CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
                else
                    CDBG("%s: Successful cache invalidate\n", __func__);
            }
        }
    }
#endif

    return rc;
}

int32_t mm_channel_start_focus(mm_channel_t *my_obj,
                               uint32_t sensor_idx,
                               uint32_t focus_mode)
{
    return mm_camera_send_native_ctrl_cmd(my_obj->cam_obj,
                                          CAMERA_SET_PARM_AUTO_FOCUS,
                                          sizeof(uint32_t), (void*)focus_mode);
}

int32_t mm_channel_abort_focus(mm_channel_t *my_obj, uint32_t sensor_idx)
{
    return mm_camera_send_native_ctrl_cmd(my_obj->cam_obj,
                                          CAMERA_AUTO_FOCUS_CANCEL,
                                          0, NULL);
}

int32_t mm_channel_prepare_snapshot(mm_channel_t *my_obj, uint32_t sensor_idx)
{
    return mm_camera_send_native_ctrl_timeout_cmd(my_obj->cam_obj,
                                                CAMERA_PREPARE_SNAPSHOT,
                                                0, NULL, 2000);
}

int32_t mm_channel_set_stream_parm(mm_channel_t *my_obj,
                                   uint32_t s_id,
                                   void *value)
{
    int32_t rc = -1;
    mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, s_id);
    if (NULL != s_obj) {
        rc = mm_stream_fsm_fn(s_obj,
                              MM_STREAM_EVT_SET_PARM,
                              value,
                              NULL);
    }

    return rc;
}

int32_t mm_channel_get_stream_parm(mm_channel_t *my_obj,
                                   uint32_t s_id,
                                   void *value)
{
    int32_t rc = -1;
    mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, s_id);
    if (NULL != s_obj) {
        rc = mm_stream_fsm_fn(s_obj,
                              MM_STREAM_EVT_GET_PARM,
                              NULL,
                              value);
    }

    return rc;
}

uint8_t mm_channel_need_do_pp(mm_channel_t *my_obj,
                              mm_channel_queue_node_t *super_buf)
{
    uint8_t need_pp = 0;
    uint8_t i;

    for (i=0; i<super_buf->num_of_bufs; i++) {
        if (super_buf->super_buf[i].need_pp) {
            need_pp = 1;
            break;
        }
    }
    return need_pp;
}

int32_t mm_channel_do_post_processing(mm_channel_t *my_obj,
                                      mm_channel_queue_node_t *super_buf)
{
    int32_t rc = 0;
    cam_sock_packet_t packet;
    uint8_t i;
    mm_stream_t* s_obj = NULL;
    mm_channel_pp_info_t *cookie = NULL;

    /* TODO : currently we only do WNR, may need extended PP */
    /* send cmd to backend to start pp */
    for (i=0; i<super_buf->num_of_bufs; i++) {
        if (super_buf->super_buf[i].need_pp) {
            s_obj = mm_channel_util_get_stream_by_handler(my_obj, super_buf->super_buf[i].stream_id);
            if (NULL != s_obj) {
                cookie = (mm_channel_pp_info_t*)malloc(sizeof(mm_channel_pp_info_t));
                if (NULL != cookie) {
                    memset(&packet, 0, sizeof(cam_sock_packet_t));
                    memset(cookie, 0, sizeof(mm_channel_pp_info_t));
                    cookie->cam_hdl = my_obj->cam_obj->my_hdl;
                    cookie->ch_hdl = my_obj->my_hdl;
                    cookie->stream_hdl = s_obj->my_hdl;
                    cookie->super_buf = super_buf;

                    packet.msg_type = CAM_SOCK_MSG_TYPE_WDN_START;
                    packet.payload.wdn_start.cookie = (unsigned long)cookie;
                    packet.payload.wdn_start.num_frames = 1;
                    packet.payload.wdn_start.ext_mode[0] = s_obj->ext_image_mode;
                    packet.payload.wdn_start.frame_idx[0] = super_buf->super_buf[i].buf->buf_idx;
                    rc = mm_camera_util_sendmsg(my_obj->cam_obj, &packet, sizeof(packet), 0);
                    if (0 != rc) {
                        CDBG_ERROR("%s: Send DoPP msg failed (rc=%d)", __func__, rc);
                        free(cookie);
                        break;
                    }
                } else {
                    CDBG_ERROR("%s: No memory for mm_channel_pp_info_t", __func__);
                    break;
                }
            }
        }
    }

    return rc;
}

int32_t mm_channel_cancel_post_processing(mm_channel_t *my_obj)
{
    int32_t rc = 0;
    /* TODO */
    /* need send cmd to backend to cancel all pp request */

    return rc;
}

int32_t mm_channel_reg_stream_cb(mm_channel_t *my_obj,
                                 mm_stream_data_cb_t *cb,
                                 uint32_t ext_image_mode,
                                 uint32_t sensor_idx)
{
    uint8_t idx;
    mm_stream_t *dest_stream = NULL;
    int32_t rc = -1;

    /* browse all streams in channel to find the destination */
    for (idx=0; idx < MM_CAMEAR_STRAEM_NUM_MAX; idx++) {
        if (my_obj->streams[idx].state != MM_STREAM_STATE_NOTUSED &&
            my_obj->streams[idx].ext_image_mode == ext_image_mode &&
            my_obj->streams[idx].sensor_idx == sensor_idx) {
            /* find matching stream as the destination */
            dest_stream = &my_obj->streams[idx];
            break;
        }
    }

    if (NULL != dest_stream) {
        rc = mm_stream_reg_buf_cb(dest_stream, cb);
    }

    return rc;
}

int32_t mm_channel_superbuf_queue_init(mm_channel_queue_t * queue)
{
    return mm_camera_queue_init(&queue->que);
}

int32_t mm_channel_superbuf_queue_deinit(mm_channel_queue_t * queue)
{
    return mm_camera_queue_deinit(&queue->que);
}

int8_t mm_channel_util_seq_comp_w_rollover(uint32_t v1,
                                           uint32_t v2)
{
    int8_t ret = 0;

    /* TODO: need to handle the case if v2 roll over to 0 */
    if (v1 > v2) {
        ret = 1;
    } else if (v1 < v2) {
        ret = -1;
    }

    return ret;
}

int32_t mm_channel_superbuf_comp_and_enqueue(
                        mm_channel_t* ch_obj,
                        mm_channel_queue_t * queue,
                        mm_camera_buf_info_t *buf_info)
{
    mm_camera_q_node_t* node = NULL;
    struct cam_list *head = NULL;
    struct cam_list *pos = NULL;
    mm_channel_queue_node_t* super_buf = NULL;
    uint8_t buf_s_idx, i;

    for (buf_s_idx=0; buf_s_idx < queue->num_streams; buf_s_idx++) {
        if (buf_info->stream_id == queue->bundled_streams[buf_s_idx]) {
            break;
        }
    }
    if (buf_s_idx == queue->num_streams) {
        CDBG_ERROR("%s: buf from stream (%d) not bundled", __func__, buf_info->stream_id);
        return -1;
    }

    if (mm_channel_util_seq_comp_w_rollover(buf_info->frame_idx,
                                            queue->expected_frame_id) < 0) {
        /* incoming buf is older than expected buf id, will discard it */
        mm_channel_qbuf(ch_obj, buf_info->buf);
        return 0;
    }

    if (MM_CAMERA_SUPER_BUF_PRIORITY_NORMAL != queue->attr.priority) {
        /* TODO */
        /* need to decide if we want to queue the frame based on focus or exposure
         * if frame not to be queued, we need to qbuf it back */
    }

    /* comp */
    pthread_mutex_lock(&queue->que.lock);
    head = &queue->que.head.list;
    /* get the last one in the queue which is possibly having no matching */
    pos = head->next;
    while (pos != head) {
        node = member_of(pos, mm_camera_q_node_t, list);
        super_buf = (mm_channel_queue_node_t*)node->data;
        if (NULL != super_buf) {
            if (super_buf->matched) {
                /* find a matched super buf, move to next one */
                pos = pos->next;
                continue;
            } else {
                /* have an unmatched super buf, break the loop */
                break;
            }
        }
    }

    if (pos == head) {
        /* all nodes in queue are mtached, or no node in queue
         * create a new node */
        mm_channel_queue_node_t *new_buf = NULL;
        mm_camera_q_node_t* new_node = NULL;

        new_buf = (mm_channel_queue_node_t*)malloc(sizeof(mm_channel_queue_node_t));
        new_node = (mm_camera_q_node_t*)malloc(sizeof(mm_camera_q_node_t));
        if (NULL != new_buf && NULL != new_node) {
            memset(new_buf, 0, sizeof(mm_channel_queue_node_t));
            memset(new_node, 0, sizeof(mm_camera_q_node_t));
            new_node->data = (void *)new_buf;
            new_buf->num_of_bufs = queue->num_streams;
            memcpy(&new_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t));

            /* enqueue */
            //cam_list_add_tail_node(&node->list, &queue->que.head.list);
            cam_list_add_tail_node(&new_node->list, &queue->que.head.list);
            queue->que.size++;

            if(queue->num_streams == 1) {
                //TODO : Check. Live snapshot will have one stream in bundle?
                new_buf->matched = 1;

                if (new_buf->matched) {
                    queue->expected_frame_id = buf_info->frame_idx + queue->attr.post_frame_skip;
                    queue->match_cnt++;
                }
            }
        } else {
            /* No memory */
            if (NULL != new_buf) {
                free(new_buf);
            }
            if (NULL != new_node) {
                free(new_node);
            }
            /* qbuf the new buf since we cannot enqueue */
            mm_channel_qbuf(ch_obj, buf_info->buf);
        }
    } else {
        /* find an unmatched super buf */
        if (super_buf->super_buf[buf_s_idx].frame_idx == 0) {
            /* new frame from the stream_id */
            uint8_t is_new = 1;
            uint32_t frame_idx;

            for (i=0; i < super_buf->num_of_bufs; i++) {
            //for (i=0; i < buf_s_idx; i++) {
                if(super_buf->super_buf[i].buf == NULL) {
                    continue;
                }
                frame_idx = super_buf->super_buf[i].buf->frame_idx;
                if (frame_idx == 0) {
                    continue;
                }
                if (frame_idx < buf_info->frame_idx) {
                    /* existing frame is older than the new frame, qbuf it */
                    mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf);
                    memset(&super_buf->super_buf[i], 0, sizeof(mm_camera_buf_info_t));
                } else if (frame_idx > buf_info->frame_idx) {
                    /* new frame is older */
                    is_new = 0;
                    break;
                }else{
                    //TODO: reveiw again
                    break;
                }
            }
            if (is_new) {
                memcpy(&super_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t));

                /* check if superbuf is all matched */
                super_buf->matched = 1;
                for (i=0; i < super_buf->num_of_bufs; i++) {
                    if (super_buf->super_buf[i].frame_idx == 0) {
                        super_buf->matched = 0;
                        break;
                    }
                }

                if (super_buf->matched) {
                    queue->expected_frame_id = buf_info->frame_idx + queue->attr.post_frame_skip;
                    queue->match_cnt++;
                }
            } else {
                mm_channel_qbuf(ch_obj, buf_info->buf);
            }
        } else {
            if (super_buf->super_buf[buf_s_idx].frame_idx < buf_info->frame_idx) {
                /* current frames in superbuf are older than the new frame
                 * qbuf all current frames */
                for (i=0; i<super_buf->num_of_bufs; i++) {
                    if (super_buf->super_buf[i].frame_idx != 0) {
                            mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf);
                            memset(&super_buf->super_buf[i], 0, sizeof(mm_camera_buf_info_t));
                    }
                }
                /* add the new frame into the superbuf */
                memcpy(&super_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t));
            } else {
                /* the new frame is older, just ignor */
                mm_channel_qbuf(ch_obj, buf_info->buf);
            }
        }
    }
    pthread_mutex_unlock(&queue->que.lock);

    return 0;
}

mm_channel_queue_node_t* mm_channel_superbuf_dequeue_internal(mm_channel_queue_t * queue)
{
    mm_camera_q_node_t* node = NULL;
    struct cam_list *head = NULL;
    struct cam_list *pos = NULL;
    mm_channel_queue_node_t* super_buf = NULL;

    head = &queue->que.head.list;
    pos = head->next;
    if (pos != head) {
        /* get the first node */
        node = member_of(pos, mm_camera_q_node_t, list);
        super_buf = (mm_channel_queue_node_t*)node->data;
        if (NULL != super_buf) {
            if (super_buf->matched) {
                /* we found a mtaching super buf, dequeue it */
                cam_list_del_node(&node->list);
                queue->que.size--;
                queue->match_cnt--;
                free(node);
            } else {
                super_buf = NULL;
            }
        }
    }

    return super_buf;
}

mm_channel_queue_node_t* mm_channel_superbuf_dequeue(mm_channel_queue_t * queue)
{
    mm_camera_q_node_t* node = NULL;
    struct cam_list *head = NULL;
    struct cam_list *pos = NULL;
    mm_channel_queue_node_t* super_buf = NULL;

    pthread_mutex_lock(&queue->que.lock);
    super_buf = mm_channel_superbuf_dequeue_internal(queue);
    pthread_mutex_unlock(&queue->que.lock);

    return super_buf;
}

int32_t mm_channel_superbuf_bufdone_overflow(mm_channel_t* my_obj,
                                             mm_channel_queue_t * queue)
{
    int32_t rc = 0, i;
    mm_channel_queue_node_t* super_buf = NULL;
    if (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == queue->attr.notify_mode) {
        /* for continuous streaming mode, no overflow is needed */
        return 0;
    }

    /* bufdone overflowed bufs */
    pthread_mutex_lock(&queue->que.lock);
    while (queue->match_cnt > queue->attr.water_mark) {
        super_buf = mm_channel_superbuf_dequeue_internal(queue);
        if (NULL != super_buf) {
            for (i=0; i<super_buf->num_of_bufs; i++) {
                if (NULL != super_buf->super_buf[i].buf) {
                    mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf);
                }
            }
            free(super_buf);
        }
    }
    pthread_mutex_unlock(&queue->que.lock);

    return rc;
}

int32_t mm_channel_superbuf_skip(mm_channel_t* my_obj,
                                 mm_channel_queue_t * queue)
{
    int32_t rc = 0, i, count;
    mm_channel_queue_node_t* super_buf = NULL;
    if (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == queue->attr.notify_mode) {
        /* for continuous streaming mode, no skip is needed */
        return 0;
    }

    /* bufdone overflowed bufs */
    pthread_mutex_lock(&queue->que.lock);
    while (queue->match_cnt > queue->attr.look_back) {
        super_buf = mm_channel_superbuf_dequeue_internal(queue);
        if (NULL != super_buf) {
            for (i=0; i<super_buf->num_of_bufs; i++) {
                if (NULL != super_buf->super_buf[i].buf) {
                    mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf);
                }
            }
            free(super_buf);
        }
    }
    pthread_mutex_unlock(&queue->que.lock);

    return rc;
}

