• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 // System dependencies
31 #include <stdlib.h>
32 #include <pthread.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <media/msm_media_info.h>
36 #define TIME_H <SYSTEM_HEADER_PREFIX/time.h>
37 #include TIME_H
38 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
39 #include IOCTL_H
40 #include <cutils/properties.h>
41 
42 #define ATRACE_TAG ATRACE_TAG_CAMERA
43 #include <cutils/trace.h>
44 
45 // Camera dependencies
46 #include "cam_semaphore.h"
47 #include "mm_camera_dbg.h"
48 #include "mm_camera_interface.h"
49 #include "mm_camera.h"
50 #include "mm_camera_muxer.h"
51 
52 /* internal function decalre */
53 int32_t mm_stream_qbuf(mm_stream_t *my_obj,
54                        mm_camera_buf_def_t *buf);
55 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj);
56 int32_t mm_stream_set_fmt(mm_stream_t * my_obj);
57 int32_t mm_stream_cancel_buf(mm_stream_t * my_obj,
58                            uint32_t buf_idx);
59 int32_t mm_stream_sync_info(mm_stream_t *my_obj);
60 int32_t mm_stream_init_bufs(mm_stream_t * my_obj);
61 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj);
62 int32_t mm_stream_request_buf(mm_stream_t * my_obj);
63 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj);
64 int32_t mm_stream_release(mm_stream_t *my_obj);
65 int32_t mm_stream_set_parm(mm_stream_t *my_obj,
66                            cam_stream_parm_buffer_t *value);
67 int32_t mm_stream_get_parm(mm_stream_t *my_obj,
68                            cam_stream_parm_buffer_t *value);
69 int32_t mm_stream_do_action(mm_stream_t *my_obj,
70                             void *in_value);
71 int32_t mm_stream_streamon(mm_stream_t *my_obj);
72 int32_t mm_stream_start_sensor_streaming(mm_stream_t *my_obj);
73 int32_t mm_stream_streamoff(mm_stream_t *my_obj, bool stop_immediately);
74 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
75                                  mm_camera_buf_info_t* buf_info,
76                                  uint8_t num_planes);
77 int32_t mm_stream_read_user_buf(mm_stream_t * my_obj,
78         mm_camera_buf_info_t* buf_info);
79 int32_t mm_stream_write_user_buf(mm_stream_t * my_obj,
80         mm_camera_buf_def_t *buf);
81 
82 int32_t mm_stream_init(mm_stream_t *my_obj);
83 int32_t mm_stream_deinit(mm_stream_t *my_obj);
84 int32_t mm_stream_config(mm_stream_t *my_obj,
85                          mm_camera_stream_config_t *config);
86 int32_t mm_stream_reg_buf(mm_stream_t * my_obj);
87 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
88                            mm_camera_buf_def_t *frame);
89 int32_t mm_stream_get_queued_buf_count(mm_stream_t * my_obj);
90 
91 int32_t mm_stream_calc_offset(mm_stream_t *my_obj);
92 int32_t mm_stream_calc_offset_preview(cam_stream_info_t *stream_info,
93                                       cam_dimension_t *dim,
94                                       cam_padding_info_t *padding,
95                                       cam_stream_buf_plane_info_t *buf_planes);
96 int32_t mm_stream_calc_offset_post_view(cam_stream_info_t *stream_info,
97                                       cam_dimension_t *dim,
98                                       cam_padding_info_t *padding,
99                                       cam_stream_buf_plane_info_t *buf_planes);
100 
101 int32_t mm_stream_calc_offset_snapshot(cam_format_t fmt,
102                                        cam_dimension_t *dim,
103                                        cam_padding_info_t *padding,
104                                        cam_stream_buf_plane_info_t *buf_planes);
105 int32_t mm_stream_calc_offset_raw(cam_format_t fmt,
106                                   cam_dimension_t *dim,
107                                   cam_padding_info_t *padding,
108                                   cam_stream_buf_plane_info_t *buf_planes);
109 int32_t mm_stream_calc_offset_video(cam_format_t fmt,
110         cam_dimension_t *dim,
111         cam_stream_buf_plane_info_t *buf_planes);
112 int32_t mm_stream_calc_offset_metadata(cam_dimension_t *dim,
113                                        cam_padding_info_t *padding,
114                                        cam_stream_buf_plane_info_t *buf_planes);
115 int32_t mm_stream_calc_offset_postproc(cam_stream_info_t *stream_info,
116                                        cam_padding_info_t *padding,
117                                        cam_stream_buf_plane_info_t *plns);
118 uint32_t mm_stream_calc_lcm(int32_t num1, int32_t num2);
119 
120 
121 /* state machine function declare */
122 int32_t mm_stream_fsm_inited(mm_stream_t * my_obj,
123                              mm_stream_evt_type_t evt,
124                              void * in_val,
125                              void * out_val);
126 int32_t mm_stream_fsm_acquired(mm_stream_t * my_obj,
127                                mm_stream_evt_type_t evt,
128                                void * in_val,
129                                void * out_val);
130 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
131                           mm_stream_evt_type_t evt,
132                           void * in_val,
133                           void * out_val);
134 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
135                              mm_stream_evt_type_t evt,
136                              void * in_val,
137                              void * out_val);
138 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
139                           mm_stream_evt_type_t evt,
140                           void * in_val,
141                           void * out_val);
142 int32_t mm_stream_fsm_active(mm_stream_t * my_obj,
143                              mm_stream_evt_type_t evt,
144                              void * in_val,
145                              void * out_val);
146 uint32_t mm_stream_get_v4l2_fmt(cam_format_t fmt);
147 int32_t mm_stream_reg_frame_sync(mm_stream_t *my_obj,
148         mm_evt_paylod_reg_frame_sync *sync);
149 int32_t mm_stream_handle_cache_ops(mm_stream_t* my_obj,
150         mm_camera_buf_def_t* buf, bool deque);
151 int32_t mm_stream_trigger_frame_sync(mm_stream_t *my_obj,
152         mm_camera_cb_req_type type);
153 
154 /*===========================================================================
155  * FUNCTION   : mm_stream_notify_channel
156  *
157  * DESCRIPTION: function to notify channel object on received buffer
158  *
159  * PARAMETERS :
160  *   @ch_obj  : channel object
161  *   @buf_info: ptr to struct storing buffer information
162  *
163  * RETURN     : int32_t type of status
164  *              0  -- success
165  *              0> -- failure
166  *==========================================================================*/
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     default:
3657         LOGE("Invalid cam_format for snapshot %d",
3658                     fmt);
3659         rc = -1;
3660         break;
3661     }
3662 
3663     return rc;
3664 }
3665 
3666 /*===========================================================================
3667  * FUNCTION   : mm_stream_calc_offset_raw
3668  *
3669  * DESCRIPTION: calculate raw frame offset based on format and padding information
3670  *
3671  * PARAMETERS :
3672  *   @fmt     : image format
3673  *   @dim     : image dimension
3674  *   @padding : padding information
3675  *   @buf_planes : [out] buffer plane information
3676  *
3677  * RETURN     : int32_t type of status
3678  *              0  -- success
3679  *              -1 -- failure
3680  *==========================================================================*/
mm_stream_calc_offset_raw(cam_format_t fmt,cam_dimension_t * dim,cam_padding_info_t * padding,cam_stream_buf_plane_info_t * buf_planes)3681 int32_t mm_stream_calc_offset_raw(cam_format_t fmt,
3682                                   cam_dimension_t *dim,
3683                                   cam_padding_info_t *padding,
3684                                   cam_stream_buf_plane_info_t *buf_planes)
3685 {
3686     int32_t rc = 0;
3687 
3688     if ((NULL == dim) || (NULL == padding) || (NULL == buf_planes)) {
3689         return -1;
3690     }
3691 
3692     int32_t stride = PAD_TO_SIZE(dim->width, (int32_t)padding->width_padding);
3693     int32_t stride_in_bytes = stride;
3694     int32_t scanline = PAD_TO_SIZE(dim->height, (int32_t)padding->height_padding);
3695 
3696     switch (fmt) {
3697     case CAM_FORMAT_YUV_420_NV21:
3698         /* 2 planes: Y + CbCr */
3699         buf_planes->plane_info.num_planes = 2;
3700 
3701         buf_planes->plane_info.mp[0].len =
3702                 PAD_TO_SIZE((uint32_t)(stride * scanline),
3703                 padding->plane_padding);
3704         buf_planes->plane_info.mp[0].offset = 0;
3705         buf_planes->plane_info.mp[0].offset_x = 0;
3706         buf_planes->plane_info.mp[0].offset_y = 0;
3707         buf_planes->plane_info.mp[0].stride = stride;
3708         buf_planes->plane_info.mp[0].stride_in_bytes = stride;
3709         buf_planes->plane_info.mp[0].scanline = scanline;
3710         buf_planes->plane_info.mp[0].width = dim->width;
3711         buf_planes->plane_info.mp[0].height = dim->height;
3712 
3713         scanline = scanline / 2;
3714         buf_planes->plane_info.mp[1].len =
3715                 PAD_TO_SIZE((uint32_t)(stride * scanline),
3716                 padding->plane_padding);
3717         buf_planes->plane_info.mp[1].offset = 0;
3718         buf_planes->plane_info.mp[1].offset_x = 0;
3719         buf_planes->plane_info.mp[1].offset_y = 0;
3720         buf_planes->plane_info.mp[1].stride = stride;
3721         buf_planes->plane_info.mp[1].stride_in_bytes = stride;
3722         buf_planes->plane_info.mp[1].scanline = scanline;
3723         buf_planes->plane_info.mp[1].width = dim->width;
3724         buf_planes->plane_info.mp[1].height = dim->height / 2;
3725 
3726         buf_planes->plane_info.frame_len =
3727                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
3728                 buf_planes->plane_info.mp[1].len,
3729                 CAM_PAD_TO_4K);
3730         break;
3731     case CAM_FORMAT_YUV_RAW_8BIT_YUYV:
3732     case CAM_FORMAT_YUV_RAW_8BIT_YVYU:
3733     case CAM_FORMAT_YUV_RAW_8BIT_UYVY:
3734     case CAM_FORMAT_YUV_RAW_8BIT_VYUY:
3735     case CAM_FORMAT_JPEG_RAW_8BIT:
3736         /* 1 plane */
3737         /* Every 16 pixels occupy 16 bytes */
3738         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
3739         stride_in_bytes = stride * 2;
3740         buf_planes->plane_info.num_planes = 1;
3741         buf_planes->plane_info.mp[0].offset = 0;
3742         buf_planes->plane_info.mp[0].len =
3743                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3744                         padding->plane_padding);
3745         buf_planes->plane_info.frame_len =
3746                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3747         buf_planes->plane_info.mp[0].offset_x =0;
3748         buf_planes->plane_info.mp[0].offset_y = 0;
3749         buf_planes->plane_info.mp[0].stride = stride;
3750         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3751         buf_planes->plane_info.mp[0].scanline = scanline;
3752         buf_planes->plane_info.mp[0].width =
3753                 (int32_t)buf_planes->plane_info.mp[0].len;
3754         buf_planes->plane_info.mp[0].height = 1;
3755         break;
3756     case CAM_FORMAT_META_RAW_8BIT:
3757         // Every 16 pixels occupy 16 bytes
3758         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
3759         stride_in_bytes = stride * 2;
3760         buf_planes->plane_info.num_planes = 1;
3761         buf_planes->plane_info.mp[0].offset = 0;
3762         buf_planes->plane_info.mp[0].len =
3763                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3764                         padding->plane_padding);
3765         buf_planes->plane_info.frame_len =
3766                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3767         buf_planes->plane_info.mp[0].offset_x =0;
3768         buf_planes->plane_info.mp[0].offset_y = 0;
3769         buf_planes->plane_info.mp[0].stride = stride;
3770         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3771         buf_planes->plane_info.mp[0].scanline = scanline;
3772         break;
3773 
3774     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GBRG:
3775     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GRBG:
3776     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_RGGB:
3777     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_BGGR:
3778     case CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GREY:
3779     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG:
3780     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GRBG:
3781     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_RGGB:
3782     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_BGGR:
3783     case CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GREY:
3784     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GBRG:
3785     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GRBG:
3786     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_RGGB:
3787     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_BGGR:
3788     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_8BPP_GREY:
3789     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GBRG:
3790     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GRBG:
3791     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_RGGB:
3792     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_BGGR:
3793     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_8BPP_GREY:
3794     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_GBRG:
3795     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_GRBG:
3796     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_RGGB:
3797     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN8_8BPP_BGGR:
3798         /* 1 plane */
3799         /* Every 16 pixels occupy 16 bytes */
3800         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
3801         stride_in_bytes = stride;
3802         buf_planes->plane_info.num_planes = 1;
3803         buf_planes->plane_info.mp[0].offset = 0;
3804         buf_planes->plane_info.mp[0].len =
3805                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3806                         padding->plane_padding);
3807         buf_planes->plane_info.frame_len =
3808                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3809         buf_planes->plane_info.mp[0].offset_x =0;
3810         buf_planes->plane_info.mp[0].offset_y = 0;
3811         buf_planes->plane_info.mp[0].stride = stride;
3812         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3813         buf_planes->plane_info.mp[0].scanline = scanline;
3814         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
3815         buf_planes->plane_info.mp[0].height = 1;
3816         break;
3817     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG:
3818     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GRBG:
3819     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_RGGB:
3820     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_BGGR:
3821     case CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GREY:
3822     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GBRG:
3823     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GRBG:
3824     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_RGGB:
3825     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_BGGR:
3826     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_10BPP_GREY:
3827         /* Every 12 pixels occupy 16 bytes */
3828         stride = (dim->width + 11)/12 * 12;
3829         stride_in_bytes = stride * 8 / 6;
3830         buf_planes->plane_info.num_planes = 1;
3831         buf_planes->plane_info.mp[0].offset = 0;
3832         buf_planes->plane_info.mp[0].len =
3833                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3834                         padding->plane_padding);
3835         buf_planes->plane_info.frame_len =
3836                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3837         buf_planes->plane_info.mp[0].offset_x =0;
3838         buf_planes->plane_info.mp[0].offset_y = 0;
3839         buf_planes->plane_info.mp[0].stride = stride;
3840         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3841         buf_planes->plane_info.mp[0].scanline = scanline;
3842         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
3843         buf_planes->plane_info.mp[0].height = 1;
3844         break;
3845     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GBRG:
3846     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GRBG:
3847     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_RGGB:
3848     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_BGGR:
3849     case CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GREY:
3850     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GBRG:
3851     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GRBG:
3852     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_RGGB:
3853     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_BGGR:
3854     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_12BPP_GREY:
3855         /* Every 10 pixels occupy 16 bytes */
3856         stride = (dim->width + 9)/10 * 10;
3857         stride_in_bytes = stride * 8 / 5;
3858         buf_planes->plane_info.num_planes = 1;
3859         buf_planes->plane_info.mp[0].offset = 0;
3860         buf_planes->plane_info.mp[0].len =
3861                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3862                         padding->plane_padding);
3863         buf_planes->plane_info.frame_len =
3864                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3865         buf_planes->plane_info.mp[0].offset_x =0;
3866         buf_planes->plane_info.mp[0].offset_y = 0;
3867         buf_planes->plane_info.mp[0].stride = stride;
3868         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3869         buf_planes->plane_info.mp[0].scanline = scanline;
3870         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
3871         buf_planes->plane_info.mp[0].height = 1;
3872         break;
3873     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG:
3874     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GRBG:
3875     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_RGGB:
3876     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_BGGR:
3877     case CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GREY:
3878     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GBRG:
3879     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GRBG:
3880     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_RGGB:
3881     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_BGGR:
3882     case CAM_FORMAT_META_RAW_10BIT:
3883     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GREY:
3884         /* Every 64 pixels occupy 80 bytes */
3885         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_4);
3886         stride_in_bytes = PAD_TO_SIZE(stride * 5 / 4, CAM_PAD_TO_8);
3887         buf_planes->plane_info.num_planes = 1;
3888         buf_planes->plane_info.mp[0].offset = 0;
3889         buf_planes->plane_info.mp[0].len =
3890                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3891                         padding->plane_padding);
3892         buf_planes->plane_info.frame_len =
3893                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3894         buf_planes->plane_info.mp[0].offset_x =0;
3895         buf_planes->plane_info.mp[0].offset_y = 0;
3896         buf_planes->plane_info.mp[0].stride = stride;
3897         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3898         buf_planes->plane_info.mp[0].scanline = scanline;
3899         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
3900         buf_planes->plane_info.mp[0].height = 1;
3901         break;
3902     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GBRG:
3903     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GRBG:
3904     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_RGGB:
3905     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR:
3906     case CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GREY:
3907     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GBRG:
3908     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GRBG:
3909     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_RGGB:
3910     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_BGGR:
3911     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_12BPP_GREY:
3912         /* Every 32 pixels occupy 48 bytes */
3913         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_32);
3914         stride_in_bytes = stride * 3 / 2;
3915         buf_planes->plane_info.num_planes = 1;
3916         buf_planes->plane_info.mp[0].offset = 0;
3917         buf_planes->plane_info.mp[0].len =
3918                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3919                         padding->plane_padding);
3920         buf_planes->plane_info.frame_len =
3921                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3922         buf_planes->plane_info.mp[0].offset_x =0;
3923         buf_planes->plane_info.mp[0].offset_y = 0;
3924         buf_planes->plane_info.mp[0].stride = stride;
3925         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3926         buf_planes->plane_info.mp[0].scanline = scanline;
3927         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
3928         buf_planes->plane_info.mp[0].height = 1;
3929         break;
3930     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_GBRG:
3931     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_GRBG:
3932     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_RGGB:
3933     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_8BPP_BGGR:
3934     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_GBRG:
3935     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_GRBG:
3936     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_RGGB:
3937     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_10BPP_BGGR:
3938     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_GBRG:
3939     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_GRBG:
3940     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_RGGB:
3941     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_12BPP_BGGR:
3942     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_14BPP_GBRG:
3943     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_14BPP_GRBG:
3944     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_14BPP_RGGB:
3945     case CAM_FORMAT_BAYER_IDEAL_RAW_PLAIN16_14BPP_BGGR:
3946         /* Every 8 pixels occupy 16 bytes */
3947         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_8);
3948         stride_in_bytes = stride * 2;
3949         buf_planes->plane_info.num_planes = 1;
3950         buf_planes->plane_info.mp[0].offset = 0;
3951         buf_planes->plane_info.mp[0].len =
3952                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3953                         padding->plane_padding);
3954         buf_planes->plane_info.frame_len =
3955                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3956         buf_planes->plane_info.mp[0].offset_x =0;
3957         buf_planes->plane_info.mp[0].offset_y = 0;
3958         buf_planes->plane_info.mp[0].stride = stride;
3959         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3960         buf_planes->plane_info.mp[0].scanline = scanline;
3961         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
3962         buf_planes->plane_info.mp[0].height = 1;
3963         break;
3964     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_GBRG:
3965     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_GRBG:
3966     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_RGGB:
3967     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_BGGR:
3968     case CAM_FORMAT_BAYER_MIPI_RAW_14BPP_GREY:
3969     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_GBRG:
3970     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_GRBG:
3971     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_RGGB:
3972     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_BGGR:
3973     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_14BPP_GREY:
3974         /* Every 64 pixels occupy 112 bytes */
3975         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_64);
3976         stride_in_bytes = stride * 7 / 4;
3977         buf_planes->plane_info.num_planes = 1;
3978         buf_planes->plane_info.mp[0].offset = 0;
3979         buf_planes->plane_info.mp[0].len =
3980                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
3981                 padding->plane_padding);
3982         buf_planes->plane_info.frame_len =
3983                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
3984         buf_planes->plane_info.mp[0].offset_x =0;
3985         buf_planes->plane_info.mp[0].offset_y = 0;
3986         buf_planes->plane_info.mp[0].stride = stride;
3987         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
3988         buf_planes->plane_info.mp[0].scanline = scanline;
3989         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
3990         buf_planes->plane_info.mp[0].height = 1;
3991         break;
3992     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_GBRG:
3993     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_GRBG:
3994     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_RGGB:
3995     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_BGGR:
3996     case CAM_FORMAT_BAYER_QCOM_RAW_14BPP_GREY:
3997     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_GBRG:
3998     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_GRBG:
3999     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_RGGB:
4000     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_BGGR:
4001     case CAM_FORMAT_BAYER_IDEAL_RAW_QCOM_14BPP_GREY:
4002         /* Every 16 pixels occupy 32 bytes */
4003         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_16);
4004         stride_in_bytes = stride * 2;
4005         buf_planes->plane_info.num_planes = 1;
4006         buf_planes->plane_info.mp[0].offset = 0;
4007         buf_planes->plane_info.mp[0].len =
4008                 PAD_TO_SIZE((uint32_t)(stride_in_bytes * scanline),
4009                 padding->plane_padding);
4010         buf_planes->plane_info.frame_len =
4011                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
4012         buf_planes->plane_info.mp[0].offset_x =0;
4013         buf_planes->plane_info.mp[0].offset_y = 0;
4014         buf_planes->plane_info.mp[0].stride = stride;
4015         buf_planes->plane_info.mp[0].stride_in_bytes = stride_in_bytes;
4016         buf_planes->plane_info.mp[0].scanline = scanline;
4017         buf_planes->plane_info.mp[0].width = (int32_t)buf_planes->plane_info.mp[0].len;
4018         buf_planes->plane_info.mp[0].height = 1;
4019         break;
4020     default:
4021         LOGE("Invalid cam_format %d for raw stream",
4022                     fmt);
4023         rc = -1;
4024         break;
4025     }
4026 
4027     return rc;
4028 }
4029 
4030 /*===========================================================================
4031  * FUNCTION   : mm_stream_calc_offset_video
4032  *
4033  * DESCRIPTION: calculate video frame offset based on format and
4034  *              padding information
4035  *
4036  * PARAMETERS :
4037   *   @fmt     : image format
4038  *   @dim     : image dimension
4039  *   @buf_planes : [out] buffer plane information
4040  *
4041  * RETURN     : int32_t type of status
4042  *              0  -- success
4043  *              -1 -- failure
4044  *==========================================================================*/
mm_stream_calc_offset_video(cam_format_t fmt,cam_dimension_t * dim,cam_stream_buf_plane_info_t * buf_planes)4045 int32_t mm_stream_calc_offset_video(cam_format_t fmt,
4046         cam_dimension_t *dim, cam_stream_buf_plane_info_t *buf_planes)
4047 {
4048     int32_t rc = 0;
4049     int stride = 0, scanline = 0;
4050 
4051     #ifdef UBWC_PRESENT
4052     int meta_stride = 0,meta_scanline = 0;
4053     #endif
4054 
4055 
4056     switch (fmt) {
4057         case CAM_FORMAT_YUV_420_NV12:
4058         case CAM_FORMAT_Y_ONLY:
4059         case CAM_FORMAT_Y_ONLY_10_BPP:
4060         case CAM_FORMAT_Y_ONLY_12_BPP:
4061         case CAM_FORMAT_Y_ONLY_14_BPP:
4062             buf_planes->plane_info.num_planes = 2;
4063 
4064             stride = dim->width;
4065             scanline = dim->height;
4066             buf_planes->plane_info.mp[0].len =
4067                     PAD_TO_SIZE((uint32_t)(stride * scanline),
4068                     CAM_PAD_TO_2K);
4069             buf_planes->plane_info.mp[0].offset = 0;
4070             buf_planes->plane_info.mp[0].offset_x =0;
4071             buf_planes->plane_info.mp[0].offset_y = 0;
4072             buf_planes->plane_info.mp[0].stride = stride;
4073             buf_planes->plane_info.mp[0].scanline = scanline;
4074             buf_planes->plane_info.mp[0].width = dim->width;
4075             buf_planes->plane_info.mp[0].height = dim->height;
4076 
4077             stride = dim->width;
4078             scanline = dim->height / 2;
4079             buf_planes->plane_info.mp[1].len =
4080                     PAD_TO_SIZE((uint32_t)(stride * scanline),
4081                     CAM_PAD_TO_2K);
4082             buf_planes->plane_info.mp[1].offset = 0;
4083             buf_planes->plane_info.mp[1].offset_x =0;
4084             buf_planes->plane_info.mp[1].offset_y = 0;
4085             buf_planes->plane_info.mp[1].stride = stride;
4086             buf_planes->plane_info.mp[1].scanline = scanline;
4087             buf_planes->plane_info.mp[1].width = dim->width;
4088             buf_planes->plane_info.mp[1].height = dim->height / 2;
4089 
4090             buf_planes->plane_info.frame_len =
4091                     PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
4092                     buf_planes->plane_info.mp[1].len,
4093                     CAM_PAD_TO_4K);
4094             break;
4095         case CAM_FORMAT_YUV_420_NV12_VENUS:
4096 #ifdef VENUS_PRESENT
4097             // using Venus
4098             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
4099             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
4100 
4101             buf_planes->plane_info.frame_len =
4102                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12, dim->width, dim->height);
4103             buf_planes->plane_info.num_planes = 2;
4104             buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
4105             buf_planes->plane_info.mp[0].offset = 0;
4106             buf_planes->plane_info.mp[0].offset_x =0;
4107             buf_planes->plane_info.mp[0].offset_y = 0;
4108             buf_planes->plane_info.mp[0].stride = stride;
4109             buf_planes->plane_info.mp[0].scanline = scanline;
4110             buf_planes->plane_info.mp[0].width = dim->width;
4111             buf_planes->plane_info.mp[0].height = dim->height;
4112             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
4113             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
4114             buf_planes->plane_info.mp[1].len =
4115                     buf_planes->plane_info.frame_len -
4116                     buf_planes->plane_info.mp[0].len;
4117             buf_planes->plane_info.mp[1].offset = 0;
4118             buf_planes->plane_info.mp[1].offset_x =0;
4119             buf_planes->plane_info.mp[1].offset_y = 0;
4120             buf_planes->plane_info.mp[1].stride = stride;
4121             buf_planes->plane_info.mp[1].scanline = scanline;
4122             buf_planes->plane_info.mp[1].width = dim->width;
4123             buf_planes->plane_info.mp[1].height = dim->height/2;
4124 #else
4125             LOGD("Video format VENUS is not supported = %d",
4126                      fmt);
4127 #endif
4128             break;
4129         case CAM_FORMAT_YUV_420_NV21_VENUS:
4130 #ifdef VENUS_PRESENT
4131             // using Venus
4132             stride = VENUS_Y_STRIDE(COLOR_FMT_NV21, dim->width);
4133             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV21, dim->height);
4134 
4135             buf_planes->plane_info.frame_len =
4136                     VENUS_BUFFER_SIZE(COLOR_FMT_NV21, dim->width, dim->height);
4137             buf_planes->plane_info.num_planes = 2;
4138             buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
4139             buf_planes->plane_info.mp[0].offset = 0;
4140             buf_planes->plane_info.mp[0].offset_x =0;
4141             buf_planes->plane_info.mp[0].offset_y = 0;
4142             buf_planes->plane_info.mp[0].stride = stride;
4143             buf_planes->plane_info.mp[0].scanline = scanline;
4144             buf_planes->plane_info.mp[0].width = dim->width;
4145             buf_planes->plane_info.mp[0].height = dim->height;
4146             stride = VENUS_UV_STRIDE(COLOR_FMT_NV21, dim->width);
4147             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV21, dim->height);
4148             buf_planes->plane_info.mp[1].len =
4149                     buf_planes->plane_info.frame_len -
4150                     buf_planes->plane_info.mp[0].len;
4151             buf_planes->plane_info.mp[1].offset = 0;
4152             buf_planes->plane_info.mp[1].offset_x =0;
4153             buf_planes->plane_info.mp[1].offset_y = 0;
4154             buf_planes->plane_info.mp[1].stride = stride;
4155             buf_planes->plane_info.mp[1].scanline = scanline;
4156             buf_planes->plane_info.mp[1].width = dim->width;
4157             buf_planes->plane_info.mp[1].height = dim->height / 2;
4158 #else
4159             LOGD("Video format VENUS is not supported = %d",
4160                      fmt);
4161 #endif
4162             break;
4163         case CAM_FORMAT_YUV_420_NV12_UBWC:
4164 #ifdef UBWC_PRESENT
4165             // using UBWC
4166             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
4167             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
4168             meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
4169             meta_scanline = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
4170 
4171             buf_planes->plane_info.frame_len =
4172                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, dim->width, dim->height);
4173             buf_planes->plane_info.num_planes = 2;
4174             buf_planes->plane_info.mp[0].offset = 0;
4175             buf_planes->plane_info.mp[0].offset_x =0;
4176             buf_planes->plane_info.mp[0].offset_y = 0;
4177             buf_planes->plane_info.mp[0].stride = stride;
4178             buf_planes->plane_info.mp[0].scanline = scanline;
4179             buf_planes->plane_info.mp[0].width = dim->width;
4180             buf_planes->plane_info.mp[0].height = dim->height;
4181             buf_planes->plane_info.mp[0].meta_stride = meta_stride;
4182             buf_planes->plane_info.mp[0].meta_scanline = meta_scanline;
4183             buf_planes->plane_info.mp[0].meta_len =
4184                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
4185             buf_planes->plane_info.mp[0].len =
4186                     (uint32_t)(MSM_MEDIA_ALIGN((stride * scanline), 4096) +
4187                     (buf_planes->plane_info.mp[0].meta_len));
4188 
4189             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
4190             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
4191             meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
4192             meta_scanline = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
4193 
4194             buf_planes->plane_info.mp[1].offset = 0;
4195             buf_planes->plane_info.mp[1].offset_x =0;
4196             buf_planes->plane_info.mp[1].offset_y = 0;
4197             buf_planes->plane_info.mp[1].stride = stride;
4198             buf_planes->plane_info.mp[1].scanline = scanline;
4199             buf_planes->plane_info.mp[1].width = dim->width;
4200             buf_planes->plane_info.mp[1].height = dim->height/2;
4201             buf_planes->plane_info.mp[1].meta_stride = meta_stride;
4202             buf_planes->plane_info.mp[1].meta_scanline = meta_scanline;
4203             buf_planes->plane_info.mp[1].meta_len =
4204                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
4205             buf_planes->plane_info.mp[1].len =
4206                     buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
4207 
4208 #else
4209             LOGD("Video format UBWC is not supported = %d",
4210                      fmt);
4211             rc = -1;
4212 #endif
4213             break;
4214         default:
4215             LOGD("Invalid Video Format = %d", fmt);
4216             rc = -1;
4217             break;
4218     }
4219     return rc;
4220 }
4221 
4222 /*===========================================================================
4223  * FUNCTION   : mm_stream_calc_offset_metadata
4224  *
4225  * DESCRIPTION: calculate metadata frame offset based on format and
4226  *              padding information
4227  *
4228  * PARAMETERS :
4229  *   @dim     : image dimension
4230  *   @padding : padding information
4231  *   @buf_planes : [out] buffer plane information
4232  *
4233  * RETURN     : int32_t type of status
4234  *              0  -- success
4235  *              -1 -- failure
4236  *==========================================================================*/
mm_stream_calc_offset_metadata(cam_dimension_t * dim,cam_padding_info_t * padding,cam_stream_buf_plane_info_t * buf_planes)4237 int32_t mm_stream_calc_offset_metadata(cam_dimension_t *dim,
4238                                        cam_padding_info_t *padding,
4239                                        cam_stream_buf_plane_info_t *buf_planes)
4240 {
4241     int32_t rc = 0;
4242     buf_planes->plane_info.num_planes = 1;
4243     buf_planes->plane_info.mp[0].offset = 0;
4244     buf_planes->plane_info.mp[0].len =
4245             PAD_TO_SIZE((uint32_t)(dim->width * dim->height),
4246                     padding->plane_padding);
4247     buf_planes->plane_info.frame_len =
4248         buf_planes->plane_info.mp[0].len;
4249 
4250     buf_planes->plane_info.mp[0].offset_x =0;
4251     buf_planes->plane_info.mp[0].offset_y = 0;
4252     buf_planes->plane_info.mp[0].stride = dim->width;
4253     buf_planes->plane_info.mp[0].scanline = dim->height;
4254     buf_planes->plane_info.mp[0].width = dim->width;
4255     buf_planes->plane_info.mp[0].height = dim->height;
4256     return rc;
4257 }
4258 
4259 /*===========================================================================
4260  * FUNCTION   : mm_stream_calc_offset_analysis
4261  *
4262  * DESCRIPTION: calculate analysis frame offset based on format and
4263  *              padding information
4264  *
4265  * PARAMETERS :
4266  *   @fmt     : image format
4267  *   @dim     : image dimension
4268  *   @padding : padding information
4269  *   @buf_planes : [out] buffer plane information
4270  *
4271  * RETURN     : int32_t type of status
4272  *              0  -- success
4273  *              -1 -- failure
4274  *==========================================================================*/
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)4275 int32_t mm_stream_calc_offset_analysis(cam_format_t fmt,
4276                                        cam_dimension_t *dim,
4277                                        cam_padding_info_t *padding,
4278                                        cam_stream_buf_plane_info_t *buf_planes)
4279 {
4280     int32_t rc = 0;
4281     int32_t offset_x = 0, offset_y = 0;
4282     int32_t stride, scanline;
4283 
4284     /* Clip to minimum supported bytes per line */
4285     if ((uint32_t)dim->width < padding->min_stride) {
4286         stride = (int32_t)padding->min_stride;
4287     } else {
4288         stride = dim->width;
4289     }
4290 
4291     if ((uint32_t)dim->height < padding->min_scanline) {
4292       scanline = (int32_t)padding->min_scanline;
4293     } else {
4294       scanline = dim->height;
4295     }
4296 
4297     stride = PAD_TO_SIZE(stride, padding->width_padding);
4298     scanline = PAD_TO_SIZE(scanline, padding->height_padding);
4299 
4300     switch (fmt) {
4301     case CAM_FORMAT_YUV_420_NV12:
4302     case CAM_FORMAT_YUV_420_NV21:
4303         /* 2 planes: Y + CbCr */
4304         buf_planes->plane_info.num_planes = 2;
4305 
4306         buf_planes->plane_info.mp[0].len =
4307                 PAD_TO_SIZE((uint32_t)(stride * scanline),
4308                         padding->plane_padding);
4309         buf_planes->plane_info.mp[0].offset =
4310                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
4311                         padding->plane_padding);
4312         buf_planes->plane_info.mp[0].offset_x = offset_x;
4313         buf_planes->plane_info.mp[0].offset_y = offset_y;
4314         buf_planes->plane_info.mp[0].stride = stride;
4315         buf_planes->plane_info.mp[0].scanline = scanline;
4316         buf_planes->plane_info.mp[0].width = dim->width;
4317         buf_planes->plane_info.mp[0].height = dim->height;
4318 
4319         scanline = scanline / 2;
4320         buf_planes->plane_info.mp[1].len =
4321                 PAD_TO_SIZE((uint32_t)(stride * scanline),
4322                         padding->plane_padding);
4323         buf_planes->plane_info.mp[1].offset =
4324                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
4325                         padding->plane_padding);
4326         buf_planes->plane_info.mp[1].offset_x = offset_x;
4327         buf_planes->plane_info.mp[1].offset_y = offset_y;
4328         buf_planes->plane_info.mp[1].stride = stride;
4329         buf_planes->plane_info.mp[1].scanline = scanline;
4330         buf_planes->plane_info.mp[1].width = dim->width;
4331         buf_planes->plane_info.mp[1].height = dim->height / 2;
4332 
4333         buf_planes->plane_info.frame_len =
4334                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
4335                         buf_planes->plane_info.mp[1].len,
4336                         CAM_PAD_TO_4K);
4337         break;
4338     case CAM_FORMAT_YUV_420_YV12:
4339         /* 3 planes: Y + Cr + Cb */
4340         buf_planes->plane_info.num_planes = 3;
4341 
4342         buf_planes->plane_info.mp[0].offset =
4343                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
4344                         padding->plane_padding);
4345         buf_planes->plane_info.mp[0].len =
4346                 PAD_TO_SIZE((uint32_t)(stride * scanline),
4347                         padding->plane_padding);
4348         buf_planes->plane_info.mp[0].offset_x = offset_x;
4349         buf_planes->plane_info.mp[0].offset_y = offset_y;
4350         buf_planes->plane_info.mp[0].stride = stride;
4351         buf_planes->plane_info.mp[0].scanline = scanline;
4352         buf_planes->plane_info.mp[0].width = dim->width;
4353         buf_planes->plane_info.mp[0].height = dim->height;
4354 
4355         stride = PAD_TO_SIZE(stride / 2, CAM_PAD_TO_16);
4356         scanline = scanline / 2;
4357         buf_planes->plane_info.mp[1].offset =
4358                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
4359                         padding->plane_padding);
4360         buf_planes->plane_info.mp[1].len =
4361                 PAD_TO_SIZE((uint32_t)(stride * scanline),
4362                         padding->plane_padding);
4363         buf_planes->plane_info.mp[1].offset_x = offset_x;
4364         buf_planes->plane_info.mp[1].offset_y = offset_y;
4365         buf_planes->plane_info.mp[1].stride = stride;
4366         buf_planes->plane_info.mp[1].scanline = scanline;
4367         buf_planes->plane_info.mp[1].width = dim->width / 2;
4368         buf_planes->plane_info.mp[1].height = dim->height / 2;
4369 
4370         buf_planes->plane_info.mp[2].offset =
4371                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
4372                         padding->plane_padding);
4373         buf_planes->plane_info.mp[2].len =
4374                 PAD_TO_SIZE((uint32_t)(stride * scanline),
4375                         padding->plane_padding);
4376         buf_planes->plane_info.mp[2].offset_x = offset_x;
4377         buf_planes->plane_info.mp[2].offset_y = offset_y;
4378         buf_planes->plane_info.mp[2].stride = stride;
4379         buf_planes->plane_info.mp[2].scanline = scanline;
4380         buf_planes->plane_info.mp[2].width = dim->width / 2;
4381         buf_planes->plane_info.mp[2].height = dim->height / 2;
4382 
4383         buf_planes->plane_info.frame_len =
4384                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len +
4385                         buf_planes->plane_info.mp[1].len +
4386                         buf_planes->plane_info.mp[2].len,
4387                         CAM_PAD_TO_4K);
4388         break;
4389     case CAM_FORMAT_YUV_422_NV16:
4390     case CAM_FORMAT_YUV_422_NV61:
4391         /* 2 planes: Y + CbCr */
4392         buf_planes->plane_info.num_planes = 2;
4393         buf_planes->plane_info.mp[0].len =
4394                 PAD_TO_SIZE((uint32_t)(stride * scanline),
4395                         padding->plane_padding);
4396         buf_planes->plane_info.mp[0].offset =
4397                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
4398                         padding->plane_padding);
4399         buf_planes->plane_info.mp[0].offset_x = offset_x;
4400         buf_planes->plane_info.mp[0].offset_y = offset_y;
4401         buf_planes->plane_info.mp[0].stride = stride;
4402         buf_planes->plane_info.mp[0].scanline = scanline;
4403         buf_planes->plane_info.mp[0].width = dim->width;
4404         buf_planes->plane_info.mp[0].height = dim->height;
4405 
4406         buf_planes->plane_info.mp[1].len =
4407                 PAD_TO_SIZE((uint32_t)(stride * scanline),
4408                         padding->plane_padding);
4409         buf_planes->plane_info.mp[1].offset =
4410                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
4411                         padding->plane_padding);
4412         buf_planes->plane_info.mp[1].offset_x = offset_x;
4413         buf_planes->plane_info.mp[1].offset_y = offset_y;
4414         buf_planes->plane_info.mp[1].stride = stride;
4415         buf_planes->plane_info.mp[1].scanline = scanline;
4416         buf_planes->plane_info.mp[1].width = dim->width;
4417         buf_planes->plane_info.mp[1].height = dim->height;
4418 
4419         buf_planes->plane_info.frame_len = PAD_TO_SIZE(
4420             buf_planes->plane_info.mp[0].len + buf_planes->plane_info.mp[1].len,
4421             CAM_PAD_TO_4K);
4422         break;
4423     case CAM_FORMAT_Y_ONLY:
4424     case CAM_FORMAT_Y_ONLY_10_BPP:
4425     case CAM_FORMAT_Y_ONLY_12_BPP:
4426     case CAM_FORMAT_Y_ONLY_14_BPP:
4427         buf_planes->plane_info.num_planes = 1;
4428 
4429         buf_planes->plane_info.mp[0].len =
4430                 PAD_TO_SIZE((uint32_t)(stride * scanline),
4431                 padding->plane_padding);
4432         buf_planes->plane_info.mp[0].offset =
4433                 PAD_TO_SIZE((uint32_t)(offset_x + stride * offset_y),
4434                 padding->plane_padding);
4435         buf_planes->plane_info.mp[0].offset_x = offset_x;
4436         buf_planes->plane_info.mp[0].offset_y = offset_y;
4437         buf_planes->plane_info.mp[0].stride = stride;
4438         buf_planes->plane_info.mp[0].scanline = scanline;
4439         buf_planes->plane_info.mp[0].width = dim->width;
4440         buf_planes->plane_info.mp[0].height = dim->height;
4441         buf_planes->plane_info.frame_len =
4442                 PAD_TO_SIZE(buf_planes->plane_info.mp[0].len, CAM_PAD_TO_4K);
4443         break;
4444     case CAM_FORMAT_YUV_420_NV12_VENUS:
4445 #ifdef VENUS_PRESENT
4446         // using Venus
4447         stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, dim->width);
4448         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12, dim->height);
4449 
4450         buf_planes->plane_info.frame_len =
4451                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, stride, scanline);
4452         buf_planes->plane_info.num_planes = 2;
4453         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
4454         buf_planes->plane_info.mp[0].offset = 0;
4455         buf_planes->plane_info.mp[0].offset_x =0;
4456         buf_planes->plane_info.mp[0].offset_y = 0;
4457         buf_planes->plane_info.mp[0].stride = stride;
4458         buf_planes->plane_info.mp[0].scanline = scanline;
4459         buf_planes->plane_info.mp[0].width = dim->width;
4460         buf_planes->plane_info.mp[0].height = dim->height;
4461         stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, dim->width);
4462         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12, dim->height);
4463         buf_planes->plane_info.mp[1].len =
4464                 buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
4465         buf_planes->plane_info.mp[1].offset = 0;
4466         buf_planes->plane_info.mp[1].offset_x =0;
4467         buf_planes->plane_info.mp[1].offset_y = 0;
4468         buf_planes->plane_info.mp[1].stride = stride;
4469         buf_planes->plane_info.mp[1].scanline = scanline;
4470         buf_planes->plane_info.mp[1].width = dim->width;
4471         buf_planes->plane_info.mp[1].height = dim->height / 2;
4472 #else
4473         LOGE("Venus hardware not avail, cannot use this format");
4474         rc = -1;
4475 #endif
4476         break;
4477     case CAM_FORMAT_YUV_420_NV21_VENUS:
4478 #ifdef VENUS_PRESENT
4479         // using Venus
4480         stride = VENUS_Y_STRIDE(COLOR_FMT_NV21, dim->width);
4481         scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV21, dim->height);
4482 
4483         buf_planes->plane_info.frame_len =
4484                 VENUS_BUFFER_SIZE(COLOR_FMT_NV21, stride, scanline);
4485         buf_planes->plane_info.num_planes = 2;
4486         buf_planes->plane_info.mp[0].len = (uint32_t)(stride * scanline);
4487         buf_planes->plane_info.mp[0].offset = 0;
4488         buf_planes->plane_info.mp[0].offset_x =0;
4489         buf_planes->plane_info.mp[0].offset_y = 0;
4490         buf_planes->plane_info.mp[0].stride = stride;
4491         buf_planes->plane_info.mp[0].scanline = scanline;
4492         buf_planes->plane_info.mp[0].width = dim->width;
4493         buf_planes->plane_info.mp[0].height = dim->height;
4494         stride = VENUS_UV_STRIDE(COLOR_FMT_NV21, dim->width);
4495         scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV21, dim->height);
4496         buf_planes->plane_info.mp[1].len =
4497                 buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
4498         buf_planes->plane_info.mp[1].offset = 0;
4499         buf_planes->plane_info.mp[1].offset_x =0;
4500         buf_planes->plane_info.mp[1].offset_y = 0;
4501         buf_planes->plane_info.mp[1].stride = stride;
4502         buf_planes->plane_info.mp[1].scanline = scanline;
4503         buf_planes->plane_info.mp[1].width = dim->width;
4504         buf_planes->plane_info.mp[1].height = dim->height / 2;
4505 #else
4506         LOGE("Venus hardware not avail, cannot use this format");
4507         rc = -1;
4508 #endif
4509         break;
4510     case CAM_FORMAT_YUV_420_NV12_UBWC:
4511 #ifdef UBWC_PRESENT
4512         {
4513             int meta_stride = 0,meta_scanline = 0;
4514             // using UBWC
4515             stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
4516             scanline = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
4517             meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
4518             meta_scanline = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
4519 
4520             buf_planes->plane_info.frame_len =
4521                     VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, stride, scanline);
4522             buf_planes->plane_info.num_planes = 2;
4523             buf_planes->plane_info.mp[0].offset = 0;
4524             buf_planes->plane_info.mp[0].offset_x =0;
4525             buf_planes->plane_info.mp[0].offset_y = 0;
4526             buf_planes->plane_info.mp[0].stride = stride;
4527             buf_planes->plane_info.mp[0].scanline = scanline;
4528             buf_planes->plane_info.mp[0].width = dim->width;
4529             buf_planes->plane_info.mp[0].height = dim->height;
4530             buf_planes->plane_info.mp[0].meta_stride = meta_stride;
4531             buf_planes->plane_info.mp[0].meta_scanline = meta_scanline;
4532             buf_planes->plane_info.mp[0].meta_len =
4533                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
4534             buf_planes->plane_info.mp[0].len =
4535                     (uint32_t)(MSM_MEDIA_ALIGN((stride * scanline), 4096) +
4536                     (buf_planes->plane_info.mp[0].meta_len));
4537 
4538             stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
4539             scanline = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
4540             meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, dim->width);
4541             meta_scanline = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, dim->height);
4542             buf_planes->plane_info.mp[1].offset = 0;
4543             buf_planes->plane_info.mp[1].offset_x =0;
4544             buf_planes->plane_info.mp[1].offset_y = 0;
4545             buf_planes->plane_info.mp[1].stride = stride;
4546             buf_planes->plane_info.mp[1].scanline = scanline;
4547             buf_planes->plane_info.mp[1].width = dim->width;
4548             buf_planes->plane_info.mp[1].height = dim->height/2;
4549             buf_planes->plane_info.mp[1].meta_stride = meta_stride;
4550             buf_planes->plane_info.mp[1].meta_scanline = meta_scanline;
4551             buf_planes->plane_info.mp[1].meta_len =
4552                     MSM_MEDIA_ALIGN(meta_stride * meta_scanline, 4096);
4553             buf_planes->plane_info.mp[1].len =
4554                     buf_planes->plane_info.frame_len - buf_planes->plane_info.mp[0].len;
4555         }
4556 #else
4557         LOGE("UBWC hardware not avail, cannot use this format");
4558         rc = -1;
4559 #endif
4560         break;
4561     default:
4562         LOGE("Invalid cam_format for anlysis %d",
4563                     fmt);
4564         rc = -1;
4565         break;
4566     }
4567 
4568     return rc;
4569 }
4570 
4571 /*===========================================================================
4572  * FUNCTION   : mm_stream_calc_offset_postproc
4573  *
4574  * DESCRIPTION: calculate postprocess frame offset
4575  *
4576  * PARAMETERS :
4577  *   @stream_info: ptr to stream info
4578  *   @padding : padding information
4579  *   @plns : [out] buffer plane information
4580  *
4581  * RETURN     : int32_t type of status
4582  *              0  -- success
4583  *              -1 -- failure
4584  *==========================================================================*/
mm_stream_calc_offset_postproc(cam_stream_info_t * stream_info,cam_padding_info_t * padding,cam_stream_buf_plane_info_t * plns)4585 int32_t mm_stream_calc_offset_postproc(cam_stream_info_t *stream_info,
4586                                        cam_padding_info_t *padding,
4587                                        cam_stream_buf_plane_info_t *plns)
4588 {
4589     int32_t rc = 0;
4590     cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT;
4591     if (stream_info->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
4592         type = stream_info->reprocess_config.offline.input_type;
4593         if (CAM_STREAM_TYPE_DEFAULT == type) {
4594             if (plns->plane_info.frame_len == 0) {
4595                 // take offset from input source
4596                 *plns = stream_info->reprocess_config.offline.input_buf_planes;
4597                 return rc;
4598             }
4599         } else {
4600             type = stream_info->reprocess_config.offline.input_type;
4601         }
4602     } else {
4603         type = stream_info->reprocess_config.online.input_stream_type;
4604     }
4605 
4606     switch (type) {
4607     case CAM_STREAM_TYPE_PREVIEW:
4608         rc = mm_stream_calc_offset_preview(stream_info,
4609                                            &stream_info->dim,
4610                                            padding,
4611                                            plns);
4612         break;
4613     case CAM_STREAM_TYPE_POSTVIEW:
4614         rc = mm_stream_calc_offset_post_view(stream_info,
4615                                            &stream_info->dim,
4616                                            padding,
4617                                            plns);
4618         break;
4619     case CAM_STREAM_TYPE_SNAPSHOT:
4620     case CAM_STREAM_TYPE_CALLBACK:
4621         rc = mm_stream_calc_offset_snapshot(stream_info->fmt,
4622                                             &stream_info->dim,
4623                                             padding,
4624                                             plns);
4625         break;
4626     case CAM_STREAM_TYPE_VIDEO:
4627         rc = mm_stream_calc_offset_video(stream_info->fmt,
4628                 &stream_info->dim, plns);
4629         break;
4630     case CAM_STREAM_TYPE_RAW:
4631         rc = mm_stream_calc_offset_raw(stream_info->fmt,
4632                                        &stream_info->dim,
4633                                        padding,
4634                                        plns);
4635         break;
4636     case CAM_STREAM_TYPE_ANALYSIS:
4637         rc = mm_stream_calc_offset_analysis(stream_info->fmt,
4638                                             &stream_info->dim,
4639                                             padding,
4640                                             plns);
4641         break;
4642     case CAM_STREAM_TYPE_METADATA:
4643         rc = mm_stream_calc_offset_metadata(&stream_info->dim,
4644                                             padding,
4645                                             plns);
4646         break;
4647     case CAM_STREAM_TYPE_OFFLINE_PROC:
4648         rc = mm_stream_calc_offset_snapshot(stream_info->fmt,
4649                 &stream_info->dim, padding, plns);
4650         break;
4651     default:
4652         LOGE("not supported for stream type %d",
4653                     type);
4654         rc = -1;
4655         break;
4656     }
4657     return rc;
4658 }
4659 
4660 /*===========================================================================
4661 * FUNCTION    : mm_stream_calc_lcm
4662 *
4663 * DESCRIPTION: calculate LCM of two numbers
4664 *
4665 * PARAMETERS :
4666 *   @num1  : number 1
4667 *   @num2  : number 2
4668 *
4669 * RETURN     : uint32_t type
4670 *
4671 *===========================================================================*/
mm_stream_calc_lcm(int32_t num1,int32_t num2)4672 uint32_t mm_stream_calc_lcm(int32_t num1, int32_t num2)
4673 {
4674     uint32_t lcm = 0;
4675     uint32_t temp = 0;
4676 
4677     if ((num1 < 1) && (num2 < 1)) {
4678         return 0;
4679     } else if (num1 < 1) {
4680         return num2;
4681     } else if (num2 < 1) {
4682         return num1;
4683     }
4684 
4685     if (num1 > num2) {
4686         lcm = num1;
4687     } else {
4688         lcm = num2;
4689     }
4690     temp = lcm;
4691 
4692     while (1) {
4693         if (((lcm%num1) == 0) && ((lcm%num2) == 0)) {
4694             break;
4695         }
4696         lcm += temp;
4697     }
4698     return lcm;
4699 }
4700 
4701 /*===========================================================================
4702  * FUNCTION   : mm_stream_calc_offset
4703  *
4704  * DESCRIPTION: calculate frame offset based on format and padding information
4705  *
4706  * PARAMETERS :
4707  *   @my_obj  : stream object
4708  *
4709  * RETURN     : int32_t type of status
4710  *              0  -- success
4711  *              -1 -- failure
4712  *==========================================================================*/
mm_stream_calc_offset(mm_stream_t * my_obj)4713 int32_t mm_stream_calc_offset(mm_stream_t *my_obj)
4714 {
4715     int32_t rc = 0;
4716     uint32_t i;
4717 
4718     cam_dimension_t dim = my_obj->stream_info->dim;
4719     if (my_obj->stream_info->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
4720         my_obj->stream_info->stream_type != CAM_STREAM_TYPE_VIDEO) {
4721         if (my_obj->stream_info->pp_config.rotation == ROTATE_90 ||
4722             my_obj->stream_info->pp_config.rotation == ROTATE_270) {
4723             // rotated by 90 or 270, need to switch width and height
4724             dim.width = my_obj->stream_info->dim.height;
4725             dim.height = my_obj->stream_info->dim.width;
4726         }
4727     }
4728 
4729     switch (my_obj->stream_info->stream_type) {
4730     case CAM_STREAM_TYPE_PREVIEW:
4731         rc = mm_stream_calc_offset_preview(my_obj->stream_info,
4732                                            &dim,
4733                                            &my_obj->padding_info,
4734                                            &my_obj->stream_info->buf_planes);
4735         break;
4736     case CAM_STREAM_TYPE_POSTVIEW:
4737       rc = mm_stream_calc_offset_post_view(my_obj->stream_info,
4738                                          &dim,
4739                                          &my_obj->padding_info,
4740                                          &my_obj->stream_info->buf_planes);
4741       break;
4742     case CAM_STREAM_TYPE_SNAPSHOT:
4743     case CAM_STREAM_TYPE_CALLBACK:
4744         rc = mm_stream_calc_offset_snapshot(my_obj->stream_info->fmt,
4745                                             &dim,
4746                                             &my_obj->padding_info,
4747                                             &my_obj->stream_info->buf_planes);
4748         break;
4749     case CAM_STREAM_TYPE_OFFLINE_PROC:
4750         rc = mm_stream_calc_offset_postproc(my_obj->stream_info,
4751                                             &my_obj->padding_info,
4752                                             &my_obj->stream_info->buf_planes);
4753         break;
4754     case CAM_STREAM_TYPE_VIDEO:
4755         rc = mm_stream_calc_offset_video(my_obj->stream_info->fmt,
4756                 &dim, &my_obj->stream_info->buf_planes);
4757         break;
4758     case CAM_STREAM_TYPE_RAW:
4759         rc = mm_stream_calc_offset_raw(my_obj->stream_info->fmt,
4760                                        &dim,
4761                                        &my_obj->padding_info,
4762                                        &my_obj->stream_info->buf_planes);
4763         break;
4764     case CAM_STREAM_TYPE_ANALYSIS:
4765         rc = mm_stream_calc_offset_analysis(my_obj->stream_info->fmt,
4766                                             &dim,
4767                                             &my_obj->padding_info,
4768                                             &my_obj->stream_info->buf_planes);
4769         break;
4770     case CAM_STREAM_TYPE_METADATA:
4771         rc = mm_stream_calc_offset_metadata(&dim,
4772                                             &my_obj->padding_info,
4773                                             &my_obj->stream_info->buf_planes);
4774         break;
4775     default:
4776         LOGE("not supported for stream type %d",
4777                     my_obj->stream_info->stream_type);
4778         rc = -1;
4779         break;
4780     }
4781 
4782     my_obj->frame_offset = my_obj->stream_info->buf_planes.plane_info;
4783     LOGH("Stream type %d num_planes %d", my_obj->stream_info->stream_type,
4784             my_obj->frame_offset.num_planes);
4785     for (i = 0; i < my_obj->frame_offset.num_planes; i++) {
4786         LOGH("Plane %d, stride %d, scanline %d, width %d, height %d, \
4787                 length %d", i, my_obj->frame_offset.mp[i].stride,
4788                 my_obj->frame_offset.mp[i].scanline,
4789                 my_obj->frame_offset.mp[i].width,
4790                 my_obj->frame_offset.mp[i].height,
4791                 my_obj->frame_offset.mp[i].len);
4792     }
4793 
4794     return rc;
4795 }
4796 
4797 /*===========================================================================
4798  * FUNCTION   : mm_stream_sync_info
4799  *
4800  * DESCRIPTION: synchronize stream information with server
4801  *
4802  * PARAMETERS :
4803  *   @my_obj  : stream object
4804  *
4805  * RETURN     : int32_t type of status
4806  *              0  -- success
4807  *              -1 -- failure
4808  * NOTE       : assume stream info buffer is mapped to server and filled in with
4809  *              stream information by upper layer. This call will let server to
4810  *              synchornize the stream information with HAL. If server find any
4811  *              fields that need to be changed accroding to hardware configuration,
4812  *              server will modify corresponding fields so that HAL could know
4813  *              about it.
4814  *==========================================================================*/
mm_stream_sync_info(mm_stream_t * my_obj)4815 int32_t mm_stream_sync_info(mm_stream_t *my_obj)
4816 {
4817     int32_t rc = 0;
4818     int32_t value = 0;
4819     my_obj->stream_info->stream_svr_id = my_obj->server_stream_id;
4820     rc = mm_stream_calc_offset(my_obj);
4821 
4822     if (rc == 0) {
4823         mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
4824         int stream_id  =  my_obj->server_stream_id;
4825         rc = mm_camera_util_s_ctrl(cam_obj, stream_id, my_obj->fd,
4826                 CAM_PRIV_STREAM_INFO_SYNC, &value);
4827     }
4828     return rc;
4829 }
4830 
4831 /*===========================================================================
4832  * FUNCTION   : mm_stream_set_fmt
4833  *
4834  * DESCRIPTION: set stream format to kernel via v4l2 ioctl
4835  *
4836  * PARAMETERS :
4837  *   @my_obj  : stream object
4838  *
4839  * RETURN     : int32_t type of status
4840  *              0  -- success
4841  *              -1 -- failure
4842  *==========================================================================*/
mm_stream_set_fmt(mm_stream_t * my_obj)4843 int32_t mm_stream_set_fmt(mm_stream_t *my_obj)
4844 {
4845     int32_t rc = 0;
4846     struct v4l2_format fmt;
4847     struct msm_v4l2_format_data msm_fmt;
4848     int i;
4849     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
4850           my_obj->my_hdl, my_obj->fd, my_obj->state);
4851 
4852     if (my_obj->stream_info->dim.width == 0 ||
4853         my_obj->stream_info->dim.height == 0) {
4854         LOGE("invalid input[w=%d,h=%d,fmt=%d]\n",
4855                    my_obj->stream_info->dim.width,
4856                    my_obj->stream_info->dim.height,
4857                    my_obj->stream_info->fmt);
4858         return -1;
4859     }
4860 
4861     memset(&fmt, 0, sizeof(fmt));
4862     memset(&msm_fmt, 0, sizeof(msm_fmt));
4863     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4864     msm_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4865 
4866     msm_fmt.width = (unsigned int)my_obj->stream_info->dim.width;
4867     msm_fmt.height = (unsigned int)my_obj->stream_info->dim.height;
4868     msm_fmt.pixelformat = mm_stream_get_v4l2_fmt(my_obj->stream_info->fmt);
4869 
4870     if (my_obj->stream_info->streaming_mode != CAM_STREAMING_MODE_BATCH) {
4871         msm_fmt.num_planes = (unsigned char)my_obj->frame_offset.num_planes;
4872         for (i = 0; i < msm_fmt.num_planes; i++) {
4873             msm_fmt.plane_sizes[i] = my_obj->frame_offset.mp[i].len;
4874         }
4875     } else {
4876         msm_fmt.num_planes = 1;
4877         msm_fmt.plane_sizes[0] = my_obj->stream_info->user_buf_info.size;
4878     }
4879 
4880     memcpy(fmt.fmt.raw_data, &msm_fmt, sizeof(msm_fmt));
4881     rc = ioctl(my_obj->fd, VIDIOC_S_FMT, &fmt);
4882     if (rc < 0) {
4883         LOGE("ioctl VIDIOC_S_FMT failed: rc=%d errno %d\n", rc, errno);
4884     } else {
4885 #ifndef DAEMON_PRESENT
4886         mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
4887         cam_shim_packet_t *shim_cmd;
4888         cam_shim_cmd_data shim_cmd_data;
4889 
4890         memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
4891         shim_cmd_data.command = MSM_CAMERA_PRIV_S_FMT;
4892         shim_cmd_data.stream_id = my_obj->server_stream_id;
4893         shim_cmd_data.value = NULL;
4894         shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
4895                 cam_obj->sessionid, &shim_cmd_data);
4896         rc = mm_camera_module_send_cmd(shim_cmd);
4897         mm_camera_destroy_shim_cmd_packet(shim_cmd);
4898 #endif /* DAEMON_PRESENT */
4899     }
4900     return rc;
4901 }
4902 
4903 /*===========================================================================
4904  * FUNCTION   : mm_stream_cancel_buf
4905  *
4906  * DESCRIPTION: Get buffer back from kernel
4907  *
4908  * PARAMETERS :
4909  *   @my_obj       : stream object
4910  *   @buf_idx        : frame index to be de-queued back from kernel
4911  *
4912  * RETURN     : int32_t type of status
4913  *              0  -- success
4914  *              -1 -- failure
4915  *==========================================================================*/
mm_stream_cancel_buf(mm_stream_t * my_obj,uint32_t buf_idx)4916 int32_t mm_stream_cancel_buf(mm_stream_t * my_obj,
4917                            uint32_t buf_idx)
4918 {
4919     int32_t rc = 0;
4920     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
4921           my_obj->my_hdl, my_obj->fd, my_obj->state);
4922 
4923     pthread_mutex_lock(&my_obj->buf_lock);
4924     if(my_obj->buf_status[buf_idx].buf_refcnt != 0) {
4925         LOGE("Error Trying to extract a frame already sent to HAL(idx=%d) count=%d\n",
4926                     buf_idx,
4927                    my_obj->buf_status[buf_idx].buf_refcnt);
4928         pthread_mutex_unlock(&my_obj->buf_lock);
4929         rc = -1;
4930         return rc;
4931     }
4932     pthread_mutex_unlock(&my_obj->buf_lock);
4933     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
4934         /*rc = mm_stream_write_user_buf(my_obj, frame);*/
4935         // TODO handling batch buffers
4936     } else {
4937         pthread_mutex_lock(&my_obj->buf_lock);
4938         //my_obj->buf_status[buf_idx].buf_refcnt++;
4939         {
4940             pthread_mutex_unlock(&my_obj->buf_lock);
4941             LOGD("<DEBUG> : Cancel Buffer done for buffer:%d, stream type:%d", buf_idx, my_obj->stream_info->stream_type);
4942 
4943             struct msm_camera_return_buf bufid;
4944             memset(&bufid, 0, sizeof(struct msm_camera_return_buf));
4945             bufid.index = buf_idx;
4946 
4947             struct msm_camera_private_ioctl_arg arg;
4948             memset(&arg, 0, sizeof(struct msm_camera_private_ioctl_arg));
4949             arg.id = MSM_CAMERA_PRIV_IOCTL_ID_RETURN_BUF;
4950             arg.size = sizeof(struct msm_camera_return_buf);
4951             arg.ioctl_ptr = (uint32_t) &bufid;
4952 
4953 
4954             rc = ioctl(my_obj->fd, VIDIOC_MSM_CAMERA_PRIVATE_IOCTL_CMD, &arg);
4955 
4956             if(rc < 0) {
4957                 LOGE("mm_stream_cancel_buf(idx=%d) err=%d\n",
4958                             buf_idx, rc);
4959             } else {
4960                 //my_obj->buf_status[frame->buf_idx].in_kernel = 0;
4961             }
4962         }
4963     }
4964     return rc;
4965 }
4966 
4967 
4968 /*===========================================================================
4969  * FUNCTION   : mm_stream_buf_done
4970  *
4971  * DESCRIPTION: enqueue buffer back to kernel
4972  *
4973  * PARAMETERS :
4974  *   @my_obj       : stream object
4975  *   @frame        : frame to be enqueued back to kernel
4976  *
4977  * RETURN     : int32_t type of status
4978  *              0  -- success
4979  *              -1 -- failure
4980  *==========================================================================*/
mm_stream_buf_done(mm_stream_t * my_obj,mm_camera_buf_def_t * frame)4981 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
4982                            mm_camera_buf_def_t *frame)
4983 {
4984     int32_t rc = 0;
4985     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
4986           my_obj->my_hdl, my_obj->fd, my_obj->state);
4987 
4988     pthread_mutex_lock(&my_obj->buf_lock);
4989     if(my_obj->buf_status[frame->buf_idx].buf_refcnt == 0) {
4990         LOGW("Warning: trying to free buffer for the second time?(idx=%d)\n",
4991                     frame->buf_idx);
4992         pthread_mutex_unlock(&my_obj->buf_lock);
4993         rc = -1;
4994         return rc;
4995     }
4996     pthread_mutex_unlock(&my_obj->buf_lock);
4997     if (my_obj->stream_info->streaming_mode == CAM_STREAMING_MODE_BATCH) {
4998         rc = mm_stream_write_user_buf(my_obj, frame);
4999     } else {
5000         pthread_mutex_lock(&my_obj->buf_lock);
5001         my_obj->buf_status[frame->buf_idx].buf_refcnt--;
5002         if (0 == my_obj->buf_status[frame->buf_idx].buf_refcnt) {
5003             pthread_mutex_unlock(&my_obj->buf_lock);
5004             LOGD("<DEBUG> : Buf done for buffer:%d, stream:%d", frame->buf_idx, frame->stream_type);
5005             rc = mm_stream_qbuf(my_obj, frame);
5006             if(rc < 0) {
5007                 LOGE("mm_camera_stream_qbuf(idx=%d) err=%d\n",
5008                             frame->buf_idx, rc);
5009             } else {
5010                 my_obj->buf_status[frame->buf_idx].in_kernel = 1;
5011             }
5012         }else{
5013             LOGD("<DEBUG> : Still ref count pending count :%d",
5014                  my_obj->buf_status[frame->buf_idx].buf_refcnt);
5015             LOGD("<DEBUG> : for buffer:%p:%d",
5016                  my_obj, frame->buf_idx);
5017             pthread_mutex_unlock(&my_obj->buf_lock);
5018         }
5019     }
5020     return rc;
5021 }
5022 
5023 
5024 /*===========================================================================
5025  * FUNCTION   : mm_stream_get_queued_buf_count
5026  *
5027  * DESCRIPTION: return queued buffer count
5028  *
5029  * PARAMETERS :
5030  *   @my_obj       : stream object
5031  *
5032  * RETURN     : queued buffer count
5033  *==========================================================================*/
mm_stream_get_queued_buf_count(mm_stream_t * my_obj)5034 int32_t mm_stream_get_queued_buf_count(mm_stream_t *my_obj)
5035 {
5036     int32_t rc = 0;
5037     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
5038              my_obj->my_hdl, my_obj->fd, my_obj->state);
5039     pthread_mutex_lock(&my_obj->buf_lock);
5040     rc = my_obj->queued_buffer_count;
5041     pthread_mutex_unlock(&my_obj->buf_lock);
5042     return rc;
5043 }
5044 
5045 /*===========================================================================
5046  * FUNCTION   : mm_stream_reg_buf_cb
5047  *
5048  * DESCRIPTION: Allow other stream to register dataCB at this stream.
5049  *
5050  * PARAMETERS :
5051  *   @my_obj       : stream object
5052  *   @val          : callback function to be registered
5053  *
5054  * RETURN     : int32_t type of status
5055  *              0  -- success
5056  *              -1 -- failure
5057  *==========================================================================*/
mm_stream_reg_buf_cb(mm_stream_t * my_obj,mm_stream_data_cb_t val)5058 int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
5059         mm_stream_data_cb_t val)
5060 {
5061     int32_t rc = -1;
5062     uint8_t i;
5063     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
5064           my_obj->my_hdl, my_obj->fd, my_obj->state);
5065 
5066     pthread_mutex_lock(&my_obj->cb_lock);
5067     for (i=0 ;i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
5068         if(NULL == my_obj->buf_cb[i].cb) {
5069             my_obj->buf_cb[i] = val;
5070             rc = 0;
5071             break;
5072         }
5073     }
5074     pthread_mutex_unlock(&my_obj->cb_lock);
5075 
5076     return rc;
5077 }
5078 
5079 /*===========================================================================
5080  * FUNCTION   : mm_stream_handle_cache_ops
5081  *
5082  * DESCRIPTION: handles cache ops of a stream buffer
5083  *
5084  * PARAMETERS :
5085  *   @my_obj       : stream object
5086  *   @buf     : ptr to a stream buffer
5087  *   @deque  : specifies if enqueue or dequeue
5088  *
5089  * RETURN     : zero for success
5090  *                  non-zero error value
5091  *==========================================================================*/
mm_stream_handle_cache_ops(mm_stream_t * my_obj,mm_camera_buf_def_t * buf,bool deque)5092 int32_t mm_stream_handle_cache_ops(mm_stream_t* my_obj,
5093         mm_camera_buf_def_t* buf, bool deque)
5094 {
5095     int32_t rc = 0;
5096     if(!my_obj || !buf) {
5097         LOGE("Error!! my_obj: %p, buf_info: %p", my_obj, buf);
5098         rc = -1;
5099         return rc;
5100     }
5101     if ((my_obj->mem_vtbl.clean_invalidate_buf  == NULL) ||
5102             (my_obj->mem_vtbl.invalidate_buf  == NULL) ||
5103             (my_obj->mem_vtbl.clean_buf  == NULL)) {
5104         LOGI("Clean/Invalidate cache ops not supported %p %p %p",
5105             my_obj->mem_vtbl.clean_invalidate_buf,
5106             my_obj->mem_vtbl.invalidate_buf,
5107             my_obj->mem_vtbl.clean_buf);
5108         // Not a fatal error
5109         rc = 0;
5110         return rc;
5111     }
5112 
5113     // Modify clean and invalidate flags depending on cache ops for stream
5114     switch (my_obj->stream_info->cache_ops) {
5115         case CAM_STREAM_CACHE_OPS_CLEAR_FLAGS:
5116             buf->cache_flags = 0;
5117             break;
5118         case CAM_STREAM_CACHE_OPS_DISABLED:
5119             if (deque) {
5120                 buf->cache_flags = CPU_HAS_READ_WRITTEN;
5121             }
5122             else {
5123                 buf->cache_flags = CPU_HAS_READ;
5124             }
5125         case CAM_STREAM_CACHE_OPS_HONOUR_FLAGS:
5126         default:
5127             // Do not change flags
5128             break;
5129     }
5130 
5131     if ((buf->cache_flags & CPU_HAS_READ_WRITTEN) ==
5132         CPU_HAS_READ_WRITTEN) {
5133         rc = my_obj->mem_vtbl.clean_invalidate_buf(
5134                 buf->buf_idx, my_obj->mem_vtbl.user_data);
5135     } else if ((buf->cache_flags & CPU_HAS_READ) ==
5136         CPU_HAS_READ) {
5137         rc = my_obj->mem_vtbl.invalidate_buf(
5138                 buf->buf_idx, my_obj->mem_vtbl.user_data);
5139     } else if ((buf->cache_flags & CPU_HAS_WRITTEN) ==
5140         CPU_HAS_WRITTEN) {
5141         rc = my_obj->mem_vtbl.clean_buf(
5142                 buf->buf_idx, my_obj->mem_vtbl.user_data);
5143     }
5144 
5145     LOGH("[CACHE_OPS] Stream type: %d buf index: %d cache ops flags: 0x%x",
5146             buf->stream_type, buf->buf_idx, buf->cache_flags);
5147 
5148     if (rc != 0) {
5149         LOGE("Clean/Invalidate cache failed on buffer index: %d",
5150                 buf->buf_idx);
5151     } else {
5152        // Reset buffer cache flags after cache ops
5153         buf->cache_flags = 0;
5154     }
5155 
5156     return rc;
5157 }
5158 
5159