1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_TAG "QCamera2HWI" 31 32 // To remove 33 #include <cutils/properties.h> 34 35 // System definitions 36 #include <utils/Errors.h> 37 #include <dlfcn.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include "gralloc_priv.h" 41 #include "native_handle.h" 42 43 // Camera definitions 44 #include "android/QCamera2External.h" 45 #include "QCamera2HWI.h" 46 #include "QCameraBufferMaps.h" 47 #include "QCameraFlash.h" 48 #include "QCameraTrace.h" 49 50 extern "C" { 51 #include "mm_camera_dbg.h" 52 } 53 54 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \ 55 ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset) 56 #define CAMERA_MIN_STREAMING_BUFFERS 3 57 #define EXTRA_ZSL_PREVIEW_STREAM_BUF 2 58 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2 59 #define CAMERA_MIN_VIDEO_BUFFERS 9 60 #define CAMERA_MIN_CALLBACK_BUFFERS 5 61 #define CAMERA_LONGSHOT_STAGES 4 62 #define CAMERA_MIN_CAMERA_BATCH_BUFFERS 6 63 #define CAMERA_ISP_PING_PONG_BUFFERS 2 64 #define MIN_UNDEQUEUED_BUFFERS 1 // This is required if preview window is not set 65 #define CAMERA_MIN_DISPLAY_BUFFERS 2 66 #define CAMERA_DEFAULT_FPS 30000 67 68 #define HDR_CONFIDENCE_THRESHOLD 0.4 69 70 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds 71 72 // Very long wait, just to be sure we don't deadlock 73 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds 74 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds 75 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot 76 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5 77 #define CAMERA_MAX_PARAM_APPLY_DELAY 3 78 79 namespace qcamera { 80 81 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS]; 82 extern pthread_mutex_t gCamLock; 83 volatile uint32_t gCamHalLogLevel = 1; 84 extern uint8_t gNumCameraSessions; 85 uint32_t QCamera2HardwareInterface::sNextJobId = 1; 86 87 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = { 88 .set_preview_window = QCamera2HardwareInterface::set_preview_window, 89 .set_callbacks = QCamera2HardwareInterface::set_CallBacks, 90 .enable_msg_type = QCamera2HardwareInterface::enable_msg_type, 91 .disable_msg_type = QCamera2HardwareInterface::disable_msg_type, 92 .msg_type_enabled = QCamera2HardwareInterface::msg_type_enabled, 93 94 .start_preview = QCamera2HardwareInterface::start_preview, 95 .stop_preview = QCamera2HardwareInterface::stop_preview, 96 .preview_enabled = QCamera2HardwareInterface::preview_enabled, 97 .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers, 98 99 .start_recording = QCamera2HardwareInterface::start_recording, 100 .stop_recording = QCamera2HardwareInterface::stop_recording, 101 .recording_enabled = QCamera2HardwareInterface::recording_enabled, 102 .release_recording_frame = QCamera2HardwareInterface::release_recording_frame, 103 104 .auto_focus = QCamera2HardwareInterface::auto_focus, 105 .cancel_auto_focus = QCamera2HardwareInterface::cancel_auto_focus, 106 107 .take_picture = QCamera2HardwareInterface::take_picture, 108 .cancel_picture = QCamera2HardwareInterface::cancel_picture, 109 110 .set_parameters = QCamera2HardwareInterface::set_parameters, 111 .get_parameters = QCamera2HardwareInterface::get_parameters, 112 .put_parameters = QCamera2HardwareInterface::put_parameters, 113 .send_command = QCamera2HardwareInterface::send_command, 114 115 .release = QCamera2HardwareInterface::release, 116 .dump = QCamera2HardwareInterface::dump, 117 }; 118 119 /*=========================================================================== 120 * FUNCTION : set_preview_window 121 * 122 * DESCRIPTION: set preview window. 123 * 124 * PARAMETERS : 125 * @device : ptr to camera device struct 126 * @window : window ops table 127 * 128 * RETURN : int32_t type of status 129 * NO_ERROR -- success 130 * none-zero failure code 131 *==========================================================================*/ 132 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device, 133 struct preview_stream_ops *window) 134 { 135 ATRACE_CALL(); 136 int rc = NO_ERROR; 137 QCamera2HardwareInterface *hw = 138 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 139 if (!hw) { 140 LOGE("NULL camera device"); 141 return BAD_VALUE; 142 } 143 LOGD("E camera id %d window = %p", hw->getCameraId(), window); 144 145 hw->lockAPI(); 146 qcamera_api_result_t apiResult; 147 rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window); 148 if (rc == NO_ERROR) { 149 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult); 150 rc = apiResult.status; 151 } 152 hw->unlockAPI(); 153 LOGD("X camera id %d", hw->getCameraId()); 154 155 return rc; 156 } 157 158 /*=========================================================================== 159 * FUNCTION : set_CallBacks 160 * 161 * DESCRIPTION: set callbacks for notify and data 162 * 163 * PARAMETERS : 164 * @device : ptr to camera device struct 165 * @notify_cb : notify cb 166 * @data_cb : data cb 167 * @data_cb_timestamp : video data cd with timestamp 168 * @get_memory : ops table for request gralloc memory 169 * @user : user data ptr 170 * 171 * RETURN : none 172 *==========================================================================*/ 173 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device, 174 camera_notify_callback notify_cb, 175 camera_data_callback data_cb, 176 camera_data_timestamp_callback data_cb_timestamp, 177 camera_request_memory get_memory, 178 void *user) 179 { 180 ATRACE_CALL(); 181 QCamera2HardwareInterface *hw = 182 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 183 if (!hw) { 184 LOGE("NULL camera device"); 185 return; 186 } 187 LOGD("E camera id %d", hw->getCameraId()); 188 189 qcamera_sm_evt_setcb_payload_t payload; 190 payload.notify_cb = notify_cb; 191 payload.data_cb = data_cb; 192 payload.data_cb_timestamp = data_cb_timestamp; 193 payload.get_memory = get_memory; 194 payload.user = user; 195 196 hw->lockAPI(); 197 qcamera_api_result_t apiResult; 198 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload); 199 if (rc == NO_ERROR) { 200 hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult); 201 } 202 hw->unlockAPI(); 203 LOGD("X camera id %d", hw->getCameraId()); 204 205 } 206 207 /*=========================================================================== 208 * FUNCTION : enable_msg_type 209 * 210 * DESCRIPTION: enable certain msg type 211 * 212 * PARAMETERS : 213 * @device : ptr to camera device struct 214 * @msg_type : msg type mask 215 * 216 * RETURN : none 217 *==========================================================================*/ 218 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type) 219 { 220 ATRACE_CALL(); 221 QCamera2HardwareInterface *hw = 222 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 223 if (!hw) { 224 LOGE("NULL camera device"); 225 return; 226 } 227 LOGD("E camera id %d", hw->getCameraId()); 228 229 hw->lockAPI(); 230 qcamera_api_result_t apiResult; 231 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type); 232 if (rc == NO_ERROR) { 233 hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult); 234 } 235 hw->unlockAPI(); 236 LOGD("X camera id %d", hw->getCameraId()); 237 238 } 239 240 /*=========================================================================== 241 * FUNCTION : disable_msg_type 242 * 243 * DESCRIPTION: disable certain msg type 244 * 245 * PARAMETERS : 246 * @device : ptr to camera device struct 247 * @msg_type : msg type mask 248 * 249 * RETURN : none 250 *==========================================================================*/ 251 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type) 252 { 253 ATRACE_CALL(); 254 QCamera2HardwareInterface *hw = 255 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 256 if (!hw) { 257 LOGE("NULL camera device"); 258 return; 259 } 260 LOGD("E camera id %d", hw->getCameraId()); 261 262 hw->lockAPI(); 263 qcamera_api_result_t apiResult; 264 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type); 265 if (rc == NO_ERROR) { 266 hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult); 267 } 268 hw->unlockAPI(); 269 LOGD("X camera id %d", hw->getCameraId()); 270 271 } 272 273 /*=========================================================================== 274 * FUNCTION : msg_type_enabled 275 * 276 * DESCRIPTION: if certain msg type is enabled 277 * 278 * PARAMETERS : 279 * @device : ptr to camera device struct 280 * @msg_type : msg type mask 281 * 282 * RETURN : 1 -- enabled 283 * 0 -- not enabled 284 *==========================================================================*/ 285 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type) 286 { 287 ATRACE_CALL(); 288 int ret = NO_ERROR; 289 QCamera2HardwareInterface *hw = 290 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 291 if (!hw) { 292 LOGE("NULL camera device"); 293 return BAD_VALUE; 294 } 295 LOGD("E camera id %d", hw->getCameraId()); 296 297 hw->lockAPI(); 298 qcamera_api_result_t apiResult; 299 ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type); 300 if (ret == NO_ERROR) { 301 hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult); 302 ret = apiResult.enabled; 303 } 304 hw->unlockAPI(); 305 LOGD("X camera id %d", hw->getCameraId()); 306 307 return ret; 308 } 309 310 /*=========================================================================== 311 * FUNCTION : prepare_preview 312 * 313 * DESCRIPTION: prepare preview 314 * 315 * PARAMETERS : 316 * @device : ptr to camera device struct 317 * 318 * RETURN : int32_t type of status 319 * NO_ERROR -- success 320 * none-zero failure code 321 *==========================================================================*/ 322 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device) 323 { 324 ATRACE_CALL(); 325 int ret = NO_ERROR; 326 QCamera2HardwareInterface *hw = 327 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 328 if (!hw) { 329 LOGE("NULL camera device"); 330 return BAD_VALUE; 331 } 332 LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d", 333 hw->getCameraId()); 334 hw->lockAPI(); 335 qcamera_api_result_t apiResult; 336 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW; 337 ret = hw->processAPI(evt, NULL); 338 if (ret == NO_ERROR) { 339 hw->waitAPIResult(evt, &apiResult); 340 ret = apiResult.status; 341 } 342 hw->unlockAPI(); 343 LOGH("[KPI Perf]: X"); 344 return ret; 345 } 346 347 348 /*=========================================================================== 349 * FUNCTION : start_preview 350 * 351 * DESCRIPTION: start preview 352 * 353 * PARAMETERS : 354 * @device : ptr to camera device struct 355 * 356 * RETURN : int32_t type of status 357 * NO_ERROR -- success 358 * none-zero failure code 359 *==========================================================================*/ 360 int QCamera2HardwareInterface::start_preview(struct camera_device *device) 361 { 362 KPI_ATRACE_CALL(); 363 int ret = NO_ERROR; 364 QCamera2HardwareInterface *hw = 365 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 366 if (!hw) { 367 LOGE("NULL camera device"); 368 return BAD_VALUE; 369 } 370 LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d", 371 hw->getCameraId()); 372 373 // Release the timed perf lock acquired in openCamera 374 hw->m_perfLock.lock_rel_timed(); 375 376 hw->m_perfLock.lock_acq(); 377 hw->lockAPI(); 378 qcamera_api_result_t apiResult; 379 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW; 380 if (hw->isNoDisplayMode()) { 381 evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW; 382 } 383 ret = hw->processAPI(evt, NULL); 384 if (ret == NO_ERROR) { 385 hw->waitAPIResult(evt, &apiResult); 386 ret = apiResult.status; 387 } 388 hw->unlockAPI(); 389 hw->m_bPreviewStarted = true; 390 LOGI("[KPI Perf]: X ret = %d", ret); 391 return ret; 392 } 393 394 /*=========================================================================== 395 * FUNCTION : stop_preview 396 * 397 * DESCRIPTION: stop preview 398 * 399 * PARAMETERS : 400 * @device : ptr to camera device struct 401 * 402 * RETURN : none 403 *==========================================================================*/ 404 void QCamera2HardwareInterface::stop_preview(struct camera_device *device) 405 { 406 KPI_ATRACE_CALL(); 407 QCamera2HardwareInterface *hw = 408 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 409 if (!hw) { 410 LOGE("NULL camera device"); 411 return; 412 } 413 LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d", 414 hw->getCameraId()); 415 416 // Disable power Hint for preview 417 hw->m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false); 418 419 hw->m_perfLock.lock_acq(); 420 hw->lockAPI(); 421 qcamera_api_result_t apiResult; 422 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL); 423 if (ret == NO_ERROR) { 424 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult); 425 } 426 hw->unlockAPI(); 427 LOGI("[KPI Perf]: X ret = %d", ret); 428 } 429 430 /*=========================================================================== 431 * FUNCTION : preview_enabled 432 * 433 * DESCRIPTION: if preview is running 434 * 435 * PARAMETERS : 436 * @device : ptr to camera device struct 437 * 438 * RETURN : 1 -- running 439 * 0 -- not running 440 *==========================================================================*/ 441 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device) 442 { 443 ATRACE_CALL(); 444 int ret = NO_ERROR; 445 QCamera2HardwareInterface *hw = 446 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 447 if (!hw) { 448 LOGE("NULL camera device"); 449 return BAD_VALUE; 450 } 451 LOGD("E camera id %d", hw->getCameraId()); 452 453 hw->lockAPI(); 454 qcamera_api_result_t apiResult; 455 ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL); 456 if (ret == NO_ERROR) { 457 hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult); 458 ret = apiResult.enabled; 459 } 460 461 //if preview enabled, can enable preview callback send 462 if(apiResult.enabled) { 463 hw->m_stateMachine.setPreviewCallbackNeeded(true); 464 } 465 hw->unlockAPI(); 466 LOGD("X camera id %d", hw->getCameraId()); 467 468 return ret; 469 } 470 471 /*=========================================================================== 472 * FUNCTION : store_meta_data_in_buffers 473 * 474 * DESCRIPTION: if need to store meta data in buffers for video frame 475 * 476 * PARAMETERS : 477 * @device : ptr to camera device struct 478 * @enable : flag if enable 479 * 480 * RETURN : int32_t type of status 481 * NO_ERROR -- success 482 * none-zero failure code 483 *==========================================================================*/ 484 int QCamera2HardwareInterface::store_meta_data_in_buffers( 485 struct camera_device *device, int enable) 486 { 487 int ret = NO_ERROR; 488 QCamera2HardwareInterface *hw = 489 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 490 if (!hw) { 491 LOGE("NULL camera device"); 492 return BAD_VALUE; 493 } 494 LOGD("E camera id %d", hw->getCameraId()); 495 496 hw->lockAPI(); 497 qcamera_api_result_t apiResult; 498 ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable); 499 if (ret == NO_ERROR) { 500 hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult); 501 ret = apiResult.status; 502 } 503 hw->unlockAPI(); 504 LOGD("X camera id %d", hw->getCameraId()); 505 506 return ret; 507 } 508 509 /*=========================================================================== 510 * FUNCTION : restart_start_preview 511 * 512 * DESCRIPTION: start preview as part of the restart preview 513 * 514 * PARAMETERS : 515 * @device : ptr to camera device struct 516 * 517 * RETURN : int32_t type of status 518 * NO_ERROR -- success 519 * none-zero failure code 520 *==========================================================================*/ 521 int QCamera2HardwareInterface::restart_start_preview(struct camera_device *device) 522 { 523 ATRACE_CALL(); 524 int ret = NO_ERROR; 525 QCamera2HardwareInterface *hw = 526 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 527 if (!hw) { 528 LOGE("NULL camera device"); 529 return BAD_VALUE; 530 } 531 LOGI("E camera id %d", hw->getCameraId()); 532 hw->lockAPI(); 533 qcamera_api_result_t apiResult; 534 535 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 536 ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_START_PREVIEW, NULL); 537 if (ret == NO_ERROR) { 538 hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_START_PREVIEW, &apiResult); 539 ret = apiResult.status; 540 } 541 } else { 542 LOGE("This function is not supposed to be called in single-camera mode"); 543 ret = INVALID_OPERATION; 544 } 545 // Preview restart done, update the mPreviewRestartNeeded flag to false. 546 hw->mPreviewRestartNeeded = false; 547 hw->unlockAPI(); 548 LOGI("X camera id %d", hw->getCameraId()); 549 550 return ret; 551 } 552 553 /*=========================================================================== 554 * FUNCTION : restart_stop_preview 555 * 556 * DESCRIPTION: stop preview as part of the restart preview 557 * 558 * PARAMETERS : 559 * @device : ptr to camera device struct 560 * 561 * RETURN : int32_t type of status 562 * NO_ERROR -- success 563 * none-zero failure code 564 *==========================================================================*/ 565 int QCamera2HardwareInterface::restart_stop_preview(struct camera_device *device) 566 { 567 ATRACE_CALL(); 568 int ret = NO_ERROR; 569 QCamera2HardwareInterface *hw = 570 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 571 if (!hw) { 572 LOGE("NULL camera device"); 573 return BAD_VALUE; 574 } 575 LOGI("E camera id %d", hw->getCameraId()); 576 hw->lockAPI(); 577 qcamera_api_result_t apiResult; 578 579 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 580 ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, NULL); 581 if (ret == NO_ERROR) { 582 hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, &apiResult); 583 ret = apiResult.status; 584 } 585 } else { 586 LOGE("This function is not supposed to be called in single-camera mode"); 587 ret = INVALID_OPERATION; 588 } 589 590 hw->unlockAPI(); 591 LOGI("X camera id %d", hw->getCameraId()); 592 593 return ret; 594 } 595 596 /*=========================================================================== 597 * FUNCTION : pre_start_recording 598 * 599 * DESCRIPTION: prepare for the start recording 600 * 601 * PARAMETERS : 602 * @device : ptr to camera device struct 603 * 604 * RETURN : int32_t type of status 605 * NO_ERROR -- success 606 * none-zero failure code 607 *==========================================================================*/ 608 int QCamera2HardwareInterface::pre_start_recording(struct camera_device *device) 609 { 610 ATRACE_CALL(); 611 int ret = NO_ERROR; 612 QCamera2HardwareInterface *hw = 613 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 614 if (!hw) { 615 LOGE("NULL camera device"); 616 return BAD_VALUE; 617 } 618 LOGH("[KPI Perf]: E PROFILE_PRE_START_RECORDING camera id %d", 619 hw->getCameraId()); 620 hw->lockAPI(); 621 qcamera_api_result_t apiResult; 622 ret = hw->processAPI(QCAMERA_SM_EVT_PRE_START_RECORDING, NULL); 623 if (ret == NO_ERROR) { 624 hw->waitAPIResult(QCAMERA_SM_EVT_PRE_START_RECORDING, &apiResult); 625 ret = apiResult.status; 626 } 627 hw->unlockAPI(); 628 LOGH("[KPI Perf]: X"); 629 return ret; 630 } 631 632 /*=========================================================================== 633 * FUNCTION : start_recording 634 * 635 * DESCRIPTION: start recording 636 * 637 * PARAMETERS : 638 * @device : ptr to camera device struct 639 * 640 * RETURN : int32_t type of status 641 * NO_ERROR -- success 642 * none-zero failure code 643 *==========================================================================*/ 644 int QCamera2HardwareInterface::start_recording(struct camera_device *device) 645 { 646 ATRACE_CALL(); 647 int ret = NO_ERROR; 648 QCamera2HardwareInterface *hw = 649 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 650 if (!hw) { 651 LOGE("NULL camera device"); 652 return BAD_VALUE; 653 } 654 LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d", 655 hw->getCameraId()); 656 // Give HWI control to call pre_start_recording in single camera mode. 657 // In dual-cam mode, this control belongs to muxer. 658 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 659 ret = pre_start_recording(device); 660 if (ret != NO_ERROR) { 661 LOGE("pre_start_recording failed with ret = %d", ret); 662 return ret; 663 } 664 } 665 666 hw->lockAPI(); 667 qcamera_api_result_t apiResult; 668 ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL); 669 if (ret == NO_ERROR) { 670 hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult); 671 ret = apiResult.status; 672 } 673 hw->unlockAPI(); 674 hw->m_bRecordStarted = true; 675 LOGI("[KPI Perf]: X ret = %d", ret); 676 677 return ret; 678 } 679 680 /*=========================================================================== 681 * FUNCTION : stop_recording 682 * 683 * DESCRIPTION: stop recording 684 * 685 * PARAMETERS : 686 * @device : ptr to camera device struct 687 * 688 * RETURN : none 689 *==========================================================================*/ 690 void QCamera2HardwareInterface::stop_recording(struct camera_device *device) 691 { 692 ATRACE_CALL(); 693 QCamera2HardwareInterface *hw = 694 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 695 if (!hw) { 696 LOGE("NULL camera device"); 697 return; 698 } 699 LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d", 700 hw->getCameraId()); 701 702 hw->lockAPI(); 703 qcamera_api_result_t apiResult; 704 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL); 705 if (ret == NO_ERROR) { 706 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult); 707 } 708 hw->unlockAPI(); 709 LOGI("[KPI Perf]: X ret = %d", ret); 710 } 711 712 /*=========================================================================== 713 * FUNCTION : recording_enabled 714 * 715 * DESCRIPTION: if recording is running 716 * 717 * PARAMETERS : 718 * @device : ptr to camera device struct 719 * 720 * RETURN : 1 -- running 721 * 0 -- not running 722 *==========================================================================*/ 723 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device) 724 { 725 ATRACE_CALL(); 726 int ret = NO_ERROR; 727 QCamera2HardwareInterface *hw = 728 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 729 if (!hw) { 730 LOGE("NULL camera device"); 731 return BAD_VALUE; 732 } 733 LOGD("E camera id %d", hw->getCameraId()); 734 hw->lockAPI(); 735 qcamera_api_result_t apiResult; 736 ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL); 737 if (ret == NO_ERROR) { 738 hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult); 739 ret = apiResult.enabled; 740 } 741 hw->unlockAPI(); 742 LOGD("X camera id %d", hw->getCameraId()); 743 744 return ret; 745 } 746 747 /*=========================================================================== 748 * FUNCTION : release_recording_frame 749 * 750 * DESCRIPTION: return recording frame back 751 * 752 * PARAMETERS : 753 * @device : ptr to camera device struct 754 * @opaque : ptr to frame to be returned 755 * 756 * RETURN : none 757 *==========================================================================*/ 758 void QCamera2HardwareInterface::release_recording_frame( 759 struct camera_device *device, const void *opaque) 760 { 761 ATRACE_CALL(); 762 int32_t ret = NO_ERROR; 763 QCamera2HardwareInterface *hw = 764 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 765 if (!hw) { 766 LOGE("NULL camera device"); 767 return; 768 } 769 if (!opaque) { 770 LOGE("Error!! Frame info is NULL"); 771 return; 772 } 773 LOGD("E camera id %d", hw->getCameraId()); 774 775 hw->lockAPI(); 776 qcamera_api_result_t apiResult; 777 ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque); 778 if (ret == NO_ERROR) { 779 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult); 780 } 781 hw->unlockAPI(); 782 LOGD("X camera id %d", hw->getCameraId()); 783 } 784 785 /*=========================================================================== 786 * FUNCTION : auto_focus 787 * 788 * DESCRIPTION: start auto focus 789 * 790 * PARAMETERS : 791 * @device : ptr to camera device struct 792 * 793 * RETURN : int32_t type of status 794 * NO_ERROR -- success 795 * none-zero failure code 796 *==========================================================================*/ 797 int QCamera2HardwareInterface::auto_focus(struct camera_device *device) 798 { 799 KPI_ATRACE_INT("Camera:AutoFocus", 1); 800 int ret = NO_ERROR; 801 QCamera2HardwareInterface *hw = 802 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 803 if (!hw) { 804 LOGE("NULL camera device"); 805 return BAD_VALUE; 806 } 807 LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d", 808 hw->getCameraId()); 809 hw->lockAPI(); 810 qcamera_api_result_t apiResult; 811 ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL); 812 if (ret == NO_ERROR) { 813 hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult); 814 ret = apiResult.status; 815 } 816 hw->unlockAPI(); 817 LOGH("[KPI Perf] : X ret = %d", ret); 818 819 return ret; 820 } 821 822 /*=========================================================================== 823 * FUNCTION : cancel_auto_focus 824 * 825 * DESCRIPTION: cancel auto focus 826 * 827 * PARAMETERS : 828 * @device : ptr to camera device struct 829 * 830 * RETURN : int32_t type of status 831 * NO_ERROR -- success 832 * none-zero failure code 833 *==========================================================================*/ 834 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device) 835 { 836 ATRACE_CALL(); 837 int ret = NO_ERROR; 838 QCamera2HardwareInterface *hw = 839 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 840 if (!hw) { 841 LOGE("NULL camera device"); 842 return BAD_VALUE; 843 } 844 LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d", 845 hw->getCameraId()); 846 hw->lockAPI(); 847 qcamera_api_result_t apiResult; 848 ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL); 849 if (ret == NO_ERROR) { 850 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult); 851 ret = apiResult.status; 852 } 853 hw->unlockAPI(); 854 LOGH("[KPI Perf] : X ret = %d", ret); 855 return ret; 856 } 857 858 /*=========================================================================== 859 * FUNCTION : pre_take_picture 860 * 861 * DESCRIPTION: pre take picture, restart preview if necessary. 862 * 863 * PARAMETERS : 864 * @device : ptr to camera device struct 865 * 866 * RETURN : int32_t type of status 867 * NO_ERROR -- success 868 * none-zero failure code 869 *==========================================================================*/ 870 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device) 871 { 872 ATRACE_CALL(); 873 int ret = NO_ERROR; 874 QCamera2HardwareInterface *hw = 875 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 876 if (!hw) { 877 LOGE("NULL camera device"); 878 return BAD_VALUE; 879 } 880 LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d", 881 hw->getCameraId()); 882 hw->lockAPI(); 883 qcamera_api_result_t apiResult; 884 ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL); 885 if (ret == NO_ERROR) { 886 hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult); 887 ret = apiResult.status; 888 } 889 hw->unlockAPI(); 890 LOGH("[KPI Perf]: X"); 891 return ret; 892 } 893 894 /*=========================================================================== 895 * FUNCTION : take_picture 896 * 897 * DESCRIPTION: take picture 898 * 899 * PARAMETERS : 900 * @device : ptr to camera device struct 901 * 902 * RETURN : int32_t type of status 903 * NO_ERROR -- success 904 * none-zero failure code 905 *==========================================================================*/ 906 int QCamera2HardwareInterface::take_picture(struct camera_device *device) 907 { 908 KPI_ATRACE_CALL(); 909 int ret = NO_ERROR; 910 QCamera2HardwareInterface *hw = 911 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 912 if (!hw) { 913 LOGE("NULL camera device"); 914 return BAD_VALUE; 915 } 916 LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d", 917 hw->getCameraId()); 918 if (!hw->mLongshotEnabled) { 919 hw->m_perfLock.lock_acq(); 920 } 921 qcamera_api_result_t apiResult; 922 923 /** Added support for Retro-active Frames: 924 * takePicture() is called before preparing Snapshot to indicate the 925 * mm-camera-channel to pick up legacy frames even 926 * before LED estimation is triggered. 927 */ 928 929 LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d", 930 hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(), 931 hw->isLongshotEnabled()); 932 933 // Check for Retro-active Frames 934 if ((hw->mParameters.getNumOfRetroSnapshots() > 0) && 935 !hw->isLiveSnapshot() && hw->isZSLMode() && 936 !hw->isHDRMode() && !hw->isLongshotEnabled()) { 937 // Set Retro Picture Mode 938 hw->setRetroPicture(1); 939 hw->m_bLedAfAecLock = 0; 940 LOGL("Retro Enabled"); 941 942 // Give HWI control to call pre_take_picture in single camera mode. 943 // In dual-cam mode, this control belongs to muxer. 944 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 945 ret = pre_take_picture(device); 946 if (ret != NO_ERROR) { 947 LOGE("pre_take_picture failed with ret = %d",ret); 948 return ret; 949 } 950 } 951 952 /* Call take Picture for total number of snapshots required. 953 This includes the number of retro frames and normal frames */ 954 hw->lockAPI(); 955 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 956 if (ret == NO_ERROR) { 957 // Wait for retro frames, before calling prepare snapshot 958 LOGD("Wait for Retro frames to be done"); 959 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 960 ret = apiResult.status; 961 } 962 /* Unlock API since it is acquired in prepare snapshot seperately */ 963 hw->unlockAPI(); 964 965 /* Prepare snapshot in case LED needs to be flashed */ 966 LOGD("Start Prepare Snapshot"); 967 ret = hw->prepare_snapshot(device); 968 } 969 else { 970 hw->setRetroPicture(0); 971 // Check if prepare snapshot is done 972 if (!hw->mPrepSnapRun) { 973 // Ignore the status from prepare_snapshot 974 hw->prepare_snapshot(device); 975 } 976 977 // Give HWI control to call pre_take_picture in single camera mode. 978 // In dual-cam mode, this control belongs to muxer. 979 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 980 ret = pre_take_picture(device); 981 if (ret != NO_ERROR) { 982 LOGE("pre_take_picture failed with ret = %d",ret); 983 return ret; 984 } 985 } 986 987 // Regardless what the result value for prepare_snapshot, 988 // go ahead with capture anyway. Just like the way autofocus 989 // is handled in capture case 990 /* capture */ 991 LOGL("Capturing normal frames"); 992 hw->lockAPI(); 993 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 994 if (ret == NO_ERROR) { 995 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 996 ret = apiResult.status; 997 } 998 hw->unlockAPI(); 999 if (!hw->isLongshotEnabled()){ 1000 // For longshot mode, we prepare snapshot only once 1001 hw->mPrepSnapRun = false; 1002 } 1003 } 1004 LOGI("[KPI Perf]: X ret = %d", ret); 1005 return ret; 1006 } 1007 1008 /*=========================================================================== 1009 * FUNCTION : cancel_picture 1010 * 1011 * DESCRIPTION: cancel current take picture request 1012 * 1013 * PARAMETERS : 1014 * @device : ptr to camera device struct 1015 * 1016 * RETURN : int32_t type of status 1017 * NO_ERROR -- success 1018 * none-zero failure code 1019 *==========================================================================*/ 1020 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device) 1021 { 1022 ATRACE_CALL(); 1023 int ret = NO_ERROR; 1024 QCamera2HardwareInterface *hw = 1025 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1026 if (!hw) { 1027 LOGE("NULL camera device"); 1028 return BAD_VALUE; 1029 } 1030 LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d", 1031 hw->getCameraId()); 1032 hw->lockAPI(); 1033 qcamera_api_result_t apiResult; 1034 ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 1035 if (ret == NO_ERROR) { 1036 hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult); 1037 ret = apiResult.status; 1038 } 1039 hw->unlockAPI(); 1040 LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret); 1041 1042 return ret; 1043 } 1044 1045 /*=========================================================================== 1046 * FUNCTION : set_parameters 1047 * 1048 * DESCRIPTION: set camera parameters 1049 * 1050 * PARAMETERS : 1051 * @device : ptr to camera device struct 1052 * @parms : string of packed parameters 1053 * 1054 * RETURN : int32_t type of status 1055 * NO_ERROR -- success 1056 * none-zero failure code 1057 *==========================================================================*/ 1058 int QCamera2HardwareInterface::set_parameters(struct camera_device *device, 1059 const char *parms) 1060 { 1061 ATRACE_CALL(); 1062 int ret = NO_ERROR; 1063 QCamera2HardwareInterface *hw = 1064 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1065 if (!hw) { 1066 LOGE("NULL camera device"); 1067 return BAD_VALUE; 1068 } 1069 LOGD("E camera id %d", hw->getCameraId()); 1070 hw->lockAPI(); 1071 qcamera_api_result_t apiResult; 1072 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms); 1073 if (ret == NO_ERROR) { 1074 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult); 1075 ret = apiResult.status; 1076 } 1077 1078 // Give HWI control to restart (if necessary) after set params 1079 // in single camera mode. In dual-cam mode, this control belongs to muxer. 1080 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 1081 if ((ret == NO_ERROR) && hw->getNeedRestart()) { 1082 LOGD("stopping after param change"); 1083 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL); 1084 if (ret == NO_ERROR) { 1085 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult); 1086 ret = apiResult.status; 1087 } 1088 } 1089 1090 if (ret == NO_ERROR) { 1091 LOGD("committing param change"); 1092 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL); 1093 if (ret == NO_ERROR) { 1094 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult); 1095 ret = apiResult.status; 1096 } 1097 } 1098 1099 if ((ret == NO_ERROR) && hw->getNeedRestart()) { 1100 LOGD("restarting after param change"); 1101 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL); 1102 if (ret == NO_ERROR) { 1103 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult); 1104 ret = apiResult.status; 1105 } 1106 } 1107 } 1108 1109 hw->unlockAPI(); 1110 LOGD("X camera id %d ret %d", hw->getCameraId(), ret); 1111 1112 return ret; 1113 } 1114 1115 /*=========================================================================== 1116 * FUNCTION : stop_after_set_params 1117 * 1118 * DESCRIPTION: stop after a set param call, if necessary 1119 * 1120 * PARAMETERS : 1121 * @device : ptr to camera device struct 1122 * 1123 * RETURN : int32_t type of status 1124 * NO_ERROR -- success 1125 * none-zero failure code 1126 *==========================================================================*/ 1127 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device) 1128 { 1129 ATRACE_CALL(); 1130 int ret = NO_ERROR; 1131 QCamera2HardwareInterface *hw = 1132 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1133 if (!hw) { 1134 LOGE("NULL camera device"); 1135 return BAD_VALUE; 1136 } 1137 LOGD("E camera id %d", hw->getCameraId()); 1138 hw->lockAPI(); 1139 qcamera_api_result_t apiResult; 1140 1141 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1142 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL); 1143 if (ret == NO_ERROR) { 1144 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult); 1145 ret = apiResult.status; 1146 } 1147 } else { 1148 LOGE("is not supposed to be called in single-camera mode"); 1149 ret = INVALID_OPERATION; 1150 } 1151 1152 hw->unlockAPI(); 1153 LOGD("X camera id %d", hw->getCameraId()); 1154 1155 return ret; 1156 } 1157 1158 /*=========================================================================== 1159 * FUNCTION : commit_params 1160 * 1161 * DESCRIPTION: commit after a set param call 1162 * 1163 * PARAMETERS : 1164 * @device : ptr to camera device struct 1165 * 1166 * RETURN : int32_t type of status 1167 * NO_ERROR -- success 1168 * none-zero failure code 1169 *==========================================================================*/ 1170 int QCamera2HardwareInterface::commit_params(struct camera_device *device) 1171 { 1172 ATRACE_CALL(); 1173 int ret = NO_ERROR; 1174 QCamera2HardwareInterface *hw = 1175 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1176 if (!hw) { 1177 LOGE("NULL camera device"); 1178 return BAD_VALUE; 1179 } 1180 LOGD("E camera id %d", hw->getCameraId()); 1181 hw->lockAPI(); 1182 qcamera_api_result_t apiResult; 1183 1184 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1185 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL); 1186 if (ret == NO_ERROR) { 1187 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult); 1188 ret = apiResult.status; 1189 } 1190 } else { 1191 LOGE("is not supposed to be called in single-camera mode"); 1192 ret = INVALID_OPERATION; 1193 } 1194 1195 hw->unlockAPI(); 1196 LOGD("X camera id %d", hw->getCameraId()); 1197 1198 return ret; 1199 } 1200 1201 /*=========================================================================== 1202 * FUNCTION : restart_after_set_params 1203 * 1204 * DESCRIPTION: restart after a set param call, if necessary 1205 * 1206 * PARAMETERS : 1207 * @device : ptr to camera device struct 1208 * 1209 * RETURN : int32_t type of status 1210 * NO_ERROR -- success 1211 * none-zero failure code 1212 *==========================================================================*/ 1213 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device) 1214 { 1215 ATRACE_CALL(); 1216 int ret = NO_ERROR; 1217 QCamera2HardwareInterface *hw = 1218 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1219 if (!hw) { 1220 LOGE("NULL camera device"); 1221 return BAD_VALUE; 1222 } 1223 LOGD("E camera id %d", hw->getCameraId()); 1224 hw->lockAPI(); 1225 qcamera_api_result_t apiResult; 1226 1227 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1228 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL); 1229 if (ret == NO_ERROR) { 1230 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult); 1231 ret = apiResult.status; 1232 } 1233 } else { 1234 LOGE("is not supposed to be called in single-camera mode"); 1235 ret = INVALID_OPERATION; 1236 } 1237 1238 hw->unlockAPI(); 1239 LOGD("X camera id %d", hw->getCameraId()); 1240 return ret; 1241 } 1242 1243 /*=========================================================================== 1244 * FUNCTION : get_parameters 1245 * 1246 * DESCRIPTION: query camera parameters 1247 * 1248 * PARAMETERS : 1249 * @device : ptr to camera device struct 1250 * 1251 * RETURN : packed parameters in a string 1252 *==========================================================================*/ 1253 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device) 1254 { 1255 ATRACE_CALL(); 1256 char *ret = NULL; 1257 QCamera2HardwareInterface *hw = 1258 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1259 if (!hw) { 1260 LOGE("NULL camera device"); 1261 return NULL; 1262 } 1263 LOGD("E camera id %d", hw->getCameraId()); 1264 hw->lockAPI(); 1265 qcamera_api_result_t apiResult; 1266 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL); 1267 if (rc == NO_ERROR) { 1268 hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult); 1269 ret = apiResult.params; 1270 } 1271 hw->unlockAPI(); 1272 LOGD("E camera id %d", hw->getCameraId()); 1273 1274 return ret; 1275 } 1276 1277 /*=========================================================================== 1278 * FUNCTION : put_parameters 1279 * 1280 * DESCRIPTION: return camera parameters string back to HAL 1281 * 1282 * PARAMETERS : 1283 * @device : ptr to camera device struct 1284 * @parm : ptr to parameter string to be returned 1285 * 1286 * RETURN : none 1287 *==========================================================================*/ 1288 void QCamera2HardwareInterface::put_parameters(struct camera_device *device, 1289 char *parm) 1290 { 1291 ATRACE_CALL(); 1292 QCamera2HardwareInterface *hw = 1293 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1294 if (!hw) { 1295 LOGE("NULL camera device"); 1296 return; 1297 } 1298 LOGD("E camera id %d", hw->getCameraId()); 1299 hw->lockAPI(); 1300 qcamera_api_result_t apiResult; 1301 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm); 1302 if (ret == NO_ERROR) { 1303 hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult); 1304 } 1305 hw->unlockAPI(); 1306 LOGD("E camera id %d", hw->getCameraId()); 1307 } 1308 1309 /*=========================================================================== 1310 * FUNCTION : send_command 1311 * 1312 * DESCRIPTION: command to be executed 1313 * 1314 * PARAMETERS : 1315 * @device : ptr to camera device struct 1316 * @cmd : cmd to be executed 1317 * @arg1 : ptr to optional argument1 1318 * @arg2 : ptr to optional argument2 1319 * 1320 * RETURN : int32_t type of status 1321 * NO_ERROR -- success 1322 * none-zero failure code 1323 *==========================================================================*/ 1324 int QCamera2HardwareInterface::send_command(struct camera_device *device, 1325 int32_t cmd, 1326 int32_t arg1, 1327 int32_t arg2) 1328 { 1329 ATRACE_CALL(); 1330 int ret = NO_ERROR; 1331 QCamera2HardwareInterface *hw = 1332 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1333 if (!hw) { 1334 LOGE("NULL camera device"); 1335 return BAD_VALUE; 1336 } 1337 LOGD("E camera id %d", hw->getCameraId()); 1338 1339 qcamera_sm_evt_command_payload_t payload; 1340 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t)); 1341 payload.cmd = cmd; 1342 payload.arg1 = arg1; 1343 payload.arg2 = arg2; 1344 hw->lockAPI(); 1345 qcamera_api_result_t apiResult; 1346 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload); 1347 if (ret == NO_ERROR) { 1348 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult); 1349 ret = apiResult.status; 1350 } 1351 hw->unlockAPI(); 1352 LOGD("E camera id %d", hw->getCameraId()); 1353 1354 return ret; 1355 } 1356 1357 /*=========================================================================== 1358 * FUNCTION : send_command_restart 1359 * 1360 * DESCRIPTION: restart if necessary after a send_command 1361 * 1362 * PARAMETERS : 1363 * @device : ptr to camera device struct 1364 * @cmd : cmd to be executed 1365 * @arg1 : ptr to optional argument1 1366 * @arg2 : ptr to optional argument2 1367 * 1368 * RETURN : int32_t type of status 1369 * NO_ERROR -- success 1370 * none-zero failure code 1371 *==========================================================================*/ 1372 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device, 1373 int32_t cmd, 1374 int32_t arg1, 1375 int32_t arg2) 1376 { 1377 ATRACE_CALL(); 1378 int ret = NO_ERROR; 1379 QCamera2HardwareInterface *hw = 1380 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1381 if (!hw) { 1382 LOGE("NULL camera device"); 1383 return BAD_VALUE; 1384 } 1385 1386 qcamera_sm_evt_command_payload_t payload; 1387 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t)); 1388 payload.cmd = cmd; 1389 payload.arg1 = arg1; 1390 payload.arg2 = arg2; 1391 hw->lockAPI(); 1392 qcamera_api_result_t apiResult; 1393 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload); 1394 if (ret == NO_ERROR) { 1395 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult); 1396 ret = apiResult.status; 1397 } 1398 hw->unlockAPI(); 1399 LOGD("E camera id %d", hw->getCameraId()); 1400 1401 return ret; 1402 } 1403 1404 /*=========================================================================== 1405 * FUNCTION : release 1406 * 1407 * DESCRIPTION: release camera resource 1408 * 1409 * PARAMETERS : 1410 * @device : ptr to camera device struct 1411 * 1412 * RETURN : none 1413 *==========================================================================*/ 1414 void QCamera2HardwareInterface::release(struct camera_device *device) 1415 { 1416 ATRACE_CALL(); 1417 QCamera2HardwareInterface *hw = 1418 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1419 if (!hw) { 1420 LOGE("NULL camera device"); 1421 return; 1422 } 1423 LOGD("E camera id %d", hw->getCameraId()); 1424 hw->lockAPI(); 1425 qcamera_api_result_t apiResult; 1426 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL); 1427 if (ret == NO_ERROR) { 1428 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult); 1429 } 1430 hw->unlockAPI(); 1431 LOGD("E camera id %d", hw->getCameraId()); 1432 } 1433 1434 /*=========================================================================== 1435 * FUNCTION : dump 1436 * 1437 * DESCRIPTION: dump camera status 1438 * 1439 * PARAMETERS : 1440 * @device : ptr to camera device struct 1441 * @fd : fd for status to be dumped to 1442 * 1443 * RETURN : int32_t type of status 1444 * NO_ERROR -- success 1445 * none-zero failure code 1446 *==========================================================================*/ 1447 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd) 1448 { 1449 int ret = NO_ERROR; 1450 1451 //Log level property is read when "adb shell dumpsys media.camera" is 1452 //called so that the log level can be controlled without restarting 1453 //media server 1454 getLogLevel(); 1455 QCamera2HardwareInterface *hw = 1456 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1457 if (!hw) { 1458 LOGE("NULL camera device"); 1459 return BAD_VALUE; 1460 } 1461 LOGD("E camera id %d", hw->getCameraId()); 1462 hw->lockAPI(); 1463 qcamera_api_result_t apiResult; 1464 ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd); 1465 if (ret == NO_ERROR) { 1466 hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult); 1467 ret = apiResult.status; 1468 } 1469 hw->unlockAPI(); 1470 LOGD("E camera id %d", hw->getCameraId()); 1471 1472 return ret; 1473 } 1474 1475 /*=========================================================================== 1476 * FUNCTION : close_camera_device 1477 * 1478 * DESCRIPTION: close camera device 1479 * 1480 * PARAMETERS : 1481 * @device : ptr to camera device struct 1482 * 1483 * RETURN : int32_t type of status 1484 * NO_ERROR -- success 1485 * none-zero failure code 1486 *==========================================================================*/ 1487 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev) 1488 { 1489 KPI_ATRACE_CALL(); 1490 int ret = NO_ERROR; 1491 1492 QCamera2HardwareInterface *hw = 1493 reinterpret_cast<QCamera2HardwareInterface *>( 1494 reinterpret_cast<camera_device_t *>(hw_dev)->priv); 1495 if (!hw) { 1496 LOGE("NULL camera device"); 1497 return BAD_VALUE; 1498 } 1499 LOGI("[KPI Perf]: E camera id %d", hw->getCameraId()); 1500 delete hw; 1501 LOGI("[KPI Perf]: X"); 1502 return ret; 1503 } 1504 1505 /*=========================================================================== 1506 * FUNCTION : register_face_image 1507 * 1508 * DESCRIPTION: register a face image into imaging lib for face authenticatio/ 1509 * face recognition 1510 * 1511 * PARAMETERS : 1512 * @device : ptr to camera device struct 1513 * @img_ptr : ptr to image buffer 1514 * @config : ptr to config about input image, i.e., format, dimension, and etc. 1515 * 1516 * RETURN : >=0 unique ID of face registerd. 1517 * <0 failure. 1518 *==========================================================================*/ 1519 int QCamera2HardwareInterface::register_face_image(struct camera_device *device, 1520 void *img_ptr, 1521 cam_pp_offline_src_config_t *config) 1522 { 1523 ATRACE_CALL(); 1524 int ret = NO_ERROR; 1525 QCamera2HardwareInterface *hw = 1526 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1527 if (!hw) { 1528 LOGE("NULL camera device"); 1529 return BAD_VALUE; 1530 } 1531 LOGD("E camera id %d", hw->getCameraId()); 1532 qcamera_sm_evt_reg_face_payload_t payload; 1533 memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t)); 1534 payload.img_ptr = img_ptr; 1535 payload.config = config; 1536 hw->lockAPI(); 1537 qcamera_api_result_t apiResult; 1538 ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload); 1539 if (ret == NO_ERROR) { 1540 hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult); 1541 ret = apiResult.handle; 1542 } 1543 hw->unlockAPI(); 1544 LOGD("E camera id %d", hw->getCameraId()); 1545 1546 return ret; 1547 } 1548 1549 /*=========================================================================== 1550 * FUNCTION : prepare_snapshot 1551 * 1552 * DESCRIPTION: prepares hardware for snapshot 1553 * 1554 * PARAMETERS : 1555 * @device : ptr to camera device struct 1556 * 1557 * RETURN : int32_t type of status 1558 * NO_ERROR -- success 1559 * none-zero failure code 1560 *==========================================================================*/ 1561 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device) 1562 { 1563 ATRACE_CALL(); 1564 int ret = NO_ERROR; 1565 QCamera2HardwareInterface *hw = 1566 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1567 if (!hw) { 1568 LOGE("NULL camera device"); 1569 return BAD_VALUE; 1570 } 1571 if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) { 1572 // For longshot mode, we prepare snapshot only once 1573 LOGH("prepare snapshot only once "); 1574 return NO_ERROR; 1575 } 1576 LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d", 1577 hw->getCameraId()); 1578 hw->lockAPI(); 1579 qcamera_api_result_t apiResult; 1580 1581 /* Prepare snapshot in case LED needs to be flashed */ 1582 if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) { 1583 /* Prepare snapshot in case LED needs to be flashed */ 1584 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 1585 if (ret == NO_ERROR) { 1586 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 1587 ret = apiResult.status; 1588 } 1589 hw->mPrepSnapRun = true; 1590 } 1591 hw->unlockAPI(); 1592 LOGH("[KPI Perf]: X, ret: %d", ret); 1593 return ret; 1594 } 1595 1596 /*=========================================================================== 1597 * FUNCTION : QCamera2HardwareInterface 1598 * 1599 * DESCRIPTION: constructor of QCamera2HardwareInterface 1600 * 1601 * PARAMETERS : 1602 * @cameraId : camera ID 1603 * 1604 * RETURN : none 1605 *==========================================================================*/ 1606 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId) 1607 : mCameraId(cameraId), 1608 mCameraHandle(NULL), 1609 mCameraOpened(false), 1610 mDualCamera(false), 1611 m_bRelCamCalibValid(false), 1612 mPreviewWindow(NULL), 1613 mMsgEnabled(0), 1614 mStoreMetaDataInFrame(0), 1615 mJpegCb(NULL), 1616 mCallbackCookie(NULL), 1617 mJpegCallbackCookie(NULL), 1618 m_bMpoEnabled(TRUE), 1619 m_stateMachine(this), 1620 m_smThreadActive(true), 1621 m_postprocessor(this), 1622 m_thermalAdapter(QCameraThermalAdapter::getInstance()), 1623 m_cbNotifier(this), 1624 m_bPreviewStarted(false), 1625 m_bRecordStarted(false), 1626 m_currentFocusState(CAM_AF_STATE_INACTIVE), 1627 mDumpFrmCnt(0U), 1628 mDumpSkipCnt(0U), 1629 mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT), 1630 mActiveAF(false), 1631 m_HDRSceneEnabled(false), 1632 mLongshotEnabled(false), 1633 mLiveSnapshotThread(0), 1634 mIntPicThread(0), 1635 mFlashNeeded(false), 1636 mFlashConfigured(false), 1637 mDeviceRotation(0U), 1638 mCaptureRotation(0U), 1639 mJpegExifRotation(0U), 1640 mUseJpegExifRotation(false), 1641 mIs3ALocked(false), 1642 mPrepSnapRun(false), 1643 mZoomLevel(0), 1644 mPreviewRestartNeeded(false), 1645 mVFrameCount(0), 1646 mVLastFrameCount(0), 1647 mVLastFpsTime(0), 1648 mVFps(0), 1649 mPFrameCount(0), 1650 mPLastFrameCount(0), 1651 mPLastFpsTime(0), 1652 mPFps(0), 1653 mLowLightConfigured(false), 1654 mInstantAecFrameCount(0), 1655 m_bIntJpegEvtPending(false), 1656 m_bIntRawEvtPending(false), 1657 mReprocJob(0), 1658 mJpegJob(0), 1659 mMetadataAllocJob(0), 1660 mInitPProcJob(0), 1661 mParamAllocJob(0), 1662 mParamInitJob(0), 1663 mOutputCount(0), 1664 mInputCount(0), 1665 mAdvancedCaptureConfigured(false), 1666 mHDRBracketingEnabled(false), 1667 mNumPreviewFaces(-1), 1668 mJpegClientHandle(0), 1669 mJpegHandleOwner(false), 1670 mMetadataMem(NULL), 1671 mCACDoneReceived(false), 1672 m_bNeedRestart(false), 1673 mBootToMonoTimestampOffset(0), 1674 bDepthAFCallbacks(true) 1675 { 1676 #ifdef TARGET_TS_MAKEUP 1677 memset(&mFaceRect, -1, sizeof(mFaceRect)); 1678 #endif 1679 getLogLevel(); 1680 ATRACE_CALL(); 1681 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG; 1682 mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0); 1683 mCameraDevice.common.close = close_camera_device; 1684 mCameraDevice.ops = &mCameraOps; 1685 mCameraDevice.priv = this; 1686 1687 mDualCamera = is_dual_camera_by_idx(cameraId); 1688 1689 pthread_mutex_init(&m_lock, NULL); 1690 pthread_cond_init(&m_cond, NULL); 1691 1692 m_apiResultList = NULL; 1693 1694 pthread_mutex_init(&m_evtLock, NULL); 1695 pthread_cond_init(&m_evtCond, NULL); 1696 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 1697 1698 1699 pthread_mutex_init(&m_int_lock, NULL); 1700 pthread_cond_init(&m_int_cond, NULL); 1701 1702 memset(m_channels, 0, sizeof(m_channels)); 1703 1704 memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t)); 1705 1706 memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH); 1707 1708 memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs)); 1709 memset(&mJpegMetadata, 0, sizeof(mJpegMetadata)); 1710 memset(&mJpegHandle, 0, sizeof(mJpegHandle)); 1711 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle)); 1712 1713 mDeferredWorkThread.launch(deferredWorkRoutine, this); 1714 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE); 1715 m_perfLock.lock_init(); 1716 1717 pthread_mutex_init(&mGrallocLock, NULL); 1718 mEnqueuedBuffers = 0; 1719 mFrameSkipStart = 0; 1720 mFrameSkipEnd = 0; 1721 mLastPreviewFrameID = 0; 1722 1723 //Load and read GPU library. 1724 lib_surface_utils = NULL; 1725 LINK_get_surface_pixel_alignment = NULL; 1726 mSurfaceStridePadding = CAM_PAD_TO_32; 1727 lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW); 1728 if (lib_surface_utils) { 1729 *(void **)&LINK_get_surface_pixel_alignment = 1730 dlsym(lib_surface_utils, "get_gpu_pixel_alignment"); 1731 if (LINK_get_surface_pixel_alignment) { 1732 mSurfaceStridePadding = LINK_get_surface_pixel_alignment(); 1733 } 1734 dlclose(lib_surface_utils); 1735 } 1736 prev_zoomLevel = 0; 1737 } 1738 1739 /*=========================================================================== 1740 * FUNCTION : ~QCamera2HardwareInterface 1741 * 1742 * DESCRIPTION: destructor of QCamera2HardwareInterface 1743 * 1744 * PARAMETERS : none 1745 * 1746 * RETURN : none 1747 *==========================================================================*/ 1748 QCamera2HardwareInterface::~QCamera2HardwareInterface() 1749 { 1750 LOGH("E"); 1751 1752 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE); 1753 mDeferredWorkThread.exit(); 1754 1755 if (mMetadataMem != NULL) { 1756 delete mMetadataMem; 1757 mMetadataMem = NULL; 1758 } 1759 1760 m_perfLock.lock_acq(); 1761 lockAPI(); 1762 m_smThreadActive = false; 1763 unlockAPI(); 1764 m_stateMachine.releaseThread(); 1765 closeCamera(); 1766 m_perfLock.lock_rel(); 1767 m_perfLock.lock_deinit(); 1768 pthread_mutex_destroy(&m_lock); 1769 pthread_cond_destroy(&m_cond); 1770 pthread_mutex_destroy(&m_evtLock); 1771 pthread_cond_destroy(&m_evtCond); 1772 pthread_mutex_destroy(&m_int_lock); 1773 pthread_cond_destroy(&m_int_cond); 1774 pthread_mutex_destroy(&mGrallocLock); 1775 LOGH("X"); 1776 } 1777 1778 /*=========================================================================== 1779 * FUNCTION : deferPPInit 1780 * 1781 * DESCRIPTION: Queue postproc init task to deferred thread 1782 * 1783 * PARAMETERS : none 1784 * 1785 * RETURN : uint32_t job id of pproc init job 1786 * 0 -- failure 1787 *==========================================================================*/ 1788 uint32_t QCamera2HardwareInterface::deferPPInit() 1789 { 1790 // init pproc 1791 DeferWorkArgs args; 1792 DeferPProcInitArgs pprocInitArgs; 1793 1794 memset(&args, 0, sizeof(DeferWorkArgs)); 1795 memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs)); 1796 1797 pprocInitArgs.jpeg_cb = jpegEvtHandle; 1798 pprocInitArgs.user_data = this; 1799 args.pprocInitArgs = pprocInitArgs; 1800 1801 return queueDeferredWork(CMD_DEF_PPROC_INIT, 1802 args); 1803 } 1804 1805 /*=========================================================================== 1806 * FUNCTION : openCamera 1807 * 1808 * DESCRIPTION: open camera 1809 * 1810 * PARAMETERS : 1811 * @hw_device : double ptr for camera device struct 1812 * 1813 * RETURN : int32_t type of status 1814 * NO_ERROR -- success 1815 * none-zero failure code 1816 *==========================================================================*/ 1817 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device) 1818 { 1819 KPI_ATRACE_CALL(); 1820 int rc = NO_ERROR; 1821 if (mCameraOpened) { 1822 *hw_device = NULL; 1823 LOGE("Permission Denied"); 1824 return PERMISSION_DENIED; 1825 } 1826 LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d", 1827 mCameraId); 1828 m_perfLock.lock_acq_timed(CAMERA_OPEN_PERF_TIME_OUT); 1829 rc = openCamera(); 1830 if (rc == NO_ERROR){ 1831 *hw_device = &mCameraDevice.common; 1832 if (m_thermalAdapter.init(this) != 0) { 1833 LOGW("Init thermal adapter failed"); 1834 } 1835 } 1836 else 1837 *hw_device = NULL; 1838 1839 LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d", 1840 mCameraId, rc); 1841 1842 return rc; 1843 } 1844 1845 /*=========================================================================== 1846 * FUNCTION : openCamera 1847 * 1848 * DESCRIPTION: open camera 1849 * 1850 * PARAMETERS : none 1851 * 1852 * RETURN : int32_t type of status 1853 * NO_ERROR -- success 1854 * none-zero failure code 1855 *==========================================================================*/ 1856 int QCamera2HardwareInterface::openCamera() 1857 { 1858 int32_t rc = NO_ERROR; 1859 char value[PROPERTY_VALUE_MAX]; 1860 1861 if (mCameraHandle) { 1862 LOGE("Failure: Camera already opened"); 1863 return ALREADY_EXISTS; 1864 } 1865 1866 rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId); 1867 if (rc < 0) { 1868 LOGE("Failed to reserve flash for camera id: %d", 1869 mCameraId); 1870 return UNKNOWN_ERROR; 1871 } 1872 1873 // alloc param buffer 1874 DeferWorkArgs args; 1875 memset(&args, 0, sizeof(args)); 1876 mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args); 1877 if (mParamAllocJob == 0) { 1878 LOGE("Failed queueing PARAM_ALLOC job"); 1879 return -ENOMEM; 1880 } 1881 1882 if (gCamCapability[mCameraId] != NULL) { 1883 // allocate metadata buffers 1884 DeferWorkArgs args; 1885 DeferMetadataAllocArgs metadataAllocArgs; 1886 1887 memset(&args, 0, sizeof(args)); 1888 memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs)); 1889 1890 uint32_t padding = 1891 gCamCapability[mCameraId]->padding_info.plane_padding; 1892 metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t), 1893 padding); 1894 metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS; 1895 args.metadataAllocArgs = metadataAllocArgs; 1896 1897 mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args); 1898 if (mMetadataAllocJob == 0) { 1899 LOGE("Failed to allocate metadata buffer"); 1900 rc = -ENOMEM; 1901 goto error_exit1; 1902 } 1903 1904 rc = camera_open((uint8_t)mCameraId, &mCameraHandle); 1905 if (rc) { 1906 LOGE("camera_open failed. rc = %d, mCameraHandle = %p", 1907 rc, mCameraHandle); 1908 goto error_exit2; 1909 } 1910 1911 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, 1912 camEvtHandle, 1913 (void *) this); 1914 } else { 1915 LOGH("Capabilities not inited, initializing now."); 1916 1917 rc = camera_open((uint8_t)mCameraId, &mCameraHandle); 1918 if (rc) { 1919 LOGE("camera_open failed. rc = %d, mCameraHandle = %p", 1920 rc, mCameraHandle); 1921 goto error_exit2; 1922 } 1923 1924 if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) { 1925 LOGE("initCapabilities failed."); 1926 rc = UNKNOWN_ERROR; 1927 goto error_exit3; 1928 } 1929 1930 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, 1931 camEvtHandle, 1932 (void *) this); 1933 } 1934 1935 mActiveCamera = MM_CAMERA_TYPE_MAIN; 1936 if (isDualCamera()) { 1937 mActiveCamera |= MM_CAMERA_TYPE_AUX; 1938 } 1939 1940 // Init params in the background 1941 // 1. It's safe to queue init job, even if alloc job is not yet complete. 1942 // It will be queued to the same thread, so the alloc is guaranteed to 1943 // finish first. 1944 // 2. However, it is not safe to begin param init until after camera is 1945 // open. That is why we wait until after camera open completes to schedule 1946 // this task. 1947 memset(&args, 0, sizeof(args)); 1948 mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args); 1949 if (mParamInitJob == 0) { 1950 LOGE("Failed queuing PARAM_INIT job"); 1951 rc = -ENOMEM; 1952 goto error_exit3; 1953 } 1954 1955 mCameraOpened = true; 1956 1957 //Notify display HAL that a camera session is active. 1958 //But avoid calling the same during bootup because camera service might open/close 1959 //cameras at boot time during its initialization and display service will also internally 1960 //wait for camera service to initialize first while calling this display API, resulting in a 1961 //deadlock situation. Since boot time camera open/close calls are made only to fetch 1962 //capabilities, no need of this display bw optimization. 1963 //Use "service.bootanim.exit" property to know boot status. 1964 property_get("service.bootanim.exit", value, "0"); 1965 if (atoi(value) == 1) { 1966 pthread_mutex_lock(&gCamLock); 1967 if (gNumCameraSessions++ == 0) { 1968 setCameraLaunchStatus(true); 1969 } 1970 pthread_mutex_unlock(&gCamLock); 1971 } 1972 1973 // Setprop to decide the time source (whether boottime or monotonic). 1974 // By default, use monotonic time. 1975 property_get("persist.camera.time.monotonic", value, "1"); 1976 mBootToMonoTimestampOffset = 0; 1977 if (atoi(value) == 1) { 1978 // if monotonic is set, then need to use time in monotonic. 1979 // So, Measure the clock offset between BOOTTIME and MONOTONIC 1980 // The clock domain source for ISP is BOOTTIME and 1981 // for Video/display is MONOTONIC 1982 // The below offset is used to convert from clock domain of other subsystem 1983 // (video/hardware composer) to that of camera. Assumption is that this 1984 // offset won't change during the life cycle of the camera device. In other 1985 // words, camera device shouldn't be open during CPU suspend. 1986 mBootToMonoTimestampOffset = getBootToMonoTimeOffset(); 1987 } 1988 LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset); 1989 1990 memset(value, 0, sizeof(value)); 1991 property_get("persist.camera.depth.focus.cb", value, "1"); 1992 bDepthAFCallbacks = atoi(value); 1993 1994 return NO_ERROR; 1995 1996 error_exit3: 1997 if(mJpegClientHandle) { 1998 deinitJpegHandle(); 1999 } 2000 mCameraHandle->ops->close_camera(mCameraHandle->camera_handle); 2001 mCameraHandle = NULL; 2002 error_exit2: 2003 waitDeferredWork(mMetadataAllocJob); 2004 error_exit1: 2005 waitDeferredWork(mParamAllocJob); 2006 return rc; 2007 2008 } 2009 2010 /*=========================================================================== 2011 * FUNCTION : bundleRelatedCameras 2012 * 2013 * DESCRIPTION: bundle cameras to enable syncing of cameras 2014 * 2015 * PARAMETERS : 2016 * @sync :indicates whether syncing is On or Off 2017 * @sessionid :session id for other camera session 2018 * 2019 * RETURN : int32_t type of status 2020 * NO_ERROR -- success 2021 * none-zero failure code 2022 *==========================================================================*/ 2023 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn, 2024 uint32_t sessionid) 2025 { 2026 LOGD("bundleRelatedCameras sync %d with sessionid %d", 2027 syncOn, sessionid); 2028 2029 int32_t rc = mParameters.bundleRelatedCameras(syncOn, sessionid); 2030 if (rc != NO_ERROR) { 2031 LOGE("bundleRelatedCameras failed %d", rc); 2032 return rc; 2033 } 2034 return rc; 2035 } 2036 2037 /*=========================================================================== 2038 * FUNCTION : getCameraSessionId 2039 * 2040 * DESCRIPTION: gets the backend session Id of this HWI instance 2041 * 2042 * PARAMETERS : 2043 * @sessionid : pointer to the output session id 2044 * 2045 * RETURN : int32_t type of status 2046 * NO_ERROR -- success 2047 * none-zero failure code 2048 *==========================================================================*/ 2049 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id) 2050 { 2051 int32_t rc = NO_ERROR; 2052 2053 if(session_id != NULL) { 2054 rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle, 2055 session_id); 2056 LOGD("Getting Camera Session Id %d", *session_id); 2057 } else { 2058 LOGE("Session Id is Null"); 2059 return UNKNOWN_ERROR; 2060 } 2061 return rc; 2062 } 2063 2064 /*=========================================================================== 2065 * FUNCTION : isFrameSyncEnabled 2066 * 2067 * DESCRIPTION: returns whether frame sync is enabled 2068 * 2069 * PARAMETERS : none 2070 * 2071 * RETURN : bool indicating whether frame sync is enabled 2072 *==========================================================================*/ 2073 bool QCamera2HardwareInterface::isFrameSyncEnabled(void) 2074 { 2075 return mParameters.isFrameSyncEnabled(); 2076 } 2077 2078 /*=========================================================================== 2079 * FUNCTION : setFrameSyncEnabled 2080 * 2081 * DESCRIPTION: sets whether frame sync is enabled 2082 * 2083 * PARAMETERS : 2084 * @enable : flag whether to enable or disable frame sync 2085 * 2086 * RETURN : int32_t type of status 2087 * NO_ERROR -- success 2088 * none-zero failure code 2089 *==========================================================================*/ 2090 int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable) 2091 { 2092 return mParameters.setFrameSyncEnabled(enable); 2093 } 2094 2095 /*=========================================================================== 2096 * FUNCTION : getRelatedCamSyncInfo 2097 * 2098 * DESCRIPTION:returns the related cam sync info for this HWI instance 2099 * 2100 * PARAMETERS :none 2101 * 2102 * RETURN : const pointer to cam_sync_related_sensors_event_info_t 2103 *==========================================================================*/ 2104 const cam_sync_related_sensors_event_info_t* 2105 QCamera2HardwareInterface::getRelatedCamSyncInfo(void) 2106 { 2107 return mParameters.getRelatedCamSyncInfo(); 2108 } 2109 2110 /*=========================================================================== 2111 * FUNCTION : setRelatedCamSyncInfo 2112 * 2113 * DESCRIPTION:sets the related cam sync info for this HWI instance 2114 * 2115 * PARAMETERS : 2116 * @info : ptr to related cam info parameters 2117 * 2118 * RETURN : int32_t type of status 2119 * NO_ERROR -- success 2120 * none-zero failure code 2121 *==========================================================================*/ 2122 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo( 2123 cam_sync_related_sensors_event_info_t* info) 2124 { 2125 if(info) { 2126 return mParameters.setRelatedCamSyncInfo(info); 2127 } else { 2128 return BAD_TYPE; 2129 } 2130 } 2131 2132 /*=========================================================================== 2133 * FUNCTION : getMpoComposition 2134 * 2135 * DESCRIPTION:function to retrieve whether Mpo composition should be enabled 2136 * or not 2137 * 2138 * PARAMETERS :none 2139 * 2140 * RETURN : bool indicates whether mpo composition is enabled or not 2141 *==========================================================================*/ 2142 bool QCamera2HardwareInterface::getMpoComposition(void) 2143 { 2144 LOGH("MpoComposition:%d ", m_bMpoEnabled); 2145 return m_bMpoEnabled; 2146 } 2147 2148 /*=========================================================================== 2149 * FUNCTION : setMpoComposition 2150 * 2151 * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance 2152 * 2153 * PARAMETERS : 2154 * @enable : indicates whether Mpo composition enabled or not 2155 * 2156 * RETURN : int32_t type of status 2157 * NO_ERROR -- success 2158 * none-zero failure code 2159 *==========================================================================*/ 2160 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable) 2161 { 2162 // By default set Mpo composition to disable 2163 m_bMpoEnabled = false; 2164 2165 // Enable Mpo composition only if 2166 // 1) frame sync is ON between two cameras and 2167 // 2) any advanced features are not enabled (AOST features) and 2168 // 3) not in recording mode (for liveshot case) 2169 // 4) flash is not needed 2170 if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) && 2171 !mParameters.isAdvCamFeaturesEnabled() && 2172 !mParameters.getRecordingHintValue() && 2173 !mFlashNeeded && 2174 !isLongshotEnabled()) { 2175 m_bMpoEnabled = enable; 2176 LOGH("MpoComposition:%d ", m_bMpoEnabled); 2177 return NO_ERROR; 2178 } else { 2179 return BAD_TYPE; 2180 } 2181 } 2182 2183 /*=========================================================================== 2184 * FUNCTION : getRecordingHintValue 2185 * 2186 * DESCRIPTION:function to retrieve recording hint value 2187 * 2188 * PARAMETERS :none 2189 * 2190 * RETURN : bool indicates whether recording hint is enabled or not 2191 *==========================================================================*/ 2192 bool QCamera2HardwareInterface::getRecordingHintValue(void) 2193 { 2194 return mParameters.getRecordingHintValue(); 2195 } 2196 2197 /*=========================================================================== 2198 * FUNCTION : setRecordingHintValue 2199 * 2200 * DESCRIPTION:set recording hint value 2201 * 2202 * PARAMETERS : 2203 * @enable : video hint value 2204 * 2205 * RETURN : int32_t type of status 2206 * NO_ERROR -- success 2207 * none-zero failure code 2208 *==========================================================================*/ 2209 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value) 2210 { 2211 return mParameters.updateRecordingHintValue(value); 2212 } 2213 2214 /*=========================================================================== 2215 * FUNCTION : closeCamera 2216 * 2217 * DESCRIPTION: close camera 2218 * 2219 * PARAMETERS : none 2220 * 2221 * RETURN : int32_t type of status 2222 * NO_ERROR -- success 2223 * none-zero failure code 2224 *==========================================================================*/ 2225 int QCamera2HardwareInterface::closeCamera() 2226 { 2227 int rc = NO_ERROR; 2228 int i; 2229 char value[PROPERTY_VALUE_MAX]; 2230 LOGI("E"); 2231 if (!mCameraOpened) { 2232 return NO_ERROR; 2233 } 2234 LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d", 2235 mCameraId); 2236 2237 // set open flag to false 2238 mCameraOpened = false; 2239 2240 // Reset Stream config info 2241 mParameters.setStreamConfigure(false, false, true); 2242 2243 // deinit Parameters 2244 mParameters.deinit(); 2245 2246 // exit notifier 2247 m_cbNotifier.exit(); 2248 2249 // stop and deinit postprocessor 2250 waitDeferredWork(mReprocJob); 2251 // Close the JPEG session 2252 waitDeferredWork(mJpegJob); 2253 m_postprocessor.stop(); 2254 deinitJpegHandle(); 2255 m_postprocessor.deinit(); 2256 mInitPProcJob = 0; // reset job id, so pproc can be reinited later 2257 2258 m_thermalAdapter.deinit(); 2259 2260 // delete all channels if not already deleted 2261 for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 2262 if (m_channels[i] != NULL) { 2263 m_channels[i]->stop(); 2264 delete m_channels[i]; 2265 m_channels[i] = NULL; 2266 } 2267 } 2268 2269 //free all pending api results here 2270 if(m_apiResultList != NULL) { 2271 api_result_list *apiResultList = m_apiResultList; 2272 api_result_list *apiResultListNext; 2273 while (apiResultList != NULL) { 2274 apiResultListNext = apiResultList->next; 2275 free(apiResultList); 2276 apiResultList = apiResultListNext; 2277 } 2278 } 2279 2280 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle); 2281 mCameraHandle = NULL; 2282 2283 //Notify display HAL that there is no active camera session 2284 //but avoid calling the same during bootup. Refer to openCamera 2285 //for more details. 2286 property_get("service.bootanim.exit", value, "0"); 2287 if (atoi(value) == 1) { 2288 pthread_mutex_lock(&gCamLock); 2289 if (--gNumCameraSessions == 0) { 2290 setCameraLaunchStatus(false); 2291 } 2292 pthread_mutex_unlock(&gCamLock); 2293 } 2294 2295 if (mExifParams.debug_params) { 2296 free(mExifParams.debug_params); 2297 mExifParams.debug_params = NULL; 2298 } 2299 2300 if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) { 2301 LOGD("Failed to release flash for camera id: %d", 2302 mCameraId); 2303 } 2304 2305 LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d", 2306 mCameraId, rc); 2307 2308 return rc; 2309 } 2310 2311 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX ) 2312 2313 2314 /*=========================================================================== 2315 * FUNCTION : getCapabilities 2316 * 2317 * DESCRIPTION: query camera capability from back-end 2318 * 2319 * PARAMETERS : 2320 * @ops : mm-interface ops structure 2321 * @cam_handle : camera handle for which we need capability 2322 * 2323 * RETURN : ptr type of capability structure 2324 * capability for success 2325 * NULL for failure 2326 *==========================================================================*/ 2327 cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops, 2328 uint32_t cam_handle) 2329 { 2330 int rc = NO_ERROR; 2331 QCameraHeapMemory *capabilityHeap = NULL; 2332 cam_capability_t *cap_ptr = NULL; 2333 2334 if (ops == NULL) { 2335 LOGE("Invalid arguments"); 2336 return NULL; 2337 } 2338 2339 capabilityHeap = new QCameraHeapMemory(1); 2340 if (capabilityHeap == NULL) { 2341 LOGE("creation of capabilityHeap failed"); 2342 return NULL; 2343 } 2344 2345 /* Allocate memory for capability buffer */ 2346 rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE); 2347 if(rc != OK) { 2348 LOGE("No memory for cappability"); 2349 goto allocate_failed; 2350 } 2351 2352 /* Map memory for capability buffer */ 2353 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t)); 2354 2355 cam_buf_map_type_list bufMapList; 2356 rc = QCameraBufferMaps::makeSingletonBufMapList( 2357 CAM_MAPPING_BUF_TYPE_CAPABILITY, 2358 0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/, 2359 0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t), 2360 bufMapList, capabilityHeap->getPtr(0)); 2361 2362 if (rc == NO_ERROR) { 2363 rc = ops->map_bufs(cam_handle, 2364 &bufMapList); 2365 } 2366 if(rc < 0) { 2367 LOGE("failed to map capability buffer"); 2368 goto map_failed; 2369 } 2370 2371 /* Query Capability */ 2372 rc = ops->query_capability(cam_handle); 2373 if(rc < 0) { 2374 LOGE("failed to query capability"); 2375 rc = FAILED_TRANSACTION; 2376 goto query_failed; 2377 } 2378 2379 cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t)); 2380 if (cap_ptr == NULL) { 2381 LOGE("out of memory"); 2382 rc = NO_MEMORY; 2383 goto query_failed; 2384 } 2385 2386 memset(cap_ptr, 0, sizeof(cam_capability_t)); 2387 memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t)); 2388 2389 int index; 2390 for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) { 2391 cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index]; 2392 p_analysis_info->analysis_padding_info.offset_info.offset_x = 0; 2393 p_analysis_info->analysis_padding_info.offset_info.offset_y = 0; 2394 } 2395 2396 query_failed: 2397 ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY); 2398 map_failed: 2399 capabilityHeap->deallocate(); 2400 allocate_failed: 2401 delete capabilityHeap; 2402 2403 if (rc != NO_ERROR) { 2404 return NULL; 2405 } else { 2406 return cap_ptr; 2407 } 2408 } 2409 2410 /*=========================================================================== 2411 * FUNCTION : initCapabilities 2412 * 2413 * DESCRIPTION: initialize camera capabilities in static data struct 2414 * 2415 * PARAMETERS : 2416 * @cameraId : camera Id 2417 * 2418 * RETURN : int32_t type of status 2419 * NO_ERROR -- success 2420 * none-zero failure code 2421 *==========================================================================*/ 2422 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId, 2423 mm_camera_vtbl_t *cameraHandle) 2424 { 2425 ATRACE_CALL(); 2426 int rc = 0; 2427 uint32_t handle = 0; 2428 2429 rc = camera_open((uint8_t)cameraId, &cameraHandle); 2430 if (rc) { 2431 LOGE("camera_open failed. rc = %d", rc); 2432 goto open_failed; 2433 } 2434 if (!cameraHandle) { 2435 LOGE("camera_open failed. cameraHandle = %p", cameraHandle); 2436 goto open_failed; 2437 } 2438 2439 handle = get_main_camera_handle(cameraHandle->camera_handle); 2440 gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle); 2441 if (gCamCapability[cameraId] == NULL) { 2442 rc = FAILED_TRANSACTION; 2443 goto failed_op; 2444 } 2445 2446 if (is_dual_camera_by_idx(cameraId)) { 2447 handle = get_aux_camera_handle(cameraHandle->camera_handle); 2448 gCamCapability[cameraId]->aux_cam_cap = 2449 getCapabilities(cameraHandle->ops, handle); 2450 if (gCamCapability[cameraId]->aux_cam_cap == NULL) { 2451 rc = FAILED_TRANSACTION; 2452 free(gCamCapability[cameraId]); 2453 goto failed_op; 2454 } 2455 } 2456 failed_op: 2457 cameraHandle->ops->close_camera(cameraHandle->camera_handle); 2458 cameraHandle = NULL; 2459 open_failed: 2460 return rc; 2461 } 2462 2463 /*=========================================================================== 2464 * FUNCTION : getCapabilities 2465 * 2466 * DESCRIPTION: query camera capabilities 2467 * 2468 * PARAMETERS : 2469 * @cameraId : camera Id 2470 * @info : camera info struct to be filled in with camera capabilities 2471 * 2472 * RETURN : int type of status 2473 * NO_ERROR -- success 2474 * none-zero failure code 2475 *==========================================================================*/ 2476 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId, 2477 struct camera_info *info, cam_sync_type_t *p_cam_type) 2478 { 2479 ATRACE_CALL(); 2480 int rc = NO_ERROR; 2481 struct camera_info *p_info = NULL; 2482 pthread_mutex_lock(&gCamLock); 2483 p_info = get_cam_info(cameraId, p_cam_type); 2484 p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0; 2485 p_info->static_camera_characteristics = NULL; 2486 memcpy(info, p_info, sizeof (struct camera_info)); 2487 pthread_mutex_unlock(&gCamLock); 2488 return rc; 2489 } 2490 2491 /*=========================================================================== 2492 * FUNCTION : getCamHalCapabilities 2493 * 2494 * DESCRIPTION: get the HAL capabilities structure 2495 * 2496 * PARAMETERS : 2497 * @cameraId : camera Id 2498 * 2499 * RETURN : capability structure of respective camera 2500 * 2501 *==========================================================================*/ 2502 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities() 2503 { 2504 return gCamCapability[mCameraId]; 2505 } 2506 2507 /*=========================================================================== 2508 * FUNCTION : getBufNumForAux 2509 * 2510 * DESCRIPTION: return number of stream buffers needed for aux camera given stream type 2511 * 2512 * PARAMETERS : 2513 * @stream_type : type of stream 2514 * 2515 * RETURN : number of buffers needed 2516 * NOTE : Based on the use cases and auxillary camera type, 2517 we can decide buffer count 2518 *==========================================================================*/ 2519 uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type) 2520 { 2521 if (!isDualCamera()) { 2522 return 0; 2523 } 2524 2525 uint8_t bufferCnt = 1; 2526 switch (stream_type) { 2527 case CAM_STREAM_TYPE_PREVIEW: 2528 case CAM_STREAM_TYPE_VIDEO: 2529 case CAM_STREAM_TYPE_SNAPSHOT: 2530 case CAM_STREAM_TYPE_METADATA: 2531 case CAM_STREAM_TYPE_CALLBACK: 2532 case CAM_STREAM_TYPE_ANALYSIS: 2533 case CAM_STREAM_TYPE_POSTVIEW: 2534 case CAM_STREAM_TYPE_RAW: 2535 case CAM_STREAM_TYPE_OFFLINE_PROC: 2536 case CAM_STREAM_TYPE_DEFAULT: 2537 case CAM_STREAM_TYPE_MAX: 2538 //For wide & tele, we use same buffer count premary and aux streams. 2539 bufferCnt = getBufNumRequired(stream_type); 2540 break; 2541 default: 2542 break; 2543 } 2544 LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt); 2545 return bufferCnt; 2546 } 2547 2548 /*=========================================================================== 2549 * FUNCTION : getBufNumRequired 2550 * 2551 * DESCRIPTION: return number of stream buffers needed for given stream type 2552 * 2553 * PARAMETERS : 2554 * @stream_type : type of stream 2555 * 2556 * RETURN : number of buffers needed 2557 *==========================================================================*/ 2558 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type) 2559 { 2560 int bufferCnt = 0; 2561 int minCaptureBuffers = mParameters.getNumOfSnapshots(); 2562 char value[PROPERTY_VALUE_MAX]; 2563 bool raw_yuv = false; 2564 int persist_cnt = 0; 2565 int minPrevFps, maxPrevFps; 2566 2567 int zslQBuffers = mParameters.getZSLQueueDepth(); 2568 2569 int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() + 2570 CAMERA_MIN_JPEG_ENCODING_BUFFERS; 2571 2572 int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() + 2573 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2574 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2575 mParameters.getNumOfExtraBuffersForImageProc() + 2576 EXTRA_ZSL_PREVIEW_STREAM_BUF; 2577 2578 int minUndequeCount = 0; 2579 if (!isNoDisplayMode()) { 2580 if(mPreviewWindow != NULL) { 2581 if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount) 2582 != 0) { 2583 LOGW("get_min_undequeued_buffer_count failed"); 2584 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined 2585 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS; 2586 minUndequeCount = MIN_UNDEQUEUED_BUFFERS; 2587 } 2588 } else { 2589 //preview window might not be set at this point. So, query directly 2590 //from BufferQueue implementation of gralloc buffers. 2591 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS; 2592 //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT 2593 minUndequeCount = MIN_UNDEQUEUED_BUFFERS; 2594 } 2595 if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) { 2596 // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS 2597 // and so change the MACRO as per minUndequeCount 2598 LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)", 2599 minUndequeCount, MIN_UNDEQUEUED_BUFFERS); 2600 } 2601 } 2602 2603 LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d" 2604 "maxStreamBuf = %d minUndequeCount = %d", 2605 minCaptureBuffers, zslQBuffers, minCircularBufNum, 2606 maxStreamBuf, minUndequeCount); 2607 // Get buffer count for the particular stream type 2608 switch (stream_type) { 2609 case CAM_STREAM_TYPE_PREVIEW: 2610 { 2611 if (mParameters.isZSLMode()) { 2612 // We need to add two extra streming buffers to add 2613 // flexibility in forming matched super buf in ZSL queue. 2614 // with number being 'zslQBuffers + minCircularBufNum' 2615 // we see preview buffers sometimes get dropped at CPP 2616 // and super buf is not forming in ZSL Q for long time. 2617 2618 bufferCnt = zslQBuffers + minCircularBufNum + 2619 mParameters.getNumOfExtraBuffersForImageProc() + 2620 mParameters.getNumOfExtraBuffersForPreview() + 2621 mParameters.getNumOfExtraHDRInBufsIfNeeded(); 2622 } else { 2623 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS + 2624 mParameters.getMaxUnmatchedFramesInQueue() + 2625 mParameters.getNumOfExtraBuffersForPreview(); 2626 } 2627 // ISP allocates native preview buffers and so reducing same from HAL allocation 2628 if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS ) 2629 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2630 2631 // Extra ZSL preview frames are not needed for HFR case. 2632 // Thumbnail will not be derived from preview for HFR live snapshot case. 2633 if ((mParameters.getRecordingHintValue() == true) 2634 && (!mParameters.isHfrMode())) { 2635 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF; 2636 } 2637 //Adding Extra preview buffers for 60FPS usecase. 2638 mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps); 2639 if (maxPrevFps > CAMERA_DEFAULT_FPS) { 2640 bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS; 2641 } 2642 2643 // Add the display minUndequeCount count on top of camera requirement 2644 bufferCnt += minUndequeCount; 2645 2646 property_get("persist.camera.preview_yuv", value, "0"); 2647 persist_cnt = atoi(value); 2648 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2649 && (bufferCnt < persist_cnt)) { 2650 bufferCnt = persist_cnt; 2651 } 2652 } 2653 break; 2654 case CAM_STREAM_TYPE_POSTVIEW: 2655 { 2656 bufferCnt = minCaptureBuffers + 2657 mParameters.getMaxUnmatchedFramesInQueue() + 2658 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2659 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2660 mParameters.getNumOfExtraBuffersForImageProc(); 2661 2662 if (bufferCnt > maxStreamBuf) { 2663 bufferCnt = maxStreamBuf; 2664 } 2665 bufferCnt += minUndequeCount; 2666 } 2667 break; 2668 case CAM_STREAM_TYPE_SNAPSHOT: 2669 { 2670 if (mParameters.isZSLMode() || mLongshotEnabled) { 2671 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) && 2672 !mLongshotEnabled) { 2673 // Single ZSL snapshot case 2674 bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS + 2675 mParameters.getNumOfExtraBuffersForImageProc(); 2676 } 2677 else { 2678 // ZSL Burst or Longshot case 2679 bufferCnt = zslQBuffers + minCircularBufNum + 2680 mParameters.getNumOfExtraBuffersForImageProc(); 2681 } 2682 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) { 2683 //ISP allocates native buffers in YUV case 2684 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2685 } 2686 } else { 2687 bufferCnt = minCaptureBuffers + 2688 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2689 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2690 mParameters.getNumOfExtraBuffersForImageProc(); 2691 2692 if (bufferCnt > maxStreamBuf) { 2693 bufferCnt = maxStreamBuf; 2694 } 2695 } 2696 } 2697 break; 2698 case CAM_STREAM_TYPE_RAW: 2699 property_get("persist.camera.raw_yuv", value, "0"); 2700 raw_yuv = atoi(value) > 0 ? true : false; 2701 2702 if (isRdiMode() || raw_yuv) { 2703 bufferCnt = zslQBuffers + minCircularBufNum; 2704 } else if (mParameters.isZSLMode()) { 2705 bufferCnt = zslQBuffers + minCircularBufNum; 2706 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) { 2707 //ISP allocates native buffers in YUV case 2708 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2709 } 2710 2711 } else { 2712 bufferCnt = minCaptureBuffers + 2713 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2714 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2715 mParameters.getNumOfExtraBuffersForImageProc(); 2716 2717 if (bufferCnt > maxStreamBuf) { 2718 bufferCnt = maxStreamBuf; 2719 } 2720 } 2721 2722 property_get("persist.camera.preview_raw", value, "0"); 2723 persist_cnt = atoi(value); 2724 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2725 && (bufferCnt < persist_cnt)) { 2726 bufferCnt = persist_cnt; 2727 } 2728 property_get("persist.camera.video_raw", value, "0"); 2729 persist_cnt = atoi(value); 2730 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2731 && (bufferCnt < persist_cnt)) { 2732 bufferCnt = persist_cnt; 2733 } 2734 2735 break; 2736 case CAM_STREAM_TYPE_VIDEO: 2737 { 2738 if (mParameters.getBufBatchCount()) { 2739 //Video Buffer in case of HFR or camera batching.. 2740 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS; 2741 } else if (mParameters.getVideoBatchSize()) { 2742 //Video Buffer count only for HAL to HAL batching. 2743 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS 2744 * mParameters.getVideoBatchSize()); 2745 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) { 2746 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS; 2747 } 2748 } else { 2749 // No batching enabled. 2750 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS; 2751 } 2752 2753 bufferCnt += mParameters.getNumOfExtraBuffersForVideo(); 2754 //if its 4K encoding usecase, then add extra buffer 2755 cam_dimension_t dim; 2756 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim); 2757 if (is4k2kResolution(&dim)) { 2758 //get additional buffer count 2759 property_get("vidc.enc.dcvs.extra-buff-count", value, "0"); 2760 bufferCnt += atoi(value); 2761 } 2762 } 2763 break; 2764 case CAM_STREAM_TYPE_METADATA: 2765 { 2766 if (mParameters.isZSLMode()) { 2767 // MetaData buffers should be >= (Preview buffers-minUndequeCount) 2768 bufferCnt = zslQBuffers + minCircularBufNum + 2769 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2770 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2771 mParameters.getNumOfExtraBuffersForImageProc() + 2772 EXTRA_ZSL_PREVIEW_STREAM_BUF; 2773 } else { 2774 bufferCnt = minCaptureBuffers + 2775 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2776 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2777 mParameters.getMaxUnmatchedFramesInQueue() + 2778 CAMERA_MIN_STREAMING_BUFFERS + 2779 mParameters.getNumOfExtraBuffersForImageProc(); 2780 2781 if (bufferCnt > zslQBuffers + minCircularBufNum) { 2782 bufferCnt = zslQBuffers + minCircularBufNum; 2783 } 2784 } 2785 if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) { 2786 bufferCnt = CAMERA_MIN_METADATA_BUFFERS; 2787 } 2788 } 2789 break; 2790 case CAM_STREAM_TYPE_OFFLINE_PROC: 2791 { 2792 bufferCnt = minCaptureBuffers; 2793 // One of the ubifocus buffers is miscellaneous buffer 2794 if (mParameters.isUbiRefocus()) { 2795 bufferCnt -= 1; 2796 } 2797 if (mLongshotEnabled) { 2798 bufferCnt = mParameters.getLongshotStages(); 2799 } 2800 } 2801 break; 2802 case CAM_STREAM_TYPE_CALLBACK: 2803 bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS; 2804 break; 2805 case CAM_STREAM_TYPE_ANALYSIS: 2806 case CAM_STREAM_TYPE_DEFAULT: 2807 case CAM_STREAM_TYPE_MAX: 2808 default: 2809 bufferCnt = 0; 2810 break; 2811 } 2812 2813 LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type); 2814 if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) { 2815 LOGW("Buffer count %d for stream type %d exceeds limit %d", 2816 bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM); 2817 return CAM_MAX_NUM_BUFS_PER_STREAM; 2818 } 2819 2820 return (uint8_t)bufferCnt; 2821 } 2822 2823 /*=========================================================================== 2824 * FUNCTION : getStreamRefCount 2825 * 2826 * DESCRIPTION: return number of instance of stream of stream type 2827 * 2828 * PARAMETERS : 2829 * @stream_type : type of stream 2830 * 2831 * RETURN : number of stream instances 2832 * NOTE : Based on the use cases and auxillary camera type, 2833 we can decide stream reference count. 2834 For example in wide and tele use case, we duplicate all stream 2835 streams from premary to auxillary. 2836 *==========================================================================*/ 2837 uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type) 2838 { 2839 uint8_t ref_cnt = 1; 2840 switch (stream_type) { 2841 case CAM_STREAM_TYPE_PREVIEW: 2842 case CAM_STREAM_TYPE_SNAPSHOT: 2843 case CAM_STREAM_TYPE_VIDEO: 2844 case CAM_STREAM_TYPE_METADATA: 2845 case CAM_STREAM_TYPE_ANALYSIS: 2846 case CAM_STREAM_TYPE_CALLBACK: 2847 if (isDualCamera()) { 2848 ref_cnt++; 2849 } 2850 break; 2851 case CAM_STREAM_TYPE_POSTVIEW: 2852 case CAM_STREAM_TYPE_RAW: 2853 case CAM_STREAM_TYPE_OFFLINE_PROC: 2854 case CAM_STREAM_TYPE_DEFAULT: 2855 case CAM_STREAM_TYPE_MAX: 2856 default: 2857 break; 2858 } 2859 return ref_cnt; 2860 } 2861 2862 /*=========================================================================== 2863 * FUNCTION : getCamHandleForChannel 2864 * 2865 * DESCRIPTION: return actual camera handle based on use case 2866 * 2867 * PARAMETERS : 2868 * @ch_type : type of channel 2869 * 2870 * RETURN : uint32_t type camera handle 2871 * NOTE : Based on the use cases and auxillary camera type, we can decide cam handle for channel. 2872 Incase, we want to avoid any channel for auxillary camera, we can decide here 2873 *==========================================================================*/ 2874 uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type) 2875 { 2876 uint32_t handle = 0; 2877 if (!isDualCamera()) { 2878 return mCameraHandle->camera_handle; 2879 } 2880 2881 /*Based on the use case, decide camera handle for channel*/ 2882 switch (ch_type) { 2883 case QCAMERA_CH_TYPE_ZSL: 2884 case QCAMERA_CH_TYPE_CAPTURE: 2885 case QCAMERA_CH_TYPE_PREVIEW: 2886 case QCAMERA_CH_TYPE_VIDEO: 2887 case QCAMERA_CH_TYPE_SNAPSHOT: 2888 case QCAMERA_CH_TYPE_RAW: 2889 case QCAMERA_CH_TYPE_METADATA: 2890 case QCAMERA_CH_TYPE_ANALYSIS: 2891 case QCAMERA_CH_TYPE_CALLBACK: 2892 case QCAMERA_CH_TYPE_MAX: 2893 default: 2894 handle = mCameraHandle->camera_handle; 2895 break; 2896 case QCAMERA_CH_TYPE_REPROCESSING: 2897 handle = get_main_camera_handle(mCameraHandle->camera_handle); 2898 break; 2899 } 2900 return handle; 2901 } 2902 2903 /*=========================================================================== 2904 * FUNCTION : allocateStreamBuf 2905 * 2906 * DESCRIPTION: alocate stream buffers 2907 * 2908 * PARAMETERS : 2909 * @stream_type : type of stream 2910 * @size : size of buffer 2911 * @stride : stride of buffer 2912 * @scanline : scanline of buffer 2913 * @bufferCnt : [IN/OUT] minimum num of buffers to be allocated. 2914 * could be modified during allocation if more buffers needed 2915 * 2916 * RETURN : ptr to a memory obj that holds stream buffers. 2917 * NULL if failed 2918 *==========================================================================*/ 2919 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf( 2920 cam_stream_type_t stream_type, size_t size, int stride, int scanline, 2921 uint8_t &bufferCnt) 2922 { 2923 int rc = NO_ERROR; 2924 QCameraMemory *mem = NULL; 2925 bool bCachedMem = QCAMERA_ION_USE_CACHE; 2926 bool bPoolMem = false; 2927 char value[PROPERTY_VALUE_MAX]; 2928 property_get("persist.camera.mem.usepool", value, "1"); 2929 if (atoi(value) == 1) { 2930 bPoolMem = true; 2931 } 2932 2933 // Allocate stream buffer memory object 2934 switch (stream_type) { 2935 case CAM_STREAM_TYPE_PREVIEW: 2936 { 2937 if (isNoDisplayMode()) { 2938 mem = new QCameraStreamMemory(mGetMemory, 2939 bCachedMem, 2940 (bPoolMem) ? &m_memoryPool : NULL, 2941 stream_type); 2942 } else { 2943 cam_dimension_t dim; 2944 int minFPS, maxFPS; 2945 QCameraGrallocMemory *grallocMemory = 2946 new QCameraGrallocMemory(mGetMemory); 2947 2948 mParameters.getStreamDimension(stream_type, dim); 2949 /* we are interested only in maxfps here */ 2950 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 2951 int usage = 0; 2952 if(mParameters.isUBWCEnabled()) { 2953 cam_format_t fmt; 2954 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt); 2955 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 2956 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ; 2957 } 2958 } 2959 if (grallocMemory) { 2960 grallocMemory->setMappable( 2961 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS); 2962 grallocMemory->setWindowInfo(mPreviewWindow, 2963 dim.width,dim.height, stride, scanline, 2964 mParameters.getPreviewHalPixelFormat(), 2965 maxFPS, usage); 2966 pthread_mutex_lock(&mGrallocLock); 2967 if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) { 2968 mEnqueuedBuffers = (bufferCnt - 2969 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS); 2970 } else { 2971 mEnqueuedBuffers = 0; 2972 } 2973 pthread_mutex_unlock(&mGrallocLock); 2974 } 2975 mem = grallocMemory; 2976 } 2977 } 2978 break; 2979 case CAM_STREAM_TYPE_POSTVIEW: 2980 { 2981 if (isNoDisplayMode() || isPreviewRestartEnabled()) { 2982 mem = new QCameraStreamMemory(mGetMemory, bCachedMem); 2983 } else { 2984 cam_dimension_t dim; 2985 int minFPS, maxFPS; 2986 QCameraGrallocMemory *grallocMemory = 2987 new QCameraGrallocMemory(mGetMemory); 2988 2989 mParameters.getStreamDimension(stream_type, dim); 2990 /* we are interested only in maxfps here */ 2991 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 2992 if (grallocMemory) { 2993 grallocMemory->setWindowInfo(mPreviewWindow, dim.width, 2994 dim.height, stride, scanline, 2995 mParameters.getPreviewHalPixelFormat(), maxFPS); 2996 } 2997 mem = grallocMemory; 2998 } 2999 } 3000 break; 3001 case CAM_STREAM_TYPE_ANALYSIS: 3002 case CAM_STREAM_TYPE_SNAPSHOT: 3003 case CAM_STREAM_TYPE_RAW: 3004 case CAM_STREAM_TYPE_OFFLINE_PROC: 3005 mem = new QCameraStreamMemory(mGetMemory, 3006 bCachedMem, 3007 (bPoolMem) ? &m_memoryPool : NULL, 3008 stream_type); 3009 break; 3010 case CAM_STREAM_TYPE_METADATA: 3011 { 3012 if (mMetadataMem == NULL) { 3013 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE); 3014 } else { 3015 mem = mMetadataMem; 3016 mMetadataMem = NULL; 3017 3018 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt(); 3019 if (numAdditionalBuffers > 0) { 3020 rc = mem->allocateMore(numAdditionalBuffers, size); 3021 if (rc != NO_ERROR) { 3022 LOGE("Failed to allocate additional buffers, " 3023 "but attempting to proceed."); 3024 } 3025 } 3026 bufferCnt = mem->getCnt(); 3027 // The memory is already allocated and initialized, so 3028 // simply return here. 3029 return mem; 3030 } 3031 } 3032 break; 3033 case CAM_STREAM_TYPE_VIDEO: 3034 { 3035 //Use uncached allocation by default 3036 if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() || 3037 mParameters.isHighQualityNoiseReductionMode()) { 3038 bCachedMem = QCAMERA_ION_USE_CACHE; 3039 } 3040 else { 3041 bCachedMem = QCAMERA_ION_USE_NOCACHE; 3042 } 3043 3044 QCameraVideoMemory *videoMemory = NULL; 3045 if (mParameters.getVideoBatchSize()) { 3046 videoMemory = new QCameraVideoMemory( 3047 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH); 3048 if (videoMemory == NULL) { 3049 LOGE("Out of memory for video batching obj"); 3050 return NULL; 3051 } 3052 /* 3053 * numFDs = BATCH size 3054 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT 3055 */ 3056 rc = videoMemory->allocateMeta( 3057 CAMERA_MIN_VIDEO_BATCH_BUFFERS, 3058 mParameters.getVideoBatchSize(), 3059 VIDEO_METADATA_NUM_INTS); 3060 if (rc < 0) { 3061 delete videoMemory; 3062 return NULL; 3063 } 3064 } else { 3065 videoMemory = 3066 new QCameraVideoMemory(mGetMemory, bCachedMem); 3067 if (videoMemory == NULL) { 3068 LOGE("Out of memory for video obj"); 3069 return NULL; 3070 } 3071 } 3072 3073 int usage = 0; 3074 cam_format_t fmt; 3075 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt); 3076 if (mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) { 3077 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 3078 } 3079 videoMemory->setVideoInfo(usage, fmt); 3080 mem = videoMemory; 3081 } 3082 break; 3083 case CAM_STREAM_TYPE_CALLBACK: 3084 mem = new QCameraStreamMemory(mGetMemory, 3085 bCachedMem, 3086 (bPoolMem) ? &m_memoryPool : NULL, 3087 stream_type); 3088 break; 3089 case CAM_STREAM_TYPE_DEFAULT: 3090 case CAM_STREAM_TYPE_MAX: 3091 default: 3092 break; 3093 } 3094 if (!mem) { 3095 return NULL; 3096 } 3097 3098 if (bufferCnt > 0) { 3099 if (mParameters.isSecureMode() && 3100 (stream_type == CAM_STREAM_TYPE_RAW) && 3101 (mParameters.isRdiMode())) { 3102 LOGD("Allocating %d secure buffers of size %d ", bufferCnt, size); 3103 rc = mem->allocate(bufferCnt, size, SECURE); 3104 } else { 3105 rc = mem->allocate(bufferCnt, size, NON_SECURE); 3106 } 3107 if (rc < 0) { 3108 delete mem; 3109 return NULL; 3110 } 3111 bufferCnt = mem->getCnt(); 3112 } 3113 LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d", 3114 rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem); 3115 return mem; 3116 } 3117 3118 /*=========================================================================== 3119 * FUNCTION : allocateMoreStreamBuf 3120 * 3121 * DESCRIPTION: alocate more stream buffers from the memory object 3122 * 3123 * PARAMETERS : 3124 * @mem_obj : memory object ptr 3125 * @size : size of buffer 3126 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated. 3127 * output will be the number of total buffers 3128 * 3129 * RETURN : int32_t type of status 3130 * NO_ERROR -- success 3131 * none-zero failure code 3132 *==========================================================================*/ 3133 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf( 3134 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt) 3135 { 3136 int rc = NO_ERROR; 3137 3138 if (bufferCnt > 0) { 3139 rc = mem_obj->allocateMore(bufferCnt, size); 3140 bufferCnt = mem_obj->getCnt(); 3141 } 3142 return rc; 3143 } 3144 3145 /*=========================================================================== 3146 * FUNCTION : allocateMiscBuf 3147 * 3148 * DESCRIPTION: alocate miscellaneous buffer 3149 * 3150 * PARAMETERS : 3151 * @streamInfo : stream info 3152 * 3153 * RETURN : ptr to a memory obj that holds stream info buffer. 3154 * NULL if failed 3155 *==========================================================================*/ 3156 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf( 3157 cam_stream_info_t *streamInfo) 3158 { 3159 int rc = NO_ERROR; 3160 uint8_t bufNum = 0; 3161 size_t bufSize = 0; 3162 QCameraHeapMemory *miscBuf = NULL; 3163 cam_feature_mask_t feature_mask = 3164 streamInfo->reprocess_config.pp_feature_config.feature_mask; 3165 3166 switch (streamInfo->stream_type) { 3167 case CAM_STREAM_TYPE_OFFLINE_PROC: 3168 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) { 3169 bufNum = 1; 3170 bufSize = mParameters.getTPMaxMetaSize(); 3171 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) { 3172 bufNum = 1; 3173 bufSize = mParameters.getRefocusMaxMetaSize(); 3174 } 3175 break; 3176 default: 3177 break; 3178 } 3179 3180 if (bufNum && bufSize) { 3181 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 3182 3183 if (!miscBuf) { 3184 LOGE("Unable to allocate miscBuf object"); 3185 return NULL; 3186 } 3187 3188 rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE); 3189 if (rc < 0) { 3190 LOGE("Failed to allocate misc buffer memory"); 3191 delete miscBuf; 3192 return NULL; 3193 } 3194 } 3195 3196 return miscBuf; 3197 } 3198 3199 /*=========================================================================== 3200 * FUNCTION : initStreamInfoBuf 3201 * 3202 * DESCRIPTION: initialize stream info buffer based on stream type 3203 * 3204 * PARAMETERS : 3205 * @stream_type : type of stream 3206 * 3207 * RETURN : ptr to a memory obj that holds stream info buffer. 3208 * NULL if failed 3209 *==========================================================================*/ 3210 int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type, 3211 cam_stream_info_t *streamInfo) 3212 { 3213 int rc = NO_ERROR; 3214 int32_t dt = 0; 3215 int32_t vc = 0; 3216 3217 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 3218 streamInfo->stream_type = stream_type; 3219 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt); 3220 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim); 3221 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim); 3222 streamInfo->num_bufs = getBufNumRequired(stream_type); 3223 streamInfo->buf_cnt = streamInfo->num_bufs; 3224 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 3225 streamInfo->is_secure = NON_SECURE; 3226 3227 switch (stream_type) { 3228 case CAM_STREAM_TYPE_SNAPSHOT: 3229 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) || 3230 mLongshotEnabled) { 3231 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 3232 } else { 3233 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 3234 streamInfo->num_of_burst = (uint8_t) 3235 (mParameters.getNumOfSnapshots() 3236 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 3237 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 3238 + mParameters.getNumOfExtraBuffersForImageProc()); 3239 } 3240 break; 3241 case CAM_STREAM_TYPE_RAW: { 3242 char value[PROPERTY_VALUE_MAX]; 3243 bool raw_yuv = false; 3244 property_get("persist.camera.raw_yuv", value, "0"); 3245 raw_yuv = atoi(value) > 0 ? true : false; 3246 if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) { 3247 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 3248 } else { 3249 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 3250 streamInfo->num_of_burst = mParameters.getNumOfSnapshots(); 3251 } 3252 if (mParameters.isSecureMode() && mParameters.isRdiMode()) { 3253 streamInfo->is_secure = SECURE; 3254 } else { 3255 streamInfo->is_secure = NON_SECURE; 3256 } 3257 } 3258 if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) { 3259 mParameters.updateDtVc(&dt, &vc); 3260 if (dt) 3261 streamInfo->dt = dt; 3262 streamInfo->vc = vc; 3263 } 3264 3265 break; 3266 case CAM_STREAM_TYPE_POSTVIEW: 3267 if (mLongshotEnabled) { 3268 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 3269 } else { 3270 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 3271 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots() 3272 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 3273 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 3274 + mParameters.getNumOfExtraBuffersForImageProc()); 3275 } 3276 break; 3277 case CAM_STREAM_TYPE_VIDEO: 3278 streamInfo->dis_enable = mParameters.isDISEnabled(); 3279 if (mParameters.getBufBatchCount()) { 3280 //Update stream info structure with batch mode info 3281 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH; 3282 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount(); 3283 streamInfo->user_buf_info.size = 3284 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t)); 3285 cam_fps_range_t pFpsRange; 3286 mParameters.getHfrFps(pFpsRange); 3287 streamInfo->user_buf_info.frameInterval = 3288 (long)((1000/pFpsRange.video_max_fps) * 1000); 3289 LOGH("Video Batch Count = %d, interval = %d", 3290 streamInfo->user_buf_info.frame_buf_cnt, 3291 streamInfo->user_buf_info.frameInterval); 3292 } 3293 if (mParameters.getRecordingHintValue()) { 3294 if(mParameters.isDISEnabled()) { 3295 streamInfo->is_type = mParameters.getVideoISType(); 3296 } else { 3297 streamInfo->is_type = IS_TYPE_NONE; 3298 } 3299 } 3300 if (mParameters.isSecureMode()) { 3301 streamInfo->is_secure = SECURE; 3302 } 3303 break; 3304 case CAM_STREAM_TYPE_PREVIEW: 3305 if (mParameters.getRecordingHintValue()) { 3306 if(mParameters.isDISEnabled()) { 3307 streamInfo->is_type = mParameters.getPreviewISType(); 3308 } else { 3309 streamInfo->is_type = IS_TYPE_NONE; 3310 } 3311 } 3312 if (mParameters.isSecureMode()) { 3313 streamInfo->is_secure = SECURE; 3314 } 3315 break; 3316 case CAM_STREAM_TYPE_ANALYSIS: 3317 streamInfo->noFrameExpected = 1; 3318 break; 3319 default: 3320 break; 3321 } 3322 3323 // Update feature mask 3324 mParameters.updatePpFeatureMask(stream_type); 3325 3326 // Get feature mask 3327 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask); 3328 3329 // Update pp config 3330 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) { 3331 int flipMode = mParameters.getFlipMode(stream_type); 3332 if (flipMode > 0) { 3333 streamInfo->pp_config.flip = (uint32_t)flipMode; 3334 } 3335 } 3336 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) { 3337 streamInfo->pp_config.sharpness = mParameters.getSharpness(); 3338 } 3339 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) { 3340 streamInfo->pp_config.effect = mParameters.getEffectValue(); 3341 } 3342 3343 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) { 3344 streamInfo->pp_config.denoise2d.denoise_enable = 1; 3345 streamInfo->pp_config.denoise2d.process_plates = 3346 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 3347 } 3348 3349 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type || 3350 CAM_STREAM_TYPE_RAW == stream_type))) { 3351 if (gCamCapability[mCameraId]->qcom_supported_feature_mask & 3352 CAM_QCOM_FEATURE_CROP) 3353 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 3354 if (gCamCapability[mCameraId]->qcom_supported_feature_mask & 3355 CAM_QCOM_FEATURE_SCALE) 3356 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 3357 } 3358 streamInfo->aux_str_info = NULL; 3359 3360 LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n", 3361 stream_type, streamInfo->fmt, streamInfo->dim.width, 3362 streamInfo->dim.height, streamInfo->num_bufs, 3363 streamInfo->pp_config.feature_mask, 3364 streamInfo->is_type); 3365 3366 return rc; 3367 } 3368 3369 /*=========================================================================== 3370 * FUNCTION : allocateStreamInfoBuf 3371 * 3372 * DESCRIPTION: alocate stream info buffer 3373 * 3374 * PARAMETERS : 3375 * @stream_type : type of stream 3376 * @bufCount : stream info buffer count 3377 * 3378 * RETURN : ptr to a memory obj that holds stream info buffer. 3379 * NULL if failed 3380 *==========================================================================*/ 3381 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf( 3382 cam_stream_type_t stream_type, uint8_t bufCount) 3383 { 3384 int rc = NO_ERROR; 3385 3386 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 3387 if (!streamInfoBuf) { 3388 LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object"); 3389 return NULL; 3390 } 3391 3392 if (bufCount > MM_CAMERA_MAX_CAM_CNT) { 3393 LOGE("buffer count should be lesser than max camera : %d", bufCount); 3394 return NULL; 3395 } 3396 rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t), NON_SECURE); 3397 if (rc < 0) { 3398 LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory"); 3399 delete streamInfoBuf; 3400 return NULL; 3401 } 3402 3403 for (uint8_t i = 0; i < bufCount; i++) { 3404 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i); 3405 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 3406 rc = initStreamInfoBuf(stream_type, streamInfo); 3407 if (rc < 0) { 3408 LOGE("initStreamInfoBuf failed"); 3409 delete streamInfoBuf; 3410 return NULL; 3411 } 3412 } 3413 3414 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0); 3415 if (bufCount == MM_CAMERA_MAX_CAM_CNT) { 3416 cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1); 3417 streamInfo->aux_str_info = s_streamInfo; 3418 } 3419 3420 if (streamInfo->aux_str_info != NULL) { 3421 /*Update StreamInfo for Aux camera*/ 3422 streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type); 3423 streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt; 3424 streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt; 3425 } 3426 return streamInfoBuf; 3427 } 3428 3429 /*=========================================================================== 3430 * FUNCTION : allocateStreamUserBuf 3431 * 3432 * DESCRIPTION: allocate user ptr for stream buffers 3433 * 3434 * PARAMETERS : 3435 * @streamInfo : stream info structure 3436 * 3437 * RETURN : ptr to a memory obj that holds stream info buffer. 3438 * NULL if failed 3439 3440 *==========================================================================*/ 3441 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf( 3442 cam_stream_info_t *streamInfo) 3443 { 3444 int rc = NO_ERROR; 3445 QCameraMemory *mem = NULL; 3446 int size = 0; 3447 3448 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) { 3449 LOGE("Stream is not in BATCH mode. Invalid Stream"); 3450 return NULL; 3451 } 3452 3453 // Allocate stream user buffer memory object 3454 switch (streamInfo->stream_type) { 3455 case CAM_STREAM_TYPE_VIDEO: { 3456 QCameraVideoMemory *video_mem = new QCameraVideoMemory( 3457 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH); 3458 if (video_mem == NULL) { 3459 LOGE("Out of memory for video obj"); 3460 return NULL; 3461 } 3462 /* 3463 * numFDs = BATCH size 3464 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT 3465 */ 3466 rc = video_mem->allocateMeta(streamInfo->num_bufs, 3467 mParameters.getBufBatchCount(), VIDEO_METADATA_NUM_INTS); 3468 if (rc < 0) { 3469 LOGE("allocateMeta failed"); 3470 delete video_mem; 3471 return NULL; 3472 } 3473 int usage = 0; 3474 cam_format_t fmt; 3475 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt); 3476 if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) { 3477 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 3478 } 3479 video_mem->setVideoInfo(usage, fmt); 3480 mem = static_cast<QCameraMemory *>(video_mem); 3481 } 3482 break; 3483 3484 case CAM_STREAM_TYPE_PREVIEW: 3485 case CAM_STREAM_TYPE_POSTVIEW: 3486 case CAM_STREAM_TYPE_ANALYSIS: 3487 case CAM_STREAM_TYPE_SNAPSHOT: 3488 case CAM_STREAM_TYPE_RAW: 3489 case CAM_STREAM_TYPE_METADATA: 3490 case CAM_STREAM_TYPE_OFFLINE_PROC: 3491 case CAM_STREAM_TYPE_CALLBACK: 3492 LOGE("Stream type Not supported.for BATCH processing"); 3493 break; 3494 3495 case CAM_STREAM_TYPE_DEFAULT: 3496 case CAM_STREAM_TYPE_MAX: 3497 default: 3498 break; 3499 } 3500 if (!mem) { 3501 LOGE("Failed to allocate mem"); 3502 return NULL; 3503 } 3504 3505 /*Size of this buffer will be number of batch buffer */ 3506 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size), 3507 CAM_PAD_TO_4K); 3508 3509 LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs); 3510 3511 if (size > 0) { 3512 // Allocating one buffer for all batch buffers 3513 rc = mem->allocate(1, size, NON_SECURE); 3514 if (rc < 0) { 3515 delete mem; 3516 return NULL; 3517 } 3518 } 3519 return mem; 3520 } 3521 3522 3523 /*=========================================================================== 3524 * FUNCTION : waitForDeferredAlloc 3525 * 3526 * DESCRIPTION: Wait for deferred allocation, if applicable 3527 * (applicable only for metadata buffers so far) 3528 * 3529 * PARAMETERS : 3530 * @stream_type : type of stream to (possibly) wait for 3531 * 3532 * RETURN : None 3533 *==========================================================================*/ 3534 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type) 3535 { 3536 if (stream_type == CAM_STREAM_TYPE_METADATA) { 3537 waitDeferredWork(mMetadataAllocJob); 3538 } 3539 } 3540 3541 3542 /*=========================================================================== 3543 * FUNCTION : setPreviewWindow 3544 * 3545 * DESCRIPTION: set preview window impl 3546 * 3547 * PARAMETERS : 3548 * @window : ptr to window ops table struct 3549 * 3550 * RETURN : int32_t type of status 3551 * NO_ERROR -- success 3552 * none-zero failure code 3553 *==========================================================================*/ 3554 int QCamera2HardwareInterface::setPreviewWindow( 3555 struct preview_stream_ops *window) 3556 { 3557 mPreviewWindow = window; 3558 return NO_ERROR; 3559 } 3560 3561 /*=========================================================================== 3562 * FUNCTION : setCallBacks 3563 * 3564 * DESCRIPTION: set callbacks impl 3565 * 3566 * PARAMETERS : 3567 * @notify_cb : notify cb 3568 * @data_cb : data cb 3569 * @data_cb_timestamp : data cb with time stamp 3570 * @get_memory : request memory ops table 3571 * @user : user data ptr 3572 * 3573 * RETURN : int32_t type of status 3574 * NO_ERROR -- success 3575 * none-zero failure code 3576 *==========================================================================*/ 3577 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb, 3578 camera_data_callback data_cb, 3579 camera_data_timestamp_callback data_cb_timestamp, 3580 camera_request_memory get_memory, 3581 void *user) 3582 { 3583 mNotifyCb = notify_cb; 3584 mDataCb = data_cb; 3585 mDataCbTimestamp = data_cb_timestamp; 3586 mGetMemory = get_memory; 3587 mCallbackCookie = user; 3588 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user); 3589 return NO_ERROR; 3590 } 3591 3592 /*=========================================================================== 3593 * FUNCTION : setJpegCallBacks 3594 * 3595 * DESCRIPTION: set JPEG callbacks impl 3596 * 3597 * PARAMETERS : 3598 * @jpegCb : Jpeg callback method 3599 * @callbackCookie : callback cookie 3600 * 3601 * RETURN : int32_t type of status 3602 * NO_ERROR -- success 3603 * none-zero failure code 3604 *==========================================================================*/ 3605 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb, 3606 void *callbackCookie) 3607 { 3608 LOGH("camera id %d", getCameraId()); 3609 mJpegCb = jpegCb; 3610 mJpegCallbackCookie = callbackCookie; 3611 m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie); 3612 } 3613 3614 /*=========================================================================== 3615 * FUNCTION : enableMsgType 3616 * 3617 * DESCRIPTION: enable msg type impl 3618 * 3619 * PARAMETERS : 3620 * @msg_type : msg type mask to be enabled 3621 * 3622 * RETURN : int32_t type of status 3623 * NO_ERROR -- success 3624 * none-zero failure code 3625 *==========================================================================*/ 3626 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type) 3627 { 3628 int32_t rc = NO_ERROR; 3629 3630 if (mParameters.isUBWCEnabled()) { 3631 /*Need Special CALLBACK stream incase application requesting for 3632 Preview callback in UBWC case*/ 3633 if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) && 3634 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) { 3635 // Start callback channel only when preview/zsl channel is active 3636 QCameraChannel* previewCh = NULL; 3637 if (isZSLMode() && (getRecordingHintValue() != true)) { 3638 previewCh = m_channels[QCAMERA_CH_TYPE_ZSL]; 3639 } else { 3640 previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 3641 } 3642 QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK]; 3643 if ((callbackCh != NULL) && 3644 (previewCh != NULL) && previewCh->isActive()) { 3645 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK); 3646 if (rc != NO_ERROR) { 3647 LOGE("START Callback Channel failed"); 3648 } 3649 } 3650 } 3651 } 3652 mMsgEnabled |= msg_type; 3653 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc); 3654 return rc; 3655 } 3656 3657 /*=========================================================================== 3658 * FUNCTION : disableMsgType 3659 * 3660 * DESCRIPTION: disable msg type impl 3661 * 3662 * PARAMETERS : 3663 * @msg_type : msg type mask to be disabled 3664 * 3665 * RETURN : int32_t type of status 3666 * NO_ERROR -- success 3667 * none-zero failure code 3668 *==========================================================================*/ 3669 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type) 3670 { 3671 int32_t rc = NO_ERROR; 3672 3673 if (mParameters.isUBWCEnabled()) { 3674 /*STOP CALLBACK STREAM*/ 3675 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) && 3676 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) { 3677 // Stop callback channel only if it is active 3678 if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) && 3679 (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) { 3680 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK); 3681 if (rc != NO_ERROR) { 3682 LOGE("STOP Callback Channel failed"); 3683 } 3684 } 3685 } 3686 } 3687 mMsgEnabled &= ~msg_type; 3688 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc); 3689 return rc; 3690 } 3691 3692 /*=========================================================================== 3693 * FUNCTION : msgTypeEnabled 3694 * 3695 * DESCRIPTION: impl to determine if certain msg_type is enabled 3696 * 3697 * PARAMETERS : 3698 * @msg_type : msg type mask 3699 * 3700 * RETURN : 0 -- not enabled 3701 * none 0 -- enabled 3702 *==========================================================================*/ 3703 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type) 3704 { 3705 return (mMsgEnabled & msg_type); 3706 } 3707 3708 /*=========================================================================== 3709 * FUNCTION : msgTypeEnabledWithLock 3710 * 3711 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock 3712 * 3713 * PARAMETERS : 3714 * @msg_type : msg type mask 3715 * 3716 * RETURN : 0 -- not enabled 3717 * none 0 -- enabled 3718 *==========================================================================*/ 3719 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type) 3720 { 3721 int enabled = 0; 3722 lockAPI(); 3723 enabled = mMsgEnabled & msg_type; 3724 unlockAPI(); 3725 return enabled; 3726 } 3727 3728 /*=========================================================================== 3729 * FUNCTION : startPreview 3730 * 3731 * DESCRIPTION: start preview impl 3732 * 3733 * PARAMETERS : none 3734 * 3735 * RETURN : int32_t type of status 3736 * NO_ERROR -- success 3737 * none-zero failure code 3738 *==========================================================================*/ 3739 int QCamera2HardwareInterface::startPreview() 3740 { 3741 KPI_ATRACE_CALL(); 3742 int32_t rc = NO_ERROR; 3743 3744 LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(), 3745 mParameters.getRecordingHintValue()); 3746 3747 m_perfLock.lock_acq(); 3748 3749 updateThermalLevel((void *)&mThermalLevel); 3750 3751 setDisplayFrameSkip(); 3752 3753 // start preview stream 3754 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 3755 rc = startChannel(QCAMERA_CH_TYPE_ZSL); 3756 } else { 3757 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW); 3758 } 3759 3760 if (rc != NO_ERROR) { 3761 LOGE("failed to start channels"); 3762 m_perfLock.lock_rel(); 3763 return rc; 3764 } 3765 3766 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) 3767 && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) { 3768 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK); 3769 if (rc != NO_ERROR) { 3770 LOGE("failed to start callback stream"); 3771 stopChannel(QCAMERA_CH_TYPE_ZSL); 3772 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3773 m_perfLock.lock_rel(); 3774 return rc; 3775 } 3776 } 3777 3778 updatePostPreviewParameters(); 3779 m_stateMachine.setPreviewCallbackNeeded(true); 3780 3781 // if job id is non-zero, that means the postproc init job is already 3782 // pending or complete 3783 if (mInitPProcJob == 0) { 3784 mInitPProcJob = deferPPInit(); 3785 if (mInitPProcJob == 0) { 3786 LOGE("Unable to initialize postprocessor, mCameraHandle = %p", 3787 mCameraHandle); 3788 rc = -ENOMEM; 3789 m_perfLock.lock_rel(); 3790 return rc; 3791 } 3792 } 3793 m_perfLock.lock_rel(); 3794 3795 if (rc == NO_ERROR) { 3796 // Set power Hint for preview 3797 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true); 3798 } 3799 3800 LOGI("X rc = %d", rc); 3801 return rc; 3802 } 3803 3804 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() { 3805 // Enable OIS only in Camera mode and 4k2k camcoder mode 3806 int32_t rc = NO_ERROR; 3807 rc = mParameters.updateOisValue(1); 3808 return NO_ERROR; 3809 } 3810 3811 /*=========================================================================== 3812 * FUNCTION : stopPreview 3813 * 3814 * DESCRIPTION: stop preview impl 3815 * 3816 * PARAMETERS : none 3817 * 3818 * RETURN : int32_t type of status 3819 * NO_ERROR -- success 3820 * none-zero failure code 3821 *==========================================================================*/ 3822 int QCamera2HardwareInterface::stopPreview() 3823 { 3824 KPI_ATRACE_CALL(); 3825 LOGI("E"); 3826 mNumPreviewFaces = -1; 3827 mActiveAF = false; 3828 3829 // Disable power Hint for preview 3830 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false); 3831 3832 m_perfLock.lock_acq(); 3833 3834 // stop preview stream 3835 stopChannel(QCAMERA_CH_TYPE_CALLBACK); 3836 stopChannel(QCAMERA_CH_TYPE_ZSL); 3837 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3838 stopChannel(QCAMERA_CH_TYPE_RAW); 3839 3840 m_cbNotifier.flushPreviewNotifications(); 3841 //add for ts makeup 3842 #ifdef TARGET_TS_MAKEUP 3843 ts_makeup_finish(); 3844 #endif 3845 // delete all channels from preparePreview 3846 unpreparePreview(); 3847 3848 m_perfLock.lock_rel(); 3849 3850 LOGI("X"); 3851 return NO_ERROR; 3852 } 3853 3854 /*=========================================================================== 3855 * FUNCTION : storeMetaDataInBuffers 3856 * 3857 * DESCRIPTION: enable store meta data in buffers for video frames impl 3858 * 3859 * PARAMETERS : 3860 * @enable : flag if need enable 3861 * 3862 * RETURN : int32_t type of status 3863 * NO_ERROR -- success 3864 * none-zero failure code 3865 *==========================================================================*/ 3866 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable) 3867 { 3868 mStoreMetaDataInFrame = enable; 3869 return NO_ERROR; 3870 } 3871 3872 /*=========================================================================== 3873 * FUNCTION : preStartRecording 3874 * 3875 * DESCRIPTION: Prepare start recording impl 3876 * 3877 * PARAMETERS : none 3878 * 3879 * RETURN : int32_t type of status 3880 * NO_ERROR -- success 3881 * none-zero failure code 3882 *==========================================================================*/ 3883 int QCamera2HardwareInterface::preStartRecording() 3884 { 3885 int32_t rc = NO_ERROR; 3886 LOGH("E"); 3887 if (mParameters.getRecordingHintValue() == false) { 3888 3889 // Give HWI control to restart preview only in single camera mode. 3890 // In dual-cam mode, this control belongs to muxer. 3891 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 3892 LOGH("start recording when hint is false, stop preview first"); 3893 stopPreview(); 3894 3895 // Set recording hint to TRUE 3896 mParameters.updateRecordingHintValue(TRUE); 3897 rc = preparePreview(); 3898 if (rc == NO_ERROR) { 3899 rc = startPreview(); 3900 } 3901 } 3902 else 3903 { 3904 // For dual cam mode, update the flag mPreviewRestartNeeded to true 3905 // Restart control will be handled by muxer. 3906 mPreviewRestartNeeded = true; 3907 } 3908 } 3909 3910 LOGH("X rc = %d", rc); 3911 return rc; 3912 } 3913 3914 /*=========================================================================== 3915 * FUNCTION : startRecording 3916 * 3917 * DESCRIPTION: start recording impl 3918 * 3919 * PARAMETERS : none 3920 * 3921 * RETURN : int32_t type of status 3922 * NO_ERROR -- success 3923 * none-zero failure code 3924 *==========================================================================*/ 3925 int QCamera2HardwareInterface::startRecording() 3926 { 3927 int32_t rc = NO_ERROR; 3928 3929 LOGI("E"); 3930 //link meta stream with video channel if low power mode. 3931 if (isLowPowerMode()) { 3932 // Find and try to link a metadata stream from preview channel 3933 QCameraChannel *pMetaChannel = NULL; 3934 QCameraStream *pMetaStream = NULL; 3935 QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO]; 3936 3937 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 3938 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 3939 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 3940 QCameraStream *pStream = NULL; 3941 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 3942 pStream = pMetaChannel->getStreamByIndex(i); 3943 if ((NULL != pStream) && 3944 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) { 3945 pMetaStream = pStream; 3946 break; 3947 } 3948 } 3949 } 3950 3951 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 3952 rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream); 3953 if (NO_ERROR != rc) { 3954 LOGW("Metadata stream link failed %d", rc); 3955 } 3956 } 3957 } 3958 3959 if (rc == NO_ERROR) { 3960 rc = startChannel(QCAMERA_CH_TYPE_VIDEO); 3961 } 3962 3963 if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) { 3964 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 3965 if (!mParameters.is4k2kVideoResolution()) { 3966 // Find and try to link a metadata stream from preview channel 3967 QCameraChannel *pMetaChannel = NULL; 3968 QCameraStream *pMetaStream = NULL; 3969 3970 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 3971 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 3972 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 3973 QCameraStream *pStream = NULL; 3974 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 3975 pStream = pMetaChannel->getStreamByIndex(i); 3976 if ((NULL != pStream) && 3977 (CAM_STREAM_TYPE_METADATA == 3978 pStream->getMyType())) { 3979 pMetaStream = pStream; 3980 break; 3981 } 3982 } 3983 } 3984 3985 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 3986 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 3987 if (NO_ERROR != rc) { 3988 LOGW("Metadata stream link failed %d", rc); 3989 } 3990 } 3991 } 3992 LOGH("START snapshot Channel for TNR processing"); 3993 rc = pChannel->start(); 3994 } 3995 3996 if (rc == NO_ERROR) { 3997 // Set power Hint for video encoding 3998 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true); 3999 } 4000 4001 LOGI("X rc = %d", rc); 4002 return rc; 4003 } 4004 4005 /*=========================================================================== 4006 * FUNCTION : stopRecording 4007 * 4008 * DESCRIPTION: stop recording impl 4009 * 4010 * PARAMETERS : none 4011 * 4012 * RETURN : int32_t type of status 4013 * NO_ERROR -- success 4014 * none-zero failure code 4015 *==========================================================================*/ 4016 int QCamera2HardwareInterface::stopRecording() 4017 { 4018 LOGI("E"); 4019 // stop snapshot channel 4020 if (mParameters.isTNRSnapshotEnabled()) { 4021 LOGH("STOP snapshot Channel for TNR processing"); 4022 stopChannel(QCAMERA_CH_TYPE_SNAPSHOT); 4023 } 4024 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO); 4025 4026 m_cbNotifier.flushVideoNotifications(); 4027 // Disable power hint for video encoding 4028 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false); 4029 LOGI("X rc = %d", rc); 4030 return rc; 4031 } 4032 4033 /*=========================================================================== 4034 * FUNCTION : releaseRecordingFrame 4035 * 4036 * DESCRIPTION: return video frame impl 4037 * 4038 * PARAMETERS : 4039 * @opaque : ptr to video frame to be returned 4040 * 4041 * RETURN : int32_t type of status 4042 * NO_ERROR -- success 4043 * none-zero failure code 4044 *==========================================================================*/ 4045 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque) 4046 { 4047 int32_t rc = UNKNOWN_ERROR; 4048 QCameraVideoChannel *pChannel = 4049 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO]; 4050 LOGD("opaque data = %p",opaque); 4051 4052 if(pChannel != NULL) { 4053 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0); 4054 } 4055 return rc; 4056 } 4057 4058 /*=========================================================================== 4059 * FUNCTION : autoFocus 4060 * 4061 * DESCRIPTION: start auto focus impl 4062 * 4063 * PARAMETERS : none 4064 * 4065 * RETURN : int32_t type of status 4066 * NO_ERROR -- success 4067 * none-zero failure code 4068 *==========================================================================*/ 4069 int QCamera2HardwareInterface::autoFocus() 4070 { 4071 int rc = NO_ERROR; 4072 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 4073 LOGH("E"); 4074 4075 switch (focusMode) { 4076 case CAM_FOCUS_MODE_AUTO: 4077 case CAM_FOCUS_MODE_MACRO: 4078 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 4079 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 4080 mActiveAF = true; 4081 LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d", 4082 focusMode, m_currentFocusState); 4083 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle); 4084 break; 4085 case CAM_FOCUS_MODE_INFINITY: 4086 case CAM_FOCUS_MODE_FIXED: 4087 case CAM_FOCUS_MODE_EDOF: 4088 default: 4089 LOGI("No ops in focusMode (%d)", focusMode); 4090 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 4091 break; 4092 } 4093 4094 if (NO_ERROR != rc) { 4095 mActiveAF = false; 4096 } 4097 LOGH("X rc = %d", rc); 4098 return rc; 4099 } 4100 4101 /*=========================================================================== 4102 * FUNCTION : cancelAutoFocus 4103 * 4104 * DESCRIPTION: cancel auto focus impl 4105 * 4106 * PARAMETERS : none 4107 * 4108 * RETURN : int32_t type of status 4109 * NO_ERROR -- success 4110 * none-zero failure code 4111 *==========================================================================*/ 4112 int QCamera2HardwareInterface::cancelAutoFocus() 4113 { 4114 int rc = NO_ERROR; 4115 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 4116 4117 switch (focusMode) { 4118 case CAM_FOCUS_MODE_AUTO: 4119 case CAM_FOCUS_MODE_MACRO: 4120 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 4121 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 4122 mActiveAF = false; 4123 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle); 4124 break; 4125 case CAM_FOCUS_MODE_INFINITY: 4126 case CAM_FOCUS_MODE_FIXED: 4127 case CAM_FOCUS_MODE_EDOF: 4128 default: 4129 LOGD("No ops in focusMode (%d)", focusMode); 4130 break; 4131 } 4132 return rc; 4133 } 4134 4135 /*=========================================================================== 4136 * FUNCTION : processUFDumps 4137 * 4138 * DESCRIPTION: process UF jpeg dumps for refocus support 4139 * 4140 * PARAMETERS : 4141 * @evt : payload of jpeg event, including information about jpeg encoding 4142 * status, jpeg size and so on. 4143 * 4144 * RETURN : int32_t type of status 4145 * NO_ERROR -- success 4146 * none-zero failure code 4147 * 4148 * NOTE : none 4149 *==========================================================================*/ 4150 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt) 4151 { 4152 bool ret = true; 4153 if (mParameters.isUbiRefocus()) { 4154 int index = (int)getOutputImageCount(); 4155 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1)); 4156 char name[FILENAME_MAX]; 4157 4158 camera_memory_t *jpeg_mem = NULL; 4159 omx_jpeg_ouput_buf_t *jpeg_out = NULL; 4160 size_t dataLen; 4161 uint8_t *dataPtr; 4162 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 4163 LOGE("Init PProc Deferred work failed"); 4164 return false; 4165 } 4166 if (!m_postprocessor.getJpegMemOpt()) { 4167 dataLen = evt->out_data.buf_filled_len; 4168 dataPtr = evt->out_data.buf_vaddr; 4169 } else { 4170 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr; 4171 if (!jpeg_out) { 4172 LOGE("Null pointer detected"); 4173 return false; 4174 } 4175 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl; 4176 if (!jpeg_mem) { 4177 LOGE("Null pointer detected"); 4178 return false; 4179 } 4180 dataPtr = (uint8_t *)jpeg_mem->data; 4181 dataLen = jpeg_mem->size; 4182 } 4183 4184 if (allFocusImage) { 4185 snprintf(name, sizeof(name), "AllFocusImage"); 4186 index = -1; 4187 } else { 4188 snprintf(name, sizeof(name), "%d", 0); 4189 } 4190 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg", 4191 dataPtr, dataLen); 4192 LOGD("Dump the image %d %d allFocusImage %d", 4193 getOutputImageCount(), index, allFocusImage); 4194 setOutputImageCount(getOutputImageCount() + 1); 4195 if (!allFocusImage) { 4196 ret = false; 4197 } 4198 } 4199 return ret; 4200 } 4201 4202 /*=========================================================================== 4203 * FUNCTION : unconfigureAdvancedCapture 4204 * 4205 * DESCRIPTION: unconfigure Advanced Capture. 4206 * 4207 * PARAMETERS : none 4208 * 4209 * RETURN : int32_t type of status 4210 * NO_ERROR -- success 4211 * none-zero failure code 4212 *==========================================================================*/ 4213 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture() 4214 { 4215 int32_t rc = NO_ERROR; 4216 4217 /*Disable Quadra CFA mode*/ 4218 LOGH("Disabling Quadra CFA mode"); 4219 mParameters.setQuadraCfaMode(false, true); 4220 4221 if (mAdvancedCaptureConfigured) { 4222 4223 mAdvancedCaptureConfigured = false; 4224 4225 if(mIs3ALocked) { 4226 mParameters.set3ALock(false); 4227 mIs3ALocked = false; 4228 } 4229 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) { 4230 rc = mParameters.setToneMapMode(true, true); 4231 if (rc != NO_ERROR) { 4232 LOGW("Failed to enable tone map during HDR/AEBracketing"); 4233 } 4234 mHDRBracketingEnabled = false; 4235 rc = mParameters.stopAEBracket(); 4236 } else if ((mParameters.isChromaFlashEnabled()) 4237 || (mFlashConfigured && !mLongshotEnabled) 4238 || (mLowLightConfigured == true) 4239 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4240 rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured); 4241 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4242 rc = configureAFBracketing(false); 4243 } else if (mParameters.isOptiZoomEnabled()) { 4244 rc = mParameters.setAndCommitZoom(mZoomLevel); 4245 setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY); 4246 } else if (mParameters.isStillMoreEnabled()) { 4247 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 4248 stillmore_config.burst_count = 0; 4249 mParameters.setStillMoreSettings(stillmore_config); 4250 4251 /* If SeeMore is running, it will handle re-enabling tone map */ 4252 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) { 4253 rc = mParameters.setToneMapMode(true, true); 4254 if (rc != NO_ERROR) { 4255 LOGW("Failed to enable tone map during StillMore"); 4256 } 4257 } 4258 4259 /* Re-enable Tintless */ 4260 mParameters.setTintless(true); 4261 } else { 4262 LOGW("No Advanced Capture feature enabled!!"); 4263 rc = BAD_VALUE; 4264 } 4265 } 4266 4267 return rc; 4268 } 4269 4270 /*=========================================================================== 4271 * FUNCTION : configureAdvancedCapture 4272 * 4273 * DESCRIPTION: configure Advanced Capture. 4274 * 4275 * PARAMETERS : none 4276 * 4277 * RETURN : int32_t type of status 4278 * NO_ERROR -- success 4279 * none-zero failure code 4280 *==========================================================================*/ 4281 int32_t QCamera2HardwareInterface::configureAdvancedCapture() 4282 { 4283 LOGH("E"); 4284 int32_t rc = NO_ERROR; 4285 4286 rc = mParameters.checkFeatureConcurrency(); 4287 if (rc != NO_ERROR) { 4288 LOGE("Cannot support Advanced capture modes"); 4289 return rc; 4290 } 4291 /*Enable Quadra CFA mode*/ 4292 LOGH("Enabling Quadra CFA mode"); 4293 mParameters.setQuadraCfaMode(true, true); 4294 4295 setOutputImageCount(0); 4296 mInputCount = 0; 4297 mAdvancedCaptureConfigured = true; 4298 /* Display should be disabled for advanced modes */ 4299 bool bSkipDisplay = true; 4300 4301 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) { 4302 // no Advance capture settings for Aux camera 4303 LOGH("X Secondary Camera, no need to process!! "); 4304 return rc; 4305 } 4306 4307 /* Do not stop display if in stillmore livesnapshot */ 4308 if (mParameters.isStillMoreEnabled() && 4309 mParameters.isSeeMoreEnabled()) { 4310 bSkipDisplay = false; 4311 } 4312 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4313 rc = configureAFBracketing(); 4314 } else if (mParameters.isOptiZoomEnabled()) { 4315 rc = configureOptiZoom(); 4316 } else if(mParameters.isHDREnabled()) { 4317 rc = configureHDRBracketing(); 4318 if (mHDRBracketingEnabled) { 4319 rc = mParameters.setToneMapMode(false, true); 4320 if (rc != NO_ERROR) { 4321 LOGW("Failed to disable tone map during HDR"); 4322 } 4323 } 4324 } else if (mParameters.isAEBracketEnabled()) { 4325 rc = mParameters.setToneMapMode(false, true); 4326 if (rc != NO_ERROR) { 4327 LOGW("Failed to disable tone map during AEBracketing"); 4328 } 4329 rc = configureAEBracketing(); 4330 } else if (mParameters.isStillMoreEnabled()) { 4331 bSkipDisplay = false; 4332 rc = configureStillMore(); 4333 } else if ((mParameters.isChromaFlashEnabled()) 4334 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) 4335 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4336 rc = mParameters.configFrameCapture(TRUE); 4337 if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) { 4338 mLowLightConfigured = true; 4339 } 4340 } else if (mFlashNeeded && !mLongshotEnabled) { 4341 rc = mParameters.configFrameCapture(TRUE); 4342 mFlashConfigured = true; 4343 bSkipDisplay = false; 4344 } else { 4345 LOGH("Advanced Capture feature not enabled!! "); 4346 mAdvancedCaptureConfigured = false; 4347 bSkipDisplay = false; 4348 } 4349 4350 LOGH("Stop preview temporarily for advanced captures"); 4351 setDisplaySkip(bSkipDisplay); 4352 4353 LOGH("X rc = %d", rc); 4354 return rc; 4355 } 4356 4357 /*=========================================================================== 4358 * FUNCTION : configureAFBracketing 4359 * 4360 * DESCRIPTION: configure AF Bracketing. 4361 * 4362 * PARAMETERS : none 4363 * 4364 * RETURN : int32_t type of status 4365 * NO_ERROR -- success 4366 * none-zero failure code 4367 *==========================================================================*/ 4368 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable) 4369 { 4370 LOGH("E"); 4371 int32_t rc = NO_ERROR; 4372 cam_af_bracketing_t *af_bracketing_need; 4373 4374 if (mParameters.isUbiRefocus()) { 4375 af_bracketing_need = 4376 &gCamCapability[mCameraId]->refocus_af_bracketing_need; 4377 } else { 4378 af_bracketing_need = 4379 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need; 4380 } 4381 4382 //Enable AF Bracketing. 4383 cam_af_bracketing_t afBracket; 4384 memset(&afBracket, 0, sizeof(cam_af_bracketing_t)); 4385 afBracket.enable = enable; 4386 afBracket.burst_count = af_bracketing_need->burst_count; 4387 4388 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) { 4389 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i]; 4390 LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]); 4391 } 4392 //Send cmd to backend to set AF Bracketing for Ubi Focus. 4393 rc = mParameters.commitAFBracket(afBracket); 4394 if ( NO_ERROR != rc ) { 4395 LOGE("cannot configure AF bracketing"); 4396 return rc; 4397 } 4398 if (enable) { 4399 mParameters.set3ALock(true); 4400 mIs3ALocked = true; 4401 } 4402 LOGH("X rc = %d", rc); 4403 return rc; 4404 } 4405 4406 /*=========================================================================== 4407 * FUNCTION : configureHDRBracketing 4408 * 4409 * DESCRIPTION: configure HDR Bracketing. 4410 * 4411 * PARAMETERS : none 4412 * 4413 * RETURN : int32_t type of status 4414 * NO_ERROR -- success 4415 * none-zero failure code 4416 *==========================================================================*/ 4417 int32_t QCamera2HardwareInterface::configureHDRBracketing() 4418 { 4419 LOGH("E"); 4420 int32_t rc = NO_ERROR; 4421 4422 cam_hdr_bracketing_info_t& hdrBracketingSetting = 4423 gCamCapability[mCameraId]->hdr_bracketing_setting; 4424 4425 // 'values' should be in "idx1,idx2,idx3,..." format 4426 uint32_t hdrFrameCount = 4427 hdrBracketingSetting.num_frames; 4428 LOGH("HDR values %d, %d frame count: %u", 4429 (int8_t) hdrBracketingSetting.exp_val.values[0], 4430 (int8_t) hdrBracketingSetting.exp_val.values[1], 4431 hdrFrameCount); 4432 4433 // Enable AE Bracketing for HDR 4434 cam_exp_bracketing_t aeBracket; 4435 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t)); 4436 aeBracket.mode = 4437 hdrBracketingSetting.exp_val.mode; 4438 4439 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) { 4440 mHDRBracketingEnabled = true; 4441 } 4442 4443 String8 tmp; 4444 for (uint32_t i = 0; i < hdrFrameCount; i++) { 4445 tmp.appendFormat("%d", 4446 (int8_t) hdrBracketingSetting.exp_val.values[i]); 4447 tmp.append(","); 4448 } 4449 if (mParameters.isHDR1xFrameEnabled() 4450 && mParameters.isHDR1xExtraBufferNeeded()) { 4451 tmp.appendFormat("%d", 0); 4452 tmp.append(","); 4453 } 4454 4455 if( !tmp.isEmpty() && 4456 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) { 4457 //Trim last comma 4458 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH); 4459 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1); 4460 } 4461 4462 LOGH("HDR config values %s", 4463 aeBracket.values); 4464 rc = mParameters.setHDRAEBracket(aeBracket); 4465 if ( NO_ERROR != rc ) { 4466 LOGE("cannot configure HDR bracketing"); 4467 return rc; 4468 } 4469 LOGH("X rc = %d", rc); 4470 return rc; 4471 } 4472 4473 /*=========================================================================== 4474 * FUNCTION : configureAEBracketing 4475 * 4476 * DESCRIPTION: configure AE Bracketing. 4477 * 4478 * PARAMETERS : none 4479 * 4480 * RETURN : int32_t type of status 4481 * NO_ERROR -- success 4482 * none-zero failure code 4483 *==========================================================================*/ 4484 int32_t QCamera2HardwareInterface::configureAEBracketing() 4485 { 4486 LOGH("E"); 4487 int32_t rc = NO_ERROR; 4488 4489 rc = mParameters.setAEBracketing(); 4490 if ( NO_ERROR != rc ) { 4491 LOGE("cannot configure AE bracketing"); 4492 return rc; 4493 } 4494 LOGH("X rc = %d", rc); 4495 return rc; 4496 } 4497 4498 /*=========================================================================== 4499 * FUNCTION : configureOptiZoom 4500 * 4501 * DESCRIPTION: configure Opti Zoom. 4502 * 4503 * PARAMETERS : none 4504 * 4505 * RETURN : int32_t type of status 4506 * NO_ERROR -- success 4507 * none-zero failure code 4508 *==========================================================================*/ 4509 int32_t QCamera2HardwareInterface::configureOptiZoom() 4510 { 4511 int32_t rc = NO_ERROR; 4512 4513 //store current zoom level. 4514 mZoomLevel = mParameters.getParmZoomLevel(); 4515 4516 //set zoom level to 1x; 4517 mParameters.setAndCommitZoom(0); 4518 4519 mParameters.set3ALock(true); 4520 mIs3ALocked = true; 4521 4522 return rc; 4523 } 4524 4525 /*=========================================================================== 4526 * FUNCTION : configureStillMore 4527 * 4528 * DESCRIPTION: configure StillMore. 4529 * 4530 * PARAMETERS : none 4531 * 4532 * RETURN : int32_t type of status 4533 * NO_ERROR -- success 4534 * none-zero failure code 4535 *==========================================================================*/ 4536 int32_t QCamera2HardwareInterface::configureStillMore() 4537 { 4538 int32_t rc = NO_ERROR; 4539 uint8_t burst_cnt = 0; 4540 cam_still_more_t stillmore_config; 4541 cam_still_more_t stillmore_cap; 4542 4543 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */ 4544 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) { 4545 rc = mParameters.setToneMapMode(false, true); 4546 if (rc != NO_ERROR) { 4547 LOGW("Failed to disable tone map during StillMore"); 4548 } 4549 } 4550 4551 /* Lock 3A */ 4552 mParameters.set3ALock(true); 4553 mIs3ALocked = true; 4554 4555 /* Disable Tintless */ 4556 mParameters.setTintless(false); 4557 4558 /* Initialize burst count from capability */ 4559 stillmore_cap = mParameters.getStillMoreCapability(); 4560 burst_cnt = stillmore_cap.max_burst_count; 4561 4562 /* Reconfigure burst count from dynamic scene data */ 4563 cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData(); 4564 if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count && 4565 dynamic_img_data.input_count <= stillmore_cap.max_burst_count) { 4566 burst_cnt = dynamic_img_data.input_count; 4567 } 4568 4569 /* Reconfigure burst count in the case of liveshot */ 4570 if (mParameters.isSeeMoreEnabled()) { 4571 burst_cnt = 1; 4572 } 4573 4574 /* Reconfigure burst count from user input */ 4575 char prop[PROPERTY_VALUE_MAX]; 4576 property_get("persist.camera.imglib.stillmore", prop, "0"); 4577 uint8_t burst_setprop = (uint32_t)atoi(prop); 4578 if (burst_setprop != 0) { 4579 if ((burst_setprop < stillmore_cap.min_burst_count) || 4580 (burst_setprop > stillmore_cap.max_burst_count)) { 4581 burst_cnt = stillmore_cap.max_burst_count; 4582 } else { 4583 burst_cnt = burst_setprop; 4584 } 4585 } 4586 4587 memset(&stillmore_config, 0, sizeof(cam_still_more_t)); 4588 stillmore_config.burst_count = burst_cnt; 4589 mParameters.setStillMoreSettings(stillmore_config); 4590 4591 LOGH("Stillmore burst %d", burst_cnt); 4592 4593 return rc; 4594 } 4595 4596 /*=========================================================================== 4597 * FUNCTION : stopAdvancedCapture 4598 * 4599 * DESCRIPTION: stops advanced capture based on capture type 4600 * 4601 * PARAMETERS : 4602 * @pChannel : channel. 4603 * 4604 * RETURN : int32_t type of status 4605 * NO_ERROR -- success 4606 * none-zero failure code 4607 *==========================================================================*/ 4608 int32_t QCamera2HardwareInterface::stopAdvancedCapture( 4609 QCameraPicChannel *pChannel) 4610 { 4611 LOGH("stop bracketig"); 4612 int32_t rc = NO_ERROR; 4613 4614 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4615 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING); 4616 } else if (mParameters.isChromaFlashEnabled() 4617 || (mFlashConfigured && !mLongshotEnabled) 4618 || (mLowLightConfigured == true) 4619 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4620 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE); 4621 mFlashConfigured = false; 4622 mLowLightConfigured = false; 4623 } else if(mParameters.isHDREnabled() 4624 || mParameters.isAEBracketEnabled()) { 4625 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING); 4626 } else if (mParameters.isOptiZoomEnabled()) { 4627 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X); 4628 } else if (mParameters.isStillMoreEnabled()) { 4629 LOGH("stopAdvancedCapture not needed for StillMore"); 4630 } else { 4631 LOGH("No Advanced Capture feature enabled!"); 4632 rc = BAD_VALUE; 4633 } 4634 return rc; 4635 } 4636 4637 /*=========================================================================== 4638 * FUNCTION : startAdvancedCapture 4639 * 4640 * DESCRIPTION: starts advanced capture based on capture type 4641 * 4642 * PARAMETERS : 4643 * @pChannel : channel. 4644 * 4645 * RETURN : int32_t type of status 4646 * NO_ERROR -- success 4647 * none-zero failure code 4648 *==========================================================================*/ 4649 int32_t QCamera2HardwareInterface::startAdvancedCapture( 4650 QCameraPicChannel *pChannel) 4651 { 4652 LOGH("Start bracketing"); 4653 int32_t rc = NO_ERROR; 4654 4655 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4656 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING); 4657 } else if (mParameters.isOptiZoomEnabled()) { 4658 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X); 4659 } else if (mParameters.isStillMoreEnabled()) { 4660 LOGH("startAdvancedCapture not needed for StillMore"); 4661 } else if (mParameters.isHDREnabled() 4662 || mParameters.isAEBracketEnabled()) { 4663 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING); 4664 } else if (mParameters.isChromaFlashEnabled() 4665 || (mFlashNeeded && !mLongshotEnabled) 4666 || (mLowLightConfigured == true) 4667 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4668 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig(); 4669 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config); 4670 } else { 4671 LOGE("No Advanced Capture feature enabled!"); 4672 rc = BAD_VALUE; 4673 } 4674 return rc; 4675 } 4676 4677 /*=========================================================================== 4678 * FUNCTION : preTakePicture 4679 * 4680 * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary 4681 * 4682 * PARAMETERS : none 4683 * 4684 * RETURN : int32_t type of status 4685 * NO_ERROR -- success 4686 * none-zero failure code 4687 *==========================================================================*/ 4688 int QCamera2HardwareInterface::preTakePicture() 4689 { 4690 int32_t rc = NO_ERROR; 4691 LOGH("E"); 4692 if (mParameters.getRecordingHintValue() == true) { 4693 4694 // Give HWI control to restart preview only in single camera mode. 4695 // In dual-cam mode, this control belongs to muxer. 4696 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 4697 LOGH("restart preview if rec hint is true and preview is running"); 4698 stopPreview(); 4699 mParameters.updateRecordingHintValue(FALSE); 4700 // start preview again 4701 rc = preparePreview(); 4702 if (rc == NO_ERROR) { 4703 rc = startPreview(); 4704 if (rc != NO_ERROR) { 4705 unpreparePreview(); 4706 } 4707 } 4708 } 4709 else 4710 { 4711 // For dual cam mode, update the flag mPreviewRestartNeeded to true 4712 // Restart control will be handled by muxer. 4713 mPreviewRestartNeeded = true; 4714 } 4715 } 4716 4717 LOGH("X rc = %d", rc); 4718 return rc; 4719 } 4720 4721 /*=========================================================================== 4722 * FUNCTION : takePicture 4723 * 4724 * DESCRIPTION: take picture impl 4725 * 4726 * PARAMETERS : none 4727 * 4728 * RETURN : int32_t type of status 4729 * NO_ERROR -- success 4730 * none-zero failure code 4731 *==========================================================================*/ 4732 int QCamera2HardwareInterface::takePicture() 4733 { 4734 int rc = NO_ERROR; 4735 4736 // Get total number for snapshots (retro + regular) 4737 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 4738 // Get number of retro-active snapshots 4739 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots(); 4740 LOGH("E"); 4741 4742 //Set rotation value from user settings as Jpeg rotation 4743 //to configure back-end modules. 4744 mParameters.setJpegRotation(mParameters.getRotation()); 4745 4746 // Check if retro-active snapshots are not enabled 4747 if (!isRetroPicture() || !mParameters.isZSLMode()) { 4748 numRetroSnapshots = 0; 4749 LOGH("Reset retro snaphot count to zero"); 4750 } 4751 4752 //Do special configure for advanced capture modes. 4753 rc = configureAdvancedCapture(); 4754 if (rc != NO_ERROR) { 4755 LOGE("Unsupported capture call"); 4756 return rc; 4757 } 4758 4759 #ifdef DUAL_CAM_TEST //Temporary macro. Added to simulate B+B snapshot. Will be removed 4760 if(mActiveCamera == (MM_CAMERA_TYPE_MAIN | MM_CAMERA_TYPE_AUX)) { 4761 numSnapshots = 1; 4762 } 4763 #endif 4764 4765 if (mAdvancedCaptureConfigured) { 4766 numSnapshots = mParameters.getBurstCountForAdvancedCapture(); 4767 } 4768 LOGI("snap count = %d zsl = %d advanced = %d", 4769 numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured); 4770 4771 if (mParameters.isZSLMode()) { 4772 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 4773 QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel; 4774 if (NULL != pPicChannel) { 4775 4776 if (mParameters.getofflineRAW()) { 4777 startRAWChannel(pPicChannel); 4778 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW]; 4779 if (pPicChannel == NULL) { 4780 LOGE("RAW Channel is NULL in Manual capture mode"); 4781 stopRAWChannel(); 4782 return UNKNOWN_ERROR; 4783 } 4784 } 4785 4786 rc = configureOnlineRotation(*pPicChannel); 4787 if (rc != NO_ERROR) { 4788 LOGE("online rotation failed"); 4789 return rc; 4790 } 4791 4792 // start postprocessor 4793 DeferWorkArgs args; 4794 memset(&args, 0, sizeof(DeferWorkArgs)); 4795 4796 args.pprocArgs = pPicChannel; 4797 4798 // No need to wait for mInitPProcJob here, because it was 4799 // queued in startPreview, and will definitely be processed before 4800 // mReprocJob can begin. 4801 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 4802 args); 4803 if (mReprocJob == 0) { 4804 LOGE("Failure: Unable to start pproc"); 4805 return -ENOMEM; 4806 } 4807 4808 // Check if all preview buffers are mapped before creating 4809 // a jpeg session as preview stream buffers are queried during the same 4810 uint8_t numStreams = pChannel->getNumOfStreams(); 4811 QCameraStream *pStream = NULL; 4812 QCameraStream *pPreviewStream = NULL; 4813 for (uint8_t i = 0 ; i < numStreams ; i++ ) { 4814 pStream = pChannel->getStreamByIndex(i); 4815 if (!pStream) 4816 continue; 4817 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) { 4818 pPreviewStream = pStream; 4819 break; 4820 } 4821 } 4822 if (pPreviewStream != NULL) { 4823 Mutex::Autolock l(mMapLock); 4824 QCameraMemory *pMemory = pStream->getStreamBufs(); 4825 if (!pMemory) { 4826 LOGE("Error!! pMemory is NULL"); 4827 return -ENOMEM; 4828 } 4829 4830 uint8_t waitCnt = 2; 4831 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) { 4832 LOGL(" Waiting for preview buffers to be mapped"); 4833 mMapCond.waitRelative( 4834 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT); 4835 LOGL("Wait completed!!"); 4836 waitCnt--; 4837 } 4838 // If all buffers are not mapped after retries, assert 4839 assert(pMemory->checkIfAllBuffersMapped()); 4840 } else { 4841 assert(pPreviewStream); 4842 } 4843 4844 // Create JPEG session 4845 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 4846 args); 4847 if (mJpegJob == 0) { 4848 LOGE("Failed to queue CREATE_JPEG_SESSION"); 4849 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4850 LOGE("Reprocess Deferred work was failed"); 4851 } 4852 m_postprocessor.stop(); 4853 return -ENOMEM; 4854 } 4855 4856 if (mAdvancedCaptureConfigured) { 4857 rc = startAdvancedCapture(pPicChannel); 4858 if (rc != NO_ERROR) { 4859 LOGE("cannot start zsl advanced capture"); 4860 return rc; 4861 } 4862 } 4863 if (mLongshotEnabled && mPrepSnapRun) { 4864 mCameraHandle->ops->start_zsl_snapshot( 4865 mCameraHandle->camera_handle, 4866 pPicChannel->getMyHandle()); 4867 } 4868 // If frame sync is ON and it is a SECONDARY camera, 4869 // we do not need to send the take picture command to interface 4870 // It will be handled along with PRIMARY camera takePicture request 4871 mm_camera_req_buf_t buf; 4872 memset(&buf, 0x0, sizeof(buf)); 4873 if ((!mParameters.isAdvCamFeaturesEnabled() && 4874 !mFlashNeeded && 4875 !isLongshotEnabled() && 4876 isFrameSyncEnabled()) && 4877 (getRelatedCamSyncInfo()->sync_control == 4878 CAM_SYNC_RELATED_SENSORS_ON)) { 4879 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) { 4880 buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF; 4881 buf.num_buf_requested = numSnapshots; 4882 rc = pPicChannel->takePicture(&buf); 4883 if (rc != NO_ERROR) { 4884 LOGE("FS_DBG cannot take ZSL picture, stop pproc"); 4885 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4886 LOGE("Reprocess Deferred work failed"); 4887 return UNKNOWN_ERROR; 4888 } 4889 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 4890 LOGE("Jpeg Deferred work failed"); 4891 return UNKNOWN_ERROR; 4892 } 4893 m_postprocessor.stop(); 4894 return rc; 4895 } 4896 LOGI("PRIMARY camera: send frame sync takePicture!!"); 4897 } 4898 } else { 4899 buf.type = MM_CAMERA_REQ_SUPER_BUF; 4900 buf.num_buf_requested = numSnapshots; 4901 buf.num_retro_buf_requested = numRetroSnapshots; 4902 rc = pPicChannel->takePicture(&buf); 4903 if (rc != NO_ERROR) { 4904 LOGE("cannot take ZSL picture, stop pproc"); 4905 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4906 LOGE("Reprocess Deferred work failed"); 4907 return UNKNOWN_ERROR; 4908 } 4909 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 4910 LOGE("Jpeg Deferred work failed"); 4911 return UNKNOWN_ERROR; 4912 } 4913 m_postprocessor.stop(); 4914 return rc; 4915 } 4916 } 4917 } else { 4918 LOGE("ZSL channel is NULL"); 4919 return UNKNOWN_ERROR; 4920 } 4921 } else { 4922 4923 // start snapshot 4924 if (mParameters.isJpegPictureFormat() || 4925 mParameters.isNV16PictureFormat() || 4926 mParameters.isNV21PictureFormat()) { 4927 4928 //STOP Preview for Non ZSL use case 4929 stopPreview(); 4930 4931 //Config CAPTURE channels 4932 rc = declareSnapshotStreams(); 4933 if (NO_ERROR != rc) { 4934 return rc; 4935 } 4936 4937 rc = addCaptureChannel(); 4938 if ((rc == NO_ERROR) && 4939 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) { 4940 4941 if (!mParameters.getofflineRAW()) { 4942 rc = configureOnlineRotation( 4943 *m_channels[QCAMERA_CH_TYPE_CAPTURE]); 4944 if (rc != NO_ERROR) { 4945 LOGE("online rotation failed"); 4946 delChannel(QCAMERA_CH_TYPE_CAPTURE); 4947 return rc; 4948 } 4949 } 4950 4951 DeferWorkArgs args; 4952 memset(&args, 0, sizeof(DeferWorkArgs)); 4953 4954 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE]; 4955 4956 // No need to wait for mInitPProcJob here, because it was 4957 // queued in startPreview, and will definitely be processed before 4958 // mReprocJob can begin. 4959 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 4960 args); 4961 if (mReprocJob == 0) { 4962 LOGE("Failure: Unable to start pproc"); 4963 return -ENOMEM; 4964 } 4965 4966 // Create JPEG session 4967 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 4968 args); 4969 if (mJpegJob == 0) { 4970 LOGE("Failed to queue CREATE_JPEG_SESSION"); 4971 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4972 LOGE("Reprocess Deferred work was failed"); 4973 } 4974 m_postprocessor.stop(); 4975 return -ENOMEM; 4976 } 4977 4978 // start catpure channel 4979 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start(); 4980 if (rc != NO_ERROR) { 4981 LOGE("cannot start capture channel"); 4982 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4983 LOGE("Reprocess Deferred work failed"); 4984 return UNKNOWN_ERROR; 4985 } 4986 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 4987 LOGE("Jpeg Deferred work failed"); 4988 return UNKNOWN_ERROR; 4989 } 4990 delChannel(QCAMERA_CH_TYPE_CAPTURE); 4991 return rc; 4992 } 4993 4994 QCameraPicChannel *pCapChannel = 4995 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 4996 if (NULL != pCapChannel) { 4997 if (mParameters.isUbiFocusEnabled() || 4998 mParameters.isUbiRefocus() || 4999 mParameters.isChromaFlashEnabled()) { 5000 rc = startAdvancedCapture(pCapChannel); 5001 if (rc != NO_ERROR) { 5002 LOGE("cannot start advanced capture"); 5003 return rc; 5004 } 5005 } 5006 } 5007 if ( mLongshotEnabled ) { 5008 rc = longShot(); 5009 if (NO_ERROR != rc) { 5010 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5011 LOGE("Reprocess Deferred work failed"); 5012 return UNKNOWN_ERROR; 5013 } 5014 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 5015 LOGE("Jpeg Deferred work failed"); 5016 return UNKNOWN_ERROR; 5017 } 5018 delChannel(QCAMERA_CH_TYPE_CAPTURE); 5019 return rc; 5020 } 5021 } 5022 } else { 5023 LOGE("cannot add capture channel"); 5024 delChannel(QCAMERA_CH_TYPE_CAPTURE); 5025 return rc; 5026 } 5027 } else { 5028 // Stop Preview before taking NZSL snapshot 5029 stopPreview(); 5030 5031 rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]); 5032 if (NO_ERROR != rc) { 5033 LOGE("Raw dimension update failed %d", rc); 5034 return rc; 5035 } 5036 5037 rc = declareSnapshotStreams(); 5038 if (NO_ERROR != rc) { 5039 LOGE("RAW stream info configuration failed %d", rc); 5040 return rc; 5041 } 5042 5043 rc = addChannel(QCAMERA_CH_TYPE_RAW); 5044 if (rc == NO_ERROR) { 5045 // start postprocessor 5046 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 5047 LOGE("Reprocess Deferred work failed"); 5048 return UNKNOWN_ERROR; 5049 } 5050 5051 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 5052 if (rc != NO_ERROR) { 5053 LOGE("cannot start postprocessor"); 5054 delChannel(QCAMERA_CH_TYPE_RAW); 5055 return rc; 5056 } 5057 5058 rc = startChannel(QCAMERA_CH_TYPE_RAW); 5059 if (rc != NO_ERROR) { 5060 LOGE("cannot start raw channel"); 5061 m_postprocessor.stop(); 5062 delChannel(QCAMERA_CH_TYPE_RAW); 5063 return rc; 5064 } 5065 } else { 5066 LOGE("cannot add raw channel"); 5067 return rc; 5068 } 5069 } 5070 } 5071 5072 //When take picture, stop sending preview callbacks to APP 5073 m_stateMachine.setPreviewCallbackNeeded(false); 5074 LOGI("X rc = %d", rc); 5075 return rc; 5076 } 5077 5078 /*=========================================================================== 5079 * FUNCTION : configureOnlineRotation 5080 * 5081 * DESCRIPTION: Configure backend with expected rotation for snapshot stream 5082 * 5083 * PARAMETERS : 5084 * @ch : Channel containing a snapshot stream 5085 * 5086 * RETURN : int32_t type of status 5087 * NO_ERROR -- success 5088 * none-zero failure code 5089 *==========================================================================*/ 5090 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch) 5091 { 5092 int rc = NO_ERROR; 5093 uint32_t streamId = 0; 5094 QCameraStream *pStream = NULL; 5095 5096 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) { 5097 QCameraStream *stream = ch.getStreamByIndex(i); 5098 if ((NULL != stream) && 5099 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType()) 5100 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) { 5101 pStream = stream; 5102 break; 5103 } 5104 } 5105 5106 if (NULL == pStream) { 5107 LOGE("No snapshot stream found!"); 5108 return BAD_VALUE; 5109 } 5110 5111 streamId = pStream->getMyServerID(); 5112 // Update online rotation configuration 5113 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId, 5114 mParameters.getDeviceRotation()); 5115 if (rc != NO_ERROR) { 5116 LOGE("addOnlineRotation failed %d", rc); 5117 return rc; 5118 } 5119 5120 return rc; 5121 } 5122 5123 /*=========================================================================== 5124 * FUNCTION : declareSnapshotStreams 5125 * 5126 * DESCRIPTION: Configure backend with expected snapshot streams 5127 * 5128 * PARAMETERS : none 5129 * 5130 * RETURN : int32_t type of status 5131 * NO_ERROR -- success 5132 * none-zero failure code 5133 *==========================================================================*/ 5134 int32_t QCamera2HardwareInterface::declareSnapshotStreams() 5135 { 5136 int rc = NO_ERROR; 5137 5138 // Update stream info configuration 5139 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false); 5140 if (rc != NO_ERROR) { 5141 LOGE("setStreamConfigure failed %d", rc); 5142 return rc; 5143 } 5144 5145 return rc; 5146 } 5147 5148 /*=========================================================================== 5149 * FUNCTION : longShot 5150 * 5151 * DESCRIPTION: Queue one more ZSL frame 5152 * in the longshot pipe. 5153 * 5154 * PARAMETERS : none 5155 * 5156 * RETURN : int32_t type of status 5157 * NO_ERROR -- success 5158 * none-zero failure code 5159 *==========================================================================*/ 5160 int32_t QCamera2HardwareInterface::longShot() 5161 { 5162 int32_t rc = NO_ERROR; 5163 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 5164 QCameraPicChannel *pChannel = NULL; 5165 5166 if (mParameters.isZSLMode()) { 5167 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 5168 } else { 5169 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 5170 } 5171 5172 if (NULL != pChannel) { 5173 mm_camera_req_buf_t buf; 5174 memset(&buf, 0x0, sizeof(buf)); 5175 buf.type = MM_CAMERA_REQ_SUPER_BUF; 5176 buf.num_buf_requested = numSnapshots; 5177 rc = pChannel->takePicture(&buf); 5178 } else { 5179 LOGE("Capture channel not initialized!"); 5180 rc = NO_INIT; 5181 goto end; 5182 } 5183 5184 end: 5185 return rc; 5186 } 5187 5188 /*=========================================================================== 5189 * FUNCTION : stopCaptureChannel 5190 * 5191 * DESCRIPTION: Stops capture channel 5192 * 5193 * PARAMETERS : 5194 * @destroy : Set to true to stop and delete camera channel. 5195 * Set to false to only stop capture channel. 5196 * 5197 * RETURN : int32_t type of status 5198 * NO_ERROR -- success 5199 * none-zero failure code 5200 *==========================================================================*/ 5201 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy) 5202 { 5203 int rc = NO_ERROR; 5204 if (mParameters.isJpegPictureFormat() || 5205 mParameters.isNV16PictureFormat() || 5206 mParameters.isNV21PictureFormat()) { 5207 mParameters.setQuadraCfaMode(false, true); 5208 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE); 5209 if (destroy && (NO_ERROR == rc)) { 5210 // Destroy camera channel but dont release context 5211 waitDeferredWork(mJpegJob); 5212 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false); 5213 } 5214 } 5215 5216 return rc; 5217 } 5218 5219 /*=========================================================================== 5220 * FUNCTION : cancelPicture 5221 * 5222 * DESCRIPTION: cancel picture impl 5223 * 5224 * PARAMETERS : none 5225 * 5226 * RETURN : int32_t type of status 5227 * NO_ERROR -- success 5228 * none-zero failure code 5229 *==========================================================================*/ 5230 int QCamera2HardwareInterface::cancelPicture() 5231 { 5232 waitDeferredWork(mReprocJob); 5233 waitDeferredWork(mJpegJob); 5234 5235 //stop post processor 5236 m_postprocessor.stop(); 5237 5238 unconfigureAdvancedCapture(); 5239 LOGH("Enable display frames again"); 5240 setDisplaySkip(FALSE); 5241 5242 if (!mLongshotEnabled) { 5243 m_perfLock.lock_rel(); 5244 } 5245 5246 if (mParameters.isZSLMode()) { 5247 QCameraPicChannel *pPicChannel = NULL; 5248 if (mParameters.getofflineRAW()) { 5249 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW]; 5250 } else { 5251 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 5252 } 5253 if (NULL != pPicChannel) { 5254 pPicChannel->cancelPicture(); 5255 stopRAWChannel(); 5256 stopAdvancedCapture(pPicChannel); 5257 } 5258 } else { 5259 5260 // normal capture case 5261 if (mParameters.isJpegPictureFormat() || 5262 mParameters.isNV16PictureFormat() || 5263 mParameters.isNV21PictureFormat()) { 5264 stopChannel(QCAMERA_CH_TYPE_CAPTURE); 5265 delChannel(QCAMERA_CH_TYPE_CAPTURE); 5266 } else { 5267 stopChannel(QCAMERA_CH_TYPE_RAW); 5268 delChannel(QCAMERA_CH_TYPE_RAW); 5269 } 5270 } 5271 5272 return NO_ERROR; 5273 } 5274 5275 /*=========================================================================== 5276 * FUNCTION : captureDone 5277 * 5278 * DESCRIPTION: Function called when the capture is completed before encoding 5279 * 5280 * PARAMETERS : none 5281 * 5282 * RETURN : none 5283 *==========================================================================*/ 5284 void QCamera2HardwareInterface::captureDone() 5285 { 5286 qcamera_sm_internal_evt_payload_t *payload = 5287 (qcamera_sm_internal_evt_payload_t *) 5288 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 5289 if (NULL != payload) { 5290 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 5291 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE; 5292 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 5293 if (rc != NO_ERROR) { 5294 LOGE("processEvt ZSL capture done failed"); 5295 free(payload); 5296 payload = NULL; 5297 } 5298 } else { 5299 LOGE("No memory for ZSL capture done event"); 5300 } 5301 } 5302 5303 /*=========================================================================== 5304 * FUNCTION : Live_Snapshot_thread 5305 * 5306 * DESCRIPTION: Seperate thread for taking live snapshot during recording 5307 * 5308 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 5309 * 5310 * RETURN : none 5311 *==========================================================================*/ 5312 void* Live_Snapshot_thread (void* data) 5313 { 5314 5315 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 5316 if (!hw) { 5317 LOGE("take_picture_thread: NULL camera device"); 5318 return (void *)BAD_VALUE; 5319 } 5320 if (hw->bLiveSnapshot) { 5321 hw->takeLiveSnapshot_internal(); 5322 } else { 5323 hw->cancelLiveSnapshot_internal(); 5324 } 5325 return (void* )NULL; 5326 } 5327 5328 /*=========================================================================== 5329 * FUNCTION : Int_Pic_thread 5330 * 5331 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend 5332 * 5333 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 5334 * 5335 * RETURN : none 5336 *==========================================================================*/ 5337 void* Int_Pic_thread (void* data) 5338 { 5339 int rc = NO_ERROR; 5340 5341 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 5342 5343 if (!hw) { 5344 LOGE("take_picture_thread: NULL camera device"); 5345 return (void *)BAD_VALUE; 5346 } 5347 5348 bool JpegMemOpt = false; 5349 char raw_format[PROPERTY_VALUE_MAX]; 5350 5351 memset(raw_format, 0, sizeof(raw_format)); 5352 5353 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]); 5354 if (rc == NO_ERROR) { 5355 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]); 5356 } else { 5357 //Snapshot attempt not successful, we need to do cleanup here 5358 hw->clearIntPendingEvents(); 5359 } 5360 5361 return (void* )NULL; 5362 } 5363 5364 /*=========================================================================== 5365 * FUNCTION : takeLiveSnapshot 5366 * 5367 * DESCRIPTION: take live snapshot during recording 5368 * 5369 * PARAMETERS : none 5370 * 5371 * RETURN : int32_t type of status 5372 * NO_ERROR -- success 5373 * none-zero failure code 5374 *==========================================================================*/ 5375 int QCamera2HardwareInterface::takeLiveSnapshot() 5376 { 5377 int rc = NO_ERROR; 5378 if (mLiveSnapshotThread != 0) { 5379 pthread_join(mLiveSnapshotThread,NULL); 5380 mLiveSnapshotThread = 0; 5381 } 5382 bLiveSnapshot = true; 5383 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this); 5384 if (!rc) { 5385 pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap"); 5386 } 5387 return rc; 5388 } 5389 5390 /*=========================================================================== 5391 * FUNCTION : takePictureInternal 5392 * 5393 * DESCRIPTION: take snapshot triggered by backend 5394 * 5395 * PARAMETERS : none 5396 * 5397 * RETURN : int32_t type of status 5398 * NO_ERROR -- success 5399 * none-zero failure code 5400 *==========================================================================*/ 5401 int QCamera2HardwareInterface::takePictureInternal() 5402 { 5403 int rc = NO_ERROR; 5404 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this); 5405 if (!rc) { 5406 pthread_setname_np(mIntPicThread, "CAM_IntPic"); 5407 } 5408 return rc; 5409 } 5410 5411 /*=========================================================================== 5412 * FUNCTION : checkIntPicPending 5413 * 5414 * DESCRIPTION: timed wait for jpeg completion event, and send 5415 * back completion event to backend 5416 * 5417 * PARAMETERS : none 5418 * 5419 * RETURN : none 5420 *==========================================================================*/ 5421 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format) 5422 { 5423 bool bSendToBackend = true; 5424 cam_int_evt_params_t params; 5425 int rc = NO_ERROR; 5426 5427 struct timespec ts; 5428 struct timeval tp; 5429 gettimeofday(&tp, NULL); 5430 ts.tv_sec = tp.tv_sec + 5; 5431 ts.tv_nsec = tp.tv_usec * 1000; 5432 5433 if (true == m_bIntJpegEvtPending || 5434 (true == m_bIntRawEvtPending)) { 5435 //Waiting in HAL for snapshot taken notification 5436 pthread_mutex_lock(&m_int_lock); 5437 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts); 5438 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) { 5439 //Hit a timeout, or some spurious activity 5440 bSendToBackend = false; 5441 } 5442 5443 if (true == m_bIntJpegEvtPending) { 5444 params.event_type = 0; 5445 mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format); 5446 } else if (true == m_bIntRawEvtPending) { 5447 params.event_type = 1; 5448 mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format); 5449 } 5450 pthread_mutex_unlock(&m_int_lock); 5451 5452 if (true == m_bIntJpegEvtPending) { 5453 //Attempting to restart preview after taking JPEG snapshot 5454 lockAPI(); 5455 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 5456 unlockAPI(); 5457 m_postprocessor.setJpegMemOpt(JpegMemOpt); 5458 } else if (true == m_bIntRawEvtPending) { 5459 //Attempting to restart preview after taking RAW snapshot 5460 stopChannel(QCAMERA_CH_TYPE_RAW); 5461 delChannel(QCAMERA_CH_TYPE_RAW); 5462 //restoring the old raw format 5463 property_set("persist.camera.raw.format", raw_format); 5464 } 5465 5466 if (true == bSendToBackend) { 5467 //send event back to server with the file path 5468 params.dim = m_postprocessor.m_dst_dim; 5469 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH); 5470 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH); 5471 params.size = mBackendFileSize; 5472 rc = mParameters.setIntEvent(params); 5473 } 5474 5475 clearIntPendingEvents(); 5476 } 5477 5478 return; 5479 } 5480 5481 /*=========================================================================== 5482 * FUNCTION : takeBackendPic_internal 5483 * 5484 * DESCRIPTION: take snapshot triggered by backend 5485 * 5486 * PARAMETERS : none 5487 * 5488 * RETURN : int32_t type of status 5489 * NO_ERROR -- success 5490 * none-zero failure code 5491 *==========================================================================*/ 5492 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format) 5493 { 5494 int rc = NO_ERROR; 5495 qcamera_api_result_t apiResult; 5496 5497 lockAPI(); 5498 //Set rotation value from user settings as Jpeg rotation 5499 //to configure back-end modules. 5500 mParameters.setJpegRotation(mParameters.getRotation()); 5501 5502 setRetroPicture(0); 5503 /* Prepare snapshot in case LED needs to be flashed */ 5504 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) { 5505 // Start Preparing for normal Frames 5506 LOGH("Start Prepare Snapshot"); 5507 /* Prepare snapshot in case LED needs to be flashed */ 5508 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 5509 if (rc == NO_ERROR) { 5510 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 5511 rc = apiResult.status; 5512 } 5513 LOGH("Prep Snapshot done rc = %d", rc); 5514 mPrepSnapRun = true; 5515 } 5516 unlockAPI(); 5517 5518 if (true == m_bIntJpegEvtPending) { 5519 //Attempting to take JPEG snapshot 5520 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 5521 LOGE("Init PProc Deferred work failed"); 5522 return UNKNOWN_ERROR; 5523 } 5524 *JpegMemOpt = m_postprocessor.getJpegMemOpt(); 5525 m_postprocessor.setJpegMemOpt(false); 5526 5527 /* capture */ 5528 lockAPI(); 5529 LOGH("Capturing internal snapshot"); 5530 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 5531 if (rc == NO_ERROR) { 5532 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 5533 rc = apiResult.status; 5534 } 5535 unlockAPI(); 5536 } else if (true == m_bIntRawEvtPending) { 5537 //Attempting to take RAW snapshot 5538 (void)JpegMemOpt; 5539 stopPreview(); 5540 5541 //getting the existing raw format type 5542 property_get("persist.camera.raw.format", raw_format, "17"); 5543 //setting it to a default know value for this task 5544 property_set("persist.camera.raw.format", "18"); 5545 5546 rc = addChannel(QCAMERA_CH_TYPE_RAW); 5547 if (rc == NO_ERROR) { 5548 // start postprocessor 5549 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 5550 LOGE("Init PProc Deferred work failed"); 5551 return UNKNOWN_ERROR; 5552 } 5553 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 5554 if (rc != NO_ERROR) { 5555 LOGE("cannot start postprocessor"); 5556 delChannel(QCAMERA_CH_TYPE_RAW); 5557 return rc; 5558 } 5559 5560 rc = startChannel(QCAMERA_CH_TYPE_RAW); 5561 if (rc != NO_ERROR) { 5562 LOGE("cannot start raw channel"); 5563 m_postprocessor.stop(); 5564 delChannel(QCAMERA_CH_TYPE_RAW); 5565 return rc; 5566 } 5567 } else { 5568 LOGE("cannot add raw channel"); 5569 return rc; 5570 } 5571 } 5572 5573 return rc; 5574 } 5575 5576 /*=========================================================================== 5577 * FUNCTION : clearIntPendingEvents 5578 * 5579 * DESCRIPTION: clear internal pending events pertaining to backend 5580 * snapshot requests 5581 * 5582 * PARAMETERS : none 5583 * 5584 * RETURN : int32_t type of status 5585 * NO_ERROR -- success 5586 * none-zero failure code 5587 *==========================================================================*/ 5588 void QCamera2HardwareInterface::clearIntPendingEvents() 5589 { 5590 int rc = NO_ERROR; 5591 5592 if (true == m_bIntRawEvtPending) { 5593 preparePreview(); 5594 startPreview(); 5595 } 5596 if (true == m_bIntJpegEvtPending) { 5597 if (false == mParameters.isZSLMode()) { 5598 lockAPI(); 5599 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL); 5600 unlockAPI(); 5601 } 5602 } 5603 5604 pthread_mutex_lock(&m_int_lock); 5605 if (true == m_bIntJpegEvtPending) { 5606 m_bIntJpegEvtPending = false; 5607 } else if (true == m_bIntRawEvtPending) { 5608 m_bIntRawEvtPending = false; 5609 } 5610 pthread_mutex_unlock(&m_int_lock); 5611 return; 5612 } 5613 5614 /*=========================================================================== 5615 * FUNCTION : takeLiveSnapshot_internal 5616 * 5617 * DESCRIPTION: take live snapshot during recording 5618 * 5619 * PARAMETERS : none 5620 * 5621 * RETURN : int32_t type of status 5622 * NO_ERROR -- success 5623 * none-zero failure code 5624 *==========================================================================*/ 5625 int QCamera2HardwareInterface::takeLiveSnapshot_internal() 5626 { 5627 int rc = NO_ERROR; 5628 5629 QCameraChannel *pChannel = NULL; 5630 QCameraChannel *pPreviewChannel = NULL; 5631 QCameraStream *pPreviewStream = NULL; 5632 QCameraStream *pStream = NULL; 5633 5634 //Set rotation value from user settings as Jpeg rotation 5635 //to configure back-end modules. 5636 mParameters.setJpegRotation(mParameters.getRotation()); 5637 5638 // Configure advanced capture 5639 rc = configureAdvancedCapture(); 5640 if (rc != NO_ERROR) { 5641 LOGE("Unsupported capture call"); 5642 goto end; 5643 } 5644 5645 if (isLowPowerMode()) { 5646 pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO]; 5647 } else { 5648 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 5649 } 5650 5651 if (NULL == pChannel) { 5652 LOGE("Snapshot/Video channel not initialized"); 5653 rc = NO_INIT; 5654 goto end; 5655 } 5656 5657 // Check if all preview buffers are mapped before creating 5658 // a jpeg session as preview stream buffers are queried during the same 5659 pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 5660 if (pPreviewChannel != NULL) { 5661 uint32_t numStreams = pPreviewChannel->getNumOfStreams(); 5662 5663 for (uint8_t i = 0 ; i < numStreams ; i++ ) { 5664 pStream = pPreviewChannel->getStreamByIndex(i); 5665 if (!pStream) 5666 continue; 5667 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) { 5668 pPreviewStream = pStream; 5669 break; 5670 } 5671 } 5672 5673 if (pPreviewStream != NULL) { 5674 Mutex::Autolock l(mMapLock); 5675 QCameraMemory *pMemory = pStream->getStreamBufs(); 5676 if (!pMemory) { 5677 LOGE("Error!! pMemory is NULL"); 5678 return -ENOMEM; 5679 } 5680 5681 uint8_t waitCnt = 2; 5682 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) { 5683 LOGL(" Waiting for preview buffers to be mapped"); 5684 mMapCond.waitRelative( 5685 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT); 5686 LOGL("Wait completed!!"); 5687 waitCnt--; 5688 } 5689 // If all buffers are not mapped after retries, assert 5690 assert(pMemory->checkIfAllBuffersMapped()); 5691 } else { 5692 assert(pPreviewStream); 5693 } 5694 } 5695 5696 DeferWorkArgs args; 5697 memset(&args, 0, sizeof(DeferWorkArgs)); 5698 5699 args.pprocArgs = pChannel; 5700 5701 // No need to wait for mInitPProcJob here, because it was 5702 // queued in startPreview, and will definitely be processed before 5703 // mReprocJob can begin. 5704 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 5705 args); 5706 if (mReprocJob == 0) { 5707 LOGE("Failed to queue CMD_DEF_PPROC_START"); 5708 rc = -ENOMEM; 5709 goto end; 5710 } 5711 5712 // Create JPEG session 5713 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 5714 args); 5715 if (mJpegJob == 0) { 5716 LOGE("Failed to queue CREATE_JPEG_SESSION"); 5717 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5718 LOGE("Reprocess Deferred work was failed"); 5719 } 5720 m_postprocessor.stop(); 5721 rc = -ENOMEM; 5722 goto end; 5723 } 5724 5725 if (isLowPowerMode()) { 5726 mm_camera_req_buf_t buf; 5727 memset(&buf, 0x0, sizeof(buf)); 5728 buf.type = MM_CAMERA_REQ_SUPER_BUF; 5729 buf.num_buf_requested = 1; 5730 rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf); 5731 goto end; 5732 } 5733 5734 //Disable reprocess for 4K liveshot case 5735 if (!mParameters.is4k2kVideoResolution()) { 5736 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]); 5737 if (rc != NO_ERROR) { 5738 LOGE("online rotation failed"); 5739 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5740 LOGE("Reprocess Deferred work was failed"); 5741 } 5742 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 5743 LOGE("Jpeg Deferred work was failed"); 5744 } 5745 m_postprocessor.stop(); 5746 return rc; 5747 } 5748 } 5749 5750 if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) { 5751 QCameraStream *pStream = NULL; 5752 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) { 5753 pStream = pChannel->getStreamByIndex(i); 5754 if ((NULL != pStream) && 5755 (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) { 5756 break; 5757 } 5758 } 5759 if (pStream != NULL) { 5760 LOGD("REQUEST_FRAMES event for TNR snapshot"); 5761 cam_stream_parm_buffer_t param; 5762 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 5763 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES; 5764 param.frameRequest.enableStream = 1; 5765 rc = pStream->setParameter(param); 5766 if (rc != NO_ERROR) { 5767 LOGE("Stream Event REQUEST_FRAMES failed"); 5768 } 5769 goto end; 5770 } 5771 } 5772 5773 // start snapshot channel 5774 if ((rc == NO_ERROR) && (NULL != pChannel)) { 5775 // Do not link metadata stream for 4K2k resolution 5776 // as CPP processing would be done on snapshot stream and not 5777 // reprocess stream 5778 if (!mParameters.is4k2kVideoResolution()) { 5779 // Find and try to link a metadata stream from preview channel 5780 QCameraChannel *pMetaChannel = NULL; 5781 QCameraStream *pMetaStream = NULL; 5782 QCameraStream *pPreviewStream = NULL; 5783 5784 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 5785 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 5786 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 5787 QCameraStream *pStream = NULL; 5788 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 5789 pStream = pMetaChannel->getStreamByIndex(i); 5790 if (NULL != pStream) { 5791 if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) { 5792 pMetaStream = pStream; 5793 } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) 5794 && (!mParameters.isHfrMode())) { 5795 // Do not link preview stream for HFR live snapshot. 5796 // Thumbnail will not be derived from preview for HFR live snapshot. 5797 pPreviewStream = pStream; 5798 } 5799 } 5800 } 5801 } 5802 5803 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 5804 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 5805 if (NO_ERROR != rc) { 5806 LOGE("Metadata stream link failed %d", rc); 5807 } 5808 } 5809 if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) { 5810 rc = pChannel->linkStream(pMetaChannel, pPreviewStream); 5811 if (NO_ERROR != rc) { 5812 LOGE("Preview stream link failed %d", rc); 5813 } 5814 } 5815 } 5816 rc = pChannel->start(); 5817 } 5818 5819 end: 5820 if (rc != NO_ERROR) { 5821 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 5822 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 5823 } 5824 return rc; 5825 } 5826 5827 /*=========================================================================== 5828 * FUNCTION : cancelLiveSnapshot 5829 * 5830 * DESCRIPTION: cancel current live snapshot request 5831 * 5832 * PARAMETERS : none 5833 * 5834 * RETURN : int32_t type of status 5835 * NO_ERROR -- success 5836 * none-zero failure code 5837 *==========================================================================*/ 5838 int QCamera2HardwareInterface::cancelLiveSnapshot() 5839 { 5840 int rc = NO_ERROR; 5841 if (mLiveSnapshotThread != 0) { 5842 pthread_join(mLiveSnapshotThread,NULL); 5843 mLiveSnapshotThread = 0; 5844 } 5845 bLiveSnapshot = false; 5846 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this); 5847 if (!rc) { 5848 pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap"); 5849 } 5850 return rc; 5851 } 5852 5853 /*=========================================================================== 5854 * FUNCTION : cancelLiveSnapshot_internal 5855 * 5856 * DESCRIPTION: cancel live snapshot during recording 5857 * 5858 * PARAMETERS : none 5859 * 5860 * RETURN : int32_t type of status 5861 * NO_ERROR -- success 5862 * none-zero failure code 5863 *==========================================================================*/ 5864 int QCamera2HardwareInterface::cancelLiveSnapshot_internal() { 5865 int rc = NO_ERROR; 5866 5867 unconfigureAdvancedCapture(); 5868 LOGH("Enable display frames again"); 5869 setDisplaySkip(FALSE); 5870 5871 if (!mLongshotEnabled) { 5872 m_perfLock.lock_rel(); 5873 } 5874 5875 //stop post processor 5876 m_postprocessor.stop(); 5877 5878 // stop snapshot channel 5879 if (!mParameters.isTNRSnapshotEnabled()) { 5880 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT); 5881 } else { 5882 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 5883 if (NULL != pChannel) { 5884 QCameraStream *pStream = NULL; 5885 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) { 5886 pStream = pChannel->getStreamByIndex(i); 5887 if ((NULL != pStream) && 5888 (CAM_STREAM_TYPE_SNAPSHOT == 5889 pStream->getMyType())) { 5890 break; 5891 } 5892 } 5893 if (pStream != NULL) { 5894 LOGD("REQUEST_FRAMES event for TNR snapshot"); 5895 cam_stream_parm_buffer_t param; 5896 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 5897 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES; 5898 param.frameRequest.enableStream = 0; 5899 rc = pStream->setParameter(param); 5900 if (rc != NO_ERROR) { 5901 LOGE("Stream Event REQUEST_FRAMES failed"); 5902 } 5903 } 5904 } 5905 } 5906 5907 return rc; 5908 } 5909 5910 /*=========================================================================== 5911 * FUNCTION : putParameters 5912 * 5913 * DESCRIPTION: put parameters string impl 5914 * 5915 * PARAMETERS : 5916 * @parms : parameters string to be released 5917 * 5918 * RETURN : int32_t type of status 5919 * NO_ERROR -- success 5920 * none-zero failure code 5921 *==========================================================================*/ 5922 int QCamera2HardwareInterface::putParameters(char *parms) 5923 { 5924 free(parms); 5925 return NO_ERROR; 5926 } 5927 5928 /*=========================================================================== 5929 * FUNCTION : sendCommand 5930 * 5931 * DESCRIPTION: send command impl 5932 * 5933 * PARAMETERS : 5934 * @command : command to be executed 5935 * @arg1 : optional argument 1 5936 * @arg2 : optional argument 2 5937 * 5938 * RETURN : int32_t type of status 5939 * NO_ERROR -- success 5940 * none-zero failure code 5941 *==========================================================================*/ 5942 int QCamera2HardwareInterface::sendCommand(int32_t command, 5943 __unused int32_t &arg1, __unused int32_t &arg2) 5944 { 5945 int rc = NO_ERROR; 5946 5947 switch (command) { 5948 #ifndef VANILLA_HAL 5949 case CAMERA_CMD_LONGSHOT_ON: 5950 m_perfLock.lock_acq(); 5951 arg1 = arg2 = 0; 5952 // Longshot can only be enabled when image capture 5953 // is not active. 5954 if ( !m_stateMachine.isCaptureRunning() ) { 5955 LOGI("Longshot Enabled"); 5956 mLongshotEnabled = true; 5957 rc = mParameters.setLongshotEnable(mLongshotEnabled); 5958 5959 // Due to recent buffer count optimizations 5960 // ZSL might run with considerably less buffers 5961 // when not in longshot mode. Preview needs to 5962 // restart in this case. 5963 if (isZSLMode() && m_stateMachine.isPreviewRunning()) { 5964 QCameraChannel *pChannel = NULL; 5965 QCameraStream *pSnapStream = NULL; 5966 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 5967 if (NULL != pChannel) { 5968 QCameraStream *pStream = NULL; 5969 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) { 5970 pStream = pChannel->getStreamByIndex(i); 5971 if (pStream != NULL) { 5972 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 5973 pSnapStream = pStream; 5974 break; 5975 } 5976 } 5977 } 5978 if (NULL != pSnapStream) { 5979 uint8_t required = 0; 5980 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT); 5981 if (pSnapStream->getBufferCount() < required) { 5982 // We restart here, to reset the FPS and no 5983 // of buffers as per the requirement of longshot usecase. 5984 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW; 5985 if (getRelatedCamSyncInfo()->sync_control == 5986 CAM_SYNC_RELATED_SENSORS_ON) { 5987 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART; 5988 } 5989 } 5990 } 5991 } 5992 } 5993 // 5994 mPrepSnapRun = false; 5995 mCACDoneReceived = FALSE; 5996 } else { 5997 rc = NO_INIT; 5998 } 5999 break; 6000 case CAMERA_CMD_LONGSHOT_OFF: 6001 m_perfLock.lock_rel(); 6002 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) { 6003 cancelPicture(); 6004 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 6005 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 6006 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) { 6007 mCameraHandle->ops->stop_zsl_snapshot( 6008 mCameraHandle->camera_handle, 6009 pZSLChannel->getMyHandle()); 6010 } 6011 } 6012 mPrepSnapRun = false; 6013 LOGI("Longshot Disabled"); 6014 mLongshotEnabled = false; 6015 rc = mParameters.setLongshotEnable(mLongshotEnabled); 6016 mCACDoneReceived = FALSE; 6017 break; 6018 case CAMERA_CMD_HISTOGRAM_ON: 6019 case CAMERA_CMD_HISTOGRAM_OFF: 6020 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false); 6021 LOGH("Histogram -> %s", 6022 mParameters.isHistogramEnabled() ? "Enabled" : "Disabled"); 6023 break; 6024 #endif 6025 case CAMERA_CMD_START_FACE_DETECTION: 6026 case CAMERA_CMD_STOP_FACE_DETECTION: 6027 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 6028 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 6029 LOGH("FaceDetection -> %s", 6030 mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled"); 6031 break; 6032 #ifndef VANILLA_HAL 6033 case CAMERA_CMD_HISTOGRAM_SEND_DATA: 6034 #endif 6035 default: 6036 rc = NO_ERROR; 6037 break; 6038 } 6039 return rc; 6040 } 6041 6042 /*=========================================================================== 6043 * FUNCTION : registerFaceImage 6044 * 6045 * DESCRIPTION: register face image impl 6046 * 6047 * PARAMETERS : 6048 * @img_ptr : ptr to image buffer 6049 * @config : ptr to config struct about input image info 6050 * @faceID : [OUT] face ID to uniquely identifiy the registered face image 6051 * 6052 * RETURN : int32_t type of status 6053 * NO_ERROR -- success 6054 * none-zero failure code 6055 *==========================================================================*/ 6056 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr, 6057 cam_pp_offline_src_config_t *config, 6058 int32_t &faceID) 6059 { 6060 int rc = NO_ERROR; 6061 faceID = -1; 6062 6063 if (img_ptr == NULL || config == NULL) { 6064 LOGE("img_ptr or config is NULL"); 6065 return BAD_VALUE; 6066 } 6067 6068 // allocate ion memory for source image 6069 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 6070 if (imgBuf == NULL) { 6071 LOGE("Unable to new heap memory obj for image buf"); 6072 return NO_MEMORY; 6073 } 6074 6075 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE); 6076 if (rc < 0) { 6077 LOGE("Unable to allocate heap memory for image buf"); 6078 delete imgBuf; 6079 return NO_MEMORY; 6080 } 6081 6082 void *pBufPtr = imgBuf->getPtr(0); 6083 if (pBufPtr == NULL) { 6084 LOGE("image buf is NULL"); 6085 imgBuf->deallocate(); 6086 delete imgBuf; 6087 return NO_MEMORY; 6088 } 6089 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len); 6090 6091 cam_pp_feature_config_t pp_feature; 6092 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t)); 6093 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE; 6094 QCameraReprocessChannel *pChannel = 6095 addOfflineReprocChannel(*config, pp_feature, NULL, NULL); 6096 6097 if (pChannel == NULL) { 6098 LOGE("fail to add offline reprocess channel"); 6099 imgBuf->deallocate(); 6100 delete imgBuf; 6101 return UNKNOWN_ERROR; 6102 } 6103 6104 rc = pChannel->start(); 6105 if (rc != NO_ERROR) { 6106 LOGE("Cannot start reprocess channel"); 6107 imgBuf->deallocate(); 6108 delete imgBuf; 6109 delete pChannel; 6110 return rc; 6111 } 6112 6113 ssize_t bufSize = imgBuf->getSize(0); 6114 if (BAD_INDEX != bufSize) { 6115 rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0), 6116 (size_t)bufSize, faceID); 6117 } else { 6118 LOGE("Failed to retrieve buffer size (bad index)"); 6119 return UNKNOWN_ERROR; 6120 } 6121 6122 // done with register face image, free imgbuf and delete reprocess channel 6123 imgBuf->deallocate(); 6124 delete imgBuf; 6125 imgBuf = NULL; 6126 pChannel->stop(); 6127 delete pChannel; 6128 pChannel = NULL; 6129 6130 return rc; 6131 } 6132 6133 /*=========================================================================== 6134 * FUNCTION : release 6135 * 6136 * DESCRIPTION: release camera resource impl 6137 * 6138 * PARAMETERS : none 6139 * 6140 * RETURN : int32_t type of status 6141 * NO_ERROR -- success 6142 * none-zero failure code 6143 *==========================================================================*/ 6144 int QCamera2HardwareInterface::release() 6145 { 6146 // stop and delete all channels 6147 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) { 6148 if (m_channels[i] != NULL) { 6149 stopChannel((qcamera_ch_type_enum_t)i); 6150 delChannel((qcamera_ch_type_enum_t)i); 6151 } 6152 } 6153 6154 return NO_ERROR; 6155 } 6156 6157 /*=========================================================================== 6158 * FUNCTION : dump 6159 * 6160 * DESCRIPTION: camera status dump impl 6161 * 6162 * PARAMETERS : 6163 * @fd : fd for the buffer to be dumped with camera status 6164 * 6165 * RETURN : int32_t type of status 6166 * NO_ERROR -- success 6167 * none-zero failure code 6168 *==========================================================================*/ 6169 int QCamera2HardwareInterface::dump(int fd) 6170 { 6171 dprintf(fd, "\n Camera HAL information Begin \n"); 6172 dprintf(fd, "Camera ID: %d \n", mCameraId); 6173 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame); 6174 dprintf(fd, "\n Configuration: %s", mParameters.dump().string()); 6175 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string()); 6176 dprintf(fd, "\n Camera HAL information End \n"); 6177 6178 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the 6179 debug level property */ 6180 mParameters.updateDebugLevel(); 6181 return NO_ERROR; 6182 } 6183 6184 /*=========================================================================== 6185 * FUNCTION : processAPI 6186 * 6187 * DESCRIPTION: process API calls from upper layer 6188 * 6189 * PARAMETERS : 6190 * @api : API to be processed 6191 * @api_payload : ptr to API payload if any 6192 * 6193 * RETURN : int32_t type of status 6194 * NO_ERROR -- success 6195 * none-zero failure code 6196 *==========================================================================*/ 6197 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload) 6198 { 6199 int ret = DEAD_OBJECT; 6200 6201 if (m_smThreadActive) { 6202 ret = m_stateMachine.procAPI(api, api_payload); 6203 } 6204 6205 return ret; 6206 } 6207 6208 /*=========================================================================== 6209 * FUNCTION : processEvt 6210 * 6211 * DESCRIPTION: process Evt from backend via mm-camera-interface 6212 * 6213 * PARAMETERS : 6214 * @evt : event type to be processed 6215 * @evt_payload : ptr to event payload if any 6216 * 6217 * RETURN : int32_t type of status 6218 * NO_ERROR -- success 6219 * none-zero failure code 6220 *==========================================================================*/ 6221 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 6222 { 6223 return m_stateMachine.procEvt(evt, evt_payload); 6224 } 6225 6226 /*=========================================================================== 6227 * FUNCTION : processSyncEvt 6228 * 6229 * DESCRIPTION: process synchronous Evt from backend 6230 * 6231 * PARAMETERS : 6232 * @evt : event type to be processed 6233 * @evt_payload : ptr to event payload if any 6234 * 6235 * RETURN : int32_t type of status 6236 * NO_ERROR -- success 6237 * none-zero failure code 6238 *==========================================================================*/ 6239 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 6240 { 6241 int rc = NO_ERROR; 6242 6243 pthread_mutex_lock(&m_evtLock); 6244 rc = processEvt(evt, evt_payload); 6245 if (rc == NO_ERROR) { 6246 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 6247 while (m_evtResult.request_api != evt) { 6248 pthread_cond_wait(&m_evtCond, &m_evtLock); 6249 } 6250 rc = m_evtResult.status; 6251 } 6252 pthread_mutex_unlock(&m_evtLock); 6253 6254 return rc; 6255 } 6256 6257 /*=========================================================================== 6258 * FUNCTION : evtHandle 6259 * 6260 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events 6261 * 6262 * PARAMETERS : 6263 * @camera_handle : event type to be processed 6264 * @evt : ptr to event 6265 * @user_data : user data ptr 6266 * 6267 * RETURN : none 6268 *==========================================================================*/ 6269 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/, 6270 mm_camera_event_t *evt, 6271 void *user_data) 6272 { 6273 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data; 6274 if (obj && evt) { 6275 mm_camera_event_t *payload = 6276 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t)); 6277 if (NULL != payload) { 6278 *payload = *evt; 6279 //peek into the event, if this is an eztune event from server, 6280 //then we don't need to post it to the SM Qs, we shud directly 6281 //spawn a thread and get the job done (jpeg or raw snapshot) 6282 switch (payload->server_event_type) { 6283 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 6284 //Received JPEG trigger from eztune 6285 if (false == obj->m_bIntJpegEvtPending) { 6286 pthread_mutex_lock(&obj->m_int_lock); 6287 obj->m_bIntJpegEvtPending = true; 6288 pthread_mutex_unlock(&obj->m_int_lock); 6289 obj->takePictureInternal(); 6290 } 6291 free(payload); 6292 break; 6293 case CAM_EVENT_TYPE_INT_TAKE_RAW: 6294 //Received RAW trigger from eztune 6295 if (false == obj->m_bIntRawEvtPending) { 6296 pthread_mutex_lock(&obj->m_int_lock); 6297 obj->m_bIntRawEvtPending = true; 6298 pthread_mutex_unlock(&obj->m_int_lock); 6299 obj->takePictureInternal(); 6300 } 6301 free(payload); 6302 break; 6303 case CAM_EVENT_TYPE_DAEMON_DIED: 6304 { 6305 Mutex::Autolock l(obj->mDefLock); 6306 obj->mDefCond.broadcast(); 6307 LOGH("broadcast mDefCond signal\n"); 6308 } 6309 default: 6310 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload); 6311 break; 6312 } 6313 } 6314 } else { 6315 LOGE("NULL user_data"); 6316 } 6317 } 6318 6319 /*=========================================================================== 6320 * FUNCTION : jpegEvtHandle 6321 * 6322 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events 6323 * 6324 * PARAMETERS : 6325 * @status : status of jpeg job 6326 * @client_hdl: jpeg client handle 6327 * @jobId : jpeg job Id 6328 * @p_ouput : ptr to jpeg output result struct 6329 * @userdata : user data ptr 6330 * 6331 * RETURN : none 6332 *==========================================================================*/ 6333 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status, 6334 uint32_t /*client_hdl*/, 6335 uint32_t jobId, 6336 mm_jpeg_output_t *p_output, 6337 void *userdata) 6338 { 6339 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata; 6340 if (obj) { 6341 qcamera_jpeg_evt_payload_t *payload = 6342 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t)); 6343 if (NULL != payload) { 6344 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t)); 6345 payload->status = status; 6346 payload->jobId = jobId; 6347 if (p_output != NULL) { 6348 payload->out_data = *p_output; 6349 } 6350 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload); 6351 } 6352 } else { 6353 LOGE("NULL user_data"); 6354 } 6355 } 6356 6357 /*=========================================================================== 6358 * FUNCTION : thermalEvtHandle 6359 * 6360 * DESCRIPTION: routine to handle thermal event notification 6361 * 6362 * PARAMETERS : 6363 * @level : thermal level 6364 * @userdata : userdata passed in during registration 6365 * @data : opaque data from thermal client 6366 * 6367 * RETURN : int32_t type of status 6368 * NO_ERROR -- success 6369 * none-zero failure code 6370 *==========================================================================*/ 6371 int QCamera2HardwareInterface::thermalEvtHandle( 6372 qcamera_thermal_level_enum_t *level, void *userdata, void *data) 6373 { 6374 if (!mCameraOpened) { 6375 LOGH("Camera is not opened, no need to handle thermal evt"); 6376 return NO_ERROR; 6377 } 6378 6379 // Make sure thermal events are logged 6380 LOGH("level = %d, userdata = %p, data = %p", 6381 *level, userdata, data); 6382 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY 6383 // becomes an aync call. This also means we can only pass payload 6384 // by value, not by address. 6385 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level); 6386 } 6387 6388 /*=========================================================================== 6389 * FUNCTION : sendEvtNotify 6390 * 6391 * DESCRIPTION: send event notify to notify thread 6392 * 6393 * PARAMETERS : 6394 * @msg_type: msg type to be sent 6395 * @ext1 : optional extension1 6396 * @ext2 : optional extension2 6397 * 6398 * RETURN : int32_t type of status 6399 * NO_ERROR -- success 6400 * none-zero failure code 6401 *==========================================================================*/ 6402 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type, 6403 int32_t ext1, 6404 int32_t ext2) 6405 { 6406 qcamera_callback_argm_t cbArg; 6407 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6408 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 6409 cbArg.msg_type = msg_type; 6410 cbArg.ext1 = ext1; 6411 cbArg.ext2 = ext2; 6412 return m_cbNotifier.notifyCallback(cbArg); 6413 } 6414 6415 /*=========================================================================== 6416 * FUNCTION : processAEInfo 6417 * 6418 * DESCRIPTION: process AE updates 6419 * 6420 * PARAMETERS : 6421 * @ae_params: current AE parameters 6422 * 6423 * RETURN : None 6424 *==========================================================================*/ 6425 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params) 6426 { 6427 mParameters.updateAEInfo(ae_params); 6428 if (mParameters.isInstantAECEnabled()) { 6429 // Reset Instant AEC info only if instant aec enabled. 6430 bool bResetInstantAec = false; 6431 if (ae_params.settled) { 6432 // If AEC settled, reset instant AEC 6433 bResetInstantAec = true; 6434 } else if ((mParameters.isInstantCaptureEnabled()) && 6435 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) { 6436 // if AEC not settled, and instant capture enabled, 6437 // reset instant AEC only when frame count is 6438 // more or equal to AEC frame bound value. 6439 bResetInstantAec = true; 6440 } else if ((mParameters.isInstantAECEnabled()) && 6441 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) { 6442 // if AEC not settled, and only instant AEC enabled, 6443 // reset instant AEC only when frame count is 6444 // more or equal to AEC skip display frame bound value. 6445 bResetInstantAec = true; 6446 } 6447 6448 if (bResetInstantAec) { 6449 LOGD("setting instant AEC to false"); 6450 mParameters.setInstantAEC(false, true); 6451 mInstantAecFrameCount = 0; 6452 } 6453 } 6454 return NO_ERROR; 6455 } 6456 6457 /*=========================================================================== 6458 * FUNCTION : processFocusPositionInfo 6459 * 6460 * DESCRIPTION: process AF updates 6461 * 6462 * PARAMETERS : 6463 * @cur_pos_info: current lens position 6464 * 6465 * RETURN : None 6466 *==========================================================================*/ 6467 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info) 6468 { 6469 mParameters.updateCurrentFocusPosition(cur_pos_info); 6470 return NO_ERROR; 6471 } 6472 6473 /*=========================================================================== 6474 * FUNCTION : processAutoFocusEvent 6475 * 6476 * DESCRIPTION: process auto focus event 6477 * 6478 * PARAMETERS : 6479 * @focus_data: struct containing auto focus result info 6480 * 6481 * RETURN : int32_t type of status 6482 * NO_ERROR -- success 6483 * none-zero failure code 6484 *==========================================================================*/ 6485 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data) 6486 { 6487 int32_t ret = NO_ERROR; 6488 LOGH("E"); 6489 6490 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) { 6491 // Ignore focus updates 6492 LOGH("X Secondary Camera, no need to process!! "); 6493 return ret; 6494 } 6495 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 6496 LOGH("[AF_DBG] focusMode=%d, focusState=%d isDepth=%d", 6497 focusMode, focus_data.focus_state, focus_data.isDepth); 6498 6499 switch (focusMode) { 6500 case CAM_FOCUS_MODE_AUTO: 6501 case CAM_FOCUS_MODE_MACRO: 6502 // ignore AF event if AF was already cancelled meanwhile 6503 if (!mActiveAF) { 6504 break; 6505 } 6506 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app 6507 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 6508 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6509 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 6510 mActiveAF = false; // reset the mActiveAF in this special case 6511 break; 6512 } 6513 6514 //while transitioning from CAF->Auto/Macro, we might receive CAF related 6515 //events (PASSIVE_*) due to timing. Ignore such events if any. 6516 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) || 6517 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6518 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) { 6519 break; 6520 } 6521 6522 //This is just an intermediate update to HAL indicating focus is in progress. No need 6523 //to send this event to app. Same applies to INACTIVE state as well. 6524 if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) || 6525 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6526 break; 6527 } 6528 // update focus distance 6529 mParameters.updateFocusDistances(&focus_data.focus_dist); 6530 6531 //flush any old snapshot frames in ZSL Q which are not focused. 6532 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) { 6533 QCameraPicChannel *pZSLChannel = 6534 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 6535 if (NULL != pZSLChannel) { 6536 //flush the zsl-buffer 6537 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx; 6538 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx); 6539 pZSLChannel->flushSuperbuffer(flush_frame_idx); 6540 } 6541 } 6542 6543 //send event to app finally 6544 LOGI("Send AF DOne event to app"); 6545 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 6546 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0); 6547 break; 6548 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 6549 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 6550 6551 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app 6552 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 6553 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6554 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0); 6555 mActiveAF = false; // reset the mActiveAF in this special case 6556 break; 6557 } 6558 6559 //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and 6560 //process/wait for only ACTIVE_* events. 6561 if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6562 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) || 6563 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) { 6564 break; 6565 } 6566 6567 if (!bDepthAFCallbacks && focus_data.isDepth && 6568 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) { 6569 LOGD("Skip sending scan state to app, if depth focus"); 6570 break; 6571 } 6572 6573 //These are the AF states for which we need to send notification to app in CAF mode. 6574 //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case 6575 //AF is triggered while in CAF mode) 6576 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6577 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) || 6578 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) || 6579 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) { 6580 6581 // update focus distance 6582 mParameters.updateFocusDistances(&focus_data.focus_dist); 6583 6584 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) { 6585 QCameraPicChannel *pZSLChannel = 6586 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 6587 if (NULL != pZSLChannel) { 6588 //flush the zsl-buffer 6589 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx; 6590 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx); 6591 pZSLChannel->flushSuperbuffer(flush_frame_idx); 6592 } 6593 } 6594 6595 if (mActiveAF) { 6596 LOGI("Send AF Done event to app"); 6597 } 6598 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 6599 ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6600 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0); 6601 } 6602 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE, 6603 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0); 6604 break; 6605 case CAM_FOCUS_MODE_INFINITY: 6606 case CAM_FOCUS_MODE_FIXED: 6607 case CAM_FOCUS_MODE_EDOF: 6608 default: 6609 LOGH("no ops for autofocus event in focusmode %d", focusMode); 6610 break; 6611 } 6612 6613 //Reset mActiveAF once we receive focus done event 6614 if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) || 6615 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) { 6616 mActiveAF = false; 6617 } 6618 6619 LOGH("X"); 6620 return ret; 6621 } 6622 6623 /*=========================================================================== 6624 * FUNCTION : processZoomEvent 6625 * 6626 * DESCRIPTION: process zoom event 6627 * 6628 * PARAMETERS : 6629 * @crop_info : crop info as a result of zoom operation 6630 * 6631 * RETURN : int32_t type of status 6632 * NO_ERROR -- success 6633 * none-zero failure code 6634 *==========================================================================*/ 6635 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info) 6636 { 6637 int32_t ret = NO_ERROR; 6638 6639 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 6640 if (m_channels[i] != NULL) { 6641 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info); 6642 } 6643 } 6644 return ret; 6645 } 6646 6647 /*=========================================================================== 6648 * FUNCTION : processZSLCaptureDone 6649 * 6650 * DESCRIPTION: process ZSL capture done events 6651 * 6652 * PARAMETERS : None 6653 * 6654 * RETURN : int32_t type of status 6655 * NO_ERROR -- success 6656 * none-zero failure code 6657 *==========================================================================*/ 6658 int32_t QCamera2HardwareInterface::processZSLCaptureDone() 6659 { 6660 int rc = NO_ERROR; 6661 6662 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) { 6663 rc = unconfigureAdvancedCapture(); 6664 } 6665 6666 return rc; 6667 } 6668 6669 /*=========================================================================== 6670 * FUNCTION : processRetroAECUnlock 6671 * 6672 * DESCRIPTION: process retro burst AEC unlock events 6673 * 6674 * PARAMETERS : None 6675 * 6676 * RETURN : int32_t type of status 6677 * NO_ERROR -- success 6678 * none-zero failure code 6679 *==========================================================================*/ 6680 int32_t QCamera2HardwareInterface::processRetroAECUnlock() 6681 { 6682 int rc = NO_ERROR; 6683 6684 LOGH("LED assisted AF Release AEC Lock"); 6685 rc = mParameters.setAecLock("false"); 6686 if (NO_ERROR != rc) { 6687 LOGE("Error setting AEC lock"); 6688 return rc; 6689 } 6690 6691 rc = mParameters.commitParameters(); 6692 if (NO_ERROR != rc) { 6693 LOGE("Error during camera parameter commit"); 6694 } else { 6695 m_bLedAfAecLock = FALSE; 6696 } 6697 6698 return rc; 6699 } 6700 6701 /*=========================================================================== 6702 * FUNCTION : processHDRData 6703 * 6704 * DESCRIPTION: process HDR scene events 6705 * 6706 * PARAMETERS : 6707 * @hdr_scene : HDR scene event data 6708 * 6709 * RETURN : int32_t type of status 6710 * NO_ERROR -- success 6711 * none-zero failure code 6712 *==========================================================================*/ 6713 int32_t QCamera2HardwareInterface::processHDRData( 6714 __unused cam_asd_hdr_scene_data_t hdr_scene) 6715 { 6716 int rc = NO_ERROR; 6717 6718 #ifndef VANILLA_HAL 6719 if (hdr_scene.is_hdr_scene && 6720 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) && 6721 mParameters.isAutoHDREnabled()) { 6722 m_HDRSceneEnabled = true; 6723 } else { 6724 m_HDRSceneEnabled = false; 6725 } 6726 mParameters.setHDRSceneEnable(m_HDRSceneEnabled); 6727 6728 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) { 6729 6730 size_t data_len = sizeof(int); 6731 size_t buffer_len = 1 *sizeof(int) //meta type 6732 + 1 *sizeof(int) //data len 6733 + 1 *sizeof(int); //data 6734 camera_memory_t *hdrBuffer = mGetMemory(-1, 6735 buffer_len, 6736 1, 6737 mCallbackCookie); 6738 if ( NULL == hdrBuffer ) { 6739 LOGE("Not enough memory for auto HDR data"); 6740 return NO_MEMORY; 6741 } 6742 6743 int *pHDRData = (int *)hdrBuffer->data; 6744 if (pHDRData == NULL) { 6745 LOGE("memory data ptr is NULL"); 6746 return UNKNOWN_ERROR; 6747 } 6748 6749 pHDRData[0] = CAMERA_META_DATA_HDR; 6750 pHDRData[1] = (int)data_len; 6751 pHDRData[2] = m_HDRSceneEnabled; 6752 6753 qcamera_callback_argm_t cbArg; 6754 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6755 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6756 cbArg.msg_type = CAMERA_MSG_META_DATA; 6757 cbArg.data = hdrBuffer; 6758 cbArg.user_data = hdrBuffer; 6759 cbArg.cookie = this; 6760 cbArg.release_cb = releaseCameraMemory; 6761 rc = m_cbNotifier.notifyCallback(cbArg); 6762 if (rc != NO_ERROR) { 6763 LOGE("fail sending auto HDR notification"); 6764 hdrBuffer->release(hdrBuffer); 6765 } 6766 } 6767 6768 LOGH("hdr_scene_data: processHDRData: %d %f", 6769 hdr_scene.is_hdr_scene, 6770 hdr_scene.hdr_confidence); 6771 6772 #endif 6773 return rc; 6774 } 6775 6776 /*=========================================================================== 6777 * FUNCTION : transAwbMetaToParams 6778 * 6779 * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf 6780 * 6781 * PARAMETERS : 6782 * @awb_params : awb params from metadata callback 6783 * 6784 * RETURN : int32_t type of status 6785 * NO_ERROR -- success 6786 * none-zero failure code 6787 *==========================================================================*/ 6788 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params) 6789 { 6790 mParameters.updateAWBParams(awb_params); 6791 return NO_ERROR; 6792 } 6793 6794 /*=========================================================================== 6795 * FUNCTION : processPrepSnapshotDone 6796 * 6797 * DESCRIPTION: process prep snapshot done event 6798 * 6799 * PARAMETERS : 6800 * @prep_snapshot_state : state of prepare snapshot done. In other words, 6801 * i.e. whether need future frames for capture. 6802 * 6803 * RETURN : int32_t type of status 6804 * NO_ERROR -- success 6805 * none-zero failure code 6806 *==========================================================================*/ 6807 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent( 6808 cam_prep_snapshot_state_t prep_snapshot_state) 6809 { 6810 int32_t ret = NO_ERROR; 6811 LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d", 6812 prep_snapshot_state); 6813 if (m_channels[QCAMERA_CH_TYPE_ZSL] && 6814 prep_snapshot_state == NEED_FUTURE_FRAME) { 6815 LOGH("already handled in mm-camera-intf, no ops here"); 6816 if (isRetroPicture()) { 6817 mParameters.setAecLock("true"); 6818 mParameters.commitParameters(); 6819 m_bLedAfAecLock = TRUE; 6820 } 6821 } 6822 return ret; 6823 } 6824 6825 /*=========================================================================== 6826 * FUNCTION : processASDUpdate 6827 * 6828 * DESCRIPTION: process ASD update event 6829 * 6830 * PARAMETERS : 6831 * @scene: selected scene mode 6832 * 6833 * RETURN : int32_t type of status 6834 * NO_ERROR -- success 6835 * none-zero failure code 6836 *==========================================================================*/ 6837 int32_t QCamera2HardwareInterface::processASDUpdate( 6838 __unused cam_asd_decision_t asd_decision) 6839 { 6840 #ifndef VANILLA_HAL 6841 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) { 6842 size_t data_len = sizeof(cam_auto_scene_t); 6843 size_t buffer_len = 1 *sizeof(int) //meta type 6844 + 1 *sizeof(int) //data len 6845 + data_len; //data 6846 camera_memory_t *asdBuffer = mGetMemory(-1, 6847 buffer_len, 1, mCallbackCookie); 6848 if ( NULL == asdBuffer ) { 6849 LOGE("Not enough memory for histogram data"); 6850 return NO_MEMORY; 6851 } 6852 6853 int *pASDData = (int *)asdBuffer->data; 6854 if (pASDData == NULL) { 6855 LOGE("memory data ptr is NULL"); 6856 return UNKNOWN_ERROR; 6857 } 6858 6859 pASDData[0] = CAMERA_META_DATA_ASD; 6860 pASDData[1] = (int)data_len; 6861 pASDData[2] = asd_decision.detected_scene; 6862 6863 qcamera_callback_argm_t cbArg; 6864 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6865 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6866 cbArg.msg_type = CAMERA_MSG_META_DATA; 6867 cbArg.data = asdBuffer; 6868 cbArg.user_data = asdBuffer; 6869 cbArg.cookie = this; 6870 cbArg.release_cb = releaseCameraMemory; 6871 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 6872 if (rc != NO_ERROR) { 6873 LOGE("fail sending notification"); 6874 asdBuffer->release(asdBuffer); 6875 } 6876 } 6877 #endif 6878 return NO_ERROR; 6879 } 6880 6881 /*=========================================================================== 6882 * FUNCTION : processJpegNotify 6883 * 6884 * DESCRIPTION: process jpeg event 6885 * 6886 * PARAMETERS : 6887 * @jpeg_evt: ptr to jpeg event payload 6888 * 6889 * RETURN : int32_t type of status 6890 * NO_ERROR -- success 6891 * none-zero failure code 6892 *==========================================================================*/ 6893 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt) 6894 { 6895 return m_postprocessor.processJpegEvt(jpeg_evt); 6896 } 6897 6898 6899 /*=========================================================================== 6900 * FUNCTION : processDCFOVControl 6901 * 6902 * DESCRIPTION: Fill Dual camera FOV control 6903 * 6904 * PARAMETERS : none 6905 * 6906 * RETURN : int32_t type of status 6907 * NO_ERROR -- success 6908 * none-zero failure code 6909 *==========================================================================*/ 6910 int32_t QCamera2HardwareInterface::processDCFOVControl() 6911 { 6912 int32_t zoomLevel; 6913 uint32_t camState = mActiveCamera; 6914 6915 if (!isDualCamera()) { 6916 return NO_ERROR; 6917 } 6918 6919 /*FOV control block needs to integrated here to decide dual camera 6920 switch operation. 6921 We can access application parameter, metadata buffer, 6922 parameter buffer used for back-end here*/ 6923 zoomLevel = mParameters.getParmZoomLevel(); 6924 if (zoomLevel < 20) { 6925 //WIDE Zone 6926 LOGH("WIDE ZONE : %d and %d", zoomLevel, prev_zoomLevel); 6927 if (camState & MM_CAMERA_TYPE_AUX) { 6928 //Suspend Aux 6929 camState &= (~MM_CAMERA_TYPE_AUX); 6930 } 6931 if (!(camState & MM_CAMERA_TYPE_MAIN)) { 6932 //Activate Main 6933 camState |= MM_CAMERA_TYPE_MAIN; 6934 } 6935 } else if (zoomLevel > 60) { 6936 //TELE Zone 6937 LOGH("TELE ZONE : %d and %d", zoomLevel, prev_zoomLevel); 6938 if (!(camState & MM_CAMERA_TYPE_AUX)) { 6939 //Activate Aux 6940 camState |= MM_CAMERA_TYPE_AUX; 6941 } 6942 if (camState & MM_CAMERA_TYPE_MAIN) { 6943 //Suspend Main 6944 camState &= (~MM_CAMERA_TYPE_MAIN); 6945 } 6946 } else { 6947 //Dual Zone 6948 LOGH("DUAL ZONE : %d and %d", zoomLevel, prev_zoomLevel); 6949 if (!(camState & MM_CAMERA_TYPE_AUX)) { 6950 //Activate Aux 6951 camState |= MM_CAMERA_TYPE_AUX; 6952 } 6953 if (!(camState & MM_CAMERA_TYPE_MAIN)) { 6954 //Activate Main 6955 camState |= MM_CAMERA_TYPE_MAIN; 6956 } 6957 } 6958 6959 if (camState != 0 && camState != mActiveCamera) { 6960 processCameraControl(camState); 6961 } 6962 6963 if (zoomLevel >= 40 && prev_zoomLevel < 40) { 6964 //Switch camera 6965 switchCameraCb(); 6966 prev_zoomLevel = zoomLevel; 6967 } else if (prev_zoomLevel >= 40 && zoomLevel < 40){ 6968 switchCameraCb(); 6969 prev_zoomLevel = zoomLevel; 6970 } 6971 return 0; 6972 } 6973 6974 /*=========================================================================== 6975 * FUNCTION : processCameraControl 6976 * 6977 * DESCRIPTION: Suspend and resume camera 6978 * 6979 * PARAMETERS : 6980 * 6981 * RETURN : int32_t type of status 6982 * NO_ERROR -- success 6983 * none-zero failure code 6984 *==========================================================================*/ 6985 int32_t QCamera2HardwareInterface::processCameraControl(uint32_t camState) 6986 { 6987 int32_t ret = NO_ERROR; 6988 6989 //Set camera controls to parameter and back-end 6990 ret = mParameters.setCameraControls(camState, TRUE); 6991 6992 //Update camera status to internal channel 6993 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 6994 if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) { 6995 ret = m_channels[i]->processCameraControl(camState); 6996 if (ret != NO_ERROR) { 6997 LOGE("Channel Switch Failed"); 6998 break; 6999 } 7000 } 7001 } 7002 if (ret == NO_ERROR) { 7003 if (camState == MM_CAMERA_TYPE_MAIN) { 7004 m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle); 7005 } else if (camState == MM_CAMERA_TYPE_AUX) { 7006 m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle); 7007 } 7008 } 7009 LOGH("mActiveCamera = %d to %d", mActiveCamera, camState); 7010 mActiveCamera = camState; 7011 return ret; 7012 } 7013 7014 /*=========================================================================== 7015 * FUNCTION : switchCameraCb 7016 * 7017 * DESCRIPTION: switch camera's in case of dual camera 7018 * 7019 * PARAMETERS : 7020 * 7021 * RETURN : int32_t type of status 7022 * NO_ERROR -- success 7023 * none-zero failure code 7024 *==========================================================================*/ 7025 int32_t QCamera2HardwareInterface::switchCameraCb() 7026 { 7027 int32_t ret = NO_ERROR; 7028 7029 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 7030 if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) { 7031 ret = m_channels[i]->switchChannelCb(); 7032 if (ret != NO_ERROR) { 7033 LOGE("Channel Switch Failed"); 7034 break; 7035 } 7036 } 7037 } 7038 if (ret == NO_ERROR && mActiveCamera == MM_CAMERA_DUAL_CAM) { 7039 if (get_aux_camera_handle(mCameraHandle->camera_handle) 7040 == m_ActiveHandle) { 7041 m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle); 7042 } else if (get_main_camera_handle(mCameraHandle->camera_handle) 7043 == m_ActiveHandle) { 7044 m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle); 7045 } else { 7046 m_ActiveHandle = mCameraHandle->camera_handle; 7047 } 7048 } 7049 return ret; 7050 } 7051 7052 /*=========================================================================== 7053 * FUNCTION : lockAPI 7054 * 7055 * DESCRIPTION: lock to process API 7056 * 7057 * PARAMETERS : none 7058 * 7059 * RETURN : none 7060 *==========================================================================*/ 7061 void QCamera2HardwareInterface::lockAPI() 7062 { 7063 pthread_mutex_lock(&m_lock); 7064 } 7065 7066 /*=========================================================================== 7067 * FUNCTION : waitAPIResult 7068 * 7069 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will 7070 * return only cerntain API event type arrives 7071 * 7072 * PARAMETERS : 7073 * @api_evt : API event type 7074 * 7075 * RETURN : none 7076 *==========================================================================*/ 7077 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt, 7078 qcamera_api_result_t *apiResult) 7079 { 7080 LOGD("wait for API result of evt (%d)", api_evt); 7081 int resultReceived = 0; 7082 while (!resultReceived) { 7083 pthread_cond_wait(&m_cond, &m_lock); 7084 if (m_apiResultList != NULL) { 7085 api_result_list *apiResultList = m_apiResultList; 7086 api_result_list *apiResultListPrevious = m_apiResultList; 7087 while (apiResultList != NULL) { 7088 if (apiResultList->result.request_api == api_evt) { 7089 resultReceived = 1; 7090 *apiResult = apiResultList->result; 7091 apiResultListPrevious->next = apiResultList->next; 7092 if (apiResultList == m_apiResultList) { 7093 m_apiResultList = apiResultList->next; 7094 } 7095 free(apiResultList); 7096 break; 7097 } 7098 else { 7099 apiResultListPrevious = apiResultList; 7100 apiResultList = apiResultList->next; 7101 } 7102 } 7103 } 7104 } 7105 LOGD("return (%d) from API result wait for evt (%d)", 7106 apiResult->status, api_evt); 7107 } 7108 7109 7110 /*=========================================================================== 7111 * FUNCTION : unlockAPI 7112 * 7113 * DESCRIPTION: API processing is done, unlock 7114 * 7115 * PARAMETERS : none 7116 * 7117 * RETURN : none 7118 *==========================================================================*/ 7119 void QCamera2HardwareInterface::unlockAPI() 7120 { 7121 pthread_mutex_unlock(&m_lock); 7122 } 7123 7124 /*=========================================================================== 7125 * FUNCTION : signalAPIResult 7126 * 7127 * DESCRIPTION: signal condition viarable that cerntain API event type arrives 7128 * 7129 * PARAMETERS : 7130 * @result : API result 7131 * 7132 * RETURN : none 7133 *==========================================================================*/ 7134 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result) 7135 { 7136 7137 pthread_mutex_lock(&m_lock); 7138 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list)); 7139 if (apiResult == NULL) { 7140 LOGE("ERROR: malloc for api result failed, Result will not be sent"); 7141 goto malloc_failed; 7142 } 7143 apiResult->result = *result; 7144 apiResult->next = NULL; 7145 if (m_apiResultList == NULL) m_apiResultList = apiResult; 7146 else { 7147 api_result_list *apiResultList = m_apiResultList; 7148 while(apiResultList->next != NULL) apiResultList = apiResultList->next; 7149 apiResultList->next = apiResult; 7150 } 7151 malloc_failed: 7152 pthread_cond_broadcast(&m_cond); 7153 pthread_mutex_unlock(&m_lock); 7154 } 7155 7156 /*=========================================================================== 7157 * FUNCTION : signalEvtResult 7158 * 7159 * DESCRIPTION: signal condition variable that certain event was processed 7160 * 7161 * PARAMETERS : 7162 * @result : Event result 7163 * 7164 * RETURN : none 7165 *==========================================================================*/ 7166 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result) 7167 { 7168 pthread_mutex_lock(&m_evtLock); 7169 m_evtResult = *result; 7170 pthread_cond_signal(&m_evtCond); 7171 pthread_mutex_unlock(&m_evtLock); 7172 } 7173 7174 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel) 7175 { 7176 int32_t rc = NO_ERROR; 7177 cam_dimension_t str_dim,max_dim; 7178 QCameraChannel *pChannel; 7179 7180 max_dim.width = 0; 7181 max_dim.height = 0; 7182 7183 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) { 7184 if (m_channels[j] != NULL) { 7185 pChannel = m_channels[j]; 7186 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) { 7187 QCameraStream *pStream = pChannel->getStreamByIndex(i); 7188 if (pStream != NULL) { 7189 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 7190 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) { 7191 continue; 7192 } 7193 pStream->getFrameDimension(str_dim); 7194 if (str_dim.width > max_dim.width) { 7195 max_dim.width = str_dim.width; 7196 } 7197 if (str_dim.height > max_dim.height) { 7198 max_dim.height = str_dim.height; 7199 } 7200 } 7201 } 7202 } 7203 } 7204 7205 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) { 7206 QCameraStream *pStream = curChannel->getStreamByIndex(i); 7207 if (pStream != NULL) { 7208 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 7209 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) { 7210 continue; 7211 } 7212 pStream->getFrameDimension(str_dim); 7213 if (str_dim.width > max_dim.width) { 7214 max_dim.width = str_dim.width; 7215 } 7216 if (str_dim.height > max_dim.height) { 7217 max_dim.height = str_dim.height; 7218 } 7219 } 7220 } 7221 rc = mParameters.updateRAW(max_dim); 7222 return rc; 7223 } 7224 7225 /*=========================================================================== 7226 * FUNCTION : addStreamToChannel 7227 * 7228 * DESCRIPTION: add a stream into a channel 7229 * 7230 * PARAMETERS : 7231 * @pChannel : ptr to channel obj 7232 * @streamType : type of stream to be added 7233 * @streamCB : callback of stream 7234 * @userData : user data ptr to callback 7235 * 7236 * RETURN : int32_t type of status 7237 * NO_ERROR -- success 7238 * none-zero failure code 7239 *==========================================================================*/ 7240 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel, 7241 cam_stream_type_t streamType, 7242 stream_cb_routine streamCB, 7243 void *userData) 7244 { 7245 int32_t rc = NO_ERROR; 7246 QCameraHeapMemory *pStreamInfo = NULL; 7247 7248 if (streamType == CAM_STREAM_TYPE_RAW) { 7249 prepareRawStream(pChannel); 7250 } 7251 7252 pStreamInfo = allocateStreamInfoBuf(streamType, getStreamRefCount(streamType)); 7253 if (pStreamInfo == NULL) { 7254 LOGE("no mem for stream info buf"); 7255 return NO_MEMORY; 7256 } 7257 7258 bool bDynAllocBuf = false; 7259 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) { 7260 bDynAllocBuf = true; 7261 } 7262 7263 cam_padding_info_t padding_info; 7264 7265 if (streamType == CAM_STREAM_TYPE_ANALYSIS) { 7266 cam_analysis_info_t analysisInfo; 7267 cam_feature_mask_t featureMask; 7268 7269 featureMask = 0; 7270 mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask); 7271 rc = mParameters.getAnalysisInfo( 7272 ((mParameters.getRecordingHintValue() == true) && 7273 mParameters.fdModeInVideo()), 7274 FALSE, 7275 featureMask, 7276 &analysisInfo); 7277 if (rc != NO_ERROR) { 7278 LOGE("getAnalysisInfo failed, ret = %d", rc); 7279 return rc; 7280 } 7281 7282 padding_info = analysisInfo.analysis_padding_info; 7283 } else { 7284 padding_info = 7285 gCamCapability[mCameraId]->padding_info; 7286 if (streamType == CAM_STREAM_TYPE_PREVIEW) { 7287 padding_info.width_padding = mSurfaceStridePadding; 7288 padding_info.height_padding = CAM_PAD_TO_2; 7289 } 7290 if((!needReprocess()) 7291 || (streamType != CAM_STREAM_TYPE_SNAPSHOT) 7292 || (!mParameters.isLLNoiseEnabled())) { 7293 padding_info.offset_info.offset_x = 0; 7294 padding_info.offset_info.offset_y = 0; 7295 } 7296 } 7297 7298 bool deferAllocation = needDeferred(streamType); 7299 LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d", 7300 deferAllocation, bDynAllocBuf, streamType); 7301 rc = pChannel->addStream(*this, 7302 pStreamInfo, 7303 NULL, 7304 &padding_info, 7305 streamCB, userData, 7306 bDynAllocBuf, 7307 deferAllocation); 7308 7309 if (rc != NO_ERROR) { 7310 LOGE("add stream type (%d) failed, ret = %d", 7311 streamType, rc); 7312 return rc; 7313 } 7314 7315 return rc; 7316 } 7317 7318 /*=========================================================================== 7319 * FUNCTION : addPreviewChannel 7320 * 7321 * DESCRIPTION: add a preview channel that contains a preview stream 7322 * 7323 * PARAMETERS : none 7324 * 7325 * RETURN : int32_t type of status 7326 * NO_ERROR -- success 7327 * none-zero failure code 7328 *==========================================================================*/ 7329 int32_t QCamera2HardwareInterface::addPreviewChannel() 7330 { 7331 int32_t rc = NO_ERROR; 7332 QCameraChannel *pChannel = NULL; 7333 char value[PROPERTY_VALUE_MAX]; 7334 bool raw_yuv = false; 7335 7336 7337 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 7338 // if we had preview channel before, delete it first 7339 delete m_channels[QCAMERA_CH_TYPE_PREVIEW]; 7340 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL; 7341 } 7342 7343 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW); 7344 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7345 if (NULL == pChannel) { 7346 LOGE("no mem for preview channel"); 7347 return NO_MEMORY; 7348 } 7349 7350 // preview only channel, don't need bundle attr and cb 7351 rc = pChannel->init(NULL, NULL, NULL); 7352 if (rc != NO_ERROR) { 7353 LOGE("init preview channel failed, ret = %d", rc); 7354 return rc; 7355 } 7356 7357 // meta data stream always coexists with preview if applicable 7358 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7359 metadata_stream_cb_routine, this); 7360 if (rc != NO_ERROR) { 7361 LOGE("add metadata stream failed, ret = %d", rc); 7362 return rc; 7363 } 7364 7365 if (isRdiMode()) { 7366 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 7367 rdi_mode_stream_cb_routine, this); 7368 } else { 7369 if (isNoDisplayMode()) { 7370 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7371 nodisplay_preview_stream_cb_routine, this); 7372 } else { 7373 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7374 preview_stream_cb_routine, this); 7375 #ifdef TARGET_TS_MAKEUP 7376 int whiteLevel, cleanLevel; 7377 if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false) 7378 #endif 7379 if (!isDualCamera()) { 7380 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 7381 synchronous_stream_cb_routine); 7382 } 7383 } 7384 } 7385 7386 if (((mParameters.fdModeInVideo()) 7387 || (mParameters.getDcrf() == true) 7388 || (mParameters.getRecordingHintValue() != true)) 7389 && (!mParameters.isSecureMode())) { 7390 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 7391 NULL, this); 7392 if (rc != NO_ERROR) { 7393 LOGE("add Analysis stream failed, ret = %d", rc); 7394 return rc; 7395 } 7396 } 7397 7398 property_get("persist.camera.raw_yuv", value, "0"); 7399 raw_yuv = atoi(value) > 0 ? true : false; 7400 if ( raw_yuv ) { 7401 rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW, 7402 preview_raw_stream_cb_routine,this); 7403 if ( rc != NO_ERROR ) { 7404 LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc); 7405 delete pChannel; 7406 return rc; 7407 } 7408 } 7409 7410 if (rc != NO_ERROR) { 7411 LOGE("add preview stream failed, ret = %d", rc); 7412 delete pChannel; 7413 return rc; 7414 } 7415 7416 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel; 7417 return rc; 7418 } 7419 7420 /*=========================================================================== 7421 * FUNCTION : addVideoChannel 7422 * 7423 * DESCRIPTION: add a video channel that contains a video stream 7424 * 7425 * PARAMETERS : none 7426 * 7427 * RETURN : int32_t type of status 7428 * NO_ERROR -- success 7429 * none-zero failure code 7430 *==========================================================================*/ 7431 int32_t QCamera2HardwareInterface::addVideoChannel() 7432 { 7433 int32_t rc = NO_ERROR; 7434 QCameraVideoChannel *pChannel = NULL; 7435 7436 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) { 7437 // if we had video channel before, delete it first 7438 delete m_channels[QCAMERA_CH_TYPE_VIDEO]; 7439 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL; 7440 } 7441 7442 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO); 7443 pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops); 7444 if (NULL == pChannel) { 7445 LOGE("no mem for video channel"); 7446 return NO_MEMORY; 7447 } 7448 7449 if (isLowPowerMode()) { 7450 mm_camera_channel_attr_t attr; 7451 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7452 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7453 attr.look_back = 0; //wait for future frame for liveshot 7454 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7455 attr.water_mark = 1; //hold min buffers possible in Q 7456 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7457 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this); 7458 } else { 7459 // preview only channel, don't need bundle attr and cb 7460 rc = pChannel->init(NULL, NULL, NULL); 7461 } 7462 7463 if (rc != 0) { 7464 LOGE("init video channel failed, ret = %d", rc); 7465 delete pChannel; 7466 return rc; 7467 } 7468 7469 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO, 7470 video_stream_cb_routine, this); 7471 7472 if (rc != NO_ERROR) { 7473 LOGE("add video stream failed, ret = %d", rc); 7474 delete pChannel; 7475 return rc; 7476 } 7477 7478 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel; 7479 return rc; 7480 } 7481 7482 /*=========================================================================== 7483 * FUNCTION : addSnapshotChannel 7484 * 7485 * DESCRIPTION: add a snapshot channel that contains a snapshot stream 7486 * 7487 * PARAMETERS : none 7488 * 7489 * RETURN : int32_t type of status 7490 * NO_ERROR -- success 7491 * none-zero failure code 7492 * NOTE : Add this channel for live snapshot usecase. Regular capture will 7493 * use addCaptureChannel. 7494 *==========================================================================*/ 7495 int32_t QCamera2HardwareInterface::addSnapshotChannel() 7496 { 7497 int32_t rc = NO_ERROR; 7498 QCameraChannel *pChannel = NULL; 7499 7500 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) { 7501 // if we had ZSL channel before, delete it first 7502 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 7503 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL; 7504 } 7505 7506 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT); 7507 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7508 if (NULL == pChannel) { 7509 LOGE("no mem for snapshot channel"); 7510 return NO_MEMORY; 7511 } 7512 7513 mm_camera_channel_attr_t attr; 7514 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7515 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 7516 attr.look_back = 0; //wait for future frame for liveshot 7517 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7518 attr.water_mark = 1; //hold min buffers possible in Q 7519 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7520 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW; 7521 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this); 7522 if (rc != NO_ERROR) { 7523 LOGE("init snapshot channel failed, ret = %d", rc); 7524 delete pChannel; 7525 return rc; 7526 } 7527 7528 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 7529 NULL, NULL); 7530 if (rc != NO_ERROR) { 7531 LOGE("add snapshot stream failed, ret = %d", rc); 7532 delete pChannel; 7533 return rc; 7534 } 7535 7536 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel; 7537 return rc; 7538 } 7539 7540 /*=========================================================================== 7541 * FUNCTION : addRawChannel 7542 * 7543 * DESCRIPTION: add a raw channel that contains a raw image stream 7544 * 7545 * PARAMETERS : none 7546 * 7547 * RETURN : int32_t type of status 7548 * NO_ERROR -- success 7549 * none-zero failure code 7550 *==========================================================================*/ 7551 int32_t QCamera2HardwareInterface::addRawChannel() 7552 { 7553 int32_t rc = NO_ERROR; 7554 QCameraChannel *pChannel = NULL; 7555 7556 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) { 7557 // if we had raw channel before, delete it first 7558 delete m_channels[QCAMERA_CH_TYPE_RAW]; 7559 m_channels[QCAMERA_CH_TYPE_RAW] = NULL; 7560 } 7561 7562 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW); 7563 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7564 if (NULL == pChannel) { 7565 LOGE("no mem for raw channel"); 7566 return NO_MEMORY; 7567 } 7568 7569 if (mParameters.getofflineRAW()) { 7570 mm_camera_channel_attr_t attr; 7571 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7572 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7573 attr.look_back = mParameters.getZSLBackLookCount(); 7574 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7575 attr.water_mark = 1; 7576 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7577 rc = pChannel->init(&attr, raw_channel_cb_routine, this); 7578 if (rc != NO_ERROR) { 7579 LOGE("init RAW channel failed, ret = %d", rc); 7580 delete pChannel; 7581 return rc; 7582 } 7583 } else { 7584 rc = pChannel->init(NULL, NULL, NULL); 7585 if (rc != NO_ERROR) { 7586 LOGE("init raw channel failed, ret = %d", rc); 7587 delete pChannel; 7588 return rc; 7589 } 7590 } 7591 7592 if (!mParameters.isZSLMode()) { 7593 // meta data stream always coexists with snapshot in regular RAW capture case 7594 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7595 metadata_stream_cb_routine, this); 7596 if (rc != NO_ERROR) { 7597 LOGE("add metadata stream failed, ret = %d", rc); 7598 delete pChannel; 7599 return rc; 7600 } 7601 } 7602 7603 if (mParameters.getofflineRAW()) { 7604 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 7605 NULL, this); 7606 } else { 7607 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 7608 raw_stream_cb_routine, this); 7609 } 7610 if (rc != NO_ERROR) { 7611 LOGE("add snapshot stream failed, ret = %d", rc); 7612 delete pChannel; 7613 return rc; 7614 } 7615 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel; 7616 return rc; 7617 } 7618 7619 /*=========================================================================== 7620 * FUNCTION : addZSLChannel 7621 * 7622 * DESCRIPTION: add a ZSL channel that contains a preview stream and 7623 * a snapshot stream 7624 * 7625 * PARAMETERS : none 7626 * 7627 * RETURN : int32_t type of status 7628 * NO_ERROR -- success 7629 * none-zero failure code 7630 *==========================================================================*/ 7631 int32_t QCamera2HardwareInterface::addZSLChannel() 7632 { 7633 int32_t rc = NO_ERROR; 7634 QCameraPicChannel *pChannel = NULL; 7635 char value[PROPERTY_VALUE_MAX]; 7636 bool raw_yuv = false; 7637 7638 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) { 7639 // if we had ZSL channel before, delete it first 7640 delete m_channels[QCAMERA_CH_TYPE_ZSL]; 7641 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL; 7642 } 7643 7644 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL); 7645 pChannel = new QCameraPicChannel(handle, 7646 mCameraHandle->ops); 7647 if (NULL == pChannel) { 7648 LOGE("no mem for ZSL channel"); 7649 return NO_MEMORY; 7650 } 7651 7652 // ZSL channel, init with bundle attr and cb 7653 mm_camera_channel_attr_t attr; 7654 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7655 if (mParameters.isSceneSelectionEnabled()) { 7656 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 7657 } else { 7658 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7659 } 7660 attr.look_back = mParameters.getZSLBackLookCount(); 7661 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7662 if (mParameters.isOEMFeatEnabled()) { 7663 attr.post_frame_skip++; 7664 } 7665 attr.water_mark = mParameters.getZSLQueueDepth(); 7666 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7667 attr.user_expected_frame_id = 7668 mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0; 7669 7670 //Enabled matched queue 7671 if (isFrameSyncEnabled()) { 7672 LOGH("Enabling frame sync for dual camera, camera Id: %d", 7673 mCameraId); 7674 attr.enable_frame_sync = 1; 7675 } 7676 rc = pChannel->init(&attr, 7677 zsl_channel_cb, 7678 this); 7679 if (rc != 0) { 7680 LOGE("init ZSL channel failed, ret = %d", rc); 7681 delete pChannel; 7682 return rc; 7683 } 7684 7685 // meta data stream always coexists with preview if applicable 7686 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7687 metadata_stream_cb_routine, this); 7688 if (rc != NO_ERROR) { 7689 LOGE("add metadata stream failed, ret = %d", rc); 7690 delete pChannel; 7691 return rc; 7692 } 7693 7694 if (isNoDisplayMode()) { 7695 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7696 nodisplay_preview_stream_cb_routine, this); 7697 } else { 7698 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7699 preview_stream_cb_routine, this); 7700 #ifdef TARGET_TS_MAKEUP 7701 int whiteLevel, cleanLevel; 7702 if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false) 7703 #endif 7704 if (!isDualCamera()) { 7705 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 7706 synchronous_stream_cb_routine); 7707 } 7708 } 7709 if (rc != NO_ERROR) { 7710 LOGE("add preview stream failed, ret = %d", rc); 7711 delete pChannel; 7712 return rc; 7713 } 7714 7715 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 7716 NULL, this); 7717 if (rc != NO_ERROR) { 7718 LOGE("add snapshot stream failed, ret = %d", rc); 7719 delete pChannel; 7720 return rc; 7721 } 7722 7723 if (!mParameters.isSecureMode()) { 7724 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 7725 NULL, this); 7726 if (rc != NO_ERROR) { 7727 LOGE("add Analysis stream failed, ret = %d", rc); 7728 delete pChannel; 7729 return rc; 7730 } 7731 } 7732 7733 property_get("persist.camera.raw_yuv", value, "0"); 7734 raw_yuv = atoi(value) > 0 ? true : false; 7735 if (raw_yuv) { 7736 rc = addStreamToChannel(pChannel, 7737 CAM_STREAM_TYPE_RAW, 7738 preview_raw_stream_cb_routine, 7739 this); 7740 if (rc != NO_ERROR) { 7741 LOGE("add raw stream failed, ret = %d", rc); 7742 delete pChannel; 7743 return rc; 7744 } 7745 } 7746 7747 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel; 7748 return rc; 7749 } 7750 7751 /*=========================================================================== 7752 * FUNCTION : addCaptureChannel 7753 * 7754 * DESCRIPTION: add a capture channel that contains a snapshot stream 7755 * and a postview stream 7756 * 7757 * PARAMETERS : none 7758 * 7759 * RETURN : int32_t type of status 7760 * NO_ERROR -- success 7761 * none-zero failure code 7762 * NOTE : Add this channel for regular capture usecase. 7763 * For Live snapshot usecase, use addSnapshotChannel. 7764 *==========================================================================*/ 7765 int32_t QCamera2HardwareInterface::addCaptureChannel() 7766 { 7767 int32_t rc = NO_ERROR; 7768 QCameraPicChannel *pChannel = NULL; 7769 char value[PROPERTY_VALUE_MAX]; 7770 bool raw_yuv = false; 7771 7772 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) { 7773 delete m_channels[QCAMERA_CH_TYPE_CAPTURE]; 7774 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL; 7775 } 7776 7777 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE); 7778 pChannel = new QCameraPicChannel(handle, mCameraHandle->ops); 7779 if (NULL == pChannel) { 7780 LOGE("no mem for capture channel"); 7781 return NO_MEMORY; 7782 } 7783 7784 // Capture channel, only need snapshot and postview streams start together 7785 mm_camera_channel_attr_t attr; 7786 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7787 if ( mLongshotEnabled ) { 7788 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7789 attr.look_back = mParameters.getZSLBackLookCount(); 7790 attr.water_mark = mParameters.getZSLQueueDepth(); 7791 } else { 7792 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 7793 } 7794 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7795 7796 rc = pChannel->init(&attr, 7797 capture_channel_cb_routine, 7798 this); 7799 if (rc != NO_ERROR) { 7800 LOGE("init capture channel failed, ret = %d", rc); 7801 return rc; 7802 } 7803 7804 // meta data stream always coexists with snapshot in regular capture case 7805 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7806 metadata_stream_cb_routine, this); 7807 if (rc != NO_ERROR) { 7808 LOGE("add metadata stream failed, ret = %d", rc); 7809 return rc; 7810 } 7811 7812 if (mLongshotEnabled) { 7813 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7814 preview_stream_cb_routine, this); 7815 if (rc != NO_ERROR) { 7816 LOGE("add preview stream failed, ret = %d", rc); 7817 return rc; 7818 } 7819 #ifdef TARGET_TS_MAKEUP 7820 int whiteLevel, cleanLevel; 7821 if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false) 7822 #endif 7823 if (!isDualCamera()) { 7824 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 7825 synchronous_stream_cb_routine); 7826 } 7827 //Not adding the postview stream to the capture channel if Quadra CFA is enabled. 7828 } else if (!mParameters.getQuadraCfa()) { 7829 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW, 7830 NULL, this); 7831 if (rc != NO_ERROR) { 7832 LOGE("add postview stream failed, ret = %d", rc); 7833 return rc; 7834 } 7835 } 7836 7837 if (!mParameters.getofflineRAW()) { 7838 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 7839 NULL, this); 7840 if (rc != NO_ERROR) { 7841 LOGE("add snapshot stream failed, ret = %d", rc); 7842 return rc; 7843 } 7844 } 7845 7846 stream_cb_routine stream_cb = NULL; 7847 property_get("persist.camera.raw_yuv", value, "0"); 7848 raw_yuv = atoi(value) > 0 ? true : false; 7849 7850 if (raw_yuv) { 7851 stream_cb = snapshot_raw_stream_cb_routine; 7852 } 7853 7854 if ((raw_yuv) || (mParameters.getofflineRAW())) { 7855 rc = addStreamToChannel(pChannel, 7856 CAM_STREAM_TYPE_RAW, stream_cb, this); 7857 if (rc != NO_ERROR) { 7858 LOGE("add raw stream failed, ret = %d", rc); 7859 return rc; 7860 } 7861 } 7862 7863 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel; 7864 return rc; 7865 } 7866 7867 /*=========================================================================== 7868 * FUNCTION : addMetaDataChannel 7869 * 7870 * DESCRIPTION: add a meta data channel that contains a metadata stream 7871 * 7872 * PARAMETERS : none 7873 * 7874 * RETURN : int32_t type of status 7875 * NO_ERROR -- success 7876 * none-zero failure code 7877 *==========================================================================*/ 7878 int32_t QCamera2HardwareInterface::addMetaDataChannel() 7879 { 7880 int32_t rc = NO_ERROR; 7881 QCameraChannel *pChannel = NULL; 7882 7883 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) { 7884 delete m_channels[QCAMERA_CH_TYPE_METADATA]; 7885 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL; 7886 } 7887 7888 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA); 7889 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7890 if (NULL == pChannel) { 7891 LOGE("no mem for metadata channel"); 7892 return NO_MEMORY; 7893 } 7894 7895 rc = pChannel->init(NULL, 7896 NULL, 7897 NULL); 7898 if (rc != NO_ERROR) { 7899 LOGE("init metadata channel failed, ret = %d", rc); 7900 delete pChannel; 7901 return rc; 7902 } 7903 7904 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7905 metadata_stream_cb_routine, this); 7906 if (rc != NO_ERROR) { 7907 LOGE("add metadata stream failed, ret = %d", rc); 7908 delete pChannel; 7909 return rc; 7910 } 7911 7912 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel; 7913 return rc; 7914 } 7915 7916 /*=========================================================================== 7917 * FUNCTION : addCallbackChannel 7918 * 7919 * DESCRIPTION: add a callback channel that contains a callback stream 7920 * 7921 * PARAMETERS : none 7922 * 7923 * RETURN : int32_t type of status 7924 * NO_ERROR -- success 7925 * none-zero failure code 7926 *==========================================================================*/ 7927 int32_t QCamera2HardwareInterface::addCallbackChannel() 7928 { 7929 int32_t rc = NO_ERROR; 7930 QCameraChannel *pChannel = NULL; 7931 7932 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) { 7933 delete m_channels[QCAMERA_CH_TYPE_CALLBACK]; 7934 m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL; 7935 } 7936 7937 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK); 7938 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7939 if (NULL == pChannel) { 7940 LOGE("no mem for callback channel"); 7941 return NO_MEMORY; 7942 } 7943 7944 rc = pChannel->init(NULL, NULL, this); 7945 if (rc != NO_ERROR) { 7946 LOGE("init callback channel failed, ret = %d", 7947 rc); 7948 delete pChannel; 7949 return rc; 7950 } 7951 7952 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK, 7953 callback_stream_cb_routine, this); 7954 if (rc != NO_ERROR) { 7955 LOGE("add callback stream failed, ret = %d", rc); 7956 delete pChannel; 7957 return rc; 7958 } 7959 7960 m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel; 7961 return rc; 7962 } 7963 7964 7965 /*=========================================================================== 7966 * FUNCTION : addAnalysisChannel 7967 * 7968 * DESCRIPTION: add a analysis channel that contains a analysis stream 7969 * 7970 * PARAMETERS : none 7971 * 7972 * RETURN : int32_t type of status 7973 * NO_ERROR -- success 7974 * none-zero failure code 7975 *==========================================================================*/ 7976 int32_t QCamera2HardwareInterface::addAnalysisChannel() 7977 { 7978 int32_t rc = NO_ERROR; 7979 QCameraChannel *pChannel = NULL; 7980 7981 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) { 7982 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS]; 7983 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL; 7984 } 7985 7986 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS); 7987 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7988 if (NULL == pChannel) { 7989 LOGE("no mem for metadata channel"); 7990 return NO_MEMORY; 7991 } 7992 7993 rc = pChannel->init(NULL, NULL, this); 7994 if (rc != NO_ERROR) { 7995 LOGE("init Analysis channel failed, ret = %d", rc); 7996 delete pChannel; 7997 return rc; 7998 } 7999 8000 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 8001 NULL, this); 8002 if (rc != NO_ERROR) { 8003 LOGE("add Analysis stream failed, ret = %d", rc); 8004 delete pChannel; 8005 return rc; 8006 } 8007 8008 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel; 8009 return rc; 8010 } 8011 8012 8013 /*=========================================================================== 8014 * FUNCTION : getPPConfig 8015 * 8016 * DESCRIPTION: get Post processing configaration data 8017 * 8018 * PARAMETERS : 8019 * @pp config: pp config structure pointer, 8020 * @curIndex: current pp channel index 8021 * @multipass: Flag if multipass prcessing enabled. 8022 * 8023 * RETURN : int32_t type of status 8024 * NO_ERROR -- success 8025 * none-zero failure code 8026 *==========================================================================*/ 8027 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config, 8028 int8_t curIndex, bool multipass) 8029 { 8030 int32_t rc = NO_ERROR; 8031 int32_t feature_set = 0; 8032 8033 if (multipass) { 8034 LOGW("Multi pass enabled. Total Pass = %d, cur index = %d", 8035 mParameters.getReprocCount(), curIndex); 8036 } 8037 8038 LOGH("Supported pproc feature mask = %llx", 8039 gCamCapability[mCameraId]->qcom_supported_feature_mask); 8040 cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask; 8041 int32_t zoomLevel = mParameters.getParmZoomLevel(); 8042 uint32_t rotation = mParameters.getJpegRotation(); 8043 int32_t effect = mParameters.getEffectValue(); 8044 8045 pp_config.cur_reproc_count = curIndex + 1; 8046 pp_config.total_reproc_count = mParameters.getReprocCount(); 8047 8048 //Checking what feature mask to enable 8049 if (curIndex == 0) { 8050 if (mParameters.getQuadraCfa()) { 8051 feature_set = 2; 8052 } else { 8053 feature_set = 0; 8054 } 8055 } else if (curIndex == 1) { 8056 if (mParameters.getQuadraCfa()) { 8057 feature_set = 0; 8058 } else { 8059 feature_set = 1; 8060 } 8061 } 8062 8063 switch(feature_set) { 8064 case 0: 8065 //Configure feature mask for first pass of reprocessing 8066 //check if any effects are enabled 8067 if ((CAM_EFFECT_MODE_OFF != effect) && 8068 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) { 8069 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT; 8070 pp_config.effect = effect; 8071 } 8072 8073 //check for features that need to be enabled by default like sharpness 8074 //(if supported by hw). 8075 if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) && 8076 !mParameters.isOptiZoomEnabled()) { 8077 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS; 8078 pp_config.sharpness = mParameters.getSharpness(); 8079 } 8080 8081 //check if zoom is enabled 8082 if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) { 8083 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 8084 } 8085 8086 if (mParameters.isWNREnabled() && 8087 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) { 8088 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D; 8089 pp_config.denoise2d.denoise_enable = 1; 8090 pp_config.denoise2d.process_plates = 8091 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 8092 } 8093 8094 if (isCACEnabled()) { 8095 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC; 8096 } 8097 8098 //check if rotation is required 8099 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) { 8100 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 8101 if (rotation == 0) { 8102 pp_config.rotation = ROTATE_0; 8103 } else if (rotation == 90) { 8104 pp_config.rotation = ROTATE_90; 8105 } else if (rotation == 180) { 8106 pp_config.rotation = ROTATE_180; 8107 } else if (rotation == 270) { 8108 pp_config.rotation = ROTATE_270; 8109 } 8110 } 8111 8112 if (mParameters.isHDREnabled()){ 8113 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR; 8114 pp_config.hdr_param.hdr_enable = 1; 8115 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled(); 8116 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME; 8117 } else { 8118 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR; 8119 pp_config.hdr_param.hdr_enable = 0; 8120 } 8121 8122 //check if scaling is enabled 8123 if ((feature_mask & CAM_QCOM_FEATURE_SCALE) && 8124 mParameters.isReprocScaleEnabled() && 8125 mParameters.isUnderReprocScaling()){ 8126 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 8127 mParameters.getPicSizeFromAPK( 8128 pp_config.scale_param.output_width, 8129 pp_config.scale_param.output_height); 8130 } 8131 8132 if(mParameters.isUbiFocusEnabled()) { 8133 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS; 8134 } else { 8135 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS; 8136 } 8137 8138 if(mParameters.isUbiRefocus()) { 8139 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS; 8140 pp_config.misc_buf_param.misc_buffer_index = 0; 8141 } else { 8142 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS; 8143 } 8144 8145 if(mParameters.isChromaFlashEnabled()) { 8146 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH; 8147 pp_config.flash_value = CAM_FLASH_ON; 8148 } else { 8149 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH; 8150 } 8151 8152 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) { 8153 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM; 8154 pp_config.zoom_level = (uint8_t) zoomLevel; 8155 } else { 8156 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM; 8157 } 8158 8159 if (mParameters.getofflineRAW()) { 8160 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING; 8161 } 8162 8163 if (mParameters.isTruePortraitEnabled()) { 8164 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT; 8165 pp_config.misc_buf_param.misc_buffer_index = 0; 8166 } else { 8167 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT; 8168 } 8169 8170 if(mParameters.isStillMoreEnabled()) { 8171 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE; 8172 } else { 8173 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE; 8174 } 8175 8176 if (mParameters.isOEMFeatEnabled()) { 8177 pp_config.feature_mask |= CAM_OEM_FEATURE_1; 8178 } 8179 8180 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) { 8181 if (feature_mask & CAM_QCOM_FEATURE_DSDN) { 8182 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN; 8183 } else { 8184 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS; 8185 } 8186 } 8187 8188 if ((multipass) && 8189 (m_postprocessor.getPPChannelCount() > 1) 8190 && (!mParameters.getQuadraCfa())) { 8191 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2; 8192 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION; 8193 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS; 8194 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN; 8195 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 8196 } else { 8197 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 8198 } 8199 8200 cam_dimension_t thumb_src_dim; 8201 cam_dimension_t thumb_dst_dim; 8202 mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height)); 8203 mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim); 8204 if ((thumb_dst_dim.width != thumb_src_dim.width) || 8205 (thumb_dst_dim.height != thumb_src_dim.height)) { 8206 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) { 8207 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 8208 } 8209 } 8210 8211 break; 8212 8213 case 1: 8214 //Configure feature mask for second pass of reprocessing 8215 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2; 8216 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) { 8217 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 8218 if (rotation == 0) { 8219 pp_config.rotation = ROTATE_0; 8220 } else if (rotation == 90) { 8221 pp_config.rotation = ROTATE_90; 8222 } else if (rotation == 180) { 8223 pp_config.rotation = ROTATE_180; 8224 } else if (rotation == 270) { 8225 pp_config.rotation = ROTATE_270; 8226 } 8227 } 8228 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) { 8229 if (feature_mask & CAM_QCOM_FEATURE_DSDN) { 8230 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN; 8231 } else { 8232 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS; 8233 } 8234 } 8235 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING; 8236 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING; 8237 break; 8238 8239 case 2: 8240 //Setting feature for Quadra CFA 8241 pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA; 8242 break; 8243 8244 } 8245 8246 LOGH("pproc feature mask set = %llx pass count = %d", 8247 pp_config.feature_mask, curIndex); 8248 return rc; 8249 } 8250 8251 /*=========================================================================== 8252 * FUNCTION : addReprocChannel 8253 * 8254 * DESCRIPTION: add a reprocess channel that will do reprocess on frames 8255 * coming from input channel 8256 * 8257 * PARAMETERS : 8258 * @pInputChannel : ptr to input channel whose frames will be post-processed 8259 * @cur_channel_index : Current channel index in multipass 8260 * 8261 * RETURN : Ptr to the newly created channel obj. NULL if failed. 8262 *==========================================================================*/ 8263 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel( 8264 QCameraChannel *pInputChannel, int8_t cur_channel_index) 8265 { 8266 int32_t rc = NO_ERROR; 8267 QCameraReprocessChannel *pChannel = NULL; 8268 uint32_t burst_cnt = mParameters.getNumOfSnapshots(); 8269 uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING); 8270 8271 if (pInputChannel == NULL) { 8272 LOGE("input channel obj is NULL"); 8273 return NULL; 8274 } 8275 8276 pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops); 8277 if (NULL == pChannel) { 8278 LOGE("no mem for reprocess channel"); 8279 return NULL; 8280 } 8281 8282 // Capture channel, only need snapshot and postview streams start together 8283 mm_camera_channel_attr_t attr; 8284 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 8285 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 8286 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 8287 rc = pChannel->init(&attr, 8288 postproc_channel_cb_routine, 8289 this); 8290 if (rc != NO_ERROR) { 8291 LOGE("init reprocess channel failed, ret = %d", rc); 8292 delete pChannel; 8293 return NULL; 8294 } 8295 8296 // pp feature config 8297 cam_pp_feature_config_t pp_config; 8298 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 8299 8300 rc = getPPConfig(pp_config, cur_channel_index, 8301 ((mParameters.getReprocCount() > 1) ? TRUE : FALSE)); 8302 if (rc != NO_ERROR){ 8303 LOGE("Error while creating PP config"); 8304 delete pChannel; 8305 return NULL; 8306 } 8307 8308 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC); 8309 8310 //WNR and HDR happen inline. No extra buffers needed. 8311 cam_feature_mask_t temp_feature_mask = pp_config.feature_mask; 8312 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR; 8313 if (temp_feature_mask && mParameters.isHDREnabled()) { 8314 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded()); 8315 } 8316 8317 if (mParameters.isStillMoreEnabled()) { 8318 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 8319 pp_config.burst_cnt = stillmore_config.burst_count; 8320 LOGH("Stillmore burst %d", pp_config.burst_cnt); 8321 8322 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming 8323 // number of capture is already added. In the case of liveshot, 8324 // stillmore burst is 1. This is to account for the premature decrement 8325 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) { 8326 minStreamBufNum += 1; 8327 } 8328 } 8329 8330 if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) { 8331 minStreamBufNum += mParameters.getReprocCount() - 1; 8332 burst_cnt = mParameters.getReprocCount(); 8333 if (cur_channel_index == 0) { 8334 pChannel->setReprocCount(2); 8335 } else { 8336 pChannel->setReprocCount(1); 8337 } 8338 } else { 8339 pChannel->setReprocCount(1); 8340 } 8341 8342 #ifdef DUAL_CAM_TEST //Temporary macro. Added to simulate B+B snapshot. Will be removed 8343 if (isDualCamera()) { 8344 minStreamBufNum += 1; 8345 } 8346 #endif 8347 // Add non inplace image lib buffers only when ppproc is present, 8348 // becuase pproc is non inplace and input buffers for img lib 8349 // are output for pproc and this number of extra buffers is required 8350 // If pproc is not there, input buffers for imglib are from snapshot stream 8351 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc(); 8352 if (temp_feature_mask && imglib_extra_bufs) { 8353 // 1 is added because getNumOfExtraBuffersForImageProc returns extra 8354 // buffers assuming number of capture is already added 8355 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1); 8356 } 8357 8358 //Mask out features that are already processed in snapshot stream. 8359 cam_feature_mask_t snapshot_feature_mask = 0; 8360 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask); 8361 8362 pp_config.feature_mask &= ~snapshot_feature_mask; 8363 LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d", 8364 snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum); 8365 8366 bool offlineReproc = needOfflineReprocessing(); 8367 if (m_postprocessor.mOfflineDataBufs != NULL) { 8368 offlineReproc = TRUE; 8369 } 8370 8371 cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info; 8372 paddingInfo.offset_info.offset_x = 0; 8373 paddingInfo.offset_info.offset_y = 0; 8374 rc = pChannel->addReprocStreamsFromSource(*this, 8375 pp_config, 8376 pInputChannel, 8377 minStreamBufNum, 8378 burst_cnt, 8379 &paddingInfo, 8380 mParameters, 8381 mLongshotEnabled, 8382 offlineReproc); 8383 if (rc != NO_ERROR) { 8384 delete pChannel; 8385 return NULL; 8386 } 8387 8388 return pChannel; 8389 } 8390 8391 /*=========================================================================== 8392 * FUNCTION : addOfflineReprocChannel 8393 * 8394 * DESCRIPTION: add a offline reprocess channel contains one reproc stream, 8395 * that will do reprocess on frames coming from external images 8396 * 8397 * PARAMETERS : 8398 * @img_config : offline reporcess image info 8399 * @pp_feature : pp feature config 8400 * 8401 * RETURN : int32_t type of status 8402 * NO_ERROR -- success 8403 * none-zero failure code 8404 *==========================================================================*/ 8405 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel( 8406 cam_pp_offline_src_config_t &img_config, 8407 cam_pp_feature_config_t &pp_feature, 8408 stream_cb_routine stream_cb, 8409 void *userdata) 8410 { 8411 int32_t rc = NO_ERROR; 8412 QCameraReprocessChannel *pChannel = NULL; 8413 8414 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle, 8415 mCameraHandle->ops); 8416 if (NULL == pChannel) { 8417 LOGE("no mem for reprocess channel"); 8418 return NULL; 8419 } 8420 8421 rc = pChannel->init(NULL, NULL, NULL); 8422 if (rc != NO_ERROR) { 8423 LOGE("init reprocess channel failed, ret = %d", rc); 8424 delete pChannel; 8425 return NULL; 8426 } 8427 8428 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 8429 if (pStreamInfo == NULL) { 8430 LOGE("no mem for stream info buf"); 8431 delete pChannel; 8432 return NULL; 8433 } 8434 8435 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0); 8436 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t)); 8437 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 8438 streamInfoBuf->fmt = img_config.input_fmt; 8439 streamInfoBuf->dim = img_config.input_dim; 8440 streamInfoBuf->buf_planes = img_config.input_buf_planes; 8441 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST; 8442 streamInfoBuf->num_of_burst = img_config.num_of_bufs; 8443 8444 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 8445 streamInfoBuf->reprocess_config.offline = img_config; 8446 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature; 8447 streamInfoBuf->num_bufs = img_config.num_of_bufs; 8448 8449 rc = pChannel->addStream(*this, 8450 pStreamInfo, NULL, 8451 &gCamCapability[mCameraId]->padding_info, 8452 stream_cb, userdata, false); 8453 8454 if (rc != NO_ERROR) { 8455 LOGE("add reprocess stream failed, ret = %d", rc); 8456 delete pChannel; 8457 return NULL; 8458 } 8459 8460 return pChannel; 8461 } 8462 8463 /*=========================================================================== 8464 * FUNCTION : addChannel 8465 * 8466 * DESCRIPTION: add a channel by its type 8467 * 8468 * PARAMETERS : 8469 * @ch_type : channel type 8470 * 8471 * RETURN : int32_t type of status 8472 * NO_ERROR -- success 8473 * none-zero failure code 8474 *==========================================================================*/ 8475 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type) 8476 { 8477 int32_t rc = UNKNOWN_ERROR; 8478 switch (ch_type) { 8479 case QCAMERA_CH_TYPE_ZSL: 8480 rc = addZSLChannel(); 8481 break; 8482 case QCAMERA_CH_TYPE_CAPTURE: 8483 rc = addCaptureChannel(); 8484 break; 8485 case QCAMERA_CH_TYPE_PREVIEW: 8486 rc = addPreviewChannel(); 8487 break; 8488 case QCAMERA_CH_TYPE_VIDEO: 8489 rc = addVideoChannel(); 8490 break; 8491 case QCAMERA_CH_TYPE_SNAPSHOT: 8492 rc = addSnapshotChannel(); 8493 break; 8494 case QCAMERA_CH_TYPE_RAW: 8495 rc = addRawChannel(); 8496 break; 8497 case QCAMERA_CH_TYPE_METADATA: 8498 rc = addMetaDataChannel(); 8499 break; 8500 case QCAMERA_CH_TYPE_CALLBACK: 8501 rc = addCallbackChannel(); 8502 break; 8503 case QCAMERA_CH_TYPE_ANALYSIS: 8504 rc = addAnalysisChannel(); 8505 break; 8506 default: 8507 break; 8508 } 8509 return rc; 8510 } 8511 8512 /*=========================================================================== 8513 * FUNCTION : delChannel 8514 * 8515 * DESCRIPTION: delete a channel by its type 8516 * 8517 * PARAMETERS : 8518 * @ch_type : channel type 8519 * @destroy : delete context as well 8520 * 8521 * RETURN : int32_t type of status 8522 * NO_ERROR -- success 8523 * none-zero failure code 8524 *==========================================================================*/ 8525 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type, 8526 bool destroy) 8527 { 8528 if (m_channels[ch_type] != NULL) { 8529 if (destroy) { 8530 delete m_channels[ch_type]; 8531 m_channels[ch_type] = NULL; 8532 } else { 8533 m_channels[ch_type]->deleteChannel(); 8534 } 8535 } 8536 8537 return NO_ERROR; 8538 } 8539 8540 /*=========================================================================== 8541 * FUNCTION : startChannel 8542 * 8543 * DESCRIPTION: start a channel by its type 8544 * 8545 * PARAMETERS : 8546 * @ch_type : channel type 8547 * 8548 * RETURN : int32_t type of status 8549 * NO_ERROR -- success 8550 * none-zero failure code 8551 *==========================================================================*/ 8552 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type) 8553 { 8554 int32_t rc = UNKNOWN_ERROR; 8555 if (m_channels[ch_type] != NULL) { 8556 rc = m_channels[ch_type]->start(); 8557 } 8558 return rc; 8559 } 8560 8561 /*=========================================================================== 8562 * FUNCTION : stopChannel 8563 * 8564 * DESCRIPTION: stop a channel by its type 8565 * 8566 * PARAMETERS : 8567 * @ch_type : channel type 8568 * 8569 * RETURN : int32_t type of status 8570 * NO_ERROR -- success 8571 * none-zero failure code 8572 *==========================================================================*/ 8573 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type) 8574 { 8575 int32_t rc = UNKNOWN_ERROR; 8576 if (m_channels[ch_type] != NULL) { 8577 rc = m_channels[ch_type]->stop(); 8578 } 8579 8580 return rc; 8581 } 8582 8583 /*=========================================================================== 8584 * FUNCTION : preparePreview 8585 * 8586 * DESCRIPTION: add channels needed for preview 8587 * 8588 * PARAMETERS : none 8589 * 8590 * RETURN : int32_t type of status 8591 * NO_ERROR -- success 8592 * none-zero failure code 8593 *==========================================================================*/ 8594 int32_t QCamera2HardwareInterface::preparePreview() 8595 { 8596 ATRACE_CALL(); 8597 int32_t rc = NO_ERROR; 8598 8599 LOGI("E"); 8600 rc = mParameters.setStreamConfigure(false, false, false); 8601 if (rc != NO_ERROR) { 8602 LOGE("setStreamConfigure failed %d", rc); 8603 return rc; 8604 } 8605 8606 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 8607 rc = addChannel(QCAMERA_CH_TYPE_ZSL); 8608 if (rc != NO_ERROR) { 8609 LOGE("failed!! rc = %d", rc); 8610 return rc; 8611 } 8612 8613 if (mParameters.isUBWCEnabled()) { 8614 cam_format_t fmt; 8615 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt); 8616 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 8617 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK); 8618 if (rc != NO_ERROR) { 8619 delChannel(QCAMERA_CH_TYPE_ZSL); 8620 LOGE("failed!! rc = %d", rc); 8621 return rc; 8622 } 8623 } 8624 } 8625 8626 if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) { 8627 addChannel(QCAMERA_CH_TYPE_RAW); 8628 } 8629 } else { 8630 bool recordingHint = mParameters.getRecordingHintValue(); 8631 if(!isRdiMode() && recordingHint) { 8632 //stop face detection,longshot,etc if turned ON in Camera mode 8633 #ifndef VANILLA_HAL 8634 int32_t arg; //dummy arg 8635 if (isLongshotEnabled()) { 8636 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg); 8637 } 8638 if (mParameters.isFaceDetectionEnabled() 8639 && (!mParameters.fdModeInVideo())) { 8640 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg); 8641 } 8642 if (mParameters.isHistogramEnabled()) { 8643 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg); 8644 } 8645 #endif 8646 //Don't create snapshot channel for liveshot, if low power mode is set. 8647 //Use video stream instead. 8648 if (!isLowPowerMode()) { 8649 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8650 if (rc != NO_ERROR) { 8651 return rc; 8652 } 8653 } 8654 8655 rc = addChannel(QCAMERA_CH_TYPE_VIDEO); 8656 if (rc != NO_ERROR) { 8657 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8658 LOGE("failed!! rc = %d", rc); 8659 return rc; 8660 } 8661 } 8662 8663 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW); 8664 if (!isRdiMode() && (rc != NO_ERROR)) { 8665 if (recordingHint) { 8666 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8667 delChannel(QCAMERA_CH_TYPE_VIDEO); 8668 } 8669 } 8670 8671 if (mParameters.isUBWCEnabled() && !recordingHint) { 8672 cam_format_t fmt; 8673 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt); 8674 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 8675 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK); 8676 if (rc != NO_ERROR) { 8677 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8678 if (!isRdiMode()) { 8679 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8680 delChannel(QCAMERA_CH_TYPE_VIDEO); 8681 } 8682 LOGE("failed!! rc = %d", rc); 8683 return rc; 8684 } 8685 } 8686 } 8687 8688 if (NO_ERROR != rc) { 8689 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8690 LOGE("failed!! rc = %d", rc); 8691 } 8692 } 8693 8694 LOGI("X rc = %d", rc); 8695 return rc; 8696 } 8697 8698 /*=========================================================================== 8699 * FUNCTION : unpreparePreview 8700 * 8701 * DESCRIPTION: delete channels for preview 8702 * 8703 * PARAMETERS : none 8704 * 8705 * RETURN : none 8706 *==========================================================================*/ 8707 void QCamera2HardwareInterface::unpreparePreview() 8708 { 8709 delChannel(QCAMERA_CH_TYPE_ZSL); 8710 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8711 delChannel(QCAMERA_CH_TYPE_VIDEO); 8712 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8713 delChannel(QCAMERA_CH_TYPE_CALLBACK); 8714 delChannel(QCAMERA_CH_TYPE_RAW); 8715 } 8716 8717 /*=========================================================================== 8718 * FUNCTION : playShutter 8719 * 8720 * DESCRIPTION: send request to play shutter sound 8721 * 8722 * PARAMETERS : none 8723 * 8724 * RETURN : none 8725 *==========================================================================*/ 8726 void QCamera2HardwareInterface::playShutter(){ 8727 if (mNotifyCb == NULL || 8728 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){ 8729 LOGD("shutter msg not enabled or NULL cb"); 8730 return; 8731 } 8732 LOGH("CAMERA_MSG_SHUTTER "); 8733 qcamera_callback_argm_t cbArg; 8734 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 8735 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 8736 cbArg.msg_type = CAMERA_MSG_SHUTTER; 8737 cbArg.ext1 = 0; 8738 cbArg.ext2 = false; 8739 m_cbNotifier.notifyCallback(cbArg); 8740 } 8741 8742 /*=========================================================================== 8743 * FUNCTION : getChannelByHandle 8744 * 8745 * DESCRIPTION: return a channel by its handle 8746 * 8747 * PARAMETERS : 8748 * @channelHandle : channel handle 8749 * 8750 * RETURN : a channel obj if found, NULL if not found 8751 *==========================================================================*/ 8752 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle) 8753 { 8754 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 8755 if (m_channels[i] != NULL && 8756 (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) { 8757 return m_channels[i]; 8758 } 8759 } 8760 8761 return NULL; 8762 } 8763 /*=========================================================================== 8764 * FUNCTION : needPreviewFDCallback 8765 * 8766 * DESCRIPTION: decides if needPreviewFDCallback 8767 * 8768 * PARAMETERS : 8769 * @num_faces : number of faces 8770 * 8771 * RETURN : bool type of status 8772 * true -- success 8773 * fale -- failure code 8774 *==========================================================================*/ 8775 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces) 8776 { 8777 if (num_faces == 0 && mNumPreviewFaces == 0) { 8778 return false; 8779 } 8780 8781 return true; 8782 } 8783 8784 /*=========================================================================== 8785 * FUNCTION : processFaceDetectionReuslt 8786 * 8787 * DESCRIPTION: process face detection reuslt 8788 * 8789 * PARAMETERS : 8790 * @faces_data : ptr to face processing result struct 8791 * 8792 * RETURN : int32_t type of status 8793 * NO_ERROR -- success 8794 * none-zero failure code 8795 *==========================================================================*/ 8796 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data) 8797 { 8798 if (!mParameters.isFaceDetectionEnabled()) { 8799 LOGH("FaceDetection not enabled, no ops here"); 8800 return NO_ERROR; 8801 } 8802 8803 qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type; 8804 cam_face_detection_data_t *detect_data = &(faces_data->detection_data); 8805 if ((NULL == mDataCb) || 8806 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) || 8807 (!needPreviewFDCallback(detect_data->num_faces_detected)) 8808 #ifndef VANILLA_HAL 8809 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA)) 8810 #endif 8811 ) { 8812 LOGH("metadata msgtype not enabled, no ops here"); 8813 return NO_ERROR; 8814 } 8815 8816 if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) { 8817 // Don't send callback to app if this is skipped by fd at backend 8818 return NO_ERROR; 8819 } 8820 8821 cam_dimension_t display_dim; 8822 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim); 8823 if (display_dim.width <= 0 || display_dim.height <= 0) { 8824 LOGE("Invalid preview width or height (%d x %d)", 8825 display_dim.width, display_dim.height); 8826 return UNKNOWN_ERROR; 8827 } 8828 8829 // process face detection result 8830 // need separate face detection in preview or snapshot type 8831 size_t faceResultSize = 0; 8832 size_t data_len = 0; 8833 if(fd_type == QCAMERA_FD_PREVIEW){ 8834 //fd for preview frames 8835 faceResultSize = sizeof(camera_frame_metadata_t); 8836 faceResultSize += sizeof(camera_face_t) * MAX_ROI; 8837 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 8838 #ifndef VANILLA_HAL 8839 // fd for snapshot frames 8840 //check if face is detected in this frame 8841 if(detect_data->num_faces_detected > 0){ 8842 data_len = sizeof(camera_frame_metadata_t) + 8843 sizeof(camera_face_t) * detect_data->num_faces_detected; 8844 }else{ 8845 //no face 8846 data_len = 0; 8847 } 8848 #endif 8849 faceResultSize = 1 *sizeof(int) //meta data type 8850 + 1 *sizeof(int) // meta data len 8851 + data_len; //data 8852 } 8853 8854 camera_memory_t *faceResultBuffer = mGetMemory(-1, 8855 faceResultSize, 8856 1, 8857 mCallbackCookie); 8858 if ( NULL == faceResultBuffer ) { 8859 LOGE("Not enough memory for face result data"); 8860 return NO_MEMORY; 8861 } 8862 8863 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data; 8864 memset(pFaceResult, 0, faceResultSize); 8865 unsigned char *faceData = NULL; 8866 if(fd_type == QCAMERA_FD_PREVIEW){ 8867 faceData = pFaceResult; 8868 mNumPreviewFaces = detect_data->num_faces_detected; 8869 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 8870 #ifndef VANILLA_HAL 8871 //need fill meta type and meta data len first 8872 int *data_header = (int* )pFaceResult; 8873 data_header[0] = CAMERA_META_DATA_FD; 8874 data_header[1] = (int)data_len; 8875 8876 if(data_len <= 0){ 8877 //if face is not valid or do not have face, return 8878 qcamera_callback_argm_t cbArg; 8879 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 8880 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 8881 cbArg.msg_type = CAMERA_MSG_META_DATA; 8882 cbArg.data = faceResultBuffer; 8883 cbArg.user_data = faceResultBuffer; 8884 cbArg.cookie = this; 8885 cbArg.release_cb = releaseCameraMemory; 8886 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 8887 if (rc != NO_ERROR) { 8888 LOGE("fail sending notification"); 8889 faceResultBuffer->release(faceResultBuffer); 8890 } 8891 return rc; 8892 } 8893 #endif 8894 faceData = pFaceResult + 2 *sizeof(int); //skip two int length 8895 } 8896 8897 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData; 8898 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) ); 8899 8900 roiData->number_of_faces = detect_data->num_faces_detected; 8901 roiData->faces = faces; 8902 if (roiData->number_of_faces > 0) { 8903 for (int i = 0; i < roiData->number_of_faces; i++) { 8904 faces[i].id = detect_data->faces[i].face_id; 8905 faces[i].score = detect_data->faces[i].score; 8906 8907 // left 8908 faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE( 8909 detect_data->faces[i].face_boundary.left, 8910 display_dim.width, 2000, -1000); 8911 8912 // top 8913 faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE( 8914 detect_data->faces[i].face_boundary.top, 8915 display_dim.height, 2000, -1000); 8916 8917 // right 8918 faces[i].rect[2] = faces[i].rect[0] + 8919 MAP_TO_DRIVER_COORDINATE( 8920 detect_data->faces[i].face_boundary.width, 8921 display_dim.width, 2000, 0); 8922 8923 // bottom 8924 faces[i].rect[3] = faces[i].rect[1] + 8925 MAP_TO_DRIVER_COORDINATE( 8926 detect_data->faces[i].face_boundary.height, 8927 display_dim.height, 2000, 0); 8928 8929 if (faces_data->landmark_valid) { 8930 // Center of left eye 8931 if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) { 8932 faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE( 8933 faces_data->landmark_data.face_landmarks[i].left_eye_center.x, 8934 display_dim.width, 2000, -1000); 8935 faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE( 8936 faces_data->landmark_data.face_landmarks[i].left_eye_center.y, 8937 display_dim.height, 2000, -1000); 8938 } else { 8939 faces[i].left_eye[0] = FACE_INVALID_POINT; 8940 faces[i].left_eye[1] = FACE_INVALID_POINT; 8941 } 8942 8943 // Center of right eye 8944 if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) { 8945 faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE( 8946 faces_data->landmark_data.face_landmarks[i].right_eye_center.x, 8947 display_dim.width, 2000, -1000); 8948 faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE( 8949 faces_data->landmark_data.face_landmarks[i].right_eye_center.y, 8950 display_dim.height, 2000, -1000); 8951 } else { 8952 faces[i].right_eye[0] = FACE_INVALID_POINT; 8953 faces[i].right_eye[1] = FACE_INVALID_POINT; 8954 } 8955 8956 // Center of mouth 8957 if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) { 8958 faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE( 8959 faces_data->landmark_data.face_landmarks[i].mouth_center.x, 8960 display_dim.width, 2000, -1000); 8961 faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE( 8962 faces_data->landmark_data.face_landmarks[i].mouth_center.y, 8963 display_dim.height, 2000, -1000); 8964 } else { 8965 faces[i].mouth[0] = FACE_INVALID_POINT; 8966 faces[i].mouth[1] = FACE_INVALID_POINT; 8967 } 8968 } else { 8969 // return -2000 if invalid 8970 faces[i].left_eye[0] = FACE_INVALID_POINT; 8971 faces[i].left_eye[1] = FACE_INVALID_POINT; 8972 8973 faces[i].right_eye[0] = FACE_INVALID_POINT; 8974 faces[i].right_eye[1] = FACE_INVALID_POINT; 8975 8976 faces[i].mouth[0] = FACE_INVALID_POINT; 8977 faces[i].mouth[1] = FACE_INVALID_POINT; 8978 } 8979 8980 #ifndef VANILLA_HAL 8981 #ifdef TARGET_TS_MAKEUP 8982 mFaceRect.left = detect_data->faces[i].face_boundary.left; 8983 mFaceRect.top = detect_data->faces[i].face_boundary.top; 8984 mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left; 8985 mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top; 8986 #endif 8987 if (faces_data->smile_valid) { 8988 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree; 8989 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence; 8990 } 8991 if (faces_data->blink_valid) { 8992 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected; 8993 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink; 8994 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink; 8995 } 8996 if (faces_data->recog_valid) { 8997 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised; 8998 } 8999 if (faces_data->gaze_valid) { 9000 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle; 9001 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir; 9002 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir; 9003 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir; 9004 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze; 9005 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze; 9006 } 9007 #endif 9008 9009 } 9010 } 9011 else{ 9012 #ifdef TARGET_TS_MAKEUP 9013 memset(&mFaceRect,-1,sizeof(mFaceRect)); 9014 #endif 9015 } 9016 qcamera_callback_argm_t cbArg; 9017 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 9018 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 9019 if(fd_type == QCAMERA_FD_PREVIEW){ 9020 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA; 9021 } 9022 #ifndef VANILLA_HAL 9023 else if(fd_type == QCAMERA_FD_SNAPSHOT){ 9024 cbArg.msg_type = CAMERA_MSG_META_DATA; 9025 } 9026 #endif 9027 cbArg.data = faceResultBuffer; 9028 cbArg.metadata = roiData; 9029 cbArg.user_data = faceResultBuffer; 9030 cbArg.cookie = this; 9031 cbArg.release_cb = releaseCameraMemory; 9032 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 9033 if (rc != NO_ERROR) { 9034 LOGE("fail sending notification"); 9035 faceResultBuffer->release(faceResultBuffer); 9036 } 9037 9038 return rc; 9039 } 9040 9041 /*=========================================================================== 9042 * FUNCTION : releaseCameraMemory 9043 * 9044 * DESCRIPTION: releases camera memory objects 9045 * 9046 * PARAMETERS : 9047 * @data : buffer to be released 9048 * @cookie : context data 9049 * @cbStatus: callback status 9050 * 9051 * RETURN : None 9052 *==========================================================================*/ 9053 void QCamera2HardwareInterface::releaseCameraMemory(void *data, 9054 void */*cookie*/, 9055 int32_t /*cbStatus*/) 9056 { 9057 camera_memory_t *mem = ( camera_memory_t * ) data; 9058 if ( NULL != mem ) { 9059 mem->release(mem); 9060 } 9061 } 9062 9063 /*=========================================================================== 9064 * FUNCTION : returnStreamBuffer 9065 * 9066 * DESCRIPTION: returns back a stream buffer 9067 * 9068 * PARAMETERS : 9069 * @data : buffer to be released 9070 * @cookie : context data 9071 * @cbStatus: callback status 9072 * 9073 * RETURN : None 9074 *==========================================================================*/ 9075 void QCamera2HardwareInterface::returnStreamBuffer(void *data, 9076 void *cookie, 9077 int32_t /*cbStatus*/) 9078 { 9079 QCameraStream *stream = ( QCameraStream * ) cookie; 9080 int idx = *((int *)data); 9081 if ((NULL != stream) && (0 <= idx)) { 9082 stream->bufDone((uint32_t)idx); 9083 } else { 9084 LOGE("Cannot return buffer %d %p", idx, cookie); 9085 } 9086 } 9087 9088 /*=========================================================================== 9089 * FUNCTION : processHistogramStats 9090 * 9091 * DESCRIPTION: process histogram stats 9092 * 9093 * PARAMETERS : 9094 * @hist_data : ptr to histogram stats struct 9095 * 9096 * RETURN : int32_t type of status 9097 * NO_ERROR -- success 9098 * none-zero failure code 9099 *==========================================================================*/ 9100 int32_t QCamera2HardwareInterface::processHistogramStats( 9101 __unused cam_hist_stats_t &stats_data) 9102 { 9103 #ifndef VANILLA_HAL 9104 if (!mParameters.isHistogramEnabled()) { 9105 LOGH("Histogram not enabled, no ops here"); 9106 return NO_ERROR; 9107 } 9108 9109 camera_memory_t *histBuffer = mGetMemory(-1, 9110 sizeof(cam_histogram_data_t), 9111 1, 9112 mCallbackCookie); 9113 if ( NULL == histBuffer ) { 9114 LOGE("Not enough memory for histogram data"); 9115 return NO_MEMORY; 9116 } 9117 9118 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data; 9119 if (pHistData == NULL) { 9120 LOGE("memory data ptr is NULL"); 9121 return UNKNOWN_ERROR; 9122 } 9123 9124 switch (stats_data.type) { 9125 case CAM_HISTOGRAM_TYPE_BAYER: 9126 switch (stats_data.bayer_stats.data_type) { 9127 case CAM_STATS_CHANNEL_Y: 9128 case CAM_STATS_CHANNEL_R: 9129 *pHistData = stats_data.bayer_stats.r_stats; 9130 break; 9131 case CAM_STATS_CHANNEL_GR: 9132 *pHistData = stats_data.bayer_stats.gr_stats; 9133 break; 9134 case CAM_STATS_CHANNEL_GB: 9135 case CAM_STATS_CHANNEL_ALL: 9136 *pHistData = stats_data.bayer_stats.gb_stats; 9137 break; 9138 case CAM_STATS_CHANNEL_B: 9139 *pHistData = stats_data.bayer_stats.b_stats; 9140 break; 9141 default: 9142 *pHistData = stats_data.bayer_stats.r_stats; 9143 break; 9144 } 9145 break; 9146 case CAM_HISTOGRAM_TYPE_YUV: 9147 *pHistData = stats_data.yuv_stats; 9148 break; 9149 } 9150 9151 qcamera_callback_argm_t cbArg; 9152 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 9153 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 9154 cbArg.msg_type = CAMERA_MSG_STATS_DATA; 9155 cbArg.data = histBuffer; 9156 cbArg.user_data = histBuffer; 9157 cbArg.cookie = this; 9158 cbArg.release_cb = releaseCameraMemory; 9159 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 9160 if (rc != NO_ERROR) { 9161 LOGE("fail sending notification"); 9162 histBuffer->release(histBuffer); 9163 } 9164 #endif 9165 return NO_ERROR; 9166 } 9167 9168 /*=========================================================================== 9169 * FUNCTION : calcThermalLevel 9170 * 9171 * DESCRIPTION: Calculates the target fps range depending on 9172 * the thermal level. 9173 * Note that this function can be called from QCameraParametersIntf 9174 * while mutex is held. So it should not call back into 9175 * QCameraParametersIntf causing deadlock. 9176 * 9177 * PARAMETERS : 9178 * @level : received thermal level 9179 * @minFPS : minimum configured fps range 9180 * @maxFPS : maximum configured fps range 9181 * @minVideoFps: minimum configured fps range 9182 * @maxVideoFps: maximum configured fps range 9183 * @adjustedRange : target fps range 9184 * @skipPattern : target skip pattern 9185 * 9186 * RETURN : int32_t type of status 9187 * NO_ERROR -- success 9188 * none-zero failure code 9189 *==========================================================================*/ 9190 int QCamera2HardwareInterface::calcThermalLevel( 9191 qcamera_thermal_level_enum_t level, 9192 const int minFPSi, 9193 const int maxFPSi, 9194 const float &minVideoFps, 9195 const float &maxVideoFps, 9196 cam_fps_range_t &adjustedRange, 9197 enum msm_vfe_frame_skip_pattern &skipPattern) 9198 { 9199 const float minFPS = (float)minFPSi; 9200 const float maxFPS = (float)maxFPSi; 9201 9202 LOGH("level: %d, preview minfps %f, preview maxfpS %f, " 9203 "video minfps %f, video maxfpS %f", 9204 level, minFPS, maxFPS, minVideoFps, maxVideoFps); 9205 9206 switch(level) { 9207 case QCAMERA_THERMAL_NO_ADJUSTMENT: 9208 { 9209 adjustedRange.min_fps = minFPS / 1000.0f; 9210 adjustedRange.max_fps = maxFPS / 1000.0f; 9211 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 9212 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 9213 skipPattern = NO_SKIP; 9214 } 9215 break; 9216 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT: 9217 { 9218 adjustedRange.min_fps = minFPS / 1000.0f; 9219 adjustedRange.max_fps = maxFPS / 1000.0f; 9220 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps; 9221 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps; 9222 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 9223 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 9224 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps; 9225 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps; 9226 if ( adjustedRange.min_fps < 1 ) { 9227 adjustedRange.min_fps = 1; 9228 } 9229 if ( adjustedRange.max_fps < 1 ) { 9230 adjustedRange.max_fps = 1; 9231 } 9232 if ( adjustedRange.video_min_fps < 1 ) { 9233 adjustedRange.video_min_fps = 1; 9234 } 9235 if ( adjustedRange.video_max_fps < 1 ) { 9236 adjustedRange.video_max_fps = 1; 9237 } 9238 skipPattern = EVERY_2FRAME; 9239 } 9240 break; 9241 case QCAMERA_THERMAL_BIG_ADJUSTMENT: 9242 { 9243 adjustedRange.min_fps = minFPS / 1000.0f; 9244 adjustedRange.max_fps = maxFPS / 1000.0f; 9245 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps; 9246 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps; 9247 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 9248 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 9249 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps; 9250 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps; 9251 if ( adjustedRange.min_fps < 1 ) { 9252 adjustedRange.min_fps = 1; 9253 } 9254 if ( adjustedRange.max_fps < 1 ) { 9255 adjustedRange.max_fps = 1; 9256 } 9257 if ( adjustedRange.video_min_fps < 1 ) { 9258 adjustedRange.video_min_fps = 1; 9259 } 9260 if ( adjustedRange.video_max_fps < 1 ) { 9261 adjustedRange.video_max_fps = 1; 9262 } 9263 skipPattern = EVERY_4FRAME; 9264 } 9265 break; 9266 case QCAMERA_THERMAL_MAX_ADJUSTMENT: 9267 { 9268 // Stop Preview? 9269 // Set lowest min FPS for now 9270 adjustedRange.min_fps = minFPS/1000.0f; 9271 adjustedRange.max_fps = minFPS/1000.0f; 9272 cam_capability_t *capability = gCamCapability[mCameraId]; 9273 for (size_t i = 0; 9274 i < capability->fps_ranges_tbl_cnt; 9275 i++) { 9276 if (capability->fps_ranges_tbl[i].min_fps < 9277 adjustedRange.min_fps) { 9278 adjustedRange.min_fps = 9279 capability->fps_ranges_tbl[i].min_fps; 9280 adjustedRange.max_fps = adjustedRange.min_fps; 9281 } 9282 } 9283 skipPattern = MAX_SKIP; 9284 adjustedRange.video_min_fps = adjustedRange.min_fps; 9285 adjustedRange.video_max_fps = adjustedRange.max_fps; 9286 } 9287 break; 9288 case QCAMERA_THERMAL_SHUTDOWN: 9289 { 9290 // send error notify 9291 LOGE("Received shutdown thermal level. Closing camera"); 9292 sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); 9293 } 9294 break; 9295 default: 9296 { 9297 LOGW("Invalid thermal level %d", level); 9298 return BAD_VALUE; 9299 } 9300 break; 9301 } 9302 9303 return NO_ERROR; 9304 } 9305 9306 /*=========================================================================== 9307 * FUNCTION : recalcFPSRange 9308 * 9309 * DESCRIPTION: adjust the configured fps range regarding 9310 * the last thermal level. 9311 * 9312 * PARAMETERS : 9313 * @minFPS : minimum configured fps range 9314 * @maxFPS : maximum configured fps range 9315 * @minVideoFPS : minimum configured video fps 9316 * @maxVideoFPS : maximum configured video fps 9317 * @adjustedRange : target fps range 9318 * 9319 * RETURN : int32_t type of status 9320 * NO_ERROR -- success 9321 * none-zero failure code 9322 *==========================================================================*/ 9323 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS, 9324 const float &minVideoFPS, const float &maxVideoFPS, 9325 cam_fps_range_t &adjustedRange) 9326 { 9327 enum msm_vfe_frame_skip_pattern skipPattern; 9328 calcThermalLevel(mThermalLevel, 9329 minFPS, 9330 maxFPS, 9331 minVideoFPS, 9332 maxVideoFPS, 9333 adjustedRange, 9334 skipPattern); 9335 return NO_ERROR; 9336 } 9337 9338 /*=========================================================================== 9339 * FUNCTION : updateThermalLevel 9340 * 9341 * DESCRIPTION: update thermal level depending on thermal events 9342 * 9343 * PARAMETERS : 9344 * @level : thermal level 9345 * 9346 * RETURN : int32_t type of status 9347 * NO_ERROR -- success 9348 * none-zero failure code 9349 *==========================================================================*/ 9350 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level) 9351 { 9352 int ret = NO_ERROR; 9353 cam_fps_range_t adjustedRange; 9354 int minFPS, maxFPS; 9355 float minVideoFPS, maxVideoFPS; 9356 enum msm_vfe_frame_skip_pattern skipPattern; 9357 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level; 9358 9359 9360 if (!mCameraOpened) { 9361 LOGH("Camera is not opened, no need to update camera parameters"); 9362 return NO_ERROR; 9363 } 9364 if (mParameters.getRecordingHintValue()) { 9365 LOGH("Thermal mitigation isn't enabled in camcorder mode"); 9366 return NO_ERROR; 9367 } 9368 9369 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 9370 qcamera_thermal_mode thermalMode = mParameters.getThermalMode(); 9371 if (mParameters.isHfrMode()) { 9372 cam_fps_range_t hfrFpsRange; 9373 mParameters.getHfrFps(hfrFpsRange); 9374 minVideoFPS = hfrFpsRange.video_min_fps; 9375 maxVideoFPS = hfrFpsRange.video_max_fps; 9376 } else { 9377 minVideoFPS = minFPS; 9378 maxVideoFPS = maxFPS; 9379 } 9380 9381 calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS, 9382 adjustedRange, skipPattern); 9383 mThermalLevel = level; 9384 9385 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS) 9386 ret = mParameters.adjustPreviewFpsRange(&adjustedRange); 9387 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP) 9388 ret = mParameters.setFrameSkip(skipPattern); 9389 else 9390 LOGW("Incorrect thermal mode %d", thermalMode); 9391 9392 return ret; 9393 9394 } 9395 9396 /*=========================================================================== 9397 * FUNCTION : updateParameters 9398 * 9399 * DESCRIPTION: update parameters 9400 * 9401 * PARAMETERS : 9402 * @parms : input parameters string 9403 * @needRestart : output, flag to indicate if preview restart is needed 9404 * 9405 * RETURN : int32_t type of status 9406 * NO_ERROR -- success 9407 * none-zero failure code 9408 *==========================================================================*/ 9409 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart) 9410 { 9411 int rc = NO_ERROR; 9412 9413 String8 str = String8(parms); 9414 rc = mParameters.updateParameters(str, needRestart); 9415 setNeedRestart(needRestart); 9416 9417 // update stream based parameter settings 9418 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 9419 if (m_channels[i] != NULL) { 9420 m_channels[i]->UpdateStreamBasedParameters(mParameters); 9421 } 9422 } 9423 9424 return rc; 9425 } 9426 9427 /*=========================================================================== 9428 * FUNCTION : commitParameterChanges 9429 * 9430 * DESCRIPTION: commit parameter changes to the backend to take effect 9431 * 9432 * PARAMETERS : none 9433 * 9434 * RETURN : int32_t type of status 9435 * NO_ERROR -- success 9436 * none-zero failure code 9437 * NOTE : This function must be called after updateParameters. 9438 * Otherwise, no change will be passed to backend to take effect. 9439 *==========================================================================*/ 9440 int QCamera2HardwareInterface::commitParameterChanges() 9441 { 9442 int rc = NO_ERROR; 9443 rc = mParameters.commitParameters(); 9444 if (rc == NO_ERROR) { 9445 // update number of snapshot based on committed parameters setting 9446 rc = mParameters.setNumOfSnapshot(); 9447 } 9448 return rc; 9449 } 9450 9451 /*=========================================================================== 9452 * FUNCTION : needDebugFps 9453 * 9454 * DESCRIPTION: if fps log info need to be printed out 9455 * 9456 * PARAMETERS : none 9457 * 9458 * RETURN : true: need print out fps log 9459 * false: no need to print out fps log 9460 *==========================================================================*/ 9461 bool QCamera2HardwareInterface::needDebugFps() 9462 { 9463 bool needFps = false; 9464 needFps = mParameters.isFpsDebugEnabled(); 9465 return needFps; 9466 } 9467 9468 /*=========================================================================== 9469 * FUNCTION : isCACEnabled 9470 * 9471 * DESCRIPTION: if CAC is enabled 9472 * 9473 * PARAMETERS : none 9474 * 9475 * RETURN : true: needed 9476 * false: no need 9477 *==========================================================================*/ 9478 bool QCamera2HardwareInterface::isCACEnabled() 9479 { 9480 char prop[PROPERTY_VALUE_MAX]; 9481 memset(prop, 0, sizeof(prop)); 9482 property_get("persist.camera.feature.cac", prop, "0"); 9483 int enableCAC = atoi(prop); 9484 return enableCAC == 1; 9485 } 9486 9487 /*=========================================================================== 9488 * FUNCTION : is4k2kResolution 9489 * 9490 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k 9491 * 9492 * PARAMETERS : none 9493 * 9494 * RETURN : true: needed 9495 * false: no need 9496 *==========================================================================*/ 9497 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution) 9498 { 9499 bool enabled = false; 9500 if ((resolution->width == 4096 && resolution->height == 2160) || 9501 (resolution->width == 3840 && resolution->height == 2160) ) { 9502 enabled = true; 9503 } 9504 return enabled; 9505 } 9506 9507 /*=========================================================================== 9508 * FUNCTION : isPreviewRestartEnabled 9509 * 9510 * DESCRIPTION: Check whether preview should be restarted automatically 9511 * during image capture. 9512 * 9513 * PARAMETERS : none 9514 * 9515 * RETURN : true: needed 9516 * false: no need 9517 *==========================================================================*/ 9518 bool QCamera2HardwareInterface::isPreviewRestartEnabled() 9519 { 9520 char prop[PROPERTY_VALUE_MAX]; 9521 memset(prop, 0, sizeof(prop)); 9522 property_get("persist.camera.feature.restart", prop, "0"); 9523 int earlyRestart = atoi(prop); 9524 return earlyRestart == 1; 9525 } 9526 9527 /*=========================================================================== 9528 * FUNCTION : needReprocess 9529 * 9530 * DESCRIPTION: if reprocess is needed 9531 * 9532 * PARAMETERS : none 9533 * 9534 * RETURN : true: needed 9535 * false: no need 9536 *==========================================================================*/ 9537 bool QCamera2HardwareInterface::needReprocess() 9538 { 9539 bool needReprocess = false; 9540 9541 if (!mParameters.isJpegPictureFormat() && 9542 !mParameters.isNV21PictureFormat()) { 9543 // RAW image, no need to reprocess 9544 return false; 9545 } 9546 9547 //Disable reprocess for 4K liveshot case but enable if lowpower mode 9548 if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue() 9549 && !isLowPowerMode()) { 9550 return false; 9551 } 9552 9553 // pp feature config 9554 cam_pp_feature_config_t pp_config; 9555 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 9556 9557 //Decide whether to do reprocess or not based on 9558 //ppconfig obtained in the first pass. 9559 getPPConfig(pp_config); 9560 9561 if (pp_config.feature_mask > 0) { 9562 needReprocess = true; 9563 } 9564 9565 LOGH("needReprocess %s", needReprocess ? "true" : "false"); 9566 return needReprocess; 9567 } 9568 9569 9570 /*=========================================================================== 9571 * FUNCTION : needRotationReprocess 9572 * 9573 * DESCRIPTION: if rotation needs to be done by reprocess in pp 9574 * 9575 * PARAMETERS : none 9576 * 9577 * RETURN : true: needed 9578 * false: no need 9579 *==========================================================================*/ 9580 bool QCamera2HardwareInterface::needRotationReprocess() 9581 { 9582 if (!mParameters.isJpegPictureFormat() && 9583 !mParameters.isNV21PictureFormat()) { 9584 // RAW image, no need to reprocess 9585 return false; 9586 } 9587 9588 //Disable reprocess for 4K liveshot case 9589 if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue() 9590 && !isLowPowerMode()) { 9591 //Disable reprocess for 4K liveshot case 9592 return false; 9593 } 9594 9595 if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & 9596 CAM_QCOM_FEATURE_ROTATION) > 0 && 9597 (mParameters.getJpegRotation() > 0)) { 9598 // current rotation is not zero, and pp has the capability to process rotation 9599 LOGH("need to do reprocess for rotation=%d", 9600 mParameters.getJpegRotation()); 9601 return true; 9602 } 9603 9604 return false; 9605 } 9606 9607 /*=========================================================================== 9608 * FUNCTION : getThumbnailSize 9609 * 9610 * DESCRIPTION: get user set thumbnail size 9611 * 9612 * PARAMETERS : 9613 * @dim : output of thumbnail dimension 9614 * 9615 * RETURN : none 9616 *==========================================================================*/ 9617 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim) 9618 { 9619 mParameters.getThumbnailSize(&dim.width, &dim.height); 9620 } 9621 9622 /*=========================================================================== 9623 * FUNCTION : getJpegQuality 9624 * 9625 * DESCRIPTION: get user set jpeg quality 9626 * 9627 * PARAMETERS : none 9628 * 9629 * RETURN : jpeg quality setting 9630 *==========================================================================*/ 9631 uint32_t QCamera2HardwareInterface::getJpegQuality() 9632 { 9633 uint32_t quality = 0; 9634 quality = mParameters.getJpegQuality(); 9635 return quality; 9636 } 9637 9638 /*=========================================================================== 9639 * FUNCTION : getExifData 9640 * 9641 * DESCRIPTION: get exif data to be passed into jpeg encoding 9642 * 9643 * PARAMETERS : none 9644 * 9645 * RETURN : exif data from user setting and GPS 9646 *==========================================================================*/ 9647 QCameraExif *QCamera2HardwareInterface::getExifData() 9648 { 9649 QCameraExif *exif = new QCameraExif(); 9650 if (exif == NULL) { 9651 LOGE("No memory for QCameraExif"); 9652 return NULL; 9653 } 9654 9655 int32_t rc = NO_ERROR; 9656 9657 // add exif entries 9658 String8 dateTime, subSecTime; 9659 rc = mParameters.getExifDateTime(dateTime, subSecTime); 9660 if(rc == NO_ERROR) { 9661 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII, 9662 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 9663 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII, 9664 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 9665 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII, 9666 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 9667 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII, 9668 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 9669 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII, 9670 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 9671 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII, 9672 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 9673 } else { 9674 LOGW("getExifDateTime failed"); 9675 } 9676 9677 rat_t focalLength; 9678 rc = mParameters.getExifFocalLength(&focalLength); 9679 if (rc == NO_ERROR) { 9680 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 9681 EXIF_RATIONAL, 9682 1, 9683 (void *)&(focalLength)); 9684 } else { 9685 LOGW("getExifFocalLength failed"); 9686 } 9687 9688 uint16_t isoSpeed = mParameters.getExifIsoSpeed(); 9689 if (getSensorType() != CAM_SENSOR_YUV) { 9690 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 9691 EXIF_SHORT, 9692 1, 9693 (void *)&(isoSpeed)); 9694 } 9695 9696 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 9697 uint32_t count = 0; 9698 9699 /*gps data might not be available */ 9700 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count); 9701 if(rc == NO_ERROR) { 9702 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 9703 EXIF_ASCII, 9704 count, 9705 (void *)gpsProcessingMethod); 9706 } else { 9707 LOGW("getExifGpsProcessingMethod failed"); 9708 } 9709 9710 rat_t latitude[3]; 9711 char latRef[2]; 9712 rc = mParameters.getExifLatitude(latitude, latRef); 9713 if(rc == NO_ERROR) { 9714 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 9715 EXIF_RATIONAL, 9716 3, 9717 (void *)latitude); 9718 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 9719 EXIF_ASCII, 9720 2, 9721 (void *)latRef); 9722 } else { 9723 LOGW("getExifLatitude failed"); 9724 } 9725 9726 rat_t longitude[3]; 9727 char lonRef[2]; 9728 rc = mParameters.getExifLongitude(longitude, lonRef); 9729 if(rc == NO_ERROR) { 9730 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 9731 EXIF_RATIONAL, 9732 3, 9733 (void *)longitude); 9734 9735 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 9736 EXIF_ASCII, 9737 2, 9738 (void *)lonRef); 9739 } else { 9740 LOGW("getExifLongitude failed"); 9741 } 9742 9743 rat_t altitude; 9744 char altRef; 9745 rc = mParameters.getExifAltitude(&altitude, &altRef); 9746 if(rc == NO_ERROR) { 9747 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 9748 EXIF_RATIONAL, 9749 1, 9750 (void *)&(altitude)); 9751 9752 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 9753 EXIF_BYTE, 9754 1, 9755 (void *)&altRef); 9756 } else { 9757 LOGW("getExifAltitude failed"); 9758 } 9759 9760 char gpsDateStamp[20]; 9761 rat_t gpsTimeStamp[3]; 9762 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp); 9763 if(rc == NO_ERROR) { 9764 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 9765 EXIF_ASCII, 9766 (uint32_t)(strlen(gpsDateStamp) + 1), 9767 (void *)gpsDateStamp); 9768 9769 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 9770 EXIF_RATIONAL, 9771 3, 9772 (void *)gpsTimeStamp); 9773 } else { 9774 LOGW("getExifGpsDataTimeStamp failed"); 9775 } 9776 9777 #ifdef ENABLE_MODEL_INFO_EXIF 9778 9779 char value[PROPERTY_VALUE_MAX]; 9780 if (property_get("persist.sys.exif.make", value, "") > 0 || 9781 property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 9782 exif->addEntry(EXIFTAGID_MAKE, 9783 EXIF_ASCII, strlen(value) + 1, (void *)value); 9784 } else { 9785 LOGW("getExifMaker failed"); 9786 } 9787 9788 if (property_get("persist.sys.exif.model", value, "") > 0 || 9789 property_get("ro.product.model", value, "QCAM-AA") > 0) { 9790 exif->addEntry(EXIFTAGID_MODEL, 9791 EXIF_ASCII, strlen(value) + 1, (void *)value); 9792 } else { 9793 LOGW("getExifModel failed"); 9794 } 9795 9796 if (property_get("ro.build.description", value, "QCAM-AA") > 0) { 9797 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII, 9798 (uint32_t)(strlen(value) + 1), (void *)value); 9799 } else { 9800 LOGW("getExifSoftware failed"); 9801 } 9802 9803 #endif 9804 9805 if (mParameters.useJpegExifRotation()) { 9806 int16_t orientation; 9807 switch (mParameters.getJpegExifRotation()) { 9808 case 0: 9809 orientation = 1; 9810 break; 9811 case 90: 9812 orientation = 6; 9813 break; 9814 case 180: 9815 orientation = 3; 9816 break; 9817 case 270: 9818 orientation = 8; 9819 break; 9820 default: 9821 orientation = 1; 9822 break; 9823 } 9824 exif->addEntry(EXIFTAGID_ORIENTATION, 9825 EXIF_SHORT, 9826 1, 9827 (void *)&orientation); 9828 exif->addEntry(EXIFTAGID_TN_ORIENTATION, 9829 EXIF_SHORT, 9830 1, 9831 (void *)&orientation); 9832 } 9833 9834 return exif; 9835 } 9836 9837 /*=========================================================================== 9838 * FUNCTION : setHistogram 9839 * 9840 * DESCRIPTION: set if histogram should be enabled 9841 * 9842 * PARAMETERS : 9843 * @histogram_en : bool flag if histogram should be enabled 9844 * 9845 * RETURN : int32_t type of status 9846 * NO_ERROR -- success 9847 * none-zero failure code 9848 *==========================================================================*/ 9849 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en) 9850 { 9851 return mParameters.setHistogram(histogram_en); 9852 } 9853 9854 /*=========================================================================== 9855 * FUNCTION : setFaceDetection 9856 * 9857 * DESCRIPTION: set if face detection should be enabled 9858 * 9859 * PARAMETERS : 9860 * @enabled : bool flag if face detection should be enabled 9861 * 9862 * RETURN : int32_t type of status 9863 * NO_ERROR -- success 9864 * none-zero failure code 9865 *==========================================================================*/ 9866 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled) 9867 { 9868 return mParameters.setFaceDetection(enabled, true); 9869 } 9870 9871 /*=========================================================================== 9872 * FUNCTION : isCaptureShutterEnabled 9873 * 9874 * DESCRIPTION: Check whether shutter should be triggered immediately after 9875 * capture 9876 * 9877 * PARAMETERS : 9878 * 9879 * RETURN : true - regular capture 9880 * false - other type of capture 9881 *==========================================================================*/ 9882 bool QCamera2HardwareInterface::isCaptureShutterEnabled() 9883 { 9884 char prop[PROPERTY_VALUE_MAX]; 9885 memset(prop, 0, sizeof(prop)); 9886 property_get("persist.camera.feature.shutter", prop, "0"); 9887 int enableShutter = atoi(prop); 9888 return enableShutter == 1; 9889 } 9890 9891 /*=========================================================================== 9892 * FUNCTION : needProcessPreviewFrame 9893 * 9894 * DESCRIPTION: returns whether preview frame need to be displayed 9895 * 9896 * PARAMETERS : 9897 * @frameID : frameID of frame to be processed 9898 * 9899 * RETURN : int32_t type of status 9900 * NO_ERROR -- success 9901 * none-zero failure code 9902 *==========================================================================*/ 9903 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID) 9904 { 9905 return (((m_stateMachine.isPreviewRunning()) && 9906 (!isDisplayFrameToSkip(frameID)) && 9907 (!mParameters.isInstantAECEnabled())) || 9908 (isPreviewRestartEnabled())); 9909 } 9910 9911 /*=========================================================================== 9912 * FUNCTION : needSendPreviewCallback 9913 * 9914 * DESCRIPTION: returns whether preview frame need to callback to APP 9915 * 9916 * PARAMETERS : 9917 * 9918 * RETURN : true - need preview frame callbck 9919 * false - not send preview frame callback 9920 *==========================================================================*/ 9921 bool QCamera2HardwareInterface::needSendPreviewCallback() 9922 { 9923 return m_stateMachine.isPreviewRunning() 9924 && (mDataCb != NULL) 9925 && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) 9926 && m_stateMachine.isPreviewCallbackNeeded(); 9927 }; 9928 9929 /*=========================================================================== 9930 * FUNCTION : setDisplaySkip 9931 * 9932 * DESCRIPTION: set range of frames to skip for preview 9933 * 9934 * PARAMETERS : 9935 * @enabled : TRUE to start skipping frame to display 9936 FALSE to stop skipping frame to display 9937 * @skipCnt : Number of frame to skip. 0 by default 9938 * 9939 * RETURN : None 9940 *==========================================================================*/ 9941 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt) 9942 { 9943 pthread_mutex_lock(&mGrallocLock); 9944 if (enabled) { 9945 setDisplayFrameSkip(); 9946 setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1); 9947 } else { 9948 setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1)); 9949 } 9950 pthread_mutex_unlock(&mGrallocLock); 9951 } 9952 9953 /*=========================================================================== 9954 * FUNCTION : setDisplayFrameSkip 9955 * 9956 * DESCRIPTION: set range of frames to skip for preview 9957 * 9958 * PARAMETERS : 9959 * @start : frameId to start skip 9960 * @end : frameId to stop skip 9961 * 9962 * RETURN : None 9963 *==========================================================================*/ 9964 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start, 9965 uint32_t end) 9966 { 9967 if (start == 0) { 9968 mFrameSkipStart = 0; 9969 mFrameSkipEnd = 0; 9970 return; 9971 } 9972 if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) { 9973 mFrameSkipStart = start; 9974 } 9975 if ((end == 0) || (end > mFrameSkipEnd)) { 9976 mFrameSkipEnd = end; 9977 } 9978 } 9979 9980 /*=========================================================================== 9981 * FUNCTION : isDisplayFrameToSkip 9982 * 9983 * DESCRIPTION: function to determin if input frame falls under skip range 9984 * 9985 * PARAMETERS : 9986 * @frameId : frameId to verify 9987 * 9988 * RETURN : true : need to skip 9989 * false: no need to skip 9990 *==========================================================================*/ 9991 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId) 9992 { 9993 return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) && 9994 (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE; 9995 } 9996 9997 /*=========================================================================== 9998 * FUNCTION : prepareHardwareForSnapshot 9999 * 10000 * DESCRIPTION: prepare hardware for snapshot, such as LED 10001 * 10002 * PARAMETERS : 10003 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation 10004 * 10005 * RETURN : int32_t type of status 10006 * NO_ERROR -- success 10007 * none-zero failure code 10008 *==========================================================================*/ 10009 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded) 10010 { 10011 ATRACE_CALL(); 10012 LOGI("[KPI Perf]: Send PREPARE SANSPHOT event"); 10013 return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle, 10014 afNeeded); 10015 } 10016 10017 /*=========================================================================== 10018 * FUNCTION : needFDMetadata 10019 * 10020 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel 10021 * 10022 * PARAMETERS : 10023 * @channel_type: channel type 10024 * 10025 * RETURN : true: needed 10026 * false: no need 10027 *==========================================================================*/ 10028 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type) 10029 { 10030 //Note: Currently we only process ZSL channel 10031 bool value = false; 10032 if(channel_type == QCAMERA_CH_TYPE_ZSL){ 10033 //check if FD requirement is enabled 10034 if(mParameters.isSnapshotFDNeeded() && 10035 mParameters.isFaceDetectionEnabled()){ 10036 value = true; 10037 LOGH("Face Detection metadata is required in ZSL mode."); 10038 } 10039 } 10040 10041 return value; 10042 } 10043 10044 /*=========================================================================== 10045 * FUNCTION : deferredWorkRoutine 10046 * 10047 * DESCRIPTION: data process routine that executes deferred tasks 10048 * 10049 * PARAMETERS : 10050 * @data : user data ptr (QCamera2HardwareInterface) 10051 * 10052 * RETURN : None 10053 *==========================================================================*/ 10054 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj) 10055 { 10056 int running = 1; 10057 int ret; 10058 uint8_t is_active = FALSE; 10059 int32_t job_status = 0; 10060 10061 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj; 10062 QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread; 10063 cmdThread->setName("CAM_defrdWrk"); 10064 10065 do { 10066 do { 10067 ret = cam_sem_wait(&cmdThread->cmd_sem); 10068 if (ret != 0 && errno != EINVAL) { 10069 LOGE("cam_sem_wait error (%s)", 10070 strerror(errno)); 10071 return NULL; 10072 } 10073 } while (ret != 0); 10074 10075 // we got notified about new cmd avail in cmd queue 10076 camera_cmd_type_t cmd = cmdThread->getCmd(); 10077 LOGD("cmd: %d", cmd); 10078 switch (cmd) { 10079 case CAMERA_CMD_TYPE_START_DATA_PROC: 10080 LOGH("start data proc"); 10081 is_active = TRUE; 10082 break; 10083 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 10084 LOGH("stop data proc"); 10085 is_active = FALSE; 10086 // signal cmd is completed 10087 cam_sem_post(&cmdThread->sync_sem); 10088 break; 10089 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 10090 { 10091 DefWork *dw = 10092 reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue()); 10093 10094 if ( NULL == dw ) { 10095 LOGE("Invalid deferred work"); 10096 break; 10097 } 10098 10099 switch( dw->cmd ) { 10100 case CMD_DEF_ALLOCATE_BUFF: 10101 { 10102 QCameraChannel * pChannel = dw->args.allocArgs.ch; 10103 10104 if ( NULL == pChannel ) { 10105 LOGE("Invalid deferred work channel"); 10106 job_status = BAD_VALUE; 10107 break; 10108 } 10109 10110 cam_stream_type_t streamType = dw->args.allocArgs.type; 10111 LOGH("Deferred buffer allocation started for stream type: %d", 10112 streamType); 10113 10114 uint32_t iNumOfStreams = pChannel->getNumOfStreams(); 10115 QCameraStream *pStream = NULL; 10116 for ( uint32_t i = 0; i < iNumOfStreams; ++i) { 10117 pStream = pChannel->getStreamByIndex(i); 10118 10119 if ( NULL == pStream ) { 10120 job_status = BAD_VALUE; 10121 break; 10122 } 10123 10124 if ( pStream->isTypeOf(streamType)) { 10125 if ( pStream->allocateBuffers() ) { 10126 LOGE("Error allocating buffers !!!"); 10127 job_status = NO_MEMORY; 10128 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10129 CAMERA_ERROR_UNKNOWN, 0); 10130 } 10131 break; 10132 } 10133 } 10134 } 10135 break; 10136 case CMD_DEF_PPROC_START: 10137 { 10138 int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob); 10139 if (ret != NO_ERROR) { 10140 job_status = ret; 10141 LOGE("PPROC Start failed"); 10142 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10143 CAMERA_ERROR_UNKNOWN, 0); 10144 break; 10145 } 10146 QCameraChannel * pChannel = dw->args.pprocArgs; 10147 assert(pChannel); 10148 10149 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) { 10150 LOGE("cannot start postprocessor"); 10151 job_status = BAD_VALUE; 10152 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10153 CAMERA_ERROR_UNKNOWN, 0); 10154 } 10155 } 10156 break; 10157 case CMD_DEF_METADATA_ALLOC: 10158 { 10159 int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob); 10160 if (ret != NO_ERROR) { 10161 job_status = ret; 10162 LOGE("Metadata alloc failed"); 10163 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10164 CAMERA_ERROR_UNKNOWN, 0); 10165 break; 10166 } 10167 pme->mMetadataMem = new QCameraMetadataStreamMemory( 10168 QCAMERA_ION_USE_CACHE); 10169 10170 if (pme->mMetadataMem == NULL) { 10171 LOGE("Unable to allocate metadata buffers"); 10172 job_status = BAD_VALUE; 10173 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10174 CAMERA_ERROR_UNKNOWN, 0); 10175 } else { 10176 int32_t rc = pme->mMetadataMem->allocate( 10177 dw->args.metadataAllocArgs.bufferCnt, 10178 dw->args.metadataAllocArgs.size, 10179 NON_SECURE); 10180 if (rc < 0) { 10181 delete pme->mMetadataMem; 10182 pme->mMetadataMem = NULL; 10183 } 10184 } 10185 } 10186 break; 10187 case CMD_DEF_CREATE_JPEG_SESSION: 10188 { 10189 QCameraChannel * pChannel = dw->args.pprocArgs; 10190 assert(pChannel); 10191 10192 int32_t ret = pme->getDefJobStatus(pme->mReprocJob); 10193 if (ret != NO_ERROR) { 10194 job_status = ret; 10195 LOGE("Jpeg create failed"); 10196 break; 10197 } 10198 10199 if (pme->m_postprocessor.createJpegSession(pChannel) 10200 != NO_ERROR) { 10201 LOGE("cannot create JPEG session"); 10202 job_status = UNKNOWN_ERROR; 10203 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10204 CAMERA_ERROR_UNKNOWN, 0); 10205 } 10206 } 10207 break; 10208 case CMD_DEF_PPROC_INIT: 10209 { 10210 int32_t rc = NO_ERROR; 10211 10212 jpeg_encode_callback_t jpegEvtHandle = 10213 dw->args.pprocInitArgs.jpeg_cb; 10214 void* user_data = dw->args.pprocInitArgs.user_data; 10215 QCameraPostProcessor *postProcessor = 10216 &(pme->m_postprocessor); 10217 uint32_t cameraId = pme->mCameraId; 10218 cam_capability_t *capability = 10219 gCamCapability[cameraId]; 10220 cam_padding_info_t padding_info; 10221 cam_padding_info_t& cam_capability_padding_info = 10222 capability->padding_info; 10223 10224 if(!pme->mJpegClientHandle) { 10225 rc = pme->initJpegHandle(); 10226 if (rc != NO_ERROR) { 10227 LOGE("Error!! creating JPEG handle failed"); 10228 job_status = UNKNOWN_ERROR; 10229 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10230 CAMERA_ERROR_UNKNOWN, 0); 10231 break; 10232 } 10233 } 10234 LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle); 10235 10236 rc = postProcessor->setJpegHandle(&pme->mJpegHandle, 10237 &pme->mJpegMpoHandle, 10238 pme->mJpegClientHandle); 10239 if (rc != 0) { 10240 LOGE("Error!! set JPEG handle failed"); 10241 job_status = UNKNOWN_ERROR; 10242 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10243 CAMERA_ERROR_UNKNOWN, 0); 10244 break; 10245 } 10246 10247 /* get max pic size for jpeg work buf calculation*/ 10248 rc = postProcessor->init(jpegEvtHandle, user_data); 10249 10250 if (rc != NO_ERROR) { 10251 LOGE("cannot init postprocessor"); 10252 job_status = UNKNOWN_ERROR; 10253 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10254 CAMERA_ERROR_UNKNOWN, 0); 10255 break; 10256 } 10257 10258 // update padding info from jpeg 10259 postProcessor->getJpegPaddingReq(padding_info); 10260 if (cam_capability_padding_info.width_padding < 10261 padding_info.width_padding) { 10262 cam_capability_padding_info.width_padding = 10263 padding_info.width_padding; 10264 } 10265 if (cam_capability_padding_info.height_padding < 10266 padding_info.height_padding) { 10267 cam_capability_padding_info.height_padding = 10268 padding_info.height_padding; 10269 } 10270 if (cam_capability_padding_info.plane_padding != 10271 padding_info.plane_padding) { 10272 cam_capability_padding_info.plane_padding = 10273 mm_stream_calc_lcm( 10274 cam_capability_padding_info.plane_padding, 10275 padding_info.plane_padding); 10276 } 10277 if (cam_capability_padding_info.offset_info.offset_x 10278 != padding_info.offset_info.offset_x) { 10279 cam_capability_padding_info.offset_info.offset_x = 10280 mm_stream_calc_lcm ( 10281 cam_capability_padding_info.offset_info.offset_x, 10282 padding_info.offset_info.offset_x); 10283 } 10284 if (cam_capability_padding_info.offset_info.offset_y 10285 != padding_info.offset_info.offset_y) { 10286 cam_capability_padding_info.offset_info.offset_y = 10287 mm_stream_calc_lcm ( 10288 cam_capability_padding_info.offset_info.offset_y, 10289 padding_info.offset_info.offset_y); 10290 } 10291 } 10292 break; 10293 case CMD_DEF_PARAM_ALLOC: 10294 { 10295 int32_t rc = NO_ERROR; 10296 if (pme->isDualCamera()) { 10297 rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT); 10298 } else { 10299 rc = pme->mParameters.allocate(); 10300 } 10301 // notify routine would not be initialized by this time. 10302 // So, just update error job status 10303 if (rc != NO_ERROR) { 10304 job_status = rc; 10305 LOGE("Param allocation failed"); 10306 break; 10307 } 10308 } 10309 break; 10310 case CMD_DEF_PARAM_INIT: 10311 { 10312 int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob); 10313 if (rc != NO_ERROR) { 10314 job_status = rc; 10315 LOGE("Param init failed"); 10316 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10317 CAMERA_ERROR_UNKNOWN, 0); 10318 break; 10319 } 10320 10321 uint32_t camId = pme->mCameraId; 10322 cam_capability_t * cap = gCamCapability[camId]; 10323 10324 if (pme->mCameraHandle == NULL) { 10325 LOGE("Camera handle is null"); 10326 job_status = BAD_VALUE; 10327 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10328 CAMERA_ERROR_UNKNOWN, 0); 10329 break; 10330 } 10331 10332 // Now PostProc need calibration data as initialization 10333 // time for jpeg_open and calibration data is a 10334 // get param for now, so params needs to be initialized 10335 // before postproc init 10336 rc = pme->mParameters.init(cap, 10337 pme->mCameraHandle, 10338 pme); 10339 if (rc != 0) { 10340 job_status = UNKNOWN_ERROR; 10341 LOGE("Parameter Initialization failed"); 10342 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10343 CAMERA_ERROR_UNKNOWN, 0); 10344 break; 10345 } 10346 10347 // Get related cam calibration only in 10348 // dual camera mode 10349 if (pme->getRelatedCamSyncInfo()->sync_control == 10350 CAM_SYNC_RELATED_SENSORS_ON) { 10351 rc = pme->mParameters.getRelatedCamCalibration( 10352 &(pme->mJpegMetadata.otp_calibration_data)); 10353 LOGD("Dumping Calibration Data Version Id %f rc %d", 10354 pme->mJpegMetadata.otp_calibration_data.calibration_format_version, 10355 rc); 10356 if (rc != 0) { 10357 job_status = UNKNOWN_ERROR; 10358 LOGE("getRelatedCamCalibration failed"); 10359 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10360 CAMERA_ERROR_UNKNOWN, 0); 10361 break; 10362 } 10363 pme->m_bRelCamCalibValid = true; 10364 } 10365 10366 pme->mJpegMetadata.sensor_mount_angle = 10367 cap->sensor_mount_angle; 10368 pme->mJpegMetadata.default_sensor_flip = FLIP_NONE; 10369 10370 pme->mParameters.setMinPpMask( 10371 cap->qcom_supported_feature_mask); 10372 pme->mExifParams.debug_params = 10373 (mm_jpeg_debug_exif_params_t *) 10374 malloc(sizeof(mm_jpeg_debug_exif_params_t)); 10375 if (!pme->mExifParams.debug_params) { 10376 LOGE("Out of Memory. Allocation failed for " 10377 "3A debug exif params"); 10378 job_status = NO_MEMORY; 10379 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10380 CAMERA_ERROR_UNKNOWN, 0); 10381 break; 10382 } 10383 memset(pme->mExifParams.debug_params, 0, 10384 sizeof(mm_jpeg_debug_exif_params_t)); 10385 } 10386 break; 10387 case CMD_DEF_GENERIC: 10388 { 10389 BackgroundTask *bgTask = dw->args.genericArgs; 10390 job_status = bgTask->bgFunction(bgTask->bgArgs); 10391 } 10392 break; 10393 default: 10394 LOGE("Incorrect command : %d", dw->cmd); 10395 } 10396 10397 pme->dequeueDeferredWork(dw, job_status); 10398 } 10399 break; 10400 case CAMERA_CMD_TYPE_EXIT: 10401 running = 0; 10402 break; 10403 default: 10404 break; 10405 } 10406 } while (running); 10407 10408 return NULL; 10409 } 10410 10411 /*=========================================================================== 10412 * FUNCTION : queueDeferredWork 10413 * 10414 * DESCRIPTION: function which queues deferred tasks 10415 * 10416 * PARAMETERS : 10417 * @cmd : deferred task 10418 * @args : deferred task arguments 10419 * 10420 * RETURN : job id of deferred job 10421 * : 0 in case of error 10422 *==========================================================================*/ 10423 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd, 10424 DeferWorkArgs args) 10425 { 10426 Mutex::Autolock l(mDefLock); 10427 for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) { 10428 if (mDefOngoingJobs[i].mDefJobId == 0) { 10429 DefWork *dw = new DefWork(cmd, sNextJobId, args); 10430 if (!dw) { 10431 LOGE("out of memory."); 10432 return 0; 10433 } 10434 if (mCmdQueue.enqueue(dw)) { 10435 mDefOngoingJobs[i].mDefJobId = sNextJobId++; 10436 mDefOngoingJobs[i].mDefJobStatus = 0; 10437 if (sNextJobId == 0) { // handle overflow 10438 sNextJobId = 1; 10439 } 10440 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, 10441 FALSE, 10442 FALSE); 10443 return mDefOngoingJobs[i].mDefJobId; 10444 } else { 10445 LOGD("Command queue not active! cmd = %d", cmd); 10446 delete dw; 10447 return 0; 10448 } 10449 } 10450 } 10451 return 0; 10452 } 10453 10454 /*=========================================================================== 10455 * FUNCTION : initJpegHandle 10456 * 10457 * DESCRIPTION: Opens JPEG client and gets a handle. 10458 * Sends Dual cam calibration info if present 10459 * 10460 * RETURN : int32_t type of status 10461 * NO_ERROR -- success 10462 * none-zero failure code 10463 *==========================================================================*/ 10464 int32_t QCamera2HardwareInterface::initJpegHandle() { 10465 // Check if JPEG client handle is present 10466 LOGH("E"); 10467 if(!mJpegClientHandle) { 10468 mm_dimension max_size = {0, 0}; 10469 cam_dimension_t size; 10470 10471 mParameters.getMaxPicSize(size); 10472 max_size.w = size.width; 10473 max_size.h = size.height; 10474 10475 if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 10476 if (m_bRelCamCalibValid) { 10477 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle, 10478 max_size, &mJpegMetadata); 10479 } else { 10480 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle, 10481 max_size, NULL); 10482 } 10483 } else { 10484 mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL); 10485 } 10486 if (!mJpegClientHandle) { 10487 LOGE("Error !! jpeg_open failed!! "); 10488 return UNKNOWN_ERROR; 10489 } 10490 // Set JPEG initialized as true to signify that this camera 10491 // has initialized the handle 10492 mJpegHandleOwner = true; 10493 } 10494 LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d", 10495 mJpegHandleOwner, mJpegClientHandle, mCameraId); 10496 return NO_ERROR; 10497 } 10498 10499 /*=========================================================================== 10500 * FUNCTION : deinitJpegHandle 10501 * 10502 * DESCRIPTION: Closes JPEG client using handle 10503 * 10504 * RETURN : int32_t type of status 10505 * NO_ERROR -- success 10506 * none-zero failure code 10507 *==========================================================================*/ 10508 int32_t QCamera2HardwareInterface::deinitJpegHandle() { 10509 int32_t rc = NO_ERROR; 10510 LOGH("E"); 10511 // Check if JPEG client handle is present and inited by this camera 10512 if(mJpegHandleOwner && mJpegClientHandle) { 10513 rc = mJpegHandle.close(mJpegClientHandle); 10514 if (rc != NO_ERROR) { 10515 LOGE("Error!! Closing mJpegClientHandle: %d failed", 10516 mJpegClientHandle); 10517 } 10518 memset(&mJpegHandle, 0, sizeof(mJpegHandle)); 10519 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle)); 10520 mJpegHandleOwner = false; 10521 } 10522 mJpegClientHandle = 0; 10523 LOGH("X rc = %d", rc); 10524 return rc; 10525 } 10526 10527 /*=========================================================================== 10528 * FUNCTION : setJpegHandleInfo 10529 * 10530 * DESCRIPTION: sets JPEG client handle info 10531 * 10532 * PARAMETERS: 10533 * @ops : JPEG ops 10534 * @mpo_ops : Jpeg MPO ops 10535 * @pJpegClientHandle : o/p Jpeg Client Handle 10536 * 10537 * RETURN : int32_t type of status 10538 * NO_ERROR -- success 10539 * none-zero failure code 10540 *==========================================================================*/ 10541 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops, 10542 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) { 10543 10544 if (pJpegClientHandle && ops && mpo_ops) { 10545 LOGH("Setting JPEG client handle %d", 10546 pJpegClientHandle); 10547 memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t)); 10548 memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t)); 10549 mJpegClientHandle = pJpegClientHandle; 10550 return NO_ERROR; 10551 } 10552 else { 10553 LOGE("Error!! No Handle found: %d", 10554 pJpegClientHandle); 10555 return BAD_VALUE; 10556 } 10557 } 10558 10559 /*=========================================================================== 10560 * FUNCTION : getJpegHandleInfo 10561 * 10562 * DESCRIPTION: gets JPEG client handle info 10563 * 10564 * PARAMETERS: 10565 * @ops : JPEG ops 10566 * @mpo_ops : Jpeg MPO ops 10567 * @pJpegClientHandle : o/p Jpeg Client Handle 10568 * 10569 * RETURN : int32_t type of status 10570 * NO_ERROR -- success 10571 * none-zero failure code 10572 *==========================================================================*/ 10573 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops, 10574 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) { 10575 10576 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 10577 LOGE("Init PProc Deferred work failed"); 10578 return UNKNOWN_ERROR; 10579 } 10580 // Copy JPEG ops if present 10581 if (ops && mpo_ops && pJpegClientHandle) { 10582 memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t)); 10583 memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t)); 10584 *pJpegClientHandle = mJpegClientHandle; 10585 LOGH("Getting JPEG client handle %d", 10586 pJpegClientHandle); 10587 return NO_ERROR; 10588 } else { 10589 return BAD_VALUE; 10590 } 10591 } 10592 10593 /*=========================================================================== 10594 * FUNCTION : dequeueDeferredWork 10595 * 10596 * DESCRIPTION: function which dequeues deferred tasks 10597 * 10598 * PARAMETERS : 10599 * @dw : deferred work 10600 * @jobStatus: deferred task job status 10601 * 10602 * RETURN : int32_t type of status 10603 * NO_ERROR -- success 10604 * none-zero failure code 10605 *==========================================================================*/ 10606 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus) 10607 { 10608 Mutex::Autolock l(mDefLock); 10609 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 10610 if (mDefOngoingJobs[i].mDefJobId == dw->id) { 10611 if (jobStatus != NO_ERROR) { 10612 mDefOngoingJobs[i].mDefJobStatus = jobStatus; 10613 LOGH("updating job status %d for id %d", 10614 jobStatus, dw->id); 10615 } else { 10616 mDefOngoingJobs[i].mDefJobId = 0; 10617 mDefOngoingJobs[i].mDefJobStatus = 0; 10618 } 10619 delete dw; 10620 mDefCond.broadcast(); 10621 return NO_ERROR; 10622 } 10623 } 10624 10625 return UNKNOWN_ERROR; 10626 } 10627 10628 /*=========================================================================== 10629 * FUNCTION : getDefJobStatus 10630 * 10631 * DESCRIPTION: Gets if a deferred task is success/fail 10632 * 10633 * PARAMETERS : 10634 * @job_id : deferred task id 10635 * 10636 * RETURN : NO_ERROR if the job success, otherwise false 10637 * 10638 * PRECONDITION : mDefLock is held by current thread 10639 *==========================================================================*/ 10640 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id) 10641 { 10642 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 10643 if (mDefOngoingJobs[i].mDefJobId == job_id) { 10644 if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) { 10645 LOGE("job_id (%d) was failed", job_id); 10646 return mDefOngoingJobs[i].mDefJobStatus; 10647 } 10648 else 10649 return NO_ERROR; 10650 } 10651 } 10652 return NO_ERROR; 10653 } 10654 10655 10656 /*=========================================================================== 10657 * FUNCTION : checkDeferredWork 10658 * 10659 * DESCRIPTION: checks if a deferred task is in progress 10660 * 10661 * PARAMETERS : 10662 * @job_id : deferred task id 10663 * 10664 * RETURN : true if the task exists, otherwise false 10665 * 10666 * PRECONDITION : mDefLock is held by current thread 10667 *==========================================================================*/ 10668 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id) 10669 { 10670 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 10671 if (mDefOngoingJobs[i].mDefJobId == job_id) { 10672 return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus); 10673 } 10674 } 10675 return false; 10676 } 10677 10678 /*=========================================================================== 10679 * FUNCTION : waitDeferredWork 10680 * 10681 * DESCRIPTION: waits for a deferred task to finish 10682 * 10683 * PARAMETERS : 10684 * @job_id : deferred task id 10685 * 10686 * RETURN : int32_t type of status 10687 * NO_ERROR -- success 10688 * none-zero failure code 10689 *==========================================================================*/ 10690 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id) 10691 { 10692 Mutex::Autolock l(mDefLock); 10693 10694 if (job_id == 0) { 10695 LOGD("Invalid job id %d", job_id); 10696 return NO_ERROR; 10697 } 10698 10699 while (checkDeferredWork(job_id) == true ) { 10700 mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT); 10701 } 10702 return getDefJobStatus(job_id); 10703 } 10704 10705 /*=========================================================================== 10706 * FUNCTION : scheduleBackgroundTask 10707 * 10708 * DESCRIPTION: Run a requested task in the deferred thread 10709 * 10710 * PARAMETERS : 10711 * @bgTask : Task to perform in the background 10712 * 10713 * RETURN : job id of deferred job 10714 * : 0 in case of error 10715 *==========================================================================*/ 10716 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask) 10717 { 10718 DeferWorkArgs args; 10719 memset(&args, 0, sizeof(DeferWorkArgs)); 10720 args.genericArgs = bgTask; 10721 10722 return queueDeferredWork(CMD_DEF_GENERIC, args); 10723 } 10724 10725 /*=========================================================================== 10726 * FUNCTION : waitForBackgroundTask 10727 * 10728 * DESCRIPTION: Wait for a background task to complete 10729 * 10730 * PARAMETERS : 10731 * @taskId : Task id to wait for 10732 * 10733 * RETURN : int32_t type of status 10734 * NO_ERROR -- success 10735 * none-zero failure code 10736 *==========================================================================*/ 10737 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId) 10738 { 10739 return waitDeferredWork(taskId); 10740 } 10741 10742 /*=========================================================================== 10743 * FUNCTION : needDeferedAllocation 10744 * 10745 * DESCRIPTION: Function to decide background task for streams 10746 * 10747 * PARAMETERS : 10748 * @stream_type : stream type 10749 * 10750 * RETURN : true - if background task is needed 10751 * false - if background task is NOT needed 10752 *==========================================================================*/ 10753 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type) 10754 { 10755 if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL) 10756 || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) { 10757 return FALSE; 10758 } 10759 10760 if ((stream_type == CAM_STREAM_TYPE_RAW) 10761 && (mParameters.getofflineRAW())) { 10762 return FALSE; 10763 } 10764 10765 if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT) 10766 && (!mParameters.getRecordingHintValue())){ 10767 return TRUE; 10768 } 10769 10770 if ((stream_type == CAM_STREAM_TYPE_PREVIEW) 10771 || (stream_type == CAM_STREAM_TYPE_METADATA) 10772 || (stream_type == CAM_STREAM_TYPE_RAW) 10773 || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) { 10774 return TRUE; 10775 } 10776 10777 if (stream_type == CAM_STREAM_TYPE_VIDEO) { 10778 return FALSE; 10779 } 10780 return FALSE; 10781 } 10782 10783 /*=========================================================================== 10784 * FUNCTION : isRegularCapture 10785 * 10786 * DESCRIPTION: Check configuration for regular catpure 10787 * 10788 * PARAMETERS : 10789 * 10790 * RETURN : true - regular capture 10791 * false - other type of capture 10792 *==========================================================================*/ 10793 bool QCamera2HardwareInterface::isRegularCapture() 10794 { 10795 bool ret = false; 10796 10797 if (numOfSnapshotsExpected() == 1 && 10798 !isLongshotEnabled() && 10799 !mParameters.isHDREnabled() && 10800 !mParameters.getRecordingHintValue() && 10801 !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) { 10802 ret = true; 10803 } 10804 return ret; 10805 } 10806 10807 /*=========================================================================== 10808 * FUNCTION : needOfflineReprocessing 10809 * 10810 * DESCRIPTION: Check for offline reprocessing 10811 * 10812 * PARAMETERS : 10813 * 10814 * RETURN : true - regular capture 10815 * false - other type of capture 10816 *==========================================================================*/ 10817 bool QCamera2HardwareInterface::needOfflineReprocessing() 10818 { 10819 bool ret = false; 10820 if (isRegularCapture() 10821 || isDualCamera()) { 10822 ret = true; 10823 } 10824 return ret; 10825 } 10826 10827 /*=========================================================================== 10828 * FUNCTION : getLogLevel 10829 * 10830 * DESCRIPTION: Reads the log level property into a variable 10831 * 10832 * PARAMETERS : 10833 * None 10834 * 10835 * RETURN : 10836 * None 10837 *==========================================================================*/ 10838 void QCamera2HardwareInterface::getLogLevel() 10839 { 10840 char prop[PROPERTY_VALUE_MAX]; 10841 10842 property_get("persist.camera.kpi.debug", prop, "1"); 10843 gKpiDebugLevel = atoi(prop); 10844 return; 10845 } 10846 10847 /*=========================================================================== 10848 * FUNCTION : getSensorType 10849 * 10850 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer 10851 * 10852 * PARAMETERS : 10853 * None 10854 * 10855 * RETURN : Type of sensor - bayer or YUV 10856 * 10857 *==========================================================================*/ 10858 cam_sensor_t QCamera2HardwareInterface::getSensorType() 10859 { 10860 return gCamCapability[mCameraId]->sensor_type.sens_type; 10861 } 10862 10863 /*=========================================================================== 10864 * FUNCTION : startRAWChannel 10865 * 10866 * DESCRIPTION: start RAW Channel 10867 * 10868 * PARAMETERS : 10869 * @pChannel : Src channel to link this RAW channel. 10870 * 10871 * RETURN : int32_t type of status 10872 * NO_ERROR -- success 10873 * none-zero failure code 10874 *==========================================================================*/ 10875 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel) 10876 { 10877 int32_t rc = NO_ERROR; 10878 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW]; 10879 if ((NULL != pChannel) && (mParameters.getofflineRAW())) { 10880 // Find and try to link a metadata stream from preview channel 10881 QCameraStream *pMetaStream = NULL; 10882 10883 if (pMetaChannel != NULL) { 10884 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 10885 QCameraStream *pStream = NULL; 10886 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 10887 pStream = pMetaChannel->getStreamByIndex(i); 10888 if ((NULL != pStream) && 10889 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) { 10890 pMetaStream = pStream; 10891 break; 10892 } 10893 } 10894 10895 if (NULL != pMetaStream) { 10896 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 10897 if (NO_ERROR != rc) { 10898 LOGE("Metadata stream link failed %d", rc); 10899 } 10900 } 10901 } 10902 rc = pChannel->start(); 10903 } 10904 return rc; 10905 } 10906 10907 /*=========================================================================== 10908 * FUNCTION : startRecording 10909 * 10910 * DESCRIPTION: start recording impl 10911 * 10912 * PARAMETERS : none 10913 * 10914 * RETURN : int32_t type of status 10915 * NO_ERROR -- success 10916 * none-zero failure code 10917 *==========================================================================*/ 10918 int32_t QCamera2HardwareInterface::stopRAWChannel() 10919 { 10920 int32_t rc = NO_ERROR; 10921 rc = stopChannel(QCAMERA_CH_TYPE_RAW); 10922 return rc; 10923 } 10924 10925 /*=========================================================================== 10926 * FUNCTION : isLowPowerMode 10927 * 10928 * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording 10929 * 10930 * PARAMETERS : 10931 * None 10932 * 10933 * RETURN : TRUE/FALSE 10934 * 10935 *==========================================================================*/ 10936 bool QCamera2HardwareInterface::isLowPowerMode() 10937 { 10938 cam_dimension_t dim; 10939 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim); 10940 10941 char prop[PROPERTY_VALUE_MAX]; 10942 property_get("camera.lowpower.record.enable", prop, "0"); 10943 int enable = atoi(prop); 10944 10945 //Enable low power mode if : 10946 //1. Video resolution is 2k (2048x1080) or above and 10947 //2. camera.lowpower.record.enable is set 10948 10949 bool isLowpower = mParameters.getRecordingHintValue() && enable 10950 && ((dim.width * dim.height) >= (2048 * 1080)); 10951 return isLowpower; 10952 } 10953 10954 /*=========================================================================== 10955 * FUNCTION : getBootToMonoTimeOffset 10956 * 10957 * DESCRIPTION: Calculate offset that is used to convert from 10958 * clock domain of boot to monotonic 10959 * 10960 * PARAMETERS : 10961 * None 10962 * 10963 * RETURN : clock offset between boottime and monotonic time. 10964 * 10965 *==========================================================================*/ 10966 nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset() 10967 { 10968 // try three times to get the clock offset, choose the one 10969 // with the minimum gap in measurements. 10970 const int tries = 3; 10971 nsecs_t bestGap, measured; 10972 for (int i = 0; i < tries; ++i) { 10973 const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC); 10974 const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME); 10975 const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC); 10976 const nsecs_t gap = tmono2 - tmono; 10977 if (i == 0 || gap < bestGap) { 10978 bestGap = gap; 10979 measured = tbase - ((tmono + tmono2) >> 1); 10980 } 10981 } 10982 return measured; 10983 } 10984 10985 /*=========================================================================== 10986 * FUNCTION : fillDualCameraFOVControl 10987 * 10988 * DESCRIPTION: Function to process FOV ctrl event from statemachine thread. 10989 * 10990 * PARAMETERS : none 10991 * 10992 * RETURN : none 10993 *==========================================================================*/ 10994 void QCamera2HardwareInterface::fillDualCameraFOVControl() 10995 { 10996 qcamera_sm_internal_evt_payload_t *payload = 10997 (qcamera_sm_internal_evt_payload_t *) 10998 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 10999 if (NULL != payload) { 11000 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 11001 payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL; 11002 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 11003 if (rc != NO_ERROR) { 11004 LOGE("processEvt Dual camera fill FOV control failed"); 11005 free(payload); 11006 payload = NULL; 11007 } 11008 } else { 11009 LOGE("No memory for Dual camera fill FOV control event"); 11010 } 11011 } 11012 11013 }; // namespace qcamera 11014