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