Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2014, 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 #include <pthread.h>
     31 #include <errno.h>
     32 #include <sys/ioctl.h>
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 #include <fcntl.h>
     36 #include <poll.h>
     37 #include <time.h>
     38 #include <cam_semaphore.h>
     39 #ifdef VENUS_PRESENT
     40 #include <media/msm_media_info.h>
     41 #endif
     42 
     43 #include "mm_camera_dbg.h"
     44 #include "mm_camera_interface.h"
     45 #include "mm_camera.h"
     46 
     47 /* internal function decalre */
     48 int32_t mm_stream_qbuf(mm_stream_t *my_obj,
     49                        mm_camera_buf_def_t *buf);
     50 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj);
     51 int32_t mm_stream_set_fmt(mm_stream_t * my_obj);
     52 int32_t mm_stream_sync_info(mm_stream_t *my_obj);
     53 int32_t mm_stream_init_bufs(mm_stream_t * my_obj);
     54 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj);
     55 int32_t mm_stream_request_buf(mm_stream_t * my_obj);
     56 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj);
     57 int32_t mm_stream_release(mm_stream_t *my_obj);
     58 int32_t mm_stream_set_parm(mm_stream_t *my_obj,
     59                            cam_stream_parm_buffer_t *value);
     60 int32_t mm_stream_get_parm(mm_stream_t *my_obj,
     61                            cam_stream_parm_buffer_t *value);
     62 int32_t mm_stream_do_action(mm_stream_t *my_obj,
     63                             void *in_value);
     64 int32_t mm_stream_streamon(mm_stream_t *my_obj);
     65 int32_t mm_stream_streamoff(mm_stream_t *my_obj);
     66 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
     67                                  mm_camera_buf_info_t* buf_info,
     68                                  uint8_t num_planes);
     69 int32_t mm_stream_config(mm_stream_t *my_obj,
     70                          mm_camera_stream_config_t *config);
     71 int32_t mm_stream_reg_buf(mm_stream_t * my_obj);
     72 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
     73                            mm_camera_buf_def_t *frame);
     74 int32_t mm_stream_calc_offset(mm_stream_t *my_obj);
     75 
     76 /* state machine function declare */
     77 int32_t mm_stream_fsm_inited(mm_stream_t * my_obj,
     78                              mm_stream_evt_type_t evt,
     79                              void * in_val,
     80                              void * out_val);
     81 int32_t mm_stream_fsm_acquired(mm_stream_t * my_obj,
     82                                mm_stream_evt_type_t evt,
     83                                void * in_val,
     84                                void * out_val);
     85 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
     86                           mm_stream_evt_type_t evt,
     87                           void * in_val,
     88                           void * out_val);
     89 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
     90                              mm_stream_evt_type_t evt,
     91                              void * in_val,
     92                              void * out_val);
     93 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
     94                           mm_stream_evt_type_t evt,
     95                           void * in_val,
     96                           void * out_val);
     97 int32_t mm_stream_fsm_active(mm_stream_t * my_obj,
     98                              mm_stream_evt_type_t evt,
     99                              void * in_val,
    100                              void * out_val);
    101 uint32_t mm_stream_get_v4l2_fmt(cam_format_t fmt);
    102 
    103 
    104 /*===========================================================================
    105  * FUNCTION   : mm_stream_handle_rcvd_buf
    106  *
    107  * DESCRIPTION: function to handle newly received stream buffer
    108  *
    109  * PARAMETERS :
    110  *   @cam_obj : stream object
    111  *   @buf_info: ptr to struct storing buffer information
    112  *
    113  * RETURN     : none
    114  *==========================================================================*/
    115 void mm_stream_handle_rcvd_buf(mm_stream_t *my_obj,
    116                                mm_camera_buf_info_t *buf_info,
    117                                uint8_t has_cb)
    118 {
    119     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    120          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    121 
    122     /* enqueue to super buf thread */
    123     if (my_obj->is_bundled) {
    124         mm_camera_cmdcb_t* node = NULL;
    125 
    126         /* send cam_sem_post to wake up channel cmd thread to enqueue to super buffer */
    127         node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    128         if (NULL != node) {
    129             memset(node, 0, sizeof(mm_camera_cmdcb_t));
    130             node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
    131             node->u.buf = *buf_info;
    132 
    133             /* enqueue to cmd thread */
    134             cam_queue_enq(&(my_obj->ch_obj->cmd_thread.cmd_queue), node);
    135 
    136             /* wake up cmd thread */
    137             cam_sem_post(&(my_obj->ch_obj->cmd_thread.cmd_sem));
    138         } else {
    139             CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
    140         }
    141     }
    142 
    143     if(has_cb) {
    144         mm_camera_cmdcb_t* node = NULL;
    145 
    146         /* send cam_sem_post to wake up cmd thread to dispatch dataCB */
    147         node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    148         if (NULL != node) {
    149             memset(node, 0, sizeof(mm_camera_cmdcb_t));
    150             node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
    151             node->u.buf = *buf_info;
    152 
    153             /* enqueue to cmd thread */
    154             cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node);
    155 
    156             /* wake up cmd thread */
    157             cam_sem_post(&(my_obj->cmd_thread.cmd_sem));
    158         } else {
    159             CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
    160         }
    161     }
    162 }
    163 
    164 /*===========================================================================
    165  * FUNCTION   : mm_stream_data_notify
    166  *
    167  * DESCRIPTION: callback to handle data notify from kernel
    168  *
    169  * PARAMETERS :
    170  *   @user_data : user data ptr (stream object)
    171  *
    172  * RETURN     : none
    173  *==========================================================================*/
    174 static void mm_stream_data_notify(void* user_data)
    175 {
    176     mm_stream_t *my_obj = (mm_stream_t*)user_data;
    177     int32_t idx = -1, i, rc;
    178     uint8_t has_cb = 0;
    179     mm_camera_buf_info_t buf_info;
    180 
    181     if (NULL == my_obj) {
    182         return;
    183     }
    184 
    185     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    186          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    187     if (MM_STREAM_STATE_ACTIVE != my_obj->state) {
    188         /* this Cb will only received in active_stream_on state
    189          * if not so, return here */
    190         CDBG_ERROR("%s: ERROR!! Wrong state (%d) to receive data notify!",
    191                    __func__, my_obj->state);
    192         return;
    193     }
    194 
    195     memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
    196     rc = mm_stream_read_msm_frame(my_obj, &buf_info, my_obj->frame_offset.num_planes);
    197     if (rc != 0) {
    198         return;
    199     }
    200     idx = buf_info.buf->buf_idx;
    201 
    202     pthread_mutex_lock(&my_obj->cb_lock);
    203     for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    204         if(NULL != my_obj->buf_cb[i].cb) {
    205             /* for every CB, add ref count */
    206             has_cb = 1;
    207             break;
    208         }
    209     }
    210     pthread_mutex_unlock(&my_obj->cb_lock);
    211 
    212     pthread_mutex_lock(&my_obj->buf_lock);
    213     /* update buffer location */
    214     my_obj->buf_status[idx].in_kernel = 0;
    215 
    216     /* update buf ref count */
    217     if (my_obj->is_bundled) {
    218         /* need to add into super buf since bundled, add ref count */
    219         my_obj->buf_status[idx].buf_refcnt++;
    220     }
    221     my_obj->buf_status[idx].buf_refcnt += has_cb;
    222     pthread_mutex_unlock(&my_obj->buf_lock);
    223 
    224     mm_stream_handle_rcvd_buf(my_obj, &buf_info, has_cb);
    225 }
    226 
    227 /*===========================================================================
    228  * FUNCTION   : mm_stream_dispatch_app_data
    229  *
    230  * DESCRIPTION: dispatch stream buffer to registered users
    231  *
    232  * PARAMETERS :
    233  *   @cmd_cb  : ptr storing stream buffer information
    234  *   @userdata: user data ptr (stream object)
    235  *
    236  * RETURN     : none
    237  *==========================================================================*/
    238 static void mm_stream_dispatch_app_data(mm_camera_cmdcb_t *cmd_cb,
    239                                         void* user_data)
    240 {
    241     int i;
    242     mm_stream_t * my_obj = (mm_stream_t *)user_data;
    243     mm_camera_buf_info_t* buf_info = NULL;
    244     mm_camera_super_buf_t super_buf;
    245     mm_camera_cmd_thread_name("mm_cam_stream");
    246 
    247     if (NULL == my_obj) {
    248         return;
    249     }
    250     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    251          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    252 
    253     if (MM_CAMERA_CMD_TYPE_DATA_CB != cmd_cb->cmd_type) {
    254         CDBG_ERROR("%s: Wrong cmd_type (%d) for dataCB",
    255                    __func__, cmd_cb->cmd_type);
    256         return;
    257     }
    258 
    259     buf_info = &cmd_cb->u.buf;
    260     memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
    261     super_buf.num_bufs = 1;
    262     super_buf.bufs[0] = buf_info->buf;
    263     super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
    264     super_buf.ch_id = my_obj->ch_obj->my_hdl;
    265 
    266     pthread_mutex_lock(&my_obj->cb_lock);
    267     for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    268         if(NULL != my_obj->buf_cb[i].cb) {
    269             if (my_obj->buf_cb[i].cb_count != 0) {
    270                 /* if <0, means infinite CB
    271                  * if >0, means CB for certain times
    272                  * both case we need to call CB */
    273 
    274                 /* increase buf ref cnt */
    275                 pthread_mutex_lock(&my_obj->buf_lock);
    276                 my_obj->buf_status[buf_info->buf->buf_idx].buf_refcnt++;
    277                 pthread_mutex_unlock(&my_obj->buf_lock);
    278 
    279                 /* callback */
    280                 my_obj->buf_cb[i].cb(&super_buf,
    281                                      my_obj->buf_cb[i].user_data);
    282             }
    283 
    284             /* if >0, reduce count by 1 every time we called CB until reaches 0
    285              * when count reach 0, reset the buf_cb to have no CB */
    286             if (my_obj->buf_cb[i].cb_count > 0) {
    287                 my_obj->buf_cb[i].cb_count--;
    288                 if (0 == my_obj->buf_cb[i].cb_count) {
    289                     my_obj->buf_cb[i].cb = NULL;
    290                     my_obj->buf_cb[i].user_data = NULL;
    291                 }
    292             }
    293         }
    294     }
    295     pthread_mutex_unlock(&my_obj->cb_lock);
    296 
    297     /* do buf_done since we increased refcnt by one when has_cb */
    298     mm_stream_buf_done(my_obj, buf_info->buf);
    299 }
    300 
    301 /*===========================================================================
    302  * FUNCTION   : mm_stream_fsm_fn
    303  *
    304  * DESCRIPTION: stream finite state machine entry function. Depends on stream
    305  *              state, incoming event will be handled differently.
    306  *
    307  * PARAMETERS :
    308  *   @my_obj   : ptr to a stream object
    309  *   @evt      : stream event to be processed
    310  *   @in_val   : input event payload. Can be NULL if not needed.
    311  *   @out_val  : output payload, Can be NULL if not needed.
    312  *
    313  * RETURN     : int32_t type of status
    314  *              0  -- success
    315  *              -1 -- failure
    316  *==========================================================================*/
    317 int32_t mm_stream_fsm_fn(mm_stream_t *my_obj,
    318                          mm_stream_evt_type_t evt,
    319                          void * in_val,
    320                          void * out_val)
    321 {
    322     int32_t rc = -1;
    323 
    324     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    325          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    326     switch (my_obj->state) {
    327     case MM_STREAM_STATE_NOTUSED:
    328         CDBG("%s: Not handling evt in unused state", __func__);
    329         break;
    330     case MM_STREAM_STATE_INITED:
    331         rc = mm_stream_fsm_inited(my_obj, evt, in_val, out_val);
    332         break;
    333     case MM_STREAM_STATE_ACQUIRED:
    334         rc = mm_stream_fsm_acquired(my_obj, evt, in_val, out_val);
    335         break;
    336     case MM_STREAM_STATE_CFG:
    337         rc = mm_stream_fsm_cfg(my_obj, evt, in_val, out_val);
    338         break;
    339     case MM_STREAM_STATE_BUFFED:
    340         rc = mm_stream_fsm_buffed(my_obj, evt, in_val, out_val);
    341         break;
    342     case MM_STREAM_STATE_REG:
    343         rc = mm_stream_fsm_reg(my_obj, evt, in_val, out_val);
    344         break;
    345     case MM_STREAM_STATE_ACTIVE:
    346         rc = mm_stream_fsm_active(my_obj, evt, in_val, out_val);
    347         break;
    348     default:
    349         CDBG("%s: Not a valid state (%d)", __func__, my_obj->state);
    350         break;
    351     }
    352     CDBG("%s : X rc =%d",__func__,rc);
    353     return rc;
    354 }
    355 
    356 /*===========================================================================
    357  * FUNCTION   : mm_stream_fsm_inited
    358  *
    359  * DESCRIPTION: stream finite state machine function to handle event in INITED
    360  *              state.
    361  *
    362  * PARAMETERS :
    363  *   @my_obj   : ptr to a stream object
    364  *   @evt      : stream event to be processed
    365  *   @in_val   : input event payload. Can be NULL if not needed.
    366  *   @out_val  : output payload, Can be NULL if not needed.
    367  *
    368  * RETURN     : int32_t type of status
    369  *              0  -- success
    370  *              -1 -- failure
    371  *==========================================================================*/
    372 int32_t mm_stream_fsm_inited(mm_stream_t *my_obj,
    373                              mm_stream_evt_type_t evt,
    374                              void * in_val,
    375                              void * out_val)
    376 {
    377     int32_t rc = 0;
    378     char dev_name[MM_CAMERA_DEV_NAME_LEN];
    379 
    380     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    381          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    382     switch(evt) {
    383     case MM_STREAM_EVT_ACQUIRE:
    384         if ((NULL == my_obj->ch_obj) || (NULL == my_obj->ch_obj->cam_obj)) {
    385             CDBG_ERROR("%s: NULL channel or camera obj\n", __func__);
    386             rc = -1;
    387             break;
    388         }
    389 
    390         if (NULL == my_obj) {
    391             CDBG_ERROR("%s: NULL camera object\n", __func__);
    392             rc = -1;
    393             break;
    394         }
    395         snprintf(dev_name, sizeof(dev_name), "/dev/%s",
    396                  mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl));
    397 
    398         my_obj->fd = open(dev_name, O_RDWR | O_NONBLOCK);
    399         if (my_obj->fd < 0) {
    400             CDBG_ERROR("%s: open dev returned %d\n", __func__, my_obj->fd);
    401             rc = -1;
    402             break;
    403         }
    404         CDBG("%s: open dev fd = %d\n", __func__, my_obj->fd);
    405         rc = mm_stream_set_ext_mode(my_obj);
    406         if (0 == rc) {
    407             my_obj->state = MM_STREAM_STATE_ACQUIRED;
    408         } else {
    409             /* failed setting ext_mode
    410              * close fd */
    411             close(my_obj->fd);
    412             my_obj->fd = -1;
    413             break;
    414         }
    415         break;
    416     default:
    417         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    418                    __func__, my_obj->state, evt, in_val, out_val);
    419         break;
    420     }
    421     return rc;
    422 }
    423 
    424 /*===========================================================================
    425  * FUNCTION   : mm_stream_fsm_acquired
    426  *
    427  * DESCRIPTION: stream finite state machine function to handle event in AQUIRED
    428  *              state.
    429  *
    430  * PARAMETERS :
    431  *   @my_obj   : ptr to a stream object
    432  *   @evt      : stream event to be processed
    433  *   @in_val   : input event payload. Can be NULL if not needed.
    434  *   @out_val  : output payload, Can be NULL if not needed.
    435  *
    436  * RETURN     : int32_t type of status
    437  *              0  -- success
    438  *              -1 -- failure
    439  *==========================================================================*/
    440 int32_t mm_stream_fsm_acquired(mm_stream_t *my_obj,
    441                                mm_stream_evt_type_t evt,
    442                                void * in_val,
    443                                void * out_val)
    444 {
    445     int32_t rc = 0;
    446 
    447     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    448          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    449     switch(evt) {
    450     case MM_STREAM_EVT_SET_FMT:
    451         {
    452             mm_camera_stream_config_t *config =
    453                 (mm_camera_stream_config_t *)in_val;
    454 
    455             rc = mm_stream_config(my_obj, config);
    456 
    457             /* change state to configed */
    458             my_obj->state = MM_STREAM_STATE_CFG;
    459 
    460             break;
    461         }
    462     case MM_STREAM_EVT_RELEASE:
    463         rc = mm_stream_release(my_obj);
    464         /* change state to not used */
    465          my_obj->state = MM_STREAM_STATE_NOTUSED;
    466         break;
    467     case MM_STREAM_EVT_SET_PARM:
    468         {
    469             mm_evt_paylod_set_get_stream_parms_t *payload =
    470                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    471             rc = mm_stream_set_parm(my_obj, payload->parms);
    472         }
    473         break;
    474     case MM_STREAM_EVT_GET_PARM:
    475         {
    476             mm_evt_paylod_set_get_stream_parms_t *payload =
    477                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    478             rc = mm_stream_get_parm(my_obj, payload->parms);
    479         }
    480         break;
    481     default:
    482         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    483                    __func__, my_obj->state, evt, in_val, out_val);
    484     }
    485     CDBG("%s :X rc = %d", __func__, rc);
    486     return rc;
    487 }
    488 
    489 /*===========================================================================
    490  * FUNCTION   : mm_stream_fsm_cfg
    491  *
    492  * DESCRIPTION: stream finite state machine function to handle event in CONFIGURED
    493  *              state.
    494  *
    495  * PARAMETERS :
    496  *   @my_obj   : ptr to a stream object
    497  *   @evt      : stream event to be processed
    498  *   @in_val   : input event payload. Can be NULL if not needed.
    499  *   @out_val  : output payload, Can be NULL if not needed.
    500  *
    501  * RETURN     : int32_t type of status
    502  *              0  -- success
    503  *              -1 -- failure
    504  *==========================================================================*/
    505 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
    506                           mm_stream_evt_type_t evt,
    507                           void * in_val,
    508                           void * out_val)
    509 {
    510     int32_t rc = 0;
    511     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    512          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    513     switch(evt) {
    514     case MM_STREAM_EVT_SET_FMT:
    515         {
    516             mm_camera_stream_config_t *config =
    517                 (mm_camera_stream_config_t *)in_val;
    518 
    519             rc = mm_stream_config(my_obj, config);
    520 
    521             /* change state to configed */
    522             my_obj->state = MM_STREAM_STATE_CFG;
    523 
    524             break;
    525         }
    526     case MM_STREAM_EVT_RELEASE:
    527         rc = mm_stream_release(my_obj);
    528         my_obj->state = MM_STREAM_STATE_NOTUSED;
    529         break;
    530     case MM_STREAM_EVT_SET_PARM:
    531         {
    532             mm_evt_paylod_set_get_stream_parms_t *payload =
    533                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    534             rc = mm_stream_set_parm(my_obj, payload->parms);
    535         }
    536         break;
    537     case MM_STREAM_EVT_GET_PARM:
    538         {
    539             mm_evt_paylod_set_get_stream_parms_t *payload =
    540                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    541             rc = mm_stream_get_parm(my_obj, payload->parms);
    542         }
    543         break;
    544     case MM_STREAM_EVT_GET_BUF:
    545         rc = mm_stream_init_bufs(my_obj);
    546         /* change state to buff allocated */
    547         if(0 == rc) {
    548             my_obj->state = MM_STREAM_STATE_BUFFED;
    549         }
    550         break;
    551     default:
    552         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    553                    __func__, my_obj->state, evt, in_val, out_val);
    554     }
    555     CDBG("%s :X rc = %d", __func__, rc);
    556     return rc;
    557 }
    558 
    559 /*===========================================================================
    560  * FUNCTION   : mm_stream_fsm_buffed
    561  *
    562  * DESCRIPTION: stream finite state machine function to handle event in BUFFED
    563  *              state.
    564  *
    565  * PARAMETERS :
    566  *   @my_obj   : ptr to a stream object
    567  *   @evt      : stream event to be processed
    568  *   @in_val   : input event payload. Can be NULL if not needed.
    569  *   @out_val  : output payload, Can be NULL if not needed.
    570  *
    571  * RETURN     : int32_t type of status
    572  *              0  -- success
    573  *              -1 -- failure
    574  *==========================================================================*/
    575 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
    576                              mm_stream_evt_type_t evt,
    577                              void * in_val,
    578                              void * out_val)
    579 {
    580     int32_t rc = 0;
    581     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    582          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    583     switch(evt) {
    584     case MM_STREAM_EVT_PUT_BUF:
    585         rc = mm_stream_deinit_bufs(my_obj);
    586         /* change state to configed */
    587         my_obj->state = MM_STREAM_STATE_CFG;
    588         break;
    589     case MM_STREAM_EVT_REG_BUF:
    590         rc = mm_stream_reg_buf(my_obj);
    591         /* change state to regged */
    592         if(0 == rc) {
    593             my_obj->state = MM_STREAM_STATE_REG;
    594         }
    595         break;
    596     case MM_STREAM_EVT_SET_PARM:
    597         {
    598             mm_evt_paylod_set_get_stream_parms_t *payload =
    599                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    600             rc = mm_stream_set_parm(my_obj, payload->parms);
    601         }
    602         break;
    603     case MM_STREAM_EVT_GET_PARM:
    604         {
    605             mm_evt_paylod_set_get_stream_parms_t *payload =
    606                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    607             rc = mm_stream_get_parm(my_obj, payload->parms);
    608         }
    609         break;
    610     default:
    611         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    612                    __func__, my_obj->state, evt, in_val, out_val);
    613     }
    614     CDBG("%s :X rc = %d", __func__, rc);
    615     return rc;
    616 }
    617 
    618 /*===========================================================================
    619  * FUNCTION   : mm_stream_fsm_reg
    620  *
    621  * DESCRIPTION: stream finite state machine function to handle event in REGGED
    622  *              state.
    623  *
    624  * PARAMETERS :
    625  *   @my_obj   : ptr to a stream object
    626  *   @evt      : stream event to be processed
    627  *   @in_val   : input event payload. Can be NULL if not needed.
    628  *   @out_val  : output payload, Can be NULL if not needed.
    629  *
    630  * RETURN     : int32_t type of status
    631  *              0  -- success
    632  *              -1 -- failure
    633  *==========================================================================*/
    634 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
    635                           mm_stream_evt_type_t evt,
    636                           void * in_val,
    637                           void * out_val)
    638 {
    639     int32_t rc = 0;
    640     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    641          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    642 
    643     switch(evt) {
    644     case MM_STREAM_EVT_UNREG_BUF:
    645         rc = mm_stream_unreg_buf(my_obj);
    646 
    647         /* change state to buffed */
    648         my_obj->state = MM_STREAM_STATE_BUFFED;
    649         break;
    650     case MM_STREAM_EVT_START:
    651         {
    652             uint8_t has_cb = 0;
    653             uint8_t i;
    654             /* launch cmd thread if CB is not null */
    655             pthread_mutex_lock(&my_obj->cb_lock);
    656             for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    657                 if(NULL != my_obj->buf_cb[i].cb) {
    658                     has_cb = 1;
    659                     break;
    660                 }
    661             }
    662             pthread_mutex_unlock(&my_obj->cb_lock);
    663 
    664             if (has_cb) {
    665                 mm_camera_cmd_thread_launch(&my_obj->cmd_thread,
    666                                             mm_stream_dispatch_app_data,
    667                                             (void *)my_obj);
    668             }
    669 
    670             my_obj->state = MM_STREAM_STATE_ACTIVE;
    671             rc = mm_stream_streamon(my_obj);
    672             if (0 != rc) {
    673                 /* failed stream on, need to release cmd thread if it's launched */
    674                 if (has_cb) {
    675                     mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    676                 }
    677                 my_obj->state = MM_STREAM_STATE_REG;
    678                 break;
    679             }
    680         }
    681         break;
    682     case MM_STREAM_EVT_SET_PARM:
    683         {
    684             mm_evt_paylod_set_get_stream_parms_t *payload =
    685                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    686             rc = mm_stream_set_parm(my_obj, payload->parms);
    687         }
    688         break;
    689     case MM_STREAM_EVT_GET_PARM:
    690         {
    691             mm_evt_paylod_set_get_stream_parms_t *payload =
    692                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    693             rc = mm_stream_get_parm(my_obj, payload->parms);
    694         }
    695         break;
    696     default:
    697         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    698                    __func__, my_obj->state, evt, in_val, out_val);
    699     }
    700     CDBG("%s :X rc = %d", __func__, rc);
    701     return rc;
    702 }
    703 
    704 /*===========================================================================
    705  * FUNCTION   : mm_stream_fsm_active
    706  *
    707  * DESCRIPTION: stream finite state machine function to handle event in ACTIVE
    708  *              state.
    709  *
    710  * PARAMETERS :
    711  *   @my_obj   : ptr to a stream object
    712  *   @evt      : stream event to be processed
    713  *   @in_val   : input event payload. Can be NULL if not needed.
    714  *   @out_val  : output payload, Can be NULL if not needed.
    715  *
    716  * RETURN     : int32_t type of status
    717  *              0  -- success
    718  *              -1 -- failure
    719  *==========================================================================*/
    720 int32_t mm_stream_fsm_active(mm_stream_t * my_obj,
    721                              mm_stream_evt_type_t evt,
    722                              void * in_val,
    723                              void * out_val)
    724 {
    725     int32_t rc = 0;
    726     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    727          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    728     switch(evt) {
    729     case MM_STREAM_EVT_QBUF:
    730         rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
    731         break;
    732     case MM_STREAM_EVT_STOP:
    733         {
    734             uint8_t has_cb = 0;
    735             uint8_t i;
    736             rc = mm_stream_streamoff(my_obj);
    737 
    738             pthread_mutex_lock(&my_obj->cb_lock);
    739             for (i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
    740                 if(NULL != my_obj->buf_cb[i].cb) {
    741                     has_cb = 1;
    742                     break;
    743                 }
    744             }
    745             pthread_mutex_unlock(&my_obj->cb_lock);
    746 
    747             if (has_cb) {
    748                 mm_camera_cmd_thread_release(&my_obj->cmd_thread);
    749             }
    750             my_obj->state = MM_STREAM_STATE_REG;
    751         }
    752         break;
    753     case MM_STREAM_EVT_SET_PARM:
    754         {
    755             mm_evt_paylod_set_get_stream_parms_t *payload =
    756                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    757             rc = mm_stream_set_parm(my_obj, payload->parms);
    758         }
    759         break;
    760     case MM_STREAM_EVT_GET_PARM:
    761         {
    762             mm_evt_paylod_set_get_stream_parms_t *payload =
    763                 (mm_evt_paylod_set_get_stream_parms_t *)in_val;
    764             rc = mm_stream_get_parm(my_obj, payload->parms);
    765         }
    766         break;
    767     case MM_STREAM_EVT_DO_ACTION:
    768         rc = mm_stream_do_action(my_obj, in_val);
    769         break;
    770     default:
    771         CDBG_ERROR("%s: invalid state (%d) for evt (%d), in(%p), out(%p)",
    772                    __func__, my_obj->state, evt, in_val, out_val);
    773     }
    774     CDBG("%s :X rc = %d", __func__, rc);
    775     return rc;
    776 }
    777 
    778 /*===========================================================================
    779  * FUNCTION   : mm_stream_config
    780  *
    781  * DESCRIPTION: configure a stream
    782  *
    783  * PARAMETERS :
    784  *   @my_obj       : stream object
    785  *   @config       : stream configuration
    786  *
    787  * RETURN     : int32_t type of status
    788  *              0  -- success
    789  *              -1 -- failure
    790  *==========================================================================*/
    791 int32_t mm_stream_config(mm_stream_t *my_obj,
    792                          mm_camera_stream_config_t *config)
    793 {
    794     int32_t rc = 0;
    795     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    796          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    797     my_obj->stream_info = config->stream_info;
    798     my_obj->buf_num = config->stream_info->num_bufs;
    799     my_obj->mem_vtbl = config->mem_vtbl;
    800     my_obj->padding_info = config->padding_info;
    801     /* cd through intf always palced at idx 0 of buf_cb */
    802     my_obj->buf_cb[0].cb = config->stream_cb;
    803     my_obj->buf_cb[0].user_data = config->userdata;
    804     my_obj->buf_cb[0].cb_count = -1; /* infinite by default */
    805 
    806     rc = mm_stream_sync_info(my_obj);
    807     if (rc == 0) {
    808         rc = mm_stream_set_fmt(my_obj);
    809     }
    810     return rc;
    811 }
    812 
    813 /*===========================================================================
    814  * FUNCTION   : mm_stream_release
    815  *
    816  * DESCRIPTION: release a stream resource
    817  *
    818  * PARAMETERS :
    819  *   @my_obj       : stream object
    820  *
    821  * RETURN     : int32_t type of status
    822  *              0  -- success
    823  *              -1 -- failure
    824  *==========================================================================*/
    825 int32_t mm_stream_release(mm_stream_t *my_obj)
    826 {
    827     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    828          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    829 
    830     /* close fd */
    831     if(my_obj->fd >= 0)
    832     {
    833         close(my_obj->fd);
    834     }
    835 
    836     /* destroy mutex */
    837     pthread_mutex_destroy(&my_obj->buf_lock);
    838     pthread_mutex_destroy(&my_obj->cb_lock);
    839 
    840     /* reset stream obj */
    841     memset(my_obj, 0, sizeof(mm_stream_t));
    842     my_obj->fd = -1;
    843 
    844     return 0;
    845 }
    846 
    847 /*===========================================================================
    848  * FUNCTION   : mm_stream_streamon
    849  *
    850  * DESCRIPTION: stream on a stream. sending v4l2 request to kernel
    851  *
    852  * PARAMETERS :
    853  *   @my_obj       : stream object
    854  *
    855  * RETURN     : int32_t type of status
    856  *              0  -- success
    857  *              -1 -- failure
    858  *==========================================================================*/
    859 int32_t mm_stream_streamon(mm_stream_t *my_obj)
    860 {
    861     int32_t rc;
    862     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    863 
    864     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    865          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    866 
    867     rc = ioctl(my_obj->fd, VIDIOC_STREAMON, &buf_type);
    868     if (rc < 0) {
    869         CDBG_ERROR("%s: ioctl VIDIOC_STREAMON failed: rc=%d\n",
    870                    __func__, rc);
    871         /* remove fd from data poll thread in case of failure */
    872         mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl, mm_camera_sync_call);
    873     }
    874     CDBG("%s :X rc = %d",__func__,rc);
    875     return rc;
    876 }
    877 
    878 /*===========================================================================
    879  * FUNCTION   : mm_stream_streamoff
    880  *
    881  * DESCRIPTION: stream off a stream. sending v4l2 request to kernel
    882  *
    883  * PARAMETERS :
    884  *   @my_obj       : stream object
    885  *
    886  * RETURN     : int32_t type of status
    887  *              0  -- success
    888  *              -1 -- failure
    889  *==========================================================================*/
    890 int32_t mm_stream_streamoff(mm_stream_t *my_obj)
    891 {
    892     int32_t rc;
    893     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    894     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    895          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    896 
    897     /* step1: remove fd from data poll thread */
    898     rc = mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
    899             my_obj->my_hdl, mm_camera_sync_call);
    900     if (rc < 0) {
    901         /* The error might be due to async update. In this case
    902          * wait for all updates to complete before proceeding. */
    903         rc = mm_camera_poll_thread_commit_updates(&my_obj->ch_obj->poll_thread[0]);
    904         if (rc < 0) {
    905             CDBG_ERROR("%s: Poll sync failed %d",
    906                  __func__, rc);
    907         }
    908     }
    909 
    910     /* step2: stream off */
    911     rc = ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type);
    912     if (rc < 0) {
    913         CDBG_ERROR("%s: STREAMOFF failed: %s\n",
    914                 __func__, strerror(errno));
    915     }
    916     CDBG("%s :X rc = %d",__func__,rc);
    917     return rc;
    918 }
    919 
    920 /*===========================================================================
    921  * FUNCTION   : mm_stream_read_msm_frame
    922  *
    923  * DESCRIPTION: dequeue a stream buffer from kernel queue
    924  *
    925  * PARAMETERS :
    926  *   @my_obj       : stream object
    927  *   @buf_info     : ptr to a struct storing buffer information
    928  *   @num_planes   : number of planes in the buffer
    929  *
    930  * RETURN     : int32_t type of status
    931  *              0  -- success
    932  *              -1 -- failure
    933  *==========================================================================*/
    934 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
    935                                  mm_camera_buf_info_t* buf_info,
    936                                  uint8_t num_planes)
    937 {
    938     int32_t rc = 0;
    939     struct v4l2_buffer vb;
    940     struct v4l2_plane planes[VIDEO_MAX_PLANES];
    941     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
    942          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
    943 
    944     memset(&vb,  0,  sizeof(vb));
    945     vb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    946     vb.memory = V4L2_MEMORY_USERPTR;
    947     vb.m.planes = &planes[0];
    948     vb.length = num_planes;
    949 
    950     rc = ioctl(my_obj->fd, VIDIOC_DQBUF, &vb);
    951     if (0 > rc) {
    952         CDBG_ERROR("%s: VIDIOC_DQBUF ioctl call failed on stream type %d (rc=%d): %s",
    953             __func__, my_obj->stream_info->stream_type, rc, strerror(errno));
    954     } else {
    955         pthread_mutex_lock(&my_obj->buf_lock);
    956         my_obj->queued_buffer_count--;
    957         if (0 == my_obj->queued_buffer_count) {
    958             CDBG_HIGH("%s: Stoping poll on stream %p type: %d", __func__,
    959                 my_obj, my_obj->stream_info->stream_type);
    960             mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
    961                 my_obj->my_hdl, mm_camera_async_call);
    962             CDBG_HIGH("%s: Stopped poll on stream %p type: %d", __func__,
    963                 my_obj, my_obj->stream_info->stream_type);
    964         }
    965         pthread_mutex_unlock(&my_obj->buf_lock);
    966         int8_t idx = vb.index;
    967         buf_info->buf = &my_obj->buf[idx];
    968         buf_info->frame_idx = vb.sequence;
    969         buf_info->stream_id = my_obj->my_hdl;
    970 
    971         buf_info->buf->stream_id = my_obj->my_hdl;
    972         buf_info->buf->buf_idx = idx;
    973         buf_info->buf->frame_idx = vb.sequence;
    974         buf_info->buf->ts.tv_sec  = vb.timestamp.tv_sec;
    975         buf_info->buf->ts.tv_nsec = vb.timestamp.tv_usec * 1000;
    976         CDBG("%s: VIDIOC_DQBUF buf_index %d, frame_idx %d, stream type %d, rc %d",
    977             __func__, vb.index, buf_info->buf->frame_idx,
    978             my_obj->stream_info->stream_type, rc);
    979 
    980         buf_info->buf->is_uv_subsampled =
    981             (vb.reserved == V4L2_PIX_FMT_NV14 || vb.reserved == V4L2_PIX_FMT_NV41);
    982 
    983         if ( NULL != my_obj->mem_vtbl.clean_invalidate_buf ) {
    984             rc = my_obj->mem_vtbl.clean_invalidate_buf(idx,
    985                 my_obj->mem_vtbl.user_data);
    986             if (0 > rc) {
    987                 CDBG_ERROR("%s: Clean invalidate cache failed on buffer index: %d",
    988                     __func__, idx);
    989             }
    990         } else {
    991             CDBG_ERROR("%s: Clean invalidate cache op not supported", __func__);
    992         }
    993     }
    994 
    995     CDBG("%s :X rc = %d",__func__,rc);
    996     return rc;
    997 }
    998 
    999 /*===========================================================================
   1000  * FUNCTION   : mm_stream_set_parms
   1001  *
   1002  * DESCRIPTION: set parameters per stream
   1003  *
   1004  * PARAMETERS :
   1005  *   @my_obj       : stream object
   1006  *   @in_value     : ptr to a param struct to be set to server
   1007  *
   1008  * RETURN     : int32_t type of status
   1009  *              0  -- success
   1010  *              -1 -- failure
   1011  * NOTE       : Assume the parms struct buf is already mapped to server via
   1012  *              domain socket. Corresponding fields of parameters to be set
   1013  *              are already filled in by upper layer caller.
   1014  *==========================================================================*/
   1015 int32_t mm_stream_set_parm(mm_stream_t *my_obj,
   1016                            cam_stream_parm_buffer_t *in_value)
   1017 {
   1018     int32_t rc = -1;
   1019     int32_t value = 0;
   1020     if (in_value != NULL) {
   1021         rc = mm_camera_util_s_ctrl(my_obj->fd, CAM_PRIV_STREAM_PARM, &value);
   1022     }
   1023     return rc;
   1024 }
   1025 
   1026 /*===========================================================================
   1027  * FUNCTION   : mm_stream_get_parms
   1028  *
   1029  * DESCRIPTION: get parameters per stream
   1030  *
   1031  * PARAMETERS :
   1032  *   @my_obj       : stream object
   1033  *   @in_value     : ptr to a param struct to be get from server
   1034  *
   1035  * RETURN     : int32_t type of status
   1036  *              0  -- success
   1037  *              -1 -- failure
   1038  * NOTE       : Assume the parms struct buf is already mapped to server via
   1039  *              domain socket. Corresponding fields of parameters to be get
   1040  *              are already filled in by upper layer caller.
   1041  *==========================================================================*/
   1042 int32_t mm_stream_get_parm(mm_stream_t *my_obj,
   1043                            cam_stream_parm_buffer_t *in_value)
   1044 {
   1045     int32_t rc = -1;
   1046     int32_t value = 0;
   1047     if (in_value != NULL) {
   1048         rc = mm_camera_util_g_ctrl(my_obj->fd, CAM_PRIV_STREAM_PARM, &value);
   1049     }
   1050     return rc;
   1051 }
   1052 
   1053 /*===========================================================================
   1054  * FUNCTION   : mm_stream_do_actions
   1055  *
   1056  * DESCRIPTION: request server to perform stream based actions
   1057  *
   1058  * PARAMETERS :
   1059  *   @my_obj       : stream object
   1060  *   @in_value     : ptr to a struct of actions to be performed by the server
   1061  *
   1062  * RETURN     : int32_t type of status
   1063  *              0  -- success
   1064  *              -1 -- failure
   1065  * NOTE       : Assume the action struct buf is already mapped to server via
   1066  *              domain socket. Corresponding fields of actions to be performed
   1067  *              are already filled in by upper layer caller.
   1068  *==========================================================================*/
   1069 int32_t mm_stream_do_action(mm_stream_t *my_obj,
   1070                             void *in_value)
   1071 {
   1072     int32_t rc = -1;
   1073     int32_t value = 0;
   1074     if (in_value != NULL) {
   1075         rc = mm_camera_util_s_ctrl(my_obj->fd, CAM_PRIV_STREAM_PARM, &value);
   1076     }
   1077     return rc;
   1078 }
   1079 
   1080 /*===========================================================================
   1081  * FUNCTION   : mm_stream_set_ext_mode
   1082  *
   1083  * DESCRIPTION: set stream extended mode to server via v4l2 ioctl
   1084  *
   1085  * PARAMETERS :
   1086  *   @my_obj       : stream object
   1087  *
   1088  * RETURN     : int32_t type of status
   1089  *              0  -- success
   1090  *              -1 -- failure
   1091  * NOTE       : Server will return a server stream id that uniquely identify
   1092  *              this stream on server side. Later on communication to server
   1093  *              per stream should use this server stream id.
   1094  *==========================================================================*/
   1095 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj)
   1096 {
   1097     int32_t rc = 0;
   1098     struct v4l2_streamparm s_parm;
   1099     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1100          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1101 
   1102     memset(&s_parm, 0, sizeof(s_parm));
   1103     s_parm.type =  V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1104 
   1105     rc = ioctl(my_obj->fd, VIDIOC_S_PARM, &s_parm);
   1106     CDBG("%s:stream fd=%d, rc=%d, extended_mode=%d\n",
   1107          __func__, my_obj->fd, rc, s_parm.parm.capture.extendedmode);
   1108     if (rc == 0) {
   1109         /* get server stream id */
   1110         my_obj->server_stream_id = s_parm.parm.capture.extendedmode;
   1111     }
   1112     return rc;
   1113 }
   1114 
   1115 /*===========================================================================
   1116  * FUNCTION   : mm_stream_qbuf
   1117  *
   1118  * DESCRIPTION: enqueue buffer back to kernel queue for furture use
   1119  *
   1120  * PARAMETERS :
   1121  *   @my_obj       : stream object
   1122  *   @buf          : ptr to a struct storing buffer information
   1123  *
   1124  * RETURN     : int32_t type of status
   1125  *              0  -- success
   1126  *              -1 -- failure
   1127  *==========================================================================*/
   1128 int32_t mm_stream_qbuf(mm_stream_t *my_obj, mm_camera_buf_def_t *buf)
   1129 {
   1130     int32_t rc = 0;
   1131     struct v4l2_buffer buffer;
   1132     struct v4l2_plane planes[VIDEO_MAX_PLANES];
   1133     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d, stream type = %d",
   1134          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state,
   1135          my_obj->stream_info->stream_type);
   1136 
   1137     memcpy(planes, buf->planes, sizeof(planes));
   1138     memset(&buffer, 0, sizeof(buffer));
   1139     buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1140     buffer.memory = V4L2_MEMORY_USERPTR;
   1141     buffer.index = buf->buf_idx;
   1142     buffer.m.planes = &planes[0];
   1143     buffer.length = buf->num_planes;
   1144 
   1145     CDBG("%s:plane 0: stream_hdl=%d,fd=%d,frame idx=%d,num_planes = %d, offset = %d, data_offset = %d\n", __func__,
   1146          buf->stream_id, buf->fd, buffer.index, buffer.length, buf->planes[0].reserved[0], buf->planes[0].data_offset);
   1147     CDBG("%s:plane 1: stream_hdl=%d,fd=%d,frame idx=%d,num_planes = %d, offset = %d, data_offset = %d\n", __func__,
   1148          buf->stream_id, buf->fd, buffer.index, buffer.length, buf->planes[1].reserved[0], buf->planes[1].data_offset);
   1149 
   1150     if ( NULL != my_obj->mem_vtbl.invalidate_buf ) {
   1151         rc = my_obj->mem_vtbl.invalidate_buf(buffer.index,
   1152                                              my_obj->mem_vtbl.user_data);
   1153         if ( 0 > rc ) {
   1154             CDBG_ERROR("%s: Cache invalidate failed on buffer index: %d",
   1155                        __func__,
   1156                        buffer.index);
   1157             return rc;
   1158         }
   1159     } else {
   1160         CDBG_ERROR("%s: Cache invalidate op not added", __func__);
   1161     }
   1162 
   1163     my_obj->queued_buffer_count++;
   1164     if (1 == my_obj->queued_buffer_count) {
   1165         /* Add fd to data poll thread */
   1166         CDBG_HIGH("%s: Starting poll on stream %p type: %d", __func__,
   1167             my_obj,my_obj->stream_info->stream_type);
   1168         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1169             my_obj->my_hdl, my_obj->fd, mm_stream_data_notify, (void*)my_obj,
   1170             mm_camera_async_call);
   1171         if (0 > rc) {
   1172             CDBG_ERROR("%s: Add poll on stream %p type: %d fd error (rc=%d)",
   1173                 __func__, my_obj, my_obj->stream_info->stream_type, rc);
   1174         } else {
   1175             CDBG_HIGH("%s: Started poll on stream %p type: %d", __func__,
   1176                 my_obj, my_obj->stream_info->stream_type);
   1177         }
   1178     }
   1179 
   1180     rc = ioctl(my_obj->fd, VIDIOC_QBUF, &buffer);
   1181     if (0 > rc) {
   1182         CDBG_ERROR("%s: VIDIOC_QBUF ioctl call failed on stream type %d (rc=%d): %s",
   1183             __func__, my_obj->stream_info->stream_type, rc, strerror(errno));
   1184         my_obj->queued_buffer_count--;
   1185         if (0 == my_obj->queued_buffer_count) {
   1186             /* Remove fd from data poll in case of failing
   1187              * first buffer queuing attempt */
   1188             CDBG_HIGH("%s: Stoping poll on stream %p type: %d", __func__,
   1189                 my_obj, my_obj->stream_info->stream_type);
   1190             mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
   1191                 my_obj->my_hdl, mm_camera_async_call);
   1192             CDBG_HIGH("%s: Stopped poll on stream %p type: %d", __func__,
   1193                 my_obj, my_obj->stream_info->stream_type);
   1194         }
   1195     } else {
   1196         CDBG("%s: VIDIOC_QBUF buf_index %d, stream type %d, rc %d", __func__,
   1197             buffer.index, my_obj->stream_info->stream_type, rc);
   1198     }
   1199 
   1200     return rc;
   1201 }
   1202 
   1203 /*===========================================================================
   1204  * FUNCTION   : mm_stream_request_buf
   1205  *
   1206  * DESCRIPTION: This function let kernel know the amount of buffers need to
   1207  *              be registered via v4l2 ioctl.
   1208  *
   1209  * PARAMETERS :
   1210  *   @my_obj       : stream object
   1211  *
   1212  * RETURN     : int32_t type of status
   1213  *              0  -- success
   1214  *              -1 -- failure
   1215  *==========================================================================*/
   1216 int32_t mm_stream_request_buf(mm_stream_t * my_obj)
   1217 {
   1218     int32_t rc = 0;
   1219     struct v4l2_requestbuffers bufreq;
   1220     uint8_t buf_num = my_obj->buf_num;
   1221     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1222          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1223 
   1224     CDBG_ERROR("%s: buf_num = %d, stream type = %d",
   1225          __func__, buf_num, my_obj->stream_info->stream_type);
   1226 
   1227     if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) {
   1228         CDBG_ERROR("%s: buf num %d > max limit %d\n",
   1229                    __func__, buf_num, MM_CAMERA_MAX_NUM_FRAMES);
   1230         return -1;
   1231     }
   1232 
   1233     memset(&bufreq, 0, sizeof(bufreq));
   1234     bufreq.count = buf_num;
   1235     bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1236     bufreq.memory = V4L2_MEMORY_USERPTR;
   1237     rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
   1238     if (rc < 0) {
   1239       CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n",
   1240            __func__, my_obj->fd, rc);
   1241     }
   1242 
   1243     CDBG("%s :X rc = %d",__func__,rc);
   1244     return rc;
   1245 }
   1246 
   1247 /*===========================================================================
   1248  * FUNCTION   : mm_stream_map_buf
   1249  *
   1250  * DESCRIPTION: mapping stream buffer via domain socket to server
   1251  *
   1252  * PARAMETERS :
   1253  *   @my_obj       : stream object
   1254  *   @buf_type     : type of buffer to be mapped. could be following values:
   1255  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1256  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1257  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1258  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1259  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1260  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1261  *   @plane_idx    : plane index. If all planes share the same fd,
   1262  *                   plane_idx = -1; otherwise, plean_idx is the
   1263  *                   index to plane (0..num_of_planes)
   1264  *   @fd           : file descriptor of the buffer
   1265  *   @size         : size of the buffer
   1266  *
   1267  * RETURN     : int32_t type of status
   1268  *              0  -- success
   1269  *              -1 -- failure
   1270  *==========================================================================*/
   1271 int32_t mm_stream_map_buf(mm_stream_t * my_obj,
   1272                           uint8_t buf_type,
   1273                           uint32_t frame_idx,
   1274                           int32_t plane_idx,
   1275                           int fd,
   1276                           uint32_t size)
   1277 {
   1278     if (NULL == my_obj || NULL == my_obj->ch_obj || NULL == my_obj->ch_obj->cam_obj) {
   1279         CDBG_ERROR("%s: NULL obj of stream/channel/camera", __func__);
   1280         return -1;
   1281     }
   1282 
   1283     cam_sock_packet_t packet;
   1284     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1285     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
   1286     packet.payload.buf_map.type = buf_type;
   1287     packet.payload.buf_map.fd = fd;
   1288     packet.payload.buf_map.size = size;
   1289     packet.payload.buf_map.stream_id = my_obj->server_stream_id;
   1290     packet.payload.buf_map.frame_idx = frame_idx;
   1291     packet.payload.buf_map.plane_idx = plane_idx;
   1292     return mm_camera_util_sendmsg(my_obj->ch_obj->cam_obj,
   1293                                   &packet,
   1294                                   sizeof(cam_sock_packet_t),
   1295                                   fd);
   1296 }
   1297 
   1298 /*===========================================================================
   1299  * FUNCTION   : mm_stream_unmap_buf
   1300  *
   1301  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1302  *
   1303  * PARAMETERS :
   1304  *   @my_obj       : stream object
   1305  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1306  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1307  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1308  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1309  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1310  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1311  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1312  *   @plane_idx    : plane index. If all planes share the same fd,
   1313  *                   plane_idx = -1; otherwise, plean_idx is the
   1314  *                   index to plane (0..num_of_planes)
   1315  *
   1316  * RETURN     : int32_t type of status
   1317  *              0  -- success
   1318  *              -1 -- failure
   1319  *==========================================================================*/
   1320 int32_t mm_stream_unmap_buf(mm_stream_t * my_obj,
   1321                             uint8_t buf_type,
   1322                             uint32_t frame_idx,
   1323                             int32_t plane_idx)
   1324 {
   1325     if (NULL == my_obj || NULL == my_obj->ch_obj || NULL == my_obj->ch_obj->cam_obj) {
   1326         CDBG_ERROR("%s: NULL obj of stream/channel/camera", __func__);
   1327         return -1;
   1328     }
   1329 
   1330     cam_sock_packet_t packet;
   1331     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1332     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
   1333     packet.payload.buf_unmap.type = buf_type;
   1334     packet.payload.buf_unmap.stream_id = my_obj->server_stream_id;
   1335     packet.payload.buf_unmap.frame_idx = frame_idx;
   1336     packet.payload.buf_unmap.plane_idx = plane_idx;
   1337     return mm_camera_util_sendmsg(my_obj->ch_obj->cam_obj,
   1338                                   &packet,
   1339                                   sizeof(cam_sock_packet_t),
   1340                                   0);
   1341 }
   1342 
   1343 /*===========================================================================
   1344  * FUNCTION   : mm_stream_map_buf_ops
   1345  *
   1346  * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
   1347  *              This function will be passed to upper layer as part of ops table
   1348  *              to be used by upper layer when allocating stream buffers and mapping
   1349  *              buffers to server via domain socket.
   1350  *
   1351  * PARAMETERS :
   1352  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1353  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1354  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1355  *   @plane_idx    : plane index. If all planes share the same fd,
   1356  *                   plane_idx = -1; otherwise, plean_idx is the
   1357  *                   index to plane (0..num_of_planes)
   1358  *   @fd           : file descriptor of the buffer
   1359  *   @size         : size of the buffer
   1360  *   @userdata     : user data ptr (stream object)
   1361  *
   1362  * RETURN     : int32_t type of status
   1363  *              0  -- success
   1364  *              -1 -- failure
   1365  *==========================================================================*/
   1366 static int32_t mm_stream_map_buf_ops(uint32_t frame_idx,
   1367                                      int32_t plane_idx,
   1368                                      int fd,
   1369                                      uint32_t size,
   1370                                      void *userdata)
   1371 {
   1372     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   1373     return mm_stream_map_buf(my_obj,
   1374                              CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   1375                              frame_idx, plane_idx, fd, size);
   1376 }
   1377 
   1378 /*===========================================================================
   1379  * FUNCTION   : mm_stream_unmap_buf_ops
   1380  *
   1381  * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
   1382  *              This function will be passed to upper layer as part of ops table
   1383  *              to be used by upper layer when allocating stream buffers and unmapping
   1384  *              buffers to server via domain socket.
   1385  *
   1386  * PARAMETERS :
   1387  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   1388  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1389  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1390  *   @plane_idx    : plane index. If all planes share the same fd,
   1391  *                   plane_idx = -1; otherwise, plean_idx is the
   1392  *                   index to plane (0..num_of_planes)
   1393  *   @userdata     : user data ptr (stream object)
   1394  *
   1395  * RETURN     : int32_t type of status
   1396  *              0  -- success
   1397  *              -1 -- failure
   1398  *==========================================================================*/
   1399 static int32_t mm_stream_unmap_buf_ops(uint32_t frame_idx,
   1400                                        int32_t plane_idx,
   1401                                        void *userdata)
   1402 {
   1403     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   1404     return mm_stream_unmap_buf(my_obj,
   1405                                CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   1406                                frame_idx,
   1407                                plane_idx);
   1408 }
   1409 
   1410 /*===========================================================================
   1411  * FUNCTION   : mm_stream_init_bufs
   1412  *
   1413  * DESCRIPTION: initialize stream buffers needed. This function will request
   1414  *              buffers needed from upper layer through the mem ops table passed
   1415  *              during configuration stage.
   1416  *
   1417  * PARAMETERS :
   1418  *   @my_obj  : stream object
   1419  *
   1420  * RETURN     : int32_t type of status
   1421  *              0  -- success
   1422  *              -1 -- failure
   1423  *==========================================================================*/
   1424 int32_t mm_stream_init_bufs(mm_stream_t * my_obj)
   1425 {
   1426     int32_t i, rc = 0;
   1427     uint8_t *reg_flags = NULL;
   1428     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1429          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1430 
   1431     /* deinit buf if it's not NULL*/
   1432     if (NULL != my_obj->buf) {
   1433         mm_stream_deinit_bufs(my_obj);
   1434     }
   1435 
   1436     my_obj->map_ops.map_ops = mm_stream_map_buf_ops;
   1437     my_obj->map_ops.unmap_ops = mm_stream_unmap_buf_ops;
   1438     my_obj->map_ops.userdata = my_obj;
   1439 
   1440     rc = my_obj->mem_vtbl.get_bufs(&my_obj->frame_offset,
   1441                                    &my_obj->buf_num,
   1442                                    &reg_flags,
   1443                                    &my_obj->buf,
   1444                                    &my_obj->map_ops,
   1445                                    my_obj->mem_vtbl.user_data);
   1446 
   1447     if (0 != rc) {
   1448         CDBG_ERROR("%s: Error get buf, rc = %d\n", __func__, rc);
   1449         return rc;
   1450     }
   1451 
   1452     my_obj->buf_status =
   1453         (mm_stream_buf_status_t *)malloc(sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
   1454 
   1455     if (NULL == my_obj->buf_status) {
   1456         CDBG_ERROR("%s: No memory for buf_status", __func__);
   1457         mm_stream_deinit_bufs(my_obj);
   1458         free(reg_flags);
   1459         return -1;
   1460     }
   1461 
   1462     memset(my_obj->buf_status, 0, sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
   1463     for (i = 0; i < my_obj->buf_num; i++) {
   1464         my_obj->buf_status[i].initial_reg_flag = reg_flags[i];
   1465         my_obj->buf[i].stream_id = my_obj->my_hdl;
   1466         my_obj->buf[i].stream_type = my_obj->stream_info->stream_type;
   1467     }
   1468 
   1469     free(reg_flags);
   1470     reg_flags = NULL;
   1471 
   1472     /* update in stream info about number of stream buffers */
   1473     my_obj->stream_info->num_bufs = my_obj->buf_num;
   1474 
   1475     return rc;
   1476 }
   1477 
   1478 /*===========================================================================
   1479  * FUNCTION   : mm_stream_deinit_bufs
   1480  *
   1481  * DESCRIPTION: return stream buffers to upper layer through the mem ops table
   1482  *              passed during configuration stage.
   1483  *
   1484  * PARAMETERS :
   1485  *   @my_obj  : stream object
   1486  *
   1487  * RETURN     : int32_t type of status
   1488  *              0  -- success
   1489  *              -1 -- failure
   1490  *==========================================================================*/
   1491 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj)
   1492 {
   1493     int32_t rc = 0;
   1494     mm_camera_map_unmap_ops_tbl_t ops_tbl;
   1495     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1496          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1497 
   1498     if (NULL == my_obj->buf) {
   1499         CDBG("%s: Buf is NULL, no need to deinit", __func__);
   1500         return rc;
   1501     }
   1502 
   1503     /* release bufs */
   1504     ops_tbl.map_ops = mm_stream_map_buf_ops;
   1505     ops_tbl.unmap_ops = mm_stream_unmap_buf_ops;
   1506     ops_tbl.userdata = my_obj;
   1507 
   1508     rc = my_obj->mem_vtbl.put_bufs(&ops_tbl,
   1509                                    my_obj->mem_vtbl.user_data);
   1510 
   1511     free(my_obj->buf);
   1512     my_obj->buf = NULL;
   1513     if (my_obj->buf_status != NULL) {
   1514         free(my_obj->buf_status);
   1515         my_obj->buf_status = NULL;
   1516     }
   1517 
   1518     return rc;
   1519 }
   1520 
   1521 /*===========================================================================
   1522  * FUNCTION   : mm_stream_reg_buf
   1523  *
   1524  * DESCRIPTION: register buffers with kernel by calling v4l2 ioctl QBUF for
   1525  *              each buffer in the stream
   1526  *
   1527  * PARAMETERS :
   1528  *   @my_obj  : stream object
   1529  *
   1530  * RETURN     : int32_t type of status
   1531  *              0  -- success
   1532  *              -1 -- failure
   1533  *==========================================================================*/
   1534 int32_t mm_stream_reg_buf(mm_stream_t * my_obj)
   1535 {
   1536     int32_t rc = 0;
   1537     uint8_t i;
   1538     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1539          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1540 
   1541     rc = mm_stream_request_buf(my_obj);
   1542     if (rc != 0) {
   1543         return rc;
   1544     }
   1545 
   1546     pthread_mutex_lock(&my_obj->buf_lock);
   1547     my_obj->queued_buffer_count = 0;
   1548     for(i = 0; i < my_obj->buf_num; i++){
   1549         /* check if need to qbuf initially */
   1550         if (my_obj->buf_status[i].initial_reg_flag) {
   1551             rc = mm_stream_qbuf(my_obj, &my_obj->buf[i]);
   1552             if (rc != 0) {
   1553                 CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc);
   1554                 break;
   1555             }
   1556             my_obj->buf_status[i].buf_refcnt = 0;
   1557             my_obj->buf_status[i].in_kernel = 1;
   1558         } else {
   1559             /* the buf is held by upper layer, will not queue into kernel.
   1560              * add buf reference count */
   1561             my_obj->buf_status[i].buf_refcnt = 1;
   1562             my_obj->buf_status[i].in_kernel = 0;
   1563         }
   1564     }
   1565     pthread_mutex_unlock(&my_obj->buf_lock);
   1566 
   1567     return rc;
   1568 }
   1569 
   1570 /*===========================================================================
   1571  * FUNCTION   : mm_stream_unreg buf
   1572  *
   1573  * DESCRIPTION: unregister all stream buffers from kernel
   1574  *
   1575  * PARAMETERS :
   1576  *   @my_obj  : stream object
   1577  *
   1578  * RETURN     : int32_t type of status
   1579  *              0  -- success
   1580  *              -1 -- failure
   1581  *==========================================================================*/
   1582 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj)
   1583 {
   1584     struct v4l2_requestbuffers bufreq;
   1585     int32_t i, rc = 0;
   1586     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   1587          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   1588 
   1589     /* unreg buf to kernel */
   1590     bufreq.count = 0;
   1591     bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1592     bufreq.memory = V4L2_MEMORY_USERPTR;
   1593     rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
   1594     if (rc < 0) {
   1595         CDBG_ERROR("%s: fd=%d, VIDIOC_REQBUFS failed, rc=%d\n",
   1596               __func__, my_obj->fd, rc);
   1597     }
   1598 
   1599     /* reset buf reference count */
   1600     pthread_mutex_lock(&my_obj->buf_lock);
   1601     if (NULL != my_obj->buf_status) {
   1602         for(i = 0; i < my_obj->buf_num; i++){
   1603             my_obj->buf_status[i].buf_refcnt = 0;
   1604             my_obj->buf_status[i].in_kernel = 0;
   1605         }
   1606     }
   1607     pthread_mutex_unlock(&my_obj->buf_lock);
   1608 
   1609     return rc;
   1610 }
   1611 
   1612 /*===========================================================================
   1613  * FUNCTION   : mm_stream_get_v4l2_fmt
   1614  *
   1615  * DESCRIPTION: translate camera image format into FOURCC code
   1616  *
   1617  * PARAMETERS :
   1618  *   @fmt     : camera image format
   1619  *
   1620  * RETURN     : FOURCC code for image format
   1621  *==========================================================================*/
   1622 uint32_t mm_stream_get_v4l2_fmt(cam_format_t fmt)
   1623 {
   1624     uint32_t val;
   1625     switch(fmt) {
   1626     case CAM_FORMAT_YUV_420_NV12:
   1627     case CAM_FORMAT_YUV_420_NV12_VENUS:
   1628         val = V4L2_PIX_FMT_NV12;
   1629         break;
   1630     case CAM_FORMAT_YUV_420_NV21:
   1631         val = V4L2_PIX_FMT_NV21;
   1632         break;
   1633     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG:
   1634     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GRBG:
   1635     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_RGGB:
   1636     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_BGGR:
   1637         val= V4L2_PIX_FMT_SBGGR10;
   1638         break;
   1639     case CAM_FORMAT_YUV_422_NV61:
   1640         val= V4L2_PIX_FMT_NV61;
   1641         break;
   1642     case CAM_FORMAT_YUV_RAW_8BIT_YUYV:
   1643         val= V4L2_PIX_FMT_YUYV;
   1644         break;
   1645     case CAM_FORMAT_YUV_RAW_8BIT_YVYU:
   1646         val= V4L2_PIX_FMT_YVYU;
   1647         break;
   1648     case CAM_FORMAT_YUV_RAW_8BIT_UYVY:
   1649         val= V4L2_PIX_FMT_UYVY;
   1650         break;
   1651     case CAM_FORMAT_YUV_RAW_8BIT_VYUY:
   1652         val= V4L2_PIX_FMT_VYUY;
   1653         break;
   1654     case CAM_FORMAT_YUV_420_YV12:
   1655         val= V4L2_PIX_FMT_NV12;
   1656         break;
   1657     case CAM_FORMAT_YUV_422_NV16:
   1658         val= V4L2_PIX_FMT_NV16;
   1659         break;
   1660     default:
   1661         val = 0;
   1662         CDBG_ERROR("%s: Unknown fmt=%d", __func__, fmt);
   1663         break;
   1664     }
   1665     CDBG("%s: fmt=%d, val =%d", __func__, fmt, val);
   1666     return val;
   1667 }
   1668 
   1669 /*===========================================================================
   1670  * FUNCTION   : mm_stream_calc_offset_preview
   1671  *
   1672  * DESCRIPTION: calculate preview frame offset based on format and
   1673  *              padding information
   1674  *
   1675  * PARAMETERS :
   1676  *   @fmt     : image format
   1677  *   @dim     : image dimension
   1678  *   @buf_planes : [out] buffer plane information
   1679  *
   1680  * RETURN     : int32_t type of status
   1681  *              0  -- success
   1682  *              -1 -- failure
   1683  *==========================================================================*/
   1684 int32_t mm_stream_calc_offset_preview(cam_format_t fmt,
   1685                                       cam_dimension_t *dim,
   1686                                       cam_stream_buf_plane_info_t *buf_planes)
   1687 {
   1688     int32_t rc = 0;
   1689     int stride = 0, scanline = 0;
   1690 
   1691     switch (fmt) {
   1692     case CAM_FORMAT_YUV_420_NV12:
   1693     case CAM_FORMAT_YUV_420_NV21:
   1694         /* 2 planes: Y + CbCr */
   1695         buf_planes->plane_info.num_planes = 2;
   1696 
   1697         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   1698         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_2);
   1699 
   1700         buf_planes->plane_info.mp[0].offset = 0;
   1701         buf_planes->plane_info.mp[0].len = stride * scanline;
   1702         buf_planes->plane_info.mp[0].offset_x = 0;
   1703         buf_planes->plane_info.mp[0].offset_y = 0;
   1704         buf_planes->plane_info.mp[0].stride = stride;
   1705         buf_planes->plane_info.mp[0].scanline = scanline;
   1706         buf_planes->plane_info.mp[0].width = dim->width;
   1707         buf_planes->plane_info.mp[0].height = dim->height;
   1708 
   1709         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   1710         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_2);
   1711         buf_planes->plane_info.mp[1].offset = 0;
   1712         buf_planes->plane_info.mp[1].len =
   1713             stride * scanline;
   1714         buf_planes->plane_info.mp[1].offset_x = 0;
   1715         buf_planes->plane_info.mp[1].offset_y = 0;
   1716         buf_planes->plane_info.mp[1].stride = stride;
   1717         buf_planes->plane_info.mp[1].scanline = scanline;
   1718         buf_planes->plane_info.mp[1].width = dim->width;
   1719         buf_planes->plane_info.mp[1].height = dim->height / 2;
   1720 
   1721         buf_planes->plane_info.frame_len =
   1722             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   1723                         buf_planes->plane_info.mp[1].len,
   1724                         CAM_PAD_TO_4K);
   1725         break;
   1726     case CAM_FORMAT_YUV_420_NV21_ADRENO:
   1727         /* 2 planes: Y + CbCr */
   1728         buf_planes->plane_info.num_planes = 2;
   1729 
   1730         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   1731         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_32);
   1732         buf_planes->plane_info.mp[0].offset = 0;
   1733         buf_planes->plane_info.mp[0].len =
   1734             PAD_TO_SIZE(stride * scanline,
   1735                         CAM_PAD_TO_4K);
   1736         buf_planes->plane_info.mp[0].offset_x = 0;
   1737         buf_planes->plane_info.mp[0].offset_y = 0;
   1738         buf_planes->plane_info.mp[0].stride = stride;
   1739         buf_planes->plane_info.mp[0].scanline = scanline;
   1740         buf_planes->plane_info.mp[0].width = dim->width;
   1741         buf_planes->plane_info.mp[0].height = dim->height;
   1742 
   1743         stride = PAD_TO_SIZE(dim->width / 2, CAM_PAD_TO_32) * 2;
   1744         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_32);
   1745         buf_planes->plane_info.mp[1].offset = 0;
   1746         buf_planes->plane_info.mp[1].len =
   1747             PAD_TO_SIZE(stride * scanline,
   1748                         CAM_PAD_TO_4K);
   1749         buf_planes->plane_info.mp[1].offset_x = 0;
   1750         buf_planes->plane_info.mp[1].offset_y = 0;
   1751         buf_planes->plane_info.mp[1].stride = stride;
   1752         buf_planes->plane_info.mp[1].scanline = scanline;
   1753         buf_planes->plane_info.mp[1].width = dim->width;
   1754         buf_planes->plane_info.mp[1].height = dim->height / 2;
   1755 
   1756         buf_planes->plane_info.frame_len =
   1757             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   1758                         buf_planes->plane_info.mp[1].len,
   1759                         CAM_PAD_TO_4K);
   1760         break;
   1761     case CAM_FORMAT_YUV_420_YV12:
   1762         /* 3 planes: Y + Cr + Cb */
   1763         buf_planes->plane_info.num_planes = 3;
   1764 
   1765         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   1766         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_2);
   1767         buf_planes->plane_info.mp[0].offset = 0;
   1768         buf_planes->plane_info.mp[0].len = stride * scanline;
   1769         buf_planes->plane_info.mp[0].offset_x = 0;
   1770         buf_planes->plane_info.mp[0].offset_y = 0;
   1771         buf_planes->plane_info.mp[0].stride = stride;
   1772         buf_planes->plane_info.mp[0].scanline = scanline;
   1773         buf_planes->plane_info.mp[0].width = dim->width;
   1774         buf_planes->plane_info.mp[0].height = dim->height;
   1775 
   1776         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   1777         scanline = scanline / 2;
   1778         buf_planes->plane_info.mp[1].offset = 0;
   1779         buf_planes->plane_info.mp[1].len =
   1780             stride * scanline;
   1781         buf_planes->plane_info.mp[1].offset_x = 0;
   1782         buf_planes->plane_info.mp[1].offset_y = 0;
   1783         buf_planes->plane_info.mp[1].stride = stride;
   1784         buf_planes->plane_info.mp[1].scanline = scanline;
   1785         buf_planes->plane_info.mp[1].width = dim->width / 2;
   1786         buf_planes->plane_info.mp[1].height = dim->height / 2;
   1787 
   1788         buf_planes->plane_info.mp[2].offset = 0;
   1789         buf_planes->plane_info.mp[2].len =
   1790             stride * scanline;
   1791         buf_planes->plane_info.mp[2].offset_x = 0;
   1792         buf_planes->plane_info.mp[2].offset_y = 0;
   1793         buf_planes->plane_info.mp[2].stride = stride;
   1794         buf_planes->plane_info.mp[2].scanline = scanline;
   1795         buf_planes->plane_info.mp[2].width = dim->width / 2;
   1796         buf_planes->plane_info.mp[2].height = dim->height / 2;
   1797 
   1798         buf_planes->plane_info.frame_len =
   1799             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   1800                         buf_planes->plane_info.mp[1].len +
   1801                         buf_planes->plane_info.mp[2].len,
   1802                         CAM_PAD_TO_4K);
   1803         break;
   1804     case CAM_FORMAT_YUV_422_NV16:
   1805     case CAM_FORMAT_YUV_422_NV61:
   1806         /* 2 planes: Y + CbCr */
   1807         buf_planes->plane_info.num_planes = 2;
   1808 
   1809         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   1810         scanline = dim->height;
   1811         buf_planes->plane_info.mp[0].offset = 0;
   1812         buf_planes->plane_info.mp[0].len = stride * scanline;
   1813         buf_planes->plane_info.mp[0].offset_x = 0;
   1814         buf_planes->plane_info.mp[0].offset_y = 0;
   1815         buf_planes->plane_info.mp[0].stride = stride;
   1816         buf_planes->plane_info.mp[0].scanline = scanline;
   1817         buf_planes->plane_info.mp[0].width = dim->width;
   1818         buf_planes->plane_info.mp[0].height = dim->height;
   1819 
   1820         buf_planes->plane_info.mp[1].offset = 0;
   1821         buf_planes->plane_info.mp[1].len = stride * scanline;
   1822         buf_planes->plane_info.mp[1].offset_x = 0;
   1823         buf_planes->plane_info.mp[1].offset_y = 0;
   1824         buf_planes->plane_info.mp[1].stride = stride;
   1825         buf_planes->plane_info.mp[1].scanline = scanline;
   1826         buf_planes->plane_info.mp[1].width = dim->width;
   1827         buf_planes->plane_info.mp[1].height = dim->height;
   1828 
   1829         buf_planes->plane_info.frame_len =
   1830             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   1831                         buf_planes->plane_info.mp[1].len,
   1832                         CAM_PAD_TO_4K);
   1833         break;
   1834     case CAM_FORMAT_YUV_420_NV12_VENUS:
   1835 #ifdef VENUS_PRESENT
   1836         // using Venus
   1837         stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   1838         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   1839 
   1840         buf_planes->plane_info.frame_len =
   1841             VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   1842         buf_planes->plane_info.num_planes = 2;
   1843         buf_planes->plane_info.mp[0].len = stride * scanline;
   1844         buf_planes->plane_info.mp[0].offset = 0;
   1845         buf_planes->plane_info.mp[0].offset_x =0;
   1846         buf_planes->plane_info.mp[0].offset_y = 0;
   1847         buf_planes->plane_info.mp[0].stride = stride;
   1848         buf_planes->plane_info.mp[0].scanline = scanline;
   1849         buf_planes->plane_info.mp[0].width = dim->width;
   1850         buf_planes->plane_info.mp[0].height = dim->height;
   1851         stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   1852         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   1853         buf_planes->plane_info.mp[1].len =
   1854             buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   1855         buf_planes->plane_info.mp[1].offset = 0;
   1856         buf_planes->plane_info.mp[1].offset_x =0;
   1857         buf_planes->plane_info.mp[1].offset_y = 0;
   1858         buf_planes->plane_info.mp[1].stride = stride;
   1859         buf_planes->plane_info.mp[1].scanline = scanline;
   1860         buf_planes->plane_info.mp[1].width = dim->width;
   1861         buf_planes->plane_info.mp[1].height = dim->height;
   1862 #else
   1863         CDBG_ERROR("%s: Venus hardware not avail, cannot use this format", __func__);
   1864         rc = -1;
   1865 #endif
   1866         break;
   1867     default:
   1868         CDBG_ERROR("%s: Invalid cam_format for preview %d",
   1869                    __func__, fmt);
   1870         rc = -1;
   1871         break;
   1872     }
   1873 
   1874     return rc;
   1875 }
   1876 /*===========================================================================
   1877  * FUNCTION   : mm_stream_calc_offset_post_view
   1878  *
   1879  * DESCRIPTION: calculate postview frame offset based on format and
   1880  *              padding information
   1881  *
   1882  * PARAMETERS :
   1883  *   @fmt     : image format
   1884  *   @dim     : image dimension
   1885  *   @buf_planes : [out] buffer plane information
   1886  *
   1887  * RETURN     : int32_t type of status
   1888  *              0  -- success
   1889  *              -1 -- failure
   1890  *==========================================================================*/
   1891 int32_t mm_stream_calc_offset_post_view(cam_format_t fmt,
   1892                                       cam_dimension_t *dim,
   1893                                       cam_stream_buf_plane_info_t *buf_planes)
   1894 {
   1895     int32_t rc = 0;
   1896     int stride = 0, scanline = 0;
   1897 
   1898     switch (fmt) {
   1899     case CAM_FORMAT_YUV_420_NV12:
   1900     case CAM_FORMAT_YUV_420_NV21:
   1901         /* 2 planes: Y + CbCr */
   1902         buf_planes->plane_info.num_planes = 2;
   1903 
   1904         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_64);
   1905         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_64);
   1906         buf_planes->plane_info.mp[0].offset = 0;
   1907         buf_planes->plane_info.mp[0].len = stride * scanline;
   1908         buf_planes->plane_info.mp[0].offset_x = 0;
   1909         buf_planes->plane_info.mp[0].offset_y = 0;
   1910         buf_planes->plane_info.mp[0].stride = stride;
   1911         buf_planes->plane_info.mp[0].scanline = scanline;
   1912         buf_planes->plane_info.mp[0].width = dim->width;
   1913         buf_planes->plane_info.mp[0].height = dim->height;
   1914 
   1915         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_64);
   1916         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_64);
   1917         buf_planes->plane_info.mp[1].offset = 0;
   1918         buf_planes->plane_info.mp[1].len =
   1919             stride * scanline;
   1920         buf_planes->plane_info.mp[1].offset_x = 0;
   1921         buf_planes->plane_info.mp[1].offset_y = 0;
   1922         buf_planes->plane_info.mp[1].stride = stride;
   1923         buf_planes->plane_info.mp[1].scanline = scanline;
   1924         buf_planes->plane_info.mp[1].width = dim->width;
   1925         buf_planes->plane_info.mp[1].height = dim->height / 2;
   1926 
   1927         buf_planes->plane_info.frame_len =
   1928             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   1929                         buf_planes->plane_info.mp[1].len,
   1930                         CAM_PAD_TO_4K);
   1931         break;
   1932     case CAM_FORMAT_YUV_420_NV21_ADRENO:
   1933         /* 2 planes: Y + CbCr */
   1934         buf_planes->plane_info.num_planes = 2;
   1935 
   1936         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
   1937         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_32);
   1938         buf_planes->plane_info.mp[0].offset = 0;
   1939         buf_planes->plane_info.mp[0].len =
   1940             PAD_TO_SIZE(stride * scanline,
   1941                         CAM_PAD_TO_4K);
   1942         buf_planes->plane_info.mp[0].offset_x = 0;
   1943         buf_planes->plane_info.mp[0].offset_y = 0;
   1944         buf_planes->plane_info.mp[0].stride = stride;
   1945         buf_planes->plane_info.mp[0].scanline = scanline;
   1946         buf_planes->plane_info.mp[0].width = dim->width;
   1947         buf_planes->plane_info.mp[0].height = dim->height;
   1948 
   1949         stride = PAD_TO_SIZE(dim->width / 2, CAM_PAD_TO_32) * 2;
   1950         scanline = PAD_TO_SIZE(dim->height / 2, CAM_PAD_TO_32);
   1951         buf_planes->plane_info.mp[1].offset = 0;
   1952         buf_planes->plane_info.mp[1].len =
   1953             PAD_TO_SIZE(stride * scanline,
   1954                         CAM_PAD_TO_4K);
   1955         buf_planes->plane_info.mp[1].offset_x = 0;
   1956         buf_planes->plane_info.mp[1].offset_y = 0;
   1957         buf_planes->plane_info.mp[1].stride = stride;
   1958         buf_planes->plane_info.mp[1].scanline = scanline;
   1959         buf_planes->plane_info.mp[1].width = dim->width;
   1960         buf_planes->plane_info.mp[1].height = dim->height / 2;
   1961 
   1962         buf_planes->plane_info.frame_len =
   1963             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   1964                         buf_planes->plane_info.mp[1].len,
   1965                         CAM_PAD_TO_4K);
   1966         break;
   1967     case CAM_FORMAT_YUV_420_YV12:
   1968         /* 3 planes: Y + Cr + Cb */
   1969         buf_planes->plane_info.num_planes = 3;
   1970 
   1971         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   1972         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_2);
   1973         buf_planes->plane_info.mp[0].offset = 0;
   1974         buf_planes->plane_info.mp[0].len = stride * scanline;
   1975         buf_planes->plane_info.mp[0].offset_x = 0;
   1976         buf_planes->plane_info.mp[0].offset_y = 0;
   1977         buf_planes->plane_info.mp[0].stride = stride;
   1978         buf_planes->plane_info.mp[0].scanline = scanline;
   1979         buf_planes->plane_info.mp[0].width = dim->width;
   1980         buf_planes->plane_info.mp[0].height = dim->height;
   1981 
   1982         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   1983         scanline = scanline / 2;
   1984         buf_planes->plane_info.mp[1].offset = 0;
   1985         buf_planes->plane_info.mp[1].len =
   1986             stride * scanline;
   1987         buf_planes->plane_info.mp[1].offset_x = 0;
   1988         buf_planes->plane_info.mp[1].offset_y = 0;
   1989         buf_planes->plane_info.mp[1].stride = stride;
   1990         buf_planes->plane_info.mp[1].scanline = scanline;
   1991         buf_planes->plane_info.mp[1].width = dim->width / 2;
   1992         buf_planes->plane_info.mp[1].height = dim->height / 2;
   1993 
   1994         buf_planes->plane_info.mp[2].offset = 0;
   1995         buf_planes->plane_info.mp[2].len =
   1996             stride * scanline;
   1997         buf_planes->plane_info.mp[2].offset_x = 0;
   1998         buf_planes->plane_info.mp[2].offset_y = 0;
   1999         buf_planes->plane_info.mp[2].stride = stride;
   2000         buf_planes->plane_info.mp[2].scanline = scanline;
   2001         buf_planes->plane_info.mp[2].width = dim->width / 2;
   2002         buf_planes->plane_info.mp[2].height = dim->height / 2;
   2003 
   2004         buf_planes->plane_info.frame_len =
   2005             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2006                         buf_planes->plane_info.mp[1].len +
   2007                         buf_planes->plane_info.mp[2].len,
   2008                         CAM_PAD_TO_4K);
   2009         break;
   2010     case CAM_FORMAT_YUV_422_NV16:
   2011     case CAM_FORMAT_YUV_422_NV61:
   2012         /* 2 planes: Y + CbCr */
   2013         buf_planes->plane_info.num_planes = 2;
   2014 
   2015         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2016         scanline = dim->height;
   2017         buf_planes->plane_info.mp[0].offset = 0;
   2018         buf_planes->plane_info.mp[0].len = stride * scanline;
   2019         buf_planes->plane_info.mp[0].offset_x = 0;
   2020         buf_planes->plane_info.mp[0].offset_y = 0;
   2021         buf_planes->plane_info.mp[0].stride = stride;
   2022         buf_planes->plane_info.mp[0].scanline = scanline;
   2023         buf_planes->plane_info.mp[0].width = dim->width;
   2024         buf_planes->plane_info.mp[0].height = dim->height;
   2025 
   2026         buf_planes->plane_info.mp[1].offset = 0;
   2027         buf_planes->plane_info.mp[1].len = stride * scanline;
   2028         buf_planes->plane_info.mp[1].offset_x = 0;
   2029         buf_planes->plane_info.mp[1].offset_y = 0;
   2030         buf_planes->plane_info.mp[1].stride = stride;
   2031         buf_planes->plane_info.mp[1].scanline = scanline;
   2032         buf_planes->plane_info.mp[1].width = dim->width;
   2033         buf_planes->plane_info.mp[1].height = dim->height;
   2034 
   2035         buf_planes->plane_info.frame_len =
   2036             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2037                         buf_planes->plane_info.mp[1].len,
   2038                         CAM_PAD_TO_4K);
   2039         break;
   2040     case CAM_FORMAT_YUV_420_NV12_VENUS:
   2041 #ifdef VENUS_PRESENT
   2042         // using Venus
   2043         stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   2044         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   2045 
   2046         buf_planes->plane_info.frame_len =
   2047             VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   2048         buf_planes->plane_info.num_planes = 2;
   2049         buf_planes->plane_info.mp[0].len = stride * scanline;
   2050         buf_planes->plane_info.mp[0].offset = 0;
   2051         buf_planes->plane_info.mp[0].offset_x =0;
   2052         buf_planes->plane_info.mp[0].offset_y = 0;
   2053         buf_planes->plane_info.mp[0].stride = stride;
   2054         buf_planes->plane_info.mp[0].scanline = scanline;
   2055         buf_planes->plane_info.mp[0].width = dim->width;
   2056         buf_planes->plane_info.mp[0].height = dim->height;
   2057         stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   2058         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   2059         buf_planes->plane_info.mp[1].len =
   2060             buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2061         buf_planes->plane_info.mp[1].offset = 0;
   2062         buf_planes->plane_info.mp[1].offset_x =0;
   2063         buf_planes->plane_info.mp[1].offset_y = 0;
   2064         buf_planes->plane_info.mp[1].stride = stride;
   2065         buf_planes->plane_info.mp[1].scanline = scanline;
   2066         buf_planes->plane_info.mp[1].width = dim->width;
   2067         buf_planes->plane_info.mp[1].height = dim->height;
   2068 #else
   2069         CDBG_ERROR("%s: Venus hardware not avail, cannot use this format", __func__);
   2070         rc = -1;
   2071 #endif
   2072         break;
   2073     default:
   2074         CDBG_ERROR("%s: Invalid cam_format for preview %d",
   2075                    __func__, fmt);
   2076         rc = -1;
   2077         break;
   2078     }
   2079 
   2080     return rc;
   2081 }
   2082 
   2083 /*===========================================================================
   2084  * FUNCTION   : mm_stream_calc_offset_snapshot
   2085  *
   2086  * DESCRIPTION: calculate snapshot/postproc frame offset based on format and
   2087  *              padding information
   2088  *
   2089  * PARAMETERS :
   2090  *   @fmt     : image format
   2091  *   @dim     : image dimension
   2092  *   @padding : padding information
   2093  *   @buf_planes : [out] buffer plane information
   2094  *
   2095  * RETURN     : int32_t type of status
   2096  *              0  -- success
   2097  *              -1 -- failure
   2098  *==========================================================================*/
   2099 int32_t mm_stream_calc_offset_snapshot(cam_format_t fmt,
   2100                                        cam_dimension_t *dim,
   2101                                        cam_padding_info_t *padding,
   2102                                        cam_stream_buf_plane_info_t *buf_planes)
   2103 {
   2104     int32_t rc = 0;
   2105     uint8_t isAFamily = mm_camera_util_chip_is_a_family();
   2106     int offset_x = 0, offset_y = 0;
   2107     int stride = 0, scanline = 0;
   2108 
   2109     if (isAFamily) {
   2110         stride = dim->width;
   2111         scanline = PAD_TO_SIZE(dim->height, CAM_PAD_TO_16);
   2112         offset_x = 0;
   2113         offset_y = scanline - dim->height;
   2114         scanline += offset_y; /* double padding */
   2115     } else {
   2116         stride = PAD_TO_SIZE(dim->width,
   2117                              padding->width_padding);
   2118         scanline = PAD_TO_SIZE(dim->height,
   2119                                padding->height_padding);
   2120         offset_x = 0;
   2121         offset_y = 0;
   2122     }
   2123 
   2124     switch (fmt) {
   2125     case CAM_FORMAT_YUV_420_NV12:
   2126     case CAM_FORMAT_YUV_420_NV21:
   2127         /* 2 planes: Y + CbCr */
   2128         buf_planes->plane_info.num_planes = 2;
   2129 
   2130         buf_planes->plane_info.mp[0].len =
   2131             PAD_TO_SIZE(stride * scanline,
   2132                         padding->plane_padding);
   2133         buf_planes->plane_info.mp[0].offset =
   2134             PAD_TO_SIZE(offset_x + stride * offset_y,
   2135                         padding->plane_padding);
   2136         buf_planes->plane_info.mp[0].offset_x = offset_x;
   2137         buf_planes->plane_info.mp[0].offset_y = offset_y;
   2138         buf_planes->plane_info.mp[0].stride = stride;
   2139         buf_planes->plane_info.mp[0].scanline = scanline;
   2140         buf_planes->plane_info.mp[0].width = dim->width;
   2141         buf_planes->plane_info.mp[0].height = dim->height;
   2142 
   2143         scanline = scanline / 2;
   2144         buf_planes->plane_info.mp[1].len =
   2145             PAD_TO_SIZE(stride * scanline,
   2146                         padding->plane_padding);
   2147         buf_planes->plane_info.mp[1].offset =
   2148             PAD_TO_SIZE(offset_x + stride * offset_y,
   2149                         padding->plane_padding);
   2150         buf_planes->plane_info.mp[1].offset_x = offset_x;
   2151         buf_planes->plane_info.mp[1].offset_y = offset_y;
   2152         buf_planes->plane_info.mp[1].stride = stride;
   2153         buf_planes->plane_info.mp[1].scanline = scanline;
   2154         buf_planes->plane_info.mp[1].width = dim->width;
   2155         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2156 
   2157         buf_planes->plane_info.frame_len =
   2158             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2159                         buf_planes->plane_info.mp[1].len,
   2160                         CAM_PAD_TO_4K);
   2161         break;
   2162     case CAM_FORMAT_YUV_420_YV12:
   2163         /* 3 planes: Y + Cr + Cb */
   2164         buf_planes->plane_info.num_planes = 3;
   2165 
   2166         buf_planes->plane_info.mp[0].offset =
   2167             PAD_TO_SIZE(offset_x + stride * offset_y,
   2168                         padding->plane_padding);
   2169         buf_planes->plane_info.mp[0].len =
   2170             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2171         buf_planes->plane_info.mp[0].offset_x = offset_x;
   2172         buf_planes->plane_info.mp[0].offset_y = offset_y;
   2173         buf_planes->plane_info.mp[0].stride = stride;
   2174         buf_planes->plane_info.mp[0].scanline = scanline;
   2175         buf_planes->plane_info.mp[0].width = dim->width;
   2176         buf_planes->plane_info.mp[0].height = dim->height;
   2177 
   2178         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
   2179         scanline = scanline / 2;
   2180         buf_planes->plane_info.mp[1].offset =
   2181             PAD_TO_SIZE(offset_x + stride * offset_y,
   2182                         padding->plane_padding);
   2183         buf_planes->plane_info.mp[1].len =
   2184             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2185         buf_planes->plane_info.mp[1].offset_x = offset_x;
   2186         buf_planes->plane_info.mp[1].offset_y = offset_y;
   2187         buf_planes->plane_info.mp[1].stride = stride;
   2188         buf_planes->plane_info.mp[1].scanline = scanline;
   2189         buf_planes->plane_info.mp[1].width = dim->width / 2;
   2190         buf_planes->plane_info.mp[1].height = dim->height / 2;
   2191 
   2192         buf_planes->plane_info.mp[2].offset =
   2193             PAD_TO_SIZE(offset_x + stride * offset_y,
   2194                         padding->plane_padding);
   2195         buf_planes->plane_info.mp[2].len =
   2196             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2197         buf_planes->plane_info.mp[2].offset_x = offset_x;
   2198         buf_planes->plane_info.mp[2].offset_y = offset_y;
   2199         buf_planes->plane_info.mp[2].stride = stride;
   2200         buf_planes->plane_info.mp[2].scanline = scanline;
   2201         buf_planes->plane_info.mp[2].width = dim->width / 2;
   2202         buf_planes->plane_info.mp[2].height = dim->height / 2;
   2203 
   2204         buf_planes->plane_info.frame_len =
   2205             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2206                         buf_planes->plane_info.mp[1].len +
   2207                         buf_planes->plane_info.mp[2].len,
   2208                         CAM_PAD_TO_4K);
   2209         break;
   2210     case CAM_FORMAT_YUV_422_NV16:
   2211     case CAM_FORMAT_YUV_422_NV61:
   2212         /* 2 planes: Y + CbCr */
   2213         buf_planes->plane_info.num_planes = 2;
   2214         buf_planes->plane_info.mp[0].len =
   2215             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2216         buf_planes->plane_info.mp[0].offset =
   2217             PAD_TO_SIZE(offset_x + stride * offset_y,
   2218                         padding->plane_padding);
   2219         buf_planes->plane_info.mp[0].offset_x = offset_x;
   2220         buf_planes->plane_info.mp[0].offset_y = offset_y;
   2221         buf_planes->plane_info.mp[0].stride = stride;
   2222         buf_planes->plane_info.mp[0].scanline = scanline;
   2223         buf_planes->plane_info.mp[0].width = dim->width;
   2224         buf_planes->plane_info.mp[0].height = dim->height;
   2225 
   2226         buf_planes->plane_info.mp[1].len =
   2227             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2228         buf_planes->plane_info.mp[1].offset =
   2229             PAD_TO_SIZE(offset_x + stride * offset_y,
   2230                         padding->plane_padding);
   2231         buf_planes->plane_info.mp[1].offset_x = offset_x;
   2232         buf_planes->plane_info.mp[1].offset_y = offset_y;
   2233         buf_planes->plane_info.mp[1].stride = stride;
   2234         buf_planes->plane_info.mp[1].scanline = scanline;
   2235         buf_planes->plane_info.mp[1].width = dim->width;
   2236         buf_planes->plane_info.mp[1].height = dim->height;
   2237 
   2238         buf_planes->plane_info.frame_len = PAD_TO_SIZE(
   2239             buf_planes->plane_info.mp[0].len + buf_planes->plane_info.mp[1].len,
   2240             CAM_PAD_TO_4K);
   2241         break;
   2242     default:
   2243         CDBG_ERROR("%s: Invalid cam_format for snapshot %d",
   2244                    __func__, fmt);
   2245         rc = -1;
   2246         break;
   2247     }
   2248 
   2249     return rc;
   2250 }
   2251 
   2252 /*===========================================================================
   2253  * FUNCTION   : mm_stream_calc_offset_raw
   2254  *
   2255  * DESCRIPTION: calculate raw frame offset based on format and padding information
   2256  *
   2257  * PARAMETERS :
   2258  *   @fmt     : image format
   2259  *   @dim     : image dimension
   2260  *   @padding : padding information
   2261  *   @buf_planes : [out] buffer plane information
   2262  *
   2263  * RETURN     : int32_t type of status
   2264  *              0  -- success
   2265  *              -1 -- failure
   2266  *==========================================================================*/
   2267 int32_t mm_stream_calc_offset_raw(cam_format_t fmt,
   2268                                   cam_dimension_t *dim,
   2269                                   cam_padding_info_t *padding,
   2270                                   cam_stream_buf_plane_info_t *buf_planes)
   2271 {
   2272     int32_t rc = 0;
   2273     int stride = 0;
   2274     int scanline = dim->height;
   2275 
   2276     switch (fmt) {
   2277     case CAM_FORMAT_YUV_RAW_8BIT_YUYV:
   2278     case CAM_FORMAT_YUV_RAW_8BIT_YVYU:
   2279     case CAM_FORMAT_YUV_RAW_8BIT_UYVY:
   2280     case CAM_FORMAT_YUV_RAW_8BIT_VYUY:
   2281     case CAM_FORMAT_JPEG_RAW_8BIT:
   2282         /* 1 plane */
   2283         /* Every 16 pixels occupy 16 bytes */
   2284         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2285         buf_planes->plane_info.num_planes = 1;
   2286         buf_planes->plane_info.mp[0].offset = 0;
   2287         buf_planes->plane_info.mp[0].len =
   2288             PAD_TO_SIZE(stride * scanline * 2, padding->plane_padding);
   2289         buf_planes->plane_info.frame_len =
   2290             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2291         buf_planes->plane_info.mp[0].offset_x =0;
   2292         buf_planes->plane_info.mp[0].offset_y = 0;
   2293         buf_planes->plane_info.mp[0].stride = stride;
   2294         buf_planes->plane_info.mp[0].scanline = scanline;
   2295         buf_planes->plane_info.mp[0].width = buf_planes->plane_info.mp[0].len;
   2296         buf_planes->plane_info.mp[0].height = 1;
   2297         break;
   2298     case CAM_FORMAT_META_RAW_8BIT:
   2299         // Every 16 pixels occupy 16 bytes
   2300         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2301         buf_planes->plane_info.num_planes = 1;
   2302         buf_planes->plane_info.mp[0].offset = 0;
   2303         buf_planes->plane_info.mp[0].len =
   2304             PAD_TO_SIZE(stride * scanline * 2, padding->plane_padding);
   2305         buf_planes->plane_info.frame_len =
   2306             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2307         buf_planes->plane_info.mp[0].offset_x =0;
   2308         buf_planes->plane_info.mp[0].offset_y = 0;
   2309         buf_planes->plane_info.mp[0].stride = stride;
   2310         buf_planes->plane_info.mp[0].scanline = scanline;
   2311         break;
   2312 
   2313     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GBRG:
   2314     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GRBG:
   2315     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_RGGB:
   2316     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_BGGR:
   2317     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG:
   2318     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GRBG:
   2319     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_RGGB:
   2320     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_BGGR:
   2321     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GBRG:
   2322     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GRBG:
   2323     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_RGGB:
   2324     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_BGGR:
   2325     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GBRG:
   2326     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GRBG:
   2327     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_RGGB:
   2328     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_BGGR:
   2329     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_GBRG:
   2330     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_GRBG:
   2331     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_RGGB:
   2332     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_BGGR:
   2333         /* 1 plane */
   2334         /* Every 16 pixels occupy 16 bytes */
   2335         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
   2336         buf_planes->plane_info.num_planes = 1;
   2337         buf_planes->plane_info.mp[0].offset = 0;
   2338         buf_planes->plane_info.mp[0].len =
   2339             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2340         buf_planes->plane_info.frame_len =
   2341             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2342         buf_planes->plane_info.mp[0].offset_x =0;
   2343         buf_planes->plane_info.mp[0].offset_y = 0;
   2344         buf_planes->plane_info.mp[0].stride = stride;
   2345         buf_planes->plane_info.mp[0].scanline = scanline;
   2346         buf_planes->plane_info.mp[0].width = buf_planes->plane_info.mp[0].len;
   2347         buf_planes->plane_info.mp[0].height = 1;
   2348         break;
   2349     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG:
   2350     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GRBG:
   2351     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_RGGB:
   2352     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_BGGR:
   2353     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GBRG:
   2354     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GRBG:
   2355     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_RGGB:
   2356     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_BGGR:
   2357         /* Every 12 pixels occupy 16 bytes */
   2358         stride = (dim->width + 11)/12 * 16;
   2359         buf_planes->plane_info.num_planes = 1;
   2360         buf_planes->plane_info.mp[0].offset = 0;
   2361         buf_planes->plane_info.mp[0].len =
   2362             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2363         buf_planes->plane_info.frame_len =
   2364             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2365         buf_planes->plane_info.mp[0].offset_x =0;
   2366         buf_planes->plane_info.mp[0].offset_y = 0;
   2367         buf_planes->plane_info.mp[0].stride = stride;
   2368         buf_planes->plane_info.mp[0].scanline = scanline;
   2369         buf_planes->plane_info.mp[0].width = buf_planes->plane_info.mp[0].len;
   2370         buf_planes->plane_info.mp[0].height = 1;
   2371         break;
   2372     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GBRG:
   2373     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GRBG:
   2374     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_RGGB:
   2375     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_BGGR:
   2376     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GBRG:
   2377     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GRBG:
   2378     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_RGGB:
   2379     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_BGGR:
   2380         /* Every 10 pixels occupy 16 bytes */
   2381         stride = (dim->width + 9)/10 * 16;
   2382         buf_planes->plane_info.num_planes = 1;
   2383         buf_planes->plane_info.mp[0].offset = 0;
   2384         buf_planes->plane_info.mp[0].len =
   2385             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2386         buf_planes->plane_info.frame_len =
   2387             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2388         buf_planes->plane_info.mp[0].offset_x =0;
   2389         buf_planes->plane_info.mp[0].offset_y = 0;
   2390         buf_planes->plane_info.mp[0].stride = stride;
   2391         buf_planes->plane_info.mp[0].scanline = scanline;
   2392         buf_planes->plane_info.mp[0].width = buf_planes->plane_info.mp[0].len;
   2393         buf_planes->plane_info.mp[0].height = 1;
   2394         break;
   2395     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG:
   2396     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GRBG:
   2397     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_RGGB:
   2398     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_BGGR:
   2399     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GBRG:
   2400     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GRBG:
   2401     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_RGGB:
   2402     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_BGGR:
   2403         /* Every 64 pixels occupy 80 bytes */
   2404         stride = PAD_TO_SIZE(
   2405                 PAD_TO_SIZE(dim->width, CAM_PAD_TO_4)*5/4, CAM_PAD_TO_16);
   2406         buf_planes->plane_info.num_planes = 1;
   2407         buf_planes->plane_info.mp[0].offset = 0;
   2408         buf_planes->plane_info.mp[0].len =
   2409             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2410         buf_planes->plane_info.frame_len =
   2411             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2412         buf_planes->plane_info.mp[0].offset_x =0;
   2413         buf_planes->plane_info.mp[0].offset_y = 0;
   2414         buf_planes->plane_info.mp[0].stride = stride;
   2415         buf_planes->plane_info.mp[0].scanline = scanline;
   2416         buf_planes->plane_info.mp[0].width = buf_planes->plane_info.mp[0].len;
   2417         buf_planes->plane_info.mp[0].height = 1;
   2418         break;
   2419     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GBRG:
   2420     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GRBG:
   2421     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_RGGB:
   2422     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR:
   2423     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GBRG:
   2424     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GRBG:
   2425     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_RGGB:
   2426     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_BGGR:
   2427         /* Every 32 pixels occupy 48 bytes */
   2428         stride = PAD_TO_SIZE(PAD_TO_SIZE(dim->width, 2)*3/2, CAM_PAD_TO_16);
   2429         buf_planes->plane_info.num_planes = 1;
   2430         buf_planes->plane_info.mp[0].offset = 0;
   2431         buf_planes->plane_info.mp[0].len =
   2432             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2433         buf_planes->plane_info.frame_len =
   2434             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2435         buf_planes->plane_info.mp[0].offset_x =0;
   2436         buf_planes->plane_info.mp[0].offset_y = 0;
   2437         buf_planes->plane_info.mp[0].stride = stride;
   2438         buf_planes->plane_info.mp[0].scanline = scanline;
   2439         buf_planes->plane_info.mp[0].width = buf_planes->plane_info.mp[0].len;
   2440         buf_planes->plane_info.mp[0].height = 1;
   2441         break;
   2442     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_GBRG:
   2443     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_GRBG:
   2444     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_RGGB:
   2445     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_BGGR:
   2446     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_GBRG:
   2447     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_GRBG:
   2448     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_RGGB:
   2449     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_BGGR:
   2450     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_GBRG:
   2451     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_GRBG:
   2452     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_RGGB:
   2453     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_BGGR:
   2454         /* Every 8 pixels occupy 16 bytes */
   2455         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_8) * 2;
   2456         buf_planes->plane_info.num_planes = 1;
   2457         buf_planes->plane_info.mp[0].offset = 0;
   2458         buf_planes->plane_info.mp[0].len =
   2459             PAD_TO_SIZE(stride * scanline, padding->plane_padding);
   2460         buf_planes->plane_info.frame_len =
   2461             PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
   2462         buf_planes->plane_info.mp[0].offset_x =0;
   2463         buf_planes->plane_info.mp[0].offset_y = 0;
   2464         buf_planes->plane_info.mp[0].stride = stride;
   2465         buf_planes->plane_info.mp[0].scanline = scanline;
   2466         buf_planes->plane_info.mp[0].width = buf_planes->plane_info.mp[0].len;
   2467         buf_planes->plane_info.mp[0].height = 1;
   2468         break;
   2469     default:
   2470         CDBG_ERROR("%s: Invalid cam_format %d for raw stream",
   2471                    __func__, fmt);
   2472         rc = -1;
   2473         break;
   2474     }
   2475 
   2476     return rc;
   2477 }
   2478 
   2479 /*===========================================================================
   2480  * FUNCTION   : mm_stream_calc_offset_video
   2481  *
   2482  * DESCRIPTION: calculate video frame offset based on format and
   2483  *              padding information
   2484  *
   2485  * PARAMETERS :
   2486  *   @dim     : image dimension
   2487  *   @buf_planes : [out] buffer plane information
   2488  *
   2489  * RETURN     : int32_t type of status
   2490  *              0  -- success
   2491  *              -1 -- failure
   2492  *==========================================================================*/
   2493 #ifdef VENUS_PRESENT
   2494 int32_t mm_stream_calc_offset_video(cam_dimension_t *dim,
   2495                                     cam_stream_buf_plane_info_t *buf_planes)
   2496 {
   2497     int stride = 0, scanline = 0;
   2498 
   2499     // using Venus
   2500     stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
   2501     scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
   2502 
   2503     buf_planes->plane_info.frame_len =
   2504         VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
   2505     buf_planes->plane_info.num_planes = 2;
   2506     buf_planes->plane_info.mp[0].len = stride * scanline;
   2507     buf_planes->plane_info.mp[0].offset = 0;
   2508     buf_planes->plane_info.mp[0].offset_x =0;
   2509     buf_planes->plane_info.mp[0].offset_y = 0;
   2510     buf_planes->plane_info.mp[0].stride = stride;
   2511     buf_planes->plane_info.mp[0].scanline = scanline;
   2512     buf_planes->plane_info.mp[0].width = dim->width;
   2513     buf_planes->plane_info.mp[0].height = dim->height;
   2514     stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
   2515     scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
   2516     buf_planes->plane_info.mp[1].len =
   2517         buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
   2518     buf_planes->plane_info.mp[1].offset = 0;
   2519     buf_planes->plane_info.mp[1].offset_x =0;
   2520     buf_planes->plane_info.mp[1].offset_y = 0;
   2521     buf_planes->plane_info.mp[1].stride = stride;
   2522     buf_planes->plane_info.mp[1].scanline = scanline;
   2523     buf_planes->plane_info.mp[1].width = dim->width;
   2524     buf_planes->plane_info.mp[1].height = dim->height;
   2525 
   2526     return 0;
   2527 }
   2528 #else
   2529 int32_t mm_stream_calc_offset_video(cam_dimension_t *dim,
   2530                                     cam_stream_buf_plane_info_t *buf_planes)
   2531 {
   2532     int stride = 0, scanline = 0;
   2533 
   2534     buf_planes->plane_info.num_planes = 2;
   2535 
   2536     stride = dim->width;
   2537     scanline = dim->height;
   2538     buf_planes->plane_info.mp[0].len =
   2539         PAD_TO_SIZE(stride * scanline, CAM_PAD_TO_2K);
   2540     buf_planes->plane_info.mp[0].offset = 0;
   2541     buf_planes->plane_info.mp[0].offset_x =0;
   2542     buf_planes->plane_info.mp[0].offset_y = 0;
   2543     buf_planes->plane_info.mp[0].stride = stride;
   2544     buf_planes->plane_info.mp[0].scanline = scanline;
   2545     buf_planes->plane_info.mp[0].width = dim->width;
   2546     buf_planes->plane_info.mp[0].height = dim->height;
   2547 
   2548     stride = dim->width;
   2549     scanline = dim->height / 2;
   2550     buf_planes->plane_info.mp[1].len =
   2551         PAD_TO_SIZE(stride * scanline, CAM_PAD_TO_2K);
   2552     buf_planes->plane_info.mp[1].offset = 0;
   2553     buf_planes->plane_info.mp[1].offset_x =0;
   2554     buf_planes->plane_info.mp[1].offset_y = 0;
   2555     buf_planes->plane_info.mp[1].stride = stride;
   2556     buf_planes->plane_info.mp[1].scanline = scanline;
   2557     buf_planes->plane_info.mp[0].width = dim->width;
   2558     buf_planes->plane_info.mp[0].height = dim->height / 2;
   2559 
   2560     buf_planes->plane_info.frame_len =
   2561         PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
   2562                     buf_planes->plane_info.mp[1].len,
   2563                     CAM_PAD_TO_4K);
   2564 
   2565     return 0;
   2566 }
   2567 #endif
   2568 
   2569 /*===========================================================================
   2570  * FUNCTION   : mm_stream_calc_offset_metadata
   2571  *
   2572  * DESCRIPTION: calculate metadata frame offset based on format and
   2573  *              padding information
   2574  *
   2575  * PARAMETERS :
   2576  *   @dim     : image dimension
   2577  *   @padding : padding information
   2578  *   @buf_planes : [out] buffer plane information
   2579  *
   2580  * RETURN     : int32_t type of status
   2581  *              0  -- success
   2582  *              -1 -- failure
   2583  *==========================================================================*/
   2584 int32_t mm_stream_calc_offset_metadata(cam_dimension_t *dim,
   2585                                        cam_padding_info_t *padding,
   2586                                        cam_stream_buf_plane_info_t *buf_planes)
   2587 {
   2588     int32_t rc = 0;
   2589     buf_planes->plane_info.num_planes = 1;
   2590     buf_planes->plane_info.mp[0].offset = 0;
   2591     buf_planes->plane_info.mp[0].len =
   2592         PAD_TO_SIZE(dim->width * dim->height, padding->plane_padding);
   2593     buf_planes->plane_info.frame_len =
   2594         buf_planes->plane_info.mp[0].len;
   2595 
   2596     buf_planes->plane_info.mp[0].offset_x =0;
   2597     buf_planes->plane_info.mp[0].offset_y = 0;
   2598     buf_planes->plane_info.mp[0].stride = dim->width;
   2599     buf_planes->plane_info.mp[0].scanline = dim->height;
   2600     buf_planes->plane_info.mp[0].width = dim->width;
   2601     buf_planes->plane_info.mp[0].height = dim->height;
   2602     return rc;
   2603 }
   2604 
   2605 /*===========================================================================
   2606  * FUNCTION   : mm_stream_calc_offset_postproc
   2607  *
   2608  * DESCRIPTION: calculate postprocess frame offset
   2609  *
   2610  * PARAMETERS :
   2611  *   @stream_info: ptr to stream info
   2612  *   @padding : padding information
   2613  *   @plns : [out] buffer plane information
   2614  *
   2615  * RETURN     : int32_t type of status
   2616  *              0  -- success
   2617  *              -1 -- failure
   2618  *==========================================================================*/
   2619 int32_t mm_stream_calc_offset_postproc(cam_stream_info_t *stream_info,
   2620                                        cam_padding_info_t *padding,
   2621                                        cam_stream_buf_plane_info_t *plns)
   2622 {
   2623     int32_t rc = 0;
   2624     cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT;
   2625     if (stream_info->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
   2626         type = stream_info->reprocess_config.offline.input_type;
   2627         if (CAM_STREAM_TYPE_DEFAULT == type) {
   2628             if (plns->plane_info.frame_len == 0) {
   2629                 // take offset from input source
   2630                 *plns = stream_info->reprocess_config.offline.input_buf_planes;
   2631                 return rc;
   2632             }
   2633         } else {
   2634             type = stream_info->reprocess_config.offline.input_type;
   2635         }
   2636     } else {
   2637         type = stream_info->reprocess_config.online.input_stream_type;
   2638     }
   2639 
   2640     switch (type) {
   2641     case CAM_STREAM_TYPE_PREVIEW:
   2642     case CAM_STREAM_TYPE_CALLBACK:
   2643         rc = mm_stream_calc_offset_preview(stream_info->fmt,
   2644                                            &stream_info->dim,
   2645                                            plns);
   2646         break;
   2647     case CAM_STREAM_TYPE_POSTVIEW:
   2648         rc = mm_stream_calc_offset_post_view(stream_info->fmt,
   2649                                            &stream_info->dim,
   2650                                            plns);
   2651         break;
   2652     case CAM_STREAM_TYPE_SNAPSHOT:
   2653         rc = mm_stream_calc_offset_snapshot(stream_info->fmt,
   2654                                             &stream_info->dim,
   2655                                             padding,
   2656                                             plns);
   2657         break;
   2658     case CAM_STREAM_TYPE_VIDEO:
   2659         rc = mm_stream_calc_offset_video(&stream_info->dim,
   2660                         plns);
   2661         break;
   2662     case CAM_STREAM_TYPE_RAW:
   2663         rc = mm_stream_calc_offset_raw(stream_info->fmt,
   2664                                        &stream_info->dim,
   2665                                        padding,
   2666                                        plns);
   2667         break;
   2668     case CAM_STREAM_TYPE_METADATA:
   2669         rc = mm_stream_calc_offset_metadata(&stream_info->dim,
   2670                                             padding,
   2671                                             plns);
   2672         break;
   2673     default:
   2674         CDBG_ERROR("%s: not supported for stream type %d",
   2675                    __func__, type);
   2676         rc = -1;
   2677         break;
   2678     }
   2679     return rc;
   2680 }
   2681 
   2682 /*===========================================================================
   2683  * FUNCTION   : mm_stream_calc_offset
   2684  *
   2685  * DESCRIPTION: calculate frame offset based on format and padding information
   2686  *
   2687  * PARAMETERS :
   2688  *   @my_obj  : stream object
   2689  *
   2690  * RETURN     : int32_t type of status
   2691  *              0  -- success
   2692  *              -1 -- failure
   2693  *==========================================================================*/
   2694 int32_t mm_stream_calc_offset(mm_stream_t *my_obj)
   2695 {
   2696     int32_t rc = 0;
   2697 
   2698     cam_dimension_t dim = my_obj->stream_info->dim;
   2699     if (my_obj->stream_info->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
   2700         my_obj->stream_info->stream_type != CAM_STREAM_TYPE_VIDEO) {
   2701         if (my_obj->stream_info->pp_config.rotation == ROTATE_90 ||
   2702             my_obj->stream_info->pp_config.rotation == ROTATE_270) {
   2703             // rotated by 90 or 270, need to switch width and height
   2704             dim.width = my_obj->stream_info->dim.height;
   2705             dim.height = my_obj->stream_info->dim.width;
   2706         }
   2707     }
   2708 
   2709     switch (my_obj->stream_info->stream_type) {
   2710     case CAM_STREAM_TYPE_PREVIEW:
   2711     case CAM_STREAM_TYPE_CALLBACK:
   2712         rc = mm_stream_calc_offset_preview(my_obj->stream_info->fmt,
   2713                                            &dim,
   2714                                            &my_obj->stream_info->buf_planes);
   2715         break;
   2716     case CAM_STREAM_TYPE_POSTVIEW:
   2717       rc = mm_stream_calc_offset_post_view(my_obj->stream_info->fmt,
   2718                                          &dim,
   2719                                          &my_obj->stream_info->buf_planes);
   2720       break;
   2721     case CAM_STREAM_TYPE_SNAPSHOT:
   2722         rc = mm_stream_calc_offset_snapshot(my_obj->stream_info->fmt,
   2723                                             &dim,
   2724                                             &my_obj->padding_info,
   2725                                             &my_obj->stream_info->buf_planes);
   2726         break;
   2727     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2728         rc = mm_stream_calc_offset_postproc(my_obj->stream_info,
   2729                                             &my_obj->padding_info,
   2730                                             &my_obj->stream_info->buf_planes);
   2731         break;
   2732     case CAM_STREAM_TYPE_VIDEO:
   2733         rc = mm_stream_calc_offset_video(&dim,
   2734                                          &my_obj->stream_info->buf_planes);
   2735         break;
   2736     case CAM_STREAM_TYPE_RAW:
   2737         rc = mm_stream_calc_offset_raw(my_obj->stream_info->fmt,
   2738                                        &dim,
   2739                                        &my_obj->padding_info,
   2740                                        &my_obj->stream_info->buf_planes);
   2741         break;
   2742     case CAM_STREAM_TYPE_METADATA:
   2743         rc = mm_stream_calc_offset_metadata(&dim,
   2744                                             &my_obj->padding_info,
   2745                                             &my_obj->stream_info->buf_planes);
   2746         break;
   2747     default:
   2748         CDBG_ERROR("%s: not supported for stream type %d",
   2749                    __func__, my_obj->stream_info->stream_type);
   2750         rc = -1;
   2751         break;
   2752     }
   2753 
   2754     my_obj->frame_offset = my_obj->stream_info->buf_planes.plane_info;
   2755     return rc;
   2756 }
   2757 
   2758 /*===========================================================================
   2759  * FUNCTION   : mm_stream_sync_info
   2760  *
   2761  * DESCRIPTION: synchronize stream information with server
   2762  *
   2763  * PARAMETERS :
   2764  *   @my_obj  : stream object
   2765  *
   2766  * RETURN     : int32_t type of status
   2767  *              0  -- success
   2768  *              -1 -- failure
   2769  * NOTE       : assume stream info buffer is mapped to server and filled in with
   2770  *              stream information by upper layer. This call will let server to
   2771  *              synchornize the stream information with HAL. If server find any
   2772  *              fields that need to be changed accroding to hardware configuration,
   2773  *              server will modify corresponding fields so that HAL could know
   2774  *              about it.
   2775  *==========================================================================*/
   2776 int32_t mm_stream_sync_info(mm_stream_t *my_obj)
   2777 {
   2778     int32_t rc = 0;
   2779     int32_t value = 0;
   2780     my_obj->stream_info->stream_svr_id = my_obj->server_stream_id;
   2781     rc = mm_stream_calc_offset(my_obj);
   2782 
   2783     if (rc == 0) {
   2784         rc = mm_camera_util_s_ctrl(my_obj->fd,
   2785                                    CAM_PRIV_STREAM_INFO_SYNC,
   2786                                    &value);
   2787     }
   2788     return rc;
   2789 }
   2790 
   2791 /*===========================================================================
   2792  * FUNCTION   : mm_stream_set_fmt
   2793  *
   2794  * DESCRIPTION: set stream format to kernel via v4l2 ioctl
   2795  *
   2796  * PARAMETERS :
   2797  *   @my_obj  : stream object
   2798  *
   2799  * RETURN     : int32_t type of status
   2800  *              0  -- success
   2801  *              -1 -- failure
   2802  *==========================================================================*/
   2803 int32_t mm_stream_set_fmt(mm_stream_t *my_obj)
   2804 {
   2805     int32_t rc = 0;
   2806     struct v4l2_format fmt;
   2807     struct msm_v4l2_format_data msm_fmt;
   2808     int i;
   2809 
   2810     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   2811          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   2812 
   2813     if (my_obj->stream_info->dim.width == 0 ||
   2814         my_obj->stream_info->dim.height == 0) {
   2815         CDBG_ERROR("%s:invalid input[w=%d,h=%d,fmt=%d]\n",
   2816                    __func__,
   2817                    my_obj->stream_info->dim.width,
   2818                    my_obj->stream_info->dim.height,
   2819                    my_obj->stream_info->fmt);
   2820         return -1;
   2821     }
   2822 
   2823     memset(&fmt, 0, sizeof(fmt));
   2824     memset(&msm_fmt, 0, sizeof(msm_fmt));
   2825     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2826     msm_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2827     msm_fmt.width = my_obj->stream_info->dim.width;
   2828     msm_fmt.height = my_obj->stream_info->dim.height;
   2829     msm_fmt.pixelformat = mm_stream_get_v4l2_fmt(my_obj->stream_info->fmt);
   2830     msm_fmt.num_planes = my_obj->frame_offset.num_planes;
   2831     for (i = 0; i < msm_fmt.num_planes; i++) {
   2832         msm_fmt.plane_sizes[i] = my_obj->frame_offset.mp[i].len;
   2833     }
   2834 
   2835     memcpy(fmt.fmt.raw_data, &msm_fmt, sizeof(msm_fmt));
   2836     rc = ioctl(my_obj->fd, VIDIOC_S_FMT, &fmt);
   2837     return rc;
   2838 }
   2839 
   2840 /*===========================================================================
   2841  * FUNCTION   : mm_stream_buf_done
   2842  *
   2843  * DESCRIPTION: enqueue buffer back to kernel
   2844  *
   2845  * PARAMETERS :
   2846  *   @my_obj       : stream object
   2847  *   @frame        : frame to be enqueued back to kernel
   2848  *
   2849  * RETURN     : int32_t type of status
   2850  *              0  -- success
   2851  *              -1 -- failure
   2852  *==========================================================================*/
   2853 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
   2854                            mm_camera_buf_def_t *frame)
   2855 {
   2856     int32_t rc = 0;
   2857     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   2858          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   2859 
   2860     pthread_mutex_lock(&my_obj->buf_lock);
   2861     if(my_obj->buf_status[frame->buf_idx].buf_refcnt == 0) {
   2862         CDBG("%s: Error Trying to free second time?(idx=%d) count=%d\n",
   2863                    __func__, frame->buf_idx,
   2864                    my_obj->buf_status[frame->buf_idx].buf_refcnt);
   2865         rc = -1;
   2866     }else{
   2867         my_obj->buf_status[frame->buf_idx].buf_refcnt--;
   2868         if (0 == my_obj->buf_status[frame->buf_idx].buf_refcnt) {
   2869             CDBG("<DEBUG> : Buf done for buffer:%d, stream:%d", frame->buf_idx, frame->stream_type);
   2870             rc = mm_stream_qbuf(my_obj, frame);
   2871             if(rc < 0) {
   2872                 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
   2873                            __func__, frame->buf_idx, rc);
   2874             } else {
   2875                 my_obj->buf_status[frame->buf_idx].in_kernel = 1;
   2876             }
   2877         }else{
   2878             CDBG("<DEBUG> : Still ref count pending count :%d",
   2879                  my_obj->buf_status[frame->buf_idx].buf_refcnt);
   2880             CDBG("<DEBUG> : for buffer:%p:%d",
   2881                  my_obj, frame->buf_idx);
   2882         }
   2883     }
   2884     pthread_mutex_unlock(&my_obj->buf_lock);
   2885     return rc;
   2886 }
   2887 
   2888 /*===========================================================================
   2889  * FUNCTION   : mm_stream_reg_buf_cb
   2890  *
   2891  * DESCRIPTION: Allow other stream to register dataCB at this stream.
   2892  *
   2893  * PARAMETERS :
   2894  *   @my_obj       : stream object
   2895  *   @val          : ptr to info about the callback to be registered
   2896  *
   2897  * RETURN     : int32_t type of status
   2898  *              0  -- success
   2899  *              -1 -- failure
   2900  *==========================================================================*/
   2901 int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
   2902                              mm_stream_data_cb_t *val)
   2903 {
   2904     int32_t rc = -1;
   2905     uint8_t i;
   2906     CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
   2907          __func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
   2908 
   2909     pthread_mutex_lock(&my_obj->cb_lock);
   2910     for (i=0 ;i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
   2911         if(NULL == my_obj->buf_cb[i].cb) {
   2912             my_obj->buf_cb[i] = *val;
   2913             rc = 0;
   2914             break;
   2915         }
   2916     }
   2917     pthread_mutex_unlock(&my_obj->cb_lock);
   2918 
   2919     return rc;
   2920 }
   2921