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 // To remove 31 #include <cutils/properties.h> 32 33 // System dependencies 34 #include <pthread.h> 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <stdlib.h> 38 #include <sys/stat.h> 39 #include <dlfcn.h> 40 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h> 41 #include IOCTL_H 42 43 // Camera dependencies 44 #include "cam_semaphore.h" 45 #include "mm_camera_dbg.h" 46 #include "mm_camera_sock.h" 47 #include "mm_camera_interface.h" 48 #include "mm_camera.h" 49 #include "mm_camera_muxer.h" 50 51 #define SET_PARM_BIT32(parm, parm_arr) \ 52 (parm_arr[parm/32] |= (1<<(parm%32))) 53 54 #define GET_PARM_BIT32(parm, parm_arr) \ 55 ((parm_arr[parm/32]>>(parm%32))& 0x1) 56 57 /* internal function declare */ 58 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj, 59 uint8_t reg_flag); 60 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj, 61 mm_camera_event_t *event); 62 extern mm_camera_obj_t* mm_camera_util_get_camera_by_session_id 63 (uint32_t session_id); 64 65 /*=========================================================================== 66 * FUNCTION : mm_camera_util_get_channel_by_handler 67 * 68 * DESCRIPTION: utility function to get a channel object from its handle 69 * 70 * PARAMETERS : 71 * @cam_obj: ptr to a camera object 72 * @handler: channel handle 73 * 74 * RETURN : ptr to a channel object. 75 * NULL if failed. 76 *==========================================================================*/ 77 mm_channel_t * mm_camera_util_get_channel_by_handler( 78 mm_camera_obj_t * cam_obj, 79 uint32_t handler) 80 { 81 int i; 82 mm_channel_t *ch_obj = NULL; 83 for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) { 84 if (handler == cam_obj->ch[i].my_hdl) { 85 ch_obj = &cam_obj->ch[i]; 86 break; 87 } 88 } 89 return ch_obj; 90 } 91 92 /*=========================================================================== 93 * FUNCTION : mm_camera_util_chip_is_a_family 94 * 95 * DESCRIPTION: utility function to check if the host is A family chip 96 * 97 * PARAMETERS : 98 * 99 * RETURN : TRUE if A family. 100 * FALSE otherwise. 101 *==========================================================================*/ 102 uint8_t mm_camera_util_chip_is_a_family(void) 103 { 104 #ifdef USE_A_FAMILY 105 return TRUE; 106 #else 107 return FALSE; 108 #endif 109 } 110 111 /*=========================================================================== 112 * FUNCTION : mm_camera_dispatch_app_event 113 * 114 * DESCRIPTION: dispatch event to apps who regitster for event notify 115 * 116 * PARAMETERS : 117 * @cmd_cb: ptr to a struct storing event info 118 * @user_data: user data ptr (camera object) 119 * 120 * RETURN : none 121 *==========================================================================*/ 122 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb, 123 void* user_data) 124 { 125 int i; 126 mm_camera_event_t *event = &cmd_cb->u.evt; 127 mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data; 128 if (NULL != my_obj) { 129 mm_camera_cmd_thread_name(my_obj->evt_thread.threadName); 130 pthread_mutex_lock(&my_obj->cb_lock); 131 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 132 if(my_obj->evt.evt[i].evt_cb) { 133 my_obj->evt.evt[i].evt_cb( 134 my_obj->my_hdl, 135 event, 136 my_obj->evt.evt[i].user_data); 137 } 138 } 139 pthread_mutex_unlock(&my_obj->cb_lock); 140 } 141 } 142 143 /*=========================================================================== 144 * FUNCTION : mm_camera_event_notify 145 * 146 * DESCRIPTION: callback to handle event notify from kernel. This call will 147 * dequeue event from kernel. 148 * 149 * PARAMETERS : 150 * @user_data: user data ptr (camera object) 151 * 152 * RETURN : none 153 *==========================================================================*/ 154 static void mm_camera_event_notify(void* user_data) 155 { 156 struct v4l2_event ev; 157 struct msm_v4l2_event_data *msm_evt = NULL; 158 int rc; 159 mm_camera_event_t evt; 160 memset(&evt, 0, sizeof(mm_camera_event_t)); 161 162 mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data; 163 if (NULL != my_obj) { 164 /* read evt */ 165 memset(&ev, 0, sizeof(ev)); 166 rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev); 167 168 if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) { 169 msm_evt = (struct msm_v4l2_event_data *)ev.u.data; 170 switch (msm_evt->command) { 171 case CAM_EVENT_TYPE_DAEMON_PULL_REQ: 172 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ; 173 mm_camera_enqueue_evt(my_obj, &evt); 174 break; 175 case CAM_EVENT_TYPE_MAP_UNMAP_DONE: 176 pthread_mutex_lock(&my_obj->evt_lock); 177 my_obj->evt_rcvd.server_event_type = msm_evt->command; 178 my_obj->evt_rcvd.status = msm_evt->status; 179 pthread_cond_signal(&my_obj->evt_cond); 180 pthread_mutex_unlock(&my_obj->evt_lock); 181 break; 182 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 183 case CAM_EVENT_TYPE_INT_TAKE_RAW: 184 { 185 evt.server_event_type = msm_evt->command; 186 mm_camera_enqueue_evt(my_obj, &evt); 187 } 188 break; 189 case MSM_CAMERA_PRIV_SHUTDOWN: 190 { 191 LOGE("Camera Event DAEMON DIED received"); 192 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED; 193 mm_camera_enqueue_evt(my_obj, &evt); 194 } 195 break; 196 case CAM_EVENT_TYPE_CAC_DONE: 197 { 198 evt.server_event_type = CAM_EVENT_TYPE_CAC_DONE; 199 mm_camera_enqueue_evt(my_obj, &evt); 200 } 201 break; 202 default: 203 break; 204 } 205 } 206 } 207 } 208 209 /*=========================================================================== 210 * FUNCTION : mm_camera_enqueue_evt 211 * 212 * DESCRIPTION: enqueue received event into event queue to be processed by 213 * event thread. 214 * 215 * PARAMETERS : 216 * @my_obj : ptr to a camera object 217 * @event : event to be queued 218 * 219 * RETURN : int32_t type of status 220 * 0 -- success 221 * -1 -- failure 222 *==========================================================================*/ 223 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj, 224 mm_camera_event_t *event) 225 { 226 int32_t rc = 0; 227 mm_camera_cmdcb_t *node = NULL; 228 229 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 230 if (NULL != node) { 231 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 232 node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB; 233 node->u.evt = *event; 234 235 /* enqueue to evt cmd thread */ 236 cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node); 237 /* wake up evt cmd thread */ 238 cam_sem_post(&(my_obj->evt_thread.cmd_sem)); 239 } else { 240 LOGE("No memory for mm_camera_node_t"); 241 rc = -1; 242 } 243 244 return rc; 245 } 246 247 /*=========================================================================== 248 * FUNCTION : mm_camera_open 249 * 250 * DESCRIPTION: open a camera 251 * 252 * PARAMETERS : 253 * @my_obj : ptr to a camera object 254 * 255 * RETURN : int32_t type of status 256 * 0 -- success 257 * -1 -- failure 258 *==========================================================================*/ 259 int32_t mm_camera_open(mm_camera_obj_t *my_obj) 260 { 261 char dev_name[MM_CAMERA_DEV_NAME_LEN]; 262 int32_t rc = 0; 263 int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES; 264 uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP; 265 int cam_idx = 0; 266 const char *dev_name_value = NULL; 267 int l_errno = 0; 268 269 LOGD("begin\n"); 270 271 if (NULL == my_obj) { 272 goto on_error; 273 } 274 275 dev_name_value = mm_camera_util_get_dev_name_by_num(my_obj->my_num, 276 my_obj->my_hdl); 277 if (NULL == dev_name_value) { 278 goto on_error; 279 } 280 snprintf(dev_name, sizeof(dev_name), "/dev/%s", 281 dev_name_value); 282 sscanf(dev_name, "/dev/video%d", &cam_idx); 283 LOGD("dev name = %s, cam_idx = %d", dev_name, cam_idx); 284 285 do{ 286 n_try--; 287 errno = 0; 288 my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK); 289 l_errno = errno; 290 LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno); 291 if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) { 292 break; 293 } 294 LOGE("Failed with %s error, retrying after %d milli-seconds", 295 strerror(errno), sleep_msec); 296 usleep(sleep_msec * 1000U); 297 }while (n_try > 0); 298 299 if (my_obj->ctrl_fd < 0) { 300 LOGE("cannot open control fd of '%s' (%s)\n", 301 dev_name, strerror(l_errno)); 302 if (l_errno == EBUSY) 303 rc = -EUSERS; 304 else 305 rc = -1; 306 goto on_error; 307 } else { 308 mm_camera_get_session_id(my_obj, &my_obj->sessionid); 309 LOGH("Camera Opened id = %d sessionid = %d", cam_idx, my_obj->sessionid); 310 } 311 312 #ifdef DAEMON_PRESENT 313 /* open domain socket*/ 314 n_try = MM_CAMERA_DEV_OPEN_TRIES; 315 do { 316 n_try--; 317 my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP); 318 l_errno = errno; 319 LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno); 320 if((my_obj->ds_fd >= 0) || (n_try <= 0 )) { 321 LOGD("opened, break out while loop"); 322 break; 323 } 324 LOGD("failed with I/O error retrying after %d milli-seconds", 325 sleep_msec); 326 usleep(sleep_msec * 1000U); 327 } while (n_try > 0); 328 329 if (my_obj->ds_fd < 0) { 330 LOGE("cannot open domain socket fd of '%s'(%s)\n", 331 dev_name, strerror(l_errno)); 332 rc = -1; 333 goto on_error; 334 } 335 #else /* DAEMON_PRESENT */ 336 cam_status_t cam_status; 337 cam_status = mm_camera_module_open_session(my_obj->sessionid, 338 mm_camera_module_event_handler); 339 if (cam_status < 0) { 340 LOGE("Failed to open session"); 341 if (cam_status == CAM_STATUS_BUSY) { 342 rc = -EUSERS; 343 } else { 344 rc = -1; 345 } 346 goto on_error; 347 } 348 #endif /* DAEMON_PRESENT */ 349 350 pthread_mutex_init(&my_obj->msg_lock, NULL); 351 pthread_mutex_init(&my_obj->cb_lock, NULL); 352 pthread_mutex_init(&my_obj->evt_lock, NULL); 353 pthread_cond_init(&my_obj->evt_cond, NULL); 354 355 LOGD("Launch evt Thread in Cam Open"); 356 snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch"); 357 mm_camera_cmd_thread_launch(&my_obj->evt_thread, 358 mm_camera_dispatch_app_event, 359 (void *)my_obj); 360 361 /* launch event poll thread 362 * we will add evt fd into event poll thread upon user first register for evt */ 363 LOGD("Launch evt Poll Thread in Cam Open"); 364 snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll"); 365 mm_camera_poll_thread_launch(&my_obj->evt_poll_thread, 366 MM_CAMERA_POLL_TYPE_EVT); 367 mm_camera_evt_sub(my_obj, TRUE); 368 369 /* unlock cam_lock, we need release global intf_lock in camera_open(), 370 * in order not block operation of other Camera in dual camera use case.*/ 371 pthread_mutex_unlock(&my_obj->cam_lock); 372 LOGD("end (rc = %d)\n", rc); 373 return rc; 374 375 on_error: 376 377 if (NULL == dev_name_value) { 378 LOGE("Invalid device name\n"); 379 rc = -1; 380 } 381 382 if (NULL == my_obj) { 383 LOGE("Invalid camera object\n"); 384 rc = -1; 385 } else { 386 if (my_obj->ctrl_fd >= 0) { 387 close(my_obj->ctrl_fd); 388 my_obj->ctrl_fd = -1; 389 } 390 #ifdef DAEMON_PRESENT 391 if (my_obj->ds_fd >= 0) { 392 mm_camera_socket_close(my_obj->ds_fd); 393 my_obj->ds_fd = -1; 394 } 395 #endif 396 } 397 398 /* unlock cam_lock, we need release global intf_lock in camera_open(), 399 * in order not block operation of other Camera in dual camera use case.*/ 400 pthread_mutex_unlock(&my_obj->cam_lock); 401 return rc; 402 } 403 404 /*=========================================================================== 405 * FUNCTION : mm_camera_close 406 * 407 * DESCRIPTION: enqueue received event into event queue to be processed by 408 * event thread. 409 * 410 * PARAMETERS : 411 * @my_obj : ptr to a camera object 412 * @event : event to be queued 413 * 414 * RETURN : int32_t type of status 415 * 0 -- success 416 * -1 -- failure 417 *==========================================================================*/ 418 int32_t mm_camera_close(mm_camera_obj_t *my_obj) 419 { 420 LOGD("unsubscribe evt"); 421 422 #ifndef DAEMON_PRESENT 423 mm_camera_module_close_session(my_obj->sessionid); 424 #endif /* DAEMON_PRESENT */ 425 426 mm_camera_evt_sub(my_obj, FALSE); 427 428 LOGD("Close evt Poll Thread in Cam Close"); 429 mm_camera_poll_thread_release(&my_obj->evt_poll_thread); 430 431 LOGD("Close evt cmd Thread in Cam Close"); 432 mm_camera_cmd_thread_release(&my_obj->evt_thread); 433 434 if(my_obj->ctrl_fd >= 0) { 435 close(my_obj->ctrl_fd); 436 my_obj->ctrl_fd = -1; 437 } 438 439 #ifdef DAEMON_PRESENT 440 if(my_obj->ds_fd >= 0) { 441 mm_camera_socket_close(my_obj->ds_fd); 442 my_obj->ds_fd = -1; 443 } 444 #endif 445 446 if (my_obj->master_cam_obj != NULL) { 447 my_obj->master_cam_obj->num_s_cnt--; 448 my_obj->master_cam_obj->aux_cam_obj[my_obj->master_cam_obj->num_s_cnt] = NULL; 449 } 450 pthread_mutex_destroy(&my_obj->msg_lock); 451 pthread_mutex_destroy(&my_obj->cb_lock); 452 pthread_mutex_destroy(&my_obj->evt_lock); 453 pthread_cond_destroy(&my_obj->evt_cond); 454 pthread_mutex_unlock(&my_obj->cam_lock); 455 return 0; 456 } 457 458 /*=========================================================================== 459 * FUNCTION : mm_camera_register_event_notify_internal 460 * 461 * DESCRIPTION: internal implementation for registering callback for event notify. 462 * 463 * PARAMETERS : 464 * @my_obj : ptr to a camera object 465 * @evt_cb : callback to be registered to handle event notify 466 * @user_data: user data ptr 467 * 468 * RETURN : int32_t type of status 469 * 0 -- success 470 * -1 -- failure 471 *==========================================================================*/ 472 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj, 473 mm_camera_event_notify_t evt_cb, 474 void * user_data) 475 { 476 int i; 477 int rc = -1; 478 mm_camera_evt_obj_t *evt_array = NULL; 479 480 pthread_mutex_lock(&my_obj->cb_lock); 481 evt_array = &my_obj->evt; 482 if(evt_cb) { 483 /* this is reg case */ 484 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 485 if(evt_array->evt[i].user_data == NULL) { 486 evt_array->evt[i].evt_cb = evt_cb; 487 evt_array->evt[i].user_data = user_data; 488 evt_array->reg_count++; 489 rc = 0; 490 break; 491 } 492 } 493 } else { 494 /* this is unreg case */ 495 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 496 if(evt_array->evt[i].user_data == user_data) { 497 evt_array->evt[i].evt_cb = NULL; 498 evt_array->evt[i].user_data = NULL; 499 evt_array->reg_count--; 500 rc = 0; 501 break; 502 } 503 } 504 } 505 506 pthread_mutex_unlock(&my_obj->cb_lock); 507 return rc; 508 } 509 510 /*=========================================================================== 511 * FUNCTION : mm_camera_register_event_notify 512 * 513 * DESCRIPTION: registering a callback for event notify. 514 * 515 * PARAMETERS : 516 * @my_obj : ptr to a camera object 517 * @evt_cb : callback to be registered to handle event notify 518 * @user_data: user data ptr 519 * 520 * RETURN : int32_t type of status 521 * 0 -- success 522 * -1 -- failure 523 *==========================================================================*/ 524 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj, 525 mm_camera_event_notify_t evt_cb, 526 void * user_data) 527 { 528 int rc = -1; 529 rc = mm_camera_register_event_notify_internal(my_obj, 530 evt_cb, 531 user_data); 532 pthread_mutex_unlock(&my_obj->cam_lock); 533 return rc; 534 } 535 536 /*=========================================================================== 537 * FUNCTION : mm_camera_qbuf 538 * 539 * DESCRIPTION: enqueue buffer back to kernel 540 * 541 * PARAMETERS : 542 * @my_obj : camera object 543 * @ch_id : channel handle 544 * @buf : buf ptr to be enqueued 545 * 546 * RETURN : int32_t type of status 547 * 0 -- success 548 * -1 -- failure 549 *==========================================================================*/ 550 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj, 551 uint32_t ch_id, 552 mm_camera_buf_def_t *buf) 553 { 554 int rc = -1; 555 mm_channel_t * ch_obj = NULL; 556 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 557 558 pthread_mutex_unlock(&my_obj->cam_lock); 559 560 /* we always assume qbuf will be done before channel/stream is fully stopped 561 * because qbuf is done within dataCB context 562 * in order to avoid deadlock, we are not locking ch_lock for qbuf */ 563 if (NULL != ch_obj) { 564 rc = mm_channel_qbuf(ch_obj, buf); 565 } 566 567 return rc; 568 } 569 570 /*=========================================================================== 571 * FUNCTION : mm_camera_get_queued_buf_count 572 * 573 * DESCRIPTION: return queued buffer count 574 * 575 * PARAMETERS : 576 * @my_obj : camera object 577 * @ch_id : channel handle 578 * @stream_id : stream id 579 * 580 * RETURN : queued buffer count 581 *==========================================================================*/ 582 int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj, 583 uint32_t ch_id, uint32_t stream_id) 584 { 585 int rc = -1; 586 mm_channel_t * ch_obj = NULL; 587 uint32_t payload; 588 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 589 payload = stream_id; 590 591 if (NULL != ch_obj) { 592 pthread_mutex_lock(&ch_obj->ch_lock); 593 pthread_mutex_unlock(&my_obj->cam_lock); 594 rc = mm_channel_fsm_fn(ch_obj, 595 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT, 596 (void *)&payload, 597 NULL); 598 } else { 599 pthread_mutex_unlock(&my_obj->cam_lock); 600 } 601 602 return rc; 603 } 604 605 /*=========================================================================== 606 * FUNCTION : mm_camera_query_capability 607 * 608 * DESCRIPTION: query camera capability 609 * 610 * PARAMETERS : 611 * @my_obj: camera object 612 * 613 * RETURN : int32_t type of status 614 * 0 -- success 615 * -1 -- failure 616 *==========================================================================*/ 617 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj) 618 { 619 int32_t rc = 0; 620 621 #ifdef DAEMON_PRESENT 622 struct v4l2_capability cap; 623 /* get camera capabilities */ 624 memset(&cap, 0, sizeof(cap)); 625 rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap); 626 #else /* DAEMON_PRESENT */ 627 cam_shim_packet_t *shim_cmd; 628 cam_shim_cmd_data shim_cmd_data; 629 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data)); 630 shim_cmd_data.command = MSM_CAMERA_PRIV_QUERY_CAP; 631 shim_cmd_data.stream_id = 0; 632 shim_cmd_data.value = NULL; 633 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM, 634 my_obj->sessionid,&shim_cmd_data); 635 rc = mm_camera_module_send_cmd(shim_cmd); 636 mm_camera_destroy_shim_cmd_packet(shim_cmd); 637 #endif /* DAEMON_PRESENT */ 638 if (rc != 0) { 639 LOGE("cannot get camera capabilities, rc = %d, errno %d", 640 rc, errno); 641 } 642 pthread_mutex_unlock(&my_obj->cam_lock); 643 return rc; 644 } 645 646 /*=========================================================================== 647 * FUNCTION : mm_camera_set_parms 648 * 649 * DESCRIPTION: set parameters per camera 650 * 651 * PARAMETERS : 652 * @my_obj : camera object 653 * @parms : ptr to a param struct to be set to server 654 * 655 * RETURN : int32_t type of status 656 * 0 -- success 657 * -1 -- failure 658 * NOTE : Assume the parms struct buf is already mapped to server via 659 * domain socket. Corresponding fields of parameters to be set 660 * are already filled in by upper layer caller. 661 *==========================================================================*/ 662 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj, 663 parm_buffer_t *parms) 664 { 665 int32_t rc = -1; 666 int32_t value = 0; 667 if (parms != NULL) { 668 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 669 CAM_PRIV_PARM, &value); 670 } 671 pthread_mutex_unlock(&my_obj->cam_lock); 672 return rc; 673 } 674 675 /*=========================================================================== 676 * FUNCTION : mm_camera_get_parms 677 * 678 * DESCRIPTION: get parameters per camera 679 * 680 * PARAMETERS : 681 * @my_obj : camera object 682 * @parms : ptr to a param struct to be get from server 683 * 684 * RETURN : int32_t type of status 685 * 0 -- success 686 * -1 -- failure 687 * NOTE : Assume the parms struct buf is already mapped to server via 688 * domain socket. Parameters to be get from server are already 689 * filled in by upper layer caller. After this call, corresponding 690 * fields of requested parameters will be filled in by server with 691 * detailed information. 692 *==========================================================================*/ 693 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj, 694 parm_buffer_t *parms) 695 { 696 int32_t rc = -1; 697 int32_t value = 0; 698 if (parms != NULL) { 699 rc = mm_camera_util_g_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PARM, &value); 700 } 701 pthread_mutex_unlock(&my_obj->cam_lock); 702 return rc; 703 } 704 705 /*=========================================================================== 706 * FUNCTION : mm_camera_do_auto_focus 707 * 708 * DESCRIPTION: performing auto focus 709 * 710 * PARAMETERS : 711 * @camera_handle: camera handle 712 * 713 * RETURN : int32_t type of status 714 * 0 -- success 715 * -1 -- failure 716 * NOTE : if this call success, we will always assume there will 717 * be an auto_focus event following up. 718 *==========================================================================*/ 719 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj) 720 { 721 int32_t rc = -1; 722 int32_t value = 0; 723 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value); 724 pthread_mutex_unlock(&my_obj->cam_lock); 725 return rc; 726 } 727 728 /*=========================================================================== 729 * FUNCTION : mm_camera_cancel_auto_focus 730 * 731 * DESCRIPTION: cancel auto focus 732 * 733 * PARAMETERS : 734 * @camera_handle: camera handle 735 * 736 * RETURN : int32_t type of status 737 * 0 -- success 738 * -1 -- failure 739 *==========================================================================*/ 740 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj) 741 { 742 int32_t rc = -1; 743 int32_t value = 0; 744 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value); 745 pthread_mutex_unlock(&my_obj->cam_lock); 746 return rc; 747 } 748 749 /*=========================================================================== 750 * FUNCTION : mm_camera_prepare_snapshot 751 * 752 * DESCRIPTION: prepare hardware for snapshot 753 * 754 * PARAMETERS : 755 * @my_obj : camera object 756 * @do_af_flag : flag indicating if AF is needed 757 * 758 * RETURN : int32_t type of status 759 * 0 -- success 760 * -1 -- failure 761 *==========================================================================*/ 762 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj, 763 int32_t do_af_flag) 764 { 765 int32_t rc = -1; 766 int32_t value = do_af_flag; 767 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value); 768 pthread_mutex_unlock(&my_obj->cam_lock); 769 return rc; 770 } 771 772 /*=========================================================================== 773 * FUNCTION : mm_camera_start_zsl_snapshot 774 * 775 * DESCRIPTION: start zsl snapshot 776 * 777 * PARAMETERS : 778 * @my_obj : camera object 779 * 780 * RETURN : int32_t type of status 781 * 0 -- success 782 * -1 -- failure 783 *==========================================================================*/ 784 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj) 785 { 786 int32_t rc = -1; 787 int32_t value = 0; 788 789 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 790 CAM_PRIV_START_ZSL_SNAPSHOT, &value); 791 return rc; 792 } 793 794 /*=========================================================================== 795 * FUNCTION : mm_camera_stop_zsl_snapshot 796 * 797 * DESCRIPTION: stop zsl capture 798 * 799 * PARAMETERS : 800 * @my_obj : camera object 801 * 802 * RETURN : int32_t type of status 803 * 0 -- success 804 * -1 -- failure 805 *==========================================================================*/ 806 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj) 807 { 808 int32_t rc = -1; 809 int32_t value; 810 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 811 CAM_PRIV_STOP_ZSL_SNAPSHOT, &value); 812 return rc; 813 } 814 815 /*=========================================================================== 816 * FUNCTION : mm_camera_flush 817 * 818 * DESCRIPTION: flush the current camera state and buffers 819 * 820 * PARAMETERS : 821 * @my_obj : camera object 822 * 823 * RETURN : int32_t type of status 824 * 0 -- success 825 * -1 -- failure 826 *==========================================================================*/ 827 int32_t mm_camera_flush(mm_camera_obj_t *my_obj) 828 { 829 int32_t rc = -1; 830 int32_t value; 831 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 832 CAM_PRIV_FLUSH, &value); 833 pthread_mutex_unlock(&my_obj->cam_lock); 834 return rc; 835 } 836 837 /*=========================================================================== 838 * FUNCTION : mm_camera_add_channel 839 * 840 * DESCRIPTION: add a channel 841 * 842 * PARAMETERS : 843 * @my_obj : camera object 844 * @attr : bundle attribute of the channel if needed 845 * @channel_cb : callback function for bundle data notify 846 * @userdata : user data ptr 847 * 848 * RETURN : uint32_t type of channel handle 849 * 0 -- invalid channel handle, meaning the op failed 850 * >0 -- successfully added a channel with a valid handle 851 * NOTE : if no bundle data notify is needed, meaning each stream in the 852 * channel will have its own stream data notify callback, then 853 * attr, channel_cb, and userdata can be NULL. In this case, 854 * no matching logic will be performed in channel for the bundling. 855 *==========================================================================*/ 856 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj, 857 mm_camera_channel_attr_t *attr, 858 mm_camera_buf_notify_t channel_cb, 859 void *userdata) 860 { 861 mm_channel_t *ch_obj = NULL; 862 uint8_t ch_idx = 0; 863 uint32_t ch_hdl = 0; 864 865 for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) { 866 if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) { 867 ch_obj = &my_obj->ch[ch_idx]; 868 break; 869 } 870 } 871 872 if (NULL != ch_obj) { 873 /* initialize channel obj */ 874 memset(ch_obj, 0, sizeof(mm_channel_t)); 875 ch_hdl = mm_camera_util_generate_handler_by_num(my_obj->my_num, ch_idx); 876 ch_obj->my_hdl = ch_hdl; 877 ch_obj->state = MM_CHANNEL_STATE_STOPPED; 878 ch_obj->cam_obj = my_obj; 879 pthread_mutex_init(&ch_obj->ch_lock, NULL); 880 ch_obj->sessionid = my_obj->sessionid; 881 mm_channel_init(ch_obj, attr, channel_cb, userdata); 882 } 883 884 pthread_mutex_unlock(&my_obj->cam_lock); 885 return ch_hdl; 886 } 887 888 /*=========================================================================== 889 * FUNCTION : mm_camera_del_channel 890 * 891 * DESCRIPTION: delete a channel by its handle 892 * 893 * PARAMETERS : 894 * @my_obj : camera object 895 * @ch_id : channel handle 896 * 897 * RETURN : int32_t type of status 898 * 0 -- success 899 * -1 -- failure 900 * NOTE : all streams in the channel should be stopped already before 901 * this channel can be deleted. 902 *==========================================================================*/ 903 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj, 904 uint32_t ch_id) 905 { 906 int32_t rc = -1; 907 mm_channel_t * ch_obj = 908 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 909 910 if (NULL != ch_obj) { 911 pthread_mutex_lock(&ch_obj->ch_lock); 912 pthread_mutex_unlock(&my_obj->cam_lock); 913 914 rc = mm_channel_fsm_fn(ch_obj, 915 MM_CHANNEL_EVT_DELETE, 916 NULL, 917 NULL); 918 919 if (ch_obj->master_ch_obj != NULL) { 920 ch_obj->master_ch_obj->num_s_cnt--; 921 ch_obj->master_ch_obj->aux_ch_obj[ch_obj->master_ch_obj->num_s_cnt] = NULL; 922 } 923 pthread_mutex_destroy(&ch_obj->ch_lock); 924 memset(ch_obj, 0, sizeof(mm_channel_t)); 925 } else { 926 pthread_mutex_unlock(&my_obj->cam_lock); 927 } 928 return rc; 929 } 930 931 /*=========================================================================== 932 * FUNCTION : mm_camera_get_bundle_info 933 * 934 * DESCRIPTION: query bundle info of the channel 935 * 936 * PARAMETERS : 937 * @my_obj : camera object 938 * @ch_id : channel handle 939 * @bundle_info : bundle info to be filled in 940 * 941 * RETURN : int32_t type of status 942 * 0 -- success 943 * -1 -- failure 944 * NOTE : all streams in the channel should be stopped already before 945 * this channel can be deleted. 946 *==========================================================================*/ 947 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj, 948 uint32_t ch_id, 949 cam_bundle_config_t *bundle_info) 950 { 951 int32_t rc = -1; 952 mm_channel_t * ch_obj = 953 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 954 955 if (NULL != ch_obj) { 956 pthread_mutex_lock(&ch_obj->ch_lock); 957 pthread_mutex_unlock(&my_obj->cam_lock); 958 959 rc = mm_channel_fsm_fn(ch_obj, 960 MM_CHANNEL_EVT_GET_BUNDLE_INFO, 961 (void *)bundle_info, 962 NULL); 963 } else { 964 pthread_mutex_unlock(&my_obj->cam_lock); 965 } 966 return rc; 967 } 968 969 /*=========================================================================== 970 * FUNCTION : mm_camera_link_stream 971 * 972 * DESCRIPTION: link a stream into a channel 973 * 974 * PARAMETERS : 975 * @my_obj : camera object 976 * @ch_id : channel handle 977 * @stream_id : stream that will be linked 978 * @linked_ch_id : channel in which the stream will be linked 979 * 980 * RETURN : uint32_t type of stream handle 981 * 0 -- invalid stream handle, meaning the op failed 982 * >0 -- successfully linked a stream with a valid handle 983 *==========================================================================*/ 984 uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj, 985 uint32_t ch_id, 986 uint32_t stream_id, 987 uint32_t linked_ch_id) 988 { 989 uint32_t s_hdl = 0; 990 mm_channel_t * ch_obj = 991 mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id); 992 mm_channel_t * owner_obj = 993 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 994 995 if ((NULL != ch_obj) && (NULL != owner_obj)) { 996 pthread_mutex_lock(&ch_obj->ch_lock); 997 pthread_mutex_unlock(&my_obj->cam_lock); 998 999 mm_camera_stream_link_t stream_link; 1000 memset(&stream_link, 0, sizeof(mm_camera_stream_link_t)); 1001 stream_link.ch = owner_obj; 1002 stream_link.stream_id = stream_id; 1003 mm_channel_fsm_fn(ch_obj, 1004 MM_CHANNEL_EVT_LINK_STREAM, 1005 (void*)&stream_link, 1006 (void*)&s_hdl); 1007 } else { 1008 pthread_mutex_unlock(&my_obj->cam_lock); 1009 } 1010 1011 return s_hdl; 1012 } 1013 1014 /*=========================================================================== 1015 * FUNCTION : mm_camera_add_stream 1016 * 1017 * DESCRIPTION: add a stream into a channel 1018 * 1019 * PARAMETERS : 1020 * @my_obj : camera object 1021 * @ch_id : channel handle 1022 * 1023 * RETURN : uint32_t type of stream handle 1024 * 0 -- invalid stream handle, meaning the op failed 1025 * >0 -- successfully added a stream with a valid handle 1026 *==========================================================================*/ 1027 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj, 1028 uint32_t ch_id) 1029 { 1030 uint32_t s_hdl = 0; 1031 mm_channel_t * ch_obj = 1032 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1033 1034 if (NULL != ch_obj) { 1035 pthread_mutex_lock(&ch_obj->ch_lock); 1036 pthread_mutex_unlock(&my_obj->cam_lock); 1037 1038 mm_channel_fsm_fn(ch_obj, 1039 MM_CHANNEL_EVT_ADD_STREAM, 1040 NULL, 1041 (void *)&s_hdl); 1042 } else { 1043 pthread_mutex_unlock(&my_obj->cam_lock); 1044 } 1045 1046 return s_hdl; 1047 } 1048 1049 /*=========================================================================== 1050 * FUNCTION : mm_camera_del_stream 1051 * 1052 * DESCRIPTION: delete a stream by its handle 1053 * 1054 * PARAMETERS : 1055 * @my_obj : camera object 1056 * @ch_id : channel handle 1057 * @stream_id : stream handle 1058 * 1059 * RETURN : int32_t type of status 1060 * 0 -- success 1061 * -1 -- failure 1062 * NOTE : stream should be stopped already before it can be deleted. 1063 *==========================================================================*/ 1064 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj, 1065 uint32_t ch_id, 1066 uint32_t stream_id) 1067 { 1068 int32_t rc = -1; 1069 mm_channel_t * ch_obj = 1070 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1071 1072 if (NULL != ch_obj) { 1073 pthread_mutex_lock(&ch_obj->ch_lock); 1074 pthread_mutex_unlock(&my_obj->cam_lock); 1075 1076 rc = mm_channel_fsm_fn(ch_obj, 1077 MM_CHANNEL_EVT_DEL_STREAM, 1078 (void *)&stream_id, 1079 NULL); 1080 } else { 1081 pthread_mutex_unlock(&my_obj->cam_lock); 1082 } 1083 1084 return rc; 1085 } 1086 1087 /*=========================================================================== 1088 * FUNCTION : mm_camera_start_zsl_snapshot_ch 1089 * 1090 * DESCRIPTION: starts zsl snapshot for specific channel 1091 * 1092 * PARAMETERS : 1093 * @my_obj : camera object 1094 * @ch_id : channel handle 1095 * 1096 * RETURN : int32_t type of status 1097 * 0 -- success 1098 * -1 -- failure 1099 *==========================================================================*/ 1100 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj, 1101 uint32_t ch_id) 1102 { 1103 int32_t rc = -1; 1104 mm_channel_t *ch_obj = 1105 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1106 1107 if (NULL != ch_obj) { 1108 pthread_mutex_lock(&ch_obj->ch_lock); 1109 pthread_mutex_unlock(&my_obj->cam_lock); 1110 1111 rc = mm_channel_fsm_fn(ch_obj, 1112 MM_CHANNEL_EVT_START_ZSL_SNAPSHOT, 1113 NULL, 1114 NULL); 1115 } else { 1116 pthread_mutex_unlock(&my_obj->cam_lock); 1117 } 1118 1119 return rc; 1120 } 1121 1122 /*=========================================================================== 1123 * FUNCTION : mm_camera_stop_zsl_snapshot_ch 1124 * 1125 * DESCRIPTION: stops zsl snapshot for specific channel 1126 * 1127 * PARAMETERS : 1128 * @my_obj : camera object 1129 * @ch_id : channel handle 1130 * 1131 * RETURN : int32_t type of status 1132 * 0 -- success 1133 * -1 -- failure 1134 *==========================================================================*/ 1135 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj, 1136 uint32_t ch_id) 1137 { 1138 int32_t rc = -1; 1139 mm_channel_t * ch_obj = 1140 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1141 1142 if (NULL != ch_obj) { 1143 pthread_mutex_lock(&ch_obj->ch_lock); 1144 pthread_mutex_unlock(&my_obj->cam_lock); 1145 1146 rc = mm_channel_fsm_fn(ch_obj, 1147 MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT, 1148 NULL, 1149 NULL); 1150 } else { 1151 pthread_mutex_unlock(&my_obj->cam_lock); 1152 } 1153 1154 return rc; 1155 } 1156 1157 /*=========================================================================== 1158 * FUNCTION : mm_camera_config_stream 1159 * 1160 * DESCRIPTION: configure a stream 1161 * 1162 * PARAMETERS : 1163 * @my_obj : camera object 1164 * @ch_id : channel handle 1165 * @stream_id : stream handle 1166 * @config : stream configuration 1167 * 1168 * RETURN : int32_t type of status 1169 * 0 -- success 1170 * -1 -- failure 1171 *==========================================================================*/ 1172 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj, 1173 uint32_t ch_id, 1174 uint32_t stream_id, 1175 mm_camera_stream_config_t *config) 1176 { 1177 int32_t rc = -1; 1178 mm_channel_t * ch_obj = 1179 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1180 mm_evt_paylod_config_stream_t payload; 1181 1182 if (NULL != ch_obj) { 1183 pthread_mutex_lock(&ch_obj->ch_lock); 1184 pthread_mutex_unlock(&my_obj->cam_lock); 1185 1186 memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t)); 1187 payload.stream_id = stream_id; 1188 payload.config = config; 1189 rc = mm_channel_fsm_fn(ch_obj, 1190 MM_CHANNEL_EVT_CONFIG_STREAM, 1191 (void *)&payload, 1192 NULL); 1193 } else { 1194 pthread_mutex_unlock(&my_obj->cam_lock); 1195 } 1196 1197 return rc; 1198 } 1199 1200 /*=========================================================================== 1201 * FUNCTION : mm_camera_start_channel 1202 * 1203 * DESCRIPTION: start a channel, which will start all streams in the channel 1204 * 1205 * PARAMETERS : 1206 * @my_obj : camera object 1207 * @ch_id : channel handle 1208 * 1209 * RETURN : int32_t type of status 1210 * 0 -- success 1211 * -1 -- failure 1212 *==========================================================================*/ 1213 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, uint32_t ch_id) 1214 { 1215 int32_t rc = -1; 1216 mm_channel_t * ch_obj = 1217 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1218 1219 if (NULL != ch_obj) { 1220 pthread_mutex_lock(&ch_obj->ch_lock); 1221 pthread_mutex_unlock(&my_obj->cam_lock); 1222 1223 rc = mm_channel_fsm_fn(ch_obj, 1224 MM_CHANNEL_EVT_START, 1225 NULL, 1226 NULL); 1227 } else { 1228 pthread_mutex_unlock(&my_obj->cam_lock); 1229 } 1230 1231 return rc; 1232 } 1233 1234 /*=========================================================================== 1235 * FUNCTION : mm_camera_stop_channel 1236 * 1237 * DESCRIPTION: stop a channel, which will stop all streams in the channel 1238 * 1239 * PARAMETERS : 1240 * @my_obj : camera object 1241 * @ch_id : channel handle 1242 * 1243 * RETURN : int32_t type of status 1244 * 0 -- success 1245 * -1 -- failure 1246 *==========================================================================*/ 1247 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj, 1248 uint32_t ch_id) 1249 { 1250 int32_t rc = 0; 1251 mm_channel_t * ch_obj = 1252 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1253 1254 if (NULL != ch_obj) { 1255 pthread_mutex_lock(&ch_obj->ch_lock); 1256 pthread_mutex_unlock(&my_obj->cam_lock); 1257 1258 rc = mm_channel_fsm_fn(ch_obj, 1259 MM_CHANNEL_EVT_STOP, 1260 NULL, 1261 NULL); 1262 } else { 1263 pthread_mutex_unlock(&my_obj->cam_lock); 1264 } 1265 return rc; 1266 } 1267 1268 /*=========================================================================== 1269 * FUNCTION : mm_camera_request_super_buf 1270 * 1271 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 1272 * frames from superbuf queue 1273 * 1274 * PARAMETERS : 1275 * @my_obj : camera object 1276 * @ch_id : channel handle 1277 * @num_buf_requested : number of matched frames needed 1278 * 1279 * RETURN : int32_t type of status 1280 * 0 -- success 1281 * -1 -- failure 1282 *==========================================================================*/ 1283 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj, 1284 uint32_t ch_id, mm_camera_req_buf_t *buf) 1285 { 1286 int32_t rc = -1; 1287 mm_channel_t * ch_obj = 1288 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1289 1290 if ((NULL != ch_obj) && (buf != NULL)) { 1291 pthread_mutex_lock(&ch_obj->ch_lock); 1292 pthread_mutex_unlock(&my_obj->cam_lock); 1293 1294 rc = mm_channel_fsm_fn(ch_obj, MM_CHANNEL_EVT_REQUEST_SUPER_BUF, 1295 (void *)buf, NULL); 1296 } else { 1297 pthread_mutex_unlock(&my_obj->cam_lock); 1298 } 1299 1300 return rc; 1301 } 1302 1303 /*=========================================================================== 1304 * FUNCTION : mm_camera_cancel_super_buf_request 1305 * 1306 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 1307 * of matched frames from superbuf queue 1308 * 1309 * PARAMETERS : 1310 * @my_obj : camera object 1311 * @ch_id : channel handle 1312 * 1313 * RETURN : int32_t type of status 1314 * 0 -- success 1315 * -1 -- failure 1316 *==========================================================================*/ 1317 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id) 1318 { 1319 int32_t rc = -1; 1320 mm_channel_t * ch_obj = 1321 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1322 1323 if (NULL != ch_obj) { 1324 pthread_mutex_lock(&ch_obj->ch_lock); 1325 pthread_mutex_unlock(&my_obj->cam_lock); 1326 1327 rc = mm_channel_fsm_fn(ch_obj, 1328 MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF, 1329 NULL, 1330 NULL); 1331 } else { 1332 pthread_mutex_unlock(&my_obj->cam_lock); 1333 } 1334 1335 return rc; 1336 } 1337 1338 /*=========================================================================== 1339 * FUNCTION : mm_camera_flush_super_buf_queue 1340 * 1341 * DESCRIPTION: flush out all frames in the superbuf queue 1342 * 1343 * PARAMETERS : 1344 * @my_obj : camera object 1345 * @ch_id : channel handle 1346 * 1347 * RETURN : int32_t type of status 1348 * 0 -- success 1349 * -1 -- failure 1350 *==========================================================================*/ 1351 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id, 1352 uint32_t frame_idx) 1353 { 1354 int32_t rc = -1; 1355 mm_channel_t * ch_obj = 1356 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1357 1358 if (NULL != ch_obj) { 1359 pthread_mutex_lock(&ch_obj->ch_lock); 1360 pthread_mutex_unlock(&my_obj->cam_lock); 1361 1362 rc = mm_channel_fsm_fn(ch_obj, 1363 MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE, 1364 (void *)&frame_idx, 1365 NULL); 1366 } else { 1367 pthread_mutex_unlock(&my_obj->cam_lock); 1368 } 1369 1370 return rc; 1371 } 1372 1373 /*=========================================================================== 1374 * FUNCTION : mm_camera_config_channel_notify 1375 * 1376 * DESCRIPTION: configures the channel notification mode 1377 * 1378 * PARAMETERS : 1379 * @my_obj : camera object 1380 * @ch_id : channel handle 1381 * @notify_mode : notification mode 1382 * 1383 * RETURN : int32_t type of status 1384 * 0 -- success 1385 * -1 -- failure 1386 *==========================================================================*/ 1387 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj, 1388 uint32_t ch_id, 1389 mm_camera_super_buf_notify_mode_t notify_mode) 1390 { 1391 int32_t rc = -1; 1392 mm_channel_t * ch_obj = 1393 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1394 1395 if (NULL != ch_obj) { 1396 pthread_mutex_lock(&ch_obj->ch_lock); 1397 pthread_mutex_unlock(&my_obj->cam_lock); 1398 1399 rc = mm_channel_fsm_fn(ch_obj, 1400 MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE, 1401 (void *)¬ify_mode, 1402 NULL); 1403 } else { 1404 pthread_mutex_unlock(&my_obj->cam_lock); 1405 } 1406 1407 return rc; 1408 } 1409 1410 /*=========================================================================== 1411 * FUNCTION : mm_camera_set_stream_parms 1412 * 1413 * DESCRIPTION: set parameters per stream 1414 * 1415 * PARAMETERS : 1416 * @my_obj : camera object 1417 * @ch_id : channel handle 1418 * @s_id : stream handle 1419 * @parms : ptr to a param struct to be set to server 1420 * 1421 * RETURN : int32_t type of status 1422 * 0 -- success 1423 * -1 -- failure 1424 * NOTE : Assume the parms struct buf is already mapped to server via 1425 * domain socket. Corresponding fields of parameters to be set 1426 * are already filled in by upper layer caller. 1427 *==========================================================================*/ 1428 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj, 1429 uint32_t ch_id, 1430 uint32_t s_id, 1431 cam_stream_parm_buffer_t *parms) 1432 { 1433 int32_t rc = -1; 1434 mm_evt_paylod_set_get_stream_parms_t payload; 1435 mm_channel_t * ch_obj = 1436 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1437 1438 if (NULL != ch_obj) { 1439 pthread_mutex_lock(&ch_obj->ch_lock); 1440 pthread_mutex_unlock(&my_obj->cam_lock); 1441 1442 memset(&payload, 0, sizeof(payload)); 1443 payload.stream_id = s_id; 1444 payload.parms = parms; 1445 1446 rc = mm_channel_fsm_fn(ch_obj, 1447 MM_CHANNEL_EVT_SET_STREAM_PARM, 1448 (void *)&payload, 1449 NULL); 1450 } else { 1451 pthread_mutex_unlock(&my_obj->cam_lock); 1452 } 1453 1454 return rc; 1455 } 1456 1457 /*=========================================================================== 1458 * FUNCTION : mm_camera_get_stream_parms 1459 * 1460 * DESCRIPTION: get parameters per stream 1461 * 1462 * PARAMETERS : 1463 * @my_obj : camera object 1464 * @ch_id : channel handle 1465 * @s_id : stream handle 1466 * @parms : ptr to a param struct to be get from server 1467 * 1468 * RETURN : int32_t type of status 1469 * 0 -- success 1470 * -1 -- failure 1471 * NOTE : Assume the parms struct buf is already mapped to server via 1472 * domain socket. Parameters to be get from server are already 1473 * filled in by upper layer caller. After this call, corresponding 1474 * fields of requested parameters will be filled in by server with 1475 * detailed information. 1476 *==========================================================================*/ 1477 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj, 1478 uint32_t ch_id, 1479 uint32_t s_id, 1480 cam_stream_parm_buffer_t *parms) 1481 { 1482 int32_t rc = -1; 1483 mm_evt_paylod_set_get_stream_parms_t payload; 1484 mm_channel_t * ch_obj = 1485 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1486 1487 if (NULL != ch_obj) { 1488 pthread_mutex_lock(&ch_obj->ch_lock); 1489 pthread_mutex_unlock(&my_obj->cam_lock); 1490 1491 memset(&payload, 0, sizeof(payload)); 1492 payload.stream_id = s_id; 1493 payload.parms = parms; 1494 1495 rc = mm_channel_fsm_fn(ch_obj, 1496 MM_CHANNEL_EVT_GET_STREAM_PARM, 1497 (void *)&payload, 1498 NULL); 1499 } else { 1500 pthread_mutex_unlock(&my_obj->cam_lock); 1501 } 1502 1503 return rc; 1504 } 1505 1506 /*=========================================================================== 1507 * FUNCTION : mm_camera_do_stream_action 1508 * 1509 * DESCRIPTION: request server to perform stream based action. Maybe removed later 1510 * if the functionality is included in mm_camera_set_parms 1511 * 1512 * PARAMETERS : 1513 * @my_obj : camera object 1514 * @ch_id : channel handle 1515 * @s_id : stream handle 1516 * @actions : ptr to an action struct buf to be performed by server 1517 * 1518 * RETURN : int32_t type of status 1519 * 0 -- success 1520 * -1 -- failure 1521 * NOTE : Assume the action struct buf is already mapped to server via 1522 * domain socket. Actions to be performed by server are already 1523 * filled in by upper layer caller. 1524 *==========================================================================*/ 1525 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj, 1526 uint32_t ch_id, 1527 uint32_t stream_id, 1528 void *actions) 1529 { 1530 int32_t rc = -1; 1531 mm_evt_paylod_do_stream_action_t payload; 1532 mm_channel_t * ch_obj = 1533 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1534 1535 if (NULL != ch_obj) { 1536 pthread_mutex_lock(&ch_obj->ch_lock); 1537 pthread_mutex_unlock(&my_obj->cam_lock); 1538 1539 memset(&payload, 0, sizeof(payload)); 1540 payload.stream_id = stream_id; 1541 payload.actions = actions; 1542 1543 rc = mm_channel_fsm_fn(ch_obj, 1544 MM_CHANNEL_EVT_DO_ACTION, 1545 (void*)&payload, NULL); 1546 } else { 1547 pthread_mutex_unlock(&my_obj->cam_lock); 1548 } 1549 1550 return rc; 1551 } 1552 1553 /*=========================================================================== 1554 * FUNCTION : mm_camera_map_stream_buf 1555 * 1556 * DESCRIPTION: mapping stream buffer via domain socket to server 1557 * 1558 * PARAMETERS : 1559 * @my_obj : camera object 1560 * @ch_id : channel handle 1561 * @s_id : stream handle 1562 * @buf_type : type of buffer to be mapped. could be following values: 1563 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1564 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1565 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1566 * @buf_idx : index of buffer within the stream buffers, only valid if 1567 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1568 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1569 * @plane_idx : plane index. If all planes share the same fd, 1570 * plane_idx = -1; otherwise, plean_idx is the 1571 * index to plane (0..num_of_planes) 1572 * @fd : file descriptor of the buffer 1573 * @size : size of the buffer 1574 * 1575 * RETURN : int32_t type of status 1576 * 0 -- success 1577 * -1 -- failure 1578 *==========================================================================*/ 1579 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj, 1580 uint32_t ch_id, 1581 uint32_t stream_id, 1582 uint8_t buf_type, 1583 uint32_t buf_idx, 1584 int32_t plane_idx, 1585 int fd, 1586 size_t size, 1587 void *buffer) 1588 { 1589 int32_t rc = -1; 1590 cam_buf_map_type payload; 1591 mm_channel_t * ch_obj = 1592 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1593 1594 if (NULL != ch_obj) { 1595 pthread_mutex_lock(&ch_obj->ch_lock); 1596 pthread_mutex_unlock(&my_obj->cam_lock); 1597 1598 memset(&payload, 0, sizeof(payload)); 1599 payload.stream_id = stream_id; 1600 payload.type = buf_type; 1601 payload.frame_idx = buf_idx; 1602 payload.plane_idx = plane_idx; 1603 payload.fd = fd; 1604 payload.size = size; 1605 payload.buffer = buffer; 1606 rc = mm_channel_fsm_fn(ch_obj, 1607 MM_CHANNEL_EVT_MAP_STREAM_BUF, 1608 (void*)&payload, 1609 NULL); 1610 } else { 1611 pthread_mutex_unlock(&my_obj->cam_lock); 1612 } 1613 1614 return rc; 1615 } 1616 1617 /*=========================================================================== 1618 * FUNCTION : mm_camera_map_stream_bufs 1619 * 1620 * DESCRIPTION: mapping stream buffers via domain socket to server 1621 * 1622 * PARAMETERS : 1623 * @my_obj : camera object 1624 * @ch_id : channel handle 1625 * @buf_map_list : list of buffers to be mapped 1626 * 1627 * RETURN : int32_t type of status 1628 * 0 -- success 1629 * -1 -- failure 1630 *==========================================================================*/ 1631 int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj, 1632 uint32_t ch_id, 1633 const cam_buf_map_type_list *buf_map_list) 1634 { 1635 int32_t rc = -1; 1636 cam_buf_map_type_list payload; 1637 mm_channel_t * ch_obj = 1638 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1639 1640 if (NULL != ch_obj) { 1641 pthread_mutex_lock(&ch_obj->ch_lock); 1642 pthread_mutex_unlock(&my_obj->cam_lock); 1643 1644 memcpy(&payload, buf_map_list, sizeof(payload)); 1645 rc = mm_channel_fsm_fn(ch_obj, 1646 MM_CHANNEL_EVT_MAP_STREAM_BUFS, 1647 (void*)&payload, 1648 NULL); 1649 } else { 1650 pthread_mutex_unlock(&my_obj->cam_lock); 1651 } 1652 1653 return rc; 1654 } 1655 1656 /*=========================================================================== 1657 * FUNCTION : mm_camera_unmap_stream_buf 1658 * 1659 * DESCRIPTION: unmapping stream buffer via domain socket to server 1660 * 1661 * PARAMETERS : 1662 * @my_obj : camera object 1663 * @ch_id : channel handle 1664 * @s_id : stream handle 1665 * @buf_type : type of buffer to be mapped. could be following values: 1666 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1667 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1668 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1669 * @buf_idx : index of buffer within the stream buffers, only valid if 1670 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1671 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1672 * @plane_idx : plane index. If all planes share the same fd, 1673 * plane_idx = -1; otherwise, plean_idx is the 1674 * index to plane (0..num_of_planes) 1675 * 1676 * RETURN : int32_t type of status 1677 * 0 -- success 1678 * -1 -- failure 1679 *==========================================================================*/ 1680 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj, 1681 uint32_t ch_id, 1682 uint32_t stream_id, 1683 uint8_t buf_type, 1684 uint32_t buf_idx, 1685 int32_t plane_idx) 1686 { 1687 int32_t rc = -1; 1688 cam_buf_unmap_type payload; 1689 mm_channel_t * ch_obj = 1690 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1691 1692 if (NULL != ch_obj) { 1693 pthread_mutex_lock(&ch_obj->ch_lock); 1694 pthread_mutex_unlock(&my_obj->cam_lock); 1695 1696 memset(&payload, 0, sizeof(payload)); 1697 payload.stream_id = stream_id; 1698 payload.type = buf_type; 1699 payload.frame_idx = buf_idx; 1700 payload.plane_idx = plane_idx; 1701 rc = mm_channel_fsm_fn(ch_obj, 1702 MM_CHANNEL_EVT_UNMAP_STREAM_BUF, 1703 (void*)&payload, 1704 NULL); 1705 } else { 1706 pthread_mutex_unlock(&my_obj->cam_lock); 1707 } 1708 1709 return rc; 1710 } 1711 1712 /*=========================================================================== 1713 * FUNCTION : mm_camera_evt_sub 1714 * 1715 * DESCRIPTION: subscribe/unsubscribe event notify from kernel 1716 * 1717 * PARAMETERS : 1718 * @my_obj : camera object 1719 * @reg_flag : 1 -- subscribe ; 0 -- unsubscribe 1720 * 1721 * RETURN : int32_t type of status 1722 * 0 -- success 1723 * -1 -- failure 1724 *==========================================================================*/ 1725 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj, 1726 uint8_t reg_flag) 1727 { 1728 int32_t rc = 0; 1729 struct v4l2_event_subscription sub; 1730 1731 memset(&sub, 0, sizeof(sub)); 1732 sub.type = MSM_CAMERA_V4L2_EVENT_TYPE; 1733 sub.id = MSM_CAMERA_MSM_NOTIFY; 1734 if(FALSE == reg_flag) { 1735 /* unsubscribe */ 1736 rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 1737 if (rc < 0) { 1738 LOGE("unsubscribe event rc = %d, errno %d", 1739 rc, errno); 1740 return rc; 1741 } 1742 /* remove evt fd from the polling thraed when unreg the last event */ 1743 rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread, 1744 0, my_obj->my_hdl, mm_camera_sync_call); 1745 } else { 1746 rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 1747 if (rc < 0) { 1748 LOGE("subscribe event rc = %d, errno %d", 1749 rc, errno); 1750 return rc; 1751 } 1752 /* add evt fd to polling thread when subscribe the first event */ 1753 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread, 1754 0, my_obj->my_hdl, my_obj->ctrl_fd, mm_camera_event_notify, 1755 (void*)my_obj, mm_camera_sync_call); 1756 } 1757 return rc; 1758 } 1759 1760 /*=========================================================================== 1761 * FUNCTION : mm_camera_util_wait_for_event 1762 * 1763 * DESCRIPTION: utility function to wait for certain events 1764 * 1765 * PARAMETERS : 1766 * @my_obj : camera object 1767 * @evt_mask : mask for events to be waited. Any of event in the mask would 1768 * trigger the wait to end 1769 * @status : status of the event 1770 * 1771 * RETURN : none 1772 *==========================================================================*/ 1773 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj, 1774 uint32_t evt_mask, 1775 uint32_t *status) 1776 { 1777 int32_t rc = 0; 1778 struct timespec ts; 1779 1780 pthread_mutex_lock(&my_obj->evt_lock); 1781 while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) { 1782 clock_gettime(CLOCK_REALTIME, &ts); 1783 ts.tv_sec += WAIT_TIMEOUT; 1784 rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts); 1785 if (rc) { 1786 LOGE("pthread_cond_timedwait of evt_mask 0x%x failed %d", 1787 evt_mask, rc); 1788 break; 1789 } 1790 } 1791 if (!rc) { 1792 *status = my_obj->evt_rcvd.status; 1793 } else { 1794 *status = MSM_CAMERA_STATUS_FAIL; 1795 } 1796 /* reset local storage for recieved event for next event */ 1797 memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t)); 1798 pthread_mutex_unlock(&my_obj->evt_lock); 1799 } 1800 1801 /*=========================================================================== 1802 * FUNCTION : mm_camera_util_bundled_sendmsg 1803 * 1804 * DESCRIPTION: utility function to send bundled msg via domain socket 1805 * 1806 * PARAMETERS : 1807 * @my_obj : camera object 1808 * @msg : message to be sent 1809 * @buf_size : size of the message to be sent 1810 * @sendfds : array of file descriptors to be sent 1811 * @numfds : number of file descriptors to be sent 1812 * 1813 * RETURN : int32_t type of status 1814 * 0 -- success 1815 * -1 -- failure 1816 *==========================================================================*/ 1817 int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj, 1818 void *msg, 1819 size_t buf_size, 1820 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM], 1821 int numfds) 1822 { 1823 int32_t rc = -1; 1824 uint32_t status; 1825 1826 /* need to lock msg_lock, since sendmsg until response back is deemed as one operation*/ 1827 pthread_mutex_lock(&my_obj->msg_lock); 1828 if(mm_camera_socket_bundle_sendmsg(my_obj->ds_fd, msg, buf_size, sendfds, numfds) > 0) { 1829 /* wait for event that mapping/unmapping is done */ 1830 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status); 1831 if (MSM_CAMERA_STATUS_SUCCESS == status) { 1832 rc = 0; 1833 } 1834 } 1835 pthread_mutex_unlock(&my_obj->msg_lock); 1836 return rc; 1837 } 1838 1839 /*=========================================================================== 1840 * FUNCTION : mm_camera_util_sendmsg 1841 * 1842 * DESCRIPTION: utility function to send msg via domain socket 1843 * 1844 * PARAMETERS : 1845 * @my_obj : camera object 1846 * @msg : message to be sent 1847 * @buf_size : size of the message to be sent 1848 * @sendfd : >0 if any file descriptor need to be passed across process 1849 * 1850 * RETURN : int32_t type of status 1851 * 0 -- success 1852 * -1 -- failure 1853 *==========================================================================*/ 1854 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj, 1855 void *msg, 1856 size_t buf_size, 1857 int sendfd) 1858 { 1859 int32_t rc = -1; 1860 uint32_t status; 1861 1862 /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/ 1863 pthread_mutex_lock(&my_obj->msg_lock); 1864 if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) { 1865 /* wait for event that mapping/unmapping is done */ 1866 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status); 1867 if (MSM_CAMERA_STATUS_SUCCESS == status) { 1868 rc = 0; 1869 } 1870 } 1871 pthread_mutex_unlock(&my_obj->msg_lock); 1872 return rc; 1873 } 1874 1875 /*=========================================================================== 1876 * FUNCTIOa : mm_camera_map_buf 1877 * 1878 * DESCRIPTION: mapping camera buffer via domain socket to server 1879 * 1880 * PARAMETERS : 1881 * @my_obj : camera object 1882 * @buf_type : type of buffer to be mapped. could be following values: 1883 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1884 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1885 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1886 * @fd : file descriptor of the buffer 1887 * @size : size of the buffer 1888 * 1889 * RETURN : int32_t type of status 1890 * 0 -- success 1891 * -1 -- failure 1892 *==========================================================================*/ 1893 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj, 1894 uint8_t buf_type, int fd, size_t size, void *buffer) 1895 { 1896 int32_t rc = 0; 1897 1898 cam_sock_packet_t packet; 1899 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1900 packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING; 1901 packet.payload.buf_map.type = buf_type; 1902 packet.payload.buf_map.fd = fd; 1903 packet.payload.buf_map.size = size; 1904 packet.payload.buf_map.buffer = buffer; 1905 #ifdef DAEMON_PRESENT 1906 rc = mm_camera_util_sendmsg(my_obj, 1907 &packet, 1908 sizeof(cam_sock_packet_t), 1909 fd); 1910 #else 1911 cam_shim_packet_t *shim_cmd; 1912 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF, 1913 my_obj->sessionid, &packet); 1914 rc = mm_camera_module_send_cmd(shim_cmd); 1915 mm_camera_destroy_shim_cmd_packet(shim_cmd); 1916 #endif 1917 pthread_mutex_unlock(&my_obj->cam_lock); 1918 return rc; 1919 } 1920 1921 /*=========================================================================== 1922 * FUNCTION : mm_camera_map_bufs 1923 * 1924 * DESCRIPTION: mapping camera buffers via domain socket to server 1925 * 1926 * PARAMETERS : 1927 * @my_obj : camera object 1928 * @buf_map_list : list of buffers to be mapped 1929 * 1930 * RETURN : int32_t type of status 1931 * 0 -- success 1932 * -1 -- failure 1933 *==========================================================================*/ 1934 int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj, 1935 const cam_buf_map_type_list* buf_map_list) 1936 { 1937 int32_t rc = 0; 1938 cam_sock_packet_t packet; 1939 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1940 packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING; 1941 1942 memcpy(&packet.payload.buf_map_list, buf_map_list, 1943 sizeof(packet.payload.buf_map_list)); 1944 1945 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM]; 1946 uint32_t numbufs = packet.payload.buf_map_list.length; 1947 uint32_t i; 1948 for (i = 0; i < numbufs; i++) { 1949 sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd; 1950 packet.payload.buf_map_list.buf_maps[i].buffer = 1951 buf_map_list->buf_maps[i].buffer; 1952 } 1953 for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) { 1954 packet.payload.buf_map_list.buf_maps[i].fd = -1; 1955 sendfds[i] = -1; 1956 } 1957 1958 #ifdef DAEMON_PRESENT 1959 rc = mm_camera_util_bundled_sendmsg(my_obj, 1960 &packet, sizeof(cam_sock_packet_t), 1961 sendfds, numbufs); 1962 #else 1963 cam_shim_packet_t *shim_cmd; 1964 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF, 1965 my_obj->sessionid, &packet); 1966 rc = mm_camera_module_send_cmd(shim_cmd); 1967 mm_camera_destroy_shim_cmd_packet(shim_cmd); 1968 #endif 1969 1970 pthread_mutex_unlock(&my_obj->cam_lock); 1971 return rc; 1972 } 1973 1974 /*=========================================================================== 1975 * FUNCTION : mm_camera_unmap_buf 1976 * 1977 * DESCRIPTION: unmapping camera buffer via domain socket to server 1978 * 1979 * PARAMETERS : 1980 * @my_obj : camera object 1981 * @buf_type : type of buffer to be mapped. could be following values: 1982 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1983 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1984 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1985 * 1986 * RETURN : int32_t type of status 1987 * 0 -- success 1988 * -1 -- failure 1989 *==========================================================================*/ 1990 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj, 1991 uint8_t buf_type) 1992 { 1993 int32_t rc = 0; 1994 cam_sock_packet_t packet; 1995 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1996 packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING; 1997 packet.payload.buf_unmap.type = buf_type; 1998 #ifdef DAEMON_PRESENT 1999 rc = mm_camera_util_sendmsg(my_obj, 2000 &packet, 2001 sizeof(cam_sock_packet_t), 2002 -1); 2003 #else 2004 cam_shim_packet_t *shim_cmd; 2005 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF, 2006 my_obj->sessionid, &packet); 2007 rc = mm_camera_module_send_cmd(shim_cmd); 2008 mm_camera_destroy_shim_cmd_packet(shim_cmd); 2009 #endif 2010 pthread_mutex_unlock(&my_obj->cam_lock); 2011 return rc; 2012 } 2013 2014 /*=========================================================================== 2015 * FUNCTION : mm_camera_util_s_ctrl 2016 * 2017 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl 2018 * 2019 * PARAMETERS : 2020 * @my_obj :Camera object 2021 * @stream_id :streamID 2022 * @fd : file descritpor for sending ioctl 2023 * @id : control id 2024 * @value : value of the ioctl to be sent 2025 * 2026 * RETURN : int32_t type of status 2027 * 0 -- success 2028 * -1 -- failure 2029 *==========================================================================*/ 2030 int32_t mm_camera_util_s_ctrl(__unused mm_camera_obj_t *my_obj, 2031 __unused int stream_id, int32_t fd, 2032 uint32_t id, int32_t *value) 2033 { 2034 int rc = 0; 2035 2036 #ifdef DAEMON_PRESENT 2037 struct v4l2_control control; 2038 memset(&control, 0, sizeof(control)); 2039 control.id = id; 2040 if (value != NULL) { 2041 control.value = *value; 2042 } 2043 rc = ioctl(fd, VIDIOC_S_CTRL, &control); 2044 LOGD("fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n", 2045 fd, id, value, rc); 2046 if (rc < 0) { 2047 LOGE("ioctl failed %d, errno %d", rc, errno); 2048 } else if (value != NULL) { 2049 *value = control.value; 2050 } 2051 #else /* DAEMON_PRESENT */ 2052 cam_shim_packet_t *shim_cmd; 2053 cam_shim_cmd_data shim_cmd_data; 2054 (void)fd; 2055 (void)value; 2056 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data)); 2057 2058 shim_cmd_data.command = id; 2059 shim_cmd_data.stream_id = stream_id; 2060 shim_cmd_data.value = NULL; 2061 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM, 2062 my_obj->sessionid,&shim_cmd_data); 2063 rc = mm_camera_module_send_cmd(shim_cmd); 2064 mm_camera_destroy_shim_cmd_packet(shim_cmd); 2065 #endif /* DAEMON_PRESENT */ 2066 return (rc >= 0)? 0 : -1; 2067 } 2068 2069 /*=========================================================================== 2070 * FUNCTION : mm_camera_util_g_ctrl 2071 * 2072 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl 2073 * 2074 * PARAMETERS : 2075 * @my_obj :Camera object 2076 * @stream_id :streamID 2077 * @fd : file descritpor for sending ioctl 2078 * @id : control id 2079 * @value : value of the ioctl to be sent 2080 * 2081 * RETURN : int32_t type of status 2082 * 0 -- success 2083 * -1 -- failure 2084 *==========================================================================*/ 2085 int32_t mm_camera_util_g_ctrl(__unused mm_camera_obj_t *my_obj, 2086 __unused int stream_id, int32_t fd, uint32_t id, int32_t *value) 2087 { 2088 int rc = 0; 2089 struct v4l2_control control; 2090 2091 memset(&control, 0, sizeof(control)); 2092 control.id = id; 2093 if (value != NULL) { 2094 control.value = *value; 2095 } 2096 2097 #ifdef DAEMON_PRESENT 2098 rc = ioctl(fd, VIDIOC_G_CTRL, &control); 2099 LOGD("fd=%d, G_CTRL, id=0x%x, rc = %d\n", fd, id, rc); 2100 if (value != NULL) { 2101 *value = control.value; 2102 } 2103 #else /* DAEMON_PRESENT */ 2104 cam_shim_packet_t *shim_cmd; 2105 cam_shim_cmd_data shim_cmd_data; 2106 (void)fd; 2107 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data)); 2108 2109 shim_cmd_data.command = id; 2110 shim_cmd_data.stream_id = stream_id; 2111 shim_cmd_data.value = value; 2112 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM, 2113 my_obj->sessionid, &shim_cmd_data); 2114 2115 rc = mm_camera_module_send_cmd(shim_cmd); 2116 mm_camera_destroy_shim_cmd_packet(shim_cmd); 2117 #endif /* DAEMON_PRESENT */ 2118 return (rc >= 0)? 0 : -1; 2119 } 2120 2121 /*=========================================================================== 2122 * FUNCTION : mm_camera_create_shim_cmd 2123 * 2124 * DESCRIPTION: Prepare comand packet to pass to back-end through shim layer 2125 * 2126 * PARAMETERS : 2127 * @type : type of command 2128 * @sessionID : camera sessionID 2129 * @data : command data 2130 * 2131 * RETURN : NULL in case of failures 2132 allocated pointer to shim packet 2133 *==========================================================================*/ 2134 cam_shim_packet_t *mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type, 2135 uint32_t sessionID, void *data) 2136 { 2137 cam_shim_packet_t *shim_pack = NULL; 2138 uint32_t i = 0; 2139 2140 shim_pack = (cam_shim_packet_t *)malloc(sizeof(cam_shim_packet_t)); 2141 if (shim_pack == NULL) { 2142 LOGE("Cannot allocate a memory for shim packet"); 2143 return NULL; 2144 } 2145 memset(shim_pack, 0, sizeof(cam_shim_packet_t)); 2146 shim_pack->cmd_type = type; 2147 shim_pack->session_id = sessionID; 2148 switch (type) { 2149 case CAM_SHIM_SET_PARM: 2150 case CAM_SHIM_GET_PARM: { 2151 cam_shim_cmd_data *cmd_data = (cam_shim_cmd_data *)data; 2152 shim_pack->cmd_data = *cmd_data; 2153 break; 2154 } 2155 case CAM_SHIM_REG_BUF: { 2156 cam_reg_buf_t *cmd_data = (cam_reg_buf_t *)data; 2157 shim_pack->reg_buf = *cmd_data; 2158 break; 2159 } 2160 case CAM_SHIM_BUNDLE_CMD: { 2161 cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)data; 2162 for (i = 0; i < cmd_data->stream_count; i++) { 2163 shim_pack->bundle_cmd.stream_event[i] = cmd_data->stream_event[i]; 2164 } 2165 shim_pack->bundle_cmd.stream_count = cmd_data->stream_count; 2166 break; 2167 } 2168 default: 2169 LOGW("No Data for this command"); 2170 } 2171 return shim_pack; 2172 } 2173 2174 /*=========================================================================== 2175 * FUNCTION : mm_camera_destroy_shim_cmd 2176 * 2177 * DESCRIPTION: destroy shim packet 2178 * 2179 * PARAMETERS : 2180 * @cmd : ptr to shim packet 2181 2182 * RETURN : int32_t type of status 2183 * 0 -- success 2184 * -1 -- failure 2185 *==========================================================================*/ 2186 int32_t mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t *cmd) 2187 { 2188 int32_t rc = 0; 2189 uint32_t i = 0, j = 0; 2190 2191 if (cmd == NULL) { 2192 LOGW("Command is NULL"); 2193 return rc; 2194 } 2195 2196 switch (cmd->cmd_type) { 2197 case CAM_SHIM_SET_PARM: 2198 case CAM_SHIM_GET_PARM: 2199 case CAM_SHIM_REG_BUF: 2200 break; 2201 case CAM_SHIM_BUNDLE_CMD: { 2202 cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)cmd; 2203 for (i = 0; i < cmd_data->stream_count; i++) { 2204 cam_shim_cmd_packet_t *stream_evt = &cmd_data->stream_event[i]; 2205 for (j = 0; j < stream_evt->cmd_count; j++) { 2206 if (stream_evt->cmd != NULL) { 2207 if(stream_evt->cmd->cmd_type == CAM_SHIM_BUNDLE_CMD) { 2208 mm_camera_destroy_shim_cmd_packet(stream_evt->cmd); 2209 } 2210 free(stream_evt->cmd); 2211 stream_evt->cmd = NULL; 2212 } 2213 } 2214 } 2215 break; 2216 } 2217 default: 2218 LOGW("No Data for this command"); 2219 } 2220 free(cmd); 2221 cmd = NULL; 2222 return rc; 2223 } 2224 2225 /*=========================================================================== 2226 * FUNCTION : mm_camera_channel_advanced_capture 2227 * 2228 * DESCRIPTION: sets the channel advanced capture 2229 * 2230 * PARAMETERS : 2231 * @my_obj : camera object 2232 * @ch_id : channel handle 2233 * @type : advanced capture type. 2234 * @start_flag : flag to indicate start/stop 2235 * @in_value : input configaration 2236 * 2237 * RETURN : int32_t type of status 2238 * 0 -- success 2239 * -1 -- failure 2240 *==========================================================================*/ 2241 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj, 2242 uint32_t ch_id, mm_camera_advanced_capture_t type, 2243 uint32_t trigger, void *in_value) 2244 { 2245 LOGD("E type = %d", type); 2246 int32_t rc = -1; 2247 mm_channel_t * ch_obj = 2248 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2249 2250 if (NULL != ch_obj) { 2251 pthread_mutex_lock(&ch_obj->ch_lock); 2252 pthread_mutex_unlock(&my_obj->cam_lock); 2253 switch (type) { 2254 case MM_CAMERA_AF_BRACKETING: 2255 rc = mm_channel_fsm_fn(ch_obj, 2256 MM_CHANNEL_EVT_AF_BRACKETING, 2257 (void *)&trigger, 2258 NULL); 2259 break; 2260 case MM_CAMERA_AE_BRACKETING: 2261 rc = mm_channel_fsm_fn(ch_obj, 2262 MM_CHANNEL_EVT_AE_BRACKETING, 2263 (void *)&trigger, 2264 NULL); 2265 break; 2266 case MM_CAMERA_FLASH_BRACKETING: 2267 rc = mm_channel_fsm_fn(ch_obj, 2268 MM_CHANNEL_EVT_FLASH_BRACKETING, 2269 (void *)&trigger, 2270 NULL); 2271 break; 2272 case MM_CAMERA_ZOOM_1X: 2273 rc = mm_channel_fsm_fn(ch_obj, 2274 MM_CHANNEL_EVT_ZOOM_1X, 2275 (void *)&trigger, 2276 NULL); 2277 break; 2278 case MM_CAMERA_FRAME_CAPTURE: 2279 rc = mm_channel_fsm_fn(ch_obj, 2280 MM_CAMERA_EVT_CAPTURE_SETTING, 2281 (void *)in_value, 2282 NULL); 2283 break; 2284 default: 2285 break; 2286 } 2287 2288 } else { 2289 pthread_mutex_unlock(&my_obj->cam_lock); 2290 } 2291 2292 LOGD("X"); 2293 return rc; 2294 } 2295 2296 /*=========================================================================== 2297 * FUNCTION : mm_camera_get_session_id 2298 * 2299 * DESCRIPTION: get the session identity 2300 * 2301 * PARAMETERS : 2302 * @my_obj : camera object 2303 * @sessionid: pointer to the output session id 2304 * 2305 * RETURN : int32_t type of status 2306 * 0 -- success 2307 * -1 -- failure 2308 * NOTE : if this call succeeds, we will get a valid session id 2309 *==========================================================================*/ 2310 int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj, 2311 uint32_t* sessionid) 2312 { 2313 int32_t rc = -1; 2314 int32_t value = 0; 2315 if(sessionid != NULL) { 2316 struct v4l2_control control; 2317 memset(&control, 0, sizeof(control)); 2318 control.id = MSM_CAMERA_PRIV_G_SESSION_ID; 2319 control.value = value; 2320 2321 rc = ioctl(my_obj->ctrl_fd, VIDIOC_G_CTRL, &control); 2322 value = control.value; 2323 LOGD("fd=%d, get_session_id, id=0x%x, value = %d, rc = %d\n", 2324 my_obj->ctrl_fd, MSM_CAMERA_PRIV_G_SESSION_ID, 2325 value, rc); 2326 *sessionid = value; 2327 } 2328 return rc; 2329 } 2330 2331 /*=========================================================================== 2332 * FUNCTION : mm_camera_sync_related_sensors 2333 * 2334 * DESCRIPTION: send sync cmd 2335 * 2336 * PARAMETERS : 2337 * @my_obj : camera object 2338 * @parms : ptr to the related cam info to be sent to server 2339 * 2340 * RETURN : int32_t type of status 2341 * 0 -- success 2342 * -1 -- failure 2343 * NOTE : Assume the sync struct buf is already mapped to server via 2344 * domain socket. Corresponding fields of parameters to be set 2345 * are already filled in by upper layer caller. 2346 *==========================================================================*/ 2347 int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj, 2348 cam_sync_related_sensors_event_info_t* parms) 2349 { 2350 int32_t rc = -1; 2351 int32_t value = 0; 2352 if (parms != NULL) { 2353 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 2354 CAM_PRIV_SYNC_RELATED_SENSORS, &value); 2355 } 2356 pthread_mutex_unlock(&my_obj->cam_lock); 2357 return rc; 2358 } 2359 2360 /*=========================================================================== 2361 * FUNCTION : mm_camera_reg_stream_buf_cb 2362 * 2363 * DESCRIPTION: Register callback for stream buffer 2364 * 2365 * PARAMETERS : 2366 * @my_obj : camera object 2367 * @ch_id : channel handle 2368 * @stream_id : stream that will be linked 2369 * @buf_cb : special callback needs to be registered for stream buffer 2370 * @cb_type : Callback type SYNC/ASYNC 2371 * @userdata : user data pointer 2372 * 2373 * RETURN : int32_t type of status 2374 * 0 -- success 2375 * 1 -- failure 2376 *==========================================================================*/ 2377 int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj, 2378 uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t stream_cb, 2379 mm_camera_stream_cb_type cb_type, void *userdata) 2380 { 2381 int rc = 0; 2382 mm_stream_data_cb_t buf_cb; 2383 mm_channel_t * ch_obj = 2384 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2385 2386 if (NULL != ch_obj) { 2387 pthread_mutex_lock(&ch_obj->ch_lock); 2388 pthread_mutex_unlock(&my_obj->cam_lock); 2389 2390 memset(&buf_cb, 0, sizeof(mm_stream_data_cb_t)); 2391 buf_cb.cb = stream_cb; 2392 buf_cb.cb_count = -1; 2393 buf_cb.cb_type = cb_type; 2394 buf_cb.user_data = userdata; 2395 2396 mm_evt_paylod_reg_stream_buf_cb payload; 2397 memset(&payload, 0, sizeof(mm_evt_paylod_reg_stream_buf_cb)); 2398 payload.buf_cb = buf_cb; 2399 payload.stream_id = stream_id; 2400 mm_channel_fsm_fn(ch_obj, 2401 MM_CHANNEL_EVT_REG_STREAM_BUF_CB, 2402 (void*)&payload, NULL); 2403 } else { 2404 pthread_mutex_unlock(&my_obj->cam_lock); 2405 } 2406 return rc; 2407 } 2408 2409 /*=========================================================================== 2410 * FUNCTION : mm_camera_register_frame_sync 2411 * 2412 * DESCRIPTION: register/configure frame sync for this camera 2413 * 2414 * PARAMETERS : 2415 * @my_obj : camera object 2416 * @ch_id : channel handle 2417 * @stream_id : stream that will be linked 2418 * @sync_attr : attibutes for sync queue 2419 * 2420 * RETURN : int32_t type of status 2421 * 0 -- success 2422 * 1 -- failure 2423 *==========================================================================*/ 2424 int32_t mm_camera_reg_frame_sync(mm_camera_obj_t *my_obj, 2425 uint32_t ch_id, uint32_t stream_id, 2426 mm_camera_frame_sync_t *sync_attr) 2427 { 2428 int32_t rc = -1; 2429 uint32_t sync_id = 0; 2430 mm_evt_paylod_reg_frame_sync payload; 2431 2432 mm_channel_t *ch_obj = 2433 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2434 mm_channel_t *a_ch_obj = NULL; 2435 2436 if (sync_attr != NULL && sync_attr->a_cam_obj != NULL) { 2437 a_ch_obj = mm_camera_util_get_channel_by_handler( 2438 sync_attr->a_cam_obj, sync_attr->a_ch_id); 2439 } else { 2440 LOGE("Invalid arguments"); 2441 pthread_mutex_unlock(&my_obj->cam_lock); 2442 return rc; 2443 } 2444 2445 if (NULL != ch_obj && a_ch_obj != NULL) { 2446 pthread_mutex_lock(&ch_obj->ch_lock); 2447 pthread_mutex_unlock(&my_obj->cam_lock); 2448 memset(&payload, 0, sizeof(payload)); 2449 payload.stream_id = stream_id; 2450 payload.sync_attr = sync_attr; 2451 payload.a_ch_obj = a_ch_obj; 2452 rc = mm_channel_fsm_fn(ch_obj, 2453 MM_CHANNEL_EVT_REG_FRAME_SYNC, 2454 (void*)&payload, (void*)&sync_id); 2455 } else { 2456 pthread_mutex_unlock(&my_obj->cam_lock); 2457 } 2458 return rc; 2459 } 2460 2461 /*=========================================================================== 2462 * FUNCTION : mm_camera_start_frame_sync 2463 * 2464 * DESCRIPTION: start frame sync under this camera 2465 * 2466 * PARAMETERS : 2467 * @my_obj : camera object 2468 * @ch_id : channel handle 2469 * @stream_id : stream that will be linked 2470 * 2471 * RETURN : int32_t type of status 2472 * 0 -- success 2473 * 1 -- failure 2474 *==========================================================================*/ 2475 int32_t mm_camera_start_frame_sync(mm_camera_obj_t *my_obj, 2476 uint32_t ch_id, uint32_t stream_id) 2477 { 2478 int32_t rc = -1; 2479 2480 mm_channel_t *ch_obj = 2481 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2482 if (NULL != ch_obj) { 2483 pthread_mutex_lock(&ch_obj->ch_lock); 2484 pthread_mutex_unlock(&my_obj->cam_lock); 2485 mm_evt_paylod_trigger_frame_sync payload; 2486 payload.enable_frame_sync = 1; 2487 payload.stream_id = stream_id; 2488 rc = mm_channel_fsm_fn(ch_obj, 2489 MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC, 2490 (void*)&payload, NULL); 2491 } else { 2492 pthread_mutex_unlock(&my_obj->cam_lock); 2493 } 2494 return rc; 2495 } 2496 2497 /*=========================================================================== 2498 * FUNCTION : mm_camera_stop_frame_sync 2499 * 2500 * DESCRIPTION: stop frame sync under this camera 2501 * 2502 * PARAMETERS : 2503 * @my_obj : camera object 2504 * @ch_id : channel handle 2505 * @stream_id : stream that will be linked 2506 * 2507 * RETURN : int32_t type of status 2508 * 0 -- success 2509 * 1 -- failure 2510 *==========================================================================*/ 2511 int32_t mm_camera_stop_frame_sync(mm_camera_obj_t *my_obj, 2512 uint32_t ch_id, uint32_t stream_id) 2513 { 2514 int32_t rc = -1; 2515 2516 mm_channel_t *ch_obj = 2517 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2518 2519 if (NULL != ch_obj) { 2520 pthread_mutex_lock(&ch_obj->ch_lock); 2521 pthread_mutex_unlock(&my_obj->cam_lock); 2522 mm_evt_paylod_trigger_frame_sync payload; 2523 payload.enable_frame_sync = 0; 2524 payload.stream_id = stream_id; 2525 rc = mm_channel_fsm_fn(ch_obj, 2526 MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC, 2527 (void*)&payload, NULL); 2528 2529 } else { 2530 pthread_mutex_unlock(&my_obj->cam_lock); 2531 } 2532 return rc; 2533 } 2534 2535 /*=========================================================================== 2536 * FUNCTION : mm_camera_switch_stream_cb 2537 * 2538 * DESCRIPTION: switch stream callbacks in case of multiple instance of streams 2539 * 2540 * PARAMETERS : 2541 * @my_obj : camera object 2542 * @ch_id : channel handle 2543 * @stream_id : stream id 2544 * 2545 * RETURN : int32_t type of status 2546 * 0 -- success 2547 * 1 -- failure 2548 *==========================================================================*/ 2549 int32_t mm_camera_switch_stream_cb(mm_camera_obj_t *my_obj, 2550 uint32_t ch_id, uint32_t stream_id) 2551 { 2552 int rc = -1; 2553 mm_channel_t *ch_obj = NULL; 2554 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2555 2556 if (NULL != ch_obj) { 2557 pthread_mutex_lock(&ch_obj->ch_lock); 2558 pthread_mutex_unlock(&my_obj->cam_lock); 2559 rc = mm_channel_fsm_fn(ch_obj, 2560 MM_CHANNEL_EVT_SWITCH_STREAM_CB, 2561 (void *)&stream_id, 2562 NULL); 2563 } else { 2564 pthread_mutex_unlock(&my_obj->cam_lock); 2565 } 2566 2567 return rc; 2568 } 2569 2570 #ifdef QCAMERA_REDEFINE_LOG 2571 /*=========================================================================== 2572 * DESCRIPTION: mm camera debug interface 2573 * 2574 *==========================================================================*/ 2575 pthread_mutex_t dbg_log_mutex; 2576 2577 static int cam_soft_assert = 0; 2578 static FILE *cam_log_fd = NULL; 2579 static const char *cam_log_filename = "/data/misc/camera/cam_dbg_log_hal.txt"; 2580 2581 #undef LOG_TAG 2582 #define LOG_TAG "QCamera" 2583 #define CDBG_MAX_STR_LEN 1024 2584 #define CDBG_MAX_LINE_LENGTH 256 2585 2586 /* current trace loggin permissions 2587 * {NONE, ERR, WARN, HIGH, DEBUG, LOW, INFO} */ 2588 int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1] = { 2589 {0, 1, 0, 0, 0, 0, 1}, /* CAM_NO_MODULE */ 2590 {0, 1, 0, 0, 0, 0, 1}, /* CAM_HAL_MODULE */ 2591 {0, 1, 0, 0, 0, 0, 1}, /* CAM_MCI_MODULE */ 2592 {0, 1, 0, 0, 0, 0, 1}, /* CAM_JPEG_MODULE */ 2593 }; 2594 2595 /* string representation for logging level */ 2596 static const char *cam_dbg_level_to_str[] = { 2597 "", /* CAM_GLBL_DBG_NONE */ 2598 "<ERROR>", /* CAM_GLBL_DBG_ERR */ 2599 "<WARN>", /* CAM_GLBL_DBG_WARN */ 2600 "<HIGH>", /* CAM_GLBL_DBG_HIGH */ 2601 "<DBG>", /* CAM_GLBL_DBG_DEBUG */ 2602 "<LOW>", /* CAM_GLBL_DBG_LOW */ 2603 "<INFO>" /* CAM_GLBL_DBG_INFO */ 2604 }; 2605 2606 /* current trace logging configuration */ 2607 typedef struct { 2608 cam_global_debug_level_t level; 2609 int initialized; 2610 const char *name; 2611 const char *prop; 2612 } module_debug_t; 2613 2614 static module_debug_t cam_loginfo[(int)CAM_LAST_MODULE] = { 2615 {CAM_GLBL_DBG_ERR, 1, 2616 "", "persist.camera.global.debug" }, /* CAM_NO_MODULE */ 2617 {CAM_GLBL_DBG_ERR, 1, 2618 "<HAL>", "persist.camera.hal.debug" }, /* CAM_HAL_MODULE */ 2619 {CAM_GLBL_DBG_ERR, 1, 2620 "<MCI>", "persist.camera.mci.debug" }, /* CAM_MCI_MODULE */ 2621 {CAM_GLBL_DBG_ERR, 1, 2622 "<JPEG>", "persist.camera.mmstill.logs" }, /* CAM_JPEG_MODULE */ 2623 }; 2624 2625 /** cam_get_dbg_level 2626 * 2627 * @module: module name 2628 * @level: module debug logging level 2629 * 2630 * Maps debug log string to value. 2631 * 2632 * Return: logging level 2633 **/ 2634 __unused 2635 static cam_global_debug_level_t cam_get_dbg_level(const char *module, 2636 char *pValue) { 2637 2638 cam_global_debug_level_t rc = CAM_GLBL_DBG_NONE; 2639 2640 if (!strcmp(pValue, "none")) { 2641 rc = CAM_GLBL_DBG_NONE; 2642 } else if (!strcmp(pValue, "warn")) { 2643 rc = CAM_GLBL_DBG_WARN; 2644 } else if (!strcmp(pValue, "debug")) { 2645 rc = CAM_GLBL_DBG_DEBUG; 2646 } else if (!strcmp(pValue, "error")) { 2647 rc = CAM_GLBL_DBG_ERR; 2648 } else if (!strcmp(pValue, "low")) { 2649 rc = CAM_GLBL_DBG_LOW; 2650 } else if (!strcmp(pValue, "high")) { 2651 rc = CAM_GLBL_DBG_HIGH; 2652 } else if (!strcmp(pValue, "info")) { 2653 rc = CAM_GLBL_DBG_INFO; 2654 } else { 2655 ALOGE("Invalid %s debug log level %s\n", module, pValue); 2656 } 2657 2658 ALOGD("%s debug log level: %s\n", module, cam_dbg_level_to_str[rc]); 2659 2660 return rc; 2661 } 2662 2663 /** cam_vsnprintf 2664 * @pdst: destination buffer pointer 2665 * @size: size of destination b uffer 2666 * @pfmt: string format 2667 * @argptr: variabkle length argument list 2668 * 2669 * Processes variable length argument list to a formatted string. 2670 * 2671 * Return: n/a 2672 **/ 2673 static void cam_vsnprintf(char* pdst, unsigned int size, 2674 const char* pfmt, va_list argptr) { 2675 int num_chars_written = 0; 2676 2677 pdst[0] = '\0'; 2678 num_chars_written = vsnprintf(pdst, size, pfmt, argptr); 2679 2680 if ((num_chars_written >= (int)size) && (size > 0)) { 2681 /* Message length exceeds the buffer limit size */ 2682 num_chars_written = size - 1; 2683 pdst[size - 1] = '\0'; 2684 } 2685 } 2686 2687 /** mm_camera_debug_log 2688 * @module: origin or log message 2689 * @level: logging level 2690 * @func: caller function name 2691 * @line: caller line number 2692 * @fmt: log message formatting string 2693 * @...: variable argument list 2694 * 2695 * Generig logger method. 2696 * 2697 * Return: N/A 2698 **/ 2699 void mm_camera_debug_log(const cam_modules_t module, 2700 const cam_global_debug_level_t level, 2701 const char *func, const int line, const char *fmt, ...) { 2702 char str_buffer[CDBG_MAX_STR_LEN]; 2703 va_list args; 2704 2705 va_start(args, fmt); 2706 cam_vsnprintf(str_buffer, CDBG_MAX_STR_LEN, fmt, args); 2707 va_end(args); 2708 2709 switch (level) { 2710 case CAM_GLBL_DBG_WARN: 2711 ALOGW("%s%s %s: %d: %s", cam_loginfo[module].name, 2712 cam_dbg_level_to_str[level], func, line, str_buffer); 2713 break; 2714 case CAM_GLBL_DBG_ERR: 2715 ALOGE("%s%s %s: %d: %s", cam_loginfo[module].name, 2716 cam_dbg_level_to_str[level], func, line, str_buffer); 2717 break; 2718 case CAM_GLBL_DBG_INFO: 2719 ALOGI("%s%s %s: %d: %s", cam_loginfo[module].name, 2720 cam_dbg_level_to_str[level], func, line, str_buffer); 2721 break; 2722 case CAM_GLBL_DBG_HIGH: 2723 case CAM_GLBL_DBG_DEBUG: 2724 case CAM_GLBL_DBG_LOW: 2725 default: 2726 ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name, 2727 cam_dbg_level_to_str[level], func, line, str_buffer); 2728 } 2729 2730 2731 if (cam_log_fd != NULL) { 2732 char new_str_buffer[CDBG_MAX_STR_LEN]; 2733 pthread_mutex_lock(&dbg_log_mutex); 2734 2735 struct timeval tv; 2736 struct timezone tz; 2737 gettimeofday(&tv, &tz); 2738 2739 struct tm *now; 2740 now = gmtime((time_t *)&tv.tv_sec); 2741 snprintf(new_str_buffer, CDBG_MAX_STR_LEN, "%2d %02d:%02d:%02d.%03ld %d:%d Camera%s%s %d: %s: %s", 2742 now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, tv.tv_usec, getpid(),gettid(), 2743 cam_dbg_level_to_str[level], cam_loginfo[module].name, 2744 line, func, str_buffer); 2745 2746 fprintf(cam_log_fd, "%s", new_str_buffer); 2747 pthread_mutex_unlock(&dbg_log_mutex); 2748 } 2749 2750 } 2751 2752 /** mm_camera_set_dbg_log_properties 2753 * 2754 * Set global and module log level properties. 2755 * 2756 * Return: N/A 2757 **/ 2758 void mm_camera_set_dbg_log_properties(void) { 2759 int i; 2760 unsigned int j; 2761 char property_value[PROPERTY_VALUE_MAX] = {0}; 2762 char default_value[PROPERTY_VALUE_MAX] = {0}; 2763 2764 /* set global and individual module logging levels */ 2765 pthread_mutex_lock(&dbg_log_mutex); 2766 for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) { 2767 cam_global_debug_level_t log_level; 2768 snprintf(default_value, PROPERTY_VALUE_MAX, "%d", (int)cam_loginfo[i].level); 2769 property_get(cam_loginfo[i].prop, property_value, default_value); 2770 log_level = (cam_global_debug_level_t)atoi(property_value); 2771 2772 /* fix KW warnings */ 2773 if (log_level > CAM_GLBL_DBG_INFO) { 2774 log_level = CAM_GLBL_DBG_INFO; 2775 } 2776 2777 cam_loginfo[i].level = log_level; 2778 2779 /* The logging macros will produce a log message when logging level for 2780 * a module is less or equal to the level specified in the property for 2781 * the module, or less or equal the level specified by the global logging 2782 * property. Currently we don't allow INFO logging to be turned off */ 2783 for (j = CAM_GLBL_DBG_ERR; j <= CAM_GLBL_DBG_LOW; j++) { 2784 g_cam_log[i][j] = (cam_loginfo[CAM_NO_MODULE].level != CAM_GLBL_DBG_NONE) && 2785 (cam_loginfo[i].level != CAM_GLBL_DBG_NONE) && 2786 ((j <= cam_loginfo[i].level) || 2787 (j <= cam_loginfo[CAM_NO_MODULE].level)); 2788 } 2789 } 2790 pthread_mutex_unlock(&dbg_log_mutex); 2791 } 2792 2793 /** mm_camera_debug_open 2794 * 2795 * Open log file if it is enabled 2796 * 2797 * Return: N/A 2798 **/ 2799 void mm_camera_debug_open(void) { 2800 char property_value[PROPERTY_VALUE_MAX] = {0}; 2801 2802 pthread_mutex_init(&dbg_log_mutex, 0); 2803 mm_camera_set_dbg_log_properties(); 2804 2805 /* configure asserts */ 2806 property_get("persist.camera.debug.assert", property_value, "0"); 2807 cam_soft_assert = atoi(property_value); 2808 2809 /* open default log file according to property setting */ 2810 if (cam_log_fd == NULL) { 2811 property_get("persist.camera.debug.logfile", property_value, "0"); 2812 if (atoi(property_value)) { 2813 /* we always put the current process id at end of log file name */ 2814 char pid_str[255] = {0}; 2815 char new_log_file_name[1024] = {0}; 2816 2817 snprintf(pid_str, 255, "_%d", getpid()); 2818 strlcpy(new_log_file_name, cam_log_filename, sizeof(new_log_file_name)); 2819 strlcat(new_log_file_name, pid_str, sizeof(new_log_file_name)); 2820 2821 cam_log_fd = fopen(new_log_file_name, "a"); 2822 if (cam_log_fd == NULL) { 2823 ALOGE("Failed to create debug log file %s\n", 2824 new_log_file_name); 2825 } else { 2826 ALOGD("Debug log file %s open\n", new_log_file_name); 2827 } 2828 } else { 2829 property_set("persist.camera.debug.logfile", "0"); 2830 ALOGD("Debug log file is not enabled"); 2831 return; 2832 } 2833 } 2834 } 2835 2836 /** cam_debug_close 2837 * 2838 * Release logging resources. 2839 * 2840 * Return: N/A 2841 **/ 2842 void mm_camera_debug_close(void) { 2843 2844 if (cam_log_fd != NULL) { 2845 fclose(cam_log_fd); 2846 cam_log_fd = NULL; 2847 } 2848 2849 pthread_mutex_destroy(&dbg_log_mutex); 2850 } 2851 #endif 2852