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