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 <linux/media.h> 39 #include <media/msm_cam_sensor.h> 40 #include <dlfcn.h> 41 42 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h> 43 #include IOCTL_H 44 45 // Camera dependencies 46 #include "mm_camera_dbg.h" 47 #include "mm_camera_interface.h" 48 #include "mm_camera.h" 49 #include "mm_camera_muxer.h" 50 51 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; 52 static mm_camera_ctrl_t g_cam_ctrl; 53 54 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; 55 static uint8_t g_handler_history_count = 0; /* history count for handler */ 56 57 // 16th (starting from 0) bit tells its a BACK or FRONT camera 58 #define CAM_SENSOR_FACING_MASK (1U<<16) 59 60 #ifdef DUAL_CAM_TEST //Temporary macro. Will be removed once we finalize sensor change. 61 // 24th (starting from 0) bit tells its a MAIN or AUX camera 62 #define CAM_SENSOR_MODE_MASK_MAIN (1U<<24) 63 #define CAM_SENSOR_MODE_MASK_AUX (1U<<25) 64 #define CAM_SENSOR_MODE_MASK_SECURE (1U<<26) 65 66 // 28th (starting from 0) bit tells its YUV sensor or not 67 #define CAM_SENSOR_FORMAT_MASK (1U<<28) 68 #else 69 #define CAM_SENSOR_TYPE_MASK (1U<<24) 70 #define CAM_SENSOR_FORMAT_MASK (1U<<25) 71 #endif 72 73 /*=========================================================================== 74 * FUNCTION : mm_camera_util_generate_handler 75 * 76 * DESCRIPTION: utility function to generate handler for camera/channel/stream 77 * 78 * PARAMETERS : 79 * @index: index of the object to have handler 80 * 81 * RETURN : uint32_t type of handle that uniquely identify the object 82 *==========================================================================*/ 83 uint32_t mm_camera_util_generate_handler(uint8_t index) 84 { 85 uint32_t handler = 0; 86 pthread_mutex_lock(&g_handler_lock); 87 g_handler_history_count++; 88 if (0 == g_handler_history_count) { 89 g_handler_history_count++; 90 } 91 handler = g_handler_history_count; 92 handler = (handler<<8) | index; 93 pthread_mutex_unlock(&g_handler_lock); 94 return handler; 95 } 96 97 /*=========================================================================== 98 * FUNCTION : mm_camera_util_get_index_by_handler 99 * 100 * DESCRIPTION: utility function to get index from handle 101 * 102 * PARAMETERS : 103 * @handler: object handle 104 * 105 * RETURN : uint8_t type of index derived from handle 106 *==========================================================================*/ 107 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler) 108 { 109 return (handler & 0x000000ff); 110 } 111 112 /*=========================================================================== 113 * FUNCTION : mm_camera_util_get_dev_name 114 * 115 * DESCRIPTION: utility function to get device name from camera handle 116 * 117 * PARAMETERS : 118 * @cam_handle: camera handle 119 * 120 * RETURN : char ptr to the device name stored in global variable 121 * NOTE : caller should not free the char ptr 122 *==========================================================================*/ 123 const char *mm_camera_util_get_dev_name(uint32_t cam_handle) 124 { 125 char *dev_name = NULL; 126 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle); 127 if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) { 128 dev_name = g_cam_ctrl.video_dev_name[cam_idx]; 129 } 130 return dev_name; 131 } 132 133 /*=========================================================================== 134 * FUNCTION : mm_camera_util_get_camera_by_handler 135 * 136 * DESCRIPTION: utility function to get camera object from camera handle 137 * 138 * PARAMETERS : 139 * @cam_handle: camera handle 140 * 141 * RETURN : ptr to the camera object stored in global variable 142 * NOTE : caller should not free the camera object ptr 143 *==========================================================================*/ 144 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle) 145 { 146 mm_camera_obj_t *cam_obj = NULL; 147 uint8_t cam_idx = 0; 148 149 for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) { 150 if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) && 151 (cam_handle == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) { 152 cam_obj = g_cam_ctrl.cam_obj[cam_idx]; 153 break; 154 } 155 } 156 return cam_obj; 157 } 158 159 160 /*=========================================================================== 161 * FUNCTION : mm_camera_util_set_camera_object 162 * 163 * DESCRIPTION: utility function to set camera object to global structure 164 * 165 * PARAMETERS : 166 * @cam_idx : index to store cambera object 167 * @obj : Camera object to store 168 * 169 * RETURN : int32_t type of status 170 * 0 -- success 171 * -1 -- failure 172 *==========================================================================*/ 173 int32_t mm_camera_util_set_camera_object(uint8_t cam_idx, mm_camera_obj_t *obj) 174 { 175 int32_t rc = 0; 176 pthread_mutex_lock(&g_intf_lock); 177 if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS) { 178 g_cam_ctrl.cam_obj[cam_idx] = obj; 179 } else { 180 rc = -1; 181 } 182 pthread_mutex_unlock(&g_intf_lock); 183 return rc; 184 } 185 186 /*=========================================================================== 187 * FUNCTION : mm_camera_util_get_camera_head_obj 188 * 189 * DESCRIPTION: utility function to get camera object from camera handle 190 * 191 * PARAMETERS : 192 * @cam_handle: camera handle 193 * 194 * RETURN : ptr to the master/primary camera object 195 *==========================================================================*/ 196 mm_camera_obj_t* mm_camera_util_get_camera_head(uint32_t cam_handle) 197 { 198 mm_camera_obj_t *cam_obj = NULL; 199 200 cam_obj = mm_camera_util_get_camera_by_handler(cam_handle); 201 if (cam_obj != NULL && cam_obj->master_cam_obj != NULL) { 202 cam_obj = cam_obj->master_cam_obj; 203 } 204 return cam_obj; 205 } 206 207 /*=========================================================================== 208 * FUNCTION : mm_camera_util_get_camera_by_session_id 209 * 210 * DESCRIPTION: utility function to get camera object from camera sessionID 211 * 212 * PARAMETERS : 213 * @session_id: sessionid for which cam obj mapped 214 * 215 * RETURN : ptr to the camera object stored in global variable 216 * NOTE : caller should not free the camera object ptr 217 *==========================================================================*/ 218 mm_camera_obj_t* mm_camera_util_get_camera_by_session_id(uint32_t session_id) 219 { 220 int cam_idx = 0; 221 mm_camera_obj_t *cam_obj = NULL; 222 for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) { 223 if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) && 224 (session_id == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->sessionid)) { 225 LOGD("session id:%d match idx:%d\n", session_id, cam_idx); 226 cam_obj = g_cam_ctrl.cam_obj[cam_idx]; 227 } 228 } 229 return cam_obj; 230 } 231 232 /*=========================================================================== 233 * FUNCTION : mm_camera_intf_query_capability 234 * 235 * DESCRIPTION: query camera capability 236 * 237 * PARAMETERS : 238 * @camera_handle: camera handle 239 * 240 * RETURN : int32_t type of status 241 * 0 -- success 242 * -1 -- failure 243 *==========================================================================*/ 244 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle) 245 { 246 int32_t rc = -1; 247 mm_camera_obj_t *my_obj = NULL; 248 uint32_t handle = 0; 249 uint32_t aux_handle = 0; 250 251 LOGD("E: camera_handler = %d ", camera_handle); 252 253 pthread_mutex_lock(&g_intf_lock); 254 handle = get_main_camera_handle(camera_handle); 255 aux_handle = get_aux_camera_handle(camera_handle); 256 257 if (handle) { 258 my_obj = mm_camera_util_get_camera_by_handler(handle); 259 260 if(my_obj) { 261 pthread_mutex_lock(&my_obj->cam_lock); 262 pthread_mutex_unlock(&g_intf_lock); 263 rc = mm_camera_query_capability(my_obj); 264 } else { 265 pthread_mutex_unlock(&g_intf_lock); 266 } 267 } else { 268 pthread_mutex_unlock(&g_intf_lock); 269 } 270 271 if (aux_handle) { 272 pthread_mutex_lock(&g_intf_lock); 273 my_obj = mm_camera_util_get_camera_head(aux_handle); 274 if (my_obj) { 275 pthread_mutex_lock(&my_obj->muxer_lock); 276 pthread_mutex_unlock(&g_intf_lock); 277 rc = mm_camera_muxer_query_capability(aux_handle, my_obj); 278 } else { 279 pthread_mutex_unlock(&g_intf_lock); 280 } 281 } 282 283 LOGH("camera_handle = %d rc = %d X", camera_handle, rc); 284 return rc; 285 } 286 287 /*=========================================================================== 288 * FUNCTION : mm_camera_intf_set_parms 289 * 290 * DESCRIPTION: set parameters per camera 291 * 292 * PARAMETERS : 293 * @camera_handle: camera handle 294 * @parms : ptr to a param struct to be set to server 295 * 296 * RETURN : int32_t type of status 297 * 0 -- success 298 * -1 -- failure 299 * NOTE : Assume the parms struct buf is already mapped to server via 300 * domain socket. Corresponding fields of parameters to be set 301 * are already filled in by upper layer caller. 302 *==========================================================================*/ 303 static int32_t mm_camera_intf_set_parms(uint32_t camera_handle, 304 parm_buffer_t *parms) 305 { 306 int32_t rc = -1; 307 mm_camera_obj_t * my_obj = NULL; 308 309 uint32_t handle = get_main_camera_handle(camera_handle); 310 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 311 312 if (aux_handle) { 313 pthread_mutex_lock(&g_intf_lock); 314 my_obj = mm_camera_util_get_camera_head(aux_handle); 315 if (my_obj) { 316 pthread_mutex_lock(&my_obj->muxer_lock); 317 pthread_mutex_unlock(&g_intf_lock); 318 rc = mm_camera_muxer_set_parms(aux_handle, 319 parms, my_obj); 320 } else { 321 pthread_mutex_unlock(&g_intf_lock); 322 } 323 } 324 325 if (handle) { 326 pthread_mutex_lock(&g_intf_lock); 327 my_obj = mm_camera_util_get_camera_by_handler(handle); 328 329 if(my_obj) { 330 pthread_mutex_lock(&my_obj->cam_lock); 331 pthread_mutex_unlock(&g_intf_lock); 332 rc = mm_camera_set_parms(my_obj, parms); 333 } else { 334 pthread_mutex_unlock(&g_intf_lock); 335 } 336 } 337 return rc; 338 } 339 340 /*=========================================================================== 341 * FUNCTION : mm_camera_intf_get_parms 342 * 343 * DESCRIPTION: get parameters per camera 344 * 345 * PARAMETERS : 346 * @camera_handle: camera handle 347 * @parms : ptr to a param struct to be get from server 348 * 349 * RETURN : int32_t type of status 350 * 0 -- success 351 * -1 -- failure 352 * NOTE : Assume the parms struct buf is already mapped to server via 353 * domain socket. Parameters to be get from server are already 354 * filled in by upper layer caller. After this call, corresponding 355 * fields of requested parameters will be filled in by server with 356 * detailed information. 357 *==========================================================================*/ 358 static int32_t mm_camera_intf_get_parms(uint32_t camera_handle, 359 parm_buffer_t *parms) 360 { 361 int32_t rc = -1; 362 mm_camera_obj_t * my_obj = NULL; 363 uint32_t handle = get_main_camera_handle(camera_handle); 364 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 365 366 if (aux_handle) { 367 pthread_mutex_lock(&g_intf_lock); 368 my_obj = mm_camera_util_get_camera_head(aux_handle); 369 if (my_obj) { 370 pthread_mutex_lock(&my_obj->muxer_lock); 371 pthread_mutex_unlock(&g_intf_lock); 372 rc = mm_camera_muxer_get_parms(aux_handle, 373 parms, my_obj); 374 } else { 375 pthread_mutex_unlock(&g_intf_lock); 376 } 377 } 378 379 if (handle) { 380 pthread_mutex_lock(&g_intf_lock); 381 my_obj = mm_camera_util_get_camera_by_handler(handle); 382 383 if(my_obj) { 384 pthread_mutex_lock(&my_obj->cam_lock); 385 pthread_mutex_unlock(&g_intf_lock); 386 rc = mm_camera_get_parms(my_obj, parms); 387 } else { 388 pthread_mutex_unlock(&g_intf_lock); 389 } 390 } 391 return rc; 392 393 } 394 395 /*=========================================================================== 396 * FUNCTION : mm_camera_intf_do_auto_focus 397 * 398 * DESCRIPTION: performing auto focus 399 * 400 * PARAMETERS : 401 * @camera_handle: camera handle 402 * 403 * RETURN : int32_t type of status 404 * 0 -- success 405 * -1 -- failure 406 * NOTE : if this call success, we will always assume there will 407 * be an auto_focus event following up. 408 *==========================================================================*/ 409 static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle) 410 { 411 int32_t rc = -1; 412 mm_camera_obj_t * my_obj = NULL; 413 uint32_t handle = get_main_camera_handle(camera_handle); 414 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 415 416 if (aux_handle) { 417 pthread_mutex_lock(&g_intf_lock); 418 my_obj = mm_camera_util_get_camera_head(aux_handle); 419 if (my_obj) { 420 pthread_mutex_lock(&my_obj->muxer_lock); 421 pthread_mutex_unlock(&g_intf_lock); 422 rc = mm_camera_muxer_do_auto_focus(aux_handle, my_obj); 423 } else { 424 pthread_mutex_unlock(&g_intf_lock); 425 } 426 } 427 428 if (handle) { 429 pthread_mutex_lock(&g_intf_lock); 430 my_obj = mm_camera_util_get_camera_by_handler(handle); 431 432 if(my_obj) { 433 pthread_mutex_lock(&my_obj->cam_lock); 434 pthread_mutex_unlock(&g_intf_lock); 435 rc = mm_camera_do_auto_focus(my_obj); 436 } else { 437 pthread_mutex_unlock(&g_intf_lock); 438 } 439 } 440 LOGH("rc = %d camera_handle = %d X", rc, camera_handle); 441 return rc; 442 } 443 444 /*=========================================================================== 445 * FUNCTION : mm_camera_intf_cancel_auto_focus 446 * 447 * DESCRIPTION: cancel auto focus 448 * 449 * PARAMETERS : 450 * @camera_handle: camera handle 451 * 452 * RETURN : int32_t type of status 453 * 0 -- success 454 * -1 -- failure 455 *==========================================================================*/ 456 static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle) 457 { 458 int32_t rc = -1; 459 mm_camera_obj_t * my_obj = NULL; 460 uint32_t handle = get_main_camera_handle(camera_handle); 461 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 462 463 if (aux_handle) { 464 pthread_mutex_lock(&g_intf_lock); 465 my_obj = mm_camera_util_get_camera_head(aux_handle); 466 if (my_obj) { 467 pthread_mutex_lock(&my_obj->muxer_lock); 468 pthread_mutex_unlock(&g_intf_lock); 469 rc = mm_camera_muxer_cancel_auto_focus(aux_handle, my_obj); 470 } else { 471 pthread_mutex_unlock(&g_intf_lock); 472 } 473 } 474 475 if (handle) { 476 pthread_mutex_lock(&g_intf_lock); 477 my_obj = mm_camera_util_get_camera_by_handler(handle); 478 if(my_obj) { 479 pthread_mutex_lock(&my_obj->cam_lock); 480 pthread_mutex_unlock(&g_intf_lock); 481 rc = mm_camera_cancel_auto_focus(my_obj); 482 } else { 483 pthread_mutex_unlock(&g_intf_lock); 484 } 485 } 486 LOGH("rc = %d camera_handle = %d X", rc, camera_handle); 487 return rc; 488 } 489 490 /*=========================================================================== 491 * FUNCTION : mm_camera_intf_prepare_snapshot 492 * 493 * DESCRIPTION: prepare hardware for snapshot 494 * 495 * PARAMETERS : 496 * @camera_handle: camera handle 497 * @do_af_flag : flag indicating if AF is needed 498 * 499 * RETURN : int32_t type of status 500 * 0 -- success 501 * -1 -- failure 502 *==========================================================================*/ 503 static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle, 504 int32_t do_af_flag) 505 { 506 int32_t rc = -1; 507 mm_camera_obj_t * my_obj = NULL; 508 uint32_t handle = get_main_camera_handle(camera_handle); 509 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 510 511 if (aux_handle) { 512 pthread_mutex_lock(&g_intf_lock); 513 my_obj = mm_camera_util_get_camera_head(aux_handle); 514 if (my_obj) { 515 pthread_mutex_lock(&my_obj->muxer_lock); 516 pthread_mutex_unlock(&g_intf_lock); 517 rc = mm_camera_muxer_prepare_snapshot(aux_handle, 518 do_af_flag, my_obj); 519 } else { 520 pthread_mutex_unlock(&g_intf_lock); 521 } 522 } 523 524 if (handle) { 525 pthread_mutex_lock(&g_intf_lock); 526 my_obj = mm_camera_util_get_camera_by_handler(handle); 527 528 if(my_obj) { 529 pthread_mutex_lock(&my_obj->cam_lock); 530 pthread_mutex_unlock(&g_intf_lock); 531 532 rc = mm_camera_prepare_snapshot(my_obj, do_af_flag); 533 } else { 534 pthread_mutex_unlock(&g_intf_lock); 535 } 536 return rc; 537 } 538 LOGH("rc = %d camera_handle = %d X", rc, camera_handle); 539 return rc; 540 } 541 542 /*=========================================================================== 543 * FUNCTION : mm_camera_intf_flush 544 * 545 * DESCRIPTION: flush the current camera state and buffers 546 * 547 * PARAMETERS : 548 * @camera_handle: camera handle 549 * 550 * RETURN : int32_t type of status 551 * 0 -- success 552 * -1 -- failure 553 *==========================================================================*/ 554 static int32_t mm_camera_intf_flush(uint32_t camera_handle) 555 { 556 int32_t rc = -1; 557 mm_camera_obj_t * my_obj = NULL; 558 uint32_t handle = get_main_camera_handle(camera_handle); 559 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 560 561 if (aux_handle) { 562 pthread_mutex_lock(&g_intf_lock); 563 my_obj = mm_camera_util_get_camera_head(aux_handle); 564 565 if (my_obj) { 566 pthread_mutex_lock(&my_obj->muxer_lock); 567 pthread_mutex_unlock(&g_intf_lock); 568 rc = mm_camera_muxer_flush(aux_handle, my_obj); 569 } else { 570 pthread_mutex_unlock(&g_intf_lock); 571 } 572 } 573 574 if (handle) { 575 pthread_mutex_lock(&g_intf_lock); 576 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 577 578 if(my_obj) { 579 pthread_mutex_lock(&my_obj->cam_lock); 580 pthread_mutex_unlock(&g_intf_lock); 581 rc = mm_camera_flush(my_obj); 582 } else { 583 pthread_mutex_unlock(&g_intf_lock); 584 } 585 } 586 return rc; 587 } 588 589 /*=========================================================================== 590 * FUNCTION : mm_camera_intf_close 591 * 592 * DESCRIPTION: close a camera by its handle 593 * 594 * PARAMETERS : 595 * @camera_handle: camera handle 596 * 597 * RETURN : int32_t type of status 598 * 0 -- success 599 * -1 -- failure 600 *==========================================================================*/ 601 static int32_t mm_camera_intf_close(uint32_t camera_handle) 602 { 603 int32_t rc = -1; 604 uint8_t cam_idx = -1; 605 mm_camera_obj_t *my_obj = NULL; 606 607 LOGD("E: camera_handler = %d ", camera_handle); 608 609 uint32_t handle = get_main_camera_handle(camera_handle); 610 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 611 if (aux_handle) { 612 pthread_mutex_lock(&g_intf_lock); 613 my_obj = mm_camera_util_get_camera_head(aux_handle); 614 if (my_obj) { 615 pthread_mutex_lock(&my_obj->muxer_lock); 616 pthread_mutex_unlock(&g_intf_lock); 617 rc = mm_camera_muxer_close_camera(aux_handle, my_obj); 618 } 619 } 620 621 if (handle) { 622 pthread_mutex_lock(&g_intf_lock); 623 my_obj = mm_camera_util_get_camera_by_handler(handle); 624 625 if (my_obj){ 626 if (my_obj->aux_cam_obj[0] != NULL) { 627 /*Close aux cameras*/ 628 pthread_mutex_lock(&my_obj->muxer_lock); 629 pthread_mutex_unlock(&g_intf_lock); 630 rc = mm_camera_muxer_close_camera( 631 my_obj->aux_cam_obj[0]->my_hdl, my_obj); 632 pthread_mutex_lock(&g_intf_lock); 633 } 634 635 cam_idx = mm_camera_util_get_index_by_num( 636 my_obj->my_num, my_obj->my_hdl); 637 my_obj->ref_count--; 638 if(my_obj->ref_count > 0) { 639 /* still have reference to obj, return here */ 640 LOGD("ref_count=%d\n", my_obj->ref_count); 641 pthread_mutex_unlock(&g_intf_lock); 642 rc = 0; 643 } else { 644 /* need close camera here as no other reference 645 * first empty g_cam_ctrl's referent to cam_obj */ 646 g_cam_ctrl.cam_obj[cam_idx] = NULL; 647 pthread_mutex_lock(&my_obj->cam_lock); 648 pthread_mutex_unlock(&g_intf_lock); 649 rc = mm_camera_close(my_obj); 650 pthread_mutex_destroy(&my_obj->cam_lock); 651 pthread_mutex_destroy(&my_obj->muxer_lock); 652 free(my_obj); 653 my_obj = NULL; 654 } 655 } else { 656 pthread_mutex_unlock(&g_intf_lock); 657 } 658 } else { 659 pthread_mutex_unlock(&g_intf_lock); 660 } 661 662 LOGH("camera_handler = %d rc = %d", camera_handle, rc); 663 #ifdef QCAMERA_REDEFINE_LOG 664 mm_camera_debug_close(); 665 #endif 666 667 return rc; 668 } 669 670 /*=========================================================================== 671 * FUNCTION : mm_camera_intf_add_channel 672 * 673 * DESCRIPTION: add a channel 674 * 675 * PARAMETERS : 676 * @camera_handle: camera handle 677 * @attr : bundle attribute of the channel if needed 678 * @channel_cb : callback function for bundle data notify 679 * @userdata : user data ptr 680 * 681 * RETURN : uint32_t type of channel handle 682 * 0 -- invalid channel handle, meaning the op failed 683 * >0 -- successfully added a channel with a valid handle 684 * NOTE : if no bundle data notify is needed, meaning each stream in the 685 * channel will have its own stream data notify callback, then 686 * attr, channel_cb, and userdata can be NULL. In this case, 687 * no matching logic will be performed in channel for the bundling. 688 *==========================================================================*/ 689 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle, 690 mm_camera_channel_attr_t *attr, 691 mm_camera_buf_notify_t channel_cb, 692 void *userdata) 693 { 694 uint32_t ch_id = 0, aux_ch_id = 0; 695 mm_camera_obj_t * my_obj = NULL; 696 uint32_t handle = get_main_camera_handle(camera_handle); 697 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 698 699 LOGD("E camera_handler = %d", camera_handle); 700 if (handle) { 701 pthread_mutex_lock(&g_intf_lock); 702 my_obj = mm_camera_util_get_camera_by_handler(handle); 703 if(my_obj) { 704 pthread_mutex_lock(&my_obj->cam_lock); 705 pthread_mutex_unlock(&g_intf_lock); 706 ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata); 707 } else { 708 pthread_mutex_unlock(&g_intf_lock); 709 } 710 } 711 712 if (aux_handle) { 713 pthread_mutex_lock(&g_intf_lock); 714 my_obj = mm_camera_util_get_camera_head(aux_handle); 715 if (my_obj) { 716 pthread_mutex_lock(&my_obj->muxer_lock); 717 pthread_mutex_unlock(&g_intf_lock); 718 aux_ch_id = mm_camera_muxer_add_channel(aux_handle, attr, 719 channel_cb, userdata, ch_id, my_obj); 720 if (aux_ch_id <= 0) { 721 pthread_mutex_lock(&my_obj->cam_lock); 722 mm_camera_del_channel(my_obj, ch_id); 723 } else { 724 ch_id |= aux_ch_id; 725 } 726 } else { 727 pthread_mutex_unlock(&g_intf_lock); 728 } 729 } 730 LOGH("camera_handle = %d ch_id = %d X", ch_id); 731 return ch_id; 732 } 733 734 /*=========================================================================== 735 * FUNCTION : mm_camera_intf_del_channel 736 * 737 * DESCRIPTION: delete a channel by its handle 738 * 739 * PARAMETERS : 740 * @camera_handle: camera handle 741 * @ch_id : channel handle 742 * 743 * RETURN : int32_t type of status 744 * 0 -- success 745 * -1 -- failure 746 * NOTE : all streams in the channel should be stopped already before 747 * this channel can be deleted. 748 *==========================================================================*/ 749 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle, 750 uint32_t ch_id) 751 { 752 int32_t rc = -1; 753 mm_camera_obj_t * my_obj = NULL; 754 uint32_t m_chid = get_main_camera_handle(ch_id); 755 uint32_t aux_chid = get_aux_camera_handle(ch_id); 756 757 LOGD("E ch_id = %d", ch_id); 758 759 if (aux_chid) { 760 pthread_mutex_lock(&g_intf_lock); 761 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 762 my_obj = mm_camera_util_get_camera_head(aux_handle); 763 if (my_obj) { 764 pthread_mutex_lock(&my_obj->muxer_lock); 765 pthread_mutex_unlock(&g_intf_lock); 766 mm_camera_muxer_delete_channel(aux_handle, aux_chid, my_obj); 767 } else { 768 pthread_mutex_unlock(&g_intf_lock); 769 } 770 } 771 772 if (m_chid) { 773 pthread_mutex_lock(&g_intf_lock); 774 uint32_t handle = get_main_camera_handle(camera_handle); 775 my_obj = mm_camera_util_get_camera_by_handler(handle); 776 777 if(my_obj) { 778 pthread_mutex_lock(&my_obj->cam_lock); 779 pthread_mutex_unlock(&g_intf_lock); 780 rc = mm_camera_del_channel(my_obj, m_chid); 781 } else { 782 pthread_mutex_unlock(&g_intf_lock); 783 } 784 } 785 LOGH("rc = %d ch_id = %d X", rc, ch_id); 786 return rc; 787 } 788 789 /*=========================================================================== 790 * FUNCTION : mm_camera_intf_get_bundle_info 791 * 792 * DESCRIPTION: query bundle info of the channel 793 * 794 * PARAMETERS : 795 * @camera_handle: camera handle 796 * @ch_id : channel handle 797 * @bundle_info : bundle info to be filled in 798 * 799 * RETURN : int32_t type of status 800 * 0 -- success 801 * -1 -- failure 802 * NOTE : all streams in the channel should be stopped already before 803 * this channel can be deleted. 804 *==========================================================================*/ 805 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle, 806 uint32_t ch_id, 807 cam_bundle_config_t *bundle_info) 808 { 809 int32_t rc = -1; 810 mm_camera_obj_t * my_obj = NULL; 811 uint32_t m_chid = get_main_camera_handle(ch_id); 812 uint32_t aux_chid = get_aux_camera_handle(ch_id); 813 814 LOGD("E ch_id = %d", ch_id); 815 816 if (aux_chid && m_chid) { 817 LOGE("Does not support 2 channels for bundle info"); 818 return rc; 819 } 820 821 if (aux_chid) { 822 pthread_mutex_lock(&g_intf_lock); 823 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 824 my_obj = mm_camera_util_get_camera_head(aux_handle); 825 if (my_obj) { 826 pthread_mutex_lock(&my_obj->muxer_lock); 827 pthread_mutex_unlock(&g_intf_lock); 828 rc = mm_camera_muxer_get_bundle_info(aux_handle, aux_chid, 829 bundle_info, my_obj); 830 } else { 831 pthread_mutex_unlock(&g_intf_lock); 832 } 833 } else if (m_chid) { 834 pthread_mutex_lock(&g_intf_lock); 835 uint32_t handle = get_main_camera_handle(camera_handle); 836 my_obj = mm_camera_util_get_camera_by_handler(handle); 837 if(my_obj) { 838 pthread_mutex_lock(&my_obj->cam_lock); 839 pthread_mutex_unlock(&g_intf_lock); 840 rc = mm_camera_get_bundle_info(my_obj, m_chid, bundle_info); 841 } else { 842 pthread_mutex_unlock(&g_intf_lock); 843 } 844 } 845 LOGD("rc = %d ch_id = %d X", rc, ch_id); 846 return rc; 847 } 848 849 /*=========================================================================== 850 * FUNCTION : mm_camera_intf_register_event_notify 851 * 852 * DESCRIPTION: register for event notify 853 * 854 * PARAMETERS : 855 * @camera_handle: camera handle 856 * @evt_cb : callback for event notify 857 * @user_data : user data ptr 858 * 859 * RETURN : int32_t type of status 860 * 0 -- success 861 * -1 -- failure 862 *==========================================================================*/ 863 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle, 864 mm_camera_event_notify_t evt_cb, 865 void * user_data) 866 { 867 int32_t rc = -1; 868 mm_camera_obj_t *my_obj = NULL; 869 LOGD("E "); 870 871 uint32_t handle = get_main_camera_handle(camera_handle); 872 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 873 874 if (handle) { 875 pthread_mutex_lock(&g_intf_lock); 876 my_obj = mm_camera_util_get_camera_by_handler(handle); 877 878 if(my_obj) { 879 pthread_mutex_lock(&my_obj->cam_lock); 880 pthread_mutex_unlock(&g_intf_lock); 881 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data); 882 } else { 883 pthread_mutex_unlock(&g_intf_lock); 884 } 885 } 886 887 if (aux_handle) { 888 pthread_mutex_lock(&g_intf_lock); 889 my_obj = mm_camera_util_get_camera_head(aux_handle); 890 if (my_obj) { 891 pthread_mutex_lock(&my_obj->muxer_lock); 892 pthread_mutex_unlock(&g_intf_lock); 893 rc = mm_camera_muxer_register_event_notify(aux_handle, 894 evt_cb, user_data, my_obj); 895 } 896 } 897 LOGD("E rc = %d", rc); 898 return rc; 899 } 900 901 /*=========================================================================== 902 * FUNCTION : mm_camera_intf_qbuf 903 * 904 * DESCRIPTION: enqueue buffer back to kernel 905 * 906 * PARAMETERS : 907 * @camera_handle: camera handle 908 * @ch_id : channel handle 909 * @buf : buf ptr to be enqueued 910 * 911 * RETURN : int32_t type of status 912 * 0 -- success 913 * -1 -- failure 914 *==========================================================================*/ 915 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle, 916 uint32_t ch_id, 917 mm_camera_buf_def_t *buf) 918 { 919 int32_t rc = -1; 920 mm_camera_obj_t *my_obj = NULL; 921 uint32_t strid = 0; 922 uint32_t aux_strid = 0; 923 924 if (buf != NULL) { 925 strid = get_main_camera_handle(buf->stream_id); 926 aux_strid = get_aux_camera_handle(buf->stream_id); 927 } 928 929 if (strid) { 930 pthread_mutex_lock(&g_intf_lock); 931 uint32_t handle = get_main_camera_handle(camera_handle); 932 uint32_t chid = get_main_camera_handle(ch_id); 933 my_obj = mm_camera_util_get_camera_by_handler(handle); 934 if(my_obj) { 935 pthread_mutex_lock(&my_obj->cam_lock); 936 pthread_mutex_unlock(&g_intf_lock); 937 rc = mm_camera_qbuf(my_obj, chid, buf); 938 } else { 939 pthread_mutex_unlock(&g_intf_lock); 940 } 941 } 942 943 if (aux_strid) { 944 pthread_mutex_lock(&g_intf_lock); 945 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 946 uint32_t aux_chid = get_aux_camera_handle(ch_id); 947 my_obj = mm_camera_util_get_camera_head(aux_handle); 948 if (my_obj) { 949 pthread_mutex_lock(&my_obj->muxer_lock); 950 pthread_mutex_unlock(&g_intf_lock); 951 rc = mm_camera_muxer_qbuf(aux_handle, aux_chid, buf, my_obj); 952 } else { 953 pthread_mutex_unlock(&g_intf_lock); 954 } 955 } 956 LOGD("X evt_type = %d",rc); 957 return rc; 958 } 959 960 /*=========================================================================== 961 * FUNCTION : mm_camera_intf_get_queued_buf_count 962 * 963 * DESCRIPTION: returns the queued buffer count 964 * 965 * PARAMETERS : 966 * @camera_handle: camera handle 967 * @ch_id : channel handle 968 * @stream_id : stream id 969 * 970 * RETURN : int32_t - queued buffer count 971 * 972 *==========================================================================*/ 973 static int32_t mm_camera_intf_get_queued_buf_count(uint32_t camera_handle, 974 uint32_t ch_id, uint32_t stream_id) 975 { 976 int32_t rc = -1; 977 mm_camera_obj_t * my_obj = NULL; 978 uint32_t strid = get_main_camera_handle(stream_id); 979 uint32_t aux_strid = get_main_camera_handle(stream_id); 980 981 if (strid) { 982 pthread_mutex_lock(&g_intf_lock); 983 uint32_t handle = get_main_camera_handle(camera_handle); 984 uint32_t chid = get_main_camera_handle(ch_id); 985 my_obj = mm_camera_util_get_camera_by_handler(handle); 986 if(my_obj) { 987 pthread_mutex_lock(&my_obj->cam_lock); 988 pthread_mutex_unlock(&g_intf_lock); 989 rc = mm_camera_get_queued_buf_count(my_obj, chid, stream_id); 990 } else { 991 pthread_mutex_unlock(&g_intf_lock); 992 } 993 } else if (aux_strid) { 994 pthread_mutex_lock(&g_intf_lock); 995 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 996 uint32_t aux_chid = get_aux_camera_handle(ch_id); 997 my_obj = mm_camera_util_get_camera_head(aux_handle); 998 if (my_obj) { 999 pthread_mutex_lock(&my_obj->muxer_lock); 1000 pthread_mutex_unlock(&g_intf_lock); 1001 rc = mm_camera_muxer_get_queued_buf_count(aux_handle, 1002 aux_chid, aux_strid, my_obj); 1003 } else { 1004 pthread_mutex_unlock(&g_intf_lock); 1005 } 1006 } 1007 LOGD("X queued buffer count = %d",rc); 1008 return rc; 1009 } 1010 1011 /*=========================================================================== 1012 * FUNCTION : mm_camera_intf_link_stream 1013 * 1014 * DESCRIPTION: link a stream into a new channel 1015 * 1016 * PARAMETERS : 1017 * @camera_handle: camera handle 1018 * @ch_id : channel handle 1019 * @stream_id : stream id 1020 * @linked_ch_id : channel in which the stream will be linked 1021 * 1022 * RETURN : int32_t type of stream handle 1023 * 0 -- invalid stream handle, meaning the op failed 1024 * >0 -- successfully linked a stream with a valid handle 1025 *==========================================================================*/ 1026 static int32_t mm_camera_intf_link_stream(uint32_t camera_handle, 1027 uint32_t ch_id, 1028 uint32_t stream_id, 1029 uint32_t linked_ch_id) 1030 { 1031 uint32_t id = 0; 1032 mm_camera_obj_t * my_obj = NULL; 1033 uint32_t strid = get_main_camera_handle(stream_id); 1034 uint32_t aux_strid = get_aux_camera_handle(stream_id); 1035 uint32_t linked_chid = get_main_camera_handle(linked_ch_id); 1036 uint32_t aux_linked_chid = get_aux_camera_handle(linked_ch_id); 1037 1038 LOGD("E handle = %u ch_id = %u", 1039 camera_handle, ch_id); 1040 1041 if (strid && linked_chid) { 1042 pthread_mutex_lock(&g_intf_lock); 1043 uint32_t handle = get_main_camera_handle(camera_handle); 1044 uint32_t m_chid = get_main_camera_handle(ch_id); 1045 my_obj = mm_camera_util_get_camera_by_handler(handle); 1046 1047 if(my_obj) { 1048 pthread_mutex_lock(&my_obj->cam_lock); 1049 pthread_mutex_unlock(&g_intf_lock); 1050 id = mm_camera_link_stream(my_obj, m_chid, strid, linked_chid); 1051 } else { 1052 pthread_mutex_unlock(&g_intf_lock); 1053 } 1054 } 1055 1056 if (aux_strid && aux_linked_chid) { 1057 pthread_mutex_lock(&g_intf_lock); 1058 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1059 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1060 my_obj = mm_camera_util_get_camera_head(aux_handle); 1061 if (my_obj) { 1062 pthread_mutex_lock(&my_obj->muxer_lock); 1063 pthread_mutex_unlock(&g_intf_lock); 1064 id = mm_camera_muxer_link_stream(aux_handle, aux_chid, 1065 aux_strid, aux_linked_chid, my_obj); 1066 } else { 1067 pthread_mutex_unlock(&g_intf_lock); 1068 } 1069 } 1070 1071 LOGH("X ch_id = %d stream_id = %d linked_ch_id = %d id = %d", 1072 ch_id, stream_id, linked_ch_id, id); 1073 return (int32_t)id; 1074 } 1075 1076 /*=========================================================================== 1077 * FUNCTION : mm_camera_intf_add_stream 1078 * 1079 * DESCRIPTION: add a stream into a channel 1080 * 1081 * PARAMETERS : 1082 * @camera_handle: camera handle 1083 * @ch_id : channel handle 1084 * 1085 * RETURN : uint32_t type of stream handle 1086 * 0 -- invalid stream handle, meaning the op failed 1087 * >0 -- successfully added a stream with a valid handle 1088 *==========================================================================*/ 1089 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle, 1090 uint32_t ch_id) 1091 { 1092 uint32_t stream_id = 0, aux_stream_id; 1093 mm_camera_obj_t *my_obj = NULL; 1094 uint32_t m_ch_id = get_main_camera_handle(ch_id); 1095 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1096 1097 LOGD("E handle = %d ch_id = %d", 1098 camera_handle, ch_id); 1099 if (m_ch_id) { 1100 pthread_mutex_lock(&g_intf_lock); 1101 uint32_t handle = get_main_camera_handle(camera_handle); 1102 my_obj = mm_camera_util_get_camera_by_handler(handle); 1103 if(my_obj) { 1104 pthread_mutex_lock(&my_obj->cam_lock); 1105 pthread_mutex_unlock(&g_intf_lock); 1106 stream_id = mm_camera_add_stream(my_obj, m_ch_id); 1107 } else { 1108 pthread_mutex_unlock(&g_intf_lock); 1109 } 1110 } 1111 1112 if (aux_chid) { 1113 pthread_mutex_lock(&g_intf_lock); 1114 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1115 my_obj = mm_camera_util_get_camera_head(aux_handle); 1116 if (my_obj) { 1117 pthread_mutex_lock(&my_obj->muxer_lock); 1118 pthread_mutex_unlock(&g_intf_lock); 1119 aux_stream_id = mm_camera_muxer_add_stream(aux_handle, aux_chid, 1120 m_ch_id, stream_id, my_obj); 1121 if (aux_stream_id <= 0) { 1122 LOGE("Failed to add stream"); 1123 pthread_mutex_lock(&my_obj->cam_lock); 1124 mm_camera_del_stream(my_obj, m_ch_id, stream_id); 1125 } else { 1126 stream_id = stream_id | aux_stream_id; 1127 } 1128 } else { 1129 pthread_mutex_unlock(&g_intf_lock); 1130 } 1131 } 1132 LOGH("X ch_id = %d stream_id = %d", ch_id, stream_id); 1133 return stream_id; 1134 } 1135 1136 /*=========================================================================== 1137 * FUNCTION : mm_camera_intf_del_stream 1138 * 1139 * DESCRIPTION: delete a stream by its handle 1140 * 1141 * PARAMETERS : 1142 * @camera_handle: camera handle 1143 * @ch_id : channel handle 1144 * @stream_id : stream handle 1145 * 1146 * RETURN : int32_t type of status 1147 * 0 -- success 1148 * -1 -- failure 1149 * NOTE : stream should be stopped already before it can be deleted. 1150 *==========================================================================*/ 1151 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle, 1152 uint32_t ch_id, 1153 uint32_t stream_id) 1154 { 1155 int32_t rc = -1; 1156 mm_camera_obj_t * my_obj = NULL; 1157 uint32_t m_strid = get_main_camera_handle(stream_id); 1158 uint32_t aux_strid = get_aux_camera_handle(stream_id); 1159 1160 LOGD("E handle = %d ch_id = %d stream_id = %d", 1161 camera_handle, ch_id, stream_id); 1162 1163 if (aux_strid) { 1164 pthread_mutex_lock(&g_intf_lock); 1165 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1166 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1167 my_obj = mm_camera_util_get_camera_head(aux_handle); 1168 if (my_obj) { 1169 pthread_mutex_lock(&my_obj->muxer_lock); 1170 pthread_mutex_unlock(&g_intf_lock); 1171 mm_camera_muxer_delete_stream(aux_handle, aux_chid, 1172 aux_strid, my_obj); 1173 } else { 1174 pthread_mutex_unlock(&g_intf_lock); 1175 } 1176 } 1177 1178 if (m_strid) { 1179 pthread_mutex_lock(&g_intf_lock); 1180 uint32_t handle = get_main_camera_handle(camera_handle); 1181 uint32_t m_chid = get_main_camera_handle(ch_id); 1182 1183 my_obj = mm_camera_util_get_camera_by_handler(handle); 1184 if(my_obj) { 1185 pthread_mutex_lock(&my_obj->cam_lock); 1186 pthread_mutex_unlock(&g_intf_lock); 1187 rc = mm_camera_del_stream(my_obj, m_chid, m_strid); 1188 } else { 1189 pthread_mutex_unlock(&g_intf_lock); 1190 } 1191 } 1192 LOGH("X stream_id = %d rc = %d", stream_id, rc); 1193 return rc; 1194 } 1195 1196 /*=========================================================================== 1197 * FUNCTION : mm_camera_intf_config_stream 1198 * 1199 * DESCRIPTION: configure a stream 1200 * 1201 * PARAMETERS : 1202 * @camera_handle: camera handle 1203 * @ch_id : channel handle 1204 * @stream_id : stream handle 1205 * @config : stream configuration 1206 * 1207 * RETURN : int32_t type of status 1208 * 0 -- success 1209 * -1 -- failure 1210 *==========================================================================*/ 1211 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle, 1212 uint32_t ch_id, 1213 uint32_t stream_id, 1214 mm_camera_stream_config_t *config) 1215 { 1216 int32_t rc = -1; 1217 mm_camera_obj_t * my_obj = NULL; 1218 uint32_t strid = get_main_camera_handle(stream_id); 1219 uint32_t aux_strid = get_aux_camera_handle(stream_id); 1220 1221 LOGD("E handle = %d, ch_id = %d,stream_id = %d", 1222 camera_handle, ch_id, stream_id); 1223 1224 if (strid) { 1225 pthread_mutex_lock(&g_intf_lock); 1226 uint32_t handle = get_main_camera_handle(camera_handle); 1227 uint32_t chid = get_main_camera_handle(ch_id); 1228 1229 my_obj = mm_camera_util_get_camera_by_handler(handle); 1230 if(my_obj) { 1231 pthread_mutex_lock(&my_obj->cam_lock); 1232 pthread_mutex_unlock(&g_intf_lock); 1233 rc = mm_camera_config_stream(my_obj, chid, strid, config); 1234 } else { 1235 pthread_mutex_unlock(&g_intf_lock); 1236 } 1237 } 1238 1239 if (aux_strid && rc == 0) { 1240 pthread_mutex_lock(&g_intf_lock); 1241 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1242 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1243 1244 my_obj = mm_camera_util_get_camera_head(aux_handle); 1245 if (my_obj) { 1246 pthread_mutex_lock(&my_obj->muxer_lock); 1247 pthread_mutex_unlock(&g_intf_lock); 1248 rc = mm_camera_muxer_config_stream(aux_handle, 1249 aux_chid, aux_strid, config, my_obj); 1250 } else { 1251 pthread_mutex_unlock(&g_intf_lock); 1252 } 1253 } 1254 LOGH("X stream_id = %d rc = %d", stream_id, rc); 1255 return rc; 1256 } 1257 1258 /*=========================================================================== 1259 * FUNCTION : mm_camera_intf_start_channel 1260 * 1261 * DESCRIPTION: start a channel, which will start all streams in the channel 1262 * 1263 * PARAMETERS : 1264 * @camera_handle: camera handle 1265 * @ch_id : channel handle 1266 * 1267 * RETURN : int32_t type of status 1268 * 0 -- success 1269 * -1 -- failure 1270 *==========================================================================*/ 1271 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle, 1272 uint32_t ch_id) 1273 { 1274 int32_t rc = -1; 1275 mm_camera_obj_t * my_obj = NULL; 1276 uint32_t chid = get_main_camera_handle(ch_id); 1277 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1278 1279 if (chid) { 1280 uint32_t handle = get_main_camera_handle(camera_handle); 1281 pthread_mutex_lock(&g_intf_lock); 1282 1283 my_obj = mm_camera_util_get_camera_by_handler(handle); 1284 if(my_obj) { 1285 pthread_mutex_lock(&my_obj->cam_lock); 1286 pthread_mutex_unlock(&g_intf_lock); 1287 rc = mm_camera_start_channel(my_obj, chid); 1288 } else { 1289 pthread_mutex_unlock(&g_intf_lock); 1290 } 1291 } 1292 1293 if (aux_chid && rc == 0) { 1294 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1295 pthread_mutex_lock(&g_intf_lock); 1296 1297 my_obj = mm_camera_util_get_camera_head(aux_handle); 1298 if(my_obj) { 1299 pthread_mutex_lock(&my_obj->muxer_lock); 1300 pthread_mutex_unlock(&g_intf_lock); 1301 rc = mm_camera_muxer_start_channel(aux_handle, aux_chid, my_obj); 1302 } else { 1303 pthread_mutex_unlock(&g_intf_lock); 1304 } 1305 } 1306 LOGH("X ch_id = %d rc = %d", ch_id, rc); 1307 return rc; 1308 } 1309 1310 /*=========================================================================== 1311 * FUNCTION : mm_camera_intf_stop_channel 1312 * 1313 * DESCRIPTION: stop a channel, which will stop all streams in the channel 1314 * 1315 * PARAMETERS : 1316 * @camera_handle: camera handle 1317 * @ch_id : channel handle 1318 * 1319 * RETURN : int32_t type of status 1320 * 0 -- success 1321 * -1 -- failure 1322 *==========================================================================*/ 1323 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle, 1324 uint32_t ch_id) 1325 { 1326 int32_t rc = -1; 1327 mm_camera_obj_t * my_obj = NULL; 1328 uint32_t chid = get_main_camera_handle(ch_id); 1329 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1330 1331 if (aux_chid) { 1332 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1333 pthread_mutex_lock(&g_intf_lock); 1334 1335 my_obj = mm_camera_util_get_camera_head(aux_handle); 1336 if(my_obj) { 1337 pthread_mutex_lock(&my_obj->muxer_lock); 1338 pthread_mutex_unlock(&g_intf_lock); 1339 rc = mm_camera_muxer_stop_channel(aux_handle, aux_chid, my_obj); 1340 } else { 1341 pthread_mutex_unlock(&g_intf_lock); 1342 } 1343 } 1344 1345 if (chid) { 1346 uint32_t handle = get_main_camera_handle(camera_handle); 1347 pthread_mutex_lock(&g_intf_lock); 1348 1349 my_obj = mm_camera_util_get_camera_by_handler(handle); 1350 if(my_obj) { 1351 pthread_mutex_lock(&my_obj->cam_lock); 1352 pthread_mutex_unlock(&g_intf_lock); 1353 rc = mm_camera_stop_channel(my_obj, chid); 1354 } else { 1355 pthread_mutex_unlock(&g_intf_lock); 1356 } 1357 } 1358 LOGH("X ch_id = %d rc = %d", ch_id, rc); 1359 return rc; 1360 1361 } 1362 1363 /*=========================================================================== 1364 * FUNCTION : mm_camera_intf_request_super_buf 1365 * 1366 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 1367 * frames from superbuf queue 1368 * 1369 * PARAMETERS : 1370 * @camera_handle: camera handle 1371 * @ch_id : channel handle 1372 * @buf : request buffer info 1373 * 1374 * RETURN : int32_t type of status 1375 * 0 -- success 1376 * -1 -- failure 1377 *==========================================================================*/ 1378 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle, 1379 uint32_t ch_id, mm_camera_req_buf_t *buf) 1380 { 1381 int32_t rc = -1; 1382 LOGD("E camera_handler = %d,ch_id = %d", 1383 camera_handle, ch_id); 1384 mm_camera_obj_t * my_obj = NULL; 1385 uint32_t chid = get_main_camera_handle(ch_id); 1386 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1387 1388 pthread_mutex_lock(&g_intf_lock); 1389 if (aux_chid && chid) { 1390 uint32_t handle = get_main_camera_handle(camera_handle); 1391 my_obj = mm_camera_util_get_camera_by_handler(handle); 1392 if (my_obj && buf) { 1393 pthread_mutex_lock(&my_obj->muxer_lock); 1394 pthread_mutex_unlock(&g_intf_lock); 1395 rc = mm_camera_muxer_request_super_buf( 1396 ch_id, buf, my_obj); 1397 } else { 1398 pthread_mutex_unlock(&g_intf_lock); 1399 } 1400 } else if (chid) { 1401 uint32_t handle = get_main_camera_handle(camera_handle); 1402 my_obj = mm_camera_util_get_camera_by_handler(handle); 1403 1404 if(my_obj && buf) { 1405 pthread_mutex_lock(&my_obj->cam_lock); 1406 pthread_mutex_unlock(&g_intf_lock); 1407 rc = mm_camera_request_super_buf (my_obj, chid, buf); 1408 } else { 1409 pthread_mutex_unlock(&g_intf_lock); 1410 } 1411 } else if (aux_chid) { 1412 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1413 my_obj = mm_camera_util_get_camera_by_handler(aux_handle); 1414 1415 if(my_obj && buf) { 1416 pthread_mutex_lock(&my_obj->cam_lock); 1417 pthread_mutex_unlock(&g_intf_lock); 1418 rc = mm_camera_request_super_buf (my_obj, aux_chid, buf); 1419 } else { 1420 pthread_mutex_unlock(&g_intf_lock); 1421 } 1422 } 1423 1424 LOGH("X ch_id = %d rc = %d", ch_id, rc); 1425 return rc; 1426 } 1427 1428 /*=========================================================================== 1429 * FUNCTION : mm_camera_intf_cancel_super_buf_request 1430 * 1431 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 1432 * of matched frames from superbuf queue 1433 * 1434 * PARAMETERS : 1435 * @camera_handle: camera handle 1436 * @ch_id : channel handle 1437 * 1438 * RETURN : int32_t type of status 1439 * 0 -- success 1440 * -1 -- failure 1441 *==========================================================================*/ 1442 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle, 1443 uint32_t ch_id) 1444 { 1445 int32_t rc = -1; 1446 LOGD("E camera_handler = %d,ch_id = %d", 1447 camera_handle, ch_id); 1448 mm_camera_obj_t * my_obj = NULL; 1449 uint32_t chid = get_main_camera_handle(ch_id); 1450 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1451 1452 pthread_mutex_lock(&g_intf_lock); 1453 if (aux_chid && chid) { 1454 my_obj = mm_camera_util_get_camera_head(camera_handle); 1455 if (my_obj) { 1456 pthread_mutex_lock(&my_obj->muxer_lock); 1457 pthread_mutex_unlock(&g_intf_lock); 1458 rc = mm_camera_muxer_cancel_super_buf_request( 1459 camera_handle, ch_id, my_obj); 1460 } else { 1461 pthread_mutex_unlock(&g_intf_lock); 1462 } 1463 } else if (aux_chid) { 1464 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1465 my_obj = mm_camera_util_get_camera_by_handler(aux_handle); 1466 1467 if(my_obj) { 1468 pthread_mutex_lock(&my_obj->cam_lock); 1469 pthread_mutex_unlock(&g_intf_lock); 1470 rc = mm_camera_cancel_super_buf_request(my_obj, chid); 1471 } else { 1472 pthread_mutex_unlock(&g_intf_lock); 1473 } 1474 } else if (chid) { 1475 uint32_t handle = get_main_camera_handle(camera_handle); 1476 my_obj = mm_camera_util_get_camera_by_handler(handle); 1477 1478 if(my_obj) { 1479 pthread_mutex_lock(&my_obj->cam_lock); 1480 pthread_mutex_unlock(&g_intf_lock); 1481 rc = mm_camera_cancel_super_buf_request(my_obj, chid); 1482 } else { 1483 pthread_mutex_unlock(&g_intf_lock); 1484 } 1485 } 1486 1487 LOGH("X ch_id = %d rc = %d", ch_id, rc); 1488 return rc; 1489 } 1490 1491 /*=========================================================================== 1492 * FUNCTION : mm_camera_intf_flush_super_buf_queue 1493 * 1494 * DESCRIPTION: flush out all frames in the superbuf queue 1495 * 1496 * PARAMETERS : 1497 * @camera_handle: camera handle 1498 * @ch_id : channel handle 1499 * @frame_idx : frame index 1500 * 1501 * RETURN : int32_t type of status 1502 * 0 -- success 1503 * -1 -- failure 1504 *==========================================================================*/ 1505 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle, 1506 uint32_t ch_id, uint32_t frame_idx) 1507 { 1508 int32_t rc = -1; 1509 mm_camera_obj_t * my_obj = NULL; 1510 uint32_t chid = get_main_camera_handle(ch_id); 1511 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1512 1513 LOGD("E camera_handler = %d,ch_id = %d", 1514 camera_handle, ch_id); 1515 if (chid) { 1516 pthread_mutex_lock(&g_intf_lock); 1517 uint32_t handle = get_main_camera_handle(camera_handle); 1518 my_obj = mm_camera_util_get_camera_by_handler(handle); 1519 if(my_obj) { 1520 pthread_mutex_lock(&my_obj->cam_lock); 1521 pthread_mutex_unlock(&g_intf_lock); 1522 rc = mm_camera_flush_super_buf_queue(my_obj, chid, frame_idx); 1523 } else { 1524 pthread_mutex_unlock(&g_intf_lock); 1525 } 1526 } 1527 1528 if (aux_chid) { 1529 pthread_mutex_lock(&g_intf_lock); 1530 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1531 my_obj = mm_camera_util_get_camera_head(aux_handle); 1532 if (my_obj) { 1533 pthread_mutex_lock(&my_obj->muxer_lock); 1534 pthread_mutex_unlock(&g_intf_lock); 1535 rc = mm_camera_muxer_flush_super_buf_queue(aux_handle, 1536 aux_chid, frame_idx, my_obj); 1537 } else { 1538 pthread_mutex_unlock(&g_intf_lock); 1539 } 1540 } 1541 1542 LOGH("X ch_id = %d rc = %d", ch_id, rc); 1543 return rc; 1544 } 1545 1546 /*=========================================================================== 1547 * FUNCTION : mm_camera_intf_start_zsl_snapshot 1548 * 1549 * DESCRIPTION: Starts zsl snapshot 1550 * 1551 * PARAMETERS : 1552 * @camera_handle: camera handle 1553 * @ch_id : channel handle 1554 * 1555 * RETURN : int32_t type of status 1556 * 0 -- success 1557 * -1 -- failure 1558 *==========================================================================*/ 1559 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle, 1560 uint32_t ch_id) 1561 { 1562 int32_t rc = -1; 1563 mm_camera_obj_t *my_obj = NULL; 1564 uint32_t m_chid = get_main_camera_handle(ch_id); 1565 uint32_t aux_ch_id = get_aux_camera_handle(ch_id); 1566 1567 LOGD("E camera_handler = %d,ch_id = %d", 1568 camera_handle, ch_id); 1569 1570 if (aux_ch_id) { 1571 pthread_mutex_lock(&g_intf_lock); 1572 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1573 my_obj = mm_camera_util_get_camera_head(aux_handle); 1574 if(my_obj) { 1575 pthread_mutex_lock(&my_obj->muxer_lock); 1576 pthread_mutex_unlock(&g_intf_lock); 1577 rc = mm_camera_muxer_start_zsl_snapshot(aux_handle, 1578 aux_ch_id, my_obj); 1579 } else { 1580 pthread_mutex_unlock(&g_intf_lock); 1581 } 1582 } 1583 1584 if (m_chid) { 1585 uint32_t m_handle = get_main_camera_handle(camera_handle); 1586 pthread_mutex_lock(&g_intf_lock); 1587 my_obj = mm_camera_util_get_camera_by_handler(m_handle); 1588 if(my_obj) { 1589 pthread_mutex_lock(&my_obj->cam_lock); 1590 pthread_mutex_unlock(&g_intf_lock); 1591 rc = mm_camera_start_zsl_snapshot_ch(my_obj, m_chid); 1592 } else { 1593 pthread_mutex_unlock(&g_intf_lock); 1594 } 1595 } 1596 LOGD("X rc = %d", rc); 1597 return rc; 1598 } 1599 1600 /*=========================================================================== 1601 * FUNCTION : mm_camera_intf_stop_zsl_snapshot 1602 * 1603 * DESCRIPTION: Stops zsl snapshot 1604 * 1605 * PARAMETERS : 1606 * @camera_handle: camera handle 1607 * @ch_id : channel handle 1608 * 1609 * RETURN : int32_t type of status 1610 * 0 -- success 1611 * -1 -- failure 1612 *==========================================================================*/ 1613 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle, 1614 uint32_t ch_id) 1615 { 1616 int32_t rc = -1; 1617 mm_camera_obj_t * my_obj = NULL; 1618 uint32_t m_chid = get_main_camera_handle(ch_id); 1619 uint32_t aux_ch_id = get_aux_camera_handle(ch_id); 1620 1621 LOGD("E camera_handler = %d,ch_id = %d", 1622 camera_handle, ch_id); 1623 1624 if (aux_ch_id) { 1625 pthread_mutex_lock(&g_intf_lock); 1626 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1627 my_obj = mm_camera_util_get_camera_head(aux_handle); 1628 if(my_obj) { 1629 pthread_mutex_lock(&my_obj->muxer_lock); 1630 pthread_mutex_unlock(&g_intf_lock); 1631 rc = mm_camera_muxer_stop_zsl_snapshot(aux_handle, aux_ch_id, my_obj); 1632 } else { 1633 pthread_mutex_unlock(&g_intf_lock); 1634 } 1635 } 1636 1637 if (ch_id) { 1638 pthread_mutex_lock(&g_intf_lock); 1639 uint32_t handle = get_main_camera_handle(camera_handle); 1640 my_obj = mm_camera_util_get_camera_by_handler(handle); 1641 if(my_obj) { 1642 pthread_mutex_lock(&my_obj->cam_lock); 1643 pthread_mutex_unlock(&g_intf_lock); 1644 rc = mm_camera_stop_zsl_snapshot_ch(my_obj, m_chid); 1645 } else { 1646 pthread_mutex_unlock(&g_intf_lock); 1647 } 1648 } 1649 1650 LOGD("X rc = %d", rc); 1651 return rc; 1652 } 1653 1654 /*=========================================================================== 1655 * FUNCTION : mm_camera_intf_configure_notify_mode 1656 * 1657 * DESCRIPTION: Configures channel notification mode 1658 * 1659 * PARAMETERS : 1660 * @camera_handle: camera handle 1661 * @ch_id : channel handle 1662 * @notify_mode : notification mode 1663 * 1664 * RETURN : int32_t type of status 1665 * 0 -- success 1666 * -1 -- failure 1667 *==========================================================================*/ 1668 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle, 1669 uint32_t ch_id, 1670 mm_camera_super_buf_notify_mode_t notify_mode) 1671 { 1672 int32_t rc = -1; 1673 mm_camera_obj_t * my_obj = NULL; 1674 uint32_t chid = get_main_camera_handle(ch_id); 1675 uint32_t aux_ch_id = get_aux_camera_handle(ch_id); 1676 1677 LOGD("E camera_handler = %d,ch_id = %d", 1678 camera_handle, ch_id); 1679 1680 if (aux_ch_id) { 1681 pthread_mutex_lock(&g_intf_lock); 1682 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1683 my_obj = mm_camera_util_get_camera_head(aux_handle); 1684 if(my_obj) { 1685 pthread_mutex_lock(&my_obj->cam_lock); 1686 pthread_mutex_unlock(&g_intf_lock); 1687 rc = mm_camera_muxer_configure_notify_mode(aux_handle, aux_ch_id, 1688 notify_mode, my_obj); 1689 } else { 1690 pthread_mutex_unlock(&g_intf_lock); 1691 } 1692 } 1693 1694 if (chid) { 1695 pthread_mutex_lock(&g_intf_lock); 1696 uint32_t handle = get_main_camera_handle(camera_handle); 1697 my_obj = mm_camera_util_get_camera_by_handler(handle); 1698 if(my_obj) { 1699 pthread_mutex_lock(&my_obj->muxer_lock); 1700 pthread_mutex_unlock(&g_intf_lock); 1701 rc = mm_camera_config_channel_notify(my_obj, chid, 1702 notify_mode); 1703 } else { 1704 pthread_mutex_unlock(&g_intf_lock); 1705 } 1706 } 1707 LOGD("X rc = %d", rc); 1708 return rc; 1709 } 1710 1711 /*=========================================================================== 1712 * FUNCTION : mm_camera_intf_map_buf 1713 * 1714 * DESCRIPTION: mapping camera buffer via domain socket to server 1715 * 1716 * PARAMETERS : 1717 * @camera_handle: camera handle 1718 * @buf_type : type of buffer to be mapped. could be following values: 1719 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1720 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1721 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1722 * @fd : file descriptor of the buffer 1723 * @size : size of the buffer 1724 * 1725 * RETURN : int32_t type of status 1726 * 0 -- success 1727 * -1 -- failure 1728 *==========================================================================*/ 1729 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle, 1730 uint8_t buf_type, int fd, size_t size, void *buffer) 1731 { 1732 int32_t rc = -1; 1733 mm_camera_obj_t *my_obj = NULL; 1734 uint32_t handle = get_main_camera_handle(camera_handle); 1735 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1736 1737 if (handle) { 1738 pthread_mutex_lock(&g_intf_lock); 1739 my_obj = mm_camera_util_get_camera_by_handler(handle); 1740 1741 if(my_obj) { 1742 pthread_mutex_lock(&my_obj->cam_lock); 1743 pthread_mutex_unlock(&g_intf_lock); 1744 rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer); 1745 } else { 1746 pthread_mutex_unlock(&g_intf_lock); 1747 } 1748 } else if (aux_handle) { 1749 pthread_mutex_lock(&g_intf_lock); 1750 my_obj = mm_camera_util_get_camera_head(aux_handle); 1751 if(my_obj) { 1752 pthread_mutex_lock(&my_obj->muxer_lock); 1753 pthread_mutex_unlock(&g_intf_lock); 1754 rc = mm_camera_muxer_map_buf(aux_handle, buf_type, 1755 fd, size, buffer, my_obj); 1756 } else { 1757 pthread_mutex_unlock(&g_intf_lock); 1758 } 1759 } 1760 return rc; 1761 } 1762 1763 /*=========================================================================== 1764 * FUNCTION : mm_camera_intf_map_bufs 1765 * 1766 * DESCRIPTION: mapping camera buffer via domain socket to server 1767 * 1768 * PARAMETERS : 1769 * @camera_handle: camera handle 1770 * @buf_type : type of buffer to be mapped. could be following values: 1771 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1772 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1773 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1774 * 1775 * RETURN : int32_t type of status 1776 * 0 -- success 1777 * -1 -- failure 1778 *==========================================================================*/ 1779 static int32_t mm_camera_intf_map_bufs(uint32_t camera_handle, 1780 const cam_buf_map_type_list *buf_map_list) 1781 { 1782 int32_t rc = -1; 1783 mm_camera_obj_t * my_obj = NULL; 1784 uint32_t handle = get_main_camera_handle(camera_handle); 1785 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1786 1787 if (handle) { 1788 pthread_mutex_lock(&g_intf_lock); 1789 my_obj = mm_camera_util_get_camera_by_handler(handle); 1790 if(my_obj) { 1791 pthread_mutex_lock(&my_obj->cam_lock); 1792 pthread_mutex_unlock(&g_intf_lock); 1793 rc = mm_camera_map_bufs(my_obj, buf_map_list); 1794 } else { 1795 pthread_mutex_unlock(&g_intf_lock); 1796 } 1797 } else if (aux_handle) { 1798 pthread_mutex_lock(&g_intf_lock); 1799 my_obj = mm_camera_util_get_camera_head(aux_handle); 1800 if(my_obj) { 1801 pthread_mutex_lock(&my_obj->muxer_lock); 1802 pthread_mutex_unlock(&g_intf_lock); 1803 rc = mm_camera_muxer_map_bufs(aux_handle, buf_map_list, my_obj); 1804 } else { 1805 pthread_mutex_unlock(&g_intf_lock); 1806 } 1807 } 1808 return rc; 1809 } 1810 1811 /*=========================================================================== 1812 * FUNCTION : mm_camera_intf_unmap_buf 1813 * 1814 * DESCRIPTION: unmapping camera buffer via domain socket to server 1815 * 1816 * PARAMETERS : 1817 * @camera_handle: camera handle 1818 * @buf_type : type of buffer to be unmapped. could be following values: 1819 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1820 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1821 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1822 * 1823 * RETURN : int32_t type of status 1824 * 0 -- success 1825 * -1 -- failure 1826 *==========================================================================*/ 1827 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle, 1828 uint8_t buf_type) 1829 { 1830 int32_t rc = -1; 1831 mm_camera_obj_t * my_obj = NULL; 1832 uint32_t handle = get_main_camera_handle(camera_handle); 1833 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1834 1835 if (handle) { 1836 pthread_mutex_lock(&g_intf_lock); 1837 my_obj = mm_camera_util_get_camera_by_handler(handle); 1838 1839 if(my_obj) { 1840 pthread_mutex_lock(&my_obj->cam_lock); 1841 pthread_mutex_unlock(&g_intf_lock); 1842 rc = mm_camera_unmap_buf(my_obj, buf_type); 1843 } else { 1844 pthread_mutex_unlock(&g_intf_lock); 1845 } 1846 } 1847 1848 if (aux_handle) { 1849 pthread_mutex_lock(&g_intf_lock); 1850 my_obj = mm_camera_util_get_camera_head(aux_handle); 1851 if(my_obj) { 1852 pthread_mutex_lock(&my_obj->muxer_lock); 1853 pthread_mutex_unlock(&g_intf_lock); 1854 rc = mm_camera_muxer_unmap_buf(aux_handle, buf_type, my_obj); 1855 } else { 1856 pthread_mutex_unlock(&g_intf_lock); 1857 } 1858 } 1859 return rc; 1860 } 1861 1862 /*=========================================================================== 1863 * FUNCTION : mm_camera_intf_set_stream_parms 1864 * 1865 * DESCRIPTION: set parameters per stream 1866 * 1867 * PARAMETERS : 1868 * @camera_handle: camera handle 1869 * @ch_id : channel handle 1870 * @s_id : stream handle 1871 * @parms : ptr to a param struct to be set to server 1872 * 1873 * RETURN : int32_t type of status 1874 * 0 -- success 1875 * -1 -- failure 1876 * NOTE : Assume the parms struct buf is already mapped to server via 1877 * domain socket. Corresponding fields of parameters to be set 1878 * are already filled in by upper layer caller. 1879 *==========================================================================*/ 1880 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle, 1881 uint32_t ch_id, 1882 uint32_t s_id, 1883 cam_stream_parm_buffer_t *parms) 1884 { 1885 int32_t rc = -1; 1886 mm_camera_obj_t * my_obj = NULL; 1887 uint32_t strid = get_main_camera_handle(s_id); 1888 uint32_t aux_strid = get_aux_camera_handle(s_id); 1889 1890 LOGD("E camera_handle = %d,ch_id = %d,s_id = %d", 1891 camera_handle, ch_id, s_id); 1892 if (strid) { 1893 pthread_mutex_lock(&g_intf_lock); 1894 uint32_t handle = get_main_camera_handle(camera_handle); 1895 uint32_t chid = get_main_camera_handle(ch_id); 1896 1897 my_obj = mm_camera_util_get_camera_by_handler(handle); 1898 if(my_obj) { 1899 pthread_mutex_lock(&my_obj->cam_lock); 1900 pthread_mutex_unlock(&g_intf_lock); 1901 rc = mm_camera_set_stream_parms(my_obj, chid, strid, parms); 1902 } else { 1903 pthread_mutex_unlock(&g_intf_lock); 1904 } 1905 } 1906 1907 if (aux_strid) { 1908 pthread_mutex_lock(&g_intf_lock); 1909 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1910 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1911 my_obj = mm_camera_util_get_camera_head(aux_handle); 1912 1913 if (my_obj) { 1914 pthread_mutex_lock(&my_obj->muxer_lock); 1915 pthread_mutex_unlock(&g_intf_lock); 1916 rc = mm_camera_muxer_set_stream_parms(aux_handle, aux_chid, 1917 aux_strid, parms, my_obj); 1918 } else { 1919 pthread_mutex_unlock(&g_intf_lock); 1920 } 1921 } 1922 LOGD("X rc = %d", rc); 1923 return rc; 1924 } 1925 1926 /*=========================================================================== 1927 * FUNCTION : mm_camera_intf_get_stream_parms 1928 * 1929 * DESCRIPTION: get parameters per stream 1930 * 1931 * PARAMETERS : 1932 * @camera_handle: camera handle 1933 * @ch_id : channel handle 1934 * @s_id : stream handle 1935 * @parms : ptr to a param struct to be get from server 1936 * 1937 * RETURN : int32_t type of status 1938 * 0 -- success 1939 * -1 -- failure 1940 * NOTE : Assume the parms struct buf is already mapped to server via 1941 * domain socket. Parameters to be get from server are already 1942 * filled in by upper layer caller. After this call, corresponding 1943 * fields of requested parameters will be filled in by server with 1944 * detailed information. 1945 *==========================================================================*/ 1946 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle, 1947 uint32_t ch_id, 1948 uint32_t s_id, 1949 cam_stream_parm_buffer_t *parms) 1950 { 1951 int32_t rc = -1; 1952 mm_camera_obj_t * my_obj = NULL; 1953 uint32_t strid = get_main_camera_handle(s_id); 1954 uint32_t aux_strid = get_aux_camera_handle(s_id); 1955 1956 LOGD("E camera_handle = %d,ch_id = %d,s_id = %d", 1957 camera_handle, ch_id, s_id); 1958 if (strid) { 1959 pthread_mutex_lock(&g_intf_lock); 1960 uint32_t handle = get_main_camera_handle(camera_handle); 1961 uint32_t chid = get_main_camera_handle(ch_id); 1962 1963 my_obj = mm_camera_util_get_camera_by_handler(handle); 1964 if(my_obj) { 1965 pthread_mutex_lock(&my_obj->cam_lock); 1966 pthread_mutex_unlock(&g_intf_lock); 1967 rc = mm_camera_get_stream_parms(my_obj, chid, strid, parms); 1968 } else { 1969 pthread_mutex_unlock(&g_intf_lock); 1970 } 1971 } 1972 1973 if (aux_strid) { 1974 pthread_mutex_lock(&g_intf_lock); 1975 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 1976 uint32_t aux_chid = get_aux_camera_handle(ch_id); 1977 1978 my_obj = mm_camera_util_get_camera_head(aux_handle); 1979 if (my_obj) { 1980 pthread_mutex_lock(&my_obj->muxer_lock); 1981 pthread_mutex_unlock(&g_intf_lock); 1982 rc = mm_camera_muxer_get_stream_parms(aux_handle, aux_chid, 1983 aux_strid, parms, my_obj); 1984 } else { 1985 pthread_mutex_unlock(&g_intf_lock); 1986 } 1987 } 1988 LOGD("X rc = %d", rc); 1989 return rc; 1990 } 1991 1992 /*=========================================================================== 1993 * FUNCTION : mm_camera_intf_map_stream_buf 1994 * 1995 * DESCRIPTION: mapping stream buffer via domain socket to server 1996 * 1997 * PARAMETERS : 1998 * @camera_handle: camera handle 1999 * @ch_id : channel handle 2000 * @s_id : stream handle 2001 * @buf_type : type of buffer to be mapped. could be following values: 2002 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 2003 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 2004 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 2005 * @buf_idx : index of buffer within the stream buffers, only valid if 2006 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 2007 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 2008 * @plane_idx : plane index. If all planes share the same fd, 2009 * plane_idx = -1; otherwise, plean_idx is the 2010 * index to plane (0..num_of_planes) 2011 * @fd : file descriptor of the buffer 2012 * @size : size of the buffer 2013 * 2014 * RETURN : int32_t type of status 2015 * 0 -- success 2016 * -1 -- failure 2017 *==========================================================================*/ 2018 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle, 2019 uint32_t ch_id, uint32_t stream_id, uint8_t buf_type, 2020 uint32_t buf_idx, int32_t plane_idx, int fd, 2021 size_t size, void *buffer) 2022 { 2023 int32_t rc = -1; 2024 mm_camera_obj_t * my_obj = NULL; 2025 uint32_t strid = get_main_camera_handle(stream_id); 2026 uint32_t aux_strid = get_aux_camera_handle(stream_id); 2027 2028 LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 2029 camera_handle, ch_id, stream_id, buf_idx, plane_idx); 2030 2031 if (strid) { 2032 pthread_mutex_lock(&g_intf_lock); 2033 uint32_t handle = get_main_camera_handle(camera_handle); 2034 uint32_t chid = get_main_camera_handle(ch_id); 2035 my_obj = mm_camera_util_get_camera_by_handler(handle); 2036 2037 if(my_obj) { 2038 pthread_mutex_lock(&my_obj->cam_lock); 2039 pthread_mutex_unlock(&g_intf_lock); 2040 rc = mm_camera_map_stream_buf(my_obj, chid, strid, 2041 buf_type, buf_idx, plane_idx, 2042 fd, size, buffer); 2043 } else { 2044 pthread_mutex_unlock(&g_intf_lock); 2045 } 2046 } 2047 2048 if (aux_strid) { 2049 pthread_mutex_lock(&g_intf_lock); 2050 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 2051 uint32_t aux_chid = get_aux_camera_handle(ch_id); 2052 my_obj = mm_camera_util_get_camera_head(aux_handle); 2053 if (my_obj) { 2054 pthread_mutex_lock(&my_obj->muxer_lock); 2055 pthread_mutex_unlock(&g_intf_lock); 2056 rc = mm_camera_muxer_map_stream_buf(aux_handle, aux_chid, 2057 aux_strid, buf_type, buf_idx, plane_idx, fd, size, 2058 buffer, my_obj); 2059 } else { 2060 pthread_mutex_unlock(&g_intf_lock); 2061 } 2062 } 2063 2064 LOGD("X rc = %d", rc); 2065 return rc; 2066 } 2067 2068 /*=========================================================================== 2069 * FUNCTION : mm_camera_intf_map_stream_bufs 2070 * 2071 * DESCRIPTION: mapping stream buffers via domain socket to server 2072 * 2073 * PARAMETERS : 2074 * @camera_handle: camera handle 2075 * @ch_id : channel handle 2076 * @buf_map_list : list of buffers to be mapped 2077 * 2078 * RETURN : int32_t type of status 2079 * 0 -- success 2080 * -1 -- failure 2081 *==========================================================================*/ 2082 static int32_t mm_camera_intf_map_stream_bufs(uint32_t camera_handle, 2083 uint32_t ch_id, 2084 const cam_buf_map_type_list *buf_map_list) 2085 { 2086 int32_t rc = -1; 2087 uint32_t i; 2088 mm_camera_obj_t * my_obj = NULL; 2089 cam_buf_map_type_list m_buf_list, aux_buf_list; 2090 2091 LOGD("E camera_handle = %d, ch_id = %d", 2092 camera_handle, ch_id); 2093 2094 memset(&m_buf_list, 0, sizeof(m_buf_list)); 2095 memset(&aux_buf_list, 0, sizeof(m_buf_list)); 2096 for (i = 0; i < buf_map_list->length; i++) { 2097 uint32_t strid = get_main_camera_handle(buf_map_list->buf_maps[i].stream_id); 2098 uint32_t aux_strid = get_aux_camera_handle(buf_map_list->buf_maps[i].stream_id); 2099 if (strid) { 2100 m_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i]; 2101 m_buf_list.buf_maps[aux_buf_list.length].stream_id = strid; 2102 m_buf_list.length++; 2103 } 2104 if (aux_strid) { 2105 aux_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i]; 2106 aux_buf_list.buf_maps[aux_buf_list.length].stream_id = aux_strid; 2107 aux_buf_list.length++; 2108 } 2109 } 2110 2111 if(m_buf_list.length != 0) { 2112 pthread_mutex_lock(&g_intf_lock); 2113 uint32_t handle = get_main_camera_handle(camera_handle); 2114 uint32_t chid = get_main_camera_handle(ch_id); 2115 my_obj = mm_camera_util_get_camera_by_handler(handle); 2116 if(my_obj) { 2117 pthread_mutex_lock(&my_obj->cam_lock); 2118 pthread_mutex_unlock(&g_intf_lock); 2119 rc = mm_camera_map_stream_bufs(my_obj, chid, &m_buf_list); 2120 }else{ 2121 pthread_mutex_unlock(&g_intf_lock); 2122 } 2123 } 2124 2125 if(aux_buf_list.length != 0) { 2126 pthread_mutex_lock(&g_intf_lock); 2127 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 2128 uint32_t aux_chid = get_aux_camera_handle(ch_id); 2129 my_obj = mm_camera_util_get_camera_head(aux_handle); 2130 if (my_obj != NULL) { 2131 pthread_mutex_lock(&my_obj->muxer_lock); 2132 pthread_mutex_unlock(&g_intf_lock); 2133 rc = mm_camera_muxer_map_stream_bufs(aux_handle,aux_chid, 2134 &aux_buf_list, my_obj); 2135 } else { 2136 pthread_mutex_unlock(&g_intf_lock); 2137 } 2138 } 2139 LOGD("X rc = %d", rc); 2140 return rc; 2141 } 2142 2143 /*=========================================================================== 2144 * FUNCTION : mm_camera_intf_unmap_stream_buf 2145 * 2146 * DESCRIPTION: unmapping stream buffer via domain socket to server 2147 * 2148 * PARAMETERS : 2149 * @camera_handle: camera handle 2150 * @ch_id : channel handle 2151 * @s_id : stream handle 2152 * @buf_type : type of buffer to be unmapped. could be following values: 2153 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 2154 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 2155 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 2156 * @buf_idx : index of buffer within the stream buffers, only valid if 2157 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 2158 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 2159 * @plane_idx : plane index. If all planes share the same fd, 2160 * plane_idx = -1; otherwise, plean_idx is the 2161 * index to plane (0..num_of_planes) 2162 * 2163 * RETURN : int32_t type of status 2164 * 0 -- success 2165 * -1 -- failure 2166 *==========================================================================*/ 2167 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle, 2168 uint32_t ch_id, 2169 uint32_t stream_id, 2170 uint8_t buf_type, 2171 uint32_t buf_idx, 2172 int32_t plane_idx) 2173 { 2174 int32_t rc = -1; 2175 mm_camera_obj_t * my_obj = NULL; 2176 uint32_t strid = get_main_camera_handle(stream_id); 2177 uint32_t aux_strid = get_aux_camera_handle(stream_id); 2178 2179 2180 LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 2181 camera_handle, ch_id, stream_id, buf_idx, plane_idx); 2182 2183 if (aux_strid) { 2184 pthread_mutex_lock(&g_intf_lock); 2185 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 2186 uint32_t aux_chid = get_aux_camera_handle(ch_id); 2187 my_obj = mm_camera_util_get_camera_head(aux_handle); 2188 if (my_obj) { 2189 pthread_mutex_lock(&my_obj->muxer_lock); 2190 pthread_mutex_unlock(&g_intf_lock); 2191 rc = mm_camera_muxer_unmap_stream_buf(aux_handle, aux_chid, 2192 aux_strid, buf_type, buf_idx, 2193 plane_idx, my_obj); 2194 } else { 2195 pthread_mutex_unlock(&g_intf_lock); 2196 } 2197 } 2198 2199 if (strid) { 2200 pthread_mutex_lock(&g_intf_lock); 2201 uint32_t handle = get_main_camera_handle(camera_handle); 2202 uint32_t chid = get_main_camera_handle(ch_id); 2203 my_obj = mm_camera_util_get_camera_by_handler(handle); 2204 if(my_obj) { 2205 pthread_mutex_lock(&my_obj->cam_lock); 2206 pthread_mutex_unlock(&g_intf_lock); 2207 rc = mm_camera_unmap_stream_buf(my_obj, chid, strid, 2208 buf_type, buf_idx, plane_idx); 2209 }else{ 2210 pthread_mutex_unlock(&g_intf_lock); 2211 } 2212 } 2213 2214 LOGD("X rc = %d", rc); 2215 return rc; 2216 } 2217 2218 /*=========================================================================== 2219 * FUNCTION : mm_camera_intf_get_session_id 2220 * 2221 * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance 2222 * 2223 * PARAMETERS : 2224 * @camera_handle: camera handle 2225 * @sessionid: session id to be retrieved from server 2226 * 2227 * RETURN : int32_t type of status 2228 * 0 -- success 2229 * -1 -- failure 2230 * NOTE : if this call succeeds, we will get a valid session id. 2231 *==========================================================================*/ 2232 static int32_t mm_camera_intf_get_session_id(uint32_t camera_handle, 2233 uint32_t* sessionid) 2234 { 2235 int32_t rc = -1; 2236 mm_camera_obj_t * my_obj = NULL; 2237 uint32_t handle = get_main_camera_handle(camera_handle); 2238 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 2239 2240 if (handle) { 2241 pthread_mutex_lock(&g_intf_lock); 2242 my_obj = mm_camera_util_get_camera_by_handler(handle); 2243 2244 if(my_obj) { 2245 pthread_mutex_lock(&my_obj->cam_lock); 2246 pthread_mutex_unlock(&g_intf_lock); 2247 *sessionid = my_obj->sessionid; 2248 pthread_mutex_unlock(&my_obj->cam_lock); 2249 rc = 0; 2250 } else { 2251 pthread_mutex_unlock(&g_intf_lock); 2252 } 2253 } else if (aux_handle){ 2254 pthread_mutex_lock(&g_intf_lock); 2255 my_obj = mm_camera_util_get_camera_head(aux_handle); 2256 if (my_obj) { 2257 pthread_mutex_lock(&my_obj->muxer_lock); 2258 pthread_mutex_unlock(&g_intf_lock); 2259 rc = mm_camera_muxer_get_session_id(aux_handle, sessionid, my_obj); 2260 } else { 2261 pthread_mutex_unlock(&g_intf_lock); 2262 } 2263 } 2264 return rc; 2265 } 2266 2267 /*=========================================================================== 2268 * FUNCTION : mm_camera_intf_sync_related_sensors 2269 * 2270 * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance 2271 * 2272 * PARAMETERS : 2273 * @camera_handle: camera handle 2274 * @related_cam_info: pointer to the related cam info to be sent to the server 2275 * 2276 * RETURN : int32_t type of status 2277 * 0 -- success 2278 * -1 -- failure 2279 * NOTE : if this call succeeds, we will get linking established in back end 2280 *==========================================================================*/ 2281 static int32_t mm_camera_intf_sync_related_sensors(uint32_t camera_handle, 2282 cam_sync_related_sensors_event_info_t* related_cam_info) 2283 { 2284 int32_t rc = -1; 2285 mm_camera_obj_t * my_obj = NULL; 2286 2287 pthread_mutex_lock(&g_intf_lock); 2288 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 2289 2290 if(my_obj) { 2291 pthread_mutex_lock(&my_obj->cam_lock); 2292 pthread_mutex_unlock(&g_intf_lock); 2293 rc = mm_camera_sync_related_sensors(my_obj, related_cam_info); 2294 } else { 2295 pthread_mutex_unlock(&g_intf_lock); 2296 } 2297 return rc; 2298 } 2299 2300 /*=========================================================================== 2301 * FUNCTION : get_sensor_info 2302 * 2303 * DESCRIPTION: get sensor info like facing(back/front) and mount angle 2304 * 2305 * PARAMETERS : 2306 * 2307 * RETURN : 2308 *==========================================================================*/ 2309 void get_sensor_info() 2310 { 2311 int rc = 0; 2312 int dev_fd = -1; 2313 struct media_device_info mdev_info; 2314 int num_media_devices = 0; 2315 size_t num_cameras = 0; 2316 2317 LOGD("E"); 2318 while (1) { 2319 char dev_name[32]; 2320 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 2321 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 2322 if (dev_fd < 0) { 2323 LOGD("Done discovering media devices\n"); 2324 break; 2325 } 2326 num_media_devices++; 2327 memset(&mdev_info, 0, sizeof(mdev_info)); 2328 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 2329 if (rc < 0) { 2330 LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno)); 2331 close(dev_fd); 2332 dev_fd = -1; 2333 num_cameras = 0; 2334 break; 2335 } 2336 2337 if(strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) { 2338 close(dev_fd); 2339 dev_fd = -1; 2340 continue; 2341 } 2342 2343 unsigned int num_entities = 1; 2344 while (1) { 2345 struct media_entity_desc entity; 2346 uint32_t temp; 2347 uint32_t mount_angle; 2348 uint32_t facing; 2349 int32_t type = 0; 2350 uint8_t is_yuv; 2351 2352 memset(&entity, 0, sizeof(entity)); 2353 entity.id = num_entities++; 2354 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 2355 if (rc < 0) { 2356 LOGD("Done enumerating media entities\n"); 2357 rc = 0; 2358 break; 2359 } 2360 if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV && 2361 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) { 2362 temp = entity.flags >> 8; 2363 mount_angle = (temp & 0xFF) * 90; 2364 facing = ((entity.flags & CAM_SENSOR_FACING_MASK) ? 2365 CAMERA_FACING_FRONT:CAMERA_FACING_BACK); 2366 2367 /* TODO: Need to revisit this logic if front AUX is available. */ 2368 if ((unsigned int)facing == CAMERA_FACING_FRONT) { 2369 type = CAM_TYPE_STANDALONE; 2370 } else if (entity.flags & CAM_SENSOR_TYPE_MASK) { 2371 type = CAM_TYPE_AUX; 2372 } else { 2373 type = CAM_TYPE_MAIN; 2374 } 2375 2376 is_yuv = ((entity.flags & CAM_SENSOR_FORMAT_MASK) ? 2377 CAM_SENSOR_YUV:CAM_SENSOR_RAW); 2378 LOGL("index = %u flag = %x mount_angle = %u " 2379 "facing = %u type: %u is_yuv = %u\n", 2380 (unsigned int)num_cameras, (unsigned int)temp, 2381 (unsigned int)mount_angle, (unsigned int)facing, 2382 (unsigned int)type, (uint8_t)is_yuv); 2383 g_cam_ctrl.info[num_cameras].facing = (int)facing; 2384 g_cam_ctrl.info[num_cameras].orientation = (int)mount_angle; 2385 g_cam_ctrl.cam_type[num_cameras] = type; 2386 g_cam_ctrl.is_yuv[num_cameras] = is_yuv; 2387 LOGD("dev_info[id=%zu,name='%s']\n", 2388 num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); 2389 num_cameras++; 2390 continue; 2391 } 2392 } 2393 close(dev_fd); 2394 dev_fd = -1; 2395 } 2396 2397 LOGD("num_cameras=%d\n", g_cam_ctrl.num_cam); 2398 return; 2399 } 2400 2401 /*=========================================================================== 2402 * FUNCTION : sort_camera_info 2403 * 2404 * DESCRIPTION: sort camera info to keep back cameras idx is smaller than front cameras idx 2405 * 2406 * PARAMETERS : number of cameras 2407 * 2408 * RETURN : 2409 *==========================================================================*/ 2410 void sort_camera_info(int num_cam) 2411 { 2412 int idx = 0, i; 2413 int8_t is_yuv_aux_cam_exposed = 0; 2414 char prop[PROPERTY_VALUE_MAX]; 2415 struct camera_info temp_info[MM_CAMERA_MAX_NUM_SENSORS]; 2416 cam_sync_type_t temp_type[MM_CAMERA_MAX_NUM_SENSORS]; 2417 cam_sync_mode_t temp_mode[MM_CAMERA_MAX_NUM_SENSORS]; 2418 uint8_t temp_is_yuv[MM_CAMERA_MAX_NUM_SENSORS]; 2419 char temp_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN]; 2420 uint32_t cam_idx[MM_CAMERA_MAX_NUM_SENSORS] = {0}; 2421 uint8_t prime_cam_idx = 0, aux_cam_idx = 0; 2422 2423 memset(temp_info, 0, sizeof(temp_info)); 2424 memset(temp_dev_name, 0, sizeof(temp_dev_name)); 2425 memset(temp_type, 0, sizeof(temp_type)); 2426 memset(temp_mode, 0, sizeof(temp_mode)); 2427 memset(temp_is_yuv, 0, sizeof(temp_is_yuv)); 2428 2429 // Signifies whether YUV AUX camera has to be exposed as physical camera 2430 memset(prop, 0, sizeof(prop)); 2431 property_get("persist.camera.aux.yuv", prop, "0"); 2432 is_yuv_aux_cam_exposed = atoi(prop); 2433 LOGI("YUV Aux camera exposed %d",is_yuv_aux_cam_exposed); 2434 2435 /* Order of the camera exposed is 2436 Back main, Front main, Back Aux and then Front Aux. 2437 It is because that lot of 3rd party cameras apps 2438 blindly assume 0th is Back and 1st is front */ 2439 2440 /* Firstly save the main back cameras info */ 2441 for (i = 0; i < num_cam; i++) { 2442 if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) && 2443 !(g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) 2444 && ((g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) 2445 || (g_cam_ctrl.cam_type[i] == CAM_TYPE_STANDALONE))) { 2446 temp_info[idx] = g_cam_ctrl.info[i]; 2447 temp_type[idx] = CAM_TYPE_MAIN; 2448 temp_mode[idx] = g_cam_ctrl.cam_mode[i]; 2449 temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; 2450 cam_idx[idx] = idx; 2451 prime_cam_idx = idx; 2452 LOGD("Found Back Main Camera: i: %d idx: %d", i, idx); 2453 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], 2454 MM_CAMERA_DEV_NAME_LEN); 2455 } 2456 } 2457 2458 /* Save the main front cameras info */ 2459 for (i = 0; i < num_cam; i++) { 2460 if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) && 2461 !(g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) 2462 && ((g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) 2463 || (g_cam_ctrl.cam_type[i] == CAM_TYPE_STANDALONE))) { 2464 temp_info[idx] = g_cam_ctrl.info[i]; 2465 temp_type[idx] = CAM_TYPE_MAIN; 2466 temp_mode[idx] = g_cam_ctrl.cam_mode[i]; 2467 temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; 2468 cam_idx[idx] = idx; 2469 LOGD("Found Front Main Camera: i: %d idx: %d", i, idx); 2470 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], 2471 MM_CAMERA_DEV_NAME_LEN); 2472 } 2473 } 2474 2475 /*Expose Bayer Aux as a valid sensor*/ 2476 for (i = 0; i < num_cam; i++) { 2477 if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) && 2478 (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && 2479 (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) { 2480 temp_info[idx] = g_cam_ctrl.info[i]; 2481 temp_type[idx] = CAM_TYPE_MAIN; 2482 temp_mode[idx] = g_cam_ctrl.cam_mode[i]; 2483 temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; 2484 cam_idx[idx] = idx; 2485 LOGD("Found Bayer + Aux: i: %d idx: %d", i, idx); 2486 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], 2487 MM_CAMERA_DEV_NAME_LEN); 2488 } 2489 } 2490 2491 for (i = 0; i < num_cam; i++) { 2492 if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) && 2493 (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && 2494 (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) { 2495 temp_info[idx] = g_cam_ctrl.info[i]; 2496 temp_type[idx] = CAM_TYPE_MAIN; 2497 temp_mode[idx] = g_cam_ctrl.cam_mode[i]; 2498 temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; 2499 cam_idx[idx] = idx; 2500 aux_cam_idx = idx; 2501 LOGD("Found Bayer + Aux: i: %d idx: %d", i, idx); 2502 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], 2503 MM_CAMERA_DEV_NAME_LEN); 2504 } 2505 } 2506 2507 /* Expose YUV AUX camera if persist.camera.aux.yuv is set to 1. 2508 Otherwsie expose AUX camera if it is not YUV. */ 2509 for (i = 0; i < num_cam; i++) { 2510 if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) && 2511 (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && 2512 !(g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) && 2513 (is_yuv_aux_cam_exposed || !(g_cam_ctrl.is_yuv[i]))) { 2514 temp_info[idx] = g_cam_ctrl.info[i]; 2515 temp_type[idx] = CAM_TYPE_AUX; 2516 temp_mode[idx] = g_cam_ctrl.cam_mode[i]; 2517 temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; 2518 cam_idx[idx] = idx; 2519 LOGD("Found back Aux Camera: i: %d idx: %d", i, idx); 2520 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], 2521 MM_CAMERA_DEV_NAME_LEN); 2522 } 2523 } 2524 2525 /* Expose YUV AUX camera if persist.camera.aux.yuv is set to 1. 2526 Otherwsie expose AUX camera if it is not YUV. */ 2527 for (i = 0; i < num_cam; i++) { 2528 if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) && 2529 (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && 2530 !(g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) && 2531 (is_yuv_aux_cam_exposed || !(g_cam_ctrl.is_yuv[i]))) { 2532 temp_info[idx] = g_cam_ctrl.info[i]; 2533 temp_type[idx] = CAM_TYPE_AUX; 2534 temp_mode[idx] = g_cam_ctrl.cam_mode[i]; 2535 temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; 2536 cam_idx[idx] = idx; 2537 LOGD("Found Front Aux Camera: i: %d idx: %d", i, idx); 2538 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], 2539 MM_CAMERA_DEV_NAME_LEN); 2540 } 2541 } 2542 2543 /*Expose AUX + MAIN camera*/ 2544 for (i = 0; i < num_cam; i++) { 2545 if (((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) || 2546 (g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT)) && 2547 (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && 2548 (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) { 2549 temp_info[idx] = g_cam_ctrl.info[i]; 2550 temp_type[idx] = CAM_TYPE_AUX | CAM_TYPE_MAIN; 2551 temp_mode[idx] = g_cam_ctrl.cam_mode[i]; 2552 temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; 2553 //Assuming primary is back 2554 cam_idx[idx] = (aux_cam_idx << MM_CAMERA_HANDLE_SHIFT_MASK) | prime_cam_idx; 2555 LOGD("Add additional Bayer + Aux: i: %d idx: %d", i, idx); 2556 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], 2557 MM_CAMERA_DEV_NAME_LEN); 2558 } 2559 } 2560 2561 if (idx != 0) { 2562 memcpy(g_cam_ctrl.info, temp_info, sizeof(temp_info)); 2563 memcpy(g_cam_ctrl.cam_type, temp_type, sizeof(temp_type)); 2564 memcpy(g_cam_ctrl.cam_mode, temp_mode, sizeof(temp_mode)); 2565 memcpy(g_cam_ctrl.is_yuv, temp_is_yuv, sizeof(temp_is_yuv)); 2566 memcpy(g_cam_ctrl.video_dev_name, temp_dev_name, sizeof(temp_dev_name)); 2567 memcpy(g_cam_ctrl.cam_index, cam_idx, (sizeof(uint32_t) * MM_CAMERA_MAX_NUM_SENSORS)); 2568 //Set num cam based on the cameras exposed finally via dual/aux properties. 2569 g_cam_ctrl.num_cam = idx; 2570 for (i = 0; i < idx; i++) { 2571 LOGI("Camera id: %d facing: %d, type: %d is_yuv: %d", 2572 i, g_cam_ctrl.info[i].facing, g_cam_ctrl.cam_type[i], g_cam_ctrl.is_yuv[i]); 2573 } 2574 } 2575 LOGI("Number of cameras %d sorted %d", num_cam, idx); 2576 return; 2577 } 2578 2579 /*=========================================================================== 2580 * FUNCTION : get_num_of_cameras 2581 * 2582 * DESCRIPTION: get number of cameras 2583 * 2584 * PARAMETERS : 2585 * 2586 * RETURN : number of cameras supported 2587 *==========================================================================*/ 2588 uint8_t get_num_of_cameras() 2589 { 2590 int rc = 0; 2591 int dev_fd = -1; 2592 struct media_device_info mdev_info; 2593 int num_media_devices = 0; 2594 int8_t num_cameras = 0; 2595 char subdev_name[32]; 2596 int32_t sd_fd = -1; 2597 struct sensor_init_cfg_data cfg; 2598 char prop[PROPERTY_VALUE_MAX]; 2599 2600 LOGD("E"); 2601 2602 property_get("vold.decrypt", prop, "0"); 2603 int decrypt = atoi(prop); 2604 if (decrypt == 1) 2605 return 0; 2606 pthread_mutex_lock(&g_intf_lock); 2607 2608 memset (&g_cam_ctrl, 0, sizeof (g_cam_ctrl)); 2609 #ifndef DAEMON_PRESENT 2610 if (mm_camera_load_shim_lib() < 0) { 2611 LOGE ("Failed to module shim library"); 2612 return 0; 2613 } 2614 #endif /* DAEMON_PRESENT */ 2615 2616 while (1) { 2617 uint32_t num_entities = 1U; 2618 char dev_name[32]; 2619 2620 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 2621 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 2622 if (dev_fd < 0) { 2623 LOGD("Done discovering media devices\n"); 2624 break; 2625 } 2626 num_media_devices++; 2627 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 2628 if (rc < 0) { 2629 LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno)); 2630 close(dev_fd); 2631 dev_fd = -1; 2632 break; 2633 } 2634 2635 if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, 2636 sizeof(mdev_info.model)) != 0) { 2637 close(dev_fd); 2638 dev_fd = -1; 2639 continue; 2640 } 2641 2642 while (1) { 2643 struct media_entity_desc entity; 2644 memset(&entity, 0, sizeof(entity)); 2645 entity.id = num_entities++; 2646 LOGD("entity id %d", entity.id); 2647 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 2648 if (rc < 0) { 2649 LOGD("Done enumerating media entities"); 2650 rc = 0; 2651 break; 2652 } 2653 LOGD("entity name %s type %d group id %d", 2654 entity.name, entity.type, entity.group_id); 2655 if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV && 2656 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) { 2657 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name); 2658 break; 2659 } 2660 } 2661 close(dev_fd); 2662 dev_fd = -1; 2663 } 2664 2665 /* Open sensor_init subdev */ 2666 sd_fd = open(subdev_name, O_RDWR); 2667 if (sd_fd < 0) { 2668 LOGE("Open sensor_init subdev failed"); 2669 return FALSE; 2670 } 2671 2672 cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE; 2673 cfg.cfg.setting = NULL; 2674 if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) { 2675 LOGE("failed"); 2676 } 2677 close(sd_fd); 2678 dev_fd = -1; 2679 2680 num_media_devices = 0; 2681 while (1) { 2682 uint32_t num_entities = 1U; 2683 char dev_name[32]; 2684 2685 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 2686 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 2687 if (dev_fd < 0) { 2688 LOGD("Done discovering media devices: %s\n", strerror(errno)); 2689 break; 2690 } 2691 num_media_devices++; 2692 memset(&mdev_info, 0, sizeof(mdev_info)); 2693 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 2694 if (rc < 0) { 2695 LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno)); 2696 close(dev_fd); 2697 dev_fd = -1; 2698 num_cameras = 0; 2699 break; 2700 } 2701 2702 if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) { 2703 close(dev_fd); 2704 dev_fd = -1; 2705 continue; 2706 } 2707 2708 while (1) { 2709 struct media_entity_desc entity; 2710 memset(&entity, 0, sizeof(entity)); 2711 entity.id = num_entities++; 2712 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 2713 if (rc < 0) { 2714 LOGD("Done enumerating media entities\n"); 2715 rc = 0; 2716 break; 2717 } 2718 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 2719 strlcpy(g_cam_ctrl.video_dev_name[num_cameras], 2720 entity.name, sizeof(entity.name)); 2721 LOGI("dev_info[id=%d,name='%s']\n", 2722 (int)num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); 2723 num_cameras++; 2724 break; 2725 } 2726 } 2727 close(dev_fd); 2728 dev_fd = -1; 2729 if (num_cameras >= MM_CAMERA_MAX_NUM_SENSORS) { 2730 LOGW("Maximum number of camera reached %d", num_cameras); 2731 break; 2732 } 2733 } 2734 g_cam_ctrl.num_cam = num_cameras; 2735 2736 get_sensor_info(); 2737 sort_camera_info(g_cam_ctrl.num_cam); 2738 /* unlock the mutex */ 2739 pthread_mutex_unlock(&g_intf_lock); 2740 LOGI("num_cameras=%d\n", (int)g_cam_ctrl.num_cam); 2741 return(uint8_t)g_cam_ctrl.num_cam; 2742 } 2743 2744 /*=========================================================================== 2745 * FUNCTION : mm_camera_intf_process_advanced_capture 2746 * 2747 * DESCRIPTION: Configures channel advanced capture mode 2748 * 2749 * PARAMETERS : 2750 * @camera_handle: camera handle 2751 * @type : advanced capture type 2752 * @ch_id : channel handle 2753 * @trigger : 1 for start and 0 for cancel/stop 2754 * @value : input capture configaration 2755 * 2756 * RETURN : int32_t type of status 2757 * 0 -- success 2758 * -1 -- failure 2759 *==========================================================================*/ 2760 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle, 2761 uint32_t ch_id, mm_camera_advanced_capture_t type, 2762 int8_t trigger, void *in_value) 2763 { 2764 int32_t rc = -1; 2765 mm_camera_obj_t * my_obj = NULL; 2766 uint32_t chid = get_main_camera_handle(ch_id); 2767 uint32_t aux_chid = get_aux_camera_handle(ch_id); 2768 2769 LOGD("E camera_handler = %d,ch_id = %d", 2770 camera_handle, ch_id); 2771 2772 if (chid) { 2773 pthread_mutex_lock(&g_intf_lock); 2774 uint32_t handle = get_main_camera_handle(camera_handle); 2775 my_obj = mm_camera_util_get_camera_by_handler(handle); 2776 2777 if(my_obj) { 2778 pthread_mutex_lock(&my_obj->cam_lock); 2779 pthread_mutex_unlock(&g_intf_lock); 2780 rc = mm_camera_channel_advanced_capture(my_obj, chid, type, 2781 (uint32_t)trigger, in_value); 2782 } else { 2783 pthread_mutex_unlock(&g_intf_lock); 2784 } 2785 } 2786 2787 if (aux_chid) { 2788 pthread_mutex_lock(&g_intf_lock); 2789 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 2790 my_obj = mm_camera_util_get_camera_head(aux_handle); 2791 if (my_obj) { 2792 pthread_mutex_lock(&my_obj->muxer_lock); 2793 pthread_mutex_unlock(&g_intf_lock); 2794 rc = mm_camera_muxer_process_advanced_capture(aux_handle, 2795 aux_chid, type, (uint32_t)trigger, in_value, my_obj); 2796 } else { 2797 pthread_mutex_unlock(&g_intf_lock); 2798 } 2799 } 2800 LOGH("X rc = %d ch_id = %d", rc, ch_id); 2801 return rc; 2802 } 2803 2804 /*=========================================================================== 2805 * FUNCTION : mm_camera_intf_register_stream_buf_cb 2806 * 2807 * DESCRIPTION: Register special callback for stream buffer 2808 * 2809 * PARAMETERS : 2810 * @camera_handle: camera handle 2811 * @ch_id : channel handle 2812 * @stream_id : stream handle 2813 * @buf_cb : callback function 2814 * @buf_type :SYNC/ASYNC 2815 * @userdata : userdata pointer 2816 * 2817 * RETURN : int32_t type of status 2818 * 0 -- success 2819 * 1 -- failure 2820 *==========================================================================*/ 2821 static int32_t mm_camera_intf_register_stream_buf_cb(uint32_t camera_handle, 2822 uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb, 2823 mm_camera_stream_cb_type cb_type, void *userdata) 2824 { 2825 int32_t rc = 0; 2826 mm_camera_obj_t * my_obj = NULL; 2827 uint32_t strid = get_main_camera_handle(stream_id); 2828 uint32_t aux_strid = get_aux_camera_handle(stream_id); 2829 2830 LOGD("E handle = %u ch_id = %u", 2831 camera_handle, ch_id); 2832 2833 if (strid) { 2834 pthread_mutex_lock(&g_intf_lock); 2835 uint32_t handle = get_main_camera_handle(camera_handle); 2836 uint32_t chid = get_main_camera_handle(ch_id); 2837 my_obj = mm_camera_util_get_camera_by_handler(handle); 2838 2839 if(my_obj) { 2840 pthread_mutex_lock(&my_obj->cam_lock); 2841 pthread_mutex_unlock(&g_intf_lock); 2842 rc = mm_camera_reg_stream_buf_cb(my_obj, chid, strid, 2843 buf_cb, cb_type, userdata); 2844 } else { 2845 pthread_mutex_unlock(&g_intf_lock); 2846 } 2847 } 2848 2849 if (aux_strid) { 2850 pthread_mutex_lock(&g_intf_lock); 2851 uint32_t aux_handle = get_aux_camera_handle(camera_handle); 2852 uint32_t aux_chid = get_aux_camera_handle(ch_id); 2853 my_obj = mm_camera_util_get_camera_head(aux_handle); 2854 2855 if (my_obj) { 2856 pthread_mutex_lock(&my_obj->muxer_lock); 2857 pthread_mutex_unlock(&g_intf_lock); 2858 rc = mm_camera_muxer_register_stream_buf_cb(aux_handle, 2859 aux_chid, aux_strid, 2860 buf_cb, cb_type, userdata, my_obj); 2861 } else { 2862 pthread_mutex_unlock(&g_intf_lock); 2863 } 2864 } 2865 return (int32_t)rc; 2866 } 2867 2868 /*=========================================================================== 2869 * FUNCTION : mm_camera_intf_register_frame_sync 2870 * 2871 * DESCRIPTION: start frame buffer sync for the stream 2872 * 2873 * PARAMETERS : 2874 * @camera_handle: camera handle 2875 * @ch_id : channel handle 2876 * @stream_id : stream handle 2877 * @sync_attr : frame sync attr 2878 * 2879 * RETURN : int32_t type of status 2880 * 0 -- success 2881 * 1 -- failure 2882 *==========================================================================*/ 2883 static int32_t mm_camera_intf_reg_frame_sync(uint32_t camera_handle, 2884 uint32_t ch_id, uint32_t stream_id, 2885 mm_camera_intf_frame_sync_t *sync_attr) 2886 { 2887 int32_t rc = 0; 2888 mm_camera_obj_t * my_obj = NULL; 2889 2890 LOGD("E handle = %u ch_id = %u stream_id = %u", camera_handle, ch_id, stream_id); 2891 2892 pthread_mutex_lock(&g_intf_lock); 2893 uint32_t handle = get_main_camera_handle(camera_handle); 2894 my_obj = mm_camera_util_get_camera_by_handler(handle); 2895 if(my_obj) { 2896 pthread_mutex_lock(&my_obj->muxer_lock); 2897 pthread_mutex_unlock(&g_intf_lock); 2898 rc = mm_camera_muxer_reg_frame_sync(my_obj, 2899 ch_id, stream_id, sync_attr); 2900 } else { 2901 pthread_mutex_unlock(&g_intf_lock); 2902 } 2903 return (int32_t)rc; 2904 } 2905 2906 /*=========================================================================== 2907 * FUNCTION : mm_camera_intf_start_stream_frame_sync 2908 * 2909 * DESCRIPTION: start frame buffer sync for the stream 2910 * 2911 * PARAMETERS : 2912 * @camera_handle: camera handle 2913 * @ch_id : channel handle 2914 * @stream_id : stream handle 2915 * 2916 * RETURN : int32_t type of status 2917 * 0 -- success 2918 * 1 -- failure 2919 *==========================================================================*/ 2920 static int32_t mm_camera_intf_start_stream_frame_sync(uint32_t camera_handle, 2921 uint32_t ch_id, uint32_t stream_id) 2922 { 2923 int32_t rc = 0; 2924 mm_camera_obj_t * my_obj = NULL; 2925 2926 LOGD("E handle = %u ch_id = %u stream_id = %u", 2927 camera_handle, ch_id, stream_id); 2928 2929 pthread_mutex_lock(&g_intf_lock); 2930 uint32_t handle = get_main_camera_handle(camera_handle); 2931 uint32_t m_chid = get_main_camera_handle(ch_id); 2932 uint32_t m_stream = get_main_camera_handle(stream_id); 2933 my_obj = mm_camera_util_get_camera_by_handler(handle); 2934 if(my_obj) { 2935 pthread_mutex_lock(&my_obj->muxer_lock); 2936 pthread_mutex_unlock(&g_intf_lock); 2937 rc = mm_camera_muxer_start_frame_sync(my_obj, 2938 m_chid, m_stream); 2939 } else { 2940 pthread_mutex_unlock(&g_intf_lock); 2941 } 2942 LOGH("stream_id = %d rc = %d", stream_id, rc); 2943 return (int32_t)rc; 2944 } 2945 2946 /*=========================================================================== 2947 * FUNCTION : mm_camera_intf_stop_stream_frame_sync 2948 * 2949 * DESCRIPTION: stop frame buffer sync for the stream 2950 * 2951 * PARAMETERS : 2952 * @camera_handle: camera handle 2953 * @ch_id : channel handle 2954 * @stream_id : stream handle 2955 * 2956 * RETURN : int32_t type of status 2957 * 0 -- success 2958 * 1 -- failure 2959 *==========================================================================*/ 2960 static int32_t mm_camera_intf_stop_stream_frame_sync(uint32_t camera_handle, 2961 uint32_t ch_id, uint32_t stream_id) 2962 { 2963 int32_t rc = 0; 2964 mm_camera_obj_t * my_obj = NULL; 2965 2966 LOGD("E handle = %u ch_id = %u stream_id = %u", 2967 camera_handle, ch_id, stream_id); 2968 2969 pthread_mutex_lock(&g_intf_lock); 2970 uint32_t handle = get_main_camera_handle(camera_handle); 2971 uint32_t m_chid = get_main_camera_handle(ch_id); 2972 uint32_t m_stream = get_main_camera_handle(stream_id); 2973 my_obj = mm_camera_util_get_camera_by_handler(handle); 2974 if(my_obj) { 2975 pthread_mutex_lock(&my_obj->muxer_lock); 2976 pthread_mutex_unlock(&g_intf_lock); 2977 rc = mm_camera_muxer_stop_frame_sync(my_obj, 2978 m_chid, m_stream); 2979 } else { 2980 pthread_mutex_unlock(&g_intf_lock); 2981 } 2982 LOGH("stream_id = %d rc = %d", stream_id, rc); 2983 return (int32_t)rc; 2984 } 2985 2986 /*=========================================================================== 2987 * FUNCTION : mm_camera_intf_switch_stream 2988 * 2989 * DESCRIPTION: switch between stream in case of multi streams 2990 * 2991 * PARAMETERS : 2992 * @camera_handle: camera handle 2993 * @ch_id : channel handle 2994 * @stream_id : stream handle 2995 * 2996 * RETURN : int32_t type of status 2997 * 0 -- success 2998 * 1 -- failure 2999 *==========================================================================*/ 3000 static int32_t mm_camera_intf_switch_stream_cb(uint32_t camera_handle, 3001 uint32_t ch_id, uint32_t stream_id) 3002 { 3003 int32_t rc = 0; 3004 mm_camera_obj_t * my_obj = NULL; 3005 3006 uint32_t handle = get_main_camera_handle(camera_handle); 3007 uint32_t m_chid = get_main_camera_handle(ch_id); 3008 uint32_t m_strid = get_main_camera_handle(stream_id); 3009 LOGD("E handle = %u ch_id = %u stream_id = %u", 3010 camera_handle, ch_id, stream_id); 3011 3012 pthread_mutex_lock(&g_intf_lock); 3013 my_obj = mm_camera_util_get_camera_by_handler(handle); 3014 if(my_obj) { 3015 pthread_mutex_lock(&my_obj->cam_lock); 3016 pthread_mutex_unlock(&g_intf_lock); 3017 rc = mm_camera_switch_stream_cb(my_obj, m_chid, m_strid); 3018 } else { 3019 pthread_mutex_unlock(&g_intf_lock); 3020 } 3021 LOGH("stream_id = %d rc = %d", stream_id, rc); 3022 return (int32_t)rc; 3023 } 3024 3025 struct camera_info *get_cam_info(uint32_t camera_id, cam_sync_type_t *pCamType) 3026 { 3027 *pCamType = g_cam_ctrl.cam_type[camera_id]; 3028 return &g_cam_ctrl.info[camera_id]; 3029 } 3030 3031 uint8_t is_dual_camera_by_idx(uint32_t camera_id) 3032 { 3033 return ((g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_MAIN) 3034 && (g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_AUX)); 3035 } 3036 3037 uint8_t is_dual_camera_by_handle(uint32_t handle) 3038 { 3039 return ((handle >> MM_CAMERA_HANDLE_SHIFT_MASK) 3040 ? 1 : 0); 3041 } 3042 3043 uint32_t get_aux_camera_handle(uint32_t handle) 3044 { 3045 return mm_camera_util_get_handle_by_num(1, handle); 3046 } 3047 3048 uint32_t get_main_camera_handle(uint32_t handle) 3049 { 3050 return mm_camera_util_get_handle_by_num(0, handle); 3051 } 3052 3053 uint8_t is_yuv_sensor(uint32_t camera_id) 3054 { 3055 return g_cam_ctrl.is_yuv[camera_id]; 3056 } 3057 3058 uint8_t validate_handle(uint32_t src_handle, uint32_t handle) 3059 { 3060 return ((src_handle == handle) 3061 || (get_main_camera_handle(src_handle) == handle) 3062 || (get_aux_camera_handle(src_handle) == handle) 3063 || (get_main_camera_handle(handle) == src_handle) 3064 || (get_aux_camera_handle(handle) == src_handle)); 3065 } 3066 3067 /* camera ops v-table */ 3068 static mm_camera_ops_t mm_camera_ops = { 3069 .query_capability = mm_camera_intf_query_capability, 3070 .register_event_notify = mm_camera_intf_register_event_notify, 3071 .close_camera = mm_camera_intf_close, 3072 .set_parms = mm_camera_intf_set_parms, 3073 .get_parms = mm_camera_intf_get_parms, 3074 .do_auto_focus = mm_camera_intf_do_auto_focus, 3075 .cancel_auto_focus = mm_camera_intf_cancel_auto_focus, 3076 .prepare_snapshot = mm_camera_intf_prepare_snapshot, 3077 .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot, 3078 .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot, 3079 .map_buf = mm_camera_intf_map_buf, 3080 .map_bufs = mm_camera_intf_map_bufs, 3081 .unmap_buf = mm_camera_intf_unmap_buf, 3082 .add_channel = mm_camera_intf_add_channel, 3083 .delete_channel = mm_camera_intf_del_channel, 3084 .get_bundle_info = mm_camera_intf_get_bundle_info, 3085 .add_stream = mm_camera_intf_add_stream, 3086 .link_stream = mm_camera_intf_link_stream, 3087 .delete_stream = mm_camera_intf_del_stream, 3088 .config_stream = mm_camera_intf_config_stream, 3089 .qbuf = mm_camera_intf_qbuf, 3090 .get_queued_buf_count = mm_camera_intf_get_queued_buf_count, 3091 .map_stream_buf = mm_camera_intf_map_stream_buf, 3092 .map_stream_bufs = mm_camera_intf_map_stream_bufs, 3093 .unmap_stream_buf = mm_camera_intf_unmap_stream_buf, 3094 .set_stream_parms = mm_camera_intf_set_stream_parms, 3095 .get_stream_parms = mm_camera_intf_get_stream_parms, 3096 .start_channel = mm_camera_intf_start_channel, 3097 .stop_channel = mm_camera_intf_stop_channel, 3098 .request_super_buf = mm_camera_intf_request_super_buf, 3099 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request, 3100 .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue, 3101 .configure_notify_mode = mm_camera_intf_configure_notify_mode, 3102 .process_advanced_capture = mm_camera_intf_process_advanced_capture, 3103 .get_session_id = mm_camera_intf_get_session_id, 3104 .sync_related_sensors = mm_camera_intf_sync_related_sensors, 3105 .flush = mm_camera_intf_flush, 3106 .register_stream_buf_cb = mm_camera_intf_register_stream_buf_cb, 3107 .register_frame_sync = mm_camera_intf_reg_frame_sync, 3108 .start_stream_frame_sync = mm_camera_intf_start_stream_frame_sync, 3109 .stop_stream_frame_sync = mm_camera_intf_stop_stream_frame_sync, 3110 .switch_stream_callback = mm_camera_intf_switch_stream_cb 3111 }; 3112 3113 /*=========================================================================== 3114 * FUNCTION : camera_open 3115 * 3116 * DESCRIPTION: open a camera by camera index 3117 * 3118 * PARAMETERS : 3119 * @camera_idx : camera index. should within range of 0 to num_of_cameras 3120 * @camera_vtbl : ptr to a virtual table containing camera handle and operation table. 3121 * 3122 * RETURN : int32_t type of status 3123 * 0 -- success 3124 * non-zero error code -- failure 3125 *==========================================================================*/ 3126 int32_t camera_open(uint8_t camera_idx, mm_camera_vtbl_t **camera_vtbl) 3127 { 3128 int32_t rc = 0; 3129 mm_camera_obj_t *cam_obj = NULL; 3130 uint32_t cam_idx = camera_idx; 3131 uint32_t aux_idx = 0; 3132 uint8_t is_multi_camera = 0; 3133 3134 #ifdef QCAMERA_REDEFINE_LOG 3135 mm_camera_debug_open(); 3136 #endif 3137 3138 LOGD("E camera_idx = %d\n", camera_idx); 3139 if (is_dual_camera_by_idx(camera_idx)) { 3140 is_multi_camera = 1; 3141 cam_idx = mm_camera_util_get_handle_by_num(0, 3142 g_cam_ctrl.cam_index[camera_idx]); 3143 aux_idx = (get_aux_camera_handle(g_cam_ctrl.cam_index[camera_idx]) 3144 >> MM_CAMERA_HANDLE_SHIFT_MASK); 3145 LOGH("Dual Camera: Main ID = %d Aux ID = %d", cam_idx, aux_idx); 3146 } 3147 3148 if (cam_idx >= (uint32_t)g_cam_ctrl.num_cam) { 3149 LOGE("Invalid camera_idx (%d)", cam_idx); 3150 return -EINVAL; 3151 } 3152 3153 pthread_mutex_lock(&g_intf_lock); 3154 /* opened already */ 3155 if(NULL != g_cam_ctrl.cam_obj[cam_idx] && 3156 g_cam_ctrl.cam_obj[cam_idx]->ref_count != 0) { 3157 pthread_mutex_unlock(&g_intf_lock); 3158 LOGE("Camera %d is already open", cam_idx); 3159 return -EBUSY; 3160 } 3161 3162 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); 3163 if(NULL == cam_obj) { 3164 pthread_mutex_unlock(&g_intf_lock); 3165 LOGE("no mem"); 3166 return -EINVAL; 3167 } 3168 3169 /* initialize camera obj */ 3170 memset(cam_obj, 0, sizeof(mm_camera_obj_t)); 3171 cam_obj->ctrl_fd = -1; 3172 cam_obj->ds_fd = -1; 3173 cam_obj->ref_count++; 3174 cam_obj->my_num = 0; 3175 cam_obj->my_hdl = mm_camera_util_generate_handler(cam_idx); 3176 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */ 3177 cam_obj->vtbl.ops = &mm_camera_ops; 3178 pthread_mutex_init(&cam_obj->cam_lock, NULL); 3179 pthread_mutex_init(&cam_obj->muxer_lock, NULL); 3180 /* unlock global interface lock, if not, in dual camera use case, 3181 * current open will block operation of another opened camera obj*/ 3182 pthread_mutex_lock(&cam_obj->cam_lock); 3183 pthread_mutex_unlock(&g_intf_lock); 3184 3185 rc = mm_camera_open(cam_obj); 3186 if (rc != 0) { 3187 LOGE("mm_camera_open err = %d", rc); 3188 pthread_mutex_destroy(&cam_obj->cam_lock); 3189 pthread_mutex_lock(&g_intf_lock); 3190 g_cam_ctrl.cam_obj[cam_idx] = NULL; 3191 free(cam_obj); 3192 cam_obj = NULL; 3193 pthread_mutex_unlock(&g_intf_lock); 3194 *camera_vtbl = NULL; 3195 return rc; 3196 } 3197 3198 if (is_multi_camera) { 3199 /*Open Aux camer's*/ 3200 pthread_mutex_lock(&g_intf_lock); 3201 if(NULL != g_cam_ctrl.cam_obj[aux_idx] && 3202 g_cam_ctrl.cam_obj[aux_idx]->ref_count != 0) { 3203 pthread_mutex_unlock(&g_intf_lock); 3204 LOGE("Camera %d is already open", aux_idx); 3205 rc = -EBUSY; 3206 } else { 3207 pthread_mutex_lock(&cam_obj->muxer_lock); 3208 pthread_mutex_unlock(&g_intf_lock); 3209 rc = mm_camera_muxer_camera_open(aux_idx, cam_obj); 3210 } 3211 if (rc != 0) { 3212 LOGE("muxer open err = %d", rc); 3213 pthread_mutex_lock(&g_intf_lock); 3214 g_cam_ctrl.cam_obj[cam_idx] = NULL; 3215 pthread_mutex_lock(&cam_obj->cam_lock); 3216 pthread_mutex_unlock(&g_intf_lock); 3217 rc = mm_camera_close(cam_obj); 3218 pthread_mutex_destroy(&cam_obj->cam_lock); 3219 pthread_mutex_destroy(&cam_obj->muxer_lock); 3220 free(cam_obj); 3221 cam_obj = NULL; 3222 *camera_vtbl = NULL; 3223 return rc; 3224 } 3225 } 3226 3227 LOGH("Open succeded: handle = %d", cam_obj->vtbl.camera_handle); 3228 g_cam_ctrl.cam_obj[cam_idx] = cam_obj; 3229 *camera_vtbl = &cam_obj->vtbl; 3230 return 0; 3231 } 3232 3233 /*=========================================================================== 3234 * FUNCTION : mm_camera_load_shim_lib 3235 * 3236 * DESCRIPTION: Load shim layer library 3237 * 3238 * PARAMETERS : 3239 * 3240 * RETURN : status of load shim library 3241 *==========================================================================*/ 3242 int32_t mm_camera_load_shim_lib() 3243 { 3244 const char* error = NULL; 3245 void *qdaemon_lib = NULL; 3246 3247 LOGD("E"); 3248 qdaemon_lib = dlopen(SHIMLAYER_LIB, RTLD_NOW); 3249 if (!qdaemon_lib) { 3250 error = dlerror(); 3251 LOGE("dlopen failed with error %s", error ? error : ""); 3252 return -1; 3253 } 3254 3255 *(void **)&mm_camera_shim_module_init = 3256 dlsym(qdaemon_lib, "mct_shimlayer_process_module_init"); 3257 if (!mm_camera_shim_module_init) { 3258 error = dlerror(); 3259 LOGE("dlsym failed with error code %s", error ? error: ""); 3260 dlclose(qdaemon_lib); 3261 return -1; 3262 } 3263 3264 return mm_camera_shim_module_init(&g_cam_ctrl.cam_shim_ops); 3265 } 3266 3267 /*=========================================================================== 3268 * FUNCTION : mm_camera_module_open_session 3269 * 3270 * DESCRIPTION: wrapper function to call shim layer API to open session. 3271 * 3272 * PARAMETERS : 3273 * @sessionid : sessionID to open session 3274 * @evt_cb : Event callback function 3275 * 3276 * RETURN : int32_t type of status 3277 * 0 -- success 3278 * non-zero error code -- failure 3279 *==========================================================================*/ 3280 cam_status_t mm_camera_module_open_session(int sessionid, 3281 mm_camera_shim_event_handler_func evt_cb) 3282 { 3283 cam_status_t rc = -1; 3284 if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session) { 3285 rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session( 3286 sessionid, evt_cb); 3287 } 3288 return rc; 3289 } 3290 3291 /*=========================================================================== 3292 * FUNCTION : mm_camera_module_close_session 3293 * 3294 * DESCRIPTION: wrapper function to call shim layer API to close session 3295 * 3296 * PARAMETERS : 3297 * @sessionid : sessionID to open session 3298 * 3299 * RETURN : int32_t type of status 3300 * 0 -- success 3301 * non-zero error code -- failure 3302 *==========================================================================*/ 3303 int32_t mm_camera_module_close_session(int session) 3304 { 3305 int32_t rc = -1; 3306 if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_close_session) { 3307 rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_close_session(session); 3308 } 3309 return rc; 3310 } 3311 3312 /*=========================================================================== 3313 * FUNCTION : mm_camera_module_open_session 3314 * 3315 * DESCRIPTION: wrapper function to call shim layer API 3316 * 3317 * PARAMETERS : 3318 * @sessionid : sessionID to open session 3319 * @evt_cb : Event callback function 3320 * 3321 * RETURN : int32_t type of status 3322 * 0 -- success 3323 * non-zero error code -- failure 3324 *==========================================================================*/ 3325 int32_t mm_camera_module_send_cmd(cam_shim_packet_t *event) 3326 { 3327 int32_t rc = -1; 3328 if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd) { 3329 rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd(event); 3330 } 3331 return rc; 3332 } 3333 3334 /*=========================================================================== 3335 * FUNCTION : mm_camera_module_event_handler 3336 * 3337 * DESCRIPTION: call back function for shim layer 3338 * 3339 * PARAMETERS : 3340 * 3341 * RETURN : status of call back function 3342 *==========================================================================*/ 3343 int mm_camera_module_event_handler(uint32_t session_id, cam_event_t *event) 3344 { 3345 if (!event) { 3346 LOGE("null event"); 3347 return FALSE; 3348 } 3349 mm_camera_event_t evt; 3350 3351 LOGD("session_id:%d, cmd:0x%x", session_id, event->server_event_type); 3352 memset(&evt, 0, sizeof(mm_camera_event_t)); 3353 3354 evt = *event; 3355 mm_camera_obj_t *my_obj = 3356 mm_camera_util_get_camera_by_session_id(session_id); 3357 if (!my_obj) { 3358 LOGE("my_obj:%p", my_obj); 3359 return FALSE; 3360 } 3361 switch( evt.server_event_type) { 3362 case CAM_EVENT_TYPE_DAEMON_PULL_REQ: 3363 case CAM_EVENT_TYPE_CAC_DONE: 3364 case CAM_EVENT_TYPE_DAEMON_DIED: 3365 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 3366 case CAM_EVENT_TYPE_INT_TAKE_RAW: 3367 mm_camera_enqueue_evt(my_obj, &evt); 3368 break; 3369 default: 3370 LOGE("cmd:%x from shim layer is not handled", evt.server_event_type); 3371 break; 3372 } 3373 return TRUE; 3374 } 3375 3376