1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_TAG "QCamera2HWI" 31 32 // To remove 33 #include <cutils/properties.h> 34 35 // System definitions 36 #include <utils/Errors.h> 37 #include <dlfcn.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include "gralloc_priv.h" 41 #include "native_handle.h" 42 43 // Camera definitions 44 #include "android/QCamera2External.h" 45 #include "QCamera2HWI.h" 46 #include "QCameraBufferMaps.h" 47 #include "QCameraFlash.h" 48 #include "QCameraTrace.h" 49 50 extern "C" { 51 #include "mm_camera_dbg.h" 52 } 53 54 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \ 55 ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset) 56 #define CAMERA_MIN_STREAMING_BUFFERS 3 57 #define EXTRA_ZSL_PREVIEW_STREAM_BUF 2 58 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2 59 #define CAMERA_MIN_VIDEO_BUFFERS 9 60 #define CAMERA_MIN_CALLBACK_BUFFERS 5 61 #define CAMERA_LONGSHOT_STAGES 4 62 #define CAMERA_MIN_CAMERA_BATCH_BUFFERS 6 63 #define CAMERA_ISP_PING_PONG_BUFFERS 2 64 #define MIN_UNDEQUEUED_BUFFERS 1 // This is required if preview window is not set 65 66 #define HDR_CONFIDENCE_THRESHOLD 0.4 67 68 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds 69 70 // Very long wait, just to be sure we don't deadlock 71 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds 72 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds 73 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot 74 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5 75 #define CAMERA_MAX_PARAM_APPLY_DELAY 3 76 77 namespace qcamera { 78 79 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS]; 80 extern pthread_mutex_t gCamLock; 81 volatile uint32_t gCamHalLogLevel = 1; 82 extern uint8_t gNumCameraSessions; 83 uint32_t QCamera2HardwareInterface::sNextJobId = 1; 84 85 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = { 86 .set_preview_window = QCamera2HardwareInterface::set_preview_window, 87 .set_callbacks = QCamera2HardwareInterface::set_CallBacks, 88 .enable_msg_type = QCamera2HardwareInterface::enable_msg_type, 89 .disable_msg_type = QCamera2HardwareInterface::disable_msg_type, 90 .msg_type_enabled = QCamera2HardwareInterface::msg_type_enabled, 91 92 .start_preview = QCamera2HardwareInterface::start_preview, 93 .stop_preview = QCamera2HardwareInterface::stop_preview, 94 .preview_enabled = QCamera2HardwareInterface::preview_enabled, 95 .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers, 96 97 .start_recording = QCamera2HardwareInterface::start_recording, 98 .stop_recording = QCamera2HardwareInterface::stop_recording, 99 .recording_enabled = QCamera2HardwareInterface::recording_enabled, 100 .release_recording_frame = QCamera2HardwareInterface::release_recording_frame, 101 102 .auto_focus = QCamera2HardwareInterface::auto_focus, 103 .cancel_auto_focus = QCamera2HardwareInterface::cancel_auto_focus, 104 105 .take_picture = QCamera2HardwareInterface::take_picture, 106 .cancel_picture = QCamera2HardwareInterface::cancel_picture, 107 108 .set_parameters = QCamera2HardwareInterface::set_parameters, 109 .get_parameters = QCamera2HardwareInterface::get_parameters, 110 .put_parameters = QCamera2HardwareInterface::put_parameters, 111 .send_command = QCamera2HardwareInterface::send_command, 112 113 .release = QCamera2HardwareInterface::release, 114 .dump = QCamera2HardwareInterface::dump, 115 }; 116 117 /*=========================================================================== 118 * FUNCTION : set_preview_window 119 * 120 * DESCRIPTION: set preview window. 121 * 122 * PARAMETERS : 123 * @device : ptr to camera device struct 124 * @window : window ops table 125 * 126 * RETURN : int32_t type of status 127 * NO_ERROR -- success 128 * none-zero failure code 129 *==========================================================================*/ 130 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device, 131 struct preview_stream_ops *window) 132 { 133 ATRACE_CALL(); 134 int rc = NO_ERROR; 135 QCamera2HardwareInterface *hw = 136 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 137 if (!hw) { 138 LOGE("NULL camera device"); 139 return BAD_VALUE; 140 } 141 LOGD("E camera id %d window = %p", hw->getCameraId(), window); 142 143 hw->lockAPI(); 144 qcamera_api_result_t apiResult; 145 rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window); 146 if (rc == NO_ERROR) { 147 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult); 148 rc = apiResult.status; 149 } 150 hw->unlockAPI(); 151 LOGD("X camera id %d", hw->getCameraId()); 152 153 return rc; 154 } 155 156 /*=========================================================================== 157 * FUNCTION : set_CallBacks 158 * 159 * DESCRIPTION: set callbacks for notify and data 160 * 161 * PARAMETERS : 162 * @device : ptr to camera device struct 163 * @notify_cb : notify cb 164 * @data_cb : data cb 165 * @data_cb_timestamp : video data cd with timestamp 166 * @get_memory : ops table for request gralloc memory 167 * @user : user data ptr 168 * 169 * RETURN : none 170 *==========================================================================*/ 171 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device, 172 camera_notify_callback notify_cb, 173 camera_data_callback data_cb, 174 camera_data_timestamp_callback data_cb_timestamp, 175 camera_request_memory get_memory, 176 void *user) 177 { 178 ATRACE_CALL(); 179 QCamera2HardwareInterface *hw = 180 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 181 if (!hw) { 182 LOGE("NULL camera device"); 183 return; 184 } 185 LOGD("E camera id %d", hw->getCameraId()); 186 187 qcamera_sm_evt_setcb_payload_t payload; 188 payload.notify_cb = notify_cb; 189 payload.data_cb = data_cb; 190 payload.data_cb_timestamp = data_cb_timestamp; 191 payload.get_memory = get_memory; 192 payload.user = user; 193 194 hw->lockAPI(); 195 qcamera_api_result_t apiResult; 196 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload); 197 if (rc == NO_ERROR) { 198 hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult); 199 } 200 hw->unlockAPI(); 201 LOGD("X camera id %d", hw->getCameraId()); 202 203 } 204 205 /*=========================================================================== 206 * FUNCTION : enable_msg_type 207 * 208 * DESCRIPTION: enable certain msg type 209 * 210 * PARAMETERS : 211 * @device : ptr to camera device struct 212 * @msg_type : msg type mask 213 * 214 * RETURN : none 215 *==========================================================================*/ 216 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type) 217 { 218 ATRACE_CALL(); 219 QCamera2HardwareInterface *hw = 220 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 221 if (!hw) { 222 LOGE("NULL camera device"); 223 return; 224 } 225 LOGD("E camera id %d", hw->getCameraId()); 226 227 hw->lockAPI(); 228 qcamera_api_result_t apiResult; 229 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type); 230 if (rc == NO_ERROR) { 231 hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult); 232 } 233 hw->unlockAPI(); 234 LOGD("X camera id %d", hw->getCameraId()); 235 236 } 237 238 /*=========================================================================== 239 * FUNCTION : disable_msg_type 240 * 241 * DESCRIPTION: disable certain msg type 242 * 243 * PARAMETERS : 244 * @device : ptr to camera device struct 245 * @msg_type : msg type mask 246 * 247 * RETURN : none 248 *==========================================================================*/ 249 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type) 250 { 251 ATRACE_CALL(); 252 QCamera2HardwareInterface *hw = 253 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 254 if (!hw) { 255 LOGE("NULL camera device"); 256 return; 257 } 258 LOGD("E camera id %d", hw->getCameraId()); 259 260 hw->lockAPI(); 261 qcamera_api_result_t apiResult; 262 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type); 263 if (rc == NO_ERROR) { 264 hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult); 265 } 266 hw->unlockAPI(); 267 LOGD("X camera id %d", hw->getCameraId()); 268 269 } 270 271 /*=========================================================================== 272 * FUNCTION : msg_type_enabled 273 * 274 * DESCRIPTION: if certain msg type is enabled 275 * 276 * PARAMETERS : 277 * @device : ptr to camera device struct 278 * @msg_type : msg type mask 279 * 280 * RETURN : 1 -- enabled 281 * 0 -- not enabled 282 *==========================================================================*/ 283 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type) 284 { 285 ATRACE_CALL(); 286 int ret = NO_ERROR; 287 QCamera2HardwareInterface *hw = 288 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 289 if (!hw) { 290 LOGE("NULL camera device"); 291 return BAD_VALUE; 292 } 293 LOGD("E camera id %d", hw->getCameraId()); 294 295 hw->lockAPI(); 296 qcamera_api_result_t apiResult; 297 ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type); 298 if (ret == NO_ERROR) { 299 hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult); 300 ret = apiResult.enabled; 301 } 302 hw->unlockAPI(); 303 LOGD("X camera id %d", hw->getCameraId()); 304 305 return ret; 306 } 307 308 /*=========================================================================== 309 * FUNCTION : prepare_preview 310 * 311 * DESCRIPTION: prepare preview 312 * 313 * PARAMETERS : 314 * @device : ptr to camera device struct 315 * 316 * RETURN : int32_t type of status 317 * NO_ERROR -- success 318 * none-zero failure code 319 *==========================================================================*/ 320 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device) 321 { 322 ATRACE_CALL(); 323 int ret = NO_ERROR; 324 QCamera2HardwareInterface *hw = 325 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 326 if (!hw) { 327 LOGE("NULL camera device"); 328 return BAD_VALUE; 329 } 330 LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d", 331 hw->getCameraId()); 332 hw->lockAPI(); 333 qcamera_api_result_t apiResult; 334 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW; 335 ret = hw->processAPI(evt, NULL); 336 if (ret == NO_ERROR) { 337 hw->waitAPIResult(evt, &apiResult); 338 ret = apiResult.status; 339 } 340 hw->unlockAPI(); 341 LOGH("[KPI Perf]: X"); 342 return ret; 343 } 344 345 346 /*=========================================================================== 347 * FUNCTION : start_preview 348 * 349 * DESCRIPTION: start preview 350 * 351 * PARAMETERS : 352 * @device : ptr to camera device struct 353 * 354 * RETURN : int32_t type of status 355 * NO_ERROR -- success 356 * none-zero failure code 357 *==========================================================================*/ 358 int QCamera2HardwareInterface::start_preview(struct camera_device *device) 359 { 360 KPI_ATRACE_CALL(); 361 int ret = NO_ERROR; 362 QCamera2HardwareInterface *hw = 363 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 364 if (!hw) { 365 LOGE("NULL camera device"); 366 return BAD_VALUE; 367 } 368 LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d", 369 hw->getCameraId()); 370 371 // Release the timed perf lock acquired in openCamera 372 hw->m_perfLock.lock_rel_timed(); 373 374 hw->m_perfLock.lock_acq(); 375 hw->lockAPI(); 376 qcamera_api_result_t apiResult; 377 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW; 378 if (hw->isNoDisplayMode()) { 379 evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW; 380 } 381 ret = hw->processAPI(evt, NULL); 382 if (ret == NO_ERROR) { 383 hw->waitAPIResult(evt, &apiResult); 384 ret = apiResult.status; 385 } 386 hw->unlockAPI(); 387 hw->m_bPreviewStarted = true; 388 LOGI("[KPI Perf]: X ret = %d", ret); 389 return ret; 390 } 391 392 /*=========================================================================== 393 * FUNCTION : stop_preview 394 * 395 * DESCRIPTION: stop preview 396 * 397 * PARAMETERS : 398 * @device : ptr to camera device struct 399 * 400 * RETURN : none 401 *==========================================================================*/ 402 void QCamera2HardwareInterface::stop_preview(struct camera_device *device) 403 { 404 KPI_ATRACE_CALL(); 405 QCamera2HardwareInterface *hw = 406 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 407 if (!hw) { 408 LOGE("NULL camera device"); 409 return; 410 } 411 LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d", 412 hw->getCameraId()); 413 414 // Disable power Hint for preview 415 hw->m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false); 416 417 hw->m_perfLock.lock_acq(); 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_CALL(); 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_CALL(); 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_CALL(); 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_CALL(); 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_CALL(); 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 LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d", 653 hw->getCameraId()); 654 // Give HWI control to call pre_start_recording in single camera mode. 655 // In dual-cam mode, this control belongs to muxer. 656 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 657 ret = pre_start_recording(device); 658 if (ret != NO_ERROR) { 659 LOGE("pre_start_recording failed with ret = %d", ret); 660 return ret; 661 } 662 } 663 664 hw->lockAPI(); 665 qcamera_api_result_t apiResult; 666 ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL); 667 if (ret == NO_ERROR) { 668 hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult); 669 ret = apiResult.status; 670 } 671 hw->unlockAPI(); 672 hw->m_bRecordStarted = true; 673 LOGI("[KPI Perf]: X ret = %d", ret); 674 675 return ret; 676 } 677 678 /*=========================================================================== 679 * FUNCTION : stop_recording 680 * 681 * DESCRIPTION: stop recording 682 * 683 * PARAMETERS : 684 * @device : ptr to camera device struct 685 * 686 * RETURN : none 687 *==========================================================================*/ 688 void QCamera2HardwareInterface::stop_recording(struct camera_device *device) 689 { 690 ATRACE_CALL(); 691 QCamera2HardwareInterface *hw = 692 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 693 if (!hw) { 694 LOGE("NULL camera device"); 695 return; 696 } 697 LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d", 698 hw->getCameraId()); 699 700 hw->lockAPI(); 701 qcamera_api_result_t apiResult; 702 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL); 703 if (ret == NO_ERROR) { 704 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult); 705 } 706 hw->unlockAPI(); 707 LOGI("[KPI Perf]: X ret = %d", ret); 708 } 709 710 /*=========================================================================== 711 * FUNCTION : recording_enabled 712 * 713 * DESCRIPTION: if recording is running 714 * 715 * PARAMETERS : 716 * @device : ptr to camera device struct 717 * 718 * RETURN : 1 -- running 719 * 0 -- not running 720 *==========================================================================*/ 721 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device) 722 { 723 ATRACE_CALL(); 724 int ret = NO_ERROR; 725 QCamera2HardwareInterface *hw = 726 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 727 if (!hw) { 728 LOGE("NULL camera device"); 729 return BAD_VALUE; 730 } 731 LOGD("E camera id %d", hw->getCameraId()); 732 hw->lockAPI(); 733 qcamera_api_result_t apiResult; 734 ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL); 735 if (ret == NO_ERROR) { 736 hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult); 737 ret = apiResult.enabled; 738 } 739 hw->unlockAPI(); 740 LOGD("X camera id %d", hw->getCameraId()); 741 742 return ret; 743 } 744 745 /*=========================================================================== 746 * FUNCTION : release_recording_frame 747 * 748 * DESCRIPTION: return recording frame back 749 * 750 * PARAMETERS : 751 * @device : ptr to camera device struct 752 * @opaque : ptr to frame to be returned 753 * 754 * RETURN : none 755 *==========================================================================*/ 756 void QCamera2HardwareInterface::release_recording_frame( 757 struct camera_device *device, const void *opaque) 758 { 759 ATRACE_CALL(); 760 QCamera2HardwareInterface *hw = 761 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 762 if (!hw) { 763 LOGE("NULL camera device"); 764 return; 765 } 766 if (!opaque) { 767 LOGE("Error!! Frame info is NULL"); 768 return; 769 } 770 LOGD("E camera id %d", hw->getCameraId()); 771 hw->lockAPI(); 772 qcamera_api_result_t apiResult; 773 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque); 774 if (ret == NO_ERROR) { 775 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult); 776 } 777 hw->unlockAPI(); 778 LOGD("X camera id %d", hw->getCameraId()); 779 } 780 781 /*=========================================================================== 782 * FUNCTION : auto_focus 783 * 784 * DESCRIPTION: start auto focus 785 * 786 * PARAMETERS : 787 * @device : ptr to camera device struct 788 * 789 * RETURN : int32_t type of status 790 * NO_ERROR -- success 791 * none-zero failure code 792 *==========================================================================*/ 793 int QCamera2HardwareInterface::auto_focus(struct camera_device *device) 794 { 795 KPI_ATRACE_INT("Camera:AutoFocus", 1); 796 int ret = NO_ERROR; 797 QCamera2HardwareInterface *hw = 798 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 799 if (!hw) { 800 LOGE("NULL camera device"); 801 return BAD_VALUE; 802 } 803 LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d", 804 hw->getCameraId()); 805 hw->lockAPI(); 806 qcamera_api_result_t apiResult; 807 ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL); 808 if (ret == NO_ERROR) { 809 hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult); 810 ret = apiResult.status; 811 } 812 hw->unlockAPI(); 813 LOGH("[KPI Perf] : X ret = %d", ret); 814 815 return ret; 816 } 817 818 /*=========================================================================== 819 * FUNCTION : cancel_auto_focus 820 * 821 * DESCRIPTION: cancel auto focus 822 * 823 * PARAMETERS : 824 * @device : ptr to camera device struct 825 * 826 * RETURN : int32_t type of status 827 * NO_ERROR -- success 828 * none-zero failure code 829 *==========================================================================*/ 830 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device) 831 { 832 ATRACE_CALL(); 833 int ret = NO_ERROR; 834 QCamera2HardwareInterface *hw = 835 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 836 if (!hw) { 837 LOGE("NULL camera device"); 838 return BAD_VALUE; 839 } 840 LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d", 841 hw->getCameraId()); 842 hw->lockAPI(); 843 qcamera_api_result_t apiResult; 844 ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL); 845 if (ret == NO_ERROR) { 846 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult); 847 ret = apiResult.status; 848 } 849 hw->unlockAPI(); 850 LOGH("[KPI Perf] : X ret = %d", ret); 851 return ret; 852 } 853 854 /*=========================================================================== 855 * FUNCTION : pre_take_picture 856 * 857 * DESCRIPTION: pre take picture, restart preview if necessary. 858 * 859 * PARAMETERS : 860 * @device : ptr to camera device struct 861 * 862 * RETURN : int32_t type of status 863 * NO_ERROR -- success 864 * none-zero failure code 865 *==========================================================================*/ 866 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device) 867 { 868 ATRACE_CALL(); 869 int ret = NO_ERROR; 870 QCamera2HardwareInterface *hw = 871 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 872 if (!hw) { 873 LOGE("NULL camera device"); 874 return BAD_VALUE; 875 } 876 LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d", 877 hw->getCameraId()); 878 hw->lockAPI(); 879 qcamera_api_result_t apiResult; 880 ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL); 881 if (ret == NO_ERROR) { 882 hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult); 883 ret = apiResult.status; 884 } 885 hw->unlockAPI(); 886 LOGH("[KPI Perf]: X"); 887 return ret; 888 } 889 890 /*=========================================================================== 891 * FUNCTION : take_picture 892 * 893 * DESCRIPTION: take picture 894 * 895 * PARAMETERS : 896 * @device : ptr to camera device struct 897 * 898 * RETURN : int32_t type of status 899 * NO_ERROR -- success 900 * none-zero failure code 901 *==========================================================================*/ 902 int QCamera2HardwareInterface::take_picture(struct camera_device *device) 903 { 904 KPI_ATRACE_CALL(); 905 int ret = NO_ERROR; 906 QCamera2HardwareInterface *hw = 907 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 908 if (!hw) { 909 LOGE("NULL camera device"); 910 return BAD_VALUE; 911 } 912 LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d", 913 hw->getCameraId()); 914 if (!hw->mLongshotEnabled) { 915 hw->m_perfLock.lock_acq(); 916 } 917 qcamera_api_result_t apiResult; 918 919 /** Added support for Retro-active Frames: 920 * takePicture() is called before preparing Snapshot to indicate the 921 * mm-camera-channel to pick up legacy frames even 922 * before LED estimation is triggered. 923 */ 924 925 LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d", 926 hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(), 927 hw->isLongshotEnabled()); 928 929 // Check for Retro-active Frames 930 if ((hw->mParameters.getNumOfRetroSnapshots() > 0) && 931 !hw->isLiveSnapshot() && hw->isZSLMode() && 932 !hw->isHDRMode() && !hw->isLongshotEnabled()) { 933 // Set Retro Picture Mode 934 hw->setRetroPicture(1); 935 hw->m_bLedAfAecLock = 0; 936 LOGL("Retro Enabled"); 937 938 // Give HWI control to call pre_take_picture in single camera mode. 939 // In dual-cam mode, this control belongs to muxer. 940 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 941 ret = pre_take_picture(device); 942 if (ret != NO_ERROR) { 943 LOGE("pre_take_picture failed with ret = %d",ret); 944 return ret; 945 } 946 } 947 948 /* Call take Picture for total number of snapshots required. 949 This includes the number of retro frames and normal frames */ 950 hw->lockAPI(); 951 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 952 if (ret == NO_ERROR) { 953 // Wait for retro frames, before calling prepare snapshot 954 LOGD("Wait for Retro frames to be done"); 955 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 956 ret = apiResult.status; 957 } 958 /* Unlock API since it is acquired in prepare snapshot seperately */ 959 hw->unlockAPI(); 960 961 /* Prepare snapshot in case LED needs to be flashed */ 962 LOGD("Start Prepare Snapshot"); 963 ret = hw->prepare_snapshot(device); 964 } 965 else { 966 hw->setRetroPicture(0); 967 // Check if prepare snapshot is done 968 if (!hw->mPrepSnapRun) { 969 // Ignore the status from prepare_snapshot 970 hw->prepare_snapshot(device); 971 } 972 973 // Give HWI control to call pre_take_picture in single camera mode. 974 // In dual-cam mode, this control belongs to muxer. 975 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 976 ret = pre_take_picture(device); 977 if (ret != NO_ERROR) { 978 LOGE("pre_take_picture failed with ret = %d",ret); 979 return ret; 980 } 981 } 982 983 // Regardless what the result value for prepare_snapshot, 984 // go ahead with capture anyway. Just like the way autofocus 985 // is handled in capture case 986 /* capture */ 987 LOGL("Capturing normal frames"); 988 hw->lockAPI(); 989 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 990 if (ret == NO_ERROR) { 991 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 992 ret = apiResult.status; 993 } 994 hw->unlockAPI(); 995 if (!hw->isLongshotEnabled()){ 996 // For longshot mode, we prepare snapshot only once 997 hw->mPrepSnapRun = false; 998 } 999 } 1000 LOGI("[KPI Perf]: X ret = %d", ret); 1001 return ret; 1002 } 1003 1004 /*=========================================================================== 1005 * FUNCTION : cancel_picture 1006 * 1007 * DESCRIPTION: cancel current take picture request 1008 * 1009 * PARAMETERS : 1010 * @device : ptr to camera device struct 1011 * 1012 * RETURN : int32_t type of status 1013 * NO_ERROR -- success 1014 * none-zero failure code 1015 *==========================================================================*/ 1016 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device) 1017 { 1018 ATRACE_CALL(); 1019 int ret = NO_ERROR; 1020 QCamera2HardwareInterface *hw = 1021 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1022 if (!hw) { 1023 LOGE("NULL camera device"); 1024 return BAD_VALUE; 1025 } 1026 LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d", 1027 hw->getCameraId()); 1028 hw->lockAPI(); 1029 qcamera_api_result_t apiResult; 1030 ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 1031 if (ret == NO_ERROR) { 1032 hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult); 1033 ret = apiResult.status; 1034 } 1035 hw->unlockAPI(); 1036 LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret); 1037 1038 return ret; 1039 } 1040 1041 /*=========================================================================== 1042 * FUNCTION : set_parameters 1043 * 1044 * DESCRIPTION: set camera parameters 1045 * 1046 * PARAMETERS : 1047 * @device : ptr to camera device struct 1048 * @parms : string of packed parameters 1049 * 1050 * RETURN : int32_t type of status 1051 * NO_ERROR -- success 1052 * none-zero failure code 1053 *==========================================================================*/ 1054 int QCamera2HardwareInterface::set_parameters(struct camera_device *device, 1055 const char *parms) 1056 { 1057 ATRACE_CALL(); 1058 int ret = NO_ERROR; 1059 QCamera2HardwareInterface *hw = 1060 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1061 if (!hw) { 1062 LOGE("NULL camera device"); 1063 return BAD_VALUE; 1064 } 1065 LOGD("E camera id %d", hw->getCameraId()); 1066 hw->lockAPI(); 1067 qcamera_api_result_t apiResult; 1068 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms); 1069 if (ret == NO_ERROR) { 1070 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult); 1071 ret = apiResult.status; 1072 } 1073 1074 // Give HWI control to restart (if necessary) after set params 1075 // in single camera mode. In dual-cam mode, this control belongs to muxer. 1076 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 1077 if ((ret == NO_ERROR) && hw->getNeedRestart()) { 1078 LOGD("stopping after param change"); 1079 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL); 1080 if (ret == NO_ERROR) { 1081 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult); 1082 ret = apiResult.status; 1083 } 1084 } 1085 1086 if (ret == NO_ERROR) { 1087 LOGD("committing param change"); 1088 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL); 1089 if (ret == NO_ERROR) { 1090 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult); 1091 ret = apiResult.status; 1092 } 1093 } 1094 1095 if ((ret == NO_ERROR) && hw->getNeedRestart()) { 1096 LOGD("restarting after param change"); 1097 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL); 1098 if (ret == NO_ERROR) { 1099 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult); 1100 ret = apiResult.status; 1101 } 1102 } 1103 } 1104 1105 hw->unlockAPI(); 1106 LOGD("X camera id %d ret %d", hw->getCameraId(), ret); 1107 1108 return ret; 1109 } 1110 1111 /*=========================================================================== 1112 * FUNCTION : stop_after_set_params 1113 * 1114 * DESCRIPTION: stop after a set param call, if necessary 1115 * 1116 * PARAMETERS : 1117 * @device : ptr to camera device struct 1118 * 1119 * RETURN : int32_t type of status 1120 * NO_ERROR -- success 1121 * none-zero failure code 1122 *==========================================================================*/ 1123 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device) 1124 { 1125 ATRACE_CALL(); 1126 int ret = NO_ERROR; 1127 QCamera2HardwareInterface *hw = 1128 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1129 if (!hw) { 1130 LOGE("NULL camera device"); 1131 return BAD_VALUE; 1132 } 1133 LOGD("E camera id %d", hw->getCameraId()); 1134 hw->lockAPI(); 1135 qcamera_api_result_t apiResult; 1136 1137 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1138 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL); 1139 if (ret == NO_ERROR) { 1140 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult); 1141 ret = apiResult.status; 1142 } 1143 } else { 1144 LOGE("is not supposed to be called in single-camera mode"); 1145 ret = INVALID_OPERATION; 1146 } 1147 1148 hw->unlockAPI(); 1149 LOGD("X camera id %d", hw->getCameraId()); 1150 1151 return ret; 1152 } 1153 1154 /*=========================================================================== 1155 * FUNCTION : commit_params 1156 * 1157 * DESCRIPTION: commit after a set param call 1158 * 1159 * PARAMETERS : 1160 * @device : ptr to camera device struct 1161 * 1162 * RETURN : int32_t type of status 1163 * NO_ERROR -- success 1164 * none-zero failure code 1165 *==========================================================================*/ 1166 int QCamera2HardwareInterface::commit_params(struct camera_device *device) 1167 { 1168 ATRACE_CALL(); 1169 int ret = NO_ERROR; 1170 QCamera2HardwareInterface *hw = 1171 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1172 if (!hw) { 1173 LOGE("NULL camera device"); 1174 return BAD_VALUE; 1175 } 1176 LOGD("E camera id %d", hw->getCameraId()); 1177 hw->lockAPI(); 1178 qcamera_api_result_t apiResult; 1179 1180 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1181 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL); 1182 if (ret == NO_ERROR) { 1183 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult); 1184 ret = apiResult.status; 1185 } 1186 } else { 1187 LOGE("is not supposed to be called in single-camera mode"); 1188 ret = INVALID_OPERATION; 1189 } 1190 1191 hw->unlockAPI(); 1192 LOGD("X camera id %d", hw->getCameraId()); 1193 1194 return ret; 1195 } 1196 1197 /*=========================================================================== 1198 * FUNCTION : restart_after_set_params 1199 * 1200 * DESCRIPTION: restart after a set param call, if necessary 1201 * 1202 * PARAMETERS : 1203 * @device : ptr to camera device struct 1204 * 1205 * RETURN : int32_t type of status 1206 * NO_ERROR -- success 1207 * none-zero failure code 1208 *==========================================================================*/ 1209 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device) 1210 { 1211 ATRACE_CALL(); 1212 int ret = NO_ERROR; 1213 QCamera2HardwareInterface *hw = 1214 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1215 if (!hw) { 1216 LOGE("NULL camera device"); 1217 return BAD_VALUE; 1218 } 1219 LOGD("E camera id %d", hw->getCameraId()); 1220 hw->lockAPI(); 1221 qcamera_api_result_t apiResult; 1222 1223 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 1224 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL); 1225 if (ret == NO_ERROR) { 1226 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult); 1227 ret = apiResult.status; 1228 } 1229 } else { 1230 LOGE("is not supposed to be called in single-camera mode"); 1231 ret = INVALID_OPERATION; 1232 } 1233 1234 hw->unlockAPI(); 1235 LOGD("X camera id %d", hw->getCameraId()); 1236 return ret; 1237 } 1238 1239 /*=========================================================================== 1240 * FUNCTION : get_parameters 1241 * 1242 * DESCRIPTION: query camera parameters 1243 * 1244 * PARAMETERS : 1245 * @device : ptr to camera device struct 1246 * 1247 * RETURN : packed parameters in a string 1248 *==========================================================================*/ 1249 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device) 1250 { 1251 ATRACE_CALL(); 1252 char *ret = NULL; 1253 QCamera2HardwareInterface *hw = 1254 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1255 if (!hw) { 1256 LOGE("NULL camera device"); 1257 return NULL; 1258 } 1259 LOGD("E camera id %d", hw->getCameraId()); 1260 hw->lockAPI(); 1261 qcamera_api_result_t apiResult; 1262 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL); 1263 if (rc == NO_ERROR) { 1264 hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult); 1265 ret = apiResult.params; 1266 } 1267 hw->unlockAPI(); 1268 LOGD("E camera id %d", hw->getCameraId()); 1269 1270 return ret; 1271 } 1272 1273 /*=========================================================================== 1274 * FUNCTION : put_parameters 1275 * 1276 * DESCRIPTION: return camera parameters string back to HAL 1277 * 1278 * PARAMETERS : 1279 * @device : ptr to camera device struct 1280 * @parm : ptr to parameter string to be returned 1281 * 1282 * RETURN : none 1283 *==========================================================================*/ 1284 void QCamera2HardwareInterface::put_parameters(struct camera_device *device, 1285 char *parm) 1286 { 1287 ATRACE_CALL(); 1288 QCamera2HardwareInterface *hw = 1289 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1290 if (!hw) { 1291 LOGE("NULL camera device"); 1292 return; 1293 } 1294 LOGD("E camera id %d", hw->getCameraId()); 1295 hw->lockAPI(); 1296 qcamera_api_result_t apiResult; 1297 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm); 1298 if (ret == NO_ERROR) { 1299 hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult); 1300 } 1301 hw->unlockAPI(); 1302 LOGD("E camera id %d", hw->getCameraId()); 1303 } 1304 1305 /*=========================================================================== 1306 * FUNCTION : send_command 1307 * 1308 * DESCRIPTION: command to be executed 1309 * 1310 * PARAMETERS : 1311 * @device : ptr to camera device struct 1312 * @cmd : cmd to be executed 1313 * @arg1 : ptr to optional argument1 1314 * @arg2 : ptr to optional argument2 1315 * 1316 * RETURN : int32_t type of status 1317 * NO_ERROR -- success 1318 * none-zero failure code 1319 *==========================================================================*/ 1320 int QCamera2HardwareInterface::send_command(struct camera_device *device, 1321 int32_t cmd, 1322 int32_t arg1, 1323 int32_t arg2) 1324 { 1325 ATRACE_CALL(); 1326 int ret = NO_ERROR; 1327 QCamera2HardwareInterface *hw = 1328 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1329 if (!hw) { 1330 LOGE("NULL camera device"); 1331 return BAD_VALUE; 1332 } 1333 LOGD("E camera id %d", hw->getCameraId()); 1334 1335 qcamera_sm_evt_command_payload_t payload; 1336 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t)); 1337 payload.cmd = cmd; 1338 payload.arg1 = arg1; 1339 payload.arg2 = arg2; 1340 hw->lockAPI(); 1341 qcamera_api_result_t apiResult; 1342 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload); 1343 if (ret == NO_ERROR) { 1344 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult); 1345 ret = apiResult.status; 1346 } 1347 hw->unlockAPI(); 1348 LOGD("E camera id %d", hw->getCameraId()); 1349 1350 return ret; 1351 } 1352 1353 /*=========================================================================== 1354 * FUNCTION : send_command_restart 1355 * 1356 * DESCRIPTION: restart if necessary after a send_command 1357 * 1358 * PARAMETERS : 1359 * @device : ptr to camera device struct 1360 * @cmd : cmd to be executed 1361 * @arg1 : ptr to optional argument1 1362 * @arg2 : ptr to optional argument2 1363 * 1364 * RETURN : int32_t type of status 1365 * NO_ERROR -- success 1366 * none-zero failure code 1367 *==========================================================================*/ 1368 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device, 1369 int32_t cmd, 1370 int32_t arg1, 1371 int32_t arg2) 1372 { 1373 ATRACE_CALL(); 1374 int ret = NO_ERROR; 1375 QCamera2HardwareInterface *hw = 1376 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1377 if (!hw) { 1378 LOGE("NULL camera device"); 1379 return BAD_VALUE; 1380 } 1381 1382 qcamera_sm_evt_command_payload_t payload; 1383 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t)); 1384 payload.cmd = cmd; 1385 payload.arg1 = arg1; 1386 payload.arg2 = arg2; 1387 hw->lockAPI(); 1388 qcamera_api_result_t apiResult; 1389 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload); 1390 if (ret == NO_ERROR) { 1391 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult); 1392 ret = apiResult.status; 1393 } 1394 hw->unlockAPI(); 1395 LOGD("E camera id %d", hw->getCameraId()); 1396 1397 return ret; 1398 } 1399 1400 /*=========================================================================== 1401 * FUNCTION : release 1402 * 1403 * DESCRIPTION: release camera resource 1404 * 1405 * PARAMETERS : 1406 * @device : ptr to camera device struct 1407 * 1408 * RETURN : none 1409 *==========================================================================*/ 1410 void QCamera2HardwareInterface::release(struct camera_device *device) 1411 { 1412 ATRACE_CALL(); 1413 QCamera2HardwareInterface *hw = 1414 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1415 if (!hw) { 1416 LOGE("NULL camera device"); 1417 return; 1418 } 1419 LOGD("E camera id %d", hw->getCameraId()); 1420 hw->lockAPI(); 1421 qcamera_api_result_t apiResult; 1422 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL); 1423 if (ret == NO_ERROR) { 1424 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult); 1425 } 1426 hw->unlockAPI(); 1427 LOGD("E camera id %d", hw->getCameraId()); 1428 } 1429 1430 /*=========================================================================== 1431 * FUNCTION : dump 1432 * 1433 * DESCRIPTION: dump camera status 1434 * 1435 * PARAMETERS : 1436 * @device : ptr to camera device struct 1437 * @fd : fd for status to be dumped to 1438 * 1439 * RETURN : int32_t type of status 1440 * NO_ERROR -- success 1441 * none-zero failure code 1442 *==========================================================================*/ 1443 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd) 1444 { 1445 int ret = NO_ERROR; 1446 1447 //Log level property is read when "adb shell dumpsys media.camera" is 1448 //called so that the log level can be controlled without restarting 1449 //media server 1450 getLogLevel(); 1451 QCamera2HardwareInterface *hw = 1452 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1453 if (!hw) { 1454 LOGE("NULL camera device"); 1455 return BAD_VALUE; 1456 } 1457 LOGD("E camera id %d", hw->getCameraId()); 1458 hw->lockAPI(); 1459 qcamera_api_result_t apiResult; 1460 ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd); 1461 if (ret == NO_ERROR) { 1462 hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult); 1463 ret = apiResult.status; 1464 } 1465 hw->unlockAPI(); 1466 LOGD("E camera id %d", hw->getCameraId()); 1467 1468 return ret; 1469 } 1470 1471 /*=========================================================================== 1472 * FUNCTION : close_camera_device 1473 * 1474 * DESCRIPTION: close camera device 1475 * 1476 * PARAMETERS : 1477 * @device : ptr to camera device struct 1478 * 1479 * RETURN : int32_t type of status 1480 * NO_ERROR -- success 1481 * none-zero failure code 1482 *==========================================================================*/ 1483 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev) 1484 { 1485 KPI_ATRACE_CALL(); 1486 int ret = NO_ERROR; 1487 1488 QCamera2HardwareInterface *hw = 1489 reinterpret_cast<QCamera2HardwareInterface *>( 1490 reinterpret_cast<camera_device_t *>(hw_dev)->priv); 1491 if (!hw) { 1492 LOGE("NULL camera device"); 1493 return BAD_VALUE; 1494 } 1495 LOGI("[KPI Perf]: E camera id %d", hw->getCameraId()); 1496 delete hw; 1497 LOGI("[KPI Perf]: X"); 1498 return ret; 1499 } 1500 1501 /*=========================================================================== 1502 * FUNCTION : register_face_image 1503 * 1504 * DESCRIPTION: register a face image into imaging lib for face authenticatio/ 1505 * face recognition 1506 * 1507 * PARAMETERS : 1508 * @device : ptr to camera device struct 1509 * @img_ptr : ptr to image buffer 1510 * @config : ptr to config about input image, i.e., format, dimension, and etc. 1511 * 1512 * RETURN : >=0 unique ID of face registerd. 1513 * <0 failure. 1514 *==========================================================================*/ 1515 int QCamera2HardwareInterface::register_face_image(struct camera_device *device, 1516 void *img_ptr, 1517 cam_pp_offline_src_config_t *config) 1518 { 1519 ATRACE_CALL(); 1520 int ret = NO_ERROR; 1521 QCamera2HardwareInterface *hw = 1522 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1523 if (!hw) { 1524 LOGE("NULL camera device"); 1525 return BAD_VALUE; 1526 } 1527 LOGD("E camera id %d", hw->getCameraId()); 1528 qcamera_sm_evt_reg_face_payload_t payload; 1529 memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t)); 1530 payload.img_ptr = img_ptr; 1531 payload.config = config; 1532 hw->lockAPI(); 1533 qcamera_api_result_t apiResult; 1534 ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload); 1535 if (ret == NO_ERROR) { 1536 hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult); 1537 ret = apiResult.handle; 1538 } 1539 hw->unlockAPI(); 1540 LOGD("E camera id %d", hw->getCameraId()); 1541 1542 return ret; 1543 } 1544 1545 /*=========================================================================== 1546 * FUNCTION : prepare_snapshot 1547 * 1548 * DESCRIPTION: prepares hardware for snapshot 1549 * 1550 * PARAMETERS : 1551 * @device : ptr to camera device struct 1552 * 1553 * RETURN : int32_t type of status 1554 * NO_ERROR -- success 1555 * none-zero failure code 1556 *==========================================================================*/ 1557 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device) 1558 { 1559 ATRACE_CALL(); 1560 int ret = NO_ERROR; 1561 QCamera2HardwareInterface *hw = 1562 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1563 if (!hw) { 1564 LOGE("NULL camera device"); 1565 return BAD_VALUE; 1566 } 1567 if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) { 1568 // For longshot mode, we prepare snapshot only once 1569 LOGH("prepare snapshot only once "); 1570 return NO_ERROR; 1571 } 1572 LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d", 1573 hw->getCameraId()); 1574 hw->lockAPI(); 1575 qcamera_api_result_t apiResult; 1576 1577 /* Prepare snapshot in case LED needs to be flashed */ 1578 if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) { 1579 /* Prepare snapshot in case LED needs to be flashed */ 1580 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 1581 if (ret == NO_ERROR) { 1582 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 1583 ret = apiResult.status; 1584 } 1585 hw->mPrepSnapRun = true; 1586 } 1587 hw->unlockAPI(); 1588 LOGH("[KPI Perf]: X, ret: %d", ret); 1589 return ret; 1590 } 1591 1592 /*=========================================================================== 1593 * FUNCTION : QCamera2HardwareInterface 1594 * 1595 * DESCRIPTION: constructor of QCamera2HardwareInterface 1596 * 1597 * PARAMETERS : 1598 * @cameraId : camera ID 1599 * 1600 * RETURN : none 1601 *==========================================================================*/ 1602 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId) 1603 : mCameraId(cameraId), 1604 mCameraHandle(NULL), 1605 mCameraOpened(false), 1606 m_bRelCamCalibValid(false), 1607 mPreviewWindow(NULL), 1608 mMsgEnabled(0), 1609 mStoreMetaDataInFrame(0), 1610 mJpegCb(NULL), 1611 mCallbackCookie(NULL), 1612 mJpegCallbackCookie(NULL), 1613 m_bMpoEnabled(TRUE), 1614 m_stateMachine(this), 1615 m_smThreadActive(true), 1616 m_postprocessor(this), 1617 m_thermalAdapter(QCameraThermalAdapter::getInstance()), 1618 m_cbNotifier(this), 1619 m_bPreviewStarted(false), 1620 m_bRecordStarted(false), 1621 m_currentFocusState(CAM_AF_STATE_INACTIVE), 1622 mDumpFrmCnt(0U), 1623 mDumpSkipCnt(0U), 1624 mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT), 1625 mActiveAF(false), 1626 m_HDRSceneEnabled(false), 1627 mLongshotEnabled(false), 1628 mLiveSnapshotThread(0), 1629 mIntPicThread(0), 1630 mFlashNeeded(false), 1631 mDeviceRotation(0U), 1632 mCaptureRotation(0U), 1633 mJpegExifRotation(0U), 1634 mUseJpegExifRotation(false), 1635 mIs3ALocked(false), 1636 mPrepSnapRun(false), 1637 mZoomLevel(0), 1638 mPreviewRestartNeeded(false), 1639 mVFrameCount(0), 1640 mVLastFrameCount(0), 1641 mVLastFpsTime(0), 1642 mVFps(0), 1643 mPFrameCount(0), 1644 mPLastFrameCount(0), 1645 mPLastFpsTime(0), 1646 mPFps(0), 1647 mInstantAecFrameCount(0), 1648 m_bIntJpegEvtPending(false), 1649 m_bIntRawEvtPending(false), 1650 mReprocJob(0), 1651 mJpegJob(0), 1652 mMetadataAllocJob(0), 1653 mInitPProcJob(0), 1654 mParamAllocJob(0), 1655 mParamInitJob(0), 1656 mOutputCount(0), 1657 mInputCount(0), 1658 mAdvancedCaptureConfigured(false), 1659 mHDRBracketingEnabled(false), 1660 mNumPreviewFaces(-1), 1661 mJpegClientHandle(0), 1662 mJpegHandleOwner(false), 1663 mMetadataMem(NULL), 1664 mCACDoneReceived(false), 1665 m_bNeedRestart(false) 1666 { 1667 #ifdef TARGET_TS_MAKEUP 1668 memset(&mFaceRect, -1, sizeof(mFaceRect)); 1669 #endif 1670 getLogLevel(); 1671 ATRACE_CALL(); 1672 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG; 1673 mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0); 1674 mCameraDevice.common.close = close_camera_device; 1675 mCameraDevice.ops = &mCameraOps; 1676 mCameraDevice.priv = this; 1677 1678 pthread_mutex_init(&m_lock, NULL); 1679 pthread_cond_init(&m_cond, NULL); 1680 1681 m_apiResultList = NULL; 1682 1683 pthread_mutex_init(&m_evtLock, NULL); 1684 pthread_cond_init(&m_evtCond, NULL); 1685 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 1686 1687 1688 pthread_mutex_init(&m_int_lock, NULL); 1689 pthread_cond_init(&m_int_cond, NULL); 1690 1691 memset(m_channels, 0, sizeof(m_channels)); 1692 1693 memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t)); 1694 1695 memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH); 1696 1697 memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs)); 1698 memset(&mJpegMetadata, 0, sizeof(mJpegMetadata)); 1699 memset(&mJpegHandle, 0, sizeof(mJpegHandle)); 1700 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle)); 1701 1702 mDeferredWorkThread.launch(deferredWorkRoutine, this); 1703 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE); 1704 m_perfLock.lock_init(); 1705 1706 pthread_mutex_init(&mGrallocLock, NULL); 1707 mEnqueuedBuffers = 0; 1708 mFrameSkipStart = 0; 1709 mFrameSkipEnd = 0; 1710 mLastPreviewFrameID = 0; 1711 1712 //Load and read GPU library. 1713 lib_surface_utils = NULL; 1714 LINK_get_surface_pixel_alignment = NULL; 1715 mSurfaceStridePadding = CAM_PAD_TO_32; 1716 lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW); 1717 if (lib_surface_utils) { 1718 *(void **)&LINK_get_surface_pixel_alignment = 1719 dlsym(lib_surface_utils, "get_gpu_pixel_alignment"); 1720 if (LINK_get_surface_pixel_alignment) { 1721 mSurfaceStridePadding = LINK_get_surface_pixel_alignment(); 1722 } 1723 dlclose(lib_surface_utils); 1724 } 1725 } 1726 1727 /*=========================================================================== 1728 * FUNCTION : ~QCamera2HardwareInterface 1729 * 1730 * DESCRIPTION: destructor of QCamera2HardwareInterface 1731 * 1732 * PARAMETERS : none 1733 * 1734 * RETURN : none 1735 *==========================================================================*/ 1736 QCamera2HardwareInterface::~QCamera2HardwareInterface() 1737 { 1738 LOGH("E"); 1739 1740 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE); 1741 mDeferredWorkThread.exit(); 1742 1743 if (mMetadataMem != NULL) { 1744 delete mMetadataMem; 1745 mMetadataMem = NULL; 1746 } 1747 1748 m_perfLock.lock_acq(); 1749 lockAPI(); 1750 m_smThreadActive = false; 1751 unlockAPI(); 1752 m_stateMachine.releaseThread(); 1753 closeCamera(); 1754 m_perfLock.lock_rel(); 1755 m_perfLock.lock_deinit(); 1756 pthread_mutex_destroy(&m_lock); 1757 pthread_cond_destroy(&m_cond); 1758 pthread_mutex_destroy(&m_evtLock); 1759 pthread_cond_destroy(&m_evtCond); 1760 pthread_mutex_destroy(&m_int_lock); 1761 pthread_cond_destroy(&m_int_cond); 1762 pthread_mutex_destroy(&mGrallocLock); 1763 LOGH("X"); 1764 } 1765 1766 /*=========================================================================== 1767 * FUNCTION : deferPPInit 1768 * 1769 * DESCRIPTION: Queue postproc init task to deferred thread 1770 * 1771 * PARAMETERS : none 1772 * 1773 * RETURN : uint32_t job id of pproc init job 1774 * 0 -- failure 1775 *==========================================================================*/ 1776 uint32_t QCamera2HardwareInterface::deferPPInit() 1777 { 1778 // init pproc 1779 DeferWorkArgs args; 1780 DeferPProcInitArgs pprocInitArgs; 1781 1782 memset(&args, 0, sizeof(DeferWorkArgs)); 1783 memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs)); 1784 1785 pprocInitArgs.jpeg_cb = jpegEvtHandle; 1786 pprocInitArgs.user_data = this; 1787 args.pprocInitArgs = pprocInitArgs; 1788 1789 return queueDeferredWork(CMD_DEF_PPROC_INIT, 1790 args); 1791 } 1792 1793 /*=========================================================================== 1794 * FUNCTION : openCamera 1795 * 1796 * DESCRIPTION: open camera 1797 * 1798 * PARAMETERS : 1799 * @hw_device : double ptr for camera device struct 1800 * 1801 * RETURN : int32_t type of status 1802 * NO_ERROR -- success 1803 * none-zero failure code 1804 *==========================================================================*/ 1805 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device) 1806 { 1807 KPI_ATRACE_CALL(); 1808 int rc = NO_ERROR; 1809 if (mCameraOpened) { 1810 *hw_device = NULL; 1811 LOGE("Permission Denied"); 1812 return PERMISSION_DENIED; 1813 } 1814 LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d", 1815 mCameraId); 1816 m_perfLock.lock_acq_timed(CAMERA_OPEN_PERF_TIME_OUT); 1817 rc = openCamera(); 1818 if (rc == NO_ERROR){ 1819 *hw_device = &mCameraDevice.common; 1820 if (m_thermalAdapter.init(this) != 0) { 1821 LOGW("Init thermal adapter failed"); 1822 } 1823 } 1824 else 1825 *hw_device = NULL; 1826 1827 LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d", 1828 mCameraId, rc); 1829 1830 return rc; 1831 } 1832 1833 /*=========================================================================== 1834 * FUNCTION : openCamera 1835 * 1836 * DESCRIPTION: open camera 1837 * 1838 * PARAMETERS : none 1839 * 1840 * RETURN : int32_t type of status 1841 * NO_ERROR -- success 1842 * none-zero failure code 1843 *==========================================================================*/ 1844 int QCamera2HardwareInterface::openCamera() 1845 { 1846 int32_t rc = NO_ERROR; 1847 char value[PROPERTY_VALUE_MAX]; 1848 1849 if (mCameraHandle) { 1850 LOGE("Failure: Camera already opened"); 1851 return ALREADY_EXISTS; 1852 } 1853 1854 rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId); 1855 if (rc < 0) { 1856 LOGE("Failed to reserve flash for camera id: %d", 1857 mCameraId); 1858 return UNKNOWN_ERROR; 1859 } 1860 1861 // alloc param buffer 1862 DeferWorkArgs args; 1863 memset(&args, 0, sizeof(args)); 1864 mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args); 1865 if (mParamAllocJob == 0) { 1866 LOGE("Failed queueing PARAM_ALLOC job"); 1867 return -ENOMEM; 1868 } 1869 1870 if (gCamCapability[mCameraId] != NULL) { 1871 // allocate metadata buffers 1872 DeferWorkArgs args; 1873 DeferMetadataAllocArgs metadataAllocArgs; 1874 1875 memset(&args, 0, sizeof(args)); 1876 memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs)); 1877 1878 uint32_t padding = 1879 gCamCapability[mCameraId]->padding_info.plane_padding; 1880 metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t), 1881 padding); 1882 metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS; 1883 args.metadataAllocArgs = metadataAllocArgs; 1884 1885 mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args); 1886 if (mMetadataAllocJob == 0) { 1887 LOGE("Failed to allocate metadata buffer"); 1888 rc = -ENOMEM; 1889 goto error_exit1; 1890 } 1891 1892 rc = camera_open((uint8_t)mCameraId, &mCameraHandle); 1893 if (rc) { 1894 LOGE("camera_open failed. rc = %d, mCameraHandle = %p", 1895 rc, mCameraHandle); 1896 goto error_exit2; 1897 } 1898 1899 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, 1900 camEvtHandle, 1901 (void *) this); 1902 } else { 1903 LOGH("Capabilities not inited, initializing now."); 1904 1905 rc = camera_open((uint8_t)mCameraId, &mCameraHandle); 1906 if (rc) { 1907 LOGE("camera_open failed. rc = %d, mCameraHandle = %p", 1908 rc, mCameraHandle); 1909 goto error_exit2; 1910 } 1911 1912 if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) { 1913 LOGE("initCapabilities failed."); 1914 rc = UNKNOWN_ERROR; 1915 goto error_exit3; 1916 } 1917 1918 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, 1919 camEvtHandle, 1920 (void *) this); 1921 } 1922 1923 // Init params in the background 1924 // 1. It's safe to queue init job, even if alloc job is not yet complete. 1925 // It will be queued to the same thread, so the alloc is guaranteed to 1926 // finish first. 1927 // 2. However, it is not safe to begin param init until after camera is 1928 // open. That is why we wait until after camera open completes to schedule 1929 // this task. 1930 memset(&args, 0, sizeof(args)); 1931 mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args); 1932 if (mParamInitJob == 0) { 1933 LOGE("Failed queuing PARAM_INIT job"); 1934 rc = -ENOMEM; 1935 goto error_exit3; 1936 } 1937 1938 mCameraOpened = true; 1939 1940 //Notify display HAL that a camera session is active. 1941 //But avoid calling the same during bootup because camera service might open/close 1942 //cameras at boot time during its initialization and display service will also internally 1943 //wait for camera service to initialize first while calling this display API, resulting in a 1944 //deadlock situation. Since boot time camera open/close calls are made only to fetch 1945 //capabilities, no need of this display bw optimization. 1946 //Use "service.bootanim.exit" property to know boot status. 1947 property_get("service.bootanim.exit", value, "0"); 1948 if (atoi(value) == 1) { 1949 pthread_mutex_lock(&gCamLock); 1950 if (gNumCameraSessions++ == 0) { 1951 setCameraLaunchStatus(true); 1952 } 1953 pthread_mutex_unlock(&gCamLock); 1954 } 1955 1956 return NO_ERROR; 1957 1958 error_exit3: 1959 if(mJpegClientHandle) { 1960 deinitJpegHandle(); 1961 } 1962 mCameraHandle->ops->close_camera(mCameraHandle->camera_handle); 1963 mCameraHandle = NULL; 1964 error_exit2: 1965 waitDeferredWork(mMetadataAllocJob); 1966 error_exit1: 1967 waitDeferredWork(mParamAllocJob); 1968 return rc; 1969 1970 } 1971 1972 /*=========================================================================== 1973 * FUNCTION : bundleRelatedCameras 1974 * 1975 * DESCRIPTION: bundle cameras to enable syncing of cameras 1976 * 1977 * PARAMETERS : 1978 * @sync :indicates whether syncing is On or Off 1979 * @sessionid :session id for other camera session 1980 * 1981 * RETURN : int32_t type of status 1982 * NO_ERROR -- success 1983 * none-zero failure code 1984 *==========================================================================*/ 1985 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn, 1986 uint32_t sessionid) 1987 { 1988 LOGD("bundleRelatedCameras sync %d with sessionid %d", 1989 syncOn, sessionid); 1990 1991 int32_t rc = mParameters.bundleRelatedCameras(syncOn, sessionid); 1992 if (rc != NO_ERROR) { 1993 LOGE("bundleRelatedCameras failed %d", rc); 1994 return rc; 1995 } 1996 return rc; 1997 } 1998 1999 /*=========================================================================== 2000 * FUNCTION : getCameraSessionId 2001 * 2002 * DESCRIPTION: gets the backend session Id of this HWI instance 2003 * 2004 * PARAMETERS : 2005 * @sessionid : pointer to the output session id 2006 * 2007 * RETURN : int32_t type of status 2008 * NO_ERROR -- success 2009 * none-zero failure code 2010 *==========================================================================*/ 2011 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id) 2012 { 2013 int32_t rc = NO_ERROR; 2014 2015 if(session_id != NULL) { 2016 rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle, 2017 session_id); 2018 LOGD("Getting Camera Session Id %d", *session_id); 2019 } else { 2020 LOGE("Session Id is Null"); 2021 return UNKNOWN_ERROR; 2022 } 2023 return rc; 2024 } 2025 2026 /*=========================================================================== 2027 * FUNCTION : getRelatedCamSyncInfo 2028 * 2029 * DESCRIPTION:returns the related cam sync info for this HWI instance 2030 * 2031 * PARAMETERS :none 2032 * 2033 * RETURN : const pointer to cam_sync_related_sensors_event_info_t 2034 *==========================================================================*/ 2035 const cam_sync_related_sensors_event_info_t* 2036 QCamera2HardwareInterface::getRelatedCamSyncInfo(void) 2037 { 2038 return mParameters.getRelatedCamSyncInfo(); 2039 } 2040 2041 /*=========================================================================== 2042 * FUNCTION : setRelatedCamSyncInfo 2043 * 2044 * DESCRIPTION:sets the related cam sync info for this HWI instance 2045 * 2046 * PARAMETERS : 2047 * @info : ptr to related cam info parameters 2048 * 2049 * RETURN : int32_t type of status 2050 * NO_ERROR -- success 2051 * none-zero failure code 2052 *==========================================================================*/ 2053 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo( 2054 cam_sync_related_sensors_event_info_t* info) 2055 { 2056 if(info) { 2057 return mParameters.setRelatedCamSyncInfo(info); 2058 } else { 2059 return BAD_TYPE; 2060 } 2061 } 2062 2063 /*=========================================================================== 2064 * FUNCTION : getMpoComposition 2065 * 2066 * DESCRIPTION:function to retrieve whether Mpo composition should be enabled 2067 * or not 2068 * 2069 * PARAMETERS :none 2070 * 2071 * RETURN : bool indicates whether mpo composition is enabled or not 2072 *==========================================================================*/ 2073 bool QCamera2HardwareInterface::getMpoComposition(void) 2074 { 2075 LOGH("MpoComposition:%d ", m_bMpoEnabled); 2076 return m_bMpoEnabled; 2077 } 2078 2079 /*=========================================================================== 2080 * FUNCTION : setMpoComposition 2081 * 2082 * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance 2083 * 2084 * PARAMETERS : 2085 * @enable : indicates whether Mpo composition enabled or not 2086 * 2087 * RETURN : int32_t type of status 2088 * NO_ERROR -- success 2089 * none-zero failure code 2090 *==========================================================================*/ 2091 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable) 2092 { 2093 // By default set Mpo composition to disable 2094 m_bMpoEnabled = false; 2095 2096 // Enable Mpo composition only if 2097 // 1) frame sync is ON between two cameras and 2098 // 2) any advanced features are not enabled (AOST features) and 2099 // 3) not in recording mode (for liveshot case) 2100 // 4) flash is not needed 2101 if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) && 2102 !mParameters.isAdvCamFeaturesEnabled() && 2103 !mParameters.getRecordingHintValue() && 2104 !mFlashNeeded && 2105 !isLongshotEnabled()) { 2106 m_bMpoEnabled = enable; 2107 LOGH("MpoComposition:%d ", m_bMpoEnabled); 2108 return NO_ERROR; 2109 } else { 2110 return BAD_TYPE; 2111 } 2112 } 2113 2114 /*=========================================================================== 2115 * FUNCTION : getRecordingHintValue 2116 * 2117 * DESCRIPTION:function to retrieve recording hint value 2118 * 2119 * PARAMETERS :none 2120 * 2121 * RETURN : bool indicates whether recording hint is enabled or not 2122 *==========================================================================*/ 2123 bool QCamera2HardwareInterface::getRecordingHintValue(void) 2124 { 2125 return mParameters.getRecordingHintValue(); 2126 } 2127 2128 /*=========================================================================== 2129 * FUNCTION : setRecordingHintValue 2130 * 2131 * DESCRIPTION:set recording hint value 2132 * 2133 * PARAMETERS : 2134 * @enable : video hint value 2135 * 2136 * RETURN : int32_t type of status 2137 * NO_ERROR -- success 2138 * none-zero failure code 2139 *==========================================================================*/ 2140 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value) 2141 { 2142 return mParameters.updateRecordingHintValue(value); 2143 } 2144 2145 /*=========================================================================== 2146 * FUNCTION : closeCamera 2147 * 2148 * DESCRIPTION: close camera 2149 * 2150 * PARAMETERS : none 2151 * 2152 * RETURN : int32_t type of status 2153 * NO_ERROR -- success 2154 * none-zero failure code 2155 *==========================================================================*/ 2156 int QCamera2HardwareInterface::closeCamera() 2157 { 2158 int rc = NO_ERROR; 2159 int i; 2160 char value[PROPERTY_VALUE_MAX]; 2161 LOGI("E"); 2162 if (!mCameraOpened) { 2163 return NO_ERROR; 2164 } 2165 LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d", 2166 mCameraId); 2167 2168 // set open flag to false 2169 mCameraOpened = false; 2170 2171 // Reset Stream config info 2172 mParameters.setStreamConfigure(false, false, true); 2173 2174 // deinit Parameters 2175 mParameters.deinit(); 2176 2177 // exit notifier 2178 m_cbNotifier.exit(); 2179 2180 // stop and deinit postprocessor 2181 waitDeferredWork(mReprocJob); 2182 // Close the JPEG session 2183 waitDeferredWork(mJpegJob); 2184 m_postprocessor.stop(); 2185 deinitJpegHandle(); 2186 m_postprocessor.deinit(); 2187 mInitPProcJob = 0; // reset job id, so pproc can be reinited later 2188 2189 m_thermalAdapter.deinit(); 2190 2191 // delete all channels if not already deleted 2192 for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 2193 if (m_channels[i] != NULL) { 2194 m_channels[i]->stop(); 2195 delete m_channels[i]; 2196 m_channels[i] = NULL; 2197 } 2198 } 2199 2200 //free all pending api results here 2201 if(m_apiResultList != NULL) { 2202 api_result_list *apiResultList = m_apiResultList; 2203 api_result_list *apiResultListNext; 2204 while (apiResultList != NULL) { 2205 apiResultListNext = apiResultList->next; 2206 free(apiResultList); 2207 apiResultList = apiResultListNext; 2208 } 2209 } 2210 2211 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle); 2212 mCameraHandle = NULL; 2213 2214 //Notify display HAL that there is no active camera session 2215 //but avoid calling the same during bootup. Refer to openCamera 2216 //for more details. 2217 property_get("service.bootanim.exit", value, "0"); 2218 if (atoi(value) == 1) { 2219 pthread_mutex_lock(&gCamLock); 2220 if (--gNumCameraSessions == 0) { 2221 setCameraLaunchStatus(false); 2222 } 2223 pthread_mutex_unlock(&gCamLock); 2224 } 2225 2226 if (mExifParams.debug_params) { 2227 free(mExifParams.debug_params); 2228 mExifParams.debug_params = NULL; 2229 } 2230 2231 if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) { 2232 LOGD("Failed to release flash for camera id: %d", 2233 mCameraId); 2234 } 2235 2236 LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d", 2237 mCameraId, rc); 2238 2239 return rc; 2240 } 2241 2242 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX ) 2243 2244 /*=========================================================================== 2245 * FUNCTION : initCapabilities 2246 * 2247 * DESCRIPTION: initialize camera capabilities in static data struct 2248 * 2249 * PARAMETERS : 2250 * @cameraId : camera Id 2251 * 2252 * RETURN : int32_t type of status 2253 * NO_ERROR -- success 2254 * none-zero failure code 2255 *==========================================================================*/ 2256 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId, 2257 mm_camera_vtbl_t *cameraHandle) 2258 { 2259 ATRACE_CALL(); 2260 int rc = NO_ERROR; 2261 QCameraHeapMemory *capabilityHeap = NULL; 2262 2263 /* Allocate memory for capability buffer */ 2264 capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 2265 rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE); 2266 if(rc != OK) { 2267 LOGE("No memory for cappability"); 2268 goto allocate_failed; 2269 } 2270 2271 /* Map memory for capability buffer */ 2272 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t)); 2273 2274 cam_buf_map_type_list bufMapList; 2275 rc = QCameraBufferMaps::makeSingletonBufMapList( 2276 CAM_MAPPING_BUF_TYPE_CAPABILITY, 2277 0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/, 2278 0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t), 2279 bufMapList); 2280 2281 if (rc == NO_ERROR) { 2282 rc = cameraHandle->ops->map_bufs(cameraHandle->camera_handle, 2283 &bufMapList); 2284 } 2285 2286 if(rc < 0) { 2287 LOGE("failed to map capability buffer"); 2288 goto map_failed; 2289 } 2290 2291 /* Query Capability */ 2292 rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle); 2293 if(rc < 0) { 2294 LOGE("failed to query capability"); 2295 goto query_failed; 2296 } 2297 gCamCapability[cameraId] = 2298 (cam_capability_t *)malloc(sizeof(cam_capability_t)); 2299 2300 if (!gCamCapability[cameraId]) { 2301 LOGE("out of memory"); 2302 goto query_failed; 2303 } 2304 memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0), 2305 sizeof(cam_capability_t)); 2306 gCamCapability[cameraId]->analysis_padding_info.offset_info.offset_x = 0; 2307 gCamCapability[cameraId]->analysis_padding_info.offset_info.offset_y = 0; 2308 2309 rc = NO_ERROR; 2310 2311 query_failed: 2312 cameraHandle->ops->unmap_buf(cameraHandle->camera_handle, 2313 CAM_MAPPING_BUF_TYPE_CAPABILITY); 2314 map_failed: 2315 capabilityHeap->deallocate(); 2316 delete capabilityHeap; 2317 allocate_failed: 2318 return rc; 2319 } 2320 2321 /*=========================================================================== 2322 * FUNCTION : getCapabilities 2323 * 2324 * DESCRIPTION: query camera capabilities 2325 * 2326 * PARAMETERS : 2327 * @cameraId : camera Id 2328 * @info : camera info struct to be filled in with camera capabilities 2329 * 2330 * RETURN : int type of status 2331 * NO_ERROR -- success 2332 * none-zero failure code 2333 *==========================================================================*/ 2334 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId, 2335 struct camera_info *info, cam_sync_type_t *p_cam_type) 2336 { 2337 ATRACE_CALL(); 2338 int rc = NO_ERROR; 2339 struct camera_info *p_info = NULL; 2340 pthread_mutex_lock(&gCamLock); 2341 p_info = get_cam_info(cameraId, p_cam_type); 2342 p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0; 2343 p_info->static_camera_characteristics = NULL; 2344 memcpy(info, p_info, sizeof (struct camera_info)); 2345 pthread_mutex_unlock(&gCamLock); 2346 return rc; 2347 } 2348 2349 /*=========================================================================== 2350 * FUNCTION : getCamHalCapabilities 2351 * 2352 * DESCRIPTION: get the HAL capabilities structure 2353 * 2354 * PARAMETERS : 2355 * @cameraId : camera Id 2356 * 2357 * RETURN : capability structure of respective camera 2358 * 2359 *==========================================================================*/ 2360 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities() 2361 { 2362 return gCamCapability[mCameraId]; 2363 } 2364 2365 /*=========================================================================== 2366 * FUNCTION : getBufNumRequired 2367 * 2368 * DESCRIPTION: return number of stream buffers needed for given stream type 2369 * 2370 * PARAMETERS : 2371 * @stream_type : type of stream 2372 * 2373 * RETURN : number of buffers needed 2374 *==========================================================================*/ 2375 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type) 2376 { 2377 int bufferCnt = 0; 2378 int minCaptureBuffers = mParameters.getNumOfSnapshots(); 2379 char value[PROPERTY_VALUE_MAX]; 2380 bool raw_yuv = false; 2381 int persist_cnt = 0; 2382 2383 int zslQBuffers = mParameters.getZSLQueueDepth(); 2384 2385 int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() + 2386 CAMERA_MIN_JPEG_ENCODING_BUFFERS; 2387 2388 int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() + 2389 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2390 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2391 mParameters.getNumOfExtraBuffersForImageProc() + 2392 EXTRA_ZSL_PREVIEW_STREAM_BUF; 2393 2394 int minUndequeCount = 0; 2395 if (!isNoDisplayMode()) { 2396 if(mPreviewWindow != NULL) { 2397 if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount) 2398 != 0) { 2399 LOGW("get_min_undequeued_buffer_count failed"); 2400 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined 2401 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS; 2402 minUndequeCount = MIN_UNDEQUEUED_BUFFERS; 2403 } 2404 } else { 2405 //preview window might not be set at this point. So, query directly 2406 //from BufferQueue implementation of gralloc buffers. 2407 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS; 2408 //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT 2409 minUndequeCount = MIN_UNDEQUEUED_BUFFERS; 2410 } 2411 if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) { 2412 // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS 2413 // and so change the MACRO as per minUndequeCount 2414 LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)", 2415 minUndequeCount, MIN_UNDEQUEUED_BUFFERS); 2416 } 2417 } 2418 2419 LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d" 2420 "maxStreamBuf = %d minUndequeCount = %d", 2421 minCaptureBuffers, zslQBuffers, minCircularBufNum, 2422 maxStreamBuf, minUndequeCount); 2423 // Get buffer count for the particular stream type 2424 switch (stream_type) { 2425 case CAM_STREAM_TYPE_PREVIEW: 2426 { 2427 if (mParameters.isZSLMode()) { 2428 // We need to add two extra streming buffers to add 2429 // flexibility in forming matched super buf in ZSL queue. 2430 // with number being 'zslQBuffers + minCircularBufNum' 2431 // we see preview buffers sometimes get dropped at CPP 2432 // and super buf is not forming in ZSL Q for long time. 2433 2434 bufferCnt = zslQBuffers + minCircularBufNum + 2435 mParameters.getNumOfExtraBuffersForImageProc() + 2436 mParameters.getNumOfExtraBuffersForPreview() + 2437 mParameters.getNumOfExtraHDRInBufsIfNeeded(); 2438 } else { 2439 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS + 2440 mParameters.getMaxUnmatchedFramesInQueue() + 2441 mParameters.getNumOfExtraBuffersForPreview(); 2442 } 2443 // ISP allocates native preview buffers and so reducing same from HAL allocation 2444 if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS ) 2445 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2446 2447 if (mParameters.getRecordingHintValue() == true) 2448 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF; 2449 2450 // Add the display minUndequeCount count on top of camera requirement 2451 bufferCnt += minUndequeCount; 2452 2453 property_get("persist.camera.preview_yuv", value, "0"); 2454 persist_cnt = atoi(value); 2455 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2456 && (bufferCnt < persist_cnt)) { 2457 bufferCnt = persist_cnt; 2458 } 2459 } 2460 break; 2461 case CAM_STREAM_TYPE_POSTVIEW: 2462 { 2463 bufferCnt = minCaptureBuffers + 2464 mParameters.getMaxUnmatchedFramesInQueue() + 2465 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2466 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2467 mParameters.getNumOfExtraBuffersForImageProc(); 2468 2469 if (bufferCnt > maxStreamBuf) { 2470 bufferCnt = maxStreamBuf; 2471 } 2472 bufferCnt += minUndequeCount; 2473 } 2474 break; 2475 case CAM_STREAM_TYPE_SNAPSHOT: 2476 { 2477 if (mParameters.isZSLMode() || mLongshotEnabled) { 2478 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) && 2479 !mLongshotEnabled) { 2480 // Single ZSL snapshot case 2481 bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS + 2482 mParameters.getNumOfExtraBuffersForImageProc(); 2483 } 2484 else { 2485 // ZSL Burst or Longshot case 2486 bufferCnt = zslQBuffers + minCircularBufNum + 2487 mParameters.getNumOfExtraBuffersForImageProc(); 2488 } 2489 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) { 2490 //ISP allocates native buffers in YUV case 2491 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2492 } 2493 } else { 2494 bufferCnt = minCaptureBuffers + 2495 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2496 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2497 mParameters.getNumOfExtraBuffersForImageProc(); 2498 2499 if (bufferCnt > maxStreamBuf) { 2500 bufferCnt = maxStreamBuf; 2501 } 2502 } 2503 } 2504 break; 2505 case CAM_STREAM_TYPE_RAW: 2506 property_get("persist.camera.raw_yuv", value, "0"); 2507 raw_yuv = atoi(value) > 0 ? true : false; 2508 2509 if (isRdiMode() || raw_yuv) { 2510 bufferCnt = zslQBuffers + minCircularBufNum; 2511 } else if (mParameters.isZSLMode()) { 2512 bufferCnt = zslQBuffers + minCircularBufNum; 2513 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) { 2514 //ISP allocates native buffers in YUV case 2515 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS; 2516 } 2517 2518 } else { 2519 bufferCnt = minCaptureBuffers + 2520 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2521 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2522 mParameters.getNumOfExtraBuffersForImageProc(); 2523 2524 if (bufferCnt > maxStreamBuf) { 2525 bufferCnt = maxStreamBuf; 2526 } 2527 } 2528 2529 property_get("persist.camera.preview_raw", value, "0"); 2530 persist_cnt = atoi(value); 2531 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2532 && (bufferCnt < persist_cnt)) { 2533 bufferCnt = persist_cnt; 2534 } 2535 property_get("persist.camera.video_raw", value, "0"); 2536 persist_cnt = atoi(value); 2537 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM) 2538 && (bufferCnt < persist_cnt)) { 2539 bufferCnt = persist_cnt; 2540 } 2541 2542 break; 2543 case CAM_STREAM_TYPE_VIDEO: 2544 { 2545 if (mParameters.getBufBatchCount()) { 2546 //Video Buffer in case of HFR or camera batching.. 2547 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS; 2548 } else if (mParameters.getVideoBatchSize()) { 2549 //Video Buffer count only for HAL to HAL batching. 2550 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS 2551 * mParameters.getVideoBatchSize()); 2552 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) { 2553 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS; 2554 } 2555 } else { 2556 // No batching enabled. 2557 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS; 2558 } 2559 2560 bufferCnt += mParameters.getNumOfExtraBuffersForVideo(); 2561 //if its 4K encoding usecase, then add extra buffer 2562 cam_dimension_t dim; 2563 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim); 2564 if (is4k2kResolution(&dim)) { 2565 //get additional buffer count 2566 property_get("vidc.enc.dcvs.extra-buff-count", value, "0"); 2567 bufferCnt += atoi(value); 2568 } 2569 } 2570 break; 2571 case CAM_STREAM_TYPE_METADATA: 2572 { 2573 if (mParameters.isZSLMode()) { 2574 // MetaData buffers should be >= (Preview buffers-minUndequeCount) 2575 bufferCnt = zslQBuffers + minCircularBufNum + 2576 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2577 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2578 mParameters.getNumOfExtraBuffersForImageProc() + 2579 EXTRA_ZSL_PREVIEW_STREAM_BUF; 2580 } else { 2581 bufferCnt = minCaptureBuffers + 2582 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 2583 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 2584 mParameters.getMaxUnmatchedFramesInQueue() + 2585 CAMERA_MIN_STREAMING_BUFFERS + 2586 mParameters.getNumOfExtraBuffersForImageProc(); 2587 2588 if (bufferCnt > zslQBuffers + minCircularBufNum) { 2589 bufferCnt = zslQBuffers + minCircularBufNum; 2590 } 2591 } 2592 if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) { 2593 bufferCnt = CAMERA_MIN_METADATA_BUFFERS; 2594 } 2595 } 2596 break; 2597 case CAM_STREAM_TYPE_OFFLINE_PROC: 2598 { 2599 bufferCnt = minCaptureBuffers; 2600 // One of the ubifocus buffers is miscellaneous buffer 2601 if (mParameters.isUbiRefocus()) { 2602 bufferCnt -= 1; 2603 } 2604 if (mLongshotEnabled) { 2605 bufferCnt = mParameters.getLongshotStages(); 2606 } 2607 } 2608 break; 2609 case CAM_STREAM_TYPE_CALLBACK: 2610 bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS; 2611 break; 2612 case CAM_STREAM_TYPE_ANALYSIS: 2613 case CAM_STREAM_TYPE_DEFAULT: 2614 case CAM_STREAM_TYPE_MAX: 2615 default: 2616 bufferCnt = 0; 2617 break; 2618 } 2619 2620 LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type); 2621 if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) { 2622 LOGW("Buffer count %d for stream type %d exceeds limit %d", 2623 bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM); 2624 return CAM_MAX_NUM_BUFS_PER_STREAM; 2625 } 2626 2627 return (uint8_t)bufferCnt; 2628 } 2629 2630 /*=========================================================================== 2631 * FUNCTION : allocateStreamBuf 2632 * 2633 * DESCRIPTION: alocate stream buffers 2634 * 2635 * PARAMETERS : 2636 * @stream_type : type of stream 2637 * @size : size of buffer 2638 * @stride : stride of buffer 2639 * @scanline : scanline of buffer 2640 * @bufferCnt : [IN/OUT] minimum num of buffers to be allocated. 2641 * could be modified during allocation if more buffers needed 2642 * 2643 * RETURN : ptr to a memory obj that holds stream buffers. 2644 * NULL if failed 2645 *==========================================================================*/ 2646 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf( 2647 cam_stream_type_t stream_type, size_t size, int stride, int scanline, 2648 uint8_t &bufferCnt) 2649 { 2650 int rc = NO_ERROR; 2651 QCameraMemory *mem = NULL; 2652 bool bCachedMem = QCAMERA_ION_USE_CACHE; 2653 bool bPoolMem = false; 2654 char value[PROPERTY_VALUE_MAX]; 2655 property_get("persist.camera.mem.usepool", value, "1"); 2656 if (atoi(value) == 1) { 2657 bPoolMem = true; 2658 } 2659 2660 // Allocate stream buffer memory object 2661 switch (stream_type) { 2662 case CAM_STREAM_TYPE_PREVIEW: 2663 { 2664 if (isNoDisplayMode()) { 2665 mem = new QCameraStreamMemory(mGetMemory, 2666 bCachedMem, 2667 (bPoolMem) ? &m_memoryPool : NULL, 2668 stream_type); 2669 } else { 2670 cam_dimension_t dim; 2671 int minFPS, maxFPS; 2672 QCameraGrallocMemory *grallocMemory = 2673 new QCameraGrallocMemory(mGetMemory); 2674 2675 mParameters.getStreamDimension(stream_type, dim); 2676 /* we are interested only in maxfps here */ 2677 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 2678 int usage = 0; 2679 if(mParameters.isUBWCEnabled()) { 2680 cam_format_t fmt; 2681 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt); 2682 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 2683 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ; 2684 } 2685 } 2686 if (grallocMemory) { 2687 grallocMemory->setMappable( 2688 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS); 2689 grallocMemory->setWindowInfo(mPreviewWindow, 2690 dim.width,dim.height, stride, scanline, 2691 mParameters.getPreviewHalPixelFormat(), 2692 maxFPS, usage); 2693 pthread_mutex_lock(&mGrallocLock); 2694 if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) { 2695 mEnqueuedBuffers = (bufferCnt - 2696 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS); 2697 } else { 2698 mEnqueuedBuffers = 0; 2699 } 2700 pthread_mutex_unlock(&mGrallocLock); 2701 } 2702 mem = grallocMemory; 2703 } 2704 } 2705 break; 2706 case CAM_STREAM_TYPE_POSTVIEW: 2707 { 2708 if (isNoDisplayMode() || isPreviewRestartEnabled()) { 2709 mem = new QCameraStreamMemory(mGetMemory, bCachedMem); 2710 } else { 2711 cam_dimension_t dim; 2712 int minFPS, maxFPS; 2713 QCameraGrallocMemory *grallocMemory = 2714 new QCameraGrallocMemory(mGetMemory); 2715 2716 mParameters.getStreamDimension(stream_type, dim); 2717 /* we are interested only in maxfps here */ 2718 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 2719 if (grallocMemory) { 2720 grallocMemory->setWindowInfo(mPreviewWindow, dim.width, 2721 dim.height, stride, scanline, 2722 mParameters.getPreviewHalPixelFormat(), maxFPS); 2723 } 2724 mem = grallocMemory; 2725 } 2726 } 2727 break; 2728 case CAM_STREAM_TYPE_ANALYSIS: 2729 case CAM_STREAM_TYPE_SNAPSHOT: 2730 case CAM_STREAM_TYPE_RAW: 2731 case CAM_STREAM_TYPE_OFFLINE_PROC: 2732 mem = new QCameraStreamMemory(mGetMemory, 2733 bCachedMem, 2734 (bPoolMem) ? &m_memoryPool : NULL, 2735 stream_type); 2736 break; 2737 case CAM_STREAM_TYPE_METADATA: 2738 { 2739 if (mMetadataMem == NULL) { 2740 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE); 2741 } else { 2742 mem = mMetadataMem; 2743 mMetadataMem = NULL; 2744 2745 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt(); 2746 if (numAdditionalBuffers > 0) { 2747 rc = mem->allocateMore(numAdditionalBuffers, size); 2748 if (rc != NO_ERROR) { 2749 LOGE("Failed to allocate additional buffers, " 2750 "but attempting to proceed."); 2751 } 2752 } 2753 bufferCnt = mem->getCnt(); 2754 // The memory is already allocated and initialized, so 2755 // simply return here. 2756 return mem; 2757 } 2758 } 2759 break; 2760 case CAM_STREAM_TYPE_VIDEO: 2761 { 2762 //Use uncached allocation by default 2763 if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() || 2764 mParameters.isHighQualityNoiseReductionMode()) { 2765 bCachedMem = QCAMERA_ION_USE_CACHE; 2766 } 2767 else { 2768 bCachedMem = QCAMERA_ION_USE_NOCACHE; 2769 } 2770 2771 QCameraVideoMemory *videoMemory = NULL; 2772 if (mParameters.getVideoBatchSize()) { 2773 videoMemory = new QCameraVideoMemory( 2774 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH); 2775 if (videoMemory == NULL) { 2776 LOGE("Out of memory for video batching obj"); 2777 return NULL; 2778 } 2779 /* 2780 * numFDs = BATCH size 2781 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT 2782 */ 2783 rc = videoMemory->allocateMeta( 2784 CAMERA_MIN_VIDEO_BATCH_BUFFERS, 2785 mParameters.getVideoBatchSize(), 2786 VIDEO_METADATA_NUM_INTS); 2787 if (rc < 0) { 2788 delete videoMemory; 2789 return NULL; 2790 } 2791 } else { 2792 videoMemory = 2793 new QCameraVideoMemory(mGetMemory, bCachedMem); 2794 if (videoMemory == NULL) { 2795 LOGE("Out of memory for video obj"); 2796 return NULL; 2797 } 2798 } 2799 2800 int usage = 0; 2801 cam_format_t fmt; 2802 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt); 2803 if (mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) { 2804 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 2805 } 2806 videoMemory->setVideoInfo(usage, fmt); 2807 mem = videoMemory; 2808 } 2809 break; 2810 case CAM_STREAM_TYPE_CALLBACK: 2811 mem = new QCameraStreamMemory(mGetMemory, 2812 bCachedMem, 2813 (bPoolMem) ? &m_memoryPool : NULL, 2814 stream_type); 2815 break; 2816 case CAM_STREAM_TYPE_DEFAULT: 2817 case CAM_STREAM_TYPE_MAX: 2818 default: 2819 break; 2820 } 2821 if (!mem) { 2822 return NULL; 2823 } 2824 2825 if (bufferCnt > 0) { 2826 if (mParameters.isSecureMode() && 2827 (stream_type == CAM_STREAM_TYPE_RAW) && 2828 (mParameters.isRdiMode())) { 2829 LOGD("Allocating %d secure buffers of size %d ", bufferCnt, size); 2830 rc = mem->allocate(bufferCnt, size, SECURE); 2831 } else { 2832 rc = mem->allocate(bufferCnt, size, NON_SECURE); 2833 } 2834 if (rc < 0) { 2835 delete mem; 2836 return NULL; 2837 } 2838 bufferCnt = mem->getCnt(); 2839 } 2840 LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d", 2841 rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem); 2842 return mem; 2843 } 2844 2845 /*=========================================================================== 2846 * FUNCTION : allocateMoreStreamBuf 2847 * 2848 * DESCRIPTION: alocate more stream buffers from the memory object 2849 * 2850 * PARAMETERS : 2851 * @mem_obj : memory object ptr 2852 * @size : size of buffer 2853 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated. 2854 * output will be the number of total buffers 2855 * 2856 * RETURN : int32_t type of status 2857 * NO_ERROR -- success 2858 * none-zero failure code 2859 *==========================================================================*/ 2860 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf( 2861 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt) 2862 { 2863 int rc = NO_ERROR; 2864 2865 if (bufferCnt > 0) { 2866 rc = mem_obj->allocateMore(bufferCnt, size); 2867 bufferCnt = mem_obj->getCnt(); 2868 } 2869 return rc; 2870 } 2871 2872 /*=========================================================================== 2873 * FUNCTION : allocateMiscBuf 2874 * 2875 * DESCRIPTION: alocate miscellaneous buffer 2876 * 2877 * PARAMETERS : 2878 * @streamInfo : stream info 2879 * 2880 * RETURN : ptr to a memory obj that holds stream info buffer. 2881 * NULL if failed 2882 *==========================================================================*/ 2883 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf( 2884 cam_stream_info_t *streamInfo) 2885 { 2886 int rc = NO_ERROR; 2887 uint8_t bufNum = 0; 2888 size_t bufSize = 0; 2889 QCameraHeapMemory *miscBuf = NULL; 2890 uint32_t feature_mask = 2891 streamInfo->reprocess_config.pp_feature_config.feature_mask; 2892 2893 switch (streamInfo->stream_type) { 2894 case CAM_STREAM_TYPE_OFFLINE_PROC: 2895 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) { 2896 bufNum = 1; 2897 bufSize = mParameters.getTPMaxMetaSize(); 2898 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) { 2899 bufNum = 1; 2900 bufSize = mParameters.getRefocusMaxMetaSize(); 2901 } 2902 break; 2903 default: 2904 break; 2905 } 2906 2907 if (bufNum && bufSize) { 2908 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 2909 2910 if (!miscBuf) { 2911 LOGE("Unable to allocate miscBuf object"); 2912 return NULL; 2913 } 2914 2915 rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE); 2916 if (rc < 0) { 2917 LOGE("Failed to allocate misc buffer memory"); 2918 delete miscBuf; 2919 return NULL; 2920 } 2921 } 2922 2923 return miscBuf; 2924 } 2925 2926 /*=========================================================================== 2927 * FUNCTION : allocateStreamInfoBuf 2928 * 2929 * DESCRIPTION: alocate stream info buffer 2930 * 2931 * PARAMETERS : 2932 * @stream_type : type of stream 2933 * 2934 * RETURN : ptr to a memory obj that holds stream info buffer. 2935 * NULL if failed 2936 *==========================================================================*/ 2937 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf( 2938 cam_stream_type_t stream_type) 2939 { 2940 int rc = NO_ERROR; 2941 char value[PROPERTY_VALUE_MAX]; 2942 bool raw_yuv = false; 2943 2944 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 2945 if (!streamInfoBuf) { 2946 LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object"); 2947 return NULL; 2948 } 2949 2950 rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE); 2951 if (rc < 0) { 2952 LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory"); 2953 delete streamInfoBuf; 2954 return NULL; 2955 } 2956 2957 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0); 2958 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 2959 streamInfo->stream_type = stream_type; 2960 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt); 2961 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim); 2962 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim); 2963 streamInfo->num_bufs = getBufNumRequired(stream_type); 2964 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 2965 streamInfo->is_secure = NON_SECURE; 2966 2967 switch (stream_type) { 2968 case CAM_STREAM_TYPE_SNAPSHOT: 2969 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) || 2970 mLongshotEnabled) { 2971 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 2972 } else { 2973 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 2974 streamInfo->num_of_burst = (uint8_t) 2975 (mParameters.getNumOfSnapshots() 2976 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 2977 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 2978 + mParameters.getNumOfExtraBuffersForImageProc()); 2979 } 2980 break; 2981 case CAM_STREAM_TYPE_RAW: 2982 property_get("persist.camera.raw_yuv", value, "0"); 2983 raw_yuv = atoi(value) > 0 ? true : false; 2984 if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) { 2985 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 2986 } else { 2987 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 2988 streamInfo->num_of_burst = mParameters.getNumOfSnapshots(); 2989 } 2990 if (mParameters.isSecureMode() && mParameters.isRdiMode()) { 2991 streamInfo->is_secure = SECURE; 2992 } else { 2993 streamInfo->is_secure = NON_SECURE; 2994 } 2995 break; 2996 case CAM_STREAM_TYPE_POSTVIEW: 2997 if (mLongshotEnabled) { 2998 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 2999 } else { 3000 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 3001 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots() 3002 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 3003 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 3004 + mParameters.getNumOfExtraBuffersForImageProc()); 3005 } 3006 break; 3007 case CAM_STREAM_TYPE_VIDEO: 3008 streamInfo->dis_enable = mParameters.isDISEnabled(); 3009 if (mParameters.getBufBatchCount()) { 3010 //Update stream info structure with batch mode info 3011 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH; 3012 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount(); 3013 streamInfo->user_buf_info.size = 3014 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t)); 3015 cam_fps_range_t pFpsRange; 3016 mParameters.getHfrFps(pFpsRange); 3017 streamInfo->user_buf_info.frameInterval = 3018 (long)((1000/pFpsRange.video_max_fps) * 1000); 3019 LOGH("Video Batch Count = %d, interval = %d", 3020 streamInfo->user_buf_info.frame_buf_cnt, 3021 streamInfo->user_buf_info.frameInterval); 3022 } 3023 case CAM_STREAM_TYPE_PREVIEW: 3024 if (mParameters.getRecordingHintValue()) { 3025 if(mParameters.isDISEnabled()) { 3026 streamInfo->is_type = mParameters.getISType(); 3027 } else { 3028 streamInfo->is_type = IS_TYPE_NONE; 3029 } 3030 } 3031 if (mParameters.isSecureMode()) { 3032 streamInfo->is_secure = SECURE; 3033 } 3034 break; 3035 case CAM_STREAM_TYPE_ANALYSIS: 3036 streamInfo->noFrameExpected = 1; 3037 break; 3038 default: 3039 break; 3040 } 3041 3042 // Update feature mask 3043 mParameters.updatePpFeatureMask(stream_type); 3044 3045 // Get feature mask 3046 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask); 3047 3048 // Update pp config 3049 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) { 3050 int flipMode = mParameters.getFlipMode(stream_type); 3051 if (flipMode > 0) { 3052 streamInfo->pp_config.flip = (uint32_t)flipMode; 3053 } 3054 } 3055 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) { 3056 streamInfo->pp_config.sharpness = mParameters.getSharpness(); 3057 } 3058 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) { 3059 streamInfo->pp_config.effect = mParameters.getEffectValue(); 3060 } 3061 3062 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) { 3063 streamInfo->pp_config.denoise2d.denoise_enable = 1; 3064 streamInfo->pp_config.denoise2d.process_plates = 3065 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 3066 } 3067 3068 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type || 3069 CAM_STREAM_TYPE_RAW == stream_type))) { 3070 if (gCamCapability[mCameraId]->qcom_supported_feature_mask & 3071 CAM_QCOM_FEATURE_CROP) 3072 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 3073 if (gCamCapability[mCameraId]->qcom_supported_feature_mask & 3074 CAM_QCOM_FEATURE_SCALE) 3075 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 3076 } 3077 3078 LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x\n", 3079 stream_type, streamInfo->fmt, streamInfo->dim.width, 3080 streamInfo->dim.height, streamInfo->num_bufs, 3081 streamInfo->pp_config.feature_mask); 3082 3083 return streamInfoBuf; 3084 } 3085 3086 /*=========================================================================== 3087 * FUNCTION : allocateStreamUserBuf 3088 * 3089 * DESCRIPTION: allocate user ptr for stream buffers 3090 * 3091 * PARAMETERS : 3092 * @streamInfo : stream info structure 3093 * 3094 * RETURN : ptr to a memory obj that holds stream info buffer. 3095 * NULL if failed 3096 3097 *==========================================================================*/ 3098 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf( 3099 cam_stream_info_t *streamInfo) 3100 { 3101 int rc = NO_ERROR; 3102 QCameraMemory *mem = NULL; 3103 int size = 0; 3104 3105 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) { 3106 LOGE("Stream is not in BATCH mode. Invalid Stream"); 3107 return NULL; 3108 } 3109 3110 // Allocate stream user buffer memory object 3111 switch (streamInfo->stream_type) { 3112 case CAM_STREAM_TYPE_VIDEO: { 3113 QCameraVideoMemory *video_mem = new QCameraVideoMemory( 3114 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH); 3115 if (video_mem == NULL) { 3116 LOGE("Out of memory for video obj"); 3117 return NULL; 3118 } 3119 /* 3120 * numFDs = BATCH size 3121 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT 3122 */ 3123 rc = video_mem->allocateMeta(streamInfo->num_bufs, 3124 mParameters.getBufBatchCount(), VIDEO_METADATA_NUM_INTS); 3125 if (rc < 0) { 3126 LOGE("allocateMeta failed"); 3127 delete video_mem; 3128 return NULL; 3129 } 3130 int usage = 0; 3131 cam_format_t fmt; 3132 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt); 3133 if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) { 3134 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 3135 } 3136 video_mem->setVideoInfo(usage, fmt); 3137 mem = static_cast<QCameraMemory *>(video_mem); 3138 } 3139 break; 3140 3141 case CAM_STREAM_TYPE_PREVIEW: 3142 case CAM_STREAM_TYPE_POSTVIEW: 3143 case CAM_STREAM_TYPE_ANALYSIS: 3144 case CAM_STREAM_TYPE_SNAPSHOT: 3145 case CAM_STREAM_TYPE_RAW: 3146 case CAM_STREAM_TYPE_METADATA: 3147 case CAM_STREAM_TYPE_OFFLINE_PROC: 3148 case CAM_STREAM_TYPE_CALLBACK: 3149 LOGE("Stream type Not supported.for BATCH processing"); 3150 break; 3151 3152 case CAM_STREAM_TYPE_DEFAULT: 3153 case CAM_STREAM_TYPE_MAX: 3154 default: 3155 break; 3156 } 3157 if (!mem) { 3158 LOGE("Failed to allocate mem"); 3159 return NULL; 3160 } 3161 3162 /*Size of this buffer will be number of batch buffer */ 3163 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size), 3164 CAM_PAD_TO_4K); 3165 3166 LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs); 3167 3168 if (size > 0) { 3169 // Allocating one buffer for all batch buffers 3170 rc = mem->allocate(1, size, NON_SECURE); 3171 if (rc < 0) { 3172 delete mem; 3173 return NULL; 3174 } 3175 } 3176 return mem; 3177 } 3178 3179 3180 /*=========================================================================== 3181 * FUNCTION : waitForDeferredAlloc 3182 * 3183 * DESCRIPTION: Wait for deferred allocation, if applicable 3184 * (applicable only for metadata buffers so far) 3185 * 3186 * PARAMETERS : 3187 * @stream_type : type of stream to (possibly) wait for 3188 * 3189 * RETURN : None 3190 *==========================================================================*/ 3191 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type) 3192 { 3193 if (stream_type == CAM_STREAM_TYPE_METADATA) { 3194 waitDeferredWork(mMetadataAllocJob); 3195 } 3196 } 3197 3198 3199 /*=========================================================================== 3200 * FUNCTION : setPreviewWindow 3201 * 3202 * DESCRIPTION: set preview window impl 3203 * 3204 * PARAMETERS : 3205 * @window : ptr to window ops table struct 3206 * 3207 * RETURN : int32_t type of status 3208 * NO_ERROR -- success 3209 * none-zero failure code 3210 *==========================================================================*/ 3211 int QCamera2HardwareInterface::setPreviewWindow( 3212 struct preview_stream_ops *window) 3213 { 3214 mPreviewWindow = window; 3215 return NO_ERROR; 3216 } 3217 3218 /*=========================================================================== 3219 * FUNCTION : setCallBacks 3220 * 3221 * DESCRIPTION: set callbacks impl 3222 * 3223 * PARAMETERS : 3224 * @notify_cb : notify cb 3225 * @data_cb : data cb 3226 * @data_cb_timestamp : data cb with time stamp 3227 * @get_memory : request memory ops table 3228 * @user : user data ptr 3229 * 3230 * RETURN : int32_t type of status 3231 * NO_ERROR -- success 3232 * none-zero failure code 3233 *==========================================================================*/ 3234 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb, 3235 camera_data_callback data_cb, 3236 camera_data_timestamp_callback data_cb_timestamp, 3237 camera_request_memory get_memory, 3238 void *user) 3239 { 3240 mNotifyCb = notify_cb; 3241 mDataCb = data_cb; 3242 mDataCbTimestamp = data_cb_timestamp; 3243 mGetMemory = get_memory; 3244 mCallbackCookie = user; 3245 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user); 3246 return NO_ERROR; 3247 } 3248 3249 /*=========================================================================== 3250 * FUNCTION : setJpegCallBacks 3251 * 3252 * DESCRIPTION: set JPEG callbacks impl 3253 * 3254 * PARAMETERS : 3255 * @jpegCb : Jpeg callback method 3256 * @callbackCookie : callback cookie 3257 * 3258 * RETURN : int32_t type of status 3259 * NO_ERROR -- success 3260 * none-zero failure code 3261 *==========================================================================*/ 3262 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb, 3263 void *callbackCookie) 3264 { 3265 LOGH("camera id %d", getCameraId()); 3266 mJpegCb = jpegCb; 3267 mJpegCallbackCookie = callbackCookie; 3268 m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie); 3269 } 3270 3271 /*=========================================================================== 3272 * FUNCTION : enableMsgType 3273 * 3274 * DESCRIPTION: enable msg type impl 3275 * 3276 * PARAMETERS : 3277 * @msg_type : msg type mask to be enabled 3278 * 3279 * RETURN : int32_t type of status 3280 * NO_ERROR -- success 3281 * none-zero failure code 3282 *==========================================================================*/ 3283 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type) 3284 { 3285 int32_t rc = NO_ERROR; 3286 3287 if (mParameters.isUBWCEnabled()) { 3288 /*Need Special CALLBACK stream incase application requesting for 3289 Preview callback in UBWC case*/ 3290 if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) && 3291 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) { 3292 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) { 3293 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK); 3294 if (rc != NO_ERROR) { 3295 LOGE("START Callback Channel failed"); 3296 } 3297 } 3298 } 3299 } 3300 mMsgEnabled |= msg_type; 3301 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc); 3302 return rc; 3303 } 3304 3305 /*=========================================================================== 3306 * FUNCTION : disableMsgType 3307 * 3308 * DESCRIPTION: disable msg type impl 3309 * 3310 * PARAMETERS : 3311 * @msg_type : msg type mask to be disabled 3312 * 3313 * RETURN : int32_t type of status 3314 * NO_ERROR -- success 3315 * none-zero failure code 3316 *==========================================================================*/ 3317 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type) 3318 { 3319 int32_t rc = NO_ERROR; 3320 3321 if (mParameters.isUBWCEnabled()) { 3322 /*STOP CALLBACK STREAM*/ 3323 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) && 3324 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) { 3325 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) { 3326 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK); 3327 if (rc != NO_ERROR) { 3328 LOGE("STOP Callback Channel failed"); 3329 } 3330 } 3331 } 3332 } 3333 mMsgEnabled &= ~msg_type; 3334 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc); 3335 return rc; 3336 } 3337 3338 /*=========================================================================== 3339 * FUNCTION : msgTypeEnabled 3340 * 3341 * DESCRIPTION: impl to determine if certain msg_type is enabled 3342 * 3343 * PARAMETERS : 3344 * @msg_type : msg type mask 3345 * 3346 * RETURN : 0 -- not enabled 3347 * none 0 -- enabled 3348 *==========================================================================*/ 3349 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type) 3350 { 3351 return (mMsgEnabled & msg_type); 3352 } 3353 3354 /*=========================================================================== 3355 * FUNCTION : msgTypeEnabledWithLock 3356 * 3357 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock 3358 * 3359 * PARAMETERS : 3360 * @msg_type : msg type mask 3361 * 3362 * RETURN : 0 -- not enabled 3363 * none 0 -- enabled 3364 *==========================================================================*/ 3365 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type) 3366 { 3367 int enabled = 0; 3368 lockAPI(); 3369 enabled = mMsgEnabled & msg_type; 3370 unlockAPI(); 3371 return enabled; 3372 } 3373 3374 /*=========================================================================== 3375 * FUNCTION : startPreview 3376 * 3377 * DESCRIPTION: start preview impl 3378 * 3379 * PARAMETERS : none 3380 * 3381 * RETURN : int32_t type of status 3382 * NO_ERROR -- success 3383 * none-zero failure code 3384 *==========================================================================*/ 3385 int QCamera2HardwareInterface::startPreview() 3386 { 3387 KPI_ATRACE_CALL(); 3388 int32_t rc = NO_ERROR; 3389 3390 LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(), 3391 mParameters.getRecordingHintValue()); 3392 3393 m_perfLock.lock_acq(); 3394 3395 updateThermalLevel((void *)&mThermalLevel); 3396 3397 setDisplayFrameSkip(); 3398 3399 // start preview stream 3400 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 3401 rc = startChannel(QCAMERA_CH_TYPE_ZSL); 3402 } else { 3403 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW); 3404 } 3405 3406 if (rc != NO_ERROR) { 3407 LOGE("failed to start channels"); 3408 m_perfLock.lock_rel(); 3409 return rc; 3410 } 3411 3412 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) 3413 && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) { 3414 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK); 3415 if (rc != NO_ERROR) { 3416 LOGE("failed to start callback stream"); 3417 stopChannel(QCAMERA_CH_TYPE_ZSL); 3418 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3419 m_perfLock.lock_rel(); 3420 return rc; 3421 } 3422 } 3423 3424 updatePostPreviewParameters(); 3425 m_stateMachine.setPreviewCallbackNeeded(true); 3426 3427 // if job id is non-zero, that means the postproc init job is already 3428 // pending or complete 3429 if (mInitPProcJob == 0) { 3430 mInitPProcJob = deferPPInit(); 3431 if (mInitPProcJob == 0) { 3432 LOGE("Unable to initialize postprocessor, mCameraHandle = %p", 3433 mCameraHandle); 3434 rc = -ENOMEM; 3435 m_perfLock.lock_rel(); 3436 return rc; 3437 } 3438 } 3439 m_perfLock.lock_rel(); 3440 3441 if (rc == NO_ERROR) { 3442 // Set power Hint for preview 3443 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true); 3444 } 3445 3446 LOGI("X rc = %d", rc); 3447 return rc; 3448 } 3449 3450 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() { 3451 // Enable OIS only in Camera mode and 4k2k camcoder mode 3452 int32_t rc = NO_ERROR; 3453 rc = mParameters.updateOisValue(1); 3454 return NO_ERROR; 3455 } 3456 3457 /*=========================================================================== 3458 * FUNCTION : stopPreview 3459 * 3460 * DESCRIPTION: stop preview impl 3461 * 3462 * PARAMETERS : none 3463 * 3464 * RETURN : int32_t type of status 3465 * NO_ERROR -- success 3466 * none-zero failure code 3467 *==========================================================================*/ 3468 int QCamera2HardwareInterface::stopPreview() 3469 { 3470 KPI_ATRACE_CALL(); 3471 LOGI("E"); 3472 mNumPreviewFaces = -1; 3473 mActiveAF = false; 3474 3475 // Disable power Hint for preview 3476 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false); 3477 3478 m_perfLock.lock_acq(); 3479 3480 // stop preview stream 3481 stopChannel(QCAMERA_CH_TYPE_CALLBACK); 3482 stopChannel(QCAMERA_CH_TYPE_ZSL); 3483 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3484 stopChannel(QCAMERA_CH_TYPE_RAW); 3485 3486 m_cbNotifier.flushPreviewNotifications(); 3487 //add for ts makeup 3488 #ifdef TARGET_TS_MAKEUP 3489 ts_makeup_finish(); 3490 #endif 3491 // delete all channels from preparePreview 3492 unpreparePreview(); 3493 3494 m_perfLock.lock_rel(); 3495 3496 LOGI("X"); 3497 return NO_ERROR; 3498 } 3499 3500 /*=========================================================================== 3501 * FUNCTION : storeMetaDataInBuffers 3502 * 3503 * DESCRIPTION: enable store meta data in buffers for video frames impl 3504 * 3505 * PARAMETERS : 3506 * @enable : flag if need enable 3507 * 3508 * RETURN : int32_t type of status 3509 * NO_ERROR -- success 3510 * none-zero failure code 3511 *==========================================================================*/ 3512 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable) 3513 { 3514 mStoreMetaDataInFrame = enable; 3515 return NO_ERROR; 3516 } 3517 3518 /*=========================================================================== 3519 * FUNCTION : preStartRecording 3520 * 3521 * DESCRIPTION: Prepare start recording impl 3522 * 3523 * PARAMETERS : none 3524 * 3525 * RETURN : int32_t type of status 3526 * NO_ERROR -- success 3527 * none-zero failure code 3528 *==========================================================================*/ 3529 int QCamera2HardwareInterface::preStartRecording() 3530 { 3531 int32_t rc = NO_ERROR; 3532 LOGH("E"); 3533 if (mParameters.getRecordingHintValue() == false) { 3534 3535 // Give HWI control to restart preview only in single camera mode. 3536 // In dual-cam mode, this control belongs to muxer. 3537 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 3538 LOGH("start recording when hint is false, stop preview first"); 3539 stopPreview(); 3540 3541 // Set recording hint to TRUE 3542 mParameters.updateRecordingHintValue(TRUE); 3543 rc = preparePreview(); 3544 if (rc == NO_ERROR) { 3545 rc = startPreview(); 3546 } 3547 } 3548 else 3549 { 3550 // For dual cam mode, update the flag mPreviewRestartNeeded to true 3551 // Restart control will be handled by muxer. 3552 mPreviewRestartNeeded = true; 3553 } 3554 } 3555 3556 LOGH("X rc = %d", rc); 3557 return rc; 3558 } 3559 3560 /*=========================================================================== 3561 * FUNCTION : startRecording 3562 * 3563 * DESCRIPTION: start recording impl 3564 * 3565 * PARAMETERS : none 3566 * 3567 * RETURN : int32_t type of status 3568 * NO_ERROR -- success 3569 * none-zero failure code 3570 *==========================================================================*/ 3571 int QCamera2HardwareInterface::startRecording() 3572 { 3573 int32_t rc = NO_ERROR; 3574 3575 LOGI("E"); 3576 //link meta stream with video channel if low power mode. 3577 if (isLowPowerMode()) { 3578 // Find and try to link a metadata stream from preview channel 3579 QCameraChannel *pMetaChannel = NULL; 3580 QCameraStream *pMetaStream = NULL; 3581 QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO]; 3582 3583 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 3584 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 3585 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 3586 QCameraStream *pStream = NULL; 3587 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 3588 pStream = pMetaChannel->getStreamByIndex(i); 3589 if ((NULL != pStream) && 3590 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) { 3591 pMetaStream = pStream; 3592 break; 3593 } 3594 } 3595 } 3596 3597 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 3598 rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream); 3599 if (NO_ERROR != rc) { 3600 LOGW("Metadata stream link failed %d", rc); 3601 } 3602 } 3603 } 3604 3605 if (rc == NO_ERROR) { 3606 rc = startChannel(QCAMERA_CH_TYPE_VIDEO); 3607 } 3608 3609 if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) { 3610 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 3611 if (!mParameters.is4k2kVideoResolution()) { 3612 // Find and try to link a metadata stream from preview channel 3613 QCameraChannel *pMetaChannel = NULL; 3614 QCameraStream *pMetaStream = NULL; 3615 3616 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 3617 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 3618 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 3619 QCameraStream *pStream = NULL; 3620 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 3621 pStream = pMetaChannel->getStreamByIndex(i); 3622 if ((NULL != pStream) && 3623 (CAM_STREAM_TYPE_METADATA == 3624 pStream->getMyType())) { 3625 pMetaStream = pStream; 3626 break; 3627 } 3628 } 3629 } 3630 3631 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 3632 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 3633 if (NO_ERROR != rc) { 3634 LOGW("Metadata stream link failed %d", rc); 3635 } 3636 } 3637 } 3638 LOGH("START snapshot Channel for TNR processing"); 3639 rc = pChannel->start(); 3640 } 3641 3642 if (rc == NO_ERROR) { 3643 // Set power Hint for video encoding 3644 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true); 3645 } 3646 3647 LOGI("X rc = %d", rc); 3648 return rc; 3649 } 3650 3651 /*=========================================================================== 3652 * FUNCTION : stopRecording 3653 * 3654 * DESCRIPTION: stop recording impl 3655 * 3656 * PARAMETERS : none 3657 * 3658 * RETURN : int32_t type of status 3659 * NO_ERROR -- success 3660 * none-zero failure code 3661 *==========================================================================*/ 3662 int QCamera2HardwareInterface::stopRecording() 3663 { 3664 LOGI("E"); 3665 // stop snapshot channel 3666 if (mParameters.isTNRSnapshotEnabled()) { 3667 LOGH("STOP snapshot Channel for TNR processing"); 3668 stopChannel(QCAMERA_CH_TYPE_SNAPSHOT); 3669 } 3670 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO); 3671 3672 // Disable power hint for video encoding 3673 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false); 3674 3675 LOGI("X rc = %d", rc); 3676 return rc; 3677 } 3678 3679 /*=========================================================================== 3680 * FUNCTION : releaseRecordingFrame 3681 * 3682 * DESCRIPTION: return video frame impl 3683 * 3684 * PARAMETERS : 3685 * @opaque : ptr to video frame to be returned 3686 * 3687 * RETURN : int32_t type of status 3688 * NO_ERROR -- success 3689 * none-zero failure code 3690 *==========================================================================*/ 3691 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque) 3692 { 3693 int32_t rc = UNKNOWN_ERROR; 3694 QCameraVideoChannel *pChannel = 3695 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO]; 3696 LOGD("opaque data = %p",opaque); 3697 if(pChannel != NULL) { 3698 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0); 3699 } 3700 return rc; 3701 } 3702 3703 /*=========================================================================== 3704 * FUNCTION : autoFocus 3705 * 3706 * DESCRIPTION: start auto focus impl 3707 * 3708 * PARAMETERS : none 3709 * 3710 * RETURN : int32_t type of status 3711 * NO_ERROR -- success 3712 * none-zero failure code 3713 *==========================================================================*/ 3714 int QCamera2HardwareInterface::autoFocus() 3715 { 3716 int rc = NO_ERROR; 3717 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 3718 LOGH("E"); 3719 3720 m_currentFocusState = CAM_AF_STATE_INACTIVE; 3721 3722 switch (focusMode) { 3723 case CAM_FOCUS_MODE_AUTO: 3724 case CAM_FOCUS_MODE_MACRO: 3725 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 3726 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 3727 mActiveAF = true; 3728 LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d", 3729 focusMode, m_currentFocusState); 3730 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle); 3731 break; 3732 case CAM_FOCUS_MODE_INFINITY: 3733 case CAM_FOCUS_MODE_FIXED: 3734 case CAM_FOCUS_MODE_EDOF: 3735 default: 3736 LOGI("No ops in focusMode (%d)", focusMode); 3737 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 3738 break; 3739 } 3740 3741 if (NO_ERROR != rc) { 3742 mActiveAF = false; 3743 } 3744 LOGH("X rc = %d", rc); 3745 return rc; 3746 } 3747 3748 /*=========================================================================== 3749 * FUNCTION : cancelAutoFocus 3750 * 3751 * DESCRIPTION: cancel auto focus impl 3752 * 3753 * PARAMETERS : none 3754 * 3755 * RETURN : int32_t type of status 3756 * NO_ERROR -- success 3757 * none-zero failure code 3758 *==========================================================================*/ 3759 int QCamera2HardwareInterface::cancelAutoFocus() 3760 { 3761 int rc = NO_ERROR; 3762 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 3763 3764 switch (focusMode) { 3765 case CAM_FOCUS_MODE_AUTO: 3766 case CAM_FOCUS_MODE_MACRO: 3767 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 3768 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 3769 mActiveAF = false; 3770 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle); 3771 break; 3772 case CAM_FOCUS_MODE_INFINITY: 3773 case CAM_FOCUS_MODE_FIXED: 3774 case CAM_FOCUS_MODE_EDOF: 3775 default: 3776 LOGD("No ops in focusMode (%d)", focusMode); 3777 break; 3778 } 3779 return rc; 3780 } 3781 3782 /*=========================================================================== 3783 * FUNCTION : processUFDumps 3784 * 3785 * DESCRIPTION: process UF jpeg dumps for refocus support 3786 * 3787 * PARAMETERS : 3788 * @evt : payload of jpeg event, including information about jpeg encoding 3789 * status, jpeg size and so on. 3790 * 3791 * RETURN : int32_t type of status 3792 * NO_ERROR -- success 3793 * none-zero failure code 3794 * 3795 * NOTE : none 3796 *==========================================================================*/ 3797 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt) 3798 { 3799 bool ret = true; 3800 if (mParameters.isUbiRefocus()) { 3801 int index = (int)getOutputImageCount(); 3802 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1)); 3803 char name[FILENAME_MAX]; 3804 3805 camera_memory_t *jpeg_mem = NULL; 3806 omx_jpeg_ouput_buf_t *jpeg_out = NULL; 3807 size_t dataLen; 3808 uint8_t *dataPtr; 3809 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 3810 LOGE("Init PProc Deferred work failed"); 3811 return false; 3812 } 3813 if (!m_postprocessor.getJpegMemOpt()) { 3814 dataLen = evt->out_data.buf_filled_len; 3815 dataPtr = evt->out_data.buf_vaddr; 3816 } else { 3817 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr; 3818 if (!jpeg_out) { 3819 LOGE("Null pointer detected"); 3820 return false; 3821 } 3822 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl; 3823 if (!jpeg_mem) { 3824 LOGE("Null pointer detected"); 3825 return false; 3826 } 3827 dataPtr = (uint8_t *)jpeg_mem->data; 3828 dataLen = jpeg_mem->size; 3829 } 3830 3831 if (allFocusImage) { 3832 snprintf(name, sizeof(name), "AllFocusImage"); 3833 index = -1; 3834 } else { 3835 snprintf(name, sizeof(name), "%d", 0); 3836 } 3837 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg", 3838 dataPtr, dataLen); 3839 LOGD("Dump the image %d %d allFocusImage %d", 3840 getOutputImageCount(), index, allFocusImage); 3841 setOutputImageCount(getOutputImageCount() + 1); 3842 if (!allFocusImage) { 3843 ret = false; 3844 } 3845 } 3846 return ret; 3847 } 3848 3849 /*=========================================================================== 3850 * FUNCTION : unconfigureAdvancedCapture 3851 * 3852 * DESCRIPTION: unconfigure Advanced Capture. 3853 * 3854 * PARAMETERS : none 3855 * 3856 * RETURN : int32_t type of status 3857 * NO_ERROR -- success 3858 * none-zero failure code 3859 *==========================================================================*/ 3860 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture() 3861 { 3862 int32_t rc = NO_ERROR; 3863 3864 if (mAdvancedCaptureConfigured) { 3865 3866 mAdvancedCaptureConfigured = false; 3867 3868 if(mIs3ALocked) { 3869 mParameters.set3ALock(false); 3870 mIs3ALocked = false; 3871 } 3872 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) { 3873 rc = mParameters.setToneMapMode(true, true); 3874 if (rc != NO_ERROR) { 3875 LOGW("Failed to enable tone map during HDR/AEBracketing"); 3876 } 3877 mHDRBracketingEnabled = false; 3878 rc = mParameters.stopAEBracket(); 3879 } else if ((mParameters.isChromaFlashEnabled()) 3880 || (mFlashNeeded && !mLongshotEnabled) 3881 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) 3882 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 3883 rc = mParameters.resetFrameCapture(TRUE); 3884 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 3885 rc = configureAFBracketing(false); 3886 } else if (mParameters.isOptiZoomEnabled()) { 3887 rc = mParameters.setAndCommitZoom(mZoomLevel); 3888 setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY); 3889 } else if (mParameters.isStillMoreEnabled()) { 3890 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 3891 stillmore_config.burst_count = 0; 3892 mParameters.setStillMoreSettings(stillmore_config); 3893 3894 /* If SeeMore is running, it will handle re-enabling tone map */ 3895 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) { 3896 rc = mParameters.setToneMapMode(true, true); 3897 if (rc != NO_ERROR) { 3898 LOGW("Failed to enable tone map during StillMore"); 3899 } 3900 } 3901 3902 /* Re-enable Tintless */ 3903 mParameters.setTintless(true); 3904 } else { 3905 LOGW("No Advanced Capture feature enabled!!"); 3906 rc = BAD_VALUE; 3907 } 3908 } 3909 3910 return rc; 3911 } 3912 3913 /*=========================================================================== 3914 * FUNCTION : configureAdvancedCapture 3915 * 3916 * DESCRIPTION: configure Advanced Capture. 3917 * 3918 * PARAMETERS : none 3919 * 3920 * RETURN : int32_t type of status 3921 * NO_ERROR -- success 3922 * none-zero failure code 3923 *==========================================================================*/ 3924 int32_t QCamera2HardwareInterface::configureAdvancedCapture() 3925 { 3926 LOGH("E"); 3927 int32_t rc = NO_ERROR; 3928 3929 rc = mParameters.checkFeatureConcurrency(); 3930 if (rc != NO_ERROR) { 3931 LOGE("Cannot support Advanced capture modes"); 3932 return rc; 3933 } 3934 3935 setOutputImageCount(0); 3936 mInputCount = 0; 3937 mAdvancedCaptureConfigured = true; 3938 /* Display should be disabled for advanced modes */ 3939 bool bSkipDisplay = true; 3940 3941 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) { 3942 // no Advance capture settings for Aux camera 3943 LOGH("X Secondary Camera, no need to process!! "); 3944 return rc; 3945 } 3946 3947 /* Do not stop display if in stillmore livesnapshot */ 3948 if (mParameters.isStillMoreEnabled() && 3949 mParameters.isSeeMoreEnabled()) { 3950 bSkipDisplay = false; 3951 } 3952 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 3953 rc = configureAFBracketing(); 3954 } else if (mParameters.isOptiZoomEnabled()) { 3955 rc = configureOptiZoom(); 3956 } else if(mParameters.isHDREnabled()) { 3957 rc = configureHDRBracketing(); 3958 if (mHDRBracketingEnabled) { 3959 rc = mParameters.setToneMapMode(false, true); 3960 if (rc != NO_ERROR) { 3961 LOGW("Failed to disable tone map during HDR"); 3962 } 3963 } 3964 } else if (mParameters.isAEBracketEnabled()) { 3965 rc = mParameters.setToneMapMode(false, true); 3966 if (rc != NO_ERROR) { 3967 LOGW("Failed to disable tone map during AEBracketing"); 3968 } 3969 rc = configureAEBracketing(); 3970 } else if (mParameters.isStillMoreEnabled()) { 3971 rc = configureStillMore(); 3972 } else if ((mParameters.isChromaFlashEnabled()) 3973 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) 3974 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 3975 rc = mParameters.configFrameCapture(TRUE); 3976 } else if (mFlashNeeded && !mLongshotEnabled) { 3977 rc = mParameters.configFrameCapture(TRUE); 3978 bSkipDisplay = false; 3979 } else { 3980 LOGH("Advanced Capture feature not enabled!! "); 3981 mAdvancedCaptureConfigured = false; 3982 bSkipDisplay = false; 3983 } 3984 3985 LOGH("Stop preview temporarily for advanced captures"); 3986 setDisplaySkip(bSkipDisplay); 3987 3988 LOGH("X rc = %d", rc); 3989 return rc; 3990 } 3991 3992 /*=========================================================================== 3993 * FUNCTION : configureAFBracketing 3994 * 3995 * DESCRIPTION: configure AF Bracketing. 3996 * 3997 * PARAMETERS : none 3998 * 3999 * RETURN : int32_t type of status 4000 * NO_ERROR -- success 4001 * none-zero failure code 4002 *==========================================================================*/ 4003 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable) 4004 { 4005 LOGH("E"); 4006 int32_t rc = NO_ERROR; 4007 cam_af_bracketing_t *af_bracketing_need; 4008 4009 if (mParameters.isUbiRefocus()) { 4010 af_bracketing_need = 4011 &gCamCapability[mCameraId]->refocus_af_bracketing_need; 4012 } else { 4013 af_bracketing_need = 4014 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need; 4015 } 4016 4017 //Enable AF Bracketing. 4018 cam_af_bracketing_t afBracket; 4019 memset(&afBracket, 0, sizeof(cam_af_bracketing_t)); 4020 afBracket.enable = enable; 4021 afBracket.burst_count = af_bracketing_need->burst_count; 4022 4023 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) { 4024 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i]; 4025 LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]); 4026 } 4027 //Send cmd to backend to set AF Bracketing for Ubi Focus. 4028 rc = mParameters.commitAFBracket(afBracket); 4029 if ( NO_ERROR != rc ) { 4030 LOGE("cannot configure AF bracketing"); 4031 return rc; 4032 } 4033 if (enable) { 4034 mParameters.set3ALock(true); 4035 mIs3ALocked = true; 4036 } 4037 LOGH("X rc = %d", rc); 4038 return rc; 4039 } 4040 4041 /*=========================================================================== 4042 * FUNCTION : configureHDRBracketing 4043 * 4044 * DESCRIPTION: configure HDR Bracketing. 4045 * 4046 * PARAMETERS : none 4047 * 4048 * RETURN : int32_t type of status 4049 * NO_ERROR -- success 4050 * none-zero failure code 4051 *==========================================================================*/ 4052 int32_t QCamera2HardwareInterface::configureHDRBracketing() 4053 { 4054 LOGH("E"); 4055 int32_t rc = NO_ERROR; 4056 4057 cam_hdr_bracketing_info_t& hdrBracketingSetting = 4058 gCamCapability[mCameraId]->hdr_bracketing_setting; 4059 4060 // 'values' should be in "idx1,idx2,idx3,..." format 4061 uint32_t hdrFrameCount = 4062 hdrBracketingSetting.num_frames; 4063 LOGH("HDR values %d, %d frame count: %u", 4064 (int8_t) hdrBracketingSetting.exp_val.values[0], 4065 (int8_t) hdrBracketingSetting.exp_val.values[1], 4066 hdrFrameCount); 4067 4068 // Enable AE Bracketing for HDR 4069 cam_exp_bracketing_t aeBracket; 4070 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t)); 4071 aeBracket.mode = 4072 hdrBracketingSetting.exp_val.mode; 4073 4074 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) { 4075 mHDRBracketingEnabled = true; 4076 } 4077 4078 String8 tmp; 4079 for (uint32_t i = 0; i < hdrFrameCount; i++) { 4080 tmp.appendFormat("%d", 4081 (int8_t) hdrBracketingSetting.exp_val.values[i]); 4082 tmp.append(","); 4083 } 4084 if (mParameters.isHDR1xFrameEnabled() 4085 && mParameters.isHDR1xExtraBufferNeeded()) { 4086 tmp.appendFormat("%d", 0); 4087 tmp.append(","); 4088 } 4089 4090 if( !tmp.isEmpty() && 4091 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) { 4092 //Trim last comma 4093 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH); 4094 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1); 4095 } 4096 4097 LOGH("HDR config values %s", 4098 aeBracket.values); 4099 rc = mParameters.setHDRAEBracket(aeBracket); 4100 if ( NO_ERROR != rc ) { 4101 LOGE("cannot configure HDR bracketing"); 4102 return rc; 4103 } 4104 LOGH("X rc = %d", rc); 4105 return rc; 4106 } 4107 4108 /*=========================================================================== 4109 * FUNCTION : configureAEBracketing 4110 * 4111 * DESCRIPTION: configure AE Bracketing. 4112 * 4113 * PARAMETERS : none 4114 * 4115 * RETURN : int32_t type of status 4116 * NO_ERROR -- success 4117 * none-zero failure code 4118 *==========================================================================*/ 4119 int32_t QCamera2HardwareInterface::configureAEBracketing() 4120 { 4121 LOGH("E"); 4122 int32_t rc = NO_ERROR; 4123 4124 rc = mParameters.setAEBracketing(); 4125 if ( NO_ERROR != rc ) { 4126 LOGE("cannot configure AE bracketing"); 4127 return rc; 4128 } 4129 LOGH("X rc = %d", rc); 4130 return rc; 4131 } 4132 4133 /*=========================================================================== 4134 * FUNCTION : configureOptiZoom 4135 * 4136 * DESCRIPTION: configure Opti Zoom. 4137 * 4138 * PARAMETERS : none 4139 * 4140 * RETURN : int32_t type of status 4141 * NO_ERROR -- success 4142 * none-zero failure code 4143 *==========================================================================*/ 4144 int32_t QCamera2HardwareInterface::configureOptiZoom() 4145 { 4146 int32_t rc = NO_ERROR; 4147 4148 //store current zoom level. 4149 mZoomLevel = mParameters.getParmZoomLevel(); 4150 4151 //set zoom level to 1x; 4152 mParameters.setAndCommitZoom(0); 4153 4154 mParameters.set3ALock(true); 4155 mIs3ALocked = true; 4156 4157 return rc; 4158 } 4159 4160 /*=========================================================================== 4161 * FUNCTION : configureStillMore 4162 * 4163 * DESCRIPTION: configure StillMore. 4164 * 4165 * PARAMETERS : none 4166 * 4167 * RETURN : int32_t type of status 4168 * NO_ERROR -- success 4169 * none-zero failure code 4170 *==========================================================================*/ 4171 int32_t QCamera2HardwareInterface::configureStillMore() 4172 { 4173 int32_t rc = NO_ERROR; 4174 uint8_t burst_cnt = 0; 4175 cam_still_more_t stillmore_config; 4176 cam_still_more_t stillmore_cap; 4177 4178 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */ 4179 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) { 4180 rc = mParameters.setToneMapMode(false, true); 4181 if (rc != NO_ERROR) { 4182 LOGW("Failed to disable tone map during StillMore"); 4183 } 4184 } 4185 4186 /* Lock 3A */ 4187 mParameters.set3ALock(true); 4188 mIs3ALocked = true; 4189 4190 /* Disable Tintless */ 4191 mParameters.setTintless(false); 4192 4193 /* Initialize burst count from capability */ 4194 stillmore_cap = mParameters.getStillMoreCapability(); 4195 burst_cnt = stillmore_cap.max_burst_count; 4196 4197 /* Reconfigure burst count from dynamic scene data */ 4198 cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData(); 4199 if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count && 4200 dynamic_img_data.input_count <= stillmore_cap.max_burst_count) { 4201 burst_cnt = dynamic_img_data.input_count; 4202 } 4203 4204 /* Reconfigure burst count in the case of liveshot */ 4205 if (mParameters.isSeeMoreEnabled()) { 4206 burst_cnt = 1; 4207 } 4208 4209 /* Reconfigure burst count from user input */ 4210 char prop[PROPERTY_VALUE_MAX]; 4211 property_get("persist.camera.imglib.stillmore", prop, "0"); 4212 uint8_t burst_setprop = (uint32_t)atoi(prop); 4213 if (burst_setprop != 0) { 4214 if ((burst_setprop < stillmore_cap.min_burst_count) || 4215 (burst_setprop > stillmore_cap.max_burst_count)) { 4216 burst_cnt = stillmore_cap.max_burst_count; 4217 } else { 4218 burst_cnt = burst_setprop; 4219 } 4220 } 4221 4222 memset(&stillmore_config, 0, sizeof(cam_still_more_t)); 4223 stillmore_config.burst_count = burst_cnt; 4224 mParameters.setStillMoreSettings(stillmore_config); 4225 4226 LOGH("Stillmore burst %d", burst_cnt); 4227 4228 return rc; 4229 } 4230 4231 /*=========================================================================== 4232 * FUNCTION : stopAdvancedCapture 4233 * 4234 * DESCRIPTION: stops advanced capture based on capture type 4235 * 4236 * PARAMETERS : 4237 * @pChannel : channel. 4238 * 4239 * RETURN : int32_t type of status 4240 * NO_ERROR -- success 4241 * none-zero failure code 4242 *==========================================================================*/ 4243 int32_t QCamera2HardwareInterface::stopAdvancedCapture( 4244 QCameraPicChannel *pChannel) 4245 { 4246 LOGH("stop bracketig"); 4247 int32_t rc = NO_ERROR; 4248 4249 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4250 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING); 4251 } else if (mParameters.isChromaFlashEnabled() 4252 || (mFlashNeeded && !mLongshotEnabled) 4253 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) 4254 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4255 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE); 4256 } else if(mParameters.isHDREnabled() 4257 || mParameters.isAEBracketEnabled()) { 4258 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING); 4259 } else if (mParameters.isOptiZoomEnabled()) { 4260 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X); 4261 } else if (mParameters.isStillMoreEnabled()) { 4262 LOGH("stopAdvancedCapture not needed for StillMore"); 4263 } else { 4264 LOGH("No Advanced Capture feature enabled!"); 4265 rc = BAD_VALUE; 4266 } 4267 return rc; 4268 } 4269 4270 /*=========================================================================== 4271 * FUNCTION : startAdvancedCapture 4272 * 4273 * DESCRIPTION: starts advanced capture based on capture type 4274 * 4275 * PARAMETERS : 4276 * @pChannel : channel. 4277 * 4278 * RETURN : int32_t type of status 4279 * NO_ERROR -- success 4280 * none-zero failure code 4281 *==========================================================================*/ 4282 int32_t QCamera2HardwareInterface::startAdvancedCapture( 4283 QCameraPicChannel *pChannel) 4284 { 4285 LOGH("Start bracketing"); 4286 int32_t rc = NO_ERROR; 4287 4288 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 4289 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING); 4290 } else if (mParameters.isOptiZoomEnabled()) { 4291 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X); 4292 } else if (mParameters.isStillMoreEnabled()) { 4293 LOGH("startAdvancedCapture not needed for StillMore"); 4294 } else if (mParameters.isHDREnabled() 4295 || mParameters.isAEBracketEnabled()) { 4296 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING); 4297 } else if (mParameters.isChromaFlashEnabled() 4298 || (mFlashNeeded && !mLongshotEnabled) 4299 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) 4300 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) { 4301 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig(); 4302 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config); 4303 } else { 4304 LOGE("No Advanced Capture feature enabled!"); 4305 rc = BAD_VALUE; 4306 } 4307 return rc; 4308 } 4309 4310 /*=========================================================================== 4311 * FUNCTION : preTakePicture 4312 * 4313 * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary 4314 * 4315 * PARAMETERS : none 4316 * 4317 * RETURN : int32_t type of status 4318 * NO_ERROR -- success 4319 * none-zero failure code 4320 *==========================================================================*/ 4321 int QCamera2HardwareInterface::preTakePicture() 4322 { 4323 int32_t rc = NO_ERROR; 4324 LOGH("E"); 4325 if (mParameters.getRecordingHintValue() == true) { 4326 4327 // Give HWI control to restart preview only in single camera mode. 4328 // In dual-cam mode, this control belongs to muxer. 4329 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) { 4330 LOGH("restart preview if rec hint is true and preview is running"); 4331 stopPreview(); 4332 mParameters.updateRecordingHintValue(FALSE); 4333 // start preview again 4334 rc = preparePreview(); 4335 if (rc == NO_ERROR) { 4336 rc = startPreview(); 4337 if (rc != NO_ERROR) { 4338 unpreparePreview(); 4339 } 4340 } 4341 } 4342 else 4343 { 4344 // For dual cam mode, update the flag mPreviewRestartNeeded to true 4345 // Restart control will be handled by muxer. 4346 mPreviewRestartNeeded = true; 4347 } 4348 } 4349 4350 LOGH("X rc = %d", rc); 4351 return rc; 4352 } 4353 4354 /*=========================================================================== 4355 * FUNCTION : takePicture 4356 * 4357 * DESCRIPTION: take picture impl 4358 * 4359 * PARAMETERS : none 4360 * 4361 * RETURN : int32_t type of status 4362 * NO_ERROR -- success 4363 * none-zero failure code 4364 *==========================================================================*/ 4365 int QCamera2HardwareInterface::takePicture() 4366 { 4367 int rc = NO_ERROR; 4368 4369 // Get total number for snapshots (retro + regular) 4370 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 4371 // Get number of retro-active snapshots 4372 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots(); 4373 LOGH("E"); 4374 4375 //Set rotation value from user settings as Jpeg rotation 4376 //to configure back-end modules. 4377 mParameters.setJpegRotation(mParameters.getRotation()); 4378 4379 // Check if retro-active snapshots are not enabled 4380 if (!isRetroPicture() || !mParameters.isZSLMode()) { 4381 numRetroSnapshots = 0; 4382 LOGH("Reset retro snaphot count to zero"); 4383 } 4384 4385 //Do special configure for advanced capture modes. 4386 rc = configureAdvancedCapture(); 4387 if (rc != NO_ERROR) { 4388 LOGE("Unsupported capture call"); 4389 return rc; 4390 } 4391 4392 if (mAdvancedCaptureConfigured) { 4393 numSnapshots = mParameters.getBurstCountForAdvancedCapture(); 4394 } 4395 LOGI("snap count = %d zsl = %d advanced = %d", 4396 numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured); 4397 4398 if (mParameters.isZSLMode()) { 4399 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 4400 QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel; 4401 if (NULL != pPicChannel) { 4402 4403 if (mParameters.getofflineRAW()) { 4404 startRAWChannel(pPicChannel); 4405 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW]; 4406 if (pPicChannel == NULL) { 4407 LOGE("RAW Channel is NULL in Manual capture mode"); 4408 stopRAWChannel(); 4409 return UNKNOWN_ERROR; 4410 } 4411 } 4412 4413 rc = configureOnlineRotation(*pPicChannel); 4414 if (rc != NO_ERROR) { 4415 LOGE("online rotation failed"); 4416 return rc; 4417 } 4418 4419 // start postprocessor 4420 DeferWorkArgs args; 4421 memset(&args, 0, sizeof(DeferWorkArgs)); 4422 4423 args.pprocArgs = pPicChannel; 4424 4425 // No need to wait for mInitPProcJob here, because it was 4426 // queued in startPreview, and will definitely be processed before 4427 // mReprocJob can begin. 4428 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 4429 args); 4430 if (mReprocJob == 0) { 4431 LOGE("Failure: Unable to start pproc"); 4432 return -ENOMEM; 4433 } 4434 4435 // Check if all preview buffers are mapped before creating 4436 // a jpeg session as preview stream buffers are queried during the same 4437 uint8_t numStreams = pChannel->getNumOfStreams(); 4438 QCameraStream *pStream = NULL; 4439 QCameraStream *pPreviewStream = NULL; 4440 for (uint8_t i = 0 ; i < numStreams ; i++ ) { 4441 pStream = pChannel->getStreamByIndex(i); 4442 if (!pStream) 4443 continue; 4444 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) { 4445 pPreviewStream = pStream; 4446 break; 4447 } 4448 } 4449 if (pPreviewStream != NULL) { 4450 Mutex::Autolock l(mMapLock); 4451 QCameraMemory *pMemory = pStream->getStreamBufs(); 4452 if (!pMemory) { 4453 LOGE("Error!! pMemory is NULL"); 4454 return -ENOMEM; 4455 } 4456 4457 uint8_t waitCnt = 2; 4458 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) { 4459 LOGL(" Waiting for preview buffers to be mapped"); 4460 mMapCond.waitRelative( 4461 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT); 4462 LOGL("Wait completed!!"); 4463 waitCnt--; 4464 } 4465 // If all buffers are not mapped after retries, assert 4466 assert(pMemory->checkIfAllBuffersMapped()); 4467 } else { 4468 assert(pPreviewStream); 4469 } 4470 4471 // Create JPEG session 4472 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 4473 args); 4474 if (mJpegJob == 0) { 4475 LOGE("Failed to queue CREATE_JPEG_SESSION"); 4476 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4477 LOGE("Reprocess Deferred work was failed"); 4478 } 4479 m_postprocessor.stop(); 4480 return -ENOMEM; 4481 } 4482 4483 if (mAdvancedCaptureConfigured) { 4484 rc = startAdvancedCapture(pPicChannel); 4485 if (rc != NO_ERROR) { 4486 LOGE("cannot start zsl advanced capture"); 4487 return rc; 4488 } 4489 } 4490 if (mLongshotEnabled && mPrepSnapRun) { 4491 mCameraHandle->ops->start_zsl_snapshot( 4492 mCameraHandle->camera_handle, 4493 pPicChannel->getMyHandle()); 4494 } 4495 // If frame sync is ON and it is a SECONDARY camera, 4496 // we do not need to send the take picture command to interface 4497 // It will be handled along with PRIMARY camera takePicture request 4498 mm_camera_req_buf_t buf; 4499 memset(&buf, 0x0, sizeof(buf)); 4500 if ((!mParameters.isAdvCamFeaturesEnabled() && 4501 !mFlashNeeded && 4502 !isLongshotEnabled() && 4503 getRelatedCamSyncInfo()->is_frame_sync_enabled) && 4504 (getRelatedCamSyncInfo()->sync_control == 4505 CAM_SYNC_RELATED_SENSORS_ON)) { 4506 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) { 4507 buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF; 4508 buf.num_buf_requested = numSnapshots; 4509 rc = pPicChannel->takePicture(&buf); 4510 if (rc != NO_ERROR) { 4511 LOGE("FS_DBG cannot take ZSL picture, stop pproc"); 4512 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4513 LOGE("Reprocess Deferred work failed"); 4514 return UNKNOWN_ERROR; 4515 } 4516 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 4517 LOGE("Jpeg Deferred work failed"); 4518 return UNKNOWN_ERROR; 4519 } 4520 m_postprocessor.stop(); 4521 return rc; 4522 } 4523 LOGI("PRIMARY camera: send frame sync takePicture!!"); 4524 } 4525 } else { 4526 buf.type = MM_CAMERA_REQ_SUPER_BUF; 4527 buf.num_buf_requested = numSnapshots; 4528 buf.num_retro_buf_requested = numRetroSnapshots; 4529 rc = pPicChannel->takePicture(&buf); 4530 if (rc != NO_ERROR) { 4531 LOGE("cannot take ZSL picture, stop pproc"); 4532 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4533 LOGE("Reprocess Deferred work failed"); 4534 return UNKNOWN_ERROR; 4535 } 4536 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 4537 LOGE("Jpeg Deferred work failed"); 4538 return UNKNOWN_ERROR; 4539 } 4540 m_postprocessor.stop(); 4541 return rc; 4542 } 4543 } 4544 } else { 4545 LOGE("ZSL channel is NULL"); 4546 return UNKNOWN_ERROR; 4547 } 4548 } else { 4549 4550 // start snapshot 4551 if (mParameters.isJpegPictureFormat() || 4552 mParameters.isNV16PictureFormat() || 4553 mParameters.isNV21PictureFormat()) { 4554 4555 //STOP Preview for Non ZSL use case 4556 stopPreview(); 4557 4558 //Config CAPTURE channels 4559 rc = declareSnapshotStreams(); 4560 if (NO_ERROR != rc) { 4561 return rc; 4562 } 4563 4564 rc = addCaptureChannel(); 4565 if ((rc == NO_ERROR) && 4566 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) { 4567 4568 if (!mParameters.getofflineRAW()) { 4569 rc = configureOnlineRotation( 4570 *m_channels[QCAMERA_CH_TYPE_CAPTURE]); 4571 if (rc != NO_ERROR) { 4572 LOGE("online rotation failed"); 4573 delChannel(QCAMERA_CH_TYPE_CAPTURE); 4574 return rc; 4575 } 4576 } 4577 4578 DeferWorkArgs args; 4579 memset(&args, 0, sizeof(DeferWorkArgs)); 4580 4581 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE]; 4582 4583 // No need to wait for mInitPProcJob here, because it was 4584 // queued in startPreview, and will definitely be processed before 4585 // mReprocJob can begin. 4586 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 4587 args); 4588 if (mReprocJob == 0) { 4589 LOGE("Failure: Unable to start pproc"); 4590 return -ENOMEM; 4591 } 4592 4593 // Create JPEG session 4594 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 4595 args); 4596 if (mJpegJob == 0) { 4597 LOGE("Failed to queue CREATE_JPEG_SESSION"); 4598 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4599 LOGE("Reprocess Deferred work was failed"); 4600 } 4601 m_postprocessor.stop(); 4602 return -ENOMEM; 4603 } 4604 4605 // start catpure channel 4606 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start(); 4607 if (rc != NO_ERROR) { 4608 LOGE("cannot start capture channel"); 4609 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4610 LOGE("Reprocess Deferred work failed"); 4611 return UNKNOWN_ERROR; 4612 } 4613 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 4614 LOGE("Jpeg Deferred work failed"); 4615 return UNKNOWN_ERROR; 4616 } 4617 delChannel(QCAMERA_CH_TYPE_CAPTURE); 4618 return rc; 4619 } 4620 4621 QCameraPicChannel *pCapChannel = 4622 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 4623 if (NULL != pCapChannel) { 4624 if (mParameters.isUbiFocusEnabled() || 4625 mParameters.isUbiRefocus() || 4626 mParameters.isChromaFlashEnabled()) { 4627 rc = startAdvancedCapture(pCapChannel); 4628 if (rc != NO_ERROR) { 4629 LOGE("cannot start advanced capture"); 4630 return rc; 4631 } 4632 } 4633 } 4634 if ( mLongshotEnabled ) { 4635 rc = longShot(); 4636 if (NO_ERROR != rc) { 4637 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 4638 LOGE("Reprocess Deferred work failed"); 4639 return UNKNOWN_ERROR; 4640 } 4641 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 4642 LOGE("Jpeg Deferred work failed"); 4643 return UNKNOWN_ERROR; 4644 } 4645 delChannel(QCAMERA_CH_TYPE_CAPTURE); 4646 return rc; 4647 } 4648 } 4649 } else { 4650 LOGE("cannot add capture channel"); 4651 delChannel(QCAMERA_CH_TYPE_CAPTURE); 4652 return rc; 4653 } 4654 } else { 4655 // Stop Preview before taking NZSL snapshot 4656 stopPreview(); 4657 4658 rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]); 4659 if (NO_ERROR != rc) { 4660 LOGE("Raw dimension update failed %d", rc); 4661 return rc; 4662 } 4663 4664 rc = declareSnapshotStreams(); 4665 if (NO_ERROR != rc) { 4666 LOGE("RAW stream info configuration failed %d", rc); 4667 return rc; 4668 } 4669 4670 rc = addChannel(QCAMERA_CH_TYPE_RAW); 4671 if (rc == NO_ERROR) { 4672 // start postprocessor 4673 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 4674 LOGE("Reprocess Deferred work failed"); 4675 return UNKNOWN_ERROR; 4676 } 4677 4678 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 4679 if (rc != NO_ERROR) { 4680 LOGE("cannot start postprocessor"); 4681 delChannel(QCAMERA_CH_TYPE_RAW); 4682 return rc; 4683 } 4684 4685 rc = startChannel(QCAMERA_CH_TYPE_RAW); 4686 if (rc != NO_ERROR) { 4687 LOGE("cannot start raw channel"); 4688 m_postprocessor.stop(); 4689 delChannel(QCAMERA_CH_TYPE_RAW); 4690 return rc; 4691 } 4692 } else { 4693 LOGE("cannot add raw channel"); 4694 return rc; 4695 } 4696 } 4697 } 4698 4699 //When take picture, stop sending preview callbacks to APP 4700 m_stateMachine.setPreviewCallbackNeeded(false); 4701 LOGI("X rc = %d", rc); 4702 return rc; 4703 } 4704 4705 /*=========================================================================== 4706 * FUNCTION : configureOnlineRotation 4707 * 4708 * DESCRIPTION: Configure backend with expected rotation for snapshot stream 4709 * 4710 * PARAMETERS : 4711 * @ch : Channel containing a snapshot stream 4712 * 4713 * RETURN : int32_t type of status 4714 * NO_ERROR -- success 4715 * none-zero failure code 4716 *==========================================================================*/ 4717 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch) 4718 { 4719 int rc = NO_ERROR; 4720 uint32_t streamId = 0; 4721 QCameraStream *pStream = NULL; 4722 4723 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) { 4724 QCameraStream *stream = ch.getStreamByIndex(i); 4725 if ((NULL != stream) && 4726 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType()) 4727 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) { 4728 pStream = stream; 4729 break; 4730 } 4731 } 4732 4733 if (NULL == pStream) { 4734 LOGE("No snapshot stream found!"); 4735 return BAD_VALUE; 4736 } 4737 4738 streamId = pStream->getMyServerID(); 4739 // Update online rotation configuration 4740 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId, 4741 mParameters.getDeviceRotation()); 4742 if (rc != NO_ERROR) { 4743 LOGE("addOnlineRotation failed %d", rc); 4744 return rc; 4745 } 4746 4747 return rc; 4748 } 4749 4750 /*=========================================================================== 4751 * FUNCTION : declareSnapshotStreams 4752 * 4753 * DESCRIPTION: Configure backend with expected snapshot streams 4754 * 4755 * PARAMETERS : none 4756 * 4757 * RETURN : int32_t type of status 4758 * NO_ERROR -- success 4759 * none-zero failure code 4760 *==========================================================================*/ 4761 int32_t QCamera2HardwareInterface::declareSnapshotStreams() 4762 { 4763 int rc = NO_ERROR; 4764 4765 // Update stream info configuration 4766 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false); 4767 if (rc != NO_ERROR) { 4768 LOGE("setStreamConfigure failed %d", rc); 4769 return rc; 4770 } 4771 4772 return rc; 4773 } 4774 4775 /*=========================================================================== 4776 * FUNCTION : longShot 4777 * 4778 * DESCRIPTION: Queue one more ZSL frame 4779 * in the longshot pipe. 4780 * 4781 * PARAMETERS : none 4782 * 4783 * RETURN : int32_t type of status 4784 * NO_ERROR -- success 4785 * none-zero failure code 4786 *==========================================================================*/ 4787 int32_t QCamera2HardwareInterface::longShot() 4788 { 4789 int32_t rc = NO_ERROR; 4790 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 4791 QCameraPicChannel *pChannel = NULL; 4792 4793 if (mParameters.isZSLMode()) { 4794 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 4795 } else { 4796 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 4797 } 4798 4799 if (NULL != pChannel) { 4800 mm_camera_req_buf_t buf; 4801 memset(&buf, 0x0, sizeof(buf)); 4802 buf.type = MM_CAMERA_REQ_SUPER_BUF; 4803 buf.num_buf_requested = numSnapshots; 4804 rc = pChannel->takePicture(&buf); 4805 } else { 4806 LOGE("Capture channel not initialized!"); 4807 rc = NO_INIT; 4808 goto end; 4809 } 4810 4811 end: 4812 return rc; 4813 } 4814 4815 /*=========================================================================== 4816 * FUNCTION : stopCaptureChannel 4817 * 4818 * DESCRIPTION: Stops capture channel 4819 * 4820 * PARAMETERS : 4821 * @destroy : Set to true to stop and delete camera channel. 4822 * Set to false to only stop capture channel. 4823 * 4824 * RETURN : int32_t type of status 4825 * NO_ERROR -- success 4826 * none-zero failure code 4827 *==========================================================================*/ 4828 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy) 4829 { 4830 int rc = NO_ERROR; 4831 if (mParameters.isJpegPictureFormat() || 4832 mParameters.isNV16PictureFormat() || 4833 mParameters.isNV21PictureFormat()) { 4834 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE); 4835 if (destroy && (NO_ERROR == rc)) { 4836 // Destroy camera channel but dont release context 4837 waitDeferredWork(mJpegJob); 4838 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false); 4839 } 4840 } 4841 4842 return rc; 4843 } 4844 4845 /*=========================================================================== 4846 * FUNCTION : cancelPicture 4847 * 4848 * DESCRIPTION: cancel picture impl 4849 * 4850 * PARAMETERS : none 4851 * 4852 * RETURN : int32_t type of status 4853 * NO_ERROR -- success 4854 * none-zero failure code 4855 *==========================================================================*/ 4856 int QCamera2HardwareInterface::cancelPicture() 4857 { 4858 waitDeferredWork(mReprocJob); 4859 waitDeferredWork(mJpegJob); 4860 4861 //stop post processor 4862 m_postprocessor.stop(); 4863 4864 unconfigureAdvancedCapture(); 4865 LOGH("Enable display frames again"); 4866 setDisplaySkip(FALSE); 4867 4868 if (!mLongshotEnabled) { 4869 m_perfLock.lock_rel(); 4870 } 4871 4872 if (mParameters.isZSLMode()) { 4873 QCameraPicChannel *pPicChannel = NULL; 4874 if (mParameters.getofflineRAW()) { 4875 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW]; 4876 } else { 4877 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 4878 } 4879 if (NULL != pPicChannel) { 4880 pPicChannel->cancelPicture(); 4881 stopRAWChannel(); 4882 stopAdvancedCapture(pPicChannel); 4883 } 4884 } else { 4885 4886 // normal capture case 4887 if (mParameters.isJpegPictureFormat() || 4888 mParameters.isNV16PictureFormat() || 4889 mParameters.isNV21PictureFormat()) { 4890 stopChannel(QCAMERA_CH_TYPE_CAPTURE); 4891 delChannel(QCAMERA_CH_TYPE_CAPTURE); 4892 } else { 4893 stopChannel(QCAMERA_CH_TYPE_RAW); 4894 delChannel(QCAMERA_CH_TYPE_RAW); 4895 } 4896 } 4897 4898 return NO_ERROR; 4899 } 4900 4901 /*=========================================================================== 4902 * FUNCTION : captureDone 4903 * 4904 * DESCRIPTION: Function called when the capture is completed before encoding 4905 * 4906 * PARAMETERS : none 4907 * 4908 * RETURN : none 4909 *==========================================================================*/ 4910 void QCamera2HardwareInterface::captureDone() 4911 { 4912 qcamera_sm_internal_evt_payload_t *payload = 4913 (qcamera_sm_internal_evt_payload_t *) 4914 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 4915 if (NULL != payload) { 4916 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 4917 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE; 4918 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 4919 if (rc != NO_ERROR) { 4920 LOGE("processEvt ZSL capture done failed"); 4921 free(payload); 4922 payload = NULL; 4923 } 4924 } else { 4925 LOGE("No memory for ZSL capture done event"); 4926 } 4927 } 4928 4929 /*=========================================================================== 4930 * FUNCTION : Live_Snapshot_thread 4931 * 4932 * DESCRIPTION: Seperate thread for taking live snapshot during recording 4933 * 4934 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 4935 * 4936 * RETURN : none 4937 *==========================================================================*/ 4938 void* Live_Snapshot_thread (void* data) 4939 { 4940 4941 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 4942 if (!hw) { 4943 LOGE("take_picture_thread: NULL camera device"); 4944 return (void *)BAD_VALUE; 4945 } 4946 hw->takeLiveSnapshot_internal(); 4947 return (void* )NULL; 4948 } 4949 4950 /*=========================================================================== 4951 * FUNCTION : Int_Pic_thread 4952 * 4953 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend 4954 * 4955 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 4956 * 4957 * RETURN : none 4958 *==========================================================================*/ 4959 void* Int_Pic_thread (void* data) 4960 { 4961 int rc = NO_ERROR; 4962 4963 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 4964 4965 if (!hw) { 4966 LOGE("take_picture_thread: NULL camera device"); 4967 return (void *)BAD_VALUE; 4968 } 4969 4970 bool JpegMemOpt = false; 4971 char raw_format[PROPERTY_VALUE_MAX]; 4972 4973 memset(raw_format, 0, sizeof(raw_format)); 4974 4975 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]); 4976 if (rc == NO_ERROR) { 4977 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]); 4978 } else { 4979 //Snapshot attempt not successful, we need to do cleanup here 4980 hw->clearIntPendingEvents(); 4981 } 4982 4983 return (void* )NULL; 4984 } 4985 4986 /*=========================================================================== 4987 * FUNCTION : takeLiveSnapshot 4988 * 4989 * DESCRIPTION: take live snapshot during recording 4990 * 4991 * PARAMETERS : none 4992 * 4993 * RETURN : int32_t type of status 4994 * NO_ERROR -- success 4995 * none-zero failure code 4996 *==========================================================================*/ 4997 int QCamera2HardwareInterface::takeLiveSnapshot() 4998 { 4999 int rc = NO_ERROR; 5000 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this); 5001 if (!rc) { 5002 pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap"); 5003 } 5004 return rc; 5005 } 5006 5007 /*=========================================================================== 5008 * FUNCTION : takePictureInternal 5009 * 5010 * DESCRIPTION: take snapshot triggered by backend 5011 * 5012 * PARAMETERS : none 5013 * 5014 * RETURN : int32_t type of status 5015 * NO_ERROR -- success 5016 * none-zero failure code 5017 *==========================================================================*/ 5018 int QCamera2HardwareInterface::takePictureInternal() 5019 { 5020 int rc = NO_ERROR; 5021 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this); 5022 if (!rc) { 5023 pthread_setname_np(mIntPicThread, "CAM_IntPic"); 5024 } 5025 return rc; 5026 } 5027 5028 /*=========================================================================== 5029 * FUNCTION : checkIntPicPending 5030 * 5031 * DESCRIPTION: timed wait for jpeg completion event, and send 5032 * back completion event to backend 5033 * 5034 * PARAMETERS : none 5035 * 5036 * RETURN : none 5037 *==========================================================================*/ 5038 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format) 5039 { 5040 bool bSendToBackend = true; 5041 cam_int_evt_params_t params; 5042 int rc = NO_ERROR; 5043 5044 struct timespec ts; 5045 struct timeval tp; 5046 gettimeofday(&tp, NULL); 5047 ts.tv_sec = tp.tv_sec + 5; 5048 ts.tv_nsec = tp.tv_usec * 1000; 5049 5050 if (true == m_bIntJpegEvtPending || 5051 (true == m_bIntRawEvtPending)) { 5052 //Waiting in HAL for snapshot taken notification 5053 pthread_mutex_lock(&m_int_lock); 5054 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts); 5055 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) { 5056 //Hit a timeout, or some spurious activity 5057 bSendToBackend = false; 5058 } 5059 5060 if (true == m_bIntJpegEvtPending) { 5061 params.event_type = 0; 5062 mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format); 5063 } else if (true == m_bIntRawEvtPending) { 5064 params.event_type = 1; 5065 mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format); 5066 } 5067 pthread_mutex_unlock(&m_int_lock); 5068 5069 if (true == m_bIntJpegEvtPending) { 5070 //Attempting to restart preview after taking JPEG snapshot 5071 lockAPI(); 5072 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 5073 unlockAPI(); 5074 m_postprocessor.setJpegMemOpt(JpegMemOpt); 5075 } else if (true == m_bIntRawEvtPending) { 5076 //Attempting to restart preview after taking RAW snapshot 5077 stopChannel(QCAMERA_CH_TYPE_RAW); 5078 delChannel(QCAMERA_CH_TYPE_RAW); 5079 //restoring the old raw format 5080 property_set("persist.camera.raw.format", raw_format); 5081 } 5082 5083 if (true == bSendToBackend) { 5084 //send event back to server with the file path 5085 params.dim = m_postprocessor.m_dst_dim; 5086 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH); 5087 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH); 5088 params.size = mBackendFileSize; 5089 rc = mParameters.setIntEvent(params); 5090 } 5091 5092 clearIntPendingEvents(); 5093 } 5094 5095 return; 5096 } 5097 5098 /*=========================================================================== 5099 * FUNCTION : takeBackendPic_internal 5100 * 5101 * DESCRIPTION: take snapshot triggered by backend 5102 * 5103 * PARAMETERS : none 5104 * 5105 * RETURN : int32_t type of status 5106 * NO_ERROR -- success 5107 * none-zero failure code 5108 *==========================================================================*/ 5109 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format) 5110 { 5111 int rc = NO_ERROR; 5112 qcamera_api_result_t apiResult; 5113 5114 lockAPI(); 5115 //Set rotation value from user settings as Jpeg rotation 5116 //to configure back-end modules. 5117 mParameters.setJpegRotation(mParameters.getRotation()); 5118 5119 setRetroPicture(0); 5120 /* Prepare snapshot in case LED needs to be flashed */ 5121 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) { 5122 // Start Preparing for normal Frames 5123 LOGH("Start Prepare Snapshot"); 5124 /* Prepare snapshot in case LED needs to be flashed */ 5125 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 5126 if (rc == NO_ERROR) { 5127 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 5128 rc = apiResult.status; 5129 } 5130 LOGH("Prep Snapshot done rc = %d", rc); 5131 mPrepSnapRun = true; 5132 } 5133 unlockAPI(); 5134 5135 if (true == m_bIntJpegEvtPending) { 5136 //Attempting to take JPEG snapshot 5137 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 5138 LOGE("Init PProc Deferred work failed"); 5139 return UNKNOWN_ERROR; 5140 } 5141 *JpegMemOpt = m_postprocessor.getJpegMemOpt(); 5142 m_postprocessor.setJpegMemOpt(false); 5143 5144 /* capture */ 5145 lockAPI(); 5146 LOGH("Capturing internal snapshot"); 5147 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 5148 if (rc == NO_ERROR) { 5149 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 5150 rc = apiResult.status; 5151 } 5152 unlockAPI(); 5153 } else if (true == m_bIntRawEvtPending) { 5154 //Attempting to take RAW snapshot 5155 (void)JpegMemOpt; 5156 stopPreview(); 5157 5158 //getting the existing raw format type 5159 property_get("persist.camera.raw.format", raw_format, "17"); 5160 //setting it to a default know value for this task 5161 property_set("persist.camera.raw.format", "18"); 5162 5163 rc = addChannel(QCAMERA_CH_TYPE_RAW); 5164 if (rc == NO_ERROR) { 5165 // start postprocessor 5166 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 5167 LOGE("Init PProc Deferred work failed"); 5168 return UNKNOWN_ERROR; 5169 } 5170 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 5171 if (rc != NO_ERROR) { 5172 LOGE("cannot start postprocessor"); 5173 delChannel(QCAMERA_CH_TYPE_RAW); 5174 return rc; 5175 } 5176 5177 rc = startChannel(QCAMERA_CH_TYPE_RAW); 5178 if (rc != NO_ERROR) { 5179 LOGE("cannot start raw channel"); 5180 m_postprocessor.stop(); 5181 delChannel(QCAMERA_CH_TYPE_RAW); 5182 return rc; 5183 } 5184 } else { 5185 LOGE("cannot add raw channel"); 5186 return rc; 5187 } 5188 } 5189 5190 return rc; 5191 } 5192 5193 /*=========================================================================== 5194 * FUNCTION : clearIntPendingEvents 5195 * 5196 * DESCRIPTION: clear internal pending events pertaining to backend 5197 * snapshot requests 5198 * 5199 * PARAMETERS : none 5200 * 5201 * RETURN : int32_t type of status 5202 * NO_ERROR -- success 5203 * none-zero failure code 5204 *==========================================================================*/ 5205 void QCamera2HardwareInterface::clearIntPendingEvents() 5206 { 5207 int rc = NO_ERROR; 5208 5209 if (true == m_bIntRawEvtPending) { 5210 preparePreview(); 5211 startPreview(); 5212 } 5213 if (true == m_bIntJpegEvtPending) { 5214 if (false == mParameters.isZSLMode()) { 5215 lockAPI(); 5216 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL); 5217 unlockAPI(); 5218 } 5219 } 5220 5221 pthread_mutex_lock(&m_int_lock); 5222 if (true == m_bIntJpegEvtPending) { 5223 m_bIntJpegEvtPending = false; 5224 } else if (true == m_bIntRawEvtPending) { 5225 m_bIntRawEvtPending = false; 5226 } 5227 pthread_mutex_unlock(&m_int_lock); 5228 return; 5229 } 5230 5231 /*=========================================================================== 5232 * FUNCTION : takeLiveSnapshot_internal 5233 * 5234 * DESCRIPTION: take live snapshot during recording 5235 * 5236 * PARAMETERS : none 5237 * 5238 * RETURN : int32_t type of status 5239 * NO_ERROR -- success 5240 * none-zero failure code 5241 *==========================================================================*/ 5242 int QCamera2HardwareInterface::takeLiveSnapshot_internal() 5243 { 5244 int rc = NO_ERROR; 5245 5246 QCameraChannel *pChannel = NULL; 5247 5248 //Set rotation value from user settings as Jpeg rotation 5249 //to configure back-end modules. 5250 mParameters.setJpegRotation(mParameters.getRotation()); 5251 5252 // Configure advanced capture 5253 rc = configureAdvancedCapture(); 5254 if (rc != NO_ERROR) { 5255 LOGE("Unsupported capture call"); 5256 goto end; 5257 } 5258 5259 if (isLowPowerMode()) { 5260 pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO]; 5261 } else { 5262 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 5263 } 5264 5265 if (NULL == pChannel) { 5266 LOGE("Snapshot/Video channel not initialized"); 5267 rc = NO_INIT; 5268 goto end; 5269 } 5270 5271 DeferWorkArgs args; 5272 memset(&args, 0, sizeof(DeferWorkArgs)); 5273 5274 args.pprocArgs = pChannel; 5275 5276 // No need to wait for mInitPProcJob here, because it was 5277 // queued in startPreview, and will definitely be processed before 5278 // mReprocJob can begin. 5279 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START, 5280 args); 5281 if (mReprocJob == 0) { 5282 LOGE("Failed to queue CMD_DEF_PPROC_START"); 5283 rc = -ENOMEM; 5284 goto end; 5285 } 5286 5287 // Create JPEG session 5288 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION, 5289 args); 5290 if (mJpegJob == 0) { 5291 LOGE("Failed to queue CREATE_JPEG_SESSION"); 5292 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5293 LOGE("Reprocess Deferred work was failed"); 5294 } 5295 m_postprocessor.stop(); 5296 rc = -ENOMEM; 5297 goto end; 5298 } 5299 5300 if (isLowPowerMode()) { 5301 mm_camera_req_buf_t buf; 5302 memset(&buf, 0x0, sizeof(buf)); 5303 buf.type = MM_CAMERA_REQ_SUPER_BUF; 5304 buf.num_buf_requested = 1; 5305 rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf); 5306 goto end; 5307 } 5308 5309 //Disable reprocess for 4K liveshot case 5310 if (!mParameters.is4k2kVideoResolution()) { 5311 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]); 5312 if (rc != NO_ERROR) { 5313 LOGE("online rotation failed"); 5314 if (NO_ERROR != waitDeferredWork(mReprocJob)) { 5315 LOGE("Reprocess Deferred work was failed"); 5316 } 5317 if (NO_ERROR != waitDeferredWork(mJpegJob)) { 5318 LOGE("Jpeg Deferred work was failed"); 5319 } 5320 m_postprocessor.stop(); 5321 return rc; 5322 } 5323 } 5324 5325 if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) { 5326 QCameraStream *pStream = NULL; 5327 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) { 5328 pStream = pChannel->getStreamByIndex(i); 5329 if ((NULL != pStream) && 5330 (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) { 5331 break; 5332 } 5333 } 5334 if (pStream != NULL) { 5335 LOGD("REQUEST_FRAMES event for TNR snapshot"); 5336 cam_stream_parm_buffer_t param; 5337 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 5338 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES; 5339 param.frameRequest.enableStream = 1; 5340 rc = pStream->setParameter(param); 5341 if (rc != NO_ERROR) { 5342 LOGE("Stream Event REQUEST_FRAMES failed"); 5343 } 5344 goto end; 5345 } 5346 } 5347 5348 // start snapshot channel 5349 if ((rc == NO_ERROR) && (NULL != pChannel)) { 5350 // Do not link metadata stream for 4K2k resolution 5351 // as CPP processing would be done on snapshot stream and not 5352 // reprocess stream 5353 if (!mParameters.is4k2kVideoResolution()) { 5354 // Find and try to link a metadata stream from preview channel 5355 QCameraChannel *pMetaChannel = NULL; 5356 QCameraStream *pMetaStream = NULL; 5357 QCameraStream *pPreviewStream = NULL; 5358 5359 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 5360 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 5361 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 5362 QCameraStream *pStream = NULL; 5363 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 5364 pStream = pMetaChannel->getStreamByIndex(i); 5365 if (NULL != pStream) { 5366 if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) { 5367 pMetaStream = pStream; 5368 } else if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) { 5369 pPreviewStream = pStream; 5370 } 5371 } 5372 } 5373 } 5374 5375 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 5376 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 5377 if (NO_ERROR != rc) { 5378 LOGE("Metadata stream link failed %d", rc); 5379 } 5380 } 5381 if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) { 5382 rc = pChannel->linkStream(pMetaChannel, pPreviewStream); 5383 if (NO_ERROR != rc) { 5384 LOGE("Preview stream link failed %d", rc); 5385 } 5386 } 5387 } 5388 rc = pChannel->start(); 5389 } 5390 5391 end: 5392 if (rc != NO_ERROR) { 5393 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 5394 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 5395 } 5396 return rc; 5397 } 5398 5399 /*=========================================================================== 5400 * FUNCTION : cancelLiveSnapshot 5401 * 5402 * DESCRIPTION: cancel current live snapshot request 5403 * 5404 * PARAMETERS : none 5405 * 5406 * RETURN : int32_t type of status 5407 * NO_ERROR -- success 5408 * none-zero failure code 5409 *==========================================================================*/ 5410 int QCamera2HardwareInterface::cancelLiveSnapshot() 5411 { 5412 int rc = NO_ERROR; 5413 5414 unconfigureAdvancedCapture(); 5415 LOGH("Enable display frames again"); 5416 setDisplaySkip(FALSE); 5417 5418 if (!mLongshotEnabled) { 5419 m_perfLock.lock_rel(); 5420 } 5421 5422 if (mLiveSnapshotThread != 0) { 5423 pthread_join(mLiveSnapshotThread,NULL); 5424 mLiveSnapshotThread = 0; 5425 } 5426 5427 //stop post processor 5428 m_postprocessor.stop(); 5429 5430 // stop snapshot channel 5431 if (!mParameters.isTNRSnapshotEnabled()) { 5432 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT); 5433 } else { 5434 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 5435 if (NULL != pChannel) { 5436 QCameraStream *pStream = NULL; 5437 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) { 5438 pStream = pChannel->getStreamByIndex(i); 5439 if ((NULL != pStream) && 5440 (CAM_STREAM_TYPE_SNAPSHOT == 5441 pStream->getMyType())) { 5442 break; 5443 } 5444 } 5445 if (pStream != NULL) { 5446 LOGD("REQUEST_FRAMES event for TNR snapshot"); 5447 cam_stream_parm_buffer_t param; 5448 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 5449 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES; 5450 param.frameRequest.enableStream = 0; 5451 rc = pStream->setParameter(param); 5452 if (rc != NO_ERROR) { 5453 LOGE("Stream Event REQUEST_FRAMES failed"); 5454 } 5455 } 5456 } 5457 } 5458 5459 return rc; 5460 } 5461 5462 /*=========================================================================== 5463 * FUNCTION : putParameters 5464 * 5465 * DESCRIPTION: put parameters string impl 5466 * 5467 * PARAMETERS : 5468 * @parms : parameters string to be released 5469 * 5470 * RETURN : int32_t type of status 5471 * NO_ERROR -- success 5472 * none-zero failure code 5473 *==========================================================================*/ 5474 int QCamera2HardwareInterface::putParameters(char *parms) 5475 { 5476 free(parms); 5477 return NO_ERROR; 5478 } 5479 5480 /*=========================================================================== 5481 * FUNCTION : sendCommand 5482 * 5483 * DESCRIPTION: send command impl 5484 * 5485 * PARAMETERS : 5486 * @command : command to be executed 5487 * @arg1 : optional argument 1 5488 * @arg2 : optional argument 2 5489 * 5490 * RETURN : int32_t type of status 5491 * NO_ERROR -- success 5492 * none-zero failure code 5493 *==========================================================================*/ 5494 int QCamera2HardwareInterface::sendCommand(int32_t command, 5495 __unused int32_t &arg1, __unused int32_t &arg2) 5496 { 5497 int rc = NO_ERROR; 5498 5499 switch (command) { 5500 #ifndef VANILLA_HAL 5501 case CAMERA_CMD_LONGSHOT_ON: 5502 m_perfLock.lock_acq(); 5503 arg1 = arg2 = 0; 5504 // Longshot can only be enabled when image capture 5505 // is not active. 5506 if ( !m_stateMachine.isCaptureRunning() ) { 5507 LOGI("Longshot Enabled"); 5508 mLongshotEnabled = true; 5509 rc = mParameters.setLongshotEnable(mLongshotEnabled); 5510 5511 // Due to recent buffer count optimizations 5512 // ZSL might run with considerably less buffers 5513 // when not in longshot mode. Preview needs to 5514 // restart in this case. 5515 if (isZSLMode() && m_stateMachine.isPreviewRunning()) { 5516 QCameraChannel *pChannel = NULL; 5517 QCameraStream *pSnapStream = NULL; 5518 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 5519 if (NULL != pChannel) { 5520 QCameraStream *pStream = NULL; 5521 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) { 5522 pStream = pChannel->getStreamByIndex(i); 5523 if (pStream != NULL) { 5524 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 5525 pSnapStream = pStream; 5526 break; 5527 } 5528 } 5529 } 5530 if (NULL != pSnapStream) { 5531 uint8_t required = 0; 5532 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT); 5533 if (pSnapStream->getBufferCount() < required) { 5534 // We restart here, to reset the FPS and no 5535 // of buffers as per the requirement of longshot usecase. 5536 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW; 5537 if (getRelatedCamSyncInfo()->sync_control == 5538 CAM_SYNC_RELATED_SENSORS_ON) { 5539 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART; 5540 } 5541 } 5542 } 5543 } 5544 } 5545 // 5546 mPrepSnapRun = false; 5547 mCACDoneReceived = FALSE; 5548 } else { 5549 rc = NO_INIT; 5550 } 5551 break; 5552 case CAMERA_CMD_LONGSHOT_OFF: 5553 m_perfLock.lock_rel(); 5554 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) { 5555 cancelPicture(); 5556 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 5557 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 5558 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) { 5559 mCameraHandle->ops->stop_zsl_snapshot( 5560 mCameraHandle->camera_handle, 5561 pZSLChannel->getMyHandle()); 5562 } 5563 } 5564 mPrepSnapRun = false; 5565 LOGI("Longshot Disabled"); 5566 mLongshotEnabled = false; 5567 rc = mParameters.setLongshotEnable(mLongshotEnabled); 5568 mCACDoneReceived = FALSE; 5569 break; 5570 case CAMERA_CMD_HISTOGRAM_ON: 5571 case CAMERA_CMD_HISTOGRAM_OFF: 5572 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false); 5573 LOGH("Histogram -> %s", 5574 mParameters.isHistogramEnabled() ? "Enabled" : "Disabled"); 5575 break; 5576 #endif 5577 case CAMERA_CMD_START_FACE_DETECTION: 5578 case CAMERA_CMD_STOP_FACE_DETECTION: 5579 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 5580 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 5581 LOGH("FaceDetection -> %s", 5582 mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled"); 5583 break; 5584 #ifndef VANILLA_HAL 5585 case CAMERA_CMD_HISTOGRAM_SEND_DATA: 5586 #endif 5587 default: 5588 rc = NO_ERROR; 5589 break; 5590 } 5591 return rc; 5592 } 5593 5594 /*=========================================================================== 5595 * FUNCTION : registerFaceImage 5596 * 5597 * DESCRIPTION: register face image impl 5598 * 5599 * PARAMETERS : 5600 * @img_ptr : ptr to image buffer 5601 * @config : ptr to config struct about input image info 5602 * @faceID : [OUT] face ID to uniquely identifiy the registered face image 5603 * 5604 * RETURN : int32_t type of status 5605 * NO_ERROR -- success 5606 * none-zero failure code 5607 *==========================================================================*/ 5608 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr, 5609 cam_pp_offline_src_config_t *config, 5610 int32_t &faceID) 5611 { 5612 int rc = NO_ERROR; 5613 faceID = -1; 5614 5615 if (img_ptr == NULL || config == NULL) { 5616 LOGE("img_ptr or config is NULL"); 5617 return BAD_VALUE; 5618 } 5619 5620 // allocate ion memory for source image 5621 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 5622 if (imgBuf == NULL) { 5623 LOGE("Unable to new heap memory obj for image buf"); 5624 return NO_MEMORY; 5625 } 5626 5627 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE); 5628 if (rc < 0) { 5629 LOGE("Unable to allocate heap memory for image buf"); 5630 delete imgBuf; 5631 return NO_MEMORY; 5632 } 5633 5634 void *pBufPtr = imgBuf->getPtr(0); 5635 if (pBufPtr == NULL) { 5636 LOGE("image buf is NULL"); 5637 imgBuf->deallocate(); 5638 delete imgBuf; 5639 return NO_MEMORY; 5640 } 5641 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len); 5642 5643 cam_pp_feature_config_t pp_feature; 5644 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t)); 5645 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE; 5646 QCameraReprocessChannel *pChannel = 5647 addOfflineReprocChannel(*config, pp_feature, NULL, NULL); 5648 5649 if (pChannel == NULL) { 5650 LOGE("fail to add offline reprocess channel"); 5651 imgBuf->deallocate(); 5652 delete imgBuf; 5653 return UNKNOWN_ERROR; 5654 } 5655 5656 rc = pChannel->start(); 5657 if (rc != NO_ERROR) { 5658 LOGE("Cannot start reprocess channel"); 5659 imgBuf->deallocate(); 5660 delete imgBuf; 5661 delete pChannel; 5662 return rc; 5663 } 5664 5665 ssize_t bufSize = imgBuf->getSize(0); 5666 if (BAD_INDEX != bufSize) { 5667 rc = pChannel->doReprocess(imgBuf->getFd(0), (size_t)bufSize, faceID); 5668 } else { 5669 LOGE("Failed to retrieve buffer size (bad index)"); 5670 return UNKNOWN_ERROR; 5671 } 5672 5673 // done with register face image, free imgbuf and delete reprocess channel 5674 imgBuf->deallocate(); 5675 delete imgBuf; 5676 imgBuf = NULL; 5677 pChannel->stop(); 5678 delete pChannel; 5679 pChannel = NULL; 5680 5681 return rc; 5682 } 5683 5684 /*=========================================================================== 5685 * FUNCTION : release 5686 * 5687 * DESCRIPTION: release camera resource impl 5688 * 5689 * PARAMETERS : none 5690 * 5691 * RETURN : int32_t type of status 5692 * NO_ERROR -- success 5693 * none-zero failure code 5694 *==========================================================================*/ 5695 int QCamera2HardwareInterface::release() 5696 { 5697 // stop and delete all channels 5698 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) { 5699 if (m_channels[i] != NULL) { 5700 stopChannel((qcamera_ch_type_enum_t)i); 5701 delChannel((qcamera_ch_type_enum_t)i); 5702 } 5703 } 5704 5705 return NO_ERROR; 5706 } 5707 5708 /*=========================================================================== 5709 * FUNCTION : dump 5710 * 5711 * DESCRIPTION: camera status dump impl 5712 * 5713 * PARAMETERS : 5714 * @fd : fd for the buffer to be dumped with camera status 5715 * 5716 * RETURN : int32_t type of status 5717 * NO_ERROR -- success 5718 * none-zero failure code 5719 *==========================================================================*/ 5720 int QCamera2HardwareInterface::dump(int fd) 5721 { 5722 dprintf(fd, "\n Camera HAL information Begin \n"); 5723 dprintf(fd, "Camera ID: %d \n", mCameraId); 5724 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame); 5725 dprintf(fd, "\n Configuration: %s", mParameters.dump().string()); 5726 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string()); 5727 dprintf(fd, "\n Camera HAL information End \n"); 5728 5729 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the 5730 debug level property */ 5731 mParameters.updateDebugLevel(); 5732 return NO_ERROR; 5733 } 5734 5735 /*=========================================================================== 5736 * FUNCTION : processAPI 5737 * 5738 * DESCRIPTION: process API calls from upper layer 5739 * 5740 * PARAMETERS : 5741 * @api : API to be processed 5742 * @api_payload : ptr to API payload if any 5743 * 5744 * RETURN : int32_t type of status 5745 * NO_ERROR -- success 5746 * none-zero failure code 5747 *==========================================================================*/ 5748 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload) 5749 { 5750 int ret = DEAD_OBJECT; 5751 5752 if (m_smThreadActive) { 5753 ret = m_stateMachine.procAPI(api, api_payload); 5754 } 5755 5756 return ret; 5757 } 5758 5759 /*=========================================================================== 5760 * FUNCTION : processEvt 5761 * 5762 * DESCRIPTION: process Evt from backend via mm-camera-interface 5763 * 5764 * PARAMETERS : 5765 * @evt : event type to be processed 5766 * @evt_payload : ptr to event payload if any 5767 * 5768 * RETURN : int32_t type of status 5769 * NO_ERROR -- success 5770 * none-zero failure code 5771 *==========================================================================*/ 5772 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 5773 { 5774 return m_stateMachine.procEvt(evt, evt_payload); 5775 } 5776 5777 /*=========================================================================== 5778 * FUNCTION : processSyncEvt 5779 * 5780 * DESCRIPTION: process synchronous Evt from backend 5781 * 5782 * PARAMETERS : 5783 * @evt : event type to be processed 5784 * @evt_payload : ptr to event payload if any 5785 * 5786 * RETURN : int32_t type of status 5787 * NO_ERROR -- success 5788 * none-zero failure code 5789 *==========================================================================*/ 5790 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 5791 { 5792 int rc = NO_ERROR; 5793 5794 pthread_mutex_lock(&m_evtLock); 5795 rc = processEvt(evt, evt_payload); 5796 if (rc == NO_ERROR) { 5797 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 5798 while (m_evtResult.request_api != evt) { 5799 pthread_cond_wait(&m_evtCond, &m_evtLock); 5800 } 5801 rc = m_evtResult.status; 5802 } 5803 pthread_mutex_unlock(&m_evtLock); 5804 5805 return rc; 5806 } 5807 5808 /*=========================================================================== 5809 * FUNCTION : evtHandle 5810 * 5811 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events 5812 * 5813 * PARAMETERS : 5814 * @camera_handle : event type to be processed 5815 * @evt : ptr to event 5816 * @user_data : user data ptr 5817 * 5818 * RETURN : none 5819 *==========================================================================*/ 5820 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/, 5821 mm_camera_event_t *evt, 5822 void *user_data) 5823 { 5824 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data; 5825 if (obj && evt) { 5826 mm_camera_event_t *payload = 5827 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t)); 5828 if (NULL != payload) { 5829 *payload = *evt; 5830 //peek into the event, if this is an eztune event from server, 5831 //then we don't need to post it to the SM Qs, we shud directly 5832 //spawn a thread and get the job done (jpeg or raw snapshot) 5833 switch (payload->server_event_type) { 5834 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 5835 //Received JPEG trigger from eztune 5836 if (false == obj->m_bIntJpegEvtPending) { 5837 pthread_mutex_lock(&obj->m_int_lock); 5838 obj->m_bIntJpegEvtPending = true; 5839 pthread_mutex_unlock(&obj->m_int_lock); 5840 obj->takePictureInternal(); 5841 } 5842 free(payload); 5843 break; 5844 case CAM_EVENT_TYPE_INT_TAKE_RAW: 5845 //Received RAW trigger from eztune 5846 if (false == obj->m_bIntRawEvtPending) { 5847 pthread_mutex_lock(&obj->m_int_lock); 5848 obj->m_bIntRawEvtPending = true; 5849 pthread_mutex_unlock(&obj->m_int_lock); 5850 obj->takePictureInternal(); 5851 } 5852 free(payload); 5853 break; 5854 case CAM_EVENT_TYPE_DAEMON_DIED: 5855 { 5856 Mutex::Autolock l(obj->mDefLock); 5857 obj->mDefCond.broadcast(); 5858 LOGH("broadcast mDefCond signal\n"); 5859 } 5860 default: 5861 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload); 5862 break; 5863 } 5864 } 5865 } else { 5866 LOGE("NULL user_data"); 5867 } 5868 } 5869 5870 /*=========================================================================== 5871 * FUNCTION : jpegEvtHandle 5872 * 5873 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events 5874 * 5875 * PARAMETERS : 5876 * @status : status of jpeg job 5877 * @client_hdl: jpeg client handle 5878 * @jobId : jpeg job Id 5879 * @p_ouput : ptr to jpeg output result struct 5880 * @userdata : user data ptr 5881 * 5882 * RETURN : none 5883 *==========================================================================*/ 5884 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status, 5885 uint32_t /*client_hdl*/, 5886 uint32_t jobId, 5887 mm_jpeg_output_t *p_output, 5888 void *userdata) 5889 { 5890 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata; 5891 if (obj) { 5892 qcamera_jpeg_evt_payload_t *payload = 5893 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t)); 5894 if (NULL != payload) { 5895 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t)); 5896 payload->status = status; 5897 payload->jobId = jobId; 5898 if (p_output != NULL) { 5899 payload->out_data = *p_output; 5900 } 5901 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload); 5902 } 5903 } else { 5904 LOGE("NULL user_data"); 5905 } 5906 } 5907 5908 /*=========================================================================== 5909 * FUNCTION : thermalEvtHandle 5910 * 5911 * DESCRIPTION: routine to handle thermal event notification 5912 * 5913 * PARAMETERS : 5914 * @level : thermal level 5915 * @userdata : userdata passed in during registration 5916 * @data : opaque data from thermal client 5917 * 5918 * RETURN : int32_t type of status 5919 * NO_ERROR -- success 5920 * none-zero failure code 5921 *==========================================================================*/ 5922 int QCamera2HardwareInterface::thermalEvtHandle( 5923 qcamera_thermal_level_enum_t *level, void *userdata, void *data) 5924 { 5925 if (!mCameraOpened) { 5926 LOGH("Camera is not opened, no need to handle thermal evt"); 5927 return NO_ERROR; 5928 } 5929 5930 // Make sure thermal events are logged 5931 LOGH("level = %d, userdata = %p, data = %p", 5932 *level, userdata, data); 5933 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY 5934 // becomes an aync call. This also means we can only pass payload 5935 // by value, not by address. 5936 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level); 5937 } 5938 5939 /*=========================================================================== 5940 * FUNCTION : sendEvtNotify 5941 * 5942 * DESCRIPTION: send event notify to notify thread 5943 * 5944 * PARAMETERS : 5945 * @msg_type: msg type to be sent 5946 * @ext1 : optional extension1 5947 * @ext2 : optional extension2 5948 * 5949 * RETURN : int32_t type of status 5950 * NO_ERROR -- success 5951 * none-zero failure code 5952 *==========================================================================*/ 5953 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type, 5954 int32_t ext1, 5955 int32_t ext2) 5956 { 5957 qcamera_callback_argm_t cbArg; 5958 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 5959 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 5960 cbArg.msg_type = msg_type; 5961 cbArg.ext1 = ext1; 5962 cbArg.ext2 = ext2; 5963 return m_cbNotifier.notifyCallback(cbArg); 5964 } 5965 5966 /*=========================================================================== 5967 * FUNCTION : processAEInfo 5968 * 5969 * DESCRIPTION: process AE updates 5970 * 5971 * PARAMETERS : 5972 * @ae_params: current AE parameters 5973 * 5974 * RETURN : None 5975 *==========================================================================*/ 5976 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params) 5977 { 5978 mParameters.updateAEInfo(ae_params); 5979 if (mParameters.isInstantAECEnabled()) { 5980 // Reset Instant AEC info only if instant aec enabled. 5981 bool bResetInstantAec = false; 5982 if (ae_params.settled) { 5983 // If AEC settled, reset instant AEC 5984 bResetInstantAec = true; 5985 } else if ((mParameters.isInstantCaptureEnabled()) && 5986 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) { 5987 // if AEC not settled, and instant capture enabled, 5988 // reset instant AEC only when frame count is 5989 // more or equal to AEC frame bound value. 5990 bResetInstantAec = true; 5991 } else if ((mParameters.isInstantAECEnabled()) && 5992 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) { 5993 // if AEC not settled, and only instant AEC enabled, 5994 // reset instant AEC only when frame count is 5995 // more or equal to AEC skip display frame bound value. 5996 bResetInstantAec = true; 5997 } 5998 5999 if (bResetInstantAec) { 6000 LOGD("setting instant AEC to false"); 6001 mParameters.setInstantAEC(false, true); 6002 mInstantAecFrameCount = 0; 6003 } 6004 } 6005 return NO_ERROR; 6006 } 6007 6008 /*=========================================================================== 6009 * FUNCTION : processFocusPositionInfo 6010 * 6011 * DESCRIPTION: process AF updates 6012 * 6013 * PARAMETERS : 6014 * @cur_pos_info: current lens position 6015 * 6016 * RETURN : None 6017 *==========================================================================*/ 6018 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info) 6019 { 6020 mParameters.updateCurrentFocusPosition(cur_pos_info); 6021 return NO_ERROR; 6022 } 6023 6024 /*=========================================================================== 6025 * FUNCTION : processAutoFocusEvent 6026 * 6027 * DESCRIPTION: process auto focus event 6028 * 6029 * PARAMETERS : 6030 * @focus_data: struct containing auto focus result info 6031 * 6032 * RETURN : int32_t type of status 6033 * NO_ERROR -- success 6034 * none-zero failure code 6035 *==========================================================================*/ 6036 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data) 6037 { 6038 int32_t ret = NO_ERROR; 6039 LOGH("E"); 6040 6041 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) { 6042 // Ignore focus updates 6043 LOGH("X Secondary Camera, no need to process!! "); 6044 return ret; 6045 } 6046 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 6047 LOGH("[AF_DBG] focusMode=%d, focusState=%d", 6048 focusMode, focus_data.focus_state); 6049 6050 switch (focusMode) { 6051 case CAM_FOCUS_MODE_AUTO: 6052 case CAM_FOCUS_MODE_MACRO: 6053 // ignore AF event if AF was already cancelled meanwhile 6054 if (!mActiveAF) { 6055 break; 6056 } 6057 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app 6058 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 6059 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6060 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 6061 mActiveAF = false; // reset the mActiveAF in this special case 6062 break; 6063 } 6064 6065 //while transitioning from CAF->Auto/Macro, we might receive CAF related 6066 //events (PASSIVE_*) due to timing. Ignore such events if any. 6067 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) || 6068 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6069 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) { 6070 break; 6071 } 6072 6073 //This is just an intermediate update to HAL indicating focus is in progress. No need 6074 //to send this event to app. Same applies to INACTIVE state as well. 6075 if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) || 6076 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6077 break; 6078 } 6079 // update focus distance 6080 mParameters.updateFocusDistances(&focus_data.focus_dist); 6081 6082 //flush any old snapshot frames in ZSL Q which are not focused. 6083 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) { 6084 QCameraPicChannel *pZSLChannel = 6085 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 6086 if (NULL != pZSLChannel) { 6087 //flush the zsl-buffer 6088 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx; 6089 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx); 6090 pZSLChannel->flushSuperbuffer(flush_frame_idx); 6091 } 6092 } 6093 6094 //send event to app finally 6095 LOGI("Send AF DOne event to app"); 6096 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 6097 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0); 6098 break; 6099 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 6100 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 6101 6102 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app 6103 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 6104 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) { 6105 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0); 6106 mActiveAF = false; // reset the mActiveAF in this special case 6107 break; 6108 } 6109 6110 //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and 6111 //process/wait for only ACTIVE_* events. 6112 if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6113 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) || 6114 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) { 6115 break; 6116 } 6117 6118 //These are the AF states for which we need to send notification to app in CAF mode. 6119 //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case 6120 //AF is triggered while in CAF mode) 6121 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6122 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) || 6123 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) || 6124 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) { 6125 6126 // update focus distance 6127 mParameters.updateFocusDistances(&focus_data.focus_dist); 6128 6129 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) { 6130 QCameraPicChannel *pZSLChannel = 6131 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 6132 if (NULL != pZSLChannel) { 6133 //flush the zsl-buffer 6134 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx; 6135 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx); 6136 pZSLChannel->flushSuperbuffer(flush_frame_idx); 6137 } 6138 } 6139 6140 if (mActiveAF) { 6141 LOGI("Send AF Done event to app"); 6142 } 6143 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 6144 ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) || 6145 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0); 6146 } 6147 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE, 6148 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0); 6149 break; 6150 case CAM_FOCUS_MODE_INFINITY: 6151 case CAM_FOCUS_MODE_FIXED: 6152 case CAM_FOCUS_MODE_EDOF: 6153 default: 6154 LOGH("no ops for autofocus event in focusmode %d", focusMode); 6155 break; 6156 } 6157 6158 //Reset mActiveAF once we receive focus done event 6159 if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) || 6160 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) { 6161 mActiveAF = false; 6162 } 6163 6164 LOGH("X"); 6165 return ret; 6166 } 6167 6168 /*=========================================================================== 6169 * FUNCTION : processZoomEvent 6170 * 6171 * DESCRIPTION: process zoom event 6172 * 6173 * PARAMETERS : 6174 * @crop_info : crop info as a result of zoom operation 6175 * 6176 * RETURN : int32_t type of status 6177 * NO_ERROR -- success 6178 * none-zero failure code 6179 *==========================================================================*/ 6180 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info) 6181 { 6182 int32_t ret = NO_ERROR; 6183 6184 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 6185 if (m_channels[i] != NULL) { 6186 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info); 6187 } 6188 } 6189 return ret; 6190 } 6191 6192 /*=========================================================================== 6193 * FUNCTION : processZSLCaptureDone 6194 * 6195 * DESCRIPTION: process ZSL capture done events 6196 * 6197 * PARAMETERS : None 6198 * 6199 * RETURN : int32_t type of status 6200 * NO_ERROR -- success 6201 * none-zero failure code 6202 *==========================================================================*/ 6203 int32_t QCamera2HardwareInterface::processZSLCaptureDone() 6204 { 6205 int rc = NO_ERROR; 6206 6207 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) { 6208 rc = unconfigureAdvancedCapture(); 6209 } 6210 6211 return rc; 6212 } 6213 6214 /*=========================================================================== 6215 * FUNCTION : processRetroAECUnlock 6216 * 6217 * DESCRIPTION: process retro burst AEC unlock events 6218 * 6219 * PARAMETERS : None 6220 * 6221 * RETURN : int32_t type of status 6222 * NO_ERROR -- success 6223 * none-zero failure code 6224 *==========================================================================*/ 6225 int32_t QCamera2HardwareInterface::processRetroAECUnlock() 6226 { 6227 int rc = NO_ERROR; 6228 6229 LOGH("LED assisted AF Release AEC Lock"); 6230 rc = mParameters.setAecLock("false"); 6231 if (NO_ERROR != rc) { 6232 LOGE("Error setting AEC lock"); 6233 return rc; 6234 } 6235 6236 rc = mParameters.commitParameters(); 6237 if (NO_ERROR != rc) { 6238 LOGE("Error during camera parameter commit"); 6239 } else { 6240 m_bLedAfAecLock = FALSE; 6241 } 6242 6243 return rc; 6244 } 6245 6246 /*=========================================================================== 6247 * FUNCTION : processHDRData 6248 * 6249 * DESCRIPTION: process HDR scene events 6250 * 6251 * PARAMETERS : 6252 * @hdr_scene : HDR scene event data 6253 * 6254 * RETURN : int32_t type of status 6255 * NO_ERROR -- success 6256 * none-zero failure code 6257 *==========================================================================*/ 6258 int32_t QCamera2HardwareInterface::processHDRData( 6259 __unused cam_asd_hdr_scene_data_t hdr_scene) 6260 { 6261 int rc = NO_ERROR; 6262 6263 #ifndef VANILLA_HAL 6264 if (hdr_scene.is_hdr_scene && 6265 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) && 6266 mParameters.isAutoHDREnabled()) { 6267 m_HDRSceneEnabled = true; 6268 } else { 6269 m_HDRSceneEnabled = false; 6270 } 6271 mParameters.setHDRSceneEnable(m_HDRSceneEnabled); 6272 6273 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) { 6274 6275 size_t data_len = sizeof(int); 6276 size_t buffer_len = 1 *sizeof(int) //meta type 6277 + 1 *sizeof(int) //data len 6278 + 1 *sizeof(int); //data 6279 camera_memory_t *hdrBuffer = mGetMemory(-1, 6280 buffer_len, 6281 1, 6282 mCallbackCookie); 6283 if ( NULL == hdrBuffer ) { 6284 LOGE("Not enough memory for auto HDR data"); 6285 return NO_MEMORY; 6286 } 6287 6288 int *pHDRData = (int *)hdrBuffer->data; 6289 if (pHDRData == NULL) { 6290 LOGE("memory data ptr is NULL"); 6291 return UNKNOWN_ERROR; 6292 } 6293 6294 pHDRData[0] = CAMERA_META_DATA_HDR; 6295 pHDRData[1] = (int)data_len; 6296 pHDRData[2] = m_HDRSceneEnabled; 6297 6298 qcamera_callback_argm_t cbArg; 6299 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6300 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6301 cbArg.msg_type = CAMERA_MSG_META_DATA; 6302 cbArg.data = hdrBuffer; 6303 cbArg.user_data = hdrBuffer; 6304 cbArg.cookie = this; 6305 cbArg.release_cb = releaseCameraMemory; 6306 rc = m_cbNotifier.notifyCallback(cbArg); 6307 if (rc != NO_ERROR) { 6308 LOGE("fail sending auto HDR notification"); 6309 hdrBuffer->release(hdrBuffer); 6310 } 6311 } 6312 6313 LOGH("hdr_scene_data: processHDRData: %d %f", 6314 hdr_scene.is_hdr_scene, 6315 hdr_scene.hdr_confidence); 6316 6317 #endif 6318 return rc; 6319 } 6320 6321 /*=========================================================================== 6322 * FUNCTION : transAwbMetaToParams 6323 * 6324 * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf 6325 * 6326 * PARAMETERS : 6327 * @awb_params : awb params from metadata callback 6328 * 6329 * RETURN : int32_t type of status 6330 * NO_ERROR -- success 6331 * none-zero failure code 6332 *==========================================================================*/ 6333 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params) 6334 { 6335 mParameters.updateAWBParams(awb_params); 6336 return NO_ERROR; 6337 } 6338 6339 /*=========================================================================== 6340 * FUNCTION : processPrepSnapshotDone 6341 * 6342 * DESCRIPTION: process prep snapshot done event 6343 * 6344 * PARAMETERS : 6345 * @prep_snapshot_state : state of prepare snapshot done. In other words, 6346 * i.e. whether need future frames for capture. 6347 * 6348 * RETURN : int32_t type of status 6349 * NO_ERROR -- success 6350 * none-zero failure code 6351 *==========================================================================*/ 6352 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent( 6353 cam_prep_snapshot_state_t prep_snapshot_state) 6354 { 6355 int32_t ret = NO_ERROR; 6356 LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d", 6357 prep_snapshot_state); 6358 if (m_channels[QCAMERA_CH_TYPE_ZSL] && 6359 prep_snapshot_state == NEED_FUTURE_FRAME) { 6360 LOGH("already handled in mm-camera-intf, no ops here"); 6361 if (isRetroPicture()) { 6362 mParameters.setAecLock("true"); 6363 mParameters.commitParameters(); 6364 m_bLedAfAecLock = TRUE; 6365 } 6366 } 6367 return ret; 6368 } 6369 6370 /*=========================================================================== 6371 * FUNCTION : processASDUpdate 6372 * 6373 * DESCRIPTION: process ASD update event 6374 * 6375 * PARAMETERS : 6376 * @scene: selected scene mode 6377 * 6378 * RETURN : int32_t type of status 6379 * NO_ERROR -- success 6380 * none-zero failure code 6381 *==========================================================================*/ 6382 int32_t QCamera2HardwareInterface::processASDUpdate( 6383 __unused cam_asd_decision_t asd_decision) 6384 { 6385 size_t data_len = sizeof(cam_auto_scene_t); 6386 size_t buffer_len = 1 *sizeof(int) //meta type 6387 + 1 *sizeof(int) //data len 6388 + data_len; //data 6389 camera_memory_t *asdBuffer = mGetMemory(-1, 6390 buffer_len, 6391 1, 6392 mCallbackCookie); 6393 if ( NULL == asdBuffer ) { 6394 LOGE("Not enough memory for histogram data"); 6395 return NO_MEMORY; 6396 } 6397 6398 int *pASDData = (int *)asdBuffer->data; 6399 if (pASDData == NULL) { 6400 LOGE("memory data ptr is NULL"); 6401 return UNKNOWN_ERROR; 6402 } 6403 6404 #ifndef VANILLA_HAL 6405 pASDData[0] = CAMERA_META_DATA_ASD; 6406 pASDData[1] = (int)data_len; 6407 pASDData[2] = asd_decision.detected_scene; 6408 6409 qcamera_callback_argm_t cbArg; 6410 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6411 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6412 cbArg.msg_type = CAMERA_MSG_META_DATA; 6413 cbArg.data = asdBuffer; 6414 cbArg.user_data = asdBuffer; 6415 cbArg.cookie = this; 6416 cbArg.release_cb = releaseCameraMemory; 6417 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 6418 if (rc != NO_ERROR) { 6419 LOGE("fail sending notification"); 6420 asdBuffer->release(asdBuffer); 6421 } 6422 #endif 6423 return NO_ERROR; 6424 6425 } 6426 6427 /*=========================================================================== 6428 * FUNCTION : processJpegNotify 6429 * 6430 * DESCRIPTION: process jpeg event 6431 * 6432 * PARAMETERS : 6433 * @jpeg_evt: ptr to jpeg event payload 6434 * 6435 * RETURN : int32_t type of status 6436 * NO_ERROR -- success 6437 * none-zero failure code 6438 *==========================================================================*/ 6439 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt) 6440 { 6441 return m_postprocessor.processJpegEvt(jpeg_evt); 6442 } 6443 6444 /*=========================================================================== 6445 * FUNCTION : lockAPI 6446 * 6447 * DESCRIPTION: lock to process API 6448 * 6449 * PARAMETERS : none 6450 * 6451 * RETURN : none 6452 *==========================================================================*/ 6453 void QCamera2HardwareInterface::lockAPI() 6454 { 6455 pthread_mutex_lock(&m_lock); 6456 } 6457 6458 /*=========================================================================== 6459 * FUNCTION : waitAPIResult 6460 * 6461 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will 6462 * return only cerntain API event type arrives 6463 * 6464 * PARAMETERS : 6465 * @api_evt : API event type 6466 * 6467 * RETURN : none 6468 *==========================================================================*/ 6469 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt, 6470 qcamera_api_result_t *apiResult) 6471 { 6472 LOGD("wait for API result of evt (%d)", api_evt); 6473 int resultReceived = 0; 6474 while (!resultReceived) { 6475 pthread_cond_wait(&m_cond, &m_lock); 6476 if (m_apiResultList != NULL) { 6477 api_result_list *apiResultList = m_apiResultList; 6478 api_result_list *apiResultListPrevious = m_apiResultList; 6479 while (apiResultList != NULL) { 6480 if (apiResultList->result.request_api == api_evt) { 6481 resultReceived = 1; 6482 *apiResult = apiResultList->result; 6483 apiResultListPrevious->next = apiResultList->next; 6484 if (apiResultList == m_apiResultList) { 6485 m_apiResultList = apiResultList->next; 6486 } 6487 free(apiResultList); 6488 break; 6489 } 6490 else { 6491 apiResultListPrevious = apiResultList; 6492 apiResultList = apiResultList->next; 6493 } 6494 } 6495 } 6496 } 6497 LOGD("return (%d) from API result wait for evt (%d)", 6498 apiResult->status, api_evt); 6499 } 6500 6501 6502 /*=========================================================================== 6503 * FUNCTION : unlockAPI 6504 * 6505 * DESCRIPTION: API processing is done, unlock 6506 * 6507 * PARAMETERS : none 6508 * 6509 * RETURN : none 6510 *==========================================================================*/ 6511 void QCamera2HardwareInterface::unlockAPI() 6512 { 6513 pthread_mutex_unlock(&m_lock); 6514 } 6515 6516 /*=========================================================================== 6517 * FUNCTION : signalAPIResult 6518 * 6519 * DESCRIPTION: signal condition viarable that cerntain API event type arrives 6520 * 6521 * PARAMETERS : 6522 * @result : API result 6523 * 6524 * RETURN : none 6525 *==========================================================================*/ 6526 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result) 6527 { 6528 6529 pthread_mutex_lock(&m_lock); 6530 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list)); 6531 if (apiResult == NULL) { 6532 LOGE("ERROR: malloc for api result failed, Result will not be sent"); 6533 goto malloc_failed; 6534 } 6535 apiResult->result = *result; 6536 apiResult->next = NULL; 6537 if (m_apiResultList == NULL) m_apiResultList = apiResult; 6538 else { 6539 api_result_list *apiResultList = m_apiResultList; 6540 while(apiResultList->next != NULL) apiResultList = apiResultList->next; 6541 apiResultList->next = apiResult; 6542 } 6543 malloc_failed: 6544 pthread_cond_broadcast(&m_cond); 6545 pthread_mutex_unlock(&m_lock); 6546 } 6547 6548 /*=========================================================================== 6549 * FUNCTION : signalEvtResult 6550 * 6551 * DESCRIPTION: signal condition variable that certain event was processed 6552 * 6553 * PARAMETERS : 6554 * @result : Event result 6555 * 6556 * RETURN : none 6557 *==========================================================================*/ 6558 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result) 6559 { 6560 pthread_mutex_lock(&m_evtLock); 6561 m_evtResult = *result; 6562 pthread_cond_signal(&m_evtCond); 6563 pthread_mutex_unlock(&m_evtLock); 6564 } 6565 6566 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel) 6567 { 6568 int32_t rc = NO_ERROR; 6569 cam_dimension_t str_dim,max_dim; 6570 QCameraChannel *pChannel; 6571 6572 max_dim.width = 0; 6573 max_dim.height = 0; 6574 6575 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) { 6576 if (m_channels[j] != NULL) { 6577 pChannel = m_channels[j]; 6578 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) { 6579 QCameraStream *pStream = pChannel->getStreamByIndex(i); 6580 if (pStream != NULL) { 6581 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 6582 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) { 6583 continue; 6584 } 6585 pStream->getFrameDimension(str_dim); 6586 if (str_dim.width > max_dim.width) { 6587 max_dim.width = str_dim.width; 6588 } 6589 if (str_dim.height > max_dim.height) { 6590 max_dim.height = str_dim.height; 6591 } 6592 } 6593 } 6594 } 6595 } 6596 6597 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) { 6598 QCameraStream *pStream = curChannel->getStreamByIndex(i); 6599 if (pStream != NULL) { 6600 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 6601 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) { 6602 continue; 6603 } 6604 pStream->getFrameDimension(str_dim); 6605 if (str_dim.width > max_dim.width) { 6606 max_dim.width = str_dim.width; 6607 } 6608 if (str_dim.height > max_dim.height) { 6609 max_dim.height = str_dim.height; 6610 } 6611 } 6612 } 6613 rc = mParameters.updateRAW(max_dim); 6614 return rc; 6615 } 6616 /*=========================================================================== 6617 * FUNCTION : addStreamToChannel 6618 * 6619 * DESCRIPTION: add a stream into a channel 6620 * 6621 * PARAMETERS : 6622 * @pChannel : ptr to channel obj 6623 * @streamType : type of stream to be added 6624 * @streamCB : callback of stream 6625 * @userData : user data ptr to callback 6626 * 6627 * RETURN : int32_t type of status 6628 * NO_ERROR -- success 6629 * none-zero failure code 6630 *==========================================================================*/ 6631 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel, 6632 cam_stream_type_t streamType, 6633 stream_cb_routine streamCB, 6634 void *userData) 6635 { 6636 int32_t rc = NO_ERROR; 6637 6638 if (streamType == CAM_STREAM_TYPE_RAW) { 6639 prepareRawStream(pChannel); 6640 } 6641 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType); 6642 if (pStreamInfo == NULL) { 6643 LOGE("no mem for stream info buf"); 6644 return NO_MEMORY; 6645 } 6646 uint8_t minStreamBufNum = getBufNumRequired(streamType); 6647 bool bDynAllocBuf = false; 6648 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) { 6649 bDynAllocBuf = true; 6650 } 6651 6652 cam_padding_info_t padding_info; 6653 if (streamType == CAM_STREAM_TYPE_ANALYSIS) { 6654 padding_info = 6655 gCamCapability[mCameraId]->analysis_padding_info; 6656 } else { 6657 padding_info = 6658 gCamCapability[mCameraId]->padding_info; 6659 if (streamType == CAM_STREAM_TYPE_PREVIEW) { 6660 padding_info.width_padding = mSurfaceStridePadding; 6661 padding_info.height_padding = CAM_PAD_TO_2; 6662 } 6663 if((!needReprocess()) 6664 || (streamType != CAM_STREAM_TYPE_SNAPSHOT) 6665 || (!mParameters.isLLNoiseEnabled())) { 6666 padding_info.offset_info.offset_x = 0; 6667 padding_info.offset_info.offset_y = 0; 6668 } 6669 } 6670 6671 bool deferAllocation = needDeferred(streamType); 6672 LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d", 6673 deferAllocation, bDynAllocBuf, streamType); 6674 rc = pChannel->addStream(*this, 6675 pStreamInfo, 6676 NULL, 6677 minStreamBufNum, 6678 &padding_info, 6679 streamCB, userData, 6680 bDynAllocBuf, 6681 deferAllocation); 6682 6683 if (rc != NO_ERROR) { 6684 LOGE("add stream type (%d) failed, ret = %d", 6685 streamType, rc); 6686 return rc; 6687 } 6688 6689 return rc; 6690 } 6691 6692 /*=========================================================================== 6693 * FUNCTION : addPreviewChannel 6694 * 6695 * DESCRIPTION: add a preview channel that contains a preview stream 6696 * 6697 * PARAMETERS : none 6698 * 6699 * RETURN : int32_t type of status 6700 * NO_ERROR -- success 6701 * none-zero failure code 6702 *==========================================================================*/ 6703 int32_t QCamera2HardwareInterface::addPreviewChannel() 6704 { 6705 int32_t rc = NO_ERROR; 6706 QCameraChannel *pChannel = NULL; 6707 char value[PROPERTY_VALUE_MAX]; 6708 bool raw_yuv = false; 6709 6710 6711 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 6712 // if we had preview channel before, delete it first 6713 delete m_channels[QCAMERA_CH_TYPE_PREVIEW]; 6714 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL; 6715 } 6716 6717 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 6718 mCameraHandle->ops); 6719 if (NULL == pChannel) { 6720 LOGE("no mem for preview channel"); 6721 return NO_MEMORY; 6722 } 6723 6724 // preview only channel, don't need bundle attr and cb 6725 rc = pChannel->init(NULL, NULL, NULL); 6726 if (rc != NO_ERROR) { 6727 LOGE("init preview channel failed, ret = %d", rc); 6728 return rc; 6729 } 6730 6731 // meta data stream always coexists with preview if applicable 6732 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 6733 metadata_stream_cb_routine, this); 6734 if (rc != NO_ERROR) { 6735 LOGE("add metadata stream failed, ret = %d", rc); 6736 return rc; 6737 } 6738 6739 if (isRdiMode()) { 6740 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 6741 rdi_mode_stream_cb_routine, this); 6742 } else { 6743 if (isNoDisplayMode()) { 6744 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 6745 nodisplay_preview_stream_cb_routine, this); 6746 } else { 6747 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 6748 preview_stream_cb_routine, this); 6749 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 6750 synchronous_stream_cb_routine); 6751 } 6752 } 6753 6754 if (((mParameters.fdModeInVideo()) 6755 || (mParameters.getDcrf() == true) 6756 || (mParameters.getRecordingHintValue() != true)) 6757 && (!mParameters.isSecureMode())) { 6758 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 6759 NULL, this); 6760 if (rc != NO_ERROR) { 6761 LOGE("add Analysis stream failed, ret = %d", rc); 6762 return rc; 6763 } 6764 } 6765 6766 property_get("persist.camera.raw_yuv", value, "0"); 6767 raw_yuv = atoi(value) > 0 ? true : false; 6768 if ( raw_yuv ) { 6769 rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW, 6770 preview_raw_stream_cb_routine,this); 6771 if ( rc != NO_ERROR ) { 6772 LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc); 6773 delete pChannel; 6774 return rc; 6775 } 6776 } 6777 6778 if (rc != NO_ERROR) { 6779 LOGE("add preview stream failed, ret = %d", rc); 6780 delete pChannel; 6781 return rc; 6782 } 6783 6784 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel; 6785 return rc; 6786 } 6787 6788 /*=========================================================================== 6789 * FUNCTION : addVideoChannel 6790 * 6791 * DESCRIPTION: add a video channel that contains a video stream 6792 * 6793 * PARAMETERS : none 6794 * 6795 * RETURN : int32_t type of status 6796 * NO_ERROR -- success 6797 * none-zero failure code 6798 *==========================================================================*/ 6799 int32_t QCamera2HardwareInterface::addVideoChannel() 6800 { 6801 int32_t rc = NO_ERROR; 6802 QCameraVideoChannel *pChannel = NULL; 6803 6804 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) { 6805 // if we had video channel before, delete it first 6806 delete m_channels[QCAMERA_CH_TYPE_VIDEO]; 6807 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL; 6808 } 6809 6810 pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle, 6811 mCameraHandle->ops); 6812 if (NULL == pChannel) { 6813 LOGE("no mem for video channel"); 6814 return NO_MEMORY; 6815 } 6816 6817 if (isLowPowerMode()) { 6818 mm_camera_channel_attr_t attr; 6819 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 6820 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 6821 attr.look_back = 0; //wait for future frame for liveshot 6822 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 6823 attr.water_mark = 1; //hold min buffers possible in Q 6824 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 6825 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this); 6826 } else { 6827 // preview only channel, don't need bundle attr and cb 6828 rc = pChannel->init(NULL, NULL, NULL); 6829 } 6830 6831 if (rc != 0) { 6832 LOGE("init video channel failed, ret = %d", rc); 6833 delete pChannel; 6834 return rc; 6835 } 6836 6837 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO, 6838 video_stream_cb_routine, this); 6839 if (rc != NO_ERROR) { 6840 LOGE("add video stream failed, ret = %d", rc); 6841 delete pChannel; 6842 return rc; 6843 } 6844 6845 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel; 6846 return rc; 6847 } 6848 6849 /*=========================================================================== 6850 * FUNCTION : addSnapshotChannel 6851 * 6852 * DESCRIPTION: add a snapshot channel that contains a snapshot stream 6853 * 6854 * PARAMETERS : none 6855 * 6856 * RETURN : int32_t type of status 6857 * NO_ERROR -- success 6858 * none-zero failure code 6859 * NOTE : Add this channel for live snapshot usecase. Regular capture will 6860 * use addCaptureChannel. 6861 *==========================================================================*/ 6862 int32_t QCamera2HardwareInterface::addSnapshotChannel() 6863 { 6864 int32_t rc = NO_ERROR; 6865 QCameraChannel *pChannel = NULL; 6866 6867 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) { 6868 // if we had ZSL channel before, delete it first 6869 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 6870 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL; 6871 } 6872 6873 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 6874 mCameraHandle->ops); 6875 if (NULL == pChannel) { 6876 LOGE("no mem for snapshot channel"); 6877 return NO_MEMORY; 6878 } 6879 6880 mm_camera_channel_attr_t attr; 6881 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 6882 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 6883 attr.look_back = 0; //wait for future frame for liveshot 6884 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 6885 attr.water_mark = 1; //hold min buffers possible in Q 6886 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 6887 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW; 6888 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this); 6889 if (rc != NO_ERROR) { 6890 LOGE("init snapshot channel failed, ret = %d", rc); 6891 delete pChannel; 6892 return rc; 6893 } 6894 6895 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 6896 NULL, NULL); 6897 if (rc != NO_ERROR) { 6898 LOGE("add snapshot stream failed, ret = %d", rc); 6899 delete pChannel; 6900 return rc; 6901 } 6902 6903 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel; 6904 return rc; 6905 } 6906 6907 /*=========================================================================== 6908 * FUNCTION : addRawChannel 6909 * 6910 * DESCRIPTION: add a raw channel that contains a raw image stream 6911 * 6912 * PARAMETERS : none 6913 * 6914 * RETURN : int32_t type of status 6915 * NO_ERROR -- success 6916 * none-zero failure code 6917 *==========================================================================*/ 6918 int32_t QCamera2HardwareInterface::addRawChannel() 6919 { 6920 int32_t rc = NO_ERROR; 6921 QCameraChannel *pChannel = NULL; 6922 6923 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) { 6924 // if we had raw channel before, delete it first 6925 delete m_channels[QCAMERA_CH_TYPE_RAW]; 6926 m_channels[QCAMERA_CH_TYPE_RAW] = NULL; 6927 } 6928 6929 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 6930 mCameraHandle->ops); 6931 if (NULL == pChannel) { 6932 LOGE("no mem for raw channel"); 6933 return NO_MEMORY; 6934 } 6935 6936 if (mParameters.getofflineRAW()) { 6937 mm_camera_channel_attr_t attr; 6938 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 6939 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 6940 attr.look_back = mParameters.getZSLBackLookCount(); 6941 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 6942 attr.water_mark = 1; 6943 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 6944 rc = pChannel->init(&attr, raw_channel_cb_routine, this); 6945 if (rc != NO_ERROR) { 6946 LOGE("init RAW channel failed, ret = %d", rc); 6947 delete pChannel; 6948 return rc; 6949 } 6950 } else { 6951 rc = pChannel->init(NULL, NULL, NULL); 6952 if (rc != NO_ERROR) { 6953 LOGE("init raw channel failed, ret = %d", rc); 6954 delete pChannel; 6955 return rc; 6956 } 6957 } 6958 6959 if (!mParameters.isZSLMode()) { 6960 // meta data stream always coexists with snapshot in regular RAW capture case 6961 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 6962 metadata_stream_cb_routine, this); 6963 if (rc != NO_ERROR) { 6964 LOGE("add metadata stream failed, ret = %d", rc); 6965 delete pChannel; 6966 return rc; 6967 } 6968 } 6969 6970 if (mParameters.getofflineRAW()) { 6971 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 6972 NULL, this); 6973 } else { 6974 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 6975 raw_stream_cb_routine, this); 6976 } 6977 if (rc != NO_ERROR) { 6978 LOGE("add snapshot stream failed, ret = %d", rc); 6979 delete pChannel; 6980 return rc; 6981 } 6982 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel; 6983 return rc; 6984 } 6985 6986 /*=========================================================================== 6987 * FUNCTION : addZSLChannel 6988 * 6989 * DESCRIPTION: add a ZSL channel that contains a preview stream and 6990 * a snapshot stream 6991 * 6992 * PARAMETERS : none 6993 * 6994 * RETURN : int32_t type of status 6995 * NO_ERROR -- success 6996 * none-zero failure code 6997 *==========================================================================*/ 6998 int32_t QCamera2HardwareInterface::addZSLChannel() 6999 { 7000 int32_t rc = NO_ERROR; 7001 QCameraPicChannel *pChannel = NULL; 7002 char value[PROPERTY_VALUE_MAX]; 7003 bool raw_yuv = false; 7004 7005 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) { 7006 // if we had ZSL channel before, delete it first 7007 delete m_channels[QCAMERA_CH_TYPE_ZSL]; 7008 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL; 7009 } 7010 7011 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle, 7012 mCameraHandle->ops); 7013 if (NULL == pChannel) { 7014 LOGE("no mem for ZSL channel"); 7015 return NO_MEMORY; 7016 } 7017 7018 // ZSL channel, init with bundle attr and cb 7019 mm_camera_channel_attr_t attr; 7020 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7021 if (mParameters.isSceneSelectionEnabled()) { 7022 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 7023 } else { 7024 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7025 } 7026 attr.look_back = mParameters.getZSLBackLookCount(); 7027 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 7028 if (mParameters.isOEMFeatEnabled()) { 7029 attr.post_frame_skip++; 7030 } 7031 attr.water_mark = mParameters.getZSLQueueDepth(); 7032 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7033 attr.user_expected_frame_id = 7034 mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0; 7035 7036 //Enabled matched queue 7037 if (getRelatedCamSyncInfo()->is_frame_sync_enabled) { 7038 LOGH("Enabling frame sync for dual camera, camera Id: %d", 7039 mCameraId); 7040 attr.enable_frame_sync = 1; 7041 } 7042 rc = pChannel->init(&attr, 7043 zsl_channel_cb, 7044 this); 7045 if (rc != 0) { 7046 LOGE("init ZSL channel failed, ret = %d", rc); 7047 delete pChannel; 7048 return rc; 7049 } 7050 7051 // meta data stream always coexists with preview if applicable 7052 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7053 metadata_stream_cb_routine, this); 7054 if (rc != NO_ERROR) { 7055 LOGE("add metadata stream failed, ret = %d", rc); 7056 delete pChannel; 7057 return rc; 7058 } 7059 7060 if (isNoDisplayMode()) { 7061 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7062 nodisplay_preview_stream_cb_routine, this); 7063 } else { 7064 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7065 preview_stream_cb_routine, this); 7066 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 7067 synchronous_stream_cb_routine); 7068 } 7069 if (rc != NO_ERROR) { 7070 LOGE("add preview stream failed, ret = %d", rc); 7071 delete pChannel; 7072 return rc; 7073 } 7074 7075 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 7076 NULL, this); 7077 if (rc != NO_ERROR) { 7078 LOGE("add snapshot stream failed, ret = %d", rc); 7079 delete pChannel; 7080 return rc; 7081 } 7082 7083 if (!mParameters.isSecureMode()) { 7084 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 7085 NULL, this); 7086 if (rc != NO_ERROR) { 7087 LOGE("add Analysis stream failed, ret = %d", rc); 7088 delete pChannel; 7089 return rc; 7090 } 7091 } 7092 7093 property_get("persist.camera.raw_yuv", value, "0"); 7094 raw_yuv = atoi(value) > 0 ? true : false; 7095 if (raw_yuv) { 7096 rc = addStreamToChannel(pChannel, 7097 CAM_STREAM_TYPE_RAW, 7098 NULL, 7099 this); 7100 if (rc != NO_ERROR) { 7101 LOGE("add raw stream failed, ret = %d", rc); 7102 delete pChannel; 7103 return rc; 7104 } 7105 } 7106 7107 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel; 7108 return rc; 7109 } 7110 7111 /*=========================================================================== 7112 * FUNCTION : addCaptureChannel 7113 * 7114 * DESCRIPTION: add a capture channel that contains a snapshot stream 7115 * and a postview stream 7116 * 7117 * PARAMETERS : none 7118 * 7119 * RETURN : int32_t type of status 7120 * NO_ERROR -- success 7121 * none-zero failure code 7122 * NOTE : Add this channel for regular capture usecase. 7123 * For Live snapshot usecase, use addSnapshotChannel. 7124 *==========================================================================*/ 7125 int32_t QCamera2HardwareInterface::addCaptureChannel() 7126 { 7127 int32_t rc = NO_ERROR; 7128 QCameraPicChannel *pChannel = NULL; 7129 char value[PROPERTY_VALUE_MAX]; 7130 bool raw_yuv = false; 7131 7132 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) { 7133 delete m_channels[QCAMERA_CH_TYPE_CAPTURE]; 7134 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL; 7135 } 7136 7137 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle, 7138 mCameraHandle->ops); 7139 if (NULL == pChannel) { 7140 LOGE("no mem for capture channel"); 7141 return NO_MEMORY; 7142 } 7143 7144 // Capture channel, only need snapshot and postview streams start together 7145 mm_camera_channel_attr_t attr; 7146 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7147 if ( mLongshotEnabled ) { 7148 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 7149 attr.look_back = mParameters.getZSLBackLookCount(); 7150 attr.water_mark = mParameters.getZSLQueueDepth(); 7151 } else { 7152 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 7153 } 7154 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7155 7156 rc = pChannel->init(&attr, 7157 capture_channel_cb_routine, 7158 this); 7159 if (rc != NO_ERROR) { 7160 LOGE("init capture channel failed, ret = %d", rc); 7161 return rc; 7162 } 7163 7164 // meta data stream always coexists with snapshot in regular capture case 7165 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7166 metadata_stream_cb_routine, this); 7167 if (rc != NO_ERROR) { 7168 LOGE("add metadata stream failed, ret = %d", rc); 7169 return rc; 7170 } 7171 7172 if (!mLongshotEnabled) { 7173 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW, 7174 NULL, this); 7175 7176 if (rc != NO_ERROR) { 7177 LOGE("add postview stream failed, ret = %d", rc); 7178 return rc; 7179 } 7180 } else { 7181 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 7182 preview_stream_cb_routine, this); 7183 7184 if (rc != NO_ERROR) { 7185 LOGE("add preview stream failed, ret = %d", rc); 7186 return rc; 7187 } 7188 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, 7189 synchronous_stream_cb_routine); 7190 } 7191 7192 if (!mParameters.getofflineRAW()) { 7193 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 7194 NULL, this); 7195 if (rc != NO_ERROR) { 7196 LOGE("add snapshot stream failed, ret = %d", rc); 7197 return rc; 7198 } 7199 } 7200 7201 stream_cb_routine stream_cb = NULL; 7202 property_get("persist.camera.raw_yuv", value, "0"); 7203 raw_yuv = atoi(value) > 0 ? true : false; 7204 7205 if (raw_yuv) { 7206 stream_cb = snapshot_raw_stream_cb_routine; 7207 } 7208 7209 if ((raw_yuv) || (mParameters.getofflineRAW())) { 7210 rc = addStreamToChannel(pChannel, 7211 CAM_STREAM_TYPE_RAW, stream_cb, this); 7212 if (rc != NO_ERROR) { 7213 LOGE("add raw stream failed, ret = %d", rc); 7214 return rc; 7215 } 7216 } 7217 7218 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel; 7219 return rc; 7220 } 7221 7222 /*=========================================================================== 7223 * FUNCTION : addMetaDataChannel 7224 * 7225 * DESCRIPTION: add a meta data channel that contains a metadata stream 7226 * 7227 * PARAMETERS : none 7228 * 7229 * RETURN : int32_t type of status 7230 * NO_ERROR -- success 7231 * none-zero failure code 7232 *==========================================================================*/ 7233 int32_t QCamera2HardwareInterface::addMetaDataChannel() 7234 { 7235 int32_t rc = NO_ERROR; 7236 QCameraChannel *pChannel = NULL; 7237 7238 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) { 7239 delete m_channels[QCAMERA_CH_TYPE_METADATA]; 7240 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL; 7241 } 7242 7243 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 7244 mCameraHandle->ops); 7245 if (NULL == pChannel) { 7246 LOGE("no mem for metadata channel"); 7247 return NO_MEMORY; 7248 } 7249 7250 rc = pChannel->init(NULL, 7251 NULL, 7252 NULL); 7253 if (rc != NO_ERROR) { 7254 LOGE("init metadata channel failed, ret = %d", rc); 7255 delete pChannel; 7256 return rc; 7257 } 7258 7259 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 7260 metadata_stream_cb_routine, this); 7261 if (rc != NO_ERROR) { 7262 LOGE("add metadata stream failed, ret = %d", rc); 7263 delete pChannel; 7264 return rc; 7265 } 7266 7267 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel; 7268 return rc; 7269 } 7270 7271 /*=========================================================================== 7272 * FUNCTION : addCallbackChannel 7273 * 7274 * DESCRIPTION: add a callback channel that contains a callback stream 7275 * 7276 * PARAMETERS : none 7277 * 7278 * RETURN : int32_t type of status 7279 * NO_ERROR -- success 7280 * none-zero failure code 7281 *==========================================================================*/ 7282 int32_t QCamera2HardwareInterface::addCallbackChannel() 7283 { 7284 int32_t rc = NO_ERROR; 7285 QCameraChannel *pChannel = NULL; 7286 7287 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) { 7288 delete m_channels[QCAMERA_CH_TYPE_CALLBACK]; 7289 m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL; 7290 } 7291 7292 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 7293 mCameraHandle->ops); 7294 if (NULL == pChannel) { 7295 LOGE("no mem for callback channel"); 7296 return NO_MEMORY; 7297 } 7298 7299 rc = pChannel->init(NULL, NULL, this); 7300 if (rc != NO_ERROR) { 7301 LOGE("init callback channel failed, ret = %d", 7302 rc); 7303 delete pChannel; 7304 return rc; 7305 } 7306 7307 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK, 7308 callback_stream_cb_routine, this); 7309 if (rc != NO_ERROR) { 7310 LOGE("add callback stream failed, ret = %d", rc); 7311 delete pChannel; 7312 return rc; 7313 } 7314 7315 m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel; 7316 return rc; 7317 } 7318 7319 7320 /*=========================================================================== 7321 * FUNCTION : addAnalysisChannel 7322 * 7323 * DESCRIPTION: add a analysis channel that contains a analysis stream 7324 * 7325 * PARAMETERS : none 7326 * 7327 * RETURN : int32_t type of status 7328 * NO_ERROR -- success 7329 * none-zero failure code 7330 *==========================================================================*/ 7331 int32_t QCamera2HardwareInterface::addAnalysisChannel() 7332 { 7333 int32_t rc = NO_ERROR; 7334 QCameraChannel *pChannel = NULL; 7335 7336 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) { 7337 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS]; 7338 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL; 7339 } 7340 7341 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 7342 mCameraHandle->ops); 7343 if (NULL == pChannel) { 7344 LOGE("no mem for metadata channel"); 7345 return NO_MEMORY; 7346 } 7347 7348 rc = pChannel->init(NULL, NULL, this); 7349 if (rc != NO_ERROR) { 7350 LOGE("init Analysis channel failed, ret = %d", rc); 7351 delete pChannel; 7352 return rc; 7353 } 7354 7355 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 7356 NULL, this); 7357 if (rc != NO_ERROR) { 7358 LOGE("add Analysis stream failed, ret = %d", rc); 7359 delete pChannel; 7360 return rc; 7361 } 7362 7363 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel; 7364 return rc; 7365 } 7366 7367 7368 /*=========================================================================== 7369 * FUNCTION : getPPConfig 7370 * 7371 * DESCRIPTION: get Post processing configaration data 7372 * 7373 * PARAMETERS : 7374 * @pp config: pp config structure pointer, 7375 * @curIndex: current pp channel index 7376 * @multipass: Flag if multipass prcessing enabled. 7377 * 7378 * RETURN : int32_t type of status 7379 * NO_ERROR -- success 7380 * none-zero failure code 7381 *==========================================================================*/ 7382 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config, 7383 int8_t curIndex, bool multipass) 7384 { 7385 int32_t rc = NO_ERROR; 7386 7387 if (multipass) { 7388 LOGW("Multi pass enabled. Total Pass = %d, cur index = %d", 7389 mParameters.getReprocCount(), curIndex); 7390 } 7391 7392 LOGH("Supported pproc feature mask = %x", 7393 gCamCapability[mCameraId]->qcom_supported_feature_mask); 7394 uint32_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask; 7395 int32_t zoomLevel = mParameters.getParmZoomLevel(); 7396 uint32_t rotation = mParameters.getJpegRotation(); 7397 int32_t effect = mParameters.getEffectValue(); 7398 7399 pp_config.cur_reproc_count = curIndex + 1; 7400 pp_config.total_reproc_count = mParameters.getReprocCount(); 7401 7402 switch(curIndex) { 7403 case 0: 7404 //Configure feature mask for first pass of reprocessing 7405 //check if any effects are enabled 7406 if ((CAM_EFFECT_MODE_OFF != effect) && 7407 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) { 7408 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT; 7409 pp_config.effect = effect; 7410 } 7411 7412 //check for features that need to be enabled by default like sharpness 7413 //(if supported by hw). 7414 if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) && 7415 !mParameters.isOptiZoomEnabled()) { 7416 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS; 7417 pp_config.sharpness = mParameters.getSharpness(); 7418 } 7419 7420 //check if zoom is enabled 7421 if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) { 7422 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 7423 } 7424 7425 if (mParameters.isWNREnabled() && 7426 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) { 7427 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D; 7428 pp_config.denoise2d.denoise_enable = 1; 7429 pp_config.denoise2d.process_plates = 7430 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 7431 } 7432 7433 if (isCACEnabled()) { 7434 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC; 7435 } 7436 7437 //check if rotation is required 7438 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) { 7439 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 7440 if (rotation == 0) { 7441 pp_config.rotation = ROTATE_0; 7442 } else if (rotation == 90) { 7443 pp_config.rotation = ROTATE_90; 7444 } else if (rotation == 180) { 7445 pp_config.rotation = ROTATE_180; 7446 } else if (rotation == 270) { 7447 pp_config.rotation = ROTATE_270; 7448 } 7449 } 7450 7451 if (mParameters.isHDREnabled()){ 7452 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR; 7453 pp_config.hdr_param.hdr_enable = 1; 7454 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled(); 7455 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME; 7456 } else { 7457 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR; 7458 pp_config.hdr_param.hdr_enable = 0; 7459 } 7460 7461 //check if scaling is enabled 7462 if ((feature_mask & CAM_QCOM_FEATURE_SCALE) && 7463 mParameters.isReprocScaleEnabled() && 7464 mParameters.isUnderReprocScaling()){ 7465 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 7466 mParameters.getPicSizeFromAPK( 7467 pp_config.scale_param.output_width, 7468 pp_config.scale_param.output_height); 7469 } 7470 7471 if(mParameters.isUbiFocusEnabled()) { 7472 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS; 7473 } else { 7474 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS; 7475 } 7476 7477 if(mParameters.isUbiRefocus()) { 7478 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS; 7479 pp_config.misc_buf_param.misc_buffer_index = 0; 7480 } else { 7481 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS; 7482 } 7483 7484 if(mParameters.isChromaFlashEnabled()) { 7485 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH; 7486 pp_config.flash_value = CAM_FLASH_ON; 7487 } else { 7488 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH; 7489 } 7490 7491 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) { 7492 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM; 7493 pp_config.zoom_level = (uint8_t) zoomLevel; 7494 } else { 7495 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM; 7496 } 7497 7498 if (mParameters.getofflineRAW()) { 7499 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING; 7500 } 7501 7502 if (mParameters.isTruePortraitEnabled()) { 7503 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT; 7504 pp_config.misc_buf_param.misc_buffer_index = 0; 7505 } else { 7506 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT; 7507 } 7508 7509 if(mParameters.isStillMoreEnabled()) { 7510 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE; 7511 } else { 7512 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE; 7513 } 7514 7515 if (mParameters.isOEMFeatEnabled()) { 7516 pp_config.feature_mask |= CAM_OEM_FEATURE_1; 7517 } 7518 7519 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) { 7520 if (feature_mask & CAM_QCOM_FEATURE_DSDN) { 7521 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN; 7522 } else { 7523 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS; 7524 } 7525 } 7526 7527 if ((multipass) && 7528 (m_postprocessor.getPPChannelCount() > 1)) { 7529 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2; 7530 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION; 7531 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS; 7532 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN; 7533 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 7534 } else { 7535 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 7536 } 7537 7538 cam_dimension_t thumb_src_dim; 7539 cam_dimension_t thumb_dst_dim; 7540 mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height)); 7541 mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim); 7542 if ((thumb_dst_dim.width != thumb_src_dim.width) || 7543 (thumb_dst_dim.height != thumb_src_dim.height)) { 7544 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) { 7545 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 7546 } 7547 } 7548 7549 break; 7550 7551 case 1: 7552 //Configure feature mask for second pass of reprocessing 7553 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2; 7554 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) { 7555 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 7556 if (rotation == 0) { 7557 pp_config.rotation = ROTATE_0; 7558 } else if (rotation == 90) { 7559 pp_config.rotation = ROTATE_90; 7560 } else if (rotation == 180) { 7561 pp_config.rotation = ROTATE_180; 7562 } else if (rotation == 270) { 7563 pp_config.rotation = ROTATE_270; 7564 } 7565 } 7566 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) { 7567 if (feature_mask & CAM_QCOM_FEATURE_DSDN) { 7568 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN; 7569 } else { 7570 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS; 7571 } 7572 } 7573 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING; 7574 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING; 7575 break; 7576 7577 } 7578 LOGH("pproc feature mask set = %x pass count = %d", 7579 pp_config.feature_mask, curIndex); 7580 return rc; 7581 } 7582 7583 /*=========================================================================== 7584 * FUNCTION : addReprocChannel 7585 * 7586 * DESCRIPTION: add a reprocess channel that will do reprocess on frames 7587 * coming from input channel 7588 * 7589 * PARAMETERS : 7590 * @pInputChannel : ptr to input channel whose frames will be post-processed 7591 * @cur_channel_index : Current channel index in multipass 7592 * 7593 * RETURN : Ptr to the newly created channel obj. NULL if failed. 7594 *==========================================================================*/ 7595 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel( 7596 QCameraChannel *pInputChannel, int8_t cur_channel_index) 7597 { 7598 int32_t rc = NO_ERROR; 7599 QCameraReprocessChannel *pChannel = NULL; 7600 uint32_t burst_cnt = mParameters.getNumOfSnapshots(); 7601 7602 if (pInputChannel == NULL) { 7603 LOGE("input channel obj is NULL"); 7604 return NULL; 7605 } 7606 7607 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle, 7608 mCameraHandle->ops); 7609 if (NULL == pChannel) { 7610 LOGE("no mem for reprocess channel"); 7611 return NULL; 7612 } 7613 7614 // Capture channel, only need snapshot and postview streams start together 7615 mm_camera_channel_attr_t attr; 7616 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 7617 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 7618 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 7619 rc = pChannel->init(&attr, 7620 postproc_channel_cb_routine, 7621 this); 7622 if (rc != NO_ERROR) { 7623 LOGE("init reprocess channel failed, ret = %d", rc); 7624 delete pChannel; 7625 return NULL; 7626 } 7627 7628 // pp feature config 7629 cam_pp_feature_config_t pp_config; 7630 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 7631 7632 rc = getPPConfig(pp_config, cur_channel_index, 7633 ((mParameters.getReprocCount() > 1) ? TRUE : FALSE)); 7634 if (rc != NO_ERROR){ 7635 LOGE("Error while creating PP config"); 7636 delete pChannel; 7637 return NULL; 7638 } 7639 7640 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC); 7641 7642 //WNR and HDR happen inline. No extra buffers needed. 7643 uint32_t temp_feature_mask = pp_config.feature_mask; 7644 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR; 7645 if (temp_feature_mask && mParameters.isHDREnabled()) { 7646 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded()); 7647 } 7648 7649 if (mParameters.isStillMoreEnabled()) { 7650 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 7651 pp_config.burst_cnt = stillmore_config.burst_count; 7652 LOGH("Stillmore burst %d", pp_config.burst_cnt); 7653 7654 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming 7655 // number of capture is already added. In the case of liveshot, 7656 // stillmore burst is 1. This is to account for the premature decrement 7657 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) { 7658 minStreamBufNum += 1; 7659 } 7660 } 7661 7662 if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) { 7663 minStreamBufNum += mParameters.getReprocCount() - 1; 7664 burst_cnt = mParameters.getReprocCount(); 7665 if (cur_channel_index == 0) { 7666 pChannel->setReprocCount(2); 7667 } else { 7668 pChannel->setReprocCount(1); 7669 } 7670 } else { 7671 pChannel->setReprocCount(1); 7672 } 7673 7674 // Add non inplace image lib buffers only when ppproc is present, 7675 // becuase pproc is non inplace and input buffers for img lib 7676 // are output for pproc and this number of extra buffers is required 7677 // If pproc is not there, input buffers for imglib are from snapshot stream 7678 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc(); 7679 if (temp_feature_mask && imglib_extra_bufs) { 7680 // 1 is added because getNumOfExtraBuffersForImageProc returns extra 7681 // buffers assuming number of capture is already added 7682 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1); 7683 } 7684 7685 //Mask out features that are already processed in snapshot stream. 7686 uint32_t snapshot_feature_mask = 0; 7687 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask); 7688 7689 pp_config.feature_mask &= ~snapshot_feature_mask; 7690 LOGH("Snapshot feature mask: 0x%x, reproc feature mask: 0x%x", 7691 snapshot_feature_mask, pp_config.feature_mask); 7692 7693 bool offlineReproc = isRegularCapture(); 7694 if (m_postprocessor.mOfflineDataBufs != NULL) { 7695 offlineReproc = TRUE; 7696 } 7697 7698 cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info; 7699 paddingInfo.offset_info.offset_x = 0; 7700 paddingInfo.offset_info.offset_y = 0; 7701 rc = pChannel->addReprocStreamsFromSource(*this, 7702 pp_config, 7703 pInputChannel, 7704 minStreamBufNum, 7705 burst_cnt, 7706 &paddingInfo, 7707 mParameters, 7708 mLongshotEnabled, 7709 offlineReproc); 7710 if (rc != NO_ERROR) { 7711 delete pChannel; 7712 return NULL; 7713 } 7714 7715 return pChannel; 7716 } 7717 7718 /*=========================================================================== 7719 * FUNCTION : addOfflineReprocChannel 7720 * 7721 * DESCRIPTION: add a offline reprocess channel contains one reproc stream, 7722 * that will do reprocess on frames coming from external images 7723 * 7724 * PARAMETERS : 7725 * @img_config : offline reporcess image info 7726 * @pp_feature : pp feature config 7727 * 7728 * RETURN : int32_t type of status 7729 * NO_ERROR -- success 7730 * none-zero failure code 7731 *==========================================================================*/ 7732 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel( 7733 cam_pp_offline_src_config_t &img_config, 7734 cam_pp_feature_config_t &pp_feature, 7735 stream_cb_routine stream_cb, 7736 void *userdata) 7737 { 7738 int32_t rc = NO_ERROR; 7739 QCameraReprocessChannel *pChannel = NULL; 7740 7741 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle, 7742 mCameraHandle->ops); 7743 if (NULL == pChannel) { 7744 LOGE("no mem for reprocess channel"); 7745 return NULL; 7746 } 7747 7748 rc = pChannel->init(NULL, NULL, NULL); 7749 if (rc != NO_ERROR) { 7750 LOGE("init reprocess channel failed, ret = %d", rc); 7751 delete pChannel; 7752 return NULL; 7753 } 7754 7755 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 7756 if (pStreamInfo == NULL) { 7757 LOGE("no mem for stream info buf"); 7758 delete pChannel; 7759 return NULL; 7760 } 7761 7762 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0); 7763 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t)); 7764 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 7765 streamInfoBuf->fmt = img_config.input_fmt; 7766 streamInfoBuf->dim = img_config.input_dim; 7767 streamInfoBuf->buf_planes = img_config.input_buf_planes; 7768 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST; 7769 streamInfoBuf->num_of_burst = img_config.num_of_bufs; 7770 7771 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 7772 streamInfoBuf->reprocess_config.offline = img_config; 7773 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature; 7774 7775 rc = pChannel->addStream(*this, 7776 pStreamInfo, NULL, img_config.num_of_bufs, 7777 &gCamCapability[mCameraId]->padding_info, 7778 stream_cb, userdata, false); 7779 7780 if (rc != NO_ERROR) { 7781 LOGE("add reprocess stream failed, ret = %d", rc); 7782 delete pChannel; 7783 return NULL; 7784 } 7785 7786 return pChannel; 7787 } 7788 7789 /*=========================================================================== 7790 * FUNCTION : addChannel 7791 * 7792 * DESCRIPTION: add a channel by its type 7793 * 7794 * PARAMETERS : 7795 * @ch_type : channel type 7796 * 7797 * RETURN : int32_t type of status 7798 * NO_ERROR -- success 7799 * none-zero failure code 7800 *==========================================================================*/ 7801 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type) 7802 { 7803 int32_t rc = UNKNOWN_ERROR; 7804 switch (ch_type) { 7805 case QCAMERA_CH_TYPE_ZSL: 7806 rc = addZSLChannel(); 7807 break; 7808 case QCAMERA_CH_TYPE_CAPTURE: 7809 rc = addCaptureChannel(); 7810 break; 7811 case QCAMERA_CH_TYPE_PREVIEW: 7812 rc = addPreviewChannel(); 7813 break; 7814 case QCAMERA_CH_TYPE_VIDEO: 7815 rc = addVideoChannel(); 7816 break; 7817 case QCAMERA_CH_TYPE_SNAPSHOT: 7818 rc = addSnapshotChannel(); 7819 break; 7820 case QCAMERA_CH_TYPE_RAW: 7821 rc = addRawChannel(); 7822 break; 7823 case QCAMERA_CH_TYPE_METADATA: 7824 rc = addMetaDataChannel(); 7825 break; 7826 case QCAMERA_CH_TYPE_CALLBACK: 7827 rc = addCallbackChannel(); 7828 break; 7829 case QCAMERA_CH_TYPE_ANALYSIS: 7830 rc = addAnalysisChannel(); 7831 break; 7832 default: 7833 break; 7834 } 7835 return rc; 7836 } 7837 7838 /*=========================================================================== 7839 * FUNCTION : delChannel 7840 * 7841 * DESCRIPTION: delete a channel by its type 7842 * 7843 * PARAMETERS : 7844 * @ch_type : channel type 7845 * @destroy : delete context as well 7846 * 7847 * RETURN : int32_t type of status 7848 * NO_ERROR -- success 7849 * none-zero failure code 7850 *==========================================================================*/ 7851 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type, 7852 bool destroy) 7853 { 7854 if (m_channels[ch_type] != NULL) { 7855 if (destroy) { 7856 delete m_channels[ch_type]; 7857 m_channels[ch_type] = NULL; 7858 } else { 7859 m_channels[ch_type]->deleteChannel(); 7860 } 7861 } 7862 7863 return NO_ERROR; 7864 } 7865 7866 /*=========================================================================== 7867 * FUNCTION : startChannel 7868 * 7869 * DESCRIPTION: start a channel by its type 7870 * 7871 * PARAMETERS : 7872 * @ch_type : channel type 7873 * 7874 * RETURN : int32_t type of status 7875 * NO_ERROR -- success 7876 * none-zero failure code 7877 *==========================================================================*/ 7878 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type) 7879 { 7880 int32_t rc = UNKNOWN_ERROR; 7881 if (m_channels[ch_type] != NULL) { 7882 rc = m_channels[ch_type]->start(); 7883 } 7884 return rc; 7885 } 7886 7887 /*=========================================================================== 7888 * FUNCTION : stopChannel 7889 * 7890 * DESCRIPTION: stop a channel by its type 7891 * 7892 * PARAMETERS : 7893 * @ch_type : channel type 7894 * 7895 * RETURN : int32_t type of status 7896 * NO_ERROR -- success 7897 * none-zero failure code 7898 *==========================================================================*/ 7899 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type) 7900 { 7901 int32_t rc = UNKNOWN_ERROR; 7902 if (m_channels[ch_type] != NULL) { 7903 rc = m_channels[ch_type]->stop(); 7904 } 7905 7906 return rc; 7907 } 7908 7909 /*=========================================================================== 7910 * FUNCTION : preparePreview 7911 * 7912 * DESCRIPTION: add channels needed for preview 7913 * 7914 * PARAMETERS : none 7915 * 7916 * RETURN : int32_t type of status 7917 * NO_ERROR -- success 7918 * none-zero failure code 7919 *==========================================================================*/ 7920 int32_t QCamera2HardwareInterface::preparePreview() 7921 { 7922 ATRACE_CALL(); 7923 int32_t rc = NO_ERROR; 7924 7925 LOGI("E"); 7926 rc = mParameters.setStreamConfigure(false, false, false); 7927 if (rc != NO_ERROR) { 7928 LOGE("setStreamConfigure failed %d", rc); 7929 return rc; 7930 } 7931 7932 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 7933 rc = addChannel(QCAMERA_CH_TYPE_ZSL); 7934 if (rc != NO_ERROR) { 7935 LOGE("failed!! rc = %d", rc); 7936 return rc; 7937 } 7938 7939 if (mParameters.isUBWCEnabled()) { 7940 cam_format_t fmt; 7941 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt); 7942 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 7943 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK); 7944 if (rc != NO_ERROR) { 7945 delChannel(QCAMERA_CH_TYPE_ZSL); 7946 LOGE("failed!! rc = %d", rc); 7947 return rc; 7948 } 7949 } 7950 } 7951 7952 if (mParameters.getofflineRAW()) { 7953 addChannel(QCAMERA_CH_TYPE_RAW); 7954 } 7955 } else { 7956 bool recordingHint = mParameters.getRecordingHintValue(); 7957 if(!isRdiMode() && recordingHint) { 7958 //stop face detection,longshot,etc if turned ON in Camera mode 7959 #ifndef VANILLA_HAL 7960 int32_t arg; //dummy arg 7961 if (isLongshotEnabled()) { 7962 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg); 7963 } 7964 if (mParameters.isFaceDetectionEnabled() 7965 && (!mParameters.fdModeInVideo())) { 7966 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg); 7967 } 7968 if (mParameters.isHistogramEnabled()) { 7969 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg); 7970 } 7971 #endif 7972 //Don't create snapshot channel for liveshot, if low power mode is set. 7973 //Use video stream instead. 7974 if (!isLowPowerMode()) { 7975 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT); 7976 if (rc != NO_ERROR) { 7977 return rc; 7978 } 7979 } 7980 7981 rc = addChannel(QCAMERA_CH_TYPE_VIDEO); 7982 if (rc != NO_ERROR) { 7983 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 7984 LOGE("failed!! rc = %d", rc); 7985 return rc; 7986 } 7987 } 7988 7989 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW); 7990 if (!isRdiMode() && (rc != NO_ERROR)) { 7991 if (recordingHint) { 7992 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 7993 delChannel(QCAMERA_CH_TYPE_VIDEO); 7994 } 7995 } 7996 7997 if (mParameters.isUBWCEnabled() && !recordingHint) { 7998 cam_format_t fmt; 7999 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt); 8000 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) { 8001 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK); 8002 if (rc != NO_ERROR) { 8003 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8004 if (!isRdiMode()) { 8005 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8006 delChannel(QCAMERA_CH_TYPE_VIDEO); 8007 } 8008 LOGE("failed!! rc = %d", rc); 8009 return rc; 8010 } 8011 } 8012 } 8013 8014 if (NO_ERROR != rc) { 8015 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8016 LOGE("failed!! rc = %d", rc); 8017 } 8018 } 8019 8020 LOGI("E rc = %d", rc); 8021 return rc; 8022 } 8023 8024 /*=========================================================================== 8025 * FUNCTION : unpreparePreview 8026 * 8027 * DESCRIPTION: delete channels for preview 8028 * 8029 * PARAMETERS : none 8030 * 8031 * RETURN : none 8032 *==========================================================================*/ 8033 void QCamera2HardwareInterface::unpreparePreview() 8034 { 8035 delChannel(QCAMERA_CH_TYPE_ZSL); 8036 delChannel(QCAMERA_CH_TYPE_PREVIEW); 8037 delChannel(QCAMERA_CH_TYPE_VIDEO); 8038 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 8039 delChannel(QCAMERA_CH_TYPE_CALLBACK); 8040 delChannel(QCAMERA_CH_TYPE_RAW); 8041 } 8042 8043 /*=========================================================================== 8044 * FUNCTION : playShutter 8045 * 8046 * DESCRIPTION: send request to play shutter sound 8047 * 8048 * PARAMETERS : none 8049 * 8050 * RETURN : none 8051 *==========================================================================*/ 8052 void QCamera2HardwareInterface::playShutter(){ 8053 if (mNotifyCb == NULL || 8054 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){ 8055 LOGD("shutter msg not enabled or NULL cb"); 8056 return; 8057 } 8058 LOGH("CAMERA_MSG_SHUTTER "); 8059 qcamera_callback_argm_t cbArg; 8060 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 8061 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 8062 cbArg.msg_type = CAMERA_MSG_SHUTTER; 8063 cbArg.ext1 = 0; 8064 cbArg.ext2 = false; 8065 m_cbNotifier.notifyCallback(cbArg); 8066 } 8067 8068 /*=========================================================================== 8069 * FUNCTION : getChannelByHandle 8070 * 8071 * DESCRIPTION: return a channel by its handle 8072 * 8073 * PARAMETERS : 8074 * @channelHandle : channel handle 8075 * 8076 * RETURN : a channel obj if found, NULL if not found 8077 *==========================================================================*/ 8078 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle) 8079 { 8080 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 8081 if (m_channels[i] != NULL && 8082 m_channels[i]->getMyHandle() == channelHandle) { 8083 return m_channels[i]; 8084 } 8085 } 8086 8087 return NULL; 8088 } 8089 /*=========================================================================== 8090 * FUNCTION : needPreviewFDCallback 8091 * 8092 * DESCRIPTION: decides if needPreviewFDCallback 8093 * 8094 * PARAMETERS : 8095 * @num_faces : number of faces 8096 * 8097 * RETURN : bool type of status 8098 * true -- success 8099 * fale -- failure code 8100 *==========================================================================*/ 8101 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces) 8102 { 8103 if (num_faces == 0 && mNumPreviewFaces == 0) { 8104 return false; 8105 } 8106 8107 return true; 8108 } 8109 8110 /*=========================================================================== 8111 * FUNCTION : processFaceDetectionReuslt 8112 * 8113 * DESCRIPTION: process face detection reuslt 8114 * 8115 * PARAMETERS : 8116 * @faces_data : ptr to face processing result struct 8117 * 8118 * RETURN : int32_t type of status 8119 * NO_ERROR -- success 8120 * none-zero failure code 8121 *==========================================================================*/ 8122 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data) 8123 { 8124 if (!mParameters.isFaceDetectionEnabled()) { 8125 LOGH("FaceDetection not enabled, no ops here"); 8126 return NO_ERROR; 8127 } 8128 8129 qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type; 8130 cam_face_detection_data_t *detect_data = &(faces_data->detection_data); 8131 if ((NULL == mDataCb) || 8132 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) || 8133 (!needPreviewFDCallback(detect_data->num_faces_detected)) 8134 #ifndef VANILLA_HAL 8135 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA)) 8136 #endif 8137 ) { 8138 LOGH("metadata msgtype not enabled, no ops here"); 8139 return NO_ERROR; 8140 } 8141 8142 if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) { 8143 // Don't send callback to app if this is skipped by fd at backend 8144 return NO_ERROR; 8145 } 8146 8147 cam_dimension_t display_dim; 8148 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim); 8149 if (display_dim.width <= 0 || display_dim.height <= 0) { 8150 LOGE("Invalid preview width or height (%d x %d)", 8151 display_dim.width, display_dim.height); 8152 return UNKNOWN_ERROR; 8153 } 8154 8155 // process face detection result 8156 // need separate face detection in preview or snapshot type 8157 size_t faceResultSize = 0; 8158 size_t data_len = 0; 8159 if(fd_type == QCAMERA_FD_PREVIEW){ 8160 //fd for preview frames 8161 faceResultSize = sizeof(camera_frame_metadata_t); 8162 faceResultSize += sizeof(camera_face_t) * MAX_ROI; 8163 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 8164 #ifndef VANILLA_HAL 8165 // fd for snapshot frames 8166 //check if face is detected in this frame 8167 if(detect_data->num_faces_detected > 0){ 8168 data_len = sizeof(camera_frame_metadata_t) + 8169 sizeof(camera_face_t) * detect_data->num_faces_detected; 8170 }else{ 8171 //no face 8172 data_len = 0; 8173 } 8174 #endif 8175 faceResultSize = 1 *sizeof(int) //meta data type 8176 + 1 *sizeof(int) // meta data len 8177 + data_len; //data 8178 } 8179 8180 camera_memory_t *faceResultBuffer = mGetMemory(-1, 8181 faceResultSize, 8182 1, 8183 mCallbackCookie); 8184 if ( NULL == faceResultBuffer ) { 8185 LOGE("Not enough memory for face result data"); 8186 return NO_MEMORY; 8187 } 8188 8189 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data; 8190 memset(pFaceResult, 0, faceResultSize); 8191 unsigned char *faceData = NULL; 8192 if(fd_type == QCAMERA_FD_PREVIEW){ 8193 faceData = pFaceResult; 8194 mNumPreviewFaces = detect_data->num_faces_detected; 8195 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 8196 #ifndef VANILLA_HAL 8197 //need fill meta type and meta data len first 8198 int *data_header = (int* )pFaceResult; 8199 data_header[0] = CAMERA_META_DATA_FD; 8200 data_header[1] = (int)data_len; 8201 8202 if(data_len <= 0){ 8203 //if face is not valid or do not have face, return 8204 qcamera_callback_argm_t cbArg; 8205 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 8206 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 8207 cbArg.msg_type = CAMERA_MSG_META_DATA; 8208 cbArg.data = faceResultBuffer; 8209 cbArg.user_data = faceResultBuffer; 8210 cbArg.cookie = this; 8211 cbArg.release_cb = releaseCameraMemory; 8212 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 8213 if (rc != NO_ERROR) { 8214 LOGE("fail sending notification"); 8215 faceResultBuffer->release(faceResultBuffer); 8216 } 8217 return rc; 8218 } 8219 #endif 8220 faceData = pFaceResult + 2 *sizeof(int); //skip two int length 8221 } 8222 8223 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData; 8224 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) ); 8225 8226 roiData->number_of_faces = detect_data->num_faces_detected; 8227 roiData->faces = faces; 8228 if (roiData->number_of_faces > 0) { 8229 for (int i = 0; i < roiData->number_of_faces; i++) { 8230 faces[i].id = detect_data->faces[i].face_id; 8231 faces[i].score = detect_data->faces[i].score; 8232 8233 // left 8234 faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE( 8235 detect_data->faces[i].face_boundary.left, 8236 display_dim.width, 2000, -1000); 8237 8238 // top 8239 faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE( 8240 detect_data->faces[i].face_boundary.top, 8241 display_dim.height, 2000, -1000); 8242 8243 // right 8244 faces[i].rect[2] = faces[i].rect[0] + 8245 MAP_TO_DRIVER_COORDINATE( 8246 detect_data->faces[i].face_boundary.width, 8247 display_dim.width, 2000, 0); 8248 8249 // bottom 8250 faces[i].rect[3] = faces[i].rect[1] + 8251 MAP_TO_DRIVER_COORDINATE( 8252 detect_data->faces[i].face_boundary.height, 8253 display_dim.height, 2000, 0); 8254 8255 if (faces_data->landmark_valid) { 8256 // Center of left eye 8257 faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE( 8258 faces_data->landmark_data.face_landmarks[i].left_eye_center.x, 8259 display_dim.width, 2000, -1000); 8260 faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE( 8261 faces_data->landmark_data.face_landmarks[i].left_eye_center.y, 8262 display_dim.height, 2000, -1000); 8263 8264 // Center of right eye 8265 faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE( 8266 faces_data->landmark_data.face_landmarks[i].right_eye_center.x, 8267 display_dim.width, 2000, -1000); 8268 faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE( 8269 faces_data->landmark_data.face_landmarks[i].right_eye_center.y, 8270 display_dim.height, 2000, -1000); 8271 8272 // Center of mouth 8273 faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE( 8274 faces_data->landmark_data.face_landmarks[i].mouth_center.x, 8275 display_dim.width, 2000, -1000); 8276 faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE( 8277 faces_data->landmark_data.face_landmarks[i].mouth_center.y, 8278 display_dim.height, 2000, -1000); 8279 } else { 8280 // return -2000 if invalid 8281 faces[i].left_eye[0] = -2000; 8282 faces[i].left_eye[1] = -2000; 8283 8284 faces[i].right_eye[0] = -2000; 8285 faces[i].right_eye[1] = -2000; 8286 8287 faces[i].mouth[0] = -2000; 8288 faces[i].mouth[1] = -2000; 8289 } 8290 8291 #ifndef VANILLA_HAL 8292 #ifdef TARGET_TS_MAKEUP 8293 mFaceRect.left = detect_data->faces[i].face_boundary.left; 8294 mFaceRect.top = detect_data->faces[i].face_boundary.top; 8295 mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left; 8296 mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top; 8297 #endif 8298 if (faces_data->smile_valid) { 8299 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree; 8300 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence; 8301 } 8302 if (faces_data->blink_valid) { 8303 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected; 8304 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink; 8305 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink; 8306 } 8307 if (faces_data->recog_valid) { 8308 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised; 8309 } 8310 if (faces_data->gaze_valid) { 8311 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle; 8312 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir; 8313 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir; 8314 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir; 8315 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze; 8316 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze; 8317 } 8318 #endif 8319 8320 } 8321 } 8322 else{ 8323 #ifdef TARGET_TS_MAKEUP 8324 memset(&mFaceRect,-1,sizeof(mFaceRect)); 8325 #endif 8326 } 8327 qcamera_callback_argm_t cbArg; 8328 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 8329 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 8330 if(fd_type == QCAMERA_FD_PREVIEW){ 8331 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA; 8332 } 8333 #ifndef VANILLA_HAL 8334 else if(fd_type == QCAMERA_FD_SNAPSHOT){ 8335 cbArg.msg_type = CAMERA_MSG_META_DATA; 8336 } 8337 #endif 8338 cbArg.data = faceResultBuffer; 8339 cbArg.metadata = roiData; 8340 cbArg.user_data = faceResultBuffer; 8341 cbArg.cookie = this; 8342 cbArg.release_cb = releaseCameraMemory; 8343 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 8344 if (rc != NO_ERROR) { 8345 LOGE("fail sending notification"); 8346 faceResultBuffer->release(faceResultBuffer); 8347 } 8348 8349 return rc; 8350 } 8351 8352 /*=========================================================================== 8353 * FUNCTION : releaseCameraMemory 8354 * 8355 * DESCRIPTION: releases camera memory objects 8356 * 8357 * PARAMETERS : 8358 * @data : buffer to be released 8359 * @cookie : context data 8360 * @cbStatus: callback status 8361 * 8362 * RETURN : None 8363 *==========================================================================*/ 8364 void QCamera2HardwareInterface::releaseCameraMemory(void *data, 8365 void */*cookie*/, 8366 int32_t /*cbStatus*/) 8367 { 8368 camera_memory_t *mem = ( camera_memory_t * ) data; 8369 if ( NULL != mem ) { 8370 mem->release(mem); 8371 } 8372 } 8373 8374 /*=========================================================================== 8375 * FUNCTION : returnStreamBuffer 8376 * 8377 * DESCRIPTION: returns back a stream buffer 8378 * 8379 * PARAMETERS : 8380 * @data : buffer to be released 8381 * @cookie : context data 8382 * @cbStatus: callback status 8383 * 8384 * RETURN : None 8385 *==========================================================================*/ 8386 void QCamera2HardwareInterface::returnStreamBuffer(void *data, 8387 void *cookie, 8388 int32_t /*cbStatus*/) 8389 { 8390 QCameraStream *stream = ( QCameraStream * ) cookie; 8391 int idx = *((int *)data); 8392 if ((NULL != stream) && (0 <= idx)) { 8393 stream->bufDone((uint32_t)idx); 8394 } else { 8395 LOGE("Cannot return buffer %d %p", idx, cookie); 8396 } 8397 } 8398 8399 /*=========================================================================== 8400 * FUNCTION : processHistogramStats 8401 * 8402 * DESCRIPTION: process histogram stats 8403 * 8404 * PARAMETERS : 8405 * @hist_data : ptr to histogram stats struct 8406 * 8407 * RETURN : int32_t type of status 8408 * NO_ERROR -- success 8409 * none-zero failure code 8410 *==========================================================================*/ 8411 int32_t QCamera2HardwareInterface::processHistogramStats( 8412 __unused cam_hist_stats_t &stats_data) 8413 { 8414 #ifndef VANILLA_HAL 8415 if (!mParameters.isHistogramEnabled()) { 8416 LOGH("Histogram not enabled, no ops here"); 8417 return NO_ERROR; 8418 } 8419 8420 camera_memory_t *histBuffer = mGetMemory(-1, 8421 sizeof(cam_histogram_data_t), 8422 1, 8423 mCallbackCookie); 8424 if ( NULL == histBuffer ) { 8425 LOGE("Not enough memory for histogram data"); 8426 return NO_MEMORY; 8427 } 8428 8429 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data; 8430 if (pHistData == NULL) { 8431 LOGE("memory data ptr is NULL"); 8432 return UNKNOWN_ERROR; 8433 } 8434 8435 switch (stats_data.type) { 8436 case CAM_HISTOGRAM_TYPE_BAYER: 8437 *pHistData = stats_data.bayer_stats.gb_stats; 8438 break; 8439 case CAM_HISTOGRAM_TYPE_YUV: 8440 *pHistData = stats_data.yuv_stats; 8441 break; 8442 } 8443 8444 qcamera_callback_argm_t cbArg; 8445 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 8446 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 8447 cbArg.msg_type = CAMERA_MSG_STATS_DATA; 8448 cbArg.data = histBuffer; 8449 cbArg.user_data = histBuffer; 8450 cbArg.cookie = this; 8451 cbArg.release_cb = releaseCameraMemory; 8452 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 8453 if (rc != NO_ERROR) { 8454 LOGE("fail sending notification"); 8455 histBuffer->release(histBuffer); 8456 } 8457 #endif 8458 return NO_ERROR; 8459 } 8460 8461 /*=========================================================================== 8462 * FUNCTION : calcThermalLevel 8463 * 8464 * DESCRIPTION: Calculates the target fps range depending on 8465 * the thermal level. 8466 * Note that this function can be called from QCameraParametersIntf 8467 * while mutex is held. So it should not call back into 8468 * QCameraParametersIntf causing deadlock. 8469 * 8470 * PARAMETERS : 8471 * @level : received thermal level 8472 * @minFPS : minimum configured fps range 8473 * @maxFPS : maximum configured fps range 8474 * @minVideoFps: minimum configured fps range 8475 * @maxVideoFps: maximum configured fps range 8476 * @adjustedRange : target fps range 8477 * @skipPattern : target skip pattern 8478 * 8479 * RETURN : int32_t type of status 8480 * NO_ERROR -- success 8481 * none-zero failure code 8482 *==========================================================================*/ 8483 int QCamera2HardwareInterface::calcThermalLevel( 8484 qcamera_thermal_level_enum_t level, 8485 const int minFPSi, 8486 const int maxFPSi, 8487 const float &minVideoFps, 8488 const float &maxVideoFps, 8489 cam_fps_range_t &adjustedRange, 8490 enum msm_vfe_frame_skip_pattern &skipPattern) 8491 { 8492 const float minFPS = (float)minFPSi; 8493 const float maxFPS = (float)maxFPSi; 8494 8495 LOGH("level: %d, preview minfps %f, preview maxfpS %f, " 8496 "video minfps %f, video maxfpS %f", 8497 level, minFPS, maxFPS, minVideoFps, maxVideoFps); 8498 8499 switch(level) { 8500 case QCAMERA_THERMAL_NO_ADJUSTMENT: 8501 { 8502 adjustedRange.min_fps = minFPS / 1000.0f; 8503 adjustedRange.max_fps = maxFPS / 1000.0f; 8504 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 8505 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 8506 skipPattern = NO_SKIP; 8507 } 8508 break; 8509 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT: 8510 { 8511 adjustedRange.min_fps = minFPS / 1000.0f; 8512 adjustedRange.max_fps = maxFPS / 1000.0f; 8513 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps; 8514 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps; 8515 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 8516 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 8517 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps; 8518 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps; 8519 if ( adjustedRange.min_fps < 1 ) { 8520 adjustedRange.min_fps = 1; 8521 } 8522 if ( adjustedRange.max_fps < 1 ) { 8523 adjustedRange.max_fps = 1; 8524 } 8525 if ( adjustedRange.video_min_fps < 1 ) { 8526 adjustedRange.video_min_fps = 1; 8527 } 8528 if ( adjustedRange.video_max_fps < 1 ) { 8529 adjustedRange.video_max_fps = 1; 8530 } 8531 skipPattern = EVERY_2FRAME; 8532 } 8533 break; 8534 case QCAMERA_THERMAL_BIG_ADJUSTMENT: 8535 { 8536 adjustedRange.min_fps = minFPS / 1000.0f; 8537 adjustedRange.max_fps = maxFPS / 1000.0f; 8538 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps; 8539 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps; 8540 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 8541 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 8542 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps; 8543 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps; 8544 if ( adjustedRange.min_fps < 1 ) { 8545 adjustedRange.min_fps = 1; 8546 } 8547 if ( adjustedRange.max_fps < 1 ) { 8548 adjustedRange.max_fps = 1; 8549 } 8550 if ( adjustedRange.video_min_fps < 1 ) { 8551 adjustedRange.video_min_fps = 1; 8552 } 8553 if ( adjustedRange.video_max_fps < 1 ) { 8554 adjustedRange.video_max_fps = 1; 8555 } 8556 skipPattern = EVERY_4FRAME; 8557 } 8558 break; 8559 case QCAMERA_THERMAL_MAX_ADJUSTMENT: 8560 { 8561 // Stop Preview? 8562 // Set lowest min FPS for now 8563 adjustedRange.min_fps = minFPS/1000.0f; 8564 adjustedRange.max_fps = minFPS/1000.0f; 8565 cam_capability_t *capability = gCamCapability[mCameraId]; 8566 for (size_t i = 0; 8567 i < capability->fps_ranges_tbl_cnt; 8568 i++) { 8569 if (capability->fps_ranges_tbl[i].min_fps < 8570 adjustedRange.min_fps) { 8571 adjustedRange.min_fps = 8572 capability->fps_ranges_tbl[i].min_fps; 8573 adjustedRange.max_fps = adjustedRange.min_fps; 8574 } 8575 } 8576 skipPattern = MAX_SKIP; 8577 adjustedRange.video_min_fps = adjustedRange.min_fps; 8578 adjustedRange.video_max_fps = adjustedRange.max_fps; 8579 } 8580 break; 8581 case QCAMERA_THERMAL_SHUTDOWN: 8582 { 8583 // send error notify 8584 LOGE("Received shutdown thermal level. Closing camera"); 8585 sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); 8586 } 8587 break; 8588 default: 8589 { 8590 LOGW("Invalid thermal level %d", level); 8591 return BAD_VALUE; 8592 } 8593 break; 8594 } 8595 8596 return NO_ERROR; 8597 } 8598 8599 /*=========================================================================== 8600 * FUNCTION : recalcFPSRange 8601 * 8602 * DESCRIPTION: adjust the configured fps range regarding 8603 * the last thermal level. 8604 * 8605 * PARAMETERS : 8606 * @minFPS : minimum configured fps range 8607 * @maxFPS : maximum configured fps range 8608 * @minVideoFPS : minimum configured video fps 8609 * @maxVideoFPS : maximum configured video fps 8610 * @adjustedRange : target fps range 8611 * 8612 * RETURN : int32_t type of status 8613 * NO_ERROR -- success 8614 * none-zero failure code 8615 *==========================================================================*/ 8616 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS, 8617 const float &minVideoFPS, const float &maxVideoFPS, 8618 cam_fps_range_t &adjustedRange) 8619 { 8620 enum msm_vfe_frame_skip_pattern skipPattern; 8621 calcThermalLevel(mThermalLevel, 8622 minFPS, 8623 maxFPS, 8624 minVideoFPS, 8625 maxVideoFPS, 8626 adjustedRange, 8627 skipPattern); 8628 return NO_ERROR; 8629 } 8630 8631 /*=========================================================================== 8632 * FUNCTION : updateThermalLevel 8633 * 8634 * DESCRIPTION: update thermal level depending on thermal events 8635 * 8636 * PARAMETERS : 8637 * @level : thermal level 8638 * 8639 * RETURN : int32_t type of status 8640 * NO_ERROR -- success 8641 * none-zero failure code 8642 *==========================================================================*/ 8643 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level) 8644 { 8645 int ret = NO_ERROR; 8646 cam_fps_range_t adjustedRange; 8647 int minFPS, maxFPS; 8648 float minVideoFPS, maxVideoFPS; 8649 enum msm_vfe_frame_skip_pattern skipPattern; 8650 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level; 8651 8652 8653 if (!mCameraOpened) { 8654 LOGH("Camera is not opened, no need to update camera parameters"); 8655 return NO_ERROR; 8656 } 8657 if (mParameters.getRecordingHintValue()) { 8658 LOGH("Thermal mitigation isn't enabled in camcorder mode"); 8659 return NO_ERROR; 8660 } 8661 8662 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 8663 qcamera_thermal_mode thermalMode = mParameters.getThermalMode(); 8664 if (mParameters.isHfrMode()) { 8665 cam_fps_range_t hfrFpsRange; 8666 mParameters.getHfrFps(hfrFpsRange); 8667 minVideoFPS = hfrFpsRange.video_min_fps; 8668 maxVideoFPS = hfrFpsRange.video_max_fps; 8669 } else { 8670 minVideoFPS = minFPS; 8671 maxVideoFPS = maxFPS; 8672 } 8673 8674 calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS, 8675 adjustedRange, skipPattern); 8676 mThermalLevel = level; 8677 8678 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS) 8679 ret = mParameters.adjustPreviewFpsRange(&adjustedRange); 8680 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP) 8681 ret = mParameters.setFrameSkip(skipPattern); 8682 else 8683 LOGW("Incorrect thermal mode %d", thermalMode); 8684 8685 return ret; 8686 8687 } 8688 8689 /*=========================================================================== 8690 * FUNCTION : updateParameters 8691 * 8692 * DESCRIPTION: update parameters 8693 * 8694 * PARAMETERS : 8695 * @parms : input parameters string 8696 * @needRestart : output, flag to indicate if preview restart is needed 8697 * 8698 * RETURN : int32_t type of status 8699 * NO_ERROR -- success 8700 * none-zero failure code 8701 *==========================================================================*/ 8702 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart) 8703 { 8704 int rc = NO_ERROR; 8705 8706 String8 str = String8(parms); 8707 rc = mParameters.updateParameters(str, needRestart); 8708 setNeedRestart(needRestart); 8709 8710 // update stream based parameter settings 8711 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 8712 if (m_channels[i] != NULL) { 8713 m_channels[i]->UpdateStreamBasedParameters(mParameters); 8714 } 8715 } 8716 8717 return rc; 8718 } 8719 8720 /*=========================================================================== 8721 * FUNCTION : commitParameterChanges 8722 * 8723 * DESCRIPTION: commit parameter changes to the backend to take effect 8724 * 8725 * PARAMETERS : none 8726 * 8727 * RETURN : int32_t type of status 8728 * NO_ERROR -- success 8729 * none-zero failure code 8730 * NOTE : This function must be called after updateParameters. 8731 * Otherwise, no change will be passed to backend to take effect. 8732 *==========================================================================*/ 8733 int QCamera2HardwareInterface::commitParameterChanges() 8734 { 8735 int rc = NO_ERROR; 8736 rc = mParameters.commitParameters(); 8737 if (rc == NO_ERROR) { 8738 // update number of snapshot based on committed parameters setting 8739 rc = mParameters.setNumOfSnapshot(); 8740 } 8741 return rc; 8742 } 8743 8744 /*=========================================================================== 8745 * FUNCTION : needDebugFps 8746 * 8747 * DESCRIPTION: if fps log info need to be printed out 8748 * 8749 * PARAMETERS : none 8750 * 8751 * RETURN : true: need print out fps log 8752 * false: no need to print out fps log 8753 *==========================================================================*/ 8754 bool QCamera2HardwareInterface::needDebugFps() 8755 { 8756 bool needFps = false; 8757 needFps = mParameters.isFpsDebugEnabled(); 8758 return needFps; 8759 } 8760 8761 /*=========================================================================== 8762 * FUNCTION : isCACEnabled 8763 * 8764 * DESCRIPTION: if CAC is enabled 8765 * 8766 * PARAMETERS : none 8767 * 8768 * RETURN : true: needed 8769 * false: no need 8770 *==========================================================================*/ 8771 bool QCamera2HardwareInterface::isCACEnabled() 8772 { 8773 char prop[PROPERTY_VALUE_MAX]; 8774 memset(prop, 0, sizeof(prop)); 8775 property_get("persist.camera.feature.cac", prop, "0"); 8776 int enableCAC = atoi(prop); 8777 return enableCAC == 1; 8778 } 8779 8780 /*=========================================================================== 8781 * FUNCTION : is4k2kResolution 8782 * 8783 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k 8784 * 8785 * PARAMETERS : none 8786 * 8787 * RETURN : true: needed 8788 * false: no need 8789 *==========================================================================*/ 8790 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution) 8791 { 8792 bool enabled = false; 8793 if ((resolution->width == 4096 && resolution->height == 2160) || 8794 (resolution->width == 3840 && resolution->height == 2160) ) { 8795 enabled = true; 8796 } 8797 return enabled; 8798 } 8799 8800 /*=========================================================================== 8801 * FUNCTION : isPreviewRestartEnabled 8802 * 8803 * DESCRIPTION: Check whether preview should be restarted automatically 8804 * during image capture. 8805 * 8806 * PARAMETERS : none 8807 * 8808 * RETURN : true: needed 8809 * false: no need 8810 *==========================================================================*/ 8811 bool QCamera2HardwareInterface::isPreviewRestartEnabled() 8812 { 8813 char prop[PROPERTY_VALUE_MAX]; 8814 memset(prop, 0, sizeof(prop)); 8815 property_get("persist.camera.feature.restart", prop, "0"); 8816 int earlyRestart = atoi(prop); 8817 return earlyRestart == 1; 8818 } 8819 8820 /*=========================================================================== 8821 * FUNCTION : needReprocess 8822 * 8823 * DESCRIPTION: if reprocess is needed 8824 * 8825 * PARAMETERS : none 8826 * 8827 * RETURN : true: needed 8828 * false: no need 8829 *==========================================================================*/ 8830 bool QCamera2HardwareInterface::needReprocess() 8831 { 8832 bool needReprocess = false; 8833 8834 if (!mParameters.isJpegPictureFormat() && 8835 !mParameters.isNV21PictureFormat()) { 8836 // RAW image, no need to reprocess 8837 return false; 8838 } 8839 8840 //Disable reprocess for 4K liveshot case but enable if lowpower mode 8841 if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue() 8842 && !isLowPowerMode()) { 8843 return false; 8844 } 8845 8846 // pp feature config 8847 cam_pp_feature_config_t pp_config; 8848 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 8849 8850 //Decide whether to do reprocess or not based on 8851 //ppconfig obtained in the first pass. 8852 getPPConfig(pp_config); 8853 8854 if (pp_config.feature_mask > 0) { 8855 needReprocess = true; 8856 } 8857 8858 LOGH("needReprocess %s", needReprocess ? "true" : "false"); 8859 return needReprocess; 8860 } 8861 8862 8863 /*=========================================================================== 8864 * FUNCTION : needRotationReprocess 8865 * 8866 * DESCRIPTION: if rotation needs to be done by reprocess in pp 8867 * 8868 * PARAMETERS : none 8869 * 8870 * RETURN : true: needed 8871 * false: no need 8872 *==========================================================================*/ 8873 bool QCamera2HardwareInterface::needRotationReprocess() 8874 { 8875 if (!mParameters.isJpegPictureFormat() && 8876 !mParameters.isNV21PictureFormat()) { 8877 // RAW image, no need to reprocess 8878 return false; 8879 } 8880 8881 //Disable reprocess for 4K liveshot case 8882 if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue() 8883 && !isLowPowerMode()) { 8884 //Disable reprocess for 4K liveshot case 8885 return false; 8886 } 8887 8888 if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & 8889 CAM_QCOM_FEATURE_ROTATION) > 0 && 8890 (mParameters.getJpegRotation() > 0)) { 8891 // current rotation is not zero, and pp has the capability to process rotation 8892 LOGH("need to do reprocess for rotation=%d", 8893 mParameters.getJpegRotation()); 8894 return true; 8895 } 8896 8897 return false; 8898 } 8899 8900 /*=========================================================================== 8901 * FUNCTION : getThumbnailSize 8902 * 8903 * DESCRIPTION: get user set thumbnail size 8904 * 8905 * PARAMETERS : 8906 * @dim : output of thumbnail dimension 8907 * 8908 * RETURN : none 8909 *==========================================================================*/ 8910 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim) 8911 { 8912 mParameters.getThumbnailSize(&dim.width, &dim.height); 8913 } 8914 8915 /*=========================================================================== 8916 * FUNCTION : getJpegQuality 8917 * 8918 * DESCRIPTION: get user set jpeg quality 8919 * 8920 * PARAMETERS : none 8921 * 8922 * RETURN : jpeg quality setting 8923 *==========================================================================*/ 8924 uint32_t QCamera2HardwareInterface::getJpegQuality() 8925 { 8926 uint32_t quality = 0; 8927 quality = mParameters.getJpegQuality(); 8928 return quality; 8929 } 8930 8931 /*=========================================================================== 8932 * FUNCTION : getExifData 8933 * 8934 * DESCRIPTION: get exif data to be passed into jpeg encoding 8935 * 8936 * PARAMETERS : none 8937 * 8938 * RETURN : exif data from user setting and GPS 8939 *==========================================================================*/ 8940 QCameraExif *QCamera2HardwareInterface::getExifData() 8941 { 8942 QCameraExif *exif = new QCameraExif(); 8943 if (exif == NULL) { 8944 LOGE("No memory for QCameraExif"); 8945 return NULL; 8946 } 8947 8948 int32_t rc = NO_ERROR; 8949 8950 // add exif entries 8951 String8 dateTime, subSecTime; 8952 rc = mParameters.getExifDateTime(dateTime, subSecTime); 8953 if(rc == NO_ERROR) { 8954 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII, 8955 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 8956 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII, 8957 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 8958 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII, 8959 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 8960 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII, 8961 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 8962 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII, 8963 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 8964 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII, 8965 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 8966 } else { 8967 LOGW("getExifDateTime failed"); 8968 } 8969 8970 rat_t focalLength; 8971 rc = mParameters.getExifFocalLength(&focalLength); 8972 if (rc == NO_ERROR) { 8973 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 8974 EXIF_RATIONAL, 8975 1, 8976 (void *)&(focalLength)); 8977 } else { 8978 LOGW("getExifFocalLength failed"); 8979 } 8980 8981 uint16_t isoSpeed = mParameters.getExifIsoSpeed(); 8982 if (getSensorType() != CAM_SENSOR_YUV) { 8983 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 8984 EXIF_SHORT, 8985 1, 8986 (void *)&(isoSpeed)); 8987 } 8988 8989 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 8990 uint32_t count = 0; 8991 8992 /*gps data might not be available */ 8993 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count); 8994 if(rc == NO_ERROR) { 8995 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 8996 EXIF_ASCII, 8997 count, 8998 (void *)gpsProcessingMethod); 8999 } else { 9000 LOGW("getExifGpsProcessingMethod failed"); 9001 } 9002 9003 rat_t latitude[3]; 9004 char latRef[2]; 9005 rc = mParameters.getExifLatitude(latitude, latRef); 9006 if(rc == NO_ERROR) { 9007 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 9008 EXIF_RATIONAL, 9009 3, 9010 (void *)latitude); 9011 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 9012 EXIF_ASCII, 9013 2, 9014 (void *)latRef); 9015 } else { 9016 LOGW("getExifLatitude failed"); 9017 } 9018 9019 rat_t longitude[3]; 9020 char lonRef[2]; 9021 rc = mParameters.getExifLongitude(longitude, lonRef); 9022 if(rc == NO_ERROR) { 9023 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 9024 EXIF_RATIONAL, 9025 3, 9026 (void *)longitude); 9027 9028 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 9029 EXIF_ASCII, 9030 2, 9031 (void *)lonRef); 9032 } else { 9033 LOGW("getExifLongitude failed"); 9034 } 9035 9036 rat_t altitude; 9037 char altRef; 9038 rc = mParameters.getExifAltitude(&altitude, &altRef); 9039 if(rc == NO_ERROR) { 9040 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 9041 EXIF_RATIONAL, 9042 1, 9043 (void *)&(altitude)); 9044 9045 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 9046 EXIF_BYTE, 9047 1, 9048 (void *)&altRef); 9049 } else { 9050 LOGW("getExifAltitude failed"); 9051 } 9052 9053 char gpsDateStamp[20]; 9054 rat_t gpsTimeStamp[3]; 9055 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp); 9056 if(rc == NO_ERROR) { 9057 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 9058 EXIF_ASCII, 9059 (uint32_t)(strlen(gpsDateStamp) + 1), 9060 (void *)gpsDateStamp); 9061 9062 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 9063 EXIF_RATIONAL, 9064 3, 9065 (void *)gpsTimeStamp); 9066 } else { 9067 LOGW("getExifGpsDataTimeStamp failed"); 9068 } 9069 9070 #ifdef ENABLE_MODEL_INFO_EXIF 9071 9072 char value[PROPERTY_VALUE_MAX]; 9073 if (property_get("persist.sys.exif.make", value, "") > 0 || 9074 property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 9075 exif->addEntry(EXIFTAGID_MAKE, 9076 EXIF_ASCII, strlen(value) + 1, (void *)value); 9077 } else { 9078 LOGW("getExifMaker failed"); 9079 } 9080 9081 if (property_get("persist.sys.exif.model", value, "") > 0 || 9082 property_get("ro.product.model", value, "QCAM-AA") > 0) { 9083 exif->addEntry(EXIFTAGID_MODEL, 9084 EXIF_ASCII, strlen(value) + 1, (void *)value); 9085 } else { 9086 LOGW("getExifModel failed"); 9087 } 9088 9089 if (property_get("ro.build.description", value, "QCAM-AA") > 0) { 9090 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII, 9091 (uint32_t)(strlen(value) + 1), (void *)value); 9092 } else { 9093 LOGW("getExifSoftware failed"); 9094 } 9095 9096 #endif 9097 9098 if (mParameters.useJpegExifRotation()) { 9099 int16_t orientation; 9100 switch (mParameters.getJpegExifRotation()) { 9101 case 0: 9102 orientation = 1; 9103 break; 9104 case 90: 9105 orientation = 6; 9106 break; 9107 case 180: 9108 orientation = 3; 9109 break; 9110 case 270: 9111 orientation = 8; 9112 break; 9113 default: 9114 orientation = 1; 9115 break; 9116 } 9117 exif->addEntry(EXIFTAGID_ORIENTATION, 9118 EXIF_SHORT, 9119 1, 9120 (void *)&orientation); 9121 exif->addEntry(EXIFTAGID_TN_ORIENTATION, 9122 EXIF_SHORT, 9123 1, 9124 (void *)&orientation); 9125 } 9126 9127 return exif; 9128 } 9129 9130 /*=========================================================================== 9131 * FUNCTION : setHistogram 9132 * 9133 * DESCRIPTION: set if histogram should be enabled 9134 * 9135 * PARAMETERS : 9136 * @histogram_en : bool flag if histogram should be enabled 9137 * 9138 * RETURN : int32_t type of status 9139 * NO_ERROR -- success 9140 * none-zero failure code 9141 *==========================================================================*/ 9142 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en) 9143 { 9144 return mParameters.setHistogram(histogram_en); 9145 } 9146 9147 /*=========================================================================== 9148 * FUNCTION : setFaceDetection 9149 * 9150 * DESCRIPTION: set if face detection should be enabled 9151 * 9152 * PARAMETERS : 9153 * @enabled : bool flag if face detection should be enabled 9154 * 9155 * RETURN : int32_t type of status 9156 * NO_ERROR -- success 9157 * none-zero failure code 9158 *==========================================================================*/ 9159 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled) 9160 { 9161 return mParameters.setFaceDetection(enabled, true); 9162 } 9163 9164 /*=========================================================================== 9165 * FUNCTION : isCaptureShutterEnabled 9166 * 9167 * DESCRIPTION: Check whether shutter should be triggered immediately after 9168 * capture 9169 * 9170 * PARAMETERS : 9171 * 9172 * RETURN : true - regular capture 9173 * false - other type of capture 9174 *==========================================================================*/ 9175 bool QCamera2HardwareInterface::isCaptureShutterEnabled() 9176 { 9177 char prop[PROPERTY_VALUE_MAX]; 9178 memset(prop, 0, sizeof(prop)); 9179 property_get("persist.camera.feature.shutter", prop, "0"); 9180 int enableShutter = atoi(prop); 9181 return enableShutter == 1; 9182 } 9183 9184 /*=========================================================================== 9185 * FUNCTION : needProcessPreviewFrame 9186 * 9187 * DESCRIPTION: returns whether preview frame need to be displayed 9188 * 9189 * PARAMETERS : 9190 * @frameID : frameID of frame to be processed 9191 * 9192 * RETURN : int32_t type of status 9193 * NO_ERROR -- success 9194 * none-zero failure code 9195 *==========================================================================*/ 9196 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID) 9197 { 9198 return ((m_stateMachine.isPreviewRunning()) && 9199 (!isDisplayFrameToSkip(frameID)) && 9200 (!mParameters.isInstantAECEnabled())); 9201 } 9202 9203 /*=========================================================================== 9204 * FUNCTION : needSendPreviewCallback 9205 * 9206 * DESCRIPTION: returns whether preview frame need to callback to APP 9207 * 9208 * PARAMETERS : 9209 * 9210 * RETURN : true - need preview frame callbck 9211 * false - not send preview frame callback 9212 *==========================================================================*/ 9213 bool QCamera2HardwareInterface::needSendPreviewCallback() 9214 { 9215 return m_stateMachine.isPreviewRunning() 9216 && (mDataCb != NULL) 9217 && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) 9218 && m_stateMachine.isPreviewCallbackNeeded(); 9219 }; 9220 9221 /*=========================================================================== 9222 * FUNCTION : setDisplaySkip 9223 * 9224 * DESCRIPTION: set range of frames to skip for preview 9225 * 9226 * PARAMETERS : 9227 * @enabled : TRUE to start skipping frame to display 9228 FALSE to stop skipping frame to display 9229 * @skipCnt : Number of frame to skip. 0 by default 9230 * 9231 * RETURN : None 9232 *==========================================================================*/ 9233 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt) 9234 { 9235 pthread_mutex_lock(&mGrallocLock); 9236 if (enabled) { 9237 setDisplayFrameSkip(); 9238 setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1); 9239 } else { 9240 setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1)); 9241 } 9242 pthread_mutex_unlock(&mGrallocLock); 9243 } 9244 9245 /*=========================================================================== 9246 * FUNCTION : setDisplayFrameSkip 9247 * 9248 * DESCRIPTION: set range of frames to skip for preview 9249 * 9250 * PARAMETERS : 9251 * @start : frameId to start skip 9252 * @end : frameId to stop skip 9253 * 9254 * RETURN : None 9255 *==========================================================================*/ 9256 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start, 9257 uint32_t end) 9258 { 9259 if (start == 0) { 9260 mFrameSkipStart = 0; 9261 mFrameSkipEnd = 0; 9262 return; 9263 } 9264 if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) { 9265 mFrameSkipStart = start; 9266 } 9267 if ((end == 0) || (end > mFrameSkipEnd)) { 9268 mFrameSkipEnd = end; 9269 } 9270 } 9271 9272 /*=========================================================================== 9273 * FUNCTION : isDisplayFrameToSkip 9274 * 9275 * DESCRIPTION: function to determin if input frame falls under skip range 9276 * 9277 * PARAMETERS : 9278 * @frameId : frameId to verify 9279 * 9280 * RETURN : true : need to skip 9281 * false: no need to skip 9282 *==========================================================================*/ 9283 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId) 9284 { 9285 return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) && 9286 (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE; 9287 } 9288 9289 /*=========================================================================== 9290 * FUNCTION : prepareHardwareForSnapshot 9291 * 9292 * DESCRIPTION: prepare hardware for snapshot, such as LED 9293 * 9294 * PARAMETERS : 9295 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation 9296 * 9297 * RETURN : int32_t type of status 9298 * NO_ERROR -- success 9299 * none-zero failure code 9300 *==========================================================================*/ 9301 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded) 9302 { 9303 ATRACE_CALL(); 9304 LOGI("[KPI Perf]: Send PREPARE SANSPHOT event"); 9305 return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle, 9306 afNeeded); 9307 } 9308 9309 /*=========================================================================== 9310 * FUNCTION : needFDMetadata 9311 * 9312 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel 9313 * 9314 * PARAMETERS : 9315 * @channel_type: channel type 9316 * 9317 * RETURN : true: needed 9318 * false: no need 9319 *==========================================================================*/ 9320 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type) 9321 { 9322 //Note: Currently we only process ZSL channel 9323 bool value = false; 9324 if(channel_type == QCAMERA_CH_TYPE_ZSL){ 9325 //check if FD requirement is enabled 9326 if(mParameters.isSnapshotFDNeeded() && 9327 mParameters.isFaceDetectionEnabled()){ 9328 value = true; 9329 LOGH("Face Detection metadata is required in ZSL mode."); 9330 } 9331 } 9332 9333 return value; 9334 } 9335 9336 /*=========================================================================== 9337 * FUNCTION : deferredWorkRoutine 9338 * 9339 * DESCRIPTION: data process routine that executes deferred tasks 9340 * 9341 * PARAMETERS : 9342 * @data : user data ptr (QCamera2HardwareInterface) 9343 * 9344 * RETURN : None 9345 *==========================================================================*/ 9346 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj) 9347 { 9348 int running = 1; 9349 int ret; 9350 uint8_t is_active = FALSE; 9351 int32_t job_status = 0; 9352 9353 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj; 9354 QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread; 9355 cmdThread->setName("CAM_defrdWrk"); 9356 9357 do { 9358 do { 9359 ret = cam_sem_wait(&cmdThread->cmd_sem); 9360 if (ret != 0 && errno != EINVAL) { 9361 LOGE("cam_sem_wait error (%s)", 9362 strerror(errno)); 9363 return NULL; 9364 } 9365 } while (ret != 0); 9366 9367 // we got notified about new cmd avail in cmd queue 9368 camera_cmd_type_t cmd = cmdThread->getCmd(); 9369 LOGD("cmd: %d", cmd); 9370 switch (cmd) { 9371 case CAMERA_CMD_TYPE_START_DATA_PROC: 9372 LOGH("start data proc"); 9373 is_active = TRUE; 9374 break; 9375 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 9376 LOGH("stop data proc"); 9377 is_active = FALSE; 9378 // signal cmd is completed 9379 cam_sem_post(&cmdThread->sync_sem); 9380 break; 9381 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 9382 { 9383 DefWork *dw = 9384 reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue()); 9385 9386 if ( NULL == dw ) { 9387 LOGE("Invalid deferred work"); 9388 break; 9389 } 9390 9391 switch( dw->cmd ) { 9392 case CMD_DEF_ALLOCATE_BUFF: 9393 { 9394 QCameraChannel * pChannel = dw->args.allocArgs.ch; 9395 9396 if ( NULL == pChannel ) { 9397 LOGE("Invalid deferred work channel"); 9398 job_status = BAD_VALUE; 9399 break; 9400 } 9401 9402 cam_stream_type_t streamType = dw->args.allocArgs.type; 9403 LOGH("Deferred buffer allocation started for stream type: %d", 9404 streamType); 9405 9406 uint32_t iNumOfStreams = pChannel->getNumOfStreams(); 9407 QCameraStream *pStream = NULL; 9408 for ( uint32_t i = 0; i < iNumOfStreams; ++i) { 9409 pStream = pChannel->getStreamByIndex(i); 9410 9411 if ( NULL == pStream ) { 9412 job_status = BAD_VALUE; 9413 break; 9414 } 9415 9416 if ( pStream->isTypeOf(streamType)) { 9417 if ( pStream->allocateBuffers() ) { 9418 LOGE("Error allocating buffers !!!"); 9419 job_status = NO_MEMORY; 9420 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9421 CAMERA_ERROR_UNKNOWN, 0); 9422 } 9423 break; 9424 } 9425 } 9426 } 9427 break; 9428 case CMD_DEF_PPROC_START: 9429 { 9430 int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob); 9431 if (ret != NO_ERROR) { 9432 job_status = ret; 9433 LOGE("PPROC Start failed"); 9434 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9435 CAMERA_ERROR_UNKNOWN, 0); 9436 break; 9437 } 9438 QCameraChannel * pChannel = dw->args.pprocArgs; 9439 assert(pChannel); 9440 9441 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) { 9442 LOGE("cannot start postprocessor"); 9443 job_status = BAD_VALUE; 9444 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9445 CAMERA_ERROR_UNKNOWN, 0); 9446 } 9447 } 9448 break; 9449 case CMD_DEF_METADATA_ALLOC: 9450 { 9451 int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob); 9452 if (ret != NO_ERROR) { 9453 job_status = ret; 9454 LOGE("Metadata alloc failed"); 9455 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9456 CAMERA_ERROR_UNKNOWN, 0); 9457 break; 9458 } 9459 pme->mMetadataMem = new QCameraMetadataStreamMemory( 9460 QCAMERA_ION_USE_CACHE); 9461 9462 if (pme->mMetadataMem == NULL) { 9463 LOGE("Unable to allocate metadata buffers"); 9464 job_status = BAD_VALUE; 9465 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9466 CAMERA_ERROR_UNKNOWN, 0); 9467 } else { 9468 int32_t rc = pme->mMetadataMem->allocate( 9469 dw->args.metadataAllocArgs.bufferCnt, 9470 dw->args.metadataAllocArgs.size, 9471 NON_SECURE); 9472 if (rc < 0) { 9473 delete pme->mMetadataMem; 9474 pme->mMetadataMem = NULL; 9475 } 9476 } 9477 } 9478 break; 9479 case CMD_DEF_CREATE_JPEG_SESSION: 9480 { 9481 QCameraChannel * pChannel = dw->args.pprocArgs; 9482 assert(pChannel); 9483 9484 int32_t ret = pme->getDefJobStatus(pme->mReprocJob); 9485 if (ret != NO_ERROR) { 9486 job_status = ret; 9487 LOGE("Jpeg create failed"); 9488 break; 9489 } 9490 9491 if (pme->m_postprocessor.createJpegSession(pChannel) 9492 != NO_ERROR) { 9493 LOGE("cannot create JPEG session"); 9494 job_status = UNKNOWN_ERROR; 9495 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9496 CAMERA_ERROR_UNKNOWN, 0); 9497 } 9498 } 9499 break; 9500 case CMD_DEF_PPROC_INIT: 9501 { 9502 int32_t rc = NO_ERROR; 9503 9504 jpeg_encode_callback_t jpegEvtHandle = 9505 dw->args.pprocInitArgs.jpeg_cb; 9506 void* user_data = dw->args.pprocInitArgs.user_data; 9507 QCameraPostProcessor *postProcessor = 9508 &(pme->m_postprocessor); 9509 uint32_t cameraId = pme->mCameraId; 9510 cam_capability_t *capability = 9511 gCamCapability[cameraId]; 9512 cam_padding_info_t padding_info; 9513 cam_padding_info_t& cam_capability_padding_info = 9514 capability->padding_info; 9515 9516 if(!pme->mJpegClientHandle) { 9517 rc = pme->initJpegHandle(); 9518 if (rc != NO_ERROR) { 9519 LOGE("Error!! creating JPEG handle failed"); 9520 job_status = UNKNOWN_ERROR; 9521 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9522 CAMERA_ERROR_UNKNOWN, 0); 9523 break; 9524 } 9525 } 9526 LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle); 9527 9528 rc = postProcessor->setJpegHandle(&pme->mJpegHandle, 9529 &pme->mJpegMpoHandle, 9530 pme->mJpegClientHandle); 9531 if (rc != 0) { 9532 LOGE("Error!! set JPEG handle failed"); 9533 job_status = UNKNOWN_ERROR; 9534 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9535 CAMERA_ERROR_UNKNOWN, 0); 9536 break; 9537 } 9538 9539 /* get max pic size for jpeg work buf calculation*/ 9540 rc = postProcessor->init(jpegEvtHandle, user_data); 9541 9542 if (rc != NO_ERROR) { 9543 LOGE("cannot init postprocessor"); 9544 job_status = UNKNOWN_ERROR; 9545 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9546 CAMERA_ERROR_UNKNOWN, 0); 9547 break; 9548 } 9549 9550 // update padding info from jpeg 9551 postProcessor->getJpegPaddingReq(padding_info); 9552 if (cam_capability_padding_info.width_padding < 9553 padding_info.width_padding) { 9554 cam_capability_padding_info.width_padding = 9555 padding_info.width_padding; 9556 } 9557 if (cam_capability_padding_info.height_padding < 9558 padding_info.height_padding) { 9559 cam_capability_padding_info.height_padding = 9560 padding_info.height_padding; 9561 } 9562 if (cam_capability_padding_info.plane_padding != 9563 padding_info.plane_padding) { 9564 cam_capability_padding_info.plane_padding = 9565 mm_stream_calc_lcm( 9566 cam_capability_padding_info.plane_padding, 9567 padding_info.plane_padding); 9568 } 9569 if (cam_capability_padding_info.offset_info.offset_x 9570 != padding_info.offset_info.offset_x) { 9571 cam_capability_padding_info.offset_info.offset_x = 9572 mm_stream_calc_lcm ( 9573 cam_capability_padding_info.offset_info.offset_x, 9574 padding_info.offset_info.offset_x); 9575 } 9576 if (cam_capability_padding_info.offset_info.offset_y 9577 != padding_info.offset_info.offset_y) { 9578 cam_capability_padding_info.offset_info.offset_y = 9579 mm_stream_calc_lcm ( 9580 cam_capability_padding_info.offset_info.offset_y, 9581 padding_info.offset_info.offset_y); 9582 } 9583 } 9584 break; 9585 case CMD_DEF_PARAM_ALLOC: 9586 { 9587 int32_t rc = pme->mParameters.allocate(); 9588 // notify routine would not be initialized by this time. 9589 // So, just update error job status 9590 if (rc != NO_ERROR) { 9591 job_status = rc; 9592 LOGE("Param allocation failed"); 9593 break; 9594 } 9595 } 9596 break; 9597 case CMD_DEF_PARAM_INIT: 9598 { 9599 int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob); 9600 if (rc != NO_ERROR) { 9601 job_status = rc; 9602 LOGE("Param init failed"); 9603 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9604 CAMERA_ERROR_UNKNOWN, 0); 9605 break; 9606 } 9607 9608 uint32_t camId = pme->mCameraId; 9609 cam_capability_t * cap = gCamCapability[camId]; 9610 9611 if (pme->mCameraHandle == NULL) { 9612 LOGE("Camera handle is null"); 9613 job_status = BAD_VALUE; 9614 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9615 CAMERA_ERROR_UNKNOWN, 0); 9616 break; 9617 } 9618 9619 // Now PostProc need calibration data as initialization 9620 // time for jpeg_open and calibration data is a 9621 // get param for now, so params needs to be initialized 9622 // before postproc init 9623 rc = pme->mParameters.init(cap, 9624 pme->mCameraHandle, 9625 pme); 9626 if (rc != 0) { 9627 job_status = UNKNOWN_ERROR; 9628 LOGE("Parameter Initialization failed"); 9629 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9630 CAMERA_ERROR_UNKNOWN, 0); 9631 break; 9632 } 9633 9634 // Get related cam calibration only in 9635 // dual camera mode 9636 if (pme->getRelatedCamSyncInfo()->sync_control == 9637 CAM_SYNC_RELATED_SENSORS_ON) { 9638 rc = pme->mParameters.getRelatedCamCalibration( 9639 &(pme->mJpegMetadata.otp_calibration_data)); 9640 LOGD("Dumping Calibration Data Version Id %f rc %d", 9641 pme->mJpegMetadata.otp_calibration_data.calibration_format_version, 9642 rc); 9643 if (rc != 0) { 9644 job_status = UNKNOWN_ERROR; 9645 LOGE("getRelatedCamCalibration failed"); 9646 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9647 CAMERA_ERROR_UNKNOWN, 0); 9648 break; 9649 } 9650 pme->m_bRelCamCalibValid = true; 9651 } 9652 9653 pme->mJpegMetadata.sensor_mount_angle = 9654 cap->sensor_mount_angle; 9655 pme->mJpegMetadata.default_sensor_flip = FLIP_NONE; 9656 9657 pme->mParameters.setMinPpMask( 9658 cap->qcom_supported_feature_mask); 9659 pme->mExifParams.debug_params = 9660 (mm_jpeg_debug_exif_params_t *) 9661 malloc(sizeof(mm_jpeg_debug_exif_params_t)); 9662 if (!pme->mExifParams.debug_params) { 9663 LOGE("Out of Memory. Allocation failed for " 9664 "3A debug exif params"); 9665 job_status = NO_MEMORY; 9666 pme->sendEvtNotify(CAMERA_MSG_ERROR, 9667 CAMERA_ERROR_UNKNOWN, 0); 9668 break; 9669 } 9670 memset(pme->mExifParams.debug_params, 0, 9671 sizeof(mm_jpeg_debug_exif_params_t)); 9672 } 9673 break; 9674 case CMD_DEF_GENERIC: 9675 { 9676 BackgroundTask *bgTask = dw->args.genericArgs; 9677 job_status = bgTask->bgFunction(bgTask->bgArgs); 9678 } 9679 break; 9680 default: 9681 LOGE("Incorrect command : %d", dw->cmd); 9682 } 9683 9684 pme->dequeueDeferredWork(dw, job_status); 9685 } 9686 break; 9687 case CAMERA_CMD_TYPE_EXIT: 9688 running = 0; 9689 break; 9690 default: 9691 break; 9692 } 9693 } while (running); 9694 9695 return NULL; 9696 } 9697 9698 /*=========================================================================== 9699 * FUNCTION : queueDeferredWork 9700 * 9701 * DESCRIPTION: function which queues deferred tasks 9702 * 9703 * PARAMETERS : 9704 * @cmd : deferred task 9705 * @args : deferred task arguments 9706 * 9707 * RETURN : job id of deferred job 9708 * : 0 in case of error 9709 *==========================================================================*/ 9710 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd, 9711 DeferWorkArgs args) 9712 { 9713 Mutex::Autolock l(mDefLock); 9714 for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) { 9715 if (mDefOngoingJobs[i].mDefJobId == 0) { 9716 DefWork *dw = new DefWork(cmd, sNextJobId, args); 9717 if (!dw) { 9718 LOGE("out of memory."); 9719 return 0; 9720 } 9721 if (mCmdQueue.enqueue(dw)) { 9722 mDefOngoingJobs[i].mDefJobId = sNextJobId++; 9723 mDefOngoingJobs[i].mDefJobStatus = 0; 9724 if (sNextJobId == 0) { // handle overflow 9725 sNextJobId = 1; 9726 } 9727 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, 9728 FALSE, 9729 FALSE); 9730 return mDefOngoingJobs[i].mDefJobId; 9731 } else { 9732 LOGD("Command queue not active! cmd = %d", cmd); 9733 delete dw; 9734 return 0; 9735 } 9736 } 9737 } 9738 return 0; 9739 } 9740 9741 /*=========================================================================== 9742 * FUNCTION : initJpegHandle 9743 * 9744 * DESCRIPTION: Opens JPEG client and gets a handle. 9745 * Sends Dual cam calibration info if present 9746 * 9747 * RETURN : int32_t type of status 9748 * NO_ERROR -- success 9749 * none-zero failure code 9750 *==========================================================================*/ 9751 int32_t QCamera2HardwareInterface::initJpegHandle() { 9752 // Check if JPEG client handle is present 9753 LOGH("E"); 9754 if(!mJpegClientHandle) { 9755 mm_dimension max_size = {0, 0}; 9756 cam_dimension_t size; 9757 9758 mParameters.getMaxPicSize(size); 9759 max_size.w = size.width; 9760 max_size.h = size.height; 9761 9762 if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) { 9763 if (m_bRelCamCalibValid) { 9764 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle, 9765 max_size, &mJpegMetadata); 9766 } else { 9767 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle, 9768 max_size, NULL); 9769 } 9770 } else { 9771 mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL); 9772 } 9773 if (!mJpegClientHandle) { 9774 LOGE("Error !! jpeg_open failed!! "); 9775 return UNKNOWN_ERROR; 9776 } 9777 // Set JPEG initialized as true to signify that this camera 9778 // has initialized the handle 9779 mJpegHandleOwner = true; 9780 } 9781 LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d", 9782 mJpegHandleOwner, mJpegClientHandle, mCameraId); 9783 return NO_ERROR; 9784 } 9785 9786 /*=========================================================================== 9787 * FUNCTION : deinitJpegHandle 9788 * 9789 * DESCRIPTION: Closes JPEG client using handle 9790 * 9791 * RETURN : int32_t type of status 9792 * NO_ERROR -- success 9793 * none-zero failure code 9794 *==========================================================================*/ 9795 int32_t QCamera2HardwareInterface::deinitJpegHandle() { 9796 int32_t rc = NO_ERROR; 9797 LOGH("E"); 9798 // Check if JPEG client handle is present and inited by this camera 9799 if(mJpegHandleOwner && mJpegClientHandle) { 9800 rc = mJpegHandle.close(mJpegClientHandle); 9801 if (rc != NO_ERROR) { 9802 LOGE("Error!! Closing mJpegClientHandle: %d failed", 9803 mJpegClientHandle); 9804 } 9805 memset(&mJpegHandle, 0, sizeof(mJpegHandle)); 9806 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle)); 9807 mJpegHandleOwner = false; 9808 } 9809 mJpegClientHandle = 0; 9810 LOGH("X rc = %d", rc); 9811 return rc; 9812 } 9813 9814 /*=========================================================================== 9815 * FUNCTION : setJpegHandleInfo 9816 * 9817 * DESCRIPTION: sets JPEG client handle info 9818 * 9819 * PARAMETERS: 9820 * @ops : JPEG ops 9821 * @mpo_ops : Jpeg MPO ops 9822 * @pJpegClientHandle : o/p Jpeg Client Handle 9823 * 9824 * RETURN : int32_t type of status 9825 * NO_ERROR -- success 9826 * none-zero failure code 9827 *==========================================================================*/ 9828 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops, 9829 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) { 9830 9831 if (pJpegClientHandle && ops && mpo_ops) { 9832 LOGH("Setting JPEG client handle %d", 9833 pJpegClientHandle); 9834 memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t)); 9835 memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t)); 9836 mJpegClientHandle = pJpegClientHandle; 9837 return NO_ERROR; 9838 } 9839 else { 9840 LOGE("Error!! No Handle found: %d", 9841 pJpegClientHandle); 9842 return BAD_VALUE; 9843 } 9844 } 9845 9846 /*=========================================================================== 9847 * FUNCTION : getJpegHandleInfo 9848 * 9849 * DESCRIPTION: gets JPEG client handle info 9850 * 9851 * PARAMETERS: 9852 * @ops : JPEG ops 9853 * @mpo_ops : Jpeg MPO ops 9854 * @pJpegClientHandle : o/p Jpeg Client Handle 9855 * 9856 * RETURN : int32_t type of status 9857 * NO_ERROR -- success 9858 * none-zero failure code 9859 *==========================================================================*/ 9860 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops, 9861 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) { 9862 9863 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) { 9864 LOGE("Init PProc Deferred work failed"); 9865 return UNKNOWN_ERROR; 9866 } 9867 // Copy JPEG ops if present 9868 if (ops && mpo_ops && pJpegClientHandle) { 9869 memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t)); 9870 memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t)); 9871 *pJpegClientHandle = mJpegClientHandle; 9872 LOGH("Getting JPEG client handle %d", 9873 pJpegClientHandle); 9874 return NO_ERROR; 9875 } else { 9876 return BAD_VALUE; 9877 } 9878 } 9879 9880 /*=========================================================================== 9881 * FUNCTION : dequeueDeferredWork 9882 * 9883 * DESCRIPTION: function which dequeues deferred tasks 9884 * 9885 * PARAMETERS : 9886 * @dw : deferred work 9887 * @jobStatus: deferred task job status 9888 * 9889 * RETURN : int32_t type of status 9890 * NO_ERROR -- success 9891 * none-zero failure code 9892 *==========================================================================*/ 9893 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus) 9894 { 9895 Mutex::Autolock l(mDefLock); 9896 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 9897 if (mDefOngoingJobs[i].mDefJobId == dw->id) { 9898 if (jobStatus != NO_ERROR) { 9899 mDefOngoingJobs[i].mDefJobStatus = jobStatus; 9900 LOGH("updating job status %d for id %d", 9901 jobStatus, dw->id); 9902 } else { 9903 mDefOngoingJobs[i].mDefJobId = 0; 9904 mDefOngoingJobs[i].mDefJobStatus = 0; 9905 } 9906 delete dw; 9907 mDefCond.broadcast(); 9908 return NO_ERROR; 9909 } 9910 } 9911 9912 return UNKNOWN_ERROR; 9913 } 9914 9915 /*=========================================================================== 9916 * FUNCTION : getDefJobStatus 9917 * 9918 * DESCRIPTION: Gets if a deferred task is success/fail 9919 * 9920 * PARAMETERS : 9921 * @job_id : deferred task id 9922 * 9923 * RETURN : NO_ERROR if the job success, otherwise false 9924 * 9925 * PRECONDITION : mDefLock is held by current thread 9926 *==========================================================================*/ 9927 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id) 9928 { 9929 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 9930 if (mDefOngoingJobs[i].mDefJobId == job_id) { 9931 if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) { 9932 LOGE("job_id (%d) was failed", job_id); 9933 return mDefOngoingJobs[i].mDefJobStatus; 9934 } 9935 else 9936 return NO_ERROR; 9937 } 9938 } 9939 return NO_ERROR; 9940 } 9941 9942 9943 /*=========================================================================== 9944 * FUNCTION : checkDeferredWork 9945 * 9946 * DESCRIPTION: checks if a deferred task is in progress 9947 * 9948 * PARAMETERS : 9949 * @job_id : deferred task id 9950 * 9951 * RETURN : true if the task exists, otherwise false 9952 * 9953 * PRECONDITION : mDefLock is held by current thread 9954 *==========================================================================*/ 9955 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id) 9956 { 9957 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) { 9958 if (mDefOngoingJobs[i].mDefJobId == job_id) { 9959 return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus); 9960 } 9961 } 9962 return false; 9963 } 9964 9965 /*=========================================================================== 9966 * FUNCTION : waitDeferredWork 9967 * 9968 * DESCRIPTION: waits for a deferred task to finish 9969 * 9970 * PARAMETERS : 9971 * @job_id : deferred task id 9972 * 9973 * RETURN : int32_t type of status 9974 * NO_ERROR -- success 9975 * none-zero failure code 9976 *==========================================================================*/ 9977 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id) 9978 { 9979 Mutex::Autolock l(mDefLock); 9980 9981 if (job_id == 0) { 9982 LOGD("Invalid job id %d", job_id); 9983 return NO_ERROR; 9984 } 9985 9986 while (checkDeferredWork(job_id) == true ) { 9987 mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT); 9988 } 9989 return getDefJobStatus(job_id); 9990 } 9991 9992 /*=========================================================================== 9993 * FUNCTION : scheduleBackgroundTask 9994 * 9995 * DESCRIPTION: Run a requested task in the deferred thread 9996 * 9997 * PARAMETERS : 9998 * @bgTask : Task to perform in the background 9999 * 10000 * RETURN : job id of deferred job 10001 * : 0 in case of error 10002 *==========================================================================*/ 10003 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask) 10004 { 10005 DeferWorkArgs args; 10006 memset(&args, 0, sizeof(DeferWorkArgs)); 10007 args.genericArgs = bgTask; 10008 10009 return queueDeferredWork(CMD_DEF_GENERIC, args); 10010 } 10011 10012 /*=========================================================================== 10013 * FUNCTION : waitForBackgroundTask 10014 * 10015 * DESCRIPTION: Wait for a background task to complete 10016 * 10017 * PARAMETERS : 10018 * @taskId : Task id to wait for 10019 * 10020 * RETURN : int32_t type of status 10021 * NO_ERROR -- success 10022 * none-zero failure code 10023 *==========================================================================*/ 10024 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId) 10025 { 10026 return waitDeferredWork(taskId); 10027 } 10028 10029 /*=========================================================================== 10030 * FUNCTION : needDeferedAllocation 10031 * 10032 * DESCRIPTION: Function to decide background task for streams 10033 * 10034 * PARAMETERS : 10035 * @stream_type : stream type 10036 * 10037 * RETURN : true - if background task is needed 10038 * false - if background task is NOT needed 10039 *==========================================================================*/ 10040 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type) 10041 { 10042 if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL) 10043 || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) { 10044 return FALSE; 10045 } 10046 10047 if ((stream_type == CAM_STREAM_TYPE_RAW) 10048 && (mParameters.getofflineRAW())) { 10049 return FALSE; 10050 } 10051 10052 if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT) 10053 && (!mParameters.getRecordingHintValue())){ 10054 return TRUE; 10055 } 10056 10057 if ((stream_type == CAM_STREAM_TYPE_PREVIEW) 10058 || (stream_type == CAM_STREAM_TYPE_METADATA) 10059 || (stream_type == CAM_STREAM_TYPE_RAW) 10060 || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) { 10061 return TRUE; 10062 } 10063 10064 if (stream_type == CAM_STREAM_TYPE_VIDEO) { 10065 return FALSE; 10066 } 10067 return FALSE; 10068 } 10069 10070 /*=========================================================================== 10071 * FUNCTION : isRegularCapture 10072 * 10073 * DESCRIPTION: Check configuration for regular catpure 10074 * 10075 * PARAMETERS : 10076 * 10077 * RETURN : true - regular capture 10078 * false - other type of capture 10079 *==========================================================================*/ 10080 bool QCamera2HardwareInterface::isRegularCapture() 10081 { 10082 bool ret = false; 10083 10084 if (numOfSnapshotsExpected() == 1 && 10085 !isLongshotEnabled() && 10086 !mParameters.isHDREnabled() && 10087 !mParameters.getRecordingHintValue() && 10088 !isZSLMode() && !mParameters.getofflineRAW()) { 10089 ret = true; 10090 } 10091 return ret; 10092 } 10093 10094 /*=========================================================================== 10095 * FUNCTION : getLogLevel 10096 * 10097 * DESCRIPTION: Reads the log level property into a variable 10098 * 10099 * PARAMETERS : 10100 * None 10101 * 10102 * RETURN : 10103 * None 10104 *==========================================================================*/ 10105 void QCamera2HardwareInterface::getLogLevel() 10106 { 10107 char prop[PROPERTY_VALUE_MAX]; 10108 10109 property_get("persist.camera.kpi.debug", prop, "1"); 10110 gKpiDebugLevel = atoi(prop); 10111 return; 10112 } 10113 10114 /*=========================================================================== 10115 * FUNCTION : getSensorType 10116 * 10117 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer 10118 * 10119 * PARAMETERS : 10120 * None 10121 * 10122 * RETURN : Type of sensor - bayer or YUV 10123 * 10124 *==========================================================================*/ 10125 cam_sensor_t QCamera2HardwareInterface::getSensorType() 10126 { 10127 return gCamCapability[mCameraId]->sensor_type.sens_type; 10128 } 10129 10130 /*=========================================================================== 10131 * FUNCTION : startRAWChannel 10132 * 10133 * DESCRIPTION: start RAW Channel 10134 * 10135 * PARAMETERS : 10136 * @pChannel : Src channel to link this RAW channel. 10137 * 10138 * RETURN : int32_t type of status 10139 * NO_ERROR -- success 10140 * none-zero failure code 10141 *==========================================================================*/ 10142 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel) 10143 { 10144 int32_t rc = NO_ERROR; 10145 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW]; 10146 if ((NULL != pChannel) && (mParameters.getofflineRAW())) { 10147 // Find and try to link a metadata stream from preview channel 10148 QCameraStream *pMetaStream = NULL; 10149 10150 if (pMetaChannel != NULL) { 10151 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 10152 QCameraStream *pStream = NULL; 10153 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 10154 pStream = pMetaChannel->getStreamByIndex(i); 10155 if ((NULL != pStream) && 10156 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) { 10157 pMetaStream = pStream; 10158 break; 10159 } 10160 } 10161 10162 if (NULL != pMetaStream) { 10163 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 10164 if (NO_ERROR != rc) { 10165 LOGE("Metadata stream link failed %d", rc); 10166 } 10167 } 10168 } 10169 rc = pChannel->start(); 10170 } 10171 return rc; 10172 } 10173 10174 /*=========================================================================== 10175 * FUNCTION : startRecording 10176 * 10177 * DESCRIPTION: start recording impl 10178 * 10179 * PARAMETERS : none 10180 * 10181 * RETURN : int32_t type of status 10182 * NO_ERROR -- success 10183 * none-zero failure code 10184 *==========================================================================*/ 10185 int32_t QCamera2HardwareInterface::stopRAWChannel() 10186 { 10187 int32_t rc = NO_ERROR; 10188 rc = stopChannel(QCAMERA_CH_TYPE_RAW); 10189 return rc; 10190 } 10191 10192 /*=========================================================================== 10193 * FUNCTION : isLowPowerMode 10194 * 10195 * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording 10196 * 10197 * PARAMETERS : 10198 * None 10199 * 10200 * RETURN : TRUE/FALSE 10201 * 10202 *==========================================================================*/ 10203 bool QCamera2HardwareInterface::isLowPowerMode() 10204 { 10205 cam_dimension_t dim; 10206 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim); 10207 10208 char prop[PROPERTY_VALUE_MAX]; 10209 property_get("camera.lowpower.record.enable", prop, "0"); 10210 int enable = atoi(prop); 10211 10212 //Enable low power mode if : 10213 //1. Video resolution is 2k (2048x1080) or above and 10214 //2. camera.lowpower.record.enable is set 10215 10216 bool isLowpower = mParameters.getRecordingHintValue() && enable 10217 && ((dim.width * dim.height) >= (2048 * 1080)); 10218 return isLowpower; 10219 } 10220 10221 }; // namespace qcamera 10222