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 <pthread.h> 32 #include <fcntl.h> 33 34 // Camera dependencies 35 #include "cam_semaphore.h" 36 #include "mm_camera_dbg.h" 37 #include "mm_camera_interface.h" 38 #include "mm_camera.h" 39 #include "mm_camera_muxer.h" 40 41 #include "cam_cond.h" 42 43 extern mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler); 44 extern mm_channel_t * mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj, 45 uint32_t handler); 46 /* Static frame sync info used between different camera channels*/ 47 static mm_channel_frame_sync_info_t fs = { .num_cam =0, .pos = 0}; 48 /* Frame sync info access lock */ 49 static pthread_mutex_t fs_lock = PTHREAD_MUTEX_INITIALIZER; 50 51 /* internal function declare goes here */ 52 int32_t mm_channel_qbuf(mm_channel_t *my_obj, 53 mm_camera_buf_def_t *buf); 54 int32_t mm_channel_cancel_buf(mm_channel_t *my_obj, 55 uint32_t stream_id, uint32_t buf_idx); 56 int32_t mm_channel_init(mm_channel_t *my_obj, 57 mm_camera_channel_attr_t *attr, 58 mm_camera_buf_notify_t channel_cb, 59 void *userdata); 60 void mm_channel_release(mm_channel_t *my_obj); 61 uint32_t mm_channel_add_stream(mm_channel_t *my_obj); 62 int32_t mm_channel_del_stream(mm_channel_t *my_obj, 63 uint32_t stream_id); 64 uint32_t mm_channel_link_stream(mm_channel_t *my_obj, 65 mm_camera_stream_link_t *stream_link); 66 uint32_t mm_channel_reg_frame_sync(mm_channel_t *my_obj, 67 mm_evt_paylod_reg_frame_sync *sync); 68 int32_t mm_channel_trigger_frame_sync(mm_channel_t *my_obj, 69 mm_evt_paylod_trigger_frame_sync *payload); 70 int32_t mm_channel_config_stream(mm_channel_t *my_obj, 71 uint32_t stream_id, 72 mm_camera_stream_config_t *config); 73 int32_t mm_channel_get_bundle_info(mm_channel_t *my_obj, 74 cam_bundle_config_t *bundle_info); 75 int32_t mm_channel_start(mm_channel_t *my_obj); 76 int32_t mm_channel_start_sensor_streaming(mm_channel_t *my_obj); 77 int32_t mm_channel_stop(mm_channel_t *my_obj, bool stop_immediately); 78 int32_t mm_channel_request_super_buf(mm_channel_t *my_obj, 79 mm_camera_req_buf_t *buf); 80 int32_t mm_channel_cancel_super_buf_request(mm_channel_t *my_obj); 81 int32_t mm_channel_flush_super_buf_queue(mm_channel_t *my_obj, 82 uint32_t frame_idx, 83 cam_stream_type_t stream_type); 84 int32_t mm_channel_config_notify_mode(mm_channel_t *my_obj, 85 mm_camera_super_buf_notify_mode_t notify_mode); 86 int32_t mm_channel_start_zsl_snapshot(mm_channel_t *my_obj); 87 int32_t mm_channel_stop_zsl_snapshot(mm_channel_t *my_obj); 88 int32_t mm_channel_superbuf_flush(mm_channel_t* my_obj, 89 mm_channel_queue_t * queue, cam_stream_type_t cam_type); 90 int32_t mm_channel_set_stream_parm(mm_channel_t *my_obj, 91 mm_evt_paylod_set_get_stream_parms_t *payload); 92 int32_t mm_channel_get_queued_buf_count(mm_channel_t *my_obj, 93 uint32_t stream_id); 94 95 int32_t mm_channel_get_stream_parm(mm_channel_t *my_obj, 96 mm_evt_paylod_set_get_stream_parms_t *payload); 97 int32_t mm_channel_do_stream_action(mm_channel_t *my_obj, 98 mm_evt_paylod_do_stream_action_t *payload); 99 int32_t mm_channel_map_stream_buf(mm_channel_t *my_obj, 100 cam_buf_map_type *payload); 101 int32_t mm_channel_map_stream_bufs(mm_channel_t *my_obj, 102 cam_buf_map_type_list *payload); 103 int32_t mm_channel_unmap_stream_buf(mm_channel_t *my_obj, 104 cam_buf_unmap_type *payload); 105 106 /* state machine function declare */ 107 int32_t mm_channel_fsm_fn_notused(mm_channel_t *my_obj, 108 mm_channel_evt_type_t evt, 109 void * in_val, 110 void * out_val); 111 int32_t mm_channel_fsm_fn_stopped(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_active(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_paused(mm_channel_t *my_obj, 120 mm_channel_evt_type_t evt, 121 void * in_val, 122 void * out_val); 123 124 /* channel super queue functions */ 125 int32_t mm_channel_superbuf_queue_init(mm_channel_queue_t * queue); 126 int32_t mm_channel_superbuf_queue_deinit(mm_channel_queue_t * queue); 127 int32_t mm_channel_superbuf_comp_and_enqueue(mm_channel_t *ch_obj, 128 mm_channel_queue_t * queue, 129 mm_camera_buf_info_t *buf); 130 mm_channel_queue_node_t* mm_channel_superbuf_dequeue( 131 mm_channel_queue_t * queue, mm_channel_t *ch_obj); 132 int32_t mm_channel_superbuf_bufdone_overflow(mm_channel_t *my_obj, 133 mm_channel_queue_t *queue); 134 int32_t mm_channel_superbuf_skip(mm_channel_t *my_obj, 135 mm_channel_queue_t *queue); 136 137 static int32_t mm_channel_proc_general_cmd(mm_channel_t *my_obj, 138 mm_camera_generic_cmd_t *p_gen_cmd); 139 int32_t mm_channel_superbuf_flush_matched(mm_channel_t* my_obj, 140 mm_channel_queue_t * queue); 141 142 /* Start of Frame Sync util methods */ 143 void mm_frame_sync_reset(); 144 int32_t mm_frame_sync_register_channel(mm_channel_t *ch_obj); 145 int32_t mm_frame_sync_unregister_channel(mm_channel_t *ch_obj); 146 int32_t mm_frame_sync_add(uint32_t frame_id, mm_channel_t *ch_obj); 147 int32_t mm_frame_sync_remove(uint32_t frame_id); 148 uint32_t mm_frame_sync_find_matched(uint8_t oldest); 149 int8_t mm_frame_sync_find_frame_index(uint32_t frame_id); 150 void mm_frame_sync_lock_queues(); 151 void mm_frame_sync_unlock_queues(); 152 void mm_channel_node_qbuf(mm_channel_t *ch_obj, mm_channel_queue_node_t *node); 153 /* End of Frame Sync Util methods */ 154 void mm_channel_send_super_buf(mm_channel_node_info_t *info); 155 mm_channel_queue_node_t* mm_channel_superbuf_dequeue_frame_internal( 156 mm_channel_queue_t * queue, uint32_t frame_idx); 157 158 /*=========================================================================== 159 * FUNCTION : mm_channel_util_get_stream_by_handler 160 * 161 * DESCRIPTION: utility function to get a stream object from its handle 162 * 163 * PARAMETERS : 164 * @cam_obj: ptr to a channel object 165 * @handler: stream handle 166 * 167 * RETURN : ptr to a stream object. 168 * NULL if failed. 169 *==========================================================================*/ 170 mm_stream_t * mm_channel_util_get_stream_by_handler( 171 mm_channel_t * ch_obj, 172 uint32_t handler) 173 { 174 int i; 175 mm_stream_t *s_obj = NULL; 176 177 for(i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) { 178 if ((MM_STREAM_STATE_NOTUSED != ch_obj->streams[i].state) && 179 (handler == ch_obj->streams[i].my_hdl)) { 180 s_obj = &ch_obj->streams[i]; 181 break; 182 } 183 } 184 return s_obj; 185 } 186 187 /*=========================================================================== 188 * FUNCTION : mm_channel_dispatch_super_buf 189 * 190 * DESCRIPTION: dispatch super buffer of bundle to registered user 191 * 192 * PARAMETERS : 193 * @cmd_cb : ptr storing matched super buf information 194 * @userdata: user data ptr 195 * 196 * RETURN : none 197 *==========================================================================*/ 198 static void mm_channel_dispatch_super_buf(mm_camera_cmdcb_t *cmd_cb, 199 void* user_data) 200 { 201 mm_channel_t *my_obj = (mm_channel_t *)user_data; 202 mm_channel_t *m_obj = my_obj; 203 uint32_t i = 0; 204 205 if (NULL == my_obj) { 206 return; 207 } 208 209 if (m_obj->master_ch_obj != NULL) { 210 //get master object 211 m_obj = m_obj->master_ch_obj; 212 } 213 214 pthread_mutex_lock(&m_obj->frame_sync.sync_lock); 215 if(m_obj->frame_sync.is_active) { 216 //Frame sync enabled on master 217 switch(cmd_cb->cmd_type) { 218 case MM_CAMERA_CMD_TYPE_SUPER_BUF_DATA_CB: { 219 mm_camera_muxer_channel_frame_sync(&cmd_cb->u.superbuf, my_obj); 220 } 221 break; 222 case MM_CAMERA_CMD_TYPE_REQ_DATA_CB : { 223 mm_camera_muxer_channel_req_data_cb(&cmd_cb->u.req_buf, my_obj); 224 } 225 break; 226 case MM_CAMERA_CMD_TYPE_FLUSH_QUEUE : { 227 mm_camera_muxer_channel_frame_sync_flush(my_obj); 228 cam_sem_post(&my_obj->cb_thread.sync_sem); 229 } 230 break; 231 default : { 232 LOGW("Invalid cmd type %d", cmd_cb->cmd_type); 233 } 234 break; 235 } 236 } else if (my_obj->bundle.super_buf_notify_cb && my_obj->bundle.is_cb_active) { 237 //Super buffer channel callback is active 238 my_obj->bundle.super_buf_notify_cb(&cmd_cb->u.superbuf, my_obj->bundle.user_data); 239 } else { 240 //Nothing enabled. Return this buffer 241 mm_camera_super_buf_t *buffer = &cmd_cb->u.superbuf; 242 for (i=0; i < buffer->num_bufs; i++) { 243 if (buffer->bufs[i] != NULL) { 244 mm_channel_qbuf(my_obj, buffer->bufs[i]); 245 } 246 } 247 } 248 pthread_mutex_unlock(&m_obj->frame_sync.sync_lock); 249 } 250 251 /*=========================================================================== 252 * FUNCTION : mm_channel_send_frame_sync_req_buf 253 * 254 * DESCRIPTION: Request buffer from super buffer sync queue 255 * 256 * PARAMETERS : 257 * @my_obj : channel object 258 * 259 * RETURN : int32_t type of status 260 * 0 -- success 261 * -1 -- failure 262 *==========================================================================*/ 263 int32_t mm_channel_send_frame_sync_req_buf(mm_channel_t* my_obj) 264 { 265 int32_t rc = 0; 266 mm_channel_t *m_obj = my_obj; 267 mm_camera_req_buf_type_t type = my_obj->req_type; 268 269 if (m_obj->master_ch_obj != NULL) { 270 m_obj = m_obj->master_ch_obj; 271 } 272 273 if (!m_obj->frame_sync.is_active) { 274 return rc; 275 } 276 277 if (MM_CAMERA_REQ_FRAME_SYNC_BUF != type) { 278 m_obj = my_obj; 279 } else if (m_obj != my_obj) { 280 /*Issue sync request only using master channel*/ 281 return rc; 282 } 283 284 mm_camera_cmdcb_t* cb_node = NULL; 285 286 /* send cam_sem_post to wake up cb thread to flush sync queue */ 287 cb_node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 288 if (NULL != cb_node) { 289 memset(cb_node, 0, sizeof(mm_camera_cmdcb_t)); 290 cb_node->cmd_type = MM_CAMERA_CMD_TYPE_REQ_DATA_CB; 291 292 cb_node->u.req_buf.type = type; 293 cb_node->u.req_buf.num_buf_requested = 1; 294 cb_node->u.req_buf.cam_num = m_obj->cam_obj->my_num; 295 296 /* enqueue to cb thread */ 297 cam_queue_enq(&(m_obj->cb_thread.cmd_queue), cb_node); 298 /* wake up cb thread */ 299 cam_sem_post(&(m_obj->cb_thread.cmd_sem)); 300 } else { 301 LOGE("No memory for mm_camera_node_t"); 302 rc = -1; 303 } 304 return rc; 305 } 306 307 /*=========================================================================== 308 * FUNCTION : mm_channel_process_stream_buf 309 * 310 * DESCRIPTION: handle incoming buffer from stream in a bundle. In this function, 311 * matching logic will be performed on incoming stream frames. 312 * Will depends on the bundle attribute, either storing matched frames 313 * in the superbuf queue, or sending matched superbuf frames to upper 314 * layer through registered callback. 315 * 316 * PARAMETERS : 317 * @cmd_cb : ptr storing matched super buf information 318 * @userdata: user data ptr 319 * 320 * RETURN : none 321 *==========================================================================*/ 322 static void mm_channel_process_stream_buf(mm_camera_cmdcb_t * cmd_cb, 323 void *user_data) 324 { 325 mm_camera_super_buf_notify_mode_t notify_mode; 326 mm_channel_queue_node_t *node = NULL; 327 mm_channel_t *ch_obj = (mm_channel_t *)user_data; 328 mm_channel_t *m_obj = ch_obj; 329 uint32_t i = 0; 330 /* Set expected frame id to a future frame idx, large enough to wait 331 * for good_frame_idx_range, and small enough to still capture an image */ 332 uint8_t needStartZSL = FALSE; 333 334 if (NULL == ch_obj) { 335 return; 336 } 337 338 //get Master object incase of multiple channel 339 if (m_obj->master_ch_obj != NULL) { 340 m_obj = m_obj->master_ch_obj; 341 } 342 343 if (MM_CAMERA_CMD_TYPE_DATA_CB == cmd_cb->cmd_type) { 344 /* comp_and_enqueue */ 345 mm_channel_superbuf_comp_and_enqueue( 346 ch_obj, 347 &ch_obj->bundle.superbuf_queue, 348 &cmd_cb->u.buf); 349 } else if (MM_CAMERA_CMD_TYPE_REQ_DATA_CB == cmd_cb->cmd_type) { 350 /* skip frames if needed */ 351 ch_obj->pending_cnt = cmd_cb->u.req_buf.num_buf_requested; 352 ch_obj->pending_retro_cnt = cmd_cb->u.req_buf.num_retro_buf_requested; 353 ch_obj->req_type = cmd_cb->u.req_buf.type; 354 ch_obj->bWaitForPrepSnapshotDone = 0; 355 if (cmd_cb->u.req_buf.frame_idx) { 356 ch_obj->requested_frame_id[ch_obj->frame_req_cnt++] = 357 cmd_cb->u.req_buf.frame_idx; 358 LOGH("FrameID Request from Q = %d", cmd_cb->u.req_buf.frame_idx); 359 } 360 361 LOGH("pending cnt (%d)", ch_obj->pending_cnt); 362 if (!ch_obj->pending_cnt || (ch_obj->pending_retro_cnt > ch_obj->pending_cnt)) { 363 ch_obj->pending_retro_cnt = ch_obj->pending_cnt; 364 } 365 if (ch_obj->pending_retro_cnt > 0) { 366 LOGL("Resetting need Led Flash!!!"); 367 ch_obj->needLEDFlash = 0; 368 } 369 ch_obj->stopZslSnapshot = 0; 370 ch_obj->unLockAEC = 0; 371 372 mm_channel_superbuf_skip(ch_obj, &ch_obj->bundle.superbuf_queue); 373 374 } else if (MM_CAMERA_CMD_TYPE_START_ZSL == cmd_cb->cmd_type) { 375 ch_obj->manualZSLSnapshot = TRUE; 376 mm_camera_start_zsl_snapshot(ch_obj->cam_obj); 377 } else if (MM_CAMERA_CMD_TYPE_STOP_ZSL == cmd_cb->cmd_type) { 378 ch_obj->manualZSLSnapshot = FALSE; 379 mm_camera_stop_zsl_snapshot(ch_obj->cam_obj); 380 } else if (MM_CAMERA_CMD_TYPE_CONFIG_NOTIFY == cmd_cb->cmd_type) { 381 ch_obj->bundle.superbuf_queue.attr.notify_mode = cmd_cb->u.notify_mode; 382 } else if (MM_CAMERA_CMD_TYPE_FLUSH_QUEUE == cmd_cb->cmd_type) { 383 ch_obj->bundle.superbuf_queue.expected_frame_id = cmd_cb->u.flush_cmd.frame_idx; 384 mm_channel_superbuf_flush(ch_obj, 385 &ch_obj->bundle.superbuf_queue, cmd_cb->u.flush_cmd.stream_type); 386 if (m_obj->frame_sync.is_active) { 387 cam_sem_wait(&(m_obj->cb_thread.sync_sem)); 388 } 389 cam_sem_post(&(ch_obj->cmd_thread.sync_sem)); 390 return; 391 } else if (MM_CAMERA_CMD_TYPE_GENERAL == cmd_cb->cmd_type) { 392 LOGH("MM_CAMERA_CMD_TYPE_GENERAL"); 393 switch (cmd_cb->u.gen_cmd.type) { 394 case MM_CAMERA_GENERIC_CMD_TYPE_AE_BRACKETING: 395 case MM_CAMERA_GENERIC_CMD_TYPE_AF_BRACKETING: { 396 uint32_t start = cmd_cb->u.gen_cmd.payload[0]; 397 LOGI("MM_CAMERA_GENERIC_CMDTYPE_AF_BRACKETING %u", 398 start); 399 mm_channel_superbuf_flush(ch_obj, 400 &ch_obj->bundle.superbuf_queue, CAM_STREAM_TYPE_DEFAULT); 401 402 if (start) { 403 LOGH("need AE bracketing, start zsl snapshot"); 404 ch_obj->bracketingState = MM_CHANNEL_BRACKETING_STATE_WAIT_GOOD_FRAME_IDX; 405 } else { 406 ch_obj->bracketingState = MM_CHANNEL_BRACKETING_STATE_OFF; 407 } 408 } 409 break; 410 case MM_CAMERA_GENERIC_CMD_TYPE_FLASH_BRACKETING: { 411 uint32_t start = cmd_cb->u.gen_cmd.payload[0]; 412 LOGI("MM_CAMERA_GENERIC_CMDTYPE_FLASH_BRACKETING %u", 413 start); 414 mm_channel_superbuf_flush(ch_obj, 415 &ch_obj->bundle.superbuf_queue, CAM_STREAM_TYPE_DEFAULT); 416 417 if (start) { 418 LOGH("need flash bracketing"); 419 ch_obj->isFlashBracketingEnabled = TRUE; 420 } else { 421 ch_obj->isFlashBracketingEnabled = FALSE; 422 } 423 } 424 break; 425 case MM_CAMERA_GENERIC_CMD_TYPE_ZOOM_1X: { 426 uint32_t start = cmd_cb->u.gen_cmd.payload[0]; 427 LOGI("MM_CAMERA_GENERIC_CMD_TYPE_ZOOM_1X %u", 428 start); 429 mm_channel_superbuf_flush(ch_obj, 430 &ch_obj->bundle.superbuf_queue, CAM_STREAM_TYPE_DEFAULT); 431 432 if (start) { 433 LOGH("need zoom 1x frame"); 434 ch_obj->isZoom1xFrameRequested = TRUE; 435 } else { 436 ch_obj->isZoom1xFrameRequested = FALSE; 437 } 438 } 439 break; 440 case MM_CAMERA_GENERIC_CMD_TYPE_CAPTURE_SETTING: { 441 uint32_t start = cmd_cb->u.gen_cmd.payload[0]; 442 LOGI("MM_CAMERA_GENERIC_CMD_TYPE_CAPTURE_SETTING %u num_batch = %d", 443 start, cmd_cb->u.gen_cmd.frame_config.num_batch); 444 445 if (start) { 446 memset(&ch_obj->frameConfig, 0, sizeof(cam_capture_frame_config_t)); 447 for (i = 0; i < cmd_cb->u.gen_cmd.frame_config.num_batch; i++) { 448 if (cmd_cb->u.gen_cmd.frame_config.configs[i].type 449 != CAM_CAPTURE_RESET) { 450 ch_obj->frameConfig.configs[ 451 ch_obj->frameConfig.num_batch] = 452 cmd_cb->u.gen_cmd.frame_config.configs[i]; 453 ch_obj->frameConfig.num_batch++; 454 LOGH("capture setting frame = %d type = %d", 455 i,ch_obj->frameConfig.configs[ 456 ch_obj->frameConfig.num_batch].type); 457 } 458 } 459 LOGD("Capture setting Batch Count %d", 460 ch_obj->frameConfig.num_batch); 461 ch_obj->isConfigCapture = TRUE; 462 } else { 463 ch_obj->isConfigCapture = FALSE; 464 memset(&ch_obj->frameConfig, 0, sizeof(cam_capture_frame_config_t)); 465 } 466 ch_obj->cur_capture_idx = 0; 467 memset(ch_obj->capture_frame_id, 0, sizeof(uint8_t) * MAX_CAPTURE_BATCH_NUM); 468 break; 469 } 470 default: 471 LOGE("Error: Invalid command"); 472 break; 473 } 474 } 475 notify_mode = ch_obj->bundle.superbuf_queue.attr.notify_mode; 476 477 /*Handle use case which does not need start ZSL even in unified case*/ 478 if ((ch_obj->pending_cnt > 0) 479 && (ch_obj->isConfigCapture) 480 && (ch_obj->manualZSLSnapshot == FALSE) 481 && (ch_obj->startZSlSnapshotCalled == FALSE)) { 482 needStartZSL = TRUE; 483 for (i = ch_obj->cur_capture_idx; 484 i < ch_obj->frameConfig.num_batch; 485 i++) { 486 cam_capture_type type = ch_obj->frameConfig.configs[i].type; 487 if (((type == CAM_CAPTURE_FLASH) && (!ch_obj->needLEDFlash)) 488 || ((type == CAM_CAPTURE_LOW_LIGHT) && (!ch_obj->needLowLightZSL))) { 489 /*For flash and low light capture, start ZSL is triggered only if needed*/ 490 needStartZSL = FALSE; 491 break; 492 } 493 } 494 } 495 496 if ((ch_obj->isConfigCapture) 497 && (needStartZSL)) { 498 for (i = ch_obj->cur_capture_idx; 499 i < ch_obj->frameConfig.num_batch; 500 i++) { 501 ch_obj->capture_frame_id[i] = 502 ch_obj->bundle.superbuf_queue.expected_frame_id 503 + MM_CAMERA_MAX_FUTURE_FRAME_WAIT; 504 } 505 506 /* Need to Flush the queue and trigger frame config */ 507 mm_channel_superbuf_flush(ch_obj, 508 &ch_obj->bundle.superbuf_queue, CAM_STREAM_TYPE_DEFAULT); 509 LOGI("TRIGGER Start ZSL"); 510 mm_camera_start_zsl_snapshot(ch_obj->cam_obj); 511 ch_obj->startZSlSnapshotCalled = TRUE; 512 ch_obj->burstSnapNum = ch_obj->pending_cnt; 513 ch_obj->bWaitForPrepSnapshotDone = 0; 514 } else if ((ch_obj->pending_cnt > 0) 515 && ((ch_obj->needLEDFlash == TRUE) || 516 (MM_CHANNEL_BRACKETING_STATE_OFF != ch_obj->bracketingState)) 517 && (ch_obj->manualZSLSnapshot == FALSE) 518 && ch_obj->startZSlSnapshotCalled == FALSE) { 519 520 LOGI("TRIGGER Start ZSL for Flash"); 521 mm_camera_start_zsl_snapshot(ch_obj->cam_obj); 522 ch_obj->startZSlSnapshotCalled = TRUE; 523 ch_obj->burstSnapNum = ch_obj->pending_cnt; 524 ch_obj->bWaitForPrepSnapshotDone = 0; 525 } else if (((ch_obj->pending_cnt == 0) || (ch_obj->stopZslSnapshot == 1)) 526 && (ch_obj->manualZSLSnapshot == FALSE) 527 && (ch_obj->startZSlSnapshotCalled == TRUE)) { 528 LOGI("TRIGGER Stop ZSL for cancel picture"); 529 mm_camera_stop_zsl_snapshot(ch_obj->cam_obj); 530 // Unlock AEC 531 ch_obj->startZSlSnapshotCalled = FALSE; 532 ch_obj->needLEDFlash = FALSE; 533 ch_obj->burstSnapNum = 0; 534 ch_obj->stopZslSnapshot = 0; 535 ch_obj->bWaitForPrepSnapshotDone = 0; 536 ch_obj->unLockAEC = 1; 537 ch_obj->bracketingState = MM_CHANNEL_BRACKETING_STATE_OFF; 538 ch_obj->isConfigCapture = FALSE; 539 } 540 /* bufdone for overflowed bufs */ 541 mm_channel_superbuf_bufdone_overflow(ch_obj, &ch_obj->bundle.superbuf_queue); 542 543 LOGD("Super Buffer received, pending_cnt=%d queue cnt = %d expected = %d", 544 ch_obj->pending_cnt, ch_obj->bundle.superbuf_queue.match_cnt, 545 ch_obj->bundle.superbuf_queue.expected_frame_id); 546 547 /* dispatch frame if pending_cnt>0 or is in continuous streaming mode */ 548 while ((((ch_obj->pending_cnt > 0) || 549 (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == notify_mode)) && 550 (!ch_obj->bWaitForPrepSnapshotDone)) 551 || (m_obj->frame_sync.is_active)) { 552 uint8_t trigger_cb = 0; 553 554 /* dequeue */ 555 mm_channel_node_info_t info; 556 memset(&info, 0x0, sizeof(info)); 557 558 if (ch_obj->req_type == MM_CAMERA_REQ_FRAME_SYNC_BUF 559 && !m_obj->frame_sync.is_active) { 560 // Lock the Queues 561 mm_frame_sync_lock_queues(); 562 uint32_t match_frame = mm_frame_sync_find_matched(FALSE); 563 if (match_frame) { 564 uint8_t j = 0; 565 for (j = 0; j < MAX_NUM_CAMERA_PER_BUNDLE; j++) { 566 if (fs.ch_obj[j]) { 567 mm_channel_queue_t *ch_queue = 568 &fs.ch_obj[j]->bundle.superbuf_queue; 569 if (ch_queue == NULL) { 570 LOGW("Channel queue is NULL"); 571 break; 572 } 573 node = mm_channel_superbuf_dequeue_frame_internal( 574 ch_queue, match_frame); 575 if (node != NULL) { 576 info.ch_obj[info.num_nodes] = fs.ch_obj[j]; 577 info.node[info.num_nodes] = node; 578 info.num_nodes++; 579 LOGH("Added ch(%p) to node ,num nodes %d", 580 fs.ch_obj[j], info.num_nodes); 581 } 582 } 583 } 584 mm_frame_sync_remove(match_frame); 585 LOGI("match frame %d", match_frame); 586 if (info.num_nodes != fs.num_cam) { 587 LOGI("num node %d != num cam (%d) Debug this", 588 info.num_nodes, fs.num_cam); 589 uint8_t j = 0; 590 // free super buffers from various nodes 591 for (j = 0; j < info.num_nodes; j++) { 592 if (info.node[j]) { 593 mm_channel_node_qbuf(info.ch_obj[j], info.node[j]); 594 free(info.node[j]); 595 } 596 } 597 // we should not use it as matched dual camera frames 598 info.num_nodes = 0; 599 } 600 } 601 mm_frame_sync_unlock_queues(); 602 } else { 603 if (ch_obj->frame_req_cnt == 0) { 604 node = mm_channel_superbuf_dequeue(&ch_obj->bundle.superbuf_queue, ch_obj); 605 } else { 606 uint32_t req_frame = ch_obj->requested_frame_id[ch_obj->cur_req_idx]; 607 node = mm_channel_superbuf_dequeue_frame_internal( 608 &ch_obj->bundle.superbuf_queue, 609 req_frame); 610 } 611 if (node != NULL) { 612 if (ch_obj->isConfigCapture && 613 ((node->frame_idx < 614 ch_obj->capture_frame_id[ch_obj->cur_capture_idx])) 615 && (ch_obj->frame_req_cnt == 0)) { 616 uint8_t i; 617 LOGD("Not expected super buffer. frameID = %d expected = %d", 618 node->frame_idx, ch_obj->capture_frame_id[ch_obj->cur_capture_idx]); 619 for (i = 0; i < node->num_of_bufs; i++) { 620 mm_channel_qbuf(ch_obj, node->super_buf[i].buf); 621 } 622 free(node); 623 } else { 624 info.num_nodes = 1; 625 info.ch_obj[0] = ch_obj; 626 info.node[0] = node; 627 } 628 } 629 } 630 if (info.num_nodes > 0) { 631 if ((m_obj->frame_sync.is_active) 632 && (ch_obj->pending_cnt > 0)) { 633 trigger_cb = 1; 634 } 635 /* decrease pending_cnt */ 636 if (MM_CAMERA_SUPER_BUF_NOTIFY_BURST == notify_mode 637 && ch_obj->pending_cnt > 0) { 638 ch_obj->pending_cnt--; 639 if (ch_obj->pending_retro_cnt > 0) { 640 if (ch_obj->pending_retro_cnt == 1) { 641 ch_obj->bWaitForPrepSnapshotDone = 1; 642 } 643 ch_obj->pending_retro_cnt--; 644 } 645 646 if (ch_obj->frame_req_cnt != 0) { 647 ch_obj->cur_req_idx++; 648 } 649 if (((ch_obj->pending_cnt == 0) || 650 (ch_obj->stopZslSnapshot == 1)) && 651 (ch_obj->manualZSLSnapshot == FALSE) && 652 ch_obj->startZSlSnapshotCalled == TRUE) { 653 LOGI("TRIGGER Stop ZSL. All frame received"); 654 mm_camera_stop_zsl_snapshot(ch_obj->cam_obj); 655 ch_obj->startZSlSnapshotCalled = FALSE; 656 ch_obj->burstSnapNum = 0; 657 ch_obj->stopZslSnapshot = 0; 658 ch_obj->unLockAEC = 1; 659 ch_obj->needLEDFlash = FALSE; 660 ch_obj->bracketingState = MM_CHANNEL_BRACKETING_STATE_OFF; 661 ch_obj->isConfigCapture = FALSE; 662 ch_obj->cur_req_idx = 0; 663 ch_obj->frame_req_cnt = 0; 664 memset(ch_obj->requested_frame_id, 0, 665 sizeof(uint8_t) * MAX_CAPTURE_BATCH_NUM); 666 } 667 668 if (ch_obj->isConfigCapture) { 669 if (ch_obj->frameConfig.configs[ch_obj->cur_capture_idx].num_frames != 0) { 670 ch_obj->frameConfig.configs[ch_obj->cur_capture_idx].num_frames--; 671 } else { 672 LOGW("Invalid frame config batch index %d max batch = %d", 673 ch_obj->cur_capture_idx, ch_obj->frameConfig.num_batch); 674 } 675 676 if (ch_obj->frameConfig.configs[ch_obj->cur_capture_idx].num_frames == 0) { 677 //Received all frames for current batch 678 ch_obj->cur_capture_idx++; 679 ch_obj->bundle.superbuf_queue.expected_frame_id = 680 ch_obj->capture_frame_id[ch_obj->cur_capture_idx]; 681 ch_obj->bundle.superbuf_queue.good_frame_id = 682 ch_obj->capture_frame_id[ch_obj->cur_capture_idx]; 683 } else { 684 LOGH("Need %d frames more for batch %d", 685 ch_obj->frameConfig.configs[ch_obj->cur_capture_idx].num_frames, 686 ch_obj->cur_capture_idx); 687 } 688 } 689 } 690 /* dispatch superbuf */ 691 mm_channel_send_super_buf(&info); 692 693 if (trigger_cb) { 694 trigger_cb = 0; 695 mm_channel_send_frame_sync_req_buf(ch_obj); 696 } 697 } else { 698 /* no superbuf avail, break the loop */ 699 break; 700 } 701 } 702 } 703 704 /*=========================================================================== 705 * FUNCTION : mm_channel_send_super_buf 706 * 707 * DESCRIPTION: Send super buffers to HAL 708 * 709 * PARAMETERS : 710 * @info : Info of super buffers to be sent in callback 711 * 712 * RETURN : None 713 *==========================================================================*/ 714 void mm_channel_send_super_buf(mm_channel_node_info_t *info) 715 { 716 if (!info || !info->num_nodes){ 717 LOGE("X Error!! Info invalid"); 718 return; 719 } 720 mm_channel_queue_node_t *node = NULL; 721 722 LOGH("num nodes %d to send", info->num_nodes); 723 uint32_t idx = 0; 724 mm_channel_t *ch_obj = NULL; 725 for (idx = 0; idx < info->num_nodes; idx++) { 726 node = info->node[idx]; 727 ch_obj = info->ch_obj[idx]; 728 if ((ch_obj) && (NULL != ch_obj->bundle.super_buf_notify_cb) && node) { 729 mm_camera_cmdcb_t* cb_node = NULL; 730 LOGD("Send superbuf to HAL, pending_cnt=%d", 731 ch_obj->pending_cnt); 732 /* send cam_sem_post to wake up cb thread to dispatch super buffer */ 733 cb_node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 734 if (NULL != cb_node) { 735 memset(cb_node, 0, sizeof(mm_camera_cmdcb_t)); 736 cb_node->cmd_type = MM_CAMERA_CMD_TYPE_SUPER_BUF_DATA_CB; 737 cb_node->u.superbuf.num_bufs = node->num_of_bufs; 738 uint8_t i = 0; 739 for (i = 0; i < node->num_of_bufs; i++) { 740 cb_node->u.superbuf.bufs[i] = node->super_buf[i].buf; 741 } 742 cb_node->u.superbuf.camera_handle = ch_obj->cam_obj->my_hdl; 743 cb_node->u.superbuf.ch_id = ch_obj->my_hdl; 744 cb_node->u.superbuf.bReadyForPrepareSnapshot = 745 ch_obj->bWaitForPrepSnapshotDone; 746 if (ch_obj->unLockAEC == 1) { 747 cb_node->u.superbuf.bUnlockAEC = 1; 748 LOGH("Unlocking AEC"); 749 ch_obj->unLockAEC = 0; 750 } 751 /* enqueue to cb thread */ 752 cam_queue_enq(&(ch_obj->cb_thread.cmd_queue), cb_node); 753 /* wake up cb thread */ 754 cam_sem_post(&(ch_obj->cb_thread.cmd_sem)); 755 LOGH("Sent super buf for node[%d] ", idx); 756 757 } else { 758 LOGE("No memory for mm_camera_node_t"); 759 /* buf done with the unused super buf */ 760 uint8_t i = 0; 761 for (i = 0; i < node->num_of_bufs; i++) { 762 mm_channel_qbuf(ch_obj, node->super_buf[i].buf); 763 } 764 } 765 free(node); 766 } else if ((ch_obj != NULL) && (node != NULL)) { 767 /* buf done with the unused super buf */ 768 uint8_t i; 769 for (i = 0; i < node->num_of_bufs; i++) { 770 mm_channel_qbuf(ch_obj, node->super_buf[i].buf); 771 } 772 free(node); 773 } else { 774 LOGE("node is NULL, debug this"); 775 } 776 } 777 } 778 779 /*=========================================================================== 780 * FUNCTION : mm_channel_reg_stream_buf_cb 781 * 782 * DESCRIPTION: Register callback for stream buffer 783 * 784 * PARAMETERS : 785 * @my_obj : Channel object 786 * @stream_id : stream that will be linked 787 * @buf_cb : special callback needs to be registered for stream buffer 788 * 789 * RETURN : int32_t type of status 790 * 0 -- success 791 * -1 -- failure 792 *==========================================================================*/ 793 int32_t mm_channel_reg_stream_buf_cb (mm_channel_t* my_obj, 794 uint32_t stream_id, mm_stream_data_cb_t buf_cb) 795 { 796 int32_t rc = -1; 797 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, 798 stream_id); 799 800 if (NULL != s_obj) { 801 if (s_obj->ch_obj != my_obj) { 802 /* No op. on linked streams */ 803 return 0; 804 } 805 rc = mm_stream_reg_buf_cb(s_obj, buf_cb); 806 } 807 808 return rc; 809 810 } 811 812 /*=========================================================================== 813 * FUNCTION : mm_channel_fsm_fn 814 * 815 * DESCRIPTION: channel finite state machine entry function. Depends on channel 816 * state, incoming event will be handled differently. 817 * 818 * PARAMETERS : 819 * @my_obj : ptr to a channel object 820 * @evt : channel event to be processed 821 * @in_val : input event payload. Can be NULL if not needed. 822 * @out_val : output payload, Can be NULL if not needed. 823 * 824 * RETURN : int32_t type of status 825 * 0 -- success 826 * -1 -- failure 827 *==========================================================================*/ 828 int32_t mm_channel_fsm_fn(mm_channel_t *my_obj, 829 mm_channel_evt_type_t evt, 830 void * in_val, 831 void * out_val) 832 { 833 int32_t rc = -1; 834 835 LOGD("E state = %d", my_obj->state); 836 switch (my_obj->state) { 837 case MM_CHANNEL_STATE_NOTUSED: 838 rc = mm_channel_fsm_fn_notused(my_obj, evt, in_val, out_val); 839 break; 840 case MM_CHANNEL_STATE_STOPPED: 841 rc = mm_channel_fsm_fn_stopped(my_obj, evt, in_val, out_val); 842 break; 843 case MM_CHANNEL_STATE_ACTIVE: 844 rc = mm_channel_fsm_fn_active(my_obj, evt, in_val, out_val); 845 break; 846 case MM_CHANNEL_STATE_PAUSED: 847 rc = mm_channel_fsm_fn_paused(my_obj, evt, in_val, out_val); 848 break; 849 default: 850 LOGD("Not a valid state (%d)", my_obj->state); 851 break; 852 } 853 854 /* unlock ch_lock */ 855 pthread_mutex_unlock(&my_obj->ch_lock); 856 LOGD("X rc = %d", rc); 857 return rc; 858 } 859 860 /*=========================================================================== 861 * FUNCTION : mm_channel_fsm_fn_notused 862 * 863 * DESCRIPTION: channel finite state machine function to handle event 864 * in NOT_USED state. 865 * 866 * PARAMETERS : 867 * @my_obj : ptr to a channel object 868 * @evt : channel event to be processed 869 * @in_val : input event payload. Can be NULL if not needed. 870 * @out_val : output payload, Can be NULL if not needed. 871 * 872 * RETURN : int32_t type of status 873 * 0 -- success 874 * -1 -- failure 875 *==========================================================================*/ 876 int32_t mm_channel_fsm_fn_notused(mm_channel_t *my_obj, 877 mm_channel_evt_type_t evt, 878 void * in_val, 879 void * out_val) 880 { 881 int32_t rc = -1; 882 883 switch (evt) { 884 default: 885 LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)", 886 my_obj->state, evt, in_val, out_val); 887 break; 888 } 889 890 return rc; 891 } 892 893 /*=========================================================================== 894 * FUNCTION : mm_channel_fsm_fn_stopped 895 * 896 * DESCRIPTION: channel finite state machine function to handle event 897 * in STOPPED state. 898 * 899 * PARAMETERS : 900 * @my_obj : ptr to a channel object 901 * @evt : channel event to be processed 902 * @in_val : input event payload. Can be NULL if not needed. 903 * @out_val : output payload, Can be NULL if not needed. 904 * 905 * RETURN : int32_t type of status 906 * 0 -- success 907 * -1 -- failure 908 *==========================================================================*/ 909 int32_t mm_channel_fsm_fn_stopped(mm_channel_t *my_obj, 910 mm_channel_evt_type_t evt, 911 void * in_val, 912 void * out_val) 913 { 914 int32_t rc = 0; 915 LOGD("E evt = %d", evt); 916 switch (evt) { 917 case MM_CHANNEL_EVT_ADD_STREAM: 918 { 919 uint32_t s_hdl = 0; 920 s_hdl = mm_channel_add_stream(my_obj); 921 *((uint32_t*)out_val) = s_hdl; 922 rc = 0; 923 } 924 break; 925 case MM_CHANNEL_EVT_LINK_STREAM: 926 { 927 mm_camera_stream_link_t *stream_link = NULL; 928 uint32_t s_hdl = 0; 929 stream_link = (mm_camera_stream_link_t *) in_val; 930 s_hdl = mm_channel_link_stream(my_obj, stream_link); 931 *((uint32_t*)out_val) = s_hdl; 932 rc = 0; 933 } 934 break; 935 case MM_CHANNEL_EVT_REG_FRAME_SYNC: 936 { 937 mm_evt_paylod_reg_frame_sync *frame_sync = NULL; 938 uint32_t s_hdl = 0; 939 frame_sync = (mm_evt_paylod_reg_frame_sync *) in_val; 940 s_hdl = mm_channel_reg_frame_sync(my_obj, frame_sync); 941 *((uint32_t*)out_val) = s_hdl; 942 rc = 0; 943 } 944 break; 945 case MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC: 946 { 947 rc = mm_channel_trigger_frame_sync(my_obj, 948 (mm_evt_paylod_trigger_frame_sync *)in_val); 949 } 950 break; 951 case MM_CHANNEL_EVT_DEL_STREAM: 952 { 953 uint32_t s_id = *((uint32_t *)in_val); 954 rc = mm_channel_del_stream(my_obj, s_id); 955 } 956 break; 957 case MM_CHANNEL_EVT_START: 958 { 959 rc = mm_channel_start(my_obj); 960 /* first stream started in stopped state 961 * move to active state */ 962 if (0 == rc) { 963 my_obj->state = MM_CHANNEL_STATE_ACTIVE; 964 } 965 } 966 break; 967 case MM_CHANNEL_EVT_CONFIG_STREAM: 968 { 969 mm_evt_paylod_config_stream_t *payload = 970 (mm_evt_paylod_config_stream_t *)in_val; 971 rc = mm_channel_config_stream(my_obj, 972 payload->stream_id, 973 payload->config); 974 } 975 break; 976 case MM_CHANNEL_EVT_GET_BUNDLE_INFO: 977 { 978 cam_bundle_config_t *payload = 979 (cam_bundle_config_t *)in_val; 980 rc = mm_channel_get_bundle_info(my_obj, payload); 981 } 982 break; 983 case MM_CHANNEL_EVT_DELETE: 984 { 985 mm_channel_release(my_obj); 986 rc = 0; 987 } 988 break; 989 case MM_CHANNEL_EVT_SET_STREAM_PARM: 990 { 991 mm_evt_paylod_set_get_stream_parms_t *payload = 992 (mm_evt_paylod_set_get_stream_parms_t *)in_val; 993 rc = mm_channel_set_stream_parm(my_obj, payload); 994 } 995 break; 996 case MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT: 997 { 998 uint32_t stream_id = *((uint32_t *)in_val); 999 rc = mm_channel_get_queued_buf_count(my_obj, stream_id); 1000 } 1001 break; 1002 case MM_CHANNEL_EVT_GET_STREAM_PARM: 1003 { 1004 mm_evt_paylod_set_get_stream_parms_t *payload = 1005 (mm_evt_paylod_set_get_stream_parms_t *)in_val; 1006 rc = mm_channel_get_stream_parm(my_obj, payload); 1007 } 1008 break; 1009 case MM_CHANNEL_EVT_DO_ACTION: 1010 { 1011 mm_evt_paylod_do_stream_action_t *payload = 1012 (mm_evt_paylod_do_stream_action_t *)in_val; 1013 rc = mm_channel_do_stream_action(my_obj, payload); 1014 } 1015 break; 1016 case MM_CHANNEL_EVT_MAP_STREAM_BUF: 1017 { 1018 cam_buf_map_type *payload = 1019 (cam_buf_map_type *)in_val; 1020 rc = mm_channel_map_stream_buf(my_obj, payload); 1021 } 1022 break; 1023 case MM_CHANNEL_EVT_MAP_STREAM_BUFS: 1024 { 1025 cam_buf_map_type_list *payload = 1026 (cam_buf_map_type_list *)in_val; 1027 rc = mm_channel_map_stream_bufs(my_obj, payload); 1028 } 1029 break; 1030 case MM_CHANNEL_EVT_UNMAP_STREAM_BUF: 1031 { 1032 cam_buf_unmap_type *payload = 1033 (cam_buf_unmap_type *)in_val; 1034 rc = mm_channel_unmap_stream_buf(my_obj, payload); 1035 } 1036 break; 1037 case MM_CHANNEL_EVT_REG_STREAM_BUF_CB: 1038 { 1039 mm_evt_paylod_reg_stream_buf_cb *payload = 1040 (mm_evt_paylod_reg_stream_buf_cb *)in_val; 1041 rc = mm_channel_reg_stream_buf_cb (my_obj, 1042 payload->stream_id, payload->buf_cb); 1043 } 1044 break; 1045 default: 1046 LOGW("invalid state (%d) for evt (%d)", 1047 my_obj->state, evt); 1048 break; 1049 } 1050 LOGD("E rc = %d", rc); 1051 return rc; 1052 } 1053 1054 /*=========================================================================== 1055 * FUNCTION : mm_channel_fsm_fn_active 1056 * 1057 * DESCRIPTION: channel finite state machine function to handle event 1058 * in ACTIVE state. 1059 * 1060 * PARAMETERS : 1061 * @my_obj : ptr to a channel object 1062 * @evt : channel event to be processed 1063 * @in_val : input event payload. Can be NULL if not needed. 1064 * @out_val : output payload, Can be NULL if not needed. 1065 * 1066 * RETURN : int32_t type of status 1067 * 0 -- success 1068 * -1 -- failure 1069 *==========================================================================*/ 1070 int32_t mm_channel_fsm_fn_active(mm_channel_t *my_obj, 1071 mm_channel_evt_type_t evt, 1072 void * in_val, 1073 void * out_val) 1074 { 1075 int32_t rc = 0; 1076 1077 LOGD("E evt = %d", evt); 1078 switch (evt) { 1079 case MM_CHANNEL_EVT_STOP: 1080 { 1081 bool stop_immediately = in_val ? *(bool*)in_val : FALSE; 1082 rc = mm_channel_stop(my_obj, stop_immediately); 1083 my_obj->state = MM_CHANNEL_STATE_STOPPED; 1084 } 1085 break; 1086 case MM_CHANNEL_EVT_REQUEST_SUPER_BUF: 1087 { 1088 mm_camera_req_buf_t *payload = 1089 (mm_camera_req_buf_t *)in_val; 1090 rc = mm_channel_request_super_buf(my_obj, payload); 1091 } 1092 break; 1093 case MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF: 1094 { 1095 rc = mm_channel_cancel_super_buf_request(my_obj); 1096 } 1097 break; 1098 case MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE: 1099 { 1100 uint32_t frame_idx = *((uint32_t *)in_val); 1101 rc = mm_channel_flush_super_buf_queue(my_obj, frame_idx, CAM_STREAM_TYPE_DEFAULT); 1102 } 1103 break; 1104 case MM_CHANNEL_EVT_START_ZSL_SNAPSHOT: 1105 { 1106 rc = mm_channel_start_zsl_snapshot(my_obj); 1107 } 1108 break; 1109 case MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT: 1110 { 1111 rc = mm_channel_stop_zsl_snapshot(my_obj); 1112 } 1113 break; 1114 case MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE: 1115 { 1116 mm_camera_super_buf_notify_mode_t notify_mode = 1117 *((mm_camera_super_buf_notify_mode_t *)in_val); 1118 rc = mm_channel_config_notify_mode(my_obj, notify_mode); 1119 } 1120 break; 1121 case MM_CHANNEL_EVT_SET_STREAM_PARM: 1122 { 1123 mm_evt_paylod_set_get_stream_parms_t *payload = 1124 (mm_evt_paylod_set_get_stream_parms_t *)in_val; 1125 rc = mm_channel_set_stream_parm(my_obj, payload); 1126 } 1127 break; 1128 case MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT: 1129 { 1130 uint32_t stream_id = *((uint32_t *)in_val); 1131 rc = mm_channel_get_queued_buf_count(my_obj, stream_id); 1132 } 1133 break; 1134 case MM_CHANNEL_EVT_GET_STREAM_PARM: 1135 { 1136 mm_evt_paylod_set_get_stream_parms_t *payload = 1137 (mm_evt_paylod_set_get_stream_parms_t *)in_val; 1138 rc = mm_channel_get_stream_parm(my_obj, payload); 1139 } 1140 break; 1141 case MM_CHANNEL_EVT_DO_ACTION: 1142 { 1143 mm_evt_paylod_do_stream_action_t *payload = 1144 (mm_evt_paylod_do_stream_action_t *)in_val; 1145 rc = mm_channel_do_stream_action(my_obj, payload); 1146 } 1147 break; 1148 case MM_CHANNEL_EVT_MAP_STREAM_BUF: 1149 { 1150 cam_buf_map_type *payload = 1151 (cam_buf_map_type *)in_val; 1152 if (payload != NULL) { 1153 uint8_t type = payload->type; 1154 if ((type == CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF) || 1155 (type == CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF)) { 1156 rc = mm_channel_map_stream_buf(my_obj, payload); 1157 } 1158 } else { 1159 LOGE("cannot map regualr stream buf in active state"); 1160 } 1161 } 1162 break; 1163 case MM_CHANNEL_EVT_MAP_STREAM_BUFS: 1164 { 1165 cam_buf_map_type_list *payload = 1166 (cam_buf_map_type_list *)in_val; 1167 if ((payload != NULL) && (payload->length > 0)) { 1168 uint8_t type = payload->buf_maps[0].type; 1169 if ((type == CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF) || 1170 (type == CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF)) { 1171 rc = mm_channel_map_stream_bufs(my_obj, payload); 1172 } 1173 } else { 1174 LOGE("cannot map regualr stream buf in active state"); 1175 } 1176 } 1177 break; 1178 case MM_CHANNEL_EVT_UNMAP_STREAM_BUF: 1179 { 1180 cam_buf_unmap_type *payload = 1181 (cam_buf_unmap_type *)in_val; 1182 if (payload != NULL) { 1183 uint8_t type = payload->type; 1184 if ((type == CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF) || 1185 (type == CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF)) { 1186 rc = mm_channel_unmap_stream_buf(my_obj, payload); 1187 } 1188 } else { 1189 LOGE("cannot unmap regualr stream buf in active state"); 1190 } 1191 } 1192 break; 1193 case MM_CHANNEL_EVT_AF_BRACKETING: 1194 { 1195 LOGH("MM_CHANNEL_EVT_AF_BRACKETING"); 1196 uint32_t start_flag = *((uint32_t *)in_val); 1197 mm_camera_generic_cmd_t gen_cmd; 1198 gen_cmd.type = MM_CAMERA_GENERIC_CMD_TYPE_AF_BRACKETING; 1199 gen_cmd.payload[0] = start_flag; 1200 rc = mm_channel_proc_general_cmd(my_obj, &gen_cmd); 1201 } 1202 break; 1203 case MM_CHANNEL_EVT_AE_BRACKETING: 1204 { 1205 LOGH("MM_CHANNEL_EVT_AE_BRACKETING"); 1206 uint32_t start_flag = *((uint32_t *)in_val); 1207 mm_camera_generic_cmd_t gen_cmd; 1208 gen_cmd.type = MM_CAMERA_GENERIC_CMD_TYPE_AE_BRACKETING; 1209 gen_cmd.payload[0] = start_flag; 1210 rc = mm_channel_proc_general_cmd(my_obj, &gen_cmd); 1211 } 1212 break; 1213 case MM_CHANNEL_EVT_FLASH_BRACKETING: 1214 { 1215 LOGH("MM_CHANNEL_EVT_FLASH_BRACKETING"); 1216 uint32_t start_flag = *((uint32_t *)in_val); 1217 mm_camera_generic_cmd_t gen_cmd; 1218 gen_cmd.type = MM_CAMERA_GENERIC_CMD_TYPE_FLASH_BRACKETING; 1219 gen_cmd.payload[0] = start_flag; 1220 rc = mm_channel_proc_general_cmd(my_obj, &gen_cmd); 1221 } 1222 break; 1223 case MM_CHANNEL_EVT_ZOOM_1X: 1224 { 1225 LOGH("MM_CHANNEL_EVT_ZOOM_1X"); 1226 uint32_t start_flag = *((uint32_t *)in_val); 1227 mm_camera_generic_cmd_t gen_cmd; 1228 gen_cmd.type = MM_CAMERA_GENERIC_CMD_TYPE_ZOOM_1X; 1229 gen_cmd.payload[0] = start_flag; 1230 rc = mm_channel_proc_general_cmd(my_obj, &gen_cmd); 1231 } 1232 break; 1233 case MM_CAMERA_EVT_CAPTURE_SETTING: 1234 { 1235 mm_camera_generic_cmd_t gen_cmd; 1236 cam_capture_frame_config_t *input; 1237 gen_cmd.type = MM_CAMERA_GENERIC_CMD_TYPE_CAPTURE_SETTING; 1238 LOGH("MM_CAMERA_EVT_CAPTURE_SETTING"); 1239 if (in_val == NULL) { 1240 gen_cmd.payload[0] = 0; 1241 memset(&gen_cmd.frame_config, 0, sizeof(cam_capture_frame_config_t)); 1242 } else { 1243 gen_cmd.payload[0] = 1; 1244 input = (cam_capture_frame_config_t *)in_val; 1245 gen_cmd.frame_config = *input; 1246 } 1247 rc = mm_channel_proc_general_cmd(my_obj, &gen_cmd); 1248 } 1249 break; 1250 case MM_CHANNEL_EVT_REG_STREAM_BUF_CB: 1251 { 1252 mm_evt_paylod_reg_stream_buf_cb *payload = 1253 (mm_evt_paylod_reg_stream_buf_cb *)in_val; 1254 rc = mm_channel_reg_stream_buf_cb (my_obj, 1255 payload->stream_id, payload->buf_cb); 1256 } 1257 break; 1258 case MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC: 1259 { 1260 rc = mm_channel_trigger_frame_sync(my_obj, 1261 (mm_evt_paylod_trigger_frame_sync *)in_val); 1262 } 1263 break; 1264 1265 case MM_CHANNEL_EVT_START_SENSOR_STREAMING: 1266 { 1267 rc = mm_channel_start_sensor_streaming(my_obj); 1268 } 1269 break; 1270 1271 default: 1272 LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)", 1273 my_obj->state, evt, in_val, out_val); 1274 break; 1275 } 1276 LOGD("X rc = %d", rc); 1277 return rc; 1278 } 1279 1280 /*=========================================================================== 1281 * FUNCTION : mm_channel_fsm_fn_paused 1282 * 1283 * DESCRIPTION: channel finite state machine function to handle event 1284 * in PAUSED state. 1285 * 1286 * PARAMETERS : 1287 * @my_obj : ptr to a channel object 1288 * @evt : channel event to be processed 1289 * @in_val : input event payload. Can be NULL if not needed. 1290 * @out_val : output payload, Can be NULL if not needed. 1291 * 1292 * RETURN : int32_t type of status 1293 * 0 -- success 1294 * -1 -- failure 1295 *==========================================================================*/ 1296 int32_t mm_channel_fsm_fn_paused(mm_channel_t *my_obj, 1297 mm_channel_evt_type_t evt, 1298 void * in_val, 1299 void * out_val) 1300 { 1301 int32_t rc = 0; 1302 1303 /* currently we are not supporting pause/resume channel */ 1304 LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)", 1305 my_obj->state, evt, in_val, out_val); 1306 1307 return rc; 1308 } 1309 1310 /*=========================================================================== 1311 * FUNCTION : mm_channel_init 1312 * 1313 * DESCRIPTION: initialize a channel 1314 * 1315 * PARAMETERS : 1316 * @my_obj : channel object be to initialized 1317 * @attr : bundle attribute of the channel if needed 1318 * @channel_cb : callback function for bundle data notify 1319 * @userdata : user data ptr 1320 * 1321 * RETURN : int32_t type of status 1322 * 0 -- success 1323 * -1 -- failure 1324 * NOTE : if no bundle data notify is needed, meaning each stream in the 1325 * channel will have its own stream data notify callback, then 1326 * attr, channel_cb, and userdata can be NULL. In this case, 1327 * no matching logic will be performed in channel for the bundling. 1328 *==========================================================================*/ 1329 int32_t mm_channel_init(mm_channel_t *my_obj, 1330 mm_camera_channel_attr_t *attr, 1331 mm_camera_buf_notify_t channel_cb, 1332 void *userdata) 1333 { 1334 int32_t rc = 0; 1335 1336 my_obj->bundle.super_buf_notify_cb = channel_cb; 1337 my_obj->bundle.user_data = userdata; 1338 if (NULL != attr) { 1339 my_obj->bundle.superbuf_queue.attr = *attr; 1340 } 1341 1342 my_obj->num_s_cnt = 0; 1343 memset(&my_obj->frame_sync, 0, sizeof(my_obj->frame_sync)); 1344 pthread_mutex_init(&my_obj->frame_sync.sync_lock, NULL); 1345 mm_muxer_frame_sync_queue_init(&my_obj->frame_sync.superbuf_queue); 1346 my_obj->bundle.is_cb_active = 1; 1347 1348 LOGD("Launch data poll thread in channel open"); 1349 snprintf(my_obj->poll_thread[0].threadName, THREAD_NAME_SIZE, "CAM_dataPoll"); 1350 mm_camera_poll_thread_launch(&my_obj->poll_thread[0], 1351 MM_CAMERA_POLL_TYPE_DATA); 1352 1353 /* change state to stopped state */ 1354 my_obj->state = MM_CHANNEL_STATE_STOPPED; 1355 return rc; 1356 } 1357 1358 /*=========================================================================== 1359 * FUNCTION : mm_channel_release 1360 * 1361 * DESCRIPTION: release a channel resource. Channel state will move to UNUSED 1362 * state after this call. 1363 * 1364 * PARAMETERS : 1365 * @my_obj : channel object 1366 * 1367 * RETURN : none 1368 *==========================================================================*/ 1369 void mm_channel_release(mm_channel_t *my_obj) 1370 { 1371 /* stop data poll thread */ 1372 mm_camera_poll_thread_release(&my_obj->poll_thread[0]); 1373 1374 mm_muxer_frame_sync_queue_deinit(&my_obj->frame_sync.superbuf_queue); 1375 pthread_mutex_destroy(&my_obj->frame_sync.sync_lock); 1376 1377 /* memset bundle info */ 1378 memset(&my_obj->bundle, 0, sizeof(mm_channel_bundle_t)); 1379 1380 /* change state to notused state */ 1381 my_obj->state = MM_CHANNEL_STATE_NOTUSED; 1382 } 1383 1384 /*=========================================================================== 1385 * FUNCTION : mm_channel_link_stream 1386 * 1387 * DESCRIPTION: link a stream from external channel into this channel 1388 * 1389 * PARAMETERS : 1390 * @my_obj : channel object 1391 * @stream_link : channel and stream to be linked 1392 * 1393 * RETURN : uint32_t type of stream handle 1394 * 0 -- invalid stream handle, meaning the op failed 1395 * >0 -- successfully added a stream with a valid handle 1396 *==========================================================================*/ 1397 uint32_t mm_channel_link_stream(mm_channel_t *my_obj, 1398 mm_camera_stream_link_t *stream_link) 1399 { 1400 uint8_t idx = 0; 1401 uint32_t s_hdl = 0; 1402 mm_stream_t *stream_obj = NULL; 1403 mm_stream_t *stream = NULL; 1404 1405 if (NULL == stream_link) { 1406 LOGE("Invalid stream link"); 1407 return 0; 1408 } 1409 1410 stream = mm_channel_util_get_stream_by_handler(stream_link->ch, 1411 stream_link->stream_id); 1412 if (NULL == stream) { 1413 return 0; 1414 } 1415 1416 /* check available stream */ 1417 for (idx = 0; idx < MAX_STREAM_NUM_IN_BUNDLE; idx++) { 1418 if (MM_STREAM_STATE_NOTUSED == my_obj->streams[idx].state) { 1419 stream_obj = &my_obj->streams[idx]; 1420 break; 1421 } 1422 } 1423 if (NULL == stream_obj) { 1424 LOGE("streams reach max, no more stream allowed to add"); 1425 return s_hdl; 1426 } 1427 1428 /* initialize stream object */ 1429 *stream_obj = *stream; 1430 stream_obj->linked_stream = stream; 1431 s_hdl = stream->my_hdl; 1432 1433 LOGD("stream handle = %d", s_hdl); 1434 return s_hdl; 1435 } 1436 1437 /*=========================================================================== 1438 * FUNCTION : mm_channel_reg_frame_sync 1439 * 1440 * DESCRIPTION: register/configure frame sync for stream 1441 * 1442 * PARAMETERS : 1443 * @my_obj : camera object 1444 * @ch_id : channel handle 1445 * @stream_id : stream that will be linked 1446 * @sync_attr : attibutes for sync queue 1447 * 1448 * RETURN : int32_t type of status 1449 * 0 -- success 1450 * 1 -- failure 1451 *==========================================================================*/ 1452 uint32_t mm_channel_reg_frame_sync(mm_channel_t *my_obj, 1453 mm_evt_paylod_reg_frame_sync *sync) 1454 { 1455 uint32_t rc = 0; 1456 mm_stream_t * stream_obj = NULL; 1457 1458 if (NULL == sync || sync->a_ch_obj == NULL) { 1459 LOGE("Invalid arguments"); 1460 return -1; 1461 } 1462 1463 if (sync->stream_id != 0) { 1464 //Frame sync reg for stream 1465 stream_obj = mm_channel_util_get_stream_by_handler( 1466 my_obj, sync->stream_id); 1467 if (stream_obj == NULL) { 1468 LOGE("Invalid Stream ID %d", sync->stream_id); 1469 return -1; 1470 } 1471 sync->a_str_obj = mm_channel_util_get_stream_by_handler( 1472 sync->a_ch_obj, sync->sync_attr->a_stream_id); 1473 return mm_stream_fsm_fn(stream_obj, 1474 MM_STREAM_EVT_REG_FRAME_SYNC, 1475 sync, 1476 NULL); 1477 } 1478 1479 //Frame sync reg for channel 1480 mm_frame_sync_t *frame_sync = &my_obj->frame_sync; 1481 pthread_mutex_lock(&frame_sync->sync_lock); 1482 mm_frame_sync_queue_t *queue = NULL; 1483 if (sync->sync_attr->buf_cb == NULL) { 1484 frame_sync->super_buf_notify_cb = 1485 my_obj->bundle.super_buf_notify_cb; 1486 } else { 1487 frame_sync->super_buf_notify_cb = sync->sync_attr->buf_cb; 1488 } 1489 if (sync->sync_attr->userdata == NULL) { 1490 frame_sync->user_data = 1491 my_obj->bundle.user_data; 1492 } else { 1493 frame_sync->user_data = sync->sync_attr->userdata; 1494 } 1495 frame_sync->is_active = sync->sync_attr->is_active; 1496 queue = &frame_sync->superbuf_queue; 1497 queue->attr = sync->sync_attr->attr; 1498 queue->num_objs = 0; 1499 memset(&queue->bundled_objs, 0, sizeof(queue->bundled_objs)); 1500 queue->bundled_objs[queue->num_objs] = my_obj->my_hdl; 1501 queue->num_objs++; 1502 queue->bundled_objs[queue->num_objs] = sync->a_ch_obj->my_hdl; 1503 queue->num_objs++; 1504 1505 my_obj->aux_ch_obj[my_obj->num_s_cnt++] = sync->a_ch_obj; 1506 sync->a_ch_obj->master_ch_obj = my_obj; 1507 pthread_mutex_unlock(&frame_sync->sync_lock); 1508 LOGD("stream handle = %d", rc); 1509 return rc; 1510 } 1511 1512 /*=========================================================================== 1513 * FUNCTION : mm_channel_trigger_frame_sync 1514 * 1515 * DESCRIPTION: start/stop frame sync under this channel 1516 * 1517 * PARAMETERS : 1518 * @my_obj : camera object 1519 * @ch_id : channel handle 1520 * @stream_id : stream that will be linked 1521 * 1522 * RETURN : int32_t type of status 1523 * 0 -- success 1524 * 1 -- failure 1525 *==========================================================================*/ 1526 int32_t mm_channel_trigger_frame_sync(mm_channel_t *my_obj, 1527 mm_evt_paylod_trigger_frame_sync *payload) 1528 { 1529 int32_t rc = 0; 1530 mm_stream_t * stream_obj = NULL; 1531 mm_channel_t *m_obj = my_obj; 1532 1533 if (m_obj->master_ch_obj != NULL) { 1534 m_obj = m_obj->master_ch_obj; 1535 } 1536 1537 if (payload->stream_id != 0) { 1538 stream_obj = mm_channel_util_get_stream_by_handler( 1539 my_obj, payload->stream_id); 1540 if (stream_obj == NULL) { 1541 LOGE("Invalid Stream ID %d", payload->stream_id); 1542 return -1; 1543 } 1544 return mm_stream_fsm_fn(stream_obj, 1545 MM_STREAM_EVT_TRIGGER_FRAME_SYNC, 1546 &payload->type, 1547 NULL); 1548 } 1549 1550 if (payload->type == MM_CAMERA_CB_REQ_TYPE_FRAME_SYNC) { 1551 mm_frame_sync_t *frame_sync = &m_obj->frame_sync; 1552 pthread_mutex_lock(&frame_sync->sync_lock); 1553 frame_sync->is_active = 1; 1554 pthread_mutex_unlock(&frame_sync->sync_lock); 1555 } else { 1556 LOGE("Not supported for Channel"); 1557 rc = -1; 1558 } 1559 return rc; 1560 } 1561 1562 /*=========================================================================== 1563 * FUNCTION : mm_channel_add_stream 1564 * 1565 * DESCRIPTION: add a stream into the channel 1566 * 1567 * PARAMETERS : 1568 * @my_obj : channel object 1569 * 1570 * RETURN : uint32_t type of stream handle 1571 * 0 -- invalid stream handle, meaning the op failed 1572 * >0 -- successfully added a stream with a valid handle 1573 *==========================================================================*/ 1574 uint32_t mm_channel_add_stream(mm_channel_t *my_obj) 1575 { 1576 int32_t rc = 0; 1577 uint8_t idx = 0; 1578 uint32_t s_hdl = 0; 1579 mm_stream_t *stream_obj = NULL; 1580 1581 LOGD("E"); 1582 /* check available stream */ 1583 for (idx = 0; idx < MAX_STREAM_NUM_IN_BUNDLE; idx++) { 1584 if (MM_STREAM_STATE_NOTUSED == my_obj->streams[idx].state) { 1585 stream_obj = &my_obj->streams[idx]; 1586 break; 1587 } 1588 } 1589 if (NULL == stream_obj) { 1590 LOGE("streams reach max, no more stream allowed to add"); 1591 return s_hdl; 1592 } 1593 1594 /* initialize stream object */ 1595 memset(stream_obj, 0, sizeof(mm_stream_t)); 1596 stream_obj->fd = -1; 1597 stream_obj->my_hdl = mm_camera_util_generate_handler_by_num ( 1598 my_obj->cam_obj->my_num, idx); 1599 stream_obj->ch_obj = my_obj; 1600 stream_obj->state = MM_STREAM_STATE_INITED; 1601 1602 /* acquire stream */ 1603 rc = mm_stream_fsm_fn(stream_obj, MM_STREAM_EVT_ACQUIRE, NULL, NULL); 1604 if (0 == rc) { 1605 s_hdl = stream_obj->my_hdl; 1606 } else { 1607 /* error during acquire, de-init */ 1608 pthread_cond_destroy(&stream_obj->buf_cond); 1609 pthread_mutex_destroy(&stream_obj->buf_lock); 1610 pthread_mutex_destroy(&stream_obj->cb_lock); 1611 pthread_mutex_destroy(&stream_obj->cmd_lock); 1612 memset(stream_obj, 0, sizeof(mm_stream_t)); 1613 } 1614 LOGD("stream handle = %d", s_hdl); 1615 return s_hdl; 1616 } 1617 1618 /*=========================================================================== 1619 * FUNCTION : mm_channel_del_stream 1620 * 1621 * DESCRIPTION: delete a stream from the channel bu its handle 1622 * 1623 * PARAMETERS : 1624 * @my_obj : channel object 1625 * @stream_id : stream handle 1626 * 1627 * RETURN : int32_t type of status 1628 * 0 -- success 1629 * -1 -- failure 1630 * NOTE : assume steam is stooped before it can be deleted 1631 *==========================================================================*/ 1632 int32_t mm_channel_del_stream(mm_channel_t *my_obj, 1633 uint32_t stream_id) 1634 { 1635 int rc = -1; 1636 mm_stream_t * stream_obj = NULL; 1637 stream_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id); 1638 1639 if (NULL == stream_obj) { 1640 LOGE("Invalid Stream Object for stream_id = %d", stream_id); 1641 return rc; 1642 } 1643 1644 if (stream_obj->ch_obj != my_obj) { 1645 /* Only unlink stream */ 1646 pthread_mutex_lock(&stream_obj->linked_stream->buf_lock); 1647 stream_obj->linked_stream->is_linked = 0; 1648 stream_obj->linked_stream->linked_obj = NULL; 1649 pthread_mutex_unlock(&stream_obj->linked_stream->buf_lock); 1650 memset(stream_obj, 0, sizeof(mm_stream_t)); 1651 1652 return 0; 1653 } 1654 1655 rc = mm_stream_fsm_fn(stream_obj, 1656 MM_STREAM_EVT_RELEASE, 1657 NULL, 1658 NULL); 1659 1660 LOGD("stream handle = %d rc = %d", stream_id, rc); 1661 return rc; 1662 } 1663 1664 /*=========================================================================== 1665 * FUNCTION : mm_channel_config_stream 1666 * 1667 * DESCRIPTION: configure a stream 1668 * 1669 * PARAMETERS : 1670 * @my_obj : channel object 1671 * @stream_id : stream handle 1672 * @config : stream configuration 1673 * 1674 * RETURN : int32_t type of status 1675 * 0 -- success 1676 * -1 -- failure 1677 *==========================================================================*/ 1678 int32_t mm_channel_config_stream(mm_channel_t *my_obj, 1679 uint32_t stream_id, 1680 mm_camera_stream_config_t *config) 1681 { 1682 int rc = -1; 1683 mm_stream_t * stream_obj = NULL; 1684 LOGD("E stream ID = %d", stream_id); 1685 stream_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id); 1686 1687 if (NULL == stream_obj) { 1688 LOGE("Invalid Stream Object for stream_id = %d", stream_id); 1689 return rc; 1690 } 1691 1692 if (stream_obj->ch_obj != my_obj) { 1693 /* No op. on linked streams */ 1694 return 0; 1695 } 1696 1697 /* set stream fmt */ 1698 rc = mm_stream_fsm_fn(stream_obj, 1699 MM_STREAM_EVT_SET_FMT, 1700 (void *)config, 1701 NULL); 1702 LOGD("X rc = %d",rc); 1703 return rc; 1704 } 1705 1706 /*=========================================================================== 1707 * FUNCTION : mm_channel_get_bundle_info 1708 * 1709 * DESCRIPTION: query bundle info of the channel, which should include all 1710 * streams within this channel 1711 * 1712 * PARAMETERS : 1713 * @my_obj : channel object 1714 * @bundle_info : bundle info to be filled in 1715 * 1716 * RETURN : int32_t type of status 1717 * 0 -- success 1718 * -1 -- failure 1719 *==========================================================================*/ 1720 int32_t mm_channel_get_bundle_info(mm_channel_t *my_obj, 1721 cam_bundle_config_t *bundle_info) 1722 { 1723 int i; 1724 mm_stream_t *s_obj = NULL; 1725 cam_stream_type_t stream_type = CAM_STREAM_TYPE_DEFAULT; 1726 int32_t rc = 0; 1727 1728 memset(bundle_info, 0, sizeof(cam_bundle_config_t)); 1729 bundle_info->bundle_id = my_obj->my_hdl; 1730 bundle_info->num_of_streams = 0; 1731 for (i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) { 1732 if (my_obj->streams[i].my_hdl > 0) { 1733 s_obj = mm_channel_util_get_stream_by_handler(my_obj, 1734 my_obj->streams[i].my_hdl); 1735 if (NULL != s_obj) { 1736 stream_type = s_obj->stream_info->stream_type; 1737 if ((CAM_STREAM_TYPE_METADATA != stream_type) && 1738 (s_obj->ch_obj == my_obj)) { 1739 bundle_info->stream_ids[bundle_info->num_of_streams++] = 1740 s_obj->server_stream_id; 1741 } 1742 } else { 1743 LOGE("cannot find stream obj (%d) by handler (%d)", 1744 i, my_obj->streams[i].my_hdl); 1745 rc = -1; 1746 break; 1747 } 1748 } 1749 } 1750 if (rc != 0) { 1751 /* error, reset to 0 */ 1752 memset(bundle_info, 0, sizeof(cam_bundle_config_t)); 1753 } 1754 return rc; 1755 } 1756 1757 /*=========================================================================== 1758 * FUNCTION : mm_channel_start 1759 * 1760 * DESCRIPTION: start a channel, which will start all streams in the channel 1761 * 1762 * PARAMETERS : 1763 * @my_obj : channel object 1764 * 1765 * RETURN : int32_t type of status 1766 * 0 -- success 1767 * -1 -- failure 1768 *==========================================================================*/ 1769 int32_t mm_channel_start(mm_channel_t *my_obj) 1770 { 1771 int32_t rc = 0; 1772 int i = 0, j = 0; 1773 mm_stream_t *s_objs[MAX_STREAM_NUM_IN_BUNDLE] = {NULL}; 1774 uint8_t num_streams_to_start = 0; 1775 uint8_t num_streams_in_bundle_queue = 0; 1776 mm_stream_t *s_obj = NULL; 1777 int meta_stream_idx = 0; 1778 cam_stream_type_t stream_type = CAM_STREAM_TYPE_DEFAULT; 1779 1780 for (i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) { 1781 if (my_obj->streams[i].my_hdl > 0) { 1782 s_obj = mm_channel_util_get_stream_by_handler(my_obj, 1783 my_obj->streams[i].my_hdl); 1784 if (NULL != s_obj) { 1785 stream_type = s_obj->stream_info->stream_type; 1786 /* remember meta data stream index */ 1787 if ((stream_type == CAM_STREAM_TYPE_METADATA) && 1788 (s_obj->ch_obj == my_obj)) { 1789 meta_stream_idx = num_streams_to_start; 1790 } 1791 s_objs[num_streams_to_start++] = s_obj; 1792 1793 if (!s_obj->stream_info->noFrameExpected) { 1794 num_streams_in_bundle_queue++; 1795 } 1796 } 1797 } 1798 } 1799 1800 if (meta_stream_idx > 0 ) { 1801 /* always start meta data stream first, so switch the stream object with the first one */ 1802 s_obj = s_objs[0]; 1803 s_objs[0] = s_objs[meta_stream_idx]; 1804 s_objs[meta_stream_idx] = s_obj; 1805 } 1806 1807 if (NULL != my_obj->bundle.super_buf_notify_cb) { 1808 /* need to send up cb, therefore launch thread */ 1809 /* init superbuf queue */ 1810 mm_channel_superbuf_queue_init(&my_obj->bundle.superbuf_queue); 1811 my_obj->bundle.superbuf_queue.num_streams = num_streams_in_bundle_queue; 1812 my_obj->bundle.superbuf_queue.expected_frame_id = 1813 my_obj->bundle.superbuf_queue.attr.user_expected_frame_id; 1814 my_obj->bundle.superbuf_queue.expected_frame_id_without_led = 0; 1815 my_obj->bundle.superbuf_queue.led_off_start_frame_id = 0; 1816 my_obj->bundle.superbuf_queue.led_on_start_frame_id = 0; 1817 my_obj->bundle.superbuf_queue.led_on_num_frames = 0; 1818 my_obj->bundle.superbuf_queue.good_frame_id = 0; 1819 1820 for (i = 0; i < num_streams_to_start; i++) { 1821 /* Only bundle streams that belong to the channel */ 1822 if(!(s_objs[i]->stream_info->noFrameExpected)) { 1823 if (s_objs[i]->ch_obj == my_obj) { 1824 /* set bundled flag to streams */ 1825 s_objs[i]->is_bundled = 1; 1826 } 1827 my_obj->bundle.superbuf_queue.bundled_streams[j++] = s_objs[i]->my_hdl; 1828 } 1829 } 1830 1831 /* launch cb thread for dispatching super buf through cb */ 1832 snprintf(my_obj->cb_thread.threadName, THREAD_NAME_SIZE, "CAM_SuperBuf"); 1833 mm_camera_cmd_thread_launch(&my_obj->cb_thread, 1834 mm_channel_dispatch_super_buf, 1835 (void*)my_obj); 1836 1837 /* launch cmd thread for super buf dataCB */ 1838 snprintf(my_obj->cmd_thread.threadName, THREAD_NAME_SIZE, "CAM_SuperBufCB"); 1839 mm_camera_cmd_thread_launch(&my_obj->cmd_thread, 1840 mm_channel_process_stream_buf, 1841 (void*)my_obj); 1842 1843 /* set flag to TRUE */ 1844 my_obj->bundle.is_active = TRUE; 1845 } 1846 1847 /* link any streams first before starting the rest of the streams */ 1848 for (i = 0; i < num_streams_to_start; i++) { 1849 if (s_objs[i]->ch_obj != my_obj) { 1850 pthread_mutex_lock(&s_objs[i]->linked_stream->buf_lock); 1851 s_objs[i]->linked_stream->linked_obj = my_obj; 1852 s_objs[i]->linked_stream->is_linked = 1; 1853 pthread_mutex_unlock(&s_objs[i]->linked_stream->buf_lock); 1854 continue; 1855 } 1856 } 1857 1858 for (i = 0; i < num_streams_to_start; i++) { 1859 if (s_objs[i]->ch_obj != my_obj) { 1860 continue; 1861 } 1862 /* all streams within a channel should be started at the same time */ 1863 if (s_objs[i]->state == MM_STREAM_STATE_ACTIVE) { 1864 LOGE("stream already started idx(%d)", i); 1865 rc = -1; 1866 break; 1867 } 1868 1869 /* allocate buf */ 1870 rc = mm_stream_fsm_fn(s_objs[i], 1871 MM_STREAM_EVT_GET_BUF, 1872 NULL, 1873 NULL); 1874 if (0 != rc) { 1875 LOGE("get buf failed at idx(%d)", i); 1876 break; 1877 } 1878 1879 /* reg buf */ 1880 rc = mm_stream_fsm_fn(s_objs[i], 1881 MM_STREAM_EVT_REG_BUF, 1882 NULL, 1883 NULL); 1884 if (0 != rc) { 1885 LOGE("reg buf failed at idx(%d)", i); 1886 break; 1887 } 1888 1889 /* start stream */ 1890 rc = mm_stream_fsm_fn(s_objs[i], 1891 MM_STREAM_EVT_START, 1892 NULL, 1893 NULL); 1894 if (0 != rc) { 1895 LOGE("start stream failed at idx(%d)", i); 1896 break; 1897 } 1898 } 1899 1900 /* error handling */ 1901 if (0 != rc) { 1902 /* unlink the streams first */ 1903 for (j = 0; j < num_streams_to_start; j++) { 1904 if (s_objs[j]->ch_obj != my_obj) { 1905 pthread_mutex_lock(&s_objs[j]->linked_stream->buf_lock); 1906 s_objs[j]->linked_stream->is_linked = 0; 1907 s_objs[j]->linked_stream->linked_obj = NULL; 1908 pthread_mutex_unlock(&s_objs[j]->linked_stream->buf_lock); 1909 1910 if (TRUE == my_obj->bundle.is_active) { 1911 mm_channel_flush_super_buf_queue(my_obj, 0, 1912 s_objs[i]->stream_info->stream_type); 1913 } 1914 memset(s_objs[j], 0, sizeof(mm_stream_t)); 1915 continue; 1916 } 1917 } 1918 1919 for (j = 0; j <= i; j++) { 1920 if ((NULL == s_objs[j]) || (s_objs[j]->ch_obj != my_obj)) { 1921 continue; 1922 } 1923 /* stop streams*/ 1924 mm_stream_fsm_fn(s_objs[j], 1925 MM_STREAM_EVT_STOP, 1926 NULL, 1927 NULL); 1928 1929 /* unreg buf */ 1930 mm_stream_fsm_fn(s_objs[j], 1931 MM_STREAM_EVT_UNREG_BUF, 1932 NULL, 1933 NULL); 1934 1935 /* put buf back */ 1936 mm_stream_fsm_fn(s_objs[j], 1937 MM_STREAM_EVT_PUT_BUF, 1938 NULL, 1939 NULL); 1940 } 1941 1942 /* destroy super buf cmd thread */ 1943 if (TRUE == my_obj->bundle.is_active) { 1944 /* first stop bundle thread */ 1945 mm_camera_cmd_thread_release(&my_obj->cmd_thread); 1946 mm_camera_cmd_thread_release(&my_obj->cb_thread); 1947 1948 /* deinit superbuf queue */ 1949 mm_channel_superbuf_queue_deinit(&my_obj->bundle.superbuf_queue); 1950 1951 /* memset super buffer queue info */ 1952 my_obj->bundle.is_active = 0; 1953 memset(&my_obj->bundle.superbuf_queue, 0, sizeof(mm_channel_queue_t)); 1954 } 1955 } 1956 my_obj->bWaitForPrepSnapshotDone = 0; 1957 if (my_obj->bundle.superbuf_queue.attr.enable_frame_sync) { 1958 LOGH("registering Channel obj %p", my_obj); 1959 mm_frame_sync_register_channel(my_obj); 1960 } 1961 return rc; 1962 } 1963 1964 int32_t mm_channel_start_sensor_streaming(mm_channel_t *my_obj) 1965 { 1966 int32_t rc = 0; 1967 int i = 0; 1968 mm_stream_t *s_objs[MAX_STREAM_NUM_IN_BUNDLE] = {NULL}; 1969 uint8_t num_streams_to_start = 0; 1970 mm_stream_t *s_obj = NULL; 1971 int meta_stream_idx = 0; 1972 cam_stream_type_t stream_type = CAM_STREAM_TYPE_DEFAULT; 1973 1974 for (i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) { 1975 if (my_obj->streams[i].my_hdl > 0) { 1976 s_obj = mm_channel_util_get_stream_by_handler(my_obj, 1977 my_obj->streams[i].my_hdl); 1978 if (NULL != s_obj) { 1979 stream_type = s_obj->stream_info->stream_type; 1980 /* remember meta data stream index */ 1981 if ((stream_type == CAM_STREAM_TYPE_METADATA) && 1982 (s_obj->ch_obj == my_obj)) { 1983 meta_stream_idx = num_streams_to_start; 1984 } 1985 s_objs[num_streams_to_start++] = s_obj; 1986 } 1987 } 1988 } 1989 1990 if (meta_stream_idx > 0 ) { 1991 /* always start meta data stream first, so switch the stream object with the first one */ 1992 s_obj = s_objs[0]; 1993 s_objs[0] = s_objs[meta_stream_idx]; 1994 s_objs[meta_stream_idx] = s_obj; 1995 } 1996 1997 for (i = 0; i < num_streams_to_start; i++) { 1998 if (s_objs[i]->ch_obj != my_obj) { 1999 continue; 2000 } 2001 2002 /* start sensor streaming */ 2003 rc = mm_stream_fsm_fn(s_objs[i], 2004 MM_STREAM_EVT_START_SENSOR_STREAMING, 2005 NULL, 2006 NULL); 2007 if (0 != rc) { 2008 LOGE("start stream failed at idx(%d)", i); 2009 break; 2010 } 2011 } 2012 2013 return rc; 2014 } 2015 2016 /*=========================================================================== 2017 * FUNCTION : mm_channel_stop 2018 * 2019 * DESCRIPTION: stop a channel, which will stop all streams in the channel 2020 * 2021 * PARAMETERS : 2022 * @my_obj : channel object 2023 * 2024 * RETURN : int32_t type of status 2025 * 0 -- success 2026 * -1 -- failure 2027 *==========================================================================*/ 2028 int32_t mm_channel_stop(mm_channel_t *my_obj, bool stopImmediately) 2029 { 2030 int32_t rc = 0; 2031 int i; 2032 mm_stream_t *s_objs[MAX_STREAM_NUM_IN_BUNDLE] = {NULL}; 2033 uint8_t num_streams_to_stop = 0; 2034 mm_stream_t *s_obj = NULL; 2035 int meta_stream_idx = 0; 2036 cam_stream_type_t stream_type = CAM_STREAM_TYPE_DEFAULT; 2037 2038 if (my_obj->bundle.superbuf_queue.attr.enable_frame_sync) { 2039 mm_frame_sync_unregister_channel(my_obj); 2040 } 2041 2042 for (i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) { 2043 if (my_obj->streams[i].my_hdl > 0) { 2044 s_obj = mm_channel_util_get_stream_by_handler(my_obj, 2045 my_obj->streams[i].my_hdl); 2046 if (NULL != s_obj) { 2047 if (s_obj->ch_obj == my_obj) { 2048 stream_type = s_obj->stream_info->stream_type; 2049 /* remember meta data stream index */ 2050 if (stream_type == CAM_STREAM_TYPE_METADATA) { 2051 meta_stream_idx = num_streams_to_stop; 2052 } 2053 } 2054 s_objs[num_streams_to_stop++] = s_obj; 2055 } 2056 } 2057 } 2058 2059 if (meta_stream_idx < num_streams_to_stop - 1 ) { 2060 /* always stop meta data stream last, so switch the stream object with the last one */ 2061 s_obj = s_objs[num_streams_to_stop - 1]; 2062 s_objs[num_streams_to_stop - 1] = s_objs[meta_stream_idx]; 2063 s_objs[meta_stream_idx] = s_obj; 2064 } 2065 2066 for (i = 0; i < num_streams_to_stop; i++) { 2067 /* stream that are linked to this channel should not be stopped */ 2068 if (s_objs[i]->ch_obj != my_obj) { 2069 continue; 2070 } 2071 2072 /* stream off */ 2073 mm_stream_fsm_fn(s_objs[i], 2074 MM_STREAM_EVT_STOP, 2075 &stopImmediately, 2076 NULL); 2077 2078 /* unreg buf at kernel */ 2079 mm_stream_fsm_fn(s_objs[i], 2080 MM_STREAM_EVT_UNREG_BUF, 2081 NULL, 2082 NULL); 2083 } 2084 2085 for (i = 0; i < num_streams_to_stop; i++) { 2086 if (s_objs[i]->ch_obj != my_obj) { 2087 /* Only unlink stream */ 2088 pthread_mutex_lock(&s_objs[i]->linked_stream->buf_lock); 2089 s_objs[i]->linked_stream->is_linked = 0; 2090 s_objs[i]->linked_stream->linked_obj = NULL; 2091 pthread_mutex_unlock(&s_objs[i]->linked_stream->buf_lock); 2092 } 2093 } 2094 2095 /* destroy super buf cmd thread */ 2096 if (TRUE == my_obj->bundle.is_active) { 2097 mm_channel_flush_super_buf_queue(my_obj, 0, CAM_STREAM_TYPE_DEFAULT); 2098 /* first stop bundle thread */ 2099 mm_camera_cmd_thread_release(&my_obj->cmd_thread); 2100 mm_camera_cmd_thread_release(&my_obj->cb_thread); 2101 2102 /* deinit superbuf queue */ 2103 mm_channel_superbuf_queue_deinit(&my_obj->bundle.superbuf_queue); 2104 2105 /* reset few fields in the bundle info */ 2106 my_obj->bundle.is_active = 0; 2107 my_obj->bundle.superbuf_queue.expected_frame_id = 0; 2108 my_obj->bundle.superbuf_queue.good_frame_id = 0; 2109 my_obj->bundle.superbuf_queue.match_cnt = 0; 2110 } 2111 2112 /* since all streams are stopped, we are safe to 2113 * release all buffers allocated in stream */ 2114 for (i = 0; i < num_streams_to_stop; i++) { 2115 if (s_objs[i]->ch_obj != my_obj) { 2116 continue; 2117 } 2118 /* put buf back */ 2119 mm_stream_fsm_fn(s_objs[i], 2120 MM_STREAM_EVT_PUT_BUF, 2121 NULL, 2122 NULL); 2123 } 2124 2125 for (i = 0; i < num_streams_to_stop; i++) { 2126 if (s_objs[i]->ch_obj != my_obj) { 2127 memset(s_objs[i], 0, sizeof(mm_stream_t)); 2128 } else { 2129 continue; 2130 } 2131 } 2132 return rc; 2133 } 2134 2135 /*=========================================================================== 2136 * FUNCTION : mm_channel_request_super_buf 2137 * 2138 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 2139 * frames from superbuf queue 2140 * 2141 * PARAMETERS : 2142 * @my_obj : channel object 2143 * @num_buf_requested : number of matched frames needed 2144 * @num_retro_buf_requested : number of retro frames needed 2145 * 2146 * RETURN : int32_t type of status 2147 * 0 -- success 2148 * -1 -- failure 2149 *==========================================================================*/ 2150 int32_t mm_channel_request_super_buf(mm_channel_t *my_obj, 2151 mm_camera_req_buf_t *buf) 2152 { 2153 int32_t rc = 0; 2154 mm_camera_cmdcb_t* node = NULL; 2155 2156 if(!buf) { 2157 LOGE("Request info buf is NULL"); 2158 return -1; 2159 } 2160 2161 /* set pending_cnt 2162 * will trigger dispatching super frames if pending_cnt > 0 */ 2163 /* send cam_sem_post to wake up cmd thread to dispatch super buffer */ 2164 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 2165 if (NULL != node) { 2166 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 2167 node->cmd_type = MM_CAMERA_CMD_TYPE_REQ_DATA_CB; 2168 node->u.req_buf = *buf; 2169 2170 /* enqueue to cmd thread */ 2171 cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node); 2172 2173 /* wake up cmd thread */ 2174 cam_sem_post(&(my_obj->cmd_thread.cmd_sem)); 2175 } else { 2176 LOGE("No memory for mm_camera_node_t"); 2177 rc = -1; 2178 } 2179 2180 return rc; 2181 } 2182 2183 /*=========================================================================== 2184 * FUNCTION : mm_channel_cancel_super_buf_request 2185 * 2186 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 2187 * of matched frames from superbuf queue 2188 * 2189 * PARAMETERS : 2190 * @my_obj : channel object 2191 * 2192 * RETURN : int32_t type of status 2193 * 0 -- success 2194 * -1 -- failure 2195 *==========================================================================*/ 2196 int32_t mm_channel_cancel_super_buf_request(mm_channel_t *my_obj) 2197 { 2198 int32_t rc = 0; 2199 /* reset pending_cnt */ 2200 mm_camera_req_buf_t buf; 2201 memset(&buf, 0x0, sizeof(buf)); 2202 buf.type = MM_CAMERA_REQ_SUPER_BUF; 2203 buf.num_buf_requested = 0; 2204 rc = mm_channel_request_super_buf(my_obj, &buf); 2205 return rc; 2206 } 2207 2208 /*=========================================================================== 2209 * FUNCTION : mm_channel_flush_super_buf_queue 2210 * 2211 * DESCRIPTION: flush superbuf queue 2212 * 2213 * PARAMETERS : 2214 * @my_obj : channel object 2215 * @frame_idx : frame idx until which to flush all superbufs 2216 * 2217 * RETURN : int32_t type of status 2218 * 0 -- success 2219 * -1 -- failure 2220 *==========================================================================*/ 2221 int32_t mm_channel_flush_super_buf_queue(mm_channel_t *my_obj, uint32_t frame_idx, 2222 cam_stream_type_t stream_type) 2223 { 2224 int32_t rc = 0; 2225 mm_camera_cmdcb_t* node = NULL; 2226 2227 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 2228 if (NULL != node) { 2229 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 2230 node->cmd_type = MM_CAMERA_CMD_TYPE_FLUSH_QUEUE; 2231 node->u.flush_cmd.frame_idx = frame_idx; 2232 node->u.flush_cmd.stream_type = stream_type; 2233 2234 /* enqueue to cmd thread */ 2235 cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node); 2236 2237 /* wake up cmd thread */ 2238 cam_sem_post(&(my_obj->cmd_thread.cmd_sem)); 2239 2240 /* wait for ack from cmd thread */ 2241 cam_sem_wait(&(my_obj->cmd_thread.sync_sem)); 2242 } else { 2243 LOGE("No memory for mm_camera_node_t"); 2244 rc = -1; 2245 } 2246 2247 return rc; 2248 } 2249 2250 /*=========================================================================== 2251 * FUNCTION : mm_channel_config_notify_mode 2252 * 2253 * DESCRIPTION: configure notification mode 2254 * 2255 * PARAMETERS : 2256 * @my_obj : channel object 2257 * @notify_mode : notification mode 2258 * 2259 * RETURN : int32_t type of status 2260 * 0 -- success 2261 * -1 -- failure 2262 *==========================================================================*/ 2263 int32_t mm_channel_config_notify_mode(mm_channel_t *my_obj, 2264 mm_camera_super_buf_notify_mode_t notify_mode) 2265 { 2266 int32_t rc = 0; 2267 mm_camera_cmdcb_t* node = NULL; 2268 2269 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 2270 if (NULL != node) { 2271 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 2272 node->u.notify_mode = notify_mode; 2273 node->cmd_type = MM_CAMERA_CMD_TYPE_CONFIG_NOTIFY; 2274 2275 /* enqueue to cmd thread */ 2276 cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node); 2277 2278 /* wake up cmd thread */ 2279 cam_sem_post(&(my_obj->cmd_thread.cmd_sem)); 2280 } else { 2281 LOGE("No memory for mm_camera_node_t"); 2282 rc = -1; 2283 } 2284 2285 return rc; 2286 } 2287 2288 /*=========================================================================== 2289 * FUNCTION : mm_channel_start_zsl_snapshot 2290 * 2291 * DESCRIPTION: start zsl snapshot 2292 * 2293 * PARAMETERS : 2294 * @my_obj : channel object 2295 * 2296 * RETURN : int32_t type of status 2297 * 0 -- success 2298 * -1 -- failure 2299 *==========================================================================*/ 2300 int32_t mm_channel_start_zsl_snapshot(mm_channel_t *my_obj) 2301 { 2302 int32_t rc = 0; 2303 mm_camera_cmdcb_t* node = NULL; 2304 2305 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 2306 if (NULL != node) { 2307 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 2308 node->cmd_type = MM_CAMERA_CMD_TYPE_START_ZSL; 2309 2310 /* enqueue to cmd thread */ 2311 cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node); 2312 2313 /* wake up cmd thread */ 2314 cam_sem_post(&(my_obj->cmd_thread.cmd_sem)); 2315 } else { 2316 LOGE("No memory for mm_camera_node_t"); 2317 rc = -1; 2318 } 2319 2320 return rc; 2321 } 2322 2323 /*=========================================================================== 2324 * FUNCTION : mm_channel_stop_zsl_snapshot 2325 * 2326 * DESCRIPTION: stop zsl snapshot 2327 * 2328 * PARAMETERS : 2329 * @my_obj : channel object 2330 * 2331 * RETURN : int32_t type of status 2332 * 0 -- success 2333 * -1 -- failure 2334 *==========================================================================*/ 2335 int32_t mm_channel_stop_zsl_snapshot(mm_channel_t *my_obj) 2336 { 2337 int32_t rc = 0; 2338 mm_camera_cmdcb_t* node = NULL; 2339 2340 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 2341 if (NULL != node) { 2342 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 2343 node->cmd_type = MM_CAMERA_CMD_TYPE_STOP_ZSL; 2344 2345 /* enqueue to cmd thread */ 2346 cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node); 2347 2348 /* wake up cmd thread */ 2349 cam_sem_post(&(my_obj->cmd_thread.cmd_sem)); 2350 } else { 2351 LOGE("No memory for mm_camera_node_t"); 2352 rc = -1; 2353 } 2354 2355 return rc; 2356 } 2357 2358 /*=========================================================================== 2359 * FUNCTION : mm_channel_qbuf 2360 * 2361 * DESCRIPTION: enqueue buffer back to kernel 2362 * 2363 * PARAMETERS : 2364 * @my_obj : channel object 2365 * @buf : buf ptr to be enqueued 2366 * 2367 * RETURN : int32_t type of status 2368 * 0 -- success 2369 * -1 -- failure 2370 *==========================================================================*/ 2371 int32_t mm_channel_qbuf(mm_channel_t *my_obj, 2372 mm_camera_buf_def_t *buf) 2373 { 2374 int32_t rc = -1; 2375 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, buf->stream_id); 2376 2377 if (NULL != s_obj) { 2378 if (s_obj->ch_obj != my_obj) { 2379 /* Redirect to linked stream */ 2380 rc = mm_stream_fsm_fn(s_obj->linked_stream, 2381 MM_STREAM_EVT_QBUF, 2382 (void *)buf, 2383 NULL); 2384 } else { 2385 rc = mm_stream_fsm_fn(s_obj, 2386 MM_STREAM_EVT_QBUF, 2387 (void *)buf, 2388 NULL); 2389 } 2390 } 2391 2392 return rc; 2393 } 2394 2395 /*=========================================================================== 2396 * FUNCTION : mm_channel_cancel_buf 2397 * 2398 * DESCRIPTION: Get back buffer already sent to kernel 2399 * 2400 * PARAMETERS : 2401 * @my_obj : channel object 2402 * @buf : buf ptr to be enqueued 2403 * 2404 * RETURN : int32_t type of status 2405 * 0 -- success 2406 * -1 -- failure 2407 *==========================================================================*/ 2408 int32_t mm_channel_cancel_buf(mm_channel_t *my_obj, 2409 uint32_t stream_id, uint32_t buf_idx) 2410 { 2411 int32_t rc = -1; 2412 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id); 2413 2414 if (NULL != s_obj) { 2415 if (s_obj->ch_obj != my_obj) { 2416 /* Redirect to linked stream */ 2417 rc = mm_stream_fsm_fn(s_obj->linked_stream, 2418 MM_STREAM_EVT_CANCEL_BUF, 2419 (void *)&buf_idx, 2420 NULL); 2421 } else { 2422 rc = mm_stream_fsm_fn(s_obj, 2423 MM_STREAM_EVT_CANCEL_BUF, 2424 (void *)&buf_idx, 2425 NULL); 2426 } 2427 } 2428 2429 return rc; 2430 } 2431 2432 2433 /*=========================================================================== 2434 * FUNCTION : mm_channel_get_queued_buf_count 2435 * 2436 * DESCRIPTION: return queued buffer count 2437 * 2438 * PARAMETERS : 2439 * @my_obj : channel object 2440 * @stream_id : steam_id 2441 * 2442 * RETURN : queued buffer count 2443 *==========================================================================*/ 2444 int32_t mm_channel_get_queued_buf_count(mm_channel_t *my_obj, uint32_t stream_id) 2445 { 2446 int32_t rc = -1; 2447 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id); 2448 2449 if (NULL != s_obj) { 2450 if (s_obj->ch_obj != my_obj) { 2451 /* Redirect to linked stream */ 2452 rc = mm_stream_fsm_fn(s_obj->linked_stream, 2453 MM_STREAM_EVT_GET_QUEUED_BUF_COUNT, 2454 NULL, 2455 NULL); 2456 } else { 2457 rc = mm_stream_fsm_fn(s_obj, 2458 MM_STREAM_EVT_GET_QUEUED_BUF_COUNT, 2459 NULL, 2460 NULL); 2461 } 2462 } 2463 2464 return rc; 2465 } 2466 2467 /*=========================================================================== 2468 * FUNCTION : mm_channel_set_stream_parms 2469 * 2470 * DESCRIPTION: set parameters per stream 2471 * 2472 * PARAMETERS : 2473 * @my_obj : channel object 2474 * @s_id : stream handle 2475 * @parms : ptr to a param struct to be set to server 2476 * 2477 * RETURN : int32_t type of status 2478 * 0 -- success 2479 * -1 -- failure 2480 * NOTE : Assume the parms struct buf is already mapped to server via 2481 * domain socket. Corresponding fields of parameters to be set 2482 * are already filled in by upper layer caller. 2483 *==========================================================================*/ 2484 int32_t mm_channel_set_stream_parm(mm_channel_t *my_obj, 2485 mm_evt_paylod_set_get_stream_parms_t *payload) 2486 { 2487 int32_t rc = -1; 2488 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, 2489 payload->stream_id); 2490 if (NULL != s_obj) { 2491 if (s_obj->ch_obj != my_obj) { 2492 /* No op. on linked streams */ 2493 return 0; 2494 } 2495 2496 rc = mm_stream_fsm_fn(s_obj, 2497 MM_STREAM_EVT_SET_PARM, 2498 (void *)payload, 2499 NULL); 2500 } 2501 2502 return rc; 2503 } 2504 2505 /*=========================================================================== 2506 * FUNCTION : mm_channel_get_stream_parms 2507 * 2508 * DESCRIPTION: get parameters per stream 2509 * 2510 * PARAMETERS : 2511 * @my_obj : channel object 2512 * @s_id : stream handle 2513 * @parms : ptr to a param struct to be get from server 2514 * 2515 * RETURN : int32_t type of status 2516 * 0 -- success 2517 * -1 -- failure 2518 * NOTE : Assume the parms struct buf is already mapped to server via 2519 * domain socket. Parameters to be get from server are already 2520 * filled in by upper layer caller. After this call, corresponding 2521 * fields of requested parameters will be filled in by server with 2522 * detailed information. 2523 *==========================================================================*/ 2524 int32_t mm_channel_get_stream_parm(mm_channel_t *my_obj, 2525 mm_evt_paylod_set_get_stream_parms_t *payload) 2526 { 2527 int32_t rc = -1; 2528 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, 2529 payload->stream_id); 2530 if (NULL != s_obj) { 2531 if (s_obj->ch_obj != my_obj) { 2532 /* No op. on linked streams */ 2533 return 0; 2534 } 2535 2536 rc = mm_stream_fsm_fn(s_obj, 2537 MM_STREAM_EVT_GET_PARM, 2538 (void *)payload, 2539 NULL); 2540 } 2541 2542 return rc; 2543 } 2544 2545 /*=========================================================================== 2546 * FUNCTION : mm_channel_do_stream_action 2547 * 2548 * DESCRIPTION: request server to perform stream based action. Maybe removed later 2549 * if the functionality is included in mm_camera_set_parms 2550 * 2551 * PARAMETERS : 2552 * @my_obj : channel object 2553 * @s_id : stream handle 2554 * @actions : ptr to an action struct buf to be performed by server 2555 * 2556 * RETURN : int32_t type of status 2557 * 0 -- success 2558 * -1 -- failure 2559 * NOTE : Assume the action struct buf is already mapped to server via 2560 * domain socket. Actions to be performed by server are already 2561 * filled in by upper layer caller. 2562 *==========================================================================*/ 2563 int32_t mm_channel_do_stream_action(mm_channel_t *my_obj, 2564 mm_evt_paylod_do_stream_action_t *payload) 2565 { 2566 int32_t rc = -1; 2567 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, 2568 payload->stream_id); 2569 if (NULL != s_obj) { 2570 if (s_obj->ch_obj != my_obj) { 2571 /* No op. on linked streams */ 2572 return 0; 2573 } 2574 2575 rc = mm_stream_fsm_fn(s_obj, 2576 MM_STREAM_EVT_DO_ACTION, 2577 (void *)payload, 2578 NULL); 2579 } 2580 2581 return rc; 2582 } 2583 2584 /*=========================================================================== 2585 * FUNCTION : mm_channel_map_stream_buf 2586 * 2587 * DESCRIPTION: mapping stream buffer via domain socket to server 2588 * 2589 * PARAMETERS : 2590 * @my_obj : channel object 2591 * @payload : ptr to payload for mapping 2592 * 2593 * RETURN : int32_t type of status 2594 * 0 -- success 2595 * -1 -- failure 2596 *==========================================================================*/ 2597 int32_t mm_channel_map_stream_buf(mm_channel_t *my_obj, 2598 cam_buf_map_type *payload) 2599 { 2600 int32_t rc = -1; 2601 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, 2602 payload->stream_id); 2603 if (NULL != s_obj) { 2604 if (s_obj->ch_obj != my_obj) { 2605 /* No op. on linked streams */ 2606 return 0; 2607 } 2608 rc = mm_stream_map_buf(s_obj, 2609 payload->type, payload->frame_idx, 2610 payload->plane_idx, payload->fd, 2611 payload->size, payload->buffer); 2612 } 2613 2614 return rc; 2615 } 2616 2617 /*=========================================================================== 2618 * FUNCTION : mm_channel_map_stream_bufs 2619 * 2620 * DESCRIPTION: mapping stream buffers via domain socket to server 2621 * 2622 * PARAMETERS : 2623 * @my_obj : channel object 2624 * @payload : ptr to payload for mapping 2625 * 2626 * RETURN : int32_t type of status 2627 * 0 -- success 2628 * -1 -- failure 2629 *==========================================================================*/ 2630 int32_t mm_channel_map_stream_bufs(mm_channel_t *my_obj, 2631 cam_buf_map_type_list *payload) 2632 { 2633 int32_t rc = -1; 2634 if ((payload == NULL) || (payload->length == 0)) { 2635 return rc; 2636 } 2637 2638 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, 2639 payload->buf_maps[0].stream_id); 2640 if (NULL != s_obj) { 2641 if (s_obj->ch_obj != my_obj) { 2642 /* No op. on linked streams */ 2643 return 0; 2644 } 2645 rc = mm_stream_map_bufs(s_obj, payload); 2646 } 2647 return rc; 2648 } 2649 2650 /*=========================================================================== 2651 * FUNCTION : mm_channel_unmap_stream_buf 2652 * 2653 * DESCRIPTION: unmapping stream buffer via domain socket to server 2654 * 2655 * PARAMETERS : 2656 * @my_obj : channel object 2657 * @payload : ptr to unmap payload 2658 * 2659 * RETURN : int32_t type of status 2660 * 0 -- success 2661 * -1 -- failure 2662 *==========================================================================*/ 2663 int32_t mm_channel_unmap_stream_buf(mm_channel_t *my_obj, 2664 cam_buf_unmap_type *payload) 2665 { 2666 int32_t rc = -1; 2667 mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, 2668 payload->stream_id); 2669 if (NULL != s_obj) { 2670 if (s_obj->ch_obj != my_obj) { 2671 /* No op. on linked streams */ 2672 return 0; 2673 } 2674 2675 rc = mm_stream_unmap_buf(s_obj, payload->type, 2676 payload->frame_idx, payload->plane_idx); 2677 } 2678 2679 return rc; 2680 } 2681 2682 /*=========================================================================== 2683 * FUNCTION : mm_channel_superbuf_queue_init 2684 * 2685 * DESCRIPTION: initialize superbuf queue in the channel 2686 * 2687 * PARAMETERS : 2688 * @queue : ptr to superbuf queue to be initialized 2689 * 2690 * RETURN : int32_t type of status 2691 * 0 -- success 2692 * -1 -- failure 2693 *==========================================================================*/ 2694 int32_t mm_channel_superbuf_queue_init(mm_channel_queue_t * queue) 2695 { 2696 return cam_queue_init(&queue->que); 2697 } 2698 2699 /*=========================================================================== 2700 * FUNCTION : mm_channel_superbuf_queue_deinit 2701 * 2702 * DESCRIPTION: deinitialize superbuf queue in the channel 2703 * 2704 * PARAMETERS : 2705 * @queue : ptr to superbuf queue to be deinitialized 2706 * 2707 * RETURN : int32_t type of status 2708 * 0 -- success 2709 * -1 -- failure 2710 *==========================================================================*/ 2711 int32_t mm_channel_superbuf_queue_deinit(mm_channel_queue_t * queue) 2712 { 2713 return cam_queue_deinit(&queue->que); 2714 } 2715 2716 /*=========================================================================== 2717 * FUNCTION : mm_channel_util_seq_comp_w_rollover 2718 * 2719 * DESCRIPTION: utility function to handle sequence number comparison with rollover 2720 * 2721 * PARAMETERS : 2722 * @v1 : first value to be compared 2723 * @v2 : second value to be compared 2724 * 2725 * RETURN : int8_t type of comparison result 2726 * >0 -- v1 larger than v2 2727 * =0 -- vi equal to v2 2728 * <0 -- v1 smaller than v2 2729 *==========================================================================*/ 2730 int8_t mm_channel_util_seq_comp_w_rollover(uint32_t v1, 2731 uint32_t v2) 2732 { 2733 int8_t ret = 0; 2734 2735 /* TODO: need to handle the case if v2 roll over to 0 */ 2736 if (v1 > v2) { 2737 ret = 1; 2738 } else if (v1 < v2) { 2739 ret = -1; 2740 } 2741 2742 return ret; 2743 } 2744 2745 /*=========================================================================== 2746 * FUNCTION : mm_channel_validate_super_buf. 2747 * 2748 * DESCRIPTION: Validate incoming buffer with existing super buffer. 2749 * 2750 * PARAMETERS : 2751 * @ch_obj : channel object 2752 * @queue : superbuf queue 2753 * @buf_info: new buffer from stream 2754 * 2755 * RETURN : int8_t type of validation result 2756 * >0 -- Valid frame 2757 * =0 -- Cannot validate 2758 * <0 -- Invalid frame. Can be freed 2759 *==========================================================================*/ 2760 int8_t mm_channel_validate_super_buf(mm_channel_t* ch_obj, 2761 mm_channel_queue_t *queue, mm_camera_buf_info_t *buf_info) 2762 { 2763 int8_t ret = 0; 2764 cam_node_t* node = NULL; 2765 struct cam_list *head = NULL; 2766 struct cam_list *pos = NULL; 2767 mm_channel_queue_node_t* super_buf = NULL; 2768 2769 (void)ch_obj; 2770 2771 /* comp */ 2772 pthread_mutex_lock(&queue->que.lock); 2773 head = &queue->que.head.list; 2774 /* get the last one in the queue which is possibly having no matching */ 2775 pos = head->next; 2776 while (pos != head) { 2777 node = member_of(pos, cam_node_t, list); 2778 super_buf = (mm_channel_queue_node_t*)node->data; 2779 if (NULL != super_buf) { 2780 if ((super_buf->expected_frame) && 2781 (buf_info->frame_idx == super_buf->frame_idx)) { 2782 //This is good frame. Expecting more frames. Keeping this frame. 2783 ret = 1; 2784 break; 2785 } else { 2786 pos = pos->next; 2787 continue; 2788 } 2789 } 2790 } 2791 pthread_mutex_unlock(&queue->que.lock); 2792 return ret; 2793 } 2794 2795 /*=========================================================================== 2796 * FUNCTION : mm_channel_handle_metadata 2797 * 2798 * DESCRIPTION: Handle frame matching logic change due to metadata 2799 * 2800 * PARAMETERS : 2801 * @ch_obj : channel object 2802 * @queue : superbuf queue 2803 * @buf_info: new buffer from stream 2804 * 2805 * RETURN : int32_t type of status 2806 * 0 -- success 2807 * -1 -- failure 2808 *==========================================================================*/ 2809 int32_t mm_channel_handle_metadata( 2810 mm_channel_t* ch_obj, 2811 mm_channel_queue_t * queue, 2812 mm_camera_buf_info_t *buf_info) 2813 { 2814 2815 int rc = 0 ; 2816 mm_stream_t* stream_obj = NULL; 2817 stream_obj = mm_channel_util_get_stream_by_handler(ch_obj, 2818 buf_info->stream_id); 2819 uint8_t is_prep_snapshot_done_valid = 0; 2820 uint8_t is_good_frame_idx_range_valid = 0; 2821 int32_t prep_snapshot_done_state = 0; 2822 cam_frame_idx_range_t good_frame_idx_range; 2823 uint8_t is_crop_1x_found = 0; 2824 uint32_t snapshot_stream_id = 0; 2825 uint32_t i; 2826 /* Set expected frame id to a future frame idx, large enough to wait 2827 * for good_frame_idx_range, and small enough to still capture an image */ 2828 const uint32_t max_future_frame_offset = MM_CAMERA_MAX_FUTURE_FRAME_WAIT; 2829 2830 memset(&good_frame_idx_range, 0, sizeof(good_frame_idx_range)); 2831 2832 if (NULL == stream_obj) { 2833 LOGE("Invalid Stream Object for stream_id = %d", 2834 buf_info->stream_id); 2835 rc = -1; 2836 goto end; 2837 } 2838 if (NULL == stream_obj->stream_info) { 2839 LOGE("NULL stream info for stream_id = %d", 2840 buf_info->stream_id); 2841 rc = -1; 2842 goto end; 2843 } 2844 2845 if ((CAM_STREAM_TYPE_METADATA == stream_obj->stream_info->stream_type) && 2846 ((stream_obj->ch_obj == ch_obj) || 2847 ((stream_obj->linked_stream != NULL) && 2848 (stream_obj->linked_stream->linked_obj == ch_obj)))) { 2849 const metadata_buffer_t *metadata; 2850 metadata = (const metadata_buffer_t *)buf_info->buf->buffer; 2851 2852 if (NULL == metadata) { 2853 LOGE("NULL metadata buffer for metadata stream"); 2854 rc = -1; 2855 goto end; 2856 } 2857 LOGL("E , expected frame id: %d", queue->expected_frame_id); 2858 2859 IF_META_AVAILABLE(const int32_t, p_prep_snapshot_done_state, 2860 CAM_INTF_META_PREP_SNAPSHOT_DONE, metadata) { 2861 prep_snapshot_done_state = *p_prep_snapshot_done_state; 2862 is_prep_snapshot_done_valid = 1; 2863 LOGH("prepare snapshot done valid "); 2864 } 2865 IF_META_AVAILABLE(const cam_frame_idx_range_t, p_good_frame_idx_range, 2866 CAM_INTF_META_GOOD_FRAME_IDX_RANGE, metadata) { 2867 good_frame_idx_range = *p_good_frame_idx_range; 2868 is_good_frame_idx_range_valid = 1; 2869 LOGH("good_frame_idx_range : min: %d, max: %d , num frames = %d", 2870 good_frame_idx_range.min_frame_idx, 2871 good_frame_idx_range.max_frame_idx, good_frame_idx_range.num_led_on_frames); 2872 } 2873 IF_META_AVAILABLE(const cam_crop_data_t, p_crop_data, 2874 CAM_INTF_META_CROP_DATA, metadata) { 2875 cam_crop_data_t crop_data = *p_crop_data; 2876 2877 for (i = 0; i < ARRAY_SIZE(ch_obj->streams); i++) { 2878 if (MM_STREAM_STATE_NOTUSED == ch_obj->streams[i].state) { 2879 continue; 2880 } 2881 if (CAM_STREAM_TYPE_SNAPSHOT == 2882 ch_obj->streams[i].stream_info->stream_type) { 2883 snapshot_stream_id = ch_obj->streams[i].server_stream_id; 2884 break; 2885 } 2886 } 2887 2888 for (i=0; i<crop_data.num_of_streams; i++) { 2889 if (snapshot_stream_id == crop_data.crop_info[i].stream_id) { 2890 if (!crop_data.crop_info[i].crop.left && 2891 !crop_data.crop_info[i].crop.top) { 2892 is_crop_1x_found = 1; 2893 break; 2894 } 2895 } 2896 } 2897 } 2898 2899 IF_META_AVAILABLE(const cam_buf_divert_info_t, p_divert_info, 2900 CAM_INTF_BUF_DIVERT_INFO, metadata) { 2901 cam_buf_divert_info_t divert_info = *p_divert_info; 2902 if (divert_info.frame_id >= buf_info->frame_idx) { 2903 ch_obj->diverted_frame_id = divert_info.frame_id; 2904 } else { 2905 ch_obj->diverted_frame_id = 0; 2906 } 2907 } 2908 2909 if (ch_obj->isZoom1xFrameRequested) { 2910 if (is_crop_1x_found) { 2911 ch_obj->isZoom1xFrameRequested = 0; 2912 queue->expected_frame_id = buf_info->frame_idx + 1; 2913 } else { 2914 queue->expected_frame_id += max_future_frame_offset; 2915 /* Flush unwanted frames */ 2916 mm_channel_superbuf_flush_matched(ch_obj, queue); 2917 } 2918 goto end; 2919 } 2920 2921 if (ch_obj->startZSlSnapshotCalled && is_good_frame_idx_range_valid) { 2922 LOGI("frameID = %d, expected = %d good_frame_idx = %d", 2923 buf_info->frame_idx, queue->expected_frame_id, 2924 good_frame_idx_range.min_frame_idx); 2925 } 2926 2927 if (is_prep_snapshot_done_valid) { 2928 ch_obj->bWaitForPrepSnapshotDone = 0; 2929 if (prep_snapshot_done_state == NEED_FUTURE_FRAME) { 2930 queue->expected_frame_id += max_future_frame_offset; 2931 LOGI("PreFlash Done. Need Main Flash"); 2932 2933 mm_channel_superbuf_flush(ch_obj, 2934 queue, CAM_STREAM_TYPE_DEFAULT); 2935 2936 ch_obj->needLEDFlash = TRUE; 2937 } else { 2938 ch_obj->needLEDFlash = FALSE; 2939 } 2940 } 2941 if (is_good_frame_idx_range_valid) { 2942 queue->expected_frame_id = 2943 good_frame_idx_range.min_frame_idx; 2944 queue->good_frame_id = good_frame_idx_range.min_frame_idx; 2945 if((ch_obj->needLEDFlash == TRUE) && (ch_obj->burstSnapNum > 1)) { 2946 queue->led_on_start_frame_id = 2947 good_frame_idx_range.min_frame_idx; 2948 queue->led_off_start_frame_id = 2949 good_frame_idx_range.max_frame_idx; 2950 queue->once = 0; 2951 queue->led_on_num_frames = 2952 good_frame_idx_range.num_led_on_frames; 2953 queue->frame_skip_count = good_frame_idx_range.frame_skip_count; 2954 LOGD("Need Flash, expected frame id = %d," 2955 " led_on start = %d, led off start = %d, led on frames = %d ", 2956 queue->expected_frame_id, queue->led_on_start_frame_id, 2957 queue->led_off_start_frame_id, queue->led_on_num_frames); 2958 } else { 2959 LOGD("No flash, expected frame id = %d ", 2960 queue->expected_frame_id); 2961 } 2962 } else if ((MM_CHANNEL_BRACKETING_STATE_WAIT_GOOD_FRAME_IDX == ch_obj->bracketingState) && 2963 !is_prep_snapshot_done_valid) { 2964 /* Flush unwanted frames */ 2965 mm_channel_superbuf_flush_matched(ch_obj, queue); 2966 queue->expected_frame_id += max_future_frame_offset; 2967 } 2968 if (ch_obj->isFlashBracketingEnabled && 2969 is_good_frame_idx_range_valid) { 2970 /* Flash bracketing needs two frames, with & without led flash. 2971 * in valid range min frame is with led flash and max frame is 2972 * without led flash */ 2973 queue->expected_frame_id = 2974 good_frame_idx_range.min_frame_idx; 2975 /* max frame is without led flash */ 2976 queue->expected_frame_id_without_led = 2977 good_frame_idx_range.max_frame_idx; 2978 queue->good_frame_id = 2979 good_frame_idx_range.min_frame_idx; 2980 } else if (is_good_frame_idx_range_valid) { 2981 queue->expected_frame_id = 2982 good_frame_idx_range.min_frame_idx; 2983 ch_obj->bracketingState = MM_CHANNEL_BRACKETING_STATE_ACTIVE; 2984 queue->good_frame_id = 2985 good_frame_idx_range.min_frame_idx; 2986 } 2987 2988 if (ch_obj->isConfigCapture && is_good_frame_idx_range_valid 2989 && (good_frame_idx_range.config_batch_idx < ch_obj->frameConfig.num_batch)) { 2990 2991 LOGI("Frame Config: Expcted ID = %d batch index = %d", 2992 good_frame_idx_range.min_frame_idx, good_frame_idx_range.config_batch_idx); 2993 ch_obj->capture_frame_id[good_frame_idx_range.config_batch_idx] = 2994 good_frame_idx_range.min_frame_idx; 2995 2996 if (ch_obj->cur_capture_idx == good_frame_idx_range.config_batch_idx) { 2997 queue->expected_frame_id = 2998 good_frame_idx_range.min_frame_idx; 2999 } else { 3000 queue->expected_frame_id = 3001 ch_obj->capture_frame_id[ch_obj->cur_capture_idx]; 3002 } 3003 queue->good_frame_id = queue->expected_frame_id; 3004 } 3005 3006 if ((ch_obj->burstSnapNum > 1) && (ch_obj->needLEDFlash == TRUE) 3007 && !ch_obj->isFlashBracketingEnabled 3008 && (MM_CHANNEL_BRACKETING_STATE_OFF == ch_obj->bracketingState) 3009 && !ch_obj->isConfigCapture) { 3010 if((buf_info->frame_idx >= queue->led_off_start_frame_id) 3011 && !queue->once) { 3012 LOGD("Burst snap num = %d ", 3013 ch_obj->burstSnapNum); 3014 // Skip frames from LED OFF frame to get a good frame 3015 queue->expected_frame_id = queue->led_off_start_frame_id + 3016 queue->frame_skip_count; 3017 queue->once = 1; 3018 ch_obj->stopZslSnapshot = 1; 3019 ch_obj->needLEDFlash = FALSE; 3020 LOGD("Reached max led on frames = %d , expected id = %d", 3021 buf_info->frame_idx, queue->expected_frame_id); 3022 } 3023 } 3024 3025 IF_META_AVAILABLE(const cam_low_light_mode_t, low_light_level, 3026 CAM_INTF_META_LOW_LIGHT, metadata) { 3027 ch_obj->needLowLightZSL = *low_light_level; 3028 } 3029 3030 // For the instant capture case, if AEC settles before expected frame ID from user, 3031 // reset the expected frame ID to current frame index. 3032 if (queue->attr.user_expected_frame_id > 0) { 3033 if (queue->attr.user_expected_frame_id > buf_info->frame_idx) { 3034 IF_META_AVAILABLE(const cam_3a_params_t, ae_params, 3035 CAM_INTF_META_AEC_INFO, metadata) { 3036 if (ae_params->settled) { 3037 queue->expected_frame_id = buf_info->frame_idx; 3038 // Reset the expected frame ID from HAL to 0 3039 queue->attr.user_expected_frame_id = 0; 3040 LOGD("AEC settled, reset expected frame ID from user"); 3041 } 3042 } 3043 } else { 3044 // Reset the expected frame ID from HAL to 0 after 3045 // current frame index is greater than expected id. 3046 queue->attr.user_expected_frame_id = 0; 3047 LOGD("reset expected frame ID from user as it reached the bound"); 3048 } 3049 } 3050 } 3051 end: 3052 return rc; 3053 } 3054 3055 /*=========================================================================== 3056 * FUNCTION : mm_channel_superbuf_comp_and_enqueue 3057 * 3058 * DESCRIPTION: implementation for matching logic for superbuf 3059 * 3060 * PARAMETERS : 3061 * @ch_obj : channel object 3062 * @queue : superbuf queue 3063 * @buf_info: new buffer from stream 3064 * 3065 * RETURN : int32_t type of status 3066 * 0 -- success 3067 * -1 -- failure 3068 *==========================================================================*/ 3069 int32_t mm_channel_superbuf_comp_and_enqueue( 3070 mm_channel_t* ch_obj, 3071 mm_channel_queue_t *queue, 3072 mm_camera_buf_info_t *buf_info) 3073 { 3074 cam_node_t* node = NULL; 3075 struct cam_list *head = NULL; 3076 struct cam_list *pos = NULL; 3077 mm_channel_queue_node_t* super_buf = NULL; 3078 uint8_t buf_s_idx, i, found_super_buf, unmatched_bundles; 3079 struct cam_list *last_buf, *insert_before_buf, *last_buf_ptr; 3080 3081 LOGD("E"); 3082 3083 for (buf_s_idx = 0; buf_s_idx < queue->num_streams; buf_s_idx++) { 3084 if (buf_info->stream_id == queue->bundled_streams[buf_s_idx]) { 3085 break; 3086 } 3087 } 3088 3089 if (buf_s_idx == queue->num_streams) { 3090 LOGE("buf from stream (%d) not bundled", buf_info->stream_id); 3091 return -1; 3092 } 3093 3094 if(buf_info->frame_idx == 0) { 3095 mm_channel_qbuf(ch_obj, buf_info->buf); 3096 return 0; 3097 } 3098 3099 if (mm_channel_handle_metadata(ch_obj, queue, buf_info) < 0) { 3100 mm_channel_qbuf(ch_obj, buf_info->buf); 3101 return -1; 3102 } 3103 3104 if ((mm_channel_util_seq_comp_w_rollover(buf_info->frame_idx, 3105 queue->expected_frame_id) < 0) && 3106 (mm_channel_validate_super_buf(ch_obj, queue, buf_info) <= 0)) { 3107 LOGH("incoming buf id(%d) is older than expected buf id(%d), will discard it", 3108 buf_info->frame_idx, queue->expected_frame_id); 3109 mm_channel_qbuf(ch_obj, buf_info->buf); 3110 return 0; 3111 } 3112 3113 /* comp */ 3114 pthread_mutex_lock(&queue->que.lock); 3115 head = &queue->que.head.list; 3116 /* get the last one in the queue which is possibly having no matching */ 3117 pos = head->next; 3118 3119 found_super_buf = 0; 3120 unmatched_bundles = 0; 3121 last_buf = NULL; 3122 insert_before_buf = NULL; 3123 last_buf_ptr = NULL; 3124 3125 while (pos != head) { 3126 node = member_of(pos, cam_node_t, list); 3127 super_buf = (mm_channel_queue_node_t*)node->data; 3128 3129 if (NULL != super_buf) { 3130 if (super_buf->matched) { 3131 /* find a matched super buf, move to next one */ 3132 pos = pos->next; 3133 continue; 3134 } else if (( buf_info->frame_idx == super_buf->frame_idx ) 3135 /*Pick metadata greater than available frameID*/ 3136 || ((queue->attr.priority == MM_CAMERA_SUPER_BUF_PRIORITY_LOW) 3137 && (super_buf->super_buf[buf_s_idx].frame_idx == 0) 3138 && (buf_info->buf->stream_type == CAM_STREAM_TYPE_METADATA) 3139 && (super_buf->frame_idx < buf_info->frame_idx)) 3140 /*Pick available metadata closest to frameID*/ 3141 || ((queue->attr.priority == MM_CAMERA_SUPER_BUF_PRIORITY_LOW) 3142 && (buf_info->buf->stream_type != CAM_STREAM_TYPE_METADATA) 3143 && (super_buf->super_buf[buf_s_idx].frame_idx == 0) 3144 && (super_buf->unmatched_meta_idx > buf_info->frame_idx))){ 3145 /*super buffer frame IDs matching OR In low priority bundling 3146 metadata frameID greater than avialbale super buffer frameID OR 3147 metadata frame closest to incoming frameID will be bundled*/ 3148 found_super_buf = 1; 3149 /* If we are filling into a 'meta only' superbuf, make sure to reset 3150 the super_buf frame_idx so that missing streams in this superbuf 3151 are filled as per matching frame id logic. Note that, in low priority 3152 queue, only meta frame id need not match (closest suffices) but 3153 the other streams in this superbuf should have same frame id. */ 3154 if (super_buf->unmatched_meta_idx > 0) { 3155 super_buf->unmatched_meta_idx = 0; 3156 super_buf->frame_idx = buf_info->frame_idx; 3157 } 3158 break; 3159 } else { 3160 unmatched_bundles++; 3161 if ( NULL == last_buf ) { 3162 if ( super_buf->frame_idx < buf_info->frame_idx ) { 3163 last_buf = pos; 3164 } 3165 } 3166 if ( NULL == insert_before_buf ) { 3167 if ( super_buf->frame_idx > buf_info->frame_idx ) { 3168 insert_before_buf = pos; 3169 } 3170 } 3171 pos = pos->next; 3172 } 3173 } 3174 } 3175 3176 if ( found_super_buf ) { 3177 if(super_buf->super_buf[buf_s_idx].frame_idx != 0) { 3178 //This can cause frame drop. We are overwriting same memory. 3179 pthread_mutex_unlock(&queue->que.lock); 3180 LOGW("Warning: frame is already in camera ZSL queue"); 3181 mm_channel_qbuf(ch_obj, buf_info->buf); 3182 return 0; 3183 } 3184 3185 /*Insert incoming buffer to super buffer*/ 3186 super_buf->super_buf[buf_s_idx] = *buf_info; 3187 3188 /* check if superbuf is all matched */ 3189 super_buf->matched = 1; 3190 for (i=0; i < super_buf->num_of_bufs; i++) { 3191 if (super_buf->super_buf[i].frame_idx == 0) { 3192 super_buf->matched = 0; 3193 break; 3194 } 3195 } 3196 3197 if (super_buf->matched) { 3198 if(ch_obj->isFlashBracketingEnabled) { 3199 queue->expected_frame_id = 3200 queue->expected_frame_id_without_led; 3201 if (buf_info->frame_idx >= 3202 queue->expected_frame_id_without_led) { 3203 ch_obj->isFlashBracketingEnabled = FALSE; 3204 } 3205 } else { 3206 queue->expected_frame_id = buf_info->frame_idx 3207 + queue->attr.post_frame_skip; 3208 } 3209 3210 super_buf->expected_frame = FALSE; 3211 3212 LOGD("curr = %d, skip = %d , Expected Frame ID: %d", 3213 buf_info->frame_idx, 3214 queue->attr.post_frame_skip, queue->expected_frame_id); 3215 3216 queue->match_cnt++; 3217 if (ch_obj->bundle.superbuf_queue.attr.enable_frame_sync) { 3218 pthread_mutex_lock(&fs_lock); 3219 mm_frame_sync_add(buf_info->frame_idx, ch_obj); 3220 pthread_mutex_unlock(&fs_lock); 3221 } 3222 /* Any older unmatched buffer need to be released */ 3223 if ( last_buf ) { 3224 while ( last_buf != pos ) { 3225 node = member_of(last_buf, cam_node_t, list); 3226 super_buf = (mm_channel_queue_node_t*)node->data; 3227 if (NULL != super_buf) { 3228 for (i=0; i<super_buf->num_of_bufs; i++) { 3229 if (super_buf->super_buf[i].frame_idx != 0) { 3230 mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf); 3231 } 3232 } 3233 queue->que.size--; 3234 last_buf = last_buf->next; 3235 cam_list_del_node(&node->list); 3236 free(node); 3237 free(super_buf); 3238 } else { 3239 LOGE("Invalid superbuf in queue!"); 3240 break; 3241 } 3242 } 3243 } 3244 }else { 3245 if (ch_obj->diverted_frame_id == buf_info->frame_idx) { 3246 super_buf->expected_frame = TRUE; 3247 ch_obj->diverted_frame_id = 0; 3248 } 3249 } 3250 } else { 3251 if ((queue->attr.max_unmatched_frames < unmatched_bundles) 3252 && ( NULL == last_buf )) { 3253 /* incoming frame is older than the last bundled one */ 3254 mm_channel_qbuf(ch_obj, buf_info->buf); 3255 } else { 3256 last_buf_ptr = last_buf; 3257 3258 /* Loop to remove unmatched frames */ 3259 while ((queue->attr.max_unmatched_frames < unmatched_bundles) 3260 && (last_buf_ptr != NULL && last_buf_ptr != pos)) { 3261 node = member_of(last_buf_ptr, cam_node_t, list); 3262 super_buf = (mm_channel_queue_node_t*)node->data; 3263 if (NULL != super_buf && super_buf->expected_frame == FALSE 3264 && (&node->list != insert_before_buf)) { 3265 for (i=0; i<super_buf->num_of_bufs; i++) { 3266 if (super_buf->super_buf[i].frame_idx != 0) { 3267 mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf); 3268 } 3269 } 3270 queue->que.size--; 3271 cam_list_del_node(&node->list); 3272 free(node); 3273 free(super_buf); 3274 unmatched_bundles--; 3275 } 3276 last_buf_ptr = last_buf_ptr->next; 3277 } 3278 3279 if (queue->attr.max_unmatched_frames < unmatched_bundles) { 3280 node = member_of(last_buf, cam_node_t, list); 3281 super_buf = (mm_channel_queue_node_t*)node->data; 3282 for (i=0; i<super_buf->num_of_bufs; i++) { 3283 if (super_buf->super_buf[i].frame_idx != 0) { 3284 mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf); 3285 } 3286 } 3287 queue->que.size--; 3288 cam_list_del_node(&node->list); 3289 free(node); 3290 free(super_buf); 3291 } 3292 3293 /* insert the new frame at the appropriate position. */ 3294 3295 mm_channel_queue_node_t *new_buf = NULL; 3296 cam_node_t* new_node = NULL; 3297 3298 new_buf = (mm_channel_queue_node_t*)malloc(sizeof(mm_channel_queue_node_t)); 3299 new_node = (cam_node_t*)malloc(sizeof(cam_node_t)); 3300 if (NULL != new_buf && NULL != new_node) { 3301 memset(new_buf, 0, sizeof(mm_channel_queue_node_t)); 3302 memset(new_node, 0, sizeof(cam_node_t)); 3303 new_node->data = (void *)new_buf; 3304 new_buf->num_of_bufs = queue->num_streams; 3305 new_buf->super_buf[buf_s_idx] = *buf_info; 3306 new_buf->frame_idx = buf_info->frame_idx; 3307 3308 if ((ch_obj->diverted_frame_id == buf_info->frame_idx) 3309 || (buf_info->frame_idx == queue->good_frame_id)) { 3310 new_buf->expected_frame = TRUE; 3311 ch_obj->diverted_frame_id = 0; 3312 } 3313 3314 /* enqueue */ 3315 if ( insert_before_buf ) { 3316 cam_list_insert_before_node(&new_node->list, insert_before_buf); 3317 } else { 3318 cam_list_add_tail_node(&new_node->list, &queue->que.head.list); 3319 } 3320 queue->que.size++; 3321 3322 if(queue->num_streams == 1) { 3323 new_buf->matched = 1; 3324 new_buf->expected_frame = FALSE; 3325 queue->expected_frame_id = buf_info->frame_idx + queue->attr.post_frame_skip; 3326 queue->match_cnt++; 3327 if (ch_obj->bundle.superbuf_queue.attr.enable_frame_sync) { 3328 pthread_mutex_lock(&fs_lock); 3329 mm_frame_sync_add(buf_info->frame_idx, ch_obj); 3330 pthread_mutex_unlock(&fs_lock); 3331 } 3332 } 3333 /* In low priority queue, this will become a 'meta only' superbuf. Set the 3334 unmatched_frame_idx so that the upcoming stream buffers (other than meta) 3335 can be filled into this which are nearest to this idx. */ 3336 if ((queue->attr.priority == MM_CAMERA_SUPER_BUF_PRIORITY_LOW) 3337 && (buf_info->buf->stream_type == CAM_STREAM_TYPE_METADATA)) { 3338 new_buf->unmatched_meta_idx = buf_info->frame_idx; 3339 } 3340 } else { 3341 /* No memory */ 3342 if (NULL != new_buf) { 3343 free(new_buf); 3344 } 3345 if (NULL != new_node) { 3346 free(new_node); 3347 } 3348 /* qbuf the new buf since we cannot enqueue */ 3349 mm_channel_qbuf(ch_obj, buf_info->buf); 3350 } 3351 } 3352 } 3353 3354 pthread_mutex_unlock(&queue->que.lock); 3355 LOGD("X"); 3356 return 0; 3357 } 3358 3359 /*=========================================================================== 3360 * FUNCTION : mm_channel_superbuf_dequeue_internal 3361 * 3362 * DESCRIPTION: internal implementation for dequeue from the superbuf queue 3363 * 3364 * PARAMETERS : 3365 * @queue : superbuf queue 3366 * @matched_only : if dequeued buf should be matched 3367 * @ch_obj : channel object 3368 * 3369 * RETURN : ptr to a node from superbuf queue 3370 *==========================================================================*/ 3371 mm_channel_queue_node_t* mm_channel_superbuf_dequeue_internal( 3372 mm_channel_queue_t * queue, 3373 uint8_t matched_only, mm_channel_t *ch_obj) 3374 { 3375 cam_node_t* node = NULL; 3376 struct cam_list *head = NULL; 3377 struct cam_list *pos = NULL; 3378 mm_channel_queue_node_t* super_buf = NULL; 3379 3380 head = &queue->que.head.list; 3381 pos = head->next; 3382 if (pos != head) { 3383 /* get the first node */ 3384 node = member_of(pos, cam_node_t, list); 3385 super_buf = (mm_channel_queue_node_t*)node->data; 3386 if ( (NULL != super_buf) && 3387 (matched_only == TRUE) && 3388 (super_buf->matched == FALSE) ) { 3389 /* require to dequeue matched frame only, but this superbuf is not matched, 3390 simply set return ptr to NULL */ 3391 super_buf = NULL; 3392 } 3393 if (NULL != super_buf) { 3394 /* remove from the queue */ 3395 cam_list_del_node(&node->list); 3396 queue->que.size--; 3397 if (super_buf->matched == TRUE) { 3398 queue->match_cnt--; 3399 if (ch_obj->bundle.superbuf_queue.attr.enable_frame_sync) { 3400 pthread_mutex_lock(&fs_lock); 3401 mm_frame_sync_remove(super_buf->frame_idx); 3402 pthread_mutex_unlock(&fs_lock); 3403 } 3404 } 3405 free(node); 3406 } 3407 } 3408 3409 return super_buf; 3410 } 3411 3412 /*=========================================================================== 3413 * FUNCTION : mm_channel_superbuf_dequeue_frame_internal 3414 * 3415 * DESCRIPTION: internal implementation for dequeue based on frame index 3416 * from the superbuf queue 3417 * 3418 * PARAMETERS : 3419 * @queue : superbuf queue 3420 * @frame_idx : frame index to be dequeued 3421 * 3422 * RETURN : ptr to a node from superbuf queue with matched frame index 3423 * : NULL if not found 3424 *==========================================================================*/ 3425 mm_channel_queue_node_t* mm_channel_superbuf_dequeue_frame_internal( 3426 mm_channel_queue_t *queue, uint32_t frame_idx) 3427 { 3428 cam_node_t* node = NULL; 3429 struct cam_list *head = NULL; 3430 struct cam_list *pos = NULL; 3431 mm_channel_queue_node_t* super_buf = NULL; 3432 3433 if (!queue) { 3434 LOGE("queue is NULL"); 3435 return NULL; 3436 } 3437 3438 head = &queue->que.head.list; 3439 pos = head->next; 3440 LOGL("Searching for match frame %d", frame_idx); 3441 while ((pos != head) && (pos != NULL)) { 3442 /* get the first node */ 3443 node = member_of(pos, cam_node_t, list); 3444 super_buf = (mm_channel_queue_node_t*)node->data; 3445 if (super_buf && super_buf->matched && 3446 (frame_idx <= super_buf->frame_idx)) { 3447 /* remove from the queue */ 3448 cam_list_del_node(&node->list); 3449 queue->que.size--; 3450 queue->match_cnt--; 3451 LOGH("Found best match frame %d requested = %d", 3452 super_buf->frame_idx, frame_idx); 3453 free(node); 3454 break; 3455 } else { 3456 super_buf = NULL; 3457 } 3458 pos = pos->next; 3459 } 3460 return super_buf; 3461 } 3462 3463 3464 /*=========================================================================== 3465 * FUNCTION : mm_channel_superbuf_dequeue 3466 * 3467 * DESCRIPTION: dequeue from the superbuf queue 3468 * 3469 * PARAMETERS : 3470 * @queue : superbuf queue 3471 * @ch_obj : channel object 3472 * 3473 * RETURN : ptr to a node from superbuf queue 3474 *==========================================================================*/ 3475 mm_channel_queue_node_t* mm_channel_superbuf_dequeue( 3476 mm_channel_queue_t * queue, mm_channel_t *ch_obj) 3477 { 3478 mm_channel_queue_node_t* super_buf = NULL; 3479 3480 pthread_mutex_lock(&queue->que.lock); 3481 super_buf = mm_channel_superbuf_dequeue_internal(queue, TRUE, ch_obj); 3482 pthread_mutex_unlock(&queue->que.lock); 3483 3484 return super_buf; 3485 } 3486 3487 /*=========================================================================== 3488 * FUNCTION : mm_channel_superbuf_bufdone_overflow 3489 * 3490 * DESCRIPTION: keep superbuf queue no larger than watermark set by upper layer 3491 * via channel attribute 3492 * 3493 * PARAMETERS : 3494 * @my_obj : channel object 3495 * @queue : superbuf queue 3496 * 3497 * RETURN : int32_t type of status 3498 * 0 -- success 3499 * -1 -- failure 3500 *==========================================================================*/ 3501 int32_t mm_channel_superbuf_bufdone_overflow(mm_channel_t* my_obj, 3502 mm_channel_queue_t * queue) 3503 { 3504 int32_t rc = 0, i; 3505 mm_channel_queue_node_t* super_buf = NULL; 3506 if (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == queue->attr.notify_mode) { 3507 /* for continuous streaming mode, no overflow is needed */ 3508 return 0; 3509 } 3510 3511 LOGD("before match_cnt=%d, water_mark=%d", 3512 queue->match_cnt, queue->attr.water_mark); 3513 /* bufdone overflowed bufs */ 3514 pthread_mutex_lock(&queue->que.lock); 3515 while (queue->match_cnt > queue->attr.water_mark) { 3516 super_buf = mm_channel_superbuf_dequeue_internal(queue, TRUE, my_obj); 3517 if (NULL != super_buf) { 3518 for (i=0; i<super_buf->num_of_bufs; i++) { 3519 if (NULL != super_buf->super_buf[i].buf) { 3520 mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf); 3521 } 3522 } 3523 free(super_buf); 3524 } 3525 } 3526 pthread_mutex_unlock(&queue->que.lock); 3527 LOGD("after match_cnt=%d, water_mark=%d", 3528 queue->match_cnt, queue->attr.water_mark); 3529 3530 return rc; 3531 } 3532 3533 /*=========================================================================== 3534 * FUNCTION : mm_channel_superbuf_skip 3535 * 3536 * DESCRIPTION: depends on the lookback configuration of the channel attribute, 3537 * unwanted superbufs will be removed from the superbuf queue. 3538 * 3539 * PARAMETERS : 3540 * @my_obj : channel object 3541 * @queue : superbuf queue 3542 * 3543 * RETURN : int32_t type of status 3544 * 0 -- success 3545 * -1 -- failure 3546 *==========================================================================*/ 3547 int32_t mm_channel_superbuf_skip(mm_channel_t* my_obj, 3548 mm_channel_queue_t * queue) 3549 { 3550 int32_t rc = 0, i; 3551 mm_channel_queue_node_t* super_buf = NULL; 3552 if (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == queue->attr.notify_mode) { 3553 /* for continuous streaming mode, no skip is needed */ 3554 return 0; 3555 } 3556 3557 /* bufdone overflowed bufs */ 3558 pthread_mutex_lock(&queue->que.lock); 3559 while (queue->match_cnt > queue->attr.look_back) { 3560 super_buf = mm_channel_superbuf_dequeue_internal(queue, TRUE, my_obj); 3561 if (NULL != super_buf) { 3562 for (i=0; i<super_buf->num_of_bufs; i++) { 3563 if (NULL != super_buf->super_buf[i].buf) { 3564 mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf); 3565 } 3566 } 3567 free(super_buf); 3568 } 3569 } 3570 pthread_mutex_unlock(&queue->que.lock); 3571 3572 return rc; 3573 } 3574 3575 /*=========================================================================== 3576 * FUNCTION : mm_channel_send_frame_sync_flush 3577 * 3578 * DESCRIPTION: flush the superbuf frame sync queue. 3579 * 3580 * PARAMETERS : 3581 * @my_obj : channel object 3582 * 3583 * RETURN : int32_t type of status 3584 * 0 -- success 3585 * -1 -- failure 3586 *==========================================================================*/ 3587 int32_t mm_channel_send_frame_sync_flush(mm_channel_t* my_obj) 3588 { 3589 int32_t rc = 0; 3590 mm_channel_t *m_obj = my_obj; 3591 3592 if (m_obj->master_ch_obj != NULL) { 3593 m_obj = m_obj->master_ch_obj; 3594 } 3595 3596 if (m_obj->frame_sync.is_active) { 3597 mm_camera_cmdcb_t* cb_node = NULL; 3598 3599 /* send cam_sem_post to wake up cb thread to flush sync queue */ 3600 cb_node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 3601 if (NULL != cb_node) { 3602 memset(cb_node, 0, sizeof(mm_camera_cmdcb_t)); 3603 cb_node->cmd_type = MM_CAMERA_CMD_TYPE_FLUSH_QUEUE; 3604 /* enqueue to cb thread */ 3605 cam_queue_enq(&(m_obj->cb_thread.cmd_queue), cb_node); 3606 /* wake up cb thread */ 3607 cam_sem_post(&(m_obj->cb_thread.cmd_sem)); 3608 } else { 3609 LOGE("No memory for mm_camera_node_t"); 3610 rc = -1; 3611 } 3612 } 3613 return rc; 3614 } 3615 3616 /*=========================================================================== 3617 * FUNCTION : mm_channel_superbuf_flush 3618 * 3619 * DESCRIPTION: flush the superbuf queue. 3620 * 3621 * PARAMETERS : 3622 * @my_obj : channel object 3623 * @queue : superbuf queue 3624 * @cam_type: flush only particular type (default flushes all) 3625 * 3626 * RETURN : int32_t type of status 3627 * 0 -- success 3628 * -1 -- failure 3629 *==========================================================================*/ 3630 int32_t mm_channel_superbuf_flush(mm_channel_t* my_obj, 3631 mm_channel_queue_t * queue, cam_stream_type_t cam_type) 3632 { 3633 int32_t rc = 0, i; 3634 mm_channel_queue_node_t* super_buf = NULL; 3635 cam_stream_type_t stream_type = CAM_STREAM_TYPE_DEFAULT; 3636 3637 /* bufdone bufs */ 3638 pthread_mutex_lock(&queue->que.lock); 3639 super_buf = mm_channel_superbuf_dequeue_internal(queue, FALSE, my_obj); 3640 while (super_buf != NULL) { 3641 for (i=0; i<super_buf->num_of_bufs; i++) { 3642 if (NULL != super_buf->super_buf[i].buf) { 3643 stream_type = super_buf->super_buf[i].buf->stream_type; 3644 if ((CAM_STREAM_TYPE_DEFAULT == cam_type) || 3645 (cam_type == stream_type)) { 3646 mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf); 3647 } 3648 } 3649 } 3650 free(super_buf); 3651 super_buf = mm_channel_superbuf_dequeue_internal(queue, FALSE, my_obj); 3652 } 3653 pthread_mutex_unlock(&queue->que.lock); 3654 3655 /*Flush Super buffer frame sync queue*/ 3656 mm_channel_send_frame_sync_flush(my_obj); 3657 3658 return rc; 3659 } 3660 3661 /*=========================================================================== 3662 * FUNCTION : mm_channel_proc_general_cmd 3663 * 3664 * DESCRIPTION: process general command 3665 * 3666 * PARAMETERS : 3667 * @my_obj : channel object 3668 * @notify_mode : notification mode 3669 * 3670 * RETURN : int32_t type of status 3671 * 0 -- success 3672 * -1 -- failure 3673 *==========================================================================*/ 3674 int32_t mm_channel_proc_general_cmd(mm_channel_t *my_obj, 3675 mm_camera_generic_cmd_t *p_gen_cmd) 3676 { 3677 LOGD("E"); 3678 int32_t rc = 0; 3679 mm_camera_cmdcb_t* node = NULL; 3680 3681 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 3682 if (NULL != node) { 3683 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 3684 node->u.gen_cmd = *p_gen_cmd; 3685 node->cmd_type = MM_CAMERA_CMD_TYPE_GENERAL; 3686 3687 /* enqueue to cmd thread */ 3688 cam_queue_enq(&(my_obj->cmd_thread.cmd_queue), node); 3689 3690 /* wake up cmd thread */ 3691 cam_sem_post(&(my_obj->cmd_thread.cmd_sem)); 3692 } else { 3693 LOGE("No memory for mm_camera_node_t"); 3694 rc = -1; 3695 } 3696 LOGD("X"); 3697 3698 return rc; 3699 } 3700 3701 /*=========================================================================== 3702 * FUNCTION : mm_channel_superbuf_flush_matched 3703 * 3704 * DESCRIPTION: flush matched buffers from the superbuf queue. 3705 * 3706 * PARAMETERS : 3707 * @my_obj : channel object 3708 * @queue : superbuf queue 3709 * 3710 * RETURN : int32_t type of status 3711 * 0 -- success 3712 * -1 -- failure 3713 *==========================================================================*/ 3714 int32_t mm_channel_superbuf_flush_matched(mm_channel_t* my_obj, 3715 mm_channel_queue_t * queue) 3716 { 3717 int32_t rc = 0, i; 3718 mm_channel_queue_node_t* super_buf = NULL; 3719 3720 /* bufdone bufs */ 3721 pthread_mutex_lock(&queue->que.lock); 3722 super_buf = mm_channel_superbuf_dequeue_internal(queue, TRUE, my_obj); 3723 while (super_buf != NULL) { 3724 for (i=0; i<super_buf->num_of_bufs; i++) { 3725 if (NULL != super_buf->super_buf[i].buf) { 3726 mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf); 3727 } 3728 } 3729 free(super_buf); 3730 super_buf = mm_channel_superbuf_dequeue_internal(queue, TRUE, my_obj); 3731 } 3732 pthread_mutex_unlock(&queue->que.lock); 3733 3734 return rc; 3735 } 3736 3737 3738 /*=========================================================================== 3739 * FUNCTION : mm_frame_sync_reset 3740 * 3741 * DESCRIPTION: Reset Frame sync info 3742 * 3743 * RETURN : None 3744 *==========================================================================*/ 3745 void mm_frame_sync_reset() { 3746 memset(&fs, 0x0, sizeof(fs)); 3747 LOGD("Reset Done"); 3748 } 3749 3750 /*=========================================================================== 3751 * FUNCTION : mm_frame_sync_register_channel 3752 * 3753 * DESCRIPTION: Register Channel for frame sync 3754 * 3755 * PARAMETERS : 3756 * @ch_obj : channel object 3757 * 3758 * RETURN : int32_t type of status 3759 * 0 -- success 3760 * -1 -- failure 3761 *==========================================================================*/ 3762 int32_t mm_frame_sync_register_channel(mm_channel_t *ch_obj) { 3763 // Lock frame sync info 3764 pthread_mutex_lock(&fs_lock); 3765 if ((fs.num_cam >= MAX_NUM_CAMERA_PER_BUNDLE) || (!ch_obj)) { 3766 LOGE("Error!! num cam(%d) is out of range ", 3767 fs.num_cam); 3768 pthread_mutex_unlock(&fs_lock); 3769 return -1; 3770 } 3771 if (fs.num_cam == 0) { 3772 LOGH("First channel registering!!"); 3773 mm_frame_sync_reset(); 3774 } 3775 uint8_t i = 0; 3776 for (i = 0; i < MAX_NUM_CAMERA_PER_BUNDLE; i++) { 3777 if (fs.ch_obj[i] == NULL) { 3778 fs.ch_obj[i] = ch_obj; 3779 fs.cb[i] = ch_obj->bundle.super_buf_notify_cb; 3780 fs.num_cam++; 3781 LOGD("DBG_FS index %d", i); 3782 break; 3783 } 3784 } 3785 if (i >= MAX_NUM_CAMERA_PER_BUNDLE) { 3786 LOGH("X, DBG_FS Cannot register channel!!"); 3787 pthread_mutex_unlock(&fs_lock); 3788 return -1; 3789 } 3790 LOGH("num_cam %d ", fs.num_cam); 3791 pthread_mutex_unlock(&fs_lock); 3792 return 0; 3793 } 3794 3795 /*=========================================================================== 3796 * FUNCTION : mm_frame_sync_unregister_channel 3797 * 3798 * DESCRIPTION: un-register Channel for frame sync 3799 * 3800 * PARAMETERS : 3801 * @ch_obj : channel object 3802 * 3803 * RETURN : int32_t type of status 3804 * 0 -- success 3805 * -1 -- failure 3806 *==========================================================================*/ 3807 int32_t mm_frame_sync_unregister_channel(mm_channel_t *ch_obj) { 3808 uint8_t i = 0; 3809 // Lock frame sync info 3810 pthread_mutex_lock(&fs_lock); 3811 if (!fs.num_cam || !ch_obj) { 3812 LOGH("X, DBG_FS: channel not found !!"); 3813 // Lock frame sync info 3814 pthread_mutex_unlock(&fs_lock); 3815 return -1; 3816 } 3817 for (i = 0; i < MAX_NUM_CAMERA_PER_BUNDLE; i++) { 3818 if (fs.ch_obj[i] == ch_obj) { 3819 LOGD("found ch_obj at i (%d) ", i); 3820 break; 3821 } 3822 } 3823 if (i < MAX_NUM_CAMERA_PER_BUNDLE) { 3824 LOGD("remove channel info "); 3825 fs.ch_obj[i] = NULL; 3826 fs.cb[i] = NULL; 3827 fs.num_cam--; 3828 } else { 3829 LOGD("DBG_FS Channel not found "); 3830 } 3831 if (fs.num_cam == 0) { 3832 mm_frame_sync_reset(); 3833 } 3834 LOGH("X, fs.num_cam %d", fs.num_cam); 3835 pthread_mutex_unlock(&fs_lock); 3836 return 0; 3837 } 3838 3839 3840 /*=========================================================================== 3841 * FUNCTION : mm_frame_sync_add 3842 * 3843 * DESCRIPTION: Add frame info into frame sync nodes 3844 * 3845 * PARAMETERS : 3846 * @frame_id : frame id to be added 3847 * @ch_obj : channel object 3848 * 3849 * RETURN : int32_t type of status 3850 * 0 -- success 3851 * -1 -- failure 3852 *==========================================================================*/ 3853 int32_t mm_frame_sync_add(uint32_t frame_id, mm_channel_t *ch_obj) { 3854 3855 LOGD("E, frame id %d ch_obj %p", frame_id, ch_obj); 3856 if (!frame_id || !ch_obj) { 3857 LOGH("X : Error, cannot add sync frame !!"); 3858 return -1; 3859 } 3860 3861 int8_t ch_idx = -1; 3862 uint8_t i = 0; 3863 for (i = 0; i < MAX_NUM_CAMERA_PER_BUNDLE; i++) { 3864 if (fs.ch_obj[i] == ch_obj) { 3865 ch_idx = i; 3866 LOGD("ch id %d ", ch_idx); 3867 break; 3868 } 3869 } 3870 if (ch_idx < 0) { 3871 LOGH("X : DBG_FS ch not found!!"); 3872 return -1; 3873 } 3874 int8_t index = mm_frame_sync_find_frame_index(frame_id); 3875 if ((index >= 0) && (index < MM_CAMERA_FRAME_SYNC_NODES)) { 3876 fs.node[index].frame_valid[ch_idx] = 1; 3877 } else if (index < 0) { 3878 if (fs.pos >= MM_CAMERA_FRAME_SYNC_NODES) { 3879 fs.pos = 0; 3880 } 3881 index = fs.pos; 3882 memset(&fs.node[index], 0x00, sizeof(mm_channel_sync_node_t)); 3883 fs.pos++; 3884 fs.node[index].frame_idx = frame_id; 3885 fs.node[index].frame_valid[ch_idx] = 1; 3886 if (fs.num_cam == 1) { 3887 LOGD("Single camera frame %d , matched ", frame_id); 3888 fs.node[index].matched = 1; 3889 } 3890 } 3891 uint8_t frames_valid = 0; 3892 if (!fs.node[index].matched) { 3893 for (i = 0; i < MAX_NUM_CAMERA_PER_BUNDLE; i++) { 3894 if (fs.node[index].frame_valid[i]) { 3895 frames_valid++; 3896 } 3897 } 3898 if (frames_valid == fs.num_cam) { 3899 fs.node[index].matched = 1; 3900 LOGD("dual camera frame %d , matched ", 3901 frame_id); 3902 } 3903 } 3904 return 0; 3905 } 3906 3907 /*=========================================================================== 3908 * FUNCTION : mm_frame_sync_remove 3909 * 3910 * DESCRIPTION: Remove frame info from frame sync nodes 3911 * 3912 * PARAMETERS : 3913 * @frame_id : frame id to be removed 3914 * 3915 * RETURN : int32_t type of status 3916 * 0 -- success 3917 * -1 -- failure 3918 *==========================================================================*/ 3919 int32_t mm_frame_sync_remove(uint32_t frame_id) { 3920 int8_t index = -1; 3921 3922 LOGD("E, frame_id %d", frame_id); 3923 if (!frame_id) { 3924 LOGE("X, DBG_FS frame id invalid"); 3925 return -1; 3926 } 3927 3928 index = mm_frame_sync_find_frame_index(frame_id); 3929 if ((index >= 0) && (index < MM_CAMERA_FRAME_SYNC_NODES)) { 3930 LOGD("Removing sync frame %d", frame_id); 3931 memset(&fs.node[index], 0x00, sizeof(mm_channel_sync_node_t)); 3932 } 3933 LOGD("X "); 3934 return 0; 3935 } 3936 3937 /*=========================================================================== 3938 * FUNCTION : mm_frame_sync_find_matched 3939 * 3940 * DESCRIPTION: Find a matched sync frame from the node array 3941 * 3942 * PARAMETERS : 3943 * @oldest : If enabled, find oldest matched frame., 3944 * If not enabled, get the first matched frame found 3945 * 3946 * RETURN : unt32_t type of status 3947 * 0 -- If no matched frames found 3948 * frame index: inf matched frame found 3949 *==========================================================================*/ 3950 uint32_t mm_frame_sync_find_matched(uint8_t oldest) { 3951 LOGH("E, oldest %d ", oldest); 3952 uint8_t i = 0; 3953 uint32_t frame_idx = 0; 3954 uint32_t curr_frame_idx = 0; 3955 for (i = 0; i < MM_CAMERA_FRAME_SYNC_NODES; i++) { 3956 if (fs.node[i].matched) { 3957 curr_frame_idx = fs.node[i].frame_idx; 3958 if (!frame_idx) { 3959 frame_idx = curr_frame_idx; 3960 } 3961 if (!oldest) { 3962 break; 3963 } else if (frame_idx > curr_frame_idx) { 3964 frame_idx = curr_frame_idx; 3965 } 3966 } 3967 } 3968 LOGH("X, oldest %d frame idx %d", oldest, frame_idx); 3969 return frame_idx; 3970 } 3971 3972 /*=========================================================================== 3973 * FUNCTION : mm_frame_sync_find_frame_index 3974 * 3975 * DESCRIPTION: Find sync frame index if present 3976 * 3977 * PARAMETERS : 3978 * @frame_id : frame id to be searched 3979 * 3980 * RETURN : int8_t type of status 3981 * -1 -- If desired frame not found 3982 * index: node array index if frame is found 3983 *==========================================================================*/ 3984 int8_t mm_frame_sync_find_frame_index(uint32_t frame_id) { 3985 3986 LOGD("E, frame_id %d", frame_id); 3987 int8_t index = -1, i = 0; 3988 for (i = 0; i < MM_CAMERA_FRAME_SYNC_NODES; i++) { 3989 if (fs.node[i].frame_idx == frame_id) { 3990 index = i; 3991 break; 3992 } 3993 } 3994 LOGD("X index :%d", index); 3995 return index; 3996 } 3997 3998 /*=========================================================================== 3999 * FUNCTION : mm_frame_sync_lock_queues 4000 * 4001 * DESCRIPTION: Lock all channel queues present in node info 4002 * 4003 * RETURN : None 4004 *==========================================================================*/ 4005 void mm_frame_sync_lock_queues() { 4006 uint8_t j = 0; 4007 LOGD("E "); 4008 for (j = 0; j < MAX_NUM_CAMERA_PER_BUNDLE; j++) { 4009 if (fs.ch_obj[j]) { 4010 mm_channel_queue_t *ch_queue = 4011 &fs.ch_obj[j]->bundle.superbuf_queue; 4012 if (ch_queue) { 4013 pthread_mutex_lock(&ch_queue->que.lock); 4014 LOGL("Done locking fs.ch_obj[%d] ", j); 4015 } 4016 } 4017 } 4018 pthread_mutex_lock(&fs_lock); 4019 LOGD("X "); 4020 } 4021 4022 /*=========================================================================== 4023 * FUNCTION : mm_frame_sync_unlock_queues 4024 * 4025 * DESCRIPTION: Unlock all channel queues 4026 * 4027 * RETURN : None 4028 *==========================================================================*/ 4029 void mm_frame_sync_unlock_queues() { 4030 // Unlock all queues 4031 uint8_t j = 0; 4032 LOGD("E "); 4033 pthread_mutex_unlock(&fs_lock); 4034 LOGL("Done unlocking fs "); 4035 for (j = 0; j < MAX_NUM_CAMERA_PER_BUNDLE; j++) { 4036 if (fs.ch_obj[j]) { 4037 mm_channel_queue_t *ch_queue = 4038 &fs.ch_obj[j]->bundle.superbuf_queue; 4039 if (ch_queue) { 4040 pthread_mutex_unlock(&ch_queue->que.lock); 4041 LOGL("Done unlocking fs.ch_obj[%d] ", j); 4042 } 4043 } 4044 } 4045 LOGD("X "); 4046 } 4047 4048 /*=========================================================================== 4049 * FUNCTION : mm_channel_node_qbuf 4050 * 4051 * DESCRIPTION: qbuf all buffers in a node 4052 * 4053 * PARAMETERS : 4054 * @ch_obj : Channel info 4055 * @node : node to qbuf 4056 * 4057 * RETURN : None 4058 *==========================================================================*/ 4059 void mm_channel_node_qbuf(mm_channel_t *ch_obj, mm_channel_queue_node_t *node) { 4060 uint8_t i; 4061 if (!ch_obj || !node) { 4062 return; 4063 } 4064 for (i = 0; i < node->num_of_bufs; i++) { 4065 mm_channel_qbuf(ch_obj, node->super_buf[i].buf); 4066 } 4067 return; 4068 } 4069