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