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