1 /* 2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <pthread.h> 31 #include <errno.h> 32 #include <sys/ioctl.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <fcntl.h> 36 #include <poll.h> 37 #include <semaphore.h> 38 #include <linux/msm_ion.h> 39 40 #include "mm_camera_dbg.h" 41 #include "mm_camera_interface.h" 42 #include "mm_camera.h" 43 44 extern mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler); 45 extern mm_channel_t * mm_camera_util_get_channel_by_handler( 46 mm_camera_obj_t * cam_obj, 47 uint32_t handler); 48 extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj, 49 cam_ctrl_type type, 50 uint32_t length, 51 void *value); 52 extern int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj, 53 cam_ctrl_type type, 54 uint32_t length, 55 void *value, 56 int timeout); 57 58 /* internal function declare goes here */ 59 int32_t mm_channel_qbuf(mm_channel_t *my_obj, 60 mm_camera_buf_def_t *buf); 61 int32_t mm_channel_init(mm_channel_t *my_obj); 62 void mm_channel_release(mm_channel_t *my_obj); 63 uint32_t mm_channel_add_stream(mm_channel_t *my_obj, 64 mm_camera_buf_notify_t buf_cb, void *user_data, 65 uint32_t ext_image_mode, uint32_t sensor_idx); 66 int32_t mm_channel_del_stream(mm_channel_t *my_obj, 67 uint32_t stream_id); 68 int32_t mm_channel_config_stream(mm_channel_t *my_obj, 69 uint32_t stream_id, 70 mm_camera_stream_config_t *config); 71 int32_t mm_channel_bundle_stream(mm_channel_t *my_obj, 72 mm_camera_buf_notify_t super_frame_notify_cb, 73 void *user_data, 74 mm_camera_bundle_attr_t *attr, 75 uint8_t num_streams, 76 uint32_t *stream_ids); 77 int32_t mm_channel_destroy_bundle(mm_channel_t *my_obj); 78 int32_t mm_channel_start_streams(mm_channel_t *my_obj, 79 uint8_t num_streams, 80 uint32_t *stream_ids); 81 int32_t mm_channel_stop_streams(mm_channel_t *my_obj, 82 uint8_t num_streams, 83 uint32_t *stream_ids, 84 uint8_t tear_down_flag); 85 int32_t mm_channel_request_super_buf(mm_channel_t *my_obj); 86 int32_t mm_channel_cancel_super_buf_request(mm_channel_t *my_obj); 87 int32_t mm_channel_start_focus(mm_channel_t *my_obj, 88 uint32_t sensor_idx, 89 uint32_t focus_mode); 90 int32_t mm_channel_abort_focus(mm_channel_t *my_obj, 91 uint32_t sensor_idx); 92 int32_t mm_channel_prepare_snapshot(mm_channel_t *my_obj, 93 uint32_t sensor_idx); 94 int32_t mm_channel_set_stream_parm(mm_channel_t *my_obj, 95 uint32_t s_id, 96 void *value); 97 int32_t mm_channel_get_stream_parm(mm_channel_t *my_obj, 98 uint32_t s_id, 99 void *value); 100 uint8_t mm_channel_need_do_pp(mm_channel_t *my_obj, 101 mm_channel_queue_node_t *super_buf); 102 int32_t mm_channel_do_post_processing(mm_channel_t *my_obj, 103 mm_channel_queue_node_t *super_buf); 104 int32_t mm_channel_cancel_post_processing(mm_channel_t *my_obj); 105 int32_t mm_channel_superbuf_bufdone_overflow(mm_channel_t* my_obj, 106 mm_channel_queue_t * queue); 107 int32_t mm_channel_superbuf_skip(mm_channel_t* my_obj, 108 mm_channel_queue_t * queue); 109 110 /* state machine function declare */ 111 int32_t mm_channel_fsm_fn_notused(mm_channel_t *my_obj, 112 mm_channel_evt_type_t evt, 113 void * in_val, 114 void * out_val); 115 int32_t mm_channel_fsm_fn_stopped(mm_channel_t *my_obj, 116 mm_channel_evt_type_t evt, 117 void * in_val, 118 void * out_val); 119 int32_t mm_channel_fsm_fn_active(mm_channel_t *my_obj, 120 mm_channel_evt_type_t evt, 121 void * in_val, 122 void * out_val); 123 int32_t mm_channel_fsm_fn_paused(mm_channel_t *my_obj, 124 mm_channel_evt_type_t evt, 125 void * in_val, 126 void * out_val); 127 128 /* channel super queue functions */ 129 int32_t mm_channel_superbuf_queue_init(mm_channel_queue_t * queue); 130 int32_t mm_channel_superbuf_queue_deinit(mm_channel_queue_t * queue); 131 int32_t mm_channel_superbuf_comp_and_enqueue(mm_channel_t *ch_obj, 132 mm_channel_queue_t * queue, 133 mm_camera_buf_info_t *buf); 134 mm_channel_queue_node_t* mm_channel_superbuf_dequeue(mm_channel_queue_t * queue); 135 136 /* channel utility function */ 137 mm_stream_t * mm_channel_util_get_stream_by_handler( 138 mm_channel_t * ch_obj, 139 uint32_t handler) 140 { 141 int i; 142 mm_stream_t *s_obj = NULL; 143 uint8_t ch_idx = mm_camera_util_get_index_by_handler(handler); 144 145 for(i = 0; i < MM_CAMEAR_STRAEM_NUM_MAX; i++) { 146 if (handler == ch_obj->streams[i].my_hdl) { 147 s_obj = &ch_obj->streams[i]; 148 break; 149 } 150 } 151 return s_obj; 152 } 153 154 /* CB for handling post processing result from ctrl evt */ 155 static void mm_channel_pp_result_notify(uint32_t camera_handler, 156 mm_camera_event_t *evt, 157 void *user_data) 158 { 159 uint32_t ch_hdl = (uint32_t)user_data; 160 mm_camera_obj_t *cam_obj = NULL; 161 mm_channel_t *ch_obj = NULL; 162 mm_channel_queue_node_t * node = NULL; 163 mm_channel_pp_info_t* pp_info = NULL; 164 165 cam_obj = mm_camera_util_get_camera_by_handler(camera_handler); 166 if (NULL == cam_obj) { 167 CDBG("%s: No matching camera handler", __func__); 168 return; 169 } 170 171 ch_obj = mm_camera_util_get_channel_by_handler(cam_obj, ch_hdl); 172 if (NULL == ch_obj) { 173 CDBG("%s: No matching channel handler", __func__); 174 return; 175 } 176 177 pthread_mutex_lock(&ch_obj->ch_lock); 178 if (ch_obj->pending_pp_cnt > 0) { 179 if (MM_CAMERA_EVT_TYPE_CTRL == evt->event_type) { 180 /* PP result is sent as CTRL event 181 * currently we only have WNR */ 182 if (MM_CAMERA_CTRL_EVT_WDN_DONE == evt->e.ctrl.evt) { 183 /* WNR result */ 184 pp_info = (mm_channel_pp_info_t *)evt->e.ctrl.cookie; 185 if (NULL != pp_info) { 186 node = pp_info->super_buf; 187 } 188 } 189 } 190 191 if (NULL != node) { 192 uint8_t pp_done = 1; 193 if (CAM_CTRL_SUCCESS == evt->e.ctrl.status) { 194 uint8_t i; 195 /* 1) update need_pp flag as action done */ 196 for (i=0; i<node->num_of_bufs; i++) { 197 if (node->super_buf[i].stream_id == pp_info->stream_hdl) { 198 /* stream pp is done, set the flag to 0*/ 199 node->super_buf[i].need_pp = 0; 200 break; 201 } 202 } 203 204 /* 2) check if all bufs done with pp */ 205 for (i=0; i<node->num_of_bufs; i++) { 206 if (node->super_buf[i].need_pp) { 207 pp_done = 0; 208 break; 209 } 210 } 211 } 212 213 if (pp_done) { 214 /* send super buf to CB */ 215 if (NULL != ch_obj->bundle.super_buf_notify_cb) { 216 mm_camera_super_buf_t super_buf; 217 uint8_t i; 218 219 memset(&super_buf, 0, sizeof(mm_camera_super_buf_t)); 220 super_buf.num_bufs = node->num_of_bufs; 221 for (i=0; i<node->num_of_bufs; i++) { 222 super_buf.bufs[i] = node->super_buf[i].buf; 223 } 224 super_buf.camera_handle = ch_obj->cam_obj->my_hdl; 225 super_buf.ch_id = ch_obj->my_hdl; 226 227 ch_obj->bundle.super_buf_notify_cb(&super_buf, 228 ch_obj->bundle.user_data); 229 ch_obj->pending_pp_cnt--; 230 } else { 231 /* buf done with the nonuse super buf */ 232 uint8_t i; 233 for (i=0; i<node->num_of_bufs; i++) { 234 mm_channel_qbuf(ch_obj, node->super_buf[i].buf); 235 } 236 } 237 238 /* done with node, free it */ 239 free(node); 240 } 241 } 242 } 243 pthread_mutex_unlock(&ch_obj->ch_lock); 244 } 245 246 /* CB for processing stream buffer */ 247 static void mm_channel_process_stream_buf(mm_camera_cmdcb_t * cmd_cb, 248 void *user_data) 249 { 250 mm_camera_super_buf_notify_mode_t notify_mode; 251 mm_channel_queue_node_t *node = NULL; 252 mm_channel_t *ch_obj = (mm_channel_t *)user_data; 253 if (NULL == ch_obj) { 254 return; 255 } 256 257 if (MM_CAMERA_CMD_TYPE_DATA_CB == cmd_cb->cmd_type) { 258 /* comp_and_enqueue */ 259 mm_channel_superbuf_comp_and_enqueue( 260 ch_obj, 261 &ch_obj->bundle.superbuf_queue, 262 &cmd_cb->u.buf); 263 } 264 265 notify_mode = ch_obj->bundle.superbuf_queue.attr.notify_mode; 266 267 /* bufdone for overflowed bufs */ 268 mm_channel_superbuf_bufdone_overflow(ch_obj, &ch_obj->bundle.superbuf_queue); 269 270 /* lock ch_lock */ 271 pthread_mutex_lock(&ch_obj->ch_lock); 272 273 /* dispatch frame if pending_cnt>0 or is in continuous streaming mode */ 274 while ( (ch_obj->pending_cnt > 0) || 275 (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == notify_mode) ) { 276 277 /* skip frames if needed */ 278 mm_channel_superbuf_skip(ch_obj, &ch_obj->bundle.superbuf_queue); 279 280 /* dequeue */ 281 node = mm_channel_superbuf_dequeue(&ch_obj->bundle.superbuf_queue); 282 if (NULL != node) { 283 /* decrease pending_cnt */ 284 CDBG("%s: Super Buffer received, Call client callback",__func__); 285 if (MM_CAMERA_SUPER_BUF_NOTIFY_BURST == notify_mode) { 286 ch_obj->pending_cnt--; 287 } 288 289 if (mm_channel_need_do_pp(ch_obj, node)) { 290 /* do post processing */ 291 ch_obj->pending_pp_cnt++; 292 mm_channel_do_post_processing(ch_obj, node); 293 /* no need to free node here 294 * node will be as cookie sent to backend doing pp */ 295 } else { 296 /* dispatch superbuf */ 297 if (NULL != ch_obj->bundle.super_buf_notify_cb) { 298 mm_camera_super_buf_t super_buf; 299 uint8_t i; 300 301 memset(&super_buf, 0, sizeof(mm_camera_super_buf_t)); 302 super_buf.num_bufs = node->num_of_bufs; 303 for (i=0; i<node->num_of_bufs; i++) { 304 super_buf.bufs[i] = node->super_buf[i].buf; 305 } 306 super_buf.camera_handle = ch_obj->cam_obj->my_hdl; 307 super_buf.ch_id = ch_obj->my_hdl; 308 309 ch_obj->bundle.super_buf_notify_cb(&super_buf, 310 ch_obj->bundle.user_data); 311 } else { 312 /* buf done with the nonuse super buf */ 313 uint8_t i; 314 for (i=0; i<node->num_of_bufs; i++) { 315 mm_channel_qbuf(ch_obj, node->super_buf[i].buf); 316 } 317 } 318 free(node); 319 } 320 } else { 321 /* no superbuf avail, break the loop */ 322 CDBG_ERROR("%s : Superbuffer not available",__func__); 323 break; 324 } 325 } 326 327 /* unlock ch_lock */ 328 pthread_mutex_unlock(&ch_obj->ch_lock); 329 } 330 331 /* state machine entry */ 332 int32_t mm_channel_fsm_fn(mm_channel_t *my_obj, 333 mm_channel_evt_type_t evt, 334 void * in_val, 335 void * out_val) 336 { 337 int32_t rc = -1; 338 339 CDBG("%s : E state = %d",__func__,my_obj->state); 340 switch (my_obj->state) { 341 case MM_CHANNEL_STATE_NOTUSED: 342 rc = mm_channel_fsm_fn_notused(my_obj, evt, in_val, out_val); 343 break; 344 case MM_CHANNEL_STATE_STOPPED: 345 rc = mm_channel_fsm_fn_stopped(my_obj, evt, in_val, out_val); 346 break; 347 case MM_CHANNEL_STATE_ACTIVE: 348 rc = mm_channel_fsm_fn_active(my_obj, evt, in_val, out_val); 349 break; 350 case MM_CHANNEL_STATE_PAUSED: 351 rc = mm_channel_fsm_fn_paused(my_obj, evt, in_val, out_val); 352 break; 353 default: 354 CDBG("%s: Not a valid state (%d)", __func__, my_obj->state); 355 break; 356 } 357 358 /* unlock ch_lock */ 359 pthread_mutex_unlock(&my_obj->ch_lock); 360 CDBG("%s : X rc = %d",__func__,rc); 361 return rc; 362 } 363 364 int32_t mm_channel_fsm_fn_notused(mm_channel_t *my_obj, 365 mm_channel_evt_type_t evt, 366 void * in_val, 367 void * out_val) 368 { 369 int32_t rc = -1; 370 371 switch (evt) { 372 default: 373 CDBG_ERROR("%s: invalid state (%d) for evt (%d)", 374 __func__, my_obj->state, evt); 375 break; 376 } 377 378 return rc; 379 } 380 381 int32_t mm_channel_fsm_fn_stopped(mm_channel_t *my_obj, 382 mm_channel_evt_type_t evt, 383 void * in_val, 384 void * out_val) 385 { 386 int32_t rc = -1; 387 CDBG("%s : E evt = %d",__func__,evt); 388 switch (evt) { 389 case MM_CHANNEL_EVT_ADD_STREAM: 390 { 391 uint32_t s_hdl = 0; 392 mm_evt_paylod_add_stream_t *payload = 393 (mm_evt_paylod_add_stream_t *)in_val; 394 s_hdl = mm_channel_add_stream(my_obj, 395 payload->buf_cb, 396 payload->user_data, 397 payload->ext_image_mode, 398 payload->sensor_idx); 399 *((uint32_t*)out_val) = s_hdl; 400 rc = 0; 401 } 402 break; 403 case MM_CHANNEL_EVT_DEL_STREAM: 404 { 405 uint32_t s_id = *((uint32_t *)in_val); 406 rc = mm_channel_del_stream(my_obj, s_id); 407 } 408 break; 409 case MM_CHANNEL_EVT_START_STREAM: 410 { 411 mm_evt_payload_start_stream_t *payload = 412 (mm_evt_payload_start_stream_t *)in_val; 413 rc = mm_channel_start_streams(my_obj, 414 payload->num_streams, 415 payload->stream_ids); 416 /* first stream started in stopped state 417 * move to active state */ 418 if (0 == rc) { 419 my_obj->state = MM_CHANNEL_STATE_ACTIVE; 420 } 421 } 422 break; 423 case MM_CHANNEL_EVT_CONFIG_STREAM: 424 { 425 mm_evt_paylod_config_stream_t *payload = 426 (mm_evt_paylod_config_stream_t *)in_val; 427 rc = mm_channel_config_stream(my_obj, 428 payload->stream_id, 429 payload->config); 430 } 431 break; 432 case MM_CHANNEL_EVT_INIT_BUNDLE: 433 { 434 mm_evt_payload_bundle_stream_t *payload = 435 (mm_evt_payload_bundle_stream_t *)in_val; 436 rc = mm_channel_bundle_stream(my_obj, 437 payload->super_frame_notify_cb, 438 payload->user_data, 439 payload->attr, 440 payload->num_streams, 441 payload->stream_ids); 442 } 443 break; 444 case MM_CHANNEL_EVT_DESTROY_BUNDLE: 445 rc = mm_channel_destroy_bundle(my_obj); 446 break; 447 case MM_CHANNEL_EVT_PREPARE_SNAPSHOT: 448 { 449 uint32_t sensor_idx = (uint32_t)in_val; 450 rc = mm_channel_prepare_snapshot(my_obj, sensor_idx); 451 } 452 break; 453 case MM_CHANNEL_EVT_DELETE: 454 mm_channel_release(my_obj); 455 rc = 0; 456 break; 457 case MM_CHANNEL_EVT_SET_STREAM_PARM: 458 { 459 uint32_t s_id = (uint32_t)in_val; 460 rc = mm_channel_set_stream_parm(my_obj, s_id, out_val); 461 } 462 break; 463 case MM_CHANNEL_EVT_GET_STREAM_PARM: 464 { 465 uint32_t s_id = (uint32_t)in_val; 466 rc = mm_channel_get_stream_parm(my_obj, s_id, out_val); 467 } 468 break; 469 default: 470 CDBG_ERROR("%s: invalid state (%d) for evt (%d)", 471 __func__, my_obj->state, evt); 472 break; 473 } 474 CDBG("%s : E rc = %d",__func__,rc); 475 return rc; 476 } 477 478 int32_t mm_channel_fsm_fn_active(mm_channel_t *my_obj, 479 mm_channel_evt_type_t evt, 480 void * in_val, 481 void * out_val) 482 { 483 int32_t rc = -1; 484 485 CDBG("%s : E evt = %d",__func__,evt); 486 switch (evt) { 487 case MM_CHANNEL_EVT_CONFIG_STREAM: 488 { 489 mm_evt_paylod_config_stream_t *payload = 490 (mm_evt_paylod_config_stream_t *)in_val; 491 rc = mm_channel_config_stream(my_obj, 492 payload->stream_id, 493 payload->config); 494 } 495 break; 496 case MM_CHANNEL_EVT_START_STREAM: 497 { 498 mm_evt_payload_start_stream_t *payload = 499 (mm_evt_payload_start_stream_t *)in_val; 500 rc = mm_channel_start_streams(my_obj, 501 payload->num_streams, 502 payload->stream_ids); 503 } 504 break; 505 case MM_CHANNEL_EVT_STOP_STREAM: 506 case MM_CHANNEL_EVT_TEARDOWN_STREAM: 507 { 508 int i; 509 uint8_t tear_down_flag = (MM_CHANNEL_EVT_TEARDOWN_STREAM == evt)? 1:0; 510 uint8_t all_stopped = 1; 511 mm_evt_payload_stop_stream_t *payload = 512 (mm_evt_payload_stop_stream_t *)in_val; 513 514 rc = mm_channel_stop_streams(my_obj, 515 payload->num_streams, 516 payload->stream_ids, 517 tear_down_flag); 518 519 /* check if all streams are stopped 520 * then we move to stopped state */ 521 522 for (i=0; i<MM_CAMEAR_STRAEM_NUM_MAX; i++) { 523 if (MM_STREAM_STATE_ACTIVE_STREAM_ON == my_obj->streams[i].state || 524 MM_STREAM_STATE_ACTIVE_STREAM_OFF == my_obj->streams[i].state) { 525 all_stopped = 0; 526 break; 527 } 528 } 529 if (all_stopped) { 530 my_obj->state = MM_CHANNEL_STATE_STOPPED; 531 } 532 533 } 534 break; 535 case MM_CHANNEL_EVT_INIT_BUNDLE: 536 { 537 mm_evt_payload_bundle_stream_t *payload = 538 (mm_evt_payload_bundle_stream_t *)in_val; 539 rc = mm_channel_bundle_stream(my_obj, 540 payload->super_frame_notify_cb, 541 payload->user_data, 542 payload->attr, 543 payload->num_streams, 544 payload->stream_ids); 545 } 546 break; 547 case MM_CHANNEL_EVT_DESTROY_BUNDLE: 548 rc = mm_channel_destroy_bundle(my_obj); 549 break; 550 case MM_CHANNEL_EVT_REQUEST_SUPER_BUF: 551 rc = mm_channel_request_super_buf(my_obj); 552 break; 553 case MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF: 554 rc = mm_channel_cancel_super_buf_request(my_obj); 555 break; 556 case MM_CHANNEL_EVT_START_FOCUS: 557 { 558 mm_evt_payload_start_focus_t* payload = 559 (mm_evt_payload_start_focus_t *)in_val; 560 rc = mm_channel_start_focus(my_obj, 561 payload->sensor_idx, 562 payload->focus_mode); 563 } 564 break; 565 case MM_CHANNEL_EVT_ABORT_FOCUS: 566 { 567 uint32_t sensor_idx = (uint32_t)in_val; 568 rc = mm_channel_abort_focus(my_obj, sensor_idx); 569 } 570 break; 571 case MM_CHANNEL_EVT_PREPARE_SNAPSHOT: 572 { 573 uint32_t sensor_idx = (uint32_t)in_val; 574 rc = mm_channel_prepare_snapshot(my_obj, sensor_idx); 575 } 576 break; 577 case MM_CHANNEL_EVT_SET_STREAM_PARM: 578 { 579 uint32_t s_id = (uint32_t)in_val; 580 rc = mm_channel_set_stream_parm(my_obj, s_id, out_val); 581 } 582 break; 583 case MM_CHANNEL_EVT_GET_STREAM_PARM: 584 { 585 uint32_t s_id = (uint32_t)in_val; 586 rc = mm_channel_get_stream_parm(my_obj, s_id, out_val); 587 } 588 break; 589 590 case MM_CHANNEL_EVT_DEL_STREAM: 591 { 592 uint32_t s_id = *((uint32_t *)in_val); 593 rc = mm_channel_del_stream(my_obj, s_id); 594 } 595 break; 596 default: 597 CDBG_ERROR("%s: invalid state (%d) for evt (%d)", 598 __func__, my_obj->state, evt); 599 break; 600 } 601 CDBG("%s : X rc = %d",__func__,rc); 602 return rc; 603 } 604 605 int32_t mm_channel_fsm_fn_paused(mm_channel_t *my_obj, 606 mm_channel_evt_type_t evt, 607 void * in_val, 608 void * out_val) 609 { 610 int32_t rc = -1; 611 612 /* currently we are not supporting pause/resume channel */ 613 CDBG_ERROR("%s: evt (%d) not supported in state (%d)", 614 __func__, evt, my_obj->state); 615 616 return rc; 617 } 618 619 int32_t mm_channel_init(mm_channel_t *my_obj) 620 { 621 int32_t rc = 0; 622 CDBG("%s : Launch data poll thread in channel open",__func__); 623 mm_camera_poll_thread_launch(&my_obj->poll_thread[0], 624 MM_CAMERA_POLL_TYPE_CH); 625 626 /* change state to stopped state */ 627 my_obj->state = MM_CHANNEL_STATE_STOPPED; 628 return rc; 629 } 630 631 void mm_channel_release(mm_channel_t *my_obj) 632 { 633 /* stop data poll thread */ 634 mm_camera_poll_thread_release(&my_obj->poll_thread[0]); 635 636 /* change state to notused state */ 637 my_obj->state = MM_CHANNEL_STATE_NOTUSED; 638 } 639 640 uint32_t mm_channel_add_stream(mm_channel_t *my_obj, 641 mm_camera_buf_notify_t buf_cb, void *user_data, 642 uint32_t ext_image_mode, uint32_t sensor_idx) 643 { 644 int32_t rc = 0; 645 uint8_t idx = 0; 646 uint32_t s_hdl = 0; 647 mm_stream_t *stream_obj = NULL; 648 649 CDBG("%s : image mode = %d",__func__,ext_image_mode); 650 /* check available stream */ 651 for (idx = 0; idx < MM_CAMEAR_STRAEM_NUM_MAX; idx++) { 652 if (MM_STREAM_STATE_NOTUSED == my_obj->streams[idx].state) { 653 stream_obj = &my_obj->streams[idx]; 654 break; 655 } 656 } 657 if (NULL == stream_obj) { 658 CDBG_ERROR("%s: streams reach max, no more stream allowed to add", __func__); 659 return s_hdl; 660 } 661 662 /* initialize stream object */ 663 memset(stream_obj, 0, sizeof(mm_stream_t)); 664 stream_obj->my_hdl = mm_camera_util_generate_handler(idx); 665 stream_obj->ch_obj = my_obj; 666 /* cd through intf always palced at idx 0 of buf_cb */ 667 stream_obj->buf_cb[0].cb = buf_cb; 668 stream_obj->buf_cb[0].user_data = user_data; 669 stream_obj->buf_cb[0].cb_count = -1; /* infinite by default */ 670 stream_obj->ext_image_mode = ext_image_mode + 1; 671 stream_obj->sensor_idx = sensor_idx; 672 stream_obj->fd = -1; 673 pthread_mutex_init(&stream_obj->buf_lock, NULL); 674 pthread_mutex_init(&stream_obj->cb_lock, NULL); 675 stream_obj->state = MM_STREAM_STATE_INITED; 676 677 /* acquire stream */ 678 rc = mm_stream_fsm_fn(stream_obj, MM_STREAM_EVT_ACQUIRE, NULL, NULL); 679 if (0 == rc) { 680 s_hdl = stream_obj->my_hdl; 681 } else { 682 /* error during acquire, de-init */ 683 pthread_mutex_destroy(&stream_obj->buf_lock); 684 pthread_mutex_destroy(&stream_obj->cb_lock); 685 memset(stream_obj, 0, sizeof(mm_stream_t)); 686 } 687 CDBG("%s : stream handle = %d",__func__,s_hdl); 688 return s_hdl; 689 } 690 691 int32_t mm_channel_del_stream(mm_channel_t *my_obj, 692 uint32_t stream_id) 693 { 694 int rc = -1; 695 mm_stream_t * stream_obj = NULL; 696 stream_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id); 697 698 if (NULL == stream_obj) { 699 CDBG_ERROR("%s :Invalid Stream Object",__func__); 700 return rc; 701 } 702 703 rc = mm_stream_fsm_fn(stream_obj, 704 MM_STREAM_EVT_RELEASE, 705 NULL, 706 NULL); 707 708 return rc; 709 } 710 711 int32_t mm_channel_config_stream(mm_channel_t *my_obj, 712 uint32_t stream_id, 713 mm_camera_stream_config_t *config) 714 { 715 int rc = -1; 716 mm_stream_t * stream_obj = NULL; 717 CDBG("%s : E stream ID = %d",__func__,stream_id); 718 stream_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id); 719 720 if (NULL == stream_obj) { 721 CDBG_ERROR("%s : X rc = %d",__func__,rc); 722 return rc; 723 } 724 725 /* set stream fmt */ 726 rc = mm_stream_fsm_fn(stream_obj, 727 MM_STREAM_EVT_SET_FMT, 728 (void *)config, 729 NULL); 730 CDBG("%s : X rc = %d",__func__,rc); 731 return rc; 732 } 733 734 int32_t mm_channel_bundle_stream(mm_channel_t *my_obj, 735 mm_camera_buf_notify_t super_frame_notify_cb, 736 void *user_data, 737 mm_camera_bundle_attr_t *attr, 738 uint8_t num_streams, 739 uint32_t *stream_ids) 740 { 741 int32_t rc = 0; 742 int i; 743 mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL}; 744 745 /* first check if all streams to be bundled are valid */ 746 for (i=0; i < num_streams; i++) { 747 s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, stream_ids[i]); 748 if (NULL == s_objs[i]) { 749 CDBG_ERROR("%s: invalid stream handler %d (idx=%d) to be bundled", 750 __func__, stream_ids[i], i); 751 return -1; 752 } 753 } 754 755 /* init superbuf queue */ 756 mm_channel_superbuf_queue_init(&my_obj->bundle.superbuf_queue); 757 758 /* save bundle config */ 759 memcpy(&my_obj->bundle.superbuf_queue.attr, attr, sizeof(mm_camera_bundle_attr_t)); 760 my_obj->bundle.super_buf_notify_cb = super_frame_notify_cb; 761 my_obj->bundle.user_data = user_data; 762 my_obj->bundle.superbuf_queue.num_streams = num_streams; 763 my_obj->bundle.superbuf_queue.expected_frame_id = 0; 764 765 for (i=0; i < num_streams; i++) { 766 /* set bundled flag to streams */ 767 s_objs[i]->is_bundled = 1; 768 /* init bundled streams to invalid value -1 */ 769 //my_obj->bundle.superbuf_queue.bundled_streams[i] = -1; 770 my_obj->bundle.superbuf_queue.bundled_streams[i] = stream_ids[i]; 771 } 772 773 /* launch cmd thread for super buf dataCB */ 774 mm_camera_cmd_thread_launch(&my_obj->cmd_thread, 775 mm_channel_process_stream_buf, 776 (void*)my_obj); 777 778 /* check if we need to do post-processing */ 779 if (my_obj->cam_obj->need_pp) { 780 /* register postProcessingCB at camera evt polling thread 781 * because pp result is coming from ctrl evt */ 782 mm_camera_register_event_notify_internal(my_obj->cam_obj, 783 mm_channel_pp_result_notify, 784 (void *)my_obj->my_hdl, 785 MM_CAMERA_EVT_TYPE_CTRL); 786 } 787 788 return rc; 789 } 790 791 /* bundled streams must all be stopped before bundle can be destroyed */ 792 int32_t mm_channel_destroy_bundle(mm_channel_t *my_obj) 793 { 794 795 mm_camera_cmd_thread_release(&my_obj->cmd_thread); 796 797 /* deinit superbuf queue */ 798 mm_channel_superbuf_queue_deinit(&my_obj->bundle.superbuf_queue); 799 800 /* memset bundle info */ 801 memset(&my_obj->bundle, 0, sizeof(mm_channel_bundle_t)); 802 return 0; 803 } 804 805 int32_t mm_channel_start_streams(mm_channel_t *my_obj, 806 uint8_t num_streams, 807 uint32_t *stream_ids) 808 { 809 int32_t rc = 0; 810 int i, j; 811 mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL}; 812 uint8_t num_streams_to_start = num_streams; 813 uint32_t streams_to_start[MM_CAMEAR_MAX_STRAEM_BUNDLE]; 814 uint8_t bundle_to_start = 0; 815 816 /* check if any bundled stream to be start, 817 * then all bundled stream should be started */ 818 memcpy(streams_to_start, stream_ids, sizeof(uint32_t) * num_streams); 819 for (i=0; i < num_streams; i++) { 820 for (j=0; j < my_obj->bundle.superbuf_queue.num_streams; j++) { 821 if (stream_ids[i] == my_obj->bundle.superbuf_queue.bundled_streams[j]) { 822 bundle_to_start = 1; 823 break; 824 } 825 } 826 } 827 828 if (bundle_to_start) { 829 uint8_t need_add; 830 /* add bundled streams into the start list if not already added*/ 831 for (i=0; i<my_obj->bundle.superbuf_queue.num_streams; i++) { 832 need_add = 1; 833 for (j=0; j<num_streams; j++) { 834 if (stream_ids[j] == my_obj->bundle.superbuf_queue.bundled_streams[i]) { 835 need_add = 0; 836 break; 837 } 838 } 839 if (need_add) { 840 streams_to_start[num_streams_to_start++] = 841 my_obj->bundle.superbuf_queue.bundled_streams[i]; 842 } 843 } 844 } 845 846 /* check if all streams to be started are valid */ 847 for (i=0; i<num_streams_to_start; i++) { 848 s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, streams_to_start[i]); 849 850 if (NULL == s_objs[i]) { 851 CDBG_ERROR("%s: invalid stream handler %d (idx=%d) to be started", 852 __func__, streams_to_start[i], i); 853 return -1; 854 } 855 } 856 857 for (i=0; i<num_streams_to_start; i++) { 858 /* allocate buf */ 859 rc = mm_stream_fsm_fn(s_objs[i], 860 MM_STREAM_EVT_GET_BUF, 861 NULL, 862 NULL); 863 if (0 != rc) { 864 CDBG_ERROR("%s: get buf failed at idx(%d)", __func__, i); 865 break; 866 } 867 868 /* reg buf */ 869 rc = mm_stream_fsm_fn(s_objs[i], 870 MM_STREAM_EVT_REG_BUF, 871 NULL, 872 NULL); 873 if (0 != rc) { 874 CDBG_ERROR("%s: reg buf failed at idx(%d)", __func__, i); 875 break; 876 } 877 878 /* TODO */ 879 /* for now, hard-coded to 1 for main image stream */ 880 /* Query if stream need to do pp under current hardware configuration, 881 * when camera has offline pp capability */ 882 if (my_obj->cam_obj->need_pp) { 883 if (MSM_V4L2_EXT_CAPTURE_MODE_MAIN == s_objs[i]->ext_image_mode) { 884 s_objs[i]->is_pp_needed = 1; 885 } else { 886 s_objs[i]->is_pp_needed = 0; 887 } 888 } 889 890 /* start stream */ 891 rc = mm_stream_fsm_fn(s_objs[i], 892 MM_STREAM_EVT_START, 893 NULL, 894 NULL); 895 if (0 != rc) { 896 CDBG_ERROR("%s: start stream failed at idx(%d)", __func__, i); 897 break; 898 } 899 } 900 901 /* error handling */ 902 if (0 != rc) { 903 for (j=0; j<=i; j++) { 904 /* stop streams*/ 905 mm_stream_fsm_fn(s_objs[i], 906 MM_STREAM_EVT_STOP, 907 NULL, 908 NULL); 909 910 /* unreg buf */ 911 mm_stream_fsm_fn(s_objs[i], 912 MM_STREAM_EVT_UNREG_BUF, 913 NULL, 914 NULL); 915 916 /* put buf back */ 917 mm_stream_fsm_fn(s_objs[i], 918 MM_STREAM_EVT_PUT_BUF, 919 NULL, 920 NULL); 921 } 922 } 923 924 return rc; 925 } 926 927 /* Required: bundled streams need to be stopped together */ 928 int32_t mm_channel_stop_streams(mm_channel_t *my_obj, 929 uint8_t num_streams, 930 uint32_t *stream_ids, 931 uint8_t tear_down_flag) 932 { 933 int32_t rc = 0; 934 int i, j; 935 mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL}; 936 uint8_t num_streams_to_stop = num_streams; 937 uint32_t streams_to_stop[MM_CAMEAR_MAX_STRAEM_BUNDLE]; 938 uint8_t bundle_to_stop = 0; 939 940 /* make sure bundled streams are stopped together */ 941 memcpy(streams_to_stop, stream_ids, sizeof(uint32_t) * num_streams); 942 for (i=0; i<num_streams; i++) { 943 for (j=0; j<my_obj->bundle.superbuf_queue.num_streams; j++) { 944 if (stream_ids[i] == my_obj->bundle.superbuf_queue.bundled_streams[j]) { 945 bundle_to_stop = 1; 946 break; 947 } 948 } 949 } 950 if (bundle_to_stop) { 951 uint8_t need_add; 952 /* add bundled streams into the start list if not already added*/ 953 for (i=0; i<my_obj->bundle.superbuf_queue.num_streams; i++) { 954 need_add = 1; 955 for (j=0; j<num_streams; j++) { 956 if (stream_ids[j] == my_obj->bundle.superbuf_queue.bundled_streams[i]) { 957 need_add = 0; 958 break; 959 } 960 } 961 if (need_add) { 962 streams_to_stop[num_streams_to_stop++] = 963 my_obj->bundle.superbuf_queue.bundled_streams[i]; 964 } 965 } 966 } 967 968 for (i=0; i<num_streams_to_stop; i++) { 969 s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, streams_to_stop[i]); 970 971 if (NULL != s_objs[i]) { 972 /* stream off */ 973 mm_stream_fsm_fn(s_objs[i], 974 MM_STREAM_EVT_STOP, 975 NULL, 976 NULL); 977 978 /* unreg buf at kernel */ 979 mm_stream_fsm_fn(s_objs[i], 980 MM_STREAM_EVT_UNREG_BUF, 981 NULL, 982 NULL); 983 } 984 } 985 986 /* since all streams are stopped, we are safe to 987 * release all buffers allocated in stream */ 988 for (i=0; i<num_streams_to_stop; i++) { 989 if (NULL != s_objs[i]) { 990 /* put buf back */ 991 mm_stream_fsm_fn(s_objs[i], 992 MM_STREAM_EVT_PUT_BUF, 993 NULL, 994 NULL); 995 996 if (tear_down_flag) { 997 /* to tear down stream totally, stream needs to be released */ 998 mm_stream_fsm_fn(s_objs[i], 999 MM_STREAM_EVT_RELEASE, 1000 NULL, 1001 NULL); 1002 } 1003 } 1004 } 1005 1006 return rc; 1007 } 1008 1009 int32_t mm_channel_request_super_buf(mm_channel_t *my_obj) 1010 { 1011 int32_t rc = 0; 1012 mm_camera_cmdcb_t* node = NULL; 1013 1014 /* set pending_cnt 1015 * will trigger dispatching super frames if pending_cnt > 0 */ 1016 my_obj->pending_cnt = my_obj->bundle.superbuf_queue.attr.burst_num; 1017 1018 /* send sem_post to wake up cmd thread to dispatch super buffer */ 1019 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 1020 if (NULL != node) { 1021 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 1022 node->cmd_type = MM_CAMERA_CMD_TYPE_REQ_DATA_CB; 1023 1024 /* enqueue to cmd thread */ 1025 mm_camera_queue_enq(&(my_obj->cmd_thread.cmd_queue), node); 1026 1027 /* wake up cmd thread */ 1028 sem_post(&(my_obj->cmd_thread.cmd_sem)); 1029 } else { 1030 CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__); 1031 rc = -1; 1032 } 1033 1034 return rc; 1035 } 1036 1037 int32_t mm_channel_cancel_super_buf_request(mm_channel_t *my_obj) 1038 { 1039 int32_t rc = 0; 1040 /* reset pending_cnt */ 1041 my_obj->pending_cnt = 0; 1042 1043 if (my_obj->pending_pp_cnt > 0) { 1044 rc = mm_channel_cancel_post_processing(my_obj); 1045 } 1046 my_obj->pending_pp_cnt = 0; 1047 return rc; 1048 } 1049 1050 int32_t mm_channel_qbuf(mm_channel_t *my_obj, 1051 mm_camera_buf_def_t *buf) 1052 { 1053 int32_t rc = -1; 1054 struct ion_flush_data cache_inv_data; 1055 int ion_fd; 1056 struct msm_frame *cache_frame; 1057 struct msm_frame *cache_frame1 = NULL; 1058 1059 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, buf->stream_id); 1060 1061 if (NULL != s_obj) { 1062 rc = mm_stream_fsm_fn(s_obj, 1063 MM_STREAM_EVT_QBUF, 1064 (void *)buf, 1065 NULL); 1066 } 1067 1068 #ifdef USE_ION 1069 cache_inv_data.vaddr = cache_frame->buffer; 1070 cache_inv_data.fd = cache_frame->fd; 1071 cache_inv_data.handle = cache_frame->fd_data.handle; 1072 cache_inv_data.length = cache_frame->ion_alloc.len; 1073 ion_fd = cache_frame->ion_dev_fd; 1074 if(ion_fd > 0) { 1075 if(ioctl(ion_fd, ION_IOC_INV_CACHES, &cache_inv_data) < 0) 1076 CDBG_ERROR("%s: Cache Invalidate failed\n", __func__); 1077 else { 1078 CDBG("%s: Successful cache invalidate\n", __func__); 1079 if(cache_frame1) { 1080 ion_fd = cache_frame1->ion_dev_fd; 1081 cache_inv_data.vaddr = cache_frame1->buffer; 1082 cache_inv_data.fd = cache_frame1->fd; 1083 cache_inv_data.handle = cache_frame1->fd_data.handle; 1084 cache_inv_data.length = cache_frame1->ion_alloc.len; 1085 if(ioctl(ion_fd, ION_IOC_INV_CACHES, &cache_inv_data) < 0) 1086 CDBG_ERROR("%s: Cache Invalidate failed\n", __func__); 1087 else 1088 CDBG("%s: Successful cache invalidate\n", __func__); 1089 } 1090 } 1091 } 1092 #endif 1093 1094 return rc; 1095 } 1096 1097 int32_t mm_channel_start_focus(mm_channel_t *my_obj, 1098 uint32_t sensor_idx, 1099 uint32_t focus_mode) 1100 { 1101 return mm_camera_send_native_ctrl_cmd(my_obj->cam_obj, 1102 CAMERA_SET_PARM_AUTO_FOCUS, 1103 sizeof(uint32_t), (void*)focus_mode); 1104 } 1105 1106 int32_t mm_channel_abort_focus(mm_channel_t *my_obj, uint32_t sensor_idx) 1107 { 1108 return mm_camera_send_native_ctrl_cmd(my_obj->cam_obj, 1109 CAMERA_AUTO_FOCUS_CANCEL, 1110 0, NULL); 1111 } 1112 1113 int32_t mm_channel_prepare_snapshot(mm_channel_t *my_obj, uint32_t sensor_idx) 1114 { 1115 return mm_camera_send_native_ctrl_timeout_cmd(my_obj->cam_obj, 1116 CAMERA_PREPARE_SNAPSHOT, 1117 0, NULL, 2000); 1118 } 1119 1120 int32_t mm_channel_set_stream_parm(mm_channel_t *my_obj, 1121 uint32_t s_id, 1122 void *value) 1123 { 1124 int32_t rc = -1; 1125 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, s_id); 1126 if (NULL != s_obj) { 1127 rc = mm_stream_fsm_fn(s_obj, 1128 MM_STREAM_EVT_SET_PARM, 1129 value, 1130 NULL); 1131 } 1132 1133 return rc; 1134 } 1135 1136 int32_t mm_channel_get_stream_parm(mm_channel_t *my_obj, 1137 uint32_t s_id, 1138 void *value) 1139 { 1140 int32_t rc = -1; 1141 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, s_id); 1142 if (NULL != s_obj) { 1143 rc = mm_stream_fsm_fn(s_obj, 1144 MM_STREAM_EVT_GET_PARM, 1145 NULL, 1146 value); 1147 } 1148 1149 return rc; 1150 } 1151 1152 uint8_t mm_channel_need_do_pp(mm_channel_t *my_obj, 1153 mm_channel_queue_node_t *super_buf) 1154 { 1155 uint8_t need_pp = 0; 1156 uint8_t i; 1157 1158 for (i=0; i<super_buf->num_of_bufs; i++) { 1159 if (super_buf->super_buf[i].need_pp) { 1160 need_pp = 1; 1161 break; 1162 } 1163 } 1164 return need_pp; 1165 } 1166 1167 int32_t mm_channel_do_post_processing(mm_channel_t *my_obj, 1168 mm_channel_queue_node_t *super_buf) 1169 { 1170 int32_t rc = 0; 1171 cam_sock_packet_t packet; 1172 uint8_t i; 1173 mm_stream_t* s_obj = NULL; 1174 mm_channel_pp_info_t *cookie = NULL; 1175 1176 /* TODO : currently we only do WNR, may need extended PP */ 1177 /* send cmd to backend to start pp */ 1178 for (i=0; i<super_buf->num_of_bufs; i++) { 1179 if (super_buf->super_buf[i].need_pp) { 1180 s_obj = mm_channel_util_get_stream_by_handler(my_obj, super_buf->super_buf[i].stream_id); 1181 if (NULL != s_obj) { 1182 cookie = (mm_channel_pp_info_t*)malloc(sizeof(mm_channel_pp_info_t)); 1183 if (NULL != cookie) { 1184 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1185 memset(cookie, 0, sizeof(mm_channel_pp_info_t)); 1186 cookie->cam_hdl = my_obj->cam_obj->my_hdl; 1187 cookie->ch_hdl = my_obj->my_hdl; 1188 cookie->stream_hdl = s_obj->my_hdl; 1189 cookie->super_buf = super_buf; 1190 1191 packet.msg_type = CAM_SOCK_MSG_TYPE_WDN_START; 1192 packet.payload.wdn_start.cookie = (unsigned long)cookie; 1193 packet.payload.wdn_start.num_frames = 1; 1194 packet.payload.wdn_start.ext_mode[0] = s_obj->ext_image_mode; 1195 packet.payload.wdn_start.frame_idx[0] = super_buf->super_buf[i].buf->buf_idx; 1196 rc = mm_camera_util_sendmsg(my_obj->cam_obj, &packet, sizeof(packet), 0); 1197 if (0 != rc) { 1198 CDBG_ERROR("%s: Send DoPP msg failed (rc=%d)", __func__, rc); 1199 free(cookie); 1200 break; 1201 } 1202 } else { 1203 CDBG_ERROR("%s: No memory for mm_channel_pp_info_t", __func__); 1204 break; 1205 } 1206 } 1207 } 1208 } 1209 1210 return rc; 1211 } 1212 1213 int32_t mm_channel_cancel_post_processing(mm_channel_t *my_obj) 1214 { 1215 int32_t rc = 0; 1216 /* TODO */ 1217 /* need send cmd to backend to cancel all pp request */ 1218 1219 return rc; 1220 } 1221 1222 int32_t mm_channel_reg_stream_cb(mm_channel_t *my_obj, 1223 mm_stream_data_cb_t *cb, 1224 uint32_t ext_image_mode, 1225 uint32_t sensor_idx) 1226 { 1227 uint8_t idx; 1228 mm_stream_t *dest_stream = NULL; 1229 int32_t rc = -1; 1230 1231 /* browse all streams in channel to find the destination */ 1232 for (idx=0; idx < MM_CAMEAR_STRAEM_NUM_MAX; idx++) { 1233 if (my_obj->streams[idx].state != MM_STREAM_STATE_NOTUSED && 1234 my_obj->streams[idx].ext_image_mode == ext_image_mode && 1235 my_obj->streams[idx].sensor_idx == sensor_idx) { 1236 /* find matching stream as the destination */ 1237 dest_stream = &my_obj->streams[idx]; 1238 break; 1239 } 1240 } 1241 1242 if (NULL != dest_stream) { 1243 rc = mm_stream_reg_buf_cb(dest_stream, cb); 1244 } 1245 1246 return rc; 1247 } 1248 1249 int32_t mm_channel_superbuf_queue_init(mm_channel_queue_t * queue) 1250 { 1251 return mm_camera_queue_init(&queue->que); 1252 } 1253 1254 int32_t mm_channel_superbuf_queue_deinit(mm_channel_queue_t * queue) 1255 { 1256 return mm_camera_queue_deinit(&queue->que); 1257 } 1258 1259 int8_t mm_channel_util_seq_comp_w_rollover(uint32_t v1, 1260 uint32_t v2) 1261 { 1262 int8_t ret = 0; 1263 1264 /* TODO: need to handle the case if v2 roll over to 0 */ 1265 if (v1 > v2) { 1266 ret = 1; 1267 } else if (v1 < v2) { 1268 ret = -1; 1269 } 1270 1271 return ret; 1272 } 1273 1274 int32_t mm_channel_superbuf_comp_and_enqueue( 1275 mm_channel_t* ch_obj, 1276 mm_channel_queue_t * queue, 1277 mm_camera_buf_info_t *buf_info) 1278 { 1279 mm_camera_q_node_t* node = NULL; 1280 struct cam_list *head = NULL; 1281 struct cam_list *pos = NULL; 1282 mm_channel_queue_node_t* super_buf = NULL; 1283 uint8_t buf_s_idx, i; 1284 1285 for (buf_s_idx=0; buf_s_idx < queue->num_streams; buf_s_idx++) { 1286 if (buf_info->stream_id == queue->bundled_streams[buf_s_idx]) { 1287 break; 1288 } 1289 } 1290 if (buf_s_idx == queue->num_streams) { 1291 CDBG_ERROR("%s: buf from stream (%d) not bundled", __func__, buf_info->stream_id); 1292 return -1; 1293 } 1294 1295 if (mm_channel_util_seq_comp_w_rollover(buf_info->frame_idx, 1296 queue->expected_frame_id) < 0) { 1297 /* incoming buf is older than expected buf id, will discard it */ 1298 mm_channel_qbuf(ch_obj, buf_info->buf); 1299 return 0; 1300 } 1301 1302 if (MM_CAMERA_SUPER_BUF_PRIORITY_NORMAL != queue->attr.priority) { 1303 /* TODO */ 1304 /* need to decide if we want to queue the frame based on focus or exposure 1305 * if frame not to be queued, we need to qbuf it back */ 1306 } 1307 1308 /* comp */ 1309 pthread_mutex_lock(&queue->que.lock); 1310 head = &queue->que.head.list; 1311 /* get the last one in the queue which is possibly having no matching */ 1312 pos = head->next; 1313 while (pos != head) { 1314 node = member_of(pos, mm_camera_q_node_t, list); 1315 super_buf = (mm_channel_queue_node_t*)node->data; 1316 if (NULL != super_buf) { 1317 if (super_buf->matched) { 1318 /* find a matched super buf, move to next one */ 1319 pos = pos->next; 1320 continue; 1321 } else { 1322 /* have an unmatched super buf, break the loop */ 1323 break; 1324 } 1325 } 1326 } 1327 1328 if (pos == head) { 1329 /* all nodes in queue are mtached, or no node in queue 1330 * create a new node */ 1331 mm_channel_queue_node_t *new_buf = NULL; 1332 mm_camera_q_node_t* new_node = NULL; 1333 1334 new_buf = (mm_channel_queue_node_t*)malloc(sizeof(mm_channel_queue_node_t)); 1335 new_node = (mm_camera_q_node_t*)malloc(sizeof(mm_camera_q_node_t)); 1336 if (NULL != new_buf && NULL != new_node) { 1337 memset(new_buf, 0, sizeof(mm_channel_queue_node_t)); 1338 memset(new_node, 0, sizeof(mm_camera_q_node_t)); 1339 new_node->data = (void *)new_buf; 1340 new_buf->num_of_bufs = queue->num_streams; 1341 memcpy(&new_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t)); 1342 1343 /* enqueue */ 1344 //cam_list_add_tail_node(&node->list, &queue->que.head.list); 1345 cam_list_add_tail_node(&new_node->list, &queue->que.head.list); 1346 queue->que.size++; 1347 1348 if(queue->num_streams == 1) { 1349 //TODO : Check. Live snapshot will have one stream in bundle? 1350 new_buf->matched = 1; 1351 1352 if (new_buf->matched) { 1353 queue->expected_frame_id = buf_info->frame_idx + queue->attr.post_frame_skip; 1354 queue->match_cnt++; 1355 } 1356 } 1357 } else { 1358 /* No memory */ 1359 if (NULL != new_buf) { 1360 free(new_buf); 1361 } 1362 if (NULL != new_node) { 1363 free(new_node); 1364 } 1365 /* qbuf the new buf since we cannot enqueue */ 1366 mm_channel_qbuf(ch_obj, buf_info->buf); 1367 } 1368 } else { 1369 /* find an unmatched super buf */ 1370 if (super_buf->super_buf[buf_s_idx].frame_idx == 0) { 1371 /* new frame from the stream_id */ 1372 uint8_t is_new = 1; 1373 uint32_t frame_idx; 1374 1375 for (i=0; i < super_buf->num_of_bufs; i++) { 1376 //for (i=0; i < buf_s_idx; i++) { 1377 if(super_buf->super_buf[i].buf == NULL) { 1378 continue; 1379 } 1380 frame_idx = super_buf->super_buf[i].buf->frame_idx; 1381 if (frame_idx == 0) { 1382 continue; 1383 } 1384 if (frame_idx < buf_info->frame_idx) { 1385 /* existing frame is older than the new frame, qbuf it */ 1386 mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf); 1387 memset(&super_buf->super_buf[i], 0, sizeof(mm_camera_buf_info_t)); 1388 } else if (frame_idx > buf_info->frame_idx) { 1389 /* new frame is older */ 1390 is_new = 0; 1391 break; 1392 }else{ 1393 //TODO: reveiw again 1394 break; 1395 } 1396 } 1397 if (is_new) { 1398 memcpy(&super_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t)); 1399 1400 /* check if superbuf is all matched */ 1401 super_buf->matched = 1; 1402 for (i=0; i < super_buf->num_of_bufs; i++) { 1403 if (super_buf->super_buf[i].frame_idx == 0) { 1404 super_buf->matched = 0; 1405 break; 1406 } 1407 } 1408 1409 if (super_buf->matched) { 1410 queue->expected_frame_id = buf_info->frame_idx + queue->attr.post_frame_skip; 1411 queue->match_cnt++; 1412 } 1413 } else { 1414 mm_channel_qbuf(ch_obj, buf_info->buf); 1415 } 1416 } else { 1417 if (super_buf->super_buf[buf_s_idx].frame_idx < buf_info->frame_idx) { 1418 /* current frames in superbuf are older than the new frame 1419 * qbuf all current frames */ 1420 for (i=0; i<super_buf->num_of_bufs; i++) { 1421 if (super_buf->super_buf[i].frame_idx != 0) { 1422 mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf); 1423 memset(&super_buf->super_buf[i], 0, sizeof(mm_camera_buf_info_t)); 1424 } 1425 } 1426 /* add the new frame into the superbuf */ 1427 memcpy(&super_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t)); 1428 } else { 1429 /* the new frame is older, just ignor */ 1430 mm_channel_qbuf(ch_obj, buf_info->buf); 1431 } 1432 } 1433 } 1434 pthread_mutex_unlock(&queue->que.lock); 1435 1436 return 0; 1437 } 1438 1439 mm_channel_queue_node_t* mm_channel_superbuf_dequeue_internal(mm_channel_queue_t * queue) 1440 { 1441 mm_camera_q_node_t* node = NULL; 1442 struct cam_list *head = NULL; 1443 struct cam_list *pos = NULL; 1444 mm_channel_queue_node_t* super_buf = NULL; 1445 1446 head = &queue->que.head.list; 1447 pos = head->next; 1448 if (pos != head) { 1449 /* get the first node */ 1450 node = member_of(pos, mm_camera_q_node_t, list); 1451 super_buf = (mm_channel_queue_node_t*)node->data; 1452 if (NULL != super_buf) { 1453 if (super_buf->matched) { 1454 /* we found a mtaching super buf, dequeue it */ 1455 cam_list_del_node(&node->list); 1456 queue->que.size--; 1457 queue->match_cnt--; 1458 free(node); 1459 } else { 1460 super_buf = NULL; 1461 } 1462 } 1463 } 1464 1465 return super_buf; 1466 } 1467 1468 mm_channel_queue_node_t* mm_channel_superbuf_dequeue(mm_channel_queue_t * queue) 1469 { 1470 mm_camera_q_node_t* node = NULL; 1471 struct cam_list *head = NULL; 1472 struct cam_list *pos = NULL; 1473 mm_channel_queue_node_t* super_buf = NULL; 1474 1475 pthread_mutex_lock(&queue->que.lock); 1476 super_buf = mm_channel_superbuf_dequeue_internal(queue); 1477 pthread_mutex_unlock(&queue->que.lock); 1478 1479 return super_buf; 1480 } 1481 1482 int32_t mm_channel_superbuf_bufdone_overflow(mm_channel_t* my_obj, 1483 mm_channel_queue_t * queue) 1484 { 1485 int32_t rc = 0, i; 1486 mm_channel_queue_node_t* super_buf = NULL; 1487 if (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == queue->attr.notify_mode) { 1488 /* for continuous streaming mode, no overflow is needed */ 1489 return 0; 1490 } 1491 1492 /* bufdone overflowed bufs */ 1493 pthread_mutex_lock(&queue->que.lock); 1494 while (queue->match_cnt > queue->attr.water_mark) { 1495 super_buf = mm_channel_superbuf_dequeue_internal(queue); 1496 if (NULL != super_buf) { 1497 for (i=0; i<super_buf->num_of_bufs; i++) { 1498 if (NULL != super_buf->super_buf[i].buf) { 1499 mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf); 1500 } 1501 } 1502 free(super_buf); 1503 } 1504 } 1505 pthread_mutex_unlock(&queue->que.lock); 1506 1507 return rc; 1508 } 1509 1510 int32_t mm_channel_superbuf_skip(mm_channel_t* my_obj, 1511 mm_channel_queue_t * queue) 1512 { 1513 int32_t rc = 0, i, count; 1514 mm_channel_queue_node_t* super_buf = NULL; 1515 if (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == queue->attr.notify_mode) { 1516 /* for continuous streaming mode, no skip is needed */ 1517 return 0; 1518 } 1519 1520 /* bufdone overflowed bufs */ 1521 pthread_mutex_lock(&queue->que.lock); 1522 while (queue->match_cnt > queue->attr.look_back) { 1523 super_buf = mm_channel_superbuf_dequeue_internal(queue); 1524 if (NULL != super_buf) { 1525 for (i=0; i<super_buf->num_of_bufs; i++) { 1526 if (NULL != super_buf->super_buf[i].buf) { 1527 mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf); 1528 } 1529 } 1530 free(super_buf); 1531 } 1532 } 1533 pthread_mutex_unlock(&queue->que.lock); 1534 1535 return rc; 1536 } 1537 1538