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