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