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