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