1 /* Copyright (c) 2012-2017, 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_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PREVIEW_WINDOW); 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_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_CALLBACKS); 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_CAMSCOPE_CALL(CAMSCOPE_HAL1_ENABLE_MSG_TYPE); 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_CAMSCOPE_CALL(CAMSCOPE_HAL1_DISABLE_MSG_TYPE); 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_CAMSCOPE_CALL(CAMSCOPE_HAL1_MSG_TYPE_ENABLED); 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_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_PREVIEW); 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_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_PREVIEW); 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 hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW); 374 hw->lockAPI(); 375 qcamera_api_result_t apiResult; 376 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW; 377 if (hw->isNoDisplayMode()) { 378 evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW; 379 } 380 ret = hw->processAPI(evt, NULL); 381 if (ret == NO_ERROR) { 382 hw->waitAPIResult(evt, &apiResult); 383 ret = apiResult.status; 384 } 385 hw->unlockAPI(); 386 hw->m_bPreviewStarted = true; 387 LOGI("[KPI Perf]: X ret = %d", ret); 388 return ret; 389 } 390 391 /*=========================================================================== 392 * FUNCTION : stop_preview 393 * 394 * DESCRIPTION: stop preview 395 * 396 * PARAMETERS : 397 * @device : ptr to camera device struct 398 * 399 * RETURN : none 400 *==========================================================================*/ 401 void QCamera2HardwareInterface::stop_preview(struct camera_device *device) 402 { 403 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_PREVIEW); 404 QCamera2HardwareInterface *hw = 405 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 406 if (!hw) { 407 LOGE("NULL camera device"); 408 return; 409 } 410 LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d", 411 hw->getCameraId()); 412 413 // Disable power Hint for preview 414 hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW); 415 416 hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW); 417 418 hw->lockAPI(); 419 qcamera_api_result_t apiResult; 420 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL); 421 if (ret == NO_ERROR) { 422 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult); 423 } 424 hw->unlockAPI(); 425 LOGI("[KPI Perf]: X ret = %d", ret); 426 } 427 428 /*=========================================================================== 429 * FUNCTION : preview_enabled 430 * 431 * DESCRIPTION: if preview is running 432 * 433 * PARAMETERS : 434 * @device : ptr to camera device struct 435 * 436 * RETURN : 1 -- running 437 * 0 -- not running 438 *==========================================================================*/ 439 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device) 440 { 441 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREVIEW_ENABLED); 442 int ret = NO_ERROR; 443 QCamera2HardwareInterface *hw = 444 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 445 if (!hw) { 446 LOGE("NULL camera device"); 447 return BAD_VALUE; 448 } 449 LOGD("E camera id %d", hw->getCameraId()); 450 451 hw->lockAPI(); 452 qcamera_api_result_t apiResult; 453 ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL); 454 if (ret == NO_ERROR) { 455 hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult); 456 ret = apiResult.enabled; 457 } 458 459 //if preview enabled, can enable preview callback send 460 if(apiResult.enabled) { 461 hw->m_stateMachine.setPreviewCallbackNeeded(true); 462 } 463 hw->unlockAPI(); 464 LOGD("X camera id %d", hw->getCameraId()); 465 466 return ret; 467 } 468 469 /*=========================================================================== 470 * FUNCTION : store_meta_data_in_buffers 471 * 472 * DESCRIPTION: if need to store meta data in buffers for video frame 473 * 474 * PARAMETERS : 475 * @device : ptr to camera device struct 476 * @enable : flag if enable 477 * 478 * RETURN : int32_t type of status 479 * NO_ERROR -- success 480 * none-zero failure code 481 *==========================================================================*/ 482 int QCamera2HardwareInterface::store_meta_data_in_buffers( 483 struct camera_device *device, int enable) 484 { 485 int ret = NO_ERROR; 486 QCamera2HardwareInterface *hw = 487 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 488 if (!hw) { 489 LOGE("NULL camera device"); 490 return BAD_VALUE; 491 } 492 LOGD("E camera id %d", hw->getCameraId()); 493 494 hw->lockAPI(); 495 qcamera_api_result_t apiResult; 496 ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable); 497 if (ret == NO_ERROR) { 498 hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult); 499 ret = apiResult.status; 500 } 501 hw->unlockAPI(); 502 LOGD("X camera id %d", hw->getCameraId()); 503 504 return ret; 505 } 506 507 /*=========================================================================== 508 * FUNCTION : restart_start_preview 509 * 510 * DESCRIPTION: start preview as part of the restart preview 511 * 512 * PARAMETERS : 513 * @device : ptr to camera device struct 514 * 515 * RETURN : int32_t type of status 516 * NO_ERROR -- success 517 * none-zero failure code 518 *==========================================================================*/ 519 int QCamera2HardwareInterface::restart_start_preview(struct camera_device *device) 520 { 521 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_START_PREVIEW); 522 int ret = NO_ERROR; 523 QCamera2HardwareInterface *hw = 524 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 525 if (!hw) { 526 LOGE("NULL camera device"); 527 return BAD_VALUE; 528 } 529 LOGI("E camera id %d", hw->getCameraId()); 530 hw->lockAPI(); 531 qcamera_api_result_t apiResult; 532 533 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 534 ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_START_PREVIEW, NULL); 535 if (ret == NO_ERROR) { 536 hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_START_PREVIEW, &apiResult); 537 ret = apiResult.status; 538 } 539 } else { 540 LOGE("This function is not supposed to be called in single-camera mode"); 541 ret = INVALID_OPERATION; 542 } 543 // Preview restart done, update the mPreviewRestartNeeded flag to false. 544 hw->mPreviewRestartNeeded = false; 545 hw->unlockAPI(); 546 LOGI("X camera id %d", hw->getCameraId()); 547 548 return ret; 549 } 550 551 /*=========================================================================== 552 * FUNCTION : restart_stop_preview 553 * 554 * DESCRIPTION: stop preview as part of the restart preview 555 * 556 * PARAMETERS : 557 * @device : ptr to camera device struct 558 * 559 * RETURN : int32_t type of status 560 * NO_ERROR -- success 561 * none-zero failure code 562 *==========================================================================*/ 563 int QCamera2HardwareInterface::restart_stop_preview(struct camera_device *device) 564 { 565 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_STOP_PREVIEW); 566 int ret = NO_ERROR; 567 QCamera2HardwareInterface *hw = 568 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 569 if (!hw) { 570 LOGE("NULL camera device"); 571 return BAD_VALUE; 572 } 573 LOGI("E camera id %d", hw->getCameraId()); 574 hw->lockAPI(); 575 qcamera_api_result_t apiResult; 576 577 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 578 ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, NULL); 579 if (ret == NO_ERROR) { 580 hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, &apiResult); 581 ret = apiResult.status; 582 } 583 } else { 584 LOGE("This function is not supposed to be called in single-camera mode"); 585 ret = INVALID_OPERATION; 586 } 587 588 hw->unlockAPI(); 589 LOGI("X camera id %d", hw->getCameraId()); 590 591 return ret; 592 } 593 594 /*=========================================================================== 595 * FUNCTION : pre_start_recording 596 * 597 * DESCRIPTION: prepare for the start recording 598 * 599 * PARAMETERS : 600 * @device : ptr to camera device struct 601 * 602 * RETURN : int32_t type of status 603 * NO_ERROR -- success 604 * none-zero failure code 605 *==========================================================================*/ 606 int QCamera2HardwareInterface::pre_start_recording(struct camera_device *device) 607 { 608 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_START_RECORDING); 609 int ret = NO_ERROR; 610 QCamera2HardwareInterface *hw = 611 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 612 if (!hw) { 613 LOGE("NULL camera device"); 614 return BAD_VALUE; 615 } 616 LOGH("[KPI Perf]: E PROFILE_PRE_START_RECORDING camera id %d", 617 hw->getCameraId()); 618 hw->lockAPI(); 619 qcamera_api_result_t apiResult; 620 ret = hw->processAPI(QCAMERA_SM_EVT_PRE_START_RECORDING, NULL); 621 if (ret == NO_ERROR) { 622 hw->waitAPIResult(QCAMERA_SM_EVT_PRE_START_RECORDING, &apiResult); 623 ret = apiResult.status; 624 } 625 hw->unlockAPI(); 626 LOGH("[KPI Perf]: X"); 627 return ret; 628 } 629 630 /*=========================================================================== 631 * FUNCTION : start_recording 632 * 633 * DESCRIPTION: start recording 634 * 635 * PARAMETERS : 636 * @device : ptr to camera device struct 637 * 638 * RETURN : int32_t type of status 639 * NO_ERROR -- success 640 * none-zero failure code 641 *==========================================================================*/ 642 int QCamera2HardwareInterface::start_recording(struct camera_device *device) 643 { 644 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_RECORDING); 645 int ret = NO_ERROR; 646 QCamera2HardwareInterface *hw = 647 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 648 if (!hw) { 649 LOGE("NULL camera device"); 650 return BAD_VALUE; 651 } 652 653 hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING); 654 655 LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d", 656 hw->getCameraId()); 657 // Give HWI control to call pre_start_recording in single camera mode. 658 // In dual-cam mode, this control belongs to muxer. 659 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 660 ret = pre_start_recording(device); 661 if (ret != NO_ERROR) { 662 LOGE("pre_start_recording failed with ret = %d", ret); 663 hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING); 664 return ret; 665 } 666 } 667 668 hw->lockAPI(); 669 qcamera_api_result_t apiResult; 670 ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL); 671 if (ret == NO_ERROR) { 672 hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult); 673 ret = apiResult.status; 674 } 675 hw->unlockAPI(); 676 hw->m_bRecordStarted = true; 677 LOGI("[KPI Perf]: X ret = %d", ret); 678 679 return ret; 680 } 681 682 /*=========================================================================== 683 * FUNCTION : stop_recording 684 * 685 * DESCRIPTION: stop recording 686 * 687 * PARAMETERS : 688 * @device : ptr to camera device struct 689 * 690 * RETURN : none 691 *==========================================================================*/ 692 void QCamera2HardwareInterface::stop_recording(struct camera_device *device) 693 { 694 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_RECORDING); 695 QCamera2HardwareInterface *hw = 696 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 697 if (!hw) { 698 LOGE("NULL camera device"); 699 return; 700 } 701 702 hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING); 703 704 LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d", 705 hw->getCameraId()); 706 707 hw->lockAPI(); 708 qcamera_api_result_t apiResult; 709 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL); 710 if (ret == NO_ERROR) { 711 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult); 712 } 713 hw->unlockAPI(); 714 LOGI("[KPI Perf]: X ret = %d", ret); 715 } 716 717 /*=========================================================================== 718 * FUNCTION : recording_enabled 719 * 720 * DESCRIPTION: if recording is running 721 * 722 * PARAMETERS : 723 * @device : ptr to camera device struct 724 * 725 * RETURN : 1 -- running 726 * 0 -- not running 727 *==========================================================================*/ 728 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device) 729 { 730 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RECORDING_ENABLED); 731 int ret = NO_ERROR; 732 QCamera2HardwareInterface *hw = 733 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 734 if (!hw) { 735 LOGE("NULL camera device"); 736 return BAD_VALUE; 737 } 738 LOGD("E camera id %d", hw->getCameraId()); 739 hw->lockAPI(); 740 qcamera_api_result_t apiResult; 741 ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL); 742 if (ret == NO_ERROR) { 743 hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult); 744 ret = apiResult.enabled; 745 } 746 hw->unlockAPI(); 747 LOGD("X camera id %d", hw->getCameraId()); 748 749 return ret; 750 } 751 752 /*=========================================================================== 753 * FUNCTION : release_recording_frame 754 * 755 * DESCRIPTION: return recording frame back 756 * 757 * PARAMETERS : 758 * @device : ptr to camera device struct 759 * @opaque : ptr to frame to be returned 760 * 761 * RETURN : none 762 *==========================================================================*/ 763 void QCamera2HardwareInterface::release_recording_frame( 764 struct camera_device *device, const void *opaque) 765 { 766 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REL_REC_FRAME); 767 int32_t ret = NO_ERROR; 768 QCamera2HardwareInterface *hw = 769 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 770 if (!hw) { 771 LOGE("NULL camera device"); 772 return; 773 } 774 if (!opaque) { 775 LOGE("Error!! Frame info is NULL"); 776 return; 777 } 778 LOGD("E camera id %d", hw->getCameraId()); 779 780 hw->lockAPI(); 781 qcamera_api_result_t apiResult; 782 ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque); 783 if (ret == NO_ERROR) { 784 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult); 785 } 786 hw->unlockAPI(); 787 LOGD("X camera id %d", hw->getCameraId()); 788 } 789 790 /*=========================================================================== 791 * FUNCTION : auto_focus 792 * 793 * DESCRIPTION: start auto focus 794 * 795 * PARAMETERS : 796 * @device : ptr to camera device struct 797 * 798 * RETURN : int32_t type of status 799 * NO_ERROR -- success 800 * none-zero failure code 801 *==========================================================================*/ 802 int QCamera2HardwareInterface::auto_focus(struct camera_device *device) 803 { 804 KPI_ATRACE_INT("Camera:AutoFocus", 1); 805 int ret = NO_ERROR; 806 QCamera2HardwareInterface *hw = 807 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 808 if (!hw) { 809 LOGE("NULL camera device"); 810 return BAD_VALUE; 811 } 812 LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d", 813 hw->getCameraId()); 814 hw->lockAPI(); 815 qcamera_api_result_t apiResult; 816 ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL); 817 if (ret == NO_ERROR) { 818 hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult); 819 ret = apiResult.status; 820 } 821 hw->unlockAPI(); 822 LOGH("[KPI Perf] : X ret = %d", ret); 823 824 return ret; 825 } 826 827 /*=========================================================================== 828 * FUNCTION : cancel_auto_focus 829 * 830 * DESCRIPTION: cancel auto focus 831 * 832 * PARAMETERS : 833 * @device : ptr to camera device struct 834 * 835 * RETURN : int32_t type of status 836 * NO_ERROR -- success 837 * none-zero failure code 838 *==========================================================================*/ 839 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device) 840 { 841 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_AF); 842 int ret = NO_ERROR; 843 QCamera2HardwareInterface *hw = 844 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 845 if (!hw) { 846 LOGE("NULL camera device"); 847 return BAD_VALUE; 848 } 849 LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d", 850 hw->getCameraId()); 851 hw->lockAPI(); 852 qcamera_api_result_t apiResult; 853 ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL); 854 if (ret == NO_ERROR) { 855 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult); 856 ret = apiResult.status; 857 } 858 hw->unlockAPI(); 859 LOGH("[KPI Perf] : X ret = %d", ret); 860 return ret; 861 } 862 863 /*=========================================================================== 864 * FUNCTION : pre_take_picture 865 * 866 * DESCRIPTION: pre take picture, restart preview if necessary. 867 * 868 * PARAMETERS : 869 * @device : ptr to camera device struct 870 * 871 * RETURN : int32_t type of status 872 * NO_ERROR -- success 873 * none-zero failure code 874 *==========================================================================*/ 875 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device) 876 { 877 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_TAKE_PICTURE); 878 int ret = NO_ERROR; 879 QCamera2HardwareInterface *hw = 880 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 881 if (!hw) { 882 LOGE("NULL camera device"); 883 return BAD_VALUE; 884 } 885 LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d", 886 hw->getCameraId()); 887 hw->lockAPI(); 888 qcamera_api_result_t apiResult; 889 ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL); 890 if (ret == NO_ERROR) { 891 hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult); 892 ret = apiResult.status; 893 } 894 hw->unlockAPI(); 895 LOGH("[KPI Perf]: X"); 896 return ret; 897 } 898 899 /*=========================================================================== 900 * FUNCTION : take_picture 901 * 902 * DESCRIPTION: take picture 903 * 904 * PARAMETERS : 905 * @device : ptr to camera device struct 906 * 907 * RETURN : int32_t type of status 908 * NO_ERROR -- success 909 * none-zero failure code 910 *==========================================================================*/ 911 int QCamera2HardwareInterface::take_picture(struct camera_device *device) 912 { 913 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_TAKE_PICTURE); 914 int ret = NO_ERROR; 915 QCamera2HardwareInterface *hw = 916 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 917 if (!hw) { 918 LOGE("NULL camera device"); 919 return BAD_VALUE; 920 } 921 LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d", 922 hw->getCameraId()); 923 924 // Acquire the perf lock for JPEG snapshot only 925 if (hw->mParameters.isJpegPictureFormat()) { 926 hw->m_perfLockMgr.acquirePerfLock(PERF_LOCK_TAKE_SNAPSHOT); 927 } 928 929 qcamera_api_result_t apiResult; 930 931 /** Added support for Retro-active Frames: 932 * takePicture() is called before preparing Snapshot to indicate the 933 * mm-camera-channel to pick up legacy frames even 934 * before LED estimation is triggered. 935 */ 936 937 LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d", 938 hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(), 939 hw->isLongshotEnabled()); 940 941 // Check for Retro-active Frames 942 if ((hw->mParameters.getNumOfRetroSnapshots() > 0) && 943 !hw->isLiveSnapshot() && hw->isZSLMode() && 944 !hw->isHDRMode() && !hw->isLongshotEnabled()) { 945 // Set Retro Picture Mode 946 hw->setRetroPicture(1); 947 hw->m_bLedAfAecLock = 0; 948 LOGL("Retro Enabled"); 949 950 // Give HWI control to call pre_take_picture in single camera mode. 951 // In dual-cam mode, this control belongs to muxer. 952 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 953 ret = pre_take_picture(device); 954 if (ret != NO_ERROR) { 955 LOGE("pre_take_picture failed with ret = %d",ret); 956 return ret; 957 } 958 } 959 960 /* Call take Picture for total number of snapshots required. 961 This includes the number of retro frames and normal frames */ 962 hw->lockAPI(); 963 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 964 if (ret == NO_ERROR) { 965 // Wait for retro frames, before calling prepare snapshot 966 LOGD("Wait for Retro frames to be done"); 967 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 968 ret = apiResult.status; 969 } 970 /* Unlock API since it is acquired in prepare snapshot seperately */ 971 hw->unlockAPI(); 972 973 /* Prepare snapshot in case LED needs to be flashed */ 974 LOGD("Start Prepare Snapshot"); 975 ret = hw->prepare_snapshot(device); 976 } 977 else { 978 hw->setRetroPicture(0); 979 // Check if prepare snapshot is done 980 if (!hw->mPrepSnapRun) { 981 // Ignore the status from prepare_snapshot 982 hw->prepare_snapshot(device); 983 } 984 985 // Give HWI control to call pre_take_picture in single camera mode. 986 // In dual-cam mode, this control belongs to muxer. 987 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 988 ret = pre_take_picture(device); 989 if (ret != NO_ERROR) { 990 LOGE("pre_take_picture failed with ret = %d",ret); 991 return ret; 992 } 993 } 994 995 // Regardless what the result value for prepare_snapshot, 996 // go ahead with capture anyway. Just like the way autofocus 997 // is handled in capture case 998 /* capture */ 999 LOGL("Capturing normal frames"); 1000 hw->lockAPI(); 1001 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 1002 if (ret == NO_ERROR) { 1003 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 1004 ret = apiResult.status; 1005 } 1006 hw->unlockAPI(); 1007 if (!hw->isLongshotEnabled()){ 1008 // For longshot mode, we prepare snapshot only once 1009 hw->mPrepSnapRun = false; 1010 } 1011 } 1012 LOGI("[KPI Perf]: X ret = %d", ret); 1013 return ret; 1014 } 1015 1016 /*=========================================================================== 1017 * FUNCTION : cancel_picture 1018 * 1019 * DESCRIPTION: cancel current take picture request 1020 * 1021 * PARAMETERS : 1022 * @device : ptr to camera device struct 1023 * 1024 * RETURN : int32_t type of status 1025 * NO_ERROR -- success 1026 * none-zero failure code 1027 *==========================================================================*/ 1028 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device) 1029 { 1030 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_PICTURE); 1031 int ret = NO_ERROR; 1032 QCamera2HardwareInterface *hw = 1033 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1034 if (!hw) { 1035 LOGE("NULL camera device"); 1036 return BAD_VALUE; 1037 } 1038 LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d", 1039 hw->getCameraId()); 1040 hw->lockAPI(); 1041 qcamera_api_result_t apiResult; 1042 ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 1043 if (ret == NO_ERROR) { 1044 hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult); 1045 ret = apiResult.status; 1046 } 1047 hw->unlockAPI(); 1048 LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret); 1049 1050 return ret; 1051 } 1052 1053 /*=========================================================================== 1054 * FUNCTION : set_parameters 1055 * 1056 * DESCRIPTION: set camera parameters 1057 * 1058 * PARAMETERS : 1059 * @device : ptr to camera device struct 1060 * @parms : string of packed parameters 1061 * 1062 * RETURN : int32_t type of status 1063 * NO_ERROR -- success 1064 * none-zero failure code 1065 *==========================================================================*/ 1066 int QCamera2HardwareInterface::set_parameters(struct camera_device *device, 1067 const char *parms) 1068 { 1069 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PARAMETERS); 1070 int ret = NO_ERROR; 1071 QCamera2HardwareInterface *hw = 1072 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1073 if (!hw) { 1074 LOGE("NULL camera device"); 1075 return BAD_VALUE; 1076 } 1077 LOGD("E camera id %d", hw->getCameraId()); 1078 hw->lockAPI(); 1079 qcamera_api_result_t apiResult; 1080 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms); 1081 if (ret == NO_ERROR) { 1082 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult); 1083 ret = apiResult.status; 1084 } 1085 1086 // Give HWI control to restart (if necessary) after set params 1087 // in single camera mode. In dual-cam mode, this control belongs to muxer. 1088 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 1089 if ((ret == NO_ERROR) && hw->getNeedRestart()) { 1090 LOGD("stopping after param change"); 1091 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL); 1092 if (ret == NO_ERROR) { 1093 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult); 1094 ret = apiResult.status; 1095 } 1096 } 1097 1098 if (ret == NO_ERROR) { 1099 LOGD("committing param change"); 1100 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL); 1101 if (ret == NO_ERROR) { 1102 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult); 1103 ret = apiResult.status; 1104 } 1105 } 1106 1107 if ((ret == NO_ERROR) && hw->getNeedRestart()) { 1108 LOGD("restarting after param change"); 1109 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL); 1110 if (ret == NO_ERROR) { 1111 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult); 1112 ret = apiResult.status; 1113 } 1114 } 1115 } 1116 1117 hw->unlockAPI(); 1118 LOGD("X camera id %d ret %d", hw->getCameraId(), ret); 1119 1120 return ret; 1121 } 1122 1123 /*=========================================================================== 1124 * FUNCTION : stop_after_set_params 1125 * 1126 * DESCRIPTION: stop after a set param call, if necessary 1127 * 1128 * PARAMETERS : 1129 * @device : ptr to camera device struct 1130 * 1131 * RETURN : int32_t type of status 1132 * NO_ERROR -- success 1133 * none-zero failure code 1134 *==========================================================================*/ 1135 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device) 1136 { 1137 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_AFTER_SET_PARAMS); 1138 int ret = NO_ERROR; 1139 QCamera2HardwareInterface *hw = 1140 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1141 if (!hw) { 1142 LOGE("NULL camera device"); 1143 return BAD_VALUE; 1144 } 1145 LOGD("E camera id %d", hw->getCameraId()); 1146 hw->lockAPI(); 1147 qcamera_api_result_t apiResult; 1148 1149 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1150 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL); 1151 if (ret == NO_ERROR) { 1152 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult); 1153 ret = apiResult.status; 1154 } 1155 } else { 1156 LOGE("is not supposed to be called in single-camera mode"); 1157 ret = INVALID_OPERATION; 1158 } 1159 1160 hw->unlockAPI(); 1161 LOGD("X camera id %d", hw->getCameraId()); 1162 1163 return ret; 1164 } 1165 1166 /*=========================================================================== 1167 * FUNCTION : commit_params 1168 * 1169 * DESCRIPTION: commit after a set param call 1170 * 1171 * PARAMETERS : 1172 * @device : ptr to camera device struct 1173 * 1174 * RETURN : int32_t type of status 1175 * NO_ERROR -- success 1176 * none-zero failure code 1177 *==========================================================================*/ 1178 int QCamera2HardwareInterface::commit_params(struct camera_device *device) 1179 { 1180 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_COMMIT_PARAMS); 1181 int ret = NO_ERROR; 1182 QCamera2HardwareInterface *hw = 1183 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1184 if (!hw) { 1185 LOGE("NULL camera device"); 1186 return BAD_VALUE; 1187 } 1188 LOGD("E camera id %d", hw->getCameraId()); 1189 hw->lockAPI(); 1190 qcamera_api_result_t apiResult; 1191 1192 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1193 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL); 1194 if (ret == NO_ERROR) { 1195 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult); 1196 ret = apiResult.status; 1197 } 1198 } else { 1199 LOGE("is not supposed to be called in single-camera mode"); 1200 ret = INVALID_OPERATION; 1201 } 1202 1203 hw->unlockAPI(); 1204 LOGD("X camera id %d", hw->getCameraId()); 1205 1206 return ret; 1207 } 1208 1209 /*=========================================================================== 1210 * FUNCTION : restart_after_set_params 1211 * 1212 * DESCRIPTION: restart after a set param call, if necessary 1213 * 1214 * PARAMETERS : 1215 * @device : ptr to camera device struct 1216 * 1217 * RETURN : int32_t type of status 1218 * NO_ERROR -- success 1219 * none-zero failure code 1220 *==========================================================================*/ 1221 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device) 1222 { 1223 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_AFTER_SET_PARAMS); 1224 int ret = NO_ERROR; 1225 QCamera2HardwareInterface *hw = 1226 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1227 if (!hw) { 1228 LOGE("NULL camera device"); 1229 return BAD_VALUE; 1230 } 1231 LOGD("E camera id %d", hw->getCameraId()); 1232 hw->lockAPI(); 1233 qcamera_api_result_t apiResult; 1234 1235 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1236 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL); 1237 if (ret == NO_ERROR) { 1238 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult); 1239 ret = apiResult.status; 1240 } 1241 } else { 1242 LOGE("is not supposed to be called in single-camera mode"); 1243 ret = INVALID_OPERATION; 1244 } 1245 1246 hw->unlockAPI(); 1247 LOGD("X camera id %d", hw->getCameraId()); 1248 return ret; 1249 } 1250 1251 /*=========================================================================== 1252 * FUNCTION : get_parameters 1253 * 1254 * DESCRIPTION: query camera parameters 1255 * 1256 * PARAMETERS : 1257 * @device : ptr to camera device struct 1258 * 1259 * RETURN : packed parameters in a string 1260 *==========================================================================*/ 1261 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device) 1262 { 1263 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_PARAMETERS); 1264 char *ret = NULL; 1265 QCamera2HardwareInterface *hw = 1266 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1267 if (!hw) { 1268 LOGE("NULL camera device"); 1269 return NULL; 1270 } 1271 LOGD("E camera id %d", hw->getCameraId()); 1272 hw->lockAPI(); 1273 qcamera_api_result_t apiResult; 1274 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL); 1275 if (rc == NO_ERROR) { 1276 hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult); 1277 ret = apiResult.params; 1278 } 1279 hw->unlockAPI(); 1280 LOGD("E camera id %d", hw->getCameraId()); 1281 1282 return ret; 1283 } 1284 1285 /*=========================================================================== 1286 * FUNCTION : put_parameters 1287 * 1288 * DESCRIPTION: return camera parameters string back to HAL 1289 * 1290 * PARAMETERS : 1291 * @device : ptr to camera device struct 1292 * @parm : ptr to parameter string to be returned 1293 * 1294 * RETURN : none 1295 *==========================================================================*/ 1296 void QCamera2HardwareInterface::put_parameters(struct camera_device *device, 1297 char *parm) 1298 { 1299 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PUT_PARAMETERS); 1300 QCamera2HardwareInterface *hw = 1301 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1302 if (!hw) { 1303 LOGE("NULL camera device"); 1304 return; 1305 } 1306 LOGD("E camera id %d", hw->getCameraId()); 1307 hw->lockAPI(); 1308 qcamera_api_result_t apiResult; 1309 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm); 1310 if (ret == NO_ERROR) { 1311 hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult); 1312 } 1313 hw->unlockAPI(); 1314 LOGD("E camera id %d", hw->getCameraId()); 1315 } 1316 1317 /*=========================================================================== 1318 * FUNCTION : send_command 1319 * 1320 * DESCRIPTION: command to be executed 1321 * 1322 * PARAMETERS : 1323 * @device : ptr to camera device struct 1324 * @cmd : cmd to be executed 1325 * @arg1 : ptr to optional argument1 1326 * @arg2 : ptr to optional argument2 1327 * 1328 * RETURN : int32_t type of status 1329 * NO_ERROR -- success 1330 * none-zero failure code 1331 *==========================================================================*/ 1332 int QCamera2HardwareInterface::send_command(struct camera_device *device, 1333 int32_t cmd, 1334 int32_t arg1, 1335 int32_t arg2) 1336 { 1337 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND); 1338 int ret = NO_ERROR; 1339 QCamera2HardwareInterface *hw = 1340 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1341 if (!hw) { 1342 LOGE("NULL camera device"); 1343 return BAD_VALUE; 1344 } 1345 LOGD("E camera id %d", hw->getCameraId()); 1346 1347 qcamera_sm_evt_command_payload_t payload; 1348 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t)); 1349 payload.cmd = cmd; 1350 payload.arg1 = arg1; 1351 payload.arg2 = arg2; 1352 hw->lockAPI(); 1353 qcamera_api_result_t apiResult; 1354 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload); 1355 if (ret == NO_ERROR) { 1356 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult); 1357 ret = apiResult.status; 1358 } 1359 hw->unlockAPI(); 1360 LOGD("E camera id %d", hw->getCameraId()); 1361 1362 return ret; 1363 } 1364 1365 /*=========================================================================== 1366 * FUNCTION : send_command_restart 1367 * 1368 * DESCRIPTION: restart if necessary after a send_command 1369 * 1370 * PARAMETERS : 1371 * @device : ptr to camera device struct 1372 * @cmd : cmd to be executed 1373 * @arg1 : ptr to optional argument1 1374 * @arg2 : ptr to optional argument2 1375 * 1376 * RETURN : int32_t type of status 1377 * NO_ERROR -- success 1378 * none-zero failure code 1379 *==========================================================================*/ 1380 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device, 1381 int32_t cmd, 1382 int32_t arg1, 1383 int32_t arg2) 1384 { 1385 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND_RESTART); 1386 int ret = NO_ERROR; 1387 QCamera2HardwareInterface *hw = 1388 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1389 if (!hw) { 1390 LOGE("NULL camera device"); 1391 return BAD_VALUE; 1392 } 1393 1394 qcamera_sm_evt_command_payload_t payload; 1395 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t)); 1396 payload.cmd = cmd; 1397 payload.arg1 = arg1; 1398 payload.arg2 = arg2; 1399 hw->lockAPI(); 1400 qcamera_api_result_t apiResult; 1401 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload); 1402 if (ret == NO_ERROR) { 1403 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult); 1404 ret = apiResult.status; 1405 } 1406 hw->unlockAPI(); 1407 LOGD("E camera id %d", hw->getCameraId()); 1408 1409 return ret; 1410 } 1411 1412 /*=========================================================================== 1413 * FUNCTION : release 1414 * 1415 * DESCRIPTION: release camera resource 1416 * 1417 * PARAMETERS : 1418 * @device : ptr to camera device struct 1419 * 1420 * RETURN : none 1421 *==========================================================================*/ 1422 void QCamera2HardwareInterface::release(struct camera_device *device) 1423 { 1424 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RELEASE); 1425 QCamera2HardwareInterface *hw = 1426 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1427 if (!hw) { 1428 LOGE("NULL camera device"); 1429 return; 1430 } 1431 LOGD("E camera id %d", hw->getCameraId()); 1432 hw->lockAPI(); 1433 qcamera_api_result_t apiResult; 1434 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL); 1435 if (ret == NO_ERROR) { 1436 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult); 1437 } 1438 hw->unlockAPI(); 1439 LOGD("E camera id %d", hw->getCameraId()); 1440 } 1441 1442 /*=========================================================================== 1443 * FUNCTION : dump 1444 * 1445 * DESCRIPTION: dump camera status 1446 * 1447 * PARAMETERS : 1448 * @device : ptr to camera device struct 1449 * @fd : fd for status to be dumped to 1450 * 1451 * RETURN : int32_t type of status 1452 * NO_ERROR -- success 1453 * none-zero failure code 1454 *==========================================================================*/ 1455 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd) 1456 { 1457 int ret = NO_ERROR; 1458 1459 //Log level property is read when "adb shell dumpsys media.camera" is 1460 //called so that the log level can be controlled without restarting 1461 //media server 1462 getLogLevel(); 1463 QCamera2HardwareInterface *hw = 1464 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1465 if (!hw) { 1466 LOGE("NULL camera device"); 1467 return BAD_VALUE; 1468 } 1469 LOGD("E camera id %d", hw->getCameraId()); 1470 hw->lockAPI(); 1471 qcamera_api_result_t apiResult; 1472 ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd); 1473 if (ret == NO_ERROR) { 1474 hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult); 1475 ret = apiResult.status; 1476 } 1477 hw->unlockAPI(); 1478 LOGD("E camera id %d", hw->getCameraId()); 1479 1480 return ret; 1481 } 1482 1483 /*=========================================================================== 1484 * FUNCTION : close_camera_device 1485 * 1486 * DESCRIPTION: close camera device 1487 * 1488 * PARAMETERS : 1489 * @device : ptr to camera device struct 1490 * 1491 * RETURN : int32_t type of status 1492 * NO_ERROR -- success 1493 * none-zero failure code 1494 *==========================================================================*/ 1495 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev) 1496 { 1497 KPI_ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_HAL1_CLOSECAMERA); 1498 int ret = NO_ERROR; 1499 1500 QCamera2HardwareInterface *hw = 1501 reinterpret_cast<QCamera2HardwareInterface *>( 1502 reinterpret_cast<camera_device_t *>(hw_dev)->priv); 1503 if (!hw) { 1504 LOGE("NULL camera device"); 1505 return BAD_VALUE; 1506 } 1507 LOGI("[KPI Perf]: E camera id %d", hw->getCameraId()); 1508 delete hw; 1509 LOGI("[KPI Perf]: X"); 1510 KPI_ATRACE_CAMSCOPE_END(CAMSCOPE_HAL1_CLOSECAMERA); 1511 CAMSCOPE_DESTROY(CAMSCOPE_SECTION_HAL); 1512 return ret; 1513 } 1514 1515 /*=========================================================================== 1516 * FUNCTION : register_face_image 1517 * 1518 * DESCRIPTION: register a face image into imaging lib for face authenticatio/ 1519 * face recognition 1520 * 1521 * PARAMETERS : 1522 * @device : ptr to camera device struct 1523 * @img_ptr : ptr to image buffer 1524 * @config : ptr to config about input image, i.e., format, dimension, and etc. 1525 * 1526 * RETURN : >=0 unique ID of face registerd. 1527 * <0 failure. 1528 *==========================================================================*/ 1529 int QCamera2HardwareInterface::register_face_image(struct camera_device *device, 1530 void *img_ptr, 1531 cam_pp_offline_src_config_t *config) 1532 { 1533 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REGISTER_FACE_IMAGE); 1534 int ret = NO_ERROR; 1535 QCamera2HardwareInterface *hw = 1536 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1537 if (!hw) { 1538 LOGE("NULL camera device"); 1539 return BAD_VALUE; 1540 } 1541 LOGD("E camera id %d", hw->getCameraId()); 1542 qcamera_sm_evt_reg_face_payload_t payload; 1543 memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t)); 1544 payload.img_ptr = img_ptr; 1545 payload.config = config; 1546 hw->lockAPI(); 1547 qcamera_api_result_t apiResult; 1548 ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload); 1549 if (ret == NO_ERROR) { 1550 hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult); 1551 ret = apiResult.handle; 1552 } 1553 hw->unlockAPI(); 1554 LOGD("E camera id %d", hw->getCameraId()); 1555 1556 return ret; 1557 } 1558 1559 /*=========================================================================== 1560 * FUNCTION : prepare_snapshot 1561 * 1562 * DESCRIPTION: prepares hardware for snapshot 1563 * 1564 * PARAMETERS : 1565 * @device : ptr to camera device struct 1566 * 1567 * RETURN : int32_t type of status 1568 * NO_ERROR -- success 1569 * none-zero failure code 1570 *==========================================================================*/ 1571 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device) 1572 { 1573 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_SNAPSHOT); 1574 int ret = NO_ERROR; 1575 QCamera2HardwareInterface *hw = 1576 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1577 if (!hw) { 1578 LOGE("NULL camera device"); 1579 return BAD_VALUE; 1580 } 1581 if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) { 1582 // For longshot mode, we prepare snapshot only once 1583 LOGH("prepare snapshot only once "); 1584 return NO_ERROR; 1585 } 1586 LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d", 1587 hw->getCameraId()); 1588 hw->lockAPI(); 1589 qcamera_api_result_t apiResult; 1590 1591 /* Prepare snapshot in case LED needs to be flashed */ 1592 if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) { 1593 /* Prepare snapshot in case LED needs to be flashed */ 1594 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 1595 if (ret == NO_ERROR) { 1596 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 1597 ret = apiResult.status; 1598 } 1599 hw->mPrepSnapRun = true; 1600 } 1601 hw->unlockAPI(); 1602 LOGH("[KPI Perf]: X, ret: %d", ret); 1603 return ret; 1604 } 1605 1606 /*=========================================================================== 1607 * FUNCTION : QCamera2HardwareInterface 1608 * 1609 * DESCRIPTION: constructor of QCamera2HardwareInterface 1610 * 1611 * PARAMETERS : 1612 * @cameraId : camera ID 1613 * 1614 * RETURN : none 1615 *==========================================================================*/ 1616 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId) 1617 : mCameraId(cameraId), 1618 mCameraHandle(NULL), 1619 mMasterCamera(CAM_TYPE_MAIN), 1620 mCameraOpened(false), 1621 mDualCamera(false), 1622 m_pFovControl(NULL), 1623 m_bRelCamCalibValid(false), 1624 mPreviewWindow(NULL), 1625 mMsgEnabled(0), 1626 mStoreMetaDataInFrame(0), 1627 mJpegCb(NULL), 1628 mCallbackCookie(NULL), 1629 mJpegCallbackCookie(NULL), 1630 m_bMpoEnabled(TRUE), 1631 m_stateMachine(this), 1632 m_smThreadActive(true), 1633 m_postprocessor(this), 1634 m_thermalAdapter(QCameraThermalAdapter::getInstance()), 1635 m_cbNotifier(this), 1636 m_perfLockMgr(), 1637 m_bPreviewStarted(false), 1638 m_bRecordStarted(false), 1639 m_currentFocusState(CAM_AF_STATE_INACTIVE), 1640 mDumpFrmCnt(0U), 1641 mDumpSkipCnt(0U), 1642 mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT), 1643 mActiveAF(false), 1644 m_HDRSceneEnabled(false), 1645 mLongshotEnabled(false), 1646 mLiveSnapshotThread(0), 1647 mIntPicThread(0), 1648 mFlashNeeded(false), 1649 mFlashConfigured(false), 1650 mDeviceRotation(0U), 1651 mCaptureRotation(0U), 1652 mJpegExifRotation(0U), 1653 mUseJpegExifRotation(false), 1654 mIs3ALocked(false), 1655 mPrepSnapRun(false), 1656 mZoomLevel(0), 1657 mPreviewRestartNeeded(false), 1658 mVFrameCount(0), 1659 mVLastFrameCount(0), 1660 mVLastFpsTime(0), 1661 mVFps(0), 1662 mPFrameCount(0), 1663 mPLastFrameCount(0), 1664 mPLastFpsTime(0), 1665 mPFps(0), 1666 mLowLightConfigured(false), 1667 mInstantAecFrameCount(0), 1668 m_bIntJpegEvtPending(false), 1669 m_bIntRawEvtPending(false), 1670 mReprocJob(0), 1671 mJpegJob(0), 1672 mMetadataAllocJob(0), 1673 mInitPProcJob(0), 1674 mParamAllocJob(0), 1675 mParamInitJob(0), 1676 mOutputCount(0), 1677 mInputCount(0), 1678 mAdvancedCaptureConfigured(false), 1679 mHDRBracketingEnabled(false), 1680 mNumPreviewFaces(-1), 1681 mJpegClientHandle(0), 1682 mJpegHandleOwner(false), 1683 mMetadataMem(NULL), 1684 mCACDoneReceived(false), 1685 m_bNeedRestart(false), 1686 mBootToMonoTimestampOffset(0), 1687 bDepthAFCallbacks(true), 1688 m_bNeedHalPP(FALSE) 1689 { 1690 #ifdef TARGET_TS_MAKEUP 1691 memset(&mFaceRect, -1, sizeof(mFaceRect)); 1692 #endif 1693 getLogLevel(); 1694 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_QCAMERA2HWI); 1695 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG; 1696 mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0); 1697 mCameraDevice.common.close = close_camera_device; 1698 mCameraDevice.ops = &mCameraOps; 1699 mCameraDevice.priv = this; 1700 1701 mDualCamera = is_dual_camera_by_idx(cameraId); 1702 1703 pthread_mutex_init(&m_lock, NULL); 1704 pthread_cond_init(&m_cond, NULL); 1705 1706 m_apiResultList = NULL; 1707 1708 pthread_mutex_init(&m_evtLock, NULL); 1709 pthread_cond_init(&m_evtCond, NULL); 1710 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 1711 1712 1713 pthread_mutex_init(&m_int_lock, NULL); 1714 pthread_cond_init(&m_int_cond, NULL); 1715 1716 memset(m_channels, 0, sizeof(m_channels)); 1717 1718 memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t)); 1719 1720 memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH); 1721 1722 memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs)); 1723 memset(&mJpegMetadata, 0, sizeof(mJpegMetadata)); 1724 memset(&mJpegHandle, 0, sizeof(mJpegHandle)); 1725 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle)); 1726 1727 mDeferredWorkThread.launch(deferredWorkRoutine, this); 1728 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE); 1729 1730 pthread_mutex_init(&mGrallocLock, NULL); 1731 mEnqueuedBuffers = 0; 1732 mFrameSkipStart = 0; 1733 mFrameSkipEnd = 0; 1734 mLastPreviewFrameID = 0; 1735 1736 //Load and read GPU library. 1737 lib_surface_utils = NULL; 1738 LINK_get_surface_pixel_alignment = NULL; 1739 mSurfaceStridePadding = CAM_PAD_TO_32; 1740 lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW); 1741 if (lib_surface_utils) { 1742 *(void **)&LINK_get_surface_pixel_alignment = 1743 dlsym(lib_surface_utils, "get_gpu_pixel_alignment"); 1744 if (LINK_get_surface_pixel_alignment) { 1745 mSurfaceStridePadding = LINK_get_surface_pixel_alignment(); 1746 } 1747 dlclose(lib_surface_utils); 1748 } 1749 } 1750 1751 /*=========================================================================== 1752 * FUNCTION : ~QCamera2HardwareInterface 1753 * 1754 * DESCRIPTION: destructor of QCamera2HardwareInterface 1755 * 1756 * PARAMETERS : none 1757 * 1758 * RETURN : none 1759 *==========================================================================*/ 1760 QCamera2HardwareInterface::~QCamera2HardwareInterface() 1761 { 1762 LOGH("E"); 1763 1764 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE); 1765 mDeferredWorkThread.exit(); 1766 1767 if (mMetadataMem != NULL) { 1768 delete mMetadataMem; 1769 mMetadataMem = NULL; 1770 } 1771 1772 if (m_pFovControl) { 1773 delete m_pFovControl; 1774 m_pFovControl = NULL; 1775 } 1776 1777 m_perfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA); 1778 lockAPI(); 1779 m_smThreadActive = false; 1780 unlockAPI(); 1781 m_stateMachine.releaseThread(); 1782 closeCamera(); 1783 m_perfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA); 1784 1785 pthread_mutex_destroy(&m_lock); 1786 pthread_cond_destroy(&m_cond); 1787 pthread_mutex_destroy(&m_evtLock); 1788 pthread_cond_destroy(&m_evtCond); 1789 pthread_mutex_destroy(&m_int_lock); 1790 pthread_cond_destroy(&m_int_cond); 1791 pthread_mutex_destroy(&mGrallocLock); 1792 LOGH("X"); 1793 } 1794 1795 /*=========================================================================== 1796 * FUNCTION : deferPPInit 1797 * 1798 * DESCRIPTION: Queue postproc init task to deferred thread 1799 * 1800 * PARAMETERS : none 1801 * 1802 * RETURN : uint32_t job id of pproc init job 1803 * 0 -- failure 1804 *==========================================================================*/ 1805 uint32_t QCamera2HardwareInterface::deferPPInit() 1806 { 1807 // init pproc 1808 DeferWorkArgs args; 1809 DeferPProcInitArgs pprocInitArgs; 1810 1811 memset(&args, 0, sizeof(DeferWorkArgs)); 1812 memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs)); 1813 1814 pprocInitArgs.jpeg_cb = jpegEvtHandle; 1815 pprocInitArgs.user_data = this; 1816 args.pprocInitArgs = pprocInitArgs; 1817 1818 return queueDeferredWork(CMD_DEF_PPROC_INIT, 1819 args); 1820 } 1821 1822 /*=========================================================================== 1823 * FUNCTION : openCamera 1824 * 1825 * DESCRIPTION: open camera 1826 * 1827 * PARAMETERS : 1828 * @hw_device : double ptr for camera device struct 1829 * 1830 * RETURN : int32_t type of status 1831 * NO_ERROR -- success 1832 * none-zero failure code 1833 *==========================================================================*/ 1834 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device) 1835 { 1836 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_OPENCAMERA); 1837 int rc = NO_ERROR; 1838 if (mCameraOpened) { 1839 *hw_device = NULL; 1840 LOGE("Permission Denied"); 1841 return PERMISSION_DENIED; 1842 } 1843 LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d", 1844 mCameraId); 1845 1846 m_perfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA); 1847 1848 rc = openCamera(); 1849 if (rc == NO_ERROR){ 1850 *hw_device = &mCameraDevice.common; 1851 if (m_thermalAdapter.init(this) != 0) { 1852 LOGW("Init thermal adapter failed"); 1853 } 1854 } 1855 else 1856 *hw_device = NULL; 1857 1858 LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d", 1859 mCameraId, rc); 1860 1861 return rc; 1862 } 1863 1864 /*=========================================================================== 1865 * FUNCTION : openCamera 1866 * 1867 * DESCRIPTION: open camera 1868 * 1869 * PARAMETERS : none 1870 * 1871 * RETURN : int32_t type of status 1872 * NO_ERROR -- success 1873 * none-zero failure code 1874 *==========================================================================*/ 1875 int QCamera2HardwareInterface::openCamera() 1876 { 1877 int32_t rc = NO_ERROR; 1878 char value[PROPERTY_VALUE_MAX]; 1879 1880 if (mCameraHandle) { 1881 LOGE("Failure: Camera already opened"); 1882 return ALREADY_EXISTS; 1883 } 1884 1885 rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId); 1886 if (rc < 0) { 1887 LOGE("Failed to reserve flash for camera id: %d", 1888 mCameraId); 1889 return UNKNOWN_ERROR; 1890 } 1891 1892 // alloc param buffer 1893 DeferWorkArgs args; 1894 memset(&args, 0, sizeof(args)); 1895 mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args); 1896 if (mParamAllocJob == 0) { 1897 LOGE("Failed queueing PARAM_ALLOC job"); 1898 return -ENOMEM; 1899 } 1900 1901 if (gCamCapability[mCameraId] != NULL) { 1902 // allocate metadata buffers 1903 DeferWorkArgs args; 1904 DeferMetadataAllocArgs metadataAllocArgs; 1905 1906 memset(&args, 0, sizeof(args)); 1907 memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs)); 1908 1909 uint32_t padding = 1910 gCamCapability[mCameraId]->padding_info.plane_padding; 1911 metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t), 1912 padding); 1913 metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS; 1914 args.metadataAllocArgs = metadataAllocArgs; 1915 1916 mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args); 1917 if (mMetadataAllocJob == 0) { 1918 LOGE("Failed to allocate metadata buffer"); 1919 rc = -ENOMEM; 1920 goto error_exit1; 1921 } 1922 1923 rc = camera_open((uint8_t)mCameraId, &mCameraHandle); 1924 if (rc) { 1925 LOGE("camera_open failed. rc = %d, mCameraHandle = %p", 1926 rc, mCameraHandle); 1927 goto error_exit2; 1928 } 1929 1930 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, 1931 camEvtHandle, 1932 (void *) this); 1933 } else { 1934 LOGH("Capabilities not inited, initializing now."); 1935 1936 rc = camera_open((uint8_t)mCameraId, &mCameraHandle); 1937 if (rc) { 1938 LOGE("camera_open failed. rc = %d, mCameraHandle = %p", 1939 rc, mCameraHandle); 1940 goto error_exit2; 1941 } 1942 1943 if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) { 1944 LOGE("initCapabilities failed."); 1945 rc = UNKNOWN_ERROR; 1946 goto error_exit3; 1947 } 1948 1949 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, 1950 camEvtHandle, 1951 (void *) this); 1952 } 1953 mBundledSnapshot = 0; 1954 mActiveCameras = MM_CAMERA_TYPE_MAIN; 1955 if (isDualCamera()) { 1956 mActiveCameras |= MM_CAMERA_TYPE_AUX; 1957 1958 // Create and initialize FOV-control object 1959 m_pFovControl = QCameraFOVControl::create(gCamCapability[mCameraId]->main_cam_cap, 1960 gCamCapability[mCameraId]->aux_cam_cap); 1961 if (m_pFovControl) { 1962 *gCamCapability[mCameraId] = m_pFovControl->consolidateCapabilities( 1963 gCamCapability[mCameraId]->main_cam_cap, 1964 gCamCapability[mCameraId]->aux_cam_cap); 1965 } else { 1966 LOGE("FOV-control: Failed to create an object"); 1967 rc = NO_MEMORY; 1968 goto error_exit3; 1969 } 1970 } 1971 1972 // Init params in the background 1973 // 1. It's safe to queue init job, even if alloc job is not yet complete. 1974 // It will be queued to the same thread, so the alloc is guaranteed to 1975 // finish first. 1976 // 2. However, it is not safe to begin param init until after camera is 1977 // open. That is why we wait until after camera open completes to schedule 1978 // this task. 1979 memset(&args, 0, sizeof(args)); 1980 mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args); 1981 if (mParamInitJob == 0) { 1982 LOGE("Failed queuing PARAM_INIT job"); 1983 rc = -ENOMEM; 1984 goto error_exit3; 1985 } 1986 1987 mCameraOpened = true; 1988 1989 //Notify display HAL that a camera session is active. 1990 //But avoid calling the same during bootup because camera service might open/close 1991 //cameras at boot time during its initialization and display service will also internally 1992 //wait for camera service to initialize first while calling this display API, resulting in a 1993 //deadlock situation. Since boot time camera open/close calls are made only to fetch 1994 //capabilities, no need of this display bw optimization. 1995 //Use "service.bootanim.exit" property to know boot status. 1996 property_get("service.bootanim.exit", value, "0"); 1997 if (atoi(value) == 1) { 1998 pthread_mutex_lock(&gCamLock); 1999 if (gNumCameraSessions++ == 0) { 2000 setCameraLaunchStatus(true); 2001 } 2002 pthread_mutex_unlock(&gCamLock); 2003 } 2004 2005 // Setprop to decide the time source (whether boottime or monotonic). 2006 // By default, use monotonic time. 2007 property_get("persist.camera.time.monotonic", value, "1"); 2008 mBootToMonoTimestampOffset = 0; 2009 if (atoi(value) == 1) { 2010 // if monotonic is set, then need to use time in monotonic. 2011 // So, Measure the clock offset between BOOTTIME and MONOTONIC 2012 // The clock domain source for ISP is BOOTTIME and 2013 // for Video/display is MONOTONIC 2014 // The below offset is used to convert from clock domain of other subsystem 2015 // (video/hardware composer) to that of camera. Assumption is that this 2016 // offset won't change during the life cycle of the camera device. In other 2017 // words, camera device shouldn't be open during CPU suspend. 2018 mBootToMonoTimestampOffset = getBootToMonoTimeOffset(); 2019 } 2020 LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset); 2021 2022 memset(value, 0, sizeof(value)); 2023 property_get("persist.camera.depth.focus.cb", value, "1"); 2024 bDepthAFCallbacks = atoi(value); 2025 2026 memset(value, 0, sizeof(value)); 2027 property_get("persist.camera.cache.optimize", value, "1"); 2028 m_bOptimizeCacheOps = atoi(value); 2029 2030 return NO_ERROR; 2031 2032 error_exit3: 2033 if(mJpegClientHandle) { 2034 deinitJpegHandle(); 2035 } 2036 mCameraHandle->ops->close_camera(mCameraHandle->camera_handle); 2037 mCameraHandle = NULL; 2038 error_exit2: 2039 waitDeferredWork(mMetadataAllocJob); 2040 error_exit1: 2041 waitDeferredWork(mParamAllocJob); 2042 return rc; 2043 2044 } 2045 2046 /*=========================================================================== 2047 * FUNCTION : bundleRelatedCameras 2048 * 2049 * DESCRIPTION: bundle cameras to enable syncing of cameras 2050 * 2051 * PARAMETERS : 2052 * @sync :indicates whether syncing is On or Off 2053 * 2054 * RETURN : int32_t type of status 2055 * NO_ERROR -- success 2056 * none-zero failure code 2057 *==========================================================================*/ 2058 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn) 2059 { 2060 int32_t rc = mParameters.bundleRelatedCameras(syncOn); 2061 if (rc != NO_ERROR) { 2062 LOGE("bundleRelatedCameras failed %d", rc); 2063 return rc; 2064 } 2065 return rc; 2066 } 2067 2068 /*=========================================================================== 2069 * FUNCTION : getCameraSessionId 2070 * 2071 * DESCRIPTION: gets the backend session Id of this HWI instance 2072 * 2073 * PARAMETERS : 2074 * @sessionid : pointer to the output session id 2075 * 2076 * RETURN : int32_t type of status 2077 * NO_ERROR -- success 2078 * none-zero failure code 2079 *==========================================================================*/ 2080 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id) 2081 { 2082 int32_t rc = NO_ERROR; 2083 2084 if(session_id != NULL) { 2085 rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle, 2086 session_id); 2087 LOGD("Getting Camera Session Id %d", *session_id); 2088 } else { 2089 LOGE("Session Id is Null"); 2090 return UNKNOWN_ERROR; 2091 } 2092 return rc; 2093 } 2094 2095 /*=========================================================================== 2096 * FUNCTION : isFrameSyncEnabled 2097 * 2098 * DESCRIPTION: returns whether frame sync is enabled 2099 * 2100 * PARAMETERS : none 2101 * 2102 * RETURN : bool indicating whether frame sync is enabled 2103 *==========================================================================*/ 2104 bool QCamera2HardwareInterface::isFrameSyncEnabled(void) 2105 { 2106 return mParameters.isFrameSyncEnabled(); 2107 } 2108 2109 /*=========================================================================== 2110 * FUNCTION : setFrameSyncEnabled 2111 * 2112 * DESCRIPTION: sets whether frame sync is enabled 2113 * 2114 * PARAMETERS : 2115 * @enable : flag whether to enable or disable frame sync 2116 * 2117 * RETURN : int32_t type of status 2118 * NO_ERROR -- success 2119 * none-zero failure code 2120 *==========================================================================*/ 2121 int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable) 2122 { 2123 return mParameters.setFrameSyncEnabled(enable); 2124 } 2125 2126 /*=========================================================================== 2127 * FUNCTION : getRelatedCamSyncInfo 2128 * 2129 * DESCRIPTION:returns the related cam sync info for this HWI instance 2130 * 2131 * PARAMETERS :none 2132 * 2133 * RETURN : const pointer to cam_sync_related_sensors_event_info_t 2134 *==========================================================================*/ 2135 const cam_sync_related_sensors_event_info_t* 2136 QCamera2HardwareInterface::getRelatedCamSyncInfo(void) 2137 { 2138 return mParameters.getRelatedCamSyncInfo(); 2139 } 2140 2141 /*=========================================================================== 2142 * FUNCTION : setRelatedCamSyncInfo 2143 * 2144 * DESCRIPTION:sets the related cam sync info for this HWI instance 2145 * 2146 * PARAMETERS : 2147 * @info : ptr to related cam info parameters 2148 * 2149 * RETURN : int32_t type of status 2150 * NO_ERROR -- success 2151 * none-zero failure code 2152 *==========================================================================*/ 2153 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo( 2154 cam_sync_related_sensors_event_info_t* info) 2155 { 2156 if(info) { 2157 return mParameters.setRelatedCamSyncInfo(info); 2158 } else { 2159 return BAD_TYPE; 2160 } 2161 } 2162 2163 /*=========================================================================== 2164 * FUNCTION : getMpoComposition 2165 * 2166 * DESCRIPTION:function to retrieve whether Mpo composition should be enabled 2167 * or not 2168 * 2169 * PARAMETERS :none 2170 * 2171 * RETURN : bool indicates whether mpo composition is enabled or not 2172 *==========================================================================*/ 2173 bool QCamera2HardwareInterface::getMpoComposition(void) 2174 { 2175 LOGH("MpoComposition:%d ", m_bMpoEnabled); 2176 return m_bMpoEnabled; 2177 } 2178 2179 /*=========================================================================== 2180 * FUNCTION : setMpoComposition 2181 * 2182 * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance 2183 * 2184 * PARAMETERS : 2185 * @enable : indicates whether Mpo composition enabled or not 2186 * 2187 * RETURN : int32_t type of status 2188 * NO_ERROR -- success 2189 * none-zero failure code 2190 *==========================================================================*/ 2191 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable) 2192 { 2193 // By default set Mpo composition to disable 2194 m_bMpoEnabled = false; 2195 2196 // Enable Mpo composition only if 2197 // 1) frame sync is ON between two cameras and 2198 // 2) any advanced features are not enabled (AOST features) and 2199 // 3) not in recording mode (for liveshot case) 2200 // 4) flash is not needed 2201 if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) && 2202 !mParameters.isAdvCamFeaturesEnabled() && 2203 !mParameters.getRecordingHintValue() && 2204 !mFlashNeeded && 2205 !isLongshotEnabled()) { 2206 m_bMpoEnabled = enable; 2207 LOGH("MpoComposition:%d ", m_bMpoEnabled); 2208 return NO_ERROR; 2209 } else { 2210 return BAD_TYPE; 2211 } 2212 } 2213 2214 /*=========================================================================== 2215 * FUNCTION : getRecordingHintValue 2216 * 2217 * DESCRIPTION:function to retrieve recording hint value 2218 * 2219 * PARAMETERS :none 2220 * 2221 * RETURN : bool indicates whether recording hint is enabled or not 2222 *==========================================================================*/ 2223 bool QCamera2HardwareInterface::getRecordingHintValue(void) 2224 { 2225 return mParameters.getRecordingHintValue(); 2226 } 2227 2228 /*=========================================================================== 2229 * FUNCTION : setRecordingHintValue 2230 * 2231 * DESCRIPTION:set recording hint value 2232 * 2233 * PARAMETERS : 2234 * @enable : video hint value 2235 * 2236 * RETURN : int32_t type of status 2237 * NO_ERROR -- success 2238 * none-zero failure code 2239 *==========================================================================*/ 2240 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value) 2241 { 2242 return mParameters.updateRecordingHintValue(value); 2243 } 2244 2245 /*=========================================================================== 2246 * FUNCTION : closeCamera 2247 * 2248 * DESCRIPTION: close camera 2249 * 2250 * PARAMETERS : none 2251 * 2252 * RETURN : int32_t type of status 2253 * NO_ERROR -- success 2254 * none-zero failure code 2255 *==========================================================================*/ 2256 int QCamera2HardwareInterface::closeCamera() 2257 { 2258 int rc = NO_ERROR; 2259 int i; 2260 char value[PROPERTY_VALUE_MAX]; 2261 LOGI("E"); 2262 if (!mCameraOpened) { 2263 return NO_ERROR; 2264 } 2265 LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d", 2266 mCameraId); 2267 2268 // set open flag to false 2269 mCameraOpened = false; 2270 2271 // Reset Stream config info 2272 mParameters.setStreamConfigure(false, false, true); 2273 2274 // deinit Parameters 2275 mParameters.deinit(); 2276 2277 // exit notifier 2278 m_cbNotifier.exit(); 2279 2280 // stop and deinit postprocessor 2281 waitDeferredWork(mReprocJob); 2282 // Close the JPEG session 2283 waitDeferredWork(mJpegJob); 2284 m_postprocessor.stop(); 2285 deinitJpegHandle(); 2286 m_postprocessor.deinit(); 2287 mInitPProcJob = 0; // reset job id, so pproc can be reinited later 2288 2289 m_thermalAdapter.deinit(); 2290 2291 // delete all channels if not already deleted 2292 for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 2293 if (m_channels[i] != NULL) { 2294 m_channels[i]->stop(); 2295 delete m_channels[i]; 2296 m_channels[i] = NULL; 2297 } 2298 } 2299 2300 //free all pending api results here 2301 if(m_apiResultList != NULL) { 2302 api_result_list *apiResultList = m_apiResultList; 2303 api_result_list *apiResultListNext; 2304 while (apiResultList != NULL) { 2305 apiResultListNext = apiResultList->next; 2306 free(apiResultList); 2307 apiResultList = apiResultListNext; 2308 } 2309 } 2310 2311 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle); 2312 mCameraHandle = NULL; 2313 2314 //Notify display HAL that there is no active camera session 2315 //but avoid calling the same during bootup. Refer to openCamera 2316 //for more details. 2317 property_get("service.bootanim.exit", value, "0"); 2318 if (atoi(value) == 1) { 2319 pthread_mutex_lock(&gCamLock); 2320 if (--gNumCameraSessions == 0) { 2321 setCameraLaunchStatus(false); 2322 } 2323 pthread_mutex_unlock(&gCamLock); 2324 } 2325 2326 if (mExifParams.debug_params) { 2327 free(mExifParams.debug_params); 2328 mExifParams.debug_params = NULL; 2329 } 2330 2331 if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) { 2332 LOGD("Failed to release flash for camera id: %d", 2333 mCameraId); 2334 } 2335 2336 LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d", 2337 mCameraId, rc); 2338 2339 return rc; 2340 } 2341 2342 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX ) 2343 2344 2345 /*=========================================================================== 2346 * FUNCTION : getCapabilities 2347 * 2348 * DESCRIPTION: query camera capability from back-end 2349 * 2350 * PARAMETERS : 2351 * @ops : mm-interface ops structure 2352 * @cam_handle : camera handle for which we need capability 2353 * 2354 * RETURN : ptr type of capability structure 2355 * capability for success 2356 * NULL for failure 2357 *==========================================================================*/ 2358 cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops, 2359 uint32_t cam_handle) 2360 { 2361 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP); 2362 int rc = NO_ERROR; 2363 QCameraHeapMemory *capabilityHeap = NULL; 2364 cam_capability_t *cap_ptr = NULL; 2365 2366 if (ops == NULL) { 2367 LOGE("Invalid arguments"); 2368 return NULL; 2369 } 2370 2371 capabilityHeap = new QCameraHeapMemory(1); 2372 if (capabilityHeap == NULL) { 2373 LOGE("creation of capabilityHeap failed"); 2374 return NULL; 2375 } 2376 2377 /* Allocate memory for capability buffer */ 2378 rc = capabilityHeap->allocate(1, sizeof(cam_capability_t)); 2379 if(rc != OK) { 2380 LOGE("No memory for capability"); 2381 goto allocate_failed; 2382 } 2383 2384 /* Map memory for capability buffer */ 2385 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t)); 2386 2387 cam_buf_map_type_list bufMapList; 2388 rc = QCameraBufferMaps::makeSingletonBufMapList( 2389 CAM_MAPPING_BUF_TYPE_CAPABILITY, 2390 0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/, 2391 0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t), 2392 bufMapList, capabilityHeap->getPtr(0)); 2393 2394 if (rc == NO_ERROR) { 2395 rc = ops->map_bufs(cam_handle, 2396 &bufMapList); 2397 } 2398 if(rc < 0) { 2399 LOGE("failed to map capability buffer"); 2400 goto map_failed; 2401 } 2402 2403 /* Query Capability */ 2404 rc = ops->query_capability(cam_handle); 2405 if(rc < 0) { 2406 LOGE("failed to query capability"); 2407 rc = FAILED_TRANSACTION; 2408 goto query_failed; 2409 } 2410 2411 cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t)); 2412 if (cap_ptr == NULL) { 2413 LOGE("out of memory"); 2414 rc = NO_MEMORY; 2415 goto query_failed; 2416 } 2417 2418 memset(cap_ptr, 0, sizeof(cam_capability_t)); 2419 memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t)); 2420 2421 int index; 2422 for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) { 2423 cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index]; 2424 p_analysis_info->analysis_padding_info.offset_info.offset_x = 0; 2425 p_analysis_info->analysis_padding_info.offset_info.offset_y = 0; 2426 } 2427 2428 query_failed: 2429 ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY); 2430 map_failed: 2431 capabilityHeap->deallocate(); 2432 allocate_failed: 2433 delete capabilityHeap; 2434 2435 if (rc != NO_ERROR) { 2436 return NULL; 2437 } else { 2438 return cap_ptr; 2439 } 2440 } 2441 2442 /*=========================================================================== 2443 * FUNCTION : initCapabilities 2444 * 2445 * DESCRIPTION: initialize camera capabilities in static data struct 2446 * 2447 * PARAMETERS : 2448 * @cameraId : camera Id 2449 * 2450 * RETURN : int32_t type of status 2451 * NO_ERROR -- success 2452 * none-zero failure code 2453 *==========================================================================*/ 2454 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId, 2455 mm_camera_vtbl_t *cameraHandle) 2456 { 2457 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_INIT_CAP); 2458 int rc = 0; 2459 uint32_t handle = 0; 2460 2461 rc = camera_open((uint8_t)cameraId, &cameraHandle); 2462 if (rc) { 2463 LOGE("camera_open failed. rc = %d", rc); 2464 goto open_failed; 2465 } 2466 if (!cameraHandle) { 2467 LOGE("camera_open failed. cameraHandle = %p", cameraHandle); 2468 goto open_failed; 2469 } 2470 2471 handle = get_main_camera_handle(cameraHandle->camera_handle); 2472 gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle); 2473 if (gCamCapability[cameraId] == NULL) { 2474 rc = FAILED_TRANSACTION; 2475 goto failed_op; 2476 } 2477 2478 gCamCapability[cameraId]->camera_index = cameraId; 2479 if (is_dual_camera_by_idx(cameraId)) { 2480 handle = get_aux_camera_handle(cameraHandle->camera_handle); 2481 gCamCapability[cameraId]->aux_cam_cap = 2482 getCapabilities(cameraHandle->ops, handle); 2483 if (gCamCapability[cameraId]->aux_cam_cap == NULL) { 2484 rc = FAILED_TRANSACTION; 2485 free(gCamCapability[cameraId]); 2486 goto failed_op; 2487 } 2488 2489 // Copy the main camera capability to main_cam_cap struct 2490 gCamCapability[cameraId]->main_cam_cap = 2491 (cam_capability_t *)malloc(sizeof(cam_capability_t)); 2492 if (gCamCapability[cameraId]->main_cam_cap == NULL) { 2493 LOGE("out of memory"); 2494 rc = NO_MEMORY; 2495 goto failed_op; 2496 } 2497 memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId], 2498 sizeof(cam_capability_t)); 2499 } 2500 failed_op: 2501 cameraHandle->ops->close_camera(cameraHandle->camera_handle); 2502 cameraHandle = NULL; 2503 open_failed: 2504 return rc; 2505 } 2506 2507 /*=========================================================================== 2508 * FUNCTION : getCapabilities 2509 * 2510 * DESCRIPTION: query camera capabilities 2511 * 2512 * PARAMETERS : 2513 * @cameraId : camera Id 2514 * @info : camera info struct to be filled in with camera capabilities 2515 * 2516 * RETURN : int type of status 2517 * NO_ERROR -- success 2518 * none-zero failure code 2519 *==========================================================================*/ 2520 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId, 2521 struct camera_info *info, cam_sync_type_t *p_cam_type) 2522 { 2523 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP); 2524 int rc = NO_ERROR; 2525 struct camera_info *p_info = NULL; 2526 pthread_mutex_lock(&gCamLock); 2527 p_info = get_cam_info(cameraId, p_cam_type); 2528 p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0; 2529 p_info->static_camera_characteristics = NULL; 2530 memcpy(info, p_info, sizeof (struct camera_info)); 2531 pthread_mutex_unlock(&gCamLock); 2532 return rc; 2533 } 2534 2535 /*=========================================================================== 2536 * FUNCTION : getCamHalCapabilities 2537 * 2538 * DESCRIPTION: get the HAL capabilities structure 2539 * 2540 * PARAMETERS : 2541 * @cameraId : camera Id 2542 * 2543 * RETURN : capability structure of respective camera 2544 * 2545 *==========================================================================*/ 2546 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities() 2547 { 2548 return gCamCapability[mCameraId]; 2549 } 2550 2551 /*=========================================================================== 2552 * FUNCTION : getBufNumForAux 2553 * 2554 * DESCRIPTION: return number of stream buffers needed for aux camera given stream type 2555 * 2556 * PARAMETERS : 2557 * @stream_type : type of stream 2558 * 2559 * RETURN : number of buffers needed 2560 * NOTE : Based on the use cases and auxillary camera type, 2561 we can decide buffer count 2562 *==========================================================================*/ 2563 uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type) 2564 { 2565 if (!isDualCamera()) { 2566 return 0; 2567 } 2568 2569 uint8_t bufferCnt = 1; 2570 switch (stream_type) { 2571 case CAM_STREAM_TYPE_PREVIEW: 2572 case CAM_STREAM_TYPE_VIDEO: 2573 case CAM_STREAM_TYPE_SNAPSHOT: 2574 case CAM_STREAM_TYPE_METADATA: 2575 case CAM_STREAM_TYPE_CALLBACK: 2576 case CAM_STREAM_TYPE_ANALYSIS: 2577 case CAM_STREAM_TYPE_POSTVIEW: 2578 case CAM_STREAM_TYPE_RAW: 2579 case CAM_STREAM_TYPE_OFFLINE_PROC: 2580 case CAM_STREAM_TYPE_DEFAULT: 2581 case CAM_STREAM_TYPE_MAX: 2582 //For wide & tele, we use same buffer count premary and aux streams. 2583 bufferCnt = getBufNumRequired(stream_type); 2584 break; 2585 default: 2586 break; 2587 } 2588 LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt); 2589 return bufferCnt; 2590 } 2591 2592 /*=========================================================================== 2593 * FUNCTION : getBufNumRequired 2594 * 2595 * DESCRIPTION: return number of stream buffers needed for given stream type 2596 * 2597 * PARAMETERS : 2598 * @stream_type : type of stream 2599 * 2600 * RETURN : number of buffers needed 2601 *==========================================================================*/ 2602 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type) 2603 { 2604 int bufferCnt = 0; 2605 int minCaptureBuffers = mParameters.getNumOfSnapshots(); 2606 char value[PROPERTY_VALUE_MAX]; 2607 bool raw_yuv = false; 2608 int persist_cnt = 0; 2609 int minPrevFps, maxPrevFps; 2610 2611 int zslQBuffers = mParameters.getZSLQueueDepth(); 2612 2613 int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() + 2614 CAMERA_MIN_JPEG_ENCODING_BUFFERS; 2615 2616 int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() + 2617 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2618 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2619 mParameters.getNumOfExtraBuffersForImageProc() + 2620 EXTRA_ZSL_PREVIEW_STREAM_BUF; 2621 2622 int minUndequeCount = 0; 2623 if (!isNoDisplayMode()) { 2624 if(mPreviewWindow != NULL) { 2625 if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount) 2626 != 0) { 2627 LOGW("get_min_undequeued_buffer_count failed"); 2628 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined 2629 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS; 2630 minUndequeCount = MIN_UNDEQUEUED_BUFFERS; 2631 } 2632 } else { 2633 //preview window might not be set at this point. So, query directly 2634 //from BufferQueue implementation of gralloc buffers. 2635 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS; 2636 //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT 2637 minUndequeCount = MIN_UNDEQUEUED_BUFFERS; 2638 } 2639 if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) { 2640 // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS 2641 // and so change the MACRO as per minUndequeCount 2642 LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)", 2643 minUndequeCount, MIN_UNDEQUEUED_BUFFERS); 2644 } 2645 } 2646 2647 LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d" 2648 "maxStreamBuf = %d minUndequeCount = %d", 2649 minCaptureBuffers, zslQBuffers, minCircularBufNum, 2650 maxStreamBuf, minUndequeCount); 2651 // Get buffer count for the particular stream type 2652 switch (stream_type) { 2653 case CAM_STREAM_TYPE_PREVIEW: 2654 { 2655 if (mParameters.isZSLMode()) { 2656 // We need to add two extra streming buffers to add 2657 // flexibility in forming matched super buf in ZSL queue. 2658 // with number being 'zslQBuffers + minCircularBufNum' 2659 // we see preview buffers sometimes get dropped at CPP 2660 // and super buf is not forming in ZSL Q for long time. 2661 2662 bufferCnt = zslQBuffers + minCircularBufNum + 2663 mParameters.getNumOfExtraBuffersForImageProc() + 2664 mParameters.getNumOfExtraBuffersForPreview() + 2665 mParameters.getNumOfExtraHDRInBufsIfNeeded(); 2666 if (isDualCamera()) { 2667 bufferCnt += zslQBuffers; 2668 } 2669 } else { 2670 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS + 2671 mParameters.getMaxUnmatchedFramesInQueue() + 2672 mParameters.getNumOfExtraBuffersForPreview(); 2673 } 2674 // ISP allocates native preview buffers and so reducing same from HAL allocation 2675 if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS ) 2676 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2677 2678 // Extra ZSL preview frames are not needed for HFR case. 2679 // Thumbnail will not be derived from preview for HFR live snapshot case. 2680 if ((mParameters.getRecordingHintValue() == true) 2681 && (!mParameters.isHfrMode())) { 2682 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF; 2683 } 2684 //Adding Extra preview buffers for 60FPS usecase. 2685 mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps); 2686 if (maxPrevFps > CAMERA_DEFAULT_FPS) { 2687 bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS; 2688 } 2689 2690 // Add the display minUndequeCount count on top of camera requirement 2691 bufferCnt += minUndequeCount; 2692 2693 property_get("persist.camera.preview_yuv", value, "0"); 2694 persist_cnt = atoi(value); 2695 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2696 && (bufferCnt < persist_cnt)) { 2697 bufferCnt = persist_cnt; 2698 } 2699 } 2700 break; 2701 case CAM_STREAM_TYPE_POSTVIEW: 2702 { 2703 bufferCnt = minCaptureBuffers + 2704 mParameters.getMaxUnmatchedFramesInQueue() + 2705 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2706 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2707 mParameters.getNumOfExtraBuffersForImageProc(); 2708 2709 if (bufferCnt > maxStreamBuf) { 2710 bufferCnt = maxStreamBuf; 2711 } 2712 bufferCnt += minUndequeCount; 2713 } 2714 break; 2715 case CAM_STREAM_TYPE_SNAPSHOT: 2716 { 2717 if (mParameters.isZSLMode() || mLongshotEnabled) { 2718 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) && 2719 !mLongshotEnabled) { 2720 // Single ZSL snapshot case 2721 bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS + 2722 mParameters.getNumOfExtraBuffersForImageProc(); 2723 } else { 2724 // ZSL Burst or Longshot case 2725 bufferCnt = zslQBuffers + minCircularBufNum + 2726 mParameters.getNumOfExtraBuffersForImageProc(); 2727 } 2728 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) { 2729 //ISP allocates native buffers in YUV case 2730 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2731 } 2732 if (isDualCamera()) { 2733 bufferCnt += zslQBuffers; 2734 } 2735 } else { 2736 bufferCnt = minCaptureBuffers + 2737 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2738 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2739 mParameters.getNumOfExtraBuffersForImageProc(); 2740 2741 if (bufferCnt > maxStreamBuf) { 2742 bufferCnt = maxStreamBuf; 2743 } 2744 } 2745 } 2746 break; 2747 case CAM_STREAM_TYPE_RAW: 2748 property_get("persist.camera.raw_yuv", value, "0"); 2749 raw_yuv = atoi(value) > 0 ? true : false; 2750 2751 if (isRdiMode() || raw_yuv || isSecureMode()) { 2752 bufferCnt = zslQBuffers + minCircularBufNum; 2753 } else if (mParameters.isZSLMode()) { 2754 bufferCnt = zslQBuffers + minCircularBufNum; 2755 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) { 2756 //ISP allocates native buffers in YUV case 2757 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2758 } 2759 2760 } else { 2761 bufferCnt = minCaptureBuffers + 2762 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2763 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2764 mParameters.getNumOfExtraBuffersForImageProc(); 2765 2766 if (bufferCnt > maxStreamBuf) { 2767 bufferCnt = maxStreamBuf; 2768 } 2769 } 2770 2771 property_get("persist.camera.preview_raw", value, "0"); 2772 persist_cnt = atoi(value); 2773 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2774 && (bufferCnt < persist_cnt)) { 2775 bufferCnt = persist_cnt; 2776 } 2777 property_get("persist.camera.video_raw", value, "0"); 2778 persist_cnt = atoi(value); 2779 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2780 && (bufferCnt < persist_cnt)) { 2781 bufferCnt = persist_cnt; 2782 } 2783 2784 break; 2785 case CAM_STREAM_TYPE_VIDEO: 2786 { 2787 if (mParameters.getBufBatchCount()) { 2788 //Video Buffer in case of HFR or camera batching.. 2789 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS; 2790 } else if (mParameters.getVideoBatchSize()) { 2791 //Video Buffer count only for HAL to HAL batching. 2792 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS 2793 * mParameters.getVideoBatchSize()); 2794 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) { 2795 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS; 2796 } 2797 } else { 2798 // No batching enabled. 2799 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS; 2800 } 2801 2802 bufferCnt += mParameters.getNumOfExtraBuffersForVideo(); 2803 //if its 4K encoding usecase, then add extra buffer 2804 cam_dimension_t dim; 2805 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim); 2806 if (is4k2kResolution(&dim)) { 2807 //get additional buffer count 2808 property_get("vidc.enc.dcvs.extra-buff-count", value, "0"); 2809 bufferCnt += atoi(value); 2810 } 2811 } 2812 break; 2813 case CAM_STREAM_TYPE_METADATA: 2814 { 2815 if (mParameters.isZSLMode()) { 2816 // MetaData buffers should be >= (Preview buffers-minUndequeCount) 2817 bufferCnt = zslQBuffers + minCircularBufNum + 2818 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2819 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2820 mParameters.getNumOfExtraBuffersForImageProc() + 2821 EXTRA_ZSL_PREVIEW_STREAM_BUF; 2822 if (isDualCamera()) { 2823 bufferCnt += zslQBuffers; 2824 } 2825 } else { 2826 bufferCnt = minCaptureBuffers + 2827 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2828 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2829 mParameters.getMaxUnmatchedFramesInQueue() + 2830 CAMERA_MIN_STREAMING_BUFFERS + 2831 mParameters.getNumOfExtraBuffersForImageProc(); 2832 2833 if (bufferCnt > zslQBuffers + minCircularBufNum) { 2834 bufferCnt = zslQBuffers + minCircularBufNum; 2835 } 2836 } 2837 if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) { 2838 bufferCnt = CAMERA_MIN_METADATA_BUFFERS; 2839 } 2840 } 2841 break; 2842 case CAM_STREAM_TYPE_OFFLINE_PROC: 2843 { 2844 bufferCnt = minCaptureBuffers; 2845 // One of the ubifocus buffers is miscellaneous buffer 2846 if (mParameters.isUbiRefocus()) { 2847 bufferCnt -= 1; 2848 } 2849 if (mLongshotEnabled) { 2850 bufferCnt = mParameters.getLongshotStages(); 2851 } 2852 } 2853 break; 2854 case CAM_STREAM_TYPE_CALLBACK: 2855 bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS; 2856 break; 2857 case CAM_STREAM_TYPE_ANALYSIS: 2858 case CAM_STREAM_TYPE_DEFAULT: 2859 case CAM_STREAM_TYPE_MAX: 2860 default: 2861 bufferCnt = 0; 2862 break; 2863 } 2864 2865 LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type); 2866 if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) { 2867 LOGW("Buffer count %d for stream type %d exceeds limit %d", 2868 bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM); 2869 return CAM_MAX_NUM_BUFS_PER_STREAM; 2870 } 2871 2872 return (uint8_t)bufferCnt; 2873 } 2874 2875 /*=========================================================================== 2876 * FUNCTION : getStreamRefCount 2877 * 2878 * DESCRIPTION: return number of instance of stream of stream type 2879 * 2880 * PARAMETERS : 2881 * @stream_type : type of stream 2882 * @cam_type : Type of camera for this stream 2883 * 2884 * RETURN : number of stream instances 2885 * NOTE : Based on the use cases and auxillary camera type, 2886 we can decide stream reference count. 2887 For example in wide and tele use case, we duplicate all stream 2888 streams from premary to auxillary. 2889 *==========================================================================*/ 2890 uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type, 2891 uint32_t cam_type) 2892 { 2893 uint8_t ref_cnt = 1; 2894 2895 if (cam_type != MM_CAMERA_DUAL_CAM) { 2896 return ref_cnt; 2897 } 2898 2899 switch (stream_type) { 2900 case CAM_STREAM_TYPE_PREVIEW: 2901 case CAM_STREAM_TYPE_SNAPSHOT: 2902 case CAM_STREAM_TYPE_VIDEO: 2903 case CAM_STREAM_TYPE_METADATA: 2904 case CAM_STREAM_TYPE_ANALYSIS: 2905 case CAM_STREAM_TYPE_CALLBACK: 2906 if (isDualCamera()) { 2907 ref_cnt++; 2908 } 2909 break; 2910 case CAM_STREAM_TYPE_POSTVIEW: 2911 case CAM_STREAM_TYPE_RAW: 2912 case CAM_STREAM_TYPE_OFFLINE_PROC: 2913 case CAM_STREAM_TYPE_DEFAULT: 2914 case CAM_STREAM_TYPE_MAX: 2915 default: 2916 break; 2917 } 2918 return ref_cnt; 2919 } 2920 2921 /*=========================================================================== 2922 * FUNCTION : getCamHandleForChannel 2923 * 2924 * DESCRIPTION: return actual camera handle based on use case 2925 * 2926 * PARAMETERS : 2927 * @ch_type : type of channel 2928 * 2929 * RETURN : uint32_t type camera handle 2930 * NOTE : Based on the use cases and auxillary camera type, we can decide cam handle for channel. 2931 Incase, we want to avoid any channel for auxillary camera, we can decide here 2932 *==========================================================================*/ 2933 uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type) 2934 { 2935 uint32_t handle = 0; 2936 if (!isDualCamera()) { 2937 return mCameraHandle->camera_handle; 2938 } 2939 2940 /*Based on the use case, decide camera handle for channel*/ 2941 switch (ch_type) { 2942 case QCAMERA_CH_TYPE_ZSL: 2943 case QCAMERA_CH_TYPE_CAPTURE: 2944 case QCAMERA_CH_TYPE_PREVIEW: 2945 case QCAMERA_CH_TYPE_VIDEO: 2946 case QCAMERA_CH_TYPE_SNAPSHOT: 2947 case QCAMERA_CH_TYPE_RAW: 2948 case QCAMERA_CH_TYPE_METADATA: 2949 case QCAMERA_CH_TYPE_ANALYSIS: 2950 case QCAMERA_CH_TYPE_CALLBACK: 2951 case QCAMERA_CH_TYPE_MAX: 2952 default: 2953 handle = mCameraHandle->camera_handle; 2954 break; 2955 case QCAMERA_CH_TYPE_REPROCESSING: 2956 if (!mParameters.isDCmAsymmetricSnapMode()) { 2957 handle = get_main_camera_handle(mCameraHandle->camera_handle); 2958 } else { 2959 /*In Asymmetric mode, we create 2 reproc channels. But 2960 one stream is added per channel */ 2961 handle = mCameraHandle->camera_handle; 2962 } 2963 break; 2964 } 2965 return handle; 2966 } 2967 2968 /*=========================================================================== 2969 * FUNCTION : allocateStreamBuf 2970 * 2971 * DESCRIPTION: alocate stream buffers 2972 * 2973 * PARAMETERS : 2974 * @stream_type : type of stream 2975 * @size : size of buffer 2976 * @stride : stride of buffer 2977 * @scanline : scanline of buffer 2978 * @bufferCnt : [IN/OUT] minimum num of buffers to be allocated. 2979 * could be modified during allocation if more buffers needed 2980 * 2981 * RETURN : ptr to a memory obj that holds stream buffers. 2982 * NULL if failed 2983 *==========================================================================*/ 2984 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf( 2985 cam_stream_type_t stream_type, size_t size, int stride, int scanline, 2986 uint8_t &bufferCnt) 2987 { 2988 int rc = NO_ERROR; 2989 QCameraMemory *mem = NULL; 2990 bool bCachedMem = QCAMERA_ION_USE_CACHE; 2991 bool bPoolMem = false; 2992 char value[PROPERTY_VALUE_MAX]; 2993 property_get("persist.camera.mem.usepool", value, "1"); 2994 if (atoi(value) == 1) { 2995 bPoolMem = true; 2996 } 2997 2998 // Allocate stream buffer memory object 2999 switch (stream_type) { 3000 case CAM_STREAM_TYPE_PREVIEW: 3001 { 3002 if (isNoDisplayMode()) { 3003 mem = new QCameraStreamMemory(mGetMemory, 3004 mCallbackCookie, 3005 bCachedMem, 3006 (bPoolMem) ? &m_memoryPool : NULL, 3007 stream_type); 3008 } else { 3009 cam_dimension_t dim; 3010 int minFPS, maxFPS; 3011 QCameraGrallocMemory *grallocMemory = NULL; 3012 3013 if (isSecureMode()) { 3014 grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie, QCAMERA_MEM_TYPE_SECURE); 3015 }else { 3016 grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie); 3017 } 3018 3019 mParameters.getStreamDimension(stream_type, dim); 3020 /* we are interested only in maxfps here */ 3021 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 3022 int usage = 0; 3023 if(mParameters.isUBWCEnabled()) { 3024 cam_format_t fmt; 3025 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt); 3026 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 3027 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ; 3028 } 3029 } 3030 if (grallocMemory) { 3031 grallocMemory->setMappable( 3032 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS); 3033 grallocMemory->setWindowInfo(mPreviewWindow, 3034 dim.width,dim.height, stride, scanline, 3035 mParameters.getPreviewHalPixelFormat(), 3036 maxFPS, usage); 3037 pthread_mutex_lock(&mGrallocLock); 3038 if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) { 3039 mEnqueuedBuffers = (bufferCnt - 3040 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS); 3041 } else { 3042 mEnqueuedBuffers = 0; 3043 } 3044 pthread_mutex_unlock(&mGrallocLock); 3045 } 3046 mem = grallocMemory; 3047 } 3048 } 3049 break; 3050 case CAM_STREAM_TYPE_POSTVIEW: 3051 { 3052 if (isNoDisplayMode() || isPreviewRestartEnabled()) { 3053 mem = new QCameraStreamMemory(mGetMemory, mCallbackCookie, bCachedMem); 3054 } else { 3055 cam_dimension_t dim; 3056 int minFPS, maxFPS; 3057 QCameraGrallocMemory *grallocMemory = 3058 new QCameraGrallocMemory(mGetMemory, mCallbackCookie); 3059 3060 mParameters.getStreamDimension(stream_type, dim); 3061 /* we are interested only in maxfps here */ 3062 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 3063 if (grallocMemory) { 3064 grallocMemory->setWindowInfo(mPreviewWindow, dim.width, 3065 dim.height, stride, scanline, 3066 mParameters.getPreviewHalPixelFormat(), maxFPS); 3067 } 3068 mem = grallocMemory; 3069 } 3070 } 3071 break; 3072 case CAM_STREAM_TYPE_ANALYSIS: 3073 case CAM_STREAM_TYPE_SNAPSHOT: 3074 case CAM_STREAM_TYPE_OFFLINE_PROC: 3075 mem = new QCameraStreamMemory(mGetMemory, 3076 mCallbackCookie, 3077 bCachedMem, 3078 (bPoolMem) ? &m_memoryPool : NULL, 3079 stream_type); 3080 break; 3081 case CAM_STREAM_TYPE_RAW: 3082 if(isSecureMode()) { 3083 mem = new QCameraStreamMemory(mGetMemory, 3084 mCallbackCookie, 3085 bCachedMem, 3086 (bPoolMem) ? &m_memoryPool : NULL, 3087 stream_type, 3088 QCAMERA_MEM_TYPE_SECURE); 3089 LOGH("Allocating %d secure buffers of size %d ", bufferCnt, size); 3090 } else { 3091 mem = new QCameraStreamMemory(mGetMemory, 3092 mCallbackCookie, 3093 bCachedMem, 3094 (bPoolMem) ? &m_memoryPool : NULL, 3095 stream_type); 3096 } 3097 break; 3098 case CAM_STREAM_TYPE_METADATA: 3099 { 3100 if (mMetadataMem == NULL) { 3101 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE); 3102 } else { 3103 mem = mMetadataMem; 3104 mMetadataMem = NULL; 3105 3106 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt(); 3107 if (numAdditionalBuffers > 0) { 3108 rc = mem->allocateMore(numAdditionalBuffers, size); 3109 if (rc != NO_ERROR) { 3110 LOGE("Failed to allocate additional buffers, " 3111 "but attempting to proceed."); 3112 } 3113 } 3114 bufferCnt = mem->getCnt(); 3115 // The memory is already allocated and initialized, so 3116 // simply return here. 3117 return mem; 3118 } 3119 } 3120 break; 3121 case CAM_STREAM_TYPE_VIDEO: 3122 { 3123 //Use uncached allocation by default 3124 if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() || 3125 mParameters.isHighQualityNoiseReductionMode()) { 3126 bCachedMem = QCAMERA_ION_USE_CACHE; 3127 } 3128 else { 3129 bCachedMem = QCAMERA_ION_USE_NOCACHE; 3130 } 3131 3132 QCameraVideoMemory *videoMemory = NULL; 3133 int usage = 0; 3134 cam_format_t fmt; 3135 3136 if (mParameters.getVideoBatchSize()) { 3137 videoMemory = new QCameraVideoMemory( 3138 mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH); 3139 if (videoMemory == NULL) { 3140 LOGE("Out of memory for video batching obj"); 3141 return NULL; 3142 } 3143 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt); 3144 if (mParameters.isUBWCEnabled() && 3145 (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) { 3146 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 3147 } 3148 videoMemory->setVideoInfo(usage, fmt); 3149 /* 3150 * numFDs = BATCH size 3151 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT 3152 */ 3153 rc = videoMemory->allocateMeta( 3154 CAMERA_MIN_VIDEO_BATCH_BUFFERS, 3155 mParameters.getVideoBatchSize()); 3156 if (rc < 0) { 3157 delete videoMemory; 3158 return NULL; 3159 } 3160 } else { 3161 videoMemory = 3162 new QCameraVideoMemory(mGetMemory, mCallbackCookie, bCachedMem); 3163 if (videoMemory == NULL) { 3164 LOGE("Out of memory for video obj"); 3165 return NULL; 3166 } 3167 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt); 3168 if (mParameters.isUBWCEnabled() && 3169 (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) { 3170 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 3171 } 3172 videoMemory->setVideoInfo(usage, fmt); 3173 } 3174 mem = videoMemory; 3175 } 3176 break; 3177 case CAM_STREAM_TYPE_CALLBACK: 3178 mem = new QCameraStreamMemory(mGetMemory, 3179 mCallbackCookie, 3180 bCachedMem, 3181 (bPoolMem) ? &m_memoryPool : NULL, 3182 stream_type); 3183 break; 3184 case CAM_STREAM_TYPE_DEFAULT: 3185 case CAM_STREAM_TYPE_MAX: 3186 default: 3187 break; 3188 } 3189 if (!mem) { 3190 return NULL; 3191 } 3192 3193 if (bufferCnt > 0) { 3194 rc = mem->allocate(bufferCnt, size); 3195 if (rc < 0) { 3196 delete mem; 3197 return NULL; 3198 } 3199 bufferCnt = mem->getCnt(); 3200 } 3201 LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d mEnqueuedBuffers = %d", 3202 rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem, mEnqueuedBuffers); 3203 return mem; 3204 } 3205 3206 /*=========================================================================== 3207 * FUNCTION : allocateMoreStreamBuf 3208 * 3209 * DESCRIPTION: alocate more stream buffers from the memory object 3210 * 3211 * PARAMETERS : 3212 * @mem_obj : memory object ptr 3213 * @size : size of buffer 3214 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated. 3215 * output will be the number of total buffers 3216 * 3217 * RETURN : int32_t type of status 3218 * NO_ERROR -- success 3219 * none-zero failure code 3220 *==========================================================================*/ 3221 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf( 3222 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt) 3223 { 3224 int rc = NO_ERROR; 3225 3226 if (bufferCnt > 0) { 3227 rc = mem_obj->allocateMore(bufferCnt, size); 3228 bufferCnt = mem_obj->getCnt(); 3229 } 3230 return rc; 3231 } 3232 3233 /*=========================================================================== 3234 * FUNCTION : allocateMiscBuf 3235 * 3236 * DESCRIPTION: alocate miscellaneous buffer 3237 * 3238 * PARAMETERS : 3239 * @streamInfo : stream info 3240 * 3241 * RETURN : ptr to a memory obj that holds stream info buffer. 3242 * NULL if failed 3243 *==========================================================================*/ 3244 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf( 3245 cam_stream_info_t *streamInfo) 3246 { 3247 int rc = NO_ERROR; 3248 uint8_t bufNum = 0; 3249 size_t bufSize = 0; 3250 QCameraHeapMemory *miscBuf = NULL; 3251 cam_feature_mask_t feature_mask = 3252 streamInfo->reprocess_config.pp_feature_config.feature_mask; 3253 3254 switch (streamInfo->stream_type) { 3255 case CAM_STREAM_TYPE_OFFLINE_PROC: 3256 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) { 3257 bufNum = 1; 3258 bufSize = mParameters.getTPMaxMetaSize(); 3259 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) { 3260 bufNum = 1; 3261 bufSize = mParameters.getRefocusMaxMetaSize(); 3262 } 3263 break; 3264 default: 3265 break; 3266 } 3267 3268 if (bufNum && bufSize) { 3269 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 3270 3271 if (!miscBuf) { 3272 LOGE("Unable to allocate miscBuf object"); 3273 return NULL; 3274 } 3275 3276 rc = miscBuf->allocate(bufNum, bufSize); 3277 if (rc < 0) { 3278 LOGE("Failed to allocate misc buffer memory"); 3279 delete miscBuf; 3280 return NULL; 3281 } 3282 } 3283 3284 return miscBuf; 3285 } 3286 3287 /*=========================================================================== 3288 * FUNCTION : initStreamInfoBuf 3289 * 3290 * DESCRIPTION: initialize stream info buffer based on stream type 3291 * 3292 * PARAMETERS : 3293 * @stream_type : type of stream 3294 * @cam_type : Camera type in case of dual camera 3295 * 3296 * RETURN : ptr to a memory obj that holds stream info buffer. 3297 * NULL if failed 3298 *==========================================================================*/ 3299 int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type, 3300 cam_stream_info_t *streamInfo, uint32_t cam_type) 3301 { 3302 int rc = NO_ERROR; 3303 int32_t dt = 0; 3304 int32_t vc = 0; 3305 3306 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 3307 streamInfo->stream_type = stream_type; 3308 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt); 3309 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim, cam_type); 3310 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim); 3311 streamInfo->num_bufs = getBufNumRequired(stream_type); 3312 streamInfo->buf_cnt = streamInfo->num_bufs; 3313 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 3314 streamInfo->is_secure = NON_SECURE; 3315 // Initialize cache ops 3316 if (!m_bOptimizeCacheOps) { 3317 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_DISABLED; 3318 } else { 3319 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_HONOUR_FLAGS; 3320 } 3321 3322 switch (stream_type) { 3323 case CAM_STREAM_TYPE_SNAPSHOT: 3324 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) || 3325 mLongshotEnabled) { 3326 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 3327 } else { 3328 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 3329 streamInfo->num_of_burst = (uint8_t) 3330 (mParameters.getNumOfSnapshots() 3331 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 3332 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 3333 + mParameters.getNumOfExtraBuffersForImageProc()); 3334 } 3335 break; 3336 case CAM_STREAM_TYPE_RAW: { 3337 char value[PROPERTY_VALUE_MAX]; 3338 bool raw_yuv = false; 3339 property_get("persist.camera.raw_yuv", value, "0"); 3340 raw_yuv = atoi(value) > 0 ? true : false; 3341 if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv) || isSecureMode()) { 3342 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 3343 } else { 3344 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 3345 streamInfo->num_of_burst = mParameters.getNumOfSnapshots(); 3346 } 3347 if (isSecureMode()) { 3348 streamInfo->is_secure = SECURE; 3349 } else { 3350 streamInfo->is_secure = NON_SECURE; 3351 } 3352 } 3353 if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) { 3354 mParameters.updateDtVc(&dt, &vc); 3355 if (dt) 3356 streamInfo->dt = dt; 3357 streamInfo->vc = vc; 3358 } 3359 3360 break; 3361 case CAM_STREAM_TYPE_POSTVIEW: 3362 if (mLongshotEnabled) { 3363 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 3364 } else { 3365 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 3366 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots() 3367 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 3368 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 3369 + mParameters.getNumOfExtraBuffersForImageProc()); 3370 } 3371 break; 3372 case CAM_STREAM_TYPE_VIDEO: 3373 streamInfo->dis_enable = mParameters.isDISEnabled(); 3374 if (mParameters.getBufBatchCount()) { 3375 //Update stream info structure with batch mode info 3376 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH; 3377 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount(); 3378 streamInfo->user_buf_info.size = 3379 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t)); 3380 cam_fps_range_t pFpsRange; 3381 mParameters.getHfrFps(pFpsRange); 3382 streamInfo->user_buf_info.frameInterval = 3383 (long)((1000/pFpsRange.video_max_fps) * 1000); 3384 LOGH("Video Batch Count = %d, interval = %d", 3385 streamInfo->user_buf_info.frame_buf_cnt, 3386 streamInfo->user_buf_info.frameInterval); 3387 } 3388 if (mParameters.getRecordingHintValue()) { 3389 if(mParameters.isDISEnabled()) { 3390 streamInfo->is_type = mParameters.getVideoISType(); 3391 } else { 3392 streamInfo->is_type = IS_TYPE_NONE; 3393 } 3394 } 3395 if (mParameters.isSecureMode()) { 3396 streamInfo->is_secure = SECURE; 3397 } 3398 break; 3399 case CAM_STREAM_TYPE_PREVIEW: 3400 if (mParameters.getRecordingHintValue()) { 3401 if(mParameters.isDISEnabled()) { 3402 streamInfo->is_type = mParameters.getPreviewISType(); 3403 } else { 3404 streamInfo->is_type = IS_TYPE_NONE; 3405 } 3406 } 3407 if (isSecureMode()) { 3408 streamInfo->is_secure = SECURE; 3409 } else { 3410 streamInfo->is_secure = NON_SECURE; 3411 } 3412 // If SAT enabled, don't add preview stream to Bundled queue 3413 if (isDualCamera()) { 3414 char prop[PROPERTY_VALUE_MAX]; 3415 memset(prop, 0, sizeof(prop)); 3416 bool satEnabledFlag = FALSE; 3417 property_get("persist.camera.sat.enable", prop, "0"); 3418 satEnabledFlag = atoi(prop); 3419 if (satEnabledFlag) { 3420 streamInfo->noFrameExpected = 1; 3421 } 3422 } 3423 break; 3424 case CAM_STREAM_TYPE_ANALYSIS: 3425 streamInfo->noFrameExpected = 1; 3426 break; 3427 case CAM_STREAM_TYPE_METADATA: 3428 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_CLEAR_FLAGS; 3429 break; 3430 default: 3431 break; 3432 } 3433 3434 // Update feature mask 3435 mParameters.updatePpFeatureMask(stream_type); 3436 3437 // Get feature mask 3438 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask); 3439 3440 // Update pp config 3441 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) { 3442 int flipMode = mParameters.getFlipMode(stream_type); 3443 if (flipMode > 0) { 3444 streamInfo->pp_config.flip = (uint32_t)flipMode; 3445 } 3446 } 3447 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) { 3448 streamInfo->pp_config.sharpness = mParameters.getSharpness(); 3449 } 3450 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) { 3451 streamInfo->pp_config.effect = mParameters.getEffectValue(); 3452 } 3453 3454 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) { 3455 streamInfo->pp_config.denoise2d.denoise_enable = 1; 3456 streamInfo->pp_config.denoise2d.process_plates = 3457 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 3458 } 3459 3460 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type || 3461 CAM_STREAM_TYPE_RAW == stream_type))) { 3462 if (gCamCapability[mCameraId]->qcom_supported_feature_mask & 3463 CAM_QCOM_FEATURE_CROP) 3464 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 3465 if (gCamCapability[mCameraId]->qcom_supported_feature_mask & 3466 CAM_QCOM_FEATURE_SCALE) 3467 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 3468 } 3469 streamInfo->aux_str_info = NULL; 3470 3471 LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n", 3472 stream_type, streamInfo->fmt, streamInfo->dim.width, 3473 streamInfo->dim.height, streamInfo->num_bufs, 3474 streamInfo->pp_config.feature_mask, 3475 streamInfo->is_type); 3476 3477 return rc; 3478 } 3479 3480 /*=========================================================================== 3481 * FUNCTION : allocateStreamInfoBuf 3482 * 3483 * DESCRIPTION: alocate stream info buffer 3484 * 3485 * PARAMETERS : 3486 * @stream_type : type of stream 3487 * @bufCount : stream info buffer count 3488 * @cam_type : Camera type in case of dual camera 3489 * 3490 * RETURN : ptr to a memory obj that holds stream info buffer. 3491 * NULL if failed 3492 *==========================================================================*/ 3493 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf( 3494 cam_stream_type_t stream_type, uint8_t bufCount, uint32_t cam_type) 3495 { 3496 int rc = NO_ERROR; 3497 3498 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 3499 if (!streamInfoBuf) { 3500 LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object"); 3501 return NULL; 3502 } 3503 3504 if (bufCount > MM_CAMERA_MAX_CAM_CNT) { 3505 LOGE("buffer count should be lesser than max camera : %d", bufCount); 3506 return NULL; 3507 } 3508 rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t)); 3509 if (rc < 0) { 3510 LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory"); 3511 delete streamInfoBuf; 3512 return NULL; 3513 } 3514 3515 for (uint8_t i = 0; i < bufCount; i++) { 3516 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i); 3517 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 3518 rc = initStreamInfoBuf(stream_type, streamInfo, cam_type); 3519 if (rc < 0) { 3520 LOGE("initStreamInfoBuf failed"); 3521 delete streamInfoBuf; 3522 return NULL; 3523 } 3524 } 3525 3526 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0); 3527 if (bufCount == MM_CAMERA_MAX_CAM_CNT) { 3528 cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1); 3529 streamInfo->aux_str_info = s_streamInfo; 3530 } 3531 3532 if (streamInfo->aux_str_info != NULL) { 3533 /*Update StreamInfo for Aux camera*/ 3534 streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type); 3535 streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt; 3536 streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt; 3537 } 3538 return streamInfoBuf; 3539 } 3540 3541 /*=========================================================================== 3542 * FUNCTION : allocateStreamUserBuf 3543 * 3544 * DESCRIPTION: allocate user ptr for stream buffers 3545 * 3546 * PARAMETERS : 3547 * @streamInfo : stream info structure 3548 * 3549 * RETURN : ptr to a memory obj that holds stream info buffer. 3550 * NULL if failed 3551 3552 *==========================================================================*/ 3553 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf( 3554 cam_stream_info_t *streamInfo) 3555 { 3556 int rc = NO_ERROR; 3557 QCameraMemory *mem = NULL; 3558 int size = 0; 3559 3560 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) { 3561 LOGE("Stream is not in BATCH mode. Invalid Stream"); 3562 return NULL; 3563 } 3564 3565 // Allocate stream user buffer memory object 3566 switch (streamInfo->stream_type) { 3567 case CAM_STREAM_TYPE_VIDEO: { 3568 QCameraVideoMemory *video_mem = new QCameraVideoMemory( 3569 mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH); 3570 if (video_mem == NULL) { 3571 LOGE("Out of memory for video obj"); 3572 return NULL; 3573 } 3574 3575 int usage = 0; 3576 cam_format_t fmt; 3577 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt); 3578 if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) { 3579 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 3580 } 3581 video_mem->setVideoInfo(usage, fmt); 3582 3583 /* 3584 * numFDs = BATCH size 3585 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT 3586 */ 3587 rc = video_mem->allocateMeta(streamInfo->num_bufs, 3588 mParameters.getBufBatchCount()); 3589 if (rc < 0) { 3590 LOGE("allocateMeta failed"); 3591 delete video_mem; 3592 return NULL; 3593 } 3594 mem = static_cast<QCameraMemory *>(video_mem); 3595 } 3596 break; 3597 3598 case CAM_STREAM_TYPE_PREVIEW: 3599 case CAM_STREAM_TYPE_POSTVIEW: 3600 case CAM_STREAM_TYPE_ANALYSIS: 3601 case CAM_STREAM_TYPE_SNAPSHOT: 3602 case CAM_STREAM_TYPE_RAW: 3603 case CAM_STREAM_TYPE_METADATA: 3604 case CAM_STREAM_TYPE_OFFLINE_PROC: 3605 case CAM_STREAM_TYPE_CALLBACK: 3606 LOGE("Stream type Not supported.for BATCH processing"); 3607 break; 3608 3609 case CAM_STREAM_TYPE_DEFAULT: 3610 case CAM_STREAM_TYPE_MAX: 3611 default: 3612 break; 3613 } 3614 if (!mem) { 3615 LOGE("Failed to allocate mem"); 3616 return NULL; 3617 } 3618 3619 /*Size of this buffer will be number of batch buffer */ 3620 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size), 3621 CAM_PAD_TO_4K); 3622 3623 LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs); 3624 3625 if (size > 0) { 3626 // Allocating one buffer for all batch buffers 3627 rc = mem->allocate(1, size); 3628 if (rc < 0) { 3629 delete mem; 3630 return NULL; 3631 } 3632 } 3633 return mem; 3634 } 3635 3636 3637 /*=========================================================================== 3638 * FUNCTION : waitForDeferredAlloc 3639 * 3640 * DESCRIPTION: Wait for deferred allocation, if applicable 3641 * (applicable only for metadata buffers so far) 3642 * 3643 * PARAMETERS : 3644 * @stream_type : type of stream to (possibly) wait for 3645 * 3646 * RETURN : None 3647 *==========================================================================*/ 3648 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type) 3649 { 3650 if (stream_type == CAM_STREAM_TYPE_METADATA) { 3651 waitDeferredWork(mMetadataAllocJob); 3652 } 3653 } 3654 3655 3656 /*=========================================================================== 3657 * FUNCTION : setPreviewWindow 3658 * 3659 * DESCRIPTION: set preview window impl 3660 * 3661 * PARAMETERS : 3662 * @window : ptr to window ops table struct 3663 * 3664 * RETURN : int32_t type of status 3665 * NO_ERROR -- success 3666 * none-zero failure code 3667 *==========================================================================*/ 3668 int QCamera2HardwareInterface::setPreviewWindow( 3669 struct preview_stream_ops *window) 3670 { 3671 mPreviewWindow = window; 3672 return NO_ERROR; 3673 } 3674 3675 /*=========================================================================== 3676 * FUNCTION : setCallBacks 3677 * 3678 * DESCRIPTION: set callbacks impl 3679 * 3680 * PARAMETERS : 3681 * @notify_cb : notify cb 3682 * @data_cb : data cb 3683 * @data_cb_timestamp : data cb with time stamp 3684 * @get_memory : request memory ops table 3685 * @user : user data ptr 3686 * 3687 * RETURN : int32_t type of status 3688 * NO_ERROR -- success 3689 * none-zero failure code 3690 *==========================================================================*/ 3691 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb, 3692 camera_data_callback data_cb, 3693 camera_data_timestamp_callback data_cb_timestamp, 3694 camera_request_memory get_memory, 3695 void *user) 3696 { 3697 mNotifyCb = notify_cb; 3698 mDataCb = data_cb; 3699 mDataCbTimestamp = data_cb_timestamp; 3700 mGetMemory = get_memory; 3701 mCallbackCookie = user; 3702 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user); 3703 return NO_ERROR; 3704 } 3705 3706 /*=========================================================================== 3707 * FUNCTION : setJpegCallBacks 3708 * 3709 * DESCRIPTION: set JPEG callbacks impl 3710 * 3711 * PARAMETERS : 3712 * @jpegCb : Jpeg callback method 3713 * @callbackCookie : callback cookie 3714 * 3715 * RETURN : int32_t type of status 3716 * NO_ERROR -- success 3717 * none-zero failure code 3718 *==========================================================================*/ 3719 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb, 3720 void *callbackCookie) 3721 { 3722 LOGH("camera id %d", getCameraId()); 3723 mJpegCb = jpegCb; 3724 mJpegCallbackCookie = callbackCookie; 3725 m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie); 3726 } 3727 3728 /*=========================================================================== 3729 * FUNCTION : enableMsgType 3730 * 3731 * DESCRIPTION: enable msg type impl 3732 * 3733 * PARAMETERS : 3734 * @msg_type : msg type mask to be enabled 3735 * 3736 * RETURN : int32_t type of status 3737 * NO_ERROR -- success 3738 * none-zero failure code 3739 *==========================================================================*/ 3740 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type) 3741 { 3742 int32_t rc = NO_ERROR; 3743 3744 if (mParameters.isUBWCEnabled()) { 3745 /*Need Special CALLBACK stream incase application requesting for 3746 Preview callback in UBWC case*/ 3747 if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) && 3748 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) { 3749 // Start callback channel only when preview/zsl channel is active 3750 QCameraChannel* previewCh = NULL; 3751 if (isZSLMode() && (getRecordingHintValue() != true)) { 3752 previewCh = m_channels[QCAMERA_CH_TYPE_ZSL]; 3753 } else { 3754 previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 3755 } 3756 QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK]; 3757 if ((callbackCh != NULL) && 3758 (previewCh != NULL) && previewCh->isActive()) { 3759 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK); 3760 if (rc != NO_ERROR) { 3761 LOGE("START Callback Channel failed"); 3762 } 3763 } 3764 } 3765 } 3766 mMsgEnabled |= msg_type; 3767 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc); 3768 return rc; 3769 } 3770 3771 /*=========================================================================== 3772 * FUNCTION : disableMsgType 3773 * 3774 * DESCRIPTION: disable msg type impl 3775 * 3776 * PARAMETERS : 3777 * @msg_type : msg type mask to be disabled 3778 * 3779 * RETURN : int32_t type of status 3780 * NO_ERROR -- success 3781 * none-zero failure code 3782 *==========================================================================*/ 3783 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type) 3784 { 3785 int32_t rc = NO_ERROR; 3786 3787 if (mParameters.isUBWCEnabled()) { 3788 /*STOP CALLBACK STREAM*/ 3789 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) && 3790 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) { 3791 // Stop callback channel only if it is active 3792 if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) && 3793 (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) { 3794 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK); 3795 if (rc != NO_ERROR) { 3796 LOGE("STOP Callback Channel failed"); 3797 } 3798 } 3799 } 3800 } 3801 mMsgEnabled &= ~msg_type; 3802 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc); 3803 return rc; 3804 } 3805 3806 /*=========================================================================== 3807 * FUNCTION : msgTypeEnabled 3808 * 3809 * DESCRIPTION: impl to determine if certain msg_type is enabled 3810 * 3811 * PARAMETERS : 3812 * @msg_type : msg type mask 3813 * 3814 * RETURN : 0 -- not enabled 3815 * none 0 -- enabled 3816 *==========================================================================*/ 3817 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type) 3818 { 3819 return (mMsgEnabled & msg_type); 3820 } 3821 3822 /*=========================================================================== 3823 * FUNCTION : msgTypeEnabledWithLock 3824 * 3825 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock 3826 * 3827 * PARAMETERS : 3828 * @msg_type : msg type mask 3829 * 3830 * RETURN : 0 -- not enabled 3831 * none 0 -- enabled 3832 *==========================================================================*/ 3833 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type) 3834 { 3835 int enabled = 0; 3836 lockAPI(); 3837 enabled = mMsgEnabled & msg_type; 3838 unlockAPI(); 3839 return enabled; 3840 } 3841 3842 /*=========================================================================== 3843 * FUNCTION : startPreview 3844 * 3845 * DESCRIPTION: start preview impl 3846 * 3847 * PARAMETERS : none 3848 * 3849 * RETURN : int32_t type of status 3850 * NO_ERROR -- success 3851 * none-zero failure code 3852 *==========================================================================*/ 3853 int QCamera2HardwareInterface::startPreview() 3854 { 3855 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW); 3856 int32_t rc = NO_ERROR; 3857 3858 LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(), 3859 mParameters.getRecordingHintValue()); 3860 3861 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW); 3862 3863 updateThermalLevel((void *)&mThermalLevel); 3864 3865 setDisplayFrameSkip(); 3866 3867 // start preview stream 3868 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 3869 rc = startChannel(QCAMERA_CH_TYPE_ZSL); 3870 } else if (isSecureMode()) { 3871 if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) { 3872 rc = startChannel(QCAMERA_CH_TYPE_RAW); 3873 }else { 3874 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW); 3875 } 3876 } else { 3877 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW); 3878 } 3879 3880 if (isDualCamera()) { 3881 if (rc == NO_ERROR) { 3882 mParameters.setDeferCamera(CAM_DEFER_PROCESS); 3883 } else { 3884 mParameters.setDeferCamera(CAM_DEFER_FLUSH); 3885 } 3886 } 3887 3888 if (rc != NO_ERROR) { 3889 LOGE("failed to start channels"); 3890 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW); 3891 return rc; 3892 } 3893 3894 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) 3895 && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) { 3896 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK); 3897 if (rc != NO_ERROR) { 3898 LOGE("failed to start callback stream"); 3899 stopChannel(QCAMERA_CH_TYPE_ZSL); 3900 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3901 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW); 3902 return rc; 3903 } 3904 } 3905 3906 updatePostPreviewParameters(); 3907 m_stateMachine.setPreviewCallbackNeeded(true); 3908 3909 // if job id is non-zero, that means the postproc init job is already 3910 // pending or complete 3911 if (mInitPProcJob == 0) { 3912 mInitPProcJob = deferPPInit(); 3913 if (mInitPProcJob == 0) { 3914 LOGE("Unable to initialize postprocessor, mCameraHandle = %p", 3915 mCameraHandle); 3916 rc = -ENOMEM; 3917 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW); 3918 return rc; 3919 } 3920 } 3921 3922 LOGI("X rc = %d", rc); 3923 return rc; 3924 } 3925 3926 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() { 3927 // Enable OIS only in Camera mode and 4k2k camcoder mode 3928 int32_t rc = NO_ERROR; 3929 rc = mParameters.updateOisValue(1); 3930 return NO_ERROR; 3931 } 3932 3933 /*=========================================================================== 3934 * FUNCTION : stopPreview 3935 * 3936 * DESCRIPTION: stop preview impl 3937 * 3938 * PARAMETERS : none 3939 * 3940 * RETURN : int32_t type of status 3941 * NO_ERROR -- success 3942 * none-zero failure code 3943 *==========================================================================*/ 3944 int QCamera2HardwareInterface::stopPreview() 3945 { 3946 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOPPREVIEW); 3947 LOGI("E"); 3948 mNumPreviewFaces = -1; 3949 mActiveAF = false; 3950 3951 // Disable power Hint for preview 3952 m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW); 3953 3954 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW); 3955 3956 // stop preview stream 3957 stopChannel(QCAMERA_CH_TYPE_CALLBACK); 3958 stopChannel(QCAMERA_CH_TYPE_ZSL); 3959 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3960 stopChannel(QCAMERA_CH_TYPE_RAW); 3961 3962 m_cbNotifier.flushPreviewNotifications(); 3963 //add for ts makeup 3964 #ifdef TARGET_TS_MAKEUP 3965 ts_makeup_finish(); 3966 #endif 3967 // delete all channels from preparePreview 3968 unpreparePreview(); 3969 3970 m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_PREVIEW); 3971 LOGI("X"); 3972 return NO_ERROR; 3973 } 3974 3975 /*=========================================================================== 3976 * FUNCTION : storeMetaDataInBuffers 3977 * 3978 * DESCRIPTION: enable store meta data in buffers for video frames impl 3979 * 3980 * PARAMETERS : 3981 * @enable : flag if need enable 3982 * 3983 * RETURN : int32_t type of status 3984 * NO_ERROR -- success 3985 * none-zero failure code 3986 *==========================================================================*/ 3987 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable) 3988 { 3989 mStoreMetaDataInFrame = enable; 3990 return NO_ERROR; 3991 } 3992 3993 /*=========================================================================== 3994 * FUNCTION : preStartRecording 3995 * 3996 * DESCRIPTION: Prepare start recording impl 3997 * 3998 * PARAMETERS : none 3999 * 4000 * RETURN : int32_t type of status 4001 * NO_ERROR -- success 4002 * none-zero failure code 4003 *==========================================================================*/ 4004 int QCamera2HardwareInterface::preStartRecording() 4005 { 4006 int32_t rc = NO_ERROR; 4007 LOGH("E"); 4008 if (mParameters.getRecordingHintValue() == false) { 4009 4010 // Give HWI control to restart preview only in single camera mode. 4011 // In dual-cam mode, this control belongs to muxer. 4012 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 4013 LOGH("start recording when hint is false, stop preview first"); 4014 stopPreview(); 4015 4016 // Set recording hint to TRUE 4017 mParameters.updateRecordingHintValue(TRUE); 4018 rc = preparePreview(); 4019 if (rc == NO_ERROR) { 4020 rc = startPreview(); 4021 } 4022 } 4023 else 4024 { 4025 // For dual cam mode, update the flag mPreviewRestartNeeded to true 4026 // Restart control will be handled by muxer. 4027 mPreviewRestartNeeded = true; 4028 } 4029 } 4030 4031 LOGH("X rc = %d", rc); 4032 return rc; 4033 } 4034 4035 /*=========================================================================== 4036 * FUNCTION : startRecording 4037 * 4038 * DESCRIPTION: start recording impl 4039 * 4040 * PARAMETERS : none 4041 * 4042 * RETURN : int32_t type of status 4043 * NO_ERROR -- success 4044 * none-zero failure code 4045 *==========================================================================*/ 4046 int QCamera2HardwareInterface::startRecording() 4047 { 4048 int32_t rc = NO_ERROR; 4049 4050 LOGI("E"); 4051 4052 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING); 4053 4054 //link meta stream with video channel if low power mode. 4055 if (isLowPowerMode()) { 4056 // Find and try to link a metadata stream from preview channel 4057 QCameraChannel *pMetaChannel = NULL; 4058 QCameraStream *pMetaStream = NULL; 4059 QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO]; 4060 4061 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 4062 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 4063 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 4064 QCameraStream *pStream = NULL; 4065 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 4066 pStream = pMetaChannel->getStreamByIndex(i); 4067 if ((NULL != pStream) && 4068 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) { 4069 pMetaStream = pStream; 4070 break; 4071 } 4072 } 4073 } 4074 4075 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 4076 rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream); 4077 if (NO_ERROR != rc) { 4078 LOGW("Metadata stream link failed %d", rc); 4079 } 4080 } 4081 } 4082 4083 if (rc == NO_ERROR) { 4084 rc = startChannel(QCAMERA_CH_TYPE_VIDEO); 4085 } 4086 4087 if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) { 4088 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 4089 if (!mParameters.is4k2kVideoResolution()) { 4090 // Find and try to link a metadata stream from preview channel 4091 QCameraChannel *pMetaChannel = NULL; 4092 QCameraStream *pMetaStream = NULL; 4093 4094 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 4095 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 4096 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 4097 QCameraStream *pStream = NULL; 4098 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 4099 pStream = pMetaChannel->getStreamByIndex(i); 4100 if ((NULL != pStream) && 4101 (CAM_STREAM_TYPE_METADATA == 4102 pStream->getMyType())) { 4103 pMetaStream = pStream; 4104 break; 4105 } 4106 } 4107 } 4108 4109 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 4110 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 4111 if (NO_ERROR != rc) { 4112 LOGW("Metadata stream link failed %d", rc); 4113 } 4114 } 4115 } 4116 LOGH("START snapshot Channel for TNR processing"); 4117 rc = pChannel->start(); 4118 } 4119 4120 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING); 4121 4122 if (rc == NO_ERROR) { 4123 // Set power Hint for video encoding 4124 m_perfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0); 4125 } 4126 4127 LOGI("X rc = %d", rc); 4128 return rc; 4129 } 4130 4131 /*=========================================================================== 4132 * FUNCTION : stopRecording 4133 * 4134 * DESCRIPTION: stop recording impl 4135 * 4136 * PARAMETERS : none 4137 * 4138 * RETURN : int32_t type of status 4139 * NO_ERROR -- success 4140 * none-zero failure code 4141 *==========================================================================*/ 4142 int QCamera2HardwareInterface::stopRecording() 4143 { 4144 LOGI("E"); 4145 4146 // Disable power hint for video encoding 4147 m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE); 4148 4149 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING); 4150 4151 // stop snapshot channel 4152 if (mParameters.isTNRSnapshotEnabled()) { 4153 LOGH("STOP snapshot Channel for TNR processing"); 4154 stopChannel(QCAMERA_CH_TYPE_SNAPSHOT); 4155 } 4156 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO); 4157 4158 m_cbNotifier.flushVideoNotifications(); 4159 4160 m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_RECORDING); 4161 4162 LOGI("X rc = %d", rc); 4163 return rc; 4164 } 4165 4166 /*=========================================================================== 4167 * FUNCTION : releaseRecordingFrame 4168 * 4169 * DESCRIPTION: return video frame impl 4170 * 4171 * PARAMETERS : 4172 * @opaque : ptr to video frame to be returned 4173 * 4174 * RETURN : int32_t type of status 4175 * NO_ERROR -- success 4176 * none-zero failure code 4177 *==========================================================================*/ 4178 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque) 4179 { 4180 int32_t rc = UNKNOWN_ERROR; 4181 QCameraVideoChannel *pChannel = 4182 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO]; 4183 LOGD("opaque data = %p",opaque); 4184 4185 if(pChannel != NULL) { 4186 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0); 4187 } 4188 return rc; 4189 } 4190 4191 /*=========================================================================== 4192 * FUNCTION : autoFocus 4193 * 4194 * DESCRIPTION: start auto focus impl 4195 * 4196 * PARAMETERS : none 4197 * 4198 * RETURN : int32_t type of status 4199 * NO_ERROR -- success 4200 * none-zero failure code 4201 *==========================================================================*/ 4202 int QCamera2HardwareInterface::autoFocus() 4203 { 4204 int rc = NO_ERROR; 4205 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 4206 LOGH("E"); 4207 4208 switch (focusMode) { 4209 case CAM_FOCUS_MODE_AUTO: 4210 case CAM_FOCUS_MODE_MACRO: 4211 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 4212 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 4213 mActiveAF = true; 4214 LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d", 4215 focusMode, m_currentFocusState); 4216 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle); 4217 break; 4218 case CAM_FOCUS_MODE_INFINITY: 4219 case CAM_FOCUS_MODE_FIXED: 4220 case CAM_FOCUS_MODE_EDOF: 4221 default: 4222 LOGI("No ops in focusMode (%d)", focusMode); 4223 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 4224 break; 4225 } 4226 4227 if (NO_ERROR != rc) { 4228 mActiveAF = false; 4229 } 4230 LOGH("X rc = %d", rc); 4231 return rc; 4232 } 4233 4234 /*=========================================================================== 4235 * FUNCTION : cancelAutoFocus 4236 * 4237 * DESCRIPTION: cancel auto focus impl 4238 * 4239 * PARAMETERS : none 4240 * 4241 * RETURN : int32_t type of status 4242 * NO_ERROR -- success 4243 * none-zero failure code 4244 *==========================================================================*/ 4245 int QCamera2HardwareInterface::cancelAutoFocus() 4246 { 4247 int rc = NO_ERROR; 4248 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 4249 4250 switch (focusMode) { 4251 case CAM_FOCUS_MODE_AUTO: 4252 case CAM_FOCUS_MODE_MACRO: 4253 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 4254 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 4255 mActiveAF = false; 4256 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle); 4257 break; 4258 case CAM_FOCUS_MODE_INFINITY: 4259 case CAM_FOCUS_MODE_FIXED: 4260 case CAM_FOCUS_MODE_EDOF: 4261 default: 4262 LOGD("No ops in focusMode (%d)", focusMode); 4263 break; 4264 } 4265 return rc; 4266 } 4267 4268 /*=========================================================================== 4269 * FUNCTION : processUFDumps 4270 * 4271 * DESCRIPTION: process UF jpeg dumps for refocus support 4272 * 4273 * PARAMETERS : 4274 * @evt : payload of jpeg event, including information about jpeg encoding 4275 * status, jpeg size and so on. 4276 * 4277 * RETURN : int32_t type of status 4278 * NO_ERROR -- success 4279 * none-zero failure code 4280 * 4281 * NOTE : none 4282 *==========================================================================*/ 4283 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt) 4284 { 4285 bool ret = true; 4286 if (mParameters.isUbiRefocus()) { 4287 int index = (int)getOutputImageCount(); 4288 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1)); 4289 char name[FILENAME_MAX]; 4290 4291 camera_memory_t *jpeg_mem = NULL; 4292 omx_jpeg_ouput_buf_t *jpeg_out = NULL; 4293 size_t dataLen; 4294 uint8_t *dataPtr; 4295 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 4296 LOGE("Init PProc Deferred work failed"); 4297 return false; 4298 } 4299 if (!m_postprocessor.getJpegMemOpt()) { 4300 dataLen = evt->out_data.buf_filled_len; 4301 dataPtr = evt->out_data.buf_vaddr; 4302 } else { 4303 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr; 4304 if (!jpeg_out) { 4305 LOGE("Null pointer detected"); 4306 return false; 4307 } 4308 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl; 4309 if (!jpeg_mem) { 4310 LOGE("Null pointer detected"); 4311 return false; 4312 } 4313 dataPtr = (uint8_t *)jpeg_mem->data; 4314 dataLen = jpeg_mem->size; 4315 } 4316 4317 if (allFocusImage) { 4318 snprintf(name, sizeof(name), "AllFocusImage"); 4319 index = -1; 4320 } else { 4321 snprintf(name, sizeof(name), "%d", 0); 4322 } 4323 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg", 4324 dataPtr, dataLen); 4325 LOGD("Dump the image %d %d allFocusImage %d", 4326 getOutputImageCount(), index, allFocusImage); 4327 setOutputImageCount(getOutputImageCount() + 1); 4328 if (!allFocusImage) { 4329 ret = false; 4330 } 4331 } 4332 return ret; 4333 } 4334 4335 /*=========================================================================== 4336 * FUNCTION : unconfigureAdvancedCapture 4337 * 4338 * DESCRIPTION: unconfigure Advanced Capture. 4339 * 4340 * PARAMETERS : none 4341 * 4342 * RETURN : int32_t type of status 4343 * NO_ERROR -- success 4344 * none-zero failure code 4345 *==========================================================================*/ 4346 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture() 4347 { 4348 int32_t rc = NO_ERROR; 4349 4350 /*Disable Quadra CFA mode*/ 4351 LOGH("Disabling Quadra CFA mode"); 4352 mParameters.setQuadraCfaMode(false, true); 4353 4354 if (mAdvancedCaptureConfigured) { 4355 4356 mAdvancedCaptureConfigured = false; 4357 4358 if(mIs3ALocked) { 4359 mParameters.set3ALock(false); 4360 mIs3ALocked = false; 4361 } 4362 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) { 4363 rc = mParameters.setToneMapMode(true, true); 4364 if (rc != NO_ERROR) { 4365 LOGW("Failed to enable tone map during HDR/AEBracketing"); 4366 } 4367 mHDRBracketingEnabled = false; 4368 rc = mParameters.stopAEBracket(); 4369 } else if ((mParameters.isChromaFlashEnabled()) 4370 || (mFlashConfigured && !mLongshotEnabled) 4371 || (mLowLightConfigured == true) 4372 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4373 rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured); 4374 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4375 rc = configureAFBracketing(false); 4376 } else if (mParameters.isOptiZoomEnabled()) { 4377 rc = mParameters.setAndCommitZoom(mZoomLevel); 4378 setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY); 4379 } else if (mParameters.isStillMoreEnabled()) { 4380 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 4381 stillmore_config.burst_count = 0; 4382 mParameters.setStillMoreSettings(stillmore_config); 4383 4384 /* If SeeMore is running, it will handle re-enabling tone map */ 4385 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) { 4386 rc = mParameters.setToneMapMode(true, true); 4387 if (rc != NO_ERROR) { 4388 LOGW("Failed to enable tone map during StillMore"); 4389 } 4390 } 4391 4392 /* Re-enable Tintless */ 4393 mParameters.setTintless(true); 4394 } else { 4395 LOGW("No Advanced Capture feature enabled!!"); 4396 rc = BAD_VALUE; 4397 } 4398 } 4399 4400 return rc; 4401 } 4402 4403 /*=========================================================================== 4404 * FUNCTION : configureAdvancedCapture 4405 * 4406 * DESCRIPTION: configure Advanced Capture. 4407 * 4408 * PARAMETERS : none 4409 * 4410 * RETURN : int32_t type of status 4411 * NO_ERROR -- success 4412 * none-zero failure code 4413 *==========================================================================*/ 4414 int32_t QCamera2HardwareInterface::configureAdvancedCapture() 4415 { 4416 LOGH("E"); 4417 int32_t rc = NO_ERROR; 4418 4419 rc = mParameters.checkFeatureConcurrency(); 4420 if (rc != NO_ERROR) { 4421 LOGE("Cannot support Advanced capture modes"); 4422 return rc; 4423 } 4424 /*Enable Quadra CFA mode*/ 4425 LOGH("Enabling Quadra CFA mode"); 4426 mParameters.setQuadraCfaMode(true, true); 4427 4428 setOutputImageCount(0); 4429 mInputCount = 0; 4430 mAdvancedCaptureConfigured = true; 4431 /* Display should be disabled for advanced modes */ 4432 bool bSkipDisplay = true; 4433 4434 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) { 4435 // no Advance capture settings for Aux camera 4436 LOGH("X Secondary Camera, no need to process!! "); 4437 return rc; 4438 } 4439 4440 /* Do not stop display if in stillmore livesnapshot */ 4441 if (mParameters.isStillMoreEnabled() && 4442 mParameters.isSeeMoreEnabled()) { 4443 bSkipDisplay = false; 4444 } 4445 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4446 rc = configureAFBracketing(); 4447 } else if (mParameters.isOptiZoomEnabled()) { 4448 rc = configureOptiZoom(); 4449 } else if(mParameters.isHDREnabled()) { 4450 rc = configureHDRBracketing(); 4451 if (mHDRBracketingEnabled) { 4452 rc = mParameters.setToneMapMode(false, true); 4453 if (rc != NO_ERROR) { 4454 LOGW("Failed to disable tone map during HDR"); 4455 } 4456 } 4457 } else if (mParameters.isAEBracketEnabled()) { 4458 rc = mParameters.setToneMapMode(false, true); 4459 if (rc != NO_ERROR) { 4460 LOGW("Failed to disable tone map during AEBracketing"); 4461 } 4462 rc = configureAEBracketing(); 4463 } else if (mParameters.isStillMoreEnabled()) { 4464 bSkipDisplay = false; 4465 rc = configureStillMore(); 4466 } else if ((mParameters.isChromaFlashEnabled()) 4467 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) 4468 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4469 rc = mParameters.configFrameCapture(TRUE); 4470 if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) { 4471 mLowLightConfigured = true; 4472 } 4473 } else if (mFlashNeeded && !mLongshotEnabled) { 4474 rc = mParameters.configFrameCapture(TRUE); 4475 mFlashConfigured = true; 4476 bSkipDisplay = false; 4477 } else { 4478 LOGH("Advanced Capture feature not enabled!! "); 4479 mAdvancedCaptureConfigured = false; 4480 bSkipDisplay = false; 4481 } 4482 4483 if (m_postprocessor.isHalPPEnabled()) { 4484 LOGH("HALPP is enabled, check if halpp is needed for current snapshot."); 4485 configureHalPostProcess(); 4486 } 4487 4488 LOGH("Stop preview temporarily for advanced captures"); 4489 setDisplaySkip(bSkipDisplay); 4490 4491 LOGH("X rc = %d", rc); 4492 return rc; 4493 } 4494 4495 /*=========================================================================== 4496 * FUNCTION : configureAFBracketing 4497 * 4498 * DESCRIPTION: configure AF Bracketing. 4499 * 4500 * PARAMETERS : none 4501 * 4502 * RETURN : int32_t type of status 4503 * NO_ERROR -- success 4504 * none-zero failure code 4505 *==========================================================================*/ 4506 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable) 4507 { 4508 LOGH("E"); 4509 int32_t rc = NO_ERROR; 4510 cam_af_bracketing_t *af_bracketing_need; 4511 4512 if (mParameters.isUbiRefocus()) { 4513 af_bracketing_need = 4514 &gCamCapability[mCameraId]->refocus_af_bracketing_need; 4515 } else { 4516 af_bracketing_need = 4517 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need; 4518 } 4519 4520 //Enable AF Bracketing. 4521 cam_af_bracketing_t afBracket; 4522 memset(&afBracket, 0, sizeof(cam_af_bracketing_t)); 4523 afBracket.enable = enable; 4524 afBracket.burst_count = af_bracketing_need->burst_count; 4525 4526 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) { 4527 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i]; 4528 LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]); 4529 } 4530 //Send cmd to backend to set AF Bracketing for Ubi Focus. 4531 rc = mParameters.commitAFBracket(afBracket); 4532 if ( NO_ERROR != rc ) { 4533 LOGE("cannot configure AF bracketing"); 4534 return rc; 4535 } 4536 if (enable) { 4537 mParameters.set3ALock(true); 4538 mIs3ALocked = true; 4539 } 4540 LOGH("X rc = %d", rc); 4541 return rc; 4542 } 4543 4544 /*=========================================================================== 4545 * FUNCTION : configureHDRBracketing 4546 * 4547 * DESCRIPTION: configure HDR Bracketing. 4548 * 4549 * PARAMETERS : none 4550 * 4551 * RETURN : int32_t type of status 4552 * NO_ERROR -- success 4553 * none-zero failure code 4554 *==========================================================================*/ 4555 int32_t QCamera2HardwareInterface::configureHDRBracketing() 4556 { 4557 LOGH("E"); 4558 int32_t rc = NO_ERROR; 4559 4560 cam_hdr_bracketing_info_t& hdrBracketingSetting = 4561 gCamCapability[mCameraId]->hdr_bracketing_setting; 4562 4563 // 'values' should be in "idx1,idx2,idx3,..." format 4564 uint32_t hdrFrameCount = 4565 hdrBracketingSetting.num_frames; 4566 LOGH("HDR values %d, %d frame count: %u", 4567 (int8_t) hdrBracketingSetting.exp_val.values[0], 4568 (int8_t) hdrBracketingSetting.exp_val.values[1], 4569 hdrFrameCount); 4570 4571 // Enable AE Bracketing for HDR 4572 cam_exp_bracketing_t aeBracket; 4573 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t)); 4574 aeBracket.mode = 4575 hdrBracketingSetting.exp_val.mode; 4576 4577 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) { 4578 mHDRBracketingEnabled = true; 4579 } 4580 4581 String8 tmp; 4582 for (uint32_t i = 0; i < hdrFrameCount; i++) { 4583 tmp.appendFormat("%d", 4584 (int8_t) hdrBracketingSetting.exp_val.values[i]); 4585 tmp.append(","); 4586 } 4587 if (mParameters.isHDR1xFrameEnabled() 4588 && mParameters.isHDR1xExtraBufferNeeded()) { 4589 tmp.appendFormat("%d", 0); 4590 tmp.append(","); 4591 } 4592 4593 if( !tmp.isEmpty() && 4594 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) { 4595 //Trim last comma 4596 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH); 4597 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1); 4598 } 4599 4600 LOGH("HDR config values %s", 4601 aeBracket.values); 4602 rc = mParameters.setHDRAEBracket(aeBracket); 4603 if ( NO_ERROR != rc ) { 4604 LOGE("cannot configure HDR bracketing"); 4605 return rc; 4606 } 4607 LOGH("X rc = %d", rc); 4608 return rc; 4609 } 4610 4611 /*=========================================================================== 4612 * FUNCTION : configureAEBracketing 4613 * 4614 * DESCRIPTION: configure AE Bracketing. 4615 * 4616 * PARAMETERS : none 4617 * 4618 * RETURN : int32_t type of status 4619 * NO_ERROR -- success 4620 * none-zero failure code 4621 *==========================================================================*/ 4622 int32_t QCamera2HardwareInterface::configureAEBracketing() 4623 { 4624 LOGH("E"); 4625 int32_t rc = NO_ERROR; 4626 4627 rc = mParameters.setAEBracketing(); 4628 if ( NO_ERROR != rc ) { 4629 LOGE("cannot configure AE bracketing"); 4630 return rc; 4631 } 4632 LOGH("X rc = %d", rc); 4633 return rc; 4634 } 4635 4636 /*=========================================================================== 4637 * FUNCTION : configureOptiZoom 4638 * 4639 * DESCRIPTION: configure Opti Zoom. 4640 * 4641 * PARAMETERS : none 4642 * 4643 * RETURN : int32_t type of status 4644 * NO_ERROR -- success 4645 * none-zero failure code 4646 *==========================================================================*/ 4647 int32_t QCamera2HardwareInterface::configureOptiZoom() 4648 { 4649 int32_t rc = NO_ERROR; 4650 4651 //store current zoom level. 4652 mZoomLevel = mParameters.getParmZoomLevel(); 4653 4654 //set zoom level to 1x; 4655 mParameters.setAndCommitZoom(0); 4656 4657 mParameters.set3ALock(true); 4658 mIs3ALocked = true; 4659 4660 return rc; 4661 } 4662 4663 /*=========================================================================== 4664 * FUNCTION : configureStillMore 4665 * 4666 * DESCRIPTION: configure StillMore. 4667 * 4668 * PARAMETERS : none 4669 * 4670 * RETURN : int32_t type of status 4671 * NO_ERROR -- success 4672 * none-zero failure code 4673 *==========================================================================*/ 4674 int32_t QCamera2HardwareInterface::configureStillMore() 4675 { 4676 int32_t rc = NO_ERROR; 4677 uint8_t burst_cnt = 0; 4678 cam_still_more_t stillmore_config; 4679 cam_still_more_t stillmore_cap; 4680 4681 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */ 4682 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) { 4683 rc = mParameters.setToneMapMode(false, true); 4684 if (rc != NO_ERROR) { 4685 LOGW("Failed to disable tone map during StillMore"); 4686 } 4687 } 4688 4689 /* Lock 3A */ 4690 mParameters.set3ALock(true); 4691 mIs3ALocked = true; 4692 4693 /* Disable Tintless */ 4694 mParameters.setTintless(false); 4695 4696 /* Initialize burst count from capability */ 4697 stillmore_cap = mParameters.getStillMoreCapability(); 4698 burst_cnt = stillmore_cap.max_burst_count; 4699 4700 /* Reconfigure burst count from dynamic scene data */ 4701 cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData(); 4702 if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count && 4703 dynamic_img_data.input_count <= stillmore_cap.max_burst_count) { 4704 burst_cnt = dynamic_img_data.input_count; 4705 } 4706 4707 /* Reconfigure burst count in the case of liveshot */ 4708 if (mParameters.isSeeMoreEnabled()) { 4709 burst_cnt = 1; 4710 } 4711 4712 /* Reconfigure burst count from user input */ 4713 char prop[PROPERTY_VALUE_MAX]; 4714 property_get("persist.camera.imglib.stillmore", prop, "0"); 4715 uint8_t burst_setprop = (uint32_t)atoi(prop); 4716 if (burst_setprop != 0) { 4717 if ((burst_setprop < stillmore_cap.min_burst_count) || 4718 (burst_setprop > stillmore_cap.max_burst_count)) { 4719 burst_cnt = stillmore_cap.max_burst_count; 4720 } else { 4721 burst_cnt = burst_setprop; 4722 } 4723 } 4724 4725 memset(&stillmore_config, 0, sizeof(cam_still_more_t)); 4726 stillmore_config.burst_count = burst_cnt; 4727 mParameters.setStillMoreSettings(stillmore_config); 4728 4729 LOGH("Stillmore burst %d", burst_cnt); 4730 4731 return rc; 4732 } 4733 4734 /*=========================================================================== 4735 * FUNCTION : configureHalPostProcess 4736 * 4737 * DESCRIPTION: config hal postproc (HALPP) for current snapshot. 4738 * 4739 * PARAMETERS : none 4740 * 4741 * RETURN : int32_t type of status 4742 * NO_ERROR -- success 4743 * none-zero failure code 4744 *==========================================================================*/ 4745 int32_t QCamera2HardwareInterface::configureHalPostProcess() 4746 { 4747 LOGD("E"); 4748 int32_t rc = NO_ERROR; 4749 4750 if (!m_postprocessor.isHalPPEnabled()) { 4751 m_bNeedHalPP = FALSE; 4752 return rc; 4753 } 4754 4755 /* check if halpp is needed in dual camera mode */ 4756 if (isDualCamera()) { 4757 if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot == TRUE) { 4758 LOGH("Use HALPP for dual camera bundle snapshot."); 4759 m_bNeedHalPP = TRUE; 4760 } 4761 return rc; 4762 } 4763 4764 return rc; 4765 LOGD("X"); 4766 } 4767 4768 4769 /*=========================================================================== 4770 * FUNCTION : stopAdvancedCapture 4771 * 4772 * DESCRIPTION: stops advanced capture based on capture type 4773 * 4774 * PARAMETERS : 4775 * @pChannel : channel. 4776 * 4777 * RETURN : int32_t type of status 4778 * NO_ERROR -- success 4779 * none-zero failure code 4780 *==========================================================================*/ 4781 int32_t QCamera2HardwareInterface::stopAdvancedCapture( 4782 QCameraPicChannel *pChannel) 4783 { 4784 LOGH("stop bracketig"); 4785 int32_t rc = NO_ERROR; 4786 4787 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4788 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING); 4789 } else if (mParameters.isChromaFlashEnabled() 4790 || (mFlashConfigured && !mLongshotEnabled) 4791 || (mLowLightConfigured == true) 4792 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4793 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE); 4794 mFlashConfigured = false; 4795 mLowLightConfigured = false; 4796 } else if(mParameters.isHDREnabled() 4797 || mParameters.isAEBracketEnabled()) { 4798 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING); 4799 } else if (mParameters.isOptiZoomEnabled()) { 4800 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X); 4801 } else if (mParameters.isStillMoreEnabled()) { 4802 LOGH("stopAdvancedCapture not needed for StillMore"); 4803 } else { 4804 LOGH("No Advanced Capture feature enabled!"); 4805 rc = BAD_VALUE; 4806 } 4807 4808 m_bNeedHalPP = FALSE; 4809 return rc; 4810 } 4811 4812 /*=========================================================================== 4813 * FUNCTION : startAdvancedCapture 4814 * 4815 * DESCRIPTION: starts advanced capture based on capture type 4816 * 4817 * PARAMETERS : 4818 * @pChannel : channel. 4819 * 4820 * RETURN : int32_t type of status 4821 * NO_ERROR -- success 4822 * none-zero failure code 4823 *==========================================================================*/ 4824 int32_t QCamera2HardwareInterface::startAdvancedCapture( 4825 QCameraPicChannel *pChannel) 4826 { 4827 LOGH("Start bracketing"); 4828 int32_t rc = NO_ERROR; 4829 4830 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4831 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING); 4832 } else if (mParameters.isOptiZoomEnabled()) { 4833 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X); 4834 } else if (mParameters.isStillMoreEnabled()) { 4835 LOGH("startAdvancedCapture not needed for StillMore"); 4836 } else if (mParameters.isHDREnabled() 4837 || mParameters.isAEBracketEnabled()) { 4838 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING); 4839 } else if (mParameters.isChromaFlashEnabled() 4840 || (mFlashNeeded && !mLongshotEnabled) 4841 || (mLowLightConfigured == true) 4842 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4843 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig(); 4844 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config); 4845 } else { 4846 LOGE("No Advanced Capture feature enabled!"); 4847 rc = BAD_VALUE; 4848 } 4849 return rc; 4850 } 4851 4852 /*=========================================================================== 4853 * FUNCTION : preTakePicture 4854 * 4855 * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary 4856 * 4857 * PARAMETERS : none 4858 * 4859 * RETURN : int32_t type of status 4860 * NO_ERROR -- success 4861 * none-zero failure code 4862 *==========================================================================*/ 4863 int QCamera2HardwareInterface::preTakePicture() 4864 { 4865 int32_t rc = NO_ERROR; 4866 LOGH("E"); 4867 if (mParameters.getRecordingHintValue() == true) { 4868 4869 // Give HWI control to restart preview only in single camera mode. 4870 // In dual-cam mode, this control belongs to muxer. 4871 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 4872 LOGH("restart preview if rec hint is true and preview is running"); 4873 stopPreview(); 4874 mParameters.updateRecordingHintValue(FALSE); 4875 // start preview again 4876 rc = preparePreview(); 4877 if (rc == NO_ERROR) { 4878 rc = startPreview(); 4879 if (rc != NO_ERROR) { 4880 unpreparePreview(); 4881 } 4882 } 4883 } 4884 else 4885 { 4886 // For dual cam mode, update the flag mPreviewRestartNeeded to true 4887 // Restart control will be handled by muxer. 4888 mPreviewRestartNeeded = true; 4889 } 4890 } 4891 4892 LOGH("X rc = %d", rc); 4893 return rc; 4894 } 4895 4896 /*=========================================================================== 4897 * FUNCTION : takePicture 4898 * 4899 * DESCRIPTION: take picture impl 4900 * 4901 * PARAMETERS : none 4902 * 4903 * RETURN : int32_t type of status 4904 * NO_ERROR -- success 4905 * none-zero failure code 4906 *==========================================================================*/ 4907 int QCamera2HardwareInterface::takePicture() 4908 { 4909 int rc = NO_ERROR; 4910 4911 // Get total number for snapshots (retro + regular) 4912 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 4913 // Get number of retro-active snapshots 4914 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots(); 4915 LOGH("E"); 4916 4917 //Set rotation value from user settings as Jpeg rotation 4918 //to configure back-end modules. 4919 mParameters.setJpegRotation(mParameters.getRotation()); 4920 4921 // Check if retro-active snapshots are not enabled 4922 if (!isRetroPicture() || !mParameters.isZSLMode()) { 4923 numRetroSnapshots = 0; 4924 LOGH("Reset retro snaphot count to zero"); 4925 } 4926 4927 //Do special configure for advanced capture modes. 4928 rc = configureAdvancedCapture(); 4929 if (rc != NO_ERROR) { 4930 LOGE("Unsupported capture call"); 4931 return rc; 4932 } 4933 4934 if (mAdvancedCaptureConfigured) { 4935 numSnapshots = mParameters.getBurstCountForAdvancedCapture(); 4936 } 4937 4938 if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot) { 4939 char prop[PROPERTY_VALUE_MAX]; 4940 memset(prop, 0, sizeof(prop)); 4941 property_get("persist.camera.dualfov.jpegnum", prop, "1"); 4942 int dualfov_snap_num = atoi(prop); 4943 4944 memset(prop, 0, sizeof(prop)); 4945 property_get("persist.camera.halpp", prop, "0"); 4946 int halpp_enabled = atoi(prop); 4947 if(halpp_enabled == 0) { 4948 dualfov_snap_num = MM_CAMERA_MAX_CAM_CNT; 4949 } 4950 4951 dualfov_snap_num = (dualfov_snap_num == 0) ? 1 : dualfov_snap_num; 4952 LOGD("dualfov_snap_num:%d", dualfov_snap_num); 4953 numSnapshots /= dualfov_snap_num; 4954 } 4955 4956 LOGI("snap count = %d zsl = %d advanced = %d, active camera:%d", 4957 numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured, mActiveCameras); 4958 4959 if (mParameters.isZSLMode()) { 4960 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 4961 QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel; 4962 if (NULL != pPicChannel) { 4963 4964 if (mParameters.getofflineRAW()) { 4965 startRAWChannel(pPicChannel); 4966 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW]; 4967 if (pPicChannel == NULL) { 4968 LOGE("RAW Channel is NULL in Manual capture mode"); 4969 stopRAWChannel(); 4970 return UNKNOWN_ERROR; 4971 } 4972 } 4973 4974 rc = configureOnlineRotation(*pPicChannel); 4975 if (rc != NO_ERROR) { 4976 LOGE("online rotation failed"); 4977 return rc; 4978 } 4979 4980 // start postprocessor 4981 DeferWorkArgs args; 4982 memset(&args, 0, sizeof(DeferWorkArgs)); 4983 4984 args.pprocArgs = pPicChannel; 4985 4986 // No need to wait for mInitPProcJob here, because it was 4987 // queued in startPreview, and will definitely be processed before 4988 // mReprocJob can begin. 4989 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 4990 args); 4991 if (mReprocJob == 0) { 4992 LOGE("Failure: Unable to start pproc"); 4993 return -ENOMEM; 4994 } 4995 4996 // Check if all preview buffers are mapped before creating 4997 // a jpeg session as preview stream buffers are queried during the same 4998 uint8_t numStreams = pChannel->getNumOfStreams(); 4999 QCameraStream *pStream = NULL; 5000 QCameraStream *pPreviewStream = NULL; 5001 for (uint8_t i = 0 ; i < numStreams ; i++ ) { 5002 pStream = pChannel->getStreamByIndex(i); 5003 if (!pStream) 5004 continue; 5005 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) { 5006 pPreviewStream = pStream; 5007 break; 5008 } 5009 } 5010 if (pPreviewStream != NULL) { 5011 Mutex::Autolock l(mMapLock); 5012 QCameraMemory *pMemory = pStream->getStreamBufs(); 5013 if (!pMemory) { 5014 LOGE("Error!! pMemory is NULL"); 5015 return -ENOMEM; 5016 } 5017 5018 uint8_t waitCnt = 2; 5019 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) { 5020 LOGL(" Waiting for preview buffers to be mapped"); 5021 mMapCond.waitRelative( 5022 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT); 5023 LOGL("Wait completed!!"); 5024 waitCnt--; 5025 } 5026 // If all buffers are not mapped after retries, assert 5027 assert(pMemory->checkIfAllBuffersMapped()); 5028 } else { 5029 assert(pPreviewStream); 5030 } 5031 5032 // Create JPEG session 5033 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 5034 args); 5035 if (mJpegJob == 0) { 5036 LOGE("Failed to queue CREATE_JPEG_SESSION"); 5037 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5038 LOGE("Reprocess Deferred work was failed"); 5039 } 5040 m_postprocessor.stop(); 5041 return -ENOMEM; 5042 } 5043 5044 if (mAdvancedCaptureConfigured) { 5045 rc = startAdvancedCapture(pPicChannel); 5046 if (rc != NO_ERROR) { 5047 LOGE("cannot start zsl advanced capture"); 5048 return rc; 5049 } 5050 } 5051 if (mLongshotEnabled && mPrepSnapRun) { 5052 mCameraHandle->ops->start_zsl_snapshot( 5053 mCameraHandle->camera_handle, 5054 pPicChannel->getMyHandle()); 5055 } 5056 // If frame sync is ON and it is a SECONDARY camera, 5057 // we do not need to send the take picture command to interface 5058 // It will be handled along with PRIMARY camera takePicture request 5059 mm_camera_req_buf_t buf; 5060 memset(&buf, 0x0, sizeof(buf)); 5061 if ((!mParameters.isAdvCamFeaturesEnabled() && 5062 !mFlashNeeded && 5063 !isLongshotEnabled() && 5064 isFrameSyncEnabled()) && 5065 (getRelatedCamSyncInfo()->sync_control == 5066 CAM_SYNC_RELATED_SENSORS_ON)) { 5067 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) { 5068 buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF; 5069 buf.num_buf_requested = numSnapshots; 5070 rc = pPicChannel->takePicture(&buf); 5071 if (rc != NO_ERROR) { 5072 LOGE("FS_DBG cannot take ZSL picture, stop pproc"); 5073 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5074 LOGE("Reprocess Deferred work failed"); 5075 return UNKNOWN_ERROR; 5076 } 5077 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 5078 LOGE("Jpeg Deferred work failed"); 5079 return UNKNOWN_ERROR; 5080 } 5081 m_postprocessor.stop(); 5082 return rc; 5083 } 5084 LOGI("PRIMARY camera: send frame sync takePicture!!"); 5085 } 5086 } else { 5087 buf.type = MM_CAMERA_REQ_SUPER_BUF; 5088 buf.num_buf_requested = numSnapshots; 5089 buf.num_retro_buf_requested = numRetroSnapshots; 5090 rc = pPicChannel->takePicture(&buf); 5091 if (rc != NO_ERROR) { 5092 LOGE("cannot take ZSL picture, stop pproc"); 5093 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5094 LOGE("Reprocess Deferred work failed"); 5095 return UNKNOWN_ERROR; 5096 } 5097 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 5098 LOGE("Jpeg Deferred work failed"); 5099 return UNKNOWN_ERROR; 5100 } 5101 m_postprocessor.stop(); 5102 return rc; 5103 } 5104 } 5105 } else { 5106 LOGE("ZSL channel is NULL"); 5107 return UNKNOWN_ERROR; 5108 } 5109 } else { 5110 5111 // start snapshot 5112 if (mParameters.isJpegPictureFormat() || 5113 mParameters.isNV16PictureFormat() || 5114 mParameters.isNV21PictureFormat()) { 5115 5116 //STOP Preview for Non ZSL use case 5117 stopPreview(); 5118 5119 //Config CAPTURE channels 5120 rc = declareSnapshotStreams(); 5121 if (NO_ERROR != rc) { 5122 return rc; 5123 } 5124 5125 rc = addCaptureChannel(); 5126 if ((rc == NO_ERROR) && 5127 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) { 5128 5129 if (!mParameters.getofflineRAW()) { 5130 rc = configureOnlineRotation( 5131 *m_channels[QCAMERA_CH_TYPE_CAPTURE]); 5132 if (rc != NO_ERROR) { 5133 LOGE("online rotation failed"); 5134 delChannel(QCAMERA_CH_TYPE_CAPTURE); 5135 return rc; 5136 } 5137 } 5138 5139 DeferWorkArgs args; 5140 memset(&args, 0, sizeof(DeferWorkArgs)); 5141 5142 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE]; 5143 5144 // No need to wait for mInitPProcJob here, because it was 5145 // queued in startPreview, and will definitely be processed before 5146 // mReprocJob can begin. 5147 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 5148 args); 5149 if (mReprocJob == 0) { 5150 LOGE("Failure: Unable to start pproc"); 5151 return -ENOMEM; 5152 } 5153 5154 // Create JPEG session 5155 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 5156 args); 5157 if (mJpegJob == 0) { 5158 LOGE("Failed to queue CREATE_JPEG_SESSION"); 5159 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5160 LOGE("Reprocess Deferred work was failed"); 5161 } 5162 m_postprocessor.stop(); 5163 return -ENOMEM; 5164 } 5165 5166 // start catpure channel 5167 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start(); 5168 if (rc != NO_ERROR) { 5169 LOGE("cannot start capture channel"); 5170 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5171 LOGE("Reprocess Deferred work failed"); 5172 return UNKNOWN_ERROR; 5173 } 5174 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 5175 LOGE("Jpeg Deferred work failed"); 5176 return UNKNOWN_ERROR; 5177 } 5178 delChannel(QCAMERA_CH_TYPE_CAPTURE); 5179 return rc; 5180 } 5181 5182 QCameraPicChannel *pCapChannel = 5183 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 5184 if (NULL != pCapChannel) { 5185 if (mParameters.isUbiFocusEnabled() || 5186 mParameters.isUbiRefocus() || 5187 mParameters.isChromaFlashEnabled()) { 5188 rc = startAdvancedCapture(pCapChannel); 5189 if (rc != NO_ERROR) { 5190 LOGE("cannot start advanced capture"); 5191 return rc; 5192 } 5193 } 5194 } 5195 if ( mLongshotEnabled ) { 5196 rc = longShot(); 5197 if (NO_ERROR != rc) { 5198 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5199 LOGE("Reprocess Deferred work failed"); 5200 return UNKNOWN_ERROR; 5201 } 5202 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 5203 LOGE("Jpeg Deferred work failed"); 5204 return UNKNOWN_ERROR; 5205 } 5206 delChannel(QCAMERA_CH_TYPE_CAPTURE); 5207 return rc; 5208 } 5209 } 5210 } else { 5211 LOGE("cannot add capture channel"); 5212 delChannel(QCAMERA_CH_TYPE_CAPTURE); 5213 return rc; 5214 } 5215 } else { 5216 // Stop Preview before taking NZSL snapshot 5217 stopPreview(); 5218 5219 rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]); 5220 if (NO_ERROR != rc) { 5221 LOGE("Raw dimension update failed %d", rc); 5222 return rc; 5223 } 5224 5225 rc = declareSnapshotStreams(); 5226 if (NO_ERROR != rc) { 5227 LOGE("RAW stream info configuration failed %d", rc); 5228 return rc; 5229 } 5230 5231 rc = addChannel(QCAMERA_CH_TYPE_RAW); 5232 if (rc == NO_ERROR) { 5233 // start postprocessor 5234 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 5235 LOGE("Reprocess Deferred work failed"); 5236 return UNKNOWN_ERROR; 5237 } 5238 5239 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 5240 if (rc != NO_ERROR) { 5241 LOGE("cannot start postprocessor"); 5242 delChannel(QCAMERA_CH_TYPE_RAW); 5243 return rc; 5244 } 5245 5246 rc = startChannel(QCAMERA_CH_TYPE_RAW); 5247 if (rc != NO_ERROR) { 5248 LOGE("cannot start raw channel"); 5249 m_postprocessor.stop(); 5250 delChannel(QCAMERA_CH_TYPE_RAW); 5251 return rc; 5252 } 5253 } else { 5254 LOGE("cannot add raw channel"); 5255 return rc; 5256 } 5257 } 5258 } 5259 5260 //When take picture, stop sending preview callbacks to APP 5261 m_stateMachine.setPreviewCallbackNeeded(false); 5262 LOGI("X rc = %d", rc); 5263 return rc; 5264 } 5265 5266 /*=========================================================================== 5267 * FUNCTION : configureOnlineRotation 5268 * 5269 * DESCRIPTION: Configure backend with expected rotation for snapshot stream 5270 * 5271 * PARAMETERS : 5272 * @ch : Channel containing a snapshot stream 5273 * 5274 * RETURN : int32_t type of status 5275 * NO_ERROR -- success 5276 * none-zero failure code 5277 *==========================================================================*/ 5278 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch) 5279 { 5280 int rc = NO_ERROR; 5281 uint32_t streamId = 0; 5282 QCameraStream *pStream = NULL; 5283 5284 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) { 5285 QCameraStream *stream = ch.getStreamByIndex(i); 5286 if ((NULL != stream) && 5287 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType()) 5288 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) { 5289 pStream = stream; 5290 break; 5291 } 5292 } 5293 5294 if (NULL == pStream) { 5295 LOGE("No snapshot stream found!"); 5296 return BAD_VALUE; 5297 } 5298 5299 streamId = pStream->getMyServerID(); 5300 // Update online rotation configuration 5301 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId, 5302 mParameters.getDeviceRotation()); 5303 if (rc != NO_ERROR) { 5304 LOGE("addOnlineRotation failed %d", rc); 5305 return rc; 5306 } 5307 5308 return rc; 5309 } 5310 5311 /*=========================================================================== 5312 * FUNCTION : declareSnapshotStreams 5313 * 5314 * DESCRIPTION: Configure backend with expected snapshot streams 5315 * 5316 * PARAMETERS : none 5317 * 5318 * RETURN : int32_t type of status 5319 * NO_ERROR -- success 5320 * none-zero failure code 5321 *==========================================================================*/ 5322 int32_t QCamera2HardwareInterface::declareSnapshotStreams() 5323 { 5324 int rc = NO_ERROR; 5325 5326 // Update stream info configuration 5327 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false); 5328 if (rc != NO_ERROR) { 5329 LOGE("setStreamConfigure failed %d", rc); 5330 return rc; 5331 } 5332 5333 return rc; 5334 } 5335 5336 /*=========================================================================== 5337 * FUNCTION : longShot 5338 * 5339 * DESCRIPTION: Queue one more ZSL frame 5340 * in the longshot pipe. 5341 * 5342 * PARAMETERS : none 5343 * 5344 * RETURN : int32_t type of status 5345 * NO_ERROR -- success 5346 * none-zero failure code 5347 *==========================================================================*/ 5348 int32_t QCamera2HardwareInterface::longShot() 5349 { 5350 int32_t rc = NO_ERROR; 5351 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 5352 QCameraPicChannel *pChannel = NULL; 5353 5354 if (mParameters.isZSLMode()) { 5355 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 5356 } else { 5357 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 5358 } 5359 5360 if (NULL != pChannel) { 5361 mm_camera_req_buf_t buf; 5362 memset(&buf, 0x0, sizeof(buf)); 5363 buf.type = MM_CAMERA_REQ_SUPER_BUF; 5364 buf.num_buf_requested = numSnapshots; 5365 rc = pChannel->takePicture(&buf); 5366 } else { 5367 LOGE("Capture channel not initialized!"); 5368 rc = NO_INIT; 5369 goto end; 5370 } 5371 5372 end: 5373 return rc; 5374 } 5375 5376 /*=========================================================================== 5377 * FUNCTION : stopCaptureChannel 5378 * 5379 * DESCRIPTION: Stops capture channel 5380 * 5381 * PARAMETERS : 5382 * @destroy : Set to true to stop and delete camera channel. 5383 * Set to false to only stop capture channel. 5384 * 5385 * RETURN : int32_t type of status 5386 * NO_ERROR -- success 5387 * none-zero failure code 5388 *==========================================================================*/ 5389 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy) 5390 { 5391 int rc = NO_ERROR; 5392 if (mParameters.isJpegPictureFormat() || 5393 mParameters.isNV16PictureFormat() || 5394 mParameters.isNV21PictureFormat()) { 5395 mParameters.setQuadraCfaMode(false, true); 5396 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE); 5397 if (destroy && (NO_ERROR == rc)) { 5398 // Destroy camera channel but dont release context 5399 waitDeferredWork(mJpegJob); 5400 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false); 5401 } 5402 } 5403 5404 return rc; 5405 } 5406 5407 /*=========================================================================== 5408 * FUNCTION : cancelPicture 5409 * 5410 * DESCRIPTION: cancel picture impl 5411 * 5412 * PARAMETERS : none 5413 * 5414 * RETURN : int32_t type of status 5415 * NO_ERROR -- success 5416 * none-zero failure code 5417 *==========================================================================*/ 5418 int QCamera2HardwareInterface::cancelPicture() 5419 { 5420 waitDeferredWork(mReprocJob); 5421 waitDeferredWork(mJpegJob); 5422 5423 //stop post processor 5424 m_postprocessor.stop(); 5425 5426 unconfigureAdvancedCapture(); 5427 LOGH("Enable display frames again"); 5428 setDisplaySkip(FALSE); 5429 5430 if (mParameters.isZSLMode()) { 5431 QCameraPicChannel *pPicChannel = NULL; 5432 if (mParameters.getofflineRAW()) { 5433 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW]; 5434 } else { 5435 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 5436 } 5437 if (NULL != pPicChannel) { 5438 pPicChannel->cancelPicture(); 5439 stopRAWChannel(); 5440 stopAdvancedCapture(pPicChannel); 5441 } 5442 } else { 5443 5444 // normal capture case 5445 if (mParameters.isJpegPictureFormat() || 5446 mParameters.isNV16PictureFormat() || 5447 mParameters.isNV21PictureFormat()) { 5448 stopChannel(QCAMERA_CH_TYPE_CAPTURE); 5449 delChannel(QCAMERA_CH_TYPE_CAPTURE); 5450 } else { 5451 stopChannel(QCAMERA_CH_TYPE_RAW); 5452 delChannel(QCAMERA_CH_TYPE_RAW); 5453 } 5454 } 5455 5456 return NO_ERROR; 5457 } 5458 5459 /*=========================================================================== 5460 * FUNCTION : captureDone 5461 * 5462 * DESCRIPTION: Function called when the capture is completed before encoding 5463 * 5464 * PARAMETERS : none 5465 * 5466 * RETURN : none 5467 *==========================================================================*/ 5468 void QCamera2HardwareInterface::captureDone() 5469 { 5470 qcamera_sm_internal_evt_payload_t *payload = 5471 (qcamera_sm_internal_evt_payload_t *) 5472 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 5473 if (NULL != payload) { 5474 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 5475 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE; 5476 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 5477 if (rc != NO_ERROR) { 5478 LOGE("processEvt ZSL capture done failed"); 5479 free(payload); 5480 payload = NULL; 5481 } 5482 } else { 5483 LOGE("No memory for ZSL capture done event"); 5484 } 5485 } 5486 5487 /*=========================================================================== 5488 * FUNCTION : Live_Snapshot_thread 5489 * 5490 * DESCRIPTION: Seperate thread for taking live snapshot during recording 5491 * 5492 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 5493 * 5494 * RETURN : none 5495 *==========================================================================*/ 5496 void* Live_Snapshot_thread (void* data) 5497 { 5498 5499 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 5500 if (!hw) { 5501 LOGE("take_picture_thread: NULL camera device"); 5502 return (void *)BAD_VALUE; 5503 } 5504 if (hw->bLiveSnapshot) { 5505 hw->takeLiveSnapshot_internal(); 5506 } else { 5507 hw->cancelLiveSnapshot_internal(); 5508 } 5509 return (void* )NULL; 5510 } 5511 5512 /*=========================================================================== 5513 * FUNCTION : Int_Pic_thread 5514 * 5515 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend 5516 * 5517 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 5518 * 5519 * RETURN : none 5520 *==========================================================================*/ 5521 void* Int_Pic_thread (void* data) 5522 { 5523 int rc = NO_ERROR; 5524 5525 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 5526 5527 if (!hw) { 5528 LOGE("take_picture_thread: NULL camera device"); 5529 return (void *)BAD_VALUE; 5530 } 5531 5532 bool JpegMemOpt = false; 5533 char raw_format[PROPERTY_VALUE_MAX]; 5534 5535 memset(raw_format, 0, sizeof(raw_format)); 5536 5537 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]); 5538 if (rc == NO_ERROR) { 5539 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]); 5540 } else { 5541 //Snapshot attempt not successful, we need to do cleanup here 5542 hw->clearIntPendingEvents(); 5543 } 5544 5545 return (void* )NULL; 5546 } 5547 5548 /*=========================================================================== 5549 * FUNCTION : takeLiveSnapshot 5550 * 5551 * DESCRIPTION: take live snapshot during recording 5552 * 5553 * PARAMETERS : none 5554 * 5555 * RETURN : int32_t type of status 5556 * NO_ERROR -- success 5557 * none-zero failure code 5558 *==========================================================================*/ 5559 int QCamera2HardwareInterface::takeLiveSnapshot() 5560 { 5561 int rc = NO_ERROR; 5562 if (mLiveSnapshotThread != 0) { 5563 pthread_join(mLiveSnapshotThread,NULL); 5564 mLiveSnapshotThread = 0; 5565 } 5566 bLiveSnapshot = true; 5567 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this); 5568 if (!rc) { 5569 pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap"); 5570 } 5571 return rc; 5572 } 5573 5574 /*=========================================================================== 5575 * FUNCTION : takePictureInternal 5576 * 5577 * DESCRIPTION: take snapshot triggered by backend 5578 * 5579 * PARAMETERS : none 5580 * 5581 * RETURN : int32_t type of status 5582 * NO_ERROR -- success 5583 * none-zero failure code 5584 *==========================================================================*/ 5585 int QCamera2HardwareInterface::takePictureInternal() 5586 { 5587 int rc = NO_ERROR; 5588 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this); 5589 if (!rc) { 5590 pthread_setname_np(mIntPicThread, "CAM_IntPic"); 5591 } 5592 return rc; 5593 } 5594 5595 /*=========================================================================== 5596 * FUNCTION : checkIntPicPending 5597 * 5598 * DESCRIPTION: timed wait for jpeg completion event, and send 5599 * back completion event to backend 5600 * 5601 * PARAMETERS : none 5602 * 5603 * RETURN : none 5604 *==========================================================================*/ 5605 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format) 5606 { 5607 bool bSendToBackend = true; 5608 cam_int_evt_params_t params; 5609 int rc = NO_ERROR; 5610 5611 struct timespec ts; 5612 struct timeval tp; 5613 gettimeofday(&tp, NULL); 5614 ts.tv_sec = tp.tv_sec + 5; 5615 ts.tv_nsec = tp.tv_usec * 1000; 5616 5617 if (true == m_bIntJpegEvtPending || 5618 (true == m_bIntRawEvtPending)) { 5619 //Waiting in HAL for snapshot taken notification 5620 pthread_mutex_lock(&m_int_lock); 5621 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts); 5622 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) { 5623 //Hit a timeout, or some spurious activity 5624 bSendToBackend = false; 5625 } 5626 5627 if (true == m_bIntJpegEvtPending) { 5628 params.event_type = 0; 5629 mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format); 5630 } else if (true == m_bIntRawEvtPending) { 5631 params.event_type = 1; 5632 mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format); 5633 } 5634 pthread_mutex_unlock(&m_int_lock); 5635 5636 if (true == m_bIntJpegEvtPending) { 5637 //Attempting to restart preview after taking JPEG snapshot 5638 lockAPI(); 5639 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 5640 unlockAPI(); 5641 m_postprocessor.setJpegMemOpt(JpegMemOpt); 5642 } else if (true == m_bIntRawEvtPending) { 5643 //Attempting to restart preview after taking RAW snapshot 5644 stopChannel(QCAMERA_CH_TYPE_RAW); 5645 delChannel(QCAMERA_CH_TYPE_RAW); 5646 //restoring the old raw format 5647 property_set("persist.camera.raw.format", raw_format); 5648 } 5649 5650 if (true == bSendToBackend) { 5651 //send event back to server with the file path 5652 params.dim = m_postprocessor.m_dst_dim; 5653 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH); 5654 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH); 5655 params.size = mBackendFileSize; 5656 rc = mParameters.setIntEvent(params); 5657 } 5658 5659 clearIntPendingEvents(); 5660 } 5661 5662 return; 5663 } 5664 5665 /*=========================================================================== 5666 * FUNCTION : takeBackendPic_internal 5667 * 5668 * DESCRIPTION: take snapshot triggered by backend 5669 * 5670 * PARAMETERS : none 5671 * 5672 * RETURN : int32_t type of status 5673 * NO_ERROR -- success 5674 * none-zero failure code 5675 *==========================================================================*/ 5676 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format) 5677 { 5678 int rc = NO_ERROR; 5679 qcamera_api_result_t apiResult; 5680 5681 lockAPI(); 5682 //Set rotation value from user settings as Jpeg rotation 5683 //to configure back-end modules. 5684 mParameters.setJpegRotation(mParameters.getRotation()); 5685 5686 setRetroPicture(0); 5687 /* Prepare snapshot in case LED needs to be flashed */ 5688 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) { 5689 // Start Preparing for normal Frames 5690 LOGH("Start Prepare Snapshot"); 5691 /* Prepare snapshot in case LED needs to be flashed */ 5692 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 5693 if (rc == NO_ERROR) { 5694 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 5695 rc = apiResult.status; 5696 } 5697 LOGH("Prep Snapshot done rc = %d", rc); 5698 mPrepSnapRun = true; 5699 } 5700 unlockAPI(); 5701 5702 if (true == m_bIntJpegEvtPending) { 5703 //Attempting to take JPEG snapshot 5704 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 5705 LOGE("Init PProc Deferred work failed"); 5706 return UNKNOWN_ERROR; 5707 } 5708 *JpegMemOpt = m_postprocessor.getJpegMemOpt(); 5709 m_postprocessor.setJpegMemOpt(false); 5710 5711 /* capture */ 5712 lockAPI(); 5713 LOGH("Capturing internal snapshot"); 5714 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 5715 if (rc == NO_ERROR) { 5716 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 5717 rc = apiResult.status; 5718 } 5719 unlockAPI(); 5720 } else if (true == m_bIntRawEvtPending) { 5721 //Attempting to take RAW snapshot 5722 (void)JpegMemOpt; 5723 stopPreview(); 5724 5725 //getting the existing raw format type 5726 property_get("persist.camera.raw.format", raw_format, "17"); 5727 //setting it to a default know value for this task 5728 property_set("persist.camera.raw.format", "18"); 5729 5730 rc = addChannel(QCAMERA_CH_TYPE_RAW); 5731 if (rc == NO_ERROR) { 5732 // start postprocessor 5733 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 5734 LOGE("Init PProc Deferred work failed"); 5735 return UNKNOWN_ERROR; 5736 } 5737 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 5738 if (rc != NO_ERROR) { 5739 LOGE("cannot start postprocessor"); 5740 delChannel(QCAMERA_CH_TYPE_RAW); 5741 return rc; 5742 } 5743 5744 rc = startChannel(QCAMERA_CH_TYPE_RAW); 5745 if (rc != NO_ERROR) { 5746 LOGE("cannot start raw channel"); 5747 m_postprocessor.stop(); 5748 delChannel(QCAMERA_CH_TYPE_RAW); 5749 return rc; 5750 } 5751 } else { 5752 LOGE("cannot add raw channel"); 5753 return rc; 5754 } 5755 } 5756 5757 return rc; 5758 } 5759 5760 /*=========================================================================== 5761 * FUNCTION : clearIntPendingEvents 5762 * 5763 * DESCRIPTION: clear internal pending events pertaining to backend 5764 * snapshot requests 5765 * 5766 * PARAMETERS : none 5767 * 5768 * RETURN : int32_t type of status 5769 * NO_ERROR -- success 5770 * none-zero failure code 5771 *==========================================================================*/ 5772 void QCamera2HardwareInterface::clearIntPendingEvents() 5773 { 5774 int rc = NO_ERROR; 5775 5776 if (true == m_bIntRawEvtPending) { 5777 preparePreview(); 5778 startPreview(); 5779 } 5780 if (true == m_bIntJpegEvtPending) { 5781 if (false == mParameters.isZSLMode()) { 5782 lockAPI(); 5783 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL); 5784 unlockAPI(); 5785 } 5786 } 5787 5788 pthread_mutex_lock(&m_int_lock); 5789 if (true == m_bIntJpegEvtPending) { 5790 m_bIntJpegEvtPending = false; 5791 } else if (true == m_bIntRawEvtPending) { 5792 m_bIntRawEvtPending = false; 5793 } 5794 pthread_mutex_unlock(&m_int_lock); 5795 return; 5796 } 5797 5798 /*=========================================================================== 5799 * FUNCTION : takeLiveSnapshot_internal 5800 * 5801 * DESCRIPTION: take live snapshot during recording 5802 * 5803 * PARAMETERS : none 5804 * 5805 * RETURN : int32_t type of status 5806 * NO_ERROR -- success 5807 * none-zero failure code 5808 *==========================================================================*/ 5809 int QCamera2HardwareInterface::takeLiveSnapshot_internal() 5810 { 5811 int rc = NO_ERROR; 5812 5813 QCameraChannel *pChannel = NULL; 5814 QCameraChannel *pPreviewChannel = NULL; 5815 QCameraStream *pPreviewStream = NULL; 5816 QCameraStream *pStream = NULL; 5817 5818 //Set rotation value from user settings as Jpeg rotation 5819 //to configure back-end modules. 5820 mParameters.setJpegRotation(mParameters.getRotation()); 5821 5822 // Configure advanced capture 5823 rc = configureAdvancedCapture(); 5824 if (rc != NO_ERROR) { 5825 LOGE("Unsupported capture call"); 5826 goto end; 5827 } 5828 5829 if (isLowPowerMode()) { 5830 pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO]; 5831 } else { 5832 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 5833 } 5834 5835 if (NULL == pChannel) { 5836 LOGE("Snapshot/Video channel not initialized"); 5837 rc = NO_INIT; 5838 goto end; 5839 } 5840 5841 // Check if all preview buffers are mapped before creating 5842 // a jpeg session as preview stream buffers are queried during the same 5843 pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 5844 if (pPreviewChannel != NULL) { 5845 uint32_t numStreams = pPreviewChannel->getNumOfStreams(); 5846 5847 for (uint8_t i = 0 ; i < numStreams ; i++ ) { 5848 pStream = pPreviewChannel->getStreamByIndex(i); 5849 if (!pStream) 5850 continue; 5851 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) { 5852 pPreviewStream = pStream; 5853 break; 5854 } 5855 } 5856 5857 if (pPreviewStream != NULL) { 5858 Mutex::Autolock l(mMapLock); 5859 QCameraMemory *pMemory = pStream->getStreamBufs(); 5860 if (!pMemory) { 5861 LOGE("Error!! pMemory is NULL"); 5862 return -ENOMEM; 5863 } 5864 5865 uint8_t waitCnt = 2; 5866 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) { 5867 LOGL(" Waiting for preview buffers to be mapped"); 5868 mMapCond.waitRelative( 5869 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT); 5870 LOGL("Wait completed!!"); 5871 waitCnt--; 5872 } 5873 // If all buffers are not mapped after retries, assert 5874 assert(pMemory->checkIfAllBuffersMapped()); 5875 } else { 5876 assert(pPreviewStream); 5877 } 5878 } 5879 5880 DeferWorkArgs args; 5881 memset(&args, 0, sizeof(DeferWorkArgs)); 5882 5883 args.pprocArgs = pChannel; 5884 5885 // No need to wait for mInitPProcJob here, because it was 5886 // queued in startPreview, and will definitely be processed before 5887 // mReprocJob can begin. 5888 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 5889 args); 5890 if (mReprocJob == 0) { 5891 LOGE("Failed to queue CMD_DEF_PPROC_START"); 5892 rc = -ENOMEM; 5893 goto end; 5894 } 5895 5896 // Create JPEG session 5897 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 5898 args); 5899 if (mJpegJob == 0) { 5900 LOGE("Failed to queue CREATE_JPEG_SESSION"); 5901 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5902 LOGE("Reprocess Deferred work was failed"); 5903 } 5904 m_postprocessor.stop(); 5905 rc = -ENOMEM; 5906 goto end; 5907 } 5908 5909 if (isLowPowerMode()) { 5910 mm_camera_req_buf_t buf; 5911 memset(&buf, 0x0, sizeof(buf)); 5912 buf.type = MM_CAMERA_REQ_SUPER_BUF; 5913 buf.num_buf_requested = 1; 5914 rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf); 5915 goto end; 5916 } 5917 5918 //Disable reprocess for 4K liveshot case 5919 if (!mParameters.is4k2kVideoResolution()) { 5920 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]); 5921 if (rc != NO_ERROR) { 5922 LOGE("online rotation failed"); 5923 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5924 LOGE("Reprocess Deferred work was failed"); 5925 } 5926 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 5927 LOGE("Jpeg Deferred work was failed"); 5928 } 5929 m_postprocessor.stop(); 5930 return rc; 5931 } 5932 } 5933 5934 if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) { 5935 QCameraStream *pStream = NULL; 5936 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) { 5937 pStream = pChannel->getStreamByIndex(i); 5938 if ((NULL != pStream) && 5939 (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) { 5940 break; 5941 } 5942 } 5943 if (pStream != NULL) { 5944 LOGD("REQUEST_FRAMES event for TNR snapshot"); 5945 cam_stream_parm_buffer_t param; 5946 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 5947 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES; 5948 param.frameRequest.enableStream = 1; 5949 rc = pStream->setParameter(param); 5950 if (rc != NO_ERROR) { 5951 LOGE("Stream Event REQUEST_FRAMES failed"); 5952 } 5953 goto end; 5954 } 5955 } 5956 5957 // start snapshot channel 5958 if ((rc == NO_ERROR) && (NULL != pChannel)) { 5959 // Do not link metadata stream for 4K2k resolution 5960 // as CPP processing would be done on snapshot stream and not 5961 // reprocess stream 5962 if (!mParameters.is4k2kVideoResolution()) { 5963 // Find and try to link a metadata stream from preview channel 5964 QCameraChannel *pMetaChannel = NULL; 5965 QCameraStream *pMetaStream = NULL; 5966 QCameraStream *pPreviewStream = NULL; 5967 5968 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 5969 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 5970 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 5971 QCameraStream *pStream = NULL; 5972 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 5973 pStream = pMetaChannel->getStreamByIndex(i); 5974 if (NULL != pStream) { 5975 if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) { 5976 pMetaStream = pStream; 5977 } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) 5978 && (!mParameters.isHfrMode()) 5979 && (mParameters.isLinkPreviewForLiveShot())) { 5980 // Do not link preview stream for 5981 // 1)HFR live snapshot,Thumbnail will not be derived from 5982 // preview for HFR live snapshot. 5983 // 2)persist.camera.linkpreview is 0 5984 pPreviewStream = pStream; 5985 } 5986 } 5987 } 5988 } 5989 5990 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 5991 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 5992 if (NO_ERROR != rc) { 5993 LOGE("Metadata stream link failed %d", rc); 5994 } 5995 } 5996 if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) { 5997 rc = pChannel->linkStream(pMetaChannel, pPreviewStream); 5998 if (NO_ERROR != rc) { 5999 LOGE("Preview stream link failed %d", rc); 6000 } 6001 } 6002 } 6003 rc = pChannel->start(); 6004 } 6005 6006 end: 6007 if (rc != NO_ERROR) { 6008 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 6009 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 6010 } 6011 return rc; 6012 } 6013 6014 /*=========================================================================== 6015 * FUNCTION : cancelLiveSnapshot 6016 * 6017 * DESCRIPTION: cancel current live snapshot request 6018 * 6019 * PARAMETERS : none 6020 * 6021 * RETURN : int32_t type of status 6022 * NO_ERROR -- success 6023 * none-zero failure code 6024 *==========================================================================*/ 6025 int QCamera2HardwareInterface::cancelLiveSnapshot() 6026 { 6027 int rc = NO_ERROR; 6028 if (mLiveSnapshotThread != 0) { 6029 pthread_join(mLiveSnapshotThread,NULL); 6030 mLiveSnapshotThread = 0; 6031 } 6032 bLiveSnapshot = false; 6033 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this); 6034 if (!rc) { 6035 pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap"); 6036 } 6037 return rc; 6038 } 6039 6040 /*=========================================================================== 6041 * FUNCTION : cancelLiveSnapshot_internal 6042 * 6043 * DESCRIPTION: cancel live snapshot during recording 6044 * 6045 * PARAMETERS : none 6046 * 6047 * RETURN : int32_t type of status 6048 * NO_ERROR -- success 6049 * none-zero failure code 6050 *==========================================================================*/ 6051 int QCamera2HardwareInterface::cancelLiveSnapshot_internal() { 6052 int rc = NO_ERROR; 6053 6054 unconfigureAdvancedCapture(); 6055 LOGH("Enable display frames again"); 6056 setDisplaySkip(FALSE); 6057 6058 //wait for deferred (reprocess and jpeg) threads to finish 6059 waitDeferredWork(mReprocJob); 6060 waitDeferredWork(mJpegJob); 6061 //stop post processor 6062 m_postprocessor.stop(); 6063 6064 // stop snapshot channel 6065 if (!mParameters.isTNRSnapshotEnabled()) { 6066 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6067 } else { 6068 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 6069 if (NULL != pChannel) { 6070 QCameraStream *pStream = NULL; 6071 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) { 6072 pStream = pChannel->getStreamByIndex(i); 6073 if ((NULL != pStream) && 6074 (CAM_STREAM_TYPE_SNAPSHOT == 6075 pStream->getMyType())) { 6076 break; 6077 } 6078 } 6079 if (pStream != NULL) { 6080 LOGD("REQUEST_FRAMES event for TNR snapshot"); 6081 cam_stream_parm_buffer_t param; 6082 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 6083 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES; 6084 param.frameRequest.enableStream = 0; 6085 rc = pStream->setParameter(param); 6086 if (rc != NO_ERROR) { 6087 LOGE("Stream Event REQUEST_FRAMES failed"); 6088 } 6089 } 6090 } 6091 } 6092 6093 return rc; 6094 } 6095 6096 /*=========================================================================== 6097 * FUNCTION : putParameters 6098 * 6099 * DESCRIPTION: put parameters string impl 6100 * 6101 * PARAMETERS : 6102 * @parms : parameters string to be released 6103 * 6104 * RETURN : int32_t type of status 6105 * NO_ERROR -- success 6106 * none-zero failure code 6107 *==========================================================================*/ 6108 int QCamera2HardwareInterface::putParameters(char *parms) 6109 { 6110 free(parms); 6111 return NO_ERROR; 6112 } 6113 6114 /*=========================================================================== 6115 * FUNCTION : sendCommand 6116 * 6117 * DESCRIPTION: send command impl 6118 * 6119 * PARAMETERS : 6120 * @command : command to be executed 6121 * @arg1 : optional argument 1 6122 * @arg2 : optional argument 2 6123 * 6124 * RETURN : int32_t type of status 6125 * NO_ERROR -- success 6126 * none-zero failure code 6127 *==========================================================================*/ 6128 int QCamera2HardwareInterface::sendCommand(int32_t command, 6129 __unused int32_t &arg1, __unused int32_t &arg2) 6130 { 6131 int rc = NO_ERROR; 6132 6133 switch (command) { 6134 #ifndef VANILLA_HAL 6135 case CAMERA_CMD_LONGSHOT_ON: 6136 arg1 = arg2 = 0; 6137 // Longshot can only be enabled when image capture 6138 // is not active. 6139 if ( !m_stateMachine.isCaptureRunning() ) { 6140 LOGI("Longshot Enabled"); 6141 mLongshotEnabled = true; 6142 rc = mParameters.setLongshotEnable(mLongshotEnabled); 6143 6144 // Due to recent buffer count optimizations 6145 // ZSL might run with considerably less buffers 6146 // when not in longshot mode. Preview needs to 6147 // restart in this case. 6148 if (isZSLMode() && m_stateMachine.isPreviewRunning()) { 6149 QCameraChannel *pChannel = NULL; 6150 QCameraStream *pSnapStream = NULL; 6151 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 6152 if (NULL != pChannel) { 6153 QCameraStream *pStream = NULL; 6154 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) { 6155 pStream = pChannel->getStreamByIndex(i); 6156 if (pStream != NULL) { 6157 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 6158 pSnapStream = pStream; 6159 break; 6160 } 6161 } 6162 } 6163 if (NULL != pSnapStream) { 6164 uint8_t required = 0; 6165 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT); 6166 if (pSnapStream->getBufferCount() < required) { 6167 // We restart here, to reset the FPS and no 6168 // of buffers as per the requirement of longshot usecase. 6169 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW; 6170 if (getRelatedCamSyncInfo()->sync_control == 6171 CAM_SYNC_RELATED_SENSORS_ON) { 6172 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART; 6173 } 6174 } 6175 } 6176 } 6177 } 6178 // 6179 mPrepSnapRun = false; 6180 mCACDoneReceived = FALSE; 6181 } else { 6182 rc = NO_INIT; 6183 } 6184 break; 6185 case CAMERA_CMD_LONGSHOT_OFF: 6186 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) { 6187 cancelPicture(); 6188 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 6189 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 6190 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) { 6191 mCameraHandle->ops->stop_zsl_snapshot( 6192 mCameraHandle->camera_handle, 6193 pZSLChannel->getMyHandle()); 6194 } 6195 } 6196 mPrepSnapRun = false; 6197 LOGI("Longshot Disabled"); 6198 mLongshotEnabled = false; 6199 rc = mParameters.setLongshotEnable(mLongshotEnabled); 6200 mCACDoneReceived = FALSE; 6201 break; 6202 case CAMERA_CMD_HISTOGRAM_ON: 6203 case CAMERA_CMD_HISTOGRAM_OFF: 6204 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false); 6205 LOGH("Histogram -> %s", 6206 mParameters.isHistogramEnabled() ? "Enabled" : "Disabled"); 6207 break; 6208 #endif 6209 case CAMERA_CMD_START_FACE_DETECTION: 6210 case CAMERA_CMD_STOP_FACE_DETECTION: 6211 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 6212 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 6213 LOGH("FaceDetection -> %s", 6214 mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled"); 6215 break; 6216 #ifndef VANILLA_HAL 6217 case CAMERA_CMD_HISTOGRAM_SEND_DATA: 6218 #endif 6219 default: 6220 rc = NO_ERROR; 6221 break; 6222 } 6223 return rc; 6224 } 6225 6226 /*=========================================================================== 6227 * FUNCTION : registerFaceImage 6228 * 6229 * DESCRIPTION: register face image impl 6230 * 6231 * PARAMETERS : 6232 * @img_ptr : ptr to image buffer 6233 * @config : ptr to config struct about input image info 6234 * @faceID : [OUT] face ID to uniquely identifiy the registered face image 6235 * 6236 * RETURN : int32_t type of status 6237 * NO_ERROR -- success 6238 * none-zero failure code 6239 *==========================================================================*/ 6240 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr, 6241 cam_pp_offline_src_config_t *config, 6242 int32_t &faceID) 6243 { 6244 int rc = NO_ERROR; 6245 faceID = -1; 6246 6247 if (img_ptr == NULL || config == NULL) { 6248 LOGE("img_ptr or config is NULL"); 6249 return BAD_VALUE; 6250 } 6251 6252 // allocate ion memory for source image 6253 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 6254 if (imgBuf == NULL) { 6255 LOGE("Unable to new heap memory obj for image buf"); 6256 return NO_MEMORY; 6257 } 6258 6259 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len); 6260 if (rc < 0) { 6261 LOGE("Unable to allocate heap memory for image buf"); 6262 delete imgBuf; 6263 return NO_MEMORY; 6264 } 6265 6266 void *pBufPtr = imgBuf->getPtr(0); 6267 if (pBufPtr == NULL) { 6268 LOGE("image buf is NULL"); 6269 imgBuf->deallocate(); 6270 delete imgBuf; 6271 return NO_MEMORY; 6272 } 6273 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len); 6274 //Do cache ops before sending for reprocess 6275 imgBuf->cacheOps(0, ION_IOC_CLEAN_INV_CACHES); 6276 6277 cam_pp_feature_config_t pp_feature; 6278 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t)); 6279 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE; 6280 QCameraReprocessChannel *pChannel = 6281 addOfflineReprocChannel(*config, pp_feature, NULL, NULL); 6282 6283 if (pChannel == NULL) { 6284 LOGE("fail to add offline reprocess channel"); 6285 imgBuf->deallocate(); 6286 delete imgBuf; 6287 return UNKNOWN_ERROR; 6288 } 6289 6290 rc = pChannel->start(); 6291 if (rc != NO_ERROR) { 6292 LOGE("Cannot start reprocess channel"); 6293 imgBuf->deallocate(); 6294 delete imgBuf; 6295 delete pChannel; 6296 return rc; 6297 } 6298 6299 ssize_t bufSize = imgBuf->getSize(0); 6300 if (BAD_INDEX != bufSize) { 6301 rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0), 6302 (size_t)bufSize, faceID); 6303 } else { 6304 LOGE("Failed to retrieve buffer size (bad index)"); 6305 return UNKNOWN_ERROR; 6306 } 6307 6308 // done with register face image, free imgbuf and delete reprocess channel 6309 imgBuf->deallocate(); 6310 delete imgBuf; 6311 imgBuf = NULL; 6312 pChannel->stop(); 6313 delete pChannel; 6314 pChannel = NULL; 6315 6316 return rc; 6317 } 6318 6319 /*=========================================================================== 6320 * FUNCTION : release 6321 * 6322 * DESCRIPTION: release camera resource impl 6323 * 6324 * PARAMETERS : none 6325 * 6326 * RETURN : int32_t type of status 6327 * NO_ERROR -- success 6328 * none-zero failure code 6329 *==========================================================================*/ 6330 int QCamera2HardwareInterface::release() 6331 { 6332 // stop and delete all channels 6333 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) { 6334 if (m_channels[i] != NULL) { 6335 stopChannel((qcamera_ch_type_enum_t)i); 6336 delChannel((qcamera_ch_type_enum_t)i); 6337 } 6338 } 6339 6340 return NO_ERROR; 6341 } 6342 6343 /*=========================================================================== 6344 * FUNCTION : dump 6345 * 6346 * DESCRIPTION: camera status dump impl 6347 * 6348 * PARAMETERS : 6349 * @fd : fd for the buffer to be dumped with camera status 6350 * 6351 * RETURN : int32_t type of status 6352 * NO_ERROR -- success 6353 * none-zero failure code 6354 *==========================================================================*/ 6355 int QCamera2HardwareInterface::dump(int fd) 6356 { 6357 dprintf(fd, "\n Camera HAL information Begin \n"); 6358 dprintf(fd, "Camera ID: %d \n", mCameraId); 6359 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame); 6360 dprintf(fd, "\n Configuration: %s", mParameters.dump().string()); 6361 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string()); 6362 dprintf(fd, "\n Camera HAL information End \n"); 6363 6364 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the 6365 debug level property */ 6366 mParameters.updateDebugLevel(); 6367 return NO_ERROR; 6368 } 6369 6370 /*=========================================================================== 6371 * FUNCTION : processAPI 6372 * 6373 * DESCRIPTION: process API calls from upper layer 6374 * 6375 * PARAMETERS : 6376 * @api : API to be processed 6377 * @api_payload : ptr to API payload if any 6378 * 6379 * RETURN : int32_t type of status 6380 * NO_ERROR -- success 6381 * none-zero failure code 6382 *==========================================================================*/ 6383 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload) 6384 { 6385 int ret = DEAD_OBJECT; 6386 6387 if (m_smThreadActive) { 6388 ret = m_stateMachine.procAPI(api, api_payload); 6389 } 6390 6391 return ret; 6392 } 6393 6394 /*=========================================================================== 6395 * FUNCTION : processEvt 6396 * 6397 * DESCRIPTION: process Evt from backend via mm-camera-interface 6398 * 6399 * PARAMETERS : 6400 * @evt : event type to be processed 6401 * @evt_payload : ptr to event payload if any 6402 * 6403 * RETURN : int32_t type of status 6404 * NO_ERROR -- success 6405 * none-zero failure code 6406 *==========================================================================*/ 6407 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 6408 { 6409 return m_stateMachine.procEvt(evt, evt_payload); 6410 } 6411 6412 /*=========================================================================== 6413 * FUNCTION : processSyncEvt 6414 * 6415 * DESCRIPTION: process synchronous Evt from backend 6416 * 6417 * PARAMETERS : 6418 * @evt : event type to be processed 6419 * @evt_payload : ptr to event payload if any 6420 * 6421 * RETURN : int32_t type of status 6422 * NO_ERROR -- success 6423 * none-zero failure code 6424 *==========================================================================*/ 6425 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 6426 { 6427 int rc = NO_ERROR; 6428 6429 pthread_mutex_lock(&m_evtLock); 6430 rc = processEvt(evt, evt_payload); 6431 if (rc == NO_ERROR) { 6432 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 6433 while (m_evtResult.request_api != evt) { 6434 pthread_cond_wait(&m_evtCond, &m_evtLock); 6435 } 6436 rc = m_evtResult.status; 6437 } 6438 pthread_mutex_unlock(&m_evtLock); 6439 6440 return rc; 6441 } 6442 6443 /*=========================================================================== 6444 * FUNCTION : evtHandle 6445 * 6446 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events 6447 * 6448 * PARAMETERS : 6449 * @camera_handle : event type to be processed 6450 * @evt : ptr to event 6451 * @user_data : user data ptr 6452 * 6453 * RETURN : none 6454 *==========================================================================*/ 6455 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/, 6456 mm_camera_event_t *evt, 6457 void *user_data) 6458 { 6459 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data; 6460 if (obj && evt) { 6461 mm_camera_event_t *payload = 6462 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t)); 6463 if (NULL != payload) { 6464 *payload = *evt; 6465 //peek into the event, if this is an eztune event from server, 6466 //then we don't need to post it to the SM Qs, we shud directly 6467 //spawn a thread and get the job done (jpeg or raw snapshot) 6468 switch (payload->server_event_type) { 6469 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 6470 //Received JPEG trigger from eztune 6471 if (false == obj->m_bIntJpegEvtPending) { 6472 pthread_mutex_lock(&obj->m_int_lock); 6473 obj->m_bIntJpegEvtPending = true; 6474 pthread_mutex_unlock(&obj->m_int_lock); 6475 obj->takePictureInternal(); 6476 } 6477 free(payload); 6478 break; 6479 case CAM_EVENT_TYPE_INT_TAKE_RAW: 6480 //Received RAW trigger from eztune 6481 if (false == obj->m_bIntRawEvtPending) { 6482 pthread_mutex_lock(&obj->m_int_lock); 6483 obj->m_bIntRawEvtPending = true; 6484 pthread_mutex_unlock(&obj->m_int_lock); 6485 obj->takePictureInternal(); 6486 } 6487 free(payload); 6488 break; 6489 case CAM_EVENT_TYPE_DAEMON_DIED: 6490 { 6491 Mutex::Autolock l(obj->mDefLock); 6492 obj->mDefCond.broadcast(); 6493 LOGH("broadcast mDefCond signal\n"); 6494 } 6495 default: 6496 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload); 6497 break; 6498 } 6499 } 6500 } else { 6501 LOGE("NULL user_data"); 6502 } 6503 } 6504 6505 /*=========================================================================== 6506 * FUNCTION : jpegEvtHandle 6507 * 6508 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events 6509 * 6510 * PARAMETERS : 6511 * @status : status of jpeg job 6512 * @client_hdl: jpeg client handle 6513 * @jobId : jpeg job Id 6514 * @p_ouput : ptr to jpeg output result struct 6515 * @userdata : user data ptr 6516 * 6517 * RETURN : none 6518 *==========================================================================*/ 6519 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status, 6520 uint32_t /*client_hdl*/, 6521 uint32_t jobId, 6522 mm_jpeg_output_t *p_output, 6523 void *userdata) 6524 { 6525 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata; 6526 if (obj) { 6527 qcamera_jpeg_evt_payload_t *payload = 6528 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t)); 6529 if (NULL != payload) { 6530 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t)); 6531 payload->status = status; 6532 payload->jobId = jobId; 6533 if (p_output != NULL) { 6534 payload->out_data = *p_output; 6535 } 6536 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload); 6537 } 6538 } else { 6539 LOGE("NULL user_data"); 6540 } 6541 } 6542 6543 /*=========================================================================== 6544 * FUNCTION : thermalEvtHandle 6545 * 6546 * DESCRIPTION: routine to handle thermal event notification 6547 * 6548 * PARAMETERS : 6549 * @level : thermal level 6550 * @userdata : userdata passed in during registration 6551 * @data : opaque data from thermal client 6552 * 6553 * RETURN : int32_t type of status 6554 * NO_ERROR -- success 6555 * none-zero failure code 6556 *==========================================================================*/ 6557 int QCamera2HardwareInterface::thermalEvtHandle( 6558 qcamera_thermal_level_enum_t *level, void *userdata, void *data) 6559 { 6560 if (!mCameraOpened) { 6561 LOGH("Camera is not opened, no need to handle thermal evt"); 6562 return NO_ERROR; 6563 } 6564 6565 // Make sure thermal events are logged 6566 LOGH("level = %d, userdata = %p, data = %p", 6567 *level, userdata, data); 6568 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY 6569 // becomes an aync call. This also means we can only pass payload 6570 // by value, not by address. 6571 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level); 6572 } 6573 6574 /*=========================================================================== 6575 * FUNCTION : sendEvtNotify 6576 * 6577 * DESCRIPTION: send event notify to notify thread 6578 * 6579 * PARAMETERS : 6580 * @msg_type: msg type to be sent 6581 * @ext1 : optional extension1 6582 * @ext2 : optional extension2 6583 * 6584 * RETURN : int32_t type of status 6585 * NO_ERROR -- success 6586 * none-zero failure code 6587 *==========================================================================*/ 6588 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type, 6589 int32_t ext1, 6590 int32_t ext2) 6591 { 6592 qcamera_callback_argm_t cbArg; 6593 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6594 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 6595 cbArg.msg_type = msg_type; 6596 cbArg.ext1 = ext1; 6597 cbArg.ext2 = ext2; 6598 return m_cbNotifier.notifyCallback(cbArg); 6599 } 6600 6601 /*=========================================================================== 6602 * FUNCTION : processAEInfo 6603 * 6604 * DESCRIPTION: process AE updates 6605 * 6606 * PARAMETERS : 6607 * @ae_params: current AE parameters 6608 * 6609 * RETURN : None 6610 *==========================================================================*/ 6611 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params) 6612 { 6613 mParameters.updateAEInfo(ae_params); 6614 if (mParameters.isInstantAECEnabled()) { 6615 // Reset Instant AEC info only if instant aec enabled. 6616 bool bResetInstantAec = false; 6617 if (ae_params.settled) { 6618 // If AEC settled, reset instant AEC 6619 bResetInstantAec = true; 6620 } else if ((mParameters.isInstantCaptureEnabled()) && 6621 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) { 6622 // if AEC not settled, and instant capture enabled, 6623 // reset instant AEC only when frame count is 6624 // more or equal to AEC frame bound value. 6625 bResetInstantAec = true; 6626 } else if ((mParameters.isInstantAECEnabled()) && 6627 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) { 6628 // if AEC not settled, and only instant AEC enabled, 6629 // reset instant AEC only when frame count is 6630 // more or equal to AEC skip display frame bound value. 6631 bResetInstantAec = true; 6632 } 6633 6634 if (bResetInstantAec) { 6635 LOGD("setting instant AEC to false"); 6636 mParameters.setInstantAEC(false, true); 6637 mInstantAecFrameCount = 0; 6638 } 6639 } 6640 return NO_ERROR; 6641 } 6642 6643 /*=========================================================================== 6644 * FUNCTION : processFocusPositionInfo 6645 * 6646 * DESCRIPTION: process AF updates 6647 * 6648 * PARAMETERS : 6649 * @cur_pos_info: current lens position 6650 * 6651 * RETURN : None 6652 *==========================================================================*/ 6653 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info) 6654 { 6655 mParameters.updateCurrentFocusPosition(cur_pos_info); 6656 return NO_ERROR; 6657 } 6658 6659 /*=========================================================================== 6660 * FUNCTION : processAutoFocusEvent 6661 * 6662 * DESCRIPTION: process auto focus event 6663 * 6664 * PARAMETERS : 6665 * @focus_data: struct containing auto focus result info 6666 * 6667 * RETURN : int32_t type of status 6668 * NO_ERROR -- success 6669 * none-zero failure code 6670 *==========================================================================*/ 6671 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data) 6672 { 6673 int32_t ret = NO_ERROR; 6674 LOGH("E"); 6675 6676 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) { 6677 // Ignore focus updates 6678 LOGH("X Secondary Camera, no need to process!! "); 6679 return ret; 6680 } 6681 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 6682 LOGH("[AF_DBG] focusMode=%d, focusState=%d isDepth=%d", 6683 focusMode, focus_data.focus_state, focus_data.isDepth); 6684 6685 switch (focusMode) { 6686 case CAM_FOCUS_MODE_AUTO: 6687 case CAM_FOCUS_MODE_MACRO: 6688 // ignore AF event if AF was already cancelled meanwhile 6689 if (!mActiveAF) { 6690 break; 6691 } 6692 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app 6693 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 6694 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6695 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 6696 mActiveAF = false; // reset the mActiveAF in this special case 6697 break; 6698 } 6699 6700 //while transitioning from CAF->Auto/Macro, we might receive CAF related 6701 //events (PASSIVE_*) due to timing. Ignore such events if any. 6702 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) || 6703 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6704 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) { 6705 break; 6706 } 6707 6708 //This is just an intermediate update to HAL indicating focus is in progress. No need 6709 //to send this event to app. Same applies to INACTIVE state as well. 6710 if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) || 6711 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6712 break; 6713 } 6714 // update focus distance 6715 mParameters.updateFocusDistances(&focus_data.focus_dist); 6716 6717 //flush any old snapshot frames in ZSL Q which are not focused. 6718 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) { 6719 QCameraPicChannel *pZSLChannel = 6720 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 6721 if (NULL != pZSLChannel) { 6722 //flush the zsl-buffer 6723 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx; 6724 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx); 6725 pZSLChannel->flushSuperbuffer(flush_frame_idx); 6726 } 6727 } 6728 6729 //send event to app finally 6730 LOGI("Send AF DOne event to app"); 6731 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 6732 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0); 6733 break; 6734 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 6735 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 6736 6737 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app 6738 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 6739 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6740 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0); 6741 mActiveAF = false; // reset the mActiveAF in this special case 6742 break; 6743 } 6744 6745 //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and 6746 //process/wait for only ACTIVE_* events. 6747 if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6748 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) || 6749 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) { 6750 break; 6751 } 6752 6753 if (!bDepthAFCallbacks && focus_data.isDepth && 6754 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) { 6755 LOGD("Skip sending scan state to app, if depth focus"); 6756 break; 6757 } 6758 6759 //These are the AF states for which we need to send notification to app in CAF mode. 6760 //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case 6761 //AF is triggered while in CAF mode) 6762 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6763 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) || 6764 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) || 6765 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) { 6766 6767 // update focus distance 6768 mParameters.updateFocusDistances(&focus_data.focus_dist); 6769 6770 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) { 6771 QCameraPicChannel *pZSLChannel = 6772 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 6773 if (NULL != pZSLChannel) { 6774 //flush the zsl-buffer 6775 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx; 6776 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx); 6777 pZSLChannel->flushSuperbuffer(flush_frame_idx); 6778 } 6779 } 6780 6781 if (mActiveAF) { 6782 LOGI("Send AF Done event to app"); 6783 } 6784 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 6785 ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6786 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0); 6787 } 6788 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE, 6789 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0); 6790 break; 6791 case CAM_FOCUS_MODE_INFINITY: 6792 case CAM_FOCUS_MODE_FIXED: 6793 case CAM_FOCUS_MODE_EDOF: 6794 default: 6795 LOGH("no ops for autofocus event in focusmode %d", focusMode); 6796 break; 6797 } 6798 6799 //Reset mActiveAF once we receive focus done event 6800 if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) || 6801 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) { 6802 mActiveAF = false; 6803 } 6804 6805 LOGH("X"); 6806 return ret; 6807 } 6808 6809 /*=========================================================================== 6810 * FUNCTION : processZoomEvent 6811 * 6812 * DESCRIPTION: process zoom event 6813 * 6814 * PARAMETERS : 6815 * @crop_info : crop info as a result of zoom operation 6816 * 6817 * RETURN : int32_t type of status 6818 * NO_ERROR -- success 6819 * none-zero failure code 6820 *==========================================================================*/ 6821 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info) 6822 { 6823 int32_t ret = NO_ERROR; 6824 6825 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 6826 if (m_channels[i] != NULL) { 6827 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info); 6828 } 6829 } 6830 return ret; 6831 } 6832 6833 /*=========================================================================== 6834 * FUNCTION : processZSLCaptureDone 6835 * 6836 * DESCRIPTION: process ZSL capture done events 6837 * 6838 * PARAMETERS : None 6839 * 6840 * RETURN : int32_t type of status 6841 * NO_ERROR -- success 6842 * none-zero failure code 6843 *==========================================================================*/ 6844 int32_t QCamera2HardwareInterface::processZSLCaptureDone() 6845 { 6846 int rc = NO_ERROR; 6847 6848 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) { 6849 rc = unconfigureAdvancedCapture(); 6850 } 6851 6852 return rc; 6853 } 6854 6855 /*=========================================================================== 6856 * FUNCTION : processRetroAECUnlock 6857 * 6858 * DESCRIPTION: process retro burst AEC unlock events 6859 * 6860 * PARAMETERS : None 6861 * 6862 * RETURN : int32_t type of status 6863 * NO_ERROR -- success 6864 * none-zero failure code 6865 *==========================================================================*/ 6866 int32_t QCamera2HardwareInterface::processRetroAECUnlock() 6867 { 6868 int rc = NO_ERROR; 6869 6870 LOGH("LED assisted AF Release AEC Lock"); 6871 rc = mParameters.setAecLock("false"); 6872 if (NO_ERROR != rc) { 6873 LOGE("Error setting AEC lock"); 6874 return rc; 6875 } 6876 6877 rc = mParameters.commitParameters(); 6878 if (NO_ERROR != rc) { 6879 LOGE("Error during camera parameter commit"); 6880 } else { 6881 m_bLedAfAecLock = FALSE; 6882 } 6883 6884 return rc; 6885 } 6886 6887 /*=========================================================================== 6888 * FUNCTION : processHDRData 6889 * 6890 * DESCRIPTION: process HDR scene events 6891 * 6892 * PARAMETERS : 6893 * @hdr_scene : HDR scene event data 6894 * 6895 * RETURN : int32_t type of status 6896 * NO_ERROR -- success 6897 * none-zero failure code 6898 *==========================================================================*/ 6899 int32_t QCamera2HardwareInterface::processHDRData( 6900 __unused cam_asd_hdr_scene_data_t hdr_scene) 6901 { 6902 int rc = NO_ERROR; 6903 6904 #ifndef VANILLA_HAL 6905 if (hdr_scene.is_hdr_scene && 6906 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) && 6907 mParameters.isAutoHDREnabled()) { 6908 m_HDRSceneEnabled = true; 6909 } else { 6910 m_HDRSceneEnabled = false; 6911 } 6912 mParameters.setHDRSceneEnable(m_HDRSceneEnabled); 6913 6914 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) { 6915 6916 size_t data_len = sizeof(int); 6917 size_t buffer_len = 1 *sizeof(int) //meta type 6918 + 1 *sizeof(int) //data len 6919 + 1 *sizeof(int); //data 6920 camera_memory_t *hdrBuffer = mGetMemory(-1, 6921 buffer_len, 6922 1, 6923 mCallbackCookie); 6924 if ( NULL == hdrBuffer ) { 6925 LOGE("Not enough memory for auto HDR data"); 6926 return NO_MEMORY; 6927 } 6928 6929 int *pHDRData = (int *)hdrBuffer->data; 6930 if (pHDRData == NULL) { 6931 LOGE("memory data ptr is NULL"); 6932 return UNKNOWN_ERROR; 6933 } 6934 6935 pHDRData[0] = CAMERA_META_DATA_HDR; 6936 pHDRData[1] = (int)data_len; 6937 pHDRData[2] = m_HDRSceneEnabled; 6938 6939 qcamera_callback_argm_t cbArg; 6940 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6941 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6942 cbArg.msg_type = CAMERA_MSG_META_DATA; 6943 cbArg.data = hdrBuffer; 6944 cbArg.user_data = hdrBuffer; 6945 cbArg.cookie = this; 6946 cbArg.release_cb = releaseCameraMemory; 6947 rc = m_cbNotifier.notifyCallback(cbArg); 6948 if (rc != NO_ERROR) { 6949 LOGE("fail sending auto HDR notification"); 6950 hdrBuffer->release(hdrBuffer); 6951 } 6952 } 6953 6954 LOGH("hdr_scene_data: processHDRData: %d %f", 6955 hdr_scene.is_hdr_scene, 6956 hdr_scene.hdr_confidence); 6957 6958 #endif 6959 return rc; 6960 } 6961 6962 /*=========================================================================== 6963 * FUNCTION : processLEDCalibration 6964 * 6965 * DESCRIPTION: process LED calibration result 6966 * 6967 * PARAMETERS : 6968 * @value : Calibaration result 6969 * 6970 * RETURN : int32_t type of status 6971 * NO_ERROR -- success 6972 * none-zero failure code 6973 *==========================================================================*/ 6974 int32_t QCamera2HardwareInterface::processLEDCalibration(int32_t value) 6975 { 6976 int32_t rc = NO_ERROR; 6977 #ifndef VANILLA_HAL 6978 if (mParameters.getDualLedCalibration()) { 6979 LOGH("Dual LED calibration value = %d", value); 6980 int32_t data_len = sizeof(value); 6981 int32_t buffer_len = sizeof(int) //meta type 6982 + sizeof(int) //data len 6983 + data_len; //data 6984 camera_memory_t *buffer = mGetMemory(-1, 6985 buffer_len, 1, mCallbackCookie); 6986 if ( NULL == buffer ) { 6987 LOGE("Not enough memory for data"); 6988 return NO_MEMORY; 6989 } 6990 6991 int *pData = (int *)buffer->data; 6992 if (pData == NULL) { 6993 LOGE("memory data ptr is NULL"); 6994 buffer->release(buffer); 6995 return UNKNOWN_ERROR; 6996 } 6997 6998 pData[0] = QCAMERA_METADATA_LED_CALIB; 6999 pData[1] = (int)data_len; 7000 pData[2] = value; 7001 7002 qcamera_callback_argm_t cbArg; 7003 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 7004 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 7005 cbArg.msg_type = CAMERA_MSG_META_DATA; 7006 cbArg.data = buffer; 7007 cbArg.user_data = buffer; 7008 cbArg.cookie = this; 7009 cbArg.release_cb = releaseCameraMemory; 7010 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 7011 if (rc != NO_ERROR) { 7012 LOGE("fail sending notification"); 7013 buffer->release(buffer); 7014 } 7015 } 7016 #else 7017 (void)value; // unused 7018 #endif 7019 return rc; 7020 } 7021 7022 7023 /*=========================================================================== 7024 * FUNCTION : transAwbMetaToParams 7025 * 7026 * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf 7027 * 7028 * PARAMETERS : 7029 * @awb_params : awb params from metadata callback 7030 * 7031 * RETURN : int32_t type of status 7032 * NO_ERROR -- success 7033 * none-zero failure code 7034 *==========================================================================*/ 7035 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params) 7036 { 7037 mParameters.updateAWBParams(awb_params); 7038 return NO_ERROR; 7039 } 7040 7041 /*=========================================================================== 7042 * FUNCTION : processPrepSnapshotDone 7043 * 7044 * DESCRIPTION: process prep snapshot done event 7045 * 7046 * PARAMETERS : 7047 * @prep_snapshot_state : state of prepare snapshot done. In other words, 7048 * i.e. whether need future frames for capture. 7049 * 7050 * RETURN : int32_t type of status 7051 * NO_ERROR -- success 7052 * none-zero failure code 7053 *==========================================================================*/ 7054 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent( 7055 cam_prep_snapshot_state_t prep_snapshot_state) 7056 { 7057 int32_t ret = NO_ERROR; 7058 LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d", 7059 prep_snapshot_state); 7060 if (m_channels[QCAMERA_CH_TYPE_ZSL] && 7061 prep_snapshot_state == NEED_FUTURE_FRAME) { 7062 LOGH("already handled in mm-camera-intf, no ops here"); 7063 if (isRetroPicture()) { 7064 mParameters.setAecLock("true"); 7065 mParameters.commitParameters(); 7066 m_bLedAfAecLock = TRUE; 7067 } 7068 } 7069 return ret; 7070 } 7071 7072 /*=========================================================================== 7073 * FUNCTION : processASDUpdate 7074 * 7075 * DESCRIPTION: process ASD update event 7076 * 7077 * PARAMETERS : 7078 * @scene: selected scene mode 7079 * 7080 * RETURN : int32_t type of status 7081 * NO_ERROR -- success 7082 * none-zero failure code 7083 *==========================================================================*/ 7084 int32_t QCamera2HardwareInterface::processASDUpdate( 7085 __unused cam_asd_decision_t asd_decision) 7086 { 7087 #ifndef VANILLA_HAL 7088 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) { 7089 size_t data_len = sizeof(cam_auto_scene_t); 7090 size_t buffer_len = 1 *sizeof(int) //meta type 7091 + 1 *sizeof(int) //data len 7092 + data_len; //data 7093 camera_memory_t *asdBuffer = mGetMemory(-1, 7094 buffer_len, 1, mCallbackCookie); 7095 if ( NULL == asdBuffer ) { 7096 LOGE("Not enough memory for histogram data"); 7097 return NO_MEMORY; 7098 } 7099 7100 int *pASDData = (int *)asdBuffer->data; 7101 if (pASDData == NULL) { 7102 LOGE("memory data ptr is NULL"); 7103 return UNKNOWN_ERROR; 7104 } 7105 7106 pASDData[0] = CAMERA_META_DATA_ASD; 7107 pASDData[1] = (int)data_len; 7108 pASDData[2] = asd_decision.detected_scene; 7109 7110 qcamera_callback_argm_t cbArg; 7111 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 7112 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 7113 cbArg.msg_type = CAMERA_MSG_META_DATA; 7114 cbArg.data = asdBuffer; 7115 cbArg.user_data = asdBuffer; 7116 cbArg.cookie = this; 7117 cbArg.release_cb = releaseCameraMemory; 7118 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 7119 if (rc != NO_ERROR) { 7120 LOGE("fail sending notification"); 7121 asdBuffer->release(asdBuffer); 7122 } 7123 } 7124 #endif 7125 return NO_ERROR; 7126 } 7127 7128 /*=========================================================================== 7129 * FUNCTION : processJpegNotify 7130 * 7131 * DESCRIPTION: process jpeg event 7132 * 7133 * PARAMETERS : 7134 * @jpeg_evt: ptr to jpeg event payload 7135 * 7136 * RETURN : int32_t type of status 7137 * NO_ERROR -- success 7138 * none-zero failure code 7139 *==========================================================================*/ 7140 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt) 7141 { 7142 return m_postprocessor.processJpegEvt(jpeg_evt); 7143 } 7144 7145 7146 /*=========================================================================== 7147 * FUNCTION : processDualCamFovControl 7148 * 7149 * DESCRIPTION: Based on the result collected from FOV control- 7150 * 1. Switch the master camera if needed 7151 * 2. Toggle the Low Power Mode for slave camera 7152 * 7153 * PARAMETERS : none 7154 * 7155 * RETURN : none 7156 *==========================================================================*/ 7157 void QCamera2HardwareInterface::processDualCamFovControl() 7158 { 7159 uint32_t activeCameras; 7160 bool bundledSnapshot; 7161 fov_control_result_t fovControlResult; 7162 cam_sync_type_t camMasterSnapshot; 7163 7164 if (!isDualCamera()) { 7165 return; 7166 } 7167 7168 fovControlResult = m_pFovControl->getFovControlResult(); 7169 7170 if (fovControlResult.isValid) { 7171 activeCameras = fovControlResult.activeCameras; 7172 bundledSnapshot = fovControlResult.snapshotPostProcess; 7173 camMasterSnapshot = fovControlResult.camMasterPreview; 7174 7175 processCameraControl(activeCameras, bundledSnapshot); 7176 switchCameraCb(fovControlResult.camMasterPreview); 7177 } 7178 } 7179 7180 /*=========================================================================== 7181 * FUNCTION : processCameraControl 7182 * 7183 * DESCRIPTION: Suspend and resume camera 7184 * 7185 * PARAMETERS : 7186 * 7187 * RETURN : int32_t type of status 7188 * NO_ERROR -- success 7189 * none-zero failure code 7190 *==========================================================================*/ 7191 int32_t QCamera2HardwareInterface::processCameraControl( 7192 uint32_t activeCameras, 7193 bool bundledSnapshot) 7194 { 7195 int32_t ret = NO_ERROR; 7196 7197 //Update camera status to internal channel 7198 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 7199 if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) { 7200 ret = m_channels[i]->processCameraControl(activeCameras, bundledSnapshot); 7201 if (ret != NO_ERROR) { 7202 LOGE("Channel Switch Failed"); 7203 break; 7204 } 7205 } 7206 } 7207 7208 if ((activeCameras != mActiveCameras) || 7209 ((activeCameras == MM_CAMERA_DUAL_CAM) && (bundledSnapshot != mBundledSnapshot))) { 7210 7211 if (activeCameras != mActiveCameras) { 7212 //Set camera controls to parameter and back-end 7213 ret = mParameters.setCameraControls(activeCameras); 7214 } 7215 7216 mParameters.setBundledSnapshot(bundledSnapshot); 7217 mParameters.setNumOfSnapshot(); 7218 7219 LOGH("mActiveCameras = %d to %d, bundledSnapshot = %d to %d", 7220 mActiveCameras, activeCameras, mBundledSnapshot, bundledSnapshot); 7221 mActiveCameras = activeCameras; 7222 mBundledSnapshot = bundledSnapshot; 7223 } 7224 7225 return ret; 7226 } 7227 7228 /*=========================================================================== 7229 * FUNCTION : switchCameraCb 7230 * 7231 * DESCRIPTION: switch camera's in case of dual camera 7232 * 7233 * PARAMETERS : 7234 * @camMaster : Master camera 7235 * 7236 * RETURN : int32_t type of status 7237 * NO_ERROR -- success 7238 * none-zero failure code 7239 *==========================================================================*/ 7240 int32_t QCamera2HardwareInterface::switchCameraCb(uint32_t camMaster) 7241 { 7242 int32_t ret = NO_ERROR; 7243 7244 if (mActiveCameras & camMaster) { 7245 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 7246 if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) { 7247 ret = m_channels[i]->switchChannelCb(camMaster); 7248 if (ret != NO_ERROR) { 7249 LOGE("Channel Switch Failed"); 7250 break; 7251 } 7252 } 7253 } 7254 7255 if (mMasterCamera != camMaster) { 7256 if (ret == NO_ERROR) { 7257 //Trigger Event to modules to update Master info 7258 mParameters.setSwitchCamera(camMaster); 7259 } 7260 } 7261 // Update master camera 7262 mMasterCamera = camMaster; 7263 } 7264 7265 return ret; 7266 } 7267 7268 /*=========================================================================== 7269 * FUNCTION : lockAPI 7270 * 7271 * DESCRIPTION: lock to process API 7272 * 7273 * PARAMETERS : none 7274 * 7275 * RETURN : none 7276 *==========================================================================*/ 7277 void QCamera2HardwareInterface::lockAPI() 7278 { 7279 pthread_mutex_lock(&m_lock); 7280 } 7281 7282 /*=========================================================================== 7283 * FUNCTION : waitAPIResult 7284 * 7285 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will 7286 * return only cerntain API event type arrives 7287 * 7288 * PARAMETERS : 7289 * @api_evt : API event type 7290 * 7291 * RETURN : none 7292 *==========================================================================*/ 7293 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt, 7294 qcamera_api_result_t *apiResult) 7295 { 7296 LOGD("wait for API result of evt (%d)", api_evt); 7297 int resultReceived = 0; 7298 while (!resultReceived) { 7299 pthread_cond_wait(&m_cond, &m_lock); 7300 if (m_apiResultList != NULL) { 7301 api_result_list *apiResultList = m_apiResultList; 7302 api_result_list *apiResultListPrevious = m_apiResultList; 7303 while (apiResultList != NULL) { 7304 if (apiResultList->result.request_api == api_evt) { 7305 resultReceived = 1; 7306 *apiResult = apiResultList->result; 7307 apiResultListPrevious->next = apiResultList->next; 7308 if (apiResultList == m_apiResultList) { 7309 m_apiResultList = apiResultList->next; 7310 } 7311 free(apiResultList); 7312 break; 7313 } 7314 else { 7315 apiResultListPrevious = apiResultList; 7316 apiResultList = apiResultList->next; 7317 } 7318 } 7319 } 7320 } 7321 LOGD("return (%d) from API result wait for evt (%d)", 7322 apiResult->status, api_evt); 7323 } 7324 7325 7326 /*=========================================================================== 7327 * FUNCTION : unlockAPI 7328 * 7329 * DESCRIPTION: API processing is done, unlock 7330 * 7331 * PARAMETERS : none 7332 * 7333 * RETURN : none 7334 *==========================================================================*/ 7335 void QCamera2HardwareInterface::unlockAPI() 7336 { 7337 pthread_mutex_unlock(&m_lock); 7338 } 7339 7340 /*=========================================================================== 7341 * FUNCTION : signalAPIResult 7342 * 7343 * DESCRIPTION: signal condition viarable that cerntain API event type arrives 7344 * 7345 * PARAMETERS : 7346 * @result : API result 7347 * 7348 * RETURN : none 7349 *==========================================================================*/ 7350 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result) 7351 { 7352 7353 pthread_mutex_lock(&m_lock); 7354 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list)); 7355 if (apiResult == NULL) { 7356 LOGE("ERROR: malloc for api result failed, Result will not be sent"); 7357 goto malloc_failed; 7358 } 7359 apiResult->result = *result; 7360 apiResult->next = NULL; 7361 if (m_apiResultList == NULL) m_apiResultList = apiResult; 7362 else { 7363 api_result_list *apiResultList = m_apiResultList; 7364 while(apiResultList->next != NULL) apiResultList = apiResultList->next; 7365 apiResultList->next = apiResult; 7366 } 7367 malloc_failed: 7368 pthread_cond_broadcast(&m_cond); 7369 pthread_mutex_unlock(&m_lock); 7370 } 7371 7372 /*=========================================================================== 7373 * FUNCTION : signalEvtResult 7374 * 7375 * DESCRIPTION: signal condition variable that certain event was processed 7376 * 7377 * PARAMETERS : 7378 * @result : Event result 7379 * 7380 * RETURN : none 7381 *==========================================================================*/ 7382 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result) 7383 { 7384 pthread_mutex_lock(&m_evtLock); 7385 m_evtResult = *result; 7386 pthread_cond_signal(&m_evtCond); 7387 pthread_mutex_unlock(&m_evtLock); 7388 } 7389 7390 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel) 7391 { 7392 int32_t rc = NO_ERROR; 7393 cam_dimension_t str_dim,max_dim; 7394 QCameraChannel *pChannel; 7395 7396 max_dim.width = 0; 7397 max_dim.height = 0; 7398 7399 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) { 7400 if (m_channels[j] != NULL) { 7401 pChannel = m_channels[j]; 7402 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) { 7403 QCameraStream *pStream = pChannel->getStreamByIndex(i); 7404 if (pStream != NULL) { 7405 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 7406 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) { 7407 continue; 7408 } 7409 pStream->getFrameDimension(str_dim); 7410 if (str_dim.width > max_dim.width) { 7411 max_dim.width = str_dim.width; 7412 } 7413 if (str_dim.height > max_dim.height) { 7414 max_dim.height = str_dim.height; 7415 } 7416 } 7417 } 7418 } 7419 } 7420 7421 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) { 7422 QCameraStream *pStream = curChannel->getStreamByIndex(i); 7423 if (pStream != NULL) { 7424 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 7425 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) { 7426 continue; 7427 } 7428 pStream->getFrameDimension(str_dim); 7429 if (str_dim.width > max_dim.width) { 7430 max_dim.width = str_dim.width; 7431 } 7432 if (str_dim.height > max_dim.height) { 7433 max_dim.height = str_dim.height; 7434 } 7435 } 7436 } 7437 rc = mParameters.updateRAW(max_dim); 7438 return rc; 7439 } 7440 7441 /*=========================================================================== 7442 * FUNCTION : getPaddingInfo 7443 * 7444 * DESCRIPTION: calculate padding per stream 7445 * 7446 * PARAMETERS : 7447 * @streamType : type of stream to be added 7448 * @padding_info : Padding info. Output 7449 * 7450 * RETURN : int32_t type of status 7451 * NO_ERROR -- success 7452 * none-zero failure code 7453 *==========================================================================*/ 7454 int32_t QCamera2HardwareInterface::getPaddingInfo(cam_stream_type_t streamType, 7455 cam_padding_info_t *padding_info) 7456 { 7457 int32_t rc = NO_ERROR; 7458 if (streamType == CAM_STREAM_TYPE_ANALYSIS) { 7459 cam_analysis_info_t analysisInfo; 7460 cam_feature_mask_t featureMask; 7461 7462 featureMask = 0; 7463 mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask); 7464 rc = mParameters.getAnalysisInfo( 7465 ((mParameters.getRecordingHintValue() == true) && 7466 mParameters.fdModeInVideo()), 7467 featureMask, 7468 &analysisInfo); 7469 if (rc != NO_ERROR) { 7470 LOGE("getAnalysisInfo failed, ret = %d", rc); 7471 return rc; 7472 } 7473 7474 *padding_info = analysisInfo.analysis_padding_info; 7475 } else { 7476 *padding_info = 7477 gCamCapability[mCameraId]->padding_info; 7478 if (streamType == CAM_STREAM_TYPE_PREVIEW || streamType == CAM_STREAM_TYPE_POSTVIEW) { 7479 padding_info->width_padding = mSurfaceStridePadding; 7480 padding_info->height_padding = CAM_PAD_TO_2; 7481 } 7482 if((!needReprocess()) 7483 || (streamType != CAM_STREAM_TYPE_SNAPSHOT) 7484 || (!mParameters.isLLNoiseEnabled())) { 7485 padding_info->offset_info.offset_x = 0; 7486 padding_info->offset_info.offset_y = 0; 7487 } 7488 } 7489 return rc; 7490 } 7491 7492 /*=========================================================================== 7493 * FUNCTION : addStreamToChannel 7494 * 7495 * DESCRIPTION: add a stream into a channel 7496 * 7497 * PARAMETERS : 7498 * @pChannel : ptr to channel obj 7499 * @streamType : type of stream to be added 7500 * @streamCB : callback of stream 7501 * @userData : user data ptr to callback 7502 * 7503 * RETURN : int32_t type of status 7504 * NO_ERROR -- success 7505 * none-zero failure code 7506 *==========================================================================*/ 7507 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel, 7508 cam_stream_type_t streamType, 7509 stream_cb_routine streamCB, 7510 void *userData) 7511 { 7512 int32_t rc = NO_ERROR; 7513 QCameraHeapMemory *pStreamInfo = NULL; 7514 uint32_t cam_type = MM_CAMERA_TYPE_MAIN; 7515 bool needAuxStream = FALSE; 7516 7517 if (streamType == CAM_STREAM_TYPE_RAW) { 7518 prepareRawStream(pChannel); 7519 } 7520 7521 if (isDualCamera()) { 7522 if (!((mParameters.isDCmAsymmetricSnapMode()) && 7523 (streamType == CAM_STREAM_TYPE_SNAPSHOT))) { 7524 cam_type |= MM_CAMERA_TYPE_AUX; 7525 } else { 7526 needAuxStream = TRUE; 7527 } 7528 } 7529 7530 pStreamInfo = allocateStreamInfoBuf(streamType, 7531 getStreamRefCount(streamType, cam_type), cam_type); 7532 if (pStreamInfo == NULL) { 7533 LOGE("no mem for stream info buf"); 7534 return NO_MEMORY; 7535 } 7536 7537 bool bDynAllocBuf = false; 7538 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) { 7539 bDynAllocBuf = true; 7540 } 7541 7542 cam_padding_info_t padding_info; 7543 getPaddingInfo(streamType, &padding_info); 7544 7545 bool deferAllocation = needDeferred(streamType); 7546 LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d", 7547 deferAllocation, bDynAllocBuf, streamType); 7548 rc = pChannel->addStream(*this, 7549 pStreamInfo, NULL, &padding_info, 7550 streamCB, userData, bDynAllocBuf, 7551 deferAllocation, ROTATE_0, cam_type); 7552 7553 if (rc != NO_ERROR) { 7554 LOGE("add stream type (%d) cam = %d failed, ret = %d", 7555 streamType, cam_type, rc); 7556 return rc; 7557 } 7558 7559 /*Add stream for Asymmetric dual camera use case*/ 7560 if (needAuxStream) { 7561 cam_type = MM_CAMERA_TYPE_AUX; 7562 pStreamInfo = allocateStreamInfoBuf(streamType, 7563 getStreamRefCount(streamType, cam_type), cam_type); 7564 if (pStreamInfo == NULL) { 7565 LOGE("no mem for stream info buf"); 7566 return NO_MEMORY; 7567 } 7568 rc = pChannel->addStream(*this, 7569 pStreamInfo, NULL, &padding_info, 7570 streamCB, userData, bDynAllocBuf, 7571 deferAllocation, ROTATE_0, cam_type); 7572 if (rc != NO_ERROR) { 7573 LOGE("add stream type (%d) cam = %d failed, ret = %d", 7574 streamType, cam_type, rc); 7575 return rc; 7576 } 7577 } 7578 return rc; 7579 } 7580 7581 /*=========================================================================== 7582 * FUNCTION : addPreviewChannel 7583 * 7584 * DESCRIPTION: add a preview channel that contains a preview stream 7585 * 7586 * PARAMETERS : none 7587 * 7588 * RETURN : int32_t type of status 7589 * NO_ERROR -- success 7590 * none-zero failure code 7591 *==========================================================================*/ 7592 int32_t QCamera2HardwareInterface::addPreviewChannel() 7593 { 7594 int32_t rc = NO_ERROR; 7595 QCameraChannel *pChannel = NULL; 7596 char value[PROPERTY_VALUE_MAX]; 7597 bool raw_yuv = false; 7598 7599 7600 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 7601 // if we had preview channel before, delete it first 7602 delete m_channels[QCAMERA_CH_TYPE_PREVIEW]; 7603 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL; 7604 } 7605 7606 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW); 7607 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7608 if (NULL == pChannel) { 7609 LOGE("no mem for preview channel"); 7610 return NO_MEMORY; 7611 } 7612 7613 // preview only channel, don't need bundle attr and cb 7614 rc = pChannel->init(NULL, NULL, NULL); 7615 if (rc != NO_ERROR) { 7616 LOGE("init preview channel failed, ret = %d", rc); 7617 delete pChannel; 7618 return rc; 7619 } 7620 7621 // meta data stream always coexists with preview if applicable 7622 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7623 metadata_stream_cb_routine, this); 7624 if (rc != NO_ERROR) { 7625 LOGE("add metadata stream failed, ret = %d", rc); 7626 delete pChannel; 7627 return rc; 7628 } 7629 7630 if (isRdiMode()) { 7631 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 7632 rdi_mode_stream_cb_routine, this); 7633 } else { 7634 if (isNoDisplayMode()) { 7635 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7636 nodisplay_preview_stream_cb_routine, this); 7637 } else { 7638 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7639 preview_stream_cb_routine, this); 7640 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) { 7641 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 7642 synchronous_stream_cb_routine); 7643 } 7644 } 7645 } 7646 7647 if (rc != NO_ERROR) { 7648 LOGE("add raw/preview stream failed, ret = %d", rc); 7649 delete pChannel; 7650 return rc; 7651 } 7652 7653 if (((mParameters.fdModeInVideo()) 7654 || (mParameters.getDcrf() == true) 7655 || (mParameters.getRecordingHintValue() != true)) 7656 && (!isSecureMode())) { 7657 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 7658 NULL, this); 7659 if (rc != NO_ERROR) { 7660 LOGE("add Analysis stream failed, ret = %d", rc); 7661 delete pChannel; 7662 return rc; 7663 } 7664 } 7665 7666 property_get("persist.camera.raw_yuv", value, "0"); 7667 raw_yuv = atoi(value) > 0 ? true : false; 7668 if ( raw_yuv ) { 7669 rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW, 7670 preview_raw_stream_cb_routine,this); 7671 if ( rc != NO_ERROR ) { 7672 LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc); 7673 delete pChannel; 7674 return rc; 7675 } 7676 } 7677 7678 if (rc != NO_ERROR) { 7679 LOGE("add preview stream failed, ret = %d", rc); 7680 delete pChannel; 7681 return rc; 7682 } 7683 7684 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel; 7685 return rc; 7686 } 7687 7688 /*=========================================================================== 7689 * FUNCTION : addVideoChannel 7690 * 7691 * DESCRIPTION: add a video channel that contains a video stream 7692 * 7693 * PARAMETERS : none 7694 * 7695 * RETURN : int32_t type of status 7696 * NO_ERROR -- success 7697 * none-zero failure code 7698 *==========================================================================*/ 7699 int32_t QCamera2HardwareInterface::addVideoChannel() 7700 { 7701 int32_t rc = NO_ERROR; 7702 QCameraVideoChannel *pChannel = NULL; 7703 7704 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) { 7705 // if we had video channel before, delete it first 7706 delete m_channels[QCAMERA_CH_TYPE_VIDEO]; 7707 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL; 7708 } 7709 7710 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO); 7711 pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops); 7712 if (NULL == pChannel) { 7713 LOGE("no mem for video channel"); 7714 return NO_MEMORY; 7715 } 7716 7717 if (isLowPowerMode()) { 7718 mm_camera_channel_attr_t attr; 7719 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7720 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7721 attr.look_back = 0; //wait for future frame for liveshot 7722 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7723 attr.water_mark = 1; //hold min buffers possible in Q 7724 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7725 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this); 7726 } else { 7727 // preview only channel, don't need bundle attr and cb 7728 rc = pChannel->init(NULL, NULL, NULL); 7729 } 7730 7731 if (rc != 0) { 7732 LOGE("init video channel failed, ret = %d", rc); 7733 delete pChannel; 7734 return rc; 7735 } 7736 7737 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO, 7738 video_stream_cb_routine, this); 7739 7740 if (rc != NO_ERROR) { 7741 LOGE("add video stream failed, ret = %d", rc); 7742 delete pChannel; 7743 return rc; 7744 } 7745 7746 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel; 7747 return rc; 7748 } 7749 7750 /*=========================================================================== 7751 * FUNCTION : addSnapshotChannel 7752 * 7753 * DESCRIPTION: add a snapshot channel that contains a snapshot stream 7754 * 7755 * PARAMETERS : none 7756 * 7757 * RETURN : int32_t type of status 7758 * NO_ERROR -- success 7759 * none-zero failure code 7760 * NOTE : Add this channel for live snapshot usecase. Regular capture will 7761 * use addCaptureChannel. 7762 *==========================================================================*/ 7763 int32_t QCamera2HardwareInterface::addSnapshotChannel() 7764 { 7765 int32_t rc = NO_ERROR; 7766 QCameraChannel *pChannel = NULL; 7767 7768 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) { 7769 // if we had ZSL channel before, delete it first 7770 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 7771 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL; 7772 } 7773 7774 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT); 7775 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7776 if (NULL == pChannel) { 7777 LOGE("no mem for snapshot channel"); 7778 return NO_MEMORY; 7779 } 7780 7781 mm_camera_channel_attr_t attr; 7782 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7783 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 7784 attr.look_back = 0; //wait for future frame for liveshot 7785 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7786 attr.water_mark = 1; //hold min buffers possible in Q 7787 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7788 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW; 7789 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this); 7790 if (rc != NO_ERROR) { 7791 LOGE("init snapshot channel failed, ret = %d", rc); 7792 delete pChannel; 7793 return rc; 7794 } 7795 7796 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 7797 NULL, NULL); 7798 if (rc != NO_ERROR) { 7799 LOGE("add snapshot stream failed, ret = %d", rc); 7800 delete pChannel; 7801 return rc; 7802 } 7803 7804 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel; 7805 return rc; 7806 } 7807 7808 /*=========================================================================== 7809 * FUNCTION : addRawChannel 7810 * 7811 * DESCRIPTION: add a raw channel that contains a raw image stream 7812 * 7813 * PARAMETERS : none 7814 * 7815 * RETURN : int32_t type of status 7816 * NO_ERROR -- success 7817 * none-zero failure code 7818 *==========================================================================*/ 7819 int32_t QCamera2HardwareInterface::addRawChannel() 7820 { 7821 int32_t rc = NO_ERROR; 7822 QCameraChannel *pChannel = NULL; 7823 7824 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) { 7825 // if we had raw channel before, delete it first 7826 delete m_channels[QCAMERA_CH_TYPE_RAW]; 7827 m_channels[QCAMERA_CH_TYPE_RAW] = NULL; 7828 } 7829 7830 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW); 7831 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 7832 if (NULL == pChannel) { 7833 LOGE("no mem for raw channel"); 7834 return NO_MEMORY; 7835 } 7836 7837 if (mParameters.getofflineRAW()) { 7838 mm_camera_channel_attr_t attr; 7839 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7840 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7841 attr.look_back = mParameters.getZSLBackLookCount(); 7842 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7843 attr.water_mark = 1; 7844 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7845 rc = pChannel->init(&attr, raw_channel_cb_routine, this); 7846 if (rc != NO_ERROR) { 7847 LOGE("init RAW channel failed, ret = %d", rc); 7848 delete pChannel; 7849 return rc; 7850 } 7851 } else { 7852 rc = pChannel->init(NULL, NULL, NULL); 7853 if (rc != NO_ERROR) { 7854 LOGE("init raw channel failed, ret = %d", rc); 7855 delete pChannel; 7856 return rc; 7857 } 7858 } 7859 7860 if (!mParameters.isZSLMode()) { 7861 // meta data stream always coexists with snapshot in regular RAW capture case 7862 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7863 metadata_stream_cb_routine, this); 7864 if (rc != NO_ERROR) { 7865 LOGE("add metadata stream failed, ret = %d", rc); 7866 delete pChannel; 7867 return rc; 7868 } 7869 } 7870 7871 if (mParameters.getofflineRAW()) { 7872 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 7873 NULL, this); 7874 } else if(isSecureMode()) { 7875 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 7876 secure_stream_cb_routine, this); 7877 } else { 7878 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 7879 raw_stream_cb_routine, this); 7880 } 7881 if (rc != NO_ERROR) { 7882 LOGE("add snapshot stream failed, ret = %d", rc); 7883 delete pChannel; 7884 return rc; 7885 } 7886 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel; 7887 return rc; 7888 } 7889 7890 /*=========================================================================== 7891 * FUNCTION : addZSLChannel 7892 * 7893 * DESCRIPTION: add a ZSL channel that contains a preview stream and 7894 * a snapshot stream 7895 * 7896 * PARAMETERS : none 7897 * 7898 * RETURN : int32_t type of status 7899 * NO_ERROR -- success 7900 * none-zero failure code 7901 *==========================================================================*/ 7902 int32_t QCamera2HardwareInterface::addZSLChannel() 7903 { 7904 int32_t rc = NO_ERROR; 7905 QCameraPicChannel *pChannel = NULL; 7906 char value[PROPERTY_VALUE_MAX]; 7907 bool raw_yuv = false; 7908 7909 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) { 7910 // if we had ZSL channel before, delete it first 7911 delete m_channels[QCAMERA_CH_TYPE_ZSL]; 7912 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL; 7913 } 7914 7915 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL); 7916 pChannel = new QCameraPicChannel(handle, 7917 mCameraHandle->ops); 7918 if (NULL == pChannel) { 7919 LOGE("no mem for ZSL channel"); 7920 return NO_MEMORY; 7921 } 7922 7923 // ZSL channel, init with bundle attr and cb 7924 mm_camera_channel_attr_t attr; 7925 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7926 if (mParameters.isSceneSelectionEnabled()) { 7927 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 7928 } else { 7929 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7930 } 7931 attr.look_back = mParameters.getZSLBackLookCount(); 7932 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7933 if (mParameters.isOEMFeatEnabled()) { 7934 LOGD("EDGE SMOOTH frameskip enabled"); 7935 attr.post_frame_skip += mParameters.isOEMFeatFrameSkipEnabled(); 7936 } 7937 attr.water_mark = mParameters.getZSLQueueDepth(); 7938 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7939 attr.user_expected_frame_id = 7940 mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0; 7941 7942 //Enabled matched queue 7943 if (isFrameSyncEnabled()) { 7944 LOGH("Enabling frame sync for dual camera, camera Id: %d", 7945 mCameraId); 7946 attr.enable_frame_sync = 1; 7947 } 7948 rc = pChannel->init(&attr, 7949 zsl_channel_cb, 7950 this); 7951 if (rc != 0) { 7952 LOGE("init ZSL channel failed, ret = %d", rc); 7953 delete pChannel; 7954 return rc; 7955 } 7956 7957 // meta data stream always coexists with preview if applicable 7958 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7959 metadata_stream_cb_routine, this); 7960 if (rc != NO_ERROR) { 7961 LOGE("add metadata stream failed, ret = %d", rc); 7962 delete pChannel; 7963 return rc; 7964 } 7965 7966 if (isNoDisplayMode()) { 7967 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7968 nodisplay_preview_stream_cb_routine, this); 7969 } else { 7970 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7971 preview_stream_cb_routine, this); 7972 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) { 7973 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 7974 synchronous_stream_cb_routine); 7975 } 7976 } 7977 if (rc != NO_ERROR) { 7978 LOGE("add preview stream failed, ret = %d", rc); 7979 delete pChannel; 7980 return rc; 7981 } 7982 7983 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 7984 NULL, this); 7985 if (rc != NO_ERROR) { 7986 LOGE("add snapshot stream failed, ret = %d", rc); 7987 delete pChannel; 7988 return rc; 7989 } 7990 7991 if (!isSecureMode()) { 7992 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 7993 NULL, this); 7994 if (rc != NO_ERROR) { 7995 LOGE("add Analysis stream failed, ret = %d", rc); 7996 delete pChannel; 7997 return rc; 7998 } 7999 } 8000 8001 property_get("persist.camera.raw_yuv", value, "0"); 8002 raw_yuv = atoi(value) > 0 ? true : false; 8003 if (raw_yuv) { 8004 rc = addStreamToChannel(pChannel, 8005 CAM_STREAM_TYPE_RAW, 8006 preview_raw_stream_cb_routine, 8007 this); 8008 if (rc != NO_ERROR) { 8009 LOGE("add raw stream failed, ret = %d", rc); 8010 delete pChannel; 8011 return rc; 8012 } 8013 } 8014 8015 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel; 8016 return rc; 8017 } 8018 8019 /*=========================================================================== 8020 * FUNCTION : addCaptureChannel 8021 * 8022 * DESCRIPTION: add a capture channel that contains a snapshot stream 8023 * and a postview stream 8024 * 8025 * PARAMETERS : none 8026 * 8027 * RETURN : int32_t type of status 8028 * NO_ERROR -- success 8029 * none-zero failure code 8030 * NOTE : Add this channel for regular capture usecase. 8031 * For Live snapshot usecase, use addSnapshotChannel. 8032 *==========================================================================*/ 8033 int32_t QCamera2HardwareInterface::addCaptureChannel() 8034 { 8035 int32_t rc = NO_ERROR; 8036 QCameraPicChannel *pChannel = NULL; 8037 char value[PROPERTY_VALUE_MAX]; 8038 bool raw_yuv = false; 8039 8040 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) { 8041 delete m_channels[QCAMERA_CH_TYPE_CAPTURE]; 8042 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL; 8043 } 8044 8045 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE); 8046 pChannel = new QCameraPicChannel(handle, mCameraHandle->ops); 8047 if (NULL == pChannel) { 8048 LOGE("no mem for capture channel"); 8049 return NO_MEMORY; 8050 } 8051 8052 // Capture channel, only need snapshot and postview streams start together 8053 mm_camera_channel_attr_t attr; 8054 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 8055 if ( mLongshotEnabled ) { 8056 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 8057 attr.look_back = mParameters.getZSLBackLookCount(); 8058 attr.water_mark = mParameters.getZSLQueueDepth(); 8059 } else { 8060 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 8061 } 8062 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 8063 8064 rc = pChannel->init(&attr, 8065 capture_channel_cb_routine, 8066 this); 8067 if (rc != NO_ERROR) { 8068 LOGE("init capture channel failed, ret = %d", rc); 8069 delete pChannel; 8070 return rc; 8071 } 8072 8073 // meta data stream always coexists with snapshot in regular capture case 8074 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 8075 metadata_stream_cb_routine, this); 8076 if (rc != NO_ERROR) { 8077 LOGE("add metadata stream failed, ret = %d", rc); 8078 delete pChannel; 8079 return rc; 8080 } 8081 8082 if (mLongshotEnabled) { 8083 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 8084 preview_stream_cb_routine, this); 8085 if (rc != NO_ERROR) { 8086 LOGE("add preview stream failed, ret = %d", rc); 8087 delete pChannel; 8088 return rc; 8089 } 8090 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) { 8091 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 8092 synchronous_stream_cb_routine); 8093 } 8094 //Not adding the postview stream to the capture channel if Quadra CFA is enabled. 8095 } else if (!mParameters.getQuadraCfa()) { 8096 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW, 8097 NULL, this); 8098 if (rc != NO_ERROR) { 8099 LOGE("add postview stream failed, ret = %d", rc); 8100 delete pChannel; 8101 return rc; 8102 } 8103 } 8104 8105 if (!mParameters.getofflineRAW()) { 8106 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 8107 NULL, this); 8108 if (rc != NO_ERROR) { 8109 LOGE("add snapshot stream failed, ret = %d", rc); 8110 delete pChannel; 8111 return rc; 8112 } 8113 } 8114 8115 stream_cb_routine stream_cb = NULL; 8116 property_get("persist.camera.raw_yuv", value, "0"); 8117 raw_yuv = atoi(value) > 0 ? true : false; 8118 8119 if (raw_yuv) { 8120 stream_cb = snapshot_raw_stream_cb_routine; 8121 } 8122 8123 if ((raw_yuv) || (mParameters.getofflineRAW())) { 8124 rc = addStreamToChannel(pChannel, 8125 CAM_STREAM_TYPE_RAW, stream_cb, this); 8126 if (rc != NO_ERROR) { 8127 LOGE("add raw stream failed, ret = %d", rc); 8128 delete pChannel; 8129 return rc; 8130 } 8131 } 8132 8133 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel; 8134 return rc; 8135 } 8136 8137 /*=========================================================================== 8138 * FUNCTION : addMetaDataChannel 8139 * 8140 * DESCRIPTION: add a meta data channel that contains a metadata stream 8141 * 8142 * PARAMETERS : none 8143 * 8144 * RETURN : int32_t type of status 8145 * NO_ERROR -- success 8146 * none-zero failure code 8147 *==========================================================================*/ 8148 int32_t QCamera2HardwareInterface::addMetaDataChannel() 8149 { 8150 int32_t rc = NO_ERROR; 8151 QCameraChannel *pChannel = NULL; 8152 8153 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) { 8154 delete m_channels[QCAMERA_CH_TYPE_METADATA]; 8155 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL; 8156 } 8157 8158 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA); 8159 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 8160 if (NULL == pChannel) { 8161 LOGE("no mem for metadata channel"); 8162 return NO_MEMORY; 8163 } 8164 8165 rc = pChannel->init(NULL, 8166 NULL, 8167 NULL); 8168 if (rc != NO_ERROR) { 8169 LOGE("init metadata channel failed, ret = %d", rc); 8170 delete pChannel; 8171 return rc; 8172 } 8173 8174 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 8175 metadata_stream_cb_routine, this); 8176 if (rc != NO_ERROR) { 8177 LOGE("add metadata stream failed, ret = %d", rc); 8178 delete pChannel; 8179 return rc; 8180 } 8181 8182 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel; 8183 return rc; 8184 } 8185 8186 /*=========================================================================== 8187 * FUNCTION : addCallbackChannel 8188 * 8189 * DESCRIPTION: add a callback channel that contains a callback stream 8190 * 8191 * PARAMETERS : none 8192 * 8193 * RETURN : int32_t type of status 8194 * NO_ERROR -- success 8195 * none-zero failure code 8196 *==========================================================================*/ 8197 int32_t QCamera2HardwareInterface::addCallbackChannel() 8198 { 8199 int32_t rc = NO_ERROR; 8200 QCameraChannel *pChannel = NULL; 8201 8202 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) { 8203 delete m_channels[QCAMERA_CH_TYPE_CALLBACK]; 8204 m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL; 8205 } 8206 8207 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK); 8208 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 8209 if (NULL == pChannel) { 8210 LOGE("no mem for callback channel"); 8211 return NO_MEMORY; 8212 } 8213 8214 rc = pChannel->init(NULL, NULL, this); 8215 if (rc != NO_ERROR) { 8216 LOGE("init callback channel failed, ret = %d", 8217 rc); 8218 delete pChannel; 8219 return rc; 8220 } 8221 8222 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK, 8223 callback_stream_cb_routine, this); 8224 if (rc != NO_ERROR) { 8225 LOGE("add callback stream failed, ret = %d", rc); 8226 delete pChannel; 8227 return rc; 8228 } 8229 8230 m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel; 8231 return rc; 8232 } 8233 8234 8235 /*=========================================================================== 8236 * FUNCTION : addAnalysisChannel 8237 * 8238 * DESCRIPTION: add a analysis channel that contains a analysis stream 8239 * 8240 * PARAMETERS : none 8241 * 8242 * RETURN : int32_t type of status 8243 * NO_ERROR -- success 8244 * none-zero failure code 8245 *==========================================================================*/ 8246 int32_t QCamera2HardwareInterface::addAnalysisChannel() 8247 { 8248 int32_t rc = NO_ERROR; 8249 QCameraChannel *pChannel = NULL; 8250 8251 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) { 8252 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS]; 8253 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL; 8254 } 8255 8256 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS); 8257 pChannel = new QCameraChannel(handle, mCameraHandle->ops); 8258 if (NULL == pChannel) { 8259 LOGE("no mem for metadata channel"); 8260 return NO_MEMORY; 8261 } 8262 8263 rc = pChannel->init(NULL, NULL, this); 8264 if (rc != NO_ERROR) { 8265 LOGE("init Analysis channel failed, ret = %d", rc); 8266 delete pChannel; 8267 return rc; 8268 } 8269 8270 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 8271 NULL, this); 8272 if (rc != NO_ERROR) { 8273 LOGE("add Analysis stream failed, ret = %d", rc); 8274 delete pChannel; 8275 return rc; 8276 } 8277 8278 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel; 8279 return rc; 8280 } 8281 8282 8283 /*=========================================================================== 8284 * FUNCTION : getPPConfig 8285 * 8286 * DESCRIPTION: get Post processing configaration data 8287 * 8288 * PARAMETERS : 8289 * @pp config: pp config structure pointer, 8290 * @curIndex: current pp channel index 8291 * @multipass: Flag if multipass prcessing enabled. 8292 * 8293 * RETURN : int32_t type of status 8294 * NO_ERROR -- success 8295 * none-zero failure code 8296 *==========================================================================*/ 8297 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config, 8298 int8_t curIndex, bool multipass) 8299 { 8300 int32_t rc = NO_ERROR; 8301 int32_t feature_set = 0; 8302 8303 if (multipass) { 8304 LOGW("Multi pass enabled. Total Pass = %d, cur index = %d", 8305 mParameters.getReprocCount(), curIndex); 8306 } 8307 8308 LOGH("Supported pproc feature mask = %llx", 8309 gCamCapability[mCameraId]->qcom_supported_feature_mask); 8310 cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask; 8311 int32_t zoomLevel = mParameters.getParmZoomLevel(); 8312 uint32_t rotation = mParameters.getJpegRotation(); 8313 int32_t effect = mParameters.getEffectValue(); 8314 8315 pp_config.cur_reproc_count = curIndex + 1; 8316 pp_config.total_reproc_count = mParameters.getReprocCount(); 8317 8318 //Checking what feature mask to enable 8319 if (curIndex == 0) { 8320 if (mParameters.getQuadraCfa()) { 8321 feature_set = 2; 8322 } else { 8323 feature_set = 0; 8324 } 8325 } else if (curIndex == 1) { 8326 if (mParameters.getQuadraCfa()) { 8327 feature_set = 0; 8328 } else { 8329 feature_set = 1; 8330 } 8331 } 8332 8333 switch(feature_set) { 8334 case 0: 8335 //Configure feature mask for first pass of reprocessing 8336 //check if any effects are enabled 8337 if ((CAM_EFFECT_MODE_OFF != effect) && 8338 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) { 8339 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT; 8340 pp_config.effect = effect; 8341 } 8342 8343 //check for features that need to be enabled by default like sharpness 8344 //(if supported by hw). 8345 if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) && 8346 !mParameters.isOptiZoomEnabled()) { 8347 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS; 8348 pp_config.sharpness = mParameters.getSharpness(); 8349 } 8350 8351 //check if zoom is enabled 8352 if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) { 8353 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 8354 } 8355 8356 if (mParameters.isWNREnabled() && 8357 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) { 8358 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D; 8359 pp_config.denoise2d.denoise_enable = 1; 8360 pp_config.denoise2d.process_plates = 8361 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 8362 } 8363 8364 if (isCACEnabled()) { 8365 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC; 8366 } 8367 8368 //check if rotation is required 8369 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) { 8370 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 8371 if (rotation == 0) { 8372 pp_config.rotation = ROTATE_0; 8373 } else if (rotation == 90) { 8374 pp_config.rotation = ROTATE_90; 8375 } else if (rotation == 180) { 8376 pp_config.rotation = ROTATE_180; 8377 } else if (rotation == 270) { 8378 pp_config.rotation = ROTATE_270; 8379 } 8380 } 8381 8382 if (mParameters.isHDREnabled()){ 8383 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR; 8384 pp_config.hdr_param.hdr_enable = 1; 8385 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled(); 8386 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME; 8387 } else { 8388 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR; 8389 pp_config.hdr_param.hdr_enable = 0; 8390 } 8391 8392 //check if scaling is enabled 8393 if ((feature_mask & CAM_QCOM_FEATURE_SCALE) && 8394 mParameters.isReprocScaleEnabled() && 8395 mParameters.isUnderReprocScaling()){ 8396 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 8397 mParameters.getPicSizeFromAPK( 8398 pp_config.scale_param.output_width, 8399 pp_config.scale_param.output_height); 8400 } 8401 8402 if(mParameters.isUbiFocusEnabled()) { 8403 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS; 8404 } else { 8405 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS; 8406 } 8407 8408 if(mParameters.isUbiRefocus()) { 8409 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS; 8410 pp_config.misc_buf_param.misc_buffer_index = 0; 8411 } else { 8412 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS; 8413 } 8414 8415 if(mParameters.isChromaFlashEnabled()) { 8416 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH; 8417 pp_config.flash_value = CAM_FLASH_ON; 8418 } else { 8419 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH; 8420 } 8421 8422 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) { 8423 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM; 8424 pp_config.zoom_level = (uint8_t) zoomLevel; 8425 } else { 8426 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM; 8427 } 8428 8429 if (mParameters.getofflineRAW()) { 8430 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING; 8431 } 8432 8433 if (mParameters.isTruePortraitEnabled()) { 8434 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT; 8435 pp_config.misc_buf_param.misc_buffer_index = 0; 8436 } else { 8437 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT; 8438 } 8439 8440 if(mParameters.isStillMoreEnabled()) { 8441 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE; 8442 } else { 8443 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE; 8444 } 8445 8446 if (mParameters.isOEMFeatEnabled()) { 8447 pp_config.feature_mask |= CAM_OEM_FEATURE_1; 8448 } 8449 8450 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) { 8451 if (feature_mask & CAM_QCOM_FEATURE_DSDN) { 8452 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN; 8453 } else { 8454 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS; 8455 } 8456 } 8457 8458 if ((multipass) && 8459 (m_postprocessor.getPPChannelCount() > 1) 8460 && (!mParameters.getQuadraCfa())) { 8461 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2; 8462 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION; 8463 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS; 8464 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN; 8465 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 8466 } else { 8467 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 8468 } 8469 8470 cam_dimension_t thumb_src_dim; 8471 cam_dimension_t thumb_dst_dim; 8472 mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height)); 8473 mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim); 8474 if ((thumb_dst_dim.width != thumb_src_dim.width) || 8475 (thumb_dst_dim.height != thumb_src_dim.height)) { 8476 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) { 8477 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 8478 } 8479 } 8480 8481 break; 8482 8483 case 1: 8484 //Configure feature mask for second pass of reprocessing 8485 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2; 8486 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) { 8487 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 8488 if (rotation == 0) { 8489 pp_config.rotation = ROTATE_0; 8490 } else if (rotation == 90) { 8491 pp_config.rotation = ROTATE_90; 8492 } else if (rotation == 180) { 8493 pp_config.rotation = ROTATE_180; 8494 } else if (rotation == 270) { 8495 pp_config.rotation = ROTATE_270; 8496 } 8497 } 8498 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) { 8499 if (feature_mask & CAM_QCOM_FEATURE_DSDN) { 8500 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN; 8501 } else { 8502 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS; 8503 } 8504 } 8505 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING; 8506 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING; 8507 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_BYPASS; 8508 break; 8509 8510 case 2: 8511 //Setting feature for Quadra CFA 8512 pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA; 8513 break; 8514 8515 } 8516 8517 LOGH("pproc feature mask set = %llx pass count = %d", 8518 pp_config.feature_mask, curIndex); 8519 return rc; 8520 } 8521 8522 /*=========================================================================== 8523 * FUNCTION : addReprocChannel 8524 * 8525 * DESCRIPTION: add a reprocess channel that will do reprocess on frames 8526 * coming from input channel 8527 * 8528 * PARAMETERS : 8529 * @pInputChannel : ptr to input channel whose frames will be post-processed 8530 * @cur_channel_index : Current channel index in multipass 8531 * 8532 * RETURN : Ptr to the newly created channel obj. NULL if failed. 8533 *==========================================================================*/ 8534 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel( 8535 QCameraChannel *pInputChannel, int8_t cur_channel_index) 8536 { 8537 int32_t rc = NO_ERROR; 8538 QCameraReprocessChannel *pChannel = NULL; 8539 uint32_t burst_cnt = mParameters.getNumOfSnapshots(); 8540 uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING); 8541 8542 if (pInputChannel == NULL) { 8543 LOGE("input channel obj is NULL"); 8544 return NULL; 8545 } 8546 8547 pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops); 8548 if (NULL == pChannel) { 8549 LOGE("no mem for reprocess channel"); 8550 return NULL; 8551 } 8552 8553 // Capture channel, only need snapshot and postview streams start together 8554 mm_camera_channel_attr_t attr; 8555 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 8556 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 8557 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 8558 rc = pChannel->init(&attr, 8559 postproc_channel_cb_routine, 8560 this); 8561 if (rc != NO_ERROR) { 8562 LOGE("init reprocess channel failed, ret = %d", rc); 8563 delete pChannel; 8564 return NULL; 8565 } 8566 8567 // pp feature config 8568 cam_pp_feature_config_t pp_config; 8569 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 8570 8571 rc = getPPConfig(pp_config, cur_channel_index, 8572 ((mParameters.getReprocCount() > 1) ? TRUE : FALSE)); 8573 if (rc != NO_ERROR){ 8574 LOGE("Error while creating PP config"); 8575 delete pChannel; 8576 return NULL; 8577 } 8578 8579 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC); 8580 8581 //WNR and HDR happen inline. No extra buffers needed. 8582 cam_feature_mask_t temp_feature_mask = pp_config.feature_mask; 8583 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR; 8584 if (temp_feature_mask && mParameters.isHDREnabled()) { 8585 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded()); 8586 } 8587 8588 if (mParameters.isStillMoreEnabled()) { 8589 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 8590 pp_config.burst_cnt = stillmore_config.burst_count; 8591 LOGH("Stillmore burst %d", pp_config.burst_cnt); 8592 8593 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming 8594 // number of capture is already added. In the case of liveshot, 8595 // stillmore burst is 1. This is to account for the premature decrement 8596 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) { 8597 minStreamBufNum += 1; 8598 } 8599 } 8600 8601 if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) { 8602 minStreamBufNum += mParameters.getReprocCount() - 1; 8603 burst_cnt = mParameters.getReprocCount(); 8604 if (cur_channel_index == 0) { 8605 pChannel->setReprocCount(2); 8606 } else { 8607 pChannel->setReprocCount(1); 8608 } 8609 } else { 8610 pChannel->setReprocCount(1); 8611 } 8612 8613 if (isDualCamera() && mBundledSnapshot) { 8614 minStreamBufNum += 1; 8615 } 8616 8617 // Add non inplace image lib buffers only when ppproc is present, 8618 // becuase pproc is non inplace and input buffers for img lib 8619 // are output for pproc and this number of extra buffers is required 8620 // If pproc is not there, input buffers for imglib are from snapshot stream 8621 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc(); 8622 if (temp_feature_mask && imglib_extra_bufs) { 8623 // 1 is added because getNumOfExtraBuffersForImageProc returns extra 8624 // buffers assuming number of capture is already added 8625 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1); 8626 } 8627 8628 //Mask out features that are already processed in snapshot stream. 8629 cam_feature_mask_t snapshot_feature_mask = 0; 8630 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask); 8631 8632 pp_config.feature_mask &= ~snapshot_feature_mask; 8633 LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d", 8634 snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum); 8635 8636 bool offlineReproc = needOfflineReprocessing(); 8637 if (m_postprocessor.mOfflineDataBufs != NULL) { 8638 offlineReproc = TRUE; 8639 } 8640 8641 cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info; 8642 paddingInfo.offset_info.offset_x = 0; 8643 paddingInfo.offset_info.offset_y = 0; 8644 rc = pChannel->addReprocStreamsFromSource(*this, 8645 pp_config, 8646 pInputChannel, 8647 minStreamBufNum, 8648 burst_cnt, 8649 &paddingInfo, 8650 mParameters, 8651 mLongshotEnabled, 8652 offlineReproc); 8653 if (rc != NO_ERROR) { 8654 delete pChannel; 8655 return NULL; 8656 } 8657 8658 return pChannel; 8659 } 8660 8661 /*=========================================================================== 8662 * FUNCTION : addOfflineReprocChannel 8663 * 8664 * DESCRIPTION: add a offline reprocess channel contains one reproc stream, 8665 * that will do reprocess on frames coming from external images 8666 * 8667 * PARAMETERS : 8668 * @img_config : offline reporcess image info 8669 * @pp_feature : pp feature config 8670 * 8671 * RETURN : int32_t type of status 8672 * NO_ERROR -- success 8673 * none-zero failure code 8674 *==========================================================================*/ 8675 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel( 8676 cam_pp_offline_src_config_t &img_config, 8677 cam_pp_feature_config_t &pp_feature, 8678 stream_cb_routine stream_cb, 8679 void *userdata) 8680 { 8681 int32_t rc = NO_ERROR; 8682 QCameraReprocessChannel *pChannel = NULL; 8683 8684 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle, 8685 mCameraHandle->ops); 8686 if (NULL == pChannel) { 8687 LOGE("no mem for reprocess channel"); 8688 return NULL; 8689 } 8690 8691 rc = pChannel->init(NULL, NULL, NULL); 8692 if (rc != NO_ERROR) { 8693 LOGE("init reprocess channel failed, ret = %d", rc); 8694 delete pChannel; 8695 return NULL; 8696 } 8697 8698 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 8699 if (pStreamInfo == NULL) { 8700 LOGE("no mem for stream info buf"); 8701 delete pChannel; 8702 return NULL; 8703 } 8704 8705 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0); 8706 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t)); 8707 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 8708 streamInfoBuf->fmt = img_config.input_fmt; 8709 streamInfoBuf->dim = img_config.input_dim; 8710 streamInfoBuf->buf_planes = img_config.input_buf_planes; 8711 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST; 8712 streamInfoBuf->num_of_burst = img_config.num_of_bufs; 8713 8714 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 8715 streamInfoBuf->reprocess_config.offline = img_config; 8716 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature; 8717 streamInfoBuf->num_bufs = img_config.num_of_bufs; 8718 8719 rc = pChannel->addStream(*this, 8720 pStreamInfo, NULL, 8721 &gCamCapability[mCameraId]->padding_info, 8722 stream_cb, userdata, false); 8723 8724 if (rc != NO_ERROR) { 8725 LOGE("add reprocess stream failed, ret = %d", rc); 8726 delete pChannel; 8727 return NULL; 8728 } 8729 8730 return pChannel; 8731 } 8732 8733 /*=========================================================================== 8734 * FUNCTION : addChannel 8735 * 8736 * DESCRIPTION: add a channel by its type 8737 * 8738 * PARAMETERS : 8739 * @ch_type : channel type 8740 * 8741 * RETURN : int32_t type of status 8742 * NO_ERROR -- success 8743 * none-zero failure code 8744 *==========================================================================*/ 8745 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type) 8746 { 8747 int32_t rc = UNKNOWN_ERROR; 8748 switch (ch_type) { 8749 case QCAMERA_CH_TYPE_ZSL: 8750 rc = addZSLChannel(); 8751 break; 8752 case QCAMERA_CH_TYPE_CAPTURE: 8753 rc = addCaptureChannel(); 8754 break; 8755 case QCAMERA_CH_TYPE_PREVIEW: 8756 rc = addPreviewChannel(); 8757 break; 8758 case QCAMERA_CH_TYPE_VIDEO: 8759 rc = addVideoChannel(); 8760 break; 8761 case QCAMERA_CH_TYPE_SNAPSHOT: 8762 rc = addSnapshotChannel(); 8763 break; 8764 case QCAMERA_CH_TYPE_RAW: 8765 rc = addRawChannel(); 8766 break; 8767 case QCAMERA_CH_TYPE_METADATA: 8768 rc = addMetaDataChannel(); 8769 break; 8770 case QCAMERA_CH_TYPE_CALLBACK: 8771 rc = addCallbackChannel(); 8772 break; 8773 case QCAMERA_CH_TYPE_ANALYSIS: 8774 rc = addAnalysisChannel(); 8775 break; 8776 default: 8777 break; 8778 } 8779 return rc; 8780 } 8781 8782 /*=========================================================================== 8783 * FUNCTION : delChannel 8784 * 8785 * DESCRIPTION: delete a channel by its type 8786 * 8787 * PARAMETERS : 8788 * @ch_type : channel type 8789 * @destroy : delete context as well 8790 * 8791 * RETURN : int32_t type of status 8792 * NO_ERROR -- success 8793 * none-zero failure code 8794 *==========================================================================*/ 8795 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type, 8796 bool destroy) 8797 { 8798 if (m_channels[ch_type] != NULL) { 8799 if (destroy) { 8800 delete m_channels[ch_type]; 8801 m_channels[ch_type] = NULL; 8802 } else { 8803 m_channels[ch_type]->deleteChannel(); 8804 } 8805 } 8806 8807 return NO_ERROR; 8808 } 8809 8810 /*=========================================================================== 8811 * FUNCTION : startChannel 8812 * 8813 * DESCRIPTION: start a channel by its type 8814 * 8815 * PARAMETERS : 8816 * @ch_type : channel type 8817 * 8818 * RETURN : int32_t type of status 8819 * NO_ERROR -- success 8820 * none-zero failure code 8821 *==========================================================================*/ 8822 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type) 8823 { 8824 int32_t rc = UNKNOWN_ERROR; 8825 if (m_channels[ch_type] != NULL) { 8826 rc = m_channels[ch_type]->start(); 8827 } 8828 return rc; 8829 } 8830 8831 /*=========================================================================== 8832 * FUNCTION : stopChannel 8833 * 8834 * DESCRIPTION: stop a channel by its type 8835 * 8836 * PARAMETERS : 8837 * @ch_type : channel type 8838 * 8839 * RETURN : int32_t type of status 8840 * NO_ERROR -- success 8841 * none-zero failure code 8842 *==========================================================================*/ 8843 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type) 8844 { 8845 int32_t rc = UNKNOWN_ERROR; 8846 if (m_channels[ch_type] != NULL) { 8847 rc = m_channels[ch_type]->stop(); 8848 } 8849 8850 return rc; 8851 } 8852 8853 /*=========================================================================== 8854 * FUNCTION : preparePreview 8855 * 8856 * DESCRIPTION: add channels needed for preview 8857 * 8858 * PARAMETERS : none 8859 * 8860 * RETURN : int32_t type of status 8861 * NO_ERROR -- success 8862 * none-zero failure code 8863 *==========================================================================*/ 8864 int32_t QCamera2HardwareInterface::preparePreview() 8865 { 8866 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPAREPREVIEW); 8867 int32_t rc = NO_ERROR; 8868 8869 LOGI("E"); 8870 rc = mParameters.setStreamConfigure(false, false, false); 8871 if (rc != NO_ERROR) { 8872 LOGE("setStreamConfigure failed %d", rc); 8873 return rc; 8874 } 8875 8876 //Trigger deferred job second camera 8877 if (isDualCamera()) { 8878 mParameters.setDeferCamera(CAM_DEFER_START); 8879 } 8880 8881 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 8882 rc = addChannel(QCAMERA_CH_TYPE_ZSL); 8883 if (rc != NO_ERROR) { 8884 LOGE("failed!! rc = %d", rc); 8885 return rc; 8886 } 8887 8888 if (mParameters.isUBWCEnabled()) { 8889 cam_format_t fmt; 8890 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt); 8891 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 8892 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK); 8893 if (rc != NO_ERROR) { 8894 delChannel(QCAMERA_CH_TYPE_ZSL); 8895 LOGE("failed!! rc = %d", rc); 8896 return rc; 8897 } 8898 } 8899 } 8900 8901 if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) { 8902 addChannel(QCAMERA_CH_TYPE_RAW); 8903 } 8904 } else if(isSecureMode()) { 8905 if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) { 8906 rc = addChannel(QCAMERA_CH_TYPE_RAW); 8907 } else { 8908 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW); 8909 } 8910 } else { 8911 bool recordingHint = mParameters.getRecordingHintValue(); 8912 if(!isRdiMode() && recordingHint) { 8913 //stop face detection,longshot,etc if turned ON in Camera mode 8914 #ifndef VANILLA_HAL 8915 int32_t arg; //dummy arg 8916 if (isLongshotEnabled()) { 8917 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg); 8918 } 8919 if (mParameters.isFaceDetectionEnabled() 8920 && (!mParameters.fdModeInVideo())) { 8921 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg); 8922 } 8923 if (mParameters.isHistogramEnabled()) { 8924 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg); 8925 } 8926 #endif 8927 //Don't create snapshot channel for liveshot, if low power mode is set. 8928 //Use video stream instead. 8929 if (!isLowPowerMode()) { 8930 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8931 if (rc != NO_ERROR) { 8932 return rc; 8933 } 8934 } 8935 8936 rc = addChannel(QCAMERA_CH_TYPE_VIDEO); 8937 if (rc != NO_ERROR) { 8938 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8939 LOGE("failed!! rc = %d", rc); 8940 return rc; 8941 } 8942 } 8943 8944 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW); 8945 if (!isRdiMode() && (rc != NO_ERROR)) { 8946 if (recordingHint) { 8947 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8948 delChannel(QCAMERA_CH_TYPE_VIDEO); 8949 } 8950 } 8951 8952 if (mParameters.isUBWCEnabled() && !recordingHint) { 8953 cam_format_t fmt; 8954 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt); 8955 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 8956 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK); 8957 if (rc != NO_ERROR) { 8958 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8959 if (!isRdiMode()) { 8960 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8961 delChannel(QCAMERA_CH_TYPE_VIDEO); 8962 } 8963 LOGE("failed!! rc = %d", rc); 8964 return rc; 8965 } 8966 } 8967 } 8968 8969 if (NO_ERROR != rc) { 8970 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8971 LOGE("failed!! rc = %d", rc); 8972 } 8973 } 8974 8975 if ((rc != NO_ERROR) && (isDualCamera())) { 8976 mParameters.setDeferCamera(CAM_DEFER_FLUSH); 8977 } 8978 8979 LOGI("X rc = %d", rc); 8980 return rc; 8981 } 8982 8983 /*=========================================================================== 8984 * FUNCTION : unpreparePreview 8985 * 8986 * DESCRIPTION: delete channels for preview 8987 * 8988 * PARAMETERS : none 8989 * 8990 * RETURN : none 8991 *==========================================================================*/ 8992 void QCamera2HardwareInterface::unpreparePreview() 8993 { 8994 if (isDualCamera()) { 8995 mParameters.setDeferCamera(CAM_DEFER_FLUSH); 8996 } 8997 delChannel(QCAMERA_CH_TYPE_ZSL); 8998 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8999 delChannel(QCAMERA_CH_TYPE_VIDEO); 9000 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 9001 delChannel(QCAMERA_CH_TYPE_CALLBACK); 9002 delChannel(QCAMERA_CH_TYPE_RAW); 9003 } 9004 9005 /*=========================================================================== 9006 * FUNCTION : playShutter 9007 * 9008 * DESCRIPTION: send request to play shutter sound 9009 * 9010 * PARAMETERS : none 9011 * 9012 * RETURN : none 9013 *==========================================================================*/ 9014 void QCamera2HardwareInterface::playShutter(){ 9015 if (mNotifyCb == NULL || 9016 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){ 9017 LOGD("shutter msg not enabled or NULL cb"); 9018 return; 9019 } 9020 LOGH("CAMERA_MSG_SHUTTER "); 9021 qcamera_callback_argm_t cbArg; 9022 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 9023 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 9024 cbArg.msg_type = CAMERA_MSG_SHUTTER; 9025 cbArg.ext1 = 0; 9026 cbArg.ext2 = false; 9027 m_cbNotifier.notifyCallback(cbArg); 9028 } 9029 9030 /*=========================================================================== 9031 * FUNCTION : getChannelByHandle 9032 * 9033 * DESCRIPTION: return a channel by its handle 9034 * 9035 * PARAMETERS : 9036 * @channelHandle : channel handle 9037 * 9038 * RETURN : a channel obj if found, NULL if not found 9039 *==========================================================================*/ 9040 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle) 9041 { 9042 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 9043 if (m_channels[i] != NULL && 9044 (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) { 9045 return m_channels[i]; 9046 } 9047 } 9048 9049 return NULL; 9050 } 9051 /*=========================================================================== 9052 * FUNCTION : needPreviewFDCallback 9053 * 9054 * DESCRIPTION: decides if needPreviewFDCallback 9055 * 9056 * PARAMETERS : 9057 * @num_faces : number of faces 9058 * 9059 * RETURN : bool type of status 9060 * true -- success 9061 * fale -- failure code 9062 *==========================================================================*/ 9063 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces) 9064 { 9065 if (num_faces == 0 && mNumPreviewFaces == 0) { 9066 return false; 9067 } 9068 9069 return true; 9070 } 9071 9072 /*=========================================================================== 9073 * FUNCTION : processFaceDetectionReuslt 9074 * 9075 * DESCRIPTION: process face detection reuslt 9076 * 9077 * PARAMETERS : 9078 * @faces_data : ptr to face processing result struct 9079 * 9080 * RETURN : int32_t type of status 9081 * NO_ERROR -- success 9082 * none-zero failure code 9083 *==========================================================================*/ 9084 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data) 9085 { 9086 if (!mParameters.isFaceDetectionEnabled()) { 9087 LOGH("FaceDetection not enabled, no ops here"); 9088 return NO_ERROR; 9089 } 9090 9091 qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type; 9092 cam_face_detection_data_t *detect_data = &(faces_data->detection_data); 9093 if ((NULL == mDataCb) || 9094 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) || 9095 (!needPreviewFDCallback(detect_data->num_faces_detected)) 9096 #ifndef VANILLA_HAL 9097 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA)) 9098 #endif 9099 ) { 9100 LOGH("metadata msgtype not enabled, no ops here"); 9101 return NO_ERROR; 9102 } 9103 9104 if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) { 9105 // Don't send callback to app if this is skipped by fd at backend 9106 return NO_ERROR; 9107 } 9108 9109 cam_dimension_t display_dim; 9110 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim); 9111 if (display_dim.width <= 0 || display_dim.height <= 0) { 9112 LOGE("Invalid preview width or height (%d x %d)", 9113 display_dim.width, display_dim.height); 9114 return UNKNOWN_ERROR; 9115 } 9116 9117 // process face detection result 9118 // need separate face detection in preview or snapshot type 9119 size_t faceResultSize = 0; 9120 size_t data_len = 0; 9121 if(fd_type == QCAMERA_FD_PREVIEW){ 9122 //fd for preview frames 9123 faceResultSize = sizeof(camera_frame_metadata_t); 9124 faceResultSize += sizeof(camera_face_t) * MAX_ROI; 9125 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 9126 #ifndef VANILLA_HAL 9127 // fd for snapshot frames 9128 //check if face is detected in this frame 9129 if(detect_data->num_faces_detected > 0){ 9130 data_len = sizeof(camera_frame_metadata_t) + 9131 sizeof(camera_face_t) * detect_data->num_faces_detected; 9132 }else{ 9133 //no face 9134 data_len = 0; 9135 } 9136 #endif 9137 faceResultSize = 1 *sizeof(int) //meta data type 9138 + 1 *sizeof(int) // meta data len 9139 + data_len; //data 9140 } 9141 9142 camera_memory_t *faceResultBuffer = mGetMemory(-1, 9143 faceResultSize, 9144 1, 9145 mCallbackCookie); 9146 if ( NULL == faceResultBuffer ) { 9147 LOGE("Not enough memory for face result data"); 9148 return NO_MEMORY; 9149 } 9150 9151 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data; 9152 memset(pFaceResult, 0, faceResultSize); 9153 unsigned char *faceData = NULL; 9154 if(fd_type == QCAMERA_FD_PREVIEW){ 9155 faceData = pFaceResult; 9156 mNumPreviewFaces = detect_data->num_faces_detected; 9157 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 9158 #ifndef VANILLA_HAL 9159 //need fill meta type and meta data len first 9160 int *data_header = (int* )pFaceResult; 9161 data_header[0] = CAMERA_META_DATA_FD; 9162 data_header[1] = (int)data_len; 9163 9164 if(data_len <= 0){ 9165 //if face is not valid or do not have face, return 9166 qcamera_callback_argm_t cbArg; 9167 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 9168 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 9169 cbArg.msg_type = CAMERA_MSG_META_DATA; 9170 cbArg.data = faceResultBuffer; 9171 cbArg.user_data = faceResultBuffer; 9172 cbArg.cookie = this; 9173 cbArg.release_cb = releaseCameraMemory; 9174 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 9175 if (rc != NO_ERROR) { 9176 LOGE("fail sending notification"); 9177 faceResultBuffer->release(faceResultBuffer); 9178 } 9179 return rc; 9180 } 9181 #endif 9182 faceData = pFaceResult + 2 *sizeof(int); //skip two int length 9183 } 9184 9185 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData; 9186 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) ); 9187 9188 roiData->number_of_faces = detect_data->num_faces_detected; 9189 roiData->faces = faces; 9190 LOGL("FD_DEBUG : Frame[%d] : number_of_faces=%d, display_dim=%d %d", 9191 detect_data->frame_id, detect_data->num_faces_detected, 9192 display_dim.width, display_dim.height); 9193 if (roiData->number_of_faces > 0) { 9194 for (int i = 0; i < roiData->number_of_faces; i++) { 9195 faces[i].id = detect_data->faces[i].face_id; 9196 faces[i].score = detect_data->faces[i].score; 9197 9198 // left 9199 faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE( 9200 detect_data->faces[i].face_boundary.left, 9201 display_dim.width, 2000, -1000); 9202 9203 // top 9204 faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE( 9205 detect_data->faces[i].face_boundary.top, 9206 display_dim.height, 2000, -1000); 9207 9208 // right 9209 faces[i].rect[2] = faces[i].rect[0] + 9210 MAP_TO_DRIVER_COORDINATE( 9211 detect_data->faces[i].face_boundary.width, 9212 display_dim.width, 2000, 0); 9213 9214 // bottom 9215 faces[i].rect[3] = faces[i].rect[1] + 9216 MAP_TO_DRIVER_COORDINATE( 9217 detect_data->faces[i].face_boundary.height, 9218 display_dim.height, 2000, 0); 9219 9220 LOGL("FD_DEBUG : Frame[%d] : Face[%d] : id=%d, score=%d, " 9221 "CAM[left=%d, top=%d, w=%d, h=%d], " 9222 "APP[left=%d, top=%d, right=%d, bottom=%d] ", 9223 detect_data->frame_id, i, faces[i].id, faces[i].score, 9224 detect_data->faces[i].face_boundary.left, 9225 detect_data->faces[i].face_boundary.top, 9226 detect_data->faces[i].face_boundary.width, 9227 detect_data->faces[i].face_boundary.height, 9228 faces[i].rect[0], faces[i].rect[1], 9229 faces[i].rect[2], faces[i].rect[3]); 9230 9231 if (faces_data->landmark_valid) { 9232 // Center of left eye 9233 if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) { 9234 faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE( 9235 faces_data->landmark_data.face_landmarks[i].left_eye_center.x, 9236 display_dim.width, 2000, -1000); 9237 faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE( 9238 faces_data->landmark_data.face_landmarks[i].left_eye_center.y, 9239 display_dim.height, 2000, -1000); 9240 } else { 9241 faces[i].left_eye[0] = FACE_INVALID_POINT; 9242 faces[i].left_eye[1] = FACE_INVALID_POINT; 9243 } 9244 9245 // Center of right eye 9246 if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) { 9247 faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE( 9248 faces_data->landmark_data.face_landmarks[i].right_eye_center.x, 9249 display_dim.width, 2000, -1000); 9250 faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE( 9251 faces_data->landmark_data.face_landmarks[i].right_eye_center.y, 9252 display_dim.height, 2000, -1000); 9253 } else { 9254 faces[i].right_eye[0] = FACE_INVALID_POINT; 9255 faces[i].right_eye[1] = FACE_INVALID_POINT; 9256 } 9257 9258 // Center of mouth 9259 if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) { 9260 faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE( 9261 faces_data->landmark_data.face_landmarks[i].mouth_center.x, 9262 display_dim.width, 2000, -1000); 9263 faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE( 9264 faces_data->landmark_data.face_landmarks[i].mouth_center.y, 9265 display_dim.height, 2000, -1000); 9266 } else { 9267 faces[i].mouth[0] = FACE_INVALID_POINT; 9268 faces[i].mouth[1] = FACE_INVALID_POINT; 9269 } 9270 9271 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : " 9272 "eye : left(%d, %d) right(%d, %d), mouth(%d, %d)", 9273 detect_data->frame_id, i, faces[i].left_eye[0], faces[i].left_eye[1], 9274 faces[i].right_eye[0], faces[i].right_eye[1], 9275 faces[i].mouth[0], faces[i].mouth[1]); 9276 } else { 9277 // return -2000 if invalid 9278 faces[i].left_eye[0] = FACE_INVALID_POINT; 9279 faces[i].left_eye[1] = FACE_INVALID_POINT; 9280 9281 faces[i].right_eye[0] = FACE_INVALID_POINT; 9282 faces[i].right_eye[1] = FACE_INVALID_POINT; 9283 9284 faces[i].mouth[0] = FACE_INVALID_POINT; 9285 faces[i].mouth[1] = FACE_INVALID_POINT; 9286 } 9287 9288 #ifndef VANILLA_HAL 9289 #ifdef TARGET_TS_MAKEUP 9290 mFaceRect.left = detect_data->faces[i].face_boundary.left; 9291 mFaceRect.top = detect_data->faces[i].face_boundary.top; 9292 mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left; 9293 mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top; 9294 #endif 9295 if (faces_data->smile_valid) { 9296 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree; 9297 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence; 9298 9299 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : smile_degree=%d, smile_score=%d", 9300 detect_data->frame_id, i, faces[i].smile_degree, faces[i].smile_score); 9301 } 9302 if (faces_data->blink_valid) { 9303 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected; 9304 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink; 9305 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink; 9306 9307 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : " 9308 "blink_detected=%d, leye_blink=%d, reye_blink=%d", 9309 detect_data->frame_id, i, faces[i].blink_detected, faces[i].leye_blink, 9310 faces[i].reye_blink); 9311 } 9312 if (faces_data->recog_valid) { 9313 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised; 9314 9315 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : face_recognised=%d", 9316 detect_data->frame_id, i, faces[i].face_recognised); 9317 } 9318 if (faces_data->gaze_valid) { 9319 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle; 9320 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir; 9321 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir; 9322 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir; 9323 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze; 9324 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze; 9325 9326 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : gaze_angle=%d, updown_dir=%d, " 9327 "leftright_dir=%d,, roll_dir=%d, left_right_gaze=%d, top_bottom_gaze=%d", 9328 detect_data->frame_id, i, faces[i].gaze_angle, faces[i].updown_dir, 9329 faces[i].leftright_dir, faces[i].roll_dir, faces[i].left_right_gaze, 9330 faces[i].top_bottom_gaze); 9331 } 9332 #endif 9333 9334 } 9335 } 9336 else{ 9337 #ifdef TARGET_TS_MAKEUP 9338 memset(&mFaceRect,-1,sizeof(mFaceRect)); 9339 #endif 9340 } 9341 qcamera_callback_argm_t cbArg; 9342 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 9343 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 9344 if(fd_type == QCAMERA_FD_PREVIEW){ 9345 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA; 9346 } 9347 #ifndef VANILLA_HAL 9348 else if(fd_type == QCAMERA_FD_SNAPSHOT){ 9349 cbArg.msg_type = CAMERA_MSG_META_DATA; 9350 } 9351 #endif 9352 cbArg.data = faceResultBuffer; 9353 cbArg.metadata = roiData; 9354 cbArg.user_data = faceResultBuffer; 9355 cbArg.cookie = this; 9356 cbArg.release_cb = releaseCameraMemory; 9357 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 9358 if (rc != NO_ERROR) { 9359 LOGE("fail sending notification"); 9360 faceResultBuffer->release(faceResultBuffer); 9361 } 9362 9363 return rc; 9364 } 9365 9366 /*=========================================================================== 9367 * FUNCTION : releaseCameraMemory 9368 * 9369 * DESCRIPTION: releases camera memory objects 9370 * 9371 * PARAMETERS : 9372 * @data : buffer to be released 9373 * @cookie : context data 9374 * @cbStatus: callback status 9375 * 9376 * RETURN : None 9377 *==========================================================================*/ 9378 void QCamera2HardwareInterface::releaseCameraMemory(void *data, 9379 void */*cookie*/, 9380 int32_t /*cbStatus*/) 9381 { 9382 camera_memory_t *mem = ( camera_memory_t * ) data; 9383 if ( NULL != mem ) { 9384 mem->release(mem); 9385 } 9386 } 9387 9388 /*=========================================================================== 9389 * FUNCTION : returnStreamBuffer 9390 * 9391 * DESCRIPTION: returns back a stream buffer 9392 * 9393 * PARAMETERS : 9394 * @data : buffer to be released 9395 * @cookie : context data 9396 * @cbStatus: callback status 9397 * 9398 * RETURN : None 9399 *==========================================================================*/ 9400 void QCamera2HardwareInterface::returnStreamBuffer(void *data, 9401 void *cookie, 9402 int32_t /*cbStatus*/) 9403 { 9404 QCameraStream *stream = ( QCameraStream * ) cookie; 9405 int idx = *((int *)data); 9406 if ((NULL != stream) && (0 <= idx)) { 9407 stream->bufDone((uint32_t)idx); 9408 } else { 9409 LOGE("Cannot return buffer %d %p", idx, cookie); 9410 } 9411 } 9412 9413 /*=========================================================================== 9414 * FUNCTION : processHistogramStats 9415 * 9416 * DESCRIPTION: process histogram stats 9417 * 9418 * PARAMETERS : 9419 * @hist_data : ptr to histogram stats struct 9420 * 9421 * RETURN : int32_t type of status 9422 * NO_ERROR -- success 9423 * none-zero failure code 9424 *==========================================================================*/ 9425 int32_t QCamera2HardwareInterface::processHistogramStats( 9426 __unused cam_hist_stats_t &stats_data) 9427 { 9428 #ifndef VANILLA_HAL 9429 if (!mParameters.isHistogramEnabled()) { 9430 LOGH("Histogram not enabled, no ops here"); 9431 return NO_ERROR; 9432 } 9433 9434 camera_memory_t *histBuffer = mGetMemory(-1, 9435 sizeof(cam_histogram_data_t), 9436 1, 9437 mCallbackCookie); 9438 if ( NULL == histBuffer ) { 9439 LOGE("Not enough memory for histogram data"); 9440 return NO_MEMORY; 9441 } 9442 9443 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data; 9444 if (pHistData == NULL) { 9445 LOGE("memory data ptr is NULL"); 9446 return UNKNOWN_ERROR; 9447 } 9448 9449 switch (stats_data.type) { 9450 case CAM_HISTOGRAM_TYPE_BAYER: 9451 switch (stats_data.bayer_stats.data_type) { 9452 case CAM_STATS_CHANNEL_Y: 9453 case CAM_STATS_CHANNEL_R: 9454 *pHistData = stats_data.bayer_stats.r_stats; 9455 break; 9456 case CAM_STATS_CHANNEL_GR: 9457 *pHistData = stats_data.bayer_stats.gr_stats; 9458 break; 9459 case CAM_STATS_CHANNEL_GB: 9460 case CAM_STATS_CHANNEL_ALL: 9461 *pHistData = stats_data.bayer_stats.gb_stats; 9462 break; 9463 case CAM_STATS_CHANNEL_B: 9464 *pHistData = stats_data.bayer_stats.b_stats; 9465 break; 9466 default: 9467 *pHistData = stats_data.bayer_stats.r_stats; 9468 break; 9469 } 9470 break; 9471 case CAM_HISTOGRAM_TYPE_YUV: 9472 *pHistData = stats_data.yuv_stats; 9473 break; 9474 } 9475 9476 qcamera_callback_argm_t cbArg; 9477 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 9478 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 9479 cbArg.msg_type = CAMERA_MSG_STATS_DATA; 9480 cbArg.data = histBuffer; 9481 cbArg.user_data = histBuffer; 9482 cbArg.cookie = this; 9483 cbArg.release_cb = releaseCameraMemory; 9484 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 9485 if (rc != NO_ERROR) { 9486 LOGE("fail sending notification"); 9487 histBuffer->release(histBuffer); 9488 } 9489 #endif 9490 return NO_ERROR; 9491 } 9492 9493 /*=========================================================================== 9494 * FUNCTION : calcThermalLevel 9495 * 9496 * DESCRIPTION: Calculates the target fps range depending on 9497 * the thermal level. 9498 * Note that this function can be called from QCameraParametersIntf 9499 * while mutex is held. So it should not call back into 9500 * QCameraParametersIntf causing deadlock. 9501 * 9502 * PARAMETERS : 9503 * @level : received thermal level 9504 * @minFPS : minimum configured fps range 9505 * @maxFPS : maximum configured fps range 9506 * @minVideoFps: minimum configured fps range 9507 * @maxVideoFps: maximum configured fps range 9508 * @adjustedRange : target fps range 9509 * @skipPattern : target skip pattern 9510 * @bRecordingHint : recording hint value 9511 * 9512 * RETURN : int32_t type of status 9513 * NO_ERROR -- success 9514 * none-zero failure code 9515 *==========================================================================*/ 9516 int QCamera2HardwareInterface::calcThermalLevel( 9517 qcamera_thermal_level_enum_t level, 9518 const int minFPSi, 9519 const int maxFPSi, 9520 const float &minVideoFps, 9521 const float &maxVideoFps, 9522 cam_fps_range_t &adjustedRange, 9523 enum msm_vfe_frame_skip_pattern &skipPattern, 9524 bool bRecordingHint) 9525 { 9526 const float minFPS = (float)minFPSi; 9527 const float maxFPS = (float)maxFPSi; 9528 9529 LOGH("level: %d, preview minfps %f, preview maxfpS %f, " 9530 "video minfps %f, video maxfpS %f", 9531 level, minFPS, maxFPS, minVideoFps, maxVideoFps); 9532 9533 switch(level) { 9534 case QCAMERA_THERMAL_NO_ADJUSTMENT: 9535 { 9536 adjustedRange.min_fps = minFPS / 1000.0f; 9537 adjustedRange.max_fps = maxFPS / 1000.0f; 9538 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 9539 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 9540 skipPattern = NO_SKIP; 9541 } 9542 break; 9543 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT: 9544 { 9545 adjustedRange.min_fps = minFPS / 1000.0f; 9546 adjustedRange.max_fps = maxFPS / 1000.0f; 9547 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps; 9548 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps; 9549 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 9550 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 9551 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps; 9552 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps; 9553 if ( adjustedRange.min_fps < 1 ) { 9554 adjustedRange.min_fps = 1; 9555 } 9556 if ( adjustedRange.max_fps < 1 ) { 9557 adjustedRange.max_fps = 1; 9558 } 9559 if ( adjustedRange.video_min_fps < 1 ) { 9560 adjustedRange.video_min_fps = 1; 9561 } 9562 if ( adjustedRange.video_max_fps < 1 ) { 9563 adjustedRange.video_max_fps = 1; 9564 } 9565 skipPattern = EVERY_2FRAME; 9566 } 9567 break; 9568 case QCAMERA_THERMAL_BIG_ADJUSTMENT: 9569 { 9570 adjustedRange.min_fps = minFPS / 1000.0f; 9571 adjustedRange.max_fps = maxFPS / 1000.0f; 9572 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps; 9573 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps; 9574 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 9575 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 9576 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps; 9577 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps; 9578 if ( adjustedRange.min_fps < 1 ) { 9579 adjustedRange.min_fps = 1; 9580 } 9581 if ( adjustedRange.max_fps < 1 ) { 9582 adjustedRange.max_fps = 1; 9583 } 9584 if ( adjustedRange.video_min_fps < 1 ) { 9585 adjustedRange.video_min_fps = 1; 9586 } 9587 if ( adjustedRange.video_max_fps < 1 ) { 9588 adjustedRange.video_max_fps = 1; 9589 } 9590 skipPattern = EVERY_4FRAME; 9591 } 9592 break; 9593 case QCAMERA_THERMAL_MAX_ADJUSTMENT: 9594 { 9595 // Stop Preview? 9596 // Set lowest min FPS for now 9597 adjustedRange.min_fps = minFPS/1000.0f; 9598 adjustedRange.max_fps = minFPS/1000.0f; 9599 cam_capability_t *capability = gCamCapability[mCameraId]; 9600 for (size_t i = 0; 9601 i < capability->fps_ranges_tbl_cnt; 9602 i++) { 9603 if (capability->fps_ranges_tbl[i].min_fps < 9604 adjustedRange.min_fps) { 9605 adjustedRange.min_fps = 9606 capability->fps_ranges_tbl[i].min_fps; 9607 adjustedRange.max_fps = adjustedRange.min_fps; 9608 } 9609 } 9610 skipPattern = MAX_SKIP; 9611 adjustedRange.video_min_fps = adjustedRange.min_fps; 9612 adjustedRange.video_max_fps = adjustedRange.max_fps; 9613 } 9614 break; 9615 case QCAMERA_THERMAL_SHUTDOWN: 9616 { 9617 // send error notify 9618 LOGE("Received shutdown thermal level. Closing camera"); 9619 sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); 9620 } 9621 break; 9622 default: 9623 { 9624 LOGW("Invalid thermal level %d", level); 9625 return BAD_VALUE; 9626 } 9627 break; 9628 } 9629 if (level >= QCAMERA_THERMAL_NO_ADJUSTMENT && level <= QCAMERA_THERMAL_MAX_ADJUSTMENT) { 9630 if (bRecordingHint) { 9631 adjustedRange.min_fps = minFPS / 1000.0f; 9632 adjustedRange.max_fps = maxFPS / 1000.0f; 9633 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 9634 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 9635 skipPattern = NO_SKIP; 9636 LOGH("No FPS mitigation in camcorder mode"); 9637 } 9638 LOGH("Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d", 9639 level, adjustedRange.min_fps, adjustedRange.max_fps, 9640 adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern); 9641 } 9642 9643 return NO_ERROR; 9644 } 9645 9646 /*=========================================================================== 9647 * FUNCTION : recalcFPSRange 9648 * 9649 * DESCRIPTION: adjust the configured fps range regarding 9650 * the last thermal level. 9651 * 9652 * PARAMETERS : 9653 * @minFPS : minimum configured fps range 9654 * @maxFPS : maximum configured fps range 9655 * @minVideoFPS : minimum configured video fps 9656 * @maxVideoFPS : maximum configured video fps 9657 * @adjustedRange : target fps range 9658 * @bRecordingHint : recording hint value 9659 * 9660 * RETURN : int32_t type of status 9661 * NO_ERROR -- success 9662 * none-zero failure code 9663 *==========================================================================*/ 9664 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS, 9665 const float &minVideoFPS, const float &maxVideoFPS, 9666 cam_fps_range_t &adjustedRange, bool bRecordingHint) 9667 { 9668 enum msm_vfe_frame_skip_pattern skipPattern; 9669 calcThermalLevel(mThermalLevel, 9670 minFPS, 9671 maxFPS, 9672 minVideoFPS, 9673 maxVideoFPS, 9674 adjustedRange, 9675 skipPattern, 9676 bRecordingHint); 9677 return NO_ERROR; 9678 } 9679 9680 /*=========================================================================== 9681 * FUNCTION : updateThermalLevel 9682 * 9683 * DESCRIPTION: update thermal level depending on thermal events 9684 * 9685 * PARAMETERS : 9686 * @level : thermal level 9687 * 9688 * RETURN : int32_t type of status 9689 * NO_ERROR -- success 9690 * none-zero failure code 9691 *==========================================================================*/ 9692 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level) 9693 { 9694 int ret = NO_ERROR; 9695 cam_fps_range_t adjustedRange; 9696 int minFPS, maxFPS; 9697 float minVideoFPS, maxVideoFPS; 9698 enum msm_vfe_frame_skip_pattern skipPattern; 9699 bool value; 9700 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level; 9701 9702 9703 if (!mCameraOpened) { 9704 LOGH("Camera is not opened, no need to update camera parameters"); 9705 return NO_ERROR; 9706 } 9707 9708 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 9709 qcamera_thermal_mode thermalMode = mParameters.getThermalMode(); 9710 if (mParameters.isHfrMode()) { 9711 cam_fps_range_t hfrFpsRange; 9712 mParameters.getHfrFps(hfrFpsRange); 9713 minVideoFPS = hfrFpsRange.video_min_fps; 9714 maxVideoFPS = hfrFpsRange.video_max_fps; 9715 } else { 9716 minVideoFPS = minFPS; 9717 maxVideoFPS = maxFPS; 9718 } 9719 9720 value = mParameters.getRecordingHintValue(); 9721 calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS, 9722 adjustedRange, skipPattern, value ); 9723 mThermalLevel = level; 9724 9725 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS) 9726 ret = mParameters.adjustPreviewFpsRange(&adjustedRange); 9727 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP) 9728 ret = mParameters.setFrameSkip(skipPattern); 9729 else 9730 LOGW("Incorrect thermal mode %d", thermalMode); 9731 9732 return ret; 9733 9734 } 9735 9736 /*=========================================================================== 9737 * FUNCTION : updateParameters 9738 * 9739 * DESCRIPTION: update parameters 9740 * 9741 * PARAMETERS : 9742 * @parms : input parameters string 9743 * @needRestart : output, flag to indicate if preview restart is needed 9744 * 9745 * RETURN : int32_t type of status 9746 * NO_ERROR -- success 9747 * none-zero failure code 9748 *==========================================================================*/ 9749 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart) 9750 { 9751 int rc = NO_ERROR; 9752 9753 String8 str = String8(parms); 9754 rc = mParameters.updateParameters(str, needRestart); 9755 setNeedRestart(needRestart); 9756 9757 // update stream based parameter settings 9758 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 9759 if (m_channels[i] != NULL) { 9760 m_channels[i]->UpdateStreamBasedParameters(mParameters); 9761 } 9762 } 9763 9764 return rc; 9765 } 9766 9767 /*=========================================================================== 9768 * FUNCTION : commitParameterChanges 9769 * 9770 * DESCRIPTION: commit parameter changes to the backend to take effect 9771 * 9772 * PARAMETERS : none 9773 * 9774 * RETURN : int32_t type of status 9775 * NO_ERROR -- success 9776 * none-zero failure code 9777 * NOTE : This function must be called after updateParameters. 9778 * Otherwise, no change will be passed to backend to take effect. 9779 *==========================================================================*/ 9780 int QCamera2HardwareInterface::commitParameterChanges() 9781 { 9782 int rc = NO_ERROR; 9783 rc = mParameters.commitParameters(); 9784 if (rc == NO_ERROR) { 9785 // update number of snapshot based on committed parameters setting 9786 rc = mParameters.setNumOfSnapshot(); 9787 } 9788 9789 if (isDualCamera() && 9790 mParameters.isZoomChanged()) { 9791 // If zoom changes, get the updated FOV-control result and if needed send the dual 9792 // camera parameters to backend 9793 processDualCamFovControl(); 9794 } 9795 return rc; 9796 } 9797 9798 /*=========================================================================== 9799 * FUNCTION : needDebugFps 9800 * 9801 * DESCRIPTION: if fps log info need to be printed out 9802 * 9803 * PARAMETERS : none 9804 * 9805 * RETURN : true: need print out fps log 9806 * false: no need to print out fps log 9807 *==========================================================================*/ 9808 bool QCamera2HardwareInterface::needDebugFps() 9809 { 9810 bool needFps = false; 9811 needFps = mParameters.isFpsDebugEnabled(); 9812 return needFps; 9813 } 9814 9815 /*=========================================================================== 9816 * FUNCTION : isCACEnabled 9817 * 9818 * DESCRIPTION: if CAC is enabled 9819 * 9820 * PARAMETERS : none 9821 * 9822 * RETURN : true: needed 9823 * false: no need 9824 *==========================================================================*/ 9825 bool QCamera2HardwareInterface::isCACEnabled() 9826 { 9827 char prop[PROPERTY_VALUE_MAX]; 9828 memset(prop, 0, sizeof(prop)); 9829 property_get("persist.camera.feature.cac", prop, "0"); 9830 int enableCAC = atoi(prop); 9831 return enableCAC == 1; 9832 } 9833 9834 /*=========================================================================== 9835 * FUNCTION : is4k2kResolution 9836 * 9837 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k 9838 * 9839 * PARAMETERS : none 9840 * 9841 * RETURN : true: needed 9842 * false: no need 9843 *==========================================================================*/ 9844 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution) 9845 { 9846 bool enabled = false; 9847 if ((resolution->width == 4096 && resolution->height == 2160) || 9848 (resolution->width == 3840 && resolution->height == 2160) ) { 9849 enabled = true; 9850 } 9851 return enabled; 9852 } 9853 9854 /*=========================================================================== 9855 * FUNCTION : isPreviewRestartEnabled 9856 * 9857 * DESCRIPTION: Check whether preview should be restarted automatically 9858 * during image capture. 9859 * 9860 * PARAMETERS : none 9861 * 9862 * RETURN : true: needed 9863 * false: no need 9864 *==========================================================================*/ 9865 bool QCamera2HardwareInterface::isPreviewRestartEnabled() 9866 { 9867 char prop[PROPERTY_VALUE_MAX]; 9868 memset(prop, 0, sizeof(prop)); 9869 property_get("persist.camera.feature.restart", prop, "0"); 9870 int earlyRestart = atoi(prop); 9871 return earlyRestart == 1; 9872 } 9873 9874 /*=========================================================================== 9875 * FUNCTION : needReprocess 9876 * 9877 * DESCRIPTION: if reprocess is needed 9878 * 9879 * PARAMETERS : none 9880 * 9881 * RETURN : true: needed 9882 * false: no need 9883 *==========================================================================*/ 9884 bool QCamera2HardwareInterface::needReprocess() 9885 { 9886 bool needReprocess = false; 9887 9888 if (!mParameters.isJpegPictureFormat() && 9889 !mParameters.isNV21PictureFormat()) { 9890 // RAW image, no need to reprocess 9891 return false; 9892 } 9893 9894 //Disable reprocess for small jpeg size or 4K liveshot case but enable if lowpower mode 9895 if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue() 9896 && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) { 9897 return false; 9898 } 9899 9900 // pp feature config 9901 cam_pp_feature_config_t pp_config; 9902 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 9903 9904 //Decide whether to do reprocess or not based on 9905 //ppconfig obtained in the first pass. 9906 getPPConfig(pp_config); 9907 9908 if (pp_config.feature_mask > 0) { 9909 needReprocess = true; 9910 } 9911 9912 LOGH("needReprocess %s", needReprocess ? "true" : "false"); 9913 return needReprocess; 9914 } 9915 9916 9917 /*=========================================================================== 9918 * FUNCTION : needRotationReprocess 9919 * 9920 * DESCRIPTION: if rotation needs to be done by reprocess in pp 9921 * 9922 * PARAMETERS : none 9923 * 9924 * RETURN : true: needed 9925 * false: no need 9926 *==========================================================================*/ 9927 bool QCamera2HardwareInterface::needRotationReprocess() 9928 { 9929 if (!mParameters.isJpegPictureFormat() && 9930 !mParameters.isNV21PictureFormat()) { 9931 // RAW image, no need to reprocess 9932 return false; 9933 } 9934 9935 //Disable reprocess for 4K liveshot case 9936 if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue() 9937 && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) { 9938 //Disable reprocess for 4K liveshot case or small jpeg size 9939 return false; 9940 } 9941 9942 if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & 9943 CAM_QCOM_FEATURE_ROTATION) > 0 && 9944 (mParameters.getJpegRotation() > 0)) { 9945 // current rotation is not zero, and pp has the capability to process rotation 9946 LOGH("need to do reprocess for rotation=%d", 9947 mParameters.getJpegRotation()); 9948 return true; 9949 } 9950 9951 return false; 9952 } 9953 9954 /*=========================================================================== 9955 * FUNCTION : getThumbnailSize 9956 * 9957 * DESCRIPTION: get user set thumbnail size 9958 * 9959 * PARAMETERS : 9960 * @dim : output of thumbnail dimension 9961 * 9962 * RETURN : none 9963 *==========================================================================*/ 9964 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim) 9965 { 9966 mParameters.getThumbnailSize(&dim.width, &dim.height); 9967 } 9968 9969 /*=========================================================================== 9970 * FUNCTION : getJpegQuality 9971 * 9972 * DESCRIPTION: get user set jpeg quality 9973 * 9974 * PARAMETERS : none 9975 * 9976 * RETURN : jpeg quality setting 9977 *==========================================================================*/ 9978 uint32_t QCamera2HardwareInterface::getJpegQuality() 9979 { 9980 uint32_t quality = 0; 9981 quality = mParameters.getJpegQuality(); 9982 return quality; 9983 } 9984 9985 /*=========================================================================== 9986 * FUNCTION : getExifData 9987 * 9988 * DESCRIPTION: get exif data to be passed into jpeg encoding 9989 * 9990 * PARAMETERS : none 9991 * 9992 * RETURN : exif data from user setting and GPS 9993 *==========================================================================*/ 9994 QCameraExif *QCamera2HardwareInterface::getExifData() 9995 { 9996 QCameraExif *exif = new QCameraExif(); 9997 if (exif == NULL) { 9998 LOGE("No memory for QCameraExif"); 9999 return NULL; 10000 } 10001 10002 int32_t rc = NO_ERROR; 10003 10004 // add exif entries 10005 String8 dateTime, subSecTime; 10006 rc = mParameters.getExifDateTime(dateTime, subSecTime); 10007 if(rc == NO_ERROR) { 10008 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII, 10009 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 10010 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII, 10011 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 10012 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII, 10013 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 10014 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII, 10015 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 10016 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII, 10017 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 10018 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII, 10019 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 10020 } else { 10021 LOGW("getExifDateTime failed"); 10022 } 10023 10024 rat_t focalLength; 10025 rc = mParameters.getExifFocalLength(&focalLength); 10026 if (rc == NO_ERROR) { 10027 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 10028 EXIF_RATIONAL, 10029 1, 10030 (void *)&(focalLength)); 10031 } else { 10032 LOGW("getExifFocalLength failed"); 10033 } 10034 10035 uint16_t isoSpeed = mParameters.getExifIsoSpeed(); 10036 if (getSensorType() != CAM_SENSOR_YUV) { 10037 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 10038 EXIF_SHORT, 10039 1, 10040 (void *)&(isoSpeed)); 10041 } 10042 10043 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 10044 uint32_t count = 0; 10045 10046 /*gps data might not be available */ 10047 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count); 10048 if(rc == NO_ERROR) { 10049 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 10050 EXIF_ASCII, 10051 count, 10052 (void *)gpsProcessingMethod); 10053 } else { 10054 LOGW("getExifGpsProcessingMethod failed"); 10055 } 10056 10057 rat_t latitude[3]; 10058 char latRef[2]; 10059 rc = mParameters.getExifLatitude(latitude, latRef); 10060 if(rc == NO_ERROR) { 10061 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 10062 EXIF_RATIONAL, 10063 3, 10064 (void *)latitude); 10065 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 10066 EXIF_ASCII, 10067 2, 10068 (void *)latRef); 10069 } else { 10070 LOGW("getExifLatitude failed"); 10071 } 10072 10073 rat_t longitude[3]; 10074 char lonRef[2]; 10075 rc = mParameters.getExifLongitude(longitude, lonRef); 10076 if(rc == NO_ERROR) { 10077 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 10078 EXIF_RATIONAL, 10079 3, 10080 (void *)longitude); 10081 10082 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 10083 EXIF_ASCII, 10084 2, 10085 (void *)lonRef); 10086 } else { 10087 LOGW("getExifLongitude failed"); 10088 } 10089 10090 rat_t altitude; 10091 char altRef; 10092 rc = mParameters.getExifAltitude(&altitude, &altRef); 10093 if(rc == NO_ERROR) { 10094 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 10095 EXIF_RATIONAL, 10096 1, 10097 (void *)&(altitude)); 10098 10099 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 10100 EXIF_BYTE, 10101 1, 10102 (void *)&altRef); 10103 } else { 10104 LOGW("getExifAltitude failed"); 10105 } 10106 10107 char gpsDateStamp[20]; 10108 rat_t gpsTimeStamp[3]; 10109 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp); 10110 if(rc == NO_ERROR) { 10111 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 10112 EXIF_ASCII, 10113 (uint32_t)(strlen(gpsDateStamp) + 1), 10114 (void *)gpsDateStamp); 10115 10116 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 10117 EXIF_RATIONAL, 10118 3, 10119 (void *)gpsTimeStamp); 10120 } else { 10121 LOGW("getExifGpsDataTimeStamp failed"); 10122 } 10123 10124 #ifdef ENABLE_MODEL_INFO_EXIF 10125 10126 char value[PROPERTY_VALUE_MAX]; 10127 if (property_get("persist.sys.exif.make", value, "") > 0 || 10128 property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 10129 exif->addEntry(EXIFTAGID_MAKE, 10130 EXIF_ASCII, strlen(value) + 1, (void *)value); 10131 } else { 10132 LOGW("getExifMaker failed"); 10133 } 10134 10135 if (property_get("persist.sys.exif.model", value, "") > 0 || 10136 property_get("ro.product.model", value, "QCAM-AA") > 0) { 10137 exif->addEntry(EXIFTAGID_MODEL, 10138 EXIF_ASCII, strlen(value) + 1, (void *)value); 10139 } else { 10140 LOGW("getExifModel failed"); 10141 } 10142 10143 if (property_get("ro.build.description", value, "QCAM-AA") > 0) { 10144 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII, 10145 (uint32_t)(strlen(value) + 1), (void *)value); 10146 } else { 10147 LOGW("getExifSoftware failed"); 10148 } 10149 10150 #endif 10151 10152 if (mParameters.useJpegExifRotation()) { 10153 int16_t orientation; 10154 switch (mParameters.getJpegExifRotation()) { 10155 case 0: 10156 orientation = 1; 10157 break; 10158 case 90: 10159 orientation = 6; 10160 break; 10161 case 180: 10162 orientation = 3; 10163 break; 10164 case 270: 10165 orientation = 8; 10166 break; 10167 default: 10168 orientation = 1; 10169 break; 10170 } 10171 exif->addEntry(EXIFTAGID_ORIENTATION, 10172 EXIF_SHORT, 10173 1, 10174 (void *)&orientation); 10175 exif->addEntry(EXIFTAGID_TN_ORIENTATION, 10176 EXIF_SHORT, 10177 1, 10178 (void *)&orientation); 10179 } 10180 10181 return exif; 10182 } 10183 10184 /*=========================================================================== 10185 * FUNCTION : setHistogram 10186 * 10187 * DESCRIPTION: set if histogram should be enabled 10188 * 10189 * PARAMETERS : 10190 * @histogram_en : bool flag if histogram should be enabled 10191 * 10192 * RETURN : int32_t type of status 10193 * NO_ERROR -- success 10194 * none-zero failure code 10195 *==========================================================================*/ 10196 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en) 10197 { 10198 return mParameters.setHistogram(histogram_en); 10199 } 10200 10201 /*=========================================================================== 10202 * FUNCTION : setFaceDetection 10203 * 10204 * DESCRIPTION: set if face detection should be enabled 10205 * 10206 * PARAMETERS : 10207 * @enabled : bool flag if face detection should be enabled 10208 * 10209 * RETURN : int32_t type of status 10210 * NO_ERROR -- success 10211 * none-zero failure code 10212 *==========================================================================*/ 10213 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled) 10214 { 10215 return mParameters.setFaceDetection(enabled, true); 10216 } 10217 10218 /*=========================================================================== 10219 * FUNCTION : isCaptureShutterEnabled 10220 * 10221 * DESCRIPTION: Check whether shutter should be triggered immediately after 10222 * capture 10223 * 10224 * PARAMETERS : 10225 * 10226 * RETURN : true - regular capture 10227 * false - other type of capture 10228 *==========================================================================*/ 10229 bool QCamera2HardwareInterface::isCaptureShutterEnabled() 10230 { 10231 char prop[PROPERTY_VALUE_MAX]; 10232 memset(prop, 0, sizeof(prop)); 10233 property_get("persist.camera.feature.shutter", prop, "0"); 10234 int enableShutter = atoi(prop); 10235 return enableShutter == 1; 10236 } 10237 10238 /*=========================================================================== 10239 * FUNCTION : needProcessPreviewFrame 10240 * 10241 * DESCRIPTION: returns whether preview frame need to be displayed 10242 * 10243 * PARAMETERS : 10244 * @frameID : frameID of frame to be processed 10245 * 10246 * RETURN : int32_t type of status 10247 * NO_ERROR -- success 10248 * none-zero failure code 10249 *==========================================================================*/ 10250 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID) 10251 { 10252 return (((m_stateMachine.isPreviewRunning()) && 10253 (!isDisplayFrameToSkip(frameID)) && 10254 (!mParameters.isInstantAECEnabled())) || 10255 (isPreviewRestartEnabled())); 10256 } 10257 10258 /*=========================================================================== 10259 * FUNCTION : needSendPreviewCallback 10260 * 10261 * DESCRIPTION: returns whether preview frame need to callback to APP 10262 * 10263 * PARAMETERS : 10264 * 10265 * RETURN : true - need preview frame callbck 10266 * false - not send preview frame callback 10267 *==========================================================================*/ 10268 bool QCamera2HardwareInterface::needSendPreviewCallback() 10269 { 10270 return m_stateMachine.isPreviewRunning() 10271 && (mDataCb != NULL) 10272 && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) 10273 && m_stateMachine.isPreviewCallbackNeeded(); 10274 }; 10275 10276 /*=========================================================================== 10277 * FUNCTION : setDisplaySkip 10278 * 10279 * DESCRIPTION: set range of frames to skip for preview 10280 * 10281 * PARAMETERS : 10282 * @enabled : TRUE to start skipping frame to display 10283 FALSE to stop skipping frame to display 10284 * @skipCnt : Number of frame to skip. 0 by default 10285 * 10286 * RETURN : None 10287 *==========================================================================*/ 10288 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt) 10289 { 10290 pthread_mutex_lock(&mGrallocLock); 10291 if (enabled) { 10292 setDisplayFrameSkip(); 10293 setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1); 10294 } else { 10295 setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1)); 10296 } 10297 pthread_mutex_unlock(&mGrallocLock); 10298 } 10299 10300 /*=========================================================================== 10301 * FUNCTION : setDisplayFrameSkip 10302 * 10303 * DESCRIPTION: set range of frames to skip for preview 10304 * 10305 * PARAMETERS : 10306 * @start : frameId to start skip 10307 * @end : frameId to stop skip 10308 * 10309 * RETURN : None 10310 *==========================================================================*/ 10311 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start, 10312 uint32_t end) 10313 { 10314 if (start == 0) { 10315 mFrameSkipStart = 0; 10316 mFrameSkipEnd = 0; 10317 return; 10318 } 10319 if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) { 10320 mFrameSkipStart = start; 10321 } 10322 if ((end == 0) || (end > mFrameSkipEnd)) { 10323 mFrameSkipEnd = end; 10324 } 10325 } 10326 10327 /*=========================================================================== 10328 * FUNCTION : isDisplayFrameToSkip 10329 * 10330 * DESCRIPTION: function to determin if input frame falls under skip range 10331 * 10332 * PARAMETERS : 10333 * @frameId : frameId to verify 10334 * 10335 * RETURN : true : need to skip 10336 * false: no need to skip 10337 *==========================================================================*/ 10338 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId) 10339 { 10340 return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) && 10341 (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE; 10342 } 10343 10344 /*=========================================================================== 10345 * FUNCTION : getSnapshotHandle 10346 * 10347 * DESCRIPTION: Get the camera handle for snapshot based on the bundlesnapshot 10348 * flag and active camera state 10349 * 10350 * PARAMETERS : None 10351 * 10352 * RETURN : camera handle for snapshot 10353 * 10354 *==========================================================================*/ 10355 uint32_t QCamera2HardwareInterface::getSnapshotHandle() 10356 { 10357 uint32_t snapshotHandle = 0; 10358 10359 if ((mActiveCameras == MM_CAMERA_DUAL_CAM) && mBundledSnapshot) { 10360 snapshotHandle = mCameraHandle->camera_handle; 10361 } else { 10362 snapshotHandle = (mMasterCamera == MM_CAMERA_TYPE_MAIN) ? 10363 get_main_camera_handle(mCameraHandle->camera_handle) : 10364 get_aux_camera_handle(mCameraHandle->camera_handle); 10365 } 10366 10367 return snapshotHandle; 10368 } 10369 10370 /*=========================================================================== 10371 * FUNCTION : prepareHardwareForSnapshot 10372 * 10373 * DESCRIPTION: prepare hardware for snapshot, such as LED 10374 * 10375 * PARAMETERS : 10376 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation 10377 * 10378 * RETURN : int32_t type of status 10379 * NO_ERROR -- success 10380 * none-zero failure code 10381 *==========================================================================*/ 10382 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded) 10383 { 10384 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_HW_FOR_SNAPSHOT); 10385 LOGI("[KPI Perf]: Send PREPARE SANSPHOT event"); 10386 return mCameraHandle->ops->prepare_snapshot(getSnapshotHandle(), 10387 afNeeded); 10388 } 10389 10390 /*=========================================================================== 10391 * FUNCTION : needFDMetadata 10392 * 10393 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel 10394 * 10395 * PARAMETERS : 10396 * @channel_type: channel type 10397 * 10398 * RETURN : true: needed 10399 * false: no need 10400 *==========================================================================*/ 10401 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type) 10402 { 10403 //Note: Currently we only process ZSL channel 10404 bool value = false; 10405 if(channel_type == QCAMERA_CH_TYPE_ZSL){ 10406 //check if FD requirement is enabled 10407 if(mParameters.isSnapshotFDNeeded() && 10408 mParameters.isFaceDetectionEnabled()){ 10409 value = true; 10410 LOGH("Face Detection metadata is required in ZSL mode."); 10411 } 10412 } 10413 10414 return value; 10415 } 10416 10417 /*=========================================================================== 10418 * FUNCTION : deferredWorkRoutine 10419 * 10420 * DESCRIPTION: data process routine that executes deferred tasks 10421 * 10422 * PARAMETERS : 10423 * @data : user data ptr (QCamera2HardwareInterface) 10424 * 10425 * RETURN : None 10426 *==========================================================================*/ 10427 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj) 10428 { 10429 int running = 1; 10430 int ret; 10431 uint8_t is_active = FALSE; 10432 int32_t job_status = 0; 10433 10434 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj; 10435 QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread; 10436 cmdThread->setName("CAM_defrdWrk"); 10437 10438 do { 10439 do { 10440 ret = cam_sem_wait(&cmdThread->cmd_sem); 10441 if (ret != 0 && errno != EINVAL) { 10442 LOGE("cam_sem_wait error (%s)", 10443 strerror(errno)); 10444 return NULL; 10445 } 10446 } while (ret != 0); 10447 10448 // we got notified about new cmd avail in cmd queue 10449 camera_cmd_type_t cmd = cmdThread->getCmd(); 10450 LOGD("cmd: %d", cmd); 10451 switch (cmd) { 10452 case CAMERA_CMD_TYPE_START_DATA_PROC: 10453 LOGH("start data proc"); 10454 is_active = TRUE; 10455 break; 10456 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 10457 LOGH("stop data proc"); 10458 is_active = FALSE; 10459 // signal cmd is completed 10460 cam_sem_post(&cmdThread->sync_sem); 10461 break; 10462 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 10463 { 10464 DefWork *dw = 10465 reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue()); 10466 10467 if ( NULL == dw ) { 10468 LOGE("Invalid deferred work"); 10469 break; 10470 } 10471 10472 switch( dw->cmd ) { 10473 case CMD_DEF_ALLOCATE_BUFF: 10474 { 10475 QCameraChannel * pChannel = dw->args.allocArgs.ch; 10476 10477 if ( NULL == pChannel ) { 10478 LOGE("Invalid deferred work channel"); 10479 job_status = BAD_VALUE; 10480 break; 10481 } 10482 10483 cam_stream_type_t streamType = dw->args.allocArgs.type; 10484 LOGH("Deferred buffer allocation started for stream type: %d", 10485 streamType); 10486 10487 uint32_t iNumOfStreams = pChannel->getNumOfStreams(); 10488 QCameraStream *pStream = NULL; 10489 for ( uint32_t i = 0; i < iNumOfStreams; ++i) { 10490 pStream = pChannel->getStreamByIndex(i); 10491 10492 if ( NULL == pStream ) { 10493 job_status = BAD_VALUE; 10494 break; 10495 } 10496 10497 if ( pStream->isTypeOf(streamType)) { 10498 if ( pStream->allocateBuffers() ) { 10499 LOGE("Error allocating buffers !!!"); 10500 job_status = NO_MEMORY; 10501 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10502 CAMERA_ERROR_UNKNOWN, 0); 10503 } 10504 break; 10505 } 10506 } 10507 } 10508 break; 10509 case CMD_DEF_PPROC_START: 10510 { 10511 int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob); 10512 if (ret != NO_ERROR) { 10513 job_status = ret; 10514 LOGE("PPROC Start failed"); 10515 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10516 CAMERA_ERROR_UNKNOWN, 0); 10517 break; 10518 } 10519 QCameraChannel * pChannel = dw->args.pprocArgs; 10520 assert(pChannel); 10521 10522 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) { 10523 LOGE("cannot start postprocessor"); 10524 job_status = BAD_VALUE; 10525 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10526 CAMERA_ERROR_UNKNOWN, 0); 10527 } 10528 } 10529 break; 10530 case CMD_DEF_METADATA_ALLOC: 10531 { 10532 int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob); 10533 if (ret != NO_ERROR) { 10534 job_status = ret; 10535 LOGE("Metadata alloc failed"); 10536 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10537 CAMERA_ERROR_UNKNOWN, 0); 10538 break; 10539 } 10540 pme->mMetadataMem = new QCameraMetadataStreamMemory( 10541 QCAMERA_ION_USE_CACHE); 10542 10543 if (pme->mMetadataMem == NULL) { 10544 LOGE("Unable to allocate metadata buffers"); 10545 job_status = BAD_VALUE; 10546 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10547 CAMERA_ERROR_UNKNOWN, 0); 10548 } else { 10549 int32_t rc = pme->mMetadataMem->allocate( 10550 dw->args.metadataAllocArgs.bufferCnt, 10551 dw->args.metadataAllocArgs.size); 10552 if (rc < 0) { 10553 delete pme->mMetadataMem; 10554 pme->mMetadataMem = NULL; 10555 } 10556 } 10557 } 10558 break; 10559 case CMD_DEF_CREATE_JPEG_SESSION: 10560 { 10561 QCameraChannel * pChannel = dw->args.pprocArgs; 10562 assert(pChannel); 10563 10564 int32_t ret = pme->getDefJobStatus(pme->mReprocJob); 10565 if (ret != NO_ERROR) { 10566 job_status = ret; 10567 LOGE("Jpeg create failed"); 10568 break; 10569 } 10570 10571 if (pme->m_postprocessor.createJpegSession(pChannel) 10572 != NO_ERROR) { 10573 LOGE("cannot create JPEG session"); 10574 job_status = UNKNOWN_ERROR; 10575 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10576 CAMERA_ERROR_UNKNOWN, 0); 10577 } 10578 } 10579 break; 10580 case CMD_DEF_PPROC_INIT: 10581 { 10582 int32_t rc = NO_ERROR; 10583 10584 jpeg_encode_callback_t jpegEvtHandle = 10585 dw->args.pprocInitArgs.jpeg_cb; 10586 void* user_data = dw->args.pprocInitArgs.user_data; 10587 QCameraPostProcessor *postProcessor = 10588 &(pme->m_postprocessor); 10589 uint32_t cameraId = pme->mCameraId; 10590 cam_capability_t *capability = 10591 gCamCapability[cameraId]; 10592 cam_padding_info_t padding_info; 10593 cam_padding_info_t& cam_capability_padding_info = 10594 capability->padding_info; 10595 10596 if(!pme->mJpegClientHandle) { 10597 rc = pme->initJpegHandle(); 10598 if (rc != NO_ERROR) { 10599 LOGE("Error!! creating JPEG handle failed"); 10600 job_status = UNKNOWN_ERROR; 10601 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10602 CAMERA_ERROR_UNKNOWN, 0); 10603 break; 10604 } 10605 } 10606 LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle); 10607 10608 rc = postProcessor->setJpegHandle(&pme->mJpegHandle, 10609 &pme->mJpegMpoHandle, 10610 pme->mJpegClientHandle); 10611 if (rc != 0) { 10612 LOGE("Error!! set JPEG handle failed"); 10613 job_status = UNKNOWN_ERROR; 10614 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10615 CAMERA_ERROR_UNKNOWN, 0); 10616 break; 10617 } 10618 10619 /* get max pic size for jpeg work buf calculation*/ 10620 rc = postProcessor->init(jpegEvtHandle, user_data); 10621 10622 if (rc != NO_ERROR) { 10623 LOGE("cannot init postprocessor"); 10624 job_status = UNKNOWN_ERROR; 10625 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10626 CAMERA_ERROR_UNKNOWN, 0); 10627 break; 10628 } 10629 10630 // update padding info from jpeg 10631 postProcessor->getJpegPaddingReq(padding_info); 10632 if (cam_capability_padding_info.width_padding < 10633 padding_info.width_padding) { 10634 cam_capability_padding_info.width_padding = 10635 padding_info.width_padding; 10636 } 10637 if (cam_capability_padding_info.height_padding < 10638 padding_info.height_padding) { 10639 cam_capability_padding_info.height_padding = 10640 padding_info.height_padding; 10641 } 10642 if (cam_capability_padding_info.plane_padding != 10643 padding_info.plane_padding) { 10644 cam_capability_padding_info.plane_padding = 10645 mm_stream_calc_lcm( 10646 cam_capability_padding_info.plane_padding, 10647 padding_info.plane_padding); 10648 } 10649 if (cam_capability_padding_info.offset_info.offset_x 10650 != padding_info.offset_info.offset_x) { 10651 cam_capability_padding_info.offset_info.offset_x = 10652 mm_stream_calc_lcm ( 10653 cam_capability_padding_info.offset_info.offset_x, 10654 padding_info.offset_info.offset_x); 10655 } 10656 if (cam_capability_padding_info.offset_info.offset_y 10657 != padding_info.offset_info.offset_y) { 10658 cam_capability_padding_info.offset_info.offset_y = 10659 mm_stream_calc_lcm ( 10660 cam_capability_padding_info.offset_info.offset_y, 10661 padding_info.offset_info.offset_y); 10662 } 10663 } 10664 break; 10665 case CMD_DEF_PARAM_ALLOC: 10666 { 10667 int32_t rc = NO_ERROR; 10668 if (pme->isDualCamera()) { 10669 rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT); 10670 } else { 10671 rc = pme->mParameters.allocate(); 10672 } 10673 // notify routine would not be initialized by this time. 10674 // So, just update error job status 10675 if (rc != NO_ERROR) { 10676 job_status = rc; 10677 LOGE("Param allocation failed"); 10678 break; 10679 } 10680 } 10681 break; 10682 case CMD_DEF_PARAM_INIT: 10683 { 10684 int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob); 10685 if (rc != NO_ERROR) { 10686 job_status = rc; 10687 LOGE("Param init failed"); 10688 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10689 CAMERA_ERROR_UNKNOWN, 0); 10690 break; 10691 } 10692 10693 uint32_t camId = pme->mCameraId; 10694 cam_capability_t * cap = gCamCapability[camId]; 10695 10696 if (pme->mCameraHandle == NULL) { 10697 LOGE("Camera handle is null"); 10698 job_status = BAD_VALUE; 10699 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10700 CAMERA_ERROR_UNKNOWN, 0); 10701 break; 10702 } 10703 10704 // Now PostProc need calibration data as initialization 10705 // time for jpeg_open and calibration data is a 10706 // get param for now, so params needs to be initialized 10707 // before postproc init 10708 rc = pme->mParameters.init(cap, 10709 pme->mCameraHandle, 10710 pme, pme->m_pFovControl); 10711 if (rc != 0) { 10712 job_status = UNKNOWN_ERROR; 10713 LOGE("Parameter Initialization failed"); 10714 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10715 CAMERA_ERROR_UNKNOWN, 0); 10716 break; 10717 } 10718 10719 // Get related cam calibration only in 10720 // dual camera mode 10721 if ((pme->getRelatedCamSyncInfo()->sync_control == 10722 CAM_SYNC_RELATED_SENSORS_ON) || pme->isDualCamera()){ 10723 rc = pme->mParameters.getRelatedCamCalibration( 10724 &(pme->mJpegMetadata.otp_calibration_data)); 10725 LOGD("Dumping Calibration Data Version Id %f rc %d", 10726 pme->mJpegMetadata.otp_calibration_data.calibration_format_version, 10727 rc); 10728 if (rc != 0) { 10729 job_status = UNKNOWN_ERROR; 10730 LOGE("getRelatedCamCalibration failed"); 10731 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10732 CAMERA_ERROR_UNKNOWN, 0); 10733 break; 10734 } 10735 pme->m_bRelCamCalibValid = true; 10736 } 10737 10738 pme->mJpegMetadata.sensor_mount_angle = 10739 cap->sensor_mount_angle; 10740 pme->mJpegMetadata.default_sensor_flip = FLIP_NONE; 10741 10742 pme->mParameters.setMinPpMask( 10743 cap->qcom_supported_feature_mask); 10744 pme->mExifParams.debug_params = 10745 (mm_jpeg_debug_exif_params_t *) 10746 malloc(sizeof(mm_jpeg_debug_exif_params_t)); 10747 if (!pme->mExifParams.debug_params) { 10748 LOGE("Out of Memory. Allocation failed for " 10749 "3A debug exif params"); 10750 job_status = NO_MEMORY; 10751 pme->sendEvtNotify(CAMERA_MSG_ERROR, 10752 CAMERA_ERROR_UNKNOWN, 0); 10753 break; 10754 } 10755 memset(pme->mExifParams.debug_params, 0, 10756 sizeof(mm_jpeg_debug_exif_params_t)); 10757 } 10758 break; 10759 case CMD_DEF_GENERIC: 10760 { 10761 BackgroundTask *bgTask = dw->args.genericArgs; 10762 job_status = bgTask->bgFunction(bgTask->bgArgs); 10763 } 10764 break; 10765 default: 10766 LOGE("Incorrect command : %d", dw->cmd); 10767 } 10768 10769 pme->dequeueDeferredWork(dw, job_status); 10770 } 10771 break; 10772 case CAMERA_CMD_TYPE_EXIT: 10773 running = 0; 10774 break; 10775 default: 10776 break; 10777 } 10778 } while (running); 10779 10780 return NULL; 10781 } 10782 10783 /*=========================================================================== 10784 * FUNCTION : queueDeferredWork 10785 * 10786 * DESCRIPTION: function which queues deferred tasks 10787 * 10788 * PARAMETERS : 10789 * @cmd : deferred task 10790 * @args : deferred task arguments 10791 * 10792 * RETURN : job id of deferred job 10793 * : 0 in case of error 10794 *==========================================================================*/ 10795 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd, 10796 DeferWorkArgs args) 10797 { 10798 Mutex::Autolock l(mDefLock); 10799 for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) { 10800 if (mDefOngoingJobs[i].mDefJobId == 0) { 10801 DefWork *dw = new DefWork(cmd, sNextJobId, args); 10802 if (!dw) { 10803 LOGE("out of memory."); 10804 return 0; 10805 } 10806 if (mCmdQueue.enqueue(dw)) { 10807 mDefOngoingJobs[i].mDefJobId = sNextJobId++; 10808 mDefOngoingJobs[i].mDefJobStatus = 0; 10809 if (sNextJobId == 0) { // handle overflow 10810 sNextJobId = 1; 10811 } 10812 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, 10813 FALSE, 10814 FALSE); 10815 return mDefOngoingJobs[i].mDefJobId; 10816 } else { 10817 LOGD("Command queue not active! cmd = %d", cmd); 10818 delete dw; 10819 return 0; 10820 } 10821 } 10822 } 10823 return 0; 10824 } 10825 10826 /*=========================================================================== 10827 * FUNCTION : initJpegHandle 10828 * 10829 * DESCRIPTION: Opens JPEG client and gets a handle. 10830 * Sends Dual cam calibration info if present 10831 * 10832 * RETURN : int32_t type of status 10833 * NO_ERROR -- success 10834 * none-zero failure code 10835 *==========================================================================*/ 10836 int32_t QCamera2HardwareInterface::initJpegHandle() { 10837 // Check if JPEG client handle is present 10838 LOGH("E"); 10839 if(!mJpegClientHandle) { 10840 mm_dimension max_size = {0, 0}; 10841 cam_dimension_t size; 10842 10843 mParameters.getMaxPicSize(size); 10844 max_size.w = size.width; 10845 max_size.h = size.height; 10846 10847 if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 10848 if (m_bRelCamCalibValid) { 10849 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle, 10850 max_size, &mJpegMetadata); 10851 } else { 10852 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle, 10853 max_size, NULL); 10854 } 10855 } else { 10856 mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL); 10857 } 10858 if (!mJpegClientHandle) { 10859 LOGE("Error !! jpeg_open failed!! "); 10860 return UNKNOWN_ERROR; 10861 } 10862 // Set JPEG initialized as true to signify that this camera 10863 // has initialized the handle 10864 mJpegHandleOwner = true; 10865 } 10866 LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d", 10867 mJpegHandleOwner, mJpegClientHandle, mCameraId); 10868 return NO_ERROR; 10869 } 10870 10871 /*=========================================================================== 10872 * FUNCTION : deinitJpegHandle 10873 * 10874 * DESCRIPTION: Closes JPEG client using handle 10875 * 10876 * RETURN : int32_t type of status 10877 * NO_ERROR -- success 10878 * none-zero failure code 10879 *==========================================================================*/ 10880 int32_t QCamera2HardwareInterface::deinitJpegHandle() { 10881 int32_t rc = NO_ERROR; 10882 LOGH("E"); 10883 // Check if JPEG client handle is present and inited by this camera 10884 if(mJpegHandleOwner && mJpegClientHandle) { 10885 rc = mJpegHandle.close(mJpegClientHandle); 10886 if (rc != NO_ERROR) { 10887 LOGE("Error!! Closing mJpegClientHandle: %d failed", 10888 mJpegClientHandle); 10889 } 10890 memset(&mJpegHandle, 0, sizeof(mJpegHandle)); 10891 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle)); 10892 mJpegHandleOwner = false; 10893 } 10894 mJpegClientHandle = 0; 10895 LOGH("X rc = %d", rc); 10896 return rc; 10897 } 10898 10899 /*=========================================================================== 10900 * FUNCTION : setJpegHandleInfo 10901 * 10902 * DESCRIPTION: sets JPEG client handle info 10903 * 10904 * PARAMETERS: 10905 * @ops : JPEG ops 10906 * @mpo_ops : Jpeg MPO ops 10907 * @pJpegClientHandle : o/p Jpeg Client Handle 10908 * 10909 * RETURN : int32_t type of status 10910 * NO_ERROR -- success 10911 * none-zero failure code 10912 *==========================================================================*/ 10913 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops, 10914 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) { 10915 10916 if (pJpegClientHandle && ops && mpo_ops) { 10917 LOGH("Setting JPEG client handle %d", 10918 pJpegClientHandle); 10919 memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t)); 10920 memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t)); 10921 mJpegClientHandle = pJpegClientHandle; 10922 return NO_ERROR; 10923 } 10924 else { 10925 LOGE("Error!! No Handle found: %d", 10926 pJpegClientHandle); 10927 return BAD_VALUE; 10928 } 10929 } 10930 10931 /*=========================================================================== 10932 * FUNCTION : getJpegHandleInfo 10933 * 10934 * DESCRIPTION: gets JPEG client handle info 10935 * 10936 * PARAMETERS: 10937 * @ops : JPEG ops 10938 * @mpo_ops : Jpeg MPO ops 10939 * @pJpegClientHandle : o/p Jpeg Client Handle 10940 * 10941 * RETURN : int32_t type of status 10942 * NO_ERROR -- success 10943 * none-zero failure code 10944 *==========================================================================*/ 10945 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops, 10946 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) { 10947 10948 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 10949 LOGE("Init PProc Deferred work failed"); 10950 return UNKNOWN_ERROR; 10951 } 10952 // Copy JPEG ops if present 10953 if (ops && mpo_ops && pJpegClientHandle) { 10954 memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t)); 10955 memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t)); 10956 *pJpegClientHandle = mJpegClientHandle; 10957 LOGH("Getting JPEG client handle %d", 10958 pJpegClientHandle); 10959 return NO_ERROR; 10960 } else { 10961 return BAD_VALUE; 10962 } 10963 } 10964 10965 /*=========================================================================== 10966 * FUNCTION : dequeueDeferredWork 10967 * 10968 * DESCRIPTION: function which dequeues deferred tasks 10969 * 10970 * PARAMETERS : 10971 * @dw : deferred work 10972 * @jobStatus: deferred task job status 10973 * 10974 * RETURN : int32_t type of status 10975 * NO_ERROR -- success 10976 * none-zero failure code 10977 *==========================================================================*/ 10978 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus) 10979 { 10980 Mutex::Autolock l(mDefLock); 10981 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 10982 if (mDefOngoingJobs[i].mDefJobId == dw->id) { 10983 if (jobStatus != NO_ERROR) { 10984 mDefOngoingJobs[i].mDefJobStatus = jobStatus; 10985 LOGH("updating job status %d for id %d", 10986 jobStatus, dw->id); 10987 } else { 10988 mDefOngoingJobs[i].mDefJobId = 0; 10989 mDefOngoingJobs[i].mDefJobStatus = 0; 10990 } 10991 delete dw; 10992 mDefCond.broadcast(); 10993 return NO_ERROR; 10994 } 10995 } 10996 10997 return UNKNOWN_ERROR; 10998 } 10999 11000 /*=========================================================================== 11001 * FUNCTION : getDefJobStatus 11002 * 11003 * DESCRIPTION: Gets if a deferred task is success/fail 11004 * 11005 * PARAMETERS : 11006 * @job_id : deferred task id 11007 * 11008 * RETURN : NO_ERROR if the job success, otherwise false 11009 * 11010 * PRECONDITION : mDefLock is held by current thread 11011 *==========================================================================*/ 11012 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id) 11013 { 11014 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 11015 if (mDefOngoingJobs[i].mDefJobId == job_id) { 11016 if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) { 11017 LOGE("job_id (%d) was failed", job_id); 11018 return mDefOngoingJobs[i].mDefJobStatus; 11019 } 11020 else 11021 return NO_ERROR; 11022 } 11023 } 11024 return NO_ERROR; 11025 } 11026 11027 11028 /*=========================================================================== 11029 * FUNCTION : checkDeferredWork 11030 * 11031 * DESCRIPTION: checks if a deferred task is in progress 11032 * 11033 * PARAMETERS : 11034 * @job_id : deferred task id 11035 * 11036 * RETURN : true if the task exists, otherwise false 11037 * 11038 * PRECONDITION : mDefLock is held by current thread 11039 *==========================================================================*/ 11040 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id) 11041 { 11042 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 11043 if (mDefOngoingJobs[i].mDefJobId == job_id) { 11044 return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus); 11045 } 11046 } 11047 return false; 11048 } 11049 11050 /*=========================================================================== 11051 * FUNCTION : waitDeferredWork 11052 * 11053 * DESCRIPTION: waits for a deferred task to finish 11054 * 11055 * PARAMETERS : 11056 * @job_id : deferred task id 11057 * 11058 * RETURN : int32_t type of status 11059 * NO_ERROR -- success 11060 * none-zero failure code 11061 *==========================================================================*/ 11062 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id) 11063 { 11064 Mutex::Autolock l(mDefLock); 11065 11066 if (job_id == 0) { 11067 LOGD("Invalid job id %d", job_id); 11068 return NO_ERROR; 11069 } 11070 11071 while (checkDeferredWork(job_id) == true ) { 11072 mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT); 11073 } 11074 return getDefJobStatus(job_id); 11075 } 11076 11077 /*=========================================================================== 11078 * FUNCTION : scheduleBackgroundTask 11079 * 11080 * DESCRIPTION: Run a requested task in the deferred thread 11081 * 11082 * PARAMETERS : 11083 * @bgTask : Task to perform in the background 11084 * 11085 * RETURN : job id of deferred job 11086 * : 0 in case of error 11087 *==========================================================================*/ 11088 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask) 11089 { 11090 DeferWorkArgs args; 11091 memset(&args, 0, sizeof(DeferWorkArgs)); 11092 args.genericArgs = bgTask; 11093 11094 return queueDeferredWork(CMD_DEF_GENERIC, args); 11095 } 11096 11097 /*=========================================================================== 11098 * FUNCTION : waitForBackgroundTask 11099 * 11100 * DESCRIPTION: Wait for a background task to complete 11101 * 11102 * PARAMETERS : 11103 * @taskId : Task id to wait for 11104 * 11105 * RETURN : int32_t type of status 11106 * NO_ERROR -- success 11107 * none-zero failure code 11108 *==========================================================================*/ 11109 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId) 11110 { 11111 return waitDeferredWork(taskId); 11112 } 11113 11114 /*=========================================================================== 11115 * FUNCTION : needDeferedAllocation 11116 * 11117 * DESCRIPTION: Function to decide background task for streams 11118 * 11119 * PARAMETERS : 11120 * @stream_type : stream type 11121 * 11122 * RETURN : true - if background task is needed 11123 * false - if background task is NOT needed 11124 *==========================================================================*/ 11125 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type) 11126 { 11127 if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL) 11128 || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) { 11129 return FALSE; 11130 } 11131 11132 if ((stream_type == CAM_STREAM_TYPE_RAW) 11133 && (mParameters.getofflineRAW() && !mParameters.getQuadraCfa())) { 11134 return FALSE; 11135 } 11136 11137 if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT) 11138 && (!mParameters.getRecordingHintValue())){ 11139 return TRUE; 11140 } 11141 11142 if ((stream_type == CAM_STREAM_TYPE_PREVIEW) 11143 || (stream_type == CAM_STREAM_TYPE_METADATA) 11144 || (stream_type == CAM_STREAM_TYPE_RAW) 11145 || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) { 11146 return TRUE; 11147 } 11148 11149 if (stream_type == CAM_STREAM_TYPE_VIDEO) { 11150 return FALSE; 11151 } 11152 return FALSE; 11153 } 11154 11155 /*=========================================================================== 11156 * FUNCTION : needSyncCB 11157 * 11158 * DESCRIPTION: Decide syncronous callback per stream 11159 * 11160 * PARAMETERS : 11161 * @stream_type: stream type 11162 * 11163 * RETURN : true - if background task is needed 11164 * false - if background task is NOT needed 11165 *==========================================================================*/ 11166 bool QCamera2HardwareInterface::needSyncCB(cam_stream_type_t stream_type) 11167 { 11168 #ifdef TARGET_TS_MAKEUP 11169 int whiteLevel, cleanLevel; 11170 if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == TRUE) { 11171 return FALSE; 11172 } 11173 #endif 11174 11175 char value[PROPERTY_VALUE_MAX]; 11176 property_get("persist.camera.preview.sync_cb", value, "1"); 11177 if ((atoi(value) == 1) && (stream_type == CAM_STREAM_TYPE_PREVIEW)) { 11178 return TRUE; 11179 } 11180 return FALSE; 11181 } 11182 11183 /*=========================================================================== 11184 * FUNCTION : isRegularCapture 11185 * 11186 * DESCRIPTION: Check configuration for regular catpure 11187 * 11188 * PARAMETERS : 11189 * 11190 * RETURN : true - regular capture 11191 * false - other type of capture 11192 *==========================================================================*/ 11193 bool QCamera2HardwareInterface::isRegularCapture() 11194 { 11195 bool ret = false; 11196 11197 if (numOfSnapshotsExpected() == 1 && 11198 !isLongshotEnabled() && 11199 !mParameters.isHDREnabled() && 11200 !mParameters.getRecordingHintValue() && 11201 !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) { 11202 ret = true; 11203 } 11204 return ret; 11205 } 11206 11207 /*=========================================================================== 11208 * FUNCTION : needOfflineReprocessing 11209 * 11210 * DESCRIPTION: Check for offline reprocessing 11211 * 11212 * PARAMETERS : 11213 * 11214 * RETURN : true - regular capture 11215 * false - other type of capture 11216 *==========================================================================*/ 11217 bool QCamera2HardwareInterface::needOfflineReprocessing() 11218 { 11219 bool ret = false; 11220 if (isRegularCapture() 11221 || isDualCamera()) { 11222 ret = true; 11223 } 11224 return ret; 11225 } 11226 11227 /*=========================================================================== 11228 * FUNCTION : getLogLevel 11229 * 11230 * DESCRIPTION: Reads the log level property into a variable 11231 * 11232 * PARAMETERS : 11233 * None 11234 * 11235 * RETURN : 11236 * None 11237 *==========================================================================*/ 11238 void QCamera2HardwareInterface::getLogLevel() 11239 { 11240 char prop[PROPERTY_VALUE_MAX]; 11241 11242 property_get("persist.camera.kpi.debug", prop, "0"); 11243 gKpiDebugLevel = atoi(prop); 11244 return; 11245 } 11246 11247 /*=========================================================================== 11248 * FUNCTION : getSensorType 11249 * 11250 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer 11251 * 11252 * PARAMETERS : 11253 * None 11254 * 11255 * RETURN : Type of sensor - bayer or YUV 11256 * 11257 *==========================================================================*/ 11258 cam_sensor_t QCamera2HardwareInterface::getSensorType() 11259 { 11260 return gCamCapability[mCameraId]->sensor_type.sens_type; 11261 } 11262 11263 /*=========================================================================== 11264 * FUNCTION : startRAWChannel 11265 * 11266 * DESCRIPTION: start RAW Channel 11267 * 11268 * PARAMETERS : 11269 * @pChannel : Src channel to link this RAW channel. 11270 * 11271 * RETURN : int32_t type of status 11272 * NO_ERROR -- success 11273 * none-zero failure code 11274 *==========================================================================*/ 11275 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel) 11276 { 11277 int32_t rc = NO_ERROR; 11278 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW]; 11279 if ((NULL != pChannel) && (mParameters.getofflineRAW())) { 11280 // Find and try to link a metadata stream from preview channel 11281 QCameraStream *pMetaStream = NULL; 11282 11283 if (pMetaChannel != NULL) { 11284 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 11285 QCameraStream *pStream = NULL; 11286 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 11287 pStream = pMetaChannel->getStreamByIndex(i); 11288 if ((NULL != pStream) && 11289 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) { 11290 pMetaStream = pStream; 11291 break; 11292 } 11293 } 11294 11295 if (NULL != pMetaStream) { 11296 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 11297 if (NO_ERROR != rc) { 11298 LOGE("Metadata stream link failed %d", rc); 11299 } 11300 } 11301 } 11302 rc = pChannel->start(); 11303 } 11304 return rc; 11305 } 11306 11307 /*=========================================================================== 11308 * FUNCTION : startRecording 11309 * 11310 * DESCRIPTION: start recording impl 11311 * 11312 * PARAMETERS : none 11313 * 11314 * RETURN : int32_t type of status 11315 * NO_ERROR -- success 11316 * none-zero failure code 11317 *==========================================================================*/ 11318 int32_t QCamera2HardwareInterface::stopRAWChannel() 11319 { 11320 int32_t rc = NO_ERROR; 11321 rc = stopChannel(QCAMERA_CH_TYPE_RAW); 11322 return rc; 11323 } 11324 11325 /*=========================================================================== 11326 * FUNCTION : isLowPowerMode 11327 * 11328 * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording 11329 * 11330 * PARAMETERS : 11331 * None 11332 * 11333 * RETURN : TRUE/FALSE 11334 * 11335 *==========================================================================*/ 11336 bool QCamera2HardwareInterface::isLowPowerMode() 11337 { 11338 cam_dimension_t dim; 11339 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim); 11340 11341 char prop[PROPERTY_VALUE_MAX]; 11342 property_get("camera.lowpower.record.enable", prop, "0"); 11343 int enable = atoi(prop); 11344 11345 //Enable low power mode if : 11346 //1. Video resolution is 2k (2048x1080) or above and 11347 //2. camera.lowpower.record.enable is set 11348 11349 bool isLowpower = mParameters.getRecordingHintValue() && enable 11350 && ((dim.width * dim.height) >= (2048 * 1080)); 11351 return isLowpower; 11352 } 11353 11354 /*=========================================================================== 11355 * FUNCTION : getBootToMonoTimeOffset 11356 * 11357 * DESCRIPTION: Calculate offset that is used to convert from 11358 * clock domain of boot to monotonic 11359 * 11360 * PARAMETERS : 11361 * None 11362 * 11363 * RETURN : clock offset between boottime and monotonic time. 11364 * 11365 *==========================================================================*/ 11366 nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset() 11367 { 11368 // try three times to get the clock offset, choose the one 11369 // with the minimum gap in measurements. 11370 const int tries = 3; 11371 nsecs_t bestGap, measured; 11372 for (int i = 0; i < tries; ++i) { 11373 const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC); 11374 const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME); 11375 const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC); 11376 const nsecs_t gap = tmono2 - tmono; 11377 if (i == 0 || gap < bestGap) { 11378 bestGap = gap; 11379 measured = tbase - ((tmono + tmono2) >> 1); 11380 } 11381 } 11382 return measured; 11383 } 11384 11385 /*=========================================================================== 11386 * FUNCTION : fillDualCameraFOVControl 11387 * 11388 * DESCRIPTION: Function to process FOV ctrl event from statemachine thread. 11389 * 11390 * PARAMETERS : none 11391 * 11392 * RETURN : none 11393 *==========================================================================*/ 11394 void QCamera2HardwareInterface::fillDualCameraFOVControl() 11395 { 11396 qcamera_sm_internal_evt_payload_t *payload = 11397 (qcamera_sm_internal_evt_payload_t *) 11398 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 11399 if (NULL != payload) { 11400 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 11401 payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL; 11402 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 11403 if (rc != NO_ERROR) { 11404 LOGE("processEvt Dual camera fill FOV control failed"); 11405 free(payload); 11406 payload = NULL; 11407 } 11408 } else { 11409 LOGE("No memory for Dual camera fill FOV control event"); 11410 } 11411 } 11412 11413 }; // namespace qcamera 11414