Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2016, 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 // System dependencies
     31 #include <stdlib.h>
     32 #include <pthread.h>
     33 #include <errno.h>
     34 #include <fcntl.h>
     35 #include <media/msm_media_info.h>
     36 #define TIME_H <SYSTEM_HEADER_PREFIX/time.h>
     37 #include TIME_H
     38 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
     39 #include IOCTL_H
     40 
     41 #define ATRACE_TAG ATRACE_TAG_CAMERA
     42 #include <cutils/trace.h>
     43 
     44 // Camera dependencies
     45 #include "cam_semaphore.h"
     46 #include "mm_camera_dbg.h"
     47 #include "mm_camera_interface.h"
     48 #include "mm_camera.h"
     49 
     50 /* internal function decalre */
     51 int32_t mm_stream_qbuf(mm_stream_t *my_obj,
     52                        mm_camera_buf_def_t *buf);
     53 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj);
     54 int32_t mm_stream_set_fmt(mm_stream_t * my_obj);
     55 int32_t mm_stream_cancel_buf(mm_stream_t * my_obj,
     56                            uint32_t buf_idx);
     57 int32_t mm_stream_sync_info(mm_stream_t *my_obj);
     58 int32_t mm_stream_init_bufs(mm_stream_t * my_obj);
     59 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj);
     60 int32_t mm_stream_request_buf(mm_stream_t * my_obj);
     61 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj);
     62 int32_t mm_stream_release(mm_stream_t *my_obj);
     63 int32_t mm_stream_set_parm(mm_stream_t *my_obj,
     64                            cam_stream_parm_buffer_t *value);
     65 int32_t mm_stream_get_parm(mm_stream_t *my_obj,
     66                            cam_stream_parm_buffer_t *value);
     67 int32_t mm_stream_do_action(mm_stream_t *my_obj,
     68                             void *in_value);
     69 int32_t mm_stream_streamon(mm_stream_t *my_obj);
     70 int32_t mm_stream_streamoff(mm_stream_t *my_obj);
     71 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
     72                                  mm_camera_buf_info_t* buf_info,
     73                                  uint8_t num_planes);
     74 int32_t mm_stream_read_user_buf(mm_stream_t * my_obj,
     75         mm_camera_buf_info_t* buf_info);
     76 int32_t mm_stream_write_user_buf(mm_stream_t * my_obj,
     77         mm_camera_buf_def_t *buf);
     78 
     79 int32_t mm_stream_config(mm_stream_t *my_obj,
     80                          mm_camera_stream_config_t *config);
     81 int32_t mm_stream_reg_buf(mm_stream_t * my_obj);
     82 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
     83                            mm_camera_buf_def_t *frame);
     84 int32_t mm_stream_get_queued_buf_count(mm_stream_t * my_obj);
     85 
     86 int32_t mm_stream_calc_offset(mm_stream_t *my_obj);
     87 int32_t mm_stream_calc_offset_preview(cam_stream_info_t *stream_info,
     88                                       cam_dimension_t *dim,
     89                                       cam_padding_info_t *padding,
     90                                       cam_stream_buf_plane_info_t *buf_planes);
     91 int32_t mm_stream_calc_offset_post_view(cam_format_t fmt,
     92                                       cam_dimension_t *dim,
     93                                       cam_stream_buf_plane_info_t *buf_planes);
     94 
     95 int32_t mm_stream_calc_offset_snapshot(cam_format_t fmt,
     96                                        cam_dimension_t *dim,
     97                                        cam_padding_info_t *padding,
     98                                        cam_stream_buf_plane_info_t *buf_planes);
     99 int32_t mm_stream_calc_offset_raw(cam_format_t fmt,
    100                                   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_video(cam_format_t fmt,
    104         cam_dimension_t *dim,
    105         cam_stream_buf_plane_info_t *buf_planes);
    106 int32_t mm_stream_calc_offset_metadata(cam_dimension_t *dim,
    107                                        cam_padding_info_t *padding,
    108                                        cam_stream_buf_plane_info_t *buf_planes);
    109 int32_t mm_stream_calc_offset_postproc(cam_stream_info_t *stream_info,
    110                                        cam_padding_info_t *padding,
    111                                        cam_stream_buf_plane_info_t *plns);
    112 uint32_t mm_stream_calc_lcm(int32_t num1, int32_t num2);
    113 
    114 
    115 /* state machine function declare */
    116 int32_t mm_stream_fsm_inited(mm_stream_t * my_obj,
    117                              mm_stream_evt_type_t evt,
    118                              void * in_val,
    119                              void * out_val);
    120 int32_t mm_stream_fsm_acquired(mm_stream_t * my_obj,
    121                                mm_stream_evt_type_t evt,
    122                                void * in_val,
    123                                void * out_val);
    124 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
    125                           mm_stream_evt_type_t evt,
    126                           void * in_val,
    127                           void * out_val);
    128 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
    129                              mm_stream_evt_type_t evt,
    130                              void * in_val,
    131                              void * out_val);
    132 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
    133                           mm_stream_evt_type_t evt,
    134                           void * in_val,
    135                           void * out_val);
    136 int32_t mm_stream_fsm_active(mm_stream_t * my_obj,
    137                              mm_stream_evt_type_t evt,
    138                              void * in_val,
    139                              void * out_val);
    140 uint32_t mm_stream_get_v4l2_fmt(cam_format_t fmt);
    141 
    142 
    143 /*===========================================================================
    144  * FUNCTION   : mm_stream_notify_channel
    145  *
    146  * DESCRIPTION: function to notify channel object on received buffer
    147  *
    148  * PARAMETERS :
    149  *   @ch_obj  : channel object
    150  *   @buf_info: ptr to struct storing buffer information
    151  *
    152  * RETURN     : int32_t type of status
    153  *              0  -- success
    154  *              0> -- failure
    155  *==========================================================================*/
    156 int32_t mm_stream_notify_channel(struct mm_channel* ch_obj,
    157         mm_camera_buf_info_t *buf_info)
    158 {
    159     int32_t rc = 0;
    160     mm_camera_cmdcb_t* node = NULL;
    161 
    162     if ((NULL == ch_obj) || (NULL == buf_info)) {
    163         LOGD("Invalid channel/buffer");
    164         return -ENODEV;
    165     }
    166 
    167     /* send cam_sem_post to wake up channel cmd thread to enqueue
    168      * to super buffer */
    169     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    170     if (NULL != node) {
    171         memset(node, 0, sizeof(mm_camera_cmdcb_t));
    172         node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
    173         node->u.buf = *buf_info;
    174 
    175         /* enqueue to cmd thread */
    176         cam_queue_enq(&(ch_obj->cmd_thread.cmd_queue), node);
    177 
    178         /* wake up cmd thread */
    179         cam_sem_post(&(ch_obj->cmd_thread.cmd_sem));
    180     } else {
    181         LOGE("No memory for mm_camera_node_t");
    182         rc = -ENOMEM;
    183     }
    184 
    185     return rc;
    186 }
    187 
    188 /*===========================================================================
    189  * FUNCTION   : mm_stream_handle_rcvd_buf
    190  *
    191  * DESCRIPTION: function to handle newly received stream buffer
    192  *
    193  * PARAMETERS :
    194  *   @cam_obj : stream object
    195  *   @buf_info: ptr to struct storing buffer information
    196  *
    197  * RETURN     : none
    198  *==========================================================================*/
    199 void mm_stream_handle_rcvd_buf(mm_stream_t *my_obj,
    200                                mm_camera_buf_info_t *buf_info,
    201                                uint8_t has_cb)
    202 {
    203     int32_t rc = 0;
    204     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    205           my_obj->my_hdl, my_obj->fd, my_obj->state);
    206 
    207     /* enqueue to super buf thread */
    208     if (my_obj->is_bundled) {
    209         rc = mm_stream_notify_channel(my_obj->ch_obj, buf_info);
    210         if (rc < 0) {
    211             LOGE("Unable to notify channel");
    212         }
    213     }
    214 
    215     pthread_mutex_lock(&my_obj->buf_lock);
    216     if(my_obj->is_linked) {
    217         /* need to add into super buf for linking, add ref count */
    218         my_obj->buf_status[buf_info->buf->buf_idx].buf_refcnt++;
    219 
    220         rc = mm_stream_notify_channel(my_obj->linked_obj, buf_info);
    221         if (rc < 0) {
    222             LOGE("Unable to notify channel");
    223         }
    224     }
    225     pthread_mutex_unlock(&my_obj->buf_lock);
    226 
    227     pthread_mutex_lock(&my_obj->cmd_lock);
    228     if(has_cb && my_obj->cmd_thread.is_active) {
    229         mm_camera_cmdcb_t* node = NULL;
    230 
    231         /* send cam_sem_post to wake up cmd thread to dispatch dataCB */
    232         node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    233         if (NULL != node) {
    234             memset(node, 0, sizeof(mm_camera_cmdcb_t));
    235             node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
    236             node->u.buf = *buf_info;
    237 
    238             /* enqueue to cmd thread */
    239             cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node);
    240 
    241             /* wake up cmd thread */
    242             cam_sem_post(&(my_obj->cmd_thread.cmd_sem));
    243         } else {
    244             LOGE("No memory for mm_camera_node_t");
    245         }
    246     }
    247     pthread_mutex_unlock(&my_obj->cmd_lock);
    248 }
    249 
    250 /*===========================================================================
    251  * FUNCTION   : mm_stream_dispatch_sync_data
    252  *
    253  * DESCRIPTION: dispatch stream buffer to registered users on poll thread
    254  *
    255  * PARAMETERS :
    256  *   @cmd_cb  : ptr storing stream buffer information
    257  *   @userdata: user data ptr (stream object)
    258  *
    259  * RETURN     : none
    260  *==========================================================================*/
    261 static void mm_stream_dispatch_sync_data(mm_stream_t * my_obj,
    262          mm_stream_data_cb_t *buf_cb, mm_camera_buf_info_t *buf_info)
    263 {
    264     mm_camera_super_buf_t super_buf;
    265 
    266     if (NULL == my_obj || buf_info == NULL ||
    267             buf_cb == NULL) {
    268         return;
    269     }
    270 
    271     memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
    272     super_buf.num_bufs = 1;
    273     super_buf.bufs[0] = buf_info->buf;
    274     super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
    275     super_buf.ch_id = my_obj->ch_obj->my_hdl;
    276     if ((buf_cb != NULL) && (buf_cb->cb_type == MM_CAMERA_STREAM_CB_TYPE_SYNC)
    277             && (buf_cb->cb_count != 0)) {
    278         /* callback */
    279         buf_cb->cb(&super_buf, buf_cb->user_data);
    280 
    281         /* if >0, reduce count by 1 every time we called CB until reaches 0
    282              * when count reach 0, reset the buf_cb to have no CB */
    283         if (buf_cb->cb_count > 0) {
    284             buf_cb->cb_count--;
    285             if (0 == buf_cb->cb_count) {
    286                 buf_cb->cb = NULL;
    287                 buf_cb->user_data = NULL;
    288             }
    289         }
    290     }
    291 }
    292 
    293 /*===========================================================================
    294  * FUNCTION   : mm_stream_data_notify
    295  *
    296  * DESCRIPTION: callback to handle data notify from kernel
    297  *
    298  * PARAMETERS :
    299  *   @user_data : user data ptr (stream object)
    300  *
    301  * RETURN     : none
    302  *==========================================================================*/
    303 static void mm_stream_data_notify(void* user_data)
    304 {
    305     mm_stream_t *my_obj = (mm_stream_t*)user_data;
    306     int32_t i, rc;
    307     uint8_t has_cb = 0, length = 0;
    308     mm_camera_buf_info_t buf_info;
    309 
    310     if (NULL == my_obj) {
    311         return;
    312     }
    313 
    314     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    315           my_obj->my_hdl, my_obj->fd, my_obj->state);
    316     if (MM_STREAM_STATE_ACTIVE != my_obj->state) {
    317         /* this Cb will only received in active_stream_on state
    318          * if not so, return here */
    319         LOGE("ERROR!! Wrong state (%d) to receive data notify!",
    320                     my_obj->state);
    321         return;
    322     }
    323 
    324     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
    325         length = 1;
    326     } else {
    327         length = my_obj->frame_offset.num_planes;
    328     }
    329 
    330     memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
    331     rc = mm_stream_read_msm_frame(my_obj, &buf_info,
    332         (uint8_t)length);
    333     if (rc != 0) {
    334         return;
    335     }
    336     uint32_t idx = buf_info.buf->buf_idx;
    337 
    338     pthread_mutex_lock(&my_obj->cb_lock);
    339     for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    340         if(NULL != my_obj->buf_cb[i].cb) {
    341             if (my_obj->buf_cb[i].cb_type == MM_CAMERA_STREAM_CB_TYPE_SYNC) {
    342                 /*For every SYNC callback, send data*/
    343                 mm_stream_dispatch_sync_data(my_obj,
    344                         &my_obj->buf_cb[i], &buf_info);
    345             } else {
    346                 /* for every ASYNC CB, need ref count */
    347                 has_cb = 1;
    348             }
    349         }
    350     }
    351     pthread_mutex_unlock(&my_obj->cb_lock);
    352 
    353     pthread_mutex_lock(&my_obj->buf_lock);
    354     /* update buffer location */
    355     my_obj->buf_status[idx].in_kernel = 0;
    356 
    357     /* update buf ref count */
    358     if (my_obj->is_bundled) {
    359         /* need to add into super buf since bundled, add ref count */
    360         my_obj->buf_status[idx].buf_refcnt++;
    361     }
    362     my_obj->buf_status[idx].buf_refcnt =
    363         (uint8_t)(my_obj->buf_status[idx].buf_refcnt + has_cb);
    364     pthread_mutex_unlock(&my_obj->buf_lock);
    365 
    366     mm_stream_handle_rcvd_buf(my_obj, &buf_info, has_cb);
    367 }
    368 
    369 /*===========================================================================
    370  * FUNCTION   : mm_stream_dispatch_app_data
    371  *
    372  * DESCRIPTION: dispatch stream buffer to registered users
    373  *
    374  * PARAMETERS :
    375  *   @cmd_cb  : ptr storing stream buffer information
    376  *   @userdata: user data ptr (stream object)
    377  *
    378  * RETURN     : none
    379  *==========================================================================*/
    380 static void mm_stream_dispatch_app_data(mm_camera_cmdcb_t *cmd_cb,
    381                                         void* user_data)
    382 {
    383     int i;
    384     mm_stream_t * my_obj = (mm_stream_t *)user_data;
    385     mm_camera_buf_info_t* buf_info = NULL;
    386     mm_camera_super_buf_t super_buf;
    387 
    388     if (NULL == my_obj) {
    389         return;
    390     }
    391     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    392           my_obj->my_hdl, my_obj->fd, my_obj->state);
    393 
    394     if (MM_CAMERA_CMD_TYPE_DATA_CB != cmd_cb->cmd_type) {
    395         LOGE("Wrong cmd_type (%d) for dataCB",
    396                     cmd_cb->cmd_type);
    397         return;
    398     }
    399 
    400     buf_info = &cmd_cb->u.buf;
    401     memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
    402     super_buf.num_bufs = 1;
    403     super_buf.bufs[0] = buf_info->buf;
    404     super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
    405     super_buf.ch_id = my_obj->ch_obj->my_hdl;
    406 
    407     pthread_mutex_lock(&my_obj->cb_lock);
    408     for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    409         if(NULL != my_obj->buf_cb[i].cb
    410                 && (my_obj->buf_cb[i].cb_type !=
    411                 MM_CAMERA_STREAM_CB_TYPE_SYNC)) {
    412             if (my_obj->buf_cb[i].cb_count != 0) {
    413                 /* if <0, means infinite CB
    414                  * if >0, means CB for certain times
    415                  * both case we need to call CB */
    416 
    417                 /* increase buf ref cnt */
    418                 pthread_mutex_lock(&my_obj->buf_lock);
    419                 my_obj->buf_status[buf_info->buf->buf_idx].buf_refcnt++;
    420                 pthread_mutex_unlock(&my_obj->buf_lock);
    421 
    422                 /* callback */
    423                 my_obj->buf_cb[i].cb(&super_buf,
    424                                      my_obj->buf_cb[i].user_data);
    425             }
    426 
    427             /* if >0, reduce count by 1 every time we called CB until reaches 0
    428              * when count reach 0, reset the buf_cb to have no CB */
    429             if (my_obj->buf_cb[i].cb_count > 0) {
    430                 my_obj->buf_cb[i].cb_count--;
    431                 if (0 == my_obj->buf_cb[i].cb_count) {
    432                     my_obj->buf_cb[i].cb = NULL;
    433                     my_obj->buf_cb[i].user_data = NULL;
    434                 }
    435             }
    436         }
    437     }
    438     pthread_mutex_unlock(&my_obj->cb_lock);
    439 
    440     /* do buf_done since we increased refcnt by one when has_cb */
    441     mm_stream_buf_done(my_obj, buf_info->buf);
    442 }
    443 
    444 /*===========================================================================
    445  * FUNCTION   : mm_stream_fsm_fn
    446  *
    447  * DESCRIPTION: stream finite state machine entry function. Depends on stream
    448  *              state, incoming event will be handled differently.
    449  *
    450  * PARAMETERS :
    451  *   @my_obj   : ptr to a stream object
    452  *   @evt      : stream event to be processed
    453  *   @in_val   : input event payload. Can be NULL if not needed.
    454  *   @out_val  : output payload, Can be NULL if not needed.
    455  *
    456  * RETURN     : int32_t type of status
    457  *              0  -- success
    458  *              -1 -- failure
    459  *==========================================================================*/
    460 int32_t mm_stream_fsm_fn(mm_stream_t *my_obj,
    461                          mm_stream_evt_type_t evt,
    462                          void * in_val,
    463                          void * out_val)
    464 {
    465     int32_t rc = -1;
    466 
    467     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    468           my_obj->my_hdl, my_obj->fd, my_obj->state);
    469     switch (my_obj->state) {
    470     case MM_STREAM_STATE_NOTUSED:
    471         LOGD("Not handling evt in unused state");
    472         break;
    473     case MM_STREAM_STATE_INITED:
    474         rc = mm_stream_fsm_inited(my_obj, evt, in_val, out_val);
    475         break;
    476     case MM_STREAM_STATE_ACQUIRED:
    477         rc = mm_stream_fsm_acquired(my_obj, evt, in_val, out_val);
    478         break;
    479     case MM_STREAM_STATE_CFG:
    480         rc = mm_stream_fsm_cfg(my_obj, evt, in_val, out_val);
    481         break;
    482     case MM_STREAM_STATE_BUFFED:
    483         rc = mm_stream_fsm_buffed(my_obj, evt, in_val, out_val);
    484         break;
    485     case MM_STREAM_STATE_REG:
    486         rc = mm_stream_fsm_reg(my_obj, evt, in_val, out_val);
    487         break;
    488     case MM_STREAM_STATE_ACTIVE:
    489         rc = mm_stream_fsm_active(my_obj, evt, in_val, out_val);
    490         break;
    491     default:
    492         LOGD("Not a valid state (%d)", my_obj->state);
    493         break;
    494     }
    495     LOGD("X rc =%d",rc);
    496     return rc;
    497 }
    498 
    499 /*===========================================================================
    500  * FUNCTION   : mm_stream_fsm_inited
    501  *
    502  * DESCRIPTION: stream finite state machine function to handle event in INITED
    503  *              state.
    504  *
    505  * PARAMETERS :
    506  *   @my_obj   : ptr to a stream object
    507  *   @evt      : stream event to be processed
    508  *   @in_val   : input event payload. Can be NULL if not needed.
    509  *   @out_val  : output payload, Can be NULL if not needed.
    510  *
    511  * RETURN     : int32_t type of status
    512  *              0  -- success
    513  *              -1 -- failure
    514  *==========================================================================*/
    515 int32_t mm_stream_fsm_inited(mm_stream_t *my_obj,
    516                              mm_stream_evt_type_t evt,
    517                              void * in_val,
    518                              void * out_val)
    519 {
    520     int32_t rc = 0;
    521     char dev_name[MM_CAMERA_DEV_NAME_LEN];
    522     const char *dev_name_value = NULL;
    523     if (NULL == my_obj) {
    524       LOGE("NULL camera object\n");
    525       return -1;
    526     }
    527 
    528     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    529           my_obj->my_hdl, my_obj->fd, my_obj->state);
    530     switch(evt) {
    531     case MM_STREAM_EVT_ACQUIRE:
    532         if ((NULL == my_obj->ch_obj) || (NULL == my_obj->ch_obj->cam_obj)) {
    533             LOGE("NULL channel or camera obj\n");
    534             rc = -1;
    535             break;
    536         }
    537 
    538         dev_name_value = mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl);
    539         if (NULL == dev_name_value) {
    540             LOGE("NULL device name\n");
    541             rc = -1;
    542             break;
    543         }
    544 
    545         snprintf(dev_name, sizeof(dev_name), "/dev/%s",
    546                  dev_name_value);
    547 
    548         my_obj->fd = open(dev_name, O_RDWR | O_NONBLOCK);
    549         if (my_obj->fd < 0) {
    550             LOGE("open dev returned %d\n", my_obj->fd);
    551             rc = -1;
    552             break;
    553         }
    554         LOGD("open dev fd = %d\n", my_obj->fd);
    555         rc = mm_stream_set_ext_mode(my_obj);
    556         if (0 == rc) {
    557             my_obj->state = MM_STREAM_STATE_ACQUIRED;
    558         } else {
    559             /* failed setting ext_mode
    560              * close fd */
    561             close(my_obj->fd);
    562             my_obj->fd = -1;
    563             break;
    564         }
    565         break;
    566     default:
    567         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
    568                     my_obj->state, evt, in_val, out_val);
    569         break;
    570     }
    571     return rc;
    572 }
    573 
    574 /*===========================================================================
    575  * FUNCTION   : mm_stream_fsm_acquired
    576  *
    577  * DESCRIPTION: stream finite state machine function to handle event in AQUIRED
    578  *              state.
    579  *
    580  * PARAMETERS :
    581  *   @my_obj   : ptr to a stream object
    582  *   @evt      : stream event to be processed
    583  *   @in_val   : input event payload. Can be NULL if not needed.
    584  *   @out_val  : output payload, Can be NULL if not needed.
    585  *
    586  * RETURN     : int32_t type of status
    587  *              0  -- success
    588  *              -1 -- failure
    589  *==========================================================================*/
    590 int32_t mm_stream_fsm_acquired(mm_stream_t *my_obj,
    591                                mm_stream_evt_type_t evt,
    592                                void * in_val,
    593                                void * out_val)
    594 {
    595     int32_t rc = 0;
    596 
    597     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    598           my_obj->my_hdl, my_obj->fd, my_obj->state);
    599     switch(evt) {
    600     case MM_STREAM_EVT_SET_FMT:
    601         {
    602             mm_camera_stream_config_t *config =
    603                 (mm_camera_stream_config_t *)in_val;
    604 
    605             rc = mm_stream_config(my_obj, config);
    606 
    607             /* change state to configed */
    608             my_obj->state = MM_STREAM_STATE_CFG;
    609 
    610             break;
    611         }
    612     case MM_STREAM_EVT_RELEASE:
    613         rc = mm_stream_release(my_obj);
    614         /* change state to not used */
    615          my_obj->state = MM_STREAM_STATE_NOTUSED;
    616         break;
    617     case MM_STREAM_EVT_SET_PARM:
    618         {
    619             mm_evt_paylod_set_get_stream_parms_t *payload =
    620                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    621             rc = mm_stream_set_parm(my_obj, payload->parms);
    622         }
    623         break;
    624     case MM_STREAM_EVT_GET_PARM:
    625         {
    626             mm_evt_paylod_set_get_stream_parms_t *payload =
    627                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    628             rc = mm_stream_get_parm(my_obj, payload->parms);
    629         }
    630         break;
    631     default:
    632         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
    633                     my_obj->state, evt, in_val, out_val);
    634     }
    635     LOGD("X rc = %d", rc);
    636     return rc;
    637 }
    638 
    639 /*===========================================================================
    640  * FUNCTION   : mm_stream_fsm_cfg
    641  *
    642  * DESCRIPTION: stream finite state machine function to handle event in CONFIGURED
    643  *              state.
    644  *
    645  * PARAMETERS :
    646  *   @my_obj   : ptr to a stream object
    647  *   @evt      : stream event to be processed
    648  *   @in_val   : input event payload. Can be NULL if not needed.
    649  *   @out_val  : output payload, Can be NULL if not needed.
    650  *
    651  * RETURN     : int32_t type of status
    652  *              0  -- success
    653  *              -1 -- failure
    654  *==========================================================================*/
    655 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
    656                           mm_stream_evt_type_t evt,
    657                           void * in_val,
    658                           void * out_val)
    659 {
    660     int32_t rc = 0;
    661     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    662           my_obj->my_hdl, my_obj->fd, my_obj->state);
    663     switch(evt) {
    664     case MM_STREAM_EVT_SET_FMT:
    665         {
    666             mm_camera_stream_config_t *config =
    667                 (mm_camera_stream_config_t *)in_val;
    668 
    669             rc = mm_stream_config(my_obj, config);
    670 
    671             /* change state to configed */
    672             my_obj->state = MM_STREAM_STATE_CFG;
    673 
    674             break;
    675         }
    676     case MM_STREAM_EVT_RELEASE:
    677         rc = mm_stream_release(my_obj);
    678         my_obj->state = MM_STREAM_STATE_NOTUSED;
    679         break;
    680     case MM_STREAM_EVT_SET_PARM:
    681         {
    682             mm_evt_paylod_set_get_stream_parms_t *payload =
    683                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    684             rc = mm_stream_set_parm(my_obj, payload->parms);
    685         }
    686         break;
    687     case MM_STREAM_EVT_GET_PARM:
    688         {
    689             mm_evt_paylod_set_get_stream_parms_t *payload =
    690                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    691             rc = mm_stream_get_parm(my_obj, payload->parms);
    692         }
    693         break;
    694     case MM_STREAM_EVT_GET_BUF:
    695         rc = mm_stream_init_bufs(my_obj);
    696         /* change state to buff allocated */
    697         if(0 == rc) {
    698             my_obj->state = MM_STREAM_STATE_BUFFED;
    699         }
    700         break;
    701     default:
    702         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
    703                     my_obj->state, evt, in_val, out_val);
    704     }
    705     LOGD("X rc = %d", rc);
    706     return rc;
    707 }
    708 
    709 /*===========================================================================
    710  * FUNCTION   : mm_stream_fsm_buffed
    711  *
    712  * DESCRIPTION: stream finite state machine function to handle event in BUFFED
    713  *              state.
    714  *
    715  * PARAMETERS :
    716  *   @my_obj   : ptr to a stream object
    717  *   @evt      : stream event to be processed
    718  *   @in_val   : input event payload. Can be NULL if not needed.
    719  *   @out_val  : output payload, Can be NULL if not needed.
    720  *
    721  * RETURN     : int32_t type of status
    722  *              0  -- success
    723  *              -1 -- failure
    724  *==========================================================================*/
    725 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
    726                              mm_stream_evt_type_t evt,
    727                              void * in_val,
    728                              void * out_val)
    729 {
    730     int32_t rc = 0;
    731     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    732           my_obj->my_hdl, my_obj->fd, my_obj->state);
    733     switch(evt) {
    734     case MM_STREAM_EVT_PUT_BUF:
    735         rc = mm_stream_deinit_bufs(my_obj);
    736         /* change state to configed */
    737         my_obj->state = MM_STREAM_STATE_CFG;
    738         break;
    739     case MM_STREAM_EVT_REG_BUF:
    740         rc = mm_stream_reg_buf(my_obj);
    741         /* change state to regged */
    742         if(0 == rc) {
    743             my_obj->state = MM_STREAM_STATE_REG;
    744         }
    745         break;
    746     case MM_STREAM_EVT_SET_PARM:
    747         {
    748             mm_evt_paylod_set_get_stream_parms_t *payload =
    749                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    750             rc = mm_stream_set_parm(my_obj, payload->parms);
    751         }
    752         break;
    753     case MM_STREAM_EVT_GET_PARM:
    754         {
    755             mm_evt_paylod_set_get_stream_parms_t *payload =
    756                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    757             rc = mm_stream_get_parm(my_obj, payload->parms);
    758         }
    759         break;
    760     default:
    761         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
    762                     my_obj->state, evt, in_val, out_val);
    763     }
    764     LOGD("X rc = %d", rc);
    765     return rc;
    766 }
    767 
    768 /*===========================================================================
    769  * FUNCTION   : mm_stream_fsm_reg
    770  *
    771  * DESCRIPTION: stream finite state machine function to handle event in REGGED
    772  *              state.
    773  *
    774  * PARAMETERS :
    775  *   @my_obj   : ptr to a stream object
    776  *   @evt      : stream event to be processed
    777  *   @in_val   : input event payload. Can be NULL if not needed.
    778  *   @out_val  : output payload, Can be NULL if not needed.
    779  *
    780  * RETURN     : int32_t type of status
    781  *              0  -- success
    782  *              -1 -- failure
    783  *==========================================================================*/
    784 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
    785                           mm_stream_evt_type_t evt,
    786                           void * in_val,
    787                           void * out_val)
    788 {
    789     int32_t rc = 0;
    790     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    791           my_obj->my_hdl, my_obj->fd, my_obj->state);
    792 
    793     switch(evt) {
    794     case MM_STREAM_EVT_UNREG_BUF:
    795         rc = mm_stream_unreg_buf(my_obj);
    796 
    797         /* change state to buffed */
    798         my_obj->state = MM_STREAM_STATE_BUFFED;
    799         break;
    800     case MM_STREAM_EVT_START:
    801         {
    802             uint8_t has_cb = 0;
    803             uint8_t i;
    804             /* launch cmd thread if CB is not null */
    805             pthread_mutex_lock(&my_obj->cb_lock);
    806             for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    807                 if((NULL != my_obj->buf_cb[i].cb) &&
    808                         (my_obj->buf_cb[i].cb_type != MM_CAMERA_STREAM_CB_TYPE_SYNC)) {
    809                     has_cb = 1;
    810                     break;
    811                 }
    812             }
    813             pthread_mutex_unlock(&my_obj->cb_lock);
    814 
    815             pthread_mutex_lock(&my_obj->cmd_lock);
    816             if (has_cb) {
    817                 snprintf(my_obj->cmd_thread.threadName, THREAD_NAME_SIZE, "CAM_StrmAppData");
    818                 mm_camera_cmd_thread_launch(&my_obj->cmd_thread,
    819                                             mm_stream_dispatch_app_data,
    820                                             (void *)my_obj);
    821             }
    822             pthread_mutex_unlock(&my_obj->cmd_lock);
    823 
    824             my_obj->state = MM_STREAM_STATE_ACTIVE;
    825             rc = mm_stream_streamon(my_obj);
    826             if (0 != rc) {
    827                 /* failed stream on, need to release cmd thread if it's launched */
    828                 pthread_mutex_lock(&my_obj->cmd_lock);
    829                 if (has_cb) {
    830                     mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    831                 }
    832                 pthread_mutex_unlock(&my_obj->cmd_lock);
    833                 my_obj->state = MM_STREAM_STATE_REG;
    834                 break;
    835             }
    836         }
    837         break;
    838     case MM_STREAM_EVT_SET_PARM:
    839         {
    840             mm_evt_paylod_set_get_stream_parms_t *payload =
    841                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    842             rc = mm_stream_set_parm(my_obj, payload->parms);
    843         }
    844         break;
    845     case MM_STREAM_EVT_GET_PARM:
    846         {
    847             mm_evt_paylod_set_get_stream_parms_t *payload =
    848                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    849             rc = mm_stream_get_parm(my_obj, payload->parms);
    850         }
    851         break;
    852     default:
    853         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
    854                     my_obj->state, evt, in_val, out_val);
    855     }
    856     LOGD("X rc = %d", rc);
    857     return rc;
    858 }
    859 
    860 /*===========================================================================
    861  * FUNCTION   : mm_stream_fsm_active
    862  *
    863  * DESCRIPTION: stream finite state machine function to handle event in ACTIVE
    864  *              state.
    865  *
    866  * PARAMETERS :
    867  *   @my_obj   : ptr to a stream object
    868  *   @evt      : stream event to be processed
    869  *   @in_val   : input event payload. Can be NULL if not needed.
    870  *   @out_val  : output payload, Can be NULL if not needed.
    871  *
    872  * RETURN     : int32_t type of status
    873  *              0  -- success
    874  *              -1 -- failure
    875  *==========================================================================*/
    876 int32_t mm_stream_fsm_active(mm_stream_t * my_obj,
    877                              mm_stream_evt_type_t evt,
    878                              void * in_val,
    879                              void * out_val)
    880 {
    881     int32_t rc = 0;
    882     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
    883           my_obj->my_hdl, my_obj->fd, my_obj->state);
    884     switch(evt) {
    885     case MM_STREAM_EVT_QBUF:
    886         rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
    887         break;
    888     case MM_STREAM_EVT_CANCEL_BUF:
    889         rc = mm_stream_cancel_buf(my_obj, *((uint32_t*)in_val));
    890         break;
    891     case MM_STREAM_EVT_GET_QUEUED_BUF_COUNT:
    892         rc = mm_stream_get_queued_buf_count(my_obj);
    893         break;
    894     case MM_STREAM_EVT_STOP:
    895         {
    896             uint8_t has_cb = 0;
    897             uint8_t i;
    898             rc = mm_stream_streamoff(my_obj);
    899 
    900             pthread_mutex_lock(&my_obj->cb_lock);
    901             for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    902                 if(NULL != my_obj->buf_cb[i].cb
    903                         && my_obj->buf_cb[i].cb_type != MM_CAMERA_STREAM_CB_TYPE_SYNC) {
    904                     has_cb = 1;
    905                     break;
    906                 }
    907             }
    908             pthread_mutex_unlock(&my_obj->cb_lock);
    909 
    910             pthread_mutex_lock(&my_obj->cmd_lock);
    911             if (has_cb) {
    912                 mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    913             }
    914             pthread_mutex_unlock(&my_obj->cmd_lock);
    915             my_obj->state = MM_STREAM_STATE_REG;
    916         }
    917         break;
    918     case MM_STREAM_EVT_SET_PARM:
    919         {
    920             mm_evt_paylod_set_get_stream_parms_t *payload =
    921                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    922             rc = mm_stream_set_parm(my_obj, payload->parms);
    923         }
    924         break;
    925     case MM_STREAM_EVT_GET_PARM:
    926         {
    927             mm_evt_paylod_set_get_stream_parms_t *payload =
    928                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    929             rc = mm_stream_get_parm(my_obj, payload->parms);
    930         }
    931         break;
    932     case MM_STREAM_EVT_DO_ACTION:
    933         rc = mm_stream_do_action(my_obj, in_val);
    934         break;
    935     default:
    936         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
    937                     my_obj->state, evt, in_val, out_val);
    938     }
    939     LOGD("X rc = %d", rc);
    940     return rc;
    941 }
    942 
    943 /*===========================================================================
    944  * FUNCTION   : mm_stream_map_buf_ops
    945  *
    946  * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
    947  *              This function will be passed to upper layer as part of ops table
    948  *              to be used by upper layer when allocating stream buffers and mapping
    949  *              buffers to server via domain socket.
    950  *
    951  * PARAMETERS :
    952  *   @frame_idx    : index of buffer within the stream buffers, only valid if
    953  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
    954  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
    955  *   @plane_idx    : plane index. If all planes share the same fd,
    956  *                   plane_idx = -1; otherwise, plean_idx is the
    957  *                   index to plane (0..num_of_planes)
    958  *   @fd           : file descriptor of the buffer
    959  *   @size         : size of the buffer
    960  *   @userdata     : user data ptr (stream object)
    961  *
    962  * RETURN     : int32_t type of status
    963  *              0  -- success
    964  *              -1 -- failure
    965  *==========================================================================*/
    966 static int32_t mm_stream_map_buf_ops(uint32_t frame_idx,
    967         int32_t plane_idx, int fd, size_t size,
    968         void *buffer, cam_mapping_buf_type type,
    969         void *userdata)
    970 {
    971     mm_stream_t *my_obj = (mm_stream_t *)userdata;
    972     return mm_stream_map_buf(my_obj,
    973             type, frame_idx, plane_idx, fd, size, buffer);
    974 }
    975 
    976 /*===========================================================================
    977  * FUNCTION   : mm_stream_bundled_map_buf_ops
    978  *
    979  * DESCRIPTION: ops for mapping bundled stream buffers via domain socket to server.
    980  *              This function will be passed to upper layer as part of ops table
    981  *              to be used by upper layer when allocating stream buffers and mapping
    982  *              buffers to server via domain socket.
    983  *
    984  * PARAMETERS :
    985  *   @buf_map_list : list of buffer mapping information
    986  *   @userdata     : user data ptr (stream object)
    987  *
    988  * RETURN     : int32_t type of status
    989  *              0  -- success
    990  *              -1 -- failure
    991  *==========================================================================*/
    992 static int32_t mm_stream_bundled_map_buf_ops(
    993         const cam_buf_map_type_list *buf_map_list,
    994         void *userdata)
    995 {
    996     mm_stream_t *my_obj = (mm_stream_t *)userdata;
    997     return mm_stream_map_bufs(my_obj,
    998                               buf_map_list);
    999 }
   1000 
   1001 /*===========================================================================
   1002  * FUNCTION   : mm_stream_unmap_buf_ops
   1003  *
   1004  * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
   1005  *              This function will be passed to upper layer as part of ops table
   1006  *              to be used by upper layer when allocating stream buffers and unmapping
   1007  *              buffers to server via domain socket.
   1008  *
   1009  * PARAMETERS :
   1010  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1011  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1012  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1013  *   @plane_idx    : plane index. If all planes share the same fd,
   1014  *                   plane_idx = -1; otherwise, plean_idx is the
   1015  *                   index to plane (0..num_of_planes)
   1016  *   @userdata     : user data ptr (stream object)
   1017  *
   1018  * RETURN     : int32_t type of status
   1019  *              0  -- success
   1020  *              -1 -- failure
   1021  *==========================================================================*/
   1022 static int32_t mm_stream_unmap_buf_ops(uint32_t frame_idx,
   1023                                        int32_t plane_idx,
   1024                                        cam_mapping_buf_type type,
   1025                                        void *userdata)
   1026 {
   1027     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   1028     return mm_stream_unmap_buf(my_obj,
   1029                                type,
   1030                                frame_idx,
   1031                                plane_idx);
   1032 }
   1033 
   1034 /*===========================================================================
   1035  * FUNCTION   : mm_stream_config
   1036  *
   1037  * DESCRIPTION: configure a stream
   1038  *
   1039  * PARAMETERS :
   1040  *   @my_obj       : stream object
   1041  *   @config       : stream configuration
   1042  *
   1043  * RETURN     : int32_t type of status
   1044  *              0  -- success
   1045  *              -1 -- failure
   1046  *==========================================================================*/
   1047 int32_t mm_stream_config(mm_stream_t *my_obj,
   1048                          mm_camera_stream_config_t *config)
   1049 {
   1050     int32_t rc = 0;
   1051     int32_t cb_index = 0;
   1052 
   1053     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   1054           my_obj->my_hdl, my_obj->fd, my_obj->state);
   1055     my_obj->stream_info = config->stream_info;
   1056     my_obj->buf_num = (uint8_t) config->stream_info->num_bufs;
   1057     my_obj->mem_vtbl = config->mem_vtbl;
   1058     my_obj->padding_info = config->padding_info;
   1059 
   1060     if (config->stream_cb_sync != NULL) {
   1061         /* SYNC callback is always placed at index 0*/
   1062         my_obj->buf_cb[cb_index].cb = config->stream_cb_sync;
   1063         my_obj->buf_cb[cb_index].user_data = config->userdata;
   1064         my_obj->buf_cb[cb_index].cb_count = -1; /* infinite by default */
   1065         my_obj->buf_cb[cb_index].cb_type = MM_CAMERA_STREAM_CB_TYPE_SYNC;
   1066         cb_index++;
   1067     }
   1068     my_obj->buf_cb[cb_index].cb = config->stream_cb;
   1069     my_obj->buf_cb[cb_index].user_data = config->userdata;
   1070     my_obj->buf_cb[cb_index].cb_count = -1; /* infinite by default */
   1071     my_obj->buf_cb[cb_index].cb_type = MM_CAMERA_STREAM_CB_TYPE_ASYNC;
   1072 
   1073     rc = mm_stream_sync_info(my_obj);
   1074     if (rc == 0) {
   1075         rc = mm_stream_set_fmt(my_obj);
   1076         if (rc < 0) {
   1077             LOGE("mm_stream_set_fmt failed %d",
   1078                      rc);
   1079         }
   1080     }
   1081 
   1082     my_obj->map_ops.map_ops = mm_stream_map_buf_ops;
   1083     my_obj->map_ops.bundled_map_ops = mm_stream_bundled_map_buf_ops;
   1084     my_obj->map_ops.unmap_ops = mm_stream_unmap_buf_ops;
   1085     my_obj->map_ops.userdata = my_obj;
   1086 
   1087     if(my_obj->mem_vtbl.set_config_ops != NULL) {
   1088         my_obj->mem_vtbl.set_config_ops(&my_obj->map_ops,
   1089                 my_obj->mem_vtbl.user_data);
   1090     }
   1091     return rc;
   1092 }
   1093 
   1094 /*===========================================================================
   1095  * FUNCTION   : mm_stream_release
   1096  *
   1097  * DESCRIPTION: release a stream resource
   1098  *
   1099  * PARAMETERS :
   1100  *   @my_obj       : stream object
   1101  *
   1102  * RETURN     : int32_t type of status
   1103  *              0  -- success
   1104  *              -1 -- failure
   1105  *==========================================================================*/
   1106 int32_t mm_stream_release(mm_stream_t *my_obj)
   1107 {
   1108     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   1109           my_obj->my_hdl, my_obj->fd, my_obj->state);
   1110 
   1111     pthread_mutex_lock(&my_obj->buf_lock);
   1112     memset(my_obj->buf_status, 0, sizeof(my_obj->buf_status));
   1113     pthread_mutex_unlock(&my_obj->buf_lock);
   1114 
   1115     /* close fd */
   1116     if (my_obj->fd >= 0) {
   1117 #ifndef DAEMON_PRESENT
   1118         int32_t rc = 0;
   1119         cam_shim_packet_t *shim_cmd;
   1120         cam_shim_cmd_data shim_cmd_data;
   1121         mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   1122 
   1123         memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
   1124         shim_cmd_data.command = MSM_CAMERA_PRIV_DEL_STREAM;
   1125         shim_cmd_data.stream_id = my_obj->server_stream_id;
   1126         shim_cmd_data.value = NULL;
   1127         shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
   1128                 cam_obj->sessionid, &shim_cmd_data);
   1129         rc = mm_camera_module_send_cmd(shim_cmd);
   1130         if (rc < 0) {
   1131             LOGE("failed to DELETE STREAM");
   1132         }
   1133         mm_camera_destroy_shim_cmd_packet(shim_cmd);
   1134 #endif /* DAEMON_PRESENT */
   1135         close(my_obj->fd);
   1136     }
   1137 
   1138     /* destroy mutex */
   1139     pthread_cond_destroy(&my_obj->buf_cond);
   1140     pthread_mutex_destroy(&my_obj->buf_lock);
   1141     pthread_mutex_destroy(&my_obj->cb_lock);
   1142     pthread_mutex_destroy(&my_obj->cmd_lock);
   1143 
   1144     /* reset stream obj */
   1145     memset(my_obj, 0, sizeof(mm_stream_t));
   1146     my_obj->fd = -1;
   1147 
   1148     return 0;
   1149 }
   1150 
   1151 /*===========================================================================
   1152  * FUNCTION   : mm_stream_streamon
   1153  *
   1154  * DESCRIPTION: stream on a stream. sending v4l2 request to kernel
   1155  *
   1156  * PARAMETERS :
   1157  *   @my_obj       : stream object
   1158  *
   1159  * RETURN     : int32_t type of status
   1160  *              0  -- success
   1161  *              -1 -- failure
   1162  *==========================================================================*/
   1163 int32_t mm_stream_streamon(mm_stream_t *my_obj)
   1164 {
   1165     int32_t rc = 0;
   1166     int8_t i;
   1167     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1168 
   1169     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   1170           my_obj->my_hdl, my_obj->fd, my_obj->state);
   1171 
   1172     pthread_mutex_lock(&my_obj->buf_lock);
   1173     for (i = 0; i < my_obj->buf_num; i++) {
   1174         if ((my_obj->buf_status[i].map_status == 0) &&
   1175                 (my_obj->buf_status[i].in_kernel)) {
   1176             LOGD("waiting for mapping to done: strm fd = %d",
   1177                      my_obj->fd);
   1178             struct timespec ts;
   1179             clock_gettime(CLOCK_MONOTONIC, &ts);
   1180             ts.tv_sec += WAIT_TIMEOUT;
   1181             rc = pthread_cond_timedwait(&my_obj->buf_cond, &my_obj->buf_lock, &ts);
   1182             if (rc == ETIMEDOUT) {
   1183                 LOGE("Timed out. Abort stream-on \n");
   1184                 rc = -1;
   1185             }
   1186             break;
   1187         } else if (my_obj->buf_status[i].map_status < 0) {
   1188             LOGD("Buffer mapping failed. Abort Stream On");
   1189             rc = -1;
   1190             break;
   1191         }
   1192     }
   1193     pthread_mutex_unlock(&my_obj->buf_lock);
   1194 
   1195     if (rc < 0) {
   1196         /* remove fd from data poll thread in case of failure */
   1197         mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1198                 my_obj->my_hdl, mm_camera_sync_call);
   1199         return rc;
   1200     }
   1201     mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   1202     LOGD("E, my_handle = 0x%x, fd = %d, state = %d session_id:%d stream_id:%d",
   1203             my_obj->my_hdl, my_obj->fd, my_obj->state, cam_obj->sessionid,
   1204             my_obj->server_stream_id);
   1205 
   1206     rc = ioctl(my_obj->fd, VIDIOC_STREAMON, &buf_type);
   1207     if (rc < 0 && my_obj->stream_info->num_bufs != 0) {
   1208         LOGE("ioctl VIDIOC_STREAMON failed: rc=%d, errno %d",
   1209                 rc, errno);
   1210         goto error_case;
   1211     }
   1212 
   1213 #ifndef DAEMON_PRESENT
   1214     cam_shim_packet_t *shim_cmd;
   1215     cam_shim_cmd_data shim_cmd_data;
   1216 
   1217     memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
   1218     shim_cmd_data.command = MSM_CAMERA_PRIV_STREAM_ON;
   1219     shim_cmd_data.stream_id = my_obj->server_stream_id;
   1220     shim_cmd_data.value = NULL;
   1221     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
   1222             cam_obj->sessionid, &shim_cmd_data);
   1223     rc = mm_camera_module_send_cmd(shim_cmd);
   1224     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   1225     if (rc < 0) {
   1226         LOGE("Module StreamON failed: rc=%d", rc);
   1227         ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type);
   1228         goto error_case;
   1229     }
   1230 #endif
   1231     LOGD("X rc = %d",rc);
   1232     return rc;
   1233 error_case:
   1234      /* remove fd from data poll thread in case of failure */
   1235      mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1236              my_obj->my_hdl, mm_camera_sync_call);
   1237 
   1238     LOGD("X rc = %d",rc);
   1239     return rc;
   1240 }
   1241 
   1242 /*===========================================================================
   1243  * FUNCTION   : mm_stream_streamoff
   1244  *
   1245  * DESCRIPTION: stream off a stream. sending v4l2 request to kernel
   1246  *
   1247  * PARAMETERS :
   1248  *   @my_obj       : stream object
   1249  *
   1250  * RETURN     : int32_t type of status
   1251  *              0  -- success
   1252  *              -1 -- failure
   1253  *==========================================================================*/
   1254 int32_t mm_stream_streamoff(mm_stream_t *my_obj)
   1255 {
   1256     int32_t rc = 0;
   1257     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1258     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   1259           my_obj->my_hdl, my_obj->fd, my_obj->state);
   1260 
   1261     /* step1: remove fd from data poll thread */
   1262     rc = mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1263             my_obj->my_hdl, mm_camera_sync_call);
   1264     if (rc < 0) {
   1265         /* The error might be due to async update. In this case
   1266          * wait for all updates to complete before proceeding. */
   1267         rc = mm_camera_poll_thread_commit_updates(&my_obj->ch_obj->poll_thread[0]);
   1268         if (rc < 0) {
   1269             LOGE("Poll sync failed %d", rc);
   1270             rc = 0;
   1271         }
   1272     }
   1273 
   1274 #ifndef DAEMON_PRESENT
   1275     cam_shim_packet_t *shim_cmd;
   1276     cam_shim_cmd_data shim_cmd_data;
   1277     mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   1278 
   1279     memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
   1280     shim_cmd_data.command = MSM_CAMERA_PRIV_STREAM_OFF;
   1281     shim_cmd_data.stream_id = my_obj->server_stream_id;
   1282     shim_cmd_data.value = NULL;
   1283     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
   1284             cam_obj->sessionid, &shim_cmd_data);
   1285 
   1286     rc |= mm_camera_module_send_cmd(shim_cmd);
   1287     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   1288     if (rc < 0) {
   1289         LOGE("Module StreamOFF failed: rc=%d", rc)
   1290     }
   1291 #endif
   1292 
   1293     /* step2: stream off */
   1294     rc |= ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type);
   1295     if (rc < 0) {
   1296         LOGE("STREAMOFF ioctl failed: %s", strerror(errno));
   1297     }
   1298     return rc;
   1299 }
   1300 
   1301 /*===========================================================================
   1302  * FUNCTION   : mm_stream_write_user_buf
   1303  *
   1304  * DESCRIPTION: dequeue a stream buffer from user buffer queue and fill internal structure
   1305  *
   1306  * PARAMETERS :
   1307  *   @my_obj       : stream object
   1308  *   @buf     : ptr to a struct storing buffer information
   1309  *
   1310  * RETURN     : int32_t type of status
   1311  *              0  -- success
   1312  *              -1 -- failure
   1313  *==========================================================================*/
   1314 int32_t mm_stream_write_user_buf(mm_stream_t * my_obj,
   1315         mm_camera_buf_def_t *buf)
   1316 {
   1317     int32_t rc = 0, i;
   1318     int32_t index = -1, count = 0;
   1319     struct msm_camera_user_buf_cont_t *cont_buf = NULL;
   1320 
   1321     if (buf->buf_type == CAM_STREAM_BUF_TYPE_USERPTR) {
   1322         pthread_mutex_lock(&my_obj->buf_lock);
   1323         my_obj->buf_status[buf->buf_idx].buf_refcnt--;
   1324         if (0 == my_obj->buf_status[buf->buf_idx].buf_refcnt) {
   1325             pthread_mutex_unlock(&my_obj->buf_lock);
   1326             cont_buf = (struct msm_camera_user_buf_cont_t *)my_obj->buf[buf->buf_idx].buffer;
   1327             cont_buf->buf_cnt = my_obj->buf[buf->buf_idx].user_buf.bufs_used;
   1328             for (i = 0; i < (int32_t)cont_buf->buf_cnt; i++) {
   1329                 cont_buf->buf_idx[i] = my_obj->buf[buf->buf_idx].user_buf.buf_idx[i];
   1330             }
   1331             rc = mm_stream_qbuf(my_obj, buf);
   1332             if(rc < 0) {
   1333                 LOGE("mm_camera_stream_qbuf(idx=%d) err=%d\n",
   1334                             buf->buf_idx, rc);
   1335             } else {
   1336                 for (i = 0; i < (int32_t)cont_buf->buf_cnt; i++) {
   1337                     my_obj->buf[buf->buf_idx].user_buf.buf_idx[i] = -1;
   1338                 }
   1339                 my_obj->buf_status[buf->buf_idx].in_kernel = 1;
   1340                 my_obj->buf[buf->buf_idx].user_buf.buf_in_use = 1;
   1341             }
   1342         } else {
   1343             LOGD("<DEBUG> : ref count pending count :%d idx = %d",
   1344                  my_obj->buf_status[buf->buf_idx].buf_refcnt, buf->buf_idx);
   1345             pthread_mutex_unlock(&my_obj->buf_lock);
   1346         }
   1347         return rc;
   1348     }
   1349 
   1350     if ((my_obj->cur_buf_idx < 0)
   1351             || (my_obj->cur_buf_idx >= my_obj->buf_num)) {
   1352         for (i = 0; i < my_obj->buf_num; i++) {
   1353             if ((my_obj->buf_status[i].in_kernel)
   1354                     || (my_obj->buf[i].user_buf.buf_in_use)) {
   1355                 continue;
   1356             }
   1357 
   1358             my_obj->cur_buf_idx = index = i;
   1359             break;
   1360         }
   1361     } else {
   1362         index = my_obj->cur_buf_idx;
   1363     }
   1364 
   1365     if (index == -1) {
   1366         LOGE("No Free batch buffer");
   1367         rc = -1;
   1368         return rc;
   1369     }
   1370 
   1371     //Insert Buffer to Batch structure.
   1372     my_obj->buf[index].user_buf.buf_idx[count] = buf->buf_idx;
   1373     my_obj->cur_bufs_staged++;
   1374 
   1375     LOGD("index = %d filled = %d used = %d",
   1376             index,
   1377             my_obj->cur_bufs_staged,
   1378             my_obj->buf[index].user_buf.bufs_used);
   1379 
   1380     if (my_obj->cur_bufs_staged
   1381             == my_obj->buf[index].user_buf.bufs_used){
   1382         pthread_mutex_lock(&my_obj->buf_lock);
   1383         my_obj->buf_status[index].buf_refcnt--;
   1384         if (0 == my_obj->buf_status[index].buf_refcnt) {
   1385             pthread_mutex_unlock(&my_obj->buf_lock);
   1386             cont_buf = (struct msm_camera_user_buf_cont_t *)my_obj->buf[index].buffer;
   1387             cont_buf->buf_cnt = my_obj->buf[index].user_buf.bufs_used;
   1388             for (i = 0; i < (int32_t)cont_buf->buf_cnt; i++) {
   1389                 cont_buf->buf_idx[i] = my_obj->buf[index].user_buf.buf_idx[i];
   1390             }
   1391             rc = mm_stream_qbuf(my_obj, &my_obj->buf[index]);
   1392             if(rc < 0) {
   1393                 LOGE("mm_camera_stream_qbuf(idx=%d) err=%d\n",
   1394                             index, rc);
   1395             } else {
   1396                 for (i = 0; i < (int32_t)cont_buf->buf_cnt; i++) {
   1397                     my_obj->buf[index].user_buf.buf_idx[i] = -1;
   1398                 }
   1399                 my_obj->buf_status[index].in_kernel = 1;
   1400                 my_obj->buf[index].user_buf.buf_in_use = 1;
   1401                 my_obj->cur_bufs_staged = 0;
   1402                 my_obj->cur_buf_idx = -1;
   1403             }
   1404         }else{
   1405             LOGD("<DEBUG> : ref count pending count :%d idx = %d",
   1406                  my_obj->buf_status[index].buf_refcnt, index);
   1407             pthread_mutex_unlock(&my_obj->buf_lock);
   1408         }
   1409     }
   1410 
   1411     return rc;
   1412 }
   1413 
   1414 /*===========================================================================
   1415  * FUNCTION   : mm_stream_read_user_buf
   1416  *
   1417  * DESCRIPTION: dequeue a stream buffer from user buffer queue and fill internal structure
   1418  *
   1419  * PARAMETERS :
   1420  *   @my_obj       : stream object
   1421  *   @buf_info     : ptr to a struct storing buffer information
   1422  *
   1423  * RETURN     : int32_t type of status
   1424  *              0  -- success
   1425  *              -1 -- failure
   1426  *==========================================================================*/
   1427 int32_t mm_stream_read_user_buf(mm_stream_t * my_obj,
   1428         mm_camera_buf_info_t* buf_info)
   1429 {
   1430     int32_t rc = 0, i;
   1431     mm_camera_buf_def_t *stream_buf  = NULL;
   1432     struct msm_camera_user_buf_cont_t *user_buf = NULL;
   1433     nsecs_t interval_nsec = 0, frame_ts = 0, timeStamp = 0;
   1434     int ts_delta = 0;
   1435     uint32_t frameID = 0;
   1436 
   1437     user_buf = (struct msm_camera_user_buf_cont_t *)buf_info->buf->buffer;
   1438 
   1439     if(user_buf != my_obj->buf[buf_info->buf->buf_idx].buffer) {
   1440         LOGD("Buffer modified. ERROR");
   1441         rc = -1;
   1442         return rc;
   1443     }
   1444 
   1445     if (buf_info->buf->frame_idx == 1) {
   1446         frameID = buf_info->buf->frame_idx;
   1447     }else {
   1448         frameID = (buf_info->buf->frame_idx - 1) * user_buf->buf_cnt;
   1449     }
   1450 
   1451     timeStamp = (nsecs_t)(buf_info->buf->ts.tv_sec) *
   1452             1000000000LL + buf_info->buf->ts.tv_nsec;
   1453 
   1454     if (timeStamp <= my_obj->prev_timestamp) {
   1455         LOGE("TimeStamp received less than expected");
   1456         mm_stream_qbuf(my_obj, buf_info->buf);
   1457         return rc;
   1458     } else if (my_obj->prev_timestamp == 0
   1459             || (my_obj->prev_frameID != buf_info->buf->frame_idx + 1)) {
   1460         /* For first frame or incase batch is droped */
   1461         interval_nsec = ((my_obj->stream_info->user_buf_info.frameInterval) * 1000000);
   1462         my_obj->prev_timestamp = (timeStamp - (nsecs_t)(user_buf->buf_cnt * interval_nsec));
   1463     } else {
   1464         ts_delta = timeStamp - my_obj->prev_timestamp;
   1465         interval_nsec = (nsecs_t)(ts_delta / user_buf->buf_cnt);
   1466         LOGD("Timestamp delta = %d timestamp = %lld", ts_delta, timeStamp);
   1467     }
   1468 
   1469     for (i = 0; i < (int32_t)user_buf->buf_cnt; i++) {
   1470         buf_info->buf->user_buf.buf_idx[i] = user_buf->buf_idx[i];
   1471         stream_buf = &my_obj->plane_buf[user_buf->buf_idx[i]];
   1472         stream_buf->frame_idx = frameID + i;
   1473 
   1474         frame_ts  = (i * interval_nsec) + my_obj->prev_timestamp;
   1475 
   1476         stream_buf->ts.tv_sec  = (frame_ts / 1000000000LL);
   1477         stream_buf->ts.tv_nsec = (frame_ts - (stream_buf->ts.tv_sec * 1000000000LL));
   1478         stream_buf->is_uv_subsampled = buf_info->buf->is_uv_subsampled;
   1479 
   1480         LOGD("buf_index %d, frame_idx %d, stream type %d, timestamp = %lld",
   1481                  stream_buf->buf_idx, stream_buf->frame_idx,
   1482                 my_obj->stream_info->stream_type, frame_ts);
   1483     }
   1484 
   1485     buf_info->buf->ts.tv_sec  = (my_obj->prev_timestamp / 1000000000LL);
   1486     buf_info->buf->ts.tv_nsec = (my_obj->prev_timestamp -
   1487             (buf_info->buf->ts.tv_sec * 1000000000LL));
   1488 
   1489     buf_info->buf->user_buf.bufs_used = user_buf->buf_cnt;
   1490     buf_info->buf->user_buf.buf_in_use = 1;
   1491 
   1492     my_obj->prev_timestamp = timeStamp;
   1493     my_obj->prev_frameID = buf_info->buf->frame_idx;
   1494 
   1495     LOGD("X rc = %d",rc);
   1496     return rc;
   1497 }
   1498 
   1499 /*===========================================================================
   1500  * FUNCTION   : mm_stream_read_msm_frame
   1501  *
   1502  * DESCRIPTION: dequeue a stream buffer from kernel queue
   1503  *
   1504  * PARAMETERS :
   1505  *   @my_obj       : stream object
   1506  *   @buf_info     : ptr to a struct storing buffer information
   1507  *   @num_planes   : number of planes in the buffer
   1508  *
   1509  * RETURN     : int32_t type of status
   1510  *              0  -- success
   1511  *              -1 -- failure
   1512  *==========================================================================*/
   1513 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
   1514                                  mm_camera_buf_info_t* buf_info,
   1515                                  uint8_t num_planes)
   1516 {
   1517     int32_t rc = 0;
   1518     struct v4l2_buffer vb;
   1519     struct v4l2_plane planes[VIDEO_MAX_PLANES];
   1520     char frame_type[64];
   1521     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   1522           my_obj->my_hdl, my_obj->fd, my_obj->state);
   1523 
   1524     snprintf(frame_type, sizeof(frame_type), "DQBUF: type %d",
   1525       my_obj->stream_info->stream_type);
   1526     ATRACE_BEGIN(frame_type);
   1527 
   1528     memset(&vb,  0,  sizeof(vb));
   1529     vb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1530     vb.memory = V4L2_MEMORY_USERPTR;
   1531     vb.m.planes = &planes[0];
   1532     vb.length = num_planes;
   1533 
   1534     rc = ioctl(my_obj->fd, VIDIOC_DQBUF, &vb);
   1535     if (0 > rc) {
   1536         LOGE("VIDIOC_DQBUF ioctl call failed on stream type %d (rc=%d): %s",
   1537              my_obj->stream_info->stream_type, rc, strerror(errno));
   1538     } else {
   1539         pthread_mutex_lock(&my_obj->buf_lock);
   1540         my_obj->queued_buffer_count--;
   1541         if (0 == my_obj->queued_buffer_count) {
   1542             LOGH("Stoping poll on stream %p type: %d",
   1543                 my_obj, my_obj->stream_info->stream_type);
   1544             mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1545                 my_obj->my_hdl, mm_camera_async_call);
   1546             LOGH("Stopped poll on stream %p type: %d",
   1547                 my_obj, my_obj->stream_info->stream_type);
   1548         }
   1549         pthread_mutex_unlock(&my_obj->buf_lock);
   1550         uint32_t idx = vb.index;
   1551         buf_info->buf = &my_obj->buf[idx];
   1552         buf_info->frame_idx = vb.sequence;
   1553         buf_info->stream_id = my_obj->my_hdl;
   1554 
   1555         buf_info->buf->stream_id = my_obj->my_hdl;
   1556         buf_info->buf->buf_idx = idx;
   1557         buf_info->buf->frame_idx = vb.sequence;
   1558         buf_info->buf->ts.tv_sec  = vb.timestamp.tv_sec;
   1559         buf_info->buf->ts.tv_nsec = vb.timestamp.tv_usec * 1000;
   1560         buf_info->buf->flags = vb.flags;
   1561 
   1562         LOGH("VIDIOC_DQBUF buf_index %d, frame_idx %d, stream type %d, rc %d,"
   1563                 "queued: %d, buf_type = %d flags = %d",
   1564              vb.index, buf_info->buf->frame_idx,
   1565             my_obj->stream_info->stream_type, rc,
   1566             my_obj->queued_buffer_count, buf_info->buf->buf_type,
   1567             buf_info->buf->flags);
   1568 
   1569         buf_info->buf->is_uv_subsampled =
   1570             (vb.reserved == V4L2_PIX_FMT_NV14 || vb.reserved == V4L2_PIX_FMT_NV41);
   1571 
   1572         if(buf_info->buf->buf_type == CAM_STREAM_BUF_TYPE_USERPTR) {
   1573             mm_stream_read_user_buf(my_obj, buf_info);
   1574         }
   1575 
   1576         if ( NULL != my_obj->mem_vtbl.clean_invalidate_buf ) {
   1577             rc = my_obj->mem_vtbl.clean_invalidate_buf(idx,
   1578                 my_obj->mem_vtbl.user_data);
   1579             if (0 > rc) {
   1580                 LOGE("Clean invalidate cache failed on buffer index: %d",
   1581                      idx);
   1582             }
   1583         } else {
   1584             LOGE("Clean invalidate cache op not supported");
   1585         }
   1586     }
   1587 
   1588     LOGD("X rc = %d",rc);
   1589     ATRACE_END();
   1590     return rc;
   1591 }
   1592 
   1593 /*===========================================================================
   1594  * FUNCTION   : mm_stream_set_parms
   1595  *
   1596  * DESCRIPTION: set parameters per stream
   1597  *
   1598  * PARAMETERS :
   1599  *   @my_obj       : stream object
   1600  *   @in_value     : ptr to a param struct to be set to server
   1601  *
   1602  * RETURN     : int32_t type of status
   1603  *              0  -- success
   1604  *              -1 -- failure
   1605  * NOTE       : Assume the parms struct buf is already mapped to server via
   1606  *              domain socket. Corresponding fields of parameters to be set
   1607  *              are already filled in by upper layer caller.
   1608  *==========================================================================*/
   1609 int32_t mm_stream_set_parm(mm_stream_t *my_obj,
   1610                            cam_stream_parm_buffer_t *in_value)
   1611 {
   1612     int32_t rc = -1;
   1613     int32_t value = 0;
   1614     if (in_value != NULL) {
   1615       mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   1616       int stream_id = my_obj->server_stream_id;
   1617       rc = mm_camera_util_s_ctrl(cam_obj, stream_id, my_obj->fd,
   1618               CAM_PRIV_STREAM_PARM, &value);
   1619       if (rc < 0) {
   1620         LOGE("Failed to set stream parameter type = %d", in_value->type);
   1621       }
   1622     }
   1623     return rc;
   1624 }
   1625 
   1626 /*===========================================================================
   1627  * FUNCTION   : mm_stream_get_parms
   1628  *
   1629  * DESCRIPTION: get parameters per stream
   1630  *
   1631  * PARAMETERS :
   1632  *   @my_obj       : stream object
   1633  *   @in_value     : ptr to a param struct to be get from server
   1634  *
   1635  * RETURN     : int32_t type of status
   1636  *              0  -- success
   1637  *              -1 -- failure
   1638  * NOTE       : Assume the parms struct buf is already mapped to server via
   1639  *              domain socket. Corresponding fields of parameters to be get
   1640  *              are already filled in by upper layer caller.
   1641  *==========================================================================*/
   1642 int32_t mm_stream_get_parm(mm_stream_t *my_obj,
   1643                            cam_stream_parm_buffer_t *in_value)
   1644 {
   1645     int32_t rc = -1;
   1646     int32_t value = 0;
   1647     if (in_value != NULL) {
   1648         mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   1649         int stream_id = my_obj->server_stream_id;
   1650         rc = mm_camera_util_g_ctrl(cam_obj, stream_id, my_obj->fd,
   1651               CAM_PRIV_STREAM_PARM, &value);
   1652     }
   1653     return rc;
   1654 }
   1655 
   1656 /*===========================================================================
   1657  * FUNCTION   : mm_stream_do_actions
   1658  *
   1659  * DESCRIPTION: request server to perform stream based actions
   1660  *
   1661  * PARAMETERS :
   1662  *   @my_obj       : stream object
   1663  *   @in_value     : ptr to a struct of actions to be performed by the server
   1664  *
   1665  * RETURN     : int32_t type of status
   1666  *              0  -- success
   1667  *              -1 -- failure
   1668  * NOTE       : Assume the action struct buf is already mapped to server via
   1669  *              domain socket. Corresponding fields of actions to be performed
   1670  *              are already filled in by upper layer caller.
   1671  *==========================================================================*/
   1672 int32_t mm_stream_do_action(mm_stream_t *my_obj,
   1673                             void *in_value)
   1674 {
   1675     int32_t rc = -1;
   1676     int32_t value = 0;
   1677     if (in_value != NULL) {
   1678         mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   1679         int stream_id = my_obj->server_stream_id;
   1680         rc = mm_camera_util_s_ctrl(cam_obj, stream_id, my_obj->fd,
   1681               CAM_PRIV_STREAM_PARM, &value);
   1682     }
   1683     return rc;
   1684 }
   1685 
   1686 /*===========================================================================
   1687  * FUNCTION   : mm_stream_set_ext_mode
   1688  *
   1689  * DESCRIPTION: set stream extended mode to server via v4l2 ioctl
   1690  *
   1691  * PARAMETERS :
   1692  *   @my_obj       : stream object
   1693  *
   1694  * RETURN     : int32_t type of status
   1695  *              0  -- success
   1696  *              -1 -- failure
   1697  * NOTE       : Server will return a server stream id that uniquely identify
   1698  *              this stream on server side. Later on communication to server
   1699  *              per stream should use this server stream id.
   1700  *==========================================================================*/
   1701 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj)
   1702 {
   1703     int32_t rc = 0;
   1704     struct v4l2_streamparm s_parm;
   1705     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   1706           my_obj->my_hdl, my_obj->fd, my_obj->state);
   1707 
   1708     memset(&s_parm, 0, sizeof(s_parm));
   1709     s_parm.type =  V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1710 
   1711     rc = ioctl(my_obj->fd, VIDIOC_S_PARM, &s_parm);
   1712     LOGD("stream fd=%d, rc=%d, extended_mode=%d",
   1713          my_obj->fd, rc, s_parm.parm.capture.extendedmode);
   1714 
   1715     if (rc == 0) {
   1716         my_obj->server_stream_id = s_parm.parm.capture.extendedmode;
   1717 #ifndef DAEMON_PRESENT
   1718         cam_shim_packet_t *shim_cmd;
   1719         cam_shim_cmd_data shim_cmd_data;
   1720         mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   1721 
   1722         memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
   1723         shim_cmd_data.command = MSM_CAMERA_PRIV_NEW_STREAM;
   1724         shim_cmd_data.stream_id = my_obj->server_stream_id;
   1725         shim_cmd_data.value = NULL;
   1726         shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
   1727                 cam_obj->sessionid, &shim_cmd_data);
   1728         rc = mm_camera_module_send_cmd(shim_cmd);
   1729         mm_camera_destroy_shim_cmd_packet(shim_cmd);
   1730 #endif /* DAEMON_PRESENT */
   1731     } else {
   1732         LOGE("VIDIOC_S_PARM  extendedmode error");
   1733     }
   1734     return rc;
   1735 }
   1736 
   1737 /*===========================================================================
   1738  * FUNCTION   : mm_stream_qbuf
   1739  *
   1740  * DESCRIPTION: enqueue buffer back to kernel queue for furture use
   1741  *
   1742  * PARAMETERS :
   1743  *   @my_obj       : stream object
   1744  *   @buf          : ptr to a struct storing buffer information
   1745  *
   1746  * RETURN     : int32_t type of status
   1747  *              0  -- success
   1748  *              -1 -- failure
   1749  *==========================================================================*/
   1750 int32_t mm_stream_qbuf(mm_stream_t *my_obj, mm_camera_buf_def_t *buf)
   1751 {
   1752     int32_t rc = 0;
   1753     uint32_t length = 0;
   1754     struct v4l2_buffer buffer;
   1755     struct v4l2_plane planes[VIDEO_MAX_PLANES];
   1756     LOGD("E, my_handle = 0x%x, fd = %d, state = %d, stream type = %d",
   1757           my_obj->my_hdl, my_obj->fd, my_obj->state,
   1758          my_obj->stream_info->stream_type);
   1759 
   1760     if (buf->buf_type == CAM_STREAM_BUF_TYPE_USERPTR) {
   1761         LOGD("USERPTR num_buf = %d, idx = %d",
   1762                 buf->user_buf.bufs_used, buf->buf_idx);
   1763         memset(&planes, 0, sizeof(planes));
   1764         planes[0].length = my_obj->stream_info->user_buf_info.size;
   1765         planes[0].m.userptr = buf->fd;
   1766         length = 1;
   1767     } else {
   1768         memcpy(planes, buf->planes_buf.planes, sizeof(planes));
   1769         length = buf->planes_buf.num_planes;
   1770     }
   1771 
   1772     memset(&buffer, 0, sizeof(buffer));
   1773     buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1774     buffer.memory = V4L2_MEMORY_USERPTR;
   1775     buffer.index = (__u32)buf->buf_idx;
   1776     buffer.m.planes = &planes[0];
   1777     buffer.length = (__u32)length;
   1778 
   1779     if ( NULL != my_obj->mem_vtbl.invalidate_buf ) {
   1780         rc = my_obj->mem_vtbl.invalidate_buf(buffer.index,
   1781                                              my_obj->mem_vtbl.user_data);
   1782         if ( 0 > rc ) {
   1783             LOGE("Cache invalidate failed on buffer index: %d",
   1784                        buffer.index);
   1785             return rc;
   1786         }
   1787     } else {
   1788         LOGE("Cache invalidate op not added");
   1789     }
   1790 
   1791     pthread_mutex_lock(&my_obj->buf_lock);
   1792     my_obj->queued_buffer_count++;
   1793     if (1 == my_obj->queued_buffer_count) {
   1794         /* Add fd to data poll thread */
   1795         LOGH("Starting poll on stream %p type: %d",
   1796             my_obj,my_obj->stream_info->stream_type);
   1797         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1798             my_obj->my_hdl, my_obj->fd, mm_stream_data_notify, (void*)my_obj,
   1799             mm_camera_async_call);
   1800         if (0 > rc) {
   1801             LOGE("Add poll on stream %p type: %d fd error (rc=%d)",
   1802                  my_obj, my_obj->stream_info->stream_type, rc);
   1803         } else {
   1804             LOGH("Started poll on stream %p type: %d",
   1805                 my_obj, my_obj->stream_info->stream_type);
   1806         }
   1807     }
   1808     pthread_mutex_unlock(&my_obj->buf_lock);
   1809 
   1810     rc = ioctl(my_obj->fd, VIDIOC_QBUF, &buffer);
   1811     pthread_mutex_lock(&my_obj->buf_lock);
   1812     if (0 > rc) {
   1813         LOGE("VIDIOC_QBUF ioctl call failed on stream type %d (rc=%d): %s",
   1814              my_obj->stream_info->stream_type, rc, strerror(errno));
   1815         my_obj->queued_buffer_count--;
   1816         if (0 == my_obj->queued_buffer_count) {
   1817             /* Remove fd from data poll in case of failing
   1818              * first buffer queuing attempt */
   1819             LOGH("Stoping poll on stream %p type: %d",
   1820                 my_obj, my_obj->stream_info->stream_type);
   1821             mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1822                 my_obj->my_hdl, mm_camera_async_call);
   1823             LOGH("Stopped poll on stream %p type: %d",
   1824                 my_obj, my_obj->stream_info->stream_type);
   1825         }
   1826     } else {
   1827         LOGH("VIDIOC_QBUF buf_index %d, frame_idx %d stream type %d, rc %d,"
   1828                 " queued: %d, buf_type = %d",
   1829                  buffer.index, buf->frame_idx, my_obj->stream_info->stream_type, rc,
   1830                 my_obj->queued_buffer_count, buf->buf_type);
   1831     }
   1832     pthread_mutex_unlock(&my_obj->buf_lock);
   1833 
   1834     return rc;
   1835 }
   1836 
   1837 /*===========================================================================
   1838  * FUNCTION   : mm_stream_request_buf
   1839  *
   1840  * DESCRIPTION: This function let kernel know the amount of buffers need to
   1841  *              be registered via v4l2 ioctl.
   1842  *
   1843  * PARAMETERS :
   1844  *   @my_obj       : stream object
   1845  *
   1846  * RETURN     : int32_t type of status
   1847  *              0  -- success
   1848  *              -1 -- failure
   1849  *==========================================================================*/
   1850 int32_t mm_stream_request_buf(mm_stream_t * my_obj)
   1851 {
   1852     int32_t rc = 0;
   1853     struct v4l2_requestbuffers bufreq;
   1854     uint8_t buf_num = my_obj->buf_num;
   1855     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   1856           my_obj->my_hdl, my_obj->fd, my_obj->state);
   1857 
   1858     LOGD("buf_num = %d, stream type = %d",
   1859           buf_num, my_obj->stream_info->stream_type);
   1860 
   1861     if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) {
   1862         LOGE("buf num %d > max limit %d\n",
   1863                     buf_num, MM_CAMERA_MAX_NUM_FRAMES);
   1864         return -1;
   1865     }
   1866 
   1867     memset(&bufreq, 0, sizeof(bufreq));
   1868     bufreq.count = buf_num;
   1869     bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1870     bufreq.memory = V4L2_MEMORY_USERPTR;
   1871     rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
   1872     if (rc < 0) {
   1873       LOGE("fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d, errno %d",
   1874             my_obj->fd, rc, errno);
   1875     }
   1876 
   1877     LOGD("X rc = %d",rc);
   1878     return rc;
   1879 }
   1880 
   1881 /*===========================================================================
   1882  * FUNCTION   : mm_stream_need_wait_for_mapping
   1883  *
   1884  * DESCRIPTION: Utility function to determine whether to wait for mapping
   1885  *
   1886  * PARAMETERS :
   1887  *   @my_obj       : stream object
   1888  *
   1889  * RETURN     : int8_t whether wait is necessary
   1890  *              0  -- no wait
   1891  *              1 -- wait
   1892  *==========================================================================*/
   1893 int8_t mm_stream_need_wait_for_mapping(mm_stream_t * my_obj)
   1894 {
   1895     uint32_t i;
   1896     int8_t ret = 0;
   1897 
   1898     for (i = 0; i < my_obj->buf_num; i++) {
   1899         if ((my_obj->buf_status[i].map_status == 0)
   1900                 && (my_obj->buf_status[i].in_kernel)) {
   1901             /*do not signal in case if any buffer is not mapped
   1902               but queued to kernel.*/
   1903             ret = 1;
   1904         } else if (my_obj->buf_status[i].map_status < 0) {
   1905             return 0;
   1906         }
   1907     }
   1908 
   1909     return ret;
   1910 }
   1911 
   1912 /*===========================================================================
   1913  * FUNCTION   : mm_stream_map_buf
   1914  *
   1915  * DESCRIPTION: mapping stream buffer via domain socket to server
   1916  *
   1917  * PARAMETERS :
   1918  *   @my_obj       : stream object
   1919  *   @buf_type     : type of buffer to be mapped. could be following values:
   1920  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1921  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1922  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1923  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1924  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1925  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1926  *   @plane_idx    : plane index. If all planes share the same fd,
   1927  *                   plane_idx = -1; otherwise, plean_idx is the
   1928  *                   index to plane (0..num_of_planes)
   1929  *   @fd           : file descriptor of the buffer
   1930  *   @size         : size of the buffer
   1931  *
   1932  * RETURN     : int32_t type of status
   1933  *              0  -- success
   1934  *              -1 -- failure
   1935  *==========================================================================*/
   1936 int32_t mm_stream_map_buf(mm_stream_t * my_obj,
   1937         uint8_t buf_type, uint32_t frame_idx,
   1938         int32_t plane_idx, int32_t fd,
   1939         size_t size, void *buffer)
   1940 {
   1941     int32_t rc = 0;
   1942     if (NULL == my_obj || NULL == my_obj->ch_obj || NULL == my_obj->ch_obj->cam_obj) {
   1943         LOGE("NULL obj of stream/channel/camera");
   1944         return -1;
   1945     }
   1946 
   1947     cam_sock_packet_t packet;
   1948     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1949     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
   1950     packet.payload.buf_map.type = buf_type;
   1951     packet.payload.buf_map.fd = fd;
   1952     packet.payload.buf_map.size = size;
   1953     packet.payload.buf_map.stream_id = my_obj->server_stream_id;
   1954     packet.payload.buf_map.frame_idx = frame_idx;
   1955     packet.payload.buf_map.plane_idx = plane_idx;
   1956     packet.payload.buf_map.buffer = buffer;
   1957     LOGD("mapping buf_type %d, stream_id %d, frame_idx %d, fd %d, size %d",
   1958              buf_type, my_obj->server_stream_id, frame_idx, fd, size);
   1959 
   1960 #ifdef DAEMON_PRESENT
   1961     rc = mm_camera_util_sendmsg(my_obj->ch_obj->cam_obj,
   1962                                 &packet, sizeof(cam_sock_packet_t), fd);
   1963 #else
   1964     cam_shim_packet_t *shim_cmd;
   1965     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
   1966             my_obj->ch_obj->cam_obj->sessionid, &packet);
   1967     rc = mm_camera_module_send_cmd(shim_cmd);
   1968     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   1969 #endif
   1970     if ((buf_type == CAM_MAPPING_BUF_TYPE_STREAM_BUF)
   1971             || ((buf_type
   1972             == CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF)
   1973             && (my_obj->stream_info != NULL)
   1974             && (my_obj->stream_info->streaming_mode
   1975             == CAM_STREAMING_MODE_BATCH))) {
   1976         pthread_mutex_lock(&my_obj->buf_lock);
   1977         if (rc < 0) {
   1978             my_obj->buf_status[frame_idx].map_status = -1;
   1979             LOGE("fail status =%d", my_obj->buf_status[frame_idx].map_status);
   1980         } else {
   1981             my_obj->buf_status[frame_idx].map_status = 1;
   1982         }
   1983         if (mm_stream_need_wait_for_mapping(my_obj) == 0) {
   1984             LOGD("Buffer mapping Done: Signal strm fd = %d",
   1985                      my_obj->fd);
   1986             pthread_cond_signal(&my_obj->buf_cond);
   1987         }
   1988         pthread_mutex_unlock(&my_obj->buf_lock);
   1989     }
   1990     return rc;
   1991 }
   1992 
   1993 /*===========================================================================
   1994  * FUNCTION   : mm_stream_map_bufs
   1995  *
   1996  * DESCRIPTION: mapping stream buffers via domain socket to server
   1997  *
   1998  * PARAMETERS :
   1999  *   @my_obj       : stream object
   2000  *   @buf_map_list : list of buffer objects to map
   2001  *
   2002  * RETURN     : int32_t type of status
   2003  *              0  -- success
   2004  *              -1 -- failure
   2005  *==========================================================================*/
   2006 
   2007 int32_t mm_stream_map_bufs(mm_stream_t * my_obj,
   2008                            const cam_buf_map_type_list *buf_map_list)
   2009 {
   2010     if (NULL == my_obj || NULL == my_obj->ch_obj || NULL == my_obj->ch_obj->cam_obj) {
   2011         LOGE("NULL obj of stream/channel/camera");
   2012         return -1;
   2013     }
   2014 
   2015     cam_sock_packet_t packet;
   2016     memset(&packet, 0, sizeof(cam_sock_packet_t));
   2017     packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING;
   2018 
   2019     memcpy(&packet.payload.buf_map_list, buf_map_list,
   2020            sizeof(packet.payload.buf_map_list));
   2021 
   2022     int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM];
   2023     uint32_t numbufs = packet.payload.buf_map_list.length;
   2024     if (numbufs < 1) {
   2025       LOGD("No buffers, suppressing the mapping command");
   2026       return 0;
   2027     }
   2028 
   2029     uint32_t i;
   2030     for (i = 0; i < numbufs; i++) {
   2031         packet.payload.buf_map_list.buf_maps[i].stream_id = my_obj->server_stream_id;
   2032         sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd;
   2033     }
   2034 
   2035     for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) {
   2036         packet.payload.buf_map_list.buf_maps[i].fd = -1;
   2037         sendfds[i] = -1;
   2038     }
   2039 
   2040 #ifdef DAEMON_PRESENT
   2041     int32_t ret = mm_camera_util_bundled_sendmsg(my_obj->ch_obj->cam_obj,
   2042             &packet, sizeof(cam_sock_packet_t), sendfds, numbufs);
   2043 #else
   2044     cam_shim_packet_t *shim_cmd;
   2045     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
   2046             my_obj->ch_obj->cam_obj->sessionid, &packet);
   2047     int32_t ret = mm_camera_module_send_cmd(shim_cmd);
   2048     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   2049 #endif
   2050     if ((numbufs > 0) && ((buf_map_list->buf_maps[0].type
   2051             == CAM_MAPPING_BUF_TYPE_STREAM_BUF)
   2052             || ((buf_map_list->buf_maps[0].type ==
   2053             CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF)
   2054             && (my_obj->stream_info != NULL)
   2055             && (my_obj->stream_info->streaming_mode
   2056             == CAM_STREAMING_MODE_BATCH)))) {
   2057         pthread_mutex_lock(&my_obj->buf_lock);
   2058         for (i = 0; i < numbufs; i++) {
   2059            if (ret < 0) {
   2060                my_obj->buf_status[i].map_status = -1;
   2061            } else {
   2062                my_obj->buf_status[i].map_status = 1;
   2063            }
   2064         }
   2065 
   2066         if (mm_stream_need_wait_for_mapping(my_obj) == 0) {
   2067             LOGD("Buffer mapping Done: Signal strm fd = %d",
   2068                      my_obj->fd);
   2069             pthread_cond_signal(&my_obj->buf_cond);
   2070         }
   2071         pthread_mutex_unlock(&my_obj->buf_lock);
   2072     }
   2073     return ret;
   2074 }
   2075 
   2076 /*===========================================================================
   2077  * FUNCTION   : mm_stream_unmap_buf
   2078  *
   2079  * DESCRIPTION: unmapping stream buffer via domain socket to server
   2080  *
   2081  * PARAMETERS :
   2082  *   @my_obj       : stream object
   2083  *   @buf_type     : type of buffer to be unmapped. could be following values:
   2084  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   2085  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   2086  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2087  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   2088  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   2089  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2090  *   @plane_idx    : plane index. If all planes share the same fd,
   2091  *                   plane_idx = -1; otherwise, plean_idx is the
   2092  *                   index to plane (0..num_of_planes)
   2093  *
   2094  * RETURN     : int32_t type of status
   2095  *              0  -- success
   2096  *              -1 -- failure
   2097  *==========================================================================*/
   2098 int32_t mm_stream_unmap_buf(mm_stream_t * my_obj,
   2099                             uint8_t buf_type,
   2100                             uint32_t frame_idx,
   2101                             int32_t plane_idx)
   2102 {
   2103     int32_t ret;
   2104     if (NULL == my_obj || NULL == my_obj->ch_obj || NULL == my_obj->ch_obj->cam_obj) {
   2105         LOGE("NULL obj of stream/channel/camera");
   2106         return -1;
   2107     }
   2108     cam_sock_packet_t packet;
   2109     memset(&packet, 0, sizeof(cam_sock_packet_t));
   2110     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
   2111     packet.payload.buf_unmap.type = buf_type;
   2112     packet.payload.buf_unmap.stream_id = my_obj->server_stream_id;
   2113     packet.payload.buf_unmap.frame_idx = frame_idx;
   2114     packet.payload.buf_unmap.plane_idx = plane_idx;
   2115 #ifdef DAEMON_PRESENT
   2116     ret = mm_camera_util_sendmsg(my_obj->ch_obj->cam_obj,
   2117             &packet, sizeof(cam_sock_packet_t), -1);
   2118 #else
   2119     cam_shim_packet_t *shim_cmd;
   2120     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
   2121             my_obj->ch_obj->cam_obj->sessionid, &packet);
   2122     ret = mm_camera_module_send_cmd(shim_cmd);
   2123     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   2124 #endif
   2125     pthread_mutex_lock(&my_obj->buf_lock);
   2126     my_obj->buf_status[frame_idx].map_status = 0;
   2127     pthread_mutex_unlock(&my_obj->buf_lock);
   2128     return ret;
   2129 }
   2130 
   2131 /*===========================================================================
   2132  * FUNCTION   : mm_stream_init_bufs
   2133  *
   2134  * DESCRIPTION: initialize stream buffers needed. This function will request
   2135  *              buffers needed from upper layer through the mem ops table passed
   2136  *              during configuration stage.
   2137  *
   2138  * PARAMETERS :
   2139  *   @my_obj  : stream object
   2140  *
   2141  * RETURN     : int32_t type of status
   2142  *              0  -- success
   2143  *              -1 -- failure
   2144  *==========================================================================*/
   2145 int32_t mm_stream_init_bufs(mm_stream_t * my_obj)
   2146 {
   2147     int32_t i, rc = 0;
   2148     uint8_t *reg_flags = NULL;
   2149     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   2150           my_obj->my_hdl, my_obj->fd, my_obj->state);
   2151 
   2152     /* deinit buf if it's not NULL*/
   2153     if (NULL != my_obj->buf) {
   2154         mm_stream_deinit_bufs(my_obj);
   2155     }
   2156 
   2157     rc = my_obj->mem_vtbl.get_bufs(&my_obj->frame_offset,
   2158                                    &my_obj->buf_num,
   2159                                    &reg_flags,
   2160                                    &my_obj->buf,
   2161                                    &my_obj->map_ops,
   2162                                    my_obj->mem_vtbl.user_data);
   2163 
   2164     if (0 != rc) {
   2165         LOGE("Error get buf, rc = %d\n", rc);
   2166         return rc;
   2167     }
   2168 
   2169     for (i = 0; i < my_obj->buf_num; i++) {
   2170         my_obj->buf_status[i].initial_reg_flag = reg_flags[i];
   2171         my_obj->buf[i].stream_id = my_obj->my_hdl;
   2172         my_obj->buf[i].stream_type = my_obj->stream_info->stream_type;
   2173 
   2174         if (my_obj->buf[i].buf_type == CAM_STREAM_BUF_TYPE_USERPTR) {
   2175             my_obj->buf[i].user_buf.bufs_used =
   2176                     (int8_t)my_obj->stream_info->user_buf_info.frame_buf_cnt;
   2177             my_obj->buf[i].user_buf.buf_in_use = reg_flags[i];
   2178         }
   2179     }
   2180 
   2181     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   2182         my_obj->plane_buf = my_obj->buf[0].user_buf.plane_buf;
   2183         if (my_obj->plane_buf != NULL) {
   2184             my_obj->plane_buf_num =
   2185                     my_obj->buf_num *
   2186                     my_obj->stream_info->user_buf_info.frame_buf_cnt;
   2187             for (i = 0; i < my_obj->plane_buf_num; i++) {
   2188                 my_obj->plane_buf[i].stream_id = my_obj->my_hdl;
   2189                 my_obj->plane_buf[i].stream_type = my_obj->stream_info->stream_type;
   2190             }
   2191         }
   2192         my_obj->cur_bufs_staged = 0;
   2193         my_obj->cur_buf_idx = -1;
   2194     }
   2195 
   2196     free(reg_flags);
   2197     reg_flags = NULL;
   2198 
   2199     /* update in stream info about number of stream buffers */
   2200     my_obj->stream_info->num_bufs = my_obj->buf_num;
   2201 
   2202     return rc;
   2203 }
   2204 
   2205 /*===========================================================================
   2206  * FUNCTION   : mm_stream_deinit_bufs
   2207  *
   2208  * DESCRIPTION: return stream buffers to upper layer through the mem ops table
   2209  *              passed during configuration stage.
   2210  *
   2211  * PARAMETERS :
   2212  *   @my_obj  : stream object
   2213  *
   2214  * RETURN     : int32_t type of status
   2215  *              0  -- success
   2216  *              -1 -- failure
   2217  *==========================================================================*/
   2218 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj)
   2219 {
   2220     int32_t rc = 0;
   2221 
   2222     mm_camera_map_unmap_ops_tbl_t ops_tbl;
   2223     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   2224           my_obj->my_hdl, my_obj->fd, my_obj->state);
   2225 
   2226     if (NULL == my_obj->buf) {
   2227         LOGD("Buf is NULL, no need to deinit");
   2228         return rc;
   2229     }
   2230 
   2231     /* release bufs */
   2232     ops_tbl.map_ops = mm_stream_map_buf_ops;
   2233     ops_tbl.bundled_map_ops = mm_stream_bundled_map_buf_ops;
   2234     ops_tbl.unmap_ops = mm_stream_unmap_buf_ops;
   2235     ops_tbl.userdata = my_obj;
   2236 
   2237     rc = my_obj->mem_vtbl.put_bufs(&ops_tbl,
   2238                                    my_obj->mem_vtbl.user_data);
   2239 
   2240     if (my_obj->plane_buf != NULL) {
   2241         free(my_obj->plane_buf);
   2242         my_obj->plane_buf = NULL;
   2243     }
   2244 
   2245     free(my_obj->buf);
   2246     my_obj->buf = NULL;
   2247 
   2248     return rc;
   2249 }
   2250 
   2251 /*===========================================================================
   2252  * FUNCTION   : mm_stream_reg_buf
   2253  *
   2254  * DESCRIPTION: register buffers with kernel by calling v4l2 ioctl QBUF for
   2255  *              each buffer in the stream
   2256  *
   2257  * PARAMETERS :
   2258  *   @my_obj  : stream object
   2259  *
   2260  * RETURN     : int32_t type of status
   2261  *              0  -- success
   2262  *              -1 -- failure
   2263  *==========================================================================*/
   2264 int32_t mm_stream_reg_buf(mm_stream_t * my_obj)
   2265 {
   2266     int32_t rc = 0;
   2267     uint8_t i;
   2268     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   2269           my_obj->my_hdl, my_obj->fd, my_obj->state);
   2270 
   2271     rc = mm_stream_request_buf(my_obj);
   2272     if (rc != 0) {
   2273         return rc;
   2274     }
   2275 
   2276     my_obj->queued_buffer_count = 0;
   2277     for(i = 0; i < my_obj->buf_num; i++){
   2278         /* check if need to qbuf initially */
   2279         if (my_obj->buf_status[i].initial_reg_flag) {
   2280             rc = mm_stream_qbuf(my_obj, &my_obj->buf[i]);
   2281             if (rc != 0) {
   2282                 LOGE("VIDIOC_QBUF rc = %d\n", rc);
   2283                 break;
   2284             }
   2285             my_obj->buf_status[i].buf_refcnt = 0;
   2286             my_obj->buf_status[i].in_kernel = 1;
   2287         } else {
   2288             /* the buf is held by upper layer, will not queue into kernel.
   2289              * add buf reference count */
   2290             my_obj->buf_status[i].buf_refcnt = 1;
   2291             my_obj->buf_status[i].in_kernel = 0;
   2292         }
   2293     }
   2294 
   2295     return rc;
   2296 }
   2297 
   2298 /*===========================================================================
   2299  * FUNCTION   : mm_stream_unreg buf
   2300  *
   2301  * DESCRIPTION: unregister all stream buffers from kernel
   2302  *
   2303  * PARAMETERS :
   2304  *   @my_obj  : stream object
   2305  *
   2306  * RETURN     : int32_t type of status
   2307  *              0  -- success
   2308  *              -1 -- failure
   2309  *==========================================================================*/
   2310 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj)
   2311 {
   2312     struct v4l2_requestbuffers bufreq;
   2313     int32_t i, rc = 0;
   2314     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   2315           my_obj->my_hdl, my_obj->fd, my_obj->state);
   2316 
   2317     /* unreg buf to kernel */
   2318     bufreq.count = 0;
   2319     bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2320     bufreq.memory = V4L2_MEMORY_USERPTR;
   2321     rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
   2322     if (rc < 0) {
   2323         LOGE("fd=%d, VIDIOC_REQBUFS failed, rc=%d, errno %d",
   2324                my_obj->fd, rc, errno);
   2325     }
   2326 
   2327     /* reset buf reference count */
   2328     pthread_mutex_lock(&my_obj->buf_lock);
   2329     for(i = 0; i < my_obj->buf_num; i++){
   2330         my_obj->buf_status[i].buf_refcnt = 0;
   2331         my_obj->buf_status[i].in_kernel = 0;
   2332     }
   2333     pthread_mutex_unlock(&my_obj->buf_lock);
   2334 
   2335     return rc;
   2336 }
   2337 
   2338 /*===========================================================================
   2339  * FUNCTION   : mm_stream_get_v4l2_fmt
   2340  *
   2341  * DESCRIPTION: translate camera image format into FOURCC code
   2342  *
   2343  * PARAMETERS :
   2344  *   @fmt     : camera image format
   2345  *
   2346  * RETURN     : FOURCC code for image format
   2347  *==========================================================================*/
   2348 uint32_t mm_stream_get_v4l2_fmt(cam_format_t fmt)
   2349 {
   2350     uint32_t val = 0;
   2351     switch(fmt) {
   2352     case CAM_FORMAT_YUV_420_NV12:
   2353     case CAM_FORMAT_YUV_420_NV12_VENUS:
   2354     case CAM_FORMAT_YUV_420_NV12_UBWC:
   2355         val = V4L2_PIX_FMT_NV12;
   2356         break;
   2357     case CAM_FORMAT_YUV_420_NV21:
   2358     case CAM_FORMAT_YUV_420_NV21_VENUS:
   2359         val = V4L2_PIX_FMT_NV21;
   2360         break;
   2361     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG:
   2362     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG:
   2363         val= V4L2_PIX_FMT_SGBRG10;
   2364         break;
   2365     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GRBG:
   2366     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GRBG:
   2367         val= V4L2_PIX_FMT_SGRBG10;
   2368         break;
   2369     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_RGGB:
   2370     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_RGGB:
   2371         val= V4L2_PIX_FMT_SRGGB10;
   2372         break;
   2373     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_BGGR:
   2374     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_BGGR:
   2375         val= V4L2_PIX_FMT_SBGGR10;
   2376         break;
   2377     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GBRG:
   2378     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GBRG:
   2379         val= V4L2_PIX_FMT_SGBRG12;
   2380         break;
   2381     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GRBG:
   2382     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GRBG:
   2383         val= V4L2_PIX_FMT_SGRBG12;
   2384         break;
   2385     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_RGGB:
   2386     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_RGGB:
   2387         val= V4L2_PIX_FMT_SRGGB12;
   2388         break;
   2389     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_BGGR:
   2390     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR:
   2391         val = V4L2_PIX_FMT_SBGGR12;
   2392         break;
   2393     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_GBRG:
   2394     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_GBRG:
   2395         val= V4L2_PIX_FMT_SGBRG14;
   2396         break;
   2397     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_GRBG:
   2398     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_GRBG:
   2399         val= V4L2_PIX_FMT_SGRBG14;
   2400         break;
   2401     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_RGGB:
   2402     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_RGGB:
   2403         val= V4L2_PIX_FMT_SRGGB14;
   2404         break;
   2405     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_BGGR:
   2406     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_BGGR:
   2407         val = V4L2_PIX_FMT_SBGGR14;
   2408         break;
   2409     case CAM_FORMAT_YUV_422_NV61:
   2410         val= V4L2_PIX_FMT_NV61;
   2411         break;
   2412     case CAM_FORMAT_YUV_RAW_8BIT_YUYV:
   2413         val= V4L2_PIX_FMT_YUYV;
   2414         break;
   2415     case CAM_FORMAT_YUV_RAW_8BIT_YVYU:
   2416         val= V4L2_PIX_FMT_YVYU;
   2417         break;
   2418     case CAM_FORMAT_YUV_RAW_8BIT_UYVY:
   2419         val= V4L2_PIX_FMT_UYVY;
   2420         break;
   2421     case CAM_FORMAT_YUV_RAW_8BIT_VYUY:
   2422         val= V4L2_PIX_FMT_VYUY;
   2423         break;
   2424     case CAM_FORMAT_YUV_420_YV12:
   2425         val= V4L2_PIX_FMT_NV12;
   2426         break;
   2427     case CAM_FORMAT_YUV_422_NV16:
   2428         val= V4L2_PIX_FMT_NV16;
   2429         break;
   2430     case CAM_FORMAT_Y_ONLY:
   2431         val= V4L2_PIX_FMT_GREY;
   2432         break;
   2433     case CAM_FORMAT_Y_ONLY_10_BPP:
   2434         val= V4L2_PIX_FMT_Y10;
   2435         break;
   2436     case CAM_FORMAT_Y_ONLY_12_BPP:
   2437         val= V4L2_PIX_FMT_Y12;
   2438         break;
   2439     case CAM_FORMAT_Y_ONLY_14_BPP:
   2440         /* No v4l2 format is defined yet for CAM_FORMAT_Y_ONLY_14_BPP */
   2441         /* val= V4L2_PIX_FMT_Y14; */
   2442         val = 0;
   2443         LOGE("Unknown fmt=%d", fmt);
   2444         break;
   2445     case CAM_FORMAT_MAX:
   2446         /* CAM_STREAM_TYPE_DEFAULT,
   2447          * CAM_STREAM_TYPE_OFFLINE_PROC,
   2448          * and CAM_STREAM_TYPE_METADATA
   2449          * set fmt to CAM_FORMAT_MAX*/
   2450         val = 0;
   2451         break;
   2452     default:
   2453         val = 0;
   2454         LOGE("Unknown fmt=%d", fmt);
   2455         break;
   2456     }
   2457     LOGD("fmt=%d, val =%d", fmt, val);
   2458     return val;
   2459 }
   2460 
   2461 /*===========================================================================
   2462  * FUNCTION   : mm_stream_calc_offset_preview
   2463  *
   2464  * DESCRIPTION: calculate preview frame offset based on format and
   2465  *              padding information
   2466  *
   2467  * PARAMETERS :
   2468  *   @fmt     : image format
   2469  *   @dim     : image dimension
   2470  *   @buf_planes : [out] buffer plane information
   2471  *
   2472  * RETURN     : int32_t type of status
   2473  *              0  -- success
   2474  *              -1 -- failure
   2475  *==========================================================================*/
   2476 int32_t mm_stream_calc_offset_preview(cam_stream_info_t *stream_info,
   2477                                       cam_dimension_t *dim,
   2478                                       cam_padding_info_t *padding,
   2479                                       cam_stream_buf_plane_info_t *buf_planes)
   2480 {
   2481     int32_t rc = 0;
   2482     int stride = 0, scanline = 0;
   2483 
   2484     uint32_t width_padding = 0;
   2485     uint32_t height_padding = 0;
   2486 
   2487     switch (stream_info->fmt) {
   2488     case CAM_FORMAT_YUV_420_NV12:
   2489     case CAM_FORMAT_YUV_420_NV21:
   2490     case CAM_FORMAT_Y_ONLY:
   2491     case CAM_FORMAT_Y_ONLY_10_BPP:
   2492     case CAM_FORMAT_Y_ONLY_12_BPP:
   2493     case CAM_FORMAT_Y_ONLY_14_BPP:
   2494         /* 2 planes: Y + CbCr */
   2495         buf_planes->plane_info.num_planes = 2;
   2496 
   2497         if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2498             width_padding =  padding->width_padding;
   2499             height_padding = CAM_PAD_TO_2;
   2500         } else {
   2501             width_padding =  padding->width_padding;
   2502             height_padding = padding->height_padding;
   2503         }
   2504 
   2505         stride = PAD_TO_SIZE(dim->width, width_padding);
   2506         scanline = PAD_TO_SIZE(dim->height, height_padding);
   2507 
   2508         buf_planes->plane_info.mp[0].offset = 0;
   2509         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2510         buf_planes->plane_info.mp[0].offset_x = 0;
   2511         buf_planes->plane_info.mp[0].offset_y = 0;
   2512         buf_planes->plane_info.mp[0].stride = stride;
   2513         buf_planes->plane_info.mp[0].scanline = scanline;
   2514         buf_planes->plane_info.mp[0].width = dim->width;
   2515         buf_planes->plane_info.mp[0].height = dim->height;
   2516 
   2517         stride = PAD_TO_SIZE(dim->width, width_padding);
   2518         scanline = PAD_TO_SIZE(dim->height / 2, height_padding);
   2519         buf_planes->plane_info.mp[1].offset = 0;
   2520         buf_planes->plane_info.mp[1].len =
   2521             (uint32_t)(stride * scanline);
   2522         buf_planes->plane_info.mp[1].offset_x = 0;
   2523         buf_planes->plane_info.mp[1].offset_y = 0;
   2524         buf_planes->plane_info.mp[1].stride = stride;
   2525         buf_planes->plane_info.mp[1].scanline = scanline;
   2526         buf_planes->plane_info.mp[1].width = dim->width;
   2527         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2528 
   2529         buf_planes->plane_info.frame_len =
   2530                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2531                         buf_planes->plane_info.mp[1].len,
   2532                         CAM_PAD_TO_4K);
   2533         break;
   2534     case CAM_FORMAT_YUV_420_NV21_ADRENO:
   2535         /* 2 planes: Y + CbCr */
   2536         buf_planes->plane_info.num_planes = 2;
   2537 
   2538         if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2539             stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   2540             scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_32);
   2541         } else {
   2542             stride = PAD_TO_SIZE(dim->width, padding->width_padding);
   2543             scanline = PAD_TO_SIZE(dim->height, padding->height_padding);
   2544         }
   2545         buf_planes->plane_info.mp[0].offset = 0;
   2546         buf_planes->plane_info.mp[0].len =
   2547                 PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_4K);
   2548         buf_planes->plane_info.mp[0].offset_x = 0;
   2549         buf_planes->plane_info.mp[0].offset_y = 0;
   2550         buf_planes->plane_info.mp[0].stride = stride;
   2551         buf_planes->plane_info.mp[0].scanline = scanline;
   2552         buf_planes->plane_info.mp[0].width = dim->width;
   2553         buf_planes->plane_info.mp[0].height = dim->height;
   2554 
   2555         stride = PAD_TO_SIZE(dim->width / 2, CAM_PAD_TO_32) * 2;
   2556         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_32);
   2557         buf_planes->plane_info.mp[1].offset = 0;
   2558         buf_planes->plane_info.mp[1].len =
   2559                 PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_4K);
   2560         buf_planes->plane_info.mp[1].offset_x = 0;
   2561         buf_planes->plane_info.mp[1].offset_y = 0;
   2562         buf_planes->plane_info.mp[1].stride = stride;
   2563         buf_planes->plane_info.mp[1].scanline = scanline;
   2564         buf_planes->plane_info.mp[1].width = dim->width;
   2565         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2566 
   2567         buf_planes->plane_info.frame_len =
   2568                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2569                         buf_planes->plane_info.mp[1].len,
   2570                         CAM_PAD_TO_4K);
   2571         break;
   2572     case CAM_FORMAT_YUV_420_YV12:
   2573         /* 3 planes: Y + Cr + Cb */
   2574         buf_planes->plane_info.num_planes = 3;
   2575 
   2576         if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2577             stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2578             scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_2);
   2579         } else {
   2580             stride = PAD_TO_SIZE(dim->width, padding->width_padding);
   2581             scanline = PAD_TO_SIZE(dim->height, padding->height_padding);
   2582         }
   2583         buf_planes->plane_info.mp[0].offset = 0;
   2584         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2585         buf_planes->plane_info.mp[0].offset_x = 0;
   2586         buf_planes->plane_info.mp[0].offset_y = 0;
   2587         buf_planes->plane_info.mp[0].stride = stride;
   2588         buf_planes->plane_info.mp[0].scanline = scanline;
   2589         buf_planes->plane_info.mp[0].width = dim->width;
   2590         buf_planes->plane_info.mp[0].height = dim->height;
   2591 
   2592         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   2593         scanline = scanline / 2;
   2594         buf_planes->plane_info.mp[1].offset = 0;
   2595         buf_planes->plane_info.mp[1].len =
   2596             (uint32_t)(stride * scanline);
   2597         buf_planes->plane_info.mp[1].offset_x = 0;
   2598         buf_planes->plane_info.mp[1].offset_y = 0;
   2599         buf_planes->plane_info.mp[1].stride = stride;
   2600         buf_planes->plane_info.mp[1].scanline = scanline;
   2601         buf_planes->plane_info.mp[1].width = dim->width / 2;
   2602         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2603 
   2604         buf_planes->plane_info.mp[2].offset = 0;
   2605         buf_planes->plane_info.mp[2].len =
   2606             (uint32_t)(stride * scanline);
   2607         buf_planes->plane_info.mp[2].offset_x = 0;
   2608         buf_planes->plane_info.mp[2].offset_y = 0;
   2609         buf_planes->plane_info.mp[2].stride = stride;
   2610         buf_planes->plane_info.mp[2].scanline = scanline;
   2611         buf_planes->plane_info.mp[2].width = dim->width / 2;
   2612         buf_planes->plane_info.mp[2].height = dim->height / 2;
   2613 
   2614         buf_planes->plane_info.frame_len =
   2615                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2616                         buf_planes->plane_info.mp[1].len +
   2617                         buf_planes->plane_info.mp[2].len,
   2618                         CAM_PAD_TO_4K);
   2619         break;
   2620     case CAM_FORMAT_YUV_422_NV16:
   2621     case CAM_FORMAT_YUV_422_NV61:
   2622         /* 2 planes: Y + CbCr */
   2623         buf_planes->plane_info.num_planes = 2;
   2624 
   2625         if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2626             stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2627             scanline = dim->height;
   2628         } else {
   2629             stride = PAD_TO_SIZE(dim->width, padding->width_padding);
   2630             scanline = PAD_TO_SIZE(dim->height, padding->height_padding);
   2631         }
   2632         buf_planes->plane_info.mp[0].offset = 0;
   2633         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2634         buf_planes->plane_info.mp[0].offset_x = 0;
   2635         buf_planes->plane_info.mp[0].offset_y = 0;
   2636         buf_planes->plane_info.mp[0].stride = stride;
   2637         buf_planes->plane_info.mp[0].scanline = scanline;
   2638         buf_planes->plane_info.mp[0].width = dim->width;
   2639         buf_planes->plane_info.mp[0].height = dim->height;
   2640 
   2641         buf_planes->plane_info.mp[1].offset = 0;
   2642         buf_planes->plane_info.mp[1].len = (uint32_t)(stride * scanline);
   2643         buf_planes->plane_info.mp[1].offset_x = 0;
   2644         buf_planes->plane_info.mp[1].offset_y = 0;
   2645         buf_planes->plane_info.mp[1].stride = stride;
   2646         buf_planes->plane_info.mp[1].scanline = scanline;
   2647         buf_planes->plane_info.mp[1].width = dim->width;
   2648         buf_planes->plane_info.mp[1].height = dim->height;
   2649 
   2650         buf_planes->plane_info.frame_len =
   2651                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2652                         buf_planes->plane_info.mp[1].len,
   2653                         CAM_PAD_TO_4K);
   2654         break;
   2655     case CAM_FORMAT_YUV_420_NV12_VENUS:
   2656 #ifdef VENUS_PRESENT
   2657         // using Venus
   2658         if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2659             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   2660             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   2661         } else {
   2662             stride = PAD_TO_SIZE(dim->width, padding->width_padding);
   2663             scanline = PAD_TO_SIZE(dim->height, padding->height_padding);
   2664         }
   2665         buf_planes->plane_info.frame_len =
   2666                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, stride, scanline);
   2667         buf_planes->plane_info.num_planes = 2;
   2668         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2669         buf_planes->plane_info.mp[0].offset = 0;
   2670         buf_planes->plane_info.mp[0].offset_x =0;
   2671         buf_planes->plane_info.mp[0].offset_y = 0;
   2672         buf_planes->plane_info.mp[0].stride = stride;
   2673         buf_planes->plane_info.mp[0].scanline = scanline;
   2674         buf_planes->plane_info.mp[0].width = dim->width;
   2675         buf_planes->plane_info.mp[0].height = dim->height;
   2676         if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2677             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   2678             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   2679         } else {
   2680             stride = PAD_TO_SIZE(dim->width, padding->width_padding);
   2681             scanline = PAD_TO_SIZE(dim->height, padding->height_padding);
   2682         }
   2683         buf_planes->plane_info.mp[1].len =
   2684                 buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2685         buf_planes->plane_info.mp[1].offset = 0;
   2686         buf_planes->plane_info.mp[1].offset_x =0;
   2687         buf_planes->plane_info.mp[1].offset_y = 0;
   2688         buf_planes->plane_info.mp[1].stride = stride;
   2689         buf_planes->plane_info.mp[1].scanline = scanline;
   2690         buf_planes->plane_info.mp[1].width = dim->width;
   2691         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2692 #else
   2693         LOGE("Venus hardware not avail, cannot use this format");
   2694         rc = -1;
   2695 #endif
   2696         break;
   2697     case CAM_FORMAT_YUV_420_NV21_VENUS:
   2698 #ifdef VENUS_PRESENT
   2699         // using Venus
   2700         if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2701             stride = VENUS_Y_STRIDE(COLOR_FMT_NV21, dim->width);
   2702             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV21, dim->height);
   2703         } else {
   2704             stride = PAD_TO_SIZE(dim->width, padding->width_padding);
   2705             scanline = PAD_TO_SIZE(dim->height, padding->height_padding);
   2706         }
   2707         buf_planes->plane_info.frame_len =
   2708                 VENUS_BUFFER_SIZE(COLOR_FMT_NV21, stride, scanline);
   2709         buf_planes->plane_info.num_planes = 2;
   2710         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2711         buf_planes->plane_info.mp[0].offset = 0;
   2712         buf_planes->plane_info.mp[0].offset_x =0;
   2713         buf_planes->plane_info.mp[0].offset_y = 0;
   2714         buf_planes->plane_info.mp[0].stride = stride;
   2715         buf_planes->plane_info.mp[0].scanline = scanline;
   2716         buf_planes->plane_info.mp[0].width = dim->width;
   2717         buf_planes->plane_info.mp[0].height = dim->height;
   2718         if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2719             stride = VENUS_UV_STRIDE(COLOR_FMT_NV21, dim->width);
   2720             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV21, dim->height);
   2721         } else {
   2722             stride = PAD_TO_SIZE(dim->width, padding->width_padding);
   2723             scanline = PAD_TO_SIZE(dim->height, padding->height_padding);
   2724         }
   2725         buf_planes->plane_info.mp[1].len =
   2726                 buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2727         buf_planes->plane_info.mp[1].offset = 0;
   2728         buf_planes->plane_info.mp[1].offset_x =0;
   2729         buf_planes->plane_info.mp[1].offset_y = 0;
   2730         buf_planes->plane_info.mp[1].stride = stride;
   2731         buf_planes->plane_info.mp[1].scanline = scanline;
   2732         buf_planes->plane_info.mp[1].width = dim->width;
   2733         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2734 #else
   2735         LOGE("Venus hardware not avail, cannot use this format");
   2736         rc = -1;
   2737 #endif
   2738         break;
   2739     case CAM_FORMAT_YUV_420_NV12_UBWC:
   2740 #ifdef UBWC_PRESENT
   2741         {
   2742             int meta_stride = 0,meta_scanline = 0;
   2743             // using UBWC
   2744             if (stream_info->stream_type != CAM_STREAM_TYPE_OFFLINE_PROC) {
   2745                 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   2746                 scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   2747             } else {
   2748                 stride = PAD_TO_SIZE(dim->width, padding->width_padding);
   2749                 scanline = PAD_TO_SIZE(dim->height, padding->height_padding);
   2750             }
   2751             meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   2752             meta_scanline = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   2753 
   2754             buf_planes->plane_info.frame_len =
   2755                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, stride, scanline);
   2756             buf_planes->plane_info.num_planes = 2;
   2757             buf_planes->plane_info.mp[0].offset = 0;
   2758             buf_planes->plane_info.mp[0].offset_x =0;
   2759             buf_planes->plane_info.mp[0].offset_y = 0;
   2760             buf_planes->plane_info.mp[0].stride = stride;
   2761             buf_planes->plane_info.mp[0].scanline = scanline;
   2762             buf_planes->plane_info.mp[0].width = dim->width;
   2763             buf_planes->plane_info.mp[0].height = dim->height;
   2764             buf_planes->plane_info.mp[0].meta_stride = meta_stride;
   2765             buf_planes->plane_info.mp[0].meta_scanline = meta_scanline;
   2766             buf_planes->plane_info.mp[0].meta_len =
   2767                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   2768             buf_planes->plane_info.mp[0].len =
   2769                     (uint32_t)(MSM_MEDIA_ALIGN((stride * scanline), 4096) +
   2770                     (buf_planes->plane_info.mp[0].meta_len));
   2771 
   2772             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   2773             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   2774             meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   2775             meta_scanline = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   2776             buf_planes->plane_info.mp[1].offset = 0;
   2777             buf_planes->plane_info.mp[1].offset_x =0;
   2778             buf_planes->plane_info.mp[1].offset_y = 0;
   2779             buf_planes->plane_info.mp[1].stride = stride;
   2780             buf_planes->plane_info.mp[1].scanline = scanline;
   2781             buf_planes->plane_info.mp[1].width = dim->width;
   2782             buf_planes->plane_info.mp[1].height = dim->height/2;
   2783             buf_planes->plane_info.mp[1].meta_stride = meta_stride;
   2784             buf_planes->plane_info.mp[1].meta_scanline = meta_scanline;
   2785             buf_planes->plane_info.mp[1].meta_len =
   2786                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   2787             buf_planes->plane_info.mp[1].len =
   2788                     buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2789         }
   2790 #else
   2791         LOGE("UBWC hardware not avail, cannot use this format");
   2792         rc = -1;
   2793 #endif
   2794         break;
   2795 
   2796     default:
   2797         LOGE("Invalid cam_format for preview %d",
   2798                     stream_info->fmt);
   2799         rc = -1;
   2800         break;
   2801     }
   2802 
   2803     return rc;
   2804 }
   2805 /*===========================================================================
   2806  * FUNCTION   : mm_stream_calc_offset_post_view
   2807  *
   2808  * DESCRIPTION: calculate postview frame offset based on format and
   2809  *              padding information
   2810  *
   2811  * PARAMETERS :
   2812  *   @fmt     : image format
   2813  *   @dim     : image dimension
   2814  *   @buf_planes : [out] buffer plane information
   2815  *
   2816  * RETURN     : int32_t type of status
   2817  *              0  -- success
   2818  *              -1 -- failure
   2819  *==========================================================================*/
   2820 int32_t mm_stream_calc_offset_post_view(cam_format_t fmt,
   2821                                       cam_dimension_t *dim,
   2822                                       cam_stream_buf_plane_info_t *buf_planes)
   2823 {
   2824     int32_t rc = 0;
   2825     int stride = 0, scanline = 0;
   2826 
   2827     switch (fmt) {
   2828     case CAM_FORMAT_YUV_420_NV12:
   2829     case CAM_FORMAT_YUV_420_NV21:
   2830     case CAM_FORMAT_Y_ONLY:
   2831     case CAM_FORMAT_Y_ONLY_10_BPP:
   2832     case CAM_FORMAT_Y_ONLY_12_BPP:
   2833     case CAM_FORMAT_Y_ONLY_14_BPP:
   2834         /* 2 planes: Y + CbCr */
   2835         buf_planes->plane_info.num_planes = 2;
   2836 
   2837         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_64);
   2838         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_64);
   2839         buf_planes->plane_info.mp[0].offset = 0;
   2840         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2841         buf_planes->plane_info.mp[0].offset_x = 0;
   2842         buf_planes->plane_info.mp[0].offset_y = 0;
   2843         buf_planes->plane_info.mp[0].stride = stride;
   2844         buf_planes->plane_info.mp[0].scanline = scanline;
   2845         buf_planes->plane_info.mp[0].width = dim->width;
   2846         buf_planes->plane_info.mp[0].height = dim->height;
   2847 
   2848         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_64);
   2849         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_64);
   2850         buf_planes->plane_info.mp[1].offset = 0;
   2851         buf_planes->plane_info.mp[1].len =
   2852             (uint32_t)(stride * scanline);
   2853         buf_planes->plane_info.mp[1].offset_x = 0;
   2854         buf_planes->plane_info.mp[1].offset_y = 0;
   2855         buf_planes->plane_info.mp[1].stride = stride;
   2856         buf_planes->plane_info.mp[1].scanline = scanline;
   2857         buf_planes->plane_info.mp[1].width = dim->width;
   2858         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2859 
   2860         buf_planes->plane_info.frame_len =
   2861                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2862                         buf_planes->plane_info.mp[1].len,
   2863                         CAM_PAD_TO_4K);
   2864         break;
   2865     case CAM_FORMAT_YUV_420_NV21_ADRENO:
   2866         /* 2 planes: Y + CbCr */
   2867         buf_planes->plane_info.num_planes = 2;
   2868 
   2869         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   2870         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_32);
   2871         buf_planes->plane_info.mp[0].offset = 0;
   2872         buf_planes->plane_info.mp[0].len =
   2873                 PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_4K);
   2874         buf_planes->plane_info.mp[0].offset_x = 0;
   2875         buf_planes->plane_info.mp[0].offset_y = 0;
   2876         buf_planes->plane_info.mp[0].stride = stride;
   2877         buf_planes->plane_info.mp[0].scanline = scanline;
   2878         buf_planes->plane_info.mp[0].width = dim->width;
   2879         buf_planes->plane_info.mp[0].height = dim->height;
   2880 
   2881         stride = PAD_TO_SIZE(dim->width / 2, CAM_PAD_TO_32) * 2;
   2882         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_32);
   2883         buf_planes->plane_info.mp[1].offset = 0;
   2884         buf_planes->plane_info.mp[1].len =
   2885                 PAD_TO_SIZE((uint32_t)(stride * scanline), CAM_PAD_TO_4K);
   2886         buf_planes->plane_info.mp[1].offset_x = 0;
   2887         buf_planes->plane_info.mp[1].offset_y = 0;
   2888         buf_planes->plane_info.mp[1].stride = stride;
   2889         buf_planes->plane_info.mp[1].scanline = scanline;
   2890         buf_planes->plane_info.mp[1].width = dim->width;
   2891         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2892 
   2893         buf_planes->plane_info.frame_len =
   2894                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2895                         buf_planes->plane_info.mp[1].len,
   2896                         CAM_PAD_TO_4K);
   2897         break;
   2898     case CAM_FORMAT_YUV_420_YV12:
   2899         /* 3 planes: Y + Cr + Cb */
   2900         buf_planes->plane_info.num_planes = 3;
   2901 
   2902         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2903         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_2);
   2904         buf_planes->plane_info.mp[0].offset = 0;
   2905         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2906         buf_planes->plane_info.mp[0].offset_x = 0;
   2907         buf_planes->plane_info.mp[0].offset_y = 0;
   2908         buf_planes->plane_info.mp[0].stride = stride;
   2909         buf_planes->plane_info.mp[0].scanline = scanline;
   2910         buf_planes->plane_info.mp[0].width = dim->width;
   2911         buf_planes->plane_info.mp[0].height = dim->height;
   2912 
   2913         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   2914         scanline = scanline / 2;
   2915         buf_planes->plane_info.mp[1].offset = 0;
   2916         buf_planes->plane_info.mp[1].len =
   2917             (uint32_t)(stride * scanline);
   2918         buf_planes->plane_info.mp[1].offset_x = 0;
   2919         buf_planes->plane_info.mp[1].offset_y = 0;
   2920         buf_planes->plane_info.mp[1].stride = stride;
   2921         buf_planes->plane_info.mp[1].scanline = scanline;
   2922         buf_planes->plane_info.mp[1].width = dim->width / 2;
   2923         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2924 
   2925         buf_planes->plane_info.mp[2].offset = 0;
   2926         buf_planes->plane_info.mp[2].len =
   2927             (uint32_t)(stride * scanline);
   2928         buf_planes->plane_info.mp[2].offset_x = 0;
   2929         buf_planes->plane_info.mp[2].offset_y = 0;
   2930         buf_planes->plane_info.mp[2].stride = stride;
   2931         buf_planes->plane_info.mp[2].scanline = scanline;
   2932         buf_planes->plane_info.mp[2].width = dim->width / 2;
   2933         buf_planes->plane_info.mp[2].height = dim->height / 2;
   2934 
   2935         buf_planes->plane_info.frame_len =
   2936                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2937                         buf_planes->plane_info.mp[1].len +
   2938                         buf_planes->plane_info.mp[2].len,
   2939                         CAM_PAD_TO_4K);
   2940         break;
   2941     case CAM_FORMAT_YUV_422_NV16:
   2942     case CAM_FORMAT_YUV_422_NV61:
   2943         /* 2 planes: Y + CbCr */
   2944         buf_planes->plane_info.num_planes = 2;
   2945 
   2946         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2947         scanline = dim->height;
   2948         buf_planes->plane_info.mp[0].offset = 0;
   2949         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2950         buf_planes->plane_info.mp[0].offset_x = 0;
   2951         buf_planes->plane_info.mp[0].offset_y = 0;
   2952         buf_planes->plane_info.mp[0].stride = stride;
   2953         buf_planes->plane_info.mp[0].scanline = scanline;
   2954         buf_planes->plane_info.mp[0].width = dim->width;
   2955         buf_planes->plane_info.mp[0].height = dim->height;
   2956 
   2957         buf_planes->plane_info.mp[1].offset = 0;
   2958         buf_planes->plane_info.mp[1].len = (uint32_t)(stride * scanline);
   2959         buf_planes->plane_info.mp[1].offset_x = 0;
   2960         buf_planes->plane_info.mp[1].offset_y = 0;
   2961         buf_planes->plane_info.mp[1].stride = stride;
   2962         buf_planes->plane_info.mp[1].scanline = scanline;
   2963         buf_planes->plane_info.mp[1].width = dim->width;
   2964         buf_planes->plane_info.mp[1].height = dim->height;
   2965 
   2966         buf_planes->plane_info.frame_len =
   2967                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2968                         buf_planes->plane_info.mp[1].len,
   2969                         CAM_PAD_TO_4K);
   2970         break;
   2971     case CAM_FORMAT_YUV_420_NV12_VENUS:
   2972 #ifdef VENUS_PRESENT
   2973         // using Venus
   2974         stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   2975         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   2976 
   2977         buf_planes->plane_info.frame_len =
   2978             VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   2979         buf_planes->plane_info.num_planes = 2;
   2980         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   2981         buf_planes->plane_info.mp[0].offset = 0;
   2982         buf_planes->plane_info.mp[0].offset_x =0;
   2983         buf_planes->plane_info.mp[0].offset_y = 0;
   2984         buf_planes->plane_info.mp[0].stride = stride;
   2985         buf_planes->plane_info.mp[0].scanline = scanline;
   2986         buf_planes->plane_info.mp[0].width = dim->width;
   2987         buf_planes->plane_info.mp[0].height = dim->height;
   2988         stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   2989         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   2990         buf_planes->plane_info.mp[1].len =
   2991             buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2992         buf_planes->plane_info.mp[1].offset = 0;
   2993         buf_planes->plane_info.mp[1].offset_x =0;
   2994         buf_planes->plane_info.mp[1].offset_y = 0;
   2995         buf_planes->plane_info.mp[1].stride = stride;
   2996         buf_planes->plane_info.mp[1].scanline = scanline;
   2997         buf_planes->plane_info.mp[1].width = dim->width;
   2998         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2999 #else
   3000         LOGE("Venus hardware not avail, cannot use this format");
   3001         rc = -1;
   3002 #endif
   3003         break;
   3004     case CAM_FORMAT_YUV_420_NV21_VENUS:
   3005 #ifdef VENUS_PRESENT
   3006         // using Venus
   3007         stride = VENUS_Y_STRIDE(COLOR_FMT_NV21, dim->width);
   3008         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV21, dim->height);
   3009         buf_planes->plane_info.frame_len =
   3010                 VENUS_BUFFER_SIZE(COLOR_FMT_NV21, dim->width, dim->height);
   3011         buf_planes->plane_info.num_planes = 2;
   3012         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   3013         buf_planes->plane_info.mp[0].offset = 0;
   3014         buf_planes->plane_info.mp[0].offset_x =0;
   3015         buf_planes->plane_info.mp[0].offset_y = 0;
   3016         buf_planes->plane_info.mp[0].stride = stride;
   3017         buf_planes->plane_info.mp[0].scanline = scanline;
   3018         buf_planes->plane_info.mp[0].width = dim->width;
   3019         buf_planes->plane_info.mp[0].height = dim->height;
   3020         stride = VENUS_UV_STRIDE(COLOR_FMT_NV21, dim->width);
   3021         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV21, dim->height);
   3022         buf_planes->plane_info.mp[1].len =
   3023                 buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   3024         buf_planes->plane_info.mp[1].offset = 0;
   3025         buf_planes->plane_info.mp[1].offset_x =0;
   3026         buf_planes->plane_info.mp[1].offset_y = 0;
   3027         buf_planes->plane_info.mp[1].stride = stride;
   3028         buf_planes->plane_info.mp[1].scanline = scanline;
   3029         buf_planes->plane_info.mp[1].width = dim->width;
   3030         buf_planes->plane_info.mp[1].height = dim->height / 2;
   3031 #else
   3032         LOGE("Venus hardware not avail, cannot use this format");
   3033         rc = -1;
   3034 #endif
   3035         break;
   3036     case CAM_FORMAT_YUV_420_NV12_UBWC:
   3037 #ifdef UBWC_PRESENT
   3038         {
   3039             int meta_stride = 0,meta_scanline = 0;
   3040             // using UBWC
   3041             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3042             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3043             meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3044             meta_scanline = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3045 
   3046             buf_planes->plane_info.frame_len =
   3047                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, dim->width, dim->height);
   3048             buf_planes->plane_info.num_planes = 2;
   3049             buf_planes->plane_info.mp[0].offset = 0;
   3050             buf_planes->plane_info.mp[0].offset_x =0;
   3051             buf_planes->plane_info.mp[0].offset_y = 0;
   3052             buf_planes->plane_info.mp[0].stride = stride;
   3053             buf_planes->plane_info.mp[0].scanline = scanline;
   3054             buf_planes->plane_info.mp[0].width = dim->width;
   3055             buf_planes->plane_info.mp[0].height = dim->height;
   3056             buf_planes->plane_info.mp[0].meta_stride = meta_stride;
   3057             buf_planes->plane_info.mp[0].meta_scanline = meta_scanline;
   3058             buf_planes->plane_info.mp[0].meta_len =
   3059                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   3060             buf_planes->plane_info.mp[0].len =
   3061                     (uint32_t)(MSM_MEDIA_ALIGN((stride * scanline), 4096) +
   3062                     (buf_planes->plane_info.mp[0].meta_len));
   3063 
   3064             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3065             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3066             meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3067             meta_scanline = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3068             buf_planes->plane_info.mp[1].offset = 0;
   3069             buf_planes->plane_info.mp[1].offset_x =0;
   3070             buf_planes->plane_info.mp[1].offset_y = 0;
   3071             buf_planes->plane_info.mp[1].stride = stride;
   3072             buf_planes->plane_info.mp[1].scanline = scanline;
   3073             buf_planes->plane_info.mp[1].width = dim->width;
   3074             buf_planes->plane_info.mp[1].height = dim->height/2;
   3075             buf_planes->plane_info.mp[1].meta_stride = meta_stride;
   3076             buf_planes->plane_info.mp[1].meta_scanline = meta_scanline;
   3077             buf_planes->plane_info.mp[1].meta_len =
   3078                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   3079             buf_planes->plane_info.mp[1].len =
   3080                     buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   3081         }
   3082 #else
   3083         LOGE("UBWC hardware not avail, cannot use this format");
   3084         rc = -1;
   3085 #endif
   3086         break;
   3087     default:
   3088         LOGE("Invalid cam_format for preview %d",
   3089                     fmt);
   3090         rc = -1;
   3091         break;
   3092     }
   3093 
   3094     return rc;
   3095 }
   3096 
   3097 /*===========================================================================
   3098  * FUNCTION   : mm_stream_calc_offset_snapshot
   3099  *
   3100  * DESCRIPTION: calculate snapshot/postproc frame offset based on format and
   3101  *              padding information
   3102  *
   3103  * PARAMETERS :
   3104  *   @fmt     : image format
   3105  *   @dim     : image dimension
   3106  *   @padding : padding information
   3107  *   @buf_planes : [out] buffer plane information
   3108  *
   3109  * RETURN     : int32_t type of status
   3110  *              0  -- success
   3111  *              -1 -- failure
   3112  *==========================================================================*/
   3113 int32_t mm_stream_calc_offset_snapshot(cam_format_t fmt,
   3114                                        cam_dimension_t *dim,
   3115                                        cam_padding_info_t *padding,
   3116                                        cam_stream_buf_plane_info_t *buf_planes)
   3117 {
   3118     int32_t rc = 0;
   3119     uint8_t isAFamily = mm_camera_util_chip_is_a_family();
   3120     int offset_x = 0, offset_y = 0;
   3121     int stride = 0, scanline = 0;
   3122 
   3123     if (isAFamily) {
   3124         stride = dim->width;
   3125         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_16);
   3126         offset_x = 0;
   3127         offset_y = scanline - dim->height;
   3128         scanline += offset_y; /* double padding */
   3129     } else {
   3130         offset_x = PAD_TO_SIZE(padding->offset_info.offset_x,
   3131                 padding->plane_padding);
   3132         offset_y = PAD_TO_SIZE(padding->offset_info.offset_y,
   3133                 padding->plane_padding);
   3134         stride = PAD_TO_SIZE((dim->width +
   3135                 (2 * offset_x)), padding->width_padding);
   3136         scanline = PAD_TO_SIZE((dim->height +
   3137                 (2 * offset_y)), padding->height_padding);
   3138     }
   3139 
   3140     switch (fmt) {
   3141     case CAM_FORMAT_YUV_420_NV12:
   3142     case CAM_FORMAT_YUV_420_NV21:
   3143     case CAM_FORMAT_Y_ONLY:
   3144     case CAM_FORMAT_Y_ONLY_10_BPP:
   3145     case CAM_FORMAT_Y_ONLY_12_BPP:
   3146     case CAM_FORMAT_Y_ONLY_14_BPP:
   3147         /* 2 planes: Y + CbCr */
   3148         buf_planes->plane_info.num_planes = 2;
   3149 
   3150         buf_planes->plane_info.mp[0].len =
   3151                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3152                 padding->plane_padding);
   3153         buf_planes->plane_info.mp[0].offset =
   3154                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3155                 padding->plane_padding);
   3156         buf_planes->plane_info.mp[0].offset_x = offset_x;
   3157         buf_planes->plane_info.mp[0].offset_y = offset_y;
   3158         buf_planes->plane_info.mp[0].stride = stride;
   3159         buf_planes->plane_info.mp[0].scanline = scanline;
   3160         buf_planes->plane_info.mp[0].width = dim->width;
   3161         buf_planes->plane_info.mp[0].height = dim->height;
   3162 
   3163         scanline = scanline/2;
   3164         buf_planes->plane_info.mp[1].len =
   3165                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3166                 padding->plane_padding);
   3167         buf_planes->plane_info.mp[1].offset =
   3168                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3169                 padding->plane_padding);
   3170         buf_planes->plane_info.mp[1].offset_x = offset_x;
   3171         buf_planes->plane_info.mp[1].offset_y = offset_y;
   3172         buf_planes->plane_info.mp[1].stride = stride;
   3173         buf_planes->plane_info.mp[1].scanline = scanline;
   3174         buf_planes->plane_info.mp[1].width = dim->width;
   3175         buf_planes->plane_info.mp[1].height = dim->height / 2;
   3176 
   3177         buf_planes->plane_info.frame_len =
   3178                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   3179                 buf_planes->plane_info.mp[1].len,
   3180                 CAM_PAD_TO_4K);
   3181         break;
   3182     case CAM_FORMAT_YUV_420_YV12:
   3183         /* 3 planes: Y + Cr + Cb */
   3184         buf_planes->plane_info.num_planes = 3;
   3185 
   3186         buf_planes->plane_info.mp[0].offset =
   3187                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3188                         padding->plane_padding);
   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_x = offset_x;
   3193         buf_planes->plane_info.mp[0].offset_y = offset_y;
   3194         buf_planes->plane_info.mp[0].stride = stride;
   3195         buf_planes->plane_info.mp[0].scanline = scanline;
   3196         buf_planes->plane_info.mp[0].width = dim->width;
   3197         buf_planes->plane_info.mp[0].height = dim->height;
   3198 
   3199         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   3200         scanline = scanline / 2;
   3201         buf_planes->plane_info.mp[1].offset =
   3202                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3203                         padding->plane_padding);
   3204         buf_planes->plane_info.mp[1].len =
   3205                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3206                         padding->plane_padding);
   3207         buf_planes->plane_info.mp[1].offset_x = offset_x;
   3208         buf_planes->plane_info.mp[1].offset_y = offset_y;
   3209         buf_planes->plane_info.mp[1].stride = stride;
   3210         buf_planes->plane_info.mp[1].scanline = scanline;
   3211         buf_planes->plane_info.mp[1].width = dim->width / 2;
   3212         buf_planes->plane_info.mp[1].height = dim->height / 2;
   3213 
   3214         buf_planes->plane_info.mp[2].offset =
   3215                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3216                         padding->plane_padding);
   3217         buf_planes->plane_info.mp[2].len =
   3218                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3219                         padding->plane_padding);
   3220         buf_planes->plane_info.mp[2].offset_x = offset_x;
   3221         buf_planes->plane_info.mp[2].offset_y = offset_y;
   3222         buf_planes->plane_info.mp[2].stride = stride;
   3223         buf_planes->plane_info.mp[2].scanline = scanline;
   3224         buf_planes->plane_info.mp[2].width = dim->width / 2;
   3225         buf_planes->plane_info.mp[2].height = dim->height / 2;
   3226 
   3227         buf_planes->plane_info.frame_len =
   3228                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   3229                         buf_planes->plane_info.mp[1].len +
   3230                         buf_planes->plane_info.mp[2].len,
   3231                         CAM_PAD_TO_4K);
   3232         break;
   3233     case CAM_FORMAT_YUV_422_NV16:
   3234     case CAM_FORMAT_YUV_422_NV61:
   3235         /* 2 planes: Y + CbCr */
   3236         buf_planes->plane_info.num_planes = 2;
   3237         buf_planes->plane_info.mp[0].len =
   3238                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3239                         padding->plane_padding);
   3240         buf_planes->plane_info.mp[0].offset =
   3241                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3242                         padding->plane_padding);
   3243         buf_planes->plane_info.mp[0].offset_x = offset_x;
   3244         buf_planes->plane_info.mp[0].offset_y = offset_y;
   3245         buf_planes->plane_info.mp[0].stride = stride;
   3246         buf_planes->plane_info.mp[0].scanline = scanline;
   3247         buf_planes->plane_info.mp[0].width = dim->width;
   3248         buf_planes->plane_info.mp[0].height = dim->height;
   3249 
   3250         buf_planes->plane_info.mp[1].len =
   3251                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3252                         padding->plane_padding);
   3253         buf_planes->plane_info.mp[1].offset =
   3254                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   3255                         padding->plane_padding);
   3256         buf_planes->plane_info.mp[1].offset_x = offset_x;
   3257         buf_planes->plane_info.mp[1].offset_y = offset_y;
   3258         buf_planes->plane_info.mp[1].stride = stride;
   3259         buf_planes->plane_info.mp[1].scanline = scanline;
   3260         buf_planes->plane_info.mp[1].width = dim->width;
   3261         buf_planes->plane_info.mp[1].height = dim->height;
   3262 
   3263         buf_planes->plane_info.frame_len = PAD_TO_SIZE(
   3264             buf_planes->plane_info.mp[0].len + buf_planes->plane_info.mp[1].len,
   3265             CAM_PAD_TO_4K);
   3266         break;
   3267     case CAM_FORMAT_YUV_420_NV12_UBWC:
   3268 #ifdef UBWC_PRESENT
   3269         {
   3270             int meta_stride = 0,meta_scanline = 0;
   3271             // using UBWC
   3272             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3273             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3274             meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3275             meta_scanline = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3276 
   3277             buf_planes->plane_info.frame_len =
   3278                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, dim->width, dim->height);
   3279             buf_planes->plane_info.num_planes = 2;
   3280             buf_planes->plane_info.mp[0].offset = 0;
   3281             buf_planes->plane_info.mp[0].offset_x = 0;
   3282             buf_planes->plane_info.mp[0].offset_y = 0;
   3283             buf_planes->plane_info.mp[0].stride = stride;
   3284             buf_planes->plane_info.mp[0].scanline = scanline;
   3285             buf_planes->plane_info.mp[0].width = dim->width;
   3286             buf_planes->plane_info.mp[0].height = dim->height;
   3287             buf_planes->plane_info.mp[0].meta_stride = meta_stride;
   3288             buf_planes->plane_info.mp[0].meta_scanline = meta_scanline;
   3289             buf_planes->plane_info.mp[0].meta_len =
   3290                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   3291             buf_planes->plane_info.mp[0].len =
   3292                     (uint32_t)(MSM_MEDIA_ALIGN((stride * scanline), 4096) +
   3293                     (buf_planes->plane_info.mp[0].meta_len));
   3294 
   3295             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3296             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3297             meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3298             meta_scanline = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3299             buf_planes->plane_info.mp[1].offset = 0;
   3300             buf_planes->plane_info.mp[1].offset_x =0;
   3301             buf_planes->plane_info.mp[1].offset_y = 0;
   3302             buf_planes->plane_info.mp[1].stride = stride;
   3303             buf_planes->plane_info.mp[1].scanline = scanline;
   3304             buf_planes->plane_info.mp[1].width = dim->width;
   3305             buf_planes->plane_info.mp[1].height = dim->height/2;
   3306             buf_planes->plane_info.mp[1].meta_stride = meta_stride;
   3307             buf_planes->plane_info.mp[1].meta_scanline = meta_scanline;
   3308             buf_planes->plane_info.mp[1].meta_len =
   3309                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   3310             buf_planes->plane_info.mp[1].len =
   3311                     buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   3312         }
   3313 #else
   3314         LOGE("UBWC hardware not avail, cannot use this format");
   3315         rc = -1;
   3316 #endif
   3317         break;
   3318     case CAM_FORMAT_YUV_420_NV12_VENUS:
   3319 #ifdef VENUS_PRESENT
   3320         // using Venus
   3321         stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   3322         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   3323 
   3324         buf_planes->plane_info.frame_len =
   3325                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   3326         buf_planes->plane_info.num_planes = 2;
   3327         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   3328         buf_planes->plane_info.mp[0].offset = 0;
   3329         buf_planes->plane_info.mp[0].offset_x =0;
   3330         buf_planes->plane_info.mp[0].offset_y = 0;
   3331         buf_planes->plane_info.mp[0].stride = stride;
   3332         buf_planes->plane_info.mp[0].scanline = scanline;
   3333         buf_planes->plane_info.mp[0].width = dim->width;
   3334         buf_planes->plane_info.mp[0].height = dim->height;
   3335         stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   3336         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   3337         buf_planes->plane_info.mp[1].len =
   3338                 buf_planes->plane_info.frame_len -
   3339                 buf_planes->plane_info.mp[0].len;
   3340         buf_planes->plane_info.mp[1].offset = 0;
   3341         buf_planes->plane_info.mp[1].offset_x =0;
   3342         buf_planes->plane_info.mp[1].offset_y = 0;
   3343         buf_planes->plane_info.mp[1].stride = stride;
   3344         buf_planes->plane_info.mp[1].scanline = scanline;
   3345         buf_planes->plane_info.mp[1].width = dim->width;
   3346         buf_planes->plane_info.mp[1].height = dim->height / 2;
   3347 #else
   3348         LOGD("Video format VENUS is not supported = %d",
   3349                  fmt);
   3350 #endif
   3351         break;
   3352     case CAM_FORMAT_YUV_420_NV21_VENUS:
   3353 #ifdef VENUS_PRESENT
   3354         // using Venus
   3355         stride = VENUS_Y_STRIDE(COLOR_FMT_NV21, dim->width);
   3356         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV21, dim->height);
   3357         buf_planes->plane_info.frame_len =
   3358                 VENUS_BUFFER_SIZE(COLOR_FMT_NV21, dim->width, dim->height);
   3359         buf_planes->plane_info.num_planes = 2;
   3360         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   3361         buf_planes->plane_info.mp[0].offset = 0;
   3362         buf_planes->plane_info.mp[0].offset_x =0;
   3363         buf_planes->plane_info.mp[0].offset_y = 0;
   3364         buf_planes->plane_info.mp[0].stride = stride;
   3365         buf_planes->plane_info.mp[0].scanline = scanline;
   3366         buf_planes->plane_info.mp[0].width = dim->width;
   3367         buf_planes->plane_info.mp[0].height = dim->height;
   3368         stride = VENUS_UV_STRIDE(COLOR_FMT_NV21, dim->width);
   3369         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV21, dim->height);
   3370         buf_planes->plane_info.mp[1].len =
   3371                 buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   3372         buf_planes->plane_info.mp[1].offset = 0;
   3373         buf_planes->plane_info.mp[1].offset_x =0;
   3374         buf_planes->plane_info.mp[1].offset_y = 0;
   3375         buf_planes->plane_info.mp[1].stride = stride;
   3376         buf_planes->plane_info.mp[1].scanline = scanline;
   3377         buf_planes->plane_info.mp[1].width = dim->width;
   3378         buf_planes->plane_info.mp[1].height = dim->height / 2;
   3379 #else
   3380         LOGE("Venus hardware not avail, cannot use this format");
   3381         rc = -1;
   3382 #endif
   3383         break;
   3384     default:
   3385         LOGE("Invalid cam_format for snapshot %d",
   3386                     fmt);
   3387         rc = -1;
   3388         break;
   3389     }
   3390 
   3391     return rc;
   3392 }
   3393 
   3394 /*===========================================================================
   3395  * FUNCTION   : mm_stream_calc_offset_raw
   3396  *
   3397  * DESCRIPTION: calculate raw frame offset based on format and padding information
   3398  *
   3399  * PARAMETERS :
   3400  *   @fmt     : image format
   3401  *   @dim     : image dimension
   3402  *   @padding : padding information
   3403  *   @buf_planes : [out] buffer plane information
   3404  *
   3405  * RETURN     : int32_t type of status
   3406  *              0  -- success
   3407  *              -1 -- failure
   3408  *==========================================================================*/
   3409 int32_t mm_stream_calc_offset_raw(cam_format_t fmt,
   3410                                   cam_dimension_t *dim,
   3411                                   cam_padding_info_t *padding,
   3412                                   cam_stream_buf_plane_info_t *buf_planes)
   3413 {
   3414     int32_t rc = 0;
   3415 
   3416     if ((NULL == dim) || (NULL == padding) || (NULL == buf_planes)) {
   3417         return -1;
   3418     }
   3419 
   3420     int32_t stride = PAD_TO_SIZE(dim->width, (int32_t)padding->width_padding);
   3421     int32_t stride_in_bytes = stride;
   3422     int32_t scanline = PAD_TO_SIZE(dim->height, (int32_t)padding->height_padding);
   3423 
   3424     switch (fmt) {
   3425     case CAM_FORMAT_YUV_420_NV21:
   3426         /* 2 planes: Y + CbCr */
   3427         buf_planes->plane_info.num_planes = 2;
   3428 
   3429         buf_planes->plane_info.mp[0].len =
   3430                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3431                 padding->plane_padding);
   3432         buf_planes->plane_info.mp[0].offset = 0;
   3433         buf_planes->plane_info.mp[0].offset_x = 0;
   3434         buf_planes->plane_info.mp[0].offset_y = 0;
   3435         buf_planes->plane_info.mp[0].stride = stride;
   3436         buf_planes->plane_info.mp[0].stride_in_bytes = stride;
   3437         buf_planes->plane_info.mp[0].scanline = scanline;
   3438         buf_planes->plane_info.mp[0].width = dim->width;
   3439         buf_planes->plane_info.mp[0].height = dim->height;
   3440 
   3441         scanline = scanline / 2;
   3442         buf_planes->plane_info.mp[1].len =
   3443                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   3444                 padding->plane_padding);
   3445         buf_planes->plane_info.mp[1].offset = 0;
   3446         buf_planes->plane_info.mp[1].offset_x = 0;
   3447         buf_planes->plane_info.mp[1].offset_y = 0;
   3448         buf_planes->plane_info.mp[1].stride = stride;
   3449         buf_planes->plane_info.mp[1].stride_in_bytes = stride;
   3450         buf_planes->plane_info.mp[1].scanline = scanline;
   3451         buf_planes->plane_info.mp[1].width = dim->width;
   3452         buf_planes->plane_info.mp[1].height = dim->height / 2;
   3453 
   3454         buf_planes->plane_info.frame_len =
   3455                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   3456                 buf_planes->plane_info.mp[1].len,
   3457                 CAM_PAD_TO_4K);
   3458         break;
   3459     case CAM_FORMAT_YUV_RAW_8BIT_YUYV:
   3460     case CAM_FORMAT_YUV_RAW_8BIT_YVYU:
   3461     case CAM_FORMAT_YUV_RAW_8BIT_UYVY:
   3462     case CAM_FORMAT_YUV_RAW_8BIT_VYUY:
   3463     case CAM_FORMAT_JPEG_RAW_8BIT:
   3464         /* 1 plane */
   3465         /* Every 16 pixels occupy 16 bytes */
   3466         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   3467         stride_in_bytes = stride * 2;
   3468         buf_planes->plane_info.num_planes = 1;
   3469         buf_planes->plane_info.mp[0].offset = 0;
   3470         buf_planes->plane_info.mp[0].len =
   3471                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3472                         padding->plane_padding);
   3473         buf_planes->plane_info.frame_len =
   3474                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3475         buf_planes->plane_info.mp[0].offset_x =0;
   3476         buf_planes->plane_info.mp[0].offset_y = 0;
   3477         buf_planes->plane_info.mp[0].stride = stride;
   3478         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3479         buf_planes->plane_info.mp[0].scanline = scanline;
   3480         buf_planes->plane_info.mp[0].width =
   3481                 (int32_t)buf_planes->plane_info.mp[0].len;
   3482         buf_planes->plane_info.mp[0].height = 1;
   3483         break;
   3484     case CAM_FORMAT_META_RAW_8BIT:
   3485         // Every 16 pixels occupy 16 bytes
   3486         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   3487         stride_in_bytes = stride * 2;
   3488         buf_planes->plane_info.num_planes = 1;
   3489         buf_planes->plane_info.mp[0].offset = 0;
   3490         buf_planes->plane_info.mp[0].len =
   3491                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3492                         padding->plane_padding);
   3493         buf_planes->plane_info.frame_len =
   3494                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3495         buf_planes->plane_info.mp[0].offset_x =0;
   3496         buf_planes->plane_info.mp[0].offset_y = 0;
   3497         buf_planes->plane_info.mp[0].stride = stride;
   3498         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3499         buf_planes->plane_info.mp[0].scanline = scanline;
   3500         break;
   3501 
   3502     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GBRG:
   3503     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GRBG:
   3504     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_RGGB:
   3505     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_BGGR:
   3506     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GREY:
   3507     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG:
   3508     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GRBG:
   3509     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_RGGB:
   3510     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_BGGR:
   3511     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GREY:
   3512     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GBRG:
   3513     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GRBG:
   3514     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_RGGB:
   3515     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_BGGR:
   3516     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GREY:
   3517     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GBRG:
   3518     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GRBG:
   3519     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_RGGB:
   3520     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_BGGR:
   3521     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GREY:
   3522     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_GBRG:
   3523     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_GRBG:
   3524     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_RGGB:
   3525     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_BGGR:
   3526         /* 1 plane */
   3527         /* Every 16 pixels occupy 16 bytes */
   3528         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   3529         stride_in_bytes = stride;
   3530         buf_planes->plane_info.num_planes = 1;
   3531         buf_planes->plane_info.mp[0].offset = 0;
   3532         buf_planes->plane_info.mp[0].len =
   3533                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3534                         padding->plane_padding);
   3535         buf_planes->plane_info.frame_len =
   3536                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3537         buf_planes->plane_info.mp[0].offset_x =0;
   3538         buf_planes->plane_info.mp[0].offset_y = 0;
   3539         buf_planes->plane_info.mp[0].stride = stride;
   3540         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3541         buf_planes->plane_info.mp[0].scanline = scanline;
   3542         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   3543         buf_planes->plane_info.mp[0].height = 1;
   3544         break;
   3545     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG:
   3546     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GRBG:
   3547     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_RGGB:
   3548     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_BGGR:
   3549     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GREY:
   3550     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GBRG:
   3551     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GRBG:
   3552     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_RGGB:
   3553     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_BGGR:
   3554     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GREY:
   3555         /* Every 12 pixels occupy 16 bytes */
   3556         stride = (dim->width + 11)/12 * 12;
   3557         stride_in_bytes = stride * 8 / 6;
   3558         buf_planes->plane_info.num_planes = 1;
   3559         buf_planes->plane_info.mp[0].offset = 0;
   3560         buf_planes->plane_info.mp[0].len =
   3561                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3562                         padding->plane_padding);
   3563         buf_planes->plane_info.frame_len =
   3564                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3565         buf_planes->plane_info.mp[0].offset_x =0;
   3566         buf_planes->plane_info.mp[0].offset_y = 0;
   3567         buf_planes->plane_info.mp[0].stride = stride;
   3568         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3569         buf_planes->plane_info.mp[0].scanline = scanline;
   3570         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   3571         buf_planes->plane_info.mp[0].height = 1;
   3572         break;
   3573     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GBRG:
   3574     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GRBG:
   3575     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_RGGB:
   3576     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_BGGR:
   3577     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GREY:
   3578     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GBRG:
   3579     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GRBG:
   3580     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_RGGB:
   3581     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_BGGR:
   3582     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GREY:
   3583         /* Every 10 pixels occupy 16 bytes */
   3584         stride = (dim->width + 9)/10 * 10;
   3585         stride_in_bytes = stride * 8 / 5;
   3586         buf_planes->plane_info.num_planes = 1;
   3587         buf_planes->plane_info.mp[0].offset = 0;
   3588         buf_planes->plane_info.mp[0].len =
   3589                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3590                         padding->plane_padding);
   3591         buf_planes->plane_info.frame_len =
   3592                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3593         buf_planes->plane_info.mp[0].offset_x =0;
   3594         buf_planes->plane_info.mp[0].offset_y = 0;
   3595         buf_planes->plane_info.mp[0].stride = stride;
   3596         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3597         buf_planes->plane_info.mp[0].scanline = scanline;
   3598         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   3599         buf_planes->plane_info.mp[0].height = 1;
   3600         break;
   3601     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG:
   3602     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GRBG:
   3603     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_RGGB:
   3604     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_BGGR:
   3605     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GREY:
   3606     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GBRG:
   3607     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GRBG:
   3608     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_RGGB:
   3609     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_BGGR:
   3610     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GREY:
   3611         /* Every 64 pixels occupy 80 bytes */
   3612         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_4);
   3613         stride_in_bytes = PAD_TO_SIZE(stride * 5 / 4, CAM_PAD_TO_8);
   3614         buf_planes->plane_info.num_planes = 1;
   3615         buf_planes->plane_info.mp[0].offset = 0;
   3616         buf_planes->plane_info.mp[0].len =
   3617                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3618                         padding->plane_padding);
   3619         buf_planes->plane_info.frame_len =
   3620                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3621         buf_planes->plane_info.mp[0].offset_x =0;
   3622         buf_planes->plane_info.mp[0].offset_y = 0;
   3623         buf_planes->plane_info.mp[0].stride = stride;
   3624         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3625         buf_planes->plane_info.mp[0].scanline = scanline;
   3626         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   3627         buf_planes->plane_info.mp[0].height = 1;
   3628         break;
   3629     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GBRG:
   3630     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GRBG:
   3631     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_RGGB:
   3632     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR:
   3633     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GREY:
   3634     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GBRG:
   3635     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GRBG:
   3636     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_RGGB:
   3637     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_BGGR:
   3638     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GREY:
   3639         /* Every 32 pixels occupy 48 bytes */
   3640         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   3641         stride_in_bytes = stride * 3 / 2;
   3642         buf_planes->plane_info.num_planes = 1;
   3643         buf_planes->plane_info.mp[0].offset = 0;
   3644         buf_planes->plane_info.mp[0].len =
   3645                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3646                         padding->plane_padding);
   3647         buf_planes->plane_info.frame_len =
   3648                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3649         buf_planes->plane_info.mp[0].offset_x =0;
   3650         buf_planes->plane_info.mp[0].offset_y = 0;
   3651         buf_planes->plane_info.mp[0].stride = stride;
   3652         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3653         buf_planes->plane_info.mp[0].scanline = scanline;
   3654         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   3655         buf_planes->plane_info.mp[0].height = 1;
   3656         break;
   3657     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_GBRG:
   3658     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_GRBG:
   3659     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_RGGB:
   3660     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_BGGR:
   3661     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_GBRG:
   3662     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_GRBG:
   3663     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_RGGB:
   3664     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_BGGR:
   3665     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_GBRG:
   3666     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_GRBG:
   3667     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_RGGB:
   3668     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_BGGR:
   3669     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_14BPP_GBRG:
   3670     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_14BPP_GRBG:
   3671     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_14BPP_RGGB:
   3672     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_14BPP_BGGR:
   3673         /* Every 8 pixels occupy 16 bytes */
   3674         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_8);
   3675         stride_in_bytes = stride * 2;
   3676         buf_planes->plane_info.num_planes = 1;
   3677         buf_planes->plane_info.mp[0].offset = 0;
   3678         buf_planes->plane_info.mp[0].len =
   3679                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3680                         padding->plane_padding);
   3681         buf_planes->plane_info.frame_len =
   3682                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3683         buf_planes->plane_info.mp[0].offset_x =0;
   3684         buf_planes->plane_info.mp[0].offset_y = 0;
   3685         buf_planes->plane_info.mp[0].stride = stride;
   3686         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3687         buf_planes->plane_info.mp[0].scanline = scanline;
   3688         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   3689         buf_planes->plane_info.mp[0].height = 1;
   3690         break;
   3691     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_GBRG:
   3692     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_GRBG:
   3693     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_RGGB:
   3694     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_BGGR:
   3695     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_GREY:
   3696     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_GBRG:
   3697     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_GRBG:
   3698     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_RGGB:
   3699     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_BGGR:
   3700     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_GREY:
   3701         /* Every 64 pixels occupy 112 bytes */
   3702         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_64);
   3703         stride_in_bytes = stride * 7 / 4;
   3704         buf_planes->plane_info.num_planes = 1;
   3705         buf_planes->plane_info.mp[0].offset = 0;
   3706         buf_planes->plane_info.mp[0].len =
   3707                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3708                 padding->plane_padding);
   3709         buf_planes->plane_info.frame_len =
   3710                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3711         buf_planes->plane_info.mp[0].offset_x =0;
   3712         buf_planes->plane_info.mp[0].offset_y = 0;
   3713         buf_planes->plane_info.mp[0].stride = stride;
   3714         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3715         buf_planes->plane_info.mp[0].scanline = scanline;
   3716         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   3717         buf_planes->plane_info.mp[0].height = 1;
   3718         break;
   3719     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_GBRG:
   3720     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_GRBG:
   3721     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_RGGB:
   3722     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_BGGR:
   3723     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_GREY:
   3724     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_GBRG:
   3725     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_GRBG:
   3726     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_RGGB:
   3727     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_BGGR:
   3728     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_GREY:
   3729         /* Every 16 pixels occupy 32 bytes */
   3730         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   3731         stride_in_bytes = stride * 2;
   3732         buf_planes->plane_info.num_planes = 1;
   3733         buf_planes->plane_info.mp[0].offset = 0;
   3734         buf_planes->plane_info.mp[0].len =
   3735                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
   3736                 padding->plane_padding);
   3737         buf_planes->plane_info.frame_len =
   3738                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   3739         buf_planes->plane_info.mp[0].offset_x =0;
   3740         buf_planes->plane_info.mp[0].offset_y = 0;
   3741         buf_planes->plane_info.mp[0].stride = stride;
   3742         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
   3743         buf_planes->plane_info.mp[0].scanline = scanline;
   3744         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
   3745         buf_planes->plane_info.mp[0].height = 1;
   3746         break;
   3747     default:
   3748         LOGE("Invalid cam_format %d for raw stream",
   3749                     fmt);
   3750         rc = -1;
   3751         break;
   3752     }
   3753 
   3754     return rc;
   3755 }
   3756 
   3757 /*===========================================================================
   3758  * FUNCTION   : mm_stream_calc_offset_video
   3759  *
   3760  * DESCRIPTION: calculate video frame offset based on format and
   3761  *              padding information
   3762  *
   3763  * PARAMETERS :
   3764   *   @fmt     : image format
   3765  *   @dim     : image dimension
   3766  *   @buf_planes : [out] buffer plane information
   3767  *
   3768  * RETURN     : int32_t type of status
   3769  *              0  -- success
   3770  *              -1 -- failure
   3771  *==========================================================================*/
   3772 int32_t mm_stream_calc_offset_video(cam_format_t fmt,
   3773         cam_dimension_t *dim, cam_stream_buf_plane_info_t *buf_planes)
   3774 {
   3775     int32_t rc = 0;
   3776     int stride = 0, scanline = 0;
   3777 
   3778     #ifdef UBWC_PRESENT
   3779     int meta_stride = 0,meta_scanline = 0;
   3780     #endif
   3781 
   3782 
   3783     switch (fmt) {
   3784         case CAM_FORMAT_YUV_420_NV12:
   3785         case CAM_FORMAT_Y_ONLY:
   3786         case CAM_FORMAT_Y_ONLY_10_BPP:
   3787         case CAM_FORMAT_Y_ONLY_12_BPP:
   3788         case CAM_FORMAT_Y_ONLY_14_BPP:
   3789             buf_planes->plane_info.num_planes = 2;
   3790 
   3791             stride = dim->width;
   3792             scanline = dim->height;
   3793             buf_planes->plane_info.mp[0].len =
   3794                     PAD_TO_SIZE((uint32_t)(stride * scanline),
   3795                     CAM_PAD_TO_2K);
   3796             buf_planes->plane_info.mp[0].offset = 0;
   3797             buf_planes->plane_info.mp[0].offset_x =0;
   3798             buf_planes->plane_info.mp[0].offset_y = 0;
   3799             buf_planes->plane_info.mp[0].stride = stride;
   3800             buf_planes->plane_info.mp[0].scanline = scanline;
   3801             buf_planes->plane_info.mp[0].width = dim->width;
   3802             buf_planes->plane_info.mp[0].height = dim->height;
   3803 
   3804             stride = dim->width;
   3805             scanline = dim->height / 2;
   3806             buf_planes->plane_info.mp[1].len =
   3807                     PAD_TO_SIZE((uint32_t)(stride * scanline),
   3808                     CAM_PAD_TO_2K);
   3809             buf_planes->plane_info.mp[1].offset = 0;
   3810             buf_planes->plane_info.mp[1].offset_x =0;
   3811             buf_planes->plane_info.mp[1].offset_y = 0;
   3812             buf_planes->plane_info.mp[1].stride = stride;
   3813             buf_planes->plane_info.mp[1].scanline = scanline;
   3814             buf_planes->plane_info.mp[1].width = dim->width;
   3815             buf_planes->plane_info.mp[1].height = dim->height / 2;
   3816 
   3817             buf_planes->plane_info.frame_len =
   3818                     PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   3819                     buf_planes->plane_info.mp[1].len,
   3820                     CAM_PAD_TO_4K);
   3821             break;
   3822         case CAM_FORMAT_YUV_420_NV12_VENUS:
   3823 #ifdef VENUS_PRESENT
   3824             // using Venus
   3825             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   3826             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   3827 
   3828             buf_planes->plane_info.frame_len =
   3829                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   3830             buf_planes->plane_info.num_planes = 2;
   3831             buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   3832             buf_planes->plane_info.mp[0].offset = 0;
   3833             buf_planes->plane_info.mp[0].offset_x =0;
   3834             buf_planes->plane_info.mp[0].offset_y = 0;
   3835             buf_planes->plane_info.mp[0].stride = stride;
   3836             buf_planes->plane_info.mp[0].scanline = scanline;
   3837             buf_planes->plane_info.mp[0].width = dim->width;
   3838             buf_planes->plane_info.mp[0].height = dim->height;
   3839             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   3840             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   3841             buf_planes->plane_info.mp[1].len =
   3842                     buf_planes->plane_info.frame_len -
   3843                     buf_planes->plane_info.mp[0].len;
   3844             buf_planes->plane_info.mp[1].offset = 0;
   3845             buf_planes->plane_info.mp[1].offset_x =0;
   3846             buf_planes->plane_info.mp[1].offset_y = 0;
   3847             buf_planes->plane_info.mp[1].stride = stride;
   3848             buf_planes->plane_info.mp[1].scanline = scanline;
   3849             buf_planes->plane_info.mp[1].width = dim->width;
   3850             buf_planes->plane_info.mp[1].height = dim->height/2;
   3851 #else
   3852             LOGD("Video format VENUS is not supported = %d",
   3853                      fmt);
   3854 #endif
   3855             break;
   3856         case CAM_FORMAT_YUV_420_NV21_VENUS:
   3857 #ifdef VENUS_PRESENT
   3858             // using Venus
   3859             stride = VENUS_Y_STRIDE(COLOR_FMT_NV21, dim->width);
   3860             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV21, dim->height);
   3861 
   3862             buf_planes->plane_info.frame_len =
   3863                     VENUS_BUFFER_SIZE(COLOR_FMT_NV21, dim->width, dim->height);
   3864             buf_planes->plane_info.num_planes = 2;
   3865             buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   3866             buf_planes->plane_info.mp[0].offset = 0;
   3867             buf_planes->plane_info.mp[0].offset_x =0;
   3868             buf_planes->plane_info.mp[0].offset_y = 0;
   3869             buf_planes->plane_info.mp[0].stride = stride;
   3870             buf_planes->plane_info.mp[0].scanline = scanline;
   3871             buf_planes->plane_info.mp[0].width = dim->width;
   3872             buf_planes->plane_info.mp[0].height = dim->height;
   3873             stride = VENUS_UV_STRIDE(COLOR_FMT_NV21, dim->width);
   3874             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV21, dim->height);
   3875             buf_planes->plane_info.mp[1].len =
   3876                     buf_planes->plane_info.frame_len -
   3877                     buf_planes->plane_info.mp[0].len;
   3878             buf_planes->plane_info.mp[1].offset = 0;
   3879             buf_planes->plane_info.mp[1].offset_x =0;
   3880             buf_planes->plane_info.mp[1].offset_y = 0;
   3881             buf_planes->plane_info.mp[1].stride = stride;
   3882             buf_planes->plane_info.mp[1].scanline = scanline;
   3883             buf_planes->plane_info.mp[1].width = dim->width;
   3884             buf_planes->plane_info.mp[1].height = dim->height / 2;
   3885 #else
   3886             LOGD("Video format VENUS is not supported = %d",
   3887                      fmt);
   3888 #endif
   3889             break;
   3890         case CAM_FORMAT_YUV_420_NV12_UBWC:
   3891 #ifdef UBWC_PRESENT
   3892             // using UBWC
   3893             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3894             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3895             meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3896             meta_scanline = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3897 
   3898             buf_planes->plane_info.frame_len =
   3899                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, dim->width, dim->height);
   3900             buf_planes->plane_info.num_planes = 2;
   3901             buf_planes->plane_info.mp[0].offset = 0;
   3902             buf_planes->plane_info.mp[0].offset_x =0;
   3903             buf_planes->plane_info.mp[0].offset_y = 0;
   3904             buf_planes->plane_info.mp[0].stride = stride;
   3905             buf_planes->plane_info.mp[0].scanline = scanline;
   3906             buf_planes->plane_info.mp[0].width = dim->width;
   3907             buf_planes->plane_info.mp[0].height = dim->height;
   3908             buf_planes->plane_info.mp[0].meta_stride = meta_stride;
   3909             buf_planes->plane_info.mp[0].meta_scanline = meta_scanline;
   3910             buf_planes->plane_info.mp[0].meta_len =
   3911                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   3912             buf_planes->plane_info.mp[0].len =
   3913                     (uint32_t)(MSM_MEDIA_ALIGN((stride * scanline), 4096) +
   3914                     (buf_planes->plane_info.mp[0].meta_len));
   3915 
   3916             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3917             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3918             meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   3919             meta_scanline = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   3920 
   3921             buf_planes->plane_info.mp[1].offset = 0;
   3922             buf_planes->plane_info.mp[1].offset_x =0;
   3923             buf_planes->plane_info.mp[1].offset_y = 0;
   3924             buf_planes->plane_info.mp[1].stride = stride;
   3925             buf_planes->plane_info.mp[1].scanline = scanline;
   3926             buf_planes->plane_info.mp[1].width = dim->width;
   3927             buf_planes->plane_info.mp[1].height = dim->height/2;
   3928             buf_planes->plane_info.mp[1].meta_stride = meta_stride;
   3929             buf_planes->plane_info.mp[1].meta_scanline = meta_scanline;
   3930             buf_planes->plane_info.mp[1].meta_len =
   3931                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   3932             buf_planes->plane_info.mp[1].len =
   3933                     buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   3934 
   3935 #else
   3936             LOGD("Video format UBWC is not supported = %d",
   3937                      fmt);
   3938             rc = -1;
   3939 #endif
   3940             break;
   3941         default:
   3942             LOGD("Invalid Video Format = %d", fmt);
   3943             rc = -1;
   3944             break;
   3945     }
   3946     return rc;
   3947 }
   3948 
   3949 /*===========================================================================
   3950  * FUNCTION   : mm_stream_calc_offset_metadata
   3951  *
   3952  * DESCRIPTION: calculate metadata frame offset based on format and
   3953  *              padding information
   3954  *
   3955  * PARAMETERS :
   3956  *   @dim     : image dimension
   3957  *   @padding : padding information
   3958  *   @buf_planes : [out] buffer plane information
   3959  *
   3960  * RETURN     : int32_t type of status
   3961  *              0  -- success
   3962  *              -1 -- failure
   3963  *==========================================================================*/
   3964 int32_t mm_stream_calc_offset_metadata(cam_dimension_t *dim,
   3965                                        cam_padding_info_t *padding,
   3966                                        cam_stream_buf_plane_info_t *buf_planes)
   3967 {
   3968     int32_t rc = 0;
   3969     buf_planes->plane_info.num_planes = 1;
   3970     buf_planes->plane_info.mp[0].offset = 0;
   3971     buf_planes->plane_info.mp[0].len =
   3972             PAD_TO_SIZE((uint32_t)(dim->width * dim->height),
   3973                     padding->plane_padding);
   3974     buf_planes->plane_info.frame_len =
   3975         buf_planes->plane_info.mp[0].len;
   3976 
   3977     buf_planes->plane_info.mp[0].offset_x =0;
   3978     buf_planes->plane_info.mp[0].offset_y = 0;
   3979     buf_planes->plane_info.mp[0].stride = dim->width;
   3980     buf_planes->plane_info.mp[0].scanline = dim->height;
   3981     buf_planes->plane_info.mp[0].width = dim->width;
   3982     buf_planes->plane_info.mp[0].height = dim->height;
   3983     return rc;
   3984 }
   3985 
   3986 /*===========================================================================
   3987  * FUNCTION   : mm_stream_calc_offset_analysis
   3988  *
   3989  * DESCRIPTION: calculate analysis frame offset based on format and
   3990  *              padding information
   3991  *
   3992  * PARAMETERS :
   3993  *   @fmt     : image format
   3994  *   @dim     : image dimension
   3995  *   @padding : padding information
   3996  *   @buf_planes : [out] buffer plane information
   3997  *
   3998  * RETURN     : int32_t type of status
   3999  *              0  -- success
   4000  *              -1 -- failure
   4001  *==========================================================================*/
   4002 int32_t mm_stream_calc_offset_analysis(cam_format_t fmt,
   4003                                        cam_dimension_t *dim,
   4004                                        cam_padding_info_t *padding,
   4005                                        cam_stream_buf_plane_info_t *buf_planes)
   4006 {
   4007     int32_t rc = 0;
   4008     int32_t offset_x = 0, offset_y = 0;
   4009     int32_t stride, scanline;
   4010 
   4011     /* Clip to minimum supported bytes per line */
   4012     if ((uint32_t)dim->width < padding->min_stride) {
   4013         stride = (int32_t)padding->min_stride;
   4014     } else {
   4015         stride = dim->width;
   4016     }
   4017 
   4018     if ((uint32_t)dim->height < padding->min_scanline) {
   4019       scanline = (int32_t)padding->min_scanline;
   4020     } else {
   4021       scanline = dim->height;
   4022     }
   4023 
   4024     stride = PAD_TO_SIZE(stride, padding->width_padding);
   4025     scanline = PAD_TO_SIZE(scanline, padding->height_padding);
   4026 
   4027     switch (fmt) {
   4028     case CAM_FORMAT_YUV_420_NV12:
   4029     case CAM_FORMAT_YUV_420_NV21:
   4030         /* 2 planes: Y + CbCr */
   4031         buf_planes->plane_info.num_planes = 2;
   4032 
   4033         buf_planes->plane_info.mp[0].len =
   4034                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   4035                         padding->plane_padding);
   4036         buf_planes->plane_info.mp[0].offset =
   4037                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   4038                         padding->plane_padding);
   4039         buf_planes->plane_info.mp[0].offset_x = offset_x;
   4040         buf_planes->plane_info.mp[0].offset_y = offset_y;
   4041         buf_planes->plane_info.mp[0].stride = stride;
   4042         buf_planes->plane_info.mp[0].scanline = scanline;
   4043         buf_planes->plane_info.mp[0].width = dim->width;
   4044         buf_planes->plane_info.mp[0].height = dim->height;
   4045 
   4046         scanline = scanline / 2;
   4047         buf_planes->plane_info.mp[1].len =
   4048                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   4049                         padding->plane_padding);
   4050         buf_planes->plane_info.mp[1].offset =
   4051                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   4052                         padding->plane_padding);
   4053         buf_planes->plane_info.mp[1].offset_x = offset_x;
   4054         buf_planes->plane_info.mp[1].offset_y = offset_y;
   4055         buf_planes->plane_info.mp[1].stride = stride;
   4056         buf_planes->plane_info.mp[1].scanline = scanline;
   4057         buf_planes->plane_info.mp[1].width = dim->width;
   4058         buf_planes->plane_info.mp[1].height = dim->height / 2;
   4059 
   4060         buf_planes->plane_info.frame_len =
   4061                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   4062                         buf_planes->plane_info.mp[1].len,
   4063                         CAM_PAD_TO_4K);
   4064         break;
   4065     case CAM_FORMAT_YUV_420_YV12:
   4066         /* 3 planes: Y + Cr + Cb */
   4067         buf_planes->plane_info.num_planes = 3;
   4068 
   4069         buf_planes->plane_info.mp[0].offset =
   4070                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   4071                         padding->plane_padding);
   4072         buf_planes->plane_info.mp[0].len =
   4073                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   4074                         padding->plane_padding);
   4075         buf_planes->plane_info.mp[0].offset_x = offset_x;
   4076         buf_planes->plane_info.mp[0].offset_y = offset_y;
   4077         buf_planes->plane_info.mp[0].stride = stride;
   4078         buf_planes->plane_info.mp[0].scanline = scanline;
   4079         buf_planes->plane_info.mp[0].width = dim->width;
   4080         buf_planes->plane_info.mp[0].height = dim->height;
   4081 
   4082         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   4083         scanline = scanline / 2;
   4084         buf_planes->plane_info.mp[1].offset =
   4085                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   4086                         padding->plane_padding);
   4087         buf_planes->plane_info.mp[1].len =
   4088                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   4089                         padding->plane_padding);
   4090         buf_planes->plane_info.mp[1].offset_x = offset_x;
   4091         buf_planes->plane_info.mp[1].offset_y = offset_y;
   4092         buf_planes->plane_info.mp[1].stride = stride;
   4093         buf_planes->plane_info.mp[1].scanline = scanline;
   4094         buf_planes->plane_info.mp[1].width = dim->width / 2;
   4095         buf_planes->plane_info.mp[1].height = dim->height / 2;
   4096 
   4097         buf_planes->plane_info.mp[2].offset =
   4098                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   4099                         padding->plane_padding);
   4100         buf_planes->plane_info.mp[2].len =
   4101                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   4102                         padding->plane_padding);
   4103         buf_planes->plane_info.mp[2].offset_x = offset_x;
   4104         buf_planes->plane_info.mp[2].offset_y = offset_y;
   4105         buf_planes->plane_info.mp[2].stride = stride;
   4106         buf_planes->plane_info.mp[2].scanline = scanline;
   4107         buf_planes->plane_info.mp[2].width = dim->width / 2;
   4108         buf_planes->plane_info.mp[2].height = dim->height / 2;
   4109 
   4110         buf_planes->plane_info.frame_len =
   4111                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   4112                         buf_planes->plane_info.mp[1].len +
   4113                         buf_planes->plane_info.mp[2].len,
   4114                         CAM_PAD_TO_4K);
   4115         break;
   4116     case CAM_FORMAT_YUV_422_NV16:
   4117     case CAM_FORMAT_YUV_422_NV61:
   4118         /* 2 planes: Y + CbCr */
   4119         buf_planes->plane_info.num_planes = 2;
   4120         buf_planes->plane_info.mp[0].len =
   4121                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   4122                         padding->plane_padding);
   4123         buf_planes->plane_info.mp[0].offset =
   4124                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   4125                         padding->plane_padding);
   4126         buf_planes->plane_info.mp[0].offset_x = offset_x;
   4127         buf_planes->plane_info.mp[0].offset_y = offset_y;
   4128         buf_planes->plane_info.mp[0].stride = stride;
   4129         buf_planes->plane_info.mp[0].scanline = scanline;
   4130         buf_planes->plane_info.mp[0].width = dim->width;
   4131         buf_planes->plane_info.mp[0].height = dim->height;
   4132 
   4133         buf_planes->plane_info.mp[1].len =
   4134                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   4135                         padding->plane_padding);
   4136         buf_planes->plane_info.mp[1].offset =
   4137                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   4138                         padding->plane_padding);
   4139         buf_planes->plane_info.mp[1].offset_x = offset_x;
   4140         buf_planes->plane_info.mp[1].offset_y = offset_y;
   4141         buf_planes->plane_info.mp[1].stride = stride;
   4142         buf_planes->plane_info.mp[1].scanline = scanline;
   4143         buf_planes->plane_info.mp[1].width = dim->width;
   4144         buf_planes->plane_info.mp[1].height = dim->height;
   4145 
   4146         buf_planes->plane_info.frame_len = PAD_TO_SIZE(
   4147             buf_planes->plane_info.mp[0].len + buf_planes->plane_info.mp[1].len,
   4148             CAM_PAD_TO_4K);
   4149         break;
   4150     case CAM_FORMAT_Y_ONLY:
   4151     case CAM_FORMAT_Y_ONLY_10_BPP:
   4152     case CAM_FORMAT_Y_ONLY_12_BPP:
   4153     case CAM_FORMAT_Y_ONLY_14_BPP:
   4154         buf_planes->plane_info.num_planes = 1;
   4155 
   4156         buf_planes->plane_info.mp[0].len =
   4157                 PAD_TO_SIZE((uint32_t)(stride * scanline),
   4158                 padding->plane_padding);
   4159         buf_planes->plane_info.mp[0].offset =
   4160                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
   4161                 padding->plane_padding);
   4162         buf_planes->plane_info.mp[0].offset_x = offset_x;
   4163         buf_planes->plane_info.mp[0].offset_y = offset_y;
   4164         buf_planes->plane_info.mp[0].stride = stride;
   4165         buf_planes->plane_info.mp[0].scanline = scanline;
   4166         buf_planes->plane_info.mp[0].width = dim->width;
   4167         buf_planes->plane_info.mp[0].height = dim->height;
   4168         buf_planes->plane_info.frame_len =
   4169                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   4170         break;
   4171     case CAM_FORMAT_YUV_420_NV12_VENUS:
   4172 #ifdef VENUS_PRESENT
   4173         // using Venus
   4174         stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   4175         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   4176 
   4177         buf_planes->plane_info.frame_len =
   4178                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, stride, scanline);
   4179         buf_planes->plane_info.num_planes = 2;
   4180         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   4181         buf_planes->plane_info.mp[0].offset = 0;
   4182         buf_planes->plane_info.mp[0].offset_x =0;
   4183         buf_planes->plane_info.mp[0].offset_y = 0;
   4184         buf_planes->plane_info.mp[0].stride = stride;
   4185         buf_planes->plane_info.mp[0].scanline = scanline;
   4186         buf_planes->plane_info.mp[0].width = dim->width;
   4187         buf_planes->plane_info.mp[0].height = dim->height;
   4188         stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   4189         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   4190         buf_planes->plane_info.mp[1].len =
   4191                 buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   4192         buf_planes->plane_info.mp[1].offset = 0;
   4193         buf_planes->plane_info.mp[1].offset_x =0;
   4194         buf_planes->plane_info.mp[1].offset_y = 0;
   4195         buf_planes->plane_info.mp[1].stride = stride;
   4196         buf_planes->plane_info.mp[1].scanline = scanline;
   4197         buf_planes->plane_info.mp[1].width = dim->width;
   4198         buf_planes->plane_info.mp[1].height = dim->height / 2;
   4199 #else
   4200         LOGE("Venus hardware not avail, cannot use this format");
   4201         rc = -1;
   4202 #endif
   4203         break;
   4204     case CAM_FORMAT_YUV_420_NV21_VENUS:
   4205 #ifdef VENUS_PRESENT
   4206         // using Venus
   4207         stride = VENUS_Y_STRIDE(COLOR_FMT_NV21, dim->width);
   4208         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV21, dim->height);
   4209 
   4210         buf_planes->plane_info.frame_len =
   4211                 VENUS_BUFFER_SIZE(COLOR_FMT_NV21, stride, scanline);
   4212         buf_planes->plane_info.num_planes = 2;
   4213         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
   4214         buf_planes->plane_info.mp[0].offset = 0;
   4215         buf_planes->plane_info.mp[0].offset_x =0;
   4216         buf_planes->plane_info.mp[0].offset_y = 0;
   4217         buf_planes->plane_info.mp[0].stride = stride;
   4218         buf_planes->plane_info.mp[0].scanline = scanline;
   4219         buf_planes->plane_info.mp[0].width = dim->width;
   4220         buf_planes->plane_info.mp[0].height = dim->height;
   4221         stride = VENUS_UV_STRIDE(COLOR_FMT_NV21, dim->width);
   4222         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV21, dim->height);
   4223         buf_planes->plane_info.mp[1].len =
   4224                 buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   4225         buf_planes->plane_info.mp[1].offset = 0;
   4226         buf_planes->plane_info.mp[1].offset_x =0;
   4227         buf_planes->plane_info.mp[1].offset_y = 0;
   4228         buf_planes->plane_info.mp[1].stride = stride;
   4229         buf_planes->plane_info.mp[1].scanline = scanline;
   4230         buf_planes->plane_info.mp[1].width = dim->width;
   4231         buf_planes->plane_info.mp[1].height = dim->height / 2;
   4232 #else
   4233         LOGE("Venus hardware not avail, cannot use this format");
   4234         rc = -1;
   4235 #endif
   4236         break;
   4237     case CAM_FORMAT_YUV_420_NV12_UBWC:
   4238 #ifdef UBWC_PRESENT
   4239         {
   4240             int meta_stride = 0,meta_scanline = 0;
   4241             // using UBWC
   4242             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   4243             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   4244             meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   4245             meta_scanline = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   4246 
   4247             buf_planes->plane_info.frame_len =
   4248                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, stride, scanline);
   4249             buf_planes->plane_info.num_planes = 2;
   4250             buf_planes->plane_info.mp[0].offset = 0;
   4251             buf_planes->plane_info.mp[0].offset_x =0;
   4252             buf_planes->plane_info.mp[0].offset_y = 0;
   4253             buf_planes->plane_info.mp[0].stride = stride;
   4254             buf_planes->plane_info.mp[0].scanline = scanline;
   4255             buf_planes->plane_info.mp[0].width = dim->width;
   4256             buf_planes->plane_info.mp[0].height = dim->height;
   4257             buf_planes->plane_info.mp[0].meta_stride = meta_stride;
   4258             buf_planes->plane_info.mp[0].meta_scanline = meta_scanline;
   4259             buf_planes->plane_info.mp[0].meta_len =
   4260                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   4261             buf_planes->plane_info.mp[0].len =
   4262                     (uint32_t)(MSM_MEDIA_ALIGN((stride * scanline), 4096) +
   4263                     (buf_planes->plane_info.mp[0].meta_len));
   4264 
   4265             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   4266             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   4267             meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
   4268             meta_scanline = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
   4269             buf_planes->plane_info.mp[1].offset = 0;
   4270             buf_planes->plane_info.mp[1].offset_x =0;
   4271             buf_planes->plane_info.mp[1].offset_y = 0;
   4272             buf_planes->plane_info.mp[1].stride = stride;
   4273             buf_planes->plane_info.mp[1].scanline = scanline;
   4274             buf_planes->plane_info.mp[1].width = dim->width;
   4275             buf_planes->plane_info.mp[1].height = dim->height/2;
   4276             buf_planes->plane_info.mp[1].meta_stride = meta_stride;
   4277             buf_planes->plane_info.mp[1].meta_scanline = meta_scanline;
   4278             buf_planes->plane_info.mp[1].meta_len =
   4279                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
   4280             buf_planes->plane_info.mp[1].len =
   4281                     buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   4282         }
   4283 #else
   4284         LOGE("UBWC hardware not avail, cannot use this format");
   4285         rc = -1;
   4286 #endif
   4287         break;
   4288     default:
   4289         LOGE("Invalid cam_format for anlysis %d",
   4290                     fmt);
   4291         rc = -1;
   4292         break;
   4293     }
   4294 
   4295     return rc;
   4296 }
   4297 
   4298 /*===========================================================================
   4299  * FUNCTION   : mm_stream_calc_offset_postproc
   4300  *
   4301  * DESCRIPTION: calculate postprocess frame offset
   4302  *
   4303  * PARAMETERS :
   4304  *   @stream_info: ptr to stream info
   4305  *   @padding : padding information
   4306  *   @plns : [out] buffer plane information
   4307  *
   4308  * RETURN     : int32_t type of status
   4309  *              0  -- success
   4310  *              -1 -- failure
   4311  *==========================================================================*/
   4312 int32_t mm_stream_calc_offset_postproc(cam_stream_info_t *stream_info,
   4313                                        cam_padding_info_t *padding,
   4314                                        cam_stream_buf_plane_info_t *plns)
   4315 {
   4316     int32_t rc = 0;
   4317     cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT;
   4318     if (stream_info->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
   4319         type = stream_info->reprocess_config.offline.input_type;
   4320         if (CAM_STREAM_TYPE_DEFAULT == type) {
   4321             if (plns->plane_info.frame_len == 0) {
   4322                 // take offset from input source
   4323                 *plns = stream_info->reprocess_config.offline.input_buf_planes;
   4324                 return rc;
   4325             }
   4326         } else {
   4327             type = stream_info->reprocess_config.offline.input_type;
   4328         }
   4329     } else {
   4330         type = stream_info->reprocess_config.online.input_stream_type;
   4331     }
   4332 
   4333     switch (type) {
   4334     case CAM_STREAM_TYPE_PREVIEW:
   4335         rc = mm_stream_calc_offset_preview(stream_info,
   4336                                            &stream_info->dim,
   4337                                            padding,
   4338                                            plns);
   4339         break;
   4340     case CAM_STREAM_TYPE_POSTVIEW:
   4341         rc = mm_stream_calc_offset_post_view(stream_info->fmt,
   4342                                            &stream_info->dim,
   4343                                            plns);
   4344         break;
   4345     case CAM_STREAM_TYPE_SNAPSHOT:
   4346     case CAM_STREAM_TYPE_CALLBACK:
   4347         rc = mm_stream_calc_offset_snapshot(stream_info->fmt,
   4348                                             &stream_info->dim,
   4349                                             padding,
   4350                                             plns);
   4351         break;
   4352     case CAM_STREAM_TYPE_VIDEO:
   4353         rc = mm_stream_calc_offset_video(stream_info->fmt,
   4354                 &stream_info->dim, plns);
   4355         break;
   4356     case CAM_STREAM_TYPE_RAW:
   4357         rc = mm_stream_calc_offset_raw(stream_info->fmt,
   4358                                        &stream_info->dim,
   4359                                        padding,
   4360                                        plns);
   4361         break;
   4362     case CAM_STREAM_TYPE_ANALYSIS:
   4363         rc = mm_stream_calc_offset_analysis(stream_info->fmt,
   4364                                             &stream_info->dim,
   4365                                             padding,
   4366                                             plns);
   4367         break;
   4368     case CAM_STREAM_TYPE_METADATA:
   4369         rc = mm_stream_calc_offset_metadata(&stream_info->dim,
   4370                                             padding,
   4371                                             plns);
   4372         break;
   4373     case CAM_STREAM_TYPE_OFFLINE_PROC:
   4374         rc = mm_stream_calc_offset_snapshot(stream_info->fmt,
   4375                 &stream_info->dim, padding, plns);
   4376         break;
   4377     default:
   4378         LOGE("not supported for stream type %d",
   4379                     type);
   4380         rc = -1;
   4381         break;
   4382     }
   4383     return rc;
   4384 }
   4385 
   4386 /*===========================================================================
   4387 * FUNCTION    : mm_stream_calc_lcm
   4388 *
   4389 * DESCRIPTION: calculate LCM of two numbers
   4390 *
   4391 * PARAMETERS :
   4392 *   @num1  : number 1
   4393 *   @num2  : number 2
   4394 *
   4395 * RETURN     : uint32_t type
   4396 *
   4397 *===========================================================================*/
   4398 uint32_t mm_stream_calc_lcm(int32_t num1, int32_t num2)
   4399 {
   4400     uint32_t lcm = 0;
   4401     uint32_t temp = 0;
   4402 
   4403     if ((num1 < 1) && (num2 < 1)) {
   4404         return 0;
   4405     } else if (num1 < 1) {
   4406         return num2;
   4407     } else if (num2 < 1) {
   4408         return num1;
   4409     }
   4410 
   4411     if (num1 > num2) {
   4412         lcm = num1;
   4413     } else {
   4414         lcm = num2;
   4415     }
   4416     temp = lcm;
   4417 
   4418     while (1) {
   4419         if (((lcm%num1) == 0) && ((lcm%num2) == 0)) {
   4420             break;
   4421         }
   4422         lcm += temp;
   4423     }
   4424     return lcm;
   4425 }
   4426 
   4427 /*===========================================================================
   4428  * FUNCTION   : mm_stream_calc_offset
   4429  *
   4430  * DESCRIPTION: calculate frame offset based on format and padding information
   4431  *
   4432  * PARAMETERS :
   4433  *   @my_obj  : stream object
   4434  *
   4435  * RETURN     : int32_t type of status
   4436  *              0  -- success
   4437  *              -1 -- failure
   4438  *==========================================================================*/
   4439 int32_t mm_stream_calc_offset(mm_stream_t *my_obj)
   4440 {
   4441     int32_t rc = 0;
   4442 
   4443     cam_dimension_t dim = my_obj->stream_info->dim;
   4444     if (my_obj->stream_info->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
   4445         my_obj->stream_info->stream_type != CAM_STREAM_TYPE_VIDEO) {
   4446         if (my_obj->stream_info->pp_config.rotation == ROTATE_90 ||
   4447             my_obj->stream_info->pp_config.rotation == ROTATE_270) {
   4448             // rotated by 90 or 270, need to switch width and height
   4449             dim.width = my_obj->stream_info->dim.height;
   4450             dim.height = my_obj->stream_info->dim.width;
   4451         }
   4452     }
   4453 
   4454     switch (my_obj->stream_info->stream_type) {
   4455     case CAM_STREAM_TYPE_PREVIEW:
   4456         rc = mm_stream_calc_offset_preview(my_obj->stream_info,
   4457                                            &dim,
   4458                                            &my_obj->padding_info,
   4459                                            &my_obj->stream_info->buf_planes);
   4460         break;
   4461     case CAM_STREAM_TYPE_POSTVIEW:
   4462       rc = mm_stream_calc_offset_post_view(my_obj->stream_info->fmt,
   4463                                          &dim,
   4464                                          &my_obj->stream_info->buf_planes);
   4465       break;
   4466     case CAM_STREAM_TYPE_SNAPSHOT:
   4467     case CAM_STREAM_TYPE_CALLBACK:
   4468         rc = mm_stream_calc_offset_snapshot(my_obj->stream_info->fmt,
   4469                                             &dim,
   4470                                             &my_obj->padding_info,
   4471                                             &my_obj->stream_info->buf_planes);
   4472         break;
   4473     case CAM_STREAM_TYPE_OFFLINE_PROC:
   4474         rc = mm_stream_calc_offset_postproc(my_obj->stream_info,
   4475                                             &my_obj->padding_info,
   4476                                             &my_obj->stream_info->buf_planes);
   4477         break;
   4478     case CAM_STREAM_TYPE_VIDEO:
   4479         rc = mm_stream_calc_offset_video(my_obj->stream_info->fmt,
   4480                 &dim, &my_obj->stream_info->buf_planes);
   4481         break;
   4482     case CAM_STREAM_TYPE_RAW:
   4483         rc = mm_stream_calc_offset_raw(my_obj->stream_info->fmt,
   4484                                        &dim,
   4485                                        &my_obj->padding_info,
   4486                                        &my_obj->stream_info->buf_planes);
   4487         break;
   4488     case CAM_STREAM_TYPE_ANALYSIS:
   4489         rc = mm_stream_calc_offset_analysis(my_obj->stream_info->fmt,
   4490                                             &dim,
   4491                                             &my_obj->padding_info,
   4492                                             &my_obj->stream_info->buf_planes);
   4493         break;
   4494     case CAM_STREAM_TYPE_METADATA:
   4495         rc = mm_stream_calc_offset_metadata(&dim,
   4496                                             &my_obj->padding_info,
   4497                                             &my_obj->stream_info->buf_planes);
   4498         break;
   4499     default:
   4500         LOGE("not supported for stream type %d",
   4501                     my_obj->stream_info->stream_type);
   4502         rc = -1;
   4503         break;
   4504     }
   4505 
   4506     my_obj->frame_offset = my_obj->stream_info->buf_planes.plane_info;
   4507     return rc;
   4508 }
   4509 
   4510 /*===========================================================================
   4511  * FUNCTION   : mm_stream_sync_info
   4512  *
   4513  * DESCRIPTION: synchronize stream information with server
   4514  *
   4515  * PARAMETERS :
   4516  *   @my_obj  : stream object
   4517  *
   4518  * RETURN     : int32_t type of status
   4519  *              0  -- success
   4520  *              -1 -- failure
   4521  * NOTE       : assume stream info buffer is mapped to server and filled in with
   4522  *              stream information by upper layer. This call will let server to
   4523  *              synchornize the stream information with HAL. If server find any
   4524  *              fields that need to be changed accroding to hardware configuration,
   4525  *              server will modify corresponding fields so that HAL could know
   4526  *              about it.
   4527  *==========================================================================*/
   4528 int32_t mm_stream_sync_info(mm_stream_t *my_obj)
   4529 {
   4530     int32_t rc = 0;
   4531     int32_t value = 0;
   4532     my_obj->stream_info->stream_svr_id = my_obj->server_stream_id;
   4533     rc = mm_stream_calc_offset(my_obj);
   4534 
   4535     if (rc == 0) {
   4536         mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   4537         int stream_id  =  my_obj->server_stream_id;
   4538         rc = mm_camera_util_s_ctrl(cam_obj, stream_id, my_obj->fd,
   4539                 CAM_PRIV_STREAM_INFO_SYNC, &value);
   4540     }
   4541     return rc;
   4542 }
   4543 
   4544 /*===========================================================================
   4545  * FUNCTION   : mm_stream_set_fmt
   4546  *
   4547  * DESCRIPTION: set stream format to kernel via v4l2 ioctl
   4548  *
   4549  * PARAMETERS :
   4550  *   @my_obj  : stream object
   4551  *
   4552  * RETURN     : int32_t type of status
   4553  *              0  -- success
   4554  *              -1 -- failure
   4555  *==========================================================================*/
   4556 int32_t mm_stream_set_fmt(mm_stream_t *my_obj)
   4557 {
   4558     int32_t rc = 0;
   4559     struct v4l2_format fmt;
   4560     struct msm_v4l2_format_data msm_fmt;
   4561     int i;
   4562     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   4563           my_obj->my_hdl, my_obj->fd, my_obj->state);
   4564 
   4565     if (my_obj->stream_info->dim.width == 0 ||
   4566         my_obj->stream_info->dim.height == 0) {
   4567         LOGE("invalid input[w=%d,h=%d,fmt=%d]\n",
   4568                    my_obj->stream_info->dim.width,
   4569                    my_obj->stream_info->dim.height,
   4570                    my_obj->stream_info->fmt);
   4571         return -1;
   4572     }
   4573 
   4574     memset(&fmt, 0, sizeof(fmt));
   4575     memset(&msm_fmt, 0, sizeof(msm_fmt));
   4576     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4577     msm_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4578 
   4579     msm_fmt.width = (unsigned int)my_obj->stream_info->dim.width;
   4580     msm_fmt.height = (unsigned int)my_obj->stream_info->dim.height;
   4581     msm_fmt.pixelformat = mm_stream_get_v4l2_fmt(my_obj->stream_info->fmt);
   4582 
   4583     if (my_obj->stream_info->streaming_mode != CAM_STREAMING_MODE_BATCH) {
   4584         msm_fmt.num_planes = (unsigned char)my_obj->frame_offset.num_planes;
   4585         for (i = 0; i < msm_fmt.num_planes; i++) {
   4586             msm_fmt.plane_sizes[i] = my_obj->frame_offset.mp[i].len;
   4587         }
   4588     } else {
   4589         msm_fmt.num_planes = 1;
   4590         msm_fmt.plane_sizes[0] = my_obj->stream_info->user_buf_info.size;
   4591     }
   4592 
   4593     memcpy(fmt.fmt.raw_data, &msm_fmt, sizeof(msm_fmt));
   4594     rc = ioctl(my_obj->fd, VIDIOC_S_FMT, &fmt);
   4595     if (rc < 0) {
   4596         LOGE("ioctl VIDIOC_S_FMT failed: rc=%d errno %d\n", rc, errno);
   4597     } else {
   4598 #ifndef DAEMON_PRESENT
   4599         mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
   4600         cam_shim_packet_t *shim_cmd;
   4601         cam_shim_cmd_data shim_cmd_data;
   4602 
   4603         memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
   4604         shim_cmd_data.command = MSM_CAMERA_PRIV_S_FMT;
   4605         shim_cmd_data.stream_id = my_obj->server_stream_id;
   4606         shim_cmd_data.value = NULL;
   4607         shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
   4608                 cam_obj->sessionid, &shim_cmd_data);
   4609         rc = mm_camera_module_send_cmd(shim_cmd);
   4610         mm_camera_destroy_shim_cmd_packet(shim_cmd);
   4611 #endif /* DAEMON_PRESENT */
   4612     }
   4613     return rc;
   4614 }
   4615 
   4616 /*===========================================================================
   4617  * FUNCTION   : mm_stream_cancel_buf
   4618  *
   4619  * DESCRIPTION: Get buffer back from kernel
   4620  *
   4621  * PARAMETERS :
   4622  *   @my_obj       : stream object
   4623  *   @buf_idx        : frame index to be de-queued back from kernel
   4624  *
   4625  * RETURN     : int32_t type of status
   4626  *              0  -- success
   4627  *              -1 -- failure
   4628  *==========================================================================*/
   4629 int32_t mm_stream_cancel_buf(mm_stream_t * my_obj,
   4630                            uint32_t buf_idx)
   4631 {
   4632     int32_t rc = 0;
   4633     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   4634           my_obj->my_hdl, my_obj->fd, my_obj->state);
   4635 
   4636     pthread_mutex_lock(&my_obj->buf_lock);
   4637     if(my_obj->buf_status[buf_idx].buf_refcnt != 0) {
   4638         LOGE("Error Trying to extract a frame already sent to HAL(idx=%d) count=%d\n",
   4639                     buf_idx,
   4640                    my_obj->buf_status[buf_idx].buf_refcnt);
   4641         pthread_mutex_unlock(&my_obj->buf_lock);
   4642         rc = -1;
   4643         return rc;
   4644     }
   4645     pthread_mutex_unlock(&my_obj->buf_lock);
   4646     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   4647         /*rc = mm_stream_write_user_buf(my_obj, frame);*/
   4648         // TODO handling batch buffers
   4649     } else {
   4650         pthread_mutex_lock(&my_obj->buf_lock);
   4651         //my_obj->buf_status[buf_idx].buf_refcnt++;
   4652         {
   4653             pthread_mutex_unlock(&my_obj->buf_lock);
   4654             LOGD("<DEBUG> : Cancel Buffer done for buffer:%d, stream type:%d", buf_idx, my_obj->stream_info->stream_type);
   4655 
   4656             struct msm_camera_return_buf bufid;
   4657             memset(&bufid, 0, sizeof(struct msm_camera_return_buf));
   4658             bufid.index = buf_idx;
   4659 
   4660             struct msm_camera_private_ioctl_arg arg;
   4661             memset(&arg, 0, sizeof(struct msm_camera_private_ioctl_arg));
   4662             arg.id = MSM_CAMERA_PRIV_IOCTL_ID_RETURN_BUF;
   4663             arg.size = sizeof(struct msm_camera_return_buf);
   4664             arg.ioctl_ptr = (uint32_t) &bufid;
   4665 
   4666 
   4667             rc = ioctl(my_obj->fd, VIDIOC_MSM_CAMERA_PRIVATE_IOCTL_CMD, &arg);
   4668 
   4669             if(rc < 0) {
   4670                 LOGE("mm_stream_cancel_buf(idx=%d) err=%d\n",
   4671                             buf_idx, rc);
   4672             } else {
   4673                 //my_obj->buf_status[frame->buf_idx].in_kernel = 0;
   4674             }
   4675         }
   4676     }
   4677     return rc;
   4678 }
   4679 
   4680 
   4681 /*===========================================================================
   4682  * FUNCTION   : mm_stream_buf_done
   4683  *
   4684  * DESCRIPTION: enqueue buffer back to kernel
   4685  *
   4686  * PARAMETERS :
   4687  *   @my_obj       : stream object
   4688  *   @frame        : frame to be enqueued back to kernel
   4689  *
   4690  * RETURN     : int32_t type of status
   4691  *              0  -- success
   4692  *              -1 -- failure
   4693  *==========================================================================*/
   4694 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
   4695                            mm_camera_buf_def_t *frame)
   4696 {
   4697     int32_t rc = 0;
   4698     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   4699           my_obj->my_hdl, my_obj->fd, my_obj->state);
   4700 
   4701     pthread_mutex_lock(&my_obj->buf_lock);
   4702     if(my_obj->buf_status[frame->buf_idx].buf_refcnt == 0) {
   4703         LOGE("Error Trying to free second time?(idx=%d) count=%d\n",
   4704                     frame->buf_idx,
   4705                    my_obj->buf_status[frame->buf_idx].buf_refcnt);
   4706         pthread_mutex_unlock(&my_obj->buf_lock);
   4707         rc = -1;
   4708         return rc;
   4709     }
   4710     pthread_mutex_unlock(&my_obj->buf_lock);
   4711     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   4712         rc = mm_stream_write_user_buf(my_obj, frame);
   4713     } else {
   4714         pthread_mutex_lock(&my_obj->buf_lock);
   4715         my_obj->buf_status[frame->buf_idx].buf_refcnt--;
   4716         if (0 == my_obj->buf_status[frame->buf_idx].buf_refcnt) {
   4717             pthread_mutex_unlock(&my_obj->buf_lock);
   4718             LOGD("<DEBUG> : Buf done for buffer:%d, stream:%d", frame->buf_idx, frame->stream_type);
   4719             rc = mm_stream_qbuf(my_obj, frame);
   4720             if(rc < 0) {
   4721                 LOGE("mm_camera_stream_qbuf(idx=%d) err=%d\n",
   4722                             frame->buf_idx, rc);
   4723             } else {
   4724                 my_obj->buf_status[frame->buf_idx].in_kernel = 1;
   4725             }
   4726         }else{
   4727             LOGD("<DEBUG> : Still ref count pending count :%d",
   4728                  my_obj->buf_status[frame->buf_idx].buf_refcnt);
   4729             LOGD("<DEBUG> : for buffer:%p:%d",
   4730                  my_obj, frame->buf_idx);
   4731             pthread_mutex_unlock(&my_obj->buf_lock);
   4732         }
   4733     }
   4734     return rc;
   4735 }
   4736 
   4737 
   4738 /*===========================================================================
   4739  * FUNCTION   : mm_stream_get_queued_buf_count
   4740  *
   4741  * DESCRIPTION: return queued buffer count
   4742  *
   4743  * PARAMETERS :
   4744  *   @my_obj       : stream object
   4745  *
   4746  * RETURN     : queued buffer count
   4747  *==========================================================================*/
   4748 int32_t mm_stream_get_queued_buf_count(mm_stream_t *my_obj)
   4749 {
   4750     int32_t rc = 0;
   4751     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   4752              my_obj->my_hdl, my_obj->fd, my_obj->state);
   4753     pthread_mutex_lock(&my_obj->buf_lock);
   4754     rc = my_obj->queued_buffer_count;
   4755     pthread_mutex_unlock(&my_obj->buf_lock);
   4756     return rc;
   4757 }
   4758 
   4759 /*===========================================================================
   4760  * FUNCTION   : mm_stream_reg_buf_cb
   4761  *
   4762  * DESCRIPTION: Allow other stream to register dataCB at this stream.
   4763  *
   4764  * PARAMETERS :
   4765  *   @my_obj       : stream object
   4766  *   @val          : callback function to be registered
   4767  *
   4768  * RETURN     : int32_t type of status
   4769  *              0  -- success
   4770  *              -1 -- failure
   4771  *==========================================================================*/
   4772 int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
   4773         mm_stream_data_cb_t val)
   4774 {
   4775     int32_t rc = -1;
   4776     uint8_t i;
   4777     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
   4778           my_obj->my_hdl, my_obj->fd, my_obj->state);
   4779 
   4780     pthread_mutex_lock(&my_obj->cb_lock);
   4781     for (i=0 ;i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
   4782         if(NULL == my_obj->buf_cb[i].cb) {
   4783             my_obj->buf_cb[i] = val;
   4784             rc = 0;
   4785             break;
   4786         }
   4787     }
   4788     pthread_mutex_unlock(&my_obj->cb_lock);
   4789 
   4790     return rc;
   4791 }
   4792