1 /* Copyright (c) 2012-2015, The Linux Foundataion. 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 #define ATRACE_TAG ATRACE_TAG_CAMERA 32 33 #include <utils/Log.h> 34 #include <cutils/properties.h> 35 #include <hardware/camera.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <utils/Errors.h> 39 #include <utils/Trace.h> 40 #include <gralloc_priv.h> 41 42 #include "QCamera2HWI.h" 43 #include "QCameraMem.h" 44 45 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \ 46 ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset) 47 #define CAMERA_MIN_STREAMING_BUFFERS 3 48 #define EXTRA_ZSL_PREVIEW_STREAM_BUF 2 49 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2 50 #define CAMERA_MIN_VIDEO_BUFFERS 9 51 #define CAMERA_LONGSHOT_STAGES 4 52 #define CAMERA_MIN_VIDEO_BATCH_BUFFERS 6 53 54 //This multiplier signifies extra buffers that we need to allocate 55 //for the output of pproc 56 #define CAMERA_PPROC_OUT_BUFFER_MULTIPLIER 2 57 58 59 #define HDR_CONFIDENCE_THRESHOLD 0.4 60 61 namespace qcamera { 62 63 cam_capability_t *gCamCaps[MM_CAMERA_MAX_NUM_SENSORS]; 64 static pthread_mutex_t g_camlock = PTHREAD_MUTEX_INITIALIZER; 65 volatile uint32_t gCamHalLogLevel = 1; 66 67 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = { 68 .set_preview_window = QCamera2HardwareInterface::set_preview_window, 69 .set_callbacks = QCamera2HardwareInterface::set_CallBacks, 70 .enable_msg_type = QCamera2HardwareInterface::enable_msg_type, 71 .disable_msg_type = QCamera2HardwareInterface::disable_msg_type, 72 .msg_type_enabled = QCamera2HardwareInterface::msg_type_enabled, 73 74 .start_preview = QCamera2HardwareInterface::start_preview, 75 .stop_preview = QCamera2HardwareInterface::stop_preview, 76 .preview_enabled = QCamera2HardwareInterface::preview_enabled, 77 .store_meta_data_in_buffers = QCamera2HardwareInterface::store_meta_data_in_buffers, 78 79 .start_recording = QCamera2HardwareInterface::start_recording, 80 .stop_recording = QCamera2HardwareInterface::stop_recording, 81 .recording_enabled = QCamera2HardwareInterface::recording_enabled, 82 .release_recording_frame = QCamera2HardwareInterface::release_recording_frame, 83 84 .auto_focus = QCamera2HardwareInterface::auto_focus, 85 .cancel_auto_focus = QCamera2HardwareInterface::cancel_auto_focus, 86 87 .take_picture = QCamera2HardwareInterface::take_picture, 88 .cancel_picture = QCamera2HardwareInterface::cancel_picture, 89 90 .set_parameters = QCamera2HardwareInterface::set_parameters, 91 .get_parameters = QCamera2HardwareInterface::get_parameters, 92 .put_parameters = QCamera2HardwareInterface::put_parameters, 93 .send_command = QCamera2HardwareInterface::send_command, 94 95 .release = QCamera2HardwareInterface::release, 96 .dump = QCamera2HardwareInterface::dump, 97 }; 98 99 /*=========================================================================== 100 * FUNCTION : set_preview_window 101 * 102 * DESCRIPTION: set preview window. 103 * 104 * PARAMETERS : 105 * @device : ptr to camera device struct 106 * @window : window ops table 107 * 108 * RETURN : int32_t type of status 109 * NO_ERROR -- success 110 * none-zero failure code 111 *==========================================================================*/ 112 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device, 113 struct preview_stream_ops *window) 114 { 115 ATRACE_CALL(); 116 int rc = NO_ERROR; 117 QCamera2HardwareInterface *hw = 118 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 119 if (!hw) { 120 ALOGE("%s: NULL camera device", __func__); 121 return BAD_VALUE; 122 } 123 124 hw->lockAPI(); 125 qcamera_api_result_t apiResult; 126 rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window); 127 if (rc == NO_ERROR) { 128 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult); 129 rc = apiResult.status; 130 } 131 hw->unlockAPI(); 132 133 return rc; 134 } 135 136 /*=========================================================================== 137 * FUNCTION : set_CallBacks 138 * 139 * DESCRIPTION: set callbacks for notify and data 140 * 141 * PARAMETERS : 142 * @device : ptr to camera device struct 143 * @notify_cb : notify cb 144 * @data_cb : data cb 145 * @data_cb_timestamp : video data cd with timestamp 146 * @get_memory : ops table for request gralloc memory 147 * @user : user data ptr 148 * 149 * RETURN : none 150 *==========================================================================*/ 151 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device, 152 camera_notify_callback notify_cb, 153 camera_data_callback data_cb, 154 camera_data_timestamp_callback data_cb_timestamp, 155 camera_request_memory get_memory, 156 void *user) 157 { 158 ATRACE_CALL(); 159 QCamera2HardwareInterface *hw = 160 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 161 if (!hw) { 162 ALOGE("NULL camera device"); 163 return; 164 } 165 166 qcamera_sm_evt_setcb_payload_t payload; 167 payload.notify_cb = notify_cb; 168 payload.data_cb = data_cb; 169 payload.data_cb_timestamp = data_cb_timestamp; 170 payload.get_memory = get_memory; 171 payload.user = user; 172 173 hw->lockAPI(); 174 qcamera_api_result_t apiResult; 175 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload); 176 if (rc == NO_ERROR) { 177 hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult); 178 } 179 hw->unlockAPI(); 180 } 181 182 /*=========================================================================== 183 * FUNCTION : enable_msg_type 184 * 185 * DESCRIPTION: enable certain msg type 186 * 187 * PARAMETERS : 188 * @device : ptr to camera device struct 189 * @msg_type : msg type mask 190 * 191 * RETURN : none 192 *==========================================================================*/ 193 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type) 194 { 195 ATRACE_CALL(); 196 QCamera2HardwareInterface *hw = 197 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 198 if (!hw) { 199 ALOGE("NULL camera device"); 200 return; 201 } 202 hw->lockAPI(); 203 qcamera_api_result_t apiResult; 204 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type); 205 if (rc == NO_ERROR) { 206 hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult); 207 } 208 hw->unlockAPI(); 209 } 210 211 /*=========================================================================== 212 * FUNCTION : disable_msg_type 213 * 214 * DESCRIPTION: disable certain msg type 215 * 216 * PARAMETERS : 217 * @device : ptr to camera device struct 218 * @msg_type : msg type mask 219 * 220 * RETURN : none 221 *==========================================================================*/ 222 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type) 223 { 224 ATRACE_CALL(); 225 QCamera2HardwareInterface *hw = 226 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 227 if (!hw) { 228 ALOGE("NULL camera device"); 229 return; 230 } 231 hw->lockAPI(); 232 qcamera_api_result_t apiResult; 233 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type); 234 if (rc == NO_ERROR) { 235 hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult); 236 } 237 hw->unlockAPI(); 238 } 239 240 /*=========================================================================== 241 * FUNCTION : msg_type_enabled 242 * 243 * DESCRIPTION: if certain msg type is enabled 244 * 245 * PARAMETERS : 246 * @device : ptr to camera device struct 247 * @msg_type : msg type mask 248 * 249 * RETURN : 1 -- enabled 250 * 0 -- not enabled 251 *==========================================================================*/ 252 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type) 253 { 254 ATRACE_CALL(); 255 int ret = NO_ERROR; 256 QCamera2HardwareInterface *hw = 257 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 258 if (!hw) { 259 ALOGE("NULL camera device"); 260 return BAD_VALUE; 261 } 262 hw->lockAPI(); 263 qcamera_api_result_t apiResult; 264 ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type); 265 if (ret == NO_ERROR) { 266 hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult); 267 ret = apiResult.enabled; 268 } 269 hw->unlockAPI(); 270 271 return ret; 272 } 273 274 /*=========================================================================== 275 * FUNCTION : start_preview 276 * 277 * DESCRIPTION: start preview 278 * 279 * PARAMETERS : 280 * @device : ptr to camera device struct 281 * 282 * RETURN : int32_t type of status 283 * NO_ERROR -- success 284 * none-zero failure code 285 *==========================================================================*/ 286 int QCamera2HardwareInterface::start_preview(struct camera_device *device) 287 { 288 ATRACE_CALL(); 289 int ret = NO_ERROR; 290 QCamera2HardwareInterface *hw = 291 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 292 if (!hw) { 293 ALOGE("NULL camera device"); 294 return BAD_VALUE; 295 } 296 ALOGI("[KPI Perf] %s: E PROFILE_START_PREVIEW", __func__); 297 hw->m_perfLock.lock_acq(); 298 hw->lockAPI(); 299 qcamera_api_result_t apiResult; 300 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW; 301 if (hw->isNoDisplayMode()) { 302 evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW; 303 } 304 ret = hw->processAPI(evt, NULL); 305 if (ret == NO_ERROR) { 306 hw->waitAPIResult(evt, &apiResult); 307 ret = apiResult.status; 308 } 309 hw->unlockAPI(); 310 hw->m_bPreviewStarted = true; 311 ALOGI("[KPI Perf] %s: X", __func__); 312 hw->m_perfLock.lock_rel(); 313 return ret; 314 } 315 316 /*=========================================================================== 317 * FUNCTION : stop_preview 318 * 319 * DESCRIPTION: stop preview 320 * 321 * PARAMETERS : 322 * @device : ptr to camera device struct 323 * 324 * RETURN : none 325 *==========================================================================*/ 326 void QCamera2HardwareInterface::stop_preview(struct camera_device *device) 327 { 328 ATRACE_CALL(); 329 QCamera2HardwareInterface *hw = 330 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 331 if (!hw) { 332 ALOGE("NULL camera device"); 333 return; 334 } 335 ALOGI("[KPI Perf] %s: E PROFILE_STOP_PREVIEW", __func__); 336 hw->m_perfLock.lock_acq(); 337 hw->lockAPI(); 338 qcamera_api_result_t apiResult; 339 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL); 340 if (ret == NO_ERROR) { 341 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult); 342 } 343 hw->unlockAPI(); 344 hw->m_perfLock.lock_rel(); 345 ALOGI("[KPI Perf] %s: X", __func__); 346 } 347 348 /*=========================================================================== 349 * FUNCTION : preview_enabled 350 * 351 * DESCRIPTION: if preview is running 352 * 353 * PARAMETERS : 354 * @device : ptr to camera device struct 355 * 356 * RETURN : 1 -- running 357 * 0 -- not running 358 *==========================================================================*/ 359 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device) 360 { 361 ATRACE_CALL(); 362 int ret = NO_ERROR; 363 QCamera2HardwareInterface *hw = 364 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 365 if (!hw) { 366 ALOGE("NULL camera device"); 367 return BAD_VALUE; 368 } 369 370 hw->lockAPI(); 371 qcamera_api_result_t apiResult; 372 ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL); 373 if (ret == NO_ERROR) { 374 hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult); 375 ret = apiResult.enabled; 376 } 377 hw->unlockAPI(); 378 379 return ret; 380 } 381 382 /*=========================================================================== 383 * FUNCTION : store_meta_data_in_buffers 384 * 385 * DESCRIPTION: if need to store meta data in buffers for video frame 386 * 387 * PARAMETERS : 388 * @device : ptr to camera device struct 389 * @enable : flag if enable 390 * 391 * RETURN : int32_t type of status 392 * NO_ERROR -- success 393 * none-zero failure code 394 *==========================================================================*/ 395 int QCamera2HardwareInterface::store_meta_data_in_buffers( 396 struct camera_device *device, int enable) 397 { 398 int ret = NO_ERROR; 399 QCamera2HardwareInterface *hw = 400 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 401 if (!hw) { 402 ALOGE("NULL camera device"); 403 return BAD_VALUE; 404 } 405 406 hw->lockAPI(); 407 qcamera_api_result_t apiResult; 408 ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable); 409 if (ret == NO_ERROR) { 410 hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult); 411 ret = apiResult.status; 412 } 413 hw->unlockAPI(); 414 415 return ret; 416 } 417 418 /*=========================================================================== 419 * FUNCTION : start_recording 420 * 421 * DESCRIPTION: start recording 422 * 423 * PARAMETERS : 424 * @device : ptr to camera device struct 425 * 426 * RETURN : int32_t type of status 427 * NO_ERROR -- success 428 * none-zero failure code 429 *==========================================================================*/ 430 int QCamera2HardwareInterface::start_recording(struct camera_device *device) 431 { 432 ATRACE_CALL(); 433 int ret = NO_ERROR; 434 QCamera2HardwareInterface *hw = 435 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 436 if (!hw) { 437 ALOGE("NULL camera device"); 438 return BAD_VALUE; 439 } 440 ALOGI("[KPI Perf] %s: E PROFILE_START_RECORDING", __func__); 441 hw->lockAPI(); 442 qcamera_api_result_t apiResult; 443 ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL); 444 if (ret == NO_ERROR) { 445 hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult); 446 ret = apiResult.status; 447 } 448 hw->unlockAPI(); 449 hw->m_bRecordStarted = true; 450 ALOGI("[KPI Perf] %s: X", __func__); 451 return ret; 452 } 453 454 /*=========================================================================== 455 * FUNCTION : stop_recording 456 * 457 * DESCRIPTION: stop recording 458 * 459 * PARAMETERS : 460 * @device : ptr to camera device struct 461 * 462 * RETURN : none 463 *==========================================================================*/ 464 void QCamera2HardwareInterface::stop_recording(struct camera_device *device) 465 { 466 ATRACE_CALL(); 467 QCamera2HardwareInterface *hw = 468 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 469 if (!hw) { 470 ALOGE("NULL camera device"); 471 return; 472 } 473 ALOGI("[KPI Perf] %s: E PROFILE_STOP_RECORDING", __func__); 474 hw->lockAPI(); 475 qcamera_api_result_t apiResult; 476 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL); 477 if (ret == NO_ERROR) { 478 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult); 479 } 480 hw->unlockAPI(); 481 ALOGI("[KPI Perf] %s: X", __func__); 482 } 483 484 /*=========================================================================== 485 * FUNCTION : recording_enabled 486 * 487 * DESCRIPTION: if recording is running 488 * 489 * PARAMETERS : 490 * @device : ptr to camera device struct 491 * 492 * RETURN : 1 -- running 493 * 0 -- not running 494 *==========================================================================*/ 495 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device) 496 { 497 ATRACE_CALL(); 498 int ret = NO_ERROR; 499 QCamera2HardwareInterface *hw = 500 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 501 if (!hw) { 502 ALOGE("NULL camera device"); 503 return BAD_VALUE; 504 } 505 hw->lockAPI(); 506 qcamera_api_result_t apiResult; 507 ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL); 508 if (ret == NO_ERROR) { 509 hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult); 510 ret = apiResult.enabled; 511 } 512 hw->unlockAPI(); 513 514 return ret; 515 } 516 517 /*=========================================================================== 518 * FUNCTION : release_recording_frame 519 * 520 * DESCRIPTION: return recording frame back 521 * 522 * PARAMETERS : 523 * @device : ptr to camera device struct 524 * @opaque : ptr to frame to be returned 525 * 526 * RETURN : none 527 *==========================================================================*/ 528 void QCamera2HardwareInterface::release_recording_frame( 529 struct camera_device *device, const void *opaque) 530 { 531 ATRACE_CALL(); 532 QCamera2HardwareInterface *hw = 533 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 534 if (!hw) { 535 ALOGE("NULL camera device"); 536 return; 537 } 538 if (!opaque) { 539 ALOGE("%s: Error!! Frame info is NULL", __func__); 540 return; 541 } 542 CDBG_HIGH("%s: E", __func__); 543 hw->lockAPI(); 544 qcamera_api_result_t apiResult; 545 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque); 546 if (ret == NO_ERROR) { 547 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult); 548 } 549 hw->unlockAPI(); 550 CDBG_HIGH("%s: X", __func__); 551 } 552 553 /*=========================================================================== 554 * FUNCTION : auto_focus 555 * 556 * DESCRIPTION: start auto focus 557 * 558 * PARAMETERS : 559 * @device : ptr to camera device struct 560 * 561 * RETURN : int32_t type of status 562 * NO_ERROR -- success 563 * none-zero failure code 564 *==========================================================================*/ 565 int QCamera2HardwareInterface::auto_focus(struct camera_device *device) 566 { 567 ATRACE_INT("Camera:AutoFocus", 1); 568 int ret = NO_ERROR; 569 QCamera2HardwareInterface *hw = 570 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 571 if (!hw) { 572 ALOGE("NULL camera device"); 573 return BAD_VALUE; 574 } 575 CDBG_HIGH("[KPI Perf] %s : E PROFILE_AUTO_FOCUS", __func__); 576 hw->lockAPI(); 577 qcamera_api_result_t apiResult; 578 ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL); 579 if (ret == NO_ERROR) { 580 hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult); 581 ret = apiResult.status; 582 } 583 hw->unlockAPI(); 584 CDBG_HIGH("[KPI Perf] %s : X", __func__); 585 586 return ret; 587 } 588 589 /*=========================================================================== 590 * FUNCTION : cancel_auto_focus 591 * 592 * DESCRIPTION: cancel auto focus 593 * 594 * PARAMETERS : 595 * @device : ptr to camera device struct 596 * 597 * RETURN : int32_t type of status 598 * NO_ERROR -- success 599 * none-zero failure code 600 *==========================================================================*/ 601 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device) 602 { 603 ATRACE_CALL(); 604 int ret = NO_ERROR; 605 QCamera2HardwareInterface *hw = 606 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 607 if (!hw) { 608 ALOGE("NULL camera device"); 609 return BAD_VALUE; 610 } 611 ALOGE("[KPI Perf] %s : E PROFILE_CANCEL_AUTO_FOCUS", __func__); 612 hw->lockAPI(); 613 qcamera_api_result_t apiResult; 614 ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL); 615 if (ret == NO_ERROR) { 616 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult); 617 ret = apiResult.status; 618 } 619 hw->unlockAPI(); 620 CDBG_HIGH("[KPI Perf] %s : X", __func__); 621 return ret; 622 } 623 624 /*=========================================================================== 625 * FUNCTION : take_picture 626 * 627 * DESCRIPTION: take picture 628 * 629 * PARAMETERS : 630 * @device : ptr to camera device struct 631 * 632 * RETURN : int32_t type of status 633 * NO_ERROR -- success 634 * none-zero failure code 635 *==========================================================================*/ 636 int QCamera2HardwareInterface::take_picture(struct camera_device *device) 637 { 638 ATRACE_CALL(); 639 int ret = NO_ERROR; 640 QCamera2HardwareInterface *hw = 641 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 642 if (!hw) { 643 ALOGE("NULL camera device"); 644 return BAD_VALUE; 645 } 646 ALOGI("[KPI Perf] %s: E PROFILE_TAKE_PICTURE", __func__); 647 hw->lockAPI(); 648 if (!hw->mLongshotEnabled) { 649 hw->m_perfLock.lock_acq(); 650 } 651 qcamera_api_result_t apiResult; 652 653 /** Added support for Retro-active Frames: 654 * takePicture() is called before preparing Snapshot to indicate the 655 * mm-camera-channel to pick up legacy frames even 656 * before LED estimation is triggered. 657 */ 658 659 CDBG_HIGH("%s: [ZSL Retro]: numRetroSnap %d, isLiveSnap %d, isZSL %d, isHDR %d", 660 __func__, hw->mParameters.getNumOfRetroSnapshots(), 661 hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode()); 662 663 // Check for Retro-active Frames 664 if ((hw->mParameters.getNumOfRetroSnapshots() > 0) && 665 !hw->isLiveSnapshot() && hw->isZSLMode() && 666 !hw->isHDRMode() && !hw->isLongshotEnabled()) { 667 // Set Retro Picture Mode 668 hw->setRetroPicture(1); 669 hw->m_bLedAfAecLock = 0; 670 CDBG_HIGH("%s: [ZSL Retro] mode", __func__); 671 672 /* Call take Picture for total number of snapshots required. 673 This includes the number of retro frames and normal frames */ 674 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 675 if (ret == NO_ERROR) { 676 // Wait for retro frames, before calling prepare snapshot 677 CDBG_HIGH("%s:[ZSL Retro] Wait for Retro frames to be done", __func__); 678 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 679 ret = apiResult.status; 680 } 681 682 683 // Start Preparing for normal Frames 684 CDBG_HIGH("%s: [ZSL Retro] Start Prepare Snapshot", __func__); 685 /* Prepare snapshot in case LED needs to be flashed */ 686 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 687 if (ret == NO_ERROR) { 688 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 689 ret = apiResult.status; 690 CDBG_HIGH("%s: [ZSL Retro] Prep Snapshot done", __func__); 691 } 692 hw->mPrepSnapRun = true; 693 } 694 else { 695 hw->setRetroPicture(0); 696 CDBG_HIGH("%s: [ZSL Retro] Normal Pic Taking Mode", __func__); 697 698 CDBG_HIGH("%s: [ZSL Retro] Start Prepare Snapshot", __func__); 699 /* Prepare snapshot in case LED needs to be flashed */ 700 if (hw->mFlashNeeded == 1 || hw->mParameters.isChromaFlashEnabled()) { 701 // Start Preparing for normal Frames 702 CDBG_HIGH("%s: [ZSL Retro] Start Prepare Snapshot", __func__); 703 /* Prepare snapshot in case LED needs to be flashed */ 704 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 705 if (ret == NO_ERROR) { 706 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 707 ret = apiResult.status; 708 CDBG_HIGH("%s: [ZSL Retro] Prep Snapshot done", __func__); 709 710 } 711 hw->mPrepSnapRun = true; 712 } 713 /* Regardless what the result value for prepare_snapshot, 714 * go ahead with capture anyway. Just like the way autofocus 715 * is handled in capture case. */ 716 /* capture */ 717 CDBG_HIGH("%s: [ZSL Retro] Capturing normal frames", __func__); 718 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 719 if (ret == NO_ERROR) { 720 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 721 ret = apiResult.status; 722 } 723 } 724 hw->unlockAPI(); 725 ALOGI("[KPI Perf] %s: X", __func__); 726 return ret; 727 } 728 729 /*=========================================================================== 730 * FUNCTION : cancel_picture 731 * 732 * DESCRIPTION: cancel current take picture request 733 * 734 * PARAMETERS : 735 * @device : ptr to camera device struct 736 * 737 * RETURN : int32_t type of status 738 * NO_ERROR -- success 739 * none-zero failure code 740 *==========================================================================*/ 741 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device) 742 { 743 ATRACE_CALL(); 744 int ret = NO_ERROR; 745 QCamera2HardwareInterface *hw = 746 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 747 if (!hw) { 748 ALOGE("NULL camera device"); 749 return BAD_VALUE; 750 } 751 hw->lockAPI(); 752 qcamera_api_result_t apiResult; 753 ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 754 if (ret == NO_ERROR) { 755 hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult); 756 ret = apiResult.status; 757 } 758 hw->unlockAPI(); 759 760 return ret; 761 } 762 763 /*=========================================================================== 764 * FUNCTION : set_parameters 765 * 766 * DESCRIPTION: set camera parameters 767 * 768 * PARAMETERS : 769 * @device : ptr to camera device struct 770 * @parms : string of packed parameters 771 * 772 * RETURN : int32_t type of status 773 * NO_ERROR -- success 774 * none-zero failure code 775 *==========================================================================*/ 776 int QCamera2HardwareInterface::set_parameters(struct camera_device *device, 777 const char *parms) 778 { 779 ATRACE_CALL(); 780 int ret = NO_ERROR; 781 QCamera2HardwareInterface *hw = 782 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 783 if (!hw) { 784 ALOGE("NULL camera device"); 785 return BAD_VALUE; 786 } 787 hw->lockAPI(); 788 qcamera_api_result_t apiResult; 789 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms); 790 if (ret == NO_ERROR) { 791 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult); 792 ret = apiResult.status; 793 } 794 hw->unlockAPI(); 795 796 return ret; 797 } 798 799 /*=========================================================================== 800 * FUNCTION : get_parameters 801 * 802 * DESCRIPTION: query camera parameters 803 * 804 * PARAMETERS : 805 * @device : ptr to camera device struct 806 * 807 * RETURN : packed parameters in a string 808 *==========================================================================*/ 809 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device) 810 { 811 ATRACE_CALL(); 812 char *ret = NULL; 813 QCamera2HardwareInterface *hw = 814 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 815 if (!hw) { 816 ALOGE("NULL camera device"); 817 return NULL; 818 } 819 hw->lockAPI(); 820 qcamera_api_result_t apiResult; 821 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL); 822 if (rc == NO_ERROR) { 823 hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult); 824 ret = apiResult.params; 825 } 826 hw->unlockAPI(); 827 828 return ret; 829 } 830 831 /*=========================================================================== 832 * FUNCTION : put_parameters 833 * 834 * DESCRIPTION: return camera parameters string back to HAL 835 * 836 * PARAMETERS : 837 * @device : ptr to camera device struct 838 * @parm : ptr to parameter string to be returned 839 * 840 * RETURN : none 841 *==========================================================================*/ 842 void QCamera2HardwareInterface::put_parameters(struct camera_device *device, 843 char *parm) 844 { 845 ATRACE_CALL(); 846 QCamera2HardwareInterface *hw = 847 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 848 if (!hw) { 849 ALOGE("NULL camera device"); 850 return; 851 } 852 hw->lockAPI(); 853 qcamera_api_result_t apiResult; 854 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm); 855 if (ret == NO_ERROR) { 856 hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult); 857 } 858 hw->unlockAPI(); 859 } 860 861 /*=========================================================================== 862 * FUNCTION : send_command 863 * 864 * DESCRIPTION: command to be executed 865 * 866 * PARAMETERS : 867 * @device : ptr to camera device struct 868 * @cmd : cmd to be executed 869 * @arg1 : ptr to optional argument1 870 * @arg2 : ptr to optional argument2 871 * 872 * RETURN : int32_t type of status 873 * NO_ERROR -- success 874 * none-zero failure code 875 *==========================================================================*/ 876 int QCamera2HardwareInterface::send_command(struct camera_device *device, 877 int32_t cmd, 878 int32_t arg1, 879 int32_t arg2) 880 { 881 ATRACE_CALL(); 882 int ret = NO_ERROR; 883 QCamera2HardwareInterface *hw = 884 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 885 if (!hw) { 886 ALOGE("NULL camera device"); 887 return BAD_VALUE; 888 } 889 890 qcamera_sm_evt_command_payload_t payload; 891 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t)); 892 payload.cmd = cmd; 893 payload.arg1 = arg1; 894 payload.arg2 = arg2; 895 hw->lockAPI(); 896 qcamera_api_result_t apiResult; 897 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload); 898 if (ret == NO_ERROR) { 899 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult); 900 ret = apiResult.status; 901 } 902 hw->unlockAPI(); 903 904 return ret; 905 } 906 907 /*=========================================================================== 908 * FUNCTION : release 909 * 910 * DESCRIPTION: release camera resource 911 * 912 * PARAMETERS : 913 * @device : ptr to camera device struct 914 * 915 * RETURN : none 916 *==========================================================================*/ 917 void QCamera2HardwareInterface::release(struct camera_device *device) 918 { 919 ATRACE_CALL(); 920 QCamera2HardwareInterface *hw = 921 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 922 if (!hw) { 923 ALOGE("NULL camera device"); 924 return; 925 } 926 hw->lockAPI(); 927 qcamera_api_result_t apiResult; 928 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL); 929 if (ret == NO_ERROR) { 930 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult); 931 } 932 hw->unlockAPI(); 933 } 934 935 /*=========================================================================== 936 * FUNCTION : dump 937 * 938 * DESCRIPTION: dump camera status 939 * 940 * PARAMETERS : 941 * @device : ptr to camera device struct 942 * @fd : fd for status to be dumped to 943 * 944 * RETURN : int32_t type of status 945 * NO_ERROR -- success 946 * none-zero failure code 947 *==========================================================================*/ 948 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd) 949 { 950 int ret = NO_ERROR; 951 952 //Log level property is read when "adb shell dumpsys media.camera" is 953 //called so that the log level can be controlled without restarting 954 //media server 955 getLogLevel(); 956 QCamera2HardwareInterface *hw = 957 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 958 if (!hw) { 959 ALOGE("NULL camera device"); 960 return BAD_VALUE; 961 } 962 hw->lockAPI(); 963 qcamera_api_result_t apiResult; 964 ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd); 965 if (ret == NO_ERROR) { 966 hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult); 967 ret = apiResult.status; 968 } 969 hw->unlockAPI(); 970 971 return ret; 972 } 973 974 /*=========================================================================== 975 * FUNCTION : close_camera_device 976 * 977 * DESCRIPTION: close camera device 978 * 979 * PARAMETERS : 980 * @device : ptr to camera device struct 981 * 982 * RETURN : int32_t type of status 983 * NO_ERROR -- success 984 * none-zero failure code 985 *==========================================================================*/ 986 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev) 987 { 988 ATRACE_CALL(); 989 int ret = NO_ERROR; 990 ALOGI("[KPI Perf] %s: E",__func__); 991 QCamera2HardwareInterface *hw = 992 reinterpret_cast<QCamera2HardwareInterface *>( 993 reinterpret_cast<camera_device_t *>(hw_dev)->priv); 994 if (!hw) { 995 ALOGE("%s: NULL camera device", __func__); 996 return BAD_VALUE; 997 } 998 delete hw; 999 ALOGI("[KPI Perf] %s: X",__func__); 1000 return ret; 1001 } 1002 1003 /*=========================================================================== 1004 * FUNCTION : register_face_image 1005 * 1006 * DESCRIPTION: register a face image into imaging lib for face authenticatio/ 1007 * face recognition 1008 * 1009 * PARAMETERS : 1010 * @device : ptr to camera device struct 1011 * @img_ptr : ptr to image buffer 1012 * @config : ptr to config about input image, i.e., format, dimension, and etc. 1013 * 1014 * RETURN : >=0 unique ID of face registerd. 1015 * <0 failure. 1016 *==========================================================================*/ 1017 int QCamera2HardwareInterface::register_face_image(struct camera_device *device, 1018 void *img_ptr, 1019 cam_pp_offline_src_config_t *config) 1020 { 1021 ATRACE_CALL(); 1022 int ret = NO_ERROR; 1023 QCamera2HardwareInterface *hw = 1024 reinterpret_cast<QCamera2HardwareInterface *>(device->priv); 1025 if (!hw) { 1026 ALOGE("NULL camera device"); 1027 return BAD_VALUE; 1028 } 1029 qcamera_sm_evt_reg_face_payload_t payload; 1030 memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t)); 1031 payload.img_ptr = img_ptr; 1032 payload.config = config; 1033 hw->lockAPI(); 1034 qcamera_api_result_t apiResult; 1035 ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload); 1036 if (ret == NO_ERROR) { 1037 hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult); 1038 ret = apiResult.handle; 1039 } 1040 hw->unlockAPI(); 1041 1042 return ret; 1043 } 1044 1045 /*=========================================================================== 1046 * FUNCTION : QCamera2HardwareInterface 1047 * 1048 * DESCRIPTION: constructor of QCamera2HardwareInterface 1049 * 1050 * PARAMETERS : 1051 * @cameraId : camera ID 1052 * 1053 * RETURN : none 1054 *==========================================================================*/ 1055 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId) 1056 : mCameraId(cameraId), 1057 mCameraHandle(NULL), 1058 mCameraOpened(false), 1059 mPreviewWindow(NULL), 1060 mMsgEnabled(0), 1061 mStoreMetaDataInFrame(0), 1062 m_stateMachine(this), 1063 m_smThreadActive(true), 1064 m_postprocessor(this), 1065 m_thermalAdapter(QCameraThermalAdapter::getInstance()), 1066 m_cbNotifier(this), 1067 m_bPreviewStarted(false), 1068 m_bRecordStarted(false), 1069 m_currentFocusState(CAM_AF_SCANNING), 1070 mDumpFrmCnt(0U), 1071 mDumpSkipCnt(0U), 1072 mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT), 1073 mCancelAutoFocus(false), 1074 m_HDRSceneEnabled(false), 1075 mLongshotEnabled(false), 1076 m_max_pic_width(0), 1077 m_max_pic_height(0), 1078 mLiveSnapshotThread(0), 1079 mIntPicThread(0), 1080 mFlashNeeded(false), 1081 mDeviceRotation(0U), 1082 mCaptureRotation(0U), 1083 mJpegExifRotation(0U), 1084 mUseJpegExifRotation(false), 1085 mIs3ALocked(false), 1086 mPrepSnapRun(false), 1087 mZoomLevel(0), 1088 mVFrameCount(0), 1089 mVLastFrameCount(0), 1090 mVLastFpsTime(0), 1091 mVFps(0), 1092 mPFrameCount(0), 1093 mPLastFrameCount(0), 1094 mPLastFpsTime(0), 1095 mPFps(0), 1096 m_bIntJpegEvtPending(false), 1097 m_bIntRawEvtPending(false), 1098 mSnapshotJob(-1), 1099 mPostviewJob(-1), 1100 mMetadataJob(-1), 1101 mReprocJob(-1), 1102 mRawdataJob(-1), 1103 mOutputCount(0), 1104 mInputCount(0), 1105 mAdvancedCaptureConfigured(false), 1106 mHDRBracketingEnabled(false) 1107 { 1108 getLogLevel(); 1109 ATRACE_CALL(); 1110 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG; 1111 mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0); 1112 mCameraDevice.common.close = close_camera_device; 1113 mCameraDevice.ops = &mCameraOps; 1114 mCameraDevice.priv = this; 1115 1116 pthread_mutex_init(&m_lock, NULL); 1117 pthread_cond_init(&m_cond, NULL); 1118 1119 m_apiResultList = NULL; 1120 1121 pthread_mutex_init(&m_evtLock, NULL); 1122 pthread_cond_init(&m_evtCond, NULL); 1123 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 1124 1125 pthread_mutex_init(&m_parm_lock, NULL); 1126 1127 pthread_mutex_init(&m_int_lock, NULL); 1128 pthread_cond_init(&m_int_cond, NULL); 1129 1130 memset(m_channels, 0, sizeof(m_channels)); 1131 memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t)); 1132 1133 memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH); 1134 1135 memset(mDeffOngoingJobs, 0, sizeof(mDeffOngoingJobs)); 1136 m_perfLock.lock_init(); 1137 1138 mDefferedWorkThread.launch(defferedWorkRoutine, this); 1139 mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE); 1140 } 1141 1142 /*=========================================================================== 1143 * FUNCTION : ~QCamera2HardwareInterface 1144 * 1145 * DESCRIPTION: destructor of QCamera2HardwareInterface 1146 * 1147 * PARAMETERS : none 1148 * 1149 * RETURN : none 1150 *==========================================================================*/ 1151 QCamera2HardwareInterface::~QCamera2HardwareInterface() 1152 { 1153 mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE); 1154 mDefferedWorkThread.exit(); 1155 1156 m_perfLock.lock_acq(); 1157 lockAPI(); 1158 m_smThreadActive = false; 1159 unlockAPI(); 1160 m_stateMachine.releaseThread(); 1161 closeCamera(); 1162 m_perfLock.lock_rel(); 1163 m_perfLock.lock_deinit(); 1164 pthread_mutex_destroy(&m_lock); 1165 pthread_cond_destroy(&m_cond); 1166 pthread_mutex_destroy(&m_evtLock); 1167 pthread_cond_destroy(&m_evtCond); 1168 pthread_mutex_destroy(&m_parm_lock); 1169 pthread_mutex_destroy(&m_int_lock); 1170 pthread_cond_destroy(&m_int_cond); 1171 } 1172 1173 /*=========================================================================== 1174 * FUNCTION : openCamera 1175 * 1176 * DESCRIPTION: open camera 1177 * 1178 * PARAMETERS : 1179 * @hw_device : double ptr for camera device struct 1180 * 1181 * RETURN : int32_t type of status 1182 * NO_ERROR -- success 1183 * none-zero failure code 1184 *==========================================================================*/ 1185 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device) 1186 { 1187 ATRACE_CALL(); 1188 int rc = NO_ERROR; 1189 if (mCameraOpened) { 1190 *hw_device = NULL; 1191 return PERMISSION_DENIED; 1192 } 1193 ALOGI("[KPI Perf] %s: E PROFILE_OPEN_CAMERA camera id %d", 1194 __func__,mCameraId); 1195 m_perfLock.lock_acq(); 1196 rc = openCamera(); 1197 if (rc == NO_ERROR){ 1198 *hw_device = &mCameraDevice.common; 1199 if (m_thermalAdapter.init(this) != 0) { 1200 ALOGE("Init thermal adapter failed"); 1201 } 1202 } 1203 else 1204 *hw_device = NULL; 1205 1206 ALOGI("[KPI Perf] %s: X PROFILE_OPEN_CAMERA camera id %d, rc: %d", 1207 __func__,mCameraId, rc); 1208 1209 m_perfLock.lock_rel(); 1210 return rc; 1211 } 1212 1213 /*=========================================================================== 1214 * FUNCTION : openCamera 1215 * 1216 * DESCRIPTION: open camera 1217 * 1218 * PARAMETERS : none 1219 * 1220 * RETURN : int32_t type of status 1221 * NO_ERROR -- success 1222 * none-zero failure code 1223 *==========================================================================*/ 1224 int QCamera2HardwareInterface::openCamera() 1225 { 1226 int32_t l_curr_width = 0; 1227 int32_t l_curr_height = 0; 1228 m_max_pic_width = 0; 1229 m_max_pic_height = 0; 1230 size_t i; 1231 int32_t rc = 0; 1232 1233 if (mCameraHandle) { 1234 ALOGE("Failure: Camera already opened"); 1235 return ALREADY_EXISTS; 1236 } 1237 rc = camera_open((uint8_t)mCameraId, &mCameraHandle); 1238 if (rc) { 1239 ALOGE("camera_open failed. rc = %d, mCameraHandle = %p", rc, mCameraHandle); 1240 return rc; 1241 } 1242 if (NULL == gCamCaps[mCameraId]) 1243 initCapabilities(mCameraId,mCameraHandle); 1244 1245 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, 1246 camEvtHandle, 1247 (void *) this); 1248 1249 /* get max pic size for jpeg work buf calculation*/ 1250 for(i = 0; i < gCamCaps[mCameraId]->picture_sizes_tbl_cnt - 1; i++) 1251 { 1252 l_curr_width = gCamCaps[mCameraId]->picture_sizes_tbl[i].width; 1253 l_curr_height = gCamCaps[mCameraId]->picture_sizes_tbl[i].height; 1254 1255 if ((l_curr_width * l_curr_height) > 1256 (m_max_pic_width * m_max_pic_height)) { 1257 m_max_pic_width = l_curr_width; 1258 m_max_pic_height = l_curr_height; 1259 } 1260 } 1261 1262 rc = m_postprocessor.init(jpegEvtHandle, this); 1263 if (rc != 0) { 1264 ALOGE("Init Postprocessor failed"); 1265 mCameraHandle->ops->close_camera(mCameraHandle->camera_handle); 1266 mCameraHandle = NULL; 1267 return UNKNOWN_ERROR; 1268 } 1269 1270 // update padding info from jpeg 1271 cam_padding_info_t padding_info; 1272 m_postprocessor.getJpegPaddingReq(padding_info); 1273 if (gCamCaps[mCameraId]->padding_info.width_padding < padding_info.width_padding) { 1274 gCamCaps[mCameraId]->padding_info.width_padding = padding_info.width_padding; 1275 } 1276 if (gCamCaps[mCameraId]->padding_info.height_padding < padding_info.height_padding) { 1277 gCamCaps[mCameraId]->padding_info.height_padding = padding_info.height_padding; 1278 } 1279 if (gCamCaps[mCameraId]->padding_info.plane_padding < padding_info.plane_padding) { 1280 gCamCaps[mCameraId]->padding_info.plane_padding = padding_info.plane_padding; 1281 } 1282 1283 mParameters.init(gCamCaps[mCameraId], mCameraHandle, this); 1284 mParameters.setMinPpMask(gCamCaps[mCameraId]->min_required_pp_mask); 1285 1286 mCameraOpened = true; 1287 1288 return NO_ERROR; 1289 } 1290 1291 /*=========================================================================== 1292 * FUNCTION : closeCamera 1293 * 1294 * DESCRIPTION: close camera 1295 * 1296 * PARAMETERS : none 1297 * 1298 * RETURN : int32_t type of status 1299 * NO_ERROR -- success 1300 * none-zero failure code 1301 *==========================================================================*/ 1302 int QCamera2HardwareInterface::closeCamera() 1303 { 1304 int rc = NO_ERROR; 1305 int i; 1306 1307 if (!mCameraOpened) { 1308 return NO_ERROR; 1309 } 1310 ALOGI("[KPI Perf] %s: E PROFILE_CLOSE_CAMERA camera id %d", 1311 __func__, mCameraId); 1312 1313 pthread_mutex_lock(&m_parm_lock); 1314 1315 // set open flag to false 1316 mCameraOpened = false; 1317 1318 // Reset Stream config info 1319 mParameters.setStreamConfigure(false, false, true); 1320 1321 // deinit Parameters 1322 mParameters.deinit(); 1323 1324 pthread_mutex_unlock(&m_parm_lock); 1325 1326 // exit notifier 1327 m_cbNotifier.exit(); 1328 1329 // stop and deinit postprocessor 1330 waitDefferedWork(mReprocJob); 1331 m_postprocessor.stop(); 1332 m_postprocessor.deinit(); 1333 1334 //free all pending api results here 1335 if(m_apiResultList != NULL) { 1336 api_result_list *apiResultList = m_apiResultList; 1337 api_result_list *apiResultListNext; 1338 while (apiResultList != NULL) { 1339 apiResultListNext = apiResultList->next; 1340 free(apiResultList); 1341 apiResultList = apiResultListNext; 1342 } 1343 } 1344 1345 m_thermalAdapter.deinit(); 1346 1347 // delete all channels if not already deleted 1348 for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 1349 if (m_channels[i] != NULL) { 1350 m_channels[i]->stop(); 1351 delete m_channels[i]; 1352 m_channels[i] = NULL; 1353 } 1354 } 1355 1356 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle); 1357 mCameraHandle = NULL; 1358 ALOGI("[KPI Perf] %s: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d", 1359 __func__, mCameraId, rc); 1360 1361 return rc; 1362 } 1363 1364 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX ) 1365 1366 /*=========================================================================== 1367 * FUNCTION : initCapabilities 1368 * 1369 * DESCRIPTION: initialize camera capabilities in static data struct 1370 * 1371 * PARAMETERS : 1372 * @cameraId : camera Id 1373 * 1374 * RETURN : int32_t type of status 1375 * NO_ERROR -- success 1376 * none-zero failure code 1377 *==========================================================================*/ 1378 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId, 1379 mm_camera_vtbl_t *cameraHandle) 1380 { 1381 ATRACE_CALL(); 1382 int rc = NO_ERROR; 1383 QCameraHeapMemory *capabilityHeap = NULL; 1384 1385 /* Allocate memory for capability buffer */ 1386 capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 1387 rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE); 1388 if(rc != OK) { 1389 ALOGE("%s: No memory for cappability", __func__); 1390 goto allocate_failed; 1391 } 1392 1393 /* Map memory for capability buffer */ 1394 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t)); 1395 rc = cameraHandle->ops->map_buf(cameraHandle->camera_handle, 1396 CAM_MAPPING_BUF_TYPE_CAPABILITY, 1397 capabilityHeap->getFd(0), 1398 sizeof(cam_capability_t)); 1399 if(rc < 0) { 1400 ALOGE("%s: failed to map capability buffer", __func__); 1401 goto map_failed; 1402 } 1403 1404 /* Query Capability */ 1405 rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle); 1406 if(rc < 0) { 1407 ALOGE("%s: failed to query capability",__func__); 1408 goto query_failed; 1409 } 1410 gCamCaps[cameraId] = (cam_capability_t *)malloc(sizeof(cam_capability_t)); 1411 if (!gCamCaps[cameraId]) { 1412 ALOGE("%s: out of memory", __func__); 1413 goto query_failed; 1414 } 1415 memcpy(gCamCaps[cameraId], DATA_PTR(capabilityHeap,0), 1416 sizeof(cam_capability_t)); 1417 1418 rc = NO_ERROR; 1419 1420 query_failed: 1421 cameraHandle->ops->unmap_buf(cameraHandle->camera_handle, 1422 CAM_MAPPING_BUF_TYPE_CAPABILITY); 1423 map_failed: 1424 capabilityHeap->deallocate(); 1425 delete capabilityHeap; 1426 allocate_failed: 1427 return rc; 1428 } 1429 1430 /*=========================================================================== 1431 * FUNCTION : getCapabilities 1432 * 1433 * DESCRIPTION: query camera capabilities 1434 * 1435 * PARAMETERS : 1436 * @cameraId : camera Id 1437 * @info : camera info struct to be filled in with camera capabilities 1438 * 1439 * RETURN : int type of status 1440 * NO_ERROR -- success 1441 * none-zero failure code 1442 *==========================================================================*/ 1443 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId, 1444 struct camera_info *info) 1445 { 1446 ATRACE_CALL(); 1447 int rc = NO_ERROR; 1448 struct camera_info *p_info; 1449 pthread_mutex_lock(&g_camlock); 1450 p_info = get_cam_info(cameraId); 1451 p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0; 1452 p_info->static_camera_characteristics = NULL; 1453 memcpy(info, p_info, sizeof (struct camera_info)); 1454 pthread_mutex_unlock(&g_camlock); 1455 return rc; 1456 } 1457 1458 /*=========================================================================== 1459 * FUNCTION : getCamHalCapabilities 1460 * 1461 * DESCRIPTION: get the HAL capabilities structure 1462 * 1463 * PARAMETERS : 1464 * @cameraId : camera Id 1465 * 1466 * RETURN : capability structure of respective camera 1467 * 1468 *==========================================================================*/ 1469 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities() 1470 { 1471 return gCamCaps[mCameraId]; 1472 } 1473 1474 /*=========================================================================== 1475 * FUNCTION : getBufNumRequired 1476 * 1477 * DESCRIPTION: return number of stream buffers needed for given stream type 1478 * 1479 * PARAMETERS : 1480 * @stream_type : type of stream 1481 * 1482 * RETURN : number of buffers needed 1483 *==========================================================================*/ 1484 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type) 1485 { 1486 int bufferCnt = 0; 1487 int minCaptureBuffers = mParameters.getNumOfSnapshots(); 1488 char value[PROPERTY_VALUE_MAX]; 1489 bool raw_yuv = false; 1490 1491 int zslQBuffers = mParameters.getZSLQueueDepth(); 1492 1493 int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() + 1494 CAMERA_MIN_JPEG_ENCODING_BUFFERS; 1495 1496 int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() + 1497 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 1498 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 1499 mParameters.getNumOfExtraBuffersForImageProc() + 1500 EXTRA_ZSL_PREVIEW_STREAM_BUF; 1501 1502 int minUndequeCount = 0; 1503 if (!isNoDisplayMode()) { 1504 if(mPreviewWindow != NULL) { 1505 if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount) 1506 != 0) { 1507 ALOGE("get_min_undequeued_buffer_count failed"); 1508 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined 1509 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS; 1510 minUndequeCount = 2; 1511 } 1512 } else { 1513 //preview window might not be set at this point. So, query directly 1514 //from BufferQueue implementation of gralloc buffers. 1515 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS; 1516 //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT 1517 minUndequeCount = 2; 1518 } 1519 } 1520 1521 // Get buffer count for the particular stream type 1522 switch (stream_type) { 1523 case CAM_STREAM_TYPE_PREVIEW: 1524 { 1525 if (mParameters.isZSLMode()) { 1526 // We need to add two extra streming buffers to add 1527 // flexibility in forming matched super buf in ZSL queue. 1528 // with number being 'zslQBuffers + minCircularBufNum' 1529 // we see preview buffers sometimes get dropped at CPP 1530 // and super buf is not forming in ZSL Q for long time. 1531 1532 bufferCnt = zslQBuffers + minCircularBufNum + 1533 mParameters.getNumOfExtraBuffersForImageProc() + 1534 EXTRA_ZSL_PREVIEW_STREAM_BUF + 1535 mParameters.getNumOfExtraBuffersForPreview(); 1536 } else { 1537 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS + 1538 mParameters.getMaxUnmatchedFramesInQueue() + 1539 mParameters.getNumOfExtraBuffersForPreview(); 1540 } 1541 bufferCnt += minUndequeCount; 1542 } 1543 break; 1544 case CAM_STREAM_TYPE_POSTVIEW: 1545 { 1546 bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER + 1547 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 1548 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 1549 mParameters.getNumOfExtraBuffersForImageProc(); 1550 1551 if (bufferCnt > maxStreamBuf) { 1552 bufferCnt = maxStreamBuf; 1553 } 1554 bufferCnt += minUndequeCount; 1555 } 1556 break; 1557 case CAM_STREAM_TYPE_SNAPSHOT: 1558 { 1559 if (mParameters.isZSLMode() || mLongshotEnabled) { 1560 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) && 1561 !mLongshotEnabled) { 1562 // Single ZSL snapshot case 1563 bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS + 1564 mParameters.getNumOfExtraBuffersForImageProc(); 1565 } 1566 else { 1567 // ZSL Burst or Longshot case 1568 bufferCnt = zslQBuffers + minCircularBufNum + 1569 mParameters.getNumOfExtraBuffersForImageProc(); 1570 } 1571 } else { 1572 bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER + 1573 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 1574 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 1575 mParameters.getNumOfExtraBuffersForImageProc(); 1576 1577 if (bufferCnt > maxStreamBuf) { 1578 bufferCnt = maxStreamBuf; 1579 } 1580 } 1581 } 1582 break; 1583 case CAM_STREAM_TYPE_RAW: 1584 property_get("persist.camera.raw_yuv", value, "0"); 1585 raw_yuv = atoi(value) > 0 ? true : false; 1586 1587 if (isRdiMode() || raw_yuv) { 1588 CDBG_HIGH("RDI_DEBUG %s[%d]: CAM_STREAM_TYPE_RAW", 1589 __func__, __LINE__); 1590 bufferCnt = zslQBuffers + minCircularBufNum; 1591 } else if (mParameters.isZSLMode()) { 1592 bufferCnt = zslQBuffers + minCircularBufNum; 1593 } else { 1594 bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER + 1595 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 1596 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 1597 mParameters.getNumOfExtraBuffersForImageProc(); 1598 1599 if (bufferCnt > maxStreamBuf) { 1600 bufferCnt = maxStreamBuf; 1601 } 1602 } 1603 break; 1604 case CAM_STREAM_TYPE_VIDEO: 1605 { 1606 if (mParameters.getBufBatchCount()) { 1607 bufferCnt = CAMERA_MIN_VIDEO_BATCH_BUFFERS; 1608 } else { 1609 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS; 1610 } 1611 1612 bufferCnt += mParameters.getNumOfExtraBuffersForVideo(); 1613 //if its 4K encoding usecase, then add extra buffer 1614 cam_dimension_t dim; 1615 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim); 1616 if (is4k2kResolution(&dim)) { 1617 //get additional buffer count 1618 property_get("vidc.enc.dcvs.extra-buff-count", value, "0"); 1619 bufferCnt += atoi(value); 1620 } 1621 ALOGI("Buffer count is %d, width / height (%d/%d) ", bufferCnt, dim.width, dim.height); 1622 } 1623 break; 1624 case CAM_STREAM_TYPE_METADATA: 1625 { 1626 if (mParameters.isZSLMode()) { 1627 // MetaData buffers should be >= (Preview buffers-minUndequeCount) 1628 bufferCnt = zslQBuffers + minCircularBufNum + 1629 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 1630 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 1631 mParameters.getNumOfExtraBuffersForImageProc() + 1632 EXTRA_ZSL_PREVIEW_STREAM_BUF; 1633 } else { 1634 bufferCnt = minCaptureBuffers + 1635 mParameters.getNumOfExtraHDRInBufsIfNeeded() - 1636 mParameters.getNumOfExtraHDROutBufsIfNeeded() + 1637 mParameters.getMaxUnmatchedFramesInQueue() + 1638 CAMERA_MIN_STREAMING_BUFFERS + 1639 mParameters.getNumOfExtraBuffersForImageProc(); 1640 1641 if (bufferCnt > zslQBuffers + minCircularBufNum) { 1642 bufferCnt = zslQBuffers + minCircularBufNum; 1643 } 1644 } 1645 } 1646 break; 1647 case CAM_STREAM_TYPE_OFFLINE_PROC: 1648 { 1649 bufferCnt = minCaptureBuffers; 1650 // One of the ubifocus buffers is miscellaneous buffer 1651 if (mParameters.isUbiRefocus()) { 1652 bufferCnt -= 1; 1653 } 1654 if (mLongshotEnabled) { 1655 char prop[PROPERTY_VALUE_MAX]; 1656 memset(prop, 0, sizeof(prop)); 1657 property_get("persist.camera.longshot.stages", prop, "0"); 1658 int longshotStages = atoi(prop); 1659 if (longshotStages > 0 && longshotStages < CAMERA_LONGSHOT_STAGES) { 1660 bufferCnt = longshotStages; 1661 } 1662 else { 1663 bufferCnt = CAMERA_LONGSHOT_STAGES; 1664 } 1665 } 1666 } 1667 break; 1668 case CAM_STREAM_TYPE_ANALYSIS: 1669 case CAM_STREAM_TYPE_DEFAULT: 1670 case CAM_STREAM_TYPE_MAX: 1671 default: 1672 bufferCnt = 0; 1673 break; 1674 } 1675 1676 if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) { 1677 ALOGE("%s: Buffer count %d for stream type %d exceeds limit %d", 1678 __func__, bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM); 1679 return CAM_MAX_NUM_BUFS_PER_STREAM; 1680 } 1681 1682 return (uint8_t)bufferCnt; 1683 } 1684 1685 /*=========================================================================== 1686 * FUNCTION : allocateStreamBuf 1687 * 1688 * DESCRIPTION: alocate stream buffers 1689 * 1690 * PARAMETERS : 1691 * @stream_type : type of stream 1692 * @size : size of buffer 1693 * @stride : stride of buffer 1694 * @scanline : scanline of buffer 1695 * @bufferCnt : [IN/OUT] minimum num of buffers to be allocated. 1696 * could be modified during allocation if more buffers needed 1697 * 1698 * RETURN : ptr to a memory obj that holds stream buffers. 1699 * NULL if failed 1700 *==========================================================================*/ 1701 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf( 1702 cam_stream_type_t stream_type, size_t size, int stride, int scanline, 1703 uint8_t &bufferCnt) 1704 { 1705 int rc = NO_ERROR; 1706 QCameraMemory *mem = NULL; 1707 bool bCachedMem = QCAMERA_ION_USE_CACHE; 1708 bool bPoolMem = false; 1709 char value[PROPERTY_VALUE_MAX]; 1710 property_get("persist.camera.mem.usepool", value, "1"); 1711 if (atoi(value) == 1) { 1712 bPoolMem = true; 1713 } 1714 1715 // Allocate stream buffer memory object 1716 switch (stream_type) { 1717 case CAM_STREAM_TYPE_PREVIEW: 1718 { 1719 if (isNoDisplayMode()) { 1720 mem = new QCameraStreamMemory(mGetMemory, 1721 bCachedMem, 1722 (bPoolMem) ? &m_memoryPool : NULL, 1723 stream_type); 1724 } else { 1725 cam_dimension_t dim; 1726 QCameraGrallocMemory *grallocMemory = 1727 new QCameraGrallocMemory(mGetMemory); 1728 1729 mParameters.getStreamDimension(stream_type, dim); 1730 if (grallocMemory) 1731 grallocMemory->setWindowInfo(mPreviewWindow, dim.width, 1732 dim.height, stride, scanline, 1733 mParameters.getPreviewHalPixelFormat()); 1734 mem = grallocMemory; 1735 } 1736 } 1737 break; 1738 case CAM_STREAM_TYPE_POSTVIEW: 1739 { 1740 if (isNoDisplayMode() || isPreviewRestartEnabled()) { 1741 mem = new QCameraStreamMemory(mGetMemory, bCachedMem); 1742 } else { 1743 cam_dimension_t dim; 1744 QCameraGrallocMemory *grallocMemory = 1745 new QCameraGrallocMemory(mGetMemory); 1746 1747 mParameters.getStreamDimension(stream_type, dim); 1748 if (grallocMemory) 1749 grallocMemory->setWindowInfo(mPreviewWindow, dim.width, 1750 dim.height, stride, scanline, 1751 mParameters.getPreviewHalPixelFormat()); 1752 mem = grallocMemory; 1753 } 1754 } 1755 break; 1756 case CAM_STREAM_TYPE_ANALYSIS: 1757 case CAM_STREAM_TYPE_SNAPSHOT: 1758 case CAM_STREAM_TYPE_RAW: 1759 case CAM_STREAM_TYPE_METADATA: 1760 case CAM_STREAM_TYPE_OFFLINE_PROC: 1761 mem = new QCameraStreamMemory(mGetMemory, 1762 bCachedMem, 1763 (bPoolMem) ? &m_memoryPool : NULL, 1764 stream_type); 1765 break; 1766 case CAM_STREAM_TYPE_VIDEO: 1767 { 1768 property_get("persist.camera.mem.usecache", value, "0"); 1769 if (atoi(value) == 0) { 1770 bCachedMem = QCAMERA_ION_USE_NOCACHE; 1771 } 1772 CDBG_HIGH("%s: vidoe buf using cached memory = %d", __func__, bCachedMem); 1773 mem = new QCameraVideoMemory(mGetMemory, bCachedMem); 1774 } 1775 break; 1776 case CAM_STREAM_TYPE_DEFAULT: 1777 case CAM_STREAM_TYPE_MAX: 1778 default: 1779 break; 1780 } 1781 if (!mem) { 1782 return NULL; 1783 } 1784 1785 if (bufferCnt > 0) { 1786 if (mParameters.isSecureMode() && 1787 (stream_type == CAM_STREAM_TYPE_RAW) && 1788 (mParameters.isRdiMode())) { 1789 ALOGD("%s: Allocating %d secure buffers of size %d ", __func__, bufferCnt, size); 1790 rc = mem->allocate(bufferCnt, size, SECURE); 1791 } else { 1792 rc = mem->allocate(bufferCnt, size, NON_SECURE); 1793 } 1794 if (rc < 0) { 1795 delete mem; 1796 return NULL; 1797 } 1798 bufferCnt = mem->getCnt(); 1799 } 1800 return mem; 1801 } 1802 1803 /*=========================================================================== 1804 * FUNCTION : allocateMoreStreamBuf 1805 * 1806 * DESCRIPTION: alocate more stream buffers from the memory object 1807 * 1808 * PARAMETERS : 1809 * @mem_obj : memory object ptr 1810 * @size : size of buffer 1811 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated. 1812 * output will be the number of total buffers 1813 * 1814 * RETURN : int32_t type of status 1815 * NO_ERROR -- success 1816 * none-zero failure code 1817 *==========================================================================*/ 1818 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf( 1819 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt) 1820 { 1821 int rc = NO_ERROR; 1822 1823 if (bufferCnt > 0) { 1824 rc = mem_obj->allocateMore(bufferCnt, size); 1825 bufferCnt = mem_obj->getCnt(); 1826 } 1827 return rc; 1828 } 1829 1830 /*=========================================================================== 1831 * FUNCTION : allocateMiscBuf 1832 * 1833 * DESCRIPTION: alocate miscellaneous buffer 1834 * 1835 * PARAMETERS : 1836 * @streamInfo : stream info 1837 * 1838 * RETURN : ptr to a memory obj that holds stream info buffer. 1839 * NULL if failed 1840 *==========================================================================*/ 1841 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf( 1842 cam_stream_info_t *streamInfo) 1843 { 1844 int rc = NO_ERROR; 1845 uint8_t bufNum = 0; 1846 size_t bufSize = 0; 1847 QCameraHeapMemory *miscBuf = NULL; 1848 uint32_t feature_mask = 1849 streamInfo->reprocess_config.pp_feature_config.feature_mask; 1850 1851 switch (streamInfo->stream_type) { 1852 case CAM_STREAM_TYPE_OFFLINE_PROC: 1853 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) { 1854 bufNum = 1; 1855 bufSize = mParameters.getTPMaxMetaSize(); 1856 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) { 1857 bufNum = 1; 1858 bufSize = mParameters.getRefocusMaxMetaSize(); 1859 } 1860 break; 1861 default: 1862 break; 1863 } 1864 1865 if (bufNum && bufSize) { 1866 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 1867 1868 if (!miscBuf) { 1869 ALOGE("%s: Unable to allocate miscBuf object", __func__); 1870 return NULL; 1871 } 1872 1873 rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE); 1874 if (rc < 0) { 1875 ALOGE("%s: Failed to allocate misc buffer memory", __func__); 1876 delete miscBuf; 1877 return NULL; 1878 } 1879 } 1880 1881 return miscBuf; 1882 } 1883 1884 /*=========================================================================== 1885 * FUNCTION : allocateStreamInfoBuf 1886 * 1887 * DESCRIPTION: alocate stream info buffer 1888 * 1889 * PARAMETERS : 1890 * @stream_type : type of stream 1891 * 1892 * RETURN : ptr to a memory obj that holds stream info buffer. 1893 * NULL if failed 1894 *==========================================================================*/ 1895 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf( 1896 cam_stream_type_t stream_type) 1897 { 1898 int rc = NO_ERROR; 1899 char value[PROPERTY_VALUE_MAX]; 1900 bool raw_yuv = false; 1901 1902 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 1903 if (!streamInfoBuf) { 1904 ALOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object"); 1905 return NULL; 1906 } 1907 1908 rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE); 1909 if (rc < 0) { 1910 ALOGE("allocateStreamInfoBuf: Failed to allocate stream info memory"); 1911 delete streamInfoBuf; 1912 return NULL; 1913 } 1914 1915 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0); 1916 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 1917 streamInfo->stream_type = stream_type; 1918 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt); 1919 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim); 1920 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim); 1921 streamInfo->num_bufs = getBufNumRequired(stream_type); 1922 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1923 streamInfo->is_secure = NON_SECURE; 1924 switch (stream_type) { 1925 case CAM_STREAM_TYPE_SNAPSHOT: 1926 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) || 1927 mLongshotEnabled) { 1928 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1929 } else { 1930 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 1931 streamInfo->num_of_burst = (uint8_t) 1932 (mParameters.getNumOfSnapshots() 1933 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 1934 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 1935 + mParameters.getNumOfExtraBuffersForImageProc()); 1936 } 1937 break; 1938 case CAM_STREAM_TYPE_RAW: 1939 property_get("persist.camera.raw_yuv", value, "0"); 1940 raw_yuv = atoi(value) > 0 ? true : false; 1941 if ((mParameters.isZSLMode() || isRdiMode() || raw_yuv) && 1942 !mParameters.getofflineRAW()) { 1943 CDBG_HIGH("RDI_DEBUG %s[%d]: CAM_STREAM_TYPE_RAW", 1944 __func__, __LINE__); 1945 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1946 } else { 1947 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 1948 streamInfo->num_of_burst = mParameters.getNumOfSnapshots(); 1949 } 1950 if (mParameters.isSecureMode() && mParameters.isRdiMode()) { 1951 streamInfo->is_secure = SECURE; 1952 } else { 1953 streamInfo->is_secure = NON_SECURE; 1954 } 1955 break; 1956 case CAM_STREAM_TYPE_POSTVIEW: 1957 if (mLongshotEnabled) { 1958 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1959 } else { 1960 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 1961 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots() 1962 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 1963 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 1964 + mParameters.getNumOfExtraBuffersForImageProc()); 1965 } 1966 break; 1967 case CAM_STREAM_TYPE_VIDEO: 1968 streamInfo->dis_enable = mParameters.isDISEnabled(); 1969 if (mParameters.getBufBatchCount()) { 1970 //Update stream info structure with batch mode info 1971 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH; 1972 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount(); 1973 streamInfo->user_buf_info.size = 1974 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t)); 1975 cam_fps_range_t pFpsRange; 1976 mParameters.getHfrFps(pFpsRange); 1977 streamInfo->user_buf_info.frameInterval = 1978 (long)((1000/pFpsRange.video_max_fps) * 1000); 1979 CDBG_HIGH("%s: Video Batch Count = %d, interval = %ld", __func__, 1980 streamInfo->user_buf_info.frame_buf_cnt, 1981 streamInfo->user_buf_info.frameInterval); 1982 } 1983 case CAM_STREAM_TYPE_PREVIEW: 1984 if (mParameters.getRecordingHintValue()) { 1985 const char* dis_param = mParameters.get(QCameraParameters::KEY_QC_DIS); 1986 bool disEnabled = (dis_param != NULL) 1987 && !strcmp(dis_param,QCameraParameters::VALUE_ENABLE); 1988 if(disEnabled) { 1989 streamInfo->is_type = mParameters.getISType(); 1990 } else { 1991 streamInfo->is_type = IS_TYPE_NONE; 1992 } 1993 } 1994 if (mParameters.isSecureMode()) { 1995 streamInfo->is_secure = SECURE; 1996 } 1997 break; 1998 case CAM_STREAM_TYPE_ANALYSIS: 1999 streamInfo->noFrameExpected = 1; 2000 break; 2001 default: 2002 break; 2003 } 2004 2005 // Update feature mask 2006 mParameters.updatePpFeatureMask(stream_type); 2007 2008 // Get feature mask 2009 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask); 2010 2011 // Update pp config 2012 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) { 2013 int flipMode = mParameters.getFlipMode(stream_type); 2014 if (flipMode > 0) { 2015 streamInfo->pp_config.flip = (uint32_t)flipMode; 2016 } 2017 } 2018 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) { 2019 streamInfo->pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS); 2020 } 2021 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) { 2022 streamInfo->pp_config.effect = mParameters.getEffectValue(); 2023 } 2024 2025 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) { 2026 streamInfo->pp_config.denoise2d.denoise_enable = 1; 2027 streamInfo->pp_config.denoise2d.process_plates = 2028 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 2029 } 2030 2031 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type || 2032 CAM_STREAM_TYPE_RAW == stream_type))) { 2033 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_CROP) 2034 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 2035 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SCALE) 2036 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 2037 } 2038 2039 CDBG_HIGH("%s: allocateStreamInfoBuf: stream type: %d, pp_mask: 0x%x", 2040 __func__, stream_type, streamInfo->pp_config.feature_mask); 2041 2042 return streamInfoBuf; 2043 } 2044 2045 /*=========================================================================== 2046 * FUNCTION : allocateStreamUserBuf 2047 * 2048 * DESCRIPTION: allocate user ptr for stream buffers 2049 * 2050 * PARAMETERS : 2051 * @streamInfo : stream info structure 2052 * 2053 * RETURN : ptr to a memory obj that holds stream info buffer. 2054 * NULL if failed 2055 2056 *==========================================================================*/ 2057 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf( 2058 cam_stream_info_t *streamInfo) 2059 { 2060 int rc = NO_ERROR; 2061 QCameraMemory *mem = NULL; 2062 int bufferCnt = 0; 2063 int size = 0; 2064 2065 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) { 2066 ALOGE("%s: Stream is not in BATCH mode. Invalid Stream", __func__); 2067 return NULL; 2068 } 2069 2070 // Allocate stream user buffer memory object 2071 switch (streamInfo->stream_type) { 2072 case CAM_STREAM_TYPE_VIDEO: { 2073 QCameraVideoMemory *video_mem = new QCameraVideoMemory( 2074 mGetMemory, FALSE, CAM_STREAM_BUF_TYPE_USERPTR); 2075 video_mem->allocateMeta(streamInfo->num_bufs); 2076 mem = static_cast<QCameraMemory *>(video_mem); 2077 } 2078 break; 2079 2080 case CAM_STREAM_TYPE_PREVIEW: 2081 case CAM_STREAM_TYPE_POSTVIEW: 2082 case CAM_STREAM_TYPE_ANALYSIS: 2083 case CAM_STREAM_TYPE_SNAPSHOT: 2084 case CAM_STREAM_TYPE_RAW: 2085 case CAM_STREAM_TYPE_METADATA: 2086 case CAM_STREAM_TYPE_OFFLINE_PROC: 2087 case CAM_STREAM_TYPE_CALLBACK: 2088 ALOGE("%s: Stream type Not supported.for BATCH processing", __func__); 2089 break; 2090 2091 case CAM_STREAM_TYPE_DEFAULT: 2092 case CAM_STREAM_TYPE_MAX: 2093 default: 2094 break; 2095 } 2096 if (!mem) { 2097 ALOGE("%s: Failed to allocate mem", __func__); 2098 return NULL; 2099 } 2100 2101 /*Size of this buffer will be number of batch buffer */ 2102 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size), 2103 CAM_PAD_TO_4K); 2104 2105 CDBG_HIGH("%s: Allocating BATCH Buffer count = %d", __func__, streamInfo->num_bufs); 2106 2107 if (size > 0) { 2108 // Allocating one buffer for all batch buffers 2109 rc = mem->allocate(1, size, NON_SECURE); 2110 if (rc < 0) { 2111 delete mem; 2112 return NULL; 2113 } 2114 } 2115 return mem; 2116 } 2117 2118 2119 /*=========================================================================== 2120 * FUNCTION : setPreviewWindow 2121 * 2122 * DESCRIPTION: set preview window impl 2123 * 2124 * PARAMETERS : 2125 * @window : ptr to window ops table struct 2126 * 2127 * RETURN : int32_t type of status 2128 * NO_ERROR -- success 2129 * none-zero failure code 2130 *==========================================================================*/ 2131 int QCamera2HardwareInterface::setPreviewWindow( 2132 struct preview_stream_ops *window) 2133 { 2134 mPreviewWindow = window; 2135 return NO_ERROR; 2136 } 2137 2138 /*=========================================================================== 2139 * FUNCTION : setCallBacks 2140 * 2141 * DESCRIPTION: set callbacks impl 2142 * 2143 * PARAMETERS : 2144 * @notify_cb : notify cb 2145 * @data_cb : data cb 2146 * @data_cb_timestamp : data cb with time stamp 2147 * @get_memory : request memory ops table 2148 * @user : user data ptr 2149 * 2150 * RETURN : int32_t type of status 2151 * NO_ERROR -- success 2152 * none-zero failure code 2153 *==========================================================================*/ 2154 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb, 2155 camera_data_callback data_cb, 2156 camera_data_timestamp_callback data_cb_timestamp, 2157 camera_request_memory get_memory, 2158 void *user) 2159 { 2160 mNotifyCb = notify_cb; 2161 mDataCb = data_cb; 2162 mDataCbTimestamp = data_cb_timestamp; 2163 mGetMemory = get_memory; 2164 mCallbackCookie = user; 2165 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user); 2166 return NO_ERROR; 2167 } 2168 2169 /*=========================================================================== 2170 * FUNCTION : enableMsgType 2171 * 2172 * DESCRIPTION: enable msg type impl 2173 * 2174 * PARAMETERS : 2175 * @msg_type : msg type mask to be enabled 2176 * 2177 * RETURN : int32_t type of status 2178 * NO_ERROR -- success 2179 * none-zero failure code 2180 *==========================================================================*/ 2181 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type) 2182 { 2183 mMsgEnabled |= msg_type; 2184 return NO_ERROR; 2185 } 2186 2187 /*=========================================================================== 2188 * FUNCTION : disableMsgType 2189 * 2190 * DESCRIPTION: disable msg type impl 2191 * 2192 * PARAMETERS : 2193 * @msg_type : msg type mask to be disabled 2194 * 2195 * RETURN : int32_t type of status 2196 * NO_ERROR -- success 2197 * none-zero failure code 2198 *==========================================================================*/ 2199 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type) 2200 { 2201 mMsgEnabled &= ~msg_type; 2202 return NO_ERROR; 2203 } 2204 2205 /*=========================================================================== 2206 * FUNCTION : msgTypeEnabled 2207 * 2208 * DESCRIPTION: impl to determine if certain msg_type is enabled 2209 * 2210 * PARAMETERS : 2211 * @msg_type : msg type mask 2212 * 2213 * RETURN : 0 -- not enabled 2214 * none 0 -- enabled 2215 *==========================================================================*/ 2216 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type) 2217 { 2218 return (mMsgEnabled & msg_type); 2219 } 2220 2221 /*=========================================================================== 2222 * FUNCTION : msgTypeEnabledWithLock 2223 * 2224 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock 2225 * 2226 * PARAMETERS : 2227 * @msg_type : msg type mask 2228 * 2229 * RETURN : 0 -- not enabled 2230 * none 0 -- enabled 2231 *==========================================================================*/ 2232 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type) 2233 { 2234 int enabled = 0; 2235 lockAPI(); 2236 enabled = mMsgEnabled & msg_type; 2237 unlockAPI(); 2238 return enabled; 2239 } 2240 2241 /*=========================================================================== 2242 * FUNCTION : startPreview 2243 * 2244 * DESCRIPTION: start preview impl 2245 * 2246 * PARAMETERS : none 2247 * 2248 * RETURN : int32_t type of status 2249 * NO_ERROR -- success 2250 * none-zero failure code 2251 *==========================================================================*/ 2252 int QCamera2HardwareInterface::startPreview() 2253 { 2254 ATRACE_CALL(); 2255 int32_t rc = NO_ERROR; 2256 CDBG_HIGH("%s: E", __func__); 2257 // start preview stream 2258 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 2259 rc = startChannel(QCAMERA_CH_TYPE_ZSL); 2260 } else { 2261 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW); 2262 /* 2263 CAF needs cancel auto focus to resume after snapshot. 2264 Focus should be locked till take picture is done. 2265 In Non-zsl case if focus mode is CAF then calling cancel auto focus 2266 to resume CAF. 2267 */ 2268 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 2269 if (focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE) 2270 mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle); 2271 } 2272 updatePostPreviewParameters(); 2273 CDBG_HIGH("%s: X", __func__); 2274 return rc; 2275 } 2276 2277 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() { 2278 // Enable OIS only in Camera mode and 4k2k camcoder mode 2279 int32_t rc = NO_ERROR; 2280 rc = mParameters.updateOisValue(1); 2281 return NO_ERROR; 2282 } 2283 2284 /*=========================================================================== 2285 * FUNCTION : stopPreview 2286 * 2287 * DESCRIPTION: stop preview impl 2288 * 2289 * PARAMETERS : none 2290 * 2291 * RETURN : int32_t type of status 2292 * NO_ERROR -- success 2293 * none-zero failure code 2294 *==========================================================================*/ 2295 int QCamera2HardwareInterface::stopPreview() 2296 { 2297 ATRACE_CALL(); 2298 CDBG_HIGH("%s: E", __func__); 2299 // stop preview stream 2300 stopChannel(QCAMERA_CH_TYPE_ZSL); 2301 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 2302 2303 m_cbNotifier.flushPreviewNotifications(); 2304 // delete all channels from preparePreview 2305 unpreparePreview(); 2306 CDBG_HIGH("%s: X", __func__); 2307 return NO_ERROR; 2308 } 2309 2310 /*=========================================================================== 2311 * FUNCTION : storeMetaDataInBuffers 2312 * 2313 * DESCRIPTION: enable store meta data in buffers for video frames impl 2314 * 2315 * PARAMETERS : 2316 * @enable : flag if need enable 2317 * 2318 * RETURN : int32_t type of status 2319 * NO_ERROR -- success 2320 * none-zero failure code 2321 *==========================================================================*/ 2322 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable) 2323 { 2324 mStoreMetaDataInFrame = enable; 2325 return NO_ERROR; 2326 } 2327 2328 /*=========================================================================== 2329 * FUNCTION : startRecording 2330 * 2331 * DESCRIPTION: start recording impl 2332 * 2333 * PARAMETERS : none 2334 * 2335 * RETURN : int32_t type of status 2336 * NO_ERROR -- success 2337 * none-zero failure code 2338 *==========================================================================*/ 2339 int QCamera2HardwareInterface::startRecording() 2340 { 2341 int32_t rc = NO_ERROR; 2342 CDBG_HIGH("%s: E", __func__); 2343 if (mParameters.getRecordingHintValue() == false) { 2344 ALOGE("%s: start recording when hint is false, stop preview first", __func__); 2345 stopPreview(); 2346 2347 // Set recording hint to TRUE 2348 mParameters.updateRecordingHintValue(TRUE); 2349 rc = preparePreview(); 2350 if (rc == NO_ERROR) { 2351 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW); 2352 } 2353 } 2354 2355 if (rc == NO_ERROR) { 2356 rc = startChannel(QCAMERA_CH_TYPE_VIDEO); 2357 } 2358 2359 if (rc == NO_ERROR) { 2360 // Set power Hint for video encoding 2361 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, 1); 2362 } 2363 2364 CDBG_HIGH("%s: X", __func__); 2365 return rc; 2366 } 2367 2368 /*=========================================================================== 2369 * FUNCTION : stopRecording 2370 * 2371 * DESCRIPTION: stop recording impl 2372 * 2373 * PARAMETERS : none 2374 * 2375 * RETURN : int32_t type of status 2376 * NO_ERROR -- success 2377 * none-zero failure code 2378 *==========================================================================*/ 2379 int QCamera2HardwareInterface::stopRecording() 2380 { 2381 CDBG_HIGH("%s: E", __func__); 2382 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO); 2383 2384 if (rc == NO_ERROR) { 2385 // Disable power Hint 2386 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, 0); 2387 } 2388 CDBG_HIGH("%s: X", __func__); 2389 return rc; 2390 } 2391 2392 /*=========================================================================== 2393 * FUNCTION : releaseRecordingFrame 2394 * 2395 * DESCRIPTION: return video frame impl 2396 * 2397 * PARAMETERS : 2398 * @opaque : ptr to video frame to be returned 2399 * 2400 * RETURN : int32_t type of status 2401 * NO_ERROR -- success 2402 * none-zero failure code 2403 *==========================================================================*/ 2404 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque) 2405 { 2406 int32_t rc = UNKNOWN_ERROR; 2407 QCameraVideoChannel *pChannel = 2408 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO]; 2409 CDBG_HIGH("%s: opaque data = %p", __func__,opaque); 2410 if(pChannel != NULL) { 2411 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0); 2412 } 2413 return rc; 2414 } 2415 2416 /*=========================================================================== 2417 * FUNCTION : autoFocus 2418 * 2419 * DESCRIPTION: start auto focus impl 2420 * 2421 * PARAMETERS : none 2422 * 2423 * RETURN : int32_t type of status 2424 * NO_ERROR -- success 2425 * none-zero failure code 2426 *==========================================================================*/ 2427 int QCamera2HardwareInterface::autoFocus() 2428 { 2429 int rc = NO_ERROR; 2430 setCancelAutoFocus(false); 2431 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 2432 2433 switch (focusMode) { 2434 case CAM_FOCUS_MODE_AUTO: 2435 case CAM_FOCUS_MODE_MACRO: 2436 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 2437 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 2438 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle); 2439 break; 2440 case CAM_FOCUS_MODE_INFINITY: 2441 case CAM_FOCUS_MODE_FIXED: 2442 case CAM_FOCUS_MODE_EDOF: 2443 default: 2444 ALOGE("%s: No ops in focusMode (%d)", __func__, focusMode); 2445 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 2446 break; 2447 } 2448 return rc; 2449 } 2450 2451 /*=========================================================================== 2452 * FUNCTION : cancelAutoFocus 2453 * 2454 * DESCRIPTION: cancel auto focus impl 2455 * 2456 * PARAMETERS : none 2457 * 2458 * RETURN : int32_t type of status 2459 * NO_ERROR -- success 2460 * none-zero failure code 2461 *==========================================================================*/ 2462 int QCamera2HardwareInterface::cancelAutoFocus() 2463 { 2464 int rc = NO_ERROR; 2465 setCancelAutoFocus(true); 2466 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 2467 2468 switch (focusMode) { 2469 case CAM_FOCUS_MODE_AUTO: 2470 case CAM_FOCUS_MODE_MACRO: 2471 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 2472 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 2473 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle); 2474 break; 2475 case CAM_FOCUS_MODE_INFINITY: 2476 case CAM_FOCUS_MODE_FIXED: 2477 case CAM_FOCUS_MODE_EDOF: 2478 default: 2479 CDBG("%s: No ops in focusMode (%d)", __func__, focusMode); 2480 break; 2481 } 2482 return rc; 2483 } 2484 2485 /*=========================================================================== 2486 * FUNCTION : processUFDumps 2487 * 2488 * DESCRIPTION: process UF jpeg dumps for refocus support 2489 * 2490 * PARAMETERS : 2491 * @evt : payload of jpeg event, including information about jpeg encoding 2492 * status, jpeg size and so on. 2493 * 2494 * RETURN : int32_t type of status 2495 * NO_ERROR -- success 2496 * none-zero failure code 2497 * 2498 * NOTE : none 2499 *==========================================================================*/ 2500 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt) 2501 { 2502 bool ret = true; 2503 if (mParameters.isUbiRefocus()) { 2504 int index = (int)getOutputImageCount(); 2505 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1)); 2506 char name[FILENAME_MAX]; 2507 2508 camera_memory_t *jpeg_mem = NULL; 2509 omx_jpeg_ouput_buf_t *jpeg_out = NULL; 2510 size_t dataLen; 2511 uint8_t *dataPtr; 2512 if (!m_postprocessor.getJpegMemOpt()) { 2513 dataLen = evt->out_data.buf_filled_len; 2514 dataPtr = evt->out_data.buf_vaddr; 2515 } else { 2516 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr; 2517 if (!jpeg_out) { 2518 ALOGE("%s:%d] Null pointer detected", __func__, __LINE__); 2519 return false; 2520 } 2521 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl; 2522 if (!jpeg_mem) { 2523 ALOGE("%s:%d] Null pointer detected", __func__, __LINE__); 2524 return false; 2525 } 2526 dataPtr = (uint8_t *)jpeg_mem->data; 2527 dataLen = jpeg_mem->size; 2528 } 2529 2530 if (allFocusImage) { 2531 snprintf(name, sizeof(name), "AllFocusImage"); 2532 index = -1; 2533 } else { 2534 snprintf(name, sizeof(name), "%d", 0); 2535 } 2536 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg", 2537 dataPtr, dataLen); 2538 CDBG("%s:%d] Dump the image %d %d allFocusImage %d", __func__, __LINE__, 2539 getOutputImageCount(), index, allFocusImage); 2540 setOutputImageCount(getOutputImageCount() + 1); 2541 if (!allFocusImage) { 2542 ret = false; 2543 } 2544 } 2545 return ret; 2546 } 2547 2548 /*=========================================================================== 2549 * FUNCTION : unconfigureAdvancedCapture 2550 * 2551 * DESCRIPTION: unconfigure Advanced Capture. 2552 * 2553 * PARAMETERS : none 2554 * 2555 * RETURN : int32_t type of status 2556 * NO_ERROR -- success 2557 * none-zero failure code 2558 *==========================================================================*/ 2559 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture() 2560 { 2561 int32_t rc = NO_ERROR; 2562 2563 if (mAdvancedCaptureConfigured) { 2564 2565 mAdvancedCaptureConfigured = false; 2566 2567 if(mIs3ALocked) { 2568 mParameters.set3ALock(QCameraParameters::VALUE_FALSE); 2569 mIs3ALocked = false; 2570 } 2571 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) { 2572 rc = mParameters.setToneMapMode(true, true); 2573 if (rc != NO_ERROR) { 2574 CDBG_HIGH("%s: Failed to enable tone map during HDR/AEBracketing", __func__); 2575 } 2576 mHDRBracketingEnabled = false; 2577 rc = mParameters.stopAEBracket(); 2578 } else if (mParameters.isChromaFlashEnabled()) { 2579 rc = mParameters.resetFrameCapture(TRUE); 2580 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 2581 rc = configureAFBracketing(false); 2582 } else if (mParameters.isOptiZoomEnabled()) { 2583 rc = mParameters.setAndCommitZoom(mZoomLevel); 2584 } else if (mParameters.isStillMoreEnabled()) { 2585 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 2586 stillmore_config.burst_count = 0; 2587 mParameters.setStillMoreSettings(stillmore_config); 2588 2589 /* If SeeMore is running, it will handle re-enabling tone map */ 2590 if (!mParameters.isSeeMoreEnabled()) { 2591 rc = mParameters.setToneMapMode(true, true); 2592 if (rc != NO_ERROR) { 2593 CDBG_HIGH("%s: Failed to enable tone map during StillMore", __func__); 2594 } 2595 } 2596 2597 /* Re-enable Tintless */ 2598 mParameters.setTintless(true); 2599 } else { 2600 ALOGE("%s: No Advanced Capture feature enabled!! ", __func__); 2601 rc = BAD_VALUE; 2602 } 2603 } 2604 2605 return rc; 2606 } 2607 2608 /*=========================================================================== 2609 * FUNCTION : configureAdvancedCapture 2610 * 2611 * DESCRIPTION: configure Advanced Capture. 2612 * 2613 * PARAMETERS : none 2614 * 2615 * RETURN : int32_t type of status 2616 * NO_ERROR -- success 2617 * none-zero failure code 2618 *==========================================================================*/ 2619 int32_t QCamera2HardwareInterface::configureAdvancedCapture() 2620 { 2621 CDBG_HIGH("%s: E",__func__); 2622 int32_t rc = NO_ERROR; 2623 2624 setOutputImageCount(0); 2625 mInputCount = 0; 2626 2627 /* Temporarily stop display only if not in stillmore livesnapshot */ 2628 if (!(mParameters.isStillMoreEnabled() && 2629 mParameters.isSeeMoreEnabled())) { 2630 mParameters.setDisplayFrame(FALSE); 2631 } 2632 2633 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 2634 rc = configureAFBracketing(); 2635 } else if (mParameters.isOptiZoomEnabled()) { 2636 rc = configureOptiZoom(); 2637 } else if (mParameters.isChromaFlashEnabled()) { 2638 rc = mParameters.configFrameCapture(TRUE); 2639 } else if(mParameters.isHDREnabled()) { 2640 rc = configureHDRBracketing(); 2641 if (mHDRBracketingEnabled) { 2642 rc = mParameters.setToneMapMode(false, true); 2643 if (rc != NO_ERROR) { 2644 CDBG_HIGH("%s: Failed to disable tone map during HDR", __func__); 2645 } 2646 } 2647 } else if (mParameters.isAEBracketEnabled()) { 2648 rc = mParameters.setToneMapMode(false, true); 2649 if (rc != NO_ERROR) { 2650 CDBG_HIGH("%s: Failed to disable tone map during AEBracketing", __func__); 2651 } 2652 rc = configureAEBracketing(); 2653 } else if (mParameters.isStillMoreEnabled()) { 2654 rc = configureStillMore(); 2655 } else { 2656 ALOGE("%s: No Advanced Capture feature enabled!! ", __func__); 2657 rc = BAD_VALUE; 2658 } 2659 2660 if (NO_ERROR == rc) { 2661 mAdvancedCaptureConfigured = true; 2662 } else { 2663 mAdvancedCaptureConfigured = false; 2664 } 2665 2666 CDBG_HIGH("%s: X",__func__); 2667 return rc; 2668 } 2669 2670 /*=========================================================================== 2671 * FUNCTION : configureAFBracketing 2672 * 2673 * DESCRIPTION: configure AF Bracketing. 2674 * 2675 * PARAMETERS : none 2676 * 2677 * RETURN : int32_t type of status 2678 * NO_ERROR -- success 2679 * none-zero failure code 2680 *==========================================================================*/ 2681 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable) 2682 { 2683 CDBG_HIGH("%s: E",__func__); 2684 int32_t rc = NO_ERROR; 2685 cam_af_bracketing_t *af_bracketing_need; 2686 2687 if (mParameters.isUbiRefocus()) { 2688 af_bracketing_need = 2689 &gCamCaps[mCameraId]->refocus_af_bracketing_need; 2690 } else { 2691 af_bracketing_need = 2692 &gCamCaps[mCameraId]->ubifocus_af_bracketing_need; 2693 } 2694 2695 //Enable AF Bracketing. 2696 cam_af_bracketing_t afBracket; 2697 memset(&afBracket, 0, sizeof(cam_af_bracketing_t)); 2698 afBracket.enable = enable; 2699 afBracket.burst_count = af_bracketing_need->burst_count; 2700 2701 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) { 2702 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i]; 2703 CDBG_HIGH("%s: focus_step[%d] = %d", __func__, i, afBracket.focus_steps[i]); 2704 } 2705 //Send cmd to backend to set AF Bracketing for Ubi Focus. 2706 rc = mParameters.commitAFBracket(afBracket); 2707 if ( NO_ERROR != rc ) { 2708 ALOGE("%s: cannot configure AF bracketing", __func__); 2709 return rc; 2710 } 2711 if (enable) { 2712 mParameters.set3ALock(QCameraParameters::VALUE_TRUE); 2713 mIs3ALocked = true; 2714 } 2715 CDBG_HIGH("%s: X",__func__); 2716 return rc; 2717 } 2718 2719 /*=========================================================================== 2720 * FUNCTION : configureHDRBracketing 2721 * 2722 * DESCRIPTION: configure HDR Bracketing. 2723 * 2724 * PARAMETERS : none 2725 * 2726 * RETURN : int32_t type of status 2727 * NO_ERROR -- success 2728 * none-zero failure code 2729 *==========================================================================*/ 2730 int32_t QCamera2HardwareInterface::configureHDRBracketing() 2731 { 2732 CDBG_HIGH("%s: E",__func__); 2733 int32_t rc = NO_ERROR; 2734 2735 // 'values' should be in "idx1,idx2,idx3,..." format 2736 uint32_t hdrFrameCount = gCamCaps[mCameraId]->hdr_bracketing_setting.num_frames; 2737 CDBG_HIGH("%s : HDR values %d, %d frame count: %u", 2738 __func__, 2739 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[0], 2740 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[1], 2741 hdrFrameCount); 2742 2743 // Enable AE Bracketing for HDR 2744 cam_exp_bracketing_t aeBracket; 2745 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t)); 2746 aeBracket.mode = 2747 gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.mode; 2748 2749 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) { 2750 mHDRBracketingEnabled = true; 2751 } 2752 2753 String8 tmp; 2754 for (uint32_t i = 0; i < hdrFrameCount; i++) { 2755 tmp.appendFormat("%d", 2756 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[i]); 2757 tmp.append(","); 2758 } 2759 if (mParameters.isHDR1xFrameEnabled() 2760 && mParameters.isHDR1xExtraBufferNeeded()) { 2761 tmp.appendFormat("%d", 0); 2762 tmp.append(","); 2763 } 2764 2765 if( !tmp.isEmpty() && 2766 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) { 2767 //Trim last comma 2768 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH); 2769 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1); 2770 } 2771 2772 CDBG_HIGH("%s : HDR config values %s", 2773 __func__, 2774 aeBracket.values); 2775 rc = mParameters.setHDRAEBracket(aeBracket); 2776 if ( NO_ERROR != rc ) { 2777 ALOGE("%s: cannot configure HDR bracketing", __func__); 2778 return rc; 2779 } 2780 CDBG_HIGH("%s: X",__func__); 2781 return rc; 2782 } 2783 2784 /*=========================================================================== 2785 * FUNCTION : configureAEBracketing 2786 * 2787 * DESCRIPTION: configure AE Bracketing. 2788 * 2789 * PARAMETERS : none 2790 * 2791 * RETURN : int32_t type of status 2792 * NO_ERROR -- success 2793 * none-zero failure code 2794 *==========================================================================*/ 2795 int32_t QCamera2HardwareInterface::configureAEBracketing() 2796 { 2797 CDBG_HIGH("%s: E",__func__); 2798 int32_t rc = NO_ERROR; 2799 2800 rc = mParameters.setAEBracketing(); 2801 if ( NO_ERROR != rc ) { 2802 ALOGE("%s: cannot configure AE bracketing", __func__); 2803 return rc; 2804 } 2805 CDBG_HIGH("%s: X",__func__); 2806 return rc; 2807 } 2808 2809 /*=========================================================================== 2810 * FUNCTION : configureOptiZoom 2811 * 2812 * DESCRIPTION: configure Opti Zoom. 2813 * 2814 * PARAMETERS : none 2815 * 2816 * RETURN : int32_t type of status 2817 * NO_ERROR -- success 2818 * none-zero failure code 2819 *==========================================================================*/ 2820 int32_t QCamera2HardwareInterface::configureOptiZoom() 2821 { 2822 int32_t rc = NO_ERROR; 2823 2824 //store current zoom level. 2825 mZoomLevel = mParameters.getParmZoomLevel(); 2826 2827 //set zoom level to 1x; 2828 mParameters.setAndCommitZoom(0); 2829 2830 mParameters.set3ALock(QCameraParameters::VALUE_TRUE); 2831 mIs3ALocked = true; 2832 2833 return rc; 2834 } 2835 2836 /*=========================================================================== 2837 * FUNCTION : configureStillMore 2838 * 2839 * DESCRIPTION: configure StillMore. 2840 * 2841 * PARAMETERS : none 2842 * 2843 * RETURN : int32_t type of status 2844 * NO_ERROR -- success 2845 * none-zero failure code 2846 *==========================================================================*/ 2847 int32_t QCamera2HardwareInterface::configureStillMore() 2848 { 2849 int32_t rc = NO_ERROR; 2850 uint8_t burst_cnt = 0; 2851 cam_still_more_t stillmore_config; 2852 cam_still_more_t stillmore_cap; 2853 2854 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */ 2855 if (!mParameters.isSeeMoreEnabled()) { 2856 rc = mParameters.setToneMapMode(false, true); 2857 if (rc != NO_ERROR) { 2858 CDBG_HIGH("%s: Failed to disable tone map during StillMore", __func__); 2859 } 2860 } 2861 2862 /* Lock 3A */ 2863 mParameters.set3ALock(QCameraParameters::VALUE_TRUE); 2864 mIs3ALocked = true; 2865 2866 /* Disable Tintless */ 2867 mParameters.setTintless(false); 2868 2869 /* Configure burst count based on user input */ 2870 char prop[PROPERTY_VALUE_MAX]; 2871 property_get("persist.camera.imglib.stillmore", prop, "0"); 2872 burst_cnt = (uint32_t)atoi(prop); 2873 2874 /* In the case of liveshot, burst should be 1 */ 2875 if (mParameters.isSeeMoreEnabled()) { 2876 burst_cnt = 1; 2877 } 2878 2879 /* Validate burst count */ 2880 stillmore_cap = mParameters.getStillMoreCapability(); 2881 if ((burst_cnt < stillmore_cap.min_burst_count) || 2882 (burst_cnt > stillmore_cap.max_burst_count)) { 2883 burst_cnt = stillmore_cap.max_burst_count; 2884 } 2885 2886 memset(&stillmore_config, 0, sizeof(cam_still_more_t)); 2887 stillmore_config.burst_count = burst_cnt; 2888 mParameters.setStillMoreSettings(stillmore_config); 2889 2890 CDBG_HIGH("%s: Stillmore burst %d", __func__, burst_cnt); 2891 2892 return rc; 2893 } 2894 2895 /*=========================================================================== 2896 * FUNCTION : stopAdvancedCapture 2897 * 2898 * DESCRIPTION: stops advanced capture based on capture type 2899 * 2900 * PARAMETERS : 2901 * @pChannel : channel. 2902 * 2903 * RETURN : int32_t type of status 2904 * NO_ERROR -- success 2905 * none-zero failure code 2906 *==========================================================================*/ 2907 int32_t QCamera2HardwareInterface::stopAdvancedCapture( 2908 QCameraPicChannel *pChannel) 2909 { 2910 CDBG_HIGH("%s: stop bracketig",__func__); 2911 int32_t rc = NO_ERROR; 2912 2913 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 2914 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING); 2915 } else if (mParameters.isChromaFlashEnabled()) { 2916 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE); 2917 } else if(mParameters.isHDREnabled() 2918 || mParameters.isAEBracketEnabled()) { 2919 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING); 2920 } else if (mParameters.isOptiZoomEnabled()) { 2921 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X); 2922 } else if (mParameters.isStillMoreEnabled()) { 2923 CDBG_HIGH("%s: stopAdvancedCapture not needed for StillMore", __func__); 2924 } else { 2925 ALOGE("%s: No Advanced Capture feature enabled!",__func__); 2926 rc = BAD_VALUE; 2927 } 2928 return rc; 2929 } 2930 2931 /*=========================================================================== 2932 * FUNCTION : startAdvancedCapture 2933 * 2934 * DESCRIPTION: starts advanced capture based on capture type 2935 * 2936 * PARAMETERS : 2937 * @pChannel : channel. 2938 * 2939 * RETURN : int32_t type of status 2940 * NO_ERROR -- success 2941 * none-zero failure code 2942 *==========================================================================*/ 2943 int32_t QCamera2HardwareInterface::startAdvancedCapture( 2944 QCameraPicChannel *pChannel) 2945 { 2946 CDBG_HIGH("%s: Start bracketing",__func__); 2947 int32_t rc = NO_ERROR; 2948 2949 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 2950 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING); 2951 } else if (mParameters.isOptiZoomEnabled()) { 2952 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X); 2953 } else if (mParameters.isStillMoreEnabled()) { 2954 CDBG_HIGH("%s: startAdvancedCapture not needed for StillMore", __func__); 2955 } else if (mParameters.isHDREnabled() 2956 || mParameters.isAEBracketEnabled()) { 2957 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING); 2958 } else if (mParameters.isChromaFlashEnabled()) { 2959 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig(); 2960 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config); 2961 } else { 2962 ALOGE("%s: No Advanced Capture feature enabled!",__func__); 2963 rc = BAD_VALUE; 2964 } 2965 return rc; 2966 } 2967 2968 /*=========================================================================== 2969 * FUNCTION : takePicture 2970 * 2971 * DESCRIPTION: take picture impl 2972 * 2973 * PARAMETERS : none 2974 * 2975 * RETURN : int32_t type of status 2976 * NO_ERROR -- success 2977 * none-zero failure code 2978 *==========================================================================*/ 2979 int QCamera2HardwareInterface::takePicture() 2980 { 2981 int rc = NO_ERROR; 2982 2983 // Get total number for snapshots (retro + regular) 2984 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 2985 // Get number of retro-active snapshots 2986 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots(); 2987 CDBG_HIGH("%s: E", __func__); 2988 2989 //Set rotation value from user settings as Jpeg rotation 2990 //to configure back-end modules. 2991 mParameters.setJpegRotation(mParameters.getRotation()); 2992 2993 // Check if retro-active snapshots are not enabled 2994 if (!isRetroPicture() || !mParameters.isZSLMode()) { 2995 numRetroSnapshots = 0; 2996 CDBG_HIGH("%s: [ZSL Retro] Reset retro snaphot count to zero", __func__); 2997 } 2998 if (mParameters.isUbiFocusEnabled() || 2999 mParameters.isUbiRefocus() || 3000 mParameters.isOptiZoomEnabled() || 3001 mParameters.isHDREnabled() || 3002 mParameters.isChromaFlashEnabled() || 3003 mParameters.isAEBracketEnabled() || 3004 mParameters.isStillMoreEnabled()) { 3005 rc = configureAdvancedCapture(); 3006 if (rc == NO_ERROR) { 3007 numSnapshots = mParameters.getBurstCountForAdvancedCapture(); 3008 } 3009 } 3010 CDBG_HIGH("%s: [ZSL Retro] numSnapshots = %d, numRetroSnapshots = %d", 3011 __func__, numSnapshots, numRetroSnapshots); 3012 3013 if (mParameters.isZSLMode()) { 3014 QCameraPicChannel *pZSLChannel = 3015 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 3016 if (NULL != pZSLChannel) { 3017 3018 rc = configureOnlineRotation(*pZSLChannel); 3019 if (rc != NO_ERROR) { 3020 ALOGE("%s: online rotation failed", __func__); 3021 return rc; 3022 } 3023 3024 // start postprocessor 3025 DefferWorkArgs args; 3026 memset(&args, 0, sizeof(DefferWorkArgs)); 3027 3028 args.pprocArgs = pZSLChannel; 3029 mReprocJob = queueDefferedWork(CMD_DEFF_PPROC_START, 3030 args); 3031 3032 if (mParameters.isUbiFocusEnabled() || 3033 mParameters.isUbiRefocus() || 3034 mParameters.isOptiZoomEnabled() || 3035 mParameters.isHDREnabled() || 3036 mParameters.isChromaFlashEnabled() || 3037 mParameters.isAEBracketEnabled() || 3038 mParameters.isStillMoreEnabled()) { 3039 rc = startAdvancedCapture(pZSLChannel); 3040 if (rc != NO_ERROR) { 3041 ALOGE("%s: cannot start zsl advanced capture", __func__); 3042 return rc; 3043 } 3044 } 3045 if (mLongshotEnabled && mPrepSnapRun) { 3046 mCameraHandle->ops->start_zsl_snapshot( 3047 mCameraHandle->camera_handle, 3048 pZSLChannel->getMyHandle()); 3049 } 3050 rc = pZSLChannel->takePicture(numSnapshots, numRetroSnapshots); 3051 if (rc != NO_ERROR) { 3052 ALOGE("%s: cannot take ZSL picture, stop pproc", __func__); 3053 waitDefferedWork(mReprocJob); 3054 m_postprocessor.stop(); 3055 return rc; 3056 } 3057 } else { 3058 ALOGE("%s: ZSL channel is NULL", __func__); 3059 return UNKNOWN_ERROR; 3060 } 3061 } else { 3062 3063 // start snapshot 3064 if (mParameters.isJpegPictureFormat() || 3065 mParameters.isNV16PictureFormat() || 3066 mParameters.isNV21PictureFormat()) { 3067 3068 if (!isLongshotEnabled()) { 3069 3070 rc = addCaptureChannel(); 3071 3072 // normal capture case 3073 // need to stop preview channel 3074 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3075 delChannel(QCAMERA_CH_TYPE_PREVIEW); 3076 3077 if (NO_ERROR == rc) { 3078 rc = declareSnapshotStreams(); 3079 if (NO_ERROR != rc) { 3080 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3081 return rc; 3082 } 3083 } 3084 3085 waitDefferedWork(mSnapshotJob); 3086 waitDefferedWork(mMetadataJob); 3087 waitDefferedWork(mRawdataJob); 3088 3089 { 3090 DefferWorkArgs args; 3091 DefferAllocBuffArgs allocArgs; 3092 3093 memset(&args, 0, sizeof(DefferWorkArgs)); 3094 memset(&allocArgs, 0, sizeof(DefferAllocBuffArgs)); 3095 3096 allocArgs.ch = m_channels[QCAMERA_CH_TYPE_CAPTURE]; 3097 allocArgs.type = CAM_STREAM_TYPE_POSTVIEW; 3098 args.allocArgs = allocArgs; 3099 3100 mPostviewJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF, 3101 args); 3102 3103 if (mPostviewJob == -1) { 3104 rc = UNKNOWN_ERROR; 3105 } 3106 } 3107 3108 waitDefferedWork(mPostviewJob); 3109 } else { 3110 // normal capture case 3111 // need to stop preview channel 3112 3113 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3114 delChannel(QCAMERA_CH_TYPE_PREVIEW); 3115 3116 rc = declareSnapshotStreams(); 3117 if (NO_ERROR != rc) { 3118 return rc; 3119 } 3120 3121 rc = addCaptureChannel(); 3122 } 3123 3124 if ((rc == NO_ERROR) && 3125 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) { 3126 3127 // configure capture channel 3128 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->config(); 3129 if (rc != NO_ERROR) { 3130 ALOGE("%s: cannot configure capture channel", __func__); 3131 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3132 return rc; 3133 } 3134 3135 if (!mParameters.getofflineRAW()) { 3136 rc = configureOnlineRotation( 3137 *m_channels[QCAMERA_CH_TYPE_CAPTURE]); 3138 if (rc != NO_ERROR) { 3139 ALOGE("%s: online rotation failed", __func__); 3140 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3141 return rc; 3142 } 3143 } 3144 3145 DefferWorkArgs args; 3146 memset(&args, 0, sizeof(DefferWorkArgs)); 3147 3148 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE]; 3149 mReprocJob = queueDefferedWork(CMD_DEFF_PPROC_START, 3150 args); 3151 3152 // start catpure channel 3153 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start(); 3154 if (rc != NO_ERROR) { 3155 ALOGE("%s: cannot start capture channel", __func__); 3156 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3157 return rc; 3158 } 3159 3160 QCameraPicChannel *pCapChannel = 3161 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 3162 if (NULL != pCapChannel) { 3163 if (mParameters.isUbiFocusEnabled() || 3164 mParameters.isUbiRefocus() || 3165 mParameters.isChromaFlashEnabled()) { 3166 rc = startAdvancedCapture(pCapChannel); 3167 if (rc != NO_ERROR) { 3168 ALOGE("%s: cannot start advanced capture", __func__); 3169 return rc; 3170 } 3171 } 3172 } 3173 if ( mLongshotEnabled ) { 3174 rc = longShot(); 3175 if (NO_ERROR != rc) { 3176 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3177 return rc; 3178 } 3179 } 3180 } else { 3181 ALOGE("%s: cannot add capture channel", __func__); 3182 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3183 return rc; 3184 } 3185 } else { 3186 3187 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3188 delChannel(QCAMERA_CH_TYPE_PREVIEW); 3189 3190 rc = mParameters.updateRAW(gCamCaps[mCameraId]->raw_dim[0]); 3191 if (NO_ERROR != rc) { 3192 ALOGE("%s: Raw dimension update failed %d", __func__, rc); 3193 return rc; 3194 } 3195 3196 rc = declareSnapshotStreams(); 3197 if (NO_ERROR != rc) { 3198 ALOGE("%s: RAW stream info configuration failed %d", 3199 __func__, 3200 rc); 3201 return rc; 3202 } 3203 3204 rc = addRawChannel(); 3205 if (rc == NO_ERROR) { 3206 // start postprocessor 3207 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 3208 if (rc != NO_ERROR) { 3209 ALOGE("%s: cannot start postprocessor", __func__); 3210 delChannel(QCAMERA_CH_TYPE_RAW); 3211 return rc; 3212 } 3213 3214 rc = startChannel(QCAMERA_CH_TYPE_RAW); 3215 if (rc != NO_ERROR) { 3216 ALOGE("%s: cannot start raw channel", __func__); 3217 m_postprocessor.stop(); 3218 delChannel(QCAMERA_CH_TYPE_RAW); 3219 return rc; 3220 } 3221 } else { 3222 ALOGE("%s: cannot add raw channel", __func__); 3223 return rc; 3224 } 3225 } 3226 } 3227 CDBG_HIGH("%s: X", __func__); 3228 return rc; 3229 } 3230 3231 /*=========================================================================== 3232 * FUNCTION : configureOnlineRotation 3233 * 3234 * DESCRIPTION: Configure backend with expected rotation for snapshot stream 3235 * 3236 * PARAMETERS : 3237 * @ch : Channel containing a snapshot stream 3238 * 3239 * RETURN : int32_t type of status 3240 * NO_ERROR -- success 3241 * none-zero failure code 3242 *==========================================================================*/ 3243 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch) 3244 { 3245 int rc = NO_ERROR; 3246 uint32_t streamId = 0; 3247 QCameraStream *pStream = NULL; 3248 3249 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) { 3250 QCameraStream *stream = ch.getStreamByIndex(i); 3251 if ((NULL != stream) && 3252 (CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())) { 3253 pStream = stream; 3254 break; 3255 } 3256 } 3257 3258 if (NULL == pStream) { 3259 ALOGE("%s: No snapshot stream found!", __func__); 3260 return BAD_VALUE; 3261 } 3262 3263 streamId = pStream->getMyServerID(); 3264 // Update online rotation configuration 3265 pthread_mutex_lock(&m_parm_lock); 3266 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId, 3267 mParameters.getDeviceRotation()); 3268 if (rc != NO_ERROR) { 3269 ALOGE("%s: addOnlineRotation failed %d", __func__, rc); 3270 pthread_mutex_unlock(&m_parm_lock); 3271 return rc; 3272 } 3273 pthread_mutex_unlock(&m_parm_lock); 3274 3275 return rc; 3276 } 3277 3278 /*=========================================================================== 3279 * FUNCTION : declareSnapshotStreams 3280 * 3281 * DESCRIPTION: Configure backend with expected snapshot streams 3282 * 3283 * PARAMETERS : none 3284 * 3285 * RETURN : int32_t type of status 3286 * NO_ERROR -- success 3287 * none-zero failure code 3288 *==========================================================================*/ 3289 int32_t QCamera2HardwareInterface::declareSnapshotStreams() 3290 { 3291 int rc = NO_ERROR; 3292 3293 // Update stream info configuration 3294 pthread_mutex_lock(&m_parm_lock); 3295 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false); 3296 if (rc != NO_ERROR) { 3297 ALOGE("%s: setStreamConfigure failed %d", __func__, rc); 3298 pthread_mutex_unlock(&m_parm_lock); 3299 return rc; 3300 } 3301 pthread_mutex_unlock(&m_parm_lock); 3302 3303 return rc; 3304 } 3305 3306 /*=========================================================================== 3307 * FUNCTION : longShot 3308 * 3309 * DESCRIPTION: Queue one more ZSL frame 3310 * in the longshot pipe. 3311 * 3312 * PARAMETERS : none 3313 * 3314 * RETURN : int32_t type of status 3315 * NO_ERROR -- success 3316 * none-zero failure code 3317 *==========================================================================*/ 3318 int32_t QCamera2HardwareInterface::longShot() 3319 { 3320 int32_t rc = NO_ERROR; 3321 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 3322 QCameraPicChannel *pChannel = NULL; 3323 3324 if (mParameters.isZSLMode()) { 3325 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 3326 } else { 3327 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 3328 } 3329 3330 if (NULL != pChannel) { 3331 rc = pChannel->takePicture(numSnapshots, 0); 3332 } else { 3333 ALOGE(" %s : Capture channel not initialized!", __func__); 3334 rc = NO_INIT; 3335 goto end; 3336 } 3337 3338 end: 3339 return rc; 3340 } 3341 3342 /*=========================================================================== 3343 * FUNCTION : stopCaptureChannel 3344 * 3345 * DESCRIPTION: Stops capture channel 3346 * 3347 * PARAMETERS : 3348 * @destroy : Set to true to stop and delete camera channel. 3349 * Set to false to only stop capture channel. 3350 * 3351 * RETURN : int32_t type of status 3352 * NO_ERROR -- success 3353 * none-zero failure code 3354 *==========================================================================*/ 3355 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy) 3356 { 3357 int rc = NO_ERROR; 3358 if (mParameters.isJpegPictureFormat() || 3359 mParameters.isNV16PictureFormat() || 3360 mParameters.isNV21PictureFormat()) { 3361 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE); 3362 if (destroy && (NO_ERROR == rc)) { 3363 // Destroy camera channel but dont release context 3364 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false); 3365 } 3366 } 3367 3368 return rc; 3369 } 3370 3371 /*=========================================================================== 3372 * FUNCTION : cancelPicture 3373 * 3374 * DESCRIPTION: cancel picture impl 3375 * 3376 * PARAMETERS : none 3377 * 3378 * RETURN : int32_t type of status 3379 * NO_ERROR -- success 3380 * none-zero failure code 3381 *==========================================================================*/ 3382 int QCamera2HardwareInterface::cancelPicture() 3383 { 3384 waitDefferedWork(mReprocJob); 3385 3386 //stop post processor 3387 m_postprocessor.stop(); 3388 3389 unconfigureAdvancedCapture(); 3390 3391 mParameters.setDisplayFrame(TRUE); 3392 3393 if (!mLongshotEnabled) { 3394 m_perfLock.lock_rel(); 3395 } 3396 3397 if (mParameters.isZSLMode()) { 3398 QCameraPicChannel *pZSLChannel = 3399 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 3400 if (NULL != pZSLChannel) { 3401 stopAdvancedCapture(pZSLChannel); 3402 pZSLChannel->cancelPicture(); 3403 } 3404 } else { 3405 3406 // normal capture case 3407 if (mParameters.isJpegPictureFormat() || 3408 mParameters.isNV16PictureFormat() || 3409 mParameters.isNV21PictureFormat()) { 3410 stopChannel(QCAMERA_CH_TYPE_CAPTURE); 3411 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3412 } else { 3413 stopChannel(QCAMERA_CH_TYPE_RAW); 3414 delChannel(QCAMERA_CH_TYPE_RAW); 3415 } 3416 } 3417 3418 return NO_ERROR; 3419 } 3420 3421 /*=========================================================================== 3422 * FUNCTION : captureDone 3423 * 3424 * DESCRIPTION: Function called when the capture is completed before encoding 3425 * 3426 * PARAMETERS : none 3427 * 3428 * RETURN : none 3429 *==========================================================================*/ 3430 void QCamera2HardwareInterface::captureDone() 3431 { 3432 qcamera_sm_internal_evt_payload_t *payload = 3433 (qcamera_sm_internal_evt_payload_t *) 3434 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 3435 if (NULL != payload) { 3436 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 3437 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE; 3438 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 3439 if (rc != NO_ERROR) { 3440 ALOGE("%s: processEvt ZSL capture done failed", __func__); 3441 free(payload); 3442 payload = NULL; 3443 } 3444 } else { 3445 ALOGE("%s: No memory for ZSL capture done event", __func__); 3446 } 3447 } 3448 3449 /*=========================================================================== 3450 * FUNCTION : Live_Snapshot_thread 3451 * 3452 * DESCRIPTION: Seperate thread for taking live snapshot during recording 3453 * 3454 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 3455 * 3456 * RETURN : none 3457 *==========================================================================*/ 3458 void* Live_Snapshot_thread (void* data) 3459 { 3460 3461 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 3462 if (!hw) { 3463 ALOGE("take_picture_thread: NULL camera device"); 3464 return (void *)BAD_VALUE; 3465 } 3466 hw->takeLiveSnapshot_internal(); 3467 return (void* )NULL; 3468 } 3469 3470 /*=========================================================================== 3471 * FUNCTION : Int_Pic_thread 3472 * 3473 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend 3474 * 3475 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 3476 * 3477 * RETURN : none 3478 *==========================================================================*/ 3479 void* Int_Pic_thread (void* data) 3480 { 3481 int rc = NO_ERROR; 3482 3483 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 3484 3485 if (!hw) { 3486 ALOGE("take_picture_thread: NULL camera device"); 3487 return (void *)BAD_VALUE; 3488 } 3489 3490 bool JpegMemOpt = false; 3491 char raw_format[PROPERTY_VALUE_MAX]; 3492 3493 memset(raw_format, 0, sizeof(raw_format)); 3494 3495 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]); 3496 if (rc == NO_ERROR) { 3497 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]); 3498 } else { 3499 //Snapshot attempt not successful, we need to do cleanup here 3500 hw->clearIntPendingEvents(); 3501 } 3502 3503 return (void* )NULL; 3504 } 3505 3506 /*=========================================================================== 3507 * FUNCTION : takeLiveSnapshot 3508 * 3509 * DESCRIPTION: take live snapshot during recording 3510 * 3511 * PARAMETERS : none 3512 * 3513 * RETURN : int32_t type of status 3514 * NO_ERROR -- success 3515 * none-zero failure code 3516 *==========================================================================*/ 3517 int QCamera2HardwareInterface::takeLiveSnapshot() 3518 { 3519 int rc = NO_ERROR; 3520 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this); 3521 return rc; 3522 } 3523 3524 /*=========================================================================== 3525 * FUNCTION : takePictureInternal 3526 * 3527 * DESCRIPTION: take snapshot triggered by backend 3528 * 3529 * PARAMETERS : none 3530 * 3531 * RETURN : int32_t type of status 3532 * NO_ERROR -- success 3533 * none-zero failure code 3534 *==========================================================================*/ 3535 int QCamera2HardwareInterface::takePictureInternal() 3536 { 3537 int rc = NO_ERROR; 3538 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this); 3539 return rc; 3540 } 3541 3542 /*=========================================================================== 3543 * FUNCTION : checkIntPicPending 3544 * 3545 * DESCRIPTION: timed wait for jpeg completion event, and send 3546 * back completion event to backend 3547 * 3548 * PARAMETERS : none 3549 * 3550 * RETURN : none 3551 *==========================================================================*/ 3552 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format) 3553 { 3554 bool bSendToBackend = true; 3555 cam_int_evt_params_t params; 3556 int rc = NO_ERROR; 3557 3558 struct timespec ts; 3559 struct timeval tp; 3560 gettimeofday(&tp, NULL); 3561 ts.tv_sec = tp.tv_sec + 5; 3562 ts.tv_nsec = tp.tv_usec * 1000; 3563 3564 if (true == m_bIntJpegEvtPending || 3565 (true == m_bIntRawEvtPending)) { 3566 //Waiting in HAL for snapshot taken notification 3567 pthread_mutex_lock(&m_int_lock); 3568 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts); 3569 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) { 3570 //Hit a timeout, or some spurious activity 3571 bSendToBackend = false; 3572 } 3573 3574 if (true == m_bIntJpegEvtPending) { 3575 params.event_type = 0; 3576 } else if (true == m_bIntRawEvtPending) { 3577 params.event_type = 1; 3578 } 3579 pthread_mutex_unlock(&m_int_lock); 3580 3581 if (true == m_bIntJpegEvtPending) { 3582 //Attempting to restart preview after taking JPEG snapshot 3583 lockAPI(); 3584 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 3585 unlockAPI(); 3586 m_postprocessor.setJpegMemOpt(JpegMemOpt); 3587 } else if (true == m_bIntRawEvtPending) { 3588 //Attempting to restart preview after taking RAW snapshot 3589 stopChannel(QCAMERA_CH_TYPE_RAW); 3590 delChannel(QCAMERA_CH_TYPE_RAW); 3591 //restoring the old raw format 3592 property_set("persist.camera.raw.format", raw_format); 3593 } 3594 3595 if (true == bSendToBackend) { 3596 //send event back to server with the file path 3597 params.dim = m_postprocessor.m_dst_dim; 3598 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH); 3599 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH); 3600 params.size = mBackendFileSize; 3601 pthread_mutex_lock(&m_parm_lock); 3602 rc = mParameters.setIntEvent(params); 3603 pthread_mutex_unlock(&m_parm_lock); 3604 } 3605 3606 clearIntPendingEvents(); 3607 } 3608 3609 return; 3610 } 3611 3612 /*=========================================================================== 3613 * FUNCTION : takeBackendPic_internal 3614 * 3615 * DESCRIPTION: take snapshot triggered by backend 3616 * 3617 * PARAMETERS : none 3618 * 3619 * RETURN : int32_t type of status 3620 * NO_ERROR -- success 3621 * none-zero failure code 3622 *==========================================================================*/ 3623 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format) 3624 { 3625 int rc = NO_ERROR; 3626 qcamera_api_result_t apiResult; 3627 3628 lockAPI(); 3629 //Set rotation value from user settings as Jpeg rotation 3630 //to configure back-end modules. 3631 mParameters.setJpegRotation(mParameters.getRotation()); 3632 3633 setRetroPicture(0); 3634 /* Prepare snapshot in case LED needs to be flashed */ 3635 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) { 3636 // Start Preparing for normal Frames 3637 CDBG_HIGH("%s: Start Prepare Snapshot", __func__); 3638 /* Prepare snapshot in case LED needs to be flashed */ 3639 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 3640 if (rc == NO_ERROR) { 3641 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 3642 rc = apiResult.status; 3643 CDBG_HIGH("%s: Prep Snapshot done", __func__); 3644 } 3645 mPrepSnapRun = true; 3646 } 3647 unlockAPI(); 3648 3649 if (true == m_bIntJpegEvtPending) { 3650 //Attempting to take JPEG snapshot 3651 *JpegMemOpt = m_postprocessor.getJpegMemOpt(); 3652 m_postprocessor.setJpegMemOpt(false); 3653 3654 /* capture */ 3655 lockAPI(); 3656 CDBG_HIGH("%s: Capturing internal snapshot", __func__); 3657 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 3658 if (rc == NO_ERROR) { 3659 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 3660 rc = apiResult.status; 3661 } 3662 unlockAPI(); 3663 } else if (true == m_bIntRawEvtPending) { 3664 //Attempting to take RAW snapshot 3665 (void)JpegMemOpt; 3666 stopPreview(); 3667 3668 //getting the existing raw format type 3669 property_get("persist.camera.raw.format", raw_format, "16"); 3670 //setting it to a default know value for this task 3671 property_set("persist.camera.raw.format", "18"); 3672 3673 rc = addRawChannel(); 3674 if (rc == NO_ERROR) { 3675 // start postprocessor 3676 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 3677 if (rc != NO_ERROR) { 3678 ALOGE("%s: cannot start postprocessor", __func__); 3679 delChannel(QCAMERA_CH_TYPE_RAW); 3680 return rc; 3681 } 3682 3683 rc = startChannel(QCAMERA_CH_TYPE_RAW); 3684 if (rc != NO_ERROR) { 3685 ALOGE("%s: cannot start raw channel", __func__); 3686 m_postprocessor.stop(); 3687 delChannel(QCAMERA_CH_TYPE_RAW); 3688 return rc; 3689 } 3690 } else { 3691 ALOGE("%s: cannot add raw channel", __func__); 3692 return rc; 3693 } 3694 } 3695 3696 return rc; 3697 } 3698 3699 /*=========================================================================== 3700 * FUNCTION : clearIntPendingEvents 3701 * 3702 * DESCRIPTION: clear internal pending events pertaining to backend 3703 * snapshot requests 3704 * 3705 * PARAMETERS : none 3706 * 3707 * RETURN : int32_t type of status 3708 * NO_ERROR -- success 3709 * none-zero failure code 3710 *==========================================================================*/ 3711 void QCamera2HardwareInterface::clearIntPendingEvents() 3712 { 3713 int rc = NO_ERROR; 3714 3715 if (true == m_bIntRawEvtPending) { 3716 preparePreview(); 3717 startPreview(); 3718 } 3719 if (true == m_bIntJpegEvtPending) { 3720 if (false == mParameters.isZSLMode()) { 3721 lockAPI(); 3722 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL); 3723 unlockAPI(); 3724 } 3725 } 3726 3727 pthread_mutex_lock(&m_int_lock); 3728 if (true == m_bIntJpegEvtPending) { 3729 m_bIntJpegEvtPending = false; 3730 } else if (true == m_bIntRawEvtPending) { 3731 m_bIntRawEvtPending = false; 3732 } 3733 pthread_mutex_unlock(&m_int_lock); 3734 return; 3735 } 3736 3737 /*=========================================================================== 3738 * FUNCTION : takeLiveSnapshot_internal 3739 * 3740 * DESCRIPTION: take live snapshot during recording 3741 * 3742 * PARAMETERS : none 3743 * 3744 * RETURN : int32_t type of status 3745 * NO_ERROR -- success 3746 * none-zero failure code 3747 *==========================================================================*/ 3748 int QCamera2HardwareInterface::takeLiveSnapshot_internal() 3749 { 3750 int rc = NO_ERROR; 3751 3752 QCameraChannel *pChannel = NULL; 3753 3754 //Set rotation value from user settings as Jpeg rotation 3755 //to configure back-end modules. 3756 mParameters.setJpegRotation(mParameters.getRotation()); 3757 3758 // Configure advanced capture 3759 if (mParameters.isUbiFocusEnabled() || 3760 mParameters.isUbiRefocus() || 3761 mParameters.isOptiZoomEnabled() || 3762 mParameters.isHDREnabled() || 3763 mParameters.isChromaFlashEnabled() || 3764 mParameters.isAEBracketEnabled() || 3765 mParameters.isStillMoreEnabled()) { 3766 rc = configureAdvancedCapture(); 3767 if (rc != NO_ERROR) { 3768 CDBG_HIGH("%s: configureAdvancedCapture unsuccessful", __func__); 3769 } 3770 } 3771 3772 // start post processor 3773 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_SNAPSHOT]); 3774 if (NO_ERROR != rc) { 3775 ALOGE("%s: Post-processor start failed %d", __func__, rc); 3776 goto end; 3777 } 3778 3779 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 3780 if (NULL == pChannel) { 3781 ALOGE("%s: Snapshot channel not initialized", __func__); 3782 rc = NO_INIT; 3783 goto end; 3784 } 3785 //Disable reprocess for 4K liveshot case 3786 if (!mParameters.is4k2kVideoResolution()) { 3787 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]); 3788 if (rc != NO_ERROR) { 3789 ALOGE("%s: online rotation failed", __func__); 3790 m_postprocessor.stop(); 3791 return rc; 3792 } 3793 } 3794 // start snapshot channel 3795 if ((rc == NO_ERROR) && (NULL != pChannel)) { 3796 // Do not link metadata stream for 4K2k resolution 3797 // as CPP processing would be done on snapshot stream and not 3798 // reprocess stream 3799 if (!mParameters.is4k2kVideoResolution()) { 3800 // Find and try to link a metadata stream from preview channel 3801 QCameraChannel *pMetaChannel = NULL; 3802 QCameraStream *pMetaStream = NULL; 3803 3804 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 3805 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 3806 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 3807 QCameraStream *pStream = NULL; 3808 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 3809 pStream = pMetaChannel->getStreamByIndex(i); 3810 if ((NULL != pStream) && 3811 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) { 3812 pMetaStream = pStream; 3813 break; 3814 } 3815 } 3816 } 3817 3818 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 3819 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 3820 if (NO_ERROR != rc) { 3821 ALOGE("%s : Metadata stream link failed %d", __func__, rc); 3822 } 3823 } 3824 } 3825 3826 rc = pChannel->start(); 3827 } 3828 3829 end: 3830 if (rc != NO_ERROR) { 3831 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 3832 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 3833 } 3834 return rc; 3835 } 3836 3837 /*=========================================================================== 3838 * FUNCTION : cancelLiveSnapshot 3839 * 3840 * DESCRIPTION: cancel current live snapshot request 3841 * 3842 * PARAMETERS : none 3843 * 3844 * RETURN : int32_t type of status 3845 * NO_ERROR -- success 3846 * none-zero failure code 3847 *==========================================================================*/ 3848 int QCamera2HardwareInterface::cancelLiveSnapshot() 3849 { 3850 int rc = NO_ERROR; 3851 3852 unconfigureAdvancedCapture(); 3853 if (!mLongshotEnabled) { 3854 m_perfLock.lock_rel(); 3855 } 3856 3857 if (mLiveSnapshotThread != 0) { 3858 pthread_join(mLiveSnapshotThread,NULL); 3859 mLiveSnapshotThread = 0; 3860 } 3861 3862 //stop post processor 3863 m_postprocessor.stop(); 3864 3865 // stop snapshot channel 3866 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT); 3867 3868 return rc; 3869 } 3870 3871 /*=========================================================================== 3872 * FUNCTION : getParameters 3873 * 3874 * DESCRIPTION: get parameters impl 3875 * 3876 * PARAMETERS : none 3877 * 3878 * RETURN : a string containing parameter pairs 3879 *==========================================================================*/ 3880 char* QCamera2HardwareInterface::getParameters() 3881 { 3882 char* strParams = NULL; 3883 String8 str; 3884 3885 int cur_width, cur_height; 3886 pthread_mutex_lock(&m_parm_lock); 3887 //Need take care Scale picture size 3888 if(mParameters.m_reprocScaleParam.isScaleEnabled() && 3889 mParameters.m_reprocScaleParam.isUnderScaling()){ 3890 int scale_width, scale_height; 3891 3892 mParameters.m_reprocScaleParam.getPicSizeFromAPK(scale_width,scale_height); 3893 mParameters.getPictureSize(&cur_width, &cur_height); 3894 3895 String8 pic_size; 3896 char buffer[32]; 3897 snprintf(buffer, sizeof(buffer), "%dx%d", scale_width, scale_height); 3898 pic_size.append(buffer); 3899 mParameters.set(CameraParameters::KEY_PICTURE_SIZE, pic_size); 3900 } 3901 3902 str = mParameters.flatten( ); 3903 strParams = (char *)malloc(sizeof(char)*(str.length()+1)); 3904 if(strParams != NULL){ 3905 memset(strParams, 0, sizeof(char)*(str.length()+1)); 3906 strlcpy(strParams, str.string(), str.length()+1); 3907 strParams[str.length()] = 0; 3908 } 3909 3910 if(mParameters.m_reprocScaleParam.isScaleEnabled() && 3911 mParameters.m_reprocScaleParam.isUnderScaling()){ 3912 //need set back picture size 3913 String8 pic_size; 3914 char buffer[32]; 3915 snprintf(buffer, sizeof(buffer), "%dx%d", cur_width, cur_height); 3916 pic_size.append(buffer); 3917 mParameters.set(CameraParameters::KEY_PICTURE_SIZE, pic_size); 3918 } 3919 pthread_mutex_unlock(&m_parm_lock); 3920 return strParams; 3921 } 3922 3923 /*=========================================================================== 3924 * FUNCTION : putParameters 3925 * 3926 * DESCRIPTION: put parameters string impl 3927 * 3928 * PARAMETERS : 3929 * @parms : parameters string to be released 3930 * 3931 * RETURN : int32_t type of status 3932 * NO_ERROR -- success 3933 * none-zero failure code 3934 *==========================================================================*/ 3935 int QCamera2HardwareInterface::putParameters(char *parms) 3936 { 3937 free(parms); 3938 return NO_ERROR; 3939 } 3940 3941 /*=========================================================================== 3942 * FUNCTION : sendCommand 3943 * 3944 * DESCRIPTION: send command impl 3945 * 3946 * PARAMETERS : 3947 * @command : command to be executed 3948 * @arg1 : optional argument 1 3949 * @arg2 : optional argument 2 3950 * 3951 * RETURN : int32_t type of status 3952 * NO_ERROR -- success 3953 * none-zero failure code 3954 *==========================================================================*/ 3955 int QCamera2HardwareInterface::sendCommand(int32_t command, 3956 int32_t &arg1, int32_t &/*arg2*/) 3957 { 3958 int rc = NO_ERROR; 3959 3960 switch (command) { 3961 #ifndef VANILLA_HAL 3962 case CAMERA_CMD_LONGSHOT_ON: 3963 m_perfLock.lock_acq(); 3964 arg1 = 0; 3965 // Longshot can only be enabled when image capture 3966 // is not active. 3967 if ( !m_stateMachine.isCaptureRunning() ) { 3968 mLongshotEnabled = true; 3969 mParameters.setLongshotEnable(mLongshotEnabled); 3970 3971 // Due to recent buffer count optimizations 3972 // ZSL might run with considerably less buffers 3973 // when not in longshot mode. Preview needs to 3974 // restart in this case. 3975 if (isZSLMode() && m_stateMachine.isPreviewRunning()) { 3976 QCameraChannel *pChannel = NULL; 3977 QCameraStream *pSnapStream = NULL; 3978 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 3979 if (NULL != pChannel) { 3980 QCameraStream *pStream = NULL; 3981 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) { 3982 pStream = pChannel->getStreamByIndex(i); 3983 if (pStream != NULL) { 3984 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 3985 pSnapStream = pStream; 3986 break; 3987 } 3988 } 3989 } 3990 if (NULL != pSnapStream) { 3991 uint8_t required = 0; 3992 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT); 3993 if (pSnapStream->getBufferCount() < required) { 3994 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW; 3995 } 3996 } 3997 } 3998 } 3999 // 4000 mPrepSnapRun = false; 4001 } else { 4002 rc = NO_INIT; 4003 } 4004 break; 4005 case CAMERA_CMD_LONGSHOT_OFF: 4006 m_perfLock.lock_rel(); 4007 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) { 4008 cancelPicture(); 4009 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 4010 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 4011 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) { 4012 mCameraHandle->ops->stop_zsl_snapshot( 4013 mCameraHandle->camera_handle, 4014 pZSLChannel->getMyHandle()); 4015 } 4016 } 4017 mPrepSnapRun = false; 4018 mLongshotEnabled = false; 4019 mParameters.setLongshotEnable(mLongshotEnabled); 4020 break; 4021 case CAMERA_CMD_HISTOGRAM_ON: 4022 case CAMERA_CMD_HISTOGRAM_OFF: 4023 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false); 4024 break; 4025 #endif 4026 case CAMERA_CMD_START_FACE_DETECTION: 4027 case CAMERA_CMD_STOP_FACE_DETECTION: 4028 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 4029 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 4030 break; 4031 #ifndef VANILLA_HAL 4032 case CAMERA_CMD_HISTOGRAM_SEND_DATA: 4033 #endif 4034 default: 4035 rc = NO_ERROR; 4036 break; 4037 } 4038 return rc; 4039 } 4040 4041 /*=========================================================================== 4042 * FUNCTION : registerFaceImage 4043 * 4044 * DESCRIPTION: register face image impl 4045 * 4046 * PARAMETERS : 4047 * @img_ptr : ptr to image buffer 4048 * @config : ptr to config struct about input image info 4049 * @faceID : [OUT] face ID to uniquely identifiy the registered face image 4050 * 4051 * RETURN : int32_t type of status 4052 * NO_ERROR -- success 4053 * none-zero failure code 4054 *==========================================================================*/ 4055 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr, 4056 cam_pp_offline_src_config_t *config, 4057 int32_t &faceID) 4058 { 4059 int rc = NO_ERROR; 4060 faceID = -1; 4061 4062 if (img_ptr == NULL || config == NULL) { 4063 ALOGE("%s: img_ptr or config is NULL", __func__); 4064 return BAD_VALUE; 4065 } 4066 4067 // allocate ion memory for source image 4068 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 4069 if (imgBuf == NULL) { 4070 ALOGE("%s: Unable to new heap memory obj for image buf", __func__); 4071 return NO_MEMORY; 4072 } 4073 4074 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE); 4075 if (rc < 0) { 4076 ALOGE("%s: Unable to allocate heap memory for image buf", __func__); 4077 delete imgBuf; 4078 return NO_MEMORY; 4079 } 4080 4081 void *pBufPtr = imgBuf->getPtr(0); 4082 if (pBufPtr == NULL) { 4083 ALOGE("%s: image buf is NULL", __func__); 4084 imgBuf->deallocate(); 4085 delete imgBuf; 4086 return NO_MEMORY; 4087 } 4088 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len); 4089 4090 cam_pp_feature_config_t pp_feature; 4091 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t)); 4092 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE; 4093 QCameraReprocessChannel *pChannel = 4094 addOfflineReprocChannel(*config, pp_feature, NULL, NULL); 4095 4096 if (pChannel == NULL) { 4097 ALOGE("%s: fail to add offline reprocess channel", __func__); 4098 imgBuf->deallocate(); 4099 delete imgBuf; 4100 return UNKNOWN_ERROR; 4101 } 4102 4103 rc = pChannel->start(); 4104 if (rc != NO_ERROR) { 4105 ALOGE("%s: Cannot start reprocess channel", __func__); 4106 imgBuf->deallocate(); 4107 delete imgBuf; 4108 delete pChannel; 4109 return rc; 4110 } 4111 4112 ssize_t bufSize = imgBuf->getSize(0); 4113 if (BAD_INDEX != bufSize) { 4114 rc = pChannel->doReprocess(imgBuf->getFd(0), (size_t)bufSize, faceID); 4115 } else { 4116 ALOGE("Failed to retrieve buffer size (bad index)"); 4117 return UNKNOWN_ERROR; 4118 } 4119 4120 // done with register face image, free imgbuf and delete reprocess channel 4121 imgBuf->deallocate(); 4122 delete imgBuf; 4123 imgBuf = NULL; 4124 pChannel->stop(); 4125 delete pChannel; 4126 pChannel = NULL; 4127 4128 return rc; 4129 } 4130 4131 /*=========================================================================== 4132 * FUNCTION : release 4133 * 4134 * DESCRIPTION: release camera resource impl 4135 * 4136 * PARAMETERS : none 4137 * 4138 * RETURN : int32_t type of status 4139 * NO_ERROR -- success 4140 * none-zero failure code 4141 *==========================================================================*/ 4142 int QCamera2HardwareInterface::release() 4143 { 4144 // stop and delete all channels 4145 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) { 4146 if (m_channels[i] != NULL) { 4147 stopChannel((qcamera_ch_type_enum_t)i); 4148 delChannel((qcamera_ch_type_enum_t)i); 4149 } 4150 } 4151 4152 return NO_ERROR; 4153 } 4154 4155 /*=========================================================================== 4156 * FUNCTION : dump 4157 * 4158 * DESCRIPTION: camera status dump impl 4159 * 4160 * PARAMETERS : 4161 * @fd : fd for the buffer to be dumped with camera status 4162 * 4163 * RETURN : int32_t type of status 4164 * NO_ERROR -- success 4165 * none-zero failure code 4166 *==========================================================================*/ 4167 int QCamera2HardwareInterface::dump(int fd) 4168 { 4169 dprintf(fd, "\n Camera HAL information Begin \n"); 4170 dprintf(fd, "Camera ID: %d \n", mCameraId); 4171 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame); 4172 dprintf(fd, "\n Configuration: %s", mParameters.dump().string()); 4173 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string()); 4174 dprintf(fd, "\n Camera HAL information End \n"); 4175 4176 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the 4177 debug level property */ 4178 mParameters.updateDebugLevel(); 4179 return NO_ERROR; 4180 } 4181 4182 /*=========================================================================== 4183 * FUNCTION : processAPI 4184 * 4185 * DESCRIPTION: process API calls from upper layer 4186 * 4187 * PARAMETERS : 4188 * @api : API to be processed 4189 * @api_payload : ptr to API payload if any 4190 * 4191 * RETURN : int32_t type of status 4192 * NO_ERROR -- success 4193 * none-zero failure code 4194 *==========================================================================*/ 4195 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload) 4196 { 4197 int ret = DEAD_OBJECT; 4198 4199 if (m_smThreadActive) { 4200 ret = m_stateMachine.procAPI(api, api_payload); 4201 } 4202 4203 return ret; 4204 } 4205 4206 /*=========================================================================== 4207 * FUNCTION : processEvt 4208 * 4209 * DESCRIPTION: process Evt from backend via mm-camera-interface 4210 * 4211 * PARAMETERS : 4212 * @evt : event type to be processed 4213 * @evt_payload : ptr to event payload if any 4214 * 4215 * RETURN : int32_t type of status 4216 * NO_ERROR -- success 4217 * none-zero failure code 4218 *==========================================================================*/ 4219 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 4220 { 4221 return m_stateMachine.procEvt(evt, evt_payload); 4222 } 4223 4224 /*=========================================================================== 4225 * FUNCTION : processSyncEvt 4226 * 4227 * DESCRIPTION: process synchronous Evt from backend 4228 * 4229 * PARAMETERS : 4230 * @evt : event type to be processed 4231 * @evt_payload : ptr to event payload if any 4232 * 4233 * RETURN : int32_t type of status 4234 * NO_ERROR -- success 4235 * none-zero failure code 4236 *==========================================================================*/ 4237 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 4238 { 4239 int rc = NO_ERROR; 4240 4241 pthread_mutex_lock(&m_evtLock); 4242 rc = processEvt(evt, evt_payload); 4243 if (rc == NO_ERROR) { 4244 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 4245 while (m_evtResult.request_api != evt) { 4246 pthread_cond_wait(&m_evtCond, &m_evtLock); 4247 } 4248 rc = m_evtResult.status; 4249 } 4250 pthread_mutex_unlock(&m_evtLock); 4251 4252 return rc; 4253 } 4254 4255 /*=========================================================================== 4256 * FUNCTION : evtHandle 4257 * 4258 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events 4259 * 4260 * PARAMETERS : 4261 * @camera_handle : event type to be processed 4262 * @evt : ptr to event 4263 * @user_data : user data ptr 4264 * 4265 * RETURN : none 4266 *==========================================================================*/ 4267 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/, 4268 mm_camera_event_t *evt, 4269 void *user_data) 4270 { 4271 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data; 4272 if (obj && evt) { 4273 mm_camera_event_t *payload = 4274 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t)); 4275 if (NULL != payload) { 4276 *payload = *evt; 4277 //peek into the event, if this is an eztune event from server, 4278 //then we don't need to post it to the SM Qs, we shud directly 4279 //spawn a thread and get the job done (jpeg or raw snapshot) 4280 switch (payload->server_event_type) { 4281 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 4282 //Received JPEG trigger from eztune 4283 if (false == obj->m_bIntJpegEvtPending) { 4284 pthread_mutex_lock(&obj->m_int_lock); 4285 obj->m_bIntJpegEvtPending = true; 4286 pthread_mutex_unlock(&obj->m_int_lock); 4287 obj->takePictureInternal(); 4288 } 4289 free(payload); 4290 break; 4291 case CAM_EVENT_TYPE_INT_TAKE_RAW: 4292 //Received RAW trigger from eztune 4293 if (false == obj->m_bIntRawEvtPending) { 4294 pthread_mutex_lock(&obj->m_int_lock); 4295 obj->m_bIntRawEvtPending = true; 4296 pthread_mutex_unlock(&obj->m_int_lock); 4297 obj->takePictureInternal(); 4298 } 4299 free(payload); 4300 break; 4301 case CAM_EVENT_TYPE_DAEMON_DIED: 4302 { 4303 Mutex::Autolock l(obj->mDeffLock); 4304 obj->mDeffCond.broadcast(); 4305 CDBG_HIGH("%s: broadcast mDeffCond signal\n", __func__); 4306 } 4307 default: 4308 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload); 4309 break; 4310 } 4311 } 4312 } else { 4313 ALOGE("%s: NULL user_data", __func__); 4314 } 4315 } 4316 4317 /*=========================================================================== 4318 * FUNCTION : jpegEvtHandle 4319 * 4320 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events 4321 * 4322 * PARAMETERS : 4323 * @status : status of jpeg job 4324 * @client_hdl: jpeg client handle 4325 * @jobId : jpeg job Id 4326 * @p_ouput : ptr to jpeg output result struct 4327 * @userdata : user data ptr 4328 * 4329 * RETURN : none 4330 *==========================================================================*/ 4331 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status, 4332 uint32_t /*client_hdl*/, 4333 uint32_t jobId, 4334 mm_jpeg_output_t *p_output, 4335 void *userdata) 4336 { 4337 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata; 4338 if (obj) { 4339 qcamera_jpeg_evt_payload_t *payload = 4340 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t)); 4341 if (NULL != payload) { 4342 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t)); 4343 payload->status = status; 4344 payload->jobId = jobId; 4345 if (p_output != NULL) { 4346 payload->out_data = *p_output; 4347 } 4348 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload); 4349 } 4350 } else { 4351 ALOGE("%s: NULL user_data", __func__); 4352 } 4353 } 4354 4355 /*=========================================================================== 4356 * FUNCTION : thermalEvtHandle 4357 * 4358 * DESCRIPTION: routine to handle thermal event notification 4359 * 4360 * PARAMETERS : 4361 * @level : thermal level 4362 * @userdata : userdata passed in during registration 4363 * @data : opaque data from thermal client 4364 * 4365 * RETURN : int32_t type of status 4366 * NO_ERROR -- success 4367 * none-zero failure code 4368 *==========================================================================*/ 4369 int QCamera2HardwareInterface::thermalEvtHandle( 4370 qcamera_thermal_level_enum_t *level, void *userdata, void *data) 4371 { 4372 if (!mCameraOpened) { 4373 CDBG_HIGH("%s: Camera is not opened, no need to handle thermal evt", __func__); 4374 return NO_ERROR; 4375 } 4376 4377 // Make sure thermal events are logged 4378 CDBG_HIGH("%s: level = %d, userdata = %p, data = %p", 4379 __func__, *level, userdata, data); 4380 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY 4381 // becomes an aync call. This also means we can only pass payload 4382 // by value, not by address. 4383 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level); 4384 } 4385 4386 /*=========================================================================== 4387 * FUNCTION : sendEvtNotify 4388 * 4389 * DESCRIPTION: send event notify to notify thread 4390 * 4391 * PARAMETERS : 4392 * @msg_type: msg type to be sent 4393 * @ext1 : optional extension1 4394 * @ext2 : optional extension2 4395 * 4396 * RETURN : int32_t type of status 4397 * NO_ERROR -- success 4398 * none-zero failure code 4399 *==========================================================================*/ 4400 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type, 4401 int32_t ext1, 4402 int32_t ext2) 4403 { 4404 qcamera_callback_argm_t cbArg; 4405 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 4406 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 4407 cbArg.msg_type = msg_type; 4408 cbArg.ext1 = ext1; 4409 cbArg.ext2 = ext2; 4410 return m_cbNotifier.notifyCallback(cbArg); 4411 } 4412 4413 /*=========================================================================== 4414 * FUNCTION : processAEInfo 4415 * 4416 * DESCRIPTION: process AE updates 4417 * 4418 * PARAMETERS : 4419 * @ae_params: current AE parameters 4420 * 4421 * RETURN : None 4422 *==========================================================================*/ 4423 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params) 4424 { 4425 pthread_mutex_lock(&m_parm_lock); 4426 mParameters.updateAEInfo(ae_params); 4427 pthread_mutex_unlock(&m_parm_lock); 4428 return NO_ERROR; 4429 } 4430 4431 /*=========================================================================== 4432 * FUNCTION : processFocusPositionInfo 4433 * 4434 * DESCRIPTION: process AF updates 4435 * 4436 * PARAMETERS : 4437 * @cur_pos_info: current lens position 4438 * 4439 * RETURN : None 4440 *==========================================================================*/ 4441 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info) 4442 { 4443 pthread_mutex_lock(&m_parm_lock); 4444 mParameters.updateCurrentFocusPosition(cur_pos_info); 4445 pthread_mutex_unlock(&m_parm_lock); 4446 return NO_ERROR; 4447 } 4448 4449 /*=========================================================================== 4450 * FUNCTION : processAutoFocusEvent 4451 * 4452 * DESCRIPTION: process auto focus event 4453 * 4454 * PARAMETERS : 4455 * @focus_data: struct containing auto focus result info 4456 * 4457 * RETURN : int32_t type of status 4458 * NO_ERROR -- success 4459 * none-zero failure code 4460 *==========================================================================*/ 4461 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data) 4462 { 4463 int32_t ret = NO_ERROR; 4464 CDBG_HIGH("%s: E",__func__); 4465 4466 m_currentFocusState = focus_data.focus_state; 4467 4468 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 4469 switch (focusMode) { 4470 case CAM_FOCUS_MODE_AUTO: 4471 case CAM_FOCUS_MODE_MACRO: 4472 if (getCancelAutoFocus()) { 4473 // auto focus has canceled, just ignore it 4474 break; 4475 } 4476 // If the HAL focus mode is AUTO and AF focus mode is INFINITY, send event to app 4477 if ((focusMode == CAM_FOCUS_MODE_AUTO) && 4478 (focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 4479 (focus_data.focus_state == CAM_AF_INACTIVE)) { 4480 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 4481 break; 4482 } 4483 if (focus_data.focus_state == CAM_AF_SCANNING || 4484 focus_data.focus_state == CAM_AF_INACTIVE) { 4485 // in the middle of focusing, just ignore it 4486 break; 4487 } 4488 // update focus distance 4489 mParameters.updateFocusDistances(&focus_data.focus_dist); 4490 4491 if ((CAM_AF_FOCUSED == focus_data.focus_state) && 4492 mParameters.isZSLMode()) { 4493 QCameraPicChannel *pZSLChannel = 4494 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 4495 if (NULL != pZSLChannel) { 4496 //flush the zsl-buffer 4497 uint32_t flush_frame_idx = focus_data.focused_frame_idx; 4498 CDBG("%s, flush the zsl-buffer before frame = %u.", __func__, flush_frame_idx); 4499 pZSLChannel->flushSuperbuffer(flush_frame_idx); 4500 } 4501 } 4502 4503 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 4504 (focus_data.focus_state == CAM_AF_FOCUSED)? true : false, 4505 0); 4506 break; 4507 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 4508 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 4509 4510 // If the HAL focus mode is AUTO and AF focus mode is INFINITY, send event to app 4511 if ((focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE) && 4512 (focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 4513 (focus_data.focus_state == CAM_AF_INACTIVE)) { 4514 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0); 4515 break; 4516 } 4517 4518 if (focus_data.focus_state == CAM_AF_FOCUSED || 4519 focus_data.focus_state == CAM_AF_NOT_FOCUSED) { 4520 // update focus distance 4521 mParameters.updateFocusDistances(&focus_data.focus_dist); 4522 4523 if ((focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE) && 4524 (CAM_AF_FOCUSED == focus_data.focus_state) && 4525 mParameters.isZSLMode()) { 4526 QCameraPicChannel *pZSLChannel = 4527 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 4528 if (NULL != pZSLChannel) { 4529 //flush the zsl-buffer 4530 uint32_t flush_frame_idx = focus_data.focused_frame_idx; 4531 CDBG("%s, flush the zsl-buffer before frame = %u.", __func__, flush_frame_idx); 4532 pZSLChannel->flushSuperbuffer(flush_frame_idx); 4533 } 4534 } 4535 4536 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 4537 (focus_data.focus_state == CAM_AF_FOCUSED)? true : false, 4538 0); 4539 } 4540 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE, 4541 (focus_data.focus_state == CAM_AF_SCANNING)? true : false, 4542 0); 4543 break; 4544 case CAM_FOCUS_MODE_INFINITY: 4545 case CAM_FOCUS_MODE_FIXED: 4546 case CAM_FOCUS_MODE_EDOF: 4547 default: 4548 CDBG_HIGH("%s: no ops for autofocus event in focusmode %d", __func__, focusMode); 4549 break; 4550 } 4551 4552 CDBG_HIGH("%s: X",__func__); 4553 return ret; 4554 } 4555 4556 /*=========================================================================== 4557 * FUNCTION : processZoomEvent 4558 * 4559 * DESCRIPTION: process zoom event 4560 * 4561 * PARAMETERS : 4562 * @crop_info : crop info as a result of zoom operation 4563 * 4564 * RETURN : int32_t type of status 4565 * NO_ERROR -- success 4566 * none-zero failure code 4567 *==========================================================================*/ 4568 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info) 4569 { 4570 int32_t ret = NO_ERROR; 4571 4572 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 4573 if (m_channels[i] != NULL) { 4574 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info); 4575 } 4576 } 4577 return ret; 4578 } 4579 4580 /*=========================================================================== 4581 * FUNCTION : processZSLCaptureDone 4582 * 4583 * DESCRIPTION: process ZSL capture done events 4584 * 4585 * PARAMETERS : None 4586 * 4587 * RETURN : int32_t type of status 4588 * NO_ERROR -- success 4589 * none-zero failure code 4590 *==========================================================================*/ 4591 int32_t QCamera2HardwareInterface::processZSLCaptureDone() 4592 { 4593 int rc = NO_ERROR; 4594 4595 pthread_mutex_lock(&m_parm_lock); 4596 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) { 4597 rc = unconfigureAdvancedCapture(); 4598 } 4599 pthread_mutex_unlock(&m_parm_lock); 4600 4601 return rc; 4602 } 4603 4604 /*=========================================================================== 4605 * FUNCTION : processRetroAECUnlock 4606 * 4607 * DESCRIPTION: process retro burst AEC unlock events 4608 * 4609 * PARAMETERS : None 4610 * 4611 * RETURN : int32_t type of status 4612 * NO_ERROR -- success 4613 * none-zero failure code 4614 *==========================================================================*/ 4615 int32_t QCamera2HardwareInterface::processRetroAECUnlock() 4616 { 4617 int rc = NO_ERROR; 4618 4619 CDBG_HIGH("%s : [ZSL Retro] LED assisted AF Release AEC Lock", __func__); 4620 pthread_mutex_lock(&m_parm_lock); 4621 rc = mParameters.setAecLock("false"); 4622 if (NO_ERROR != rc) { 4623 ALOGE("%s: Error setting AEC lock", __func__); 4624 pthread_mutex_unlock(&m_parm_lock); 4625 return rc; 4626 } 4627 4628 rc = mParameters.commitParameters(); 4629 if (NO_ERROR != rc) { 4630 ALOGE("%s: Error during camera parameter commit", __func__); 4631 } else { 4632 m_bLedAfAecLock = FALSE; 4633 } 4634 4635 pthread_mutex_unlock(&m_parm_lock); 4636 4637 return rc; 4638 } 4639 4640 /*=========================================================================== 4641 * FUNCTION : processHDRData 4642 * 4643 * DESCRIPTION: process HDR scene events 4644 * 4645 * PARAMETERS : 4646 * @hdr_scene : HDR scene event data 4647 * 4648 * RETURN : int32_t type of status 4649 * NO_ERROR -- success 4650 * none-zero failure code 4651 *==========================================================================*/ 4652 int32_t QCamera2HardwareInterface::processHDRData(cam_asd_hdr_scene_data_t hdr_scene) 4653 { 4654 int rc = NO_ERROR; 4655 4656 #ifndef VANILLA_HAL 4657 if (hdr_scene.is_hdr_scene && 4658 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) && 4659 mParameters.isAutoHDREnabled()) { 4660 m_HDRSceneEnabled = true; 4661 } else { 4662 m_HDRSceneEnabled = false; 4663 } 4664 pthread_mutex_lock(&m_parm_lock); 4665 mParameters.setHDRSceneEnable(m_HDRSceneEnabled); 4666 pthread_mutex_unlock(&m_parm_lock); 4667 4668 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) { 4669 4670 size_t data_len = sizeof(int); 4671 size_t buffer_len = 1 *sizeof(int) //meta type 4672 + 1 *sizeof(int) //data len 4673 + 1 *sizeof(int); //data 4674 camera_memory_t *hdrBuffer = mGetMemory(-1, 4675 buffer_len, 4676 1, 4677 mCallbackCookie); 4678 if ( NULL == hdrBuffer ) { 4679 ALOGE("%s: Not enough memory for auto HDR data", 4680 __func__); 4681 return NO_MEMORY; 4682 } 4683 4684 int *pHDRData = (int *)hdrBuffer->data; 4685 if (pHDRData == NULL) { 4686 ALOGE("%s: memory data ptr is NULL", __func__); 4687 return UNKNOWN_ERROR; 4688 } 4689 4690 pHDRData[0] = CAMERA_META_DATA_HDR; 4691 pHDRData[1] = (int)data_len; 4692 pHDRData[2] = m_HDRSceneEnabled; 4693 4694 qcamera_callback_argm_t cbArg; 4695 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 4696 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 4697 cbArg.msg_type = CAMERA_MSG_META_DATA; 4698 cbArg.data = hdrBuffer; 4699 cbArg.user_data = hdrBuffer; 4700 cbArg.cookie = this; 4701 cbArg.release_cb = releaseCameraMemory; 4702 rc = m_cbNotifier.notifyCallback(cbArg); 4703 if (rc != NO_ERROR) { 4704 ALOGE("%s: fail sending auto HDR notification", __func__); 4705 hdrBuffer->release(hdrBuffer); 4706 } 4707 } 4708 4709 CDBG_HIGH("%s : hdr_scene_data: processHDRData: %d %f", 4710 __func__, 4711 hdr_scene.is_hdr_scene, 4712 hdr_scene.hdr_confidence); 4713 4714 #endif 4715 return rc; 4716 } 4717 4718 /*=========================================================================== 4719 * FUNCTION : transAwbMetaToParams 4720 * 4721 * DESCRIPTION: translate awb params from metadata callback to QCameraParameters 4722 * 4723 * PARAMETERS : 4724 * @awb_params : awb params from metadata callback 4725 * 4726 * RETURN : int32_t type of status 4727 * NO_ERROR -- success 4728 * none-zero failure code 4729 *==========================================================================*/ 4730 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params) 4731 { 4732 pthread_mutex_lock(&m_parm_lock); 4733 mParameters.updateAWBParams(awb_params); 4734 pthread_mutex_unlock(&m_parm_lock); 4735 return NO_ERROR; 4736 } 4737 4738 /*=========================================================================== 4739 * FUNCTION : processPrepSnapshotDone 4740 * 4741 * DESCRIPTION: process prep snapshot done event 4742 * 4743 * PARAMETERS : 4744 * @prep_snapshot_state : state of prepare snapshot done. In other words, 4745 * i.e. whether need future frames for capture. 4746 * 4747 * RETURN : int32_t type of status 4748 * NO_ERROR -- success 4749 * none-zero failure code 4750 *==========================================================================*/ 4751 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent( 4752 cam_prep_snapshot_state_t prep_snapshot_state) 4753 { 4754 int32_t ret = NO_ERROR; 4755 4756 if (m_channels[QCAMERA_CH_TYPE_ZSL] && 4757 prep_snapshot_state == NEED_FUTURE_FRAME) { 4758 CDBG_HIGH("%s: already handled in mm-camera-intf, no ops here", __func__); 4759 if (isRetroPicture()) { 4760 mParameters.setAecLock("true"); 4761 mParameters.commitParameters(); 4762 m_bLedAfAecLock = TRUE; 4763 } 4764 } 4765 return ret; 4766 } 4767 4768 /*=========================================================================== 4769 * FUNCTION : processASDUpdate 4770 * 4771 * DESCRIPTION: process ASD update event 4772 * 4773 * PARAMETERS : 4774 * @scene: selected scene mode 4775 * 4776 * RETURN : int32_t type of status 4777 * NO_ERROR -- success 4778 * none-zero failure code 4779 *==========================================================================*/ 4780 int32_t QCamera2HardwareInterface::processASDUpdate(cam_auto_scene_t scene) 4781 { 4782 //set ASD parameter 4783 mParameters.set(QCameraParameters::KEY_SELECTED_AUTO_SCENE, mParameters.getASDStateString(scene)); 4784 4785 size_t data_len = sizeof(cam_auto_scene_t); 4786 size_t buffer_len = 1 *sizeof(int) //meta type 4787 + 1 *sizeof(int) //data len 4788 + data_len; //data 4789 camera_memory_t *asdBuffer = mGetMemory(-1, 4790 buffer_len, 4791 1, 4792 mCallbackCookie); 4793 if ( NULL == asdBuffer ) { 4794 ALOGE("%s: Not enough memory for histogram data", __func__); 4795 return NO_MEMORY; 4796 } 4797 4798 int *pASDData = (int *)asdBuffer->data; 4799 if (pASDData == NULL) { 4800 ALOGE("%s: memory data ptr is NULL", __func__); 4801 return UNKNOWN_ERROR; 4802 } 4803 4804 #ifndef VANILLA_HAL 4805 pASDData[0] = CAMERA_META_DATA_ASD; 4806 pASDData[1] = (int)data_len; 4807 pASDData[2] = scene; 4808 4809 qcamera_callback_argm_t cbArg; 4810 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 4811 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 4812 cbArg.msg_type = CAMERA_MSG_META_DATA; 4813 cbArg.data = asdBuffer; 4814 cbArg.user_data = asdBuffer; 4815 cbArg.cookie = this; 4816 cbArg.release_cb = releaseCameraMemory; 4817 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 4818 if (rc != NO_ERROR) { 4819 ALOGE("%s: fail sending notification", __func__); 4820 asdBuffer->release(asdBuffer); 4821 } 4822 #endif 4823 return NO_ERROR; 4824 4825 } 4826 4827 /*=========================================================================== 4828 * FUNCTION : processJpegNotify 4829 * 4830 * DESCRIPTION: process jpeg event 4831 * 4832 * PARAMETERS : 4833 * @jpeg_evt: ptr to jpeg event payload 4834 * 4835 * RETURN : int32_t type of status 4836 * NO_ERROR -- success 4837 * none-zero failure code 4838 *==========================================================================*/ 4839 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt) 4840 { 4841 return m_postprocessor.processJpegEvt(jpeg_evt); 4842 } 4843 4844 /*=========================================================================== 4845 * FUNCTION : lockAPI 4846 * 4847 * DESCRIPTION: lock to process API 4848 * 4849 * PARAMETERS : none 4850 * 4851 * RETURN : none 4852 *==========================================================================*/ 4853 void QCamera2HardwareInterface::lockAPI() 4854 { 4855 pthread_mutex_lock(&m_lock); 4856 } 4857 4858 /*=========================================================================== 4859 * FUNCTION : waitAPIResult 4860 * 4861 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will 4862 * return only cerntain API event type arrives 4863 * 4864 * PARAMETERS : 4865 * @api_evt : API event type 4866 * 4867 * RETURN : none 4868 *==========================================================================*/ 4869 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt, 4870 qcamera_api_result_t *apiResult) 4871 { 4872 CDBG("%s: wait for API result of evt (%d)", __func__, api_evt); 4873 int resultReceived = 0; 4874 while (!resultReceived) { 4875 pthread_cond_wait(&m_cond, &m_lock); 4876 if (m_apiResultList != NULL) { 4877 api_result_list *apiResultList = m_apiResultList; 4878 api_result_list *apiResultListPrevious = m_apiResultList; 4879 while (apiResultList != NULL) { 4880 if (apiResultList->result.request_api == api_evt) { 4881 resultReceived = 1; 4882 *apiResult = apiResultList->result; 4883 apiResultListPrevious->next = apiResultList->next; 4884 if (apiResultList == m_apiResultList) { 4885 m_apiResultList = apiResultList->next; 4886 } 4887 free(apiResultList); 4888 break; 4889 } 4890 else { 4891 apiResultListPrevious = apiResultList; 4892 apiResultList = apiResultList->next; 4893 } 4894 } 4895 } 4896 } 4897 CDBG("%s: return (%d) from API result wait for evt (%d)", 4898 __func__, apiResult->status, api_evt); 4899 } 4900 4901 4902 /*=========================================================================== 4903 * FUNCTION : unlockAPI 4904 * 4905 * DESCRIPTION: API processing is done, unlock 4906 * 4907 * PARAMETERS : none 4908 * 4909 * RETURN : none 4910 *==========================================================================*/ 4911 void QCamera2HardwareInterface::unlockAPI() 4912 { 4913 pthread_mutex_unlock(&m_lock); 4914 } 4915 4916 /*=========================================================================== 4917 * FUNCTION : signalAPIResult 4918 * 4919 * DESCRIPTION: signal condition viarable that cerntain API event type arrives 4920 * 4921 * PARAMETERS : 4922 * @result : API result 4923 * 4924 * RETURN : none 4925 *==========================================================================*/ 4926 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result) 4927 { 4928 4929 pthread_mutex_lock(&m_lock); 4930 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list)); 4931 if (apiResult == NULL) { 4932 ALOGE("%s: ERROR: malloc for api result failed", __func__); 4933 ALOGE("%s: ERROR: api thread will wait forever fot this lost result", __func__); 4934 goto malloc_failed; 4935 } 4936 apiResult->result = *result; 4937 apiResult->next = NULL; 4938 if (m_apiResultList == NULL) m_apiResultList = apiResult; 4939 else { 4940 api_result_list *apiResultList = m_apiResultList; 4941 while(apiResultList->next != NULL) apiResultList = apiResultList->next; 4942 apiResultList->next = apiResult; 4943 } 4944 malloc_failed: 4945 pthread_cond_broadcast(&m_cond); 4946 pthread_mutex_unlock(&m_lock); 4947 } 4948 4949 /*=========================================================================== 4950 * FUNCTION : signalEvtResult 4951 * 4952 * DESCRIPTION: signal condition variable that certain event was processed 4953 * 4954 * PARAMETERS : 4955 * @result : Event result 4956 * 4957 * RETURN : none 4958 *==========================================================================*/ 4959 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result) 4960 { 4961 pthread_mutex_lock(&m_evtLock); 4962 m_evtResult = *result; 4963 pthread_cond_signal(&m_evtCond); 4964 pthread_mutex_unlock(&m_evtLock); 4965 } 4966 4967 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel) 4968 { 4969 int32_t rc = NO_ERROR; 4970 cam_dimension_t str_dim,max_dim; 4971 QCameraChannel *pChannel; 4972 4973 max_dim.width = 0; 4974 max_dim.height = 0; 4975 4976 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) { 4977 if (m_channels[j] != NULL) { 4978 pChannel = m_channels[j]; 4979 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) { 4980 QCameraStream *pStream = pChannel->getStreamByIndex(i); 4981 if (pStream != NULL) { 4982 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 4983 continue; 4984 } 4985 pStream->getFrameDimension(str_dim); 4986 if (str_dim.width > max_dim.width) { 4987 max_dim.width = str_dim.width; 4988 } 4989 if (str_dim.height > max_dim.height) { 4990 max_dim.height = str_dim.height; 4991 } 4992 } 4993 } 4994 } 4995 } 4996 4997 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) { 4998 QCameraStream *pStream = curChannel->getStreamByIndex(i); 4999 if (pStream != NULL) { 5000 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 5001 continue; 5002 } 5003 pStream->getFrameDimension(str_dim); 5004 if (str_dim.width > max_dim.width) { 5005 max_dim.width = str_dim.width; 5006 } 5007 if (str_dim.height > max_dim.height) { 5008 max_dim.height = str_dim.height; 5009 } 5010 } 5011 } 5012 rc = mParameters.updateRAW(max_dim); 5013 return rc; 5014 } 5015 /*=========================================================================== 5016 * FUNCTION : addStreamToChannel 5017 * 5018 * DESCRIPTION: add a stream into a channel 5019 * 5020 * PARAMETERS : 5021 * @pChannel : ptr to channel obj 5022 * @streamType : type of stream to be added 5023 * @streamCB : callback of stream 5024 * @userData : user data ptr to callback 5025 * 5026 * RETURN : int32_t type of status 5027 * NO_ERROR -- success 5028 * none-zero failure code 5029 *==========================================================================*/ 5030 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel, 5031 cam_stream_type_t streamType, 5032 stream_cb_routine streamCB, 5033 void *userData) 5034 { 5035 int32_t rc = NO_ERROR; 5036 5037 if (streamType == CAM_STREAM_TYPE_RAW) { 5038 prepareRawStream(pChannel); 5039 } 5040 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType); 5041 if (pStreamInfo == NULL) { 5042 ALOGE("%s: no mem for stream info buf", __func__); 5043 return NO_MEMORY; 5044 } 5045 uint8_t minStreamBufNum = getBufNumRequired(streamType); 5046 bool bDynAllocBuf = false; 5047 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) { 5048 bDynAllocBuf = true; 5049 } 5050 5051 if ( ( streamType == CAM_STREAM_TYPE_SNAPSHOT || 5052 streamType == CAM_STREAM_TYPE_POSTVIEW || 5053 streamType == CAM_STREAM_TYPE_METADATA || 5054 streamType == CAM_STREAM_TYPE_RAW) && 5055 !isZSLMode() && 5056 !isLongshotEnabled() && 5057 !mParameters.getRecordingHintValue() && 5058 !mParameters.isSecureMode()) { 5059 rc = pChannel->addStream(*this, 5060 pStreamInfo, 5061 NULL, 5062 minStreamBufNum, 5063 &gCamCaps[mCameraId]->padding_info, 5064 streamCB, userData, 5065 bDynAllocBuf, 5066 true); 5067 5068 // Queue buffer allocation for Snapshot and Metadata streams 5069 if ( !rc ) { 5070 DefferWorkArgs args; 5071 DefferAllocBuffArgs allocArgs; 5072 5073 memset(&args, 0, sizeof(DefferWorkArgs)); 5074 memset(&allocArgs, 0, sizeof(DefferAllocBuffArgs)); 5075 allocArgs.type = streamType; 5076 allocArgs.ch = pChannel; 5077 args.allocArgs = allocArgs; 5078 5079 if (streamType == CAM_STREAM_TYPE_SNAPSHOT) { 5080 mSnapshotJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF, 5081 args); 5082 5083 if ( mSnapshotJob == -1) { 5084 rc = UNKNOWN_ERROR; 5085 } 5086 } else if (streamType == CAM_STREAM_TYPE_METADATA) { 5087 mMetadataJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF, 5088 args); 5089 5090 if ( mMetadataJob == -1) { 5091 rc = UNKNOWN_ERROR; 5092 } 5093 } else if (streamType == CAM_STREAM_TYPE_RAW) { 5094 mRawdataJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF, 5095 args); 5096 5097 if ( mRawdataJob == -1) { 5098 rc = UNKNOWN_ERROR; 5099 } 5100 } 5101 } 5102 } else if (streamType == CAM_STREAM_TYPE_ANALYSIS) { 5103 rc = pChannel->addStream(*this, 5104 pStreamInfo, 5105 NULL, 5106 minStreamBufNum, 5107 &gCamCaps[mCameraId]->analysis_padding_info, 5108 streamCB, userData, 5109 bDynAllocBuf, 5110 false); 5111 } else { 5112 rc = pChannel->addStream(*this, 5113 pStreamInfo, 5114 NULL, 5115 minStreamBufNum, 5116 &gCamCaps[mCameraId]->padding_info, 5117 streamCB, userData, 5118 bDynAllocBuf, 5119 false); 5120 } 5121 5122 if (rc != NO_ERROR) { 5123 ALOGE("%s: add stream type (%d) failed, ret = %d", 5124 __func__, streamType, rc); 5125 } 5126 5127 return rc; 5128 } 5129 5130 /*=========================================================================== 5131 * FUNCTION : addPreviewChannel 5132 * 5133 * DESCRIPTION: add a preview channel that contains a preview stream 5134 * 5135 * PARAMETERS : none 5136 * 5137 * RETURN : int32_t type of status 5138 * NO_ERROR -- success 5139 * none-zero failure code 5140 *==========================================================================*/ 5141 int32_t QCamera2HardwareInterface::addPreviewChannel() 5142 { 5143 int32_t rc = NO_ERROR; 5144 QCameraChannel *pChannel = NULL; 5145 5146 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 5147 // if we had preview channel before, delete it first 5148 delete m_channels[QCAMERA_CH_TYPE_PREVIEW]; 5149 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL; 5150 } 5151 5152 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5153 mCameraHandle->ops); 5154 if (NULL == pChannel) { 5155 ALOGE("%s: no mem for preview channel", __func__); 5156 return NO_MEMORY; 5157 } 5158 5159 // preview only channel, don't need bundle attr and cb 5160 rc = pChannel->init(NULL, NULL, NULL); 5161 if (rc != NO_ERROR) { 5162 ALOGE("%s: init preview channel failed, ret = %d", __func__, rc); 5163 return rc; 5164 } 5165 5166 // meta data stream always coexists with preview if applicable 5167 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5168 metadata_stream_cb_routine, this); 5169 if (rc != NO_ERROR) { 5170 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5171 return rc; 5172 } 5173 5174 if (mParameters.getRecordingHintValue() != true && !mParameters.isSecureMode()) { 5175 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 5176 NULL, this); 5177 if (rc != NO_ERROR) { 5178 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc); 5179 return rc; 5180 } 5181 } 5182 5183 if (isRdiMode()) { 5184 CDBG_HIGH("RDI_DEBUG %s[%d]: Add stream to channel", __func__, __LINE__); 5185 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 5186 rdi_mode_stream_cb_routine, this); 5187 } else { 5188 if (isNoDisplayMode()) { 5189 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5190 nodisplay_preview_stream_cb_routine, this); 5191 } else { 5192 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5193 preview_stream_cb_routine, this); 5194 } 5195 } 5196 5197 if (rc != NO_ERROR) { 5198 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc); 5199 delete pChannel; 5200 return rc; 5201 } 5202 5203 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel; 5204 return rc; 5205 } 5206 5207 /*=========================================================================== 5208 * FUNCTION : addVideoChannel 5209 * 5210 * DESCRIPTION: add a video channel that contains a video stream 5211 * 5212 * PARAMETERS : none 5213 * 5214 * RETURN : int32_t type of status 5215 * NO_ERROR -- success 5216 * none-zero failure code 5217 *==========================================================================*/ 5218 int32_t QCamera2HardwareInterface::addVideoChannel() 5219 { 5220 int32_t rc = NO_ERROR; 5221 QCameraVideoChannel *pChannel = NULL; 5222 5223 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) { 5224 // if we had video channel before, delete it first 5225 delete m_channels[QCAMERA_CH_TYPE_VIDEO]; 5226 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL; 5227 } 5228 5229 pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle, 5230 mCameraHandle->ops); 5231 if (NULL == pChannel) { 5232 ALOGE("%s: no mem for video channel", __func__); 5233 return NO_MEMORY; 5234 } 5235 5236 // preview only channel, don't need bundle attr and cb 5237 rc = pChannel->init(NULL, NULL, NULL); 5238 if (rc != 0) { 5239 ALOGE("%s: init video channel failed, ret = %d", __func__, rc); 5240 delete pChannel; 5241 return rc; 5242 } 5243 5244 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO, 5245 video_stream_cb_routine, this); 5246 if (rc != NO_ERROR) { 5247 ALOGE("%s: add video stream failed, ret = %d", __func__, rc); 5248 delete pChannel; 5249 return rc; 5250 } 5251 5252 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel; 5253 return rc; 5254 } 5255 5256 /*=========================================================================== 5257 * FUNCTION : addSnapshotChannel 5258 * 5259 * DESCRIPTION: add a snapshot channel that contains a snapshot stream 5260 * 5261 * PARAMETERS : none 5262 * 5263 * RETURN : int32_t type of status 5264 * NO_ERROR -- success 5265 * none-zero failure code 5266 * NOTE : Add this channel for live snapshot usecase. Regular capture will 5267 * use addCaptureChannel. 5268 *==========================================================================*/ 5269 int32_t QCamera2HardwareInterface::addSnapshotChannel() 5270 { 5271 int32_t rc = NO_ERROR; 5272 QCameraChannel *pChannel = NULL; 5273 5274 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) { 5275 // if we had ZSL channel before, delete it first 5276 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 5277 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL; 5278 } 5279 5280 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5281 mCameraHandle->ops); 5282 if (NULL == pChannel) { 5283 ALOGE("%s: no mem for snapshot channel", __func__); 5284 return NO_MEMORY; 5285 } 5286 5287 mm_camera_channel_attr_t attr; 5288 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 5289 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 5290 attr.look_back = mParameters.getZSLBackLookCount(); 5291 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 5292 attr.water_mark = mParameters.getZSLQueueDepth(); 5293 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 5294 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW; 5295 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this); 5296 if (rc != NO_ERROR) { 5297 ALOGE("%s: init snapshot channel failed, ret = %d", __func__, rc); 5298 delete pChannel; 5299 return rc; 5300 } 5301 5302 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 5303 NULL, NULL); 5304 if (rc != NO_ERROR) { 5305 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc); 5306 delete pChannel; 5307 return rc; 5308 } 5309 5310 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel; 5311 return rc; 5312 } 5313 5314 /*=========================================================================== 5315 * FUNCTION : addRawChannel 5316 * 5317 * DESCRIPTION: add a raw channel that contains a raw image stream 5318 * 5319 * PARAMETERS : none 5320 * 5321 * RETURN : int32_t type of status 5322 * NO_ERROR -- success 5323 * none-zero failure code 5324 *==========================================================================*/ 5325 int32_t QCamera2HardwareInterface::addRawChannel() 5326 { 5327 int32_t rc = NO_ERROR; 5328 QCameraChannel *pChannel = NULL; 5329 5330 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) { 5331 // if we had raw channel before, delete it first 5332 delete m_channels[QCAMERA_CH_TYPE_RAW]; 5333 m_channels[QCAMERA_CH_TYPE_RAW] = NULL; 5334 } 5335 5336 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5337 mCameraHandle->ops); 5338 if (NULL == pChannel) { 5339 ALOGE("%s: no mem for raw channel", __func__); 5340 return NO_MEMORY; 5341 } 5342 5343 rc = pChannel->init(NULL, NULL, NULL); 5344 if (rc != NO_ERROR) { 5345 ALOGE("%s: init raw channel failed, ret = %d", __func__, rc); 5346 delete pChannel; 5347 return rc; 5348 } 5349 5350 // meta data stream always coexists with snapshot in regular RAW capture case 5351 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5352 metadata_stream_cb_routine, this); 5353 if (rc != NO_ERROR) { 5354 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5355 delete pChannel; 5356 return rc; 5357 } 5358 waitDefferedWork(mMetadataJob); 5359 5360 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 5361 raw_stream_cb_routine, this); 5362 if (rc != NO_ERROR) { 5363 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc); 5364 delete pChannel; 5365 return rc; 5366 } 5367 waitDefferedWork(mRawdataJob); 5368 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel; 5369 return rc; 5370 } 5371 5372 /*=========================================================================== 5373 * FUNCTION : addZSLChannel 5374 * 5375 * DESCRIPTION: add a ZSL channel that contains a preview stream and 5376 * a snapshot stream 5377 * 5378 * PARAMETERS : none 5379 * 5380 * RETURN : int32_t type of status 5381 * NO_ERROR -- success 5382 * none-zero failure code 5383 *==========================================================================*/ 5384 int32_t QCamera2HardwareInterface::addZSLChannel() 5385 { 5386 int32_t rc = NO_ERROR; 5387 QCameraPicChannel *pChannel = NULL; 5388 char value[PROPERTY_VALUE_MAX]; 5389 bool raw_yuv = false; 5390 5391 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) { 5392 // if we had ZSL channel before, delete it first 5393 delete m_channels[QCAMERA_CH_TYPE_ZSL]; 5394 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL; 5395 } 5396 5397 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle, 5398 mCameraHandle->ops); 5399 if (NULL == pChannel) { 5400 ALOGE("%s: no mem for ZSL channel", __func__); 5401 return NO_MEMORY; 5402 } 5403 5404 // ZSL channel, init with bundle attr and cb 5405 mm_camera_channel_attr_t attr; 5406 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 5407 if (mParameters.isSceneSelectionEnabled()) { 5408 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 5409 } else { 5410 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 5411 } 5412 attr.look_back = mParameters.getZSLBackLookCount(); 5413 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 5414 attr.water_mark = mParameters.getZSLQueueDepth(); 5415 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 5416 rc = pChannel->init(&attr, 5417 zsl_channel_cb, 5418 this); 5419 if (rc != 0) { 5420 ALOGE("%s: init ZSL channel failed, ret = %d", __func__, rc); 5421 delete pChannel; 5422 return rc; 5423 } 5424 5425 // meta data stream always coexists with preview if applicable 5426 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5427 metadata_stream_cb_routine, this); 5428 if (rc != NO_ERROR) { 5429 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5430 delete pChannel; 5431 return rc; 5432 } 5433 5434 if (isNoDisplayMode()) { 5435 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5436 nodisplay_preview_stream_cb_routine, this); 5437 } else { 5438 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5439 preview_stream_cb_routine, this); 5440 } 5441 if (rc != NO_ERROR) { 5442 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc); 5443 delete pChannel; 5444 return rc; 5445 } 5446 5447 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 5448 NULL, this); 5449 if (rc != NO_ERROR) { 5450 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc); 5451 delete pChannel; 5452 return rc; 5453 } 5454 5455 if (!mParameters.isSecureMode()) { 5456 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 5457 NULL, this); 5458 if (rc != NO_ERROR) { 5459 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc); 5460 delete pChannel; 5461 return rc; 5462 } 5463 } 5464 5465 property_get("persist.camera.raw_yuv", value, "0"); 5466 raw_yuv = atoi(value) > 0 ? true : false; 5467 if ( raw_yuv ) { 5468 rc = addStreamToChannel(pChannel, 5469 CAM_STREAM_TYPE_RAW, 5470 NULL, 5471 this); 5472 if (rc != NO_ERROR) { 5473 ALOGE("%s: add raw stream failed, ret = %d", __func__, rc); 5474 delete pChannel; 5475 return rc; 5476 } 5477 } 5478 5479 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel; 5480 return rc; 5481 } 5482 5483 /*=========================================================================== 5484 * FUNCTION : addCaptureChannel 5485 * 5486 * DESCRIPTION: add a capture channel that contains a snapshot stream 5487 * and a postview stream 5488 * 5489 * PARAMETERS : none 5490 * 5491 * RETURN : int32_t type of status 5492 * NO_ERROR -- success 5493 * none-zero failure code 5494 * NOTE : Add this channel for regular capture usecase. 5495 * For Live snapshot usecase, use addSnapshotChannel. 5496 *==========================================================================*/ 5497 int32_t QCamera2HardwareInterface::addCaptureChannel() 5498 { 5499 int32_t rc = NO_ERROR; 5500 QCameraPicChannel *pChannel = NULL; 5501 char value[PROPERTY_VALUE_MAX]; 5502 bool raw_yuv = false; 5503 5504 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) { 5505 delete m_channels[QCAMERA_CH_TYPE_CAPTURE]; 5506 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL; 5507 } 5508 5509 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle, 5510 mCameraHandle->ops); 5511 if (NULL == pChannel) { 5512 ALOGE("%s: no mem for capture channel", __func__); 5513 return NO_MEMORY; 5514 } 5515 5516 // Capture channel, only need snapshot and postview streams start together 5517 mm_camera_channel_attr_t attr; 5518 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 5519 if ( mLongshotEnabled ) { 5520 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 5521 attr.look_back = mParameters.getZSLBackLookCount(); 5522 attr.water_mark = mParameters.getZSLQueueDepth(); 5523 } else { 5524 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 5525 } 5526 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 5527 5528 rc = pChannel->init(&attr, 5529 capture_channel_cb_routine, 5530 this); 5531 if (rc != NO_ERROR) { 5532 ALOGE("%s: init capture channel failed, ret = %d", __func__, rc); 5533 return rc; 5534 } 5535 5536 // meta data stream always coexists with snapshot in regular capture case 5537 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5538 metadata_stream_cb_routine, this); 5539 if (rc != NO_ERROR) { 5540 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5541 return rc; 5542 } 5543 5544 if (!mLongshotEnabled) { 5545 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW, 5546 NULL, this); 5547 5548 if (rc != NO_ERROR) { 5549 ALOGE("%s: add postview stream failed, ret = %d", __func__, rc); 5550 return rc; 5551 } 5552 } else { 5553 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5554 preview_stream_cb_routine, this); 5555 5556 if (rc != NO_ERROR) { 5557 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc); 5558 return rc; 5559 } 5560 } 5561 5562 if (!mParameters.getofflineRAW()) { 5563 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 5564 NULL, this); 5565 if (rc != NO_ERROR) { 5566 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc); 5567 return rc; 5568 } 5569 } 5570 property_get("persist.camera.raw_yuv", value, "0"); 5571 raw_yuv = atoi(value) > 0 ? true : false; 5572 if ( raw_yuv ) { 5573 if (!mParameters.getofflineRAW()) { 5574 rc = addStreamToChannel(pChannel, 5575 CAM_STREAM_TYPE_RAW, 5576 snapshot_raw_stream_cb_routine, 5577 this); 5578 } else { 5579 rc = addStreamToChannel(pChannel, 5580 CAM_STREAM_TYPE_RAW, 5581 NULL, 5582 this); 5583 } 5584 if (rc != NO_ERROR) { 5585 ALOGE("%s: add raw stream failed, ret = %d", __func__, rc); 5586 return rc; 5587 } 5588 } 5589 5590 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel; 5591 return rc; 5592 } 5593 5594 /*=========================================================================== 5595 * FUNCTION : addMetaDataChannel 5596 * 5597 * DESCRIPTION: add a meta data channel that contains a metadata stream 5598 * 5599 * PARAMETERS : none 5600 * 5601 * RETURN : int32_t type of status 5602 * NO_ERROR -- success 5603 * none-zero failure code 5604 *==========================================================================*/ 5605 int32_t QCamera2HardwareInterface::addMetaDataChannel() 5606 { 5607 int32_t rc = NO_ERROR; 5608 QCameraChannel *pChannel = NULL; 5609 5610 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) { 5611 delete m_channels[QCAMERA_CH_TYPE_METADATA]; 5612 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL; 5613 } 5614 5615 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5616 mCameraHandle->ops); 5617 if (NULL == pChannel) { 5618 ALOGE("%s: no mem for metadata channel", __func__); 5619 return NO_MEMORY; 5620 } 5621 5622 rc = pChannel->init(NULL, 5623 NULL, 5624 NULL); 5625 if (rc != NO_ERROR) { 5626 ALOGE("%s: init metadata channel failed, ret = %d", __func__, rc); 5627 delete pChannel; 5628 return rc; 5629 } 5630 5631 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5632 metadata_stream_cb_routine, this); 5633 if (rc != NO_ERROR) { 5634 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5635 delete pChannel; 5636 return rc; 5637 } 5638 5639 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel; 5640 return rc; 5641 } 5642 5643 /*=========================================================================== 5644 * FUNCTION : addAnalysisChannel 5645 * 5646 * DESCRIPTION: add a analysis channel that contains a analysis stream 5647 * 5648 * PARAMETERS : none 5649 * 5650 * RETURN : int32_t type of status 5651 * NO_ERROR -- success 5652 * none-zero failure code 5653 *==========================================================================*/ 5654 int32_t QCamera2HardwareInterface::addAnalysisChannel() 5655 { 5656 int32_t rc = NO_ERROR; 5657 QCameraChannel *pChannel = NULL; 5658 5659 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) { 5660 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS]; 5661 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL; 5662 } 5663 5664 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5665 mCameraHandle->ops); 5666 if (NULL == pChannel) { 5667 ALOGE("%s: no mem for metadata channel", __func__); 5668 return NO_MEMORY; 5669 } 5670 5671 rc = pChannel->init(NULL, NULL, this); 5672 if (rc != NO_ERROR) { 5673 ALOGE("%s: init Analysis channel failed, ret = %d", __func__, rc); 5674 delete pChannel; 5675 return rc; 5676 } 5677 5678 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 5679 NULL, this); 5680 if (rc != NO_ERROR) { 5681 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc); 5682 delete pChannel; 5683 return rc; 5684 } 5685 5686 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel; 5687 return rc; 5688 } 5689 5690 5691 /*=========================================================================== 5692 * FUNCTION : getPPConfig 5693 * 5694 * DESCRIPTION: get Post processing configaration data 5695 * 5696 * PARAMETERS : 5697 * @pp config: pp config structure pointer, 5698 * @curCount: current pp pass count 5699 * 5700 * RETURN : int32_t type of status 5701 * NO_ERROR -- success 5702 * none-zero failure code 5703 *==========================================================================*/ 5704 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config, int curCount) 5705 { 5706 int32_t rc = NO_ERROR; 5707 5708 if ( curCount != mParameters.getReprocCount() ) { 5709 ALOGW("%s : Multi pass enabled. Total Pass = %d, cur Pass = %d", __func__, 5710 mParameters.getReprocCount(), curCount); 5711 } 5712 5713 CDBG_HIGH("%s: Minimum pproc feature mask required = %x", __func__, 5714 gCamCaps[mCameraId]->min_required_pp_mask); 5715 uint32_t required_mask = gCamCaps[mCameraId]->min_required_pp_mask; 5716 int32_t zoomLevel = 0; 5717 5718 switch(curCount) { 5719 case 1: 5720 //Configure feature mask for first pass of reprocessing 5721 if (mParameters.isZSLMode() || required_mask & CAM_QCOM_FEATURE_PP_SUPERSET) { 5722 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_EFFECT) { 5723 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT; 5724 pp_config.effect = mParameters.getEffectValue(); 5725 } 5726 if ((gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) && 5727 !mParameters.isOptiZoomEnabled()) { 5728 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS; 5729 pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS); 5730 } 5731 5732 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_CROP) { 5733 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 5734 } 5735 5736 if (mParameters.isWNREnabled()) { 5737 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D; 5738 pp_config.denoise2d.denoise_enable = 1; 5739 pp_config.denoise2d.process_plates = 5740 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 5741 } 5742 if (required_mask & CAM_QCOM_FEATURE_ROTATION) { 5743 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 5744 } 5745 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SCALE) { 5746 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 5747 } 5748 } 5749 5750 if (isCACEnabled()) { 5751 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC; 5752 } 5753 5754 if (needRotationReprocess()) { 5755 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 5756 uint32_t rotation = mParameters.getJpegRotation(); 5757 if (rotation == 0) { 5758 pp_config.rotation = ROTATE_0; 5759 } else if (rotation == 90) { 5760 pp_config.rotation = ROTATE_90; 5761 } else if (rotation == 180) { 5762 pp_config.rotation = ROTATE_180; 5763 } else if (rotation == 270) { 5764 pp_config.rotation = ROTATE_270; 5765 } 5766 } 5767 5768 if (mParameters.isHDREnabled()){ 5769 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR; 5770 pp_config.hdr_param.hdr_enable = 1; 5771 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled(); 5772 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME; 5773 } else { 5774 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR; 5775 pp_config.hdr_param.hdr_enable = 0; 5776 } 5777 5778 if(needScaleReprocess()){ 5779 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 5780 mParameters.m_reprocScaleParam.getPicSizeFromAPK( 5781 pp_config.scale_param.output_width, 5782 pp_config.scale_param.output_height); 5783 } 5784 5785 if(mParameters.isUbiFocusEnabled()) { 5786 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS; 5787 } else { 5788 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS; 5789 } 5790 5791 if(mParameters.isUbiRefocus()) { 5792 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS; 5793 pp_config.misc_buf_param.misc_buffer_index = 0; 5794 } else { 5795 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS; 5796 } 5797 5798 if(mParameters.isChromaFlashEnabled()) { 5799 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH; 5800 pp_config.flash_value = CAM_FLASH_ON; 5801 } else { 5802 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH; 5803 } 5804 5805 zoomLevel = mParameters.getParmZoomLevel(); 5806 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) { 5807 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM; 5808 pp_config.zoom_level = (uint8_t) zoomLevel; 5809 } else { 5810 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM; 5811 } 5812 5813 if (mParameters.getofflineRAW()) { 5814 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 5815 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING; 5816 } 5817 5818 if (mParameters.isTruePortraitEnabled()) { 5819 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT; 5820 pp_config.misc_buf_param.misc_buffer_index = 0; 5821 } else { 5822 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT; 5823 } 5824 5825 if(mParameters.isStillMoreEnabled()) { 5826 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE; 5827 } else { 5828 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE; 5829 } 5830 5831 if (curCount != mParameters.getReprocCount()) { 5832 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2; 5833 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION; 5834 pp_config.rotation = ROTATE_0; 5835 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 5836 } else { 5837 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 5838 } 5839 break; 5840 5841 case 2: 5842 //Configure feature mask for second pass of reprocessing 5843 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2; 5844 if (needRotationReprocess()) { 5845 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 5846 uint32_t rotation = mParameters.getJpegRotation(); 5847 if (rotation == 0) { 5848 pp_config.rotation = ROTATE_0; 5849 } else if (rotation == 90) { 5850 pp_config.rotation = ROTATE_90; 5851 } else if (rotation == 180) { 5852 pp_config.rotation = ROTATE_180; 5853 } else if (rotation == 270) { 5854 pp_config.rotation = ROTATE_270; 5855 } 5856 } 5857 break; 5858 5859 } 5860 CDBG_HIGH("%s: pproc feature mask set = %x pass count = %d", 5861 __func__, pp_config.feature_mask,curCount); 5862 return rc; 5863 } 5864 5865 /*=========================================================================== 5866 * FUNCTION : addReprocChannel 5867 * 5868 * DESCRIPTION: add a reprocess channel that will do reprocess on frames 5869 * coming from input channel 5870 * 5871 * PARAMETERS : 5872 * @pInputChannel : ptr to input channel whose frames will be post-processed 5873 * 5874 * RETURN : Ptr to the newly created channel obj. NULL if failed. 5875 *==========================================================================*/ 5876 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel( 5877 QCameraChannel *pInputChannel) 5878 { 5879 int32_t rc = NO_ERROR; 5880 QCameraReprocessChannel *pChannel = NULL; 5881 5882 if (pInputChannel == NULL) { 5883 ALOGE("%s: input channel obj is NULL", __func__); 5884 return NULL; 5885 } 5886 5887 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle, 5888 mCameraHandle->ops); 5889 if (NULL == pChannel) { 5890 ALOGE("%s: no mem for reprocess channel", __func__); 5891 return NULL; 5892 } 5893 5894 // Capture channel, only need snapshot and postview streams start together 5895 mm_camera_channel_attr_t attr; 5896 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 5897 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 5898 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 5899 rc = pChannel->init(&attr, 5900 postproc_channel_cb_routine, 5901 this); 5902 if (rc != NO_ERROR) { 5903 ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc); 5904 delete pChannel; 5905 return NULL; 5906 } 5907 5908 // pp feature config 5909 cam_pp_feature_config_t pp_config; 5910 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 5911 5912 rc = getPPConfig(pp_config, mParameters.getCurPPCount()); 5913 if (rc != NO_ERROR){ 5914 ALOGE("%s: Error while creating PP config",__func__); 5915 delete pChannel; 5916 return NULL; 5917 } 5918 5919 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC); 5920 5921 //WNR and HDR happen inline. No extra buffers needed. 5922 uint32_t temp_feature_mask = pp_config.feature_mask; 5923 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR; 5924 if (temp_feature_mask && mParameters.isHDREnabled()) { 5925 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded()); 5926 } 5927 5928 if (mParameters.isStillMoreEnabled()) { 5929 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 5930 pp_config.burst_cnt = stillmore_config.burst_count; 5931 CDBG_HIGH("%s: Stillmore burst %d", __func__, pp_config.burst_cnt); 5932 5933 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming 5934 // number of capture is already added. In the case of liveshot, 5935 // stillmore burst is 1. This is to account for the premature decrement 5936 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) { 5937 minStreamBufNum += 1; 5938 } 5939 } 5940 5941 // Add non inplace image lib buffers only when ppproc is present, 5942 // becuase pproc is non inplace and input buffers for img lib 5943 // are output for pproc and this number of extra buffers is required 5944 // If pproc is not there, input buffers for imglib are from snapshot stream 5945 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc(); 5946 if (temp_feature_mask && imglib_extra_bufs) { 5947 // 1 is added because getNumOfExtraBuffersForImageProc returns extra 5948 // buffers assuming number of capture is already added 5949 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1); 5950 } 5951 5952 // If input channel is Snapshot Channel, then update feature mask 5953 if (pInputChannel == m_channels[QCAMERA_CH_TYPE_SNAPSHOT]) { 5954 //Mask out features that are already processed in snapshot stream. 5955 uint32_t snapshot_feature_mask = 0; 5956 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask); 5957 5958 pp_config.feature_mask &= ~snapshot_feature_mask; 5959 ALOGI("%s: Snapshot feature mask: 0x%x, reproc feature mask: 0x%x", __func__, 5960 snapshot_feature_mask, pp_config.feature_mask); 5961 } 5962 5963 bool offlineReproc = isRegularCapture(); 5964 rc = pChannel->addReprocStreamsFromSource(*this, 5965 pp_config, 5966 pInputChannel, 5967 minStreamBufNum, 5968 mParameters.getNumOfSnapshots(), 5969 &gCamCaps[mCameraId]->padding_info, 5970 mParameters, 5971 mLongshotEnabled, 5972 offlineReproc); 5973 if (rc != NO_ERROR) { 5974 delete pChannel; 5975 return NULL; 5976 } 5977 5978 return pChannel; 5979 } 5980 5981 /*=========================================================================== 5982 * FUNCTION : addOfflineReprocChannel 5983 * 5984 * DESCRIPTION: add a offline reprocess channel contains one reproc stream, 5985 * that will do reprocess on frames coming from external images 5986 * 5987 * PARAMETERS : 5988 * @img_config : offline reporcess image info 5989 * @pp_feature : pp feature config 5990 * 5991 * RETURN : int32_t type of status 5992 * NO_ERROR -- success 5993 * none-zero failure code 5994 *==========================================================================*/ 5995 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel( 5996 cam_pp_offline_src_config_t &img_config, 5997 cam_pp_feature_config_t &pp_feature, 5998 stream_cb_routine stream_cb, 5999 void *userdata) 6000 { 6001 int32_t rc = NO_ERROR; 6002 QCameraReprocessChannel *pChannel = NULL; 6003 6004 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle, 6005 mCameraHandle->ops); 6006 if (NULL == pChannel) { 6007 ALOGE("%s: no mem for reprocess channel", __func__); 6008 return NULL; 6009 } 6010 6011 rc = pChannel->init(NULL, NULL, NULL); 6012 if (rc != NO_ERROR) { 6013 ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc); 6014 delete pChannel; 6015 return NULL; 6016 } 6017 6018 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 6019 if (pStreamInfo == NULL) { 6020 ALOGE("%s: no mem for stream info buf", __func__); 6021 delete pChannel; 6022 return NULL; 6023 } 6024 6025 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0); 6026 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t)); 6027 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 6028 streamInfoBuf->fmt = img_config.input_fmt; 6029 streamInfoBuf->dim = img_config.input_dim; 6030 streamInfoBuf->buf_planes = img_config.input_buf_planes; 6031 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST; 6032 streamInfoBuf->num_of_burst = img_config.num_of_bufs; 6033 6034 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 6035 streamInfoBuf->reprocess_config.offline = img_config; 6036 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature; 6037 6038 rc = pChannel->addStream(*this, 6039 pStreamInfo, NULL, img_config.num_of_bufs, 6040 &gCamCaps[mCameraId]->padding_info, 6041 stream_cb, userdata, false); 6042 6043 if (rc != NO_ERROR) { 6044 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc); 6045 pStreamInfo->deallocate(); 6046 delete pStreamInfo; 6047 delete pChannel; 6048 return NULL; 6049 } 6050 6051 return pChannel; 6052 } 6053 6054 /*=========================================================================== 6055 * FUNCTION : addChannel 6056 * 6057 * DESCRIPTION: add a channel by its type 6058 * 6059 * PARAMETERS : 6060 * @ch_type : channel type 6061 * 6062 * RETURN : int32_t type of status 6063 * NO_ERROR -- success 6064 * none-zero failure code 6065 *==========================================================================*/ 6066 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type) 6067 { 6068 int32_t rc = UNKNOWN_ERROR; 6069 switch (ch_type) { 6070 case QCAMERA_CH_TYPE_ZSL: 6071 rc = addZSLChannel(); 6072 break; 6073 case QCAMERA_CH_TYPE_CAPTURE: 6074 rc = addCaptureChannel(); 6075 break; 6076 case QCAMERA_CH_TYPE_PREVIEW: 6077 rc = addPreviewChannel(); 6078 break; 6079 case QCAMERA_CH_TYPE_VIDEO: 6080 rc = addVideoChannel(); 6081 break; 6082 case QCAMERA_CH_TYPE_SNAPSHOT: 6083 rc = addSnapshotChannel(); 6084 break; 6085 case QCAMERA_CH_TYPE_RAW: 6086 rc = addRawChannel(); 6087 break; 6088 case QCAMERA_CH_TYPE_METADATA: 6089 rc = addMetaDataChannel(); 6090 break; 6091 case QCAMERA_CH_TYPE_ANALYSIS: 6092 rc = addAnalysisChannel(); 6093 break; 6094 default: 6095 break; 6096 } 6097 return rc; 6098 } 6099 6100 /*=========================================================================== 6101 * FUNCTION : delChannel 6102 * 6103 * DESCRIPTION: delete a channel by its type 6104 * 6105 * PARAMETERS : 6106 * @ch_type : channel type 6107 * @destroy : delete context as well 6108 * 6109 * RETURN : int32_t type of status 6110 * NO_ERROR -- success 6111 * none-zero failure code 6112 *==========================================================================*/ 6113 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type, 6114 bool destroy) 6115 { 6116 if (m_channels[ch_type] != NULL) { 6117 if (destroy) { 6118 delete m_channels[ch_type]; 6119 m_channels[ch_type] = NULL; 6120 } else { 6121 m_channels[ch_type]->deleteChannel(); 6122 } 6123 } 6124 6125 return NO_ERROR; 6126 } 6127 6128 /*=========================================================================== 6129 * FUNCTION : startChannel 6130 * 6131 * DESCRIPTION: start a channel by its type 6132 * 6133 * PARAMETERS : 6134 * @ch_type : channel type 6135 * 6136 * RETURN : int32_t type of status 6137 * NO_ERROR -- success 6138 * none-zero failure code 6139 *==========================================================================*/ 6140 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type) 6141 { 6142 int32_t rc = UNKNOWN_ERROR; 6143 if (m_channels[ch_type] != NULL) { 6144 rc = m_channels[ch_type]->config(); 6145 if (NO_ERROR == rc) { 6146 rc = m_channels[ch_type]->start(); 6147 } 6148 } 6149 6150 return rc; 6151 } 6152 6153 /*=========================================================================== 6154 * FUNCTION : stopChannel 6155 * 6156 * DESCRIPTION: stop a channel by its type 6157 * 6158 * PARAMETERS : 6159 * @ch_type : channel type 6160 * 6161 * RETURN : int32_t type of status 6162 * NO_ERROR -- success 6163 * none-zero failure code 6164 *==========================================================================*/ 6165 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type) 6166 { 6167 int32_t rc = UNKNOWN_ERROR; 6168 if (m_channels[ch_type] != NULL) { 6169 rc = m_channels[ch_type]->stop(); 6170 } 6171 6172 return rc; 6173 } 6174 6175 /*=========================================================================== 6176 * FUNCTION : preparePreview 6177 * 6178 * DESCRIPTION: add channels needed for preview 6179 * 6180 * PARAMETERS : none 6181 * 6182 * RETURN : int32_t type of status 6183 * NO_ERROR -- success 6184 * none-zero failure code 6185 *==========================================================================*/ 6186 int32_t QCamera2HardwareInterface::preparePreview() 6187 { 6188 ATRACE_CALL(); 6189 int32_t rc = NO_ERROR; 6190 6191 pthread_mutex_lock(&m_parm_lock); 6192 rc = mParameters.setStreamConfigure(false, false, false); 6193 if (rc != NO_ERROR) { 6194 ALOGE("%s: setStreamConfigure failed %d", __func__, rc); 6195 pthread_mutex_unlock(&m_parm_lock); 6196 return rc; 6197 } 6198 pthread_mutex_unlock(&m_parm_lock); 6199 6200 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 6201 rc = addChannel(QCAMERA_CH_TYPE_ZSL); 6202 if (rc != NO_ERROR) { 6203 ALOGE("%s[%d]: failed!! rc = %d", __func__, __LINE__, rc); 6204 return rc; 6205 } 6206 } else { 6207 bool recordingHint = mParameters.getRecordingHintValue(); 6208 if(!isRdiMode() && recordingHint) { 6209 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6210 if (rc != NO_ERROR) { 6211 return rc; 6212 } 6213 rc = addChannel(QCAMERA_CH_TYPE_VIDEO); 6214 if (rc != NO_ERROR) { 6215 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6216 ALOGE("%s[%d]:failed!! rc = %d", __func__, __LINE__, rc); 6217 return rc; 6218 } 6219 } 6220 6221 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW); 6222 if (!isRdiMode() && (rc != NO_ERROR)) { 6223 if (recordingHint) { 6224 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6225 delChannel(QCAMERA_CH_TYPE_VIDEO); 6226 } 6227 } 6228 6229 if (!recordingHint && !mParameters.isSecureMode()) { 6230 waitDefferedWork(mMetadataJob); 6231 waitDefferedWork(mRawdataJob); 6232 } 6233 6234 if (NO_ERROR != rc) { 6235 delChannel(QCAMERA_CH_TYPE_PREVIEW); 6236 ALOGE("%s[%d]:failed!! rc = %d", __func__, __LINE__, rc); 6237 } 6238 } 6239 6240 return rc; 6241 } 6242 6243 /*=========================================================================== 6244 * FUNCTION : unpreparePreview 6245 * 6246 * DESCRIPTION: delete channels for preview 6247 * 6248 * PARAMETERS : none 6249 * 6250 * RETURN : none 6251 *==========================================================================*/ 6252 void QCamera2HardwareInterface::unpreparePreview() 6253 { 6254 delChannel(QCAMERA_CH_TYPE_ZSL); 6255 delChannel(QCAMERA_CH_TYPE_PREVIEW); 6256 delChannel(QCAMERA_CH_TYPE_VIDEO); 6257 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6258 } 6259 6260 /*=========================================================================== 6261 * FUNCTION : playShutter 6262 * 6263 * DESCRIPTION: send request to play shutter sound 6264 * 6265 * PARAMETERS : none 6266 * 6267 * RETURN : none 6268 *==========================================================================*/ 6269 void QCamera2HardwareInterface::playShutter(){ 6270 if (mNotifyCb == NULL || 6271 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){ 6272 CDBG("%s: shutter msg not enabled or NULL cb", __func__); 6273 return; 6274 } 6275 6276 qcamera_callback_argm_t cbArg; 6277 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6278 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 6279 cbArg.msg_type = CAMERA_MSG_SHUTTER; 6280 cbArg.ext1 = 0; 6281 cbArg.ext2 = false; 6282 m_cbNotifier.notifyCallback(cbArg); 6283 } 6284 6285 /*=========================================================================== 6286 * FUNCTION : getChannelByHandle 6287 * 6288 * DESCRIPTION: return a channel by its handle 6289 * 6290 * PARAMETERS : 6291 * @channelHandle : channel handle 6292 * 6293 * RETURN : a channel obj if found, NULL if not found 6294 *==========================================================================*/ 6295 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle) 6296 { 6297 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 6298 if (m_channels[i] != NULL && 6299 m_channels[i]->getMyHandle() == channelHandle) { 6300 return m_channels[i]; 6301 } 6302 } 6303 6304 return NULL; 6305 } 6306 6307 /*=========================================================================== 6308 * FUNCTION : processFaceDetectionReuslt 6309 * 6310 * DESCRIPTION: process face detection reuslt 6311 * 6312 * PARAMETERS : 6313 * @fd_data : ptr to face detection result struct 6314 * 6315 * RETURN : int32_t type of status 6316 * NO_ERROR -- success 6317 * none-zero failure code 6318 *==========================================================================*/ 6319 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_face_detection_data_t *fd_data) 6320 { 6321 if (!mParameters.isFaceDetectionEnabled()) { 6322 CDBG_HIGH("%s: FaceDetection not enabled, no ops here", __func__); 6323 return NO_ERROR; 6324 } 6325 6326 qcamera_face_detect_type_t fd_type = fd_data->fd_type; 6327 if ((NULL == mDataCb) || 6328 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) 6329 #ifndef VANILLA_HAL 6330 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA)) 6331 #endif 6332 ) { 6333 CDBG_HIGH("%s: metadata msgtype not enabled, no ops here", __func__); 6334 return NO_ERROR; 6335 } 6336 6337 cam_dimension_t display_dim; 6338 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim); 6339 if (display_dim.width <= 0 || display_dim.height <= 0) { 6340 ALOGE("%s: Invalid preview width or height (%d x %d)", 6341 __func__, display_dim.width, display_dim.height); 6342 return UNKNOWN_ERROR; 6343 } 6344 6345 // process face detection result 6346 // need separate face detection in preview or snapshot type 6347 size_t faceResultSize = 0; 6348 size_t data_len = 0; 6349 if(fd_type == QCAMERA_FD_PREVIEW){ 6350 //fd for preview frames 6351 faceResultSize = sizeof(camera_frame_metadata_t); 6352 faceResultSize += sizeof(camera_face_t) * MAX_ROI; 6353 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 6354 #ifndef VANILLA_HAL 6355 // fd for snapshot frames 6356 //check if face is detected in this frame 6357 if(fd_data->num_faces_detected > 0){ 6358 data_len = sizeof(camera_frame_metadata_t) + 6359 sizeof(camera_face_t) * fd_data->num_faces_detected; 6360 }else{ 6361 //no face 6362 data_len = 0; 6363 } 6364 #endif 6365 faceResultSize = 1 *sizeof(int) //meta data type 6366 + 1 *sizeof(int) // meta data len 6367 + data_len; //data 6368 } 6369 6370 camera_memory_t *faceResultBuffer = mGetMemory(-1, 6371 faceResultSize, 6372 1, 6373 mCallbackCookie); 6374 if ( NULL == faceResultBuffer ) { 6375 ALOGE("%s: Not enough memory for face result data", 6376 __func__); 6377 return NO_MEMORY; 6378 } 6379 6380 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data; 6381 memset(pFaceResult, 0, faceResultSize); 6382 unsigned char *faceData = NULL; 6383 if(fd_type == QCAMERA_FD_PREVIEW){ 6384 faceData = pFaceResult; 6385 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 6386 #ifndef VANILLA_HAL 6387 //need fill meta type and meta data len first 6388 int *data_header = (int* )pFaceResult; 6389 data_header[0] = CAMERA_META_DATA_FD; 6390 data_header[1] = (int)data_len; 6391 6392 if(data_len <= 0){ 6393 //if face is not valid or do not have face, return 6394 qcamera_callback_argm_t cbArg; 6395 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6396 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6397 cbArg.msg_type = CAMERA_MSG_META_DATA; 6398 cbArg.data = faceResultBuffer; 6399 cbArg.user_data = faceResultBuffer; 6400 cbArg.cookie = this; 6401 cbArg.release_cb = releaseCameraMemory; 6402 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 6403 if (rc != NO_ERROR) { 6404 ALOGE("%s: fail sending notification", __func__); 6405 faceResultBuffer->release(faceResultBuffer); 6406 } 6407 return rc; 6408 } 6409 #endif 6410 faceData = pFaceResult + 2 *sizeof(int); //skip two int length 6411 } 6412 6413 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData; 6414 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) ); 6415 6416 roiData->number_of_faces = fd_data->num_faces_detected; 6417 roiData->faces = faces; 6418 if (roiData->number_of_faces > 0) { 6419 for (int i = 0; i < roiData->number_of_faces; i++) { 6420 faces[i].id = fd_data->faces[i].face_id; 6421 faces[i].score = fd_data->faces[i].score; 6422 6423 // left 6424 faces[i].rect[0] = 6425 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.left, display_dim.width, 2000, -1000); 6426 6427 // top 6428 faces[i].rect[1] = 6429 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.top, display_dim.height, 2000, -1000); 6430 6431 // right 6432 faces[i].rect[2] = faces[i].rect[0] + 6433 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.width, display_dim.width, 2000, 0); 6434 6435 // bottom 6436 faces[i].rect[3] = faces[i].rect[1] + 6437 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.height, display_dim.height, 2000, 0); 6438 6439 // Center of left eye 6440 faces[i].left_eye[0] = 6441 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.x, display_dim.width, 2000, -1000); 6442 6443 faces[i].left_eye[1] = 6444 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.y, display_dim.height, 2000, -1000); 6445 6446 // Center of right eye 6447 faces[i].right_eye[0] = 6448 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.x, display_dim.width, 2000, -1000); 6449 6450 faces[i].right_eye[1] = 6451 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.y, display_dim.height, 2000, -1000); 6452 6453 // Center of mouth 6454 faces[i].mouth[0] = 6455 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.x, display_dim.width, 2000, -1000); 6456 6457 faces[i].mouth[1] = 6458 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.y, display_dim.height, 2000, -1000); 6459 6460 #ifndef VANILLA_HAL 6461 faces[i].smile_degree = fd_data->faces[i].smile_degree; 6462 faces[i].smile_score = fd_data->faces[i].smile_confidence; 6463 faces[i].blink_detected = fd_data->faces[i].blink_detected; 6464 faces[i].face_recognised = fd_data->faces[i].face_recognised; 6465 faces[i].gaze_angle = fd_data->faces[i].gaze_angle; 6466 6467 // upscale by 2 to recover from demaen downscaling 6468 faces[i].updown_dir = fd_data->faces[i].updown_dir * 2; 6469 faces[i].leftright_dir = fd_data->faces[i].leftright_dir * 2; 6470 faces[i].roll_dir = fd_data->faces[i].roll_dir * 2; 6471 6472 faces[i].leye_blink = fd_data->faces[i].left_blink; 6473 faces[i].reye_blink = fd_data->faces[i].right_blink; 6474 faces[i].left_right_gaze = fd_data->faces[i].left_right_gaze; 6475 faces[i].top_bottom_gaze = fd_data->faces[i].top_bottom_gaze; 6476 #endif 6477 6478 } 6479 } 6480 6481 qcamera_callback_argm_t cbArg; 6482 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6483 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6484 if(fd_type == QCAMERA_FD_PREVIEW){ 6485 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA; 6486 } 6487 #ifndef VANILLA_HAL 6488 else if(fd_type == QCAMERA_FD_SNAPSHOT){ 6489 cbArg.msg_type = CAMERA_MSG_META_DATA; 6490 } 6491 #endif 6492 cbArg.data = faceResultBuffer; 6493 cbArg.metadata = roiData; 6494 cbArg.user_data = faceResultBuffer; 6495 cbArg.cookie = this; 6496 cbArg.release_cb = releaseCameraMemory; 6497 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 6498 if (rc != NO_ERROR) { 6499 ALOGE("%s: fail sending notification", __func__); 6500 faceResultBuffer->release(faceResultBuffer); 6501 } 6502 6503 return rc; 6504 } 6505 6506 /*=========================================================================== 6507 * FUNCTION : releaseCameraMemory 6508 * 6509 * DESCRIPTION: releases camera memory objects 6510 * 6511 * PARAMETERS : 6512 * @data : buffer to be released 6513 * @cookie : context data 6514 * @cbStatus: callback status 6515 * 6516 * RETURN : None 6517 *==========================================================================*/ 6518 void QCamera2HardwareInterface::releaseCameraMemory(void *data, 6519 void */*cookie*/, 6520 int32_t /*cbStatus*/) 6521 { 6522 camera_memory_t *mem = ( camera_memory_t * ) data; 6523 if ( NULL != mem ) { 6524 mem->release(mem); 6525 } 6526 } 6527 6528 /*=========================================================================== 6529 * FUNCTION : returnStreamBuffer 6530 * 6531 * DESCRIPTION: returns back a stream buffer 6532 * 6533 * PARAMETERS : 6534 * @data : buffer to be released 6535 * @cookie : context data 6536 * @cbStatus: callback status 6537 * 6538 * RETURN : None 6539 *==========================================================================*/ 6540 void QCamera2HardwareInterface::returnStreamBuffer(void *data, 6541 void *cookie, 6542 int32_t /*cbStatus*/) 6543 { 6544 QCameraStream *stream = ( QCameraStream * ) cookie; 6545 int idx = *((int *)data); 6546 if ((NULL != stream) && (0 <= idx)) { 6547 stream->bufDone((uint32_t)idx); 6548 } else { 6549 ALOGE("%s: Cannot return buffer %d %p", __func__, idx, cookie); 6550 } 6551 } 6552 6553 /*=========================================================================== 6554 * FUNCTION : processHistogramStats 6555 * 6556 * DESCRIPTION: process histogram stats 6557 * 6558 * PARAMETERS : 6559 * @hist_data : ptr to histogram stats struct 6560 * 6561 * RETURN : int32_t type of status 6562 * NO_ERROR -- success 6563 * none-zero failure code 6564 *==========================================================================*/ 6565 int32_t QCamera2HardwareInterface::processHistogramStats(cam_hist_stats_t &stats_data) 6566 { 6567 #ifndef VANILLA_HAL 6568 if (!mParameters.isHistogramEnabled()) { 6569 CDBG_HIGH("%s: Histogram not enabled, no ops here", __func__); 6570 return NO_ERROR; 6571 } 6572 6573 camera_memory_t *histBuffer = mGetMemory(-1, 6574 sizeof(cam_histogram_data_t), 6575 1, 6576 mCallbackCookie); 6577 if ( NULL == histBuffer ) { 6578 ALOGE("%s: Not enough memory for histogram data", 6579 __func__); 6580 return NO_MEMORY; 6581 } 6582 6583 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data; 6584 if (pHistData == NULL) { 6585 ALOGE("%s: memory data ptr is NULL", __func__); 6586 return UNKNOWN_ERROR; 6587 } 6588 6589 switch (stats_data.type) { 6590 case CAM_HISTOGRAM_TYPE_BAYER: 6591 *pHistData = stats_data.bayer_stats.gb_stats; 6592 break; 6593 case CAM_HISTOGRAM_TYPE_YUV: 6594 *pHistData = stats_data.yuv_stats; 6595 break; 6596 } 6597 6598 qcamera_callback_argm_t cbArg; 6599 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6600 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6601 cbArg.msg_type = CAMERA_MSG_STATS_DATA; 6602 cbArg.data = histBuffer; 6603 cbArg.user_data = histBuffer; 6604 cbArg.cookie = this; 6605 cbArg.release_cb = releaseCameraMemory; 6606 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 6607 if (rc != NO_ERROR) { 6608 ALOGE("%s: fail sending notification", __func__); 6609 histBuffer->release(histBuffer); 6610 } 6611 #endif 6612 return NO_ERROR; 6613 } 6614 6615 /*=========================================================================== 6616 * FUNCTION : calcThermalLevel 6617 * 6618 * DESCRIPTION: Calculates the target fps range depending on 6619 * the thermal level. 6620 * 6621 * PARAMETERS : 6622 * @level : received thermal level 6623 * @minFPS : minimum configured fps range 6624 * @maxFPS : maximum configured fps range 6625 * @adjustedRange : target fps range 6626 * @skipPattern : target skip pattern 6627 * 6628 * RETURN : int32_t type of status 6629 * NO_ERROR -- success 6630 * none-zero failure code 6631 *==========================================================================*/ 6632 int QCamera2HardwareInterface::calcThermalLevel( 6633 qcamera_thermal_level_enum_t level, 6634 const int minFPSi, 6635 const int maxFPSi, 6636 cam_fps_range_t &adjustedRange, 6637 enum msm_vfe_frame_skip_pattern &skipPattern) 6638 { 6639 const float minFPS = (float)minFPSi; 6640 const float maxFPS = (float)maxFPSi; 6641 6642 // Initialize video fps to preview fps 6643 float minVideoFps = minFPS, maxVideoFps = maxFPS; 6644 cam_fps_range_t videoFps; 6645 // If HFR mode, update video fps accordingly 6646 if(isHFRMode()) { 6647 mParameters.getHfrFps(videoFps); 6648 minVideoFps = videoFps.video_min_fps; 6649 maxVideoFps = videoFps.video_max_fps; 6650 } 6651 6652 CDBG_HIGH("%s: level: %d, preview minfps %f, preview maxfpS %f, " 6653 "video minfps %f, video maxfpS %f", 6654 __func__, level, minFPS, maxFPS, minVideoFps, maxVideoFps); 6655 6656 switch(level) { 6657 case QCAMERA_THERMAL_NO_ADJUSTMENT: 6658 { 6659 adjustedRange.min_fps = minFPS / 1000.0f; 6660 adjustedRange.max_fps = maxFPS / 1000.0f; 6661 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 6662 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 6663 skipPattern = NO_SKIP; 6664 } 6665 break; 6666 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT: 6667 { 6668 adjustedRange.min_fps = minFPS / 1000.0f; 6669 adjustedRange.max_fps = maxFPS / 1000.0f; 6670 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps; 6671 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps; 6672 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 6673 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 6674 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps; 6675 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps; 6676 if ( adjustedRange.min_fps < 1 ) { 6677 adjustedRange.min_fps = 1; 6678 } 6679 if ( adjustedRange.max_fps < 1 ) { 6680 adjustedRange.max_fps = 1; 6681 } 6682 if ( adjustedRange.video_min_fps < 1 ) { 6683 adjustedRange.video_min_fps = 1; 6684 } 6685 if ( adjustedRange.video_max_fps < 1 ) { 6686 adjustedRange.video_max_fps = 1; 6687 } 6688 skipPattern = EVERY_2FRAME; 6689 } 6690 break; 6691 case QCAMERA_THERMAL_BIG_ADJUSTMENT: 6692 { 6693 adjustedRange.min_fps = minFPS / 1000.0f; 6694 adjustedRange.max_fps = maxFPS / 1000.0f; 6695 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps; 6696 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps; 6697 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 6698 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 6699 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps; 6700 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps; 6701 if ( adjustedRange.min_fps < 1 ) { 6702 adjustedRange.min_fps = 1; 6703 } 6704 if ( adjustedRange.max_fps < 1 ) { 6705 adjustedRange.max_fps = 1; 6706 } 6707 if ( adjustedRange.video_min_fps < 1 ) { 6708 adjustedRange.video_min_fps = 1; 6709 } 6710 if ( adjustedRange.video_max_fps < 1 ) { 6711 adjustedRange.video_max_fps = 1; 6712 } 6713 skipPattern = EVERY_4FRAME; 6714 } 6715 break; 6716 case QCAMERA_THERMAL_SHUTDOWN: 6717 { 6718 // Stop Preview? 6719 // Set lowest min FPS for now 6720 adjustedRange.min_fps = minFPS/1000.0f; 6721 adjustedRange.max_fps = minFPS/1000.0f; 6722 for (size_t i = 0; i < gCamCaps[mCameraId]->fps_ranges_tbl_cnt; i++) { 6723 if (gCamCaps[mCameraId]->fps_ranges_tbl[i].min_fps < adjustedRange.min_fps) { 6724 adjustedRange.min_fps = gCamCaps[mCameraId]->fps_ranges_tbl[i].min_fps; 6725 adjustedRange.max_fps = adjustedRange.min_fps; 6726 } 6727 } 6728 skipPattern = MAX_SKIP; 6729 adjustedRange.video_min_fps = adjustedRange.min_fps; 6730 adjustedRange.video_max_fps = adjustedRange.max_fps; 6731 } 6732 break; 6733 default: 6734 { 6735 ALOGE("%s: Invalid thermal level %d", __func__, level); 6736 return BAD_VALUE; 6737 } 6738 break; 6739 } 6740 CDBG_HIGH("%s: Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d", 6741 __func__, level, adjustedRange.min_fps, adjustedRange.max_fps, 6742 adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern); 6743 6744 return NO_ERROR; 6745 } 6746 6747 /*=========================================================================== 6748 * FUNCTION : recalcFPSRange 6749 * 6750 * DESCRIPTION: adjust the configured fps range regarding 6751 * the last thermal level. 6752 * 6753 * PARAMETERS : 6754 * @minFPS : minimum configured fps range 6755 * @maxFPS : maximum configured fps range 6756 * @adjustedRange : target fps range 6757 * 6758 * RETURN : int32_t type of status 6759 * NO_ERROR -- success 6760 * none-zero failure code 6761 *==========================================================================*/ 6762 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS, 6763 cam_fps_range_t &adjustedRange) 6764 { 6765 enum msm_vfe_frame_skip_pattern skipPattern; 6766 calcThermalLevel(mThermalLevel, 6767 minFPS, 6768 maxFPS, 6769 adjustedRange, 6770 skipPattern); 6771 return NO_ERROR; 6772 } 6773 6774 /*=========================================================================== 6775 * FUNCTION : updateThermalLevel 6776 * 6777 * DESCRIPTION: update thermal level depending on thermal events 6778 * 6779 * PARAMETERS : 6780 * @level : thermal level 6781 * 6782 * RETURN : int32_t type of status 6783 * NO_ERROR -- success 6784 * none-zero failure code 6785 *==========================================================================*/ 6786 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level) 6787 { 6788 int ret = NO_ERROR; 6789 cam_fps_range_t adjustedRange; 6790 int minFPS, maxFPS; 6791 enum msm_vfe_frame_skip_pattern skipPattern; 6792 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level; 6793 6794 pthread_mutex_lock(&m_parm_lock); 6795 6796 if (!mCameraOpened) { 6797 CDBG_HIGH("%s: Camera is not opened, no need to update camera parameters", __func__); 6798 pthread_mutex_unlock(&m_parm_lock); 6799 return NO_ERROR; 6800 } 6801 6802 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 6803 qcamera_thermal_mode thermalMode = mParameters.getThermalMode(); 6804 calcThermalLevel(level, minFPS, maxFPS, adjustedRange, skipPattern); 6805 mThermalLevel = level; 6806 6807 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS) 6808 ret = mParameters.adjustPreviewFpsRange(&adjustedRange); 6809 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP) 6810 ret = mParameters.setFrameSkip(skipPattern); 6811 else 6812 ALOGE("%s: Incorrect thermal mode %d", __func__, thermalMode); 6813 6814 pthread_mutex_unlock(&m_parm_lock); 6815 6816 return ret; 6817 6818 } 6819 6820 /*=========================================================================== 6821 * FUNCTION : updateParameters 6822 * 6823 * DESCRIPTION: update parameters 6824 * 6825 * PARAMETERS : 6826 * @parms : input parameters string 6827 * @needRestart : output, flag to indicate if preview restart is needed 6828 * 6829 * RETURN : int32_t type of status 6830 * NO_ERROR -- success 6831 * none-zero failure code 6832 *==========================================================================*/ 6833 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart) 6834 { 6835 int rc = NO_ERROR; 6836 pthread_mutex_lock(&m_parm_lock); 6837 String8 str = String8(parms); 6838 QCameraParameters param(str); 6839 rc = mParameters.updateParameters(param, needRestart); 6840 6841 // update stream based parameter settings 6842 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 6843 if (m_channels[i] != NULL) { 6844 m_channels[i]->UpdateStreamBasedParameters(mParameters); 6845 } 6846 } 6847 pthread_mutex_unlock(&m_parm_lock); 6848 6849 return rc; 6850 } 6851 6852 /*=========================================================================== 6853 * FUNCTION : commitParameterChanges 6854 * 6855 * DESCRIPTION: commit parameter changes to the backend to take effect 6856 * 6857 * PARAMETERS : none 6858 * 6859 * RETURN : int32_t type of status 6860 * NO_ERROR -- success 6861 * none-zero failure code 6862 * NOTE : This function must be called after updateParameters. 6863 * Otherwise, no change will be passed to backend to take effect. 6864 *==========================================================================*/ 6865 int QCamera2HardwareInterface::commitParameterChanges() 6866 { 6867 int rc = NO_ERROR; 6868 pthread_mutex_lock(&m_parm_lock); 6869 rc = mParameters.commitParameters(); 6870 if (rc == NO_ERROR) { 6871 // update number of snapshot based on committed parameters setting 6872 rc = mParameters.setNumOfSnapshot(); 6873 } 6874 pthread_mutex_unlock(&m_parm_lock); 6875 return rc; 6876 } 6877 6878 /*=========================================================================== 6879 * FUNCTION : needDebugFps 6880 * 6881 * DESCRIPTION: if fps log info need to be printed out 6882 * 6883 * PARAMETERS : none 6884 * 6885 * RETURN : true: need print out fps log 6886 * false: no need to print out fps log 6887 *==========================================================================*/ 6888 bool QCamera2HardwareInterface::needDebugFps() 6889 { 6890 bool needFps = false; 6891 pthread_mutex_lock(&m_parm_lock); 6892 needFps = mParameters.isFpsDebugEnabled(); 6893 pthread_mutex_unlock(&m_parm_lock); 6894 return needFps; 6895 } 6896 6897 /*=========================================================================== 6898 * FUNCTION : isCACEnabled 6899 * 6900 * DESCRIPTION: if CAC is enabled 6901 * 6902 * PARAMETERS : none 6903 * 6904 * RETURN : true: needed 6905 * false: no need 6906 *==========================================================================*/ 6907 bool QCamera2HardwareInterface::isCACEnabled() 6908 { 6909 char prop[PROPERTY_VALUE_MAX]; 6910 memset(prop, 0, sizeof(prop)); 6911 property_get("persist.camera.feature.cac", prop, "0"); 6912 int enableCAC = atoi(prop); 6913 return enableCAC == 1; 6914 } 6915 6916 /*=========================================================================== 6917 * FUNCTION : is4k2kResolution 6918 * 6919 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k 6920 * 6921 * PARAMETERS : none 6922 * 6923 * RETURN : true: needed 6924 * false: no need 6925 *==========================================================================*/ 6926 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution) 6927 { 6928 bool enabled = false; 6929 if ((resolution->width == 4096 && resolution->height == 2160) || 6930 (resolution->width == 3840 && resolution->height == 2160) ) { 6931 enabled = true; 6932 } 6933 return enabled; 6934 } 6935 6936 6937 /*=========================================================================== 6938 * FUNCTION : isAFRunning 6939 * 6940 * DESCRIPTION: if AF is in progress while in Auto/Macro focus modes 6941 * 6942 * PARAMETERS : none 6943 * 6944 * RETURN : true: AF in progress 6945 * false: AF not in progress 6946 *==========================================================================*/ 6947 bool QCamera2HardwareInterface::isAFRunning() 6948 { 6949 bool isAFInProgress = (m_currentFocusState == CAM_AF_SCANNING && 6950 (mParameters.getFocusMode() == CAM_FOCUS_MODE_AUTO || 6951 mParameters.getFocusMode() == CAM_FOCUS_MODE_MACRO)); 6952 6953 return isAFInProgress; 6954 } 6955 6956 /*=========================================================================== 6957 * FUNCTION : isPreviewRestartEnabled 6958 * 6959 * DESCRIPTION: Check whether preview should be restarted automatically 6960 * during image capture. 6961 * 6962 * PARAMETERS : none 6963 * 6964 * RETURN : true: needed 6965 * false: no need 6966 *==========================================================================*/ 6967 bool QCamera2HardwareInterface::isPreviewRestartEnabled() 6968 { 6969 char prop[PROPERTY_VALUE_MAX]; 6970 memset(prop, 0, sizeof(prop)); 6971 property_get("persist.camera.feature.restart", prop, "0"); 6972 int earlyRestart = atoi(prop); 6973 return earlyRestart == 1; 6974 } 6975 6976 /*=========================================================================== 6977 * FUNCTION : needReprocess 6978 * 6979 * DESCRIPTION: if reprocess is needed 6980 * 6981 * PARAMETERS : none 6982 * 6983 * RETURN : true: needed 6984 * false: no need 6985 *==========================================================================*/ 6986 bool QCamera2HardwareInterface::needReprocess() 6987 { 6988 pthread_mutex_lock(&m_parm_lock); 6989 6990 if (mParameters.getofflineRAW()) { 6991 pthread_mutex_unlock(&m_parm_lock); 6992 return true; 6993 } 6994 if (!mParameters.isJpegPictureFormat() && 6995 !mParameters.isNV21PictureFormat()) { 6996 // RAW image, no need to reprocess 6997 pthread_mutex_unlock(&m_parm_lock); 6998 return false; 6999 } 7000 7001 if (mParameters.isHDREnabled()) { 7002 CDBG_HIGH("%s: need do reprocess for HDR", __func__); 7003 pthread_mutex_unlock(&m_parm_lock); 7004 return true; 7005 } 7006 //Disable reprocess for 4K liveshot case 7007 if (mParameters.is4k2kVideoResolution()&& mParameters.getRecordingHintValue()) { 7008 //Disable reprocess for 4K liveshot case 7009 pthread_mutex_unlock(&m_parm_lock); 7010 return false; 7011 } 7012 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 && 7013 (mParameters.getJpegRotation() > 0)) { 7014 // current rotation is not zero, and pp has the capability to process rotation 7015 CDBG_HIGH("%s: need to do reprocess for rotation=%d", 7016 __func__, mParameters.getJpegRotation()); 7017 pthread_mutex_unlock(&m_parm_lock); 7018 return true; 7019 } 7020 7021 if (isZSLMode()) { 7022 if (((gCamCaps[mCameraId]->min_required_pp_mask > 0) || 7023 mParameters.isWNREnabled() || isCACEnabled())) { 7024 // TODO: add for ZSL HDR later 7025 CDBG_HIGH("%s: need do reprocess for ZSL WNR or min PP reprocess", __func__); 7026 pthread_mutex_unlock(&m_parm_lock); 7027 return true; 7028 } 7029 7030 int snapshot_flipMode = 7031 mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT); 7032 if (snapshot_flipMode > 0) { 7033 CDBG_HIGH("%s: Need do flip for snapshot in ZSL mode", __func__); 7034 pthread_mutex_unlock(&m_parm_lock); 7035 return true; 7036 } 7037 } else { 7038 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_PP_SUPERSET) { 7039 CDBG_HIGH("%s: Need CPP in non-ZSL mode", __func__); 7040 pthread_mutex_unlock(&m_parm_lock); 7041 return true; 7042 } 7043 } 7044 7045 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SCALE) > 0 && 7046 mParameters.m_reprocScaleParam.isScaleEnabled() && 7047 mParameters.m_reprocScaleParam.isUnderScaling()) { 7048 // Reproc Scale is enaled and also need Scaling to current Snapshot 7049 CDBG_HIGH("%s: need do reprocess for scale", __func__); 7050 pthread_mutex_unlock(&m_parm_lock); 7051 return true; 7052 } 7053 7054 if (mParameters.isUbiFocusEnabled() | 7055 mParameters.isUbiRefocus() | 7056 mParameters.isChromaFlashEnabled() | 7057 mParameters.isHDREnabled() | 7058 mParameters.isOptiZoomEnabled() | 7059 mParameters.isStillMoreEnabled()) { 7060 CDBG_HIGH("%s: need reprocess for |UbiFocus=%d|ChramaFlash=%d|OptiZoom=%d|StillMore=%d|", 7061 __func__, 7062 mParameters.isUbiFocusEnabled(), 7063 mParameters.isChromaFlashEnabled(), 7064 mParameters.isOptiZoomEnabled(), 7065 mParameters.isStillMoreEnabled()); 7066 pthread_mutex_unlock(&m_parm_lock); 7067 return true; 7068 } 7069 7070 pthread_mutex_unlock(&m_parm_lock); 7071 return false; 7072 } 7073 7074 /*=========================================================================== 7075 * FUNCTION : needRotationReprocess 7076 * 7077 * DESCRIPTION: if rotation needs to be done by reprocess in pp 7078 * 7079 * PARAMETERS : none 7080 * 7081 * RETURN : true: needed 7082 * false: no need 7083 *==========================================================================*/ 7084 bool QCamera2HardwareInterface::needRotationReprocess() 7085 { 7086 pthread_mutex_lock(&m_parm_lock); 7087 if (!mParameters.isJpegPictureFormat() && 7088 !mParameters.isNV21PictureFormat()) { 7089 // RAW image, no need to reprocess 7090 pthread_mutex_unlock(&m_parm_lock); 7091 return false; 7092 } 7093 7094 if (mParameters.is4k2kVideoResolution()&& mParameters.getRecordingHintValue()) { 7095 //Disable reprocess for 4K liveshot case 7096 pthread_mutex_unlock(&m_parm_lock); 7097 return false; 7098 } 7099 7100 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 && 7101 (mParameters.getJpegRotation() > 0)) { 7102 // current rotation is not zero, and pp has the capability to process rotation 7103 CDBG_HIGH("%s: need to do reprocess for rotation=%d", 7104 __func__, mParameters.getJpegRotation()); 7105 pthread_mutex_unlock(&m_parm_lock); 7106 return true; 7107 } 7108 7109 pthread_mutex_unlock(&m_parm_lock); 7110 return false; 7111 } 7112 7113 /*=========================================================================== 7114 * FUNCTION : needScaleReprocess 7115 * 7116 * DESCRIPTION: if scale needs to be done by reprocess in pp 7117 * 7118 * PARAMETERS : none 7119 * 7120 * RETURN : true: needed 7121 * false: no need 7122 *==========================================================================*/ 7123 bool QCamera2HardwareInterface::needScaleReprocess() 7124 { 7125 pthread_mutex_lock(&m_parm_lock); 7126 if (!mParameters.isJpegPictureFormat() && 7127 !mParameters.isNV21PictureFormat()) { 7128 // RAW image, no need to reprocess 7129 pthread_mutex_unlock(&m_parm_lock); 7130 return false; 7131 } 7132 7133 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SCALE) > 0 && 7134 mParameters.m_reprocScaleParam.isScaleEnabled() && 7135 mParameters.m_reprocScaleParam.isUnderScaling()) { 7136 // Reproc Scale is enaled and also need Scaling to current Snapshot 7137 CDBG_HIGH("%s: need do reprocess for scale", __func__); 7138 pthread_mutex_unlock(&m_parm_lock); 7139 return true; 7140 } 7141 7142 pthread_mutex_unlock(&m_parm_lock); 7143 return false; 7144 } 7145 7146 /*=========================================================================== 7147 * FUNCTION : getThumbnailSize 7148 * 7149 * DESCRIPTION: get user set thumbnail size 7150 * 7151 * PARAMETERS : 7152 * @dim : output of thumbnail dimension 7153 * 7154 * RETURN : none 7155 *==========================================================================*/ 7156 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim) 7157 { 7158 pthread_mutex_lock(&m_parm_lock); 7159 mParameters.getThumbnailSize(&dim.width, &dim.height); 7160 pthread_mutex_unlock(&m_parm_lock); 7161 } 7162 7163 /*=========================================================================== 7164 * FUNCTION : getJpegQuality 7165 * 7166 * DESCRIPTION: get user set jpeg quality 7167 * 7168 * PARAMETERS : none 7169 * 7170 * RETURN : jpeg quality setting 7171 *==========================================================================*/ 7172 uint32_t QCamera2HardwareInterface::getJpegQuality() 7173 { 7174 uint32_t quality = 0; 7175 pthread_mutex_lock(&m_parm_lock); 7176 quality = mParameters.getJpegQuality(); 7177 pthread_mutex_unlock(&m_parm_lock); 7178 return quality; 7179 } 7180 7181 /*=========================================================================== 7182 * FUNCTION : getExifData 7183 * 7184 * DESCRIPTION: get exif data to be passed into jpeg encoding 7185 * 7186 * PARAMETERS : none 7187 * 7188 * RETURN : exif data from user setting and GPS 7189 *==========================================================================*/ 7190 QCameraExif *QCamera2HardwareInterface::getExifData() 7191 { 7192 QCameraExif *exif = new QCameraExif(); 7193 if (exif == NULL) { 7194 ALOGE("%s: No memory for QCameraExif", __func__); 7195 return NULL; 7196 } 7197 7198 int32_t rc = NO_ERROR; 7199 7200 pthread_mutex_lock(&m_parm_lock); 7201 7202 // add exif entries 7203 String8 dateTime, subSecTime; 7204 rc = mParameters.getExifDateTime(dateTime, subSecTime); 7205 if(rc == NO_ERROR) { 7206 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII, 7207 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 7208 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII, 7209 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 7210 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII, 7211 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 7212 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII, 7213 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 7214 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII, 7215 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 7216 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII, 7217 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 7218 } else { 7219 ALOGE("%s: getExifDateTime failed", __func__); 7220 } 7221 7222 rat_t focalLength; 7223 rc = mParameters.getExifFocalLength(&focalLength); 7224 if (rc == NO_ERROR) { 7225 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 7226 EXIF_RATIONAL, 7227 1, 7228 (void *)&(focalLength)); 7229 } else { 7230 ALOGE("%s: getExifFocalLength failed", __func__); 7231 } 7232 7233 uint16_t isoSpeed = mParameters.getExifIsoSpeed(); 7234 if (getSensorType() != CAM_SENSOR_YUV) { 7235 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 7236 EXIF_SHORT, 7237 1, 7238 (void *)&(isoSpeed)); 7239 } 7240 7241 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 7242 uint32_t count = 0; 7243 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count); 7244 if(rc == NO_ERROR) { 7245 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 7246 EXIF_ASCII, 7247 count, 7248 (void *)gpsProcessingMethod); 7249 } else { 7250 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 7251 } 7252 7253 rat_t latitude[3]; 7254 char latRef[2]; 7255 rc = mParameters.getExifLatitude(latitude, latRef); 7256 if(rc == NO_ERROR) { 7257 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 7258 EXIF_RATIONAL, 7259 3, 7260 (void *)latitude); 7261 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 7262 EXIF_ASCII, 7263 2, 7264 (void *)latRef); 7265 } else { 7266 ALOGE("%s: getExifLatitude failed", __func__); 7267 } 7268 7269 rat_t longitude[3]; 7270 char lonRef[2]; 7271 rc = mParameters.getExifLongitude(longitude, lonRef); 7272 if(rc == NO_ERROR) { 7273 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 7274 EXIF_RATIONAL, 7275 3, 7276 (void *)longitude); 7277 7278 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 7279 EXIF_ASCII, 7280 2, 7281 (void *)lonRef); 7282 } else { 7283 ALOGE("%s: getExifLongitude failed", __func__); 7284 } 7285 7286 rat_t altitude; 7287 char altRef; 7288 rc = mParameters.getExifAltitude(&altitude, &altRef); 7289 if(rc == NO_ERROR) { 7290 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 7291 EXIF_RATIONAL, 7292 1, 7293 (void *)&(altitude)); 7294 7295 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 7296 EXIF_BYTE, 7297 1, 7298 (void *)&altRef); 7299 } else { 7300 ALOGE("%s: getExifAltitude failed", __func__); 7301 } 7302 7303 char gpsDateStamp[20]; 7304 rat_t gpsTimeStamp[3]; 7305 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp); 7306 if(rc == NO_ERROR) { 7307 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 7308 EXIF_ASCII, 7309 (uint32_t)(strlen(gpsDateStamp) + 1), 7310 (void *)gpsDateStamp); 7311 7312 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 7313 EXIF_RATIONAL, 7314 3, 7315 (void *)gpsTimeStamp); 7316 } else { 7317 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 7318 } 7319 7320 #ifdef ENABLE_MODEL_INFO_EXIF 7321 7322 char value[PROPERTY_VALUE_MAX]; 7323 if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 7324 exif->addEntry(EXIFTAGID_MAKE, EXIF_ASCII, 7325 (uint32_t)(strlen(value) + 1), (void *)value); 7326 } else { 7327 ALOGE("%s: getExifMaker failed", __func__); 7328 } 7329 7330 if (property_get("ro.product.model", value, "QCAM-AA") > 0) { 7331 exif->addEntry(EXIFTAGID_MODEL, EXIF_ASCII, 7332 (uint32_t)(strlen(value) + 1), (void *)value); 7333 } else { 7334 ALOGE("%s: getExifModel failed", __func__); 7335 } 7336 7337 if (property_get("ro.build.description", value, "QCAM-AA") > 0) { 7338 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII, 7339 (uint32_t)(strlen(value) + 1), (void *)value); 7340 } else { 7341 ALOGE("%s: getExifSoftware failed", __func__); 7342 } 7343 7344 #endif 7345 7346 if (mParameters.useJpegExifRotation()) { 7347 int16_t orientation; 7348 switch (mParameters.getJpegExifRotation()) { 7349 case 0: 7350 orientation = 1; 7351 break; 7352 case 90: 7353 orientation = 6; 7354 break; 7355 case 180: 7356 orientation = 3; 7357 break; 7358 case 270: 7359 orientation = 8; 7360 break; 7361 default: 7362 orientation = 1; 7363 break; 7364 } 7365 exif->addEntry(EXIFTAGID_ORIENTATION, 7366 EXIF_SHORT, 7367 1, 7368 (void *)&orientation); 7369 exif->addEntry(EXIFTAGID_TN_ORIENTATION, 7370 EXIF_SHORT, 7371 1, 7372 (void *)&orientation); 7373 } 7374 7375 pthread_mutex_unlock(&m_parm_lock); 7376 return exif; 7377 } 7378 7379 /*=========================================================================== 7380 * FUNCTION : setHistogram 7381 * 7382 * DESCRIPTION: set if histogram should be enabled 7383 * 7384 * PARAMETERS : 7385 * @histogram_en : bool flag if histogram should be enabled 7386 * 7387 * RETURN : int32_t type of status 7388 * NO_ERROR -- success 7389 * none-zero failure code 7390 *==========================================================================*/ 7391 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en) 7392 { 7393 return mParameters.setHistogram(histogram_en); 7394 } 7395 7396 /*=========================================================================== 7397 * FUNCTION : setFaceDetection 7398 * 7399 * DESCRIPTION: set if face detection should be enabled 7400 * 7401 * PARAMETERS : 7402 * @enabled : bool flag if face detection should be enabled 7403 * 7404 * RETURN : int32_t type of status 7405 * NO_ERROR -- success 7406 * none-zero failure code 7407 *==========================================================================*/ 7408 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled) 7409 { 7410 return mParameters.setFaceDetection(enabled, true); 7411 } 7412 7413 /*=========================================================================== 7414 * FUNCTION : isCaptureShutterEnabled 7415 * 7416 * DESCRIPTION: Check whether shutter should be triggered immediately after 7417 * capture 7418 * 7419 * PARAMETERS : 7420 * 7421 * RETURN : true - regular capture 7422 * false - other type of capture 7423 *==========================================================================*/ 7424 bool QCamera2HardwareInterface::isCaptureShutterEnabled() 7425 { 7426 char prop[PROPERTY_VALUE_MAX]; 7427 memset(prop, 0, sizeof(prop)); 7428 property_get("persist.camera.feature.shutter", prop, "0"); 7429 int enableShutter = atoi(prop); 7430 return enableShutter == 1; 7431 } 7432 7433 /*=========================================================================== 7434 * FUNCTION : needProcessPreviewFrame 7435 * 7436 * DESCRIPTION: returns whether preview frame need to be displayed 7437 * 7438 * PARAMETERS : 7439 * 7440 * RETURN : int32_t type of status 7441 * NO_ERROR -- success 7442 * none-zero failure code 7443 *==========================================================================*/ 7444 bool QCamera2HardwareInterface::needProcessPreviewFrame() 7445 { 7446 return m_stateMachine.isPreviewRunning() 7447 && mParameters.isDisplayFrameNeeded(); 7448 }; 7449 7450 /*=========================================================================== 7451 * FUNCTION : prepareHardwareForSnapshot 7452 * 7453 * DESCRIPTION: prepare hardware for snapshot, such as LED 7454 * 7455 * PARAMETERS : 7456 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation 7457 * 7458 * RETURN : int32_t type of status 7459 * NO_ERROR -- success 7460 * none-zero failure code 7461 *==========================================================================*/ 7462 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded) 7463 { 7464 ATRACE_CALL(); 7465 CDBG_HIGH("[KPI Perf] %s: Prepare hardware such as LED",__func__); 7466 return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle, 7467 afNeeded); 7468 } 7469 7470 /*=========================================================================== 7471 * FUNCTION : needFDMetadata 7472 * 7473 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel 7474 * 7475 * PARAMETERS : 7476 * @channel_type: channel type 7477 * 7478 * RETURN : true: needed 7479 * false: no need 7480 *==========================================================================*/ 7481 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type) 7482 { 7483 //Note: Currently we only process ZSL channel 7484 bool value = false; 7485 if(channel_type == QCAMERA_CH_TYPE_ZSL){ 7486 //check if FD requirement is enabled 7487 if(mParameters.isSnapshotFDNeeded() && 7488 mParameters.isFaceDetectionEnabled()){ 7489 value = true; 7490 CDBG_HIGH("%s: Face Detection metadata is required in ZSL mode.", __func__); 7491 } 7492 } 7493 7494 return value; 7495 } 7496 7497 /*=========================================================================== 7498 * FUNCTION : defferedWorkRoutine 7499 * 7500 * DESCRIPTION: data process routine that executes deffered tasks 7501 * 7502 * PARAMETERS : 7503 * @data : user data ptr (QCamera2HardwareInterface) 7504 * 7505 * RETURN : None 7506 *==========================================================================*/ 7507 void *QCamera2HardwareInterface::defferedWorkRoutine(void *obj) 7508 { 7509 int running = 1; 7510 int ret; 7511 uint8_t is_active = FALSE; 7512 7513 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj; 7514 QCameraCmdThread *cmdThread = &pme->mDefferedWorkThread; 7515 cmdThread->setName("CAM_defrdWrk"); 7516 7517 do { 7518 do { 7519 ret = cam_sem_wait(&cmdThread->cmd_sem); 7520 if (ret != 0 && errno != EINVAL) { 7521 ALOGE("%s: cam_sem_wait error (%s)", 7522 __func__, strerror(errno)); 7523 return NULL; 7524 } 7525 } while (ret != 0); 7526 7527 // we got notified about new cmd avail in cmd queue 7528 camera_cmd_type_t cmd = cmdThread->getCmd(); 7529 switch (cmd) { 7530 case CAMERA_CMD_TYPE_START_DATA_PROC: 7531 CDBG_HIGH("%s: start data proc", __func__); 7532 is_active = TRUE; 7533 break; 7534 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 7535 CDBG_HIGH("%s: stop data proc", __func__); 7536 is_active = FALSE; 7537 // signal cmd is completed 7538 cam_sem_post(&cmdThread->sync_sem); 7539 break; 7540 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 7541 { 7542 DeffWork *dw = 7543 reinterpret_cast<DeffWork *>(pme->mCmdQueue.dequeue()); 7544 7545 if ( NULL == dw ) { 7546 ALOGE("%s : Invalid deferred work", __func__); 7547 break; 7548 } 7549 7550 switch( dw->cmd ) { 7551 case CMD_DEFF_ALLOCATE_BUFF: 7552 { 7553 QCameraChannel * pChannel = dw->args.allocArgs.ch; 7554 7555 if ( NULL == pChannel ) { 7556 ALOGE("%s : Invalid deferred work channel", 7557 __func__); 7558 break; 7559 } 7560 7561 cam_stream_type_t streamType = dw->args.allocArgs.type; 7562 CDBG_HIGH("%s: Deffered buffer allocation started for stream type: %d", 7563 __func__, streamType); 7564 7565 uint32_t iNumOfStreams = pChannel->getNumOfStreams(); 7566 QCameraStream *pStream = NULL; 7567 for ( uint32_t i = 0; i < iNumOfStreams; ++i) { 7568 pStream = pChannel->getStreamByIndex(i); 7569 7570 if ( NULL == pStream ) { 7571 break; 7572 } 7573 7574 if ( pStream->isTypeOf(streamType)) { 7575 if ( pStream->allocateBuffers() ) { 7576 ALOGE("%s: Error allocating buffers !!!", 7577 __func__); 7578 } 7579 break; 7580 } 7581 } 7582 { 7583 Mutex::Autolock l(pme->mDeffLock); 7584 pme->mDeffOngoingJobs[dw->id] = false; 7585 CDBG_HIGH("%s: Deffered buffer allocation done for stream type: %d", 7586 __func__, streamType); 7587 delete dw; 7588 pme->mDeffCond.signal(); 7589 } 7590 7591 } 7592 break; 7593 case CMD_DEFF_PPROC_START: 7594 { 7595 QCameraChannel * pChannel = dw->args.pprocArgs; 7596 assert(pChannel); 7597 7598 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) { 7599 ALOGE("%s: cannot start postprocessor", __func__); 7600 pme->delChannel(QCAMERA_CH_TYPE_CAPTURE); 7601 } 7602 { 7603 Mutex::Autolock l(pme->mDeffLock); 7604 pme->mDeffOngoingJobs[dw->id] = false; 7605 delete dw; 7606 pme->mDeffCond.broadcast(); 7607 } 7608 } 7609 break; 7610 default: 7611 ALOGE("%s[%d]: Incorrect command : %d", 7612 __func__, 7613 __LINE__, 7614 dw->cmd); 7615 } 7616 } 7617 break; 7618 case CAMERA_CMD_TYPE_EXIT: 7619 running = 0; 7620 break; 7621 default: 7622 break; 7623 } 7624 } while (running); 7625 7626 return NULL; 7627 } 7628 7629 /*=========================================================================== 7630 * FUNCTION : queueDefferedWork 7631 * 7632 * DESCRIPTION: function which queues deferred tasks 7633 * 7634 * PARAMETERS : 7635 * @cmd : deferred task 7636 * @args : deffered task arguments 7637 * 7638 * RETURN : int32_t type of status 7639 * NO_ERROR -- success 7640 * none-zero failure code 7641 *==========================================================================*/ 7642 int32_t QCamera2HardwareInterface::queueDefferedWork(DefferedWorkCmd cmd, 7643 DefferWorkArgs args) 7644 { 7645 Mutex::Autolock l(mDeffLock); 7646 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; ++i) { 7647 if (!mDeffOngoingJobs[i]) { 7648 DeffWork *dw = new DeffWork(cmd, i, args); 7649 if (mCmdQueue.enqueue(dw)) { 7650 mDeffOngoingJobs[i] = true; 7651 mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, 7652 FALSE, 7653 FALSE); 7654 return (int32_t)i; 7655 } else { 7656 CDBG("%s: Command queue not active! cmd = %d", __func__, cmd); 7657 delete dw; 7658 return -1; 7659 } 7660 } 7661 } 7662 return -1; 7663 } 7664 7665 /*=========================================================================== 7666 * FUNCTION : waitDefferedWork 7667 * 7668 * DESCRIPTION: waits for a deffered task to finish 7669 * 7670 * PARAMETERS : 7671 * @job_id : deferred task id 7672 * 7673 * RETURN : int32_t type of status 7674 * NO_ERROR -- success 7675 * none-zero failure code 7676 *==========================================================================*/ 7677 int32_t QCamera2HardwareInterface::waitDefferedWork(int32_t &job_id) 7678 { 7679 Mutex::Autolock l(mDeffLock); 7680 7681 if ((MAX_ONGOING_JOBS <= job_id) || (0 > job_id)) { 7682 return NO_ERROR; 7683 } 7684 7685 while ( mDeffOngoingJobs[job_id] == true ) { 7686 mDeffCond.wait(mDeffLock); 7687 } 7688 7689 return NO_ERROR; 7690 } 7691 7692 /*=========================================================================== 7693 * FUNCTION : isRegularCapture 7694 * 7695 * DESCRIPTION: Check configuration for regular catpure 7696 * 7697 * PARAMETERS : 7698 * 7699 * RETURN : true - regular capture 7700 * false - other type of capture 7701 *==========================================================================*/ 7702 bool QCamera2HardwareInterface::isRegularCapture() 7703 { 7704 bool ret = false; 7705 7706 if (numOfSnapshotsExpected() == 1 && 7707 !isLongshotEnabled() && 7708 !mParameters.isHDREnabled() && 7709 !mParameters.getRecordingHintValue() && 7710 !isZSLMode() && !mParameters.getofflineRAW()) { 7711 ret = true; 7712 } 7713 return ret; 7714 } 7715 7716 /*=========================================================================== 7717 * FUNCTION : getLogLevel 7718 * 7719 * DESCRIPTION: Reads the log level property into a variable 7720 * 7721 * PARAMETERS : 7722 * None 7723 * 7724 * RETURN : 7725 * None 7726 *==========================================================================*/ 7727 void QCamera2HardwareInterface::getLogLevel() 7728 { 7729 char prop[PROPERTY_VALUE_MAX]; 7730 uint32_t globalLogLevel = 0; 7731 7732 property_get("persist.camera.hal.debug", prop, "0"); 7733 int val = atoi(prop); 7734 if (0 <= val) { 7735 gCamHalLogLevel = (uint32_t)val; 7736 } 7737 property_get("persist.camera.global.debug", prop, "0"); 7738 val = atoi(prop); 7739 if (0 <= val) { 7740 globalLogLevel = (uint32_t)val; 7741 } 7742 7743 /* Highest log level among hal.logs and global.logs is selected */ 7744 if (gCamHalLogLevel < globalLogLevel) 7745 gCamHalLogLevel = globalLogLevel; 7746 7747 return; 7748 } 7749 7750 /*=========================================================================== 7751 * FUNCTION : getSensorType 7752 * 7753 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer 7754 * 7755 * PARAMETERS : 7756 * None 7757 * 7758 * RETURN : Type of sensor - bayer or YUV 7759 * 7760 *==========================================================================*/ 7761 cam_sensor_t QCamera2HardwareInterface::getSensorType() 7762 { 7763 return gCamCaps[mCameraId]->sensor_type.sens_type; 7764 } 7765 7766 }; // namespace qcamera 7767