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