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