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