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