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