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