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