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