Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 
     30 #include <stdlib.h>
     31 #include <pthread.h>
     32 #include <errno.h>
     33 #include <sys/ioctl.h>
     34 #include <sys/types.h>
     35 #include <sys/stat.h>
     36 #include <fcntl.h>
     37 #include <poll.h>
     38 #include <time.h>
     39 #include <cam_semaphore.h>
     40 #ifdef VENUS_PRESENT
     41 #include <media/msm_media_info.h>
     42 #endif
     43 
     44 #include "mm_camera_dbg.h"
     45 #include "mm_camera_interface.h"
     46 #include "mm_camera.h"
     47 
     48 /* internal function decalre */
     49 int32_t mm_stream_qbuf(mm_stream_t *my_obj,
     50                        mm_camera_buf_def_t *buf);
     51 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj);
     52 int32_t mm_stream_set_fmt(mm_stream_t * my_obj);
     53 int32_t mm_stream_sync_info(mm_stream_t *my_obj);
     54 int32_t mm_stream_init_bufs(mm_stream_t * my_obj);
     55 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj);
     56 int32_t mm_stream_request_buf(mm_stream_t * my_obj);
     57 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj);
     58 int32_t mm_stream_release(mm_stream_t *my_obj);
     59 int32_t mm_stream_set_parm(mm_stream_t *my_obj,
     60                            cam_stream_parm_buffer_t *value);
     61 int32_t mm_stream_get_parm(mm_stream_t *my_obj,
     62                            cam_stream_parm_buffer_t *value);
     63 int32_t mm_stream_do_action(mm_stream_t *my_obj,
     64                             void *in_value);
     65 int32_t mm_stream_streamon(mm_stream_t *my_obj);
     66 int32_t mm_stream_streamoff(mm_stream_t *my_obj);
     67 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
     68                                  mm_camera_buf_info_t* buf_info,
     69                                  uint8_t num_planes);
     70 int32_t mm_stream_read_user_buf(mm_stream_t * my_obj,
     71         mm_camera_buf_info_t* buf_info);
     72 int32_t mm_stream_write_user_buf(mm_stream_t * my_obj,
     73         mm_camera_buf_def_t *buf);
     74 
     75 int32_t mm_stream_config(mm_stream_t *my_obj,
     76                          mm_camera_stream_config_t *config);
     77 int32_t mm_stream_reg_buf(mm_stream_t * my_obj);
     78 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
     79                            mm_camera_buf_def_t *frame);
     80 int32_t mm_stream_get_queued_buf_count(mm_stream_t * my_obj);
     81 
     82 int32_t mm_stream_calc_offset(mm_stream_t *my_obj);
     83 int32_t mm_stream_calc_offset_preview(cam_format_t fmt,
     84                                       cam_dimension_t *dim,
     85                                       cam_stream_buf_plane_info_t *buf_planes);
     86 int32_t mm_stream_calc_offset_post_view(cam_format_t fmt,
     87                                       cam_dimension_t *dim,
     88                                       cam_stream_buf_plane_info_t *buf_planes);
     89 
     90 int32_t mm_stream_calc_offset_snapshot(cam_format_t fmt,
     91                                        cam_dimension_t *dim,
     92                                        cam_padding_info_t *padding,
     93                                        cam_stream_buf_plane_info_t *buf_planes);
     94 int32_t mm_stream_calc_offset_raw(cam_format_t fmt,
     95                                   cam_dimension_t *dim,
     96                                   cam_padding_info_t *padding,
     97                                   cam_stream_buf_plane_info_t *buf_planes);
     98 int32_t mm_stream_calc_offset_video(cam_dimension_t *dim,
     99                                     cam_stream_buf_plane_info_t *buf_planes);
    100 int32_t mm_stream_calc_offset_metadata(cam_dimension_t *dim,
    101                                        cam_padding_info_t *padding,
    102                                        cam_stream_buf_plane_info_t *buf_planes);
    103 int32_t mm_stream_calc_offset_postproc(cam_stream_info_t *stream_info,
    104                                        cam_padding_info_t *padding,
    105                                        cam_stream_buf_plane_info_t *plns);
    106 
    107 
    108 /* state machine function declare */
    109 int32_t mm_stream_fsm_inited(mm_stream_t * my_obj,
    110                              mm_stream_evt_type_t evt,
    111                              void * in_val,
    112                              void * out_val);
    113 int32_t mm_stream_fsm_acquired(mm_stream_t * my_obj,
    114                                mm_stream_evt_type_t evt,
    115                                void * in_val,
    116                                void * out_val);
    117 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
    118                           mm_stream_evt_type_t evt,
    119                           void * in_val,
    120                           void * out_val);
    121 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
    122                              mm_stream_evt_type_t evt,
    123                              void * in_val,
    124                              void * out_val);
    125 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
    126                           mm_stream_evt_type_t evt,
    127                           void * in_val,
    128                           void * out_val);
    129 int32_t mm_stream_fsm_active(mm_stream_t * my_obj,
    130                              mm_stream_evt_type_t evt,
    131                              void * in_val,
    132                              void * out_val);
    133 uint32_t mm_stream_get_v4l2_fmt(cam_format_t fmt);
    134 
    135 
    136 /*===========================================================================
    137  * FUNCTION   : mm_stream_notify_channel
    138  *
    139  * DESCRIPTION: function to notify channel object on received buffer
    140  *
    141  * PARAMETERS :
    142  *   @ch_obj  : channel object
    143  *   @buf_info: ptr to struct storing buffer information
    144  *
    145  * RETURN     : int32_t type of status
    146  *              0  -- success
    147  *              0> -- failure
    148  *==========================================================================*/
    149 int32_t mm_stream_notify_channel(struct mm_channel* ch_obj,
    150         mm_camera_buf_info_t *buf_info)
    151 {
    152     int32_t rc = 0;
    153     mm_camera_cmdcb_t* node = NULL;
    154 
    155     if ((NULL == ch_obj) || (NULL == buf_info)) {
    156         CDBG_ERROR("%s : Invalid channel/buffer", __func__);
    157         return -ENODEV;
    158     }
    159 
    160     /* send cam_sem_post to wake up channel cmd thread to enqueue
    161      * to super buffer */
    162     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    163     if (NULL != node) {
    164         memset(node, 0, sizeof(mm_camera_cmdcb_t));
    165         node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
    166         node->u.buf = *buf_info;
    167 
    168         /* enqueue to cmd thread */
    169         cam_queue_enq(&(ch_obj->cmd_thread.cmd_queue), node);
    170 
    171         /* wake up cmd thread */
    172         cam_sem_post(&(ch_obj->cmd_thread.cmd_sem));
    173     } else {
    174         CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
    175         rc = -ENOMEM;
    176     }
    177 
    178     return rc;
    179 }
    180 
    181 /*===========================================================================
    182  * FUNCTION   : mm_stream_handle_rcvd_buf
    183  *
    184  * DESCRIPTION: function to handle newly received stream buffer
    185  *
    186  * PARAMETERS :
    187  *   @cam_obj : stream object
    188  *   @buf_info: ptr to struct storing buffer information
    189  *
    190  * RETURN     : none
    191  *==========================================================================*/
    192 void mm_stream_handle_rcvd_buf(mm_stream_t *my_obj,
    193                                mm_camera_buf_info_t *buf_info,
    194                                uint8_t has_cb)
    195 {
    196     int32_t rc = 0;
    197     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    198          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    199 
    200     /* enqueue to super buf thread */
    201     if (my_obj->is_bundled) {
    202         rc = mm_stream_notify_channel(my_obj->ch_obj, buf_info);
    203         if (rc < 0) {
    204             CDBG_ERROR("%s: Unable to notify channel", __func__);
    205         }
    206     }
    207 
    208     pthread_mutex_lock(&my_obj->buf_lock);
    209     if(my_obj->is_linked) {
    210         /* need to add into super buf for linking, add ref count */
    211         my_obj->buf_status[buf_info->buf->buf_idx].buf_refcnt++;
    212 
    213         rc = mm_stream_notify_channel(my_obj->linked_obj, buf_info);
    214         if (rc < 0) {
    215             CDBG_ERROR("%s: Unable to notify channel", __func__);
    216         }
    217     }
    218     pthread_mutex_unlock(&my_obj->buf_lock);
    219 
    220     if(has_cb) {
    221         mm_camera_cmdcb_t* node = NULL;
    222 
    223         /* send cam_sem_post to wake up cmd thread to dispatch dataCB */
    224         node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    225         if (NULL != node) {
    226             memset(node, 0, sizeof(mm_camera_cmdcb_t));
    227             node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
    228             node->u.buf = *buf_info;
    229 
    230             /* enqueue to cmd thread */
    231             cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node);
    232 
    233             /* wake up cmd thread */
    234             cam_sem_post(&(my_obj->cmd_thread.cmd_sem));
    235         } else {
    236             CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
    237         }
    238     }
    239 }
    240 
    241 /*===========================================================================
    242  * FUNCTION   : mm_stream_data_notify
    243  *
    244  * DESCRIPTION: callback to handle data notify from kernel
    245  *
    246  * PARAMETERS :
    247  *   @user_data : user data ptr (stream object)
    248  *
    249  * RETURN     : none
    250  *==========================================================================*/
    251 static void mm_stream_data_notify(void* user_data)
    252 {
    253     mm_stream_t *my_obj = (mm_stream_t*)user_data;
    254     int32_t i, rc;
    255     uint8_t has_cb = 0, length = 0;
    256     mm_camera_buf_info_t buf_info;
    257 
    258     if (NULL == my_obj) {
    259         return;
    260     }
    261 
    262     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    263          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    264     if (MM_STREAM_STATE_ACTIVE != my_obj->state) {
    265         /* this Cb will only received in active_stream_on state
    266          * if not so, return here */
    267         CDBG_ERROR("%s: ERROR!! Wrong state (%d) to receive data notify!",
    268                    __func__, my_obj->state);
    269         return;
    270     }
    271 
    272     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
    273         length = 1;
    274     } else {
    275         length = my_obj->frame_offset.num_planes;
    276     }
    277 
    278     memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
    279     rc = mm_stream_read_msm_frame(my_obj, &buf_info,
    280         (uint8_t)length);
    281     if (rc != 0) {
    282         return;
    283     }
    284     uint32_t idx = buf_info.buf->buf_idx;
    285 
    286     pthread_mutex_lock(&my_obj->cb_lock);
    287     for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    288         if(NULL != my_obj->buf_cb[i].cb) {
    289             /* for every CB, add ref count */
    290             has_cb = 1;
    291             break;
    292         }
    293     }
    294     pthread_mutex_unlock(&my_obj->cb_lock);
    295 
    296     pthread_mutex_lock(&my_obj->buf_lock);
    297     /* update buffer location */
    298     my_obj->buf_status[idx].in_kernel = 0;
    299 
    300     /* update buf ref count */
    301     if (my_obj->is_bundled) {
    302         /* need to add into super buf since bundled, add ref count */
    303         my_obj->buf_status[idx].buf_refcnt++;
    304     }
    305     my_obj->buf_status[idx].buf_refcnt =
    306         (uint8_t)(my_obj->buf_status[idx].buf_refcnt + has_cb);
    307     pthread_mutex_unlock(&my_obj->buf_lock);
    308 
    309     mm_stream_handle_rcvd_buf(my_obj, &buf_info, has_cb);
    310 }
    311 
    312 /*===========================================================================
    313  * FUNCTION   : mm_stream_dispatch_app_data
    314  *
    315  * DESCRIPTION: dispatch stream buffer to registered users
    316  *
    317  * PARAMETERS :
    318  *   @cmd_cb  : ptr storing stream buffer information
    319  *   @userdata: user data ptr (stream object)
    320  *
    321  * RETURN     : none
    322  *==========================================================================*/
    323 static void mm_stream_dispatch_app_data(mm_camera_cmdcb_t *cmd_cb,
    324                                         void* user_data)
    325 {
    326     int i;
    327     mm_stream_t * my_obj = (mm_stream_t *)user_data;
    328     mm_camera_buf_info_t* buf_info = NULL;
    329     mm_camera_super_buf_t super_buf;
    330     mm_camera_cmd_thread_name("mm_cam_stream");
    331 
    332     if (NULL == my_obj) {
    333         return;
    334     }
    335     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    336          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    337 
    338     if (MM_CAMERA_CMD_TYPE_DATA_CB != cmd_cb->cmd_type) {
    339         CDBG_ERROR("%s: Wrong cmd_type (%d) for dataCB",
    340                    __func__, cmd_cb->cmd_type);
    341         return;
    342     }
    343 
    344     buf_info = &cmd_cb->u.buf;
    345     memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
    346     super_buf.num_bufs = 1;
    347     super_buf.bufs[0] = buf_info->buf;
    348     super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
    349     super_buf.ch_id = my_obj->ch_obj->my_hdl;
    350 
    351     pthread_mutex_lock(&my_obj->cb_lock);
    352     for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    353         if(NULL != my_obj->buf_cb[i].cb) {
    354             if (my_obj->buf_cb[i].cb_count != 0) {
    355                 /* if <0, means infinite CB
    356                  * if >0, means CB for certain times
    357                  * both case we need to call CB */
    358 
    359                 /* increase buf ref cnt */
    360                 pthread_mutex_lock(&my_obj->buf_lock);
    361                 my_obj->buf_status[buf_info->buf->buf_idx].buf_refcnt++;
    362                 pthread_mutex_unlock(&my_obj->buf_lock);
    363 
    364                 /* callback */
    365                 my_obj->buf_cb[i].cb(&super_buf,
    366                                      my_obj->buf_cb[i].user_data);
    367             }
    368 
    369             /* if >0, reduce count by 1 every time we called CB until reaches 0
    370              * when count reach 0, reset the buf_cb to have no CB */
    371             if (my_obj->buf_cb[i].cb_count > 0) {
    372                 my_obj->buf_cb[i].cb_count--;
    373                 if (0 == my_obj->buf_cb[i].cb_count) {
    374                     my_obj->buf_cb[i].cb = NULL;
    375                     my_obj->buf_cb[i].user_data = NULL;
    376                 }
    377             }
    378         }
    379     }
    380     pthread_mutex_unlock(&my_obj->cb_lock);
    381 
    382     /* do buf_done since we increased refcnt by one when has_cb */
    383     mm_stream_buf_done(my_obj, buf_info->buf);
    384 }
    385 
    386 /*===========================================================================
    387  * FUNCTION   : mm_stream_fsm_fn
    388  *
    389  * DESCRIPTION: stream finite state machine entry function. Depends on stream
    390  *              state, incoming event will be handled differently.
    391  *
    392  * PARAMETERS :
    393  *   @my_obj   : ptr to a stream object
    394  *   @evt      : stream event to be processed
    395  *   @in_val   : input event payload. Can be NULL if not needed.
    396  *   @out_val  : output payload, Can be NULL if not needed.
    397  *
    398  * RETURN     : int32_t type of status
    399  *              0  -- success
    400  *              -1 -- failure
    401  *==========================================================================*/
    402 int32_t mm_stream_fsm_fn(mm_stream_t *my_obj,
    403                          mm_stream_evt_type_t evt,
    404                          void * in_val,
    405                          void * out_val)
    406 {
    407     int32_t rc = -1;
    408 
    409     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    410          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    411     switch (my_obj->state) {
    412     case MM_STREAM_STATE_NOTUSED:
    413         CDBG("%s: Not handling evt in unused state", __func__);
    414         break;
    415     case MM_STREAM_STATE_INITED:
    416         rc = mm_stream_fsm_inited(my_obj, evt, in_val, out_val);
    417         break;
    418     case MM_STREAM_STATE_ACQUIRED:
    419         rc = mm_stream_fsm_acquired(my_obj, evt, in_val, out_val);
    420         break;
    421     case MM_STREAM_STATE_CFG:
    422         rc = mm_stream_fsm_cfg(my_obj, evt, in_val, out_val);
    423         break;
    424     case MM_STREAM_STATE_BUFFED:
    425         rc = mm_stream_fsm_buffed(my_obj, evt, in_val, out_val);
    426         break;
    427     case MM_STREAM_STATE_REG:
    428         rc = mm_stream_fsm_reg(my_obj, evt, in_val, out_val);
    429         break;
    430     case MM_STREAM_STATE_ACTIVE:
    431         rc = mm_stream_fsm_active(my_obj, evt, in_val, out_val);
    432         break;
    433     default:
    434         CDBG("%s: Not a valid state (%d)", __func__, my_obj->state);
    435         break;
    436     }
    437     CDBG("%s : X rc =%d",__func__,rc);
    438     return rc;
    439 }
    440 
    441 /*===========================================================================
    442  * FUNCTION   : mm_stream_fsm_inited
    443  *
    444  * DESCRIPTION: stream finite state machine function to handle event in INITED
    445  *              state.
    446  *
    447  * PARAMETERS :
    448  *   @my_obj   : ptr to a stream object
    449  *   @evt      : stream event to be processed
    450  *   @in_val   : input event payload. Can be NULL if not needed.
    451  *   @out_val  : output payload, Can be NULL if not needed.
    452  *
    453  * RETURN     : int32_t type of status
    454  *              0  -- success
    455  *              -1 -- failure
    456  *==========================================================================*/
    457 int32_t mm_stream_fsm_inited(mm_stream_t *my_obj,
    458                              mm_stream_evt_type_t evt,
    459                              void * in_val,
    460                              void * out_val)
    461 {
    462     int32_t rc = 0;
    463     char dev_name[MM_CAMERA_DEV_NAME_LEN];
    464     const char *dev_name_value = NULL;
    465     if (NULL == my_obj) {
    466       CDBG_ERROR("%s: NULL camera object\n", __func__);
    467       return -1;
    468     }
    469 
    470     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    471          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    472     switch(evt) {
    473     case MM_STREAM_EVT_ACQUIRE:
    474         if ((NULL == my_obj->ch_obj) || (NULL == my_obj->ch_obj->cam_obj)) {
    475             CDBG_ERROR("%s: NULL channel or camera obj\n", __func__);
    476             rc = -1;
    477             break;
    478         }
    479 
    480         dev_name_value = mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl);
    481         if (NULL == dev_name_value) {
    482             CDBG_ERROR("%s: NULL device name\n", __func__);
    483             rc = -1;
    484             break;
    485         }
    486 
    487         dev_name_value = mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl);
    488         if (NULL == dev_name_value) {
    489             CDBG_ERROR("%s: NULL device name\n", __func__);
    490             rc = -1;
    491             break;
    492         }
    493         snprintf(dev_name, sizeof(dev_name), "/dev/%s",
    494                  dev_name_value);
    495 
    496         my_obj->fd = open(dev_name, O_RDWR | O_NONBLOCK);
    497         if (my_obj->fd < 0) {
    498             CDBG_ERROR("%s: open dev returned %d\n", __func__, my_obj->fd);
    499             rc = -1;
    500             break;
    501         }
    502         CDBG("%s: open dev fd = %d\n", __func__, my_obj->fd);
    503         rc = mm_stream_set_ext_mode(my_obj);
    504         if (0 == rc) {
    505             my_obj->state = MM_STREAM_STATE_ACQUIRED;
    506         } else {
    507             /* failed setting ext_mode
    508              * close fd */
    509             close(my_obj->fd);
    510             my_obj->fd = -1;
    511             break;
    512         }
    513         break;
    514     default:
    515         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    516                    __func__, my_obj->state, evt, in_val, out_val);
    517         break;
    518     }
    519     return rc;
    520 }
    521 
    522 /*===========================================================================
    523  * FUNCTION   : mm_stream_fsm_acquired
    524  *
    525  * DESCRIPTION: stream finite state machine function to handle event in AQUIRED
    526  *              state.
    527  *
    528  * PARAMETERS :
    529  *   @my_obj   : ptr to a stream object
    530  *   @evt      : stream event to be processed
    531  *   @in_val   : input event payload. Can be NULL if not needed.
    532  *   @out_val  : output payload, Can be NULL if not needed.
    533  *
    534  * RETURN     : int32_t type of status
    535  *              0  -- success
    536  *              -1 -- failure
    537  *==========================================================================*/
    538 int32_t mm_stream_fsm_acquired(mm_stream_t *my_obj,
    539                                mm_stream_evt_type_t evt,
    540                                void * in_val,
    541                                void * out_val)
    542 {
    543     int32_t rc = 0;
    544 
    545     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    546          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    547     switch(evt) {
    548     case MM_STREAM_EVT_SET_FMT:
    549         {
    550             mm_camera_stream_config_t *config =
    551                 (mm_camera_stream_config_t *)in_val;
    552 
    553             rc = mm_stream_config(my_obj, config);
    554 
    555             /* change state to configed */
    556             my_obj->state = MM_STREAM_STATE_CFG;
    557 
    558             break;
    559         }
    560     case MM_STREAM_EVT_RELEASE:
    561         rc = mm_stream_release(my_obj);
    562         /* change state to not used */
    563          my_obj->state = MM_STREAM_STATE_NOTUSED;
    564         break;
    565     case MM_STREAM_EVT_SET_PARM:
    566         {
    567             mm_evt_paylod_set_get_stream_parms_t *payload =
    568                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    569             rc = mm_stream_set_parm(my_obj, payload->parms);
    570         }
    571         break;
    572     case MM_STREAM_EVT_GET_PARM:
    573         {
    574             mm_evt_paylod_set_get_stream_parms_t *payload =
    575                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    576             rc = mm_stream_get_parm(my_obj, payload->parms);
    577         }
    578         break;
    579     default:
    580         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    581                    __func__, my_obj->state, evt, in_val, out_val);
    582     }
    583     CDBG("%s :X rc = %d", __func__, rc);
    584     return rc;
    585 }
    586 
    587 /*===========================================================================
    588  * FUNCTION   : mm_stream_fsm_cfg
    589  *
    590  * DESCRIPTION: stream finite state machine function to handle event in CONFIGURED
    591  *              state.
    592  *
    593  * PARAMETERS :
    594  *   @my_obj   : ptr to a stream object
    595  *   @evt      : stream event to be processed
    596  *   @in_val   : input event payload. Can be NULL if not needed.
    597  *   @out_val  : output payload, Can be NULL if not needed.
    598  *
    599  * RETURN     : int32_t type of status
    600  *              0  -- success
    601  *              -1 -- failure
    602  *==========================================================================*/
    603 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
    604                           mm_stream_evt_type_t evt,
    605                           void * in_val,
    606                           void * out_val)
    607 {
    608     int32_t rc = 0;
    609     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    610          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    611     switch(evt) {
    612     case MM_STREAM_EVT_SET_FMT:
    613         {
    614             mm_camera_stream_config_t *config =
    615                 (mm_camera_stream_config_t *)in_val;
    616 
    617             rc = mm_stream_config(my_obj, config);
    618 
    619             /* change state to configed */
    620             my_obj->state = MM_STREAM_STATE_CFG;
    621 
    622             break;
    623         }
    624     case MM_STREAM_EVT_RELEASE:
    625         rc = mm_stream_release(my_obj);
    626         my_obj->state = MM_STREAM_STATE_NOTUSED;
    627         break;
    628     case MM_STREAM_EVT_SET_PARM:
    629         {
    630             mm_evt_paylod_set_get_stream_parms_t *payload =
    631                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    632             rc = mm_stream_set_parm(my_obj, payload->parms);
    633         }
    634         break;
    635     case MM_STREAM_EVT_GET_PARM:
    636         {
    637             mm_evt_paylod_set_get_stream_parms_t *payload =
    638                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    639             rc = mm_stream_get_parm(my_obj, payload->parms);
    640         }
    641         break;
    642     case MM_STREAM_EVT_GET_BUF:
    643         rc = mm_stream_init_bufs(my_obj);
    644         /* change state to buff allocated */
    645         if(0 == rc) {
    646             my_obj->state = MM_STREAM_STATE_BUFFED;
    647         }
    648         break;
    649     default:
    650         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    651                    __func__, my_obj->state, evt, in_val, out_val);
    652     }
    653     CDBG("%s :X rc = %d", __func__, rc);
    654     return rc;
    655 }
    656 
    657 /*===========================================================================
    658  * FUNCTION   : mm_stream_fsm_buffed
    659  *
    660  * DESCRIPTION: stream finite state machine function to handle event in BUFFED
    661  *              state.
    662  *
    663  * PARAMETERS :
    664  *   @my_obj   : ptr to a stream object
    665  *   @evt      : stream event to be processed
    666  *   @in_val   : input event payload. Can be NULL if not needed.
    667  *   @out_val  : output payload, Can be NULL if not needed.
    668  *
    669  * RETURN     : int32_t type of status
    670  *              0  -- success
    671  *              -1 -- failure
    672  *==========================================================================*/
    673 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
    674                              mm_stream_evt_type_t evt,
    675                              void * in_val,
    676                              void * out_val)
    677 {
    678     int32_t rc = 0;
    679     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    680          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    681     switch(evt) {
    682     case MM_STREAM_EVT_PUT_BUF:
    683         rc = mm_stream_deinit_bufs(my_obj);
    684         /* change state to configed */
    685         my_obj->state = MM_STREAM_STATE_CFG;
    686         break;
    687     case MM_STREAM_EVT_REG_BUF:
    688         rc = mm_stream_reg_buf(my_obj);
    689         /* change state to regged */
    690         if(0 == rc) {
    691             my_obj->state = MM_STREAM_STATE_REG;
    692         }
    693         break;
    694     case MM_STREAM_EVT_SET_PARM:
    695         {
    696             mm_evt_paylod_set_get_stream_parms_t *payload =
    697                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    698             rc = mm_stream_set_parm(my_obj, payload->parms);
    699         }
    700         break;
    701     case MM_STREAM_EVT_GET_PARM:
    702         {
    703             mm_evt_paylod_set_get_stream_parms_t *payload =
    704                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    705             rc = mm_stream_get_parm(my_obj, payload->parms);
    706         }
    707         break;
    708     default:
    709         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    710                    __func__, my_obj->state, evt, in_val, out_val);
    711     }
    712     CDBG("%s :X rc = %d", __func__, rc);
    713     return rc;
    714 }
    715 
    716 /*===========================================================================
    717  * FUNCTION   : mm_stream_fsm_reg
    718  *
    719  * DESCRIPTION: stream finite state machine function to handle event in REGGED
    720  *              state.
    721  *
    722  * PARAMETERS :
    723  *   @my_obj   : ptr to a stream object
    724  *   @evt      : stream event to be processed
    725  *   @in_val   : input event payload. Can be NULL if not needed.
    726  *   @out_val  : output payload, Can be NULL if not needed.
    727  *
    728  * RETURN     : int32_t type of status
    729  *              0  -- success
    730  *              -1 -- failure
    731  *==========================================================================*/
    732 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
    733                           mm_stream_evt_type_t evt,
    734                           void * in_val,
    735                           void * out_val)
    736 {
    737     int32_t rc = 0;
    738     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    739          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    740 
    741     switch(evt) {
    742     case MM_STREAM_EVT_UNREG_BUF:
    743         rc = mm_stream_unreg_buf(my_obj);
    744 
    745         /* change state to buffed */
    746         my_obj->state = MM_STREAM_STATE_BUFFED;
    747         break;
    748     case MM_STREAM_EVT_START:
    749         {
    750             uint8_t has_cb = 0;
    751             uint8_t i;
    752             /* launch cmd thread if CB is not null */
    753             pthread_mutex_lock(&my_obj->cb_lock);
    754             for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    755                 if(NULL != my_obj->buf_cb[i].cb) {
    756                     has_cb = 1;
    757                     break;
    758                 }
    759             }
    760             pthread_mutex_unlock(&my_obj->cb_lock);
    761 
    762             if (has_cb) {
    763                 snprintf(my_obj->cmd_thread.threadName, THREAD_NAME_SIZE, "CAM_StrmAppData");
    764                 mm_camera_cmd_thread_launch(&my_obj->cmd_thread,
    765                                             mm_stream_dispatch_app_data,
    766                                             (void *)my_obj);
    767             }
    768 
    769             my_obj->state = MM_STREAM_STATE_ACTIVE;
    770             rc = mm_stream_streamon(my_obj);
    771             if (0 != rc) {
    772                 /* failed stream on, need to release cmd thread if it's launched */
    773                 if (has_cb) {
    774                     mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    775                 }
    776                 my_obj->state = MM_STREAM_STATE_REG;
    777                 break;
    778             }
    779         }
    780         break;
    781     case MM_STREAM_EVT_SET_PARM:
    782         {
    783             mm_evt_paylod_set_get_stream_parms_t *payload =
    784                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    785             rc = mm_stream_set_parm(my_obj, payload->parms);
    786         }
    787         break;
    788     case MM_STREAM_EVT_GET_PARM:
    789         {
    790             mm_evt_paylod_set_get_stream_parms_t *payload =
    791                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    792             rc = mm_stream_get_parm(my_obj, payload->parms);
    793         }
    794         break;
    795     default:
    796         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    797                    __func__, my_obj->state, evt, in_val, out_val);
    798     }
    799     CDBG("%s :X rc = %d", __func__, rc);
    800     return rc;
    801 }
    802 
    803 /*===========================================================================
    804  * FUNCTION   : mm_stream_fsm_active
    805  *
    806  * DESCRIPTION: stream finite state machine function to handle event in ACTIVE
    807  *              state.
    808  *
    809  * PARAMETERS :
    810  *   @my_obj   : ptr to a stream object
    811  *   @evt      : stream event to be processed
    812  *   @in_val   : input event payload. Can be NULL if not needed.
    813  *   @out_val  : output payload, Can be NULL if not needed.
    814  *
    815  * RETURN     : int32_t type of status
    816  *              0  -- success
    817  *              -1 -- failure
    818  *==========================================================================*/
    819 int32_t mm_stream_fsm_active(mm_stream_t * my_obj,
    820                              mm_stream_evt_type_t evt,
    821                              void * in_val,
    822                              void * out_val)
    823 {
    824     int32_t rc = 0;
    825     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    826          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    827     switch(evt) {
    828     case MM_STREAM_EVT_QBUF:
    829         rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
    830         break;
    831     case MM_STREAM_EVT_GET_QUEUED_BUF_COUNT:
    832         rc = mm_stream_get_queued_buf_count(my_obj);
    833         break;
    834     case MM_STREAM_EVT_STOP:
    835         {
    836             uint8_t has_cb = 0;
    837             uint8_t i;
    838             rc = mm_stream_streamoff(my_obj);
    839 
    840             pthread_mutex_lock(&my_obj->cb_lock);
    841             for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    842                 if(NULL != my_obj->buf_cb[i].cb) {
    843                     has_cb = 1;
    844                     break;
    845                 }
    846             }
    847             pthread_mutex_unlock(&my_obj->cb_lock);
    848 
    849             if (has_cb) {
    850                 mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    851             }
    852             my_obj->state = MM_STREAM_STATE_REG;
    853         }
    854         break;
    855     case MM_STREAM_EVT_SET_PARM:
    856         {
    857             mm_evt_paylod_set_get_stream_parms_t *payload =
    858                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    859             rc = mm_stream_set_parm(my_obj, payload->parms);
    860         }
    861         break;
    862     case MM_STREAM_EVT_GET_PARM:
    863         {
    864             mm_evt_paylod_set_get_stream_parms_t *payload =
    865                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    866             rc = mm_stream_get_parm(my_obj, payload->parms);
    867         }
    868         break;
    869     case MM_STREAM_EVT_DO_ACTION:
    870         rc = mm_stream_do_action(my_obj, in_val);
    871         break;
    872     default:
    873         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    874                    __func__, my_obj->state, evt, in_val, out_val);
    875     }
    876     CDBG("%s :X rc = %d", __func__, rc);
    877     return rc;
    878 }
    879 
    880 /*===========================================================================
    881  * FUNCTION   : mm_stream_config
    882  *
    883  * DESCRIPTION: configure a stream
    884  *
    885  * PARAMETERS :
    886  *   @my_obj       : stream object
    887  *   @config       : stream configuration
    888  *
    889  * RETURN     : int32_t type of status
    890  *              0  -- success
    891  *              -1 -- failure
    892  *==========================================================================*/
    893 int32_t mm_stream_config(mm_stream_t *my_obj,
    894                          mm_camera_stream_config_t *config)
    895 {
    896     int32_t rc = 0;
    897     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    898          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    899     my_obj->stream_info = config->stream_info;
    900     my_obj->buf_num = (uint8_t) config->stream_info->num_bufs;
    901     my_obj->mem_vtbl = config->mem_vtbl;
    902     my_obj->padding_info = config->padding_info;
    903     /* cd through intf always palced at idx 0 of buf_cb */
    904     my_obj->buf_cb[0].cb = config->stream_cb;
    905     my_obj->buf_cb[0].user_data = config->userdata;
    906     my_obj->buf_cb[0].cb_count = -1; /* infinite by default */
    907 
    908     rc = mm_stream_sync_info(my_obj);
    909     if (rc == 0) {
    910         rc = mm_stream_set_fmt(my_obj);
    911     }
    912     return rc;
    913 }
    914 
    915 /*===========================================================================
    916  * FUNCTION   : mm_stream_release
    917  *
    918  * DESCRIPTION: release a stream resource
    919  *
    920  * PARAMETERS :
    921  *   @my_obj       : stream object
    922  *
    923  * RETURN     : int32_t type of status
    924  *              0  -- success
    925  *              -1 -- failure
    926  *==========================================================================*/
    927 int32_t mm_stream_release(mm_stream_t *my_obj)
    928 {
    929     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    930          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    931 
    932     /* close fd */
    933     if(my_obj->fd >= 0)
    934     {
    935         close(my_obj->fd);
    936     }
    937 
    938     /* destroy mutex */
    939     pthread_mutex_destroy(&my_obj->buf_lock);
    940     pthread_mutex_destroy(&my_obj->cb_lock);
    941 
    942     /* reset stream obj */
    943     memset(my_obj, 0, sizeof(mm_stream_t));
    944     my_obj->fd = -1;
    945 
    946     return 0;
    947 }
    948 
    949 /*===========================================================================
    950  * FUNCTION   : mm_stream_streamon
    951  *
    952  * DESCRIPTION: stream on a stream. sending v4l2 request to kernel
    953  *
    954  * PARAMETERS :
    955  *   @my_obj       : stream object
    956  *
    957  * RETURN     : int32_t type of status
    958  *              0  -- success
    959  *              -1 -- failure
    960  *==========================================================================*/
    961 int32_t mm_stream_streamon(mm_stream_t *my_obj)
    962 {
    963     int32_t rc;
    964     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    965 
    966     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    967          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    968 
    969     rc = ioctl(my_obj->fd, VIDIOC_STREAMON, &buf_type);
    970     if (rc < 0) {
    971         CDBG_ERROR("%s: ioctl VIDIOC_STREAMON failed: rc=%d\n",
    972                    __func__, rc);
    973         /* remove fd from data poll thread in case of failure */
    974         mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl, mm_camera_sync_call);
    975     }
    976     CDBG("%s :X rc = %d",__func__,rc);
    977     return rc;
    978 }
    979 
    980 /*===========================================================================
    981  * FUNCTION   : mm_stream_streamoff
    982  *
    983  * DESCRIPTION: stream off a stream. sending v4l2 request to kernel
    984  *
    985  * PARAMETERS :
    986  *   @my_obj       : stream object
    987  *
    988  * RETURN     : int32_t type of status
    989  *              0  -- success
    990  *              -1 -- failure
    991  *==========================================================================*/
    992 int32_t mm_stream_streamoff(mm_stream_t *my_obj)
    993 {
    994     int32_t rc;
    995     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    996     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    997          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    998 
    999     /* step1: remove fd from data poll thread */
   1000     rc = mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1001             my_obj->my_hdl, mm_camera_sync_call);
   1002     if (rc < 0) {
   1003         /* The error might be due to async update. In this case
   1004          * wait for all updates to complete before proceeding. */
   1005         rc = mm_camera_poll_thread_commit_updates(&my_obj->ch_obj->poll_thread[0]);
   1006         if (rc < 0) {
   1007             CDBG_ERROR("%s: Poll sync failed %d",
   1008                  __func__, rc);
   1009         }
   1010     }
   1011 
   1012     /* step2: stream off */
   1013     rc = ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type);
   1014     if (rc < 0) {
   1015         CDBG_ERROR("%s: STREAMOFF failed: %s\n",
   1016                 __func__, strerror(errno));
   1017     }
   1018     CDBG("%s :X rc = %d",__func__,rc);
   1019     return rc;
   1020 }
   1021 
   1022 /*===========================================================================
   1023  * FUNCTION   : mm_stream_write_user_buf
   1024  *
   1025  * DESCRIPTION: dequeue a stream buffer from user buffer queue and fill internal structure
   1026  *
   1027  * PARAMETERS :
   1028  *   @my_obj       : stream object
   1029  *   @buf     : ptr to a struct storing buffer information
   1030  *
   1031  * RETURN     : int32_t type of status
   1032  *              0  -- success
   1033  *              -1 -- failure
   1034  *==========================================================================*/
   1035 int32_t mm_stream_write_user_buf(mm_stream_t * my_obj,
   1036         mm_camera_buf_def_t *buf)
   1037 {
   1038     int32_t rc = 0, i;
   1039     int32_t index = -1, count = 0;
   1040     struct msm_camera_user_buf_cont_t *cont_buf = NULL;
   1041 
   1042     if (buf->buf_type == CAM_STREAM_BUF_TYPE_USERPTR) {
   1043         my_obj->buf_status[buf->buf_idx].buf_refcnt--;
   1044         if (0 == my_obj->buf_status[buf->buf_idx].buf_refcnt) {
   1045             cont_buf = (struct msm_camera_user_buf_cont_t *)my_obj->buf[buf->buf_idx].buffer;
   1046             cont_buf->buf_cnt = my_obj->buf[buf->buf_idx].user_buf.bufs_used;
   1047             for (i = 0; i < (int32_t)cont_buf->buf_cnt; i++) {
   1048                 cont_buf->buf_idx[i] = my_obj->buf[buf->buf_idx].user_buf.buf_idx[i];
   1049             }
   1050             rc = mm_stream_qbuf(my_obj, buf);
   1051             if(rc < 0) {
   1052                 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
   1053                            __func__, buf->buf_idx, rc);
   1054             } else {
   1055                 for (i = 0; i < (int32_t)cont_buf->buf_cnt; i++) {
   1056                     my_obj->buf[buf->buf_idx].user_buf.buf_idx[i] = -1;
   1057                 }
   1058                 my_obj->buf_status[buf->buf_idx].in_kernel = 1;
   1059                 my_obj->buf[buf->buf_idx].user_buf.buf_in_use = 1;
   1060             }
   1061         } else {
   1062             CDBG("<DEBUG> : ref count pending count :%d idx = %d",
   1063                  my_obj->buf_status[buf->buf_idx].buf_refcnt, buf->buf_idx);
   1064         }
   1065         return rc;
   1066     }
   1067 
   1068     if ((my_obj->cur_buf_idx < 0)
   1069             || (my_obj->cur_buf_idx >= my_obj->buf_num)) {
   1070         for (i = 0; i < my_obj->buf_num; i++) {
   1071             if ((my_obj->buf_status[i].in_kernel)
   1072                     || (my_obj->buf[i].user_buf.buf_in_use)) {
   1073                 continue;
   1074             }
   1075 
   1076             my_obj->cur_buf_idx = index = i;
   1077             break;
   1078         }
   1079     } else {
   1080         index = my_obj->cur_buf_idx;
   1081     }
   1082 
   1083     if (index == -1) {
   1084         CDBG_ERROR("%s: No Free batch buffer", __func__);
   1085         rc = -1;
   1086         return rc;
   1087     }
   1088 
   1089     //Insert Buffer to Batch structure.
   1090     my_obj->buf[index].user_buf.buf_idx[count] = buf->buf_idx;
   1091     my_obj->cur_bufs_staged++;
   1092 
   1093     CDBG("%s index = %d filled = %d used = %d", __func__,
   1094             index,
   1095             my_obj->cur_bufs_staged,
   1096             my_obj->buf[index].user_buf.bufs_used);
   1097 
   1098     if (my_obj->cur_bufs_staged
   1099             == my_obj->buf[index].user_buf.bufs_used){
   1100         my_obj->buf_status[index].buf_refcnt--;
   1101         if (0 == my_obj->buf_status[index].buf_refcnt) {
   1102             cont_buf = (struct msm_camera_user_buf_cont_t *)my_obj->buf[index].buffer;
   1103             cont_buf->buf_cnt = my_obj->buf[index].user_buf.bufs_used;
   1104             for (i = 0; i < (int32_t)cont_buf->buf_cnt; i++) {
   1105                 cont_buf->buf_idx[i] = my_obj->buf[index].user_buf.buf_idx[i];
   1106             }
   1107             rc = mm_stream_qbuf(my_obj, &my_obj->buf[index]);
   1108             if(rc < 0) {
   1109                 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
   1110                            __func__, index, rc);
   1111             } else {
   1112                 for (i = 0; i < (int32_t)cont_buf->buf_cnt; i++) {
   1113                     my_obj->buf[index].user_buf.buf_idx[i] = -1;
   1114                 }
   1115                 my_obj->buf_status[index].in_kernel = 1;
   1116                 my_obj->buf[index].user_buf.buf_in_use = 1;
   1117                 my_obj->cur_bufs_staged = 0;
   1118                 my_obj->cur_buf_idx = -1;
   1119             }
   1120         }else{
   1121             CDBG("<DEBUG> : ref count pending count :%d idx = %d",
   1122                  my_obj->buf_status[index].buf_refcnt, index);
   1123         }
   1124     }
   1125 
   1126     return rc;
   1127 }
   1128 
   1129 /*===========================================================================
   1130  * FUNCTION   : mm_stream_read_user_buf
   1131  *
   1132  * DESCRIPTION: dequeue a stream buffer from user buffer queue and fill internal structure
   1133  *
   1134  * PARAMETERS :
   1135  *   @my_obj       : stream object
   1136  *   @buf_info     : ptr to a struct storing buffer information
   1137  *
   1138  * RETURN     : int32_t type of status
   1139  *              0  -- success
   1140  *              -1 -- failure
   1141  *==========================================================================*/
   1142 int32_t mm_stream_read_user_buf(mm_stream_t * my_obj,
   1143         mm_camera_buf_info_t* buf_info)
   1144 {
   1145     int32_t rc = 0, i;
   1146     mm_camera_buf_def_t *stream_buf  = NULL;
   1147     struct msm_camera_user_buf_cont_t *user_buf = NULL;
   1148     nsecs_t interval_nsec = 0, frame_ts = 0, timeStamp = 0;
   1149     int ts_delta = 0;
   1150     uint32_t frameID = 0;
   1151 
   1152     user_buf = (struct msm_camera_user_buf_cont_t *)buf_info->buf->buffer;
   1153 
   1154     if(user_buf != my_obj->buf[buf_info->buf->buf_idx].buffer) {
   1155         CDBG_ERROR("%s : Buffer modified. ERROR",__func__);
   1156         rc = -1;
   1157         return rc;
   1158     }
   1159 
   1160     if (buf_info->buf->frame_idx == 1) {
   1161         frameID = buf_info->buf->frame_idx;
   1162     }else {
   1163         frameID = (buf_info->buf->frame_idx - 1) * user_buf->buf_cnt;
   1164     }
   1165 
   1166     timeStamp = (nsecs_t)(buf_info->buf->ts.tv_sec) *
   1167             1000000000LL + buf_info->buf->ts.tv_nsec;
   1168 
   1169     if (timeStamp <= my_obj->prev_timestamp) {
   1170         CDBG_ERROR("%s: TimeStamp received less than expected", __func__);
   1171         mm_stream_qbuf(my_obj, buf_info->buf);
   1172         return rc;
   1173     } else if (my_obj->prev_timestamp == 0
   1174             || (my_obj->prev_frameID != buf_info->buf->frame_idx + 1)) {
   1175         /* For first frame or incase batch is droped */
   1176         interval_nsec = ((my_obj->stream_info->user_buf_info.frameInterval) * 1000000);
   1177         my_obj->prev_timestamp = (timeStamp - (nsecs_t)(user_buf->buf_cnt * interval_nsec));
   1178     } else {
   1179         ts_delta = timeStamp - my_obj->prev_timestamp;
   1180         interval_nsec = (nsecs_t)(ts_delta / user_buf->buf_cnt);
   1181         CDBG("%s: Timestamp delta = %d timestamp = %lld",__func__, ts_delta, timeStamp);
   1182     }
   1183 
   1184     for (i = 0; i < (int32_t)user_buf->buf_cnt; i++) {
   1185         buf_info->buf->user_buf.buf_idx[i] = user_buf->buf_idx[i];
   1186         stream_buf = &my_obj->plane_buf[user_buf->buf_idx[i]];
   1187         stream_buf->frame_idx = frameID + i;
   1188 
   1189         frame_ts  = (i * interval_nsec) + my_obj->prev_timestamp;
   1190 
   1191         stream_buf->ts.tv_sec  = (frame_ts / 1000000000LL);
   1192         stream_buf->ts.tv_nsec = (frame_ts - (stream_buf->ts.tv_sec * 1000000000LL));
   1193         stream_buf->is_uv_subsampled = buf_info->buf->is_uv_subsampled;
   1194 
   1195         CDBG("%s: buf_index %d, frame_idx %d, stream type %d, timestamp = %lld",
   1196                 __func__, stream_buf->buf_idx, stream_buf->frame_idx,
   1197                 my_obj->stream_info->stream_type, frame_ts);
   1198     }
   1199 
   1200     buf_info->buf->ts.tv_sec  = (my_obj->prev_timestamp / 1000000000LL);
   1201     buf_info->buf->ts.tv_nsec = (my_obj->prev_timestamp -
   1202             (buf_info->buf->ts.tv_sec * 1000000000LL));
   1203 
   1204     buf_info->buf->user_buf.bufs_used = user_buf->buf_cnt;
   1205     buf_info->buf->user_buf.buf_in_use = 1;
   1206 
   1207     my_obj->prev_timestamp = timeStamp;
   1208     my_obj->prev_frameID = buf_info->buf->frame_idx;
   1209 
   1210     CDBG("%s :X rc = %d",__func__,rc);
   1211     return rc;
   1212 }
   1213 
   1214 /*===========================================================================
   1215  * FUNCTION   : mm_stream_read_msm_frame
   1216  *
   1217  * DESCRIPTION: dequeue a stream buffer from kernel queue
   1218  *
   1219  * PARAMETERS :
   1220  *   @my_obj       : stream object
   1221  *   @buf_info     : ptr to a struct storing buffer information
   1222  *   @num_planes   : number of planes in the buffer
   1223  *
   1224  * RETURN     : int32_t type of status
   1225  *              0  -- success
   1226  *              -1 -- failure
   1227  *==========================================================================*/
   1228 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
   1229                                  mm_camera_buf_info_t* buf_info,
   1230                                  uint8_t num_planes)
   1231 {
   1232     int32_t rc = 0;
   1233     struct v4l2_buffer vb;
   1234     struct v4l2_plane planes[VIDEO_MAX_PLANES];
   1235     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1236          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1237 
   1238     memset(&vb,  0,  sizeof(vb));
   1239     vb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1240     vb.memory = V4L2_MEMORY_USERPTR;
   1241     vb.m.planes = &planes[0];
   1242     vb.length = num_planes;
   1243 
   1244     rc = ioctl(my_obj->fd, VIDIOC_DQBUF, &vb);
   1245     if (0 > rc) {
   1246         CDBG_ERROR("%s: VIDIOC_DQBUF ioctl call failed on stream type %d (rc=%d): %s",
   1247             __func__, my_obj->stream_info->stream_type, rc, strerror(errno));
   1248     } else {
   1249         pthread_mutex_lock(&my_obj->buf_lock);
   1250         my_obj->queued_buffer_count--;
   1251         if (0 == my_obj->queued_buffer_count) {
   1252             CDBG_HIGH("%s: Stoping poll on stream %p type: %d", __func__,
   1253                 my_obj, my_obj->stream_info->stream_type);
   1254             mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1255                 my_obj->my_hdl, mm_camera_async_call);
   1256             CDBG_HIGH("%s: Stopped poll on stream %p type: %d", __func__,
   1257                 my_obj, my_obj->stream_info->stream_type);
   1258         }
   1259         uint32_t idx = vb.index;
   1260         buf_info->buf = &my_obj->buf[idx];
   1261         buf_info->frame_idx = vb.sequence;
   1262         buf_info->stream_id = my_obj->my_hdl;
   1263 
   1264         buf_info->buf->stream_id = my_obj->my_hdl;
   1265         buf_info->buf->buf_idx = idx;
   1266         buf_info->buf->frame_idx = vb.sequence;
   1267         buf_info->buf->ts.tv_sec  = vb.timestamp.tv_sec;
   1268         buf_info->buf->ts.tv_nsec = vb.timestamp.tv_usec * 1000;
   1269         buf_info->buf->flags = vb.flags;
   1270 
   1271         CDBG_HIGH("%s: VIDIOC_DQBUF buf_index %d, frame_idx %d, stream type %d, rc %d,"
   1272                 "queued: %d, buf_type = %d flags = %d",
   1273             __func__, vb.index, buf_info->buf->frame_idx,
   1274             my_obj->stream_info->stream_type, rc,
   1275             my_obj->queued_buffer_count, buf_info->buf->buf_type,
   1276             buf_info->buf->flags);
   1277 
   1278         buf_info->buf->is_uv_subsampled =
   1279             (vb.reserved == V4L2_PIX_FMT_NV14 || vb.reserved == V4L2_PIX_FMT_NV41);
   1280 
   1281         if(buf_info->buf->buf_type == CAM_STREAM_BUF_TYPE_USERPTR) {
   1282             mm_stream_read_user_buf(my_obj, buf_info);
   1283         }
   1284         pthread_mutex_unlock(&my_obj->buf_lock);
   1285 
   1286         if ( NULL != my_obj->mem_vtbl.clean_invalidate_buf ) {
   1287             rc = my_obj->mem_vtbl.clean_invalidate_buf(idx,
   1288                 my_obj->mem_vtbl.user_data);
   1289             if (0 > rc) {
   1290                 CDBG_ERROR("%s: Clean invalidate cache failed on buffer index: %d",
   1291                     __func__, idx);
   1292             }
   1293         } else {
   1294             CDBG_ERROR("%s: Clean invalidate cache op not supported", __func__);
   1295         }
   1296     }
   1297 
   1298     CDBG("%s :X rc = %d",__func__,rc);
   1299     return rc;
   1300 }
   1301 
   1302 /*===========================================================================
   1303  * FUNCTION   : mm_stream_set_parms
   1304  *
   1305  * DESCRIPTION: set parameters per stream
   1306  *
   1307  * PARAMETERS :
   1308  *   @my_obj       : stream object
   1309  *   @in_value     : ptr to a param struct to be set to server
   1310  *
   1311  * RETURN     : int32_t type of status
   1312  *              0  -- success
   1313  *              -1 -- failure
   1314  * NOTE       : Assume the parms struct buf is already mapped to server via
   1315  *              domain socket. Corresponding fields of parameters to be set
   1316  *              are already filled in by upper layer caller.
   1317  *==========================================================================*/
   1318 int32_t mm_stream_set_parm(mm_stream_t *my_obj,
   1319                            cam_stream_parm_buffer_t *in_value)
   1320 {
   1321     int32_t rc = -1;
   1322     int32_t value = 0;
   1323     if (in_value != NULL) {
   1324         rc = mm_camera_util_s_ctrl(my_obj->fd, CAM_PRIV_STREAM_PARM, &value);
   1325     }
   1326     return rc;
   1327 }
   1328 
   1329 /*===========================================================================
   1330  * FUNCTION   : mm_stream_get_parms
   1331  *
   1332  * DESCRIPTION: get parameters per stream
   1333  *
   1334  * PARAMETERS :
   1335  *   @my_obj       : stream object
   1336  *   @in_value     : ptr to a param struct to be get from server
   1337  *
   1338  * RETURN     : int32_t type of status
   1339  *              0  -- success
   1340  *              -1 -- failure
   1341  * NOTE       : Assume the parms struct buf is already mapped to server via
   1342  *              domain socket. Corresponding fields of parameters to be get
   1343  *              are already filled in by upper layer caller.
   1344  *==========================================================================*/
   1345 int32_t mm_stream_get_parm(mm_stream_t *my_obj,
   1346                            cam_stream_parm_buffer_t *in_value)
   1347 {
   1348     int32_t rc = -1;
   1349     int32_t value = 0;
   1350     if (in_value != NULL) {
   1351         rc = mm_camera_util_g_ctrl(my_obj->fd, CAM_PRIV_STREAM_PARM, &value);
   1352     }
   1353     return rc;
   1354 }
   1355 
   1356 /*===========================================================================
   1357  * FUNCTION   : mm_stream_do_actions
   1358  *
   1359  * DESCRIPTION: request server to perform stream based actions
   1360  *
   1361  * PARAMETERS :
   1362  *   @my_obj       : stream object
   1363  *   @in_value     : ptr to a struct of actions to be performed by the server
   1364  *
   1365  * RETURN     : int32_t type of status
   1366  *              0  -- success
   1367  *              -1 -- failure
   1368  * NOTE       : Assume the action struct buf is already mapped to server via
   1369  *              domain socket. Corresponding fields of actions to be performed
   1370  *              are already filled in by upper layer caller.
   1371  *==========================================================================*/
   1372 int32_t mm_stream_do_action(mm_stream_t *my_obj,
   1373                             void *in_value)
   1374 {
   1375     int32_t rc = -1;
   1376     int32_t value = 0;
   1377     if (in_value != NULL) {
   1378         rc = mm_camera_util_s_ctrl(my_obj->fd, CAM_PRIV_STREAM_PARM, &value);
   1379     }
   1380     return rc;
   1381 }
   1382 
   1383 /*===========================================================================
   1384  * FUNCTION   : mm_stream_set_ext_mode
   1385  *
   1386  * DESCRIPTION: set stream extended mode to server via v4l2 ioctl
   1387  *
   1388  * PARAMETERS :
   1389  *   @my_obj       : stream object
   1390  *
   1391  * RETURN     : int32_t type of status
   1392  *              0  -- success
   1393  *              -1 -- failure
   1394  * NOTE       : Server will return a server stream id that uniquely identify
   1395  *              this stream on server side. Later on communication to server
   1396  *              per stream should use this server stream id.
   1397  *==========================================================================*/
   1398 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj)
   1399 {
   1400     int32_t rc = 0;
   1401     struct v4l2_streamparm s_parm;
   1402     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1403          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1404 
   1405     memset(&s_parm, 0, sizeof(s_parm));
   1406     s_parm.type =  V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1407 
   1408     rc = ioctl(my_obj->fd, VIDIOC_S_PARM, &s_parm);
   1409     CDBG("%s:stream fd=%d, rc=%d, extended_mode=%d\n",
   1410          __func__, my_obj->fd, rc, s_parm.parm.capture.extendedmode);
   1411     if (rc == 0) {
   1412         /* get server stream id */
   1413         my_obj->server_stream_id = s_parm.parm.capture.extendedmode;
   1414     }
   1415     return rc;
   1416 }
   1417 
   1418 /*===========================================================================
   1419  * FUNCTION   : mm_stream_qbuf
   1420  *
   1421  * DESCRIPTION: enqueue buffer back to kernel queue for furture use
   1422  *
   1423  * PARAMETERS :
   1424  *   @my_obj       : stream object
   1425  *   @buf          : ptr to a struct storing buffer information
   1426  *
   1427  * RETURN     : int32_t type of status
   1428  *              0  -- success
   1429  *              -1 -- failure
   1430  *==========================================================================*/
   1431 int32_t mm_stream_qbuf(mm_stream_t *my_obj, mm_camera_buf_def_t *buf)
   1432 {
   1433     int32_t rc = 0;
   1434     uint32_t length = 0;
   1435     struct v4l2_buffer buffer;
   1436     struct v4l2_plane planes[VIDEO_MAX_PLANES];
   1437     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d, stream type = %d",
   1438          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state,
   1439          my_obj->stream_info->stream_type);
   1440 
   1441     if (buf->buf_type == CAM_STREAM_BUF_TYPE_USERPTR) {
   1442         CDBG("%s: USERPTR num_buf = %d, idx = %d", __func__,
   1443                 buf->user_buf.bufs_used, buf->buf_idx);
   1444         memset(&planes, 0, sizeof(planes));
   1445         planes[0].length = my_obj->stream_info->user_buf_info.size;
   1446         planes[0].m.userptr = buf->fd;
   1447         length = 1;
   1448     } else {
   1449         memcpy(planes, buf->planes_buf.planes, sizeof(planes));
   1450         length = buf->planes_buf.num_planes;
   1451 
   1452         CDBG("%s:plane 0: stream_hdl=%u,fd=%d,frame idx=%d,num_planes = %u, "
   1453                 "offset = %d, data_offset = %d\n", __func__,
   1454                  buf->stream_id, buf->fd, buffer.index, buffer.length,
   1455                  buf->planes_buf.planes[0].reserved[0],
   1456                  buf->planes_buf.planes[0].data_offset);
   1457         CDBG("%s:plane 1: stream_hdl=%u,fd=%d,frame idx=%d,num_planes = %u, "
   1458                 "offset = %d, data_offset = %d\n", __func__,
   1459                  buf->stream_id, buf->fd, buffer.index, buffer.length,
   1460                  buf->planes_buf.planes[1].reserved[0],
   1461                  buf->planes_buf.planes[1].data_offset);
   1462     }
   1463 
   1464     memset(&buffer, 0, sizeof(buffer));
   1465     buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1466     buffer.memory = V4L2_MEMORY_USERPTR;
   1467     buffer.index = (__u32)buf->buf_idx;
   1468     buffer.m.planes = &planes[0];
   1469     buffer.length = (__u32)length;
   1470 
   1471     if ( NULL != my_obj->mem_vtbl.invalidate_buf ) {
   1472         rc = my_obj->mem_vtbl.invalidate_buf(buffer.index,
   1473                                              my_obj->mem_vtbl.user_data);
   1474         if ( 0 > rc ) {
   1475             CDBG_ERROR("%s: Cache invalidate failed on buffer index: %d",
   1476                        __func__,
   1477                        buffer.index);
   1478             return rc;
   1479         }
   1480     } else {
   1481         CDBG_ERROR("%s: Cache invalidate op not added", __func__);
   1482     }
   1483 
   1484     my_obj->queued_buffer_count++;
   1485     if (1 == my_obj->queued_buffer_count) {
   1486         /* Add fd to data poll thread */
   1487         CDBG_HIGH("%s: Starting poll on stream %p type: %d", __func__,
   1488             my_obj,my_obj->stream_info->stream_type);
   1489         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1490             my_obj->my_hdl, my_obj->fd, mm_stream_data_notify, (void*)my_obj,
   1491             mm_camera_async_call);
   1492         if (0 > rc) {
   1493             CDBG_ERROR("%s: Add poll on stream %p type: %d fd error (rc=%d)",
   1494                 __func__, my_obj, my_obj->stream_info->stream_type, rc);
   1495         } else {
   1496             CDBG_HIGH("%s: Started poll on stream %p type: %d", __func__,
   1497                 my_obj, my_obj->stream_info->stream_type);
   1498         }
   1499     }
   1500 
   1501     rc = ioctl(my_obj->fd, VIDIOC_QBUF, &buffer);
   1502     if (0 > rc) {
   1503         CDBG_ERROR("%s: VIDIOC_QBUF ioctl call failed on stream type %d (rc=%d): %s",
   1504             __func__, my_obj->stream_info->stream_type, rc, strerror(errno));
   1505         my_obj->queued_buffer_count--;
   1506         if (0 == my_obj->queued_buffer_count) {
   1507             /* Remove fd from data poll in case of failing
   1508              * first buffer queuing attempt */
   1509             CDBG_HIGH("%s: Stoping poll on stream %p type: %d", __func__,
   1510                 my_obj, my_obj->stream_info->stream_type);
   1511             mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1512                 my_obj->my_hdl, mm_camera_async_call);
   1513             CDBG_HIGH("%s: Stopped poll on stream %p type: %d", __func__,
   1514                 my_obj, my_obj->stream_info->stream_type);
   1515         }
   1516     } else {
   1517         CDBG_HIGH("%s: VIDIOC_QBUF buf_index %d, stream type %d, rc %d, queued: %d", __func__,
   1518             buffer.index, my_obj->stream_info->stream_type, rc, my_obj->queued_buffer_count);
   1519     }
   1520 
   1521     return rc;
   1522 }
   1523 
   1524 /*===========================================================================
   1525  * FUNCTION   : mm_stream_request_buf
   1526  *
   1527  * DESCRIPTION: This function let kernel know the amount of buffers need to
   1528  *              be registered via v4l2 ioctl.
   1529  *
   1530  * PARAMETERS :
   1531  *   @my_obj       : stream object
   1532  *
   1533  * RETURN     : int32_t type of status
   1534  *              0  -- success
   1535  *              -1 -- failure
   1536  *==========================================================================*/
   1537 int32_t mm_stream_request_buf(mm_stream_t * my_obj)
   1538 {
   1539     int32_t rc = 0;
   1540     struct v4l2_requestbuffers bufreq;
   1541     uint8_t buf_num = my_obj->buf_num;
   1542     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1543          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1544 
   1545     CDBG("%s: buf_num = %d, stream type = %d",
   1546          __func__, buf_num, my_obj->stream_info->stream_type);
   1547 
   1548     if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) {
   1549         CDBG_ERROR("%s: buf num %d > max limit %d\n",
   1550                    __func__, buf_num, MM_CAMERA_MAX_NUM_FRAMES);
   1551         return -1;
   1552     }
   1553 
   1554     memset(&bufreq, 0, sizeof(bufreq));
   1555     bufreq.count = buf_num;
   1556     bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1557     bufreq.memory = V4L2_MEMORY_USERPTR;
   1558     rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
   1559     if (rc < 0) {
   1560       CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n",
   1561            __func__, my_obj->fd, rc);
   1562     }
   1563 
   1564     CDBG("%s :X rc = %d",__func__,rc);
   1565     return rc;
   1566 }
   1567 
   1568 /*===========================================================================
   1569  * FUNCTION   : mm_stream_map_buf
   1570  *
   1571  * DESCRIPTION: mapping stream buffer via domain socket to server
   1572  *
   1573  * PARAMETERS :
   1574  *   @my_obj       : stream object
   1575  *   @buf_type     : type of buffer to be mapped. could be following values:
   1576  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1577  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1578  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1579  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1580  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1581  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1582  *   @plane_idx    : plane index. If all planes share the same fd,
   1583  *                   plane_idx = -1; otherwise, plean_idx is the
   1584  *                   index to plane (0..num_of_planes)
   1585  *   @fd           : file descriptor of the buffer
   1586  *   @size         : size of the buffer
   1587  *
   1588  * RETURN     : int32_t type of status
   1589  *              0  -- success
   1590  *              -1 -- failure
   1591  *==========================================================================*/
   1592 int32_t mm_stream_map_buf(mm_stream_t * my_obj,
   1593                           uint8_t buf_type,
   1594                           uint32_t frame_idx,
   1595                           int32_t plane_idx,
   1596                           int32_t fd,
   1597                           size_t size)
   1598 {
   1599     if (NULL == my_obj || NULL == my_obj->ch_obj || NULL == my_obj->ch_obj->cam_obj) {
   1600         CDBG_ERROR("%s: NULL obj of stream/channel/camera", __func__);
   1601         return -1;
   1602     }
   1603     cam_sock_packet_t packet;
   1604     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1605     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
   1606     packet.payload.buf_map.type = buf_type;
   1607     packet.payload.buf_map.fd = fd;
   1608     packet.payload.buf_map.size = size;
   1609     packet.payload.buf_map.stream_id = my_obj->server_stream_id;
   1610     packet.payload.buf_map.frame_idx = frame_idx;
   1611     packet.payload.buf_map.plane_idx = plane_idx;
   1612 
   1613     CDBG("%s: mapping buf_type %d, stream_id %d, frame_idx %d, fd %d, size %d",
   1614             __func__, buf_type, my_obj->server_stream_id, frame_idx, fd, size);
   1615     return mm_camera_util_sendmsg(my_obj->ch_obj->cam_obj,
   1616                                   &packet,
   1617                                   sizeof(cam_sock_packet_t),
   1618                                   fd);
   1619 }
   1620 
   1621 /*===========================================================================
   1622  * FUNCTION   : mm_stream_unmap_buf
   1623  *
   1624  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1625  *
   1626  * PARAMETERS :
   1627  *   @my_obj       : stream object
   1628  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1629  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1630  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1631  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1632  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1633  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1634  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1635  *   @plane_idx    : plane index. If all planes share the same fd,
   1636  *                   plane_idx = -1; otherwise, plean_idx is the
   1637  *                   index to plane (0..num_of_planes)
   1638  *
   1639  * RETURN     : int32_t type of status
   1640  *              0  -- success
   1641  *              -1 -- failure
   1642  *==========================================================================*/
   1643 int32_t mm_stream_unmap_buf(mm_stream_t * my_obj,
   1644                             uint8_t buf_type,
   1645                             uint32_t frame_idx,
   1646                             int32_t plane_idx)
   1647 {
   1648     if (NULL == my_obj || NULL == my_obj->ch_obj || NULL == my_obj->ch_obj->cam_obj) {
   1649         CDBG_ERROR("%s: NULL obj of stream/channel/camera", __func__);
   1650         return -1;
   1651     }
   1652     cam_sock_packet_t packet;
   1653     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1654     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
   1655     packet.payload.buf_unmap.type = buf_type;
   1656     packet.payload.buf_unmap.stream_id = my_obj->server_stream_id;
   1657     packet.payload.buf_unmap.frame_idx = frame_idx;
   1658     packet.payload.buf_unmap.plane_idx = plane_idx;
   1659     return mm_camera_util_sendmsg(my_obj->ch_obj->cam_obj,
   1660                                   &packet,
   1661                                   sizeof(cam_sock_packet_t),
   1662                                   -1);
   1663 }
   1664 
   1665 /*===========================================================================
   1666  * FUNCTION   : mm_stream_map_buf_ops
   1667  *
   1668  * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
   1669  *              This function will be passed to upper layer as part of ops table
   1670  *              to be used by upper layer when allocating stream buffers and mapping
   1671  *              buffers to server via domain socket.
   1672  *
   1673  * PARAMETERS :
   1674  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1675  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1676  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1677  *   @plane_idx    : plane index. If all planes share the same fd,
   1678  *                   plane_idx = -1; otherwise, plean_idx is the
   1679  *                   index to plane (0..num_of_planes)
   1680  *   @fd           : file descriptor of the buffer
   1681  *   @size         : size of the buffer
   1682  *   @userdata     : user data ptr (stream object)
   1683  *
   1684  * RETURN     : int32_t type of status
   1685  *              0  -- success
   1686  *              -1 -- failure
   1687  *==========================================================================*/
   1688 static int32_t mm_stream_map_buf_ops(uint32_t frame_idx,
   1689                                      int32_t plane_idx,
   1690                                      int fd,
   1691                                      size_t size,
   1692                                      cam_mapping_buf_type type,
   1693                                      void *userdata)
   1694 {
   1695     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   1696     return mm_stream_map_buf(my_obj,
   1697                              type,
   1698                              frame_idx, plane_idx, fd, size);
   1699 }
   1700 
   1701 /*===========================================================================
   1702  * FUNCTION   : mm_stream_unmap_buf_ops
   1703  *
   1704  * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
   1705  *              This function will be passed to upper layer as part of ops table
   1706  *              to be used by upper layer when allocating stream buffers and unmapping
   1707  *              buffers to server via domain socket.
   1708  *
   1709  * PARAMETERS :
   1710  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1711  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1712  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1713  *   @plane_idx    : plane index. If all planes share the same fd,
   1714  *                   plane_idx = -1; otherwise, plean_idx is the
   1715  *                   index to plane (0..num_of_planes)
   1716  *   @userdata     : user data ptr (stream object)
   1717  *
   1718  * RETURN     : int32_t type of status
   1719  *              0  -- success
   1720  *              -1 -- failure
   1721  *==========================================================================*/
   1722 static int32_t mm_stream_unmap_buf_ops(uint32_t frame_idx,
   1723                                        int32_t plane_idx,
   1724                                        cam_mapping_buf_type type,
   1725                                        void *userdata)
   1726 {
   1727     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   1728     return mm_stream_unmap_buf(my_obj,
   1729                                type,
   1730                                frame_idx,
   1731                                plane_idx);
   1732 }
   1733 
   1734 /*===========================================================================
   1735  * FUNCTION   : mm_stream_init_bufs
   1736  *
   1737  * DESCRIPTION: initialize stream buffers needed. This function will request
   1738  *              buffers needed from upper layer through the mem ops table passed
   1739  *              during configuration stage.
   1740  *
   1741  * PARAMETERS :
   1742  *   @my_obj  : stream object
   1743  *
   1744  * RETURN     : int32_t type of status
   1745  *              0  -- success
   1746  *              -1 -- failure
   1747  *==========================================================================*/
   1748 int32_t mm_stream_init_bufs(mm_stream_t * my_obj)
   1749 {
   1750     int32_t i, rc = 0;
   1751     uint8_t *reg_flags = NULL;
   1752     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1753          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1754 
   1755     /* deinit buf if it's not NULL*/
   1756     if (NULL != my_obj->buf) {
   1757         mm_stream_deinit_bufs(my_obj);
   1758     }
   1759 
   1760     my_obj->map_ops.map_ops = mm_stream_map_buf_ops;
   1761     my_obj->map_ops.unmap_ops = mm_stream_unmap_buf_ops;
   1762     my_obj->map_ops.userdata = my_obj;
   1763 
   1764     rc = my_obj->mem_vtbl.get_bufs(&my_obj->frame_offset,
   1765                                    &my_obj->buf_num,
   1766                                    &reg_flags,
   1767                                    &my_obj->buf,
   1768                                    &my_obj->map_ops,
   1769                                    my_obj->mem_vtbl.user_data);
   1770 
   1771     if (0 != rc) {
   1772         CDBG_ERROR("%s: Error get buf, rc = %d\n", __func__, rc);
   1773         return rc;
   1774     }
   1775 
   1776     my_obj->buf_status =
   1777         (mm_stream_buf_status_t *)malloc(sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
   1778 
   1779     if (NULL == my_obj->buf_status) {
   1780         CDBG_ERROR("%s: No memory for buf_status", __func__);
   1781         mm_stream_deinit_bufs(my_obj);
   1782         free(reg_flags);
   1783         return -1;
   1784     }
   1785 
   1786     memset(my_obj->buf_status, 0, sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
   1787     for (i = 0; i < my_obj->buf_num; i++) {
   1788         my_obj->buf_status[i].initial_reg_flag = reg_flags[i];
   1789         my_obj->buf[i].stream_id = my_obj->my_hdl;
   1790         my_obj->buf[i].stream_type = my_obj->stream_info->stream_type;
   1791 
   1792         if (my_obj->buf[i].buf_type == CAM_STREAM_BUF_TYPE_USERPTR) {
   1793             my_obj->buf[i].user_buf.bufs_used =
   1794                     (int8_t)my_obj->stream_info->user_buf_info.frame_buf_cnt;
   1795             my_obj->buf[i].user_buf.buf_in_use = reg_flags[i];
   1796         }
   1797     }
   1798 
   1799     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   1800         my_obj->plane_buf = my_obj->buf[0].user_buf.plane_buf;
   1801         if (my_obj->plane_buf != NULL) {
   1802             my_obj->plane_buf_num =
   1803                     my_obj->buf_num *
   1804                     my_obj->stream_info->user_buf_info.frame_buf_cnt;
   1805             for (i = 0; i < my_obj->plane_buf_num; i++) {
   1806                 my_obj->plane_buf[i].stream_id = my_obj->my_hdl;
   1807                 my_obj->plane_buf[i].stream_type = my_obj->stream_info->stream_type;
   1808             }
   1809         }
   1810         my_obj->cur_bufs_staged = 0;
   1811         my_obj->cur_buf_idx = -1;
   1812     }
   1813 
   1814     free(reg_flags);
   1815     reg_flags = NULL;
   1816 
   1817     /* update in stream info about number of stream buffers */
   1818     my_obj->stream_info->num_bufs = my_obj->buf_num;
   1819 
   1820     return rc;
   1821 }
   1822 
   1823 /*===========================================================================
   1824  * FUNCTION   : mm_stream_deinit_bufs
   1825  *
   1826  * DESCRIPTION: return stream buffers to upper layer through the mem ops table
   1827  *              passed during configuration stage.
   1828  *
   1829  * PARAMETERS :
   1830  *   @my_obj  : stream object
   1831  *
   1832  * RETURN     : int32_t type of status
   1833  *              0  -- success
   1834  *              -1 -- failure
   1835  *==========================================================================*/
   1836 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj)
   1837 {
   1838     int32_t rc = 0;
   1839 
   1840     mm_camera_map_unmap_ops_tbl_t ops_tbl;
   1841     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1842          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1843 
   1844     if (NULL == my_obj->buf) {
   1845         CDBG("%s: Buf is NULL, no need to deinit", __func__);
   1846         return rc;
   1847     }
   1848 
   1849     /* release bufs */
   1850     ops_tbl.map_ops = mm_stream_map_buf_ops;
   1851     ops_tbl.unmap_ops = mm_stream_unmap_buf_ops;
   1852     ops_tbl.userdata = my_obj;
   1853 
   1854     rc = my_obj->mem_vtbl.put_bufs(&ops_tbl,
   1855                                    my_obj->mem_vtbl.user_data);
   1856 
   1857     if (my_obj->plane_buf != NULL) {
   1858         free(my_obj->plane_buf);
   1859         my_obj->plane_buf = NULL;
   1860     }
   1861 
   1862     free(my_obj->buf);
   1863     my_obj->buf = NULL;
   1864     if (my_obj->buf_status != NULL) {
   1865         free(my_obj->buf_status);
   1866         my_obj->buf_status = NULL;
   1867     }
   1868 
   1869     return rc;
   1870 }
   1871 
   1872 /*===========================================================================
   1873  * FUNCTION   : mm_stream_reg_buf
   1874  *
   1875  * DESCRIPTION: register buffers with kernel by calling v4l2 ioctl QBUF for
   1876  *              each buffer in the stream
   1877  *
   1878  * PARAMETERS :
   1879  *   @my_obj  : stream object
   1880  *
   1881  * RETURN     : int32_t type of status
   1882  *              0  -- success
   1883  *              -1 -- failure
   1884  *==========================================================================*/
   1885 int32_t mm_stream_reg_buf(mm_stream_t * my_obj)
   1886 {
   1887     int32_t rc = 0;
   1888     uint8_t i;
   1889     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1890          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1891 
   1892     rc = mm_stream_request_buf(my_obj);
   1893     if (rc != 0) {
   1894         return rc;
   1895     }
   1896 
   1897     pthread_mutex_lock(&my_obj->buf_lock);
   1898     my_obj->queued_buffer_count = 0;
   1899     for(i = 0; i < my_obj->buf_num; i++){
   1900         /* check if need to qbuf initially */
   1901         if (my_obj->buf_status[i].initial_reg_flag) {
   1902             rc = mm_stream_qbuf(my_obj, &my_obj->buf[i]);
   1903             if (rc != 0) {
   1904                 CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc);
   1905                 break;
   1906             }
   1907             my_obj->buf_status[i].buf_refcnt = 0;
   1908             my_obj->buf_status[i].in_kernel = 1;
   1909         } else {
   1910             /* the buf is held by upper layer, will not queue into kernel.
   1911              * add buf reference count */
   1912             my_obj->buf_status[i].buf_refcnt = 1;
   1913             my_obj->buf_status[i].in_kernel = 0;
   1914         }
   1915     }
   1916     pthread_mutex_unlock(&my_obj->buf_lock);
   1917 
   1918     return rc;
   1919 }
   1920 
   1921 /*===========================================================================
   1922  * FUNCTION   : mm_stream_unreg buf
   1923  *
   1924  * DESCRIPTION: unregister all stream buffers from kernel
   1925  *
   1926  * PARAMETERS :
   1927  *   @my_obj  : stream object
   1928  *
   1929  * RETURN     : int32_t type of status
   1930  *              0  -- success
   1931  *              -1 -- failure
   1932  *==========================================================================*/
   1933 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj)
   1934 {
   1935     struct v4l2_requestbuffers bufreq;
   1936     int32_t i, rc = 0;
   1937     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1938          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1939 
   1940     /* unreg buf to kernel */
   1941     bufreq.count = 0;
   1942     bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1943     bufreq.memory = V4L2_MEMORY_USERPTR;
   1944     rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
   1945     if (rc < 0) {
   1946         CDBG_ERROR("%s: fd=%d, VIDIOC_REQBUFS failed, rc=%d\n",
   1947               __func__, my_obj->fd, rc);
   1948     }
   1949 
   1950     /* reset buf reference count */
   1951     pthread_mutex_lock(&my_obj->buf_lock);
   1952     if (NULL != my_obj->buf_status) {
   1953         for(i = 0; i < my_obj->buf_num; i++){
   1954             my_obj->buf_status[i].buf_refcnt = 0;
   1955             my_obj->buf_status[i].in_kernel = 0;
   1956         }
   1957     }
   1958     pthread_mutex_unlock(&my_obj->buf_lock);
   1959 
   1960     return rc;
   1961 }
   1962 
   1963 /*===========================================================================
   1964  * FUNCTION   : mm_stream_get_v4l2_fmt
   1965  *
   1966  * DESCRIPTION: translate camera image format into FOURCC code
   1967  *
   1968  * PARAMETERS :
   1969  *   @fmt     : camera image format
   1970  *
   1971  * RETURN     : FOURCC code for image format
   1972  *==========================================================================*/
   1973 uint32_t mm_stream_get_v4l2_fmt(cam_format_t fmt)
   1974 {
   1975     uint32_t val;
   1976     switch(fmt) {
   1977     case CAM_FORMAT_YUV_420_NV12:
   1978     case CAM_FORMAT_YUV_420_NV12_VENUS:
   1979         val = V4L2_PIX_FMT_NV12;
   1980         break;
   1981     case CAM_FORMAT_YUV_420_NV21:
   1982         val = V4L2_PIX_FMT_NV21;
   1983         break;
   1984     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG:
   1985     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GRBG:
   1986     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_RGGB:
   1987     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_BGGR:
   1988         val= V4L2_PIX_FMT_SBGGR10;
   1989         break;
   1990     case CAM_FORMAT_YUV_422_NV61:
   1991         val= V4L2_PIX_FMT_NV61;
   1992         break;
   1993     case CAM_FORMAT_YUV_RAW_8BIT_YUYV:
   1994         val= V4L2_PIX_FMT_YUYV;
   1995         break;
   1996     case CAM_FORMAT_YUV_RAW_8BIT_YVYU:
   1997         val= V4L2_PIX_FMT_YVYU;
   1998         break;
   1999     case CAM_FORMAT_YUV_RAW_8BIT_UYVY:
   2000         val= V4L2_PIX_FMT_UYVY;
   2001         break;
   2002     case CAM_FORMAT_YUV_RAW_8BIT_VYUY:
   2003         val= V4L2_PIX_FMT_VYUY;
   2004         break;
   2005     case CAM_FORMAT_YUV_420_YV12:
   2006         val= V4L2_PIX_FMT_NV12;
   2007         break;
   2008     case CAM_FORMAT_YUV_422_NV16:
   2009         val= V4L2_PIX_FMT_NV16;
   2010         break;
   2011     default:
   2012         val = 0;
   2013         CDBG_ERROR("%s: Unknown fmt=%d", __func__, fmt);
   2014         break;
   2015     }
   2016     CDBG("%s: fmt=%d, val =%d", __func__, fmt, val);
   2017     return val;
   2018 }
   2019 
   2020 /*===========================================================================
   2021  * FUNCTION   : mm_stream_calc_offset_preview
   2022  *
   2023  * DESCRIPTION: calculate preview frame offset based on format and
   2024  *              padding information
   2025  *
   2026  * PARAMETERS :
   2027  *   @fmt     : image format
   2028  *   @dim     : image dimension
   2029  *   @buf_planes : [out] buffer plane information
   2030  *
   2031  * RETURN     : int32_t type of status
   2032  *              0  -- success
   2033  *              -1 -- failure
   2034  *==========================================================================*/
   2035 int32_t mm_stream_calc_offset_preview(cam_format_t fmt,
   2036                                       cam_dimension_t *dim,
   2037                                       cam_stream_buf_plane_info_t *buf_planes)
   2038 {
   2039     int32_t rc = 0;
   2040     int stride = 0, scanline = 0;
   2041 
   2042     switch (fmt) {
   2043     case CAM_FORMAT_YUV_420_NV12:
   2044     case CAM_FORMAT_YUV_420_NV21:
   2045         /* 2 planes: Y + CbCr */
   2046         buf_planes->plane_info.num_planes = 2;
   2047 
   2048         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   2049         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_2);
   2050 
   2051         buf_planes->plane_info.mp[0].offset = 0;
   2052         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2053         buf_planes->plane_info.mp[0].offset_x = 0;
   2054         buf_planes->plane_info.mp[0].offset_y = 0;
   2055         buf_planes->plane_info.mp[0].stride = stride;
   2056         buf_planes->plane_info.mp[0].scanline = scanline;
   2057         buf_planes->plane_info.mp[0].width = dim->width;
   2058         buf_planes->plane_info.mp[0].height = dim->height;
   2059 
   2060         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   2061         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_2);
   2062         buf_planes->plane_info.mp[1].offset = 0;
   2063         buf_planes->plane_info.mp[1].len =
   2064             (uint32_t)(stride * scanline);
   2065         buf_planes->plane_info.mp[1].offset_x = 0;
   2066         buf_planes->plane_info.mp[1].offset_y = 0;
   2067         buf_planes->plane_info.mp[1].stride = stride;
   2068         buf_planes->plane_info.mp[1].scanline = scanline;
   2069         buf_planes->plane_info.mp[1].width = dim->width;
   2070         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2071 
   2072         buf_planes->plane_info.frame_len =
   2073                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2074                         buf_planes->plane_info.mp[1].len,
   2075                         CAM_PAD_TO_4K);
   2076         break;
   2077     case CAM_FORMAT_YUV_420_NV21_ADRENO:
   2078         /* 2 planes: Y + CbCr */
   2079         buf_planes->plane_info.num_planes = 2;
   2080 
   2081         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   2082         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_32);
   2083         buf_planes->plane_info.mp[0].offset = 0;
   2084         buf_planes->plane_info.mp[0].len =
   2085                 PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_4K);
   2086         buf_planes->plane_info.mp[0].offset_x = 0;
   2087         buf_planes->plane_info.mp[0].offset_y = 0;
   2088         buf_planes->plane_info.mp[0].stride = stride;
   2089         buf_planes->plane_info.mp[0].scanline = scanline;
   2090         buf_planes->plane_info.mp[0].width = dim->width;
   2091         buf_planes->plane_info.mp[0].height = dim->height;
   2092 
   2093         stride = PAD_TO_SIZE(dim->width / 2, CAM_PAD_TO_32) * 2;
   2094         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_32);
   2095         buf_planes->plane_info.mp[1].offset = 0;
   2096         buf_planes->plane_info.mp[1].len =
   2097                 PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_4K);
   2098         buf_planes->plane_info.mp[1].offset_x = 0;
   2099         buf_planes->plane_info.mp[1].offset_y = 0;
   2100         buf_planes->plane_info.mp[1].stride = stride;
   2101         buf_planes->plane_info.mp[1].scanline = scanline;
   2102         buf_planes->plane_info.mp[1].width = dim->width;
   2103         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2104 
   2105         buf_planes->plane_info.frame_len =
   2106                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2107                         buf_planes->plane_info.mp[1].len,
   2108                         CAM_PAD_TO_4K);
   2109         break;
   2110     case CAM_FORMAT_YUV_420_YV12:
   2111         /* 3 planes: Y + Cr + Cb */
   2112         buf_planes->plane_info.num_planes = 3;
   2113 
   2114         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2115         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_2);
   2116         buf_planes->plane_info.mp[0].offset = 0;
   2117         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2118         buf_planes->plane_info.mp[0].offset_x = 0;
   2119         buf_planes->plane_info.mp[0].offset_y = 0;
   2120         buf_planes->plane_info.mp[0].stride = stride;
   2121         buf_planes->plane_info.mp[0].scanline = scanline;
   2122         buf_planes->plane_info.mp[0].width = dim->width;
   2123         buf_planes->plane_info.mp[0].height = dim->height;
   2124 
   2125         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   2126         scanline = scanline / 2;
   2127         buf_planes->plane_info.mp[1].offset = 0;
   2128         buf_planes->plane_info.mp[1].len =
   2129             (uint32_t)(stride * scanline);
   2130         buf_planes->plane_info.mp[1].offset_x = 0;
   2131         buf_planes->plane_info.mp[1].offset_y = 0;
   2132         buf_planes->plane_info.mp[1].stride = stride;
   2133         buf_planes->plane_info.mp[1].scanline = scanline;
   2134         buf_planes->plane_info.mp[1].width = dim->width / 2;
   2135         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2136 
   2137         buf_planes->plane_info.mp[2].offset = 0;
   2138         buf_planes->plane_info.mp[2].len =
   2139             (uint32_t)(stride * scanline);
   2140         buf_planes->plane_info.mp[2].offset_x = 0;
   2141         buf_planes->plane_info.mp[2].offset_y = 0;
   2142         buf_planes->plane_info.mp[2].stride = stride;
   2143         buf_planes->plane_info.mp[2].scanline = scanline;
   2144         buf_planes->plane_info.mp[2].width = dim->width / 2;
   2145         buf_planes->plane_info.mp[2].height = dim->height / 2;
   2146 
   2147         buf_planes->plane_info.frame_len =
   2148                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2149                         buf_planes->plane_info.mp[1].len +
   2150                         buf_planes->plane_info.mp[2].len,
   2151                         CAM_PAD_TO_4K);
   2152         break;
   2153     case CAM_FORMAT_YUV_422_NV16:
   2154     case CAM_FORMAT_YUV_422_NV61:
   2155         /* 2 planes: Y + CbCr */
   2156         buf_planes->plane_info.num_planes = 2;
   2157 
   2158         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2159         scanline = dim->height;
   2160         buf_planes->plane_info.mp[0].offset = 0;
   2161         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2162         buf_planes->plane_info.mp[0].offset_x = 0;
   2163         buf_planes->plane_info.mp[0].offset_y = 0;
   2164         buf_planes->plane_info.mp[0].stride = stride;
   2165         buf_planes->plane_info.mp[0].scanline = scanline;
   2166         buf_planes->plane_info.mp[0].width = dim->width;
   2167         buf_planes->plane_info.mp[0].height = dim->height;
   2168 
   2169         buf_planes->plane_info.mp[1].offset = 0;
   2170         buf_planes->plane_info.mp[1].len = (uint32_t)(stride * scanline);
   2171         buf_planes->plane_info.mp[1].offset_x = 0;
   2172         buf_planes->plane_info.mp[1].offset_y = 0;
   2173         buf_planes->plane_info.mp[1].stride = stride;
   2174         buf_planes->plane_info.mp[1].scanline = scanline;
   2175         buf_planes->plane_info.mp[1].width = dim->width;
   2176         buf_planes->plane_info.mp[1].height = dim->height;
   2177 
   2178         buf_planes->plane_info.frame_len =
   2179                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2180                         buf_planes->plane_info.mp[1].len,
   2181                         CAM_PAD_TO_4K);
   2182         break;
   2183     case CAM_FORMAT_YUV_420_NV12_VENUS:
   2184 #ifdef VENUS_PRESENT
   2185         // using Venus
   2186         stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   2187         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   2188 
   2189         buf_planes->plane_info.frame_len =
   2190             VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   2191         buf_planes->plane_info.num_planes = 2;
   2192         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2193         buf_planes->plane_info.mp[0].offset = 0;
   2194         buf_planes->plane_info.mp[0].offset_x =0;
   2195         buf_planes->plane_info.mp[0].offset_y = 0;
   2196         buf_planes->plane_info.mp[0].stride = stride;
   2197         buf_planes->plane_info.mp[0].scanline = scanline;
   2198         buf_planes->plane_info.mp[0].width = dim->width;
   2199         buf_planes->plane_info.mp[0].height = dim->height;
   2200         stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   2201         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   2202         buf_planes->plane_info.mp[1].len =
   2203             buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2204         buf_planes->plane_info.mp[1].offset = 0;
   2205         buf_planes->plane_info.mp[1].offset_x =0;
   2206         buf_planes->plane_info.mp[1].offset_y = 0;
   2207         buf_planes->plane_info.mp[1].stride = stride;
   2208         buf_planes->plane_info.mp[1].scanline = scanline;
   2209         buf_planes->plane_info.mp[1].width = dim->width;
   2210         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2211 #else
   2212         CDBG_ERROR("%s: Venus hardware not avail, cannot use this format", __func__);
   2213         rc = -1;
   2214 #endif
   2215         break;
   2216     default:
   2217         CDBG_ERROR("%s: Invalid cam_format for preview %d",
   2218                    __func__, fmt);
   2219         rc = -1;
   2220         break;
   2221     }
   2222 
   2223     return rc;
   2224 }
   2225 /*===========================================================================
   2226  * FUNCTION   : mm_stream_calc_offset_post_view
   2227  *
   2228  * DESCRIPTION: calculate postview frame offset based on format and
   2229  *              padding information
   2230  *
   2231  * PARAMETERS :
   2232  *   @fmt     : image format
   2233  *   @dim     : image dimension
   2234  *   @buf_planes : [out] buffer plane information
   2235  *
   2236  * RETURN     : int32_t type of status
   2237  *              0  -- success
   2238  *              -1 -- failure
   2239  *==========================================================================*/
   2240 int32_t mm_stream_calc_offset_post_view(cam_format_t fmt,
   2241                                       cam_dimension_t *dim,
   2242                                       cam_stream_buf_plane_info_t *buf_planes)
   2243 {
   2244     int32_t rc = 0;
   2245     int stride = 0, scanline = 0;
   2246 
   2247     switch (fmt) {
   2248     case CAM_FORMAT_YUV_420_NV12:
   2249     case CAM_FORMAT_YUV_420_NV21:
   2250         /* 2 planes: Y + CbCr */
   2251         buf_planes->plane_info.num_planes = 2;
   2252 
   2253         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_64);
   2254         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_64);
   2255         buf_planes->plane_info.mp[0].offset = 0;
   2256         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2257         buf_planes->plane_info.mp[0].offset_x = 0;
   2258         buf_planes->plane_info.mp[0].offset_y = 0;
   2259         buf_planes->plane_info.mp[0].stride = stride;
   2260         buf_planes->plane_info.mp[0].scanline = scanline;
   2261         buf_planes->plane_info.mp[0].width = dim->width;
   2262         buf_planes->plane_info.mp[0].height = dim->height;
   2263 
   2264         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_64);
   2265         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_64);
   2266         buf_planes->plane_info.mp[1].offset = 0;
   2267         buf_planes->plane_info.mp[1].len =
   2268             (uint32_t)(stride * scanline);
   2269         buf_planes->plane_info.mp[1].offset_x = 0;
   2270         buf_planes->plane_info.mp[1].offset_y = 0;
   2271         buf_planes->plane_info.mp[1].stride = stride;
   2272         buf_planes->plane_info.mp[1].scanline = scanline;
   2273         buf_planes->plane_info.mp[1].width = dim->width;
   2274         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2275 
   2276         buf_planes->plane_info.frame_len =
   2277                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2278                         buf_planes->plane_info.mp[1].len,
   2279                         CAM_PAD_TO_4K);
   2280         break;
   2281     case CAM_FORMAT_YUV_420_NV21_ADRENO:
   2282         /* 2 planes: Y + CbCr */
   2283         buf_planes->plane_info.num_planes = 2;
   2284 
   2285         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   2286         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_32);
   2287         buf_planes->plane_info.mp[0].offset = 0;
   2288         buf_planes->plane_info.mp[0].len =
   2289                 PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_4K);
   2290         buf_planes->plane_info.mp[0].offset_x = 0;
   2291         buf_planes->plane_info.mp[0].offset_y = 0;
   2292         buf_planes->plane_info.mp[0].stride = stride;
   2293         buf_planes->plane_info.mp[0].scanline = scanline;
   2294         buf_planes->plane_info.mp[0].width = dim->width;
   2295         buf_planes->plane_info.mp[0].height = dim->height;
   2296 
   2297         stride = PAD_TO_SIZE(dim->width / 2, CAM_PAD_TO_32) * 2;
   2298         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_32);
   2299         buf_planes->plane_info.mp[1].offset = 0;
   2300         buf_planes->plane_info.mp[1].len =
   2301                 PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_4K);
   2302         buf_planes->plane_info.mp[1].offset_x = 0;
   2303         buf_planes->plane_info.mp[1].offset_y = 0;
   2304         buf_planes->plane_info.mp[1].stride = stride;
   2305         buf_planes->plane_info.mp[1].scanline = scanline;
   2306         buf_planes->plane_info.mp[1].width = dim->width;
   2307         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2308 
   2309         buf_planes->plane_info.frame_len =
   2310                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2311                         buf_planes->plane_info.mp[1].len,
   2312                         CAM_PAD_TO_4K);
   2313         break;
   2314     case CAM_FORMAT_YUV_420_YV12:
   2315         /* 3 planes: Y + Cr + Cb */
   2316         buf_planes->plane_info.num_planes = 3;
   2317 
   2318         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2319         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_2);
   2320         buf_planes->plane_info.mp[0].offset = 0;
   2321         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2322         buf_planes->plane_info.mp[0].offset_x = 0;
   2323         buf_planes->plane_info.mp[0].offset_y = 0;
   2324         buf_planes->plane_info.mp[0].stride = stride;
   2325         buf_planes->plane_info.mp[0].scanline = scanline;
   2326         buf_planes->plane_info.mp[0].width = dim->width;
   2327         buf_planes->plane_info.mp[0].height = dim->height;
   2328 
   2329         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   2330         scanline = scanline / 2;
   2331         buf_planes->plane_info.mp[1].offset = 0;
   2332         buf_planes->plane_info.mp[1].len =
   2333             (uint32_t)(stride * scanline);
   2334         buf_planes->plane_info.mp[1].offset_x = 0;
   2335         buf_planes->plane_info.mp[1].offset_y = 0;
   2336         buf_planes->plane_info.mp[1].stride = stride;
   2337         buf_planes->plane_info.mp[1].scanline = scanline;
   2338         buf_planes->plane_info.mp[1].width = dim->width / 2;
   2339         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2340 
   2341         buf_planes->plane_info.mp[2].offset = 0;
   2342         buf_planes->plane_info.mp[2].len =
   2343             (uint32_t)(stride * scanline);
   2344         buf_planes->plane_info.mp[2].offset_x = 0;
   2345         buf_planes->plane_info.mp[2].offset_y = 0;
   2346         buf_planes->plane_info.mp[2].stride = stride;
   2347         buf_planes->plane_info.mp[2].scanline = scanline;
   2348         buf_planes->plane_info.mp[2].width = dim->width / 2;
   2349         buf_planes->plane_info.mp[2].height = dim->height / 2;
   2350 
   2351         buf_planes->plane_info.frame_len =
   2352                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2353                         buf_planes->plane_info.mp[1].len +
   2354                         buf_planes->plane_info.mp[2].len,
   2355                         CAM_PAD_TO_4K);
   2356         break;
   2357     case CAM_FORMAT_YUV_422_NV16:
   2358     case CAM_FORMAT_YUV_422_NV61:
   2359         /* 2 planes: Y + CbCr */
   2360         buf_planes->plane_info.num_planes = 2;
   2361 
   2362         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2363         scanline = dim->height;
   2364         buf_planes->plane_info.mp[0].offset = 0;
   2365         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2366         buf_planes->plane_info.mp[0].offset_x = 0;
   2367         buf_planes->plane_info.mp[0].offset_y = 0;
   2368         buf_planes->plane_info.mp[0].stride = stride;
   2369         buf_planes->plane_info.mp[0].scanline = scanline;
   2370         buf_planes->plane_info.mp[0].width = dim->width;
   2371         buf_planes->plane_info.mp[0].height = dim->height;
   2372 
   2373         buf_planes->plane_info.mp[1].offset = 0;
   2374         buf_planes->plane_info.mp[1].len = (uint32_t)(stride * scanline);
   2375         buf_planes->plane_info.mp[1].offset_x = 0;
   2376         buf_planes->plane_info.mp[1].offset_y = 0;
   2377         buf_planes->plane_info.mp[1].stride = stride;
   2378         buf_planes->plane_info.mp[1].scanline = scanline;
   2379         buf_planes->plane_info.mp[1].width = dim->width;
   2380         buf_planes->plane_info.mp[1].height = dim->height;
   2381 
   2382         buf_planes->plane_info.frame_len =
   2383                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2384                         buf_planes->plane_info.mp[1].len,
   2385                         CAM_PAD_TO_4K);
   2386         break;
   2387     case CAM_FORMAT_YUV_420_NV12_VENUS:
   2388 #ifdef VENUS_PRESENT
   2389         // using Venus
   2390         stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   2391         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   2392 
   2393         buf_planes->plane_info.frame_len =
   2394             VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   2395         buf_planes->plane_info.num_planes = 2;
   2396         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2397         buf_planes->plane_info.mp[0].offset = 0;
   2398         buf_planes->plane_info.mp[0].offset_x =0;
   2399         buf_planes->plane_info.mp[0].offset_y = 0;
   2400         buf_planes->plane_info.mp[0].stride = stride;
   2401         buf_planes->plane_info.mp[0].scanline = scanline;
   2402         buf_planes->plane_info.mp[0].width = dim->width;
   2403         buf_planes->plane_info.mp[0].height = dim->height;
   2404         stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   2405         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   2406         buf_planes->plane_info.mp[1].len =
   2407             buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2408         buf_planes->plane_info.mp[1].offset = 0;
   2409         buf_planes->plane_info.mp[1].offset_x =0;
   2410         buf_planes->plane_info.mp[1].offset_y = 0;
   2411         buf_planes->plane_info.mp[1].stride = stride;
   2412         buf_planes->plane_info.mp[1].scanline = scanline;
   2413         buf_planes->plane_info.mp[1].width = dim->width;
   2414         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2415 #else
   2416         CDBG_ERROR("%s: Venus hardware not avail, cannot use this format", __func__);
   2417         rc = -1;
   2418 #endif
   2419         break;
   2420     default:
   2421         CDBG_ERROR("%s: Invalid cam_format for preview %d",
   2422                    __func__, fmt);
   2423         rc = -1;
   2424         break;
   2425     }
   2426 
   2427     return rc;
   2428 }
   2429 
   2430 /*===========================================================================
   2431  * FUNCTION   : mm_stream_calc_offset_snapshot
   2432  *
   2433  * DESCRIPTION: calculate snapshot/postproc frame offset based on format and
   2434  *              padding information
   2435  *
   2436  * PARAMETERS :
   2437  *   @fmt     : image format
   2438  *   @dim     : image dimension
   2439  *   @padding : padding information
   2440  *   @buf_planes : [out] buffer plane information
   2441  *
   2442  * RETURN     : int32_t type of status
   2443  *              0  -- success
   2444  *              -1 -- failure
   2445  *==========================================================================*/
   2446 int32_t mm_stream_calc_offset_snapshot(cam_format_t fmt,
   2447                                        cam_dimension_t *dim,
   2448                                        cam_padding_info_t *padding,
   2449                                        cam_stream_buf_plane_info_t *buf_planes)
   2450 {
   2451     int32_t rc = 0;
   2452     uint8_t isAFamily = mm_camera_util_chip_is_a_family();
   2453     int offset_x = 0, offset_y = 0;
   2454     int stride = 0, scanline = 0;
   2455 
   2456     if (isAFamily) {
   2457         stride = dim->width;
   2458         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_16);
   2459         offset_x = 0;
   2460         offset_y = scanline - dim->height;
   2461         scanline += offset_y; /* double padding */
   2462     } else {
   2463         stride = PAD_TO_SIZE(dim->width,
   2464                              padding->width_padding);
   2465         scanline = PAD_TO_SIZE(dim->height,
   2466                                padding->height_padding);
   2467         offset_x = 0;
   2468         offset_y = 0;
   2469     }
   2470 
   2471     switch (fmt) {
   2472     case CAM_FORMAT_YUV_420_NV12:
   2473     case CAM_FORMAT_YUV_420_NV21:
   2474         /* 2 planes: Y + CbCr */
   2475         buf_planes->plane_info.num_planes = 2;
   2476 
   2477         buf_planes->plane_info.mp[0].len =
   2478                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2479                         padding->plane_padding);
   2480         buf_planes->plane_info.mp[0].offset =
   2481                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   2482                         padding->plane_padding);
   2483         buf_planes->plane_info.mp[0].offset_x = offset_x;
   2484         buf_planes->plane_info.mp[0].offset_y = offset_y;
   2485         buf_planes->plane_info.mp[0].stride = stride;
   2486         buf_planes->plane_info.mp[0].scanline = scanline;
   2487         buf_planes->plane_info.mp[0].width = dim->width;
   2488         buf_planes->plane_info.mp[0].height = dim->height;
   2489 
   2490         scanline = scanline / 2;
   2491         buf_planes->plane_info.mp[1].len =
   2492                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2493                         padding->plane_padding);
   2494         buf_planes->plane_info.mp[1].offset =
   2495                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   2496                         padding->plane_padding);
   2497         buf_planes->plane_info.mp[1].offset_x = offset_x;
   2498         buf_planes->plane_info.mp[1].offset_y = offset_y;
   2499         buf_planes->plane_info.mp[1].stride = stride;
   2500         buf_planes->plane_info.mp[1].scanline = scanline;
   2501         buf_planes->plane_info.mp[1].width = dim->width;
   2502         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2503 
   2504         buf_planes->plane_info.frame_len =
   2505                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2506                         buf_planes->plane_info.mp[1].len,
   2507                         CAM_PAD_TO_4K);
   2508         break;
   2509     case CAM_FORMAT_YUV_420_YV12:
   2510         /* 3 planes: Y + Cr + Cb */
   2511         buf_planes->plane_info.num_planes = 3;
   2512 
   2513         buf_planes->plane_info.mp[0].offset =
   2514                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   2515                         padding->plane_padding);
   2516         buf_planes->plane_info.mp[0].len =
   2517                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2518                         padding->plane_padding);
   2519         buf_planes->plane_info.mp[0].offset_x = offset_x;
   2520         buf_planes->plane_info.mp[0].offset_y = offset_y;
   2521         buf_planes->plane_info.mp[0].stride = stride;
   2522         buf_planes->plane_info.mp[0].scanline = scanline;
   2523         buf_planes->plane_info.mp[0].width = dim->width;
   2524         buf_planes->plane_info.mp[0].height = dim->height;
   2525 
   2526         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   2527         scanline = scanline / 2;
   2528         buf_planes->plane_info.mp[1].offset =
   2529                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   2530                         padding->plane_padding);
   2531         buf_planes->plane_info.mp[1].len =
   2532                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2533                         padding->plane_padding);
   2534         buf_planes->plane_info.mp[1].offset_x = offset_x;
   2535         buf_planes->plane_info.mp[1].offset_y = offset_y;
   2536         buf_planes->plane_info.mp[1].stride = stride;
   2537         buf_planes->plane_info.mp[1].scanline = scanline;
   2538         buf_planes->plane_info.mp[1].width = dim->width / 2;
   2539         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2540 
   2541         buf_planes->plane_info.mp[2].offset =
   2542                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   2543                         padding->plane_padding);
   2544         buf_planes->plane_info.mp[2].len =
   2545                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2546                         padding->plane_padding);
   2547         buf_planes->plane_info.mp[2].offset_x = offset_x;
   2548         buf_planes->plane_info.mp[2].offset_y = offset_y;
   2549         buf_planes->plane_info.mp[2].stride = stride;
   2550         buf_planes->plane_info.mp[2].scanline = scanline;
   2551         buf_planes->plane_info.mp[2].width = dim->width / 2;
   2552         buf_planes->plane_info.mp[2].height = dim->height / 2;
   2553 
   2554         buf_planes->plane_info.frame_len =
   2555                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2556                         buf_planes->plane_info.mp[1].len +
   2557                         buf_planes->plane_info.mp[2].len,
   2558                         CAM_PAD_TO_4K);
   2559         break;
   2560     case CAM_FORMAT_YUV_422_NV16:
   2561     case CAM_FORMAT_YUV_422_NV61:
   2562         /* 2 planes: Y + CbCr */
   2563         buf_planes->plane_info.num_planes = 2;
   2564         buf_planes->plane_info.mp[0].len =
   2565                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2566                         padding->plane_padding);
   2567         buf_planes->plane_info.mp[0].offset =
   2568                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   2569                         padding->plane_padding);
   2570         buf_planes->plane_info.mp[0].offset_x = offset_x;
   2571         buf_planes->plane_info.mp[0].offset_y = offset_y;
   2572         buf_planes->plane_info.mp[0].stride = stride;
   2573         buf_planes->plane_info.mp[0].scanline = scanline;
   2574         buf_planes->plane_info.mp[0].width = dim->width;
   2575         buf_planes->plane_info.mp[0].height = dim->height;
   2576 
   2577         buf_planes->plane_info.mp[1].len =
   2578                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2579                         padding->plane_padding);
   2580         buf_planes->plane_info.mp[1].offset =
   2581                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   2582                         padding->plane_padding);
   2583         buf_planes->plane_info.mp[1].offset_x = offset_x;
   2584         buf_planes->plane_info.mp[1].offset_y = offset_y;
   2585         buf_planes->plane_info.mp[1].stride = stride;
   2586         buf_planes->plane_info.mp[1].scanline = scanline;
   2587         buf_planes->plane_info.mp[1].width = dim->width;
   2588         buf_planes->plane_info.mp[1].height = dim->height;
   2589 
   2590         buf_planes->plane_info.frame_len = PAD_TO_SIZE(
   2591             buf_planes->plane_info.mp[0].len + buf_planes->plane_info.mp[1].len,
   2592             CAM_PAD_TO_4K);
   2593         break;
   2594     default:
   2595         CDBG_ERROR("%s: Invalid cam_format for snapshot %d",
   2596                    __func__, fmt);
   2597         rc = -1;
   2598         break;
   2599     }
   2600 
   2601     return rc;
   2602 }
   2603 
   2604 /*===========================================================================
   2605  * FUNCTION   : mm_stream_calc_offset_raw
   2606  *
   2607  * DESCRIPTION: calculate raw frame offset based on format and padding information
   2608  *
   2609  * PARAMETERS :
   2610  *   @fmt     : image format
   2611  *   @dim     : image dimension
   2612  *   @padding : padding information
   2613  *   @buf_planes : [out] buffer plane information
   2614  *
   2615  * RETURN     : int32_t type of status
   2616  *              0  -- success
   2617  *              -1 -- failure
   2618  *==========================================================================*/
   2619 int32_t mm_stream_calc_offset_raw(cam_format_t fmt,
   2620                                   cam_dimension_t *dim,
   2621                                   cam_padding_info_t *padding,
   2622                                   cam_stream_buf_plane_info_t *buf_planes)
   2623 {
   2624     int32_t rc = 0;
   2625 
   2626     if ((NULL == dim) || (NULL == padding) || (NULL == buf_planes)) {
   2627         return -1;
   2628     }
   2629 
   2630     int32_t stride = PAD_TO_SIZE(dim->width, (int32_t)padding->width_padding);
   2631     int32_t stride_in_bytes = stride;
   2632     int32_t scanline = PAD_TO_SIZE(dim->height, (int32_t)padding->height_padding);
   2633 
   2634     switch (fmt) {
   2635     case CAM_FORMAT_YUV_420_NV21:
   2636         /* 2 planes: Y + CbCr */
   2637         buf_planes->plane_info.num_planes = 2;
   2638 
   2639         buf_planes->plane_info.mp[0].len =
   2640                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2641                 padding->plane_padding);
   2642         buf_planes->plane_info.mp[0].offset = 0;
   2643         buf_planes->plane_info.mp[0].offset_x = 0;
   2644         buf_planes->plane_info.mp[0].offset_y = 0;
   2645         buf_planes->plane_info.mp[0].stride = stride;
   2646         buf_planes->plane_info.mp[0].stride_in_bytes = stride;
   2647         buf_planes->plane_info.mp[0].scanline = scanline;
   2648         buf_planes->plane_info.mp[0].width = dim->width;
   2649         buf_planes->plane_info.mp[0].height = dim->height;
   2650 
   2651         scanline = scanline / 2;
   2652         buf_planes->plane_info.mp[1].len =
   2653                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   2654                 padding->plane_padding);
   2655         buf_planes->plane_info.mp[1].offset = 0;
   2656         buf_planes->plane_info.mp[1].offset_x = 0;
   2657         buf_planes->plane_info.mp[1].offset_y = 0;
   2658         buf_planes->plane_info.mp[1].stride = stride;
   2659         buf_planes->plane_info.mp[1].stride_in_bytes = stride;
   2660         buf_planes->plane_info.mp[1].scanline = scanline;
   2661         buf_planes->plane_info.mp[1].width = dim->width;
   2662         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2663 
   2664         buf_planes->plane_info.frame_len =
   2665                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2666                 buf_planes->plane_info.mp[1].len,
   2667                 CAM_PAD_TO_4K);
   2668         break;
   2669     case CAM_FORMAT_YUV_RAW_8BIT_YUYV:
   2670     case CAM_FORMAT_YUV_RAW_8BIT_YVYU:
   2671     case CAM_FORMAT_YUV_RAW_8BIT_UYVY:
   2672     case CAM_FORMAT_YUV_RAW_8BIT_VYUY:
   2673     case CAM_FORMAT_JPEG_RAW_8BIT:
   2674         /* 1 plane */
   2675         /* Every 16 pixels occupy 16 bytes */
   2676         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2677         stride_in_bytes = stride * 2;
   2678         buf_planes->plane_info.num_planes = 1;
   2679         buf_planes->plane_info.mp[0].offset = 0;
   2680         buf_planes->plane_info.mp[0].len =
   2681                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   2682                         padding->plane_padding);
   2683         buf_planes->plane_info.frame_len =
   2684                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2685         buf_planes->plane_info.mp[0].offset_x =0;
   2686         buf_planes->plane_info.mp[0].offset_y = 0;
   2687         buf_planes->plane_info.mp[0].stride = stride;
   2688         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   2689         buf_planes->plane_info.mp[0].scanline = scanline;
   2690         buf_planes->plane_info.mp[0].width =
   2691                 (int32_t)buf_planes->plane_info.mp[0].len;
   2692         buf_planes->plane_info.mp[0].height = 1;
   2693         break;
   2694     case CAM_FORMAT_META_RAW_8BIT:
   2695         // Every 16 pixels occupy 16 bytes
   2696         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2697         stride_in_bytes = stride * 2;
   2698         buf_planes->plane_info.num_planes = 1;
   2699         buf_planes->plane_info.mp[0].offset = 0;
   2700         buf_planes->plane_info.mp[0].len =
   2701                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   2702                         padding->plane_padding);
   2703         buf_planes->plane_info.frame_len =
   2704                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2705         buf_planes->plane_info.mp[0].offset_x =0;
   2706         buf_planes->plane_info.mp[0].offset_y = 0;
   2707         buf_planes->plane_info.mp[0].stride = stride;
   2708         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   2709         buf_planes->plane_info.mp[0].scanline = scanline;
   2710         break;
   2711 
   2712     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GBRG:
   2713     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GRBG:
   2714     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_RGGB:
   2715     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_BGGR:
   2716     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG:
   2717     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GRBG:
   2718     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_RGGB:
   2719     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_BGGR:
   2720     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GBRG:
   2721     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GRBG:
   2722     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_RGGB:
   2723     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_BGGR:
   2724     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GBRG:
   2725     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GRBG:
   2726     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_RGGB:
   2727     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_BGGR:
   2728     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_GBRG:
   2729     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_GRBG:
   2730     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_RGGB:
   2731     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_BGGR:
   2732         /* 1 plane */
   2733         /* Every 16 pixels occupy 16 bytes */
   2734         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2735         stride_in_bytes = stride;
   2736         buf_planes->plane_info.num_planes = 1;
   2737         buf_planes->plane_info.mp[0].offset = 0;
   2738         buf_planes->plane_info.mp[0].len =
   2739                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   2740                         padding->plane_padding);
   2741         buf_planes->plane_info.frame_len =
   2742                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2743         buf_planes->plane_info.mp[0].offset_x =0;
   2744         buf_planes->plane_info.mp[0].offset_y = 0;
   2745         buf_planes->plane_info.mp[0].stride = stride;
   2746         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   2747         buf_planes->plane_info.mp[0].scanline = scanline;
   2748         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   2749         buf_planes->plane_info.mp[0].height = 1;
   2750         break;
   2751     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG:
   2752     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GRBG:
   2753     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_RGGB:
   2754     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_BGGR:
   2755     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GBRG:
   2756     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GRBG:
   2757     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_RGGB:
   2758     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_BGGR:
   2759         /* Every 12 pixels occupy 16 bytes */
   2760         stride = (dim->width + 11)/12 * 12;
   2761         stride_in_bytes = stride * 8 / 6;
   2762         buf_planes->plane_info.num_planes = 1;
   2763         buf_planes->plane_info.mp[0].offset = 0;
   2764         buf_planes->plane_info.mp[0].len =
   2765                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   2766                         padding->plane_padding);
   2767         buf_planes->plane_info.frame_len =
   2768                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2769         buf_planes->plane_info.mp[0].offset_x =0;
   2770         buf_planes->plane_info.mp[0].offset_y = 0;
   2771         buf_planes->plane_info.mp[0].stride = stride;
   2772         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   2773         buf_planes->plane_info.mp[0].scanline = scanline;
   2774         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   2775         buf_planes->plane_info.mp[0].height = 1;
   2776         break;
   2777     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GBRG:
   2778     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GRBG:
   2779     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_RGGB:
   2780     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_BGGR:
   2781     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GBRG:
   2782     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GRBG:
   2783     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_RGGB:
   2784     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_BGGR:
   2785         /* Every 10 pixels occupy 16 bytes */
   2786         stride = (dim->width + 9)/10 * 10;
   2787         stride_in_bytes = stride * 8 / 5;
   2788         buf_planes->plane_info.num_planes = 1;
   2789         buf_planes->plane_info.mp[0].offset = 0;
   2790         buf_planes->plane_info.mp[0].len =
   2791                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   2792                         padding->plane_padding);
   2793         buf_planes->plane_info.frame_len =
   2794                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2795         buf_planes->plane_info.mp[0].offset_x =0;
   2796         buf_planes->plane_info.mp[0].offset_y = 0;
   2797         buf_planes->plane_info.mp[0].stride = stride;
   2798         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   2799         buf_planes->plane_info.mp[0].scanline = scanline;
   2800         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   2801         buf_planes->plane_info.mp[0].height = 1;
   2802         break;
   2803     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG:
   2804     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GRBG:
   2805     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_RGGB:
   2806     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_BGGR:
   2807     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GBRG:
   2808     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GRBG:
   2809     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_RGGB:
   2810     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_BGGR:
   2811         /* Every 64 pixels occupy 80 bytes */
   2812         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_4);
   2813         stride_in_bytes = PAD_TO_SIZE(stride * 5 / 4, CAM_PAD_TO_8);
   2814         buf_planes->plane_info.num_planes = 1;
   2815         buf_planes->plane_info.mp[0].offset = 0;
   2816         buf_planes->plane_info.mp[0].len =
   2817                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   2818                         padding->plane_padding);
   2819         buf_planes->plane_info.frame_len =
   2820                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2821         buf_planes->plane_info.mp[0].offset_x =0;
   2822         buf_planes->plane_info.mp[0].offset_y = 0;
   2823         buf_planes->plane_info.mp[0].stride = stride;
   2824         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   2825         buf_planes->plane_info.mp[0].scanline = scanline;
   2826         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   2827         buf_planes->plane_info.mp[0].height = 1;
   2828         break;
   2829     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GBRG:
   2830     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GRBG:
   2831     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_RGGB:
   2832     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR:
   2833     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GBRG:
   2834     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GRBG:
   2835     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_RGGB:
   2836     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_BGGR:
   2837         /* Every 32 pixels occupy 48 bytes */
   2838         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   2839         stride_in_bytes = stride * 3 / 2;
   2840         buf_planes->plane_info.num_planes = 1;
   2841         buf_planes->plane_info.mp[0].offset = 0;
   2842         buf_planes->plane_info.mp[0].len =
   2843                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   2844                         padding->plane_padding);
   2845         buf_planes->plane_info.frame_len =
   2846                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2847         buf_planes->plane_info.mp[0].offset_x =0;
   2848         buf_planes->plane_info.mp[0].offset_y = 0;
   2849         buf_planes->plane_info.mp[0].stride = stride;
   2850         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   2851         buf_planes->plane_info.mp[0].scanline = scanline;
   2852         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   2853         buf_planes->plane_info.mp[0].height = 1;
   2854         break;
   2855     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_GBRG:
   2856     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_GRBG:
   2857     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_RGGB:
   2858     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_BGGR:
   2859     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_GBRG:
   2860     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_GRBG:
   2861     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_RGGB:
   2862     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_BGGR:
   2863     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_GBRG:
   2864     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_GRBG:
   2865     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_RGGB:
   2866     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_BGGR:
   2867         /* Every 8 pixels occupy 16 bytes */
   2868         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_8);
   2869         stride_in_bytes = stride * 2;
   2870         buf_planes->plane_info.num_planes = 1;
   2871         buf_planes->plane_info.mp[0].offset = 0;
   2872         buf_planes->plane_info.mp[0].len =
   2873                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   2874                         padding->plane_padding);
   2875         buf_planes->plane_info.frame_len =
   2876                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2877         buf_planes->plane_info.mp[0].offset_x =0;
   2878         buf_planes->plane_info.mp[0].offset_y = 0;
   2879         buf_planes->plane_info.mp[0].stride = stride;
   2880         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   2881         buf_planes->plane_info.mp[0].scanline = scanline;
   2882         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   2883         buf_planes->plane_info.mp[0].height = 1;
   2884         break;
   2885     default:
   2886         CDBG_ERROR("%s: Invalid cam_format %d for raw stream",
   2887                    __func__, fmt);
   2888         rc = -1;
   2889         break;
   2890     }
   2891 
   2892     return rc;
   2893 }
   2894 
   2895 /*===========================================================================
   2896  * FUNCTION   : mm_stream_calc_offset_video
   2897  *
   2898  * DESCRIPTION: calculate video frame offset based on format and
   2899  *              padding information
   2900  *
   2901  * PARAMETERS :
   2902  *   @dim     : image dimension
   2903  *   @buf_planes : [out] buffer plane information
   2904  *
   2905  * RETURN     : int32_t type of status
   2906  *              0  -- success
   2907  *              -1 -- failure
   2908  *==========================================================================*/
   2909 #ifdef VENUS_PRESENT
   2910 int32_t mm_stream_calc_offset_video(cam_dimension_t *dim,
   2911                                     cam_stream_buf_plane_info_t *buf_planes)
   2912 {
   2913     int stride = 0, scanline = 0;
   2914 
   2915     // using Venus
   2916     stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   2917     scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   2918 
   2919     buf_planes->plane_info.frame_len =
   2920         VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   2921     buf_planes->plane_info.num_planes = 2;
   2922     buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2923     buf_planes->plane_info.mp[0].offset = 0;
   2924     buf_planes->plane_info.mp[0].offset_x =0;
   2925     buf_planes->plane_info.mp[0].offset_y = 0;
   2926     buf_planes->plane_info.mp[0].stride = stride;
   2927     buf_planes->plane_info.mp[0].scanline = scanline;
   2928     buf_planes->plane_info.mp[0].width = dim->width;
   2929     buf_planes->plane_info.mp[0].height = dim->height;
   2930     stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   2931     scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   2932     buf_planes->plane_info.mp[1].len =
   2933         buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2934     buf_planes->plane_info.mp[1].offset = 0;
   2935     buf_planes->plane_info.mp[1].offset_x =0;
   2936     buf_planes->plane_info.mp[1].offset_y = 0;
   2937     buf_planes->plane_info.mp[1].stride = stride;
   2938     buf_planes->plane_info.mp[1].scanline = scanline;
   2939     buf_planes->plane_info.mp[1].width = dim->width;
   2940     buf_planes->plane_info.mp[1].height = dim->height / 2;
   2941 
   2942     return 0;
   2943 }
   2944 #else
   2945 int32_t mm_stream_calc_offset_video(cam_dimension_t *dim,
   2946                                     cam_stream_buf_plane_info_t *buf_planes)
   2947 {
   2948     int stride = 0, scanline = 0;
   2949 
   2950     buf_planes->plane_info.num_planes = 2;
   2951 
   2952     stride = dim->width;
   2953     scanline = dim->height;
   2954     buf_planes->plane_info.mp[0].len =
   2955             PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_2K);
   2956     buf_planes->plane_info.mp[0].offset = 0;
   2957     buf_planes->plane_info.mp[0].offset_x =0;
   2958     buf_planes->plane_info.mp[0].offset_y = 0;
   2959     buf_planes->plane_info.mp[0].stride = stride;
   2960     buf_planes->plane_info.mp[0].scanline = scanline;
   2961     buf_planes->plane_info.mp[0].width = dim->width;
   2962     buf_planes->plane_info.mp[0].height = dim->height;
   2963 
   2964     stride = dim->width;
   2965     scanline = dim->height / 2;
   2966     buf_planes->plane_info.mp[1].len =
   2967             PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_2K);
   2968     buf_planes->plane_info.mp[1].offset = 0;
   2969     buf_planes->plane_info.mp[1].offset_x =0;
   2970     buf_planes->plane_info.mp[1].offset_y = 0;
   2971     buf_planes->plane_info.mp[1].stride = stride;
   2972     buf_planes->plane_info.mp[1].scanline = scanline;
   2973     buf_planes->plane_info.mp[1].width = dim->width;
   2974     buf_planes->plane_info.mp[1].height = dim->height / 2;
   2975 
   2976     buf_planes->plane_info.frame_len =
   2977             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2978                     buf_planes->plane_info.mp[1].len,
   2979                     CAM_PAD_TO_4K);
   2980 
   2981     return 0;
   2982 }
   2983 #endif
   2984 
   2985 /*===========================================================================
   2986  * FUNCTION   : mm_stream_calc_offset_metadata
   2987  *
   2988  * DESCRIPTION: calculate metadata frame offset based on format and
   2989  *              padding information
   2990  *
   2991  * PARAMETERS :
   2992  *   @dim     : image dimension
   2993  *   @padding : padding information
   2994  *   @buf_planes : [out] buffer plane information
   2995  *
   2996  * RETURN     : int32_t type of status
   2997  *              0  -- success
   2998  *              -1 -- failure
   2999  *==========================================================================*/
   3000 int32_t mm_stream_calc_offset_metadata(cam_dimension_t *dim,
   3001                                        cam_padding_info_t *padding,
   3002                                        cam_stream_buf_plane_info_t *buf_planes)
   3003 {
   3004     int32_t rc = 0;
   3005     buf_planes->plane_info.num_planes = 1;
   3006     buf_planes->plane_info.mp[0].offset = 0;
   3007     buf_planes->plane_info.mp[0].len =
   3008             PAD_TO_SIZE((uint32_t)(dim->width * dim->height),
   3009                     padding->plane_padding);
   3010     buf_planes->plane_info.frame_len =
   3011         buf_planes->plane_info.mp[0].len;
   3012 
   3013     buf_planes->plane_info.mp[0].offset_x =0;
   3014     buf_planes->plane_info.mp[0].offset_y = 0;
   3015     buf_planes->plane_info.mp[0].stride = dim->width;
   3016     buf_planes->plane_info.mp[0].scanline = dim->height;
   3017     buf_planes->plane_info.mp[0].width = dim->width;
   3018     buf_planes->plane_info.mp[0].height = dim->height;
   3019     return rc;
   3020 }
   3021 
   3022 /*===========================================================================
   3023  * FUNCTION   : mm_stream_calc_offset_analysis
   3024  *
   3025  * DESCRIPTION: calculate analysis frame offset based on format and
   3026  *              padding information
   3027  *
   3028  * PARAMETERS :
   3029  *   @fmt     : image format
   3030  *   @dim     : image dimension
   3031  *   @padding : padding information
   3032  *   @buf_planes : [out] buffer plane information
   3033  *
   3034  * RETURN     : int32_t type of status
   3035  *              0  -- success
   3036  *              -1 -- failure
   3037  *==========================================================================*/
   3038 int32_t mm_stream_calc_offset_analysis(cam_format_t fmt,
   3039                                        cam_dimension_t *dim,
   3040                                        cam_padding_info_t *padding,
   3041                                        cam_stream_buf_plane_info_t *buf_planes)
   3042 {
   3043     int32_t rc = 0;
   3044     int32_t offset_x = 0, offset_y = 0;
   3045     int32_t stride, scanline;
   3046 
   3047     /* Clip to minimum supported bytes per line */
   3048     if ((uint32_t)dim->width < padding->min_stride) {
   3049         stride = (int32_t)padding->min_stride;
   3050     } else {
   3051         stride = dim->width;
   3052     }
   3053 
   3054     if ((uint32_t)dim->height < padding->min_scanline) {
   3055       scanline = (int32_t)padding->min_scanline;
   3056     } else {
   3057       scanline = dim->height;
   3058     }
   3059 
   3060     stride = PAD_TO_SIZE(stride, padding->width_padding);
   3061     scanline = PAD_TO_SIZE(scanline, padding->height_padding);
   3062 
   3063     switch (fmt) {
   3064     case CAM_FORMAT_YUV_420_NV12:
   3065     case CAM_FORMAT_YUV_420_NV21:
   3066         /* 2 planes: Y + CbCr */
   3067         buf_planes->plane_info.num_planes = 2;
   3068 
   3069         buf_planes->plane_info.mp[0].len =
   3070                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3071                         padding->plane_padding);
   3072         buf_planes->plane_info.mp[0].offset =
   3073                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3074                         padding->plane_padding);
   3075         buf_planes->plane_info.mp[0].offset_x = offset_x;
   3076         buf_planes->plane_info.mp[0].offset_y = offset_y;
   3077         buf_planes->plane_info.mp[0].stride = stride;
   3078         buf_planes->plane_info.mp[0].scanline = scanline;
   3079         buf_planes->plane_info.mp[0].width = dim->width;
   3080         buf_planes->plane_info.mp[0].height = dim->height;
   3081 
   3082         scanline = scanline / 2;
   3083         buf_planes->plane_info.mp[1].len =
   3084                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3085                         padding->plane_padding);
   3086         buf_planes->plane_info.mp[1].offset =
   3087                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3088                         padding->plane_padding);
   3089         buf_planes->plane_info.mp[1].offset_x = offset_x;
   3090         buf_planes->plane_info.mp[1].offset_y = offset_y;
   3091         buf_planes->plane_info.mp[1].stride = stride;
   3092         buf_planes->plane_info.mp[1].scanline = scanline;
   3093         buf_planes->plane_info.mp[1].width = dim->width;
   3094         buf_planes->plane_info.mp[1].height = dim->height / 2;
   3095 
   3096         buf_planes->plane_info.frame_len =
   3097                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   3098                         buf_planes->plane_info.mp[1].len,
   3099                         CAM_PAD_TO_4K);
   3100         break;
   3101     case CAM_FORMAT_YUV_420_YV12:
   3102         /* 3 planes: Y + Cr + Cb */
   3103         buf_planes->plane_info.num_planes = 3;
   3104 
   3105         buf_planes->plane_info.mp[0].offset =
   3106                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3107                         padding->plane_padding);
   3108         buf_planes->plane_info.mp[0].len =
   3109                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3110                         padding->plane_padding);
   3111         buf_planes->plane_info.mp[0].offset_x = offset_x;
   3112         buf_planes->plane_info.mp[0].offset_y = offset_y;
   3113         buf_planes->plane_info.mp[0].stride = stride;
   3114         buf_planes->plane_info.mp[0].scanline = scanline;
   3115         buf_planes->plane_info.mp[0].width = dim->width;
   3116         buf_planes->plane_info.mp[0].height = dim->height;
   3117 
   3118         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   3119         scanline = scanline / 2;
   3120         buf_planes->plane_info.mp[1].offset =
   3121                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3122                         padding->plane_padding);
   3123         buf_planes->plane_info.mp[1].len =
   3124                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3125                         padding->plane_padding);
   3126         buf_planes->plane_info.mp[1].offset_x = offset_x;
   3127         buf_planes->plane_info.mp[1].offset_y = offset_y;
   3128         buf_planes->plane_info.mp[1].stride = stride;
   3129         buf_planes->plane_info.mp[1].scanline = scanline;
   3130         buf_planes->plane_info.mp[1].width = dim->width / 2;
   3131         buf_planes->plane_info.mp[1].height = dim->height / 2;
   3132 
   3133         buf_planes->plane_info.mp[2].offset =
   3134                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3135                         padding->plane_padding);
   3136         buf_planes->plane_info.mp[2].len =
   3137                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3138                         padding->plane_padding);
   3139         buf_planes->plane_info.mp[2].offset_x = offset_x;
   3140         buf_planes->plane_info.mp[2].offset_y = offset_y;
   3141         buf_planes->plane_info.mp[2].stride = stride;
   3142         buf_planes->plane_info.mp[2].scanline = scanline;
   3143         buf_planes->plane_info.mp[2].width = dim->width / 2;
   3144         buf_planes->plane_info.mp[2].height = dim->height / 2;
   3145 
   3146         buf_planes->plane_info.frame_len =
   3147                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   3148                         buf_planes->plane_info.mp[1].len +
   3149                         buf_planes->plane_info.mp[2].len,
   3150                         CAM_PAD_TO_4K);
   3151         break;
   3152     case CAM_FORMAT_YUV_422_NV16:
   3153     case CAM_FORMAT_YUV_422_NV61:
   3154         /* 2 planes: Y + CbCr */
   3155         buf_planes->plane_info.num_planes = 2;
   3156         buf_planes->plane_info.mp[0].len =
   3157                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3158                         padding->plane_padding);
   3159         buf_planes->plane_info.mp[0].offset =
   3160                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3161                         padding->plane_padding);
   3162         buf_planes->plane_info.mp[0].offset_x = offset_x;
   3163         buf_planes->plane_info.mp[0].offset_y = offset_y;
   3164         buf_planes->plane_info.mp[0].stride = stride;
   3165         buf_planes->plane_info.mp[0].scanline = scanline;
   3166         buf_planes->plane_info.mp[0].width = dim->width;
   3167         buf_planes->plane_info.mp[0].height = dim->height;
   3168 
   3169         buf_planes->plane_info.mp[1].len =
   3170                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3171                         padding->plane_padding);
   3172         buf_planes->plane_info.mp[1].offset =
   3173                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3174                         padding->plane_padding);
   3175         buf_planes->plane_info.mp[1].offset_x = offset_x;
   3176         buf_planes->plane_info.mp[1].offset_y = offset_y;
   3177         buf_planes->plane_info.mp[1].stride = stride;
   3178         buf_planes->plane_info.mp[1].scanline = scanline;
   3179         buf_planes->plane_info.mp[1].width = dim->width;
   3180         buf_planes->plane_info.mp[1].height = dim->height;
   3181 
   3182         buf_planes->plane_info.frame_len = PAD_TO_SIZE(
   3183             buf_planes->plane_info.mp[0].len + buf_planes->plane_info.mp[1].len,
   3184             CAM_PAD_TO_4K);
   3185         break;
   3186     case CAM_FORMAT_Y_ONLY:
   3187         buf_planes->plane_info.num_planes = 1;
   3188 
   3189         buf_planes->plane_info.mp[0].len =
   3190                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3191                 padding->plane_padding);
   3192         buf_planes->plane_info.mp[0].offset =
   3193                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3194                 padding->plane_padding);
   3195         buf_planes->plane_info.mp[0].offset_x = offset_x;
   3196         buf_planes->plane_info.mp[0].offset_y = offset_y;
   3197         buf_planes->plane_info.mp[0].stride = stride;
   3198         buf_planes->plane_info.mp[0].scanline = scanline;
   3199         buf_planes->plane_info.mp[0].width = dim->width;
   3200         buf_planes->plane_info.mp[0].height = dim->height;
   3201         buf_planes->plane_info.frame_len =
   3202                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3203       break;
   3204     default:
   3205         CDBG_ERROR("%s: Invalid cam_format for snapshot %d",
   3206                    __func__, fmt);
   3207         rc = -1;
   3208         break;
   3209     }
   3210 
   3211     return rc;
   3212 }
   3213 
   3214 /*===========================================================================
   3215  * FUNCTION   : mm_stream_calc_offset_postproc
   3216  *
   3217  * DESCRIPTION: calculate postprocess frame offset
   3218  *
   3219  * PARAMETERS :
   3220  *   @stream_info: ptr to stream info
   3221  *   @padding : padding information
   3222  *   @plns : [out] buffer plane information
   3223  *
   3224  * RETURN     : int32_t type of status
   3225  *              0  -- success
   3226  *              -1 -- failure
   3227  *==========================================================================*/
   3228 int32_t mm_stream_calc_offset_postproc(cam_stream_info_t *stream_info,
   3229                                        cam_padding_info_t *padding,
   3230                                        cam_stream_buf_plane_info_t *plns)
   3231 {
   3232     int32_t rc = 0;
   3233     cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT;
   3234     if (stream_info->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
   3235         type = stream_info->reprocess_config.offline.input_type;
   3236         if (CAM_STREAM_TYPE_DEFAULT == type) {
   3237             if (plns->plane_info.frame_len == 0) {
   3238                 // take offset from input source
   3239                 *plns = stream_info->reprocess_config.offline.input_buf_planes;
   3240                 return rc;
   3241             }
   3242         } else {
   3243             type = stream_info->reprocess_config.offline.input_type;
   3244         }
   3245     } else {
   3246         type = stream_info->reprocess_config.online.input_stream_type;
   3247     }
   3248 
   3249     switch (type) {
   3250     case CAM_STREAM_TYPE_PREVIEW:
   3251         rc = mm_stream_calc_offset_preview(stream_info->fmt,
   3252                                            &stream_info->dim,
   3253                                            plns);
   3254         break;
   3255     case CAM_STREAM_TYPE_POSTVIEW:
   3256         rc = mm_stream_calc_offset_post_view(stream_info->fmt,
   3257                                            &stream_info->dim,
   3258                                            plns);
   3259         break;
   3260     case CAM_STREAM_TYPE_SNAPSHOT:
   3261     case CAM_STREAM_TYPE_CALLBACK:
   3262         rc = mm_stream_calc_offset_snapshot(stream_info->fmt,
   3263                                             &stream_info->dim,
   3264                                             padding,
   3265                                             plns);
   3266         break;
   3267     case CAM_STREAM_TYPE_VIDEO:
   3268         rc = mm_stream_calc_offset_video(&stream_info->dim,
   3269                         plns);
   3270         break;
   3271     case CAM_STREAM_TYPE_RAW:
   3272         rc = mm_stream_calc_offset_raw(stream_info->fmt,
   3273                                        &stream_info->dim,
   3274                                        padding,
   3275                                        plns);
   3276         break;
   3277     case CAM_STREAM_TYPE_ANALYSIS:
   3278         rc = mm_stream_calc_offset_analysis(stream_info->fmt,
   3279                                             &stream_info->dim,
   3280                                             padding,
   3281                                             plns);
   3282         break;
   3283     case CAM_STREAM_TYPE_METADATA:
   3284         rc = mm_stream_calc_offset_metadata(&stream_info->dim,
   3285                                             padding,
   3286                                             plns);
   3287         break;
   3288     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3289         rc = mm_stream_calc_offset_snapshot(stream_info->fmt,
   3290                 &stream_info->dim, padding, plns);
   3291         break;
   3292     default:
   3293         CDBG_ERROR("%s: not supported for stream type %d",
   3294                    __func__, type);
   3295         rc = -1;
   3296         break;
   3297     }
   3298     return rc;
   3299 }
   3300 
   3301 /*===========================================================================
   3302  * FUNCTION   : mm_stream_calc_offset
   3303  *
   3304  * DESCRIPTION: calculate frame offset based on format and padding information
   3305  *
   3306  * PARAMETERS :
   3307  *   @my_obj  : stream object
   3308  *
   3309  * RETURN     : int32_t type of status
   3310  *              0  -- success
   3311  *              -1 -- failure
   3312  *==========================================================================*/
   3313 int32_t mm_stream_calc_offset(mm_stream_t *my_obj)
   3314 {
   3315     int32_t rc = 0;
   3316 
   3317     cam_dimension_t dim = my_obj->stream_info->dim;
   3318     if (my_obj->stream_info->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
   3319         my_obj->stream_info->stream_type != CAM_STREAM_TYPE_VIDEO) {
   3320         if (my_obj->stream_info->pp_config.rotation == ROTATE_90 ||
   3321             my_obj->stream_info->pp_config.rotation == ROTATE_270) {
   3322             // rotated by 90 or 270, need to switch width and height
   3323             dim.width = my_obj->stream_info->dim.height;
   3324             dim.height = my_obj->stream_info->dim.width;
   3325         }
   3326     }
   3327 
   3328     switch (my_obj->stream_info->stream_type) {
   3329     case CAM_STREAM_TYPE_PREVIEW:
   3330         rc = mm_stream_calc_offset_preview(my_obj->stream_info->fmt,
   3331                                            &dim,
   3332                                            &my_obj->stream_info->buf_planes);
   3333         break;
   3334     case CAM_STREAM_TYPE_POSTVIEW:
   3335       rc = mm_stream_calc_offset_post_view(my_obj->stream_info->fmt,
   3336                                          &dim,
   3337                                          &my_obj->stream_info->buf_planes);
   3338       break;
   3339     case CAM_STREAM_TYPE_SNAPSHOT:
   3340     case CAM_STREAM_TYPE_CALLBACK:
   3341         rc = mm_stream_calc_offset_snapshot(my_obj->stream_info->fmt,
   3342                                             &dim,
   3343                                             &my_obj->padding_info,
   3344                                             &my_obj->stream_info->buf_planes);
   3345         break;
   3346     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3347         rc = mm_stream_calc_offset_postproc(my_obj->stream_info,
   3348                                             &my_obj->padding_info,
   3349                                             &my_obj->stream_info->buf_planes);
   3350         break;
   3351     case CAM_STREAM_TYPE_VIDEO:
   3352         rc = mm_stream_calc_offset_video(&dim,
   3353                                          &my_obj->stream_info->buf_planes);
   3354         break;
   3355     case CAM_STREAM_TYPE_RAW:
   3356         rc = mm_stream_calc_offset_raw(my_obj->stream_info->fmt,
   3357                                        &dim,
   3358                                        &my_obj->padding_info,
   3359                                        &my_obj->stream_info->buf_planes);
   3360         break;
   3361     case CAM_STREAM_TYPE_ANALYSIS:
   3362         rc = mm_stream_calc_offset_analysis(my_obj->stream_info->fmt,
   3363                                             &dim,
   3364                                             &my_obj->padding_info,
   3365                                             &my_obj->stream_info->buf_planes);
   3366         break;
   3367     case CAM_STREAM_TYPE_METADATA:
   3368         rc = mm_stream_calc_offset_metadata(&dim,
   3369                                             &my_obj->padding_info,
   3370                                             &my_obj->stream_info->buf_planes);
   3371         break;
   3372     default:
   3373         CDBG_ERROR("%s: not supported for stream type %d",
   3374                    __func__, my_obj->stream_info->stream_type);
   3375         rc = -1;
   3376         break;
   3377     }
   3378 
   3379     my_obj->frame_offset = my_obj->stream_info->buf_planes.plane_info;
   3380     return rc;
   3381 }
   3382 
   3383 /*===========================================================================
   3384  * FUNCTION   : mm_stream_sync_info
   3385  *
   3386  * DESCRIPTION: synchronize stream information with server
   3387  *
   3388  * PARAMETERS :
   3389  *   @my_obj  : stream object
   3390  *
   3391  * RETURN     : int32_t type of status
   3392  *              0  -- success
   3393  *              -1 -- failure
   3394  * NOTE       : assume stream info buffer is mapped to server and filled in with
   3395  *              stream information by upper layer. This call will let server to
   3396  *              synchornize the stream information with HAL. If server find any
   3397  *              fields that need to be changed accroding to hardware configuration,
   3398  *              server will modify corresponding fields so that HAL could know
   3399  *              about it.
   3400  *==========================================================================*/
   3401 int32_t mm_stream_sync_info(mm_stream_t *my_obj)
   3402 {
   3403     int32_t rc = 0;
   3404     int32_t value = 0;
   3405     my_obj->stream_info->stream_svr_id = my_obj->server_stream_id;
   3406     rc = mm_stream_calc_offset(my_obj);
   3407 
   3408     if (rc == 0) {
   3409         rc = mm_camera_util_s_ctrl(my_obj->fd,
   3410                                    CAM_PRIV_STREAM_INFO_SYNC,
   3411                                    &value);
   3412     }
   3413     return rc;
   3414 }
   3415 
   3416 /*===========================================================================
   3417  * FUNCTION   : mm_stream_set_fmt
   3418  *
   3419  * DESCRIPTION: set stream format to kernel via v4l2 ioctl
   3420  *
   3421  * PARAMETERS :
   3422  *   @my_obj  : stream object
   3423  *
   3424  * RETURN     : int32_t type of status
   3425  *              0  -- success
   3426  *              -1 -- failure
   3427  *==========================================================================*/
   3428 int32_t mm_stream_set_fmt(mm_stream_t *my_obj)
   3429 {
   3430     int32_t rc = 0;
   3431     struct v4l2_format fmt;
   3432     struct msm_v4l2_format_data msm_fmt;
   3433     int i;
   3434 
   3435     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   3436          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   3437 
   3438     if (my_obj->stream_info->dim.width == 0 ||
   3439         my_obj->stream_info->dim.height == 0) {
   3440         CDBG_ERROR("%s:invalid input[w=%d,h=%d,fmt=%d]\n",
   3441                    __func__,
   3442                    my_obj->stream_info->dim.width,
   3443                    my_obj->stream_info->dim.height,
   3444                    my_obj->stream_info->fmt);
   3445         return -1;
   3446     }
   3447 
   3448     memset(&fmt, 0, sizeof(fmt));
   3449     memset(&msm_fmt, 0, sizeof(msm_fmt));
   3450     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3451     msm_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3452 
   3453 
   3454     msm_fmt.width = (unsigned int)my_obj->stream_info->dim.width;
   3455     msm_fmt.height = (unsigned int)my_obj->stream_info->dim.height;
   3456     msm_fmt.pixelformat = mm_stream_get_v4l2_fmt(my_obj->stream_info->fmt);
   3457 
   3458     if (my_obj->stream_info->streaming_mode != CAM_STREAMING_MODE_BATCH) {
   3459         msm_fmt.num_planes = (unsigned char)my_obj->frame_offset.num_planes;
   3460         for (i = 0; i < msm_fmt.num_planes; i++) {
   3461             msm_fmt.plane_sizes[i] = my_obj->frame_offset.mp[i].len;
   3462         }
   3463     } else {
   3464         msm_fmt.num_planes = 1;
   3465         msm_fmt.plane_sizes[0] = my_obj->stream_info->user_buf_info.size;
   3466     }
   3467 
   3468     memcpy(fmt.fmt.raw_data, &msm_fmt, sizeof(msm_fmt));
   3469     rc = ioctl(my_obj->fd, VIDIOC_S_FMT, &fmt);
   3470     return rc;
   3471 }
   3472 
   3473 /*===========================================================================
   3474  * FUNCTION   : mm_stream_buf_done
   3475  *
   3476  * DESCRIPTION: enqueue buffer back to kernel
   3477  *
   3478  * PARAMETERS :
   3479  *   @my_obj       : stream object
   3480  *   @frame        : frame to be enqueued back to kernel
   3481  *
   3482  * RETURN     : int32_t type of status
   3483  *              0  -- success
   3484  *              -1 -- failure
   3485  *==========================================================================*/
   3486 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
   3487                            mm_camera_buf_def_t *frame)
   3488 {
   3489     int32_t rc = 0;
   3490     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   3491          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   3492 
   3493     pthread_mutex_lock(&my_obj->buf_lock);
   3494     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   3495         rc = mm_stream_write_user_buf(my_obj, frame);
   3496     } else if(my_obj->buf_status[frame->buf_idx].buf_refcnt == 0) {
   3497         CDBG("%s: Error Trying to free second time?(idx=%d) count=%d\n",
   3498                    __func__, frame->buf_idx,
   3499                    my_obj->buf_status[frame->buf_idx].buf_refcnt);
   3500         rc = -1;
   3501     } else {
   3502         my_obj->buf_status[frame->buf_idx].buf_refcnt--;
   3503         if (0 == my_obj->buf_status[frame->buf_idx].buf_refcnt) {
   3504             CDBG("<DEBUG> : Buf done for buffer:%d, stream:%d", frame->buf_idx, frame->stream_type);
   3505             rc = mm_stream_qbuf(my_obj, frame);
   3506             if(rc < 0) {
   3507                 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
   3508                            __func__, frame->buf_idx, rc);
   3509             } else {
   3510                 my_obj->buf_status[frame->buf_idx].in_kernel = 1;
   3511             }
   3512         }else{
   3513             CDBG("<DEBUG> : Still ref count pending count :%d",
   3514                  my_obj->buf_status[frame->buf_idx].buf_refcnt);
   3515             CDBG("<DEBUG> : for buffer:%p:%d",
   3516                  my_obj, frame->buf_idx);
   3517         }
   3518     }
   3519     pthread_mutex_unlock(&my_obj->buf_lock);
   3520     return rc;
   3521 }
   3522 
   3523 
   3524 /*===========================================================================
   3525  * FUNCTION   : mm_stream_get_queued_buf_count
   3526  *
   3527  * DESCRIPTION: return queued buffer count
   3528  *
   3529  * PARAMETERS :
   3530  *   @my_obj       : stream object
   3531  *
   3532  * RETURN     : queued buffer count
   3533  *==========================================================================*/
   3534 int32_t mm_stream_get_queued_buf_count(mm_stream_t *my_obj)
   3535 {
   3536     int32_t rc = 0;
   3537     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   3538             __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   3539     pthread_mutex_lock(&my_obj->buf_lock);
   3540     rc = my_obj->queued_buffer_count;
   3541     pthread_mutex_unlock(&my_obj->buf_lock);
   3542     return rc;
   3543 }
   3544 
   3545 /*===========================================================================
   3546  * FUNCTION   : mm_stream_reg_buf_cb
   3547  *
   3548  * DESCRIPTION: Allow other stream to register dataCB at this stream.
   3549  *
   3550  * PARAMETERS :
   3551  *   @my_obj       : stream object
   3552  *   @val          : ptr to info about the callback to be registered
   3553  *
   3554  * RETURN     : int32_t type of status
   3555  *              0  -- success
   3556  *              -1 -- failure
   3557  *==========================================================================*/
   3558 int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
   3559                              mm_stream_data_cb_t *val)
   3560 {
   3561     int32_t rc = -1;
   3562     uint8_t i;
   3563     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   3564          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   3565 
   3566     pthread_mutex_lock(&my_obj->cb_lock);
   3567     for (i=0 ;i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
   3568         if(NULL == my_obj->buf_cb[i].cb) {
   3569             my_obj->buf_cb[i] = *val;
   3570             rc = 0;
   3571             break;
   3572         }
   3573     }
   3574     pthread_mutex_unlock(&my_obj->cb_lock);
   3575 
   3576     return rc;
   3577 }
   3578