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