mm_camera_interface.c revision 86eb8e464a1d1801878b7541b00941c220bb2a4c
1/* Copyright (c) 2012-2013, 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#include <pthread.h> 31#include <errno.h> 32#include <sys/ioctl.h> 33#include <sys/types.h> 34#include <sys/stat.h> 35#include <fcntl.h> 36#include <poll.h> 37#include <linux/media.h> 38 39#include "mm_camera_dbg.h" 40#include "mm_camera_interface.h" 41#include "mm_camera_sock.h" 42#include "mm_camera.h" 43 44static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; 45 46static mm_camera_ctrl_t g_cam_ctrl = {0, {{0}}, {0}}; 47 48static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; 49static uint16_t g_handler_history_count = 0; /* history count for handler */ 50 51/*=========================================================================== 52 * FUNCTION : mm_camera_util_generate_handler 53 * 54 * DESCRIPTION: utility function to generate handler for camera/channel/stream 55 * 56 * PARAMETERS : 57 * @index: index of the object to have handler 58 * 59 * RETURN : uint32_t type of handle that uniquely identify the object 60 *==========================================================================*/ 61uint32_t mm_camera_util_generate_handler(uint8_t index) 62{ 63 uint32_t handler = 0; 64 pthread_mutex_lock(&g_handler_lock); 65 g_handler_history_count++; 66 if (0 == g_handler_history_count) { 67 g_handler_history_count++; 68 } 69 handler = g_handler_history_count; 70 handler = (handler<<8) | index; 71 pthread_mutex_unlock(&g_handler_lock); 72 return handler; 73} 74 75/*=========================================================================== 76 * FUNCTION : mm_camera_util_get_index_by_handler 77 * 78 * DESCRIPTION: utility function to get index from handle 79 * 80 * PARAMETERS : 81 * @handler: object handle 82 * 83 * RETURN : uint8_t type of index derived from handle 84 *==========================================================================*/ 85uint8_t mm_camera_util_get_index_by_handler(uint32_t handler) 86{ 87 return (handler&0x000000ff); 88} 89 90/*=========================================================================== 91 * FUNCTION : mm_camera_util_get_dev_name 92 * 93 * DESCRIPTION: utility function to get device name from camera handle 94 * 95 * PARAMETERS : 96 * @cam_handle: camera handle 97 * 98 * RETURN : char ptr to the device name stored in global variable 99 * NOTE : caller should not free the char ptr 100 *==========================================================================*/ 101const char *mm_camera_util_get_dev_name(uint32_t cam_handle) 102{ 103 char *dev_name = NULL; 104 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle); 105 if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) { 106 dev_name = g_cam_ctrl.video_dev_name[cam_idx]; 107 } 108 return dev_name; 109} 110 111/*=========================================================================== 112 * FUNCTION : mm_camera_util_get_camera_by_handler 113 * 114 * DESCRIPTION: utility function to get camera object from camera handle 115 * 116 * PARAMETERS : 117 * @cam_handle: camera handle 118 * 119 * RETURN : ptr to the camera object stored in global variable 120 * NOTE : caller should not free the camera object ptr 121 *==========================================================================*/ 122mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle) 123{ 124 mm_camera_obj_t *cam_obj = NULL; 125 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle); 126 127 if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS && 128 (NULL != g_cam_ctrl.cam_obj[cam_idx]) && 129 (cam_handle == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) { 130 cam_obj = g_cam_ctrl.cam_obj[cam_idx]; 131 } 132 return cam_obj; 133} 134 135/*=========================================================================== 136 * FUNCTION : mm_camera_intf_query_capability 137 * 138 * DESCRIPTION: query camera capability 139 * 140 * PARAMETERS : 141 * @camera_handle: camera handle 142 * 143 * RETURN : int32_t type of status 144 * 0 -- success 145 * -1 -- failure 146 *==========================================================================*/ 147static int32_t mm_camera_intf_query_capability(uint32_t camera_handle) 148{ 149 int32_t rc = -1; 150 mm_camera_obj_t * my_obj = NULL; 151 152 CDBG("%s E: camera_handler = %d ", __func__, camera_handle); 153 154 pthread_mutex_lock(&g_intf_lock); 155 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 156 157 if(my_obj) { 158 pthread_mutex_lock(&my_obj->cam_lock); 159 pthread_mutex_unlock(&g_intf_lock); 160 rc = mm_camera_query_capability(my_obj); 161 } else { 162 pthread_mutex_unlock(&g_intf_lock); 163 } 164 CDBG("%s :X rc = %d", __func__, rc); 165 return rc; 166} 167 168/*=========================================================================== 169 * FUNCTION : mm_camera_intf_set_parms 170 * 171 * DESCRIPTION: set parameters per camera 172 * 173 * PARAMETERS : 174 * @camera_handle: camera handle 175 * @parms : ptr to a param struct to be set to server 176 * 177 * RETURN : int32_t type of status 178 * 0 -- success 179 * -1 -- failure 180 * NOTE : Assume the parms struct buf is already mapped to server via 181 * domain socket. Corresponding fields of parameters to be set 182 * are already filled in by upper layer caller. 183 *==========================================================================*/ 184static int32_t mm_camera_intf_set_parms(uint32_t camera_handle, 185 parm_buffer_t *parms) 186{ 187 int32_t rc = -1; 188 mm_camera_obj_t * my_obj = NULL; 189 190 pthread_mutex_lock(&g_intf_lock); 191 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 192 193 if(my_obj) { 194 pthread_mutex_lock(&my_obj->cam_lock); 195 pthread_mutex_unlock(&g_intf_lock); 196 rc = mm_camera_set_parms(my_obj, parms); 197 } else { 198 pthread_mutex_unlock(&g_intf_lock); 199 } 200 return rc; 201} 202 203/*=========================================================================== 204 * FUNCTION : mm_camera_intf_get_parms 205 * 206 * DESCRIPTION: get parameters per camera 207 * 208 * PARAMETERS : 209 * @camera_handle: camera handle 210 * @parms : ptr to a param struct to be get from server 211 * 212 * RETURN : int32_t type of status 213 * 0 -- success 214 * -1 -- failure 215 * NOTE : Assume the parms struct buf is already mapped to server via 216 * domain socket. Parameters to be get from server are already 217 * filled in by upper layer caller. After this call, corresponding 218 * fields of requested parameters will be filled in by server with 219 * detailed information. 220 *==========================================================================*/ 221static int32_t mm_camera_intf_get_parms(uint32_t camera_handle, 222 parm_buffer_t *parms) 223{ 224 int32_t rc = -1; 225 mm_camera_obj_t * my_obj = NULL; 226 227 pthread_mutex_lock(&g_intf_lock); 228 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 229 230 if(my_obj) { 231 pthread_mutex_lock(&my_obj->cam_lock); 232 pthread_mutex_unlock(&g_intf_lock); 233 rc = mm_camera_get_parms(my_obj, parms); 234 } else { 235 pthread_mutex_unlock(&g_intf_lock); 236 } 237 return rc; 238} 239 240/*=========================================================================== 241 * FUNCTION : mm_camera_intf_do_auto_focus 242 * 243 * DESCRIPTION: performing auto focus 244 * 245 * PARAMETERS : 246 * @camera_handle: camera handle 247 * 248 * RETURN : int32_t type of status 249 * 0 -- success 250 * -1 -- failure 251 * NOTE : if this call success, we will always assume there will 252 * be an auto_focus event following up. 253 *==========================================================================*/ 254static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle) 255{ 256 int32_t rc = -1; 257 mm_camera_obj_t * my_obj = NULL; 258 259 pthread_mutex_lock(&g_intf_lock); 260 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 261 262 if(my_obj) { 263 pthread_mutex_lock(&my_obj->cam_lock); 264 pthread_mutex_unlock(&g_intf_lock); 265 rc = mm_camera_do_auto_focus(my_obj); 266 } else { 267 pthread_mutex_unlock(&g_intf_lock); 268 } 269 return rc; 270} 271 272/*=========================================================================== 273 * FUNCTION : mm_camera_intf_cancel_auto_focus 274 * 275 * DESCRIPTION: cancel auto focus 276 * 277 * PARAMETERS : 278 * @camera_handle: camera handle 279 * 280 * RETURN : int32_t type of status 281 * 0 -- success 282 * -1 -- failure 283 *==========================================================================*/ 284static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle) 285{ 286 int32_t rc = -1; 287 mm_camera_obj_t * my_obj = NULL; 288 289 pthread_mutex_lock(&g_intf_lock); 290 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 291 292 if(my_obj) { 293 pthread_mutex_lock(&my_obj->cam_lock); 294 pthread_mutex_unlock(&g_intf_lock); 295 rc = mm_camera_cancel_auto_focus(my_obj); 296 } else { 297 pthread_mutex_unlock(&g_intf_lock); 298 } 299 return rc; 300} 301 302/*=========================================================================== 303 * FUNCTION : mm_camera_intf_prepare_snapshot 304 * 305 * DESCRIPTION: prepare hardware for snapshot 306 * 307 * PARAMETERS : 308 * @camera_handle: camera handle 309 * @do_af_flag : flag indicating if AF is needed 310 * 311 * RETURN : int32_t type of status 312 * 0 -- success 313 * -1 -- failure 314 *==========================================================================*/ 315static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle, 316 int32_t do_af_flag) 317{ 318 int32_t rc = -1; 319 mm_camera_obj_t * my_obj = NULL; 320 321 pthread_mutex_lock(&g_intf_lock); 322 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 323 324 if(my_obj) { 325 pthread_mutex_lock(&my_obj->cam_lock); 326 pthread_mutex_unlock(&g_intf_lock); 327 rc = mm_camera_prepare_snapshot(my_obj, do_af_flag); 328 } else { 329 pthread_mutex_unlock(&g_intf_lock); 330 } 331 return rc; 332} 333 334/*=========================================================================== 335 * FUNCTION : mm_camera_intf_start_zsl_snapshot 336 * 337 * DESCRIPTION: start zsl snapshot 338 * 339 * PARAMETERS : 340 * @camera_handle: camera handle 341 * 342 * RETURN : int32_t type of status 343 * 0 -- success 344 * -1 -- failure 345 *==========================================================================*/ 346static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle) 347{ 348 int32_t rc = -1; 349 mm_camera_obj_t * my_obj = NULL; 350 351 pthread_mutex_lock(&g_intf_lock); 352 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 353 354 if(my_obj) { 355 pthread_mutex_lock(&my_obj->cam_lock); 356 pthread_mutex_unlock(&g_intf_lock); 357 rc = mm_camera_start_zsl_snapshot(my_obj); 358 } else { 359 pthread_mutex_unlock(&g_intf_lock); 360 } 361 return rc; 362} 363 364/*=========================================================================== 365 * FUNCTION : mm_camera_intf_stop_zsl_snapshot 366 * 367 * DESCRIPTION: stop zsl snapshot 368 * 369 * PARAMETERS : 370 * @camera_handle: camera handle 371 * 372 * RETURN : int32_t type of status 373 * 0 -- success 374 * -1 -- failure 375 *==========================================================================*/ 376static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle) 377{ 378 int32_t rc = -1; 379 mm_camera_obj_t * my_obj = NULL; 380 381 pthread_mutex_lock(&g_intf_lock); 382 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 383 384 if(my_obj) { 385 pthread_mutex_lock(&my_obj->cam_lock); 386 pthread_mutex_unlock(&g_intf_lock); 387 rc = mm_camera_stop_zsl_snapshot(my_obj); 388 } else { 389 pthread_mutex_unlock(&g_intf_lock); 390 } 391 return rc; 392} 393 394/*=========================================================================== 395 * FUNCTION : mm_camera_intf_close 396 * 397 * DESCRIPTION: close a camera by its handle 398 * 399 * PARAMETERS : 400 * @camera_handle: camera handle 401 * 402 * RETURN : int32_t type of status 403 * 0 -- success 404 * -1 -- failure 405 *==========================================================================*/ 406static int32_t mm_camera_intf_close(uint32_t camera_handle) 407{ 408 int32_t rc = -1; 409 uint8_t cam_idx = camera_handle & 0x00ff; 410 mm_camera_obj_t * my_obj = NULL; 411 412 CDBG("%s E: camera_handler = %d ", __func__, camera_handle); 413 414 pthread_mutex_lock(&g_intf_lock); 415 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 416 417 if (my_obj){ 418 my_obj->ref_count--; 419 420 if(my_obj->ref_count > 0) { 421 /* still have reference to obj, return here */ 422 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count); 423 pthread_mutex_unlock(&g_intf_lock); 424 rc = 0; 425 } else { 426 /* need close camera here as no other reference 427 * first empty g_cam_ctrl's referent to cam_obj */ 428 g_cam_ctrl.cam_obj[cam_idx] = NULL; 429 430 pthread_mutex_lock(&my_obj->cam_lock); 431 pthread_mutex_unlock(&g_intf_lock); 432 433 rc = mm_camera_close(my_obj); 434 435 pthread_mutex_destroy(&my_obj->cam_lock); 436 free(my_obj); 437 } 438 } else { 439 pthread_mutex_unlock(&g_intf_lock); 440 } 441 442 return rc; 443} 444 445/*=========================================================================== 446 * FUNCTION : mm_camera_intf_add_channel 447 * 448 * DESCRIPTION: add a channel 449 * 450 * PARAMETERS : 451 * @camera_handle: camera handle 452 * @attr : bundle attribute of the channel if needed 453 * @channel_cb : callback function for bundle data notify 454 * @userdata : user data ptr 455 * 456 * RETURN : uint32_t type of channel handle 457 * 0 -- invalid channel handle, meaning the op failed 458 * >0 -- successfully added a channel with a valid handle 459 * NOTE : if no bundle data notify is needed, meaning each stream in the 460 * channel will have its own stream data notify callback, then 461 * attr, channel_cb, and userdata can be NULL. In this case, 462 * no matching logic will be performed in channel for the bundling. 463 *==========================================================================*/ 464static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle, 465 mm_camera_channel_attr_t *attr, 466 mm_camera_buf_notify_t channel_cb, 467 void *userdata) 468{ 469 uint32_t ch_id = 0; 470 mm_camera_obj_t * my_obj = NULL; 471 472 CDBG("%s :E camera_handler = %d", __func__, camera_handle); 473 pthread_mutex_lock(&g_intf_lock); 474 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 475 476 if(my_obj) { 477 pthread_mutex_lock(&my_obj->cam_lock); 478 pthread_mutex_unlock(&g_intf_lock); 479 ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata); 480 } else { 481 pthread_mutex_unlock(&g_intf_lock); 482 } 483 CDBG("%s :X ch_id = %d", __func__, ch_id); 484 return ch_id; 485} 486 487/*=========================================================================== 488 * FUNCTION : mm_camera_intf_del_channel 489 * 490 * DESCRIPTION: delete a channel by its handle 491 * 492 * PARAMETERS : 493 * @camera_handle: camera handle 494 * @ch_id : channel handle 495 * 496 * RETURN : int32_t type of status 497 * 0 -- success 498 * -1 -- failure 499 * NOTE : all streams in the channel should be stopped already before 500 * this channel can be deleted. 501 *==========================================================================*/ 502static int32_t mm_camera_intf_del_channel(uint32_t camera_handle, 503 uint32_t ch_id) 504{ 505 int32_t rc = -1; 506 mm_camera_obj_t * my_obj = NULL; 507 508 CDBG("%s :E ch_id = %d", __func__, ch_id); 509 pthread_mutex_lock(&g_intf_lock); 510 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 511 512 if(my_obj) { 513 pthread_mutex_lock(&my_obj->cam_lock); 514 pthread_mutex_unlock(&g_intf_lock); 515 rc = mm_camera_del_channel(my_obj, ch_id); 516 } else { 517 pthread_mutex_unlock(&g_intf_lock); 518 } 519 CDBG("%s :X", __func__); 520 return rc; 521} 522 523/*=========================================================================== 524 * FUNCTION : mm_camera_intf_get_bundle_info 525 * 526 * DESCRIPTION: query bundle info of the channel 527 * 528 * PARAMETERS : 529 * @camera_handle: camera handle 530 * @ch_id : channel handle 531 * @bundle_info : bundle info to be filled in 532 * 533 * RETURN : int32_t type of status 534 * 0 -- success 535 * -1 -- failure 536 * NOTE : all streams in the channel should be stopped already before 537 * this channel can be deleted. 538 *==========================================================================*/ 539static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle, 540 uint32_t ch_id, 541 cam_bundle_config_t *bundle_info) 542{ 543 int32_t rc = -1; 544 mm_camera_obj_t * my_obj = NULL; 545 546 CDBG("%s :E ch_id = %d", __func__, ch_id); 547 pthread_mutex_lock(&g_intf_lock); 548 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 549 550 if(my_obj) { 551 pthread_mutex_lock(&my_obj->cam_lock); 552 pthread_mutex_unlock(&g_intf_lock); 553 rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info); 554 } else { 555 pthread_mutex_unlock(&g_intf_lock); 556 } 557 CDBG("%s :X", __func__); 558 return rc; 559} 560 561/*=========================================================================== 562 * FUNCTION : mm_camera_intf_register_event_notify 563 * 564 * DESCRIPTION: register for event notify 565 * 566 * PARAMETERS : 567 * @camera_handle: camera handle 568 * @evt_cb : callback for event notify 569 * @user_data : user data ptr 570 * 571 * RETURN : int32_t type of status 572 * 0 -- success 573 * -1 -- failure 574 *==========================================================================*/ 575static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle, 576 mm_camera_event_notify_t evt_cb, 577 void * user_data) 578{ 579 int32_t rc = -1; 580 mm_camera_obj_t * my_obj = NULL; 581 582 CDBG("%s :E ", __func__); 583 pthread_mutex_lock(&g_intf_lock); 584 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 585 586 if(my_obj) { 587 pthread_mutex_lock(&my_obj->cam_lock); 588 pthread_mutex_unlock(&g_intf_lock); 589 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data); 590 } else { 591 pthread_mutex_unlock(&g_intf_lock); 592 } 593 CDBG("%s :E rc = %d", __func__, rc); 594 return rc; 595} 596 597/*=========================================================================== 598 * FUNCTION : mm_camera_intf_qbuf 599 * 600 * DESCRIPTION: enqueue buffer back to kernel 601 * 602 * PARAMETERS : 603 * @camera_handle: camera handle 604 * @ch_id : channel handle 605 * @buf : buf ptr to be enqueued 606 * 607 * RETURN : int32_t type of status 608 * 0 -- success 609 * -1 -- failure 610 *==========================================================================*/ 611static int32_t mm_camera_intf_qbuf(uint32_t camera_handle, 612 uint32_t ch_id, 613 mm_camera_buf_def_t *buf) 614{ 615 int32_t rc = -1; 616 mm_camera_obj_t * my_obj = NULL; 617 618 pthread_mutex_lock(&g_intf_lock); 619 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 620 621 if(my_obj) { 622 pthread_mutex_lock(&my_obj->cam_lock); 623 pthread_mutex_unlock(&g_intf_lock); 624 rc = mm_camera_qbuf(my_obj, ch_id, buf); 625 } else { 626 pthread_mutex_unlock(&g_intf_lock); 627 } 628 CDBG("%s :X evt_type = %d",__func__,rc); 629 return rc; 630} 631 632/*=========================================================================== 633 * FUNCTION : mm_camera_intf_add_stream 634 * 635 * DESCRIPTION: add a stream into a channel 636 * 637 * PARAMETERS : 638 * @camera_handle: camera handle 639 * @ch_id : channel handle 640 * 641 * RETURN : uint32_t type of stream handle 642 * 0 -- invalid stream handle, meaning the op failed 643 * >0 -- successfully added a stream with a valid handle 644 *==========================================================================*/ 645static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle, 646 uint32_t ch_id) 647{ 648 uint32_t stream_id = 0; 649 mm_camera_obj_t * my_obj = NULL; 650 651 CDBG("%s : E handle = %d ch_id = %d", 652 __func__, camera_handle, ch_id); 653 654 pthread_mutex_lock(&g_intf_lock); 655 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 656 657 if(my_obj) { 658 pthread_mutex_lock(&my_obj->cam_lock); 659 pthread_mutex_unlock(&g_intf_lock); 660 stream_id = mm_camera_add_stream(my_obj, ch_id); 661 } else { 662 pthread_mutex_unlock(&g_intf_lock); 663 } 664 CDBG("%s :X stream_id = %d", __func__, stream_id); 665 return stream_id; 666} 667 668/*=========================================================================== 669 * FUNCTION : mm_camera_intf_del_stream 670 * 671 * DESCRIPTION: delete a stream by its handle 672 * 673 * PARAMETERS : 674 * @camera_handle: camera handle 675 * @ch_id : channel handle 676 * @stream_id : stream handle 677 * 678 * RETURN : int32_t type of status 679 * 0 -- success 680 * -1 -- failure 681 * NOTE : stream should be stopped already before it can be deleted. 682 *==========================================================================*/ 683static int32_t mm_camera_intf_del_stream(uint32_t camera_handle, 684 uint32_t ch_id, 685 uint32_t stream_id) 686{ 687 int32_t rc = -1; 688 mm_camera_obj_t * my_obj = NULL; 689 690 CDBG("%s : E handle = %d ch_id = %d stream_id = %d", 691 __func__, camera_handle, ch_id, stream_id); 692 693 pthread_mutex_lock(&g_intf_lock); 694 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 695 696 if(my_obj) { 697 pthread_mutex_lock(&my_obj->cam_lock); 698 pthread_mutex_unlock(&g_intf_lock); 699 rc = mm_camera_del_stream(my_obj, ch_id, stream_id); 700 } else { 701 pthread_mutex_unlock(&g_intf_lock); 702 } 703 CDBG("%s :X rc = %d", __func__, rc); 704 return rc; 705} 706 707/*=========================================================================== 708 * FUNCTION : mm_camera_intf_config_stream 709 * 710 * DESCRIPTION: configure a stream 711 * 712 * PARAMETERS : 713 * @camera_handle: camera handle 714 * @ch_id : channel handle 715 * @stream_id : stream handle 716 * @config : stream configuration 717 * 718 * RETURN : int32_t type of status 719 * 0 -- success 720 * -1 -- failure 721 *==========================================================================*/ 722static int32_t mm_camera_intf_config_stream(uint32_t camera_handle, 723 uint32_t ch_id, 724 uint32_t stream_id, 725 mm_camera_stream_config_t *config) 726{ 727 int32_t rc = -1; 728 mm_camera_obj_t * my_obj = NULL; 729 730 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d", 731 __func__, camera_handle, ch_id, stream_id); 732 733 pthread_mutex_lock(&g_intf_lock); 734 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 735 736 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id); 737 738 if(my_obj) { 739 pthread_mutex_lock(&my_obj->cam_lock); 740 pthread_mutex_unlock(&g_intf_lock); 741 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config); 742 } else { 743 pthread_mutex_unlock(&g_intf_lock); 744 } 745 CDBG("%s :X rc = %d", __func__, rc); 746 return rc; 747} 748 749/*=========================================================================== 750 * FUNCTION : mm_camera_intf_start_channel 751 * 752 * DESCRIPTION: start a channel, which will start all streams in the channel 753 * 754 * PARAMETERS : 755 * @camera_handle: camera handle 756 * @ch_id : channel handle 757 * 758 * RETURN : int32_t type of status 759 * 0 -- success 760 * -1 -- failure 761 *==========================================================================*/ 762static int32_t mm_camera_intf_start_channel(uint32_t camera_handle, 763 uint32_t ch_id) 764{ 765 int32_t rc = -1; 766 mm_camera_obj_t * my_obj = NULL; 767 768 pthread_mutex_lock(&g_intf_lock); 769 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 770 771 if(my_obj) { 772 pthread_mutex_lock(&my_obj->cam_lock); 773 pthread_mutex_unlock(&g_intf_lock); 774 rc = mm_camera_start_channel(my_obj, ch_id); 775 } else { 776 pthread_mutex_unlock(&g_intf_lock); 777 } 778 CDBG("%s :X rc = %d", __func__, rc); 779 return rc; 780} 781 782/*=========================================================================== 783 * FUNCTION : mm_camera_intf_stop_channel 784 * 785 * DESCRIPTION: stop a channel, which will stop all streams in the channel 786 * 787 * PARAMETERS : 788 * @camera_handle: camera handle 789 * @ch_id : channel handle 790 * 791 * RETURN : int32_t type of status 792 * 0 -- success 793 * -1 -- failure 794 *==========================================================================*/ 795static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle, 796 uint32_t ch_id) 797{ 798 int32_t rc = -1; 799 mm_camera_obj_t * my_obj = NULL; 800 801 pthread_mutex_lock(&g_intf_lock); 802 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 803 804 if(my_obj) { 805 pthread_mutex_lock(&my_obj->cam_lock); 806 pthread_mutex_unlock(&g_intf_lock); 807 rc = mm_camera_stop_channel(my_obj, ch_id); 808 } else { 809 pthread_mutex_unlock(&g_intf_lock); 810 } 811 CDBG("%s :X rc = %d", __func__, rc); 812 return rc; 813} 814 815/*=========================================================================== 816 * FUNCTION : mm_camera_intf_request_super_buf 817 * 818 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 819 * frames from superbuf queue 820 * 821 * PARAMETERS : 822 * @camera_handle: camera handle 823 * @ch_id : channel handle 824 * @num_buf_requested : number of matched frames needed 825 * 826 * RETURN : int32_t type of status 827 * 0 -- success 828 * -1 -- failure 829 *==========================================================================*/ 830static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle, 831 uint32_t ch_id, 832 uint32_t num_buf_requested) 833{ 834 int32_t rc = -1; 835 CDBG("%s :E camera_handler = %d,ch_id = %d", 836 __func__, camera_handle, ch_id); 837 mm_camera_obj_t * my_obj = NULL; 838 839 pthread_mutex_lock(&g_intf_lock); 840 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 841 842 if(my_obj) { 843 pthread_mutex_lock(&my_obj->cam_lock); 844 pthread_mutex_unlock(&g_intf_lock); 845 rc = mm_camera_request_super_buf(my_obj, ch_id, num_buf_requested); 846 } else { 847 pthread_mutex_unlock(&g_intf_lock); 848 } 849 CDBG("%s :X rc = %d", __func__, rc); 850 return rc; 851} 852 853/*=========================================================================== 854 * FUNCTION : mm_camera_intf_cancel_super_buf_request 855 * 856 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 857 * of matched frames from superbuf queue 858 * 859 * PARAMETERS : 860 * @camera_handle: camera handle 861 * @ch_id : channel handle 862 * 863 * RETURN : int32_t type of status 864 * 0 -- success 865 * -1 -- failure 866 *==========================================================================*/ 867static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle, 868 uint32_t ch_id) 869{ 870 int32_t rc = -1; 871 mm_camera_obj_t * my_obj = NULL; 872 873 CDBG("%s :E camera_handler = %d,ch_id = %d", 874 __func__, camera_handle, ch_id); 875 pthread_mutex_lock(&g_intf_lock); 876 my_obj = mm_camera_util_get_camera_by_handler(camera_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_cancel_super_buf_request(my_obj, ch_id); 882 } else { 883 pthread_mutex_unlock(&g_intf_lock); 884 } 885 CDBG("%s :X rc = %d", __func__, rc); 886 return rc; 887} 888 889/*=========================================================================== 890 * FUNCTION : mm_camera_intf_flush_super_buf_queue 891 * 892 * DESCRIPTION: flush out all frames in the superbuf queue 893 * 894 * PARAMETERS : 895 * @camera_handle: camera handle 896 * @ch_id : channel handle 897 * @frame_idx : frame index 898 * 899 * RETURN : int32_t type of status 900 * 0 -- success 901 * -1 -- failure 902 *==========================================================================*/ 903static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle, 904 uint32_t ch_id, uint32_t frame_idx) 905{ 906 int32_t rc = -1; 907 mm_camera_obj_t * my_obj = NULL; 908 909 CDBG("%s :E camera_handler = %d,ch_id = %d", 910 __func__, camera_handle, ch_id); 911 pthread_mutex_lock(&g_intf_lock); 912 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 913 914 if(my_obj) { 915 pthread_mutex_lock(&my_obj->cam_lock); 916 pthread_mutex_unlock(&g_intf_lock); 917 rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx); 918 } else { 919 pthread_mutex_unlock(&g_intf_lock); 920 } 921 CDBG("%s :X rc = %d", __func__, rc); 922 return rc; 923} 924 925/*=========================================================================== 926 * FUNCTION : mm_camera_intf_map_buf 927 * 928 * DESCRIPTION: mapping camera buffer via domain socket to server 929 * 930 * PARAMETERS : 931 * @camera_handle: camera handle 932 * @buf_type : type of buffer to be mapped. could be following values: 933 * CAM_MAPPING_BUF_TYPE_CAPABILITY 934 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 935 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 936 * @fd : file descriptor of the buffer 937 * @size : size of the buffer 938 * 939 * RETURN : int32_t type of status 940 * 0 -- success 941 * -1 -- failure 942 *==========================================================================*/ 943static int32_t mm_camera_intf_map_buf(uint32_t camera_handle, 944 uint8_t buf_type, 945 int fd, 946 uint32_t size) 947{ 948 int32_t rc = -1; 949 mm_camera_obj_t * my_obj = NULL; 950 951 pthread_mutex_lock(&g_intf_lock); 952 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 953 954 if(my_obj) { 955 pthread_mutex_lock(&my_obj->cam_lock); 956 pthread_mutex_unlock(&g_intf_lock); 957 rc = mm_camera_map_buf(my_obj, buf_type, fd, size); 958 } else { 959 pthread_mutex_unlock(&g_intf_lock); 960 } 961 return rc; 962} 963 964/*=========================================================================== 965 * FUNCTION : mm_camera_intf_unmap_buf 966 * 967 * DESCRIPTION: unmapping camera buffer via domain socket to server 968 * 969 * PARAMETERS : 970 * @camera_handle: camera handle 971 * @buf_type : type of buffer to be unmapped. could be following values: 972 * CAM_MAPPING_BUF_TYPE_CAPABILITY 973 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 974 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 975 * 976 * RETURN : int32_t type of status 977 * 0 -- success 978 * -1 -- failure 979 *==========================================================================*/ 980static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle, 981 uint8_t buf_type) 982{ 983 int32_t rc = -1; 984 mm_camera_obj_t * my_obj = NULL; 985 986 pthread_mutex_lock(&g_intf_lock); 987 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 988 989 if(my_obj) { 990 pthread_mutex_lock(&my_obj->cam_lock); 991 pthread_mutex_unlock(&g_intf_lock); 992 rc = mm_camera_unmap_buf(my_obj, buf_type); 993 } else { 994 pthread_mutex_unlock(&g_intf_lock); 995 } 996 return rc; 997} 998 999/*=========================================================================== 1000 * FUNCTION : mm_camera_intf_set_stream_parms 1001 * 1002 * DESCRIPTION: set parameters per stream 1003 * 1004 * PARAMETERS : 1005 * @camera_handle: camera handle 1006 * @ch_id : channel handle 1007 * @s_id : stream handle 1008 * @parms : ptr to a param struct to be set to server 1009 * 1010 * RETURN : int32_t type of status 1011 * 0 -- success 1012 * -1 -- failure 1013 * NOTE : Assume the parms struct buf is already mapped to server via 1014 * domain socket. Corresponding fields of parameters to be set 1015 * are already filled in by upper layer caller. 1016 *==========================================================================*/ 1017static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle, 1018 uint32_t ch_id, 1019 uint32_t s_id, 1020 cam_stream_parm_buffer_t *parms) 1021{ 1022 int32_t rc = -1; 1023 mm_camera_obj_t * my_obj = NULL; 1024 1025 pthread_mutex_lock(&g_intf_lock); 1026 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1027 1028 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d", 1029 __func__, camera_handle, ch_id, s_id); 1030 1031 if(my_obj) { 1032 pthread_mutex_lock(&my_obj->cam_lock); 1033 pthread_mutex_unlock(&g_intf_lock); 1034 rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms); 1035 }else{ 1036 pthread_mutex_unlock(&g_intf_lock); 1037 } 1038 CDBG("%s :X rc = %d", __func__, rc); 1039 return rc; 1040} 1041 1042/*=========================================================================== 1043 * FUNCTION : mm_camera_intf_get_stream_parms 1044 * 1045 * DESCRIPTION: get parameters per stream 1046 * 1047 * PARAMETERS : 1048 * @camera_handle: camera handle 1049 * @ch_id : channel handle 1050 * @s_id : stream handle 1051 * @parms : ptr to a param struct to be get from server 1052 * 1053 * RETURN : int32_t type of status 1054 * 0 -- success 1055 * -1 -- failure 1056 * NOTE : Assume the parms struct buf is already mapped to server via 1057 * domain socket. Parameters to be get from server are already 1058 * filled in by upper layer caller. After this call, corresponding 1059 * fields of requested parameters will be filled in by server with 1060 * detailed information. 1061 *==========================================================================*/ 1062static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle, 1063 uint32_t ch_id, 1064 uint32_t s_id, 1065 cam_stream_parm_buffer_t *parms) 1066{ 1067 int32_t rc = -1; 1068 mm_camera_obj_t * my_obj = NULL; 1069 1070 pthread_mutex_lock(&g_intf_lock); 1071 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1072 1073 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d", 1074 __func__, camera_handle, ch_id, s_id); 1075 1076 if(my_obj) { 1077 pthread_mutex_lock(&my_obj->cam_lock); 1078 pthread_mutex_unlock(&g_intf_lock); 1079 rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms); 1080 }else{ 1081 pthread_mutex_unlock(&g_intf_lock); 1082 } 1083 1084 CDBG("%s :X rc = %d", __func__, rc); 1085 return rc; 1086} 1087 1088/*=========================================================================== 1089 * FUNCTION : mm_camera_intf_map_stream_buf 1090 * 1091 * DESCRIPTION: mapping stream buffer via domain socket to server 1092 * 1093 * PARAMETERS : 1094 * @camera_handle: camera handle 1095 * @ch_id : channel handle 1096 * @s_id : stream handle 1097 * @buf_type : type of buffer to be mapped. could be following values: 1098 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1099 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1100 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1101 * @buf_idx : index of buffer within the stream buffers, only valid if 1102 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1103 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1104 * @plane_idx : plane index. If all planes share the same fd, 1105 * plane_idx = -1; otherwise, plean_idx is the 1106 * index to plane (0..num_of_planes) 1107 * @fd : file descriptor of the buffer 1108 * @size : size of the buffer 1109 * 1110 * RETURN : int32_t type of status 1111 * 0 -- success 1112 * -1 -- failure 1113 *==========================================================================*/ 1114static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle, 1115 uint32_t ch_id, 1116 uint32_t stream_id, 1117 uint8_t buf_type, 1118 uint32_t buf_idx, 1119 int32_t plane_idx, 1120 int fd, 1121 uint32_t size) 1122{ 1123 int32_t rc = -1; 1124 mm_camera_obj_t * my_obj = NULL; 1125 1126 pthread_mutex_lock(&g_intf_lock); 1127 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1128 1129 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 1130 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx); 1131 1132 if(my_obj) { 1133 pthread_mutex_lock(&my_obj->cam_lock); 1134 pthread_mutex_unlock(&g_intf_lock); 1135 rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id, 1136 buf_type, buf_idx, plane_idx, 1137 fd, size); 1138 }else{ 1139 pthread_mutex_unlock(&g_intf_lock); 1140 } 1141 1142 CDBG("%s :X rc = %d", __func__, rc); 1143 return rc; 1144} 1145 1146/*=========================================================================== 1147 * FUNCTION : mm_camera_intf_unmap_stream_buf 1148 * 1149 * DESCRIPTION: unmapping stream buffer via domain socket to server 1150 * 1151 * PARAMETERS : 1152 * @camera_handle: camera handle 1153 * @ch_id : channel handle 1154 * @s_id : stream handle 1155 * @buf_type : type of buffer to be unmapped. could be following values: 1156 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1157 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1158 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1159 * @buf_idx : index of buffer within the stream buffers, only valid if 1160 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1161 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1162 * @plane_idx : plane index. If all planes share the same fd, 1163 * plane_idx = -1; otherwise, plean_idx is the 1164 * index to plane (0..num_of_planes) 1165 * 1166 * RETURN : int32_t type of status 1167 * 0 -- success 1168 * -1 -- failure 1169 *==========================================================================*/ 1170static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle, 1171 uint32_t ch_id, 1172 uint32_t stream_id, 1173 uint8_t buf_type, 1174 uint32_t buf_idx, 1175 int32_t plane_idx) 1176{ 1177 int32_t rc = -1; 1178 mm_camera_obj_t * my_obj = NULL; 1179 1180 pthread_mutex_lock(&g_intf_lock); 1181 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1182 1183 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 1184 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx); 1185 1186 if(my_obj) { 1187 pthread_mutex_lock(&my_obj->cam_lock); 1188 pthread_mutex_unlock(&g_intf_lock); 1189 rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id, 1190 buf_type, buf_idx, plane_idx); 1191 }else{ 1192 pthread_mutex_unlock(&g_intf_lock); 1193 } 1194 1195 CDBG("%s :X rc = %d", __func__, rc); 1196 return rc; 1197} 1198 1199/*=========================================================================== 1200 * FUNCTION : get_num_of_cameras 1201 * 1202 * DESCRIPTION: get number of cameras 1203 * 1204 * PARAMETERS : 1205 * 1206 * RETURN : number of cameras supported 1207 *==========================================================================*/ 1208uint8_t get_num_of_cameras() 1209{ 1210 int rc = 0; 1211 int dev_fd = 0; 1212 struct media_device_info mdev_info; 1213 int num_media_devices = 0; 1214 uint8_t num_cameras = 0; 1215 1216 CDBG("%s : E", __func__); 1217 /* lock the mutex */ 1218 pthread_mutex_lock(&g_intf_lock); 1219 while (1) { 1220 char dev_name[32]; 1221 int num_entities; 1222 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1223 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1224 if (dev_fd <= 0) { 1225 CDBG("Done discovering media devices\n"); 1226 break; 1227 } 1228 num_media_devices++; 1229 memset(&mdev_info, 0, sizeof(mdev_info)); 1230 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1231 if (rc < 0) { 1232 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1233 close(dev_fd); 1234 dev_fd = 0; 1235 num_cameras = 0; 1236 break; 1237 } 1238 1239 if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) { 1240 close(dev_fd); 1241 dev_fd = 0; 1242 continue; 1243 } 1244 1245 num_entities = 1; 1246 while (1) { 1247 struct media_entity_desc entity; 1248 memset(&entity, 0, sizeof(entity)); 1249 entity.id = num_entities++; 1250 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1251 if (rc < 0) { 1252 CDBG("Done enumerating media entities\n"); 1253 rc = 0; 1254 break; 1255 } 1256 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 1257 strncpy(g_cam_ctrl.video_dev_name[num_cameras], 1258 entity.name, sizeof(entity.name)); 1259 break; 1260 } 1261 } 1262 1263 CDBG("%s: dev_info[id=%d,name='%s']\n", 1264 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); 1265 1266 num_cameras++; 1267 close(dev_fd); 1268 dev_fd = 0; 1269 } 1270 g_cam_ctrl.num_cam = num_cameras; 1271 1272 /* unlock the mutex */ 1273 pthread_mutex_unlock(&g_intf_lock); 1274 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 1275 return g_cam_ctrl.num_cam; 1276} 1277 1278/* camera ops v-table */ 1279static mm_camera_ops_t mm_camera_ops = { 1280 .query_capability = mm_camera_intf_query_capability, 1281 .register_event_notify = mm_camera_intf_register_event_notify, 1282 .close_camera = mm_camera_intf_close, 1283 .set_parms = mm_camera_intf_set_parms, 1284 .get_parms = mm_camera_intf_get_parms, 1285 .do_auto_focus = mm_camera_intf_do_auto_focus, 1286 .cancel_auto_focus = mm_camera_intf_cancel_auto_focus, 1287 .prepare_snapshot = mm_camera_intf_prepare_snapshot, 1288 .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot, 1289 .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot, 1290 .map_buf = mm_camera_intf_map_buf, 1291 .unmap_buf = mm_camera_intf_unmap_buf, 1292 .add_channel = mm_camera_intf_add_channel, 1293 .delete_channel = mm_camera_intf_del_channel, 1294 .get_bundle_info = mm_camera_intf_get_bundle_info, 1295 .add_stream = mm_camera_intf_add_stream, 1296 .delete_stream = mm_camera_intf_del_stream, 1297 .config_stream = mm_camera_intf_config_stream, 1298 .qbuf = mm_camera_intf_qbuf, 1299 .map_stream_buf = mm_camera_intf_map_stream_buf, 1300 .unmap_stream_buf = mm_camera_intf_unmap_stream_buf, 1301 .set_stream_parms = mm_camera_intf_set_stream_parms, 1302 .get_stream_parms = mm_camera_intf_get_stream_parms, 1303 .start_channel = mm_camera_intf_start_channel, 1304 .stop_channel = mm_camera_intf_stop_channel, 1305 .request_super_buf = mm_camera_intf_request_super_buf, 1306 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request, 1307 .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue 1308}; 1309 1310/*=========================================================================== 1311 * FUNCTION : camera_open 1312 * 1313 * DESCRIPTION: open a camera by camera index 1314 * 1315 * PARAMETERS : 1316 * @camera_idx : camera index. should within range of 0 to num_of_cameras 1317 * 1318 * RETURN : ptr to a virtual table containing camera handle and operation table. 1319 * NULL if failed. 1320 *==========================================================================*/ 1321mm_camera_vtbl_t * camera_open(uint8_t camera_idx) 1322{ 1323 int32_t rc = 0; 1324 mm_camera_obj_t* cam_obj = NULL; 1325 1326 CDBG("%s: E camera_idx = %d\n", __func__, camera_idx); 1327 if (camera_idx >= g_cam_ctrl.num_cam) { 1328 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx); 1329 return NULL; 1330 } 1331 1332 pthread_mutex_lock(&g_intf_lock); 1333 /* opened already */ 1334 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) { 1335 /* Add reference */ 1336 g_cam_ctrl.cam_obj[camera_idx]->ref_count++; 1337 pthread_mutex_unlock(&g_intf_lock); 1338 CDBG("%s: opened alreadyn", __func__); 1339 return &g_cam_ctrl.cam_obj[camera_idx]->vtbl; 1340 } 1341 1342 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); 1343 if(NULL == cam_obj) { 1344 pthread_mutex_unlock(&g_intf_lock); 1345 CDBG("%s: no mem", __func__); 1346 return NULL; 1347 } 1348 1349 /* initialize camera obj */ 1350 memset(cam_obj, 0, sizeof(mm_camera_obj_t)); 1351 cam_obj->ref_count++; 1352 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx); 1353 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */ 1354 cam_obj->vtbl.ops = &mm_camera_ops; 1355 pthread_mutex_init(&cam_obj->cam_lock, NULL); 1356 1357 rc = mm_camera_open(cam_obj); 1358 if(rc != 0) { 1359 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc); 1360 pthread_mutex_destroy(&cam_obj->cam_lock); 1361 g_cam_ctrl.cam_obj[camera_idx] = NULL; 1362 free(cam_obj); 1363 cam_obj = NULL; 1364 pthread_mutex_unlock(&g_intf_lock); 1365 return NULL; 1366 }else{ 1367 CDBG("%s: Open succeded\n", __func__); 1368 g_cam_ctrl.cam_obj[camera_idx] = cam_obj; 1369 pthread_mutex_unlock(&g_intf_lock); 1370 return &cam_obj->vtbl; 1371 } 1372} 1373