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