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