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