1 /* Copyright (c) 2015-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 #define LOG_TAG "QCameraMuxer" 31 32 // System dependencies 33 #include <fcntl.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <utils/Errors.h> 37 #define STAT_H <SYSTEM_HEADER_PREFIX/stat.h> 38 #include STAT_H 39 40 // Camera dependencies 41 #include "QCameraMuxer.h" 42 #include "QCamera2HWI.h" 43 44 extern "C" { 45 #include "mm_camera_dbg.h" 46 } 47 48 /* Muxer implementation */ 49 using namespace android; 50 namespace qcamera { 51 52 QCameraMuxer *gMuxer = NULL; 53 54 //Error Check Macros 55 #define CHECK_MUXER() \ 56 if (!gMuxer) { \ 57 LOGE("Error getting muxer "); \ 58 return; \ 59 } \ 60 61 #define CHECK_MUXER_ERROR() \ 62 if (!gMuxer) { \ 63 LOGE("Error getting muxer "); \ 64 return -ENODEV; \ 65 } \ 66 67 #define CHECK_CAMERA(pCam) \ 68 if (!pCam) { \ 69 LOGE("Error getting physical camera"); \ 70 return; \ 71 } \ 72 73 #define CHECK_CAMERA_ERROR(pCam) \ 74 if (!pCam) { \ 75 LOGE("Error getting physical camera"); \ 76 return -ENODEV; \ 77 } \ 78 79 #define CHECK_HWI(hwi) \ 80 if (!hwi) { \ 81 LOGE("Error !! HWI not found!!"); \ 82 return; \ 83 } \ 84 85 #define CHECK_HWI_ERROR(hwi) \ 86 if (!hwi) { \ 87 LOGE("Error !! HWI not found!!"); \ 88 return -ENODEV; \ 89 } \ 90 91 92 /*=========================================================================== 93 * FUNCTION : getCameraMuxer 94 * 95 * DESCRIPTION : Creates Camera Muxer if not created 96 * 97 * PARAMETERS: 98 * @pMuxer : Pointer to retrieve Camera Muxer 99 * @num_of_cameras : Number of Physical Cameras on device 100 * 101 * RETURN : NONE 102 *==========================================================================*/ 103 void QCameraMuxer::getCameraMuxer( 104 QCameraMuxer** pMuxer, uint32_t num_of_cameras) 105 { 106 *pMuxer = NULL; 107 if (!gMuxer) { 108 gMuxer = new QCameraMuxer(num_of_cameras); 109 } 110 CHECK_MUXER(); 111 *pMuxer = gMuxer; 112 LOGH("gMuxer: %p ", gMuxer); 113 return; 114 } 115 116 /*=========================================================================== 117 * FUNCTION : QCameraMuxer 118 * 119 * DESCRIPTION : QCameraMuxer Constructor 120 * 121 * PARAMETERS: 122 * @num_of_cameras : Number of Physical Cameras on device 123 * 124 *==========================================================================*/ 125 QCameraMuxer::QCameraMuxer(uint32_t num_of_cameras) 126 : mJpegClientHandle(0), 127 m_pPhyCamera(NULL), 128 m_pLogicalCamera(NULL), 129 m_pCallbacks(NULL), 130 m_bAuxCameraExposed(FALSE), 131 m_nPhyCameras(num_of_cameras), 132 m_nLogicalCameras(0), 133 m_MainJpegQ(releaseJpegInfo, this), 134 m_AuxJpegQ(releaseJpegInfo, this), 135 m_pRelCamMpoJpeg(NULL), 136 m_pMpoCallbackCookie(NULL), 137 m_pJpegCallbackCookie(NULL), 138 m_bDumpImages(FALSE), 139 m_bMpoEnabled(TRUE), 140 m_bFrameSyncEnabled(FALSE), 141 m_bRecordingHintInternallySet(FALSE) 142 { 143 setupLogicalCameras(); 144 memset(&mJpegOps, 0, sizeof(mJpegOps)); 145 memset(&mJpegMpoOps, 0, sizeof(mJpegMpoOps)); 146 memset(&mGetMemoryCb, 0, sizeof(mGetMemoryCb)); 147 memset(&mDataCb, 0, sizeof(mDataCb)); 148 149 // initialize mutex for MPO composition 150 pthread_mutex_init(&m_JpegLock, NULL); 151 // launch MPO composition thread 152 m_ComposeMpoTh.launch(composeMpoRoutine, this); 153 154 //Check whether dual camera images need to be dumped 155 char prop[PROPERTY_VALUE_MAX]; 156 property_get("persist.camera.dual.camera.dump", prop, "0"); 157 m_bDumpImages = atoi(prop); 158 LOGH("dualCamera dump images:%d ", m_bDumpImages); 159 } 160 161 /*=========================================================================== 162 * FUNCTION : ~QCameraMuxer 163 * 164 * DESCRIPTION : QCameraMuxer Desctructor 165 * 166 *==========================================================================*/ 167 QCameraMuxer::~QCameraMuxer() { 168 if (m_pLogicalCamera) { 169 delete [] m_pLogicalCamera; 170 m_pLogicalCamera = NULL; 171 } 172 if (m_pPhyCamera) { 173 delete [] m_pPhyCamera; 174 m_pPhyCamera = NULL; 175 } 176 177 if (NULL != m_pRelCamMpoJpeg) { 178 m_pRelCamMpoJpeg->release(m_pRelCamMpoJpeg); 179 m_pRelCamMpoJpeg = NULL; 180 } 181 // flush Jpeg Queues 182 m_MainJpegQ.flush(); 183 m_AuxJpegQ.flush(); 184 185 // stop and exit MPO composition thread 186 m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, FALSE); 187 m_ComposeMpoTh.exit(); 188 189 pthread_mutex_destroy(&m_JpegLock); 190 } 191 192 /*=========================================================================== 193 * FUNCTION : get_number_of_cameras 194 * 195 * DESCRIPTION : Provide number of Logical Cameras 196 * 197 * RETURN : Number of logical Cameras 198 *==========================================================================*/ 199 int QCameraMuxer::get_number_of_cameras() 200 { 201 return gMuxer->getNumberOfCameras(); 202 } 203 204 /*=========================================================================== 205 * FUNCTION : get_camera_info 206 * 207 * DESCRIPTION : get logical camera info 208 * 209 * PARAMETERS: 210 * @camera_id : Logical Camera ID 211 * @info : Logical Main Camera Info 212 * 213 * RETURN : 214 * NO_ERROR : success 215 * ENODEV : Camera not found 216 * other: non-zero failure code 217 *==========================================================================*/ 218 int QCameraMuxer::get_camera_info(int camera_id, struct camera_info *info) 219 { 220 int rc = NO_ERROR; 221 LOGH("E"); 222 cam_sync_type_t type; 223 if ((camera_id < 0) || (camera_id >= gMuxer->getNumberOfCameras())) { 224 LOGE("Camera id %d not found!", camera_id); 225 return -ENODEV; 226 } 227 if(info) { 228 rc = gMuxer->getCameraInfo(camera_id, info, &type); 229 } 230 LOGH("X, rc: %d", rc); 231 return rc; 232 } 233 234 235 /*=========================================================================== 236 * FUNCTION : set_callbacks 237 * 238 * DESCRIPTION : Not Implemented 239 * 240 * PARAMETERS: 241 * @callbacks : Camera Module Callbacks 242 * 243 * RETURN : 244 * NO_ERROR : success 245 * other: non-zero failure code 246 *==========================================================================*/ 247 int QCameraMuxer::set_callbacks(__unused const camera_module_callbacks_t *callbacks) 248 { 249 // Not implemented 250 return NO_ERROR; 251 } 252 253 /*=========================================================================== 254 * FUNCTION : camera_device_open 255 * 256 * DESCRIPTION: static function to open a camera device by its ID 257 * 258 * PARAMETERS : 259 * @modue: hw module 260 * @id : camera ID 261 * @hw_device : ptr to struct storing camera hardware device info 262 * 263 * RETURN : 264 * NO_ERROR : success 265 * BAD_VALUE : Invalid Camera ID 266 * other: non-zero failure code 267 *==========================================================================*/ 268 int QCameraMuxer::camera_device_open( 269 __unused const struct hw_module_t *module, const char *id, 270 struct hw_device_t **hw_device) 271 { 272 int rc = NO_ERROR; 273 LOGH("id= %d",atoi(id)); 274 if (!id) { 275 LOGE("Invalid camera id"); 276 return BAD_VALUE; 277 } 278 279 rc = gMuxer->cameraDeviceOpen(atoi(id), hw_device); 280 LOGH("id= %d, rc: %d", atoi(id), rc); 281 return rc; 282 } 283 284 /*=========================================================================== 285 * FUNCTION : open_legacy 286 * 287 * DESCRIPTION: static function to open a camera device by its ID 288 * 289 * PARAMETERS : 290 * @modue: hw module 291 * @id : camera ID 292 * @halVersion: hal version 293 * @hw_device : ptr to struct storing camera hardware device info 294 * 295 * RETURN : 296 * NO_ERROR : success 297 * BAD_VALUE : Invalid Camera ID 298 * other: non-zero failure code 299 *==========================================================================*/ 300 int QCameraMuxer::open_legacy(__unused const struct hw_module_t* module, 301 const char* id, __unused uint32_t halVersion, struct hw_device_t** hw_device) 302 { 303 int rc = NO_ERROR; 304 LOGH("id= %d", atoi(id)); 305 if (!id) { 306 LOGE("Invalid camera id"); 307 return BAD_VALUE; 308 } 309 310 rc = gMuxer->cameraDeviceOpen(atoi(id), hw_device); 311 LOGH("id= %d, rc: %d", atoi(id), rc); 312 return rc; 313 } 314 315 /*=========================================================================== 316 * FUNCTION : set_preview_window 317 * 318 * DESCRIPTION: Set Preview window for main camera 319 * 320 * PARAMETERS : 321 * @device : camera hardware device info 322 * @window: Preview window ops 323 * 324 * RETURN : 325 * NO_ERROR : success 326 * other: non-zero failure code 327 *==========================================================================*/ 328 int QCameraMuxer::set_preview_window(struct camera_device * device, 329 struct preview_stream_ops *window) 330 { 331 int rc = NO_ERROR; 332 CHECK_MUXER_ERROR(); 333 qcamera_physical_descriptor_t *pCam = NULL; 334 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 335 CHECK_CAMERA_ERROR(cam); 336 337 for (uint32_t i = 0; i < cam->numCameras; i++) { 338 pCam = gMuxer->getPhysicalCamera(cam, i); 339 CHECK_CAMERA_ERROR(pCam); 340 341 // Set preview window only for primary camera 342 if (pCam->mode == CAM_MODE_PRIMARY) { 343 QCamera2HardwareInterface *hwi = pCam->hwi; 344 CHECK_HWI_ERROR(hwi); 345 rc = hwi->set_preview_window(pCam->dev, window); 346 if (rc != NO_ERROR) { 347 LOGE("Error!! setting preview window"); 348 return rc; 349 } 350 break; 351 } 352 } 353 return rc; 354 } 355 356 /*=========================================================================== 357 * FUNCTION : set_callBacks 358 * 359 * DESCRIPTION: Set Framework callbacks to notify various frame data asynchronously 360 * 361 * PARAMETERS : 362 * @device : camera hardware device info 363 * @notify_cb: Notification callback 364 * @data_cb: data callback 365 * @data_cb_timestamp: data timestamp callback 366 * @get_memory: callback to obtain memory 367 * @user : userdata 368 * 369 * RETURN : None 370 *==========================================================================*/ 371 void QCameraMuxer::set_callBacks(struct camera_device * device, 372 camera_notify_callback notify_cb, 373 camera_data_callback data_cb, 374 camera_data_timestamp_callback data_cb_timestamp, 375 camera_request_memory get_memory, 376 void *user) 377 { 378 LOGH("E"); 379 CHECK_MUXER(); 380 int rc = NO_ERROR; 381 qcamera_physical_descriptor_t *pCam = NULL; 382 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 383 CHECK_CAMERA(cam); 384 385 // Set callbacks to HWI 386 for (uint32_t i = 0; i < cam->numCameras; i++) { 387 pCam = gMuxer->getPhysicalCamera(cam, i); 388 CHECK_CAMERA(pCam); 389 390 QCamera2HardwareInterface *hwi = pCam->hwi; 391 CHECK_HWI(hwi); 392 393 hwi->set_CallBacks(pCam->dev, notify_cb, data_cb, data_cb_timestamp, 394 get_memory, user); 395 396 // Set JPG callbacks 397 // sending the physical camera description with the Jpeg callback 398 // this will be retrieved in callbacks to get the cam instance 399 // delivering JPEGs 400 hwi->setJpegCallBacks(jpeg_data_callback, (void*)pCam); 401 402 if (pCam->mode == CAM_MODE_PRIMARY) { 403 rc = gMuxer->setMainJpegCallbackCookie((void*)(pCam)); 404 if(rc != NO_ERROR) { 405 LOGW("Error setting Jpeg callback cookie"); 406 } 407 } 408 } 409 // Store callback in Muxer to send data callbacks 410 rc = gMuxer->setDataCallback(data_cb); 411 if(rc != NO_ERROR) { 412 LOGW("Error setting data callback"); 413 } 414 // memory callback stored to allocate memory for MPO buffer 415 rc = gMuxer->setMemoryCallback(get_memory); 416 if(rc != NO_ERROR) { 417 LOGW("Error setting memory callback"); 418 } 419 // actual user callback cookie is saved in Muxer 420 // this will be used to deliver final MPO callback to the framework 421 rc = gMuxer->setMpoCallbackCookie(user); 422 if(rc != NO_ERROR) { 423 LOGW("Error setting mpo cookie"); 424 } 425 426 LOGH("X"); 427 428 } 429 430 /*=========================================================================== 431 * FUNCTION : enable_msg_type 432 * 433 * DESCRIPTION: Enable msg_type to send callbacks 434 * 435 * PARAMETERS : 436 * @device : camera hardware device info 437 * @msg_type: callback Message type to be enabled 438 * 439 * RETURN : None 440 *==========================================================================*/ 441 void QCameraMuxer::enable_msg_type(struct camera_device * device, int32_t msg_type) 442 { 443 LOGH("E"); 444 CHECK_MUXER(); 445 qcamera_physical_descriptor_t *pCam = NULL; 446 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 447 CHECK_CAMERA(cam); 448 449 for (uint32_t i = 0; i < cam->numCameras; i++) { 450 pCam = gMuxer->getPhysicalCamera(cam, i); 451 CHECK_CAMERA(pCam); 452 QCamera2HardwareInterface *hwi = pCam->hwi; 453 CHECK_HWI(hwi); 454 hwi->enable_msg_type(pCam->dev, msg_type); 455 } 456 LOGH("X"); 457 } 458 459 /*=========================================================================== 460 * FUNCTION : disable_msg_type 461 * 462 * DESCRIPTION: disable msg_type to send callbacks 463 * 464 * PARAMETERS : 465 * @device : camera hardware device info 466 * @msg_type: callback Message type to be disabled 467 * 468 * RETURN : None 469 *==========================================================================*/ 470 void QCameraMuxer::disable_msg_type(struct camera_device * device, int32_t msg_type) 471 { 472 LOGH("E"); 473 CHECK_MUXER(); 474 qcamera_physical_descriptor_t *pCam = NULL; 475 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 476 CHECK_CAMERA(cam); 477 478 for (uint32_t i = 0; i < cam->numCameras; i++) { 479 pCam = gMuxer->getPhysicalCamera(cam, i); 480 CHECK_CAMERA(pCam); 481 QCamera2HardwareInterface *hwi = pCam->hwi; 482 CHECK_HWI(hwi); 483 hwi->disable_msg_type(pCam->dev, msg_type); 484 } 485 LOGH("X"); 486 } 487 488 /*=========================================================================== 489 * FUNCTION : msg_type_enabled 490 * 491 * DESCRIPTION: Check if message type enabled 492 * 493 * PARAMETERS : 494 * @device : camera hardware device info 495 * @msg_type: message type 496 * 497 * RETURN : true/false 498 *==========================================================================*/ 499 int QCameraMuxer::msg_type_enabled(struct camera_device * device, int32_t msg_type) 500 { 501 LOGH("E"); 502 CHECK_MUXER_ERROR(); 503 qcamera_physical_descriptor_t *pCam = NULL; 504 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 505 CHECK_CAMERA_ERROR(cam); 506 507 for (uint32_t i = 0; i < cam->numCameras; i++) { 508 pCam = gMuxer->getPhysicalCamera(cam, i); 509 CHECK_CAMERA_ERROR(pCam); 510 511 QCamera2HardwareInterface *hwi = pCam->hwi; 512 CHECK_HWI_ERROR(hwi); 513 514 if (pCam->mode == CAM_MODE_PRIMARY) { 515 return hwi->msg_type_enabled(pCam->dev, msg_type); 516 } 517 } 518 LOGH("X"); 519 return false; 520 } 521 522 /*=========================================================================== 523 * FUNCTION : start_preview 524 * 525 * DESCRIPTION: Starts logical camera preview 526 * 527 * PARAMETERS : 528 * @device : camera hardware device info 529 * 530 * RETURN : 531 * NO_ERROR : success 532 * other: non-zero failure code 533 *==========================================================================*/ 534 int QCameraMuxer::start_preview(struct camera_device * device) 535 { 536 LOGH("E"); 537 CHECK_MUXER_ERROR(); 538 int rc = NO_ERROR; 539 qcamera_physical_descriptor_t *pCam = NULL; 540 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 541 CHECK_CAMERA_ERROR(cam); 542 543 // prepare preview first for all cameras 544 for (uint32_t i = 0; i < cam->numCameras; i++) { 545 pCam = gMuxer->getPhysicalCamera(cam, i); 546 CHECK_CAMERA_ERROR(pCam); 547 548 QCamera2HardwareInterface *hwi = pCam->hwi; 549 CHECK_HWI_ERROR(hwi); 550 551 rc = hwi->prepare_preview(pCam->dev); 552 if (rc != NO_ERROR) { 553 LOGE("Error preparing preview !! "); 554 return rc; 555 } 556 } 557 558 if (cam->numCameras > 1) { 559 uint sessionId = 0; 560 // Set up sync for camera sessions 561 for (uint32_t i = 0; i < cam->numCameras; i++) { 562 pCam = gMuxer->getPhysicalCamera(cam, i); 563 CHECK_CAMERA_ERROR(pCam); 564 565 QCamera2HardwareInterface *hwi = pCam->hwi; 566 CHECK_HWI_ERROR(hwi); 567 568 if(pCam->mode == CAM_MODE_PRIMARY) { 569 // bundle primary cam with all aux cameras 570 for (uint32_t j = 0; j < cam->numCameras; j++) { 571 if (j == cam->nPrimaryPhyCamIndex) { 572 continue; 573 } 574 sessionId = cam->sId[j]; 575 LOGH("Related cam id: %d, server id: %d sync ON" 576 " related session_id %d", 577 cam->pId[i], cam->sId[i], sessionId); 578 rc = hwi->bundleRelatedCameras(true, sessionId); 579 if (rc != NO_ERROR) { 580 LOGE("Error Bundling physical cameras !! "); 581 return rc; 582 } 583 } 584 } 585 586 if (pCam->mode == CAM_MODE_SECONDARY) { 587 // bundle all aux cam with primary cams 588 sessionId = cam->sId[cam->nPrimaryPhyCamIndex]; 589 LOGH("Related cam id: %d, server id: %d sync ON" 590 " related session_id %d", 591 cam->pId[i], cam->sId[i], sessionId); 592 rc = hwi->bundleRelatedCameras(true, sessionId); 593 if (rc != NO_ERROR) { 594 LOGE("Error Bundling physical cameras !! "); 595 return rc; 596 } 597 } 598 } 599 600 // Remember Sync is ON 601 cam->bSyncOn = true; 602 } 603 // Start Preview for all cameras 604 for (uint32_t i = 0; i < cam->numCameras; i++) { 605 pCam = gMuxer->getPhysicalCamera(cam, i); 606 CHECK_CAMERA_ERROR(pCam); 607 608 QCamera2HardwareInterface *hwi = pCam->hwi; 609 CHECK_HWI_ERROR(hwi); 610 rc = hwi->start_preview(pCam->dev); 611 if (rc != NO_ERROR) { 612 LOGE("Error starting preview !! "); 613 return rc; 614 } 615 } 616 LOGH("X"); 617 return rc; 618 } 619 620 /*=========================================================================== 621 * FUNCTION : stop_preview 622 * 623 * DESCRIPTION: Stops logical camera preview 624 * 625 * PARAMETERS : 626 * @device : camera hardware device info 627 * 628 * RETURN : None 629 *==========================================================================*/ 630 void QCameraMuxer::stop_preview(struct camera_device * device) 631 { 632 LOGH("E"); 633 CHECK_MUXER(); 634 qcamera_physical_descriptor_t *pCam = NULL; 635 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 636 CHECK_CAMERA(cam); 637 638 for (uint32_t i = 0; i < cam->numCameras; i++) { 639 pCam = gMuxer->getPhysicalCamera(cam, i); 640 CHECK_CAMERA(pCam); 641 642 QCamera2HardwareInterface *hwi = pCam->hwi; 643 CHECK_HWI(hwi); 644 645 QCamera2HardwareInterface::stop_preview(pCam->dev); 646 } 647 648 //Flush JPEG Queues. Nodes in Main and Aux JPEGQ are not valid after preview stopped. 649 gMuxer->m_MainJpegQ.flush(); 650 gMuxer->m_AuxJpegQ.flush(); 651 LOGH(" X"); 652 } 653 654 /*=========================================================================== 655 * FUNCTION : preview_enabled 656 * 657 * DESCRIPTION: Checks preview enabled 658 * 659 * PARAMETERS : 660 * @device : camera hardware device info 661 * 662 * RETURN : true/false 663 *==========================================================================*/ 664 int QCameraMuxer::preview_enabled(struct camera_device * device) 665 { 666 LOGH("E"); 667 CHECK_MUXER_ERROR(); 668 qcamera_physical_descriptor_t *pCam = NULL; 669 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 670 CHECK_CAMERA_ERROR(cam); 671 672 for (uint32_t i = 0; i < cam->numCameras; i++) { 673 pCam = gMuxer->getPhysicalCamera(cam, i); 674 CHECK_CAMERA_ERROR(pCam); 675 676 QCamera2HardwareInterface *hwi = pCam->hwi; 677 CHECK_HWI_ERROR(hwi); 678 679 if (pCam->mode == CAM_MODE_PRIMARY) { 680 return hwi->preview_enabled(pCam->dev); 681 } 682 } 683 LOGH("X"); 684 return false; 685 } 686 687 /*=========================================================================== 688 * FUNCTION : store_meta_data_in_buffers 689 * 690 * DESCRIPTION: Stores metadata in buffers 691 * 692 * PARAMETERS : 693 * @device : camera hardware device info 694 * @enable: Enable/disable metadata 695 * 696 * RETURN : 697 * NO_ERROR : success 698 * other: non-zero failure code 699 *==========================================================================*/ 700 int QCameraMuxer::store_meta_data_in_buffers(struct camera_device * device, int enable) 701 { 702 LOGH("E"); 703 CHECK_MUXER_ERROR(); 704 int rc = NO_ERROR; 705 qcamera_physical_descriptor_t *pCam = NULL; 706 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 707 CHECK_CAMERA_ERROR(cam); 708 709 for (uint32_t i = 0; i < cam->numCameras; i++) { 710 pCam = gMuxer->getPhysicalCamera(cam, i); 711 CHECK_CAMERA_ERROR(pCam); 712 713 QCamera2HardwareInterface *hwi = pCam->hwi; 714 CHECK_HWI_ERROR(hwi); 715 716 rc = hwi->store_meta_data_in_buffers(pCam->dev, enable); 717 if (rc != NO_ERROR) { 718 LOGE("Error storing metat data !! "); 719 return rc; 720 } 721 } 722 LOGH("X"); 723 return rc; 724 } 725 726 /*=========================================================================== 727 * FUNCTION : start_recording 728 * 729 * DESCRIPTION: Starts recording on camcorder 730 * 731 * PARAMETERS : 732 * @device : camera hardware device info 733 * 734 * RETURN : 735 * NO_ERROR : success 736 * other: non-zero failure code 737 *==========================================================================*/ 738 int QCameraMuxer::start_recording(struct camera_device * device) 739 { 740 LOGH("E"); 741 CHECK_MUXER_ERROR(); 742 int rc = NO_ERROR; 743 bool previewRestartNeeded = false; 744 qcamera_physical_descriptor_t *pCam = NULL; 745 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 746 CHECK_CAMERA_ERROR(cam); 747 748 // In cases where recording hint is not set, hwi->start_recording will 749 // internally restart the preview. 750 // To take the preview restart control in muxer, 751 // 1. call pre_start_recording first 752 for (uint32_t i = 0; i < cam->numCameras; i++) { 753 pCam = gMuxer->getPhysicalCamera(cam, i); 754 CHECK_CAMERA_ERROR(pCam); 755 756 QCamera2HardwareInterface *hwi = pCam->hwi; 757 CHECK_HWI_ERROR(hwi); 758 759 rc = hwi->pre_start_recording(pCam->dev); 760 if (rc != NO_ERROR) { 761 LOGE("Error preparing recording start!! "); 762 return rc; 763 } 764 } 765 766 // 2. Check if preview restart is needed. Check all cameras. 767 for (uint32_t i = 0; i < cam->numCameras; i++) { 768 pCam = gMuxer->getPhysicalCamera(cam, i); 769 CHECK_CAMERA_ERROR(pCam); 770 771 QCamera2HardwareInterface *hwi = pCam->hwi; 772 CHECK_HWI_ERROR(hwi); 773 774 if (hwi->isPreviewRestartNeeded()) { 775 previewRestartNeeded = hwi->isPreviewRestartNeeded(); 776 break; 777 } 778 } 779 780 if (previewRestartNeeded) { 781 // 3. if preview restart needed. stop the preview first 782 for (uint32_t i = 0; i < cam->numCameras; i++) { 783 pCam = gMuxer->getPhysicalCamera(cam, i); 784 CHECK_CAMERA_ERROR(pCam); 785 786 QCamera2HardwareInterface *hwi = pCam->hwi; 787 CHECK_HWI_ERROR(hwi); 788 789 rc = hwi->restart_stop_preview(pCam->dev); 790 if (rc != NO_ERROR) { 791 LOGE("Error in restart stop preview!! "); 792 return rc; 793 } 794 } 795 796 //4. Update the recording hint value to TRUE 797 for (uint32_t i = 0; i < cam->numCameras; i++) { 798 pCam = gMuxer->getPhysicalCamera(cam, i); 799 CHECK_CAMERA_ERROR(pCam); 800 801 QCamera2HardwareInterface *hwi = pCam->hwi; 802 CHECK_HWI_ERROR(hwi); 803 804 rc = hwi->setRecordingHintValue(TRUE); 805 if (rc != NO_ERROR) { 806 LOGE("Error in setting recording hint value!! "); 807 return rc; 808 } 809 gMuxer->m_bRecordingHintInternallySet = TRUE; 810 } 811 812 // 5. start the preview 813 for (uint32_t i = 0; i < cam->numCameras; i++) { 814 pCam = gMuxer->getPhysicalCamera(cam, i); 815 CHECK_CAMERA_ERROR(pCam); 816 817 QCamera2HardwareInterface *hwi = pCam->hwi; 818 CHECK_HWI_ERROR(hwi); 819 820 rc = hwi->restart_start_preview(pCam->dev); 821 if (rc != NO_ERROR) { 822 LOGE("Error in restart start preview!! "); 823 return rc; 824 } 825 } 826 } 827 828 for (uint32_t i = 0; i < cam->numCameras; i++) { 829 pCam = gMuxer->getPhysicalCamera(cam, i); 830 CHECK_CAMERA_ERROR(pCam); 831 832 QCamera2HardwareInterface *hwi = pCam->hwi; 833 CHECK_HWI_ERROR(hwi); 834 835 if (pCam->mode == CAM_MODE_PRIMARY) { 836 rc = hwi->start_recording(pCam->dev); 837 if (rc != NO_ERROR) { 838 LOGE("Error starting recording!! "); 839 } 840 break; 841 } 842 } 843 LOGH("X"); 844 return rc; 845 } 846 847 /*=========================================================================== 848 * FUNCTION : stop_recording 849 * 850 * DESCRIPTION: Stops recording on camcorder 851 * 852 * PARAMETERS : 853 * @device : camera hardware device info 854 * 855 * RETURN : None 856 *==========================================================================*/ 857 void QCameraMuxer::stop_recording(struct camera_device * device) 858 { 859 860 int rc = NO_ERROR; 861 LOGH("E"); 862 863 CHECK_MUXER(); 864 qcamera_physical_descriptor_t *pCam = NULL; 865 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 866 CHECK_CAMERA(cam); 867 868 for (uint32_t i = 0; i < cam->numCameras; i++) { 869 pCam = gMuxer->getPhysicalCamera(cam, i); 870 CHECK_CAMERA(pCam); 871 872 QCamera2HardwareInterface *hwi = pCam->hwi; 873 CHECK_HWI(hwi); 874 875 if (pCam->mode == CAM_MODE_PRIMARY) { 876 QCamera2HardwareInterface::stop_recording(pCam->dev); 877 break; 878 } 879 } 880 881 // If recording hint is set internally to TRUE, 882 // we need to set it to FALSE. 883 // preview restart is needed in between 884 if (gMuxer->m_bRecordingHintInternallySet) { 885 // stop the preview first 886 for (uint32_t i = 0; i < cam->numCameras; i++) { 887 pCam = gMuxer->getPhysicalCamera(cam, i); 888 CHECK_CAMERA(pCam); 889 890 QCamera2HardwareInterface *hwi = pCam->hwi; 891 CHECK_HWI(hwi); 892 893 rc = hwi->restart_stop_preview(pCam->dev); 894 if (rc != NO_ERROR) { 895 LOGE("Error in restart stop preview!! "); 896 return; 897 } 898 } 899 900 // Update the recording hint value to FALSE 901 for (uint32_t i = 0; i < cam->numCameras; i++) { 902 pCam = gMuxer->getPhysicalCamera(cam, i); 903 CHECK_CAMERA(pCam); 904 905 QCamera2HardwareInterface *hwi = pCam->hwi; 906 CHECK_HWI(hwi); 907 908 rc = hwi->setRecordingHintValue(FALSE); 909 if (rc != NO_ERROR) { 910 LOGE("Error in setting recording hint value!! "); 911 return; 912 } 913 gMuxer->m_bRecordingHintInternallySet = FALSE; 914 } 915 916 // start the preview 917 for (uint32_t i = 0; i < cam->numCameras; i++) { 918 pCam = gMuxer->getPhysicalCamera(cam, i); 919 CHECK_CAMERA(pCam); 920 921 QCamera2HardwareInterface *hwi = pCam->hwi; 922 CHECK_HWI(hwi); 923 924 rc = hwi->restart_start_preview(pCam->dev); 925 if (rc != NO_ERROR) { 926 LOGE("Error in restart start preview!! "); 927 return; 928 } 929 } 930 } 931 LOGH("X"); 932 } 933 934 /*=========================================================================== 935 * FUNCTION : recording_enabled 936 * 937 * DESCRIPTION: Checks for recording enabled 938 * 939 * PARAMETERS : 940 * @device : camera hardware device info 941 * 942 * RETURN : true/false 943 *==========================================================================*/ 944 int QCameraMuxer::recording_enabled(struct camera_device * device) 945 { 946 LOGH("E"); 947 CHECK_MUXER_ERROR(); 948 qcamera_physical_descriptor_t *pCam = NULL; 949 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 950 CHECK_CAMERA_ERROR(cam); 951 952 for (uint32_t i = 0; i < cam->numCameras; i++) { 953 pCam = gMuxer->getPhysicalCamera(cam, i); 954 CHECK_CAMERA_ERROR(pCam); 955 956 QCamera2HardwareInterface *hwi = pCam->hwi; 957 CHECK_HWI_ERROR(hwi); 958 959 if (pCam->mode == CAM_MODE_PRIMARY) { 960 return hwi->recording_enabled(pCam->dev); 961 } 962 } 963 LOGH("X"); 964 return false; 965 } 966 967 /*=========================================================================== 968 * FUNCTION : release_recording_frame 969 * 970 * DESCRIPTION: Release the recording frame 971 * 972 * PARAMETERS : 973 * @device : camera hardware device info 974 * @opaque: Frame to be released 975 * 976 * RETURN : None 977 *==========================================================================*/ 978 void QCameraMuxer::release_recording_frame(struct camera_device * device, 979 const void *opaque) 980 { 981 LOGH("E"); 982 CHECK_MUXER(); 983 qcamera_physical_descriptor_t *pCam = NULL; 984 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 985 CHECK_CAMERA(cam); 986 987 for (uint32_t i = 0; i < cam->numCameras; i++) { 988 pCam = gMuxer->getPhysicalCamera(cam, i); 989 CHECK_CAMERA(pCam); 990 991 QCamera2HardwareInterface *hwi = pCam->hwi; 992 CHECK_HWI(hwi); 993 994 if (pCam->mode == CAM_MODE_PRIMARY) { 995 QCamera2HardwareInterface::release_recording_frame(pCam->dev, opaque); 996 break; 997 } 998 } 999 LOGH("X"); 1000 } 1001 1002 /*=========================================================================== 1003 * FUNCTION : auto_focus 1004 * 1005 * DESCRIPTION: Performs auto focus on camera 1006 * 1007 * PARAMETERS : 1008 * @device : camera hardware device info 1009 * 1010 * RETURN : 1011 * NO_ERROR : success 1012 * other: non-zero failure code 1013 *==========================================================================*/ 1014 int QCameraMuxer::auto_focus(struct camera_device * device) 1015 { 1016 LOGH("E"); 1017 CHECK_MUXER_ERROR(); 1018 int rc = NO_ERROR; 1019 qcamera_physical_descriptor_t *pCam = NULL; 1020 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1021 CHECK_CAMERA_ERROR(cam); 1022 1023 for (uint32_t i = 0; i < cam->numCameras; i++) { 1024 pCam = gMuxer->getPhysicalCamera(cam, i); 1025 CHECK_CAMERA_ERROR(pCam); 1026 1027 QCamera2HardwareInterface *hwi = pCam->hwi; 1028 CHECK_HWI_ERROR(hwi); 1029 // Call auto focus on main camera 1030 if (pCam->mode == CAM_MODE_PRIMARY) { 1031 rc = QCamera2HardwareInterface::auto_focus(pCam->dev); 1032 if (rc != NO_ERROR) { 1033 LOGE("Error auto focusing !! "); 1034 return rc; 1035 } 1036 break; 1037 } 1038 } 1039 LOGH("X"); 1040 return rc; 1041 } 1042 1043 /*=========================================================================== 1044 * FUNCTION : cancel_auto_focus 1045 * 1046 * DESCRIPTION: Cancels auto focus 1047 * 1048 * PARAMETERS : 1049 * @device : camera hardware device info 1050 * 1051 * RETURN : 1052 * NO_ERROR : success 1053 * other: non-zero failure code 1054 *==========================================================================*/ 1055 int QCameraMuxer::cancel_auto_focus(struct camera_device * device) 1056 { 1057 LOGH("E"); 1058 CHECK_MUXER_ERROR(); 1059 int rc = NO_ERROR; 1060 qcamera_physical_descriptor_t *pCam = NULL; 1061 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1062 CHECK_CAMERA_ERROR(cam); 1063 1064 for (uint32_t i = 0; i < cam->numCameras; i++) { 1065 pCam = gMuxer->getPhysicalCamera(cam, i); 1066 CHECK_CAMERA_ERROR(pCam); 1067 1068 QCamera2HardwareInterface *hwi = pCam->hwi; 1069 CHECK_HWI_ERROR(hwi); 1070 // Cancel auto focus on primary camera 1071 if (pCam->mode == CAM_MODE_PRIMARY) { 1072 rc = QCamera2HardwareInterface::cancel_auto_focus(pCam->dev); 1073 if (rc != NO_ERROR) { 1074 LOGE("Error cancelling auto focus !! "); 1075 return rc; 1076 } 1077 break; 1078 } 1079 } 1080 LOGH("X"); 1081 return rc; 1082 } 1083 1084 /*=========================================================================== 1085 * FUNCTION : take_picture 1086 * 1087 * DESCRIPTION: Take snapshots on device 1088 * 1089 * PARAMETERS : 1090 * @device : camera hardware device info 1091 * 1092 * RETURN : 1093 * NO_ERROR : success 1094 * other: non-zero failure code 1095 *==========================================================================*/ 1096 int QCameraMuxer::take_picture(struct camera_device * device) 1097 { 1098 LOGH("E"); 1099 CHECK_MUXER_ERROR(); 1100 int rc = NO_ERROR; 1101 bool previewRestartNeeded = false; 1102 qcamera_physical_descriptor_t *pCam = NULL; 1103 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1104 CHECK_CAMERA_ERROR(cam); 1105 1106 char prop[PROPERTY_VALUE_MAX]; 1107 property_get("persist.camera.dual.camera.mpo", prop, "1"); 1108 gMuxer->m_bMpoEnabled = atoi(prop); 1109 // If only one Physical Camera included in Logical, disable MPO 1110 int numOfAcitvePhyCam = 0; 1111 gMuxer->getActiveNumOfPhyCam(cam, numOfAcitvePhyCam); 1112 if (gMuxer->m_bMpoEnabled && numOfAcitvePhyCam <= 1) { 1113 gMuxer->m_bMpoEnabled = 0; 1114 } 1115 LOGH("dualCamera MPO Enabled:%d ", gMuxer->m_bMpoEnabled); 1116 1117 if (!gMuxer->mJpegClientHandle) { 1118 // set up jpeg handles 1119 pCam = gMuxer->getPhysicalCamera(cam, 0); 1120 CHECK_CAMERA_ERROR(pCam); 1121 1122 QCamera2HardwareInterface *hwi = pCam->hwi; 1123 CHECK_HWI_ERROR(hwi); 1124 1125 rc = hwi->getJpegHandleInfo(&gMuxer->mJpegOps, &gMuxer->mJpegMpoOps, 1126 &gMuxer->mJpegClientHandle); 1127 if (rc != NO_ERROR) { 1128 LOGE("Error retrieving jpeg handle!"); 1129 return rc; 1130 } 1131 1132 for (uint32_t i = 1; i < cam->numCameras; i++) { 1133 pCam = gMuxer->getPhysicalCamera(cam, i); 1134 CHECK_CAMERA_ERROR(pCam); 1135 1136 QCamera2HardwareInterface *hwi = pCam->hwi; 1137 CHECK_HWI_ERROR(hwi); 1138 1139 rc = hwi->setJpegHandleInfo(&gMuxer->mJpegOps, &gMuxer->mJpegMpoOps, 1140 gMuxer->mJpegClientHandle); 1141 if (rc != NO_ERROR) { 1142 LOGE("Error setting jpeg handle %d!", i); 1143 return rc; 1144 } 1145 } 1146 } 1147 1148 // prepare snapshot for main camera 1149 for (uint32_t i = 0; i < cam->numCameras; i++) { 1150 pCam = gMuxer->getPhysicalCamera(cam, i); 1151 CHECK_CAMERA_ERROR(pCam); 1152 1153 QCamera2HardwareInterface *hwi = pCam->hwi; 1154 CHECK_HWI_ERROR(hwi); 1155 1156 if (pCam->mode == CAM_MODE_PRIMARY) { 1157 rc = hwi->prepare_snapshot(pCam->dev); 1158 if (rc != NO_ERROR) { 1159 LOGE("Error preparing for snapshot !! "); 1160 return rc; 1161 } 1162 } 1163 // set Mpo composition for each session 1164 rc = hwi->setMpoComposition(gMuxer->m_bMpoEnabled); 1165 //disable MPO if AOST features are enabled 1166 if (rc != NO_ERROR) { 1167 gMuxer->m_bMpoEnabled = 0; 1168 rc = NO_ERROR; 1169 } 1170 } 1171 1172 // initialize Jpeg Queues 1173 gMuxer->m_MainJpegQ.init(); 1174 gMuxer->m_AuxJpegQ.init(); 1175 gMuxer->m_ComposeMpoTh.sendCmd( 1176 CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE); 1177 1178 // In cases where recording hint is set, preview is running, 1179 // hwi->take_picture will internally restart the preview. 1180 // To take the preview restart control in muxer, 1181 // 1. call pre_take_picture first 1182 for (uint32_t i = 0; i < cam->numCameras; i++) { 1183 pCam = gMuxer->getPhysicalCamera(cam, i); 1184 CHECK_CAMERA_ERROR(pCam); 1185 1186 QCamera2HardwareInterface *hwi = pCam->hwi; 1187 CHECK_HWI_ERROR(hwi); 1188 1189 // no need to call pre_take_pic on Aux if not MPO (for AOST,liveshot...etc.) 1190 if ( (gMuxer->m_bMpoEnabled == 1) || (pCam->mode == CAM_MODE_PRIMARY) ) { 1191 rc = hwi->pre_take_picture(pCam->dev); 1192 if (rc != NO_ERROR) { 1193 LOGE("Error preparing take_picture!! "); 1194 return rc; 1195 } 1196 } 1197 } 1198 1199 // 2. Check if preview restart is needed. Check all cameras. 1200 for (uint32_t i = 0; i < cam->numCameras; i++) { 1201 pCam = gMuxer->getPhysicalCamera(cam, i); 1202 CHECK_CAMERA_ERROR(pCam); 1203 1204 QCamera2HardwareInterface *hwi = pCam->hwi; 1205 CHECK_HWI_ERROR(hwi); 1206 1207 if (hwi->isPreviewRestartNeeded()) { 1208 previewRestartNeeded = hwi->isPreviewRestartNeeded(); 1209 break; 1210 } 1211 } 1212 1213 if (previewRestartNeeded) { 1214 // 3. if preview restart needed. stop the preview first 1215 for (uint32_t i = 0; i < cam->numCameras; i++) { 1216 pCam = gMuxer->getPhysicalCamera(cam, i); 1217 CHECK_CAMERA_ERROR(pCam); 1218 1219 QCamera2HardwareInterface *hwi = pCam->hwi; 1220 CHECK_HWI_ERROR(hwi); 1221 1222 rc = hwi->restart_stop_preview(pCam->dev); 1223 if (rc != NO_ERROR) { 1224 LOGE("Error in restart stop preview!! "); 1225 return rc; 1226 } 1227 } 1228 1229 //4. Update the recording hint value to FALSE 1230 for (uint32_t i = 0; i < cam->numCameras; i++) { 1231 pCam = gMuxer->getPhysicalCamera(cam, i); 1232 CHECK_CAMERA_ERROR(pCam); 1233 1234 QCamera2HardwareInterface *hwi = pCam->hwi; 1235 CHECK_HWI_ERROR(hwi); 1236 1237 rc = hwi->setRecordingHintValue(FALSE); 1238 if (rc != NO_ERROR) { 1239 LOGE("Error in setting recording hint value!! "); 1240 return rc; 1241 } 1242 } 1243 1244 // 5. start the preview 1245 for (uint32_t i = 0; i < cam->numCameras; i++) { 1246 pCam = gMuxer->getPhysicalCamera(cam, i); 1247 CHECK_CAMERA_ERROR(pCam); 1248 1249 QCamera2HardwareInterface *hwi = pCam->hwi; 1250 CHECK_HWI_ERROR(hwi); 1251 1252 rc = hwi->restart_start_preview(pCam->dev); 1253 if (rc != NO_ERROR) { 1254 LOGE("Error in restart start preview!! "); 1255 return rc; 1256 } 1257 } 1258 } 1259 1260 // As frame sync for dual cameras is enabled, the take picture call 1261 // for secondary camera is handled only till HAL level to init corresponding 1262 // pproc channel and update statemachine. 1263 // This call is forwarded to mm-camera-intf only for primary camera 1264 // Primary camera should receive the take picture call after all secondary 1265 // camera statemachines are updated 1266 for (int32_t i = cam->numCameras-1 ; i >= 0; i--) { 1267 pCam = gMuxer->getPhysicalCamera(cam, i); 1268 CHECK_CAMERA_ERROR(pCam); 1269 1270 QCamera2HardwareInterface *hwi = pCam->hwi; 1271 CHECK_HWI_ERROR(hwi); 1272 1273 // no need to call take_pic on Aux if not MPO (for AOST) 1274 if ( (gMuxer->m_bMpoEnabled == 1) || (pCam->mode == CAM_MODE_PRIMARY) ) { 1275 rc = QCamera2HardwareInterface::take_picture(pCam->dev); 1276 if (rc != NO_ERROR) { 1277 LOGE("Error taking picture !! "); 1278 return rc; 1279 } 1280 } 1281 } 1282 LOGH("X"); 1283 return rc; 1284 } 1285 1286 /*=========================================================================== 1287 * FUNCTION : cancel_picture 1288 * 1289 * DESCRIPTION: Cancel the take picture call 1290 * 1291 * PARAMETERS : 1292 * @device : camera hardware device info 1293 * 1294 * RETURN : 1295 * NO_ERROR : success 1296 * other: non-zero failure code 1297 *==========================================================================*/ 1298 int QCameraMuxer::cancel_picture(struct camera_device * device) 1299 { 1300 LOGH("E"); 1301 CHECK_MUXER_ERROR(); 1302 int rc = NO_ERROR; 1303 qcamera_physical_descriptor_t *pCam = NULL; 1304 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1305 CHECK_CAMERA_ERROR(cam); 1306 1307 for (uint32_t i = 0; i < cam->numCameras; i++) { 1308 pCam = gMuxer->getPhysicalCamera(cam, i); 1309 CHECK_CAMERA_ERROR(pCam); 1310 1311 QCamera2HardwareInterface *hwi = pCam->hwi; 1312 CHECK_HWI_ERROR(hwi); 1313 1314 rc = QCamera2HardwareInterface::cancel_picture(pCam->dev); 1315 if (rc != NO_ERROR) { 1316 LOGE("Error cancelling picture !! "); 1317 return rc; 1318 } 1319 } 1320 gMuxer->m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, FALSE); 1321 // flush Jpeg Queues 1322 gMuxer->m_MainJpegQ.flush(); 1323 gMuxer->m_AuxJpegQ.flush(); 1324 1325 LOGH("X"); 1326 return rc; 1327 } 1328 1329 /*=========================================================================== 1330 * FUNCTION : set_parameters 1331 * 1332 * DESCRIPTION: Sets the parameters on camera 1333 * 1334 * PARAMETERS : 1335 * @device : camera hardware device info 1336 * @parms : Parameters to be set on camera 1337 * 1338 * RETURN : 1339 * NO_ERROR : success 1340 * other: non-zero failure code 1341 *==========================================================================*/ 1342 int QCameraMuxer::set_parameters(struct camera_device * device, 1343 const char *parms) 1344 1345 { 1346 LOGH("E"); 1347 CHECK_MUXER_ERROR(); 1348 int rc = NO_ERROR; 1349 qcamera_physical_descriptor_t *pCam = NULL; 1350 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1351 bool needRestart = false; 1352 CHECK_CAMERA_ERROR(cam); 1353 1354 for (uint32_t i = 0; i < cam->numCameras; i++) { 1355 pCam = gMuxer->getPhysicalCamera(cam, i); 1356 CHECK_CAMERA_ERROR(pCam); 1357 1358 QCamera2HardwareInterface *hwi = pCam->hwi; 1359 CHECK_HWI_ERROR(hwi); 1360 1361 rc = QCamera2HardwareInterface::set_parameters(pCam->dev, parms); 1362 if (rc != NO_ERROR) { 1363 LOGE("Error setting parameters !! "); 1364 return rc; 1365 } 1366 1367 needRestart |= hwi->getNeedRestart(); 1368 } 1369 1370 if (needRestart) { 1371 for (uint32_t i = 0; i < cam->numCameras; i++) { 1372 pCam = gMuxer->getPhysicalCamera(cam, i); 1373 CHECK_CAMERA_ERROR(pCam); 1374 1375 QCamera2HardwareInterface *hwi = pCam->hwi; 1376 CHECK_HWI_ERROR(hwi); 1377 1378 LOGD("stopping preview for cam %d", i); 1379 rc = QCamera2HardwareInterface::stop_after_set_params(pCam->dev); 1380 if (rc != NO_ERROR) { 1381 LOGE("Error stopping camera rc=%d!! ", rc); 1382 return rc; 1383 } 1384 } 1385 } 1386 1387 for (uint32_t i = 0; i < cam->numCameras; i++) { 1388 pCam = gMuxer->getPhysicalCamera(cam, i); 1389 CHECK_CAMERA_ERROR(pCam); 1390 1391 QCamera2HardwareInterface *hwi = pCam->hwi; 1392 CHECK_HWI_ERROR(hwi); 1393 1394 LOGD("commiting parameters for cam %d", i); 1395 rc = QCamera2HardwareInterface::commit_params(pCam->dev); 1396 if (rc != NO_ERROR) { 1397 LOGE("Error committing parameters rc=%d!! ", rc); 1398 return rc; 1399 } 1400 } 1401 1402 if (needRestart) { 1403 for (uint32_t i = 0; i < cam->numCameras; i++) { 1404 pCam = gMuxer->getPhysicalCamera(cam, i); 1405 CHECK_CAMERA_ERROR(pCam); 1406 1407 QCamera2HardwareInterface *hwi = pCam->hwi; 1408 CHECK_HWI_ERROR(hwi); 1409 1410 LOGD("restarting preview for cam %d", i); 1411 rc = QCamera2HardwareInterface::restart_after_set_params(pCam->dev); 1412 if (rc != NO_ERROR) { 1413 LOGE("Error restarting camera rc=%d!! ", rc); 1414 return rc; 1415 } 1416 } 1417 } 1418 1419 LOGH(" X"); 1420 return rc; 1421 } 1422 1423 /*=========================================================================== 1424 * FUNCTION : get_parameters 1425 * 1426 * DESCRIPTION: Gets the parameters on camera 1427 * 1428 * PARAMETERS : 1429 * @device : camera hardware device info 1430 * 1431 * RETURN : Parameter string or NULL 1432 *==========================================================================*/ 1433 char* QCameraMuxer::get_parameters(struct camera_device * device) 1434 { 1435 LOGH("E"); 1436 1437 if (!gMuxer) 1438 return NULL; 1439 1440 char* ret = NULL; 1441 qcamera_physical_descriptor_t *pCam = NULL; 1442 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1443 if (!cam) { 1444 LOGE("Error getting logical camera"); 1445 return NULL; 1446 } 1447 1448 for (uint32_t i = 0; i < cam->numCameras; i++) { 1449 pCam = gMuxer->getPhysicalCamera(cam, i); 1450 if (!pCam) { 1451 LOGE("Error getting physical camera"); 1452 return NULL; 1453 } 1454 QCamera2HardwareInterface *hwi = pCam->hwi; 1455 if (!hwi) { 1456 LOGE("Allocation of hardware interface failed"); 1457 return NULL; 1458 } 1459 if (pCam->mode == CAM_MODE_PRIMARY) { 1460 // Get only primary camera parameters 1461 ret = QCamera2HardwareInterface::get_parameters(pCam->dev); 1462 break; 1463 } 1464 } 1465 1466 LOGH("X"); 1467 return ret; 1468 } 1469 1470 /*=========================================================================== 1471 * FUNCTION : put_parameters 1472 * 1473 * DESCRIPTION: Puts parameters on camera 1474 * 1475 * PARAMETERS : 1476 * @device : camera hardware device info 1477 * @parm : parameters 1478 * 1479 * RETURN : None 1480 *==========================================================================*/ 1481 void QCameraMuxer::put_parameters(struct camera_device * device, char *parm) 1482 { 1483 LOGH("E"); 1484 CHECK_MUXER(); 1485 qcamera_physical_descriptor_t *pCam = NULL; 1486 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1487 CHECK_CAMERA(cam); 1488 1489 for (uint32_t i = 0; i < cam->numCameras; i++) { 1490 pCam = gMuxer->getPhysicalCamera(cam, i); 1491 CHECK_CAMERA(pCam); 1492 1493 QCamera2HardwareInterface *hwi = pCam->hwi; 1494 CHECK_HWI(hwi); 1495 1496 if (pCam->mode == CAM_MODE_PRIMARY) { 1497 // Parameters are not used in HWI and hence freed 1498 QCamera2HardwareInterface::put_parameters(pCam->dev, parm); 1499 break; 1500 } 1501 } 1502 LOGH("X"); 1503 } 1504 1505 /*=========================================================================== 1506 * FUNCTION : send_command 1507 * 1508 * DESCRIPTION: Send command to camera 1509 * 1510 * PARAMETERS : 1511 * @device : camera hardware device info 1512 * @cmd : Command 1513 * @arg1/arg2 : command arguments 1514 * 1515 * RETURN : 1516 * NO_ERROR : success 1517 * other: non-zero failure code 1518 *==========================================================================*/ 1519 int QCameraMuxer::send_command(struct camera_device * device, 1520 int32_t cmd, int32_t arg1, int32_t arg2) 1521 { 1522 LOGH("E"); 1523 CHECK_MUXER_ERROR(); 1524 int rc = NO_ERROR; 1525 qcamera_physical_descriptor_t *pCam = NULL; 1526 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1527 CHECK_CAMERA_ERROR(cam); 1528 1529 for (uint32_t i = 0; i < cam->numCameras; i++) { 1530 pCam = gMuxer->getPhysicalCamera(cam, i); 1531 CHECK_CAMERA_ERROR(pCam); 1532 1533 QCamera2HardwareInterface *hwi = pCam->hwi; 1534 CHECK_HWI_ERROR(hwi); 1535 1536 rc = QCamera2HardwareInterface::send_command(pCam->dev, cmd, arg1, arg2); 1537 if (rc != NO_ERROR) { 1538 LOGE("Error sending command !! "); 1539 return rc; 1540 } 1541 } 1542 1543 switch (cmd) { 1544 #ifndef VANILLA_HAL 1545 case CAMERA_CMD_LONGSHOT_ON: 1546 for (uint32_t i = 0; i < cam->numCameras; i++) { 1547 pCam = gMuxer->getPhysicalCamera(cam, i); 1548 CHECK_CAMERA_ERROR(pCam); 1549 1550 QCamera2HardwareInterface *hwi = pCam->hwi; 1551 CHECK_HWI_ERROR(hwi); 1552 1553 rc = QCamera2HardwareInterface::send_command_restart(pCam->dev, 1554 cmd, arg1, arg2); 1555 if (rc != NO_ERROR) { 1556 LOGE("Error sending command restart !! "); 1557 return rc; 1558 } 1559 } 1560 break; 1561 case CAMERA_CMD_LONGSHOT_OFF: 1562 gMuxer->m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, 1563 FALSE, FALSE); 1564 // flush Jpeg Queues 1565 gMuxer->m_MainJpegQ.flush(); 1566 gMuxer->m_AuxJpegQ.flush(); 1567 break; 1568 #endif 1569 default: 1570 // do nothing 1571 rc = NO_ERROR; 1572 break; 1573 } 1574 1575 LOGH("X"); 1576 return rc; 1577 } 1578 1579 /*=========================================================================== 1580 * FUNCTION : release 1581 * 1582 * DESCRIPTION: Release the camera 1583 * 1584 * PARAMETERS : 1585 * @device : camera hardware device info 1586 * 1587 * RETURN : None 1588 *==========================================================================*/ 1589 void QCameraMuxer::release(struct camera_device * device) 1590 { 1591 LOGH("E"); 1592 CHECK_MUXER(); 1593 qcamera_physical_descriptor_t *pCam = NULL; 1594 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1595 CHECK_CAMERA(cam); 1596 1597 for (uint32_t i = 0; i < cam->numCameras; i++) { 1598 pCam = gMuxer->getPhysicalCamera(cam, i); 1599 CHECK_CAMERA(pCam); 1600 1601 QCamera2HardwareInterface *hwi = pCam->hwi; 1602 CHECK_HWI(hwi); 1603 1604 QCamera2HardwareInterface::release(pCam->dev); 1605 } 1606 LOGH("X"); 1607 } 1608 1609 /*=========================================================================== 1610 * FUNCTION : dump 1611 * 1612 * DESCRIPTION: Dump the camera info 1613 * 1614 * PARAMETERS : 1615 * @device : camera hardware device info 1616 * @fd : fd 1617 * 1618 * RETURN : 1619 * NO_ERROR : success 1620 * other: non-zero failure code 1621 *==========================================================================*/ 1622 int QCameraMuxer::dump(struct camera_device * device, int fd) 1623 { 1624 LOGH("E"); 1625 CHECK_MUXER_ERROR(); 1626 int rc = NO_ERROR; 1627 qcamera_physical_descriptor_t *pCam = NULL; 1628 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device); 1629 CHECK_CAMERA_ERROR(cam); 1630 1631 for (uint32_t i = 0; i < cam->numCameras; i++) { 1632 pCam = gMuxer->getPhysicalCamera(cam, i); 1633 CHECK_CAMERA_ERROR(pCam); 1634 1635 QCamera2HardwareInterface *hwi = pCam->hwi; 1636 CHECK_HWI_ERROR(hwi); 1637 1638 rc = QCamera2HardwareInterface::dump(pCam->dev, fd); 1639 if (rc != NO_ERROR) { 1640 LOGE("Error dumping"); 1641 return rc; 1642 } 1643 } 1644 LOGH("X"); 1645 return rc; 1646 } 1647 1648 /*=========================================================================== 1649 * FUNCTION : close_camera_device 1650 * 1651 * DESCRIPTION: Close the camera 1652 * 1653 * PARAMETERS : 1654 * @hw_dev : camera hardware device info 1655 * 1656 * RETURN : 1657 * NO_ERROR : success 1658 * other: non-zero failure code 1659 *==========================================================================*/ 1660 int QCameraMuxer::close_camera_device(hw_device_t *hw_dev) 1661 { 1662 LOGH("E"); 1663 CHECK_MUXER_ERROR(); 1664 int rc = NO_ERROR; 1665 qcamera_physical_descriptor_t *pCam = NULL; 1666 camera_device_t *cam_dev = (camera_device_t*)hw_dev; 1667 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(cam_dev); 1668 CHECK_CAMERA_ERROR(cam); 1669 1670 // Unlink camera sessions 1671 if (cam->bSyncOn) { 1672 if (cam->numCameras > 1) { 1673 uint sessionId = 0; 1674 // unbundle primary camera with all aux cameras 1675 for (uint32_t i = 0; i < cam->numCameras; i++) { 1676 pCam = gMuxer->getPhysicalCamera(cam, i); 1677 CHECK_CAMERA_ERROR(pCam); 1678 1679 QCamera2HardwareInterface *hwi = pCam->hwi; 1680 CHECK_HWI_ERROR(hwi); 1681 1682 if(pCam->mode == CAM_MODE_PRIMARY) { 1683 // bundle primary cam with all aux cameras 1684 for (uint32_t j = 0; j < cam->numCameras; j++) { 1685 if (j == cam->nPrimaryPhyCamIndex) { 1686 continue; 1687 } 1688 sessionId = cam->sId[j]; 1689 LOGH("Related cam id: %d, server id: %d sync OFF" 1690 " related session_id %d", 1691 cam->pId[i], cam->sId[i], sessionId); 1692 rc = hwi->bundleRelatedCameras(false, sessionId); 1693 if (rc != NO_ERROR) { 1694 LOGE("Error Bundling physical cameras !! "); 1695 break; 1696 } 1697 } 1698 } 1699 1700 if (pCam->mode == CAM_MODE_SECONDARY) { 1701 // unbundle all aux cam with primary cams 1702 sessionId = cam->sId[cam->nPrimaryPhyCamIndex]; 1703 LOGH("Related cam id: %d, server id: %d sync OFF" 1704 " related session_id %d", 1705 cam->pId[i], cam->sId[i], sessionId); 1706 rc = hwi->bundleRelatedCameras(false, sessionId); 1707 if (rc != NO_ERROR) { 1708 LOGE("Error Bundling physical cameras !! "); 1709 break; 1710 } 1711 } 1712 } 1713 } 1714 cam->bSyncOn = false; 1715 } 1716 1717 // Attempt to close all cameras regardless of unbundle results 1718 for (uint32_t i = 0; i < cam->numCameras; i++) { 1719 pCam = gMuxer->getPhysicalCamera(cam, i); 1720 CHECK_CAMERA_ERROR(pCam); 1721 1722 hw_device_t *dev = (hw_device_t*)(pCam->dev); 1723 LOGH("hw device %x, hw %x", dev, pCam->hwi); 1724 1725 rc = QCamera2HardwareInterface::close_camera_device(dev); 1726 if (rc != NO_ERROR) { 1727 LOGE("Error closing camera"); 1728 } 1729 pCam->hwi = NULL; 1730 pCam->dev = NULL; 1731 } 1732 1733 // Reset JPEG client handle 1734 gMuxer->setJpegHandle(0); 1735 LOGH("X, rc: %d", rc); 1736 return rc; 1737 } 1738 1739 /*=========================================================================== 1740 * FUNCTION : setupLogicalCameras 1741 * 1742 * DESCRIPTION : Creates Camera Muxer if not created 1743 * 1744 * RETURN : 1745 * NO_ERROR : success 1746 * other: non-zero failure code 1747 *==========================================================================*/ 1748 int QCameraMuxer::setupLogicalCameras() 1749 { 1750 int rc = NO_ERROR; 1751 char prop[PROPERTY_VALUE_MAX]; 1752 int i = 0; 1753 int primaryType = CAM_TYPE_MAIN; 1754 1755 LOGH("[%d] E: rc = %d", rc); 1756 // Signifies whether AUX camera has to be exposed as physical camera 1757 property_get("persist.camera.aux.camera", prop, "0"); 1758 m_bAuxCameraExposed = atoi(prop); 1759 1760 // Signifies whether AUX camera needs to be swapped 1761 property_get("persist.camera.auxcamera.swap", prop, "0"); 1762 int swapAux = atoi(prop); 1763 if (swapAux != 0) { 1764 primaryType = CAM_TYPE_AUX; 1765 } 1766 1767 // Check for number of camera present on device 1768 if (!m_nPhyCameras || (m_nPhyCameras > MM_CAMERA_MAX_NUM_SENSORS)) { 1769 LOGE("Error!! Invalid number of cameras: %d", 1770 m_nPhyCameras); 1771 return BAD_VALUE; 1772 } 1773 1774 m_pPhyCamera = new qcamera_physical_descriptor_t[m_nPhyCameras]; 1775 if (!m_pPhyCamera) { 1776 LOGE("Error allocating camera info buffer!!"); 1777 return NO_MEMORY; 1778 } 1779 memset(m_pPhyCamera, 0x00, 1780 (m_nPhyCameras * sizeof(qcamera_physical_descriptor_t))); 1781 uint32_t cameraId = 0; 1782 m_nLogicalCameras = 0; 1783 1784 // Enumerate physical cameras and logical 1785 for (i = 0; i < m_nPhyCameras ; i++, cameraId++) { 1786 camera_info *info = &m_pPhyCamera[i].cam_info; 1787 rc = QCamera2HardwareInterface::getCapabilities(cameraId, 1788 info, &m_pPhyCamera[i].type); 1789 m_pPhyCamera[i].id = cameraId; 1790 m_pPhyCamera[i].device_version = CAMERA_DEVICE_API_VERSION_1_0; 1791 m_pPhyCamera[i].mode = CAM_MODE_PRIMARY; 1792 1793 if (!m_bAuxCameraExposed && (m_pPhyCamera[i].type != primaryType)) { 1794 m_pPhyCamera[i].mode = CAM_MODE_SECONDARY; 1795 LOGH("Camera ID: %d, Aux Camera, type: %d, facing: %d", 1796 cameraId, m_pPhyCamera[i].type, 1797 m_pPhyCamera[i].cam_info.facing); 1798 } 1799 else { 1800 m_nLogicalCameras++; 1801 LOGH("Camera ID: %d, Main Camera, type: %d, facing: %d", 1802 cameraId, m_pPhyCamera[i].type, 1803 m_pPhyCamera[i].cam_info.facing); 1804 } 1805 } 1806 1807 if (!m_nLogicalCameras) { 1808 // No Main camera detected, return from here 1809 LOGE("Error !!!! detecting main camera!!"); 1810 delete [] m_pPhyCamera; 1811 m_pPhyCamera = NULL; 1812 return -ENODEV; 1813 } 1814 // Allocate Logical Camera descriptors 1815 m_pLogicalCamera = new qcamera_logical_descriptor_t[m_nLogicalCameras]; 1816 if (!m_pLogicalCamera) { 1817 LOGE("Error !!!! allocating camera info buffer!!"); 1818 delete [] m_pPhyCamera; 1819 m_pPhyCamera = NULL; 1820 return NO_MEMORY; 1821 } 1822 memset(m_pLogicalCamera, 0x00, 1823 (m_nLogicalCameras * sizeof(qcamera_logical_descriptor_t))); 1824 // Assign MAIN cameras for each logical camera 1825 int index = 0; 1826 for (i = 0; i < m_nPhyCameras ; i++) { 1827 if (m_pPhyCamera[i].mode == CAM_MODE_PRIMARY) { 1828 m_pLogicalCamera[index].nPrimaryPhyCamIndex = 0; 1829 m_pLogicalCamera[index].id = index; 1830 m_pLogicalCamera[index].device_version = CAMERA_DEVICE_API_VERSION_1_0; 1831 m_pLogicalCamera[index].pId[0] = i; 1832 m_pLogicalCamera[index].type[0] = CAM_TYPE_MAIN; 1833 m_pLogicalCamera[index].mode[0] = CAM_MODE_PRIMARY; 1834 m_pLogicalCamera[index].facing = m_pPhyCamera[i].cam_info.facing; 1835 m_pLogicalCamera[index].numCameras++; 1836 LOGH("Logical Main Camera ID: %d, facing: %d," 1837 "Phy Id: %d type: %d mode: %d", 1838 m_pLogicalCamera[index].id, 1839 m_pLogicalCamera[index].facing, 1840 m_pLogicalCamera[index].pId[0], 1841 m_pLogicalCamera[index].type[0], 1842 m_pLogicalCamera[index].mode[0]); 1843 1844 index++; 1845 } 1846 } 1847 //Now assign AUX cameras to logical camera 1848 for (i = 0; i < m_nPhyCameras ; i++) { 1849 if (m_pPhyCamera[i].mode == CAM_MODE_SECONDARY) { 1850 for (int j = 0; j < m_nLogicalCameras; j++) { 1851 int n = m_pLogicalCamera[j].numCameras; 1852 ///@note n can only be 1 at this point 1853 if ((n < MAX_NUM_CAMERA_PER_BUNDLE) && 1854 (m_pLogicalCamera[j].facing == 1855 m_pPhyCamera[i].cam_info.facing)) { 1856 m_pLogicalCamera[j].pId[n] = i; 1857 m_pLogicalCamera[j].type[n] = CAM_TYPE_AUX; 1858 m_pLogicalCamera[j].mode[n] = CAM_MODE_SECONDARY; 1859 m_pLogicalCamera[j].numCameras++; 1860 LOGH("Aux %d for Logical Camera ID: %d," 1861 "aux phy id:%d, type: %d mode: %d", 1862 n, j, m_pLogicalCamera[j].pId[n], 1863 m_pLogicalCamera[j].type[n], m_pLogicalCamera[j].mode[n]); 1864 } 1865 } 1866 } 1867 } 1868 //Print logical and physical camera tables 1869 for (i = 0; i < m_nLogicalCameras ; i++) { 1870 for (uint8_t j = 0; j < m_pLogicalCamera[i].numCameras; j++) { 1871 LOGH("Logical Camera ID: %d, index: %d, " 1872 "facing: %d, Phy Id: %d type: %d mode: %d", 1873 i, j, m_pLogicalCamera[i].facing, 1874 m_pLogicalCamera[i].pId[j], m_pLogicalCamera[i].type[j], 1875 m_pLogicalCamera[i].mode[j]); 1876 } 1877 } 1878 LOGH("[%d] X: rc = %d", rc); 1879 return rc; 1880 } 1881 1882 /*=========================================================================== 1883 * FUNCTION : getNumberOfCameras 1884 * 1885 * DESCRIPTION: query number of logical cameras detected 1886 * 1887 * RETURN : number of cameras detected 1888 *==========================================================================*/ 1889 int QCameraMuxer::getNumberOfCameras() 1890 { 1891 return m_nLogicalCameras; 1892 } 1893 1894 /*=========================================================================== 1895 * FUNCTION : getCameraInfo 1896 * 1897 * DESCRIPTION: query camera information with its ID 1898 * 1899 * PARAMETERS : 1900 * @camera_id : camera ID 1901 * @info : ptr to camera info struct 1902 * 1903 * RETURN : int32_t type of status 1904 * NO_ERROR -- success 1905 * none-zero failure code 1906 *==========================================================================*/ 1907 int QCameraMuxer::getCameraInfo(int camera_id, 1908 struct camera_info *info, __unused cam_sync_type_t *p_cam_type) 1909 { 1910 int rc = NO_ERROR; 1911 LOGH("E, camera_id = %d", camera_id); 1912 cam_sync_type_t cam_type = CAM_TYPE_MAIN; 1913 1914 if (!m_nLogicalCameras || (camera_id >= m_nLogicalCameras) || 1915 !info || (camera_id < 0)) { 1916 LOGE("m_nLogicalCameras: %d, camera id: %d", 1917 m_nLogicalCameras, camera_id); 1918 return -ENODEV; 1919 } 1920 1921 if (!m_pLogicalCamera || !m_pPhyCamera) { 1922 LOGE("Error! Cameras not initialized!"); 1923 return NO_INIT; 1924 } 1925 uint32_t phy_id = 1926 m_pLogicalCamera[camera_id].pId[ 1927 m_pLogicalCamera[camera_id].nPrimaryPhyCamIndex]; 1928 rc = QCamera2HardwareInterface::getCapabilities(phy_id, info, &cam_type); 1929 LOGH("X"); 1930 return rc; 1931 } 1932 1933 /*=========================================================================== 1934 * FUNCTION : setCallbacks 1935 * 1936 * DESCRIPTION: set callback functions to send asynchronous notifications to 1937 * frameworks. 1938 * 1939 * PARAMETERS : 1940 * @callbacks : callback function pointer 1941 * 1942 * RETURN : int32_t type of status 1943 * NO_ERROR -- success 1944 * none-zero failure code 1945 *==========================================================================*/ 1946 int32_t QCameraMuxer::setCallbacks(const camera_module_callbacks_t *callbacks) 1947 { 1948 if(callbacks) { 1949 m_pCallbacks = callbacks; 1950 return NO_ERROR; 1951 } else { 1952 return BAD_TYPE; 1953 } 1954 } 1955 1956 /*=========================================================================== 1957 * FUNCTION : setDataCallback 1958 * 1959 * DESCRIPTION: set data callback function for snapshots 1960 * 1961 * PARAMETERS : 1962 * @data_cb : callback function pointer 1963 * 1964 * RETURN : int32_t type of status 1965 * NO_ERROR -- success 1966 * none-zero failure code 1967 *==========================================================================*/ 1968 int32_t QCameraMuxer::setDataCallback(camera_data_callback data_cb) 1969 { 1970 if(data_cb) { 1971 mDataCb = data_cb; 1972 return NO_ERROR; 1973 } else { 1974 return BAD_TYPE; 1975 } 1976 } 1977 1978 /*=========================================================================== 1979 * FUNCTION : setMemoryCallback 1980 * 1981 * DESCRIPTION: set get memory callback for memory allocations 1982 * 1983 * PARAMETERS : 1984 * @get_memory : callback function pointer 1985 * 1986 * RETURN : int32_t type of status 1987 * NO_ERROR -- success 1988 * none-zero failure code 1989 *==========================================================================*/ 1990 int32_t QCameraMuxer::setMemoryCallback(camera_request_memory get_memory) 1991 { 1992 if(get_memory) { 1993 mGetMemoryCb = get_memory; 1994 return NO_ERROR; 1995 } else { 1996 return BAD_TYPE; 1997 } 1998 } 1999 2000 /*=========================================================================== 2001 * FUNCTION : setMpoCallbackCookie 2002 * 2003 * DESCRIPTION: set mpo callback cookie. will be used for sending final MPO callbacks 2004 * to framework 2005 * 2006 * PARAMETERS : 2007 * @mpoCbCookie : callback function pointer 2008 * 2009 * RETURN : int32_t type of status 2010 * NO_ERROR -- success 2011 * none-zero failure code 2012 *==========================================================================*/ 2013 int32_t QCameraMuxer::setMpoCallbackCookie(void* mpoCbCookie) 2014 { 2015 if(mpoCbCookie) { 2016 m_pMpoCallbackCookie = mpoCbCookie; 2017 return NO_ERROR; 2018 } else { 2019 return BAD_TYPE; 2020 } 2021 } 2022 2023 /*=========================================================================== 2024 * FUNCTION : getMpoCallbackCookie 2025 * 2026 * DESCRIPTION: gets the mpo callback cookie. will be used for sending final MPO callbacks 2027 * to framework 2028 * 2029 * PARAMETERS :none 2030 * 2031 * RETURN :void ptr to the mpo callback cookie 2032 *==========================================================================*/ 2033 void* QCameraMuxer::getMpoCallbackCookie(void) 2034 { 2035 return m_pMpoCallbackCookie; 2036 } 2037 2038 /*=========================================================================== 2039 * FUNCTION : setMainJpegCallbackCookie 2040 * 2041 * DESCRIPTION: set jpeg callback cookie. 2042 * set to phy cam instance of the primary related cam instance 2043 * 2044 * PARAMETERS : 2045 * @jpegCbCookie : ptr to jpeg cookie 2046 * 2047 * RETURN : int32_t type of status 2048 * NO_ERROR -- success 2049 * none-zero failure code 2050 *==========================================================================*/ 2051 int32_t QCameraMuxer::setMainJpegCallbackCookie(void* jpegCbCookie) 2052 { 2053 if(jpegCbCookie) { 2054 m_pJpegCallbackCookie = jpegCbCookie; 2055 return NO_ERROR; 2056 } else { 2057 return BAD_TYPE; 2058 } 2059 } 2060 2061 /*=========================================================================== 2062 * FUNCTION : getMainJpegCallbackCookie 2063 * 2064 * DESCRIPTION: gets the jpeg callback cookie for primary related cam instance 2065 * set to phy cam instance of the primary related cam instance 2066 * 2067 * PARAMETERS :none 2068 * 2069 * RETURN :void ptr to the jpeg callback cookie 2070 *==========================================================================*/ 2071 void* QCameraMuxer::getMainJpegCallbackCookie(void) 2072 { 2073 return m_pJpegCallbackCookie; 2074 } 2075 2076 /*=========================================================================== 2077 * FUNCTION : cameraDeviceOpen 2078 * 2079 * DESCRIPTION: open a camera device with its ID 2080 * 2081 * PARAMETERS : 2082 * @camera_id : camera ID 2083 * @hw_device : ptr to struct storing camera hardware device info 2084 * 2085 * RETURN : int32_t type of status 2086 * NO_ERROR -- success 2087 * none-zero failure code 2088 *==========================================================================*/ 2089 int QCameraMuxer::cameraDeviceOpen(int camera_id, 2090 struct hw_device_t **hw_device) 2091 { 2092 int rc = NO_ERROR; 2093 uint32_t phyId = 0; 2094 qcamera_logical_descriptor_t *cam = NULL; 2095 2096 if (camera_id < 0 || camera_id >= m_nLogicalCameras) { 2097 LOGE("Camera id %d not found!", camera_id); 2098 return -ENODEV; 2099 } 2100 2101 if ( NULL == m_pLogicalCamera) { 2102 LOGE("Hal descriptor table is not initialized!"); 2103 return NO_INIT; 2104 } 2105 2106 char prop[PROPERTY_VALUE_MAX]; 2107 property_get("persist.camera.dc.frame.sync", prop, "1"); 2108 m_bFrameSyncEnabled = atoi(prop); 2109 2110 // Get logical camera 2111 cam = &m_pLogicalCamera[camera_id]; 2112 2113 if (m_pLogicalCamera[camera_id].device_version == 2114 CAMERA_DEVICE_API_VERSION_1_0) { 2115 // HW Dev Holders 2116 hw_device_t *hw_dev[cam->numCameras]; 2117 2118 if (m_pPhyCamera[cam->pId[0]].type != CAM_TYPE_MAIN) { 2119 LOGE("Physical camera at index 0 is not main!"); 2120 return UNKNOWN_ERROR; 2121 } 2122 2123 // Open all physical cameras 2124 for (uint32_t i = 0; i < cam->numCameras; i++) { 2125 phyId = cam->pId[i]; 2126 QCamera2HardwareInterface *hw = 2127 new QCamera2HardwareInterface((uint32_t)phyId); 2128 if (!hw) { 2129 LOGE("Allocation of hardware interface failed"); 2130 return NO_MEMORY; 2131 } 2132 hw_dev[i] = NULL; 2133 2134 // Make Camera HWI aware of its mode 2135 cam_sync_related_sensors_event_info_t info; 2136 info.sync_control = CAM_SYNC_RELATED_SENSORS_ON; 2137 info.mode = m_pPhyCamera[phyId].mode; 2138 info.type = m_pPhyCamera[phyId].type; 2139 info.is_frame_sync_enabled = m_bFrameSyncEnabled; 2140 rc = hw->setRelatedCamSyncInfo(&info); 2141 if (rc != NO_ERROR) { 2142 LOGE("setRelatedCamSyncInfo failed %d", rc); 2143 delete hw; 2144 return rc; 2145 } 2146 2147 rc = hw->openCamera(&hw_dev[i]); 2148 if (rc != NO_ERROR) { 2149 delete hw; 2150 return rc; 2151 } 2152 hw->getCameraSessionId(&m_pPhyCamera[phyId].camera_server_id); 2153 m_pPhyCamera[phyId].dev = reinterpret_cast<camera_device_t*>(hw_dev[i]); 2154 m_pPhyCamera[phyId].hwi = hw; 2155 cam->sId[i] = m_pPhyCamera[phyId].camera_server_id; 2156 LOGH("camera id %d server id : %d hw device %x, hw %x", 2157 phyId, cam->sId[i], hw_dev[i], hw); 2158 } 2159 } else { 2160 LOGE("Device version for camera id %d invalid %d", 2161 camera_id, m_pLogicalCamera[camera_id].device_version); 2162 return BAD_VALUE; 2163 } 2164 2165 cam->dev.common.tag = HARDWARE_DEVICE_TAG; 2166 cam->dev.common.version = HARDWARE_DEVICE_API_VERSION(1, 0); 2167 cam->dev.common.close = close_camera_device; 2168 cam->dev.ops = &mCameraMuxerOps; 2169 cam->dev.priv = (void*)cam; 2170 *hw_device = &cam->dev.common; 2171 return rc; 2172 } 2173 2174 2175 /*=========================================================================== 2176 * FUNCTION : getLogicalCamera 2177 * 2178 * DESCRIPTION: Get logical camera descriptor 2179 * 2180 * PARAMETERS : 2181 * @device : camera hardware device info 2182 * 2183 * RETURN : logical camera descriptor or NULL 2184 *==========================================================================*/ 2185 qcamera_logical_descriptor_t* QCameraMuxer::getLogicalCamera( 2186 struct camera_device * device) 2187 { 2188 if(device && device->priv){ 2189 return (qcamera_logical_descriptor_t*)(device->priv); 2190 } 2191 return NULL; 2192 } 2193 2194 /*=========================================================================== 2195 * FUNCTION : getPhysicalCamera 2196 * 2197 * DESCRIPTION: Get physical camera descriptor 2198 * 2199 * PARAMETERS : 2200 * @log_cam : Logical camera descriptor 2201 * @index : physical camera index 2202 * 2203 * RETURN : physical camera descriptor or NULL 2204 *==========================================================================*/ 2205 qcamera_physical_descriptor_t* QCameraMuxer::getPhysicalCamera( 2206 qcamera_logical_descriptor_t* log_cam, uint32_t index) 2207 { 2208 if(!log_cam){ 2209 return NULL; 2210 } 2211 return &m_pPhyCamera[log_cam->pId[index]]; 2212 } 2213 2214 /*=========================================================================== 2215 * FUNCTION : getActiveNumOfPhyCam 2216 * 2217 * DESCRIPTION: Get active physical camera number in Logical Camera 2218 * 2219 * PARAMETERS : 2220 * @log_cam : Logical camera descriptor 2221 * @numOfAcitvePhyCam : number of active physical camera in Logical Camera. 2222 * 2223 * RETURN : 2224 * NO_ERROR : success 2225 * ENODEV : Camera not found 2226 * other: non-zero failure code 2227 *==========================================================================*/ 2228 int32_t QCameraMuxer::getActiveNumOfPhyCam( 2229 qcamera_logical_descriptor_t* log_cam, int& numOfAcitvePhyCam) 2230 { 2231 CHECK_CAMERA_ERROR(log_cam); 2232 2233 numOfAcitvePhyCam = log_cam->numCameras; 2234 return NO_ERROR; 2235 } 2236 2237 2238 /*=========================================================================== 2239 * FUNCTION : sendEvtNotify 2240 * 2241 * DESCRIPTION: send event notify to HWI for error callbacks 2242 * 2243 * PARAMETERS : 2244 * @msg_type: msg type to be sent 2245 * @ext1 : optional extension1 2246 * @ext2 : optional extension2 2247 * 2248 * RETURN : int32_t type of status 2249 * NO_ERROR -- success 2250 * none-zero failure code 2251 *==========================================================================*/ 2252 int32_t QCameraMuxer::sendEvtNotify(int32_t msg_type, int32_t ext1, 2253 int32_t ext2) 2254 { 2255 LOGH("E"); 2256 2257 CHECK_MUXER_ERROR(); 2258 2259 qcamera_physical_descriptor_t *pCam = NULL; 2260 pCam = (qcamera_physical_descriptor_t*)(gMuxer->getMainJpegCallbackCookie()); 2261 2262 CHECK_CAMERA_ERROR(pCam); 2263 2264 QCamera2HardwareInterface *hwi = pCam->hwi; 2265 CHECK_HWI_ERROR(hwi); 2266 2267 LOGH("X"); 2268 return pCam->hwi->sendEvtNotify(msg_type, ext1, ext2); 2269 } 2270 2271 /*=========================================================================== 2272 * FUNCTION : composeMpo 2273 * 2274 * DESCRIPTION: Composition of the 2 MPOs 2275 * 2276 * PARAMETERS : none 2277 * @main_Jpeg: pointer to info to Main Jpeg 2278 * @aux_Jpeg : pointer to info to Aux JPEG 2279 * 2280 * RETURN : none 2281 *==========================================================================*/ 2282 void QCameraMuxer::composeMpo(cam_compose_jpeg_info_t* main_Jpeg, 2283 cam_compose_jpeg_info_t* aux_Jpeg) 2284 { 2285 LOGH("E Main Jpeg %p Aux Jpeg %p", main_Jpeg, aux_Jpeg); 2286 2287 CHECK_MUXER(); 2288 if(main_Jpeg == NULL || aux_Jpeg == NULL) { 2289 LOGE("input buffers invalid, ret = NO_MEMORY"); 2290 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 2291 return; 2292 } 2293 2294 pthread_mutex_lock(&m_JpegLock); 2295 2296 m_pRelCamMpoJpeg = mGetMemoryCb(-1, main_Jpeg->buffer->size + 2297 aux_Jpeg->buffer->size, 1, m_pMpoCallbackCookie); 2298 if (NULL == m_pRelCamMpoJpeg) { 2299 LOGE("getMemory for mpo, ret = NO_MEMORY"); 2300 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 2301 pthread_mutex_unlock(&m_JpegLock); 2302 return; 2303 } 2304 2305 // fill all structures to send for composition 2306 mm_jpeg_mpo_info_t mpo_compose_info; 2307 mpo_compose_info.num_of_images = 2; 2308 mpo_compose_info.primary_image.buf_filled_len = main_Jpeg->buffer->size; 2309 mpo_compose_info.primary_image.buf_vaddr = 2310 (uint8_t*)(main_Jpeg->buffer->data); 2311 mpo_compose_info.aux_images[0].buf_filled_len = aux_Jpeg->buffer->size; 2312 mpo_compose_info.aux_images[0].buf_vaddr = 2313 (uint8_t*)(aux_Jpeg->buffer->data); 2314 mpo_compose_info.output_buff.buf_vaddr = 2315 (uint8_t*)m_pRelCamMpoJpeg->data; 2316 mpo_compose_info.output_buff.buf_filled_len = 0; 2317 mpo_compose_info.output_buff_size = main_Jpeg->buffer->size + 2318 aux_Jpeg->buffer->size; 2319 2320 LOGD("MPO buffer size %d\n" 2321 "expected size %d, mpo_compose_info.output_buff_size %d", 2322 m_pRelCamMpoJpeg->size, 2323 main_Jpeg->buffer->size + aux_Jpeg->buffer->size, 2324 mpo_compose_info.output_buff_size); 2325 2326 LOGD("MPO primary buffer filled lengths\n" 2327 "mpo_compose_info.primary_image.buf_filled_len %d\n" 2328 "mpo_compose_info.primary_image.buf_vaddr %p", 2329 mpo_compose_info.primary_image.buf_filled_len, 2330 mpo_compose_info.primary_image.buf_vaddr); 2331 2332 LOGD("MPO aux buffer filled lengths\n" 2333 "mpo_compose_info.aux_images[0].buf_filled_len %d" 2334 "mpo_compose_info.aux_images[0].buf_vaddr %p", 2335 mpo_compose_info.aux_images[0].buf_filled_len, 2336 mpo_compose_info.aux_images[0].buf_vaddr); 2337 2338 if(m_bDumpImages) { 2339 LOGD("Dumping Main Image for MPO"); 2340 char buf_main[QCAMERA_MAX_FILEPATH_LENGTH]; 2341 memset(buf_main, 0, sizeof(buf_main)); 2342 snprintf(buf_main, sizeof(buf_main), 2343 QCAMERA_DUMP_FRM_LOCATION "Main.jpg"); 2344 2345 int file_fd_main = open(buf_main, O_RDWR | O_CREAT, 0777); 2346 if (file_fd_main >= 0) { 2347 ssize_t written_len = write(file_fd_main, 2348 mpo_compose_info.primary_image.buf_vaddr, 2349 mpo_compose_info.primary_image.buf_filled_len); 2350 fchmod(file_fd_main, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 2351 LOGD("written number of bytes for main Image %zd\n", 2352 written_len); 2353 close(file_fd_main); 2354 } 2355 2356 LOGD("Dumping Aux Image for MPO"); 2357 char buf_aux[QCAMERA_MAX_FILEPATH_LENGTH]; 2358 memset(buf_aux, 0, sizeof(buf_aux)); 2359 snprintf(buf_aux, sizeof(buf_aux), 2360 QCAMERA_DUMP_FRM_LOCATION "Aux.jpg"); 2361 2362 int file_fd_aux = open(buf_aux, O_RDWR | O_CREAT, 0777); 2363 if (file_fd_aux >= 0) { 2364 ssize_t written_len = write(file_fd_aux, 2365 mpo_compose_info.aux_images[0].buf_vaddr, 2366 mpo_compose_info.aux_images[0].buf_filled_len); 2367 fchmod(file_fd_aux, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 2368 LOGD("written number of bytes for Aux Image %zd\n", 2369 written_len); 2370 close(file_fd_aux); 2371 } 2372 } 2373 2374 int32_t rc = mJpegMpoOps.compose_mpo(&mpo_compose_info); 2375 LOGD("Compose mpo returned %d", rc); 2376 2377 if(rc != NO_ERROR) { 2378 LOGE("ComposeMpo failed, ret = %d", rc); 2379 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 2380 pthread_mutex_unlock(&m_JpegLock); 2381 return; 2382 } 2383 2384 if(m_bDumpImages) { 2385 char buf_mpo[QCAMERA_MAX_FILEPATH_LENGTH]; 2386 memset(buf_mpo, 0, sizeof(buf_mpo)); 2387 snprintf(buf_mpo, sizeof(buf_mpo), 2388 QCAMERA_DUMP_FRM_LOCATION "Composed.MPO"); 2389 2390 int file_fd_mpo = open(buf_mpo, O_RDWR | O_CREAT, 0777); 2391 if (file_fd_mpo >= 0) { 2392 ssize_t written_len = write(file_fd_mpo, 2393 m_pRelCamMpoJpeg->data, 2394 m_pRelCamMpoJpeg->size); 2395 fchmod(file_fd_mpo, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 2396 LOGD("written number of bytes for MPO Image %zd\n", 2397 written_len); 2398 close(file_fd_mpo); 2399 } 2400 } 2401 2402 mDataCb(main_Jpeg->msg_type, 2403 m_pRelCamMpoJpeg, 2404 main_Jpeg->index, 2405 main_Jpeg->metadata, 2406 m_pMpoCallbackCookie); 2407 2408 if (NULL != m_pRelCamMpoJpeg) { 2409 m_pRelCamMpoJpeg->release(m_pRelCamMpoJpeg); 2410 m_pRelCamMpoJpeg = NULL; 2411 } 2412 2413 pthread_mutex_unlock(&m_JpegLock); 2414 LOGH("X"); 2415 return; 2416 } 2417 2418 /*=========================================================================== 2419 * FUNCTION : matchFrameId 2420 * 2421 * DESCRIPTION: function to match frame ids within queue nodes 2422 * 2423 * PARAMETERS : 2424 * @data: pointer to queue node to be matched for condition 2425 * @user_data: caller can add more info here 2426 * @match_data : value to be matched against 2427 * 2428 * RETURN : true or false based on whether match was successful or not 2429 *==========================================================================*/ 2430 bool QCameraMuxer::matchFrameId(void *data, __unused void *user_data, 2431 void *match_data) 2432 { 2433 LOGH("E"); 2434 2435 if (!data || !match_data) { 2436 return false; 2437 } 2438 2439 cam_compose_jpeg_info_t * node = (cam_compose_jpeg_info_t *) data; 2440 uint32_t frame_idx = *((uint32_t *) match_data); 2441 LOGH("X"); 2442 return node->frame_idx == frame_idx; 2443 } 2444 2445 /*=========================================================================== 2446 * FUNCTION : findPreviousJpegs 2447 * 2448 * DESCRIPTION: Finds Jpegs in the queue with index less than delivered one 2449 * 2450 * PARAMETERS : 2451 * @data: pointer to queue node to be matched for condition 2452 * @user_data: caller can add more info here 2453 * @match_data : value to be matched against 2454 * 2455 * RETURN : true or false based on whether match was successful or not 2456 *==========================================================================*/ 2457 bool QCameraMuxer::findPreviousJpegs(void *data, __unused void *user_data, 2458 void *match_data) 2459 { 2460 LOGH("E"); 2461 2462 if (!data || !match_data) { 2463 return false; 2464 } 2465 cam_compose_jpeg_info_t * node = (cam_compose_jpeg_info_t *) data; 2466 uint32_t frame_idx = *((uint32_t *) match_data); 2467 LOGH("X"); 2468 return node->frame_idx < frame_idx; 2469 } 2470 2471 /*=========================================================================== 2472 * FUNCTION : releaseJpegInfo 2473 * 2474 * DESCRIPTION: callback function for the release of individual nodes 2475 * in the JPEG queues. 2476 * 2477 * PARAMETERS : 2478 * @data : ptr to the data to be released 2479 * @user_data : caller can add more info here 2480 * 2481 * RETURN : None 2482 *==========================================================================*/ 2483 void QCameraMuxer::releaseJpegInfo(void *data, __unused void *user_data) 2484 { 2485 LOGH("E"); 2486 2487 cam_compose_jpeg_info_t *jpegInfo = (cam_compose_jpeg_info_t *)data; 2488 if(jpegInfo && jpegInfo->release_cb) { 2489 if (jpegInfo->release_data != NULL) { 2490 jpegInfo->release_cb(jpegInfo->release_data, 2491 jpegInfo->release_cookie, 2492 NO_ERROR); 2493 } 2494 } 2495 LOGH("X"); 2496 } 2497 2498 /*=========================================================================== 2499 * FUNCTION : composeMpoRoutine 2500 * 2501 * DESCRIPTION: specialized thread for MPO composition 2502 * 2503 * PARAMETERS : 2504 * @data : pointer to the thread owner 2505 * 2506 * RETURN : void* to thread 2507 *==========================================================================*/ 2508 void* QCameraMuxer::composeMpoRoutine(__unused void *data) 2509 { 2510 LOGH("E"); 2511 if (!gMuxer) { 2512 LOGE("Error getting muxer "); 2513 return NULL; 2514 } 2515 2516 int running = 1; 2517 int ret; 2518 uint8_t is_active = FALSE; 2519 QCameraCmdThread *cmdThread = &gMuxer->m_ComposeMpoTh; 2520 cmdThread->setName("CAM_ComposeMpo"); 2521 2522 do { 2523 do { 2524 ret = cam_sem_wait(&cmdThread->cmd_sem); 2525 if (ret != 0 && errno != EINVAL) { 2526 LOGE("cam_sem_wait error (%s)", strerror(errno)); 2527 return NULL; 2528 } 2529 } while (ret != 0); 2530 2531 // we got notified about new cmd avail in cmd queue 2532 camera_cmd_type_t cmd = cmdThread->getCmd(); 2533 switch (cmd) { 2534 case CAMERA_CMD_TYPE_START_DATA_PROC: 2535 { 2536 LOGH("start ComposeMpo processing"); 2537 is_active = TRUE; 2538 2539 // signal cmd is completed 2540 cam_sem_post(&cmdThread->sync_sem); 2541 } 2542 break; 2543 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 2544 { 2545 LOGH("stop ComposeMpo processing"); 2546 is_active = FALSE; 2547 2548 // signal cmd is completed 2549 cam_sem_post(&cmdThread->sync_sem); 2550 } 2551 break; 2552 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 2553 { 2554 if (is_active == TRUE) { 2555 LOGH("Mpo Composition Requested"); 2556 cam_compose_jpeg_info_t *main_jpeg_node = NULL; 2557 cam_compose_jpeg_info_t *aux_jpeg_node = NULL; 2558 bool foundMatch = false; 2559 while (!gMuxer->m_MainJpegQ.isEmpty() && 2560 !gMuxer->m_AuxJpegQ.isEmpty()) { 2561 main_jpeg_node = (cam_compose_jpeg_info_t *) 2562 gMuxer->m_MainJpegQ.dequeue(); 2563 if (main_jpeg_node != NULL) { 2564 LOGD("main_jpeg_node found frame idx %d" 2565 "ptr %p buffer_ptr %p buffer_size %d", 2566 main_jpeg_node->frame_idx, 2567 main_jpeg_node, 2568 main_jpeg_node->buffer->data, 2569 main_jpeg_node->buffer->size); 2570 // find matching aux node in Aux Jpeg Queue 2571 aux_jpeg_node = 2572 (cam_compose_jpeg_info_t *) gMuxer-> 2573 m_AuxJpegQ.dequeue(); 2574 if (aux_jpeg_node != NULL) { 2575 LOGD("aux_jpeg_node found frame idx %d" 2576 "ptr %p buffer_ptr %p buffer_size %d", 2577 aux_jpeg_node->frame_idx, 2578 aux_jpeg_node, 2579 aux_jpeg_node->buffer->data, 2580 aux_jpeg_node->buffer->size); 2581 foundMatch = true; 2582 // start MPO composition 2583 gMuxer->composeMpo(main_jpeg_node, 2584 aux_jpeg_node); 2585 } 2586 } 2587 if (main_jpeg_node != NULL) { 2588 if ( main_jpeg_node->release_cb ) { 2589 main_jpeg_node->release_cb( 2590 main_jpeg_node->release_data, 2591 main_jpeg_node->release_cookie, 2592 NO_ERROR); 2593 } 2594 free(main_jpeg_node); 2595 main_jpeg_node = NULL; 2596 } else { 2597 LOGH("Mpo Match not found"); 2598 } 2599 if (aux_jpeg_node != NULL) { 2600 if (aux_jpeg_node->release_cb) { 2601 aux_jpeg_node->release_cb( 2602 aux_jpeg_node->release_data, 2603 aux_jpeg_node->release_cookie, 2604 NO_ERROR); 2605 } 2606 free(aux_jpeg_node); 2607 aux_jpeg_node = NULL; 2608 } else { 2609 LOGH("Mpo Match not found"); 2610 } 2611 } 2612 } 2613 break; 2614 } 2615 case CAMERA_CMD_TYPE_EXIT: 2616 LOGH("ComposeMpo thread exit"); 2617 running = 0; 2618 break; 2619 default: 2620 break; 2621 } 2622 } while (running); 2623 LOGH("X"); 2624 return NULL; 2625 } 2626 2627 /*=========================================================================== 2628 * FUNCTION : jpeg_data_callback 2629 * 2630 * DESCRIPTION: JPEG data callback for snapshot 2631 * 2632 * PARAMETERS : 2633 * @msg_type : callback msg type 2634 * @data : data ptr of the buffer 2635 * @index : index of the frame 2636 * @metadata : metadata associated with the buffer 2637 * @user : callback cookie returned back to the user 2638 * @frame_idx : frame index for matching frames 2639 * @release_cb : callback function for releasing the data memory 2640 * @release_cookie : cookie for the release callback function 2641 * @release_data :pointer indicating what needs to be released 2642 * 2643 * RETURN : none 2644 *==========================================================================*/ 2645 void QCameraMuxer::jpeg_data_callback(int32_t msg_type, 2646 const camera_memory_t *data, unsigned int index, 2647 camera_frame_metadata_t *metadata, void *user, 2648 uint32_t frame_idx, camera_release_callback release_cb, 2649 void *release_cookie, void *release_data) 2650 { 2651 LOGH("E"); 2652 CHECK_MUXER(); 2653 2654 if(data != NULL) { 2655 LOGH("jpeg received: data %p size %d data ptr %p frameIdx %d", 2656 data, data->size, data->data, frame_idx); 2657 int rc = gMuxer->storeJpeg(((qcamera_physical_descriptor_t*)(user))->type, 2658 msg_type, data, index, metadata, user, frame_idx, release_cb, 2659 release_cookie, release_data); 2660 if(rc != NO_ERROR) { 2661 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 2662 } 2663 } else { 2664 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 2665 } 2666 LOGH("X"); 2667 return; 2668 } 2669 2670 /*=========================================================================== 2671 * FUNCTION : storeJpeg 2672 * 2673 * DESCRIPTION: Stores jpegs from multiple related cam instances into a common Queue 2674 * 2675 * PARAMETERS : 2676 * @cam_type : indicates whether main or aux camera sent the Jpeg callback 2677 * @msg_type : callback msg type 2678 * @data : data ptr of the buffer 2679 * @index : index of the frame 2680 * @metadata : metadata associated with the buffer 2681 * @user : callback cookie returned back to the user 2682 * @frame_idx : frame index for matching frames 2683 * @release_cb : callback function for releasing the data memory 2684 * @release_cookie : cookie for the release callback function 2685 * @release_data :pointer indicating what needs to be released 2686 * 2687 * RETURN : int32_t type of status 2688 * NO_ERROR -- success 2689 * none-zero failure code 2690 *==========================================================================*/ 2691 int32_t QCameraMuxer::storeJpeg(cam_sync_type_t cam_type, 2692 int32_t msg_type, const camera_memory_t *data, unsigned int index, 2693 camera_frame_metadata_t *metadata, void *user,uint32_t frame_idx, 2694 camera_release_callback release_cb, void *release_cookie, 2695 void *release_data) 2696 { 2697 LOGH("E jpeg received: data %p size %d data ptr %p frameIdx %d", 2698 data, data->size, data->data, frame_idx); 2699 2700 CHECK_MUXER_ERROR(); 2701 2702 if (!m_bMpoEnabled) { 2703 if (cam_type == CAM_TYPE_MAIN) { 2704 // send data callback only incase of main camera 2705 // aux image is ignored and released back 2706 mDataCb(msg_type, 2707 data, 2708 index, 2709 metadata, 2710 m_pMpoCallbackCookie); 2711 } 2712 if (release_cb) { 2713 release_cb(release_data, release_cookie, NO_ERROR); 2714 } 2715 LOGH("X"); 2716 return NO_ERROR; 2717 } 2718 2719 cam_compose_jpeg_info_t* pJpegFrame = 2720 (cam_compose_jpeg_info_t*)malloc(sizeof(cam_compose_jpeg_info_t)); 2721 if (!pJpegFrame) { 2722 LOGE("Allocation failed for MPO nodes"); 2723 return NO_MEMORY; 2724 } 2725 memset(pJpegFrame, 0, sizeof(*pJpegFrame)); 2726 2727 pJpegFrame->msg_type = msg_type; 2728 pJpegFrame->buffer = const_cast<camera_memory_t*>(data); 2729 pJpegFrame->index = index; 2730 pJpegFrame->metadata = metadata; 2731 pJpegFrame->user = user; 2732 pJpegFrame->valid = true; 2733 pJpegFrame->frame_idx = frame_idx; 2734 pJpegFrame->release_cb = release_cb; 2735 pJpegFrame->release_cookie = release_cookie; 2736 pJpegFrame->release_data = release_data; 2737 if(cam_type == CAM_TYPE_MAIN) { 2738 if (m_MainJpegQ.enqueue((void *)pJpegFrame)) { 2739 LOGD("Main FrameIdx %d", pJpegFrame->frame_idx); 2740 if (m_MainJpegQ.getCurrentSize() > 0) { 2741 LOGD("Trigger Compose"); 2742 m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 2743 } 2744 } else { 2745 LOGE("Enqueue Failed for Main Jpeg Q"); 2746 if ( pJpegFrame->release_cb ) { 2747 // release other buffer also here 2748 pJpegFrame->release_cb( 2749 pJpegFrame->release_data, 2750 pJpegFrame->release_cookie, 2751 NO_ERROR); 2752 } 2753 free(pJpegFrame); 2754 pJpegFrame = NULL; 2755 return NO_MEMORY; 2756 } 2757 2758 } else { 2759 if (m_AuxJpegQ.enqueue((void *)pJpegFrame)) { 2760 LOGD("Aux FrameIdx %d", pJpegFrame->frame_idx); 2761 if (m_AuxJpegQ.getCurrentSize() > 0) { 2762 LOGD("Trigger Compose"); 2763 m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 2764 } 2765 } else { 2766 LOGE("Enqueue Failed for Aux Jpeg Q"); 2767 if ( pJpegFrame->release_cb ) { 2768 // release other buffer also here 2769 pJpegFrame->release_cb( 2770 pJpegFrame->release_data, 2771 pJpegFrame->release_cookie, 2772 NO_ERROR); 2773 } 2774 free(pJpegFrame); 2775 pJpegFrame = NULL; 2776 return NO_MEMORY; 2777 } 2778 } 2779 LOGH("X"); 2780 2781 return NO_ERROR; 2782 } 2783 2784 2785 // Muxer Ops 2786 camera_device_ops_t QCameraMuxer::mCameraMuxerOps = { 2787 .set_preview_window = QCameraMuxer::set_preview_window, 2788 .set_callbacks = QCameraMuxer::set_callBacks, 2789 .enable_msg_type = QCameraMuxer::enable_msg_type, 2790 .disable_msg_type = QCameraMuxer::disable_msg_type, 2791 .msg_type_enabled = QCameraMuxer::msg_type_enabled, 2792 2793 .start_preview = QCameraMuxer::start_preview, 2794 .stop_preview = QCameraMuxer::stop_preview, 2795 .preview_enabled = QCameraMuxer::preview_enabled, 2796 .store_meta_data_in_buffers= QCameraMuxer::store_meta_data_in_buffers, 2797 2798 .start_recording = QCameraMuxer::start_recording, 2799 .stop_recording = QCameraMuxer::stop_recording, 2800 .recording_enabled = QCameraMuxer::recording_enabled, 2801 .release_recording_frame = QCameraMuxer::release_recording_frame, 2802 2803 .auto_focus = QCameraMuxer::auto_focus, 2804 .cancel_auto_focus = QCameraMuxer::cancel_auto_focus, 2805 2806 .take_picture = QCameraMuxer::take_picture, 2807 .cancel_picture = QCameraMuxer::cancel_picture, 2808 2809 .set_parameters = QCameraMuxer::set_parameters, 2810 .get_parameters = QCameraMuxer::get_parameters, 2811 .put_parameters = QCameraMuxer::put_parameters, 2812 .send_command = QCameraMuxer::send_command, 2813 2814 .release = QCameraMuxer::release, 2815 .dump = QCameraMuxer::dump, 2816 }; 2817 2818 2819 }; // namespace android 2820