Home | History | Annotate | Download | only in src
      1 /*
      2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are
      6 met:
      7     * Redistributions of source code must retain the above copyright
      8       notice, this list of conditions and the following disclaimer.
      9     * Redistributions in binary form must reproduce the above
     10       copyright notice, this list of conditions and the following
     11       disclaimer in the documentation and/or other materials provided
     12       with the distribution.
     13     * Neither the name of The Linux Foundation nor the names of its
     14       contributors may be used to endorse or promote products derived
     15       from this software without specific prior written permission.
     16 
     17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #include <pthread.h>
     31 #include <errno.h>
     32 #include <sys/ioctl.h>
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 #include <fcntl.h>
     36 #include <poll.h>
     37 #include <time.h>
     38 #include <semaphore.h>
     39 
     40 #include "mm_camera_dbg.h"
     41 #include "mm_camera_interface.h"
     42 #include "mm_camera.h"
     43 
     44 #define MM_CAMERA_MAX_NUM_FRAMES     16
     45 
     46 /* internal function decalre */
     47 int32_t mm_stream_qbuf(mm_stream_t *my_obj,
     48                        mm_camera_buf_def_t *buf);
     49 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj);
     50 int32_t mm_stream_set_fmt(mm_stream_t * my_obj);
     51 int32_t mm_stream_get_offset(mm_stream_t *my_obj);
     52 int32_t mm_stream_set_cid(mm_stream_t *my_obj,stream_cid_t *in_value);
     53 int32_t mm_stream_init_bufs(mm_stream_t * my_obj);
     54 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj);
     55 int32_t mm_stream_request_buf(mm_stream_t * my_obj);
     56 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj);
     57 int32_t mm_stream_release(mm_stream_t *my_obj);
     58 int32_t mm_stream_get_crop(mm_stream_t *my_obj,
     59                          mm_camera_rect_t *crop);
     60 int32_t mm_stream_get_cid(mm_stream_t *my_obj,
     61                           stream_cid_t *out_value);
     62 int32_t mm_stream_set_parm_acquire(mm_stream_t *my_obj,
     63                          void *value);
     64 int32_t mm_stream_get_parm_acquire(mm_stream_t *my_obj,
     65                          void *value);
     66 int32_t mm_stream_set_parm_config(mm_stream_t *my_obj,
     67                          void *value);
     68 int32_t mm_stream_get_parm_config(mm_stream_t *my_obj,
     69                          void *value);
     70 int32_t mm_stream_set_parm_start(mm_stream_t *my_obj,
     71                          void *value);
     72 int32_t mm_stream_get_parm_start(mm_stream_t *my_obj,
     73                          void *value);
     74 int32_t mm_stream_streamon(mm_stream_t *my_obj);
     75 int32_t mm_stream_streamoff(mm_stream_t *my_obj);
     76 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
     77                                  mm_camera_buf_info_t* buf_info);
     78 int32_t mm_stream_config(mm_stream_t *my_obj,
     79                          mm_camera_stream_config_t *config);
     80 int32_t mm_stream_reg_buf(mm_stream_t * my_obj);
     81 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
     82                            mm_camera_buf_def_t *frame);
     83 
     84 
     85 /* state machine function declare */
     86 int32_t mm_stream_fsm_inited(mm_stream_t * my_obj,
     87                              mm_stream_evt_type_t evt,
     88                              void * in_val,
     89                              void * out_val);
     90 int32_t mm_stream_fsm_acquired(mm_stream_t * my_obj,
     91                                mm_stream_evt_type_t evt,
     92                                void * in_val,
     93                                void * out_val);
     94 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
     95                           mm_stream_evt_type_t evt,
     96                           void * in_val,
     97                           void * out_val);
     98 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
     99                              mm_stream_evt_type_t evt,
    100                              void * in_val,
    101                              void * out_val);
    102 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
    103                           mm_stream_evt_type_t evt,
    104                           void * in_val,
    105                           void * out_val);
    106 int32_t mm_stream_fsm_active_stream_on(mm_stream_t * my_obj,
    107                                        mm_stream_evt_type_t evt,
    108                                        void * in_val,
    109                                        void * out_val);
    110 int32_t mm_stream_fsm_active_stream_off(mm_stream_t * my_obj,
    111                                         mm_stream_evt_type_t evt,
    112                                         void * in_val,
    113                                         void * out_val);
    114 
    115 extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
    116                                        cam_ctrl_type type,
    117                                        uint32_t length,
    118                                        void *value);
    119 
    120 static int get_stream_inst_handle(mm_stream_t *my_obj)
    121 {
    122   int rc = 0;
    123   uint32_t inst_handle;
    124   struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
    125 
    126   v4l2_ioctl.id = MSM_V4L2_PID_INST_HANDLE;
    127   v4l2_ioctl.ioctl_ptr = &inst_handle;
    128   v4l2_ioctl.len = sizeof(inst_handle);
    129   rc = ioctl(my_obj->fd, MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL, &v4l2_ioctl);
    130   if (rc) {
    131     CDBG_ERROR("%s Error getting mctl pp inst handle", __func__);
    132     return rc;
    133   }
    134 
    135   my_obj->inst_hdl = inst_handle;
    136   CDBG("%s: X, inst_handle = 0x%x, my_handle = 0x%x, "
    137        "image_mode = %d, fd = %d, state = %d, rc = %d",
    138        __func__, my_obj->inst_hdl, my_obj->my_hdl,
    139        my_obj->ext_image_mode, my_obj->fd, my_obj->state, rc);
    140   return rc;
    141 }
    142 
    143 void mm_stream_handle_rcvd_buf(mm_stream_t *my_obj,
    144                                   mm_camera_buf_info_t *buf_info)
    145 {
    146     int32_t i;
    147     uint8_t has_cb = 0;
    148     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    149          "image_mode = %d, fd = %d, state = %d",
    150          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    151          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    152 
    153     /* enqueue to super buf thread */
    154     if (my_obj->is_bundled) {
    155         mm_camera_cmdcb_t* node = NULL;
    156 
    157         /* send sem_post to wake up channel cmd thread to enqueue to super buffer */
    158         node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    159         if (NULL != node) {
    160             memset(node, 0, sizeof(mm_camera_cmdcb_t));
    161             node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
    162             memcpy(&node->u.buf, buf_info, sizeof(mm_camera_buf_info_t));
    163 
    164             /* enqueue to cmd thread */
    165             mm_camera_queue_enq(&(my_obj->ch_obj->cmd_thread.cmd_queue), node);
    166 
    167             /* wake up cmd thread */
    168             sem_post(&(my_obj->ch_obj->cmd_thread.cmd_sem));
    169         } else {
    170             CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
    171         }
    172     }
    173 
    174     /* check if has CB */
    175     for (i=0 ; i< MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    176         if(NULL != my_obj->buf_cb[i].cb) {
    177             has_cb = 1;
    178         }
    179     }
    180     if(has_cb) {
    181         mm_camera_cmdcb_t* node = NULL;
    182 
    183         /* send sem_post to wake up cmd thread to dispatch dataCB */
    184         node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    185         if (NULL != node) {
    186             memset(node, 0, sizeof(mm_camera_cmdcb_t));
    187             node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
    188             memcpy(&node->u.buf, buf_info, sizeof(mm_camera_buf_info_t));
    189 
    190             /* enqueue to cmd thread */
    191             mm_camera_queue_enq(&(my_obj->cmd_thread.cmd_queue), node);
    192 
    193             /* wake up cmd thread */
    194             sem_post(&(my_obj->cmd_thread.cmd_sem));
    195         } else {
    196             CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
    197         }
    198     }
    199 }
    200 
    201 static void mm_stream_data_notify(void* user_data)
    202 {
    203     mm_stream_t *my_obj = (mm_stream_t*)user_data;
    204     int32_t idx = -1, i, rc;
    205     uint8_t has_cb = 0;
    206     mm_camera_buf_info_t buf_info;
    207 
    208     if (NULL == my_obj) {
    209         return;
    210     }
    211 
    212     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    213          "image_mode = %d, fd = %d, state = %d",
    214          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    215          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    216     if (MM_STREAM_STATE_ACTIVE_STREAM_ON != my_obj->state) {
    217         /* this Cb will only received in active_stream_on state
    218          * if not so, return here */
    219         CDBG_ERROR("%s: ERROR!! Wrong state (%d) to receive data notify!",
    220                    __func__, my_obj->state);
    221         return;
    222     }
    223 
    224     memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
    225 
    226     pthread_mutex_lock(&my_obj->buf_lock);
    227     rc = mm_stream_read_msm_frame(my_obj, &buf_info);
    228     if (rc != 0) {
    229         pthread_mutex_unlock(&my_obj->buf_lock);
    230         return;
    231     }
    232     idx = buf_info.buf->buf_idx;
    233     /* update buffer location */
    234     my_obj->buf_status[idx].in_kernel = 0;
    235 
    236     /* update buf ref count */
    237     if (my_obj->is_bundled) {
    238         /* need to add into super buf since bundled, add ref count */
    239         my_obj->buf_status[idx].buf_refcnt++;
    240     }
    241 
    242     for (i=0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    243         if(NULL != my_obj->buf_cb[i].cb) {
    244             /* for every CB, add ref count */
    245             my_obj->buf_status[idx].buf_refcnt++;
    246             has_cb = 1;
    247         }
    248     }
    249     pthread_mutex_unlock(&my_obj->buf_lock);
    250 
    251     mm_stream_handle_rcvd_buf(my_obj, &buf_info);
    252 }
    253 
    254 /* special function for dataCB registered at other stream */
    255 static void mm_stream_buf_notify(mm_camera_super_buf_t *super_buf,
    256                                  void *user_data)
    257 {
    258     mm_stream_t * my_obj = (mm_stream_t*)user_data;
    259     mm_camera_buf_info_t buf_info;
    260     int8_t i;
    261     mm_camera_buf_def_t *buf = super_buf->bufs[0];
    262 
    263     CDBG("%s : E",__func__);
    264     if (my_obj == NULL) {
    265         return;
    266     }
    267     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    268          "image_mode = %d, fd = %d, state = %d",
    269          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    270          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    271 
    272     if (MM_STREAM_STATE_ACTIVE_STREAM_OFF != my_obj->state) {
    273         /* this CB will only received in active_stream_off state
    274          * if not so, return here */
    275         return;
    276     }
    277 
    278     /* 1) copy buf into local buf */
    279     if (my_obj->buf_num <= 0) {
    280         CDBG_ERROR("%s: Local buf is not allocated yet", __func__);
    281         return;
    282     }
    283 
    284     my_obj->buf[my_obj->local_buf_idx].buf_idx = 0;
    285     my_obj->buf[my_obj->local_buf_idx].stream_id = my_obj->my_hdl;
    286     my_obj->buf[my_obj->local_buf_idx].frame_idx = buf->frame_idx;
    287 
    288     memcpy(&my_obj->buf[my_obj->local_buf_idx].ts, &buf->ts, sizeof(buf->ts));
    289 
    290     memcpy(my_obj->buf[my_obj->local_buf_idx].buffer, buf->buffer, buf->frame_len);
    291 
    292     /* set flag to indicate buf be to sent out is from local */
    293     my_obj->is_local_buf = 1;
    294 
    295     /* 2) buf_done the buf from other stream */
    296     mm_channel_qbuf(my_obj->ch_obj, buf);
    297 
    298     /* 3) handle received buf */
    299     memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
    300     buf_info.frame_idx =my_obj->buf[my_obj->local_buf_idx].frame_idx;
    301     buf_info.buf = &my_obj->buf[my_obj->local_buf_idx];
    302     buf_info.stream_id = my_obj->my_hdl;
    303 
    304     my_obj->local_buf_idx++;
    305     if (my_obj->local_buf_idx >= my_obj->buf_num) {
    306         my_obj->local_buf_idx = 0;
    307     }
    308     mm_stream_handle_rcvd_buf(my_obj, &buf_info);
    309 }
    310 
    311 static void mm_stream_dispatch_app_data(mm_camera_cmdcb_t *cmd_cb,
    312                                         void* user_data)
    313 {
    314     int i;
    315     mm_stream_t * my_obj = (mm_stream_t *)user_data;
    316     mm_camera_buf_info_t* buf_info = NULL;
    317     mm_camera_super_buf_t super_buf;
    318 
    319     if (NULL == my_obj) {
    320         return;
    321     }
    322     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    323          "image_mode = %d, fd = %d, state = %d",
    324          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    325          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    326 
    327     if (MM_CAMERA_CMD_TYPE_DATA_CB != cmd_cb->cmd_type) {
    328         CDBG_ERROR("%s: Wrong cmd_type (%d) for dataCB",
    329                    __func__, cmd_cb->cmd_type);
    330         return;
    331     }
    332 
    333     buf_info = &cmd_cb->u.buf;
    334     memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
    335     super_buf.num_bufs = 1;
    336     super_buf.bufs[0] = buf_info->buf;
    337     super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
    338     super_buf.ch_id = my_obj->ch_obj->my_hdl;
    339 
    340 
    341     pthread_mutex_lock(&my_obj->cb_lock);
    342     for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    343         if(NULL != my_obj->buf_cb[i].cb) {
    344             if (my_obj->buf_cb[i].cb_count != 0) {
    345                 /* if <0, means infinite CB
    346                  * if >0, means CB for certain times
    347                  * both case we need to call CB */
    348                 my_obj->buf_cb[i].cb(&super_buf,
    349                                      my_obj->buf_cb[i].user_data);
    350             }
    351 
    352             /* if >0, reduce count by 1 every time we called CB until reaches 0
    353              * when count reach 0, reset the buf_cb to have no CB */
    354             if (my_obj->buf_cb[i].cb_count > 0) {
    355                 my_obj->buf_cb[i].cb_count--;
    356                 if (0 == my_obj->buf_cb[i].cb_count) {
    357                     my_obj->buf_cb[i].cb = NULL;
    358                     my_obj->buf_cb[i].user_data = NULL;
    359                 }
    360             }
    361         }
    362     }
    363     pthread_mutex_unlock(&my_obj->cb_lock);
    364 }
    365 
    366 /* state machine entry */
    367 int32_t mm_stream_fsm_fn(mm_stream_t *my_obj,
    368                          mm_stream_evt_type_t evt,
    369                          void * in_val,
    370                          void * out_val)
    371 {
    372     int32_t rc = -1;
    373 
    374     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    375          "image_mode = %d, fd = %d, state = %d, event = %d",
    376          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    377          my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
    378     switch (my_obj->state) {
    379     case MM_STREAM_STATE_NOTUSED:
    380         CDBG("%s: Not handling evt in unused state", __func__);
    381         break;
    382     case MM_STREAM_STATE_INITED:
    383         rc = mm_stream_fsm_inited(my_obj, evt, in_val, out_val);
    384         break;
    385     case MM_STREAM_STATE_ACQUIRED:
    386         rc = mm_stream_fsm_acquired(my_obj, evt, in_val, out_val);
    387         break;
    388     case MM_STREAM_STATE_CFG:
    389         rc = mm_stream_fsm_cfg(my_obj, evt, in_val, out_val);
    390         break;
    391     case MM_STREAM_STATE_BUFFED:
    392         rc = mm_stream_fsm_buffed(my_obj, evt, in_val, out_val);
    393         break;
    394     case MM_STREAM_STATE_REG:
    395         rc = mm_stream_fsm_reg(my_obj, evt, in_val, out_val);
    396         break;
    397     case MM_STREAM_STATE_ACTIVE_STREAM_ON:
    398         rc = mm_stream_fsm_active_stream_on(my_obj, evt, in_val, out_val);
    399         break;
    400     case MM_STREAM_STATE_ACTIVE_STREAM_OFF:
    401         rc = mm_stream_fsm_active_stream_off(my_obj, evt, in_val, out_val);
    402         break;
    403     default:
    404         CDBG("%s: Not a valid state (%d)", __func__, my_obj->state);
    405         break;
    406     }
    407     CDBG("%s : X rc =%d",__func__,rc);
    408     return rc;
    409 }
    410 
    411 int32_t mm_stream_fsm_inited(mm_stream_t *my_obj,
    412                              mm_stream_evt_type_t evt,
    413                              void * in_val,
    414                              void * out_val)
    415 {
    416     int32_t rc = 0;
    417     char dev_name[MM_CAMERA_DEV_NAME_LEN];
    418 
    419     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    420          "image_mode = %d, fd = %d, state = %d, event = %d",
    421          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    422          my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
    423     switch(evt) {
    424     case MM_STREAM_EVT_ACQUIRE:
    425         if ((NULL == my_obj->ch_obj) || (NULL == my_obj->ch_obj->cam_obj)) {
    426             CDBG_ERROR("%s: NULL channel or camera obj\n", __func__);
    427             rc = -1;
    428             break;
    429         }
    430 
    431         snprintf(dev_name, sizeof(dev_name), "/dev/%s",
    432                  mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl));
    433 
    434         my_obj->fd = open(dev_name, O_RDWR | O_NONBLOCK);
    435         if (my_obj->fd <= 0) {
    436             CDBG_ERROR("%s: open dev returned %d\n", __func__, my_obj->fd);
    437             rc = -1;
    438             break;
    439         }
    440         CDBG("%s: open dev fd = %d, ext_image_mode = %d, sensor_idx = %d\n",
    441                  __func__, my_obj->fd, my_obj->ext_image_mode, my_obj->sensor_idx);
    442         rc = mm_stream_set_ext_mode(my_obj);
    443         if (0 == rc) {
    444             my_obj->state = MM_STREAM_STATE_ACQUIRED;
    445         } else {
    446             /* failed setting ext_mode
    447              * close fd */
    448             if(my_obj->fd > 0) {
    449                 close(my_obj->fd);
    450                 my_obj->fd = -1;
    451             }
    452             break;
    453         }
    454         rc = get_stream_inst_handle(my_obj);
    455         if(rc) {
    456             if(my_obj->fd > 0) {
    457                 close(my_obj->fd);
    458                 my_obj->fd = -1;
    459             }
    460         }
    461         break;
    462     default:
    463         CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
    464                    __func__,evt,my_obj->state);
    465         break;
    466     }
    467     return rc;
    468 }
    469 
    470 int32_t mm_stream_fsm_acquired(mm_stream_t *my_obj,
    471                                mm_stream_evt_type_t evt,
    472                                void * in_val,
    473                                void * out_val)
    474 {
    475     int32_t rc = 0;
    476 
    477     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    478          "image_mode = %d, fd = %d, state = %d, event = %d",
    479          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    480          my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
    481     switch(evt) {
    482     case MM_STREAM_EVT_SET_FMT:
    483         {
    484             mm_camera_stream_config_t *config =
    485                 (mm_camera_stream_config_t *)in_val;
    486 
    487             rc = mm_stream_config(my_obj, config);
    488 
    489             /* change state to configed */
    490             my_obj->state = MM_STREAM_STATE_CFG;
    491 
    492             break;
    493         }
    494     case MM_STREAM_EVT_RELEASE:
    495         rc = mm_stream_release(my_obj);
    496         /* change state to not used */
    497          my_obj->state = MM_STREAM_STATE_NOTUSED;
    498         break;
    499     case MM_STREAM_EVT_SET_PARM:
    500         rc = mm_stream_set_parm_acquire(my_obj, in_val);
    501         break;
    502     case MM_STREAM_EVT_GET_PARM:
    503         rc = mm_stream_get_parm_acquire(my_obj,out_val);
    504         break;
    505     default:
    506         CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
    507                    __func__, evt, my_obj->state);
    508     }
    509     CDBG("%s :X rc = %d",__func__,rc);
    510     return rc;
    511 }
    512 
    513 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
    514                           mm_stream_evt_type_t evt,
    515                           void * in_val,
    516                           void * out_val)
    517 {
    518     int32_t rc = 0;
    519     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    520          "image_mode = %d, fd = %d, state = %d, event = %d",
    521          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    522          my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
    523     switch(evt) {
    524     case MM_STREAM_EVT_SET_FMT:
    525         {
    526             mm_camera_stream_config_t *config =
    527                 (mm_camera_stream_config_t *)in_val;
    528 
    529             rc = mm_stream_config(my_obj, config);
    530 
    531             /* change state to configed */
    532             my_obj->state = MM_STREAM_STATE_CFG;
    533 
    534             break;
    535         }
    536     case MM_STREAM_EVT_RELEASE:
    537         rc = mm_stream_release(my_obj);
    538         my_obj->state = MM_STREAM_STATE_NOTUSED;
    539         break;
    540     case MM_STREAM_EVT_SET_PARM:
    541         rc = mm_stream_set_parm_config(my_obj, in_val);
    542         break;
    543     case MM_STREAM_EVT_GET_PARM:
    544         rc = mm_stream_get_parm_config(my_obj, out_val);
    545         break;
    546     case MM_STREAM_EVT_GET_BUF:
    547         rc = mm_stream_init_bufs(my_obj);
    548         /* change state to buff allocated */
    549         if(0 == rc) {
    550             my_obj->state = MM_STREAM_STATE_BUFFED;
    551         }
    552         break;
    553     default:
    554         CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
    555                    __func__, evt, my_obj->state);
    556     }
    557     CDBG("%s :X rc = %d",__func__,rc);
    558     return rc;
    559 }
    560 
    561 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
    562                              mm_stream_evt_type_t evt,
    563                              void * in_val,
    564                              void * out_val)
    565 {
    566     int32_t rc = 0;
    567     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    568          "image_mode = %d, fd = %d, state = %d, event = %d",
    569          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    570          my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
    571     switch(evt) {
    572     case MM_STREAM_EVT_PUT_BUF:
    573         rc = mm_stream_deinit_bufs(my_obj);
    574         /* change state to configed */
    575         if(0 == rc) {
    576             my_obj->state = MM_STREAM_STATE_CFG;
    577         }
    578         break;
    579     case MM_STREAM_EVT_REG_BUF:
    580         rc = mm_stream_reg_buf(my_obj);
    581         /* change state to regged */
    582         if(0 == rc) {
    583             my_obj->state = MM_STREAM_STATE_REG;
    584         }
    585         break;
    586     case MM_STREAM_EVT_SET_PARM:
    587         rc = mm_stream_set_parm_config(my_obj, in_val);
    588         break;
    589     case MM_STREAM_EVT_GET_PARM:
    590         rc = mm_stream_get_parm_config(my_obj, out_val);
    591         break;
    592     default:
    593         CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
    594                    __func__, evt, my_obj->state);
    595     }
    596     CDBG("%s :X rc = %d",__func__,rc);
    597     return rc;
    598 }
    599 
    600 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
    601                           mm_stream_evt_type_t evt,
    602                           void * in_val,
    603                           void * out_val)
    604 {
    605     int32_t rc = 0;
    606     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    607          "image_mode = %d, fd = %d, state = %d, event = %d",
    608          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    609          my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
    610 
    611     switch(evt) {
    612     case MM_STREAM_EVT_UNREG_BUF:
    613         rc = mm_stream_unreg_buf(my_obj);
    614 
    615         /* change state to buffed */
    616         my_obj->state = MM_STREAM_STATE_BUFFED;
    617         break;
    618     case MM_STREAM_EVT_START:
    619         {
    620             /* launch cmd thread if CB is not null */
    621             if (NULL != my_obj->buf_cb) {
    622                 mm_camera_cmd_thread_launch(&my_obj->cmd_thread,
    623                                 mm_stream_dispatch_app_data,
    624                                 (void *)my_obj);
    625 
    626             }
    627 
    628             if(my_obj->need_stream_on) {
    629                 rc = mm_stream_streamon(my_obj);
    630                 if (0 != rc) {
    631                     /* failed stream on, need to release cmd thread if it's launched */
    632                     if (NULL != my_obj->buf_cb) {
    633                         mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    634 
    635                     }
    636                     break;
    637                 }
    638                 my_obj->state = MM_STREAM_STATE_ACTIVE_STREAM_ON;
    639             } else {
    640                 /* register CB at video fd */
    641                 CDBG("%s : Video Size snapshot Enabled",__func__);
    642                 mm_stream_data_cb_t cb;
    643                 memset(&cb, 0, sizeof(mm_stream_data_cb_t));
    644                 cb.cb_count = my_obj->num_stream_cb_times; /* reigstration cb times */
    645                 if (cb.cb_count == 0) {
    646                     cb.cb_count = 1;
    647                 }
    648                 cb.user_data = (void*)my_obj;
    649                 cb.cb = mm_stream_buf_notify;
    650                 rc = mm_channel_reg_stream_cb(my_obj->ch_obj, &cb,
    651                                               MSM_V4L2_EXT_CAPTURE_MODE_VIDEO,
    652                                               my_obj->sensor_idx);
    653                 my_obj->state = MM_STREAM_STATE_ACTIVE_STREAM_OFF;
    654             }
    655         }
    656         break;
    657     case MM_STREAM_EVT_SET_PARM:
    658         rc = mm_stream_set_parm_config(my_obj, in_val);
    659         break;
    660     case MM_STREAM_EVT_GET_PARM:
    661         rc = mm_stream_get_parm_config(my_obj, out_val);
    662         break;
    663     default:
    664         CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
    665                    __func__, evt, my_obj->state);
    666     }
    667     CDBG("%s :X rc = %d",__func__,rc);
    668     return rc;
    669 }
    670 
    671 int32_t mm_stream_fsm_active_stream_on(mm_stream_t * my_obj,
    672                                               mm_stream_evt_type_t evt,
    673                                               void * in_val,
    674                                               void * out_val)
    675 {
    676     int32_t rc = 0;
    677     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    678          "image_mode = %d, fd = %d, state = %d, event = %d",
    679          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    680          my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
    681     switch(evt) {
    682     case MM_STREAM_EVT_QBUF:
    683         rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
    684         break;
    685     case MM_STREAM_EVT_STOP:
    686         {
    687             rc = mm_stream_streamoff(my_obj);
    688             if (NULL != my_obj->buf_cb) {
    689                 mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    690 
    691             }
    692             my_obj->state = MM_STREAM_STATE_REG;
    693         }
    694         break;
    695     case MM_STREAM_EVT_SET_PARM:
    696         rc = mm_stream_set_parm_start(my_obj, in_val);
    697         break;
    698     case MM_STREAM_EVT_GET_PARM:
    699         rc = mm_stream_get_parm_start(my_obj, out_val);
    700         break;
    701     default:
    702         CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
    703                    __func__, evt, my_obj->state);
    704     }
    705     CDBG("%s :X rc = %d",__func__,rc);
    706     return rc;
    707 }
    708 
    709 int32_t mm_stream_fsm_active_stream_off(mm_stream_t * my_obj,
    710                                                mm_stream_evt_type_t evt,
    711                                                void * in_val,
    712                                                void * out_val)
    713 {
    714     int32_t rc = 0;
    715     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    716          "image_mode = %d, fd = %d, state = %d, event = %d",
    717          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    718          my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
    719     switch(evt) {
    720     case MM_STREAM_EVT_QBUF:
    721         rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
    722         break;
    723     case MM_STREAM_EVT_STOP:
    724         {
    725             if (NULL != my_obj->buf_cb) {
    726                 rc = mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    727 
    728             }
    729             my_obj->state = MM_STREAM_STATE_REG;
    730         }
    731         break;
    732    case MM_STREAM_EVT_SET_PARM:
    733         rc = mm_stream_set_parm_config(my_obj, in_val);
    734         break;
    735     case MM_STREAM_EVT_GET_PARM:
    736         rc = mm_stream_get_parm_config(my_obj, out_val);
    737         break;
    738     default:
    739         CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
    740                    __func__, evt, my_obj->state);
    741     }
    742     CDBG("%s :X rc = %d",__func__,rc);
    743     return rc;
    744 }
    745 
    746 int32_t mm_stream_config(mm_stream_t *my_obj,
    747                          mm_camera_stream_config_t *config)
    748 {
    749     int32_t rc = 0;
    750     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    751          "image_mode = %d, fd = %d, state = %d",
    752          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    753          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    754     memcpy(&my_obj->fmt, &config->fmt, sizeof(mm_camera_image_fmt_t));
    755     my_obj->hal_requested_num_bufs = config->num_of_bufs;
    756     my_obj->need_stream_on = config->need_stream_on;
    757     my_obj->num_stream_cb_times = config->num_stream_cb_times;
    758 
    759     rc = mm_stream_get_offset(my_obj);
    760     if(rc != 0) {
    761         CDBG_ERROR("%s: Error in offset query",__func__);
    762         return rc;
    763     }
    764     /* write back width and height to config in case mctl has modified the value */
    765     config->fmt.width = my_obj->fmt.width;
    766     config->fmt.height = my_obj->fmt.height;
    767     if(my_obj->need_stream_on) {
    768         /* only send fmt to backend if we need streamon */
    769         rc = mm_stream_set_fmt(my_obj);
    770     }
    771     return rc;
    772 }
    773 
    774 int32_t mm_stream_release(mm_stream_t *my_obj)
    775 {
    776     int32_t rc;
    777     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    778          "image_mode = %d, fd = %d, state = %d",
    779          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    780          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    781 
    782     /* close fd */
    783     if(my_obj->fd > 0)
    784     {
    785         close(my_obj->fd);
    786     }
    787 
    788     /* destroy mutex */
    789     pthread_mutex_destroy(&my_obj->buf_lock);
    790     pthread_mutex_destroy(&my_obj->cb_lock);
    791 
    792     /* reset stream obj */
    793     memset(my_obj, 0, sizeof(mm_stream_t));
    794     my_obj->fd = -1;
    795 
    796     return 0;
    797 }
    798 
    799 int32_t mm_stream_streamon(mm_stream_t *my_obj)
    800 {
    801     int32_t rc;
    802     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    803 
    804     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    805          "image_mode = %d, fd = %d, state = %d",
    806          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    807          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    808     /* Add fd to data poll thread */
    809     rc = mm_camera_poll_thread_add_poll_fd(&my_obj->ch_obj->poll_thread[0],
    810                                            my_obj->my_hdl,
    811                                            my_obj->fd,
    812                                            mm_stream_data_notify,
    813                                            (void*)my_obj);
    814     if (rc < 0) {
    815         return rc;
    816     }
    817     rc = ioctl(my_obj->fd, VIDIOC_STREAMON, &buf_type);
    818     if (rc < 0) {
    819         CDBG_ERROR("%s: ioctl VIDIOC_STREAMON failed: rc=%d\n",
    820                    __func__, rc);
    821         /* remove fd from data poll thread in case of failure */
    822         mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl);
    823     }
    824     CDBG("%s :X rc = %d",__func__,rc);
    825     return rc;
    826 }
    827 
    828 int32_t mm_stream_streamoff(mm_stream_t *my_obj)
    829 {
    830     int32_t rc;
    831     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    832     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    833          "image_mode = %d, fd = %d, state = %d",
    834          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    835          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    836 
    837     /* step1: remove fd from data poll thread */
    838     mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl);
    839 
    840     /* step2: stream off */
    841     rc = ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type);
    842     if (rc < 0) {
    843         CDBG_ERROR("%s: STREAMOFF failed: %s\n",
    844                 __func__, strerror(errno));
    845     }
    846     CDBG("%s :X rc = %d",__func__,rc);
    847     return rc;
    848 }
    849 
    850 static uint32_t mm_stream_util_get_v4l2_fmt(cam_format_t fmt,
    851                                             uint8_t *num_planes)
    852 {
    853     uint32_t val;
    854     switch(fmt) {
    855     case CAMERA_YUV_420_NV12:
    856         val = V4L2_PIX_FMT_NV12;
    857         *num_planes = 2;
    858         break;
    859     case CAMERA_YUV_420_NV21:
    860         val = V4L2_PIX_FMT_NV21;
    861         *num_planes = 2;
    862         break;
    863     case CAMERA_BAYER_SBGGR10:
    864     case CAMERA_RDI:
    865         val= V4L2_PIX_FMT_SBGGR10;
    866         *num_planes = 1;
    867         break;
    868     case CAMERA_YUV_422_NV61:
    869         val= V4L2_PIX_FMT_NV61;
    870         *num_planes = 2;
    871         break;
    872     case CAMERA_SAEC:
    873         val = V4L2_PIX_FMT_STATS_AE;
    874         *num_planes = 1;
    875         break;
    876    case CAMERA_SAWB:
    877         val = V4L2_PIX_FMT_STATS_AWB;
    878         *num_planes = 1;
    879         break;
    880    case CAMERA_SAFC:
    881         val = V4L2_PIX_FMT_STATS_AF;
    882         *num_planes = 1;
    883         break;
    884    case CAMERA_SHST:
    885         val = V4L2_PIX_FMT_STATS_IHST;
    886         *num_planes = 1;
    887         break;
    888     case CAMERA_YUV_422_YUYV:
    889         val= V4L2_PIX_FMT_YUYV;
    890         *num_planes = 1;
    891         break;
    892     case CAMERA_YUV_420_YV12:
    893         val= V4L2_PIX_FMT_NV12;
    894         *num_planes = 3;
    895         break;
    896     default:
    897         val = 0;
    898         *num_planes = 0;
    899         CDBG_ERROR("%s: Unknown fmt=%d", __func__, fmt);
    900         break;
    901     }
    902     CDBG("%s: fmt=%d, val =%d, num_planes=%d", __func__, fmt, val , *num_planes);
    903     return val;
    904 }
    905 
    906 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
    907                                  mm_camera_buf_info_t* buf_info)
    908 {
    909     int32_t idx = -1, rc = 0;
    910     struct v4l2_buffer vb;
    911     struct v4l2_plane planes[VIDEO_MAX_PLANES];
    912     uint32_t i = 0;
    913     uint8_t num_planes = 0;
    914     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    915          "image_mode = %d, fd = %d, state = %d",
    916          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    917          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    918 
    919     mm_stream_util_get_v4l2_fmt(my_obj->fmt.fmt,
    920                                 &num_planes);
    921 
    922     memset(&vb,  0,  sizeof(vb));
    923     vb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    924     vb.memory = V4L2_MEMORY_USERPTR;
    925     vb.m.planes = &planes[0];
    926     vb.length = num_planes;
    927 
    928     rc = ioctl(my_obj->fd, VIDIOC_DQBUF, &vb);
    929     if (rc < 0) {
    930         CDBG_ERROR("%s: VIDIOC_DQBUF ioctl call failed (rc=%d)\n",
    931                    __func__, rc);
    932     } else {
    933         int8_t idx = vb.index;
    934         buf_info->buf = &my_obj->buf[idx];
    935         buf_info->frame_idx = vb.sequence;
    936         buf_info->stream_id = my_obj->my_hdl;
    937 
    938         buf_info->buf->stream_id = my_obj->my_hdl;
    939         buf_info->buf->buf_idx = idx;
    940         buf_info->buf->frame_idx = vb.sequence;
    941         buf_info->buf->ts.tv_sec  = vb.timestamp.tv_sec;
    942         buf_info->buf->ts.tv_nsec = vb.timestamp.tv_usec * 1000;
    943 
    944         for(i = 0; i < vb.length; i++) {
    945             CDBG("%s plane %d addr offset: %d data offset:%d\n",
    946                  __func__, i, vb.m.planes[i].reserved[0],
    947                  vb.m.planes[i].data_offset);
    948             buf_info->buf->planes[i].reserved[0] =
    949                 vb.m.planes[i].reserved[0];
    950             buf_info->buf->planes[i].data_offset =
    951                 vb.m.planes[i].data_offset;
    952         }
    953 
    954 
    955     }
    956     CDBG("%s :X rc = %d",__func__,rc);
    957     return rc;
    958 }
    959 
    960 int32_t mm_stream_get_crop(mm_stream_t *my_obj,
    961                            mm_camera_rect_t *crop)
    962 {
    963     struct v4l2_crop crop_info;
    964     int32_t rc = 0;
    965     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    966          "image_mode = %d, fd = %d, state = %d",
    967          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    968          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
    969 
    970     memset(&crop_info, 0, sizeof(crop_info));
    971     crop_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    972     rc = ioctl(my_obj->fd, VIDIOC_G_CROP, &crop_info);
    973     if (0 == rc) {
    974         crop->left = crop_info.c.left;
    975         crop->top = crop_info.c.top;
    976         crop->width = crop_info.c.width;
    977         crop->height = crop_info.c.height;
    978     }
    979     CDBG("%s :X rc = %d",__func__,rc);
    980     return rc;
    981 }
    982 
    983 int32_t mm_stream_set_parm_acquire(mm_stream_t *my_obj,
    984                          void *in_value)
    985 {
    986     int32_t rc = 0;
    987     mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
    988     mm_camera_stream_parm_t parm_type = payload->parm_type;
    989     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
    990          "image_mode = %d, fd = %d, state = %d, parm_type = %d",
    991          __func__, my_obj->inst_hdl, my_obj->my_hdl,
    992          my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type);
    993 
    994     switch(parm_type) {
    995     case MM_CAMERA_STREAM_CID:{
    996             stream_cid_t *value = (stream_cid_t *)in_value;
    997             mm_stream_set_cid(my_obj,value);
    998             break;
    999         }
   1000         default:
   1001             CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
   1002             break;
   1003     }
   1004     return rc;
   1005 }
   1006 int32_t mm_stream_get_parm_acquire(mm_stream_t *my_obj,
   1007                          void *out_value)
   1008 {
   1009     int32_t rc = 0;
   1010     mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
   1011     mm_camera_stream_parm_t parm_type = payload->parm_type;
   1012     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1013          "image_mode = %d, fd = %d, state = %d, parm_type = %d",
   1014          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1015          my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type);
   1016 
   1017     switch(parm_type) {
   1018     case MM_CAMERA_STREAM_CID:{
   1019             stream_cid_t *value = (stream_cid_t *)out_value;
   1020             rc = mm_stream_get_cid(my_obj,value);
   1021             break;
   1022         }
   1023         case MM_CAMERA_STREAM_CROP:{
   1024             mm_camera_rect_t *crop = (mm_camera_rect_t *)out_value;
   1025             rc = mm_stream_get_crop(my_obj, crop);
   1026             break;
   1027         }
   1028         default:
   1029             CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)parm_type);
   1030             break;
   1031     }
   1032     return rc;
   1033 }
   1034 
   1035 int32_t mm_stream_set_parm_config(mm_stream_t *my_obj,
   1036                          void *in_value)
   1037 {
   1038     int32_t rc = 0;
   1039     mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
   1040     mm_camera_stream_parm_t parm_type = payload->parm_type;
   1041     void *value = payload->value;
   1042 
   1043     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1044          "image_mode = %d, fd = %d, state = %d, parm_type = %d",
   1045          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1046          my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type);
   1047     switch(parm_type) {
   1048         default:
   1049             CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
   1050             break;
   1051     }
   1052     return rc;
   1053 }
   1054 int32_t mm_stream_get_parm_config(mm_stream_t *my_obj,
   1055                          void *out_value)
   1056 {
   1057     int32_t rc = 0;
   1058     mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
   1059 
   1060     if(payload == NULL) {
   1061         CDBG_ERROR("%s : Invalid Argument",__func__);
   1062         return -1;
   1063     }
   1064     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1065      "image_mode = %d, fd = %d, state = %d, parm_type = %d",
   1066      __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1067      my_obj->ext_image_mode, my_obj->fd, my_obj->state, (int)payload->parm_type);
   1068     switch(payload->parm_type) {
   1069         case MM_CAMERA_STREAM_OFFSET:
   1070             memcpy(payload->value,(void *)&my_obj->frame_offset,sizeof(mm_camera_frame_len_offset));
   1071             break;
   1072         case MM_CAMERA_STREAM_CROP:{
   1073             mm_camera_rect_t *crop = (mm_camera_rect_t *)payload->value;
   1074             rc = mm_stream_get_crop(my_obj, crop);
   1075             break;
   1076         }
   1077         default:
   1078             CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)payload->parm_type);
   1079             break;
   1080     }
   1081     return rc;
   1082 }
   1083 
   1084 int32_t mm_stream_set_parm_start(mm_stream_t *my_obj,
   1085                          void *in_value)
   1086 {
   1087     int32_t rc = 0;
   1088     mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
   1089     mm_camera_stream_parm_t parm_type = payload->parm_type;
   1090     void *value = payload->value;
   1091 
   1092     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1093          "image_mode = %d, fd = %d, state = %d, parm_type = %d",
   1094          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1095          my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type);
   1096     switch(parm_type) {
   1097         default:
   1098             CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
   1099             break;
   1100     }
   1101     return rc;
   1102 }
   1103 int32_t mm_stream_get_parm_start(mm_stream_t *my_obj,
   1104                          void *out_value)
   1105 {
   1106     int32_t rc = 0;
   1107     mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
   1108 
   1109     if(payload == NULL) {
   1110         CDBG_ERROR("%s : Invalid Argument",__func__);
   1111         return -1;
   1112     }
   1113     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1114      "image_mode = %d, fd = %d, state = %d, parm_type = %d",
   1115      __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1116      my_obj->ext_image_mode, my_obj->fd, my_obj->state, (int)payload->parm_type);
   1117     switch(payload->parm_type) {
   1118         case MM_CAMERA_STREAM_OFFSET:
   1119             memcpy(payload->value,(void *)&my_obj->frame_offset,sizeof(mm_camera_frame_len_offset));
   1120             break;
   1121         case MM_CAMERA_STREAM_CROP:{
   1122             mm_camera_rect_t *crop = (mm_camera_rect_t *)payload->value;
   1123             rc = mm_stream_get_crop(my_obj, crop);
   1124             break;
   1125         }
   1126         default:
   1127             CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)payload->parm_type);
   1128             break;
   1129     }
   1130     return rc;
   1131 }
   1132 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj)
   1133 {
   1134     int32_t rc = 0;
   1135     struct v4l2_streamparm s_parm;
   1136     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1137          "image_mode = %d, fd = %d, state = %d",
   1138          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1139          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1140 
   1141     s_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1142     s_parm.parm.capture.extendedmode = my_obj->ext_image_mode;
   1143 
   1144     rc = ioctl(my_obj->fd, VIDIOC_S_PARM, &s_parm);
   1145         CDBG("%s:stream fd=%d, rc=%d, extended_mode=%d\n",
   1146                  __func__, my_obj->fd, rc,
   1147                  s_parm.parm.capture.extendedmode);
   1148     return rc;
   1149 }
   1150 
   1151 int32_t mm_stream_qbuf(mm_stream_t *my_obj, mm_camera_buf_def_t *buf)
   1152 {
   1153     int32_t i, rc = 0;
   1154     int *ret;
   1155     struct v4l2_buffer buffer;
   1156     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1157          "image_mode = %d, fd = %d, state = %d",
   1158          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1159          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1160 
   1161     memset(&buffer, 0, sizeof(buffer));
   1162     buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1163     buffer.memory = V4L2_MEMORY_USERPTR;
   1164     buffer.index = buf->buf_idx;
   1165     buffer.m.planes = &buf->planes[0];
   1166     buffer.length = buf->num_planes;
   1167 
   1168     CDBG("%s:stream_hdl=%d,fd=%d,frame idx=%d,num_planes = %d\n", __func__,
   1169          buf->stream_id, buf->fd, buffer.index, buffer.length);
   1170 
   1171     rc = ioctl(my_obj->fd, VIDIOC_QBUF, &buffer);
   1172     CDBG("%s: qbuf idx:%d, rc:%d", __func__, buffer.index, rc);
   1173     return rc;
   1174 }
   1175 
   1176 /* This function let kernel know amount of buffers will be registered */
   1177 int32_t mm_stream_request_buf(mm_stream_t * my_obj)
   1178 {
   1179     int32_t rc = 0;
   1180     uint8_t i,reg = 0;
   1181     struct v4l2_requestbuffers bufreq;
   1182     uint8_t buf_num = my_obj->buf_num;
   1183     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1184          "image_mode = %d, fd = %d, state = %d",
   1185          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1186          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1187 
   1188     if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) {
   1189         CDBG_ERROR("%s: buf num %d > max limit %d\n",
   1190                  __func__, buf_num, MM_CAMERA_MAX_NUM_FRAMES);
   1191         return -1;
   1192     }
   1193     pthread_mutex_lock(&my_obj->buf_lock);
   1194     for(i = 0; i < buf_num; i++){
   1195         if (my_obj->buf_status[i].initial_reg_flag){
   1196             reg = 1;
   1197             break;
   1198         }
   1199     }
   1200     pthread_mutex_unlock(&my_obj->buf_lock);
   1201     if(!reg) {
   1202         //No need to register a buffer
   1203         CDBG_ERROR("No Need to register this buffer");
   1204         return rc;
   1205     }
   1206     memset(&bufreq, 0, sizeof(bufreq));
   1207     bufreq.count = buf_num;
   1208     bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1209     bufreq.memory = V4L2_MEMORY_USERPTR;
   1210     rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
   1211     if (rc < 0) {
   1212       CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n",
   1213            __func__, my_obj->fd, rc);
   1214     }
   1215     CDBG("%s :X rc = %d",__func__,rc);
   1216     return rc;
   1217 }
   1218 
   1219 int32_t mm_stream_init_bufs(mm_stream_t * my_obj)
   1220 {
   1221     int32_t i, rc = 0, j;
   1222     int image_type;
   1223     mm_camear_mem_vtbl_t *mem_vtbl = NULL;
   1224     mm_camera_frame_len_offset frame_offset;
   1225     uint8_t *reg_flags = NULL;
   1226     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1227          "image_mode = %d, fd = %d, state = %d",
   1228          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1229          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1230 
   1231     /* deinit buf if it's not NULL*/
   1232     if (NULL != my_obj->buf) {
   1233         mm_stream_deinit_bufs(my_obj);
   1234     }
   1235 
   1236     my_obj->buf_num = my_obj->hal_requested_num_bufs;
   1237     if (mm_camera_util_get_pp_mask(my_obj->ch_obj->cam_obj) > 0) {
   1238         /* reserve extra one buf for pp */
   1239         my_obj->buf_num++;
   1240     }
   1241 
   1242     my_obj->buf =
   1243         (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t) * my_obj->buf_num);
   1244     my_obj->buf_status =
   1245         (mm_stream_buf_status_t*)malloc(sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
   1246     reg_flags = (uint8_t *)malloc(sizeof(uint8_t) * my_obj->buf_num);
   1247 
   1248     if (NULL == my_obj->buf ||
   1249         NULL == my_obj->buf_status ||
   1250         NULL == reg_flags) {
   1251         CDBG_ERROR("%s: No memory for buf", __func__);
   1252         rc = -1;
   1253         goto error_malloc;
   1254     }
   1255 
   1256     memset(my_obj->buf, 0, sizeof(mm_camera_buf_def_t) * my_obj->buf_num);
   1257     memset(my_obj->buf_status, 0, sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
   1258     memset(reg_flags, 0, sizeof(uint8_t) * my_obj->buf_num);
   1259 
   1260     mem_vtbl = my_obj->ch_obj->cam_obj->mem_vtbl;
   1261     rc = mem_vtbl->get_buf(my_obj->ch_obj->cam_obj->my_hdl,
   1262                            my_obj->ch_obj->my_hdl,
   1263                            my_obj->my_hdl,
   1264                            mem_vtbl->user_data,
   1265                            &my_obj->frame_offset,
   1266                            my_obj->buf_num,
   1267                            reg_flags,
   1268                            my_obj->buf);
   1269 
   1270     if (0 != rc) {
   1271         CDBG_ERROR("%s: Error get buf, rc = %d\n", __func__, rc);
   1272         goto error_malloc;
   1273     }
   1274 
   1275     for (i=0; i < my_obj->buf_num; i++) {
   1276         my_obj->buf_status[i].initial_reg_flag = reg_flags[i];
   1277         my_obj->buf[i].stream_id = my_obj->my_hdl;
   1278     }
   1279 
   1280     free(reg_flags);
   1281     reg_flags = NULL;
   1282 
   1283     for (i=0; i < my_obj->buf_num; i++) {
   1284         if (my_obj->buf[i].fd > 0) {
   1285             if(0 >= (rc = mm_camera_map_buf(my_obj->ch_obj->cam_obj,
   1286                           my_obj->ext_image_mode,
   1287                           i,
   1288                           my_obj->buf[i].fd,
   1289                           my_obj->buf[i].frame_len)))
   1290             {
   1291                 CDBG_ERROR("%s: Error mapping buf (rc = %d)", __func__, rc);
   1292                 goto error_map;
   1293             }
   1294         } else {
   1295             CDBG_ERROR("%s: Invalid fd for buf idx (%d)", __func__, i);
   1296         }
   1297     }
   1298 
   1299     return 0;
   1300 
   1301 error_map:
   1302     /* error, unmapping previously mapped bufs */
   1303     for (j=0; j<i; j++) {
   1304         if (my_obj->buf[j].fd > 0) {
   1305             mm_camera_unmap_buf(my_obj->ch_obj->cam_obj,
   1306                                 my_obj->ext_image_mode,
   1307                                 j);
   1308         }
   1309     }
   1310 
   1311     /* put buf back */
   1312     mem_vtbl->put_buf(my_obj->ch_obj->cam_obj->my_hdl,
   1313                       my_obj->ch_obj->my_hdl,
   1314                       my_obj->my_hdl,
   1315                       mem_vtbl->user_data,
   1316                       my_obj->buf_num,
   1317                       my_obj->buf);
   1318 
   1319 error_malloc:
   1320     if (NULL != my_obj->buf) {
   1321         free(my_obj->buf);
   1322         my_obj->buf = NULL;
   1323     }
   1324     if (NULL != my_obj->buf_status) {
   1325         free(my_obj->buf_status);
   1326         my_obj->buf_status = NULL;
   1327     }
   1328     if (NULL != reg_flags) {
   1329         free(reg_flags);
   1330         reg_flags = NULL;
   1331     }
   1332 
   1333     return rc;
   1334 }
   1335 
   1336 /* return buffers to surface or release buffers allocated */
   1337 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj)
   1338 {
   1339     int32_t rc = 0, i;
   1340     mm_camear_mem_vtbl_t *mem_vtbl = NULL;
   1341     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1342          "image_mode = %d, fd = %d, state = %d",
   1343          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1344          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1345 
   1346     if (NULL == my_obj->buf) {
   1347         CDBG("%s: Buf is NULL, no need to deinit", __func__);
   1348         return rc;
   1349     }
   1350 
   1351     /* IOMMU unmapping */
   1352     for (i=0; i<my_obj->buf_num; i++) {
   1353         if (my_obj->buf[i].fd > 0) {
   1354             rc = mm_camera_unmap_buf(my_obj->ch_obj->cam_obj,
   1355                                      my_obj->ext_image_mode,
   1356                                      i);
   1357             if (rc < 0 ) {
   1358                 CDBG_ERROR("%s: Error unmapping bufs at idx(%d) rc=%d",
   1359                            __func__, i, rc);
   1360             }
   1361         }
   1362     }
   1363 
   1364     /* release bufs */
   1365     mem_vtbl = my_obj->ch_obj->cam_obj->mem_vtbl;
   1366     if (NULL != mem_vtbl) {
   1367         rc = mem_vtbl->put_buf(my_obj->ch_obj->cam_obj->my_hdl,
   1368                           my_obj->ch_obj->my_hdl,
   1369                           my_obj->my_hdl,
   1370                           mem_vtbl->user_data,
   1371                           my_obj->buf_num,
   1372                           my_obj->buf);
   1373     } else {
   1374         CDBG_ERROR("%s: mem table is NULL, cannot release buf", __func__);
   1375         rc = -1;
   1376     }
   1377     free(my_obj->buf);
   1378     my_obj->buf = NULL;
   1379     free(my_obj->buf_status);
   1380     my_obj->buf_status = NULL;
   1381 
   1382     return rc;
   1383 }
   1384 
   1385 int32_t mm_stream_reg_buf(mm_stream_t * my_obj)
   1386 {
   1387     int32_t rc = 0;
   1388     uint8_t i;
   1389     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1390          "image_mode = %d, fd = %d, state = %d",
   1391          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1392          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1393 
   1394     rc = mm_stream_request_buf(my_obj);
   1395     if (rc != 0) {
   1396         return rc;
   1397     }
   1398 
   1399     pthread_mutex_lock(&my_obj->buf_lock);
   1400     for(i = 0; i < my_obj->buf_num; i++){
   1401         my_obj->buf[i].buf_idx = i;
   1402 
   1403         /* check if need to qbuf initially */
   1404         if (my_obj->buf_status[i].initial_reg_flag) {
   1405             rc = mm_stream_qbuf(my_obj, &my_obj->buf[i]);
   1406             if (rc != 0) {
   1407                 CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc);
   1408                 break;
   1409             }
   1410             my_obj->buf_status[i].buf_refcnt = 0;
   1411             my_obj->buf_status[i].in_kernel = 1;
   1412         } else {
   1413             /* the buf is held by upper layer, will not queue into kernel.
   1414              * add buf reference count */
   1415             my_obj->buf_status[i].buf_refcnt = 1;
   1416             my_obj->buf_status[i].in_kernel = 0;
   1417         }
   1418     }
   1419 
   1420     pthread_mutex_unlock(&my_obj->buf_lock);
   1421     return rc;
   1422 }
   1423 
   1424 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj)
   1425 {
   1426     struct v4l2_requestbuffers bufreq;
   1427     int32_t i, rc = 0,reg = 0;
   1428     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1429          "image_mode = %d, fd = %d, state = %d",
   1430          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1431          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1432 
   1433     pthread_mutex_lock(&my_obj->buf_lock);
   1434     if (NULL != my_obj->buf_status) {
   1435         for(i = 0; i < my_obj->buf_num; i++){
   1436             if (my_obj->buf_status[i].initial_reg_flag){
   1437                 reg = 1;
   1438                 break;
   1439             }
   1440         }
   1441     }
   1442     pthread_mutex_unlock(&my_obj->buf_lock);
   1443     if(!reg) {
   1444         //No need to unregister a buffer
   1445         goto end;
   1446     }
   1447     bufreq.count = 0;
   1448     bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1449     bufreq.memory = V4L2_MEMORY_USERPTR;
   1450     rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
   1451     if (rc < 0) {
   1452         CDBG_ERROR("%s: fd=%d, VIDIOC_REQBUFS failed, rc=%d\n",
   1453               __func__, my_obj->fd, rc);
   1454     }
   1455 
   1456 end:
   1457     /* reset buf reference count */
   1458     pthread_mutex_lock(&my_obj->buf_lock);
   1459     if (NULL != my_obj->buf_status) {
   1460         for(i = 0; i < my_obj->buf_num; i++){
   1461             my_obj->buf_status[i].buf_refcnt = 0;
   1462             my_obj->buf_status[i].in_kernel = 0;
   1463         }
   1464     }
   1465     pthread_mutex_unlock(&my_obj->buf_lock);
   1466 
   1467     return rc;
   1468 }
   1469 
   1470 int32_t mm_stream_set_fmt(mm_stream_t *my_obj)
   1471 {
   1472     int32_t rc = 0;
   1473     struct v4l2_format fmt;
   1474     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1475          "image_mode = %d, fd = %d, state = %d",
   1476          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1477          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1478 
   1479     if(my_obj->fmt.width == 0 || my_obj->fmt.height == 0) {
   1480         CDBG_ERROR("%s:invalid input[w=%d,h=%d,fmt=%d]\n",
   1481                  __func__, my_obj->fmt.width, my_obj->fmt.height, my_obj->fmt.fmt);
   1482         return -1;
   1483     }
   1484 
   1485     memset(&fmt, 0, sizeof(fmt));
   1486     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1487     fmt.fmt.pix_mp.width = my_obj->fmt.width;
   1488     fmt.fmt.pix_mp.height= my_obj->fmt.height;
   1489     fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   1490     fmt.fmt.pix_mp.pixelformat =
   1491             mm_stream_util_get_v4l2_fmt(my_obj->fmt.fmt,
   1492                                       &(fmt.fmt.pix_mp.num_planes));
   1493     rc = ioctl(my_obj->fd, VIDIOC_S_FMT, &fmt);
   1494     CDBG("%s:fd=%d, ext_image_mode=%d, rc=%d, fmt.fmt.pix_mp.pixelformat : 0x%x\n",
   1495        __func__, my_obj->fd, my_obj->ext_image_mode, rc,
   1496        fmt.fmt.pix_mp.pixelformat);
   1497     return rc;
   1498 }
   1499 
   1500 int32_t mm_stream_get_offset(mm_stream_t *my_obj)
   1501 {
   1502     int32_t rc = 0;
   1503     cam_frame_resolution_t frame_offset;
   1504     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1505          "image_mode = %d, fd = %d, state = %d",
   1506          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1507          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1508 
   1509     memset(&my_obj->frame_offset,0,sizeof(mm_camera_frame_len_offset));
   1510 
   1511     frame_offset.format = my_obj->fmt.fmt;
   1512     frame_offset.rotation = my_obj->fmt.rotation;
   1513     frame_offset.width = my_obj->fmt.width;
   1514     frame_offset.height = my_obj->fmt.height;
   1515     frame_offset.image_mode = my_obj->ext_image_mode;
   1516     if (!my_obj->need_stream_on &&
   1517         my_obj->ext_image_mode == MSM_V4L2_EXT_CAPTURE_MODE_MAIN) {
   1518         /* in case of video-sized snapshot,
   1519          * image_mode should be video when querying frame offset*/
   1520         frame_offset.image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
   1521     }
   1522 
   1523     switch (frame_offset.image_mode) {
   1524     case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW:
   1525         if (CAMERA_YUV_420_YV12 == frame_offset.format) {
   1526             frame_offset.padding_format = CAMERA_PAD_TO_2K;
   1527         } else {
   1528             frame_offset.padding_format = CAMERA_PAD_TO_WORD;
   1529         }
   1530         break;
   1531     case MSM_V4L2_EXT_CAPTURE_MODE_MAIN:
   1532     case MSM_V4L2_EXT_CAPTURE_MODE_RAW:
   1533     case MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL:
   1534     case MSM_V4L2_EXT_CAPTURE_MODE_RDI:
   1535         frame_offset.padding_format = CAMERA_PAD_TO_WORD;
   1536         break;
   1537     case MSM_V4L2_EXT_CAPTURE_MODE_AEC:
   1538     case MSM_V4L2_EXT_CAPTURE_MODE_AWB:
   1539     case MSM_V4L2_EXT_CAPTURE_MODE_AF:
   1540     case MSM_V4L2_EXT_CAPTURE_MODE_IHIST:
   1541         break;
   1542     case MSM_V4L2_EXT_CAPTURE_MODE_VIDEO:
   1543     default:
   1544         frame_offset.padding_format = CAMERA_PAD_TO_2K;
   1545         break;
   1546     }
   1547 
   1548     CDBG("%s: format = %d, image_mode = %d, padding_format = %d, rotation = %d,"
   1549             "width = %d height = %d",
   1550              __func__,frame_offset.format,frame_offset.image_mode,frame_offset.padding_format,
   1551              frame_offset.rotation,frame_offset.width,frame_offset.height);
   1552 
   1553     rc = mm_camera_send_native_ctrl_cmd(my_obj->ch_obj->cam_obj,
   1554                                             CAMERA_GET_PARM_FRAME_RESOLUTION,
   1555                                             sizeof(cam_frame_resolution_t),
   1556                                             &frame_offset);
   1557     if(rc != 0) {
   1558         CDBG_ERROR("%s: Failed to get the stream offset and frame length",__func__);
   1559         return rc;
   1560     }
   1561     my_obj->fmt.width = frame_offset.width;
   1562     my_obj->fmt.height = frame_offset.height;
   1563     memcpy(&my_obj->frame_offset,&frame_offset.frame_offset,sizeof(mm_camera_frame_len_offset));
   1564     CDBG("%s: Frame length = %d width = %d, height = %d, rc = %d",
   1565          __func__,my_obj->frame_offset.frame_len,my_obj->fmt.width,my_obj->fmt.height,rc);
   1566     return rc;
   1567 }
   1568 
   1569 
   1570 int32_t mm_stream_set_cid(mm_stream_t *my_obj,stream_cid_t *value)
   1571 {
   1572     int32_t rc = 0;
   1573     cam_cid_info_t cam_cid_info;
   1574     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1575          "image_mode = %d, fd = %d, state = %d",
   1576          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1577          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1578 
   1579     cam_cid_info.num_cids = 1;
   1580     cam_cid_info.cid_entries[0].cid = value->cid;
   1581     cam_cid_info.cid_entries[0].dt = value->dt;
   1582     cam_cid_info.cid_entries[0].inst_handle = my_obj->inst_hdl;
   1583 
   1584     rc = mm_camera_send_native_ctrl_cmd(my_obj->ch_obj->cam_obj,
   1585                                             CAMERA_SET_PARM_CID,
   1586                                             sizeof(cam_cid_info_t),
   1587                                             &cam_cid_info);
   1588     if(rc != 0) {
   1589         CDBG_ERROR("%s: Failed to set the CID",__func__);
   1590         return rc;
   1591     }
   1592     return rc;
   1593 }
   1594 
   1595 int32_t mm_stream_get_cid(mm_stream_t *my_obj,stream_cid_t *out_value)
   1596 {
   1597     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1598          "image_mode = %d, fd = %d, state = %d",
   1599          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1600          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1601     //TODO: Need to use sensor structure init in camera query
   1602     int32_t rc = 0;
   1603     return rc;
   1604 }
   1605 
   1606 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
   1607                            mm_camera_buf_def_t *frame)
   1608 {
   1609     int32_t rc = 0;
   1610     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1611          "image_mode = %d, fd = %d, state = %d",
   1612          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1613          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1614 
   1615     if (my_obj->is_local_buf) {
   1616         /* special case for video-sized live snapshot
   1617          * buf is local, no need to qbuf to kernel */
   1618         return 0;
   1619     }
   1620 
   1621     pthread_mutex_lock(&my_obj->buf_lock);
   1622 
   1623     if(my_obj->buf_status[frame->buf_idx].buf_refcnt == 0) {
   1624         CDBG("%s: Error Trying to free second time?(idx=%d) count=%d, ext_image_mode=%d\n",
   1625                    __func__, frame->buf_idx,
   1626                    my_obj->buf_status[frame->buf_idx].buf_refcnt,
   1627                    my_obj->ext_image_mode);
   1628         rc = -1;
   1629     }else{
   1630         my_obj->buf_status[frame->buf_idx].buf_refcnt--;
   1631         if (0 == my_obj->buf_status[frame->buf_idx].buf_refcnt) {
   1632             CDBG("<DEBUG> : Buf done for buffer:%d:%d", my_obj->ext_image_mode, frame->buf_idx);
   1633             rc = mm_stream_qbuf(my_obj, frame);
   1634             if(rc < 0) {
   1635                 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
   1636                      __func__, frame->buf_idx, rc);
   1637             } else {
   1638                 my_obj->buf_status[frame->buf_idx].in_kernel = 1;
   1639             }
   1640         }else{
   1641             CDBG("<DEBUG> : Still ref count pending count :%d",
   1642                  my_obj->buf_status[frame->buf_idx].buf_refcnt);
   1643             CDBG("<DEBUG> : for buffer:%p:%d, ext_image_mode=%d",
   1644                  my_obj, frame->buf_idx, my_obj->ext_image_mode);
   1645         }
   1646     }
   1647     pthread_mutex_unlock(&my_obj->buf_lock);
   1648     return rc;
   1649 }
   1650 
   1651 int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
   1652                              mm_stream_data_cb_t *val)
   1653 {
   1654     int32_t rc = -1;
   1655     uint8_t i;
   1656     CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
   1657          "image_mode = %d, fd = %d, state = %d",
   1658          __func__, my_obj->inst_hdl, my_obj->my_hdl,
   1659          my_obj->ext_image_mode, my_obj->fd, my_obj->state);
   1660 
   1661     pthread_mutex_lock(&my_obj->cb_lock);
   1662     for (i=0 ;i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
   1663         if(NULL == my_obj->buf_cb[i].cb) {
   1664             memcpy(&my_obj->buf_cb[i], val, sizeof(mm_stream_data_cb_t));
   1665             rc = 0;
   1666             break;
   1667         }
   1668     }
   1669     pthread_mutex_unlock(&my_obj->cb_lock);
   1670 
   1671     return rc;
   1672 }
   1673