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