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