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 mCallbackCookie, 1722 bCachedMem, 1723 (bPoolMem) ? &m_memoryPool : NULL, 1724 stream_type); 1725 } else { 1726 cam_dimension_t dim; 1727 QCameraGrallocMemory *grallocMemory = 1728 new QCameraGrallocMemory(mGetMemory, mCallbackCookie); 1729 1730 mParameters.getStreamDimension(stream_type, dim); 1731 if (grallocMemory) 1732 grallocMemory->setWindowInfo(mPreviewWindow, dim.width, 1733 dim.height, stride, scanline, 1734 mParameters.getPreviewHalPixelFormat()); 1735 mem = grallocMemory; 1736 } 1737 } 1738 break; 1739 case CAM_STREAM_TYPE_POSTVIEW: 1740 { 1741 if (isNoDisplayMode() || isPreviewRestartEnabled()) { 1742 mem = new QCameraStreamMemory(mGetMemory, mCallbackCookie, bCachedMem); 1743 } else { 1744 cam_dimension_t dim; 1745 QCameraGrallocMemory *grallocMemory = 1746 new QCameraGrallocMemory(mGetMemory, mCallbackCookie); 1747 1748 mParameters.getStreamDimension(stream_type, dim); 1749 if (grallocMemory) 1750 grallocMemory->setWindowInfo(mPreviewWindow, dim.width, 1751 dim.height, stride, scanline, 1752 mParameters.getPreviewHalPixelFormat()); 1753 mem = grallocMemory; 1754 } 1755 } 1756 break; 1757 case CAM_STREAM_TYPE_ANALYSIS: 1758 case CAM_STREAM_TYPE_SNAPSHOT: 1759 case CAM_STREAM_TYPE_RAW: 1760 case CAM_STREAM_TYPE_METADATA: 1761 case CAM_STREAM_TYPE_OFFLINE_PROC: 1762 mem = new QCameraStreamMemory(mGetMemory, 1763 mCallbackCookie, 1764 bCachedMem, 1765 (bPoolMem) ? &m_memoryPool : NULL, 1766 stream_type); 1767 break; 1768 case CAM_STREAM_TYPE_VIDEO: 1769 { 1770 property_get("persist.camera.mem.usecache", value, "0"); 1771 if (atoi(value) == 0) { 1772 bCachedMem = QCAMERA_ION_USE_NOCACHE; 1773 } 1774 CDBG_HIGH("%s: vidoe buf using cached memory = %d", __func__, bCachedMem); 1775 mem = new QCameraVideoMemory(mGetMemory, mCallbackCookie, bCachedMem); 1776 } 1777 break; 1778 case CAM_STREAM_TYPE_DEFAULT: 1779 case CAM_STREAM_TYPE_MAX: 1780 default: 1781 break; 1782 } 1783 if (!mem) { 1784 return NULL; 1785 } 1786 1787 if (bufferCnt > 0) { 1788 if (mParameters.isSecureMode() && 1789 (stream_type == CAM_STREAM_TYPE_RAW) && 1790 (mParameters.isRdiMode())) { 1791 ALOGD("%s: Allocating %d secure buffers of size %d ", __func__, bufferCnt, size); 1792 rc = mem->allocate(bufferCnt, size, SECURE); 1793 } else { 1794 rc = mem->allocate(bufferCnt, size, NON_SECURE); 1795 } 1796 if (rc < 0) { 1797 delete mem; 1798 return NULL; 1799 } 1800 bufferCnt = mem->getCnt(); 1801 } 1802 return mem; 1803 } 1804 1805 /*=========================================================================== 1806 * FUNCTION : allocateMoreStreamBuf 1807 * 1808 * DESCRIPTION: alocate more stream buffers from the memory object 1809 * 1810 * PARAMETERS : 1811 * @mem_obj : memory object ptr 1812 * @size : size of buffer 1813 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated. 1814 * output will be the number of total buffers 1815 * 1816 * RETURN : int32_t type of status 1817 * NO_ERROR -- success 1818 * none-zero failure code 1819 *==========================================================================*/ 1820 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf( 1821 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt) 1822 { 1823 int rc = NO_ERROR; 1824 1825 if (bufferCnt > 0) { 1826 rc = mem_obj->allocateMore(bufferCnt, size); 1827 bufferCnt = mem_obj->getCnt(); 1828 } 1829 return rc; 1830 } 1831 1832 /*=========================================================================== 1833 * FUNCTION : allocateMiscBuf 1834 * 1835 * DESCRIPTION: alocate miscellaneous buffer 1836 * 1837 * PARAMETERS : 1838 * @streamInfo : stream info 1839 * 1840 * RETURN : ptr to a memory obj that holds stream info buffer. 1841 * NULL if failed 1842 *==========================================================================*/ 1843 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf( 1844 cam_stream_info_t *streamInfo) 1845 { 1846 int rc = NO_ERROR; 1847 uint8_t bufNum = 0; 1848 size_t bufSize = 0; 1849 QCameraHeapMemory *miscBuf = NULL; 1850 uint32_t feature_mask = 1851 streamInfo->reprocess_config.pp_feature_config.feature_mask; 1852 1853 switch (streamInfo->stream_type) { 1854 case CAM_STREAM_TYPE_OFFLINE_PROC: 1855 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) { 1856 bufNum = 1; 1857 bufSize = mParameters.getTPMaxMetaSize(); 1858 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) { 1859 bufNum = 1; 1860 bufSize = mParameters.getRefocusMaxMetaSize(); 1861 } 1862 break; 1863 default: 1864 break; 1865 } 1866 1867 if (bufNum && bufSize) { 1868 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 1869 1870 if (!miscBuf) { 1871 ALOGE("%s: Unable to allocate miscBuf object", __func__); 1872 return NULL; 1873 } 1874 1875 rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE); 1876 if (rc < 0) { 1877 ALOGE("%s: Failed to allocate misc buffer memory", __func__); 1878 delete miscBuf; 1879 return NULL; 1880 } 1881 } 1882 1883 return miscBuf; 1884 } 1885 1886 /*=========================================================================== 1887 * FUNCTION : allocateStreamInfoBuf 1888 * 1889 * DESCRIPTION: alocate stream info buffer 1890 * 1891 * PARAMETERS : 1892 * @stream_type : type of stream 1893 * 1894 * RETURN : ptr to a memory obj that holds stream info buffer. 1895 * NULL if failed 1896 *==========================================================================*/ 1897 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf( 1898 cam_stream_type_t stream_type) 1899 { 1900 int rc = NO_ERROR; 1901 char value[PROPERTY_VALUE_MAX]; 1902 bool raw_yuv = false; 1903 1904 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 1905 if (!streamInfoBuf) { 1906 ALOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object"); 1907 return NULL; 1908 } 1909 1910 rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE); 1911 if (rc < 0) { 1912 ALOGE("allocateStreamInfoBuf: Failed to allocate stream info memory"); 1913 delete streamInfoBuf; 1914 return NULL; 1915 } 1916 1917 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0); 1918 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 1919 streamInfo->stream_type = stream_type; 1920 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt); 1921 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim); 1922 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim); 1923 streamInfo->num_bufs = getBufNumRequired(stream_type); 1924 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1925 streamInfo->is_secure = NON_SECURE; 1926 switch (stream_type) { 1927 case CAM_STREAM_TYPE_SNAPSHOT: 1928 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) || 1929 mLongshotEnabled) { 1930 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1931 } else { 1932 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 1933 streamInfo->num_of_burst = (uint8_t) 1934 (mParameters.getNumOfSnapshots() 1935 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 1936 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 1937 + mParameters.getNumOfExtraBuffersForImageProc()); 1938 } 1939 break; 1940 case CAM_STREAM_TYPE_RAW: 1941 property_get("persist.camera.raw_yuv", value, "0"); 1942 raw_yuv = atoi(value) > 0 ? true : false; 1943 if ((mParameters.isZSLMode() || isRdiMode() || raw_yuv) && 1944 !mParameters.getofflineRAW()) { 1945 CDBG_HIGH("RDI_DEBUG %s[%d]: CAM_STREAM_TYPE_RAW", 1946 __func__, __LINE__); 1947 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1948 } else { 1949 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 1950 streamInfo->num_of_burst = mParameters.getNumOfSnapshots(); 1951 } 1952 if (mParameters.isSecureMode() && mParameters.isRdiMode()) { 1953 streamInfo->is_secure = SECURE; 1954 } else { 1955 streamInfo->is_secure = NON_SECURE; 1956 } 1957 break; 1958 case CAM_STREAM_TYPE_POSTVIEW: 1959 if (mLongshotEnabled) { 1960 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1961 } else { 1962 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 1963 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots() 1964 + mParameters.getNumOfExtraHDRInBufsIfNeeded() 1965 - mParameters.getNumOfExtraHDROutBufsIfNeeded() 1966 + mParameters.getNumOfExtraBuffersForImageProc()); 1967 } 1968 break; 1969 case CAM_STREAM_TYPE_VIDEO: 1970 streamInfo->dis_enable = mParameters.isDISEnabled(); 1971 if (mParameters.getBufBatchCount()) { 1972 //Update stream info structure with batch mode info 1973 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH; 1974 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount(); 1975 streamInfo->user_buf_info.size = 1976 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t)); 1977 cam_fps_range_t pFpsRange; 1978 mParameters.getHfrFps(pFpsRange); 1979 streamInfo->user_buf_info.frameInterval = 1980 (long)((1000/pFpsRange.video_max_fps) * 1000); 1981 CDBG_HIGH("%s: Video Batch Count = %d, interval = %ld", __func__, 1982 streamInfo->user_buf_info.frame_buf_cnt, 1983 streamInfo->user_buf_info.frameInterval); 1984 } 1985 case CAM_STREAM_TYPE_PREVIEW: 1986 if (mParameters.getRecordingHintValue()) { 1987 const char* dis_param = mParameters.get(QCameraParameters::KEY_QC_DIS); 1988 bool disEnabled = (dis_param != NULL) 1989 && !strcmp(dis_param,QCameraParameters::VALUE_ENABLE); 1990 if(disEnabled) { 1991 streamInfo->is_type = mParameters.getISType(); 1992 } else { 1993 streamInfo->is_type = IS_TYPE_NONE; 1994 } 1995 } 1996 if (mParameters.isSecureMode()) { 1997 streamInfo->is_secure = SECURE; 1998 } 1999 break; 2000 case CAM_STREAM_TYPE_ANALYSIS: 2001 streamInfo->noFrameExpected = 1; 2002 break; 2003 default: 2004 break; 2005 } 2006 2007 // Update feature mask 2008 mParameters.updatePpFeatureMask(stream_type); 2009 2010 // Get feature mask 2011 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask); 2012 2013 // Update pp config 2014 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) { 2015 int flipMode = mParameters.getFlipMode(stream_type); 2016 if (flipMode > 0) { 2017 streamInfo->pp_config.flip = (uint32_t)flipMode; 2018 } 2019 } 2020 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) { 2021 streamInfo->pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS); 2022 } 2023 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) { 2024 streamInfo->pp_config.effect = mParameters.getEffectValue(); 2025 } 2026 2027 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) { 2028 streamInfo->pp_config.denoise2d.denoise_enable = 1; 2029 streamInfo->pp_config.denoise2d.process_plates = 2030 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 2031 } 2032 2033 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type || 2034 CAM_STREAM_TYPE_RAW == stream_type))) { 2035 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_CROP) 2036 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 2037 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SCALE) 2038 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 2039 } 2040 2041 CDBG_HIGH("%s: allocateStreamInfoBuf: stream type: %d, pp_mask: 0x%x", 2042 __func__, stream_type, streamInfo->pp_config.feature_mask); 2043 2044 return streamInfoBuf; 2045 } 2046 2047 /*=========================================================================== 2048 * FUNCTION : allocateStreamUserBuf 2049 * 2050 * DESCRIPTION: allocate user ptr for stream buffers 2051 * 2052 * PARAMETERS : 2053 * @streamInfo : stream info structure 2054 * 2055 * RETURN : ptr to a memory obj that holds stream info buffer. 2056 * NULL if failed 2057 2058 *==========================================================================*/ 2059 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf( 2060 cam_stream_info_t *streamInfo) 2061 { 2062 int rc = NO_ERROR; 2063 QCameraMemory *mem = NULL; 2064 int bufferCnt = 0; 2065 int size = 0; 2066 2067 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) { 2068 ALOGE("%s: Stream is not in BATCH mode. Invalid Stream", __func__); 2069 return NULL; 2070 } 2071 2072 // Allocate stream user buffer memory object 2073 switch (streamInfo->stream_type) { 2074 case CAM_STREAM_TYPE_VIDEO: { 2075 QCameraVideoMemory *video_mem = new QCameraVideoMemory( 2076 mGetMemory, mCallbackCookie, FALSE, CAM_STREAM_BUF_TYPE_USERPTR); 2077 video_mem->allocateMeta(streamInfo->num_bufs); 2078 mem = static_cast<QCameraMemory *>(video_mem); 2079 } 2080 break; 2081 2082 case CAM_STREAM_TYPE_PREVIEW: 2083 case CAM_STREAM_TYPE_POSTVIEW: 2084 case CAM_STREAM_TYPE_ANALYSIS: 2085 case CAM_STREAM_TYPE_SNAPSHOT: 2086 case CAM_STREAM_TYPE_RAW: 2087 case CAM_STREAM_TYPE_METADATA: 2088 case CAM_STREAM_TYPE_OFFLINE_PROC: 2089 case CAM_STREAM_TYPE_CALLBACK: 2090 ALOGE("%s: Stream type Not supported.for BATCH processing", __func__); 2091 break; 2092 2093 case CAM_STREAM_TYPE_DEFAULT: 2094 case CAM_STREAM_TYPE_MAX: 2095 default: 2096 break; 2097 } 2098 if (!mem) { 2099 ALOGE("%s: Failed to allocate mem", __func__); 2100 return NULL; 2101 } 2102 2103 /*Size of this buffer will be number of batch buffer */ 2104 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size), 2105 CAM_PAD_TO_4K); 2106 2107 CDBG_HIGH("%s: Allocating BATCH Buffer count = %d", __func__, streamInfo->num_bufs); 2108 2109 if (size > 0) { 2110 // Allocating one buffer for all batch buffers 2111 rc = mem->allocate(1, size, NON_SECURE); 2112 if (rc < 0) { 2113 delete mem; 2114 return NULL; 2115 } 2116 } 2117 return mem; 2118 } 2119 2120 2121 /*=========================================================================== 2122 * FUNCTION : setPreviewWindow 2123 * 2124 * DESCRIPTION: set preview window impl 2125 * 2126 * PARAMETERS : 2127 * @window : ptr to window ops table struct 2128 * 2129 * RETURN : int32_t type of status 2130 * NO_ERROR -- success 2131 * none-zero failure code 2132 *==========================================================================*/ 2133 int QCamera2HardwareInterface::setPreviewWindow( 2134 struct preview_stream_ops *window) 2135 { 2136 mPreviewWindow = window; 2137 return NO_ERROR; 2138 } 2139 2140 /*=========================================================================== 2141 * FUNCTION : setCallBacks 2142 * 2143 * DESCRIPTION: set callbacks impl 2144 * 2145 * PARAMETERS : 2146 * @notify_cb : notify cb 2147 * @data_cb : data cb 2148 * @data_cb_timestamp : data cb with time stamp 2149 * @get_memory : request memory ops table 2150 * @user : user data ptr 2151 * 2152 * RETURN : int32_t type of status 2153 * NO_ERROR -- success 2154 * none-zero failure code 2155 *==========================================================================*/ 2156 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb, 2157 camera_data_callback data_cb, 2158 camera_data_timestamp_callback data_cb_timestamp, 2159 camera_request_memory get_memory, 2160 void *user) 2161 { 2162 mNotifyCb = notify_cb; 2163 mDataCb = data_cb; 2164 mDataCbTimestamp = data_cb_timestamp; 2165 mGetMemory = get_memory; 2166 mCallbackCookie = user; 2167 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user); 2168 return NO_ERROR; 2169 } 2170 2171 /*=========================================================================== 2172 * FUNCTION : enableMsgType 2173 * 2174 * DESCRIPTION: enable msg type impl 2175 * 2176 * PARAMETERS : 2177 * @msg_type : msg type mask to be enabled 2178 * 2179 * RETURN : int32_t type of status 2180 * NO_ERROR -- success 2181 * none-zero failure code 2182 *==========================================================================*/ 2183 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type) 2184 { 2185 mMsgEnabled |= msg_type; 2186 return NO_ERROR; 2187 } 2188 2189 /*=========================================================================== 2190 * FUNCTION : disableMsgType 2191 * 2192 * DESCRIPTION: disable msg type impl 2193 * 2194 * PARAMETERS : 2195 * @msg_type : msg type mask to be disabled 2196 * 2197 * RETURN : int32_t type of status 2198 * NO_ERROR -- success 2199 * none-zero failure code 2200 *==========================================================================*/ 2201 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type) 2202 { 2203 mMsgEnabled &= ~msg_type; 2204 return NO_ERROR; 2205 } 2206 2207 /*=========================================================================== 2208 * FUNCTION : msgTypeEnabled 2209 * 2210 * DESCRIPTION: impl to determine if certain msg_type is enabled 2211 * 2212 * PARAMETERS : 2213 * @msg_type : msg type mask 2214 * 2215 * RETURN : 0 -- not enabled 2216 * none 0 -- enabled 2217 *==========================================================================*/ 2218 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type) 2219 { 2220 return (mMsgEnabled & msg_type); 2221 } 2222 2223 /*=========================================================================== 2224 * FUNCTION : msgTypeEnabledWithLock 2225 * 2226 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock 2227 * 2228 * PARAMETERS : 2229 * @msg_type : msg type mask 2230 * 2231 * RETURN : 0 -- not enabled 2232 * none 0 -- enabled 2233 *==========================================================================*/ 2234 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type) 2235 { 2236 int enabled = 0; 2237 lockAPI(); 2238 enabled = mMsgEnabled & msg_type; 2239 unlockAPI(); 2240 return enabled; 2241 } 2242 2243 /*=========================================================================== 2244 * FUNCTION : startPreview 2245 * 2246 * DESCRIPTION: start preview impl 2247 * 2248 * PARAMETERS : none 2249 * 2250 * RETURN : int32_t type of status 2251 * NO_ERROR -- success 2252 * none-zero failure code 2253 *==========================================================================*/ 2254 int QCamera2HardwareInterface::startPreview() 2255 { 2256 ATRACE_CALL(); 2257 int32_t rc = NO_ERROR; 2258 CDBG_HIGH("%s: E", __func__); 2259 // start preview stream 2260 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 2261 rc = startChannel(QCAMERA_CH_TYPE_ZSL); 2262 } else { 2263 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW); 2264 /* 2265 CAF needs cancel auto focus to resume after snapshot. 2266 Focus should be locked till take picture is done. 2267 In Non-zsl case if focus mode is CAF then calling cancel auto focus 2268 to resume CAF. 2269 */ 2270 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 2271 if (focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE) 2272 mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle); 2273 } 2274 updatePostPreviewParameters(); 2275 CDBG_HIGH("%s: X", __func__); 2276 return rc; 2277 } 2278 2279 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() { 2280 // Enable OIS only in Camera mode and 4k2k camcoder mode 2281 int32_t rc = NO_ERROR; 2282 rc = mParameters.updateOisValue(1); 2283 return NO_ERROR; 2284 } 2285 2286 /*=========================================================================== 2287 * FUNCTION : stopPreview 2288 * 2289 * DESCRIPTION: stop preview impl 2290 * 2291 * PARAMETERS : none 2292 * 2293 * RETURN : int32_t type of status 2294 * NO_ERROR -- success 2295 * none-zero failure code 2296 *==========================================================================*/ 2297 int QCamera2HardwareInterface::stopPreview() 2298 { 2299 ATRACE_CALL(); 2300 CDBG_HIGH("%s: E", __func__); 2301 // stop preview stream 2302 stopChannel(QCAMERA_CH_TYPE_ZSL); 2303 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 2304 2305 m_cbNotifier.flushPreviewNotifications(); 2306 // delete all channels from preparePreview 2307 unpreparePreview(); 2308 CDBG_HIGH("%s: X", __func__); 2309 return NO_ERROR; 2310 } 2311 2312 /*=========================================================================== 2313 * FUNCTION : storeMetaDataInBuffers 2314 * 2315 * DESCRIPTION: enable store meta data in buffers for video frames impl 2316 * 2317 * PARAMETERS : 2318 * @enable : flag if need enable 2319 * 2320 * RETURN : int32_t type of status 2321 * NO_ERROR -- success 2322 * none-zero failure code 2323 *==========================================================================*/ 2324 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable) 2325 { 2326 mStoreMetaDataInFrame = enable; 2327 return NO_ERROR; 2328 } 2329 2330 /*=========================================================================== 2331 * FUNCTION : startRecording 2332 * 2333 * DESCRIPTION: start recording impl 2334 * 2335 * PARAMETERS : none 2336 * 2337 * RETURN : int32_t type of status 2338 * NO_ERROR -- success 2339 * none-zero failure code 2340 *==========================================================================*/ 2341 int QCamera2HardwareInterface::startRecording() 2342 { 2343 int32_t rc = NO_ERROR; 2344 CDBG_HIGH("%s: E", __func__); 2345 if (mParameters.getRecordingHintValue() == false) { 2346 ALOGE("%s: start recording when hint is false, stop preview first", __func__); 2347 stopPreview(); 2348 2349 // Set recording hint to TRUE 2350 mParameters.updateRecordingHintValue(TRUE); 2351 rc = preparePreview(); 2352 if (rc == NO_ERROR) { 2353 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW); 2354 } 2355 } 2356 2357 if (rc == NO_ERROR) { 2358 rc = startChannel(QCAMERA_CH_TYPE_VIDEO); 2359 } 2360 2361 if (rc == NO_ERROR) { 2362 // Set power Hint for video encoding 2363 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, 1); 2364 } 2365 2366 CDBG_HIGH("%s: X", __func__); 2367 return rc; 2368 } 2369 2370 /*=========================================================================== 2371 * FUNCTION : stopRecording 2372 * 2373 * DESCRIPTION: stop recording impl 2374 * 2375 * PARAMETERS : none 2376 * 2377 * RETURN : int32_t type of status 2378 * NO_ERROR -- success 2379 * none-zero failure code 2380 *==========================================================================*/ 2381 int QCamera2HardwareInterface::stopRecording() 2382 { 2383 CDBG_HIGH("%s: E", __func__); 2384 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO); 2385 2386 if (rc == NO_ERROR) { 2387 // Disable power Hint 2388 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, 0); 2389 } 2390 CDBG_HIGH("%s: X", __func__); 2391 return rc; 2392 } 2393 2394 /*=========================================================================== 2395 * FUNCTION : releaseRecordingFrame 2396 * 2397 * DESCRIPTION: return video frame impl 2398 * 2399 * PARAMETERS : 2400 * @opaque : ptr to video frame to be returned 2401 * 2402 * RETURN : int32_t type of status 2403 * NO_ERROR -- success 2404 * none-zero failure code 2405 *==========================================================================*/ 2406 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque) 2407 { 2408 int32_t rc = UNKNOWN_ERROR; 2409 QCameraVideoChannel *pChannel = 2410 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO]; 2411 CDBG_HIGH("%s: opaque data = %p", __func__,opaque); 2412 if(pChannel != NULL) { 2413 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0); 2414 } 2415 return rc; 2416 } 2417 2418 /*=========================================================================== 2419 * FUNCTION : autoFocus 2420 * 2421 * DESCRIPTION: start auto focus impl 2422 * 2423 * PARAMETERS : none 2424 * 2425 * RETURN : int32_t type of status 2426 * NO_ERROR -- success 2427 * none-zero failure code 2428 *==========================================================================*/ 2429 int QCamera2HardwareInterface::autoFocus() 2430 { 2431 int rc = NO_ERROR; 2432 setCancelAutoFocus(false); 2433 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 2434 2435 switch (focusMode) { 2436 case CAM_FOCUS_MODE_AUTO: 2437 case CAM_FOCUS_MODE_MACRO: 2438 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 2439 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 2440 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle); 2441 break; 2442 case CAM_FOCUS_MODE_INFINITY: 2443 case CAM_FOCUS_MODE_FIXED: 2444 case CAM_FOCUS_MODE_EDOF: 2445 default: 2446 ALOGE("%s: No ops in focusMode (%d)", __func__, focusMode); 2447 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 2448 break; 2449 } 2450 return rc; 2451 } 2452 2453 /*=========================================================================== 2454 * FUNCTION : cancelAutoFocus 2455 * 2456 * DESCRIPTION: cancel auto focus impl 2457 * 2458 * PARAMETERS : none 2459 * 2460 * RETURN : int32_t type of status 2461 * NO_ERROR -- success 2462 * none-zero failure code 2463 *==========================================================================*/ 2464 int QCamera2HardwareInterface::cancelAutoFocus() 2465 { 2466 int rc = NO_ERROR; 2467 setCancelAutoFocus(true); 2468 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 2469 2470 switch (focusMode) { 2471 case CAM_FOCUS_MODE_AUTO: 2472 case CAM_FOCUS_MODE_MACRO: 2473 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 2474 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 2475 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle); 2476 break; 2477 case CAM_FOCUS_MODE_INFINITY: 2478 case CAM_FOCUS_MODE_FIXED: 2479 case CAM_FOCUS_MODE_EDOF: 2480 default: 2481 CDBG("%s: No ops in focusMode (%d)", __func__, focusMode); 2482 break; 2483 } 2484 return rc; 2485 } 2486 2487 /*=========================================================================== 2488 * FUNCTION : processUFDumps 2489 * 2490 * DESCRIPTION: process UF jpeg dumps for refocus support 2491 * 2492 * PARAMETERS : 2493 * @evt : payload of jpeg event, including information about jpeg encoding 2494 * status, jpeg size and so on. 2495 * 2496 * RETURN : int32_t type of status 2497 * NO_ERROR -- success 2498 * none-zero failure code 2499 * 2500 * NOTE : none 2501 *==========================================================================*/ 2502 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt) 2503 { 2504 bool ret = true; 2505 if (mParameters.isUbiRefocus()) { 2506 int index = (int)getOutputImageCount(); 2507 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1)); 2508 char name[FILENAME_MAX]; 2509 2510 camera_memory_t *jpeg_mem = NULL; 2511 omx_jpeg_ouput_buf_t *jpeg_out = NULL; 2512 size_t dataLen; 2513 uint8_t *dataPtr; 2514 if (!m_postprocessor.getJpegMemOpt()) { 2515 dataLen = evt->out_data.buf_filled_len; 2516 dataPtr = evt->out_data.buf_vaddr; 2517 } else { 2518 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr; 2519 if (!jpeg_out) { 2520 ALOGE("%s:%d] Null pointer detected", __func__, __LINE__); 2521 return false; 2522 } 2523 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl; 2524 if (!jpeg_mem) { 2525 ALOGE("%s:%d] Null pointer detected", __func__, __LINE__); 2526 return false; 2527 } 2528 dataPtr = (uint8_t *)jpeg_mem->data; 2529 dataLen = jpeg_mem->size; 2530 } 2531 2532 if (allFocusImage) { 2533 snprintf(name, sizeof(name), "AllFocusImage"); 2534 index = -1; 2535 } else { 2536 snprintf(name, sizeof(name), "%d", 0); 2537 } 2538 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg", 2539 dataPtr, dataLen); 2540 CDBG("%s:%d] Dump the image %d %d allFocusImage %d", __func__, __LINE__, 2541 getOutputImageCount(), index, allFocusImage); 2542 setOutputImageCount(getOutputImageCount() + 1); 2543 if (!allFocusImage) { 2544 ret = false; 2545 } 2546 } 2547 return ret; 2548 } 2549 2550 /*=========================================================================== 2551 * FUNCTION : unconfigureAdvancedCapture 2552 * 2553 * DESCRIPTION: unconfigure Advanced Capture. 2554 * 2555 * PARAMETERS : none 2556 * 2557 * RETURN : int32_t type of status 2558 * NO_ERROR -- success 2559 * none-zero failure code 2560 *==========================================================================*/ 2561 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture() 2562 { 2563 int32_t rc = NO_ERROR; 2564 2565 if (mAdvancedCaptureConfigured) { 2566 2567 mAdvancedCaptureConfigured = false; 2568 2569 if(mIs3ALocked) { 2570 mParameters.set3ALock(QCameraParameters::VALUE_FALSE); 2571 mIs3ALocked = false; 2572 } 2573 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) { 2574 rc = mParameters.setToneMapMode(true, true); 2575 if (rc != NO_ERROR) { 2576 CDBG_HIGH("%s: Failed to enable tone map during HDR/AEBracketing", __func__); 2577 } 2578 mHDRBracketingEnabled = false; 2579 rc = mParameters.stopAEBracket(); 2580 } else if (mParameters.isChromaFlashEnabled()) { 2581 rc = mParameters.resetFrameCapture(TRUE); 2582 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 2583 rc = configureAFBracketing(false); 2584 } else if (mParameters.isOptiZoomEnabled()) { 2585 rc = mParameters.setAndCommitZoom(mZoomLevel); 2586 } else if (mParameters.isStillMoreEnabled()) { 2587 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 2588 stillmore_config.burst_count = 0; 2589 mParameters.setStillMoreSettings(stillmore_config); 2590 2591 /* If SeeMore is running, it will handle re-enabling tone map */ 2592 if (!mParameters.isSeeMoreEnabled()) { 2593 rc = mParameters.setToneMapMode(true, true); 2594 if (rc != NO_ERROR) { 2595 CDBG_HIGH("%s: Failed to enable tone map during StillMore", __func__); 2596 } 2597 } 2598 2599 /* Re-enable Tintless */ 2600 mParameters.setTintless(true); 2601 } else { 2602 ALOGE("%s: No Advanced Capture feature enabled!! ", __func__); 2603 rc = BAD_VALUE; 2604 } 2605 } 2606 2607 return rc; 2608 } 2609 2610 /*=========================================================================== 2611 * FUNCTION : configureAdvancedCapture 2612 * 2613 * DESCRIPTION: configure Advanced Capture. 2614 * 2615 * PARAMETERS : none 2616 * 2617 * RETURN : int32_t type of status 2618 * NO_ERROR -- success 2619 * none-zero failure code 2620 *==========================================================================*/ 2621 int32_t QCamera2HardwareInterface::configureAdvancedCapture() 2622 { 2623 CDBG_HIGH("%s: E",__func__); 2624 int32_t rc = NO_ERROR; 2625 2626 setOutputImageCount(0); 2627 mInputCount = 0; 2628 2629 /* Temporarily stop display only if not in stillmore livesnapshot */ 2630 if (!(mParameters.isStillMoreEnabled() && 2631 mParameters.isSeeMoreEnabled())) { 2632 mParameters.setDisplayFrame(FALSE); 2633 } 2634 2635 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 2636 rc = configureAFBracketing(); 2637 } else if (mParameters.isOptiZoomEnabled()) { 2638 rc = configureOptiZoom(); 2639 } else if (mParameters.isChromaFlashEnabled()) { 2640 rc = mParameters.configFrameCapture(TRUE); 2641 } else if(mParameters.isHDREnabled()) { 2642 rc = configureHDRBracketing(); 2643 if (mHDRBracketingEnabled) { 2644 rc = mParameters.setToneMapMode(false, true); 2645 if (rc != NO_ERROR) { 2646 CDBG_HIGH("%s: Failed to disable tone map during HDR", __func__); 2647 } 2648 } 2649 } else if (mParameters.isAEBracketEnabled()) { 2650 rc = mParameters.setToneMapMode(false, true); 2651 if (rc != NO_ERROR) { 2652 CDBG_HIGH("%s: Failed to disable tone map during AEBracketing", __func__); 2653 } 2654 rc = configureAEBracketing(); 2655 } else if (mParameters.isStillMoreEnabled()) { 2656 rc = configureStillMore(); 2657 } else { 2658 ALOGE("%s: No Advanced Capture feature enabled!! ", __func__); 2659 rc = BAD_VALUE; 2660 } 2661 2662 if (NO_ERROR == rc) { 2663 mAdvancedCaptureConfigured = true; 2664 } else { 2665 mAdvancedCaptureConfigured = false; 2666 } 2667 2668 CDBG_HIGH("%s: X",__func__); 2669 return rc; 2670 } 2671 2672 /*=========================================================================== 2673 * FUNCTION : configureAFBracketing 2674 * 2675 * DESCRIPTION: configure AF Bracketing. 2676 * 2677 * PARAMETERS : none 2678 * 2679 * RETURN : int32_t type of status 2680 * NO_ERROR -- success 2681 * none-zero failure code 2682 *==========================================================================*/ 2683 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable) 2684 { 2685 CDBG_HIGH("%s: E",__func__); 2686 int32_t rc = NO_ERROR; 2687 cam_af_bracketing_t *af_bracketing_need; 2688 2689 if (mParameters.isUbiRefocus()) { 2690 af_bracketing_need = 2691 &gCamCaps[mCameraId]->refocus_af_bracketing_need; 2692 } else { 2693 af_bracketing_need = 2694 &gCamCaps[mCameraId]->ubifocus_af_bracketing_need; 2695 } 2696 2697 //Enable AF Bracketing. 2698 cam_af_bracketing_t afBracket; 2699 memset(&afBracket, 0, sizeof(cam_af_bracketing_t)); 2700 afBracket.enable = enable; 2701 afBracket.burst_count = af_bracketing_need->burst_count; 2702 2703 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) { 2704 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i]; 2705 CDBG_HIGH("%s: focus_step[%d] = %d", __func__, i, afBracket.focus_steps[i]); 2706 } 2707 //Send cmd to backend to set AF Bracketing for Ubi Focus. 2708 rc = mParameters.commitAFBracket(afBracket); 2709 if ( NO_ERROR != rc ) { 2710 ALOGE("%s: cannot configure AF bracketing", __func__); 2711 return rc; 2712 } 2713 if (enable) { 2714 mParameters.set3ALock(QCameraParameters::VALUE_TRUE); 2715 mIs3ALocked = true; 2716 } 2717 CDBG_HIGH("%s: X",__func__); 2718 return rc; 2719 } 2720 2721 /*=========================================================================== 2722 * FUNCTION : configureHDRBracketing 2723 * 2724 * DESCRIPTION: configure HDR Bracketing. 2725 * 2726 * PARAMETERS : none 2727 * 2728 * RETURN : int32_t type of status 2729 * NO_ERROR -- success 2730 * none-zero failure code 2731 *==========================================================================*/ 2732 int32_t QCamera2HardwareInterface::configureHDRBracketing() 2733 { 2734 CDBG_HIGH("%s: E",__func__); 2735 int32_t rc = NO_ERROR; 2736 2737 // 'values' should be in "idx1,idx2,idx3,..." format 2738 uint32_t hdrFrameCount = gCamCaps[mCameraId]->hdr_bracketing_setting.num_frames; 2739 CDBG_HIGH("%s : HDR values %d, %d frame count: %u", 2740 __func__, 2741 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[0], 2742 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[1], 2743 hdrFrameCount); 2744 2745 // Enable AE Bracketing for HDR 2746 cam_exp_bracketing_t aeBracket; 2747 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t)); 2748 aeBracket.mode = 2749 gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.mode; 2750 2751 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) { 2752 mHDRBracketingEnabled = true; 2753 } 2754 2755 String8 tmp; 2756 for (uint32_t i = 0; i < hdrFrameCount; i++) { 2757 tmp.appendFormat("%d", 2758 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[i]); 2759 tmp.append(","); 2760 } 2761 if (mParameters.isHDR1xFrameEnabled() 2762 && mParameters.isHDR1xExtraBufferNeeded()) { 2763 tmp.appendFormat("%d", 0); 2764 tmp.append(","); 2765 } 2766 2767 if( !tmp.isEmpty() && 2768 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) { 2769 //Trim last comma 2770 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH); 2771 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1); 2772 } 2773 2774 CDBG_HIGH("%s : HDR config values %s", 2775 __func__, 2776 aeBracket.values); 2777 rc = mParameters.setHDRAEBracket(aeBracket); 2778 if ( NO_ERROR != rc ) { 2779 ALOGE("%s: cannot configure HDR bracketing", __func__); 2780 return rc; 2781 } 2782 CDBG_HIGH("%s: X",__func__); 2783 return rc; 2784 } 2785 2786 /*=========================================================================== 2787 * FUNCTION : configureAEBracketing 2788 * 2789 * DESCRIPTION: configure AE Bracketing. 2790 * 2791 * PARAMETERS : none 2792 * 2793 * RETURN : int32_t type of status 2794 * NO_ERROR -- success 2795 * none-zero failure code 2796 *==========================================================================*/ 2797 int32_t QCamera2HardwareInterface::configureAEBracketing() 2798 { 2799 CDBG_HIGH("%s: E",__func__); 2800 int32_t rc = NO_ERROR; 2801 2802 rc = mParameters.setAEBracketing(); 2803 if ( NO_ERROR != rc ) { 2804 ALOGE("%s: cannot configure AE bracketing", __func__); 2805 return rc; 2806 } 2807 CDBG_HIGH("%s: X",__func__); 2808 return rc; 2809 } 2810 2811 /*=========================================================================== 2812 * FUNCTION : configureOptiZoom 2813 * 2814 * DESCRIPTION: configure Opti Zoom. 2815 * 2816 * PARAMETERS : none 2817 * 2818 * RETURN : int32_t type of status 2819 * NO_ERROR -- success 2820 * none-zero failure code 2821 *==========================================================================*/ 2822 int32_t QCamera2HardwareInterface::configureOptiZoom() 2823 { 2824 int32_t rc = NO_ERROR; 2825 2826 //store current zoom level. 2827 mZoomLevel = mParameters.getParmZoomLevel(); 2828 2829 //set zoom level to 1x; 2830 mParameters.setAndCommitZoom(0); 2831 2832 mParameters.set3ALock(QCameraParameters::VALUE_TRUE); 2833 mIs3ALocked = true; 2834 2835 return rc; 2836 } 2837 2838 /*=========================================================================== 2839 * FUNCTION : configureStillMore 2840 * 2841 * DESCRIPTION: configure StillMore. 2842 * 2843 * PARAMETERS : none 2844 * 2845 * RETURN : int32_t type of status 2846 * NO_ERROR -- success 2847 * none-zero failure code 2848 *==========================================================================*/ 2849 int32_t QCamera2HardwareInterface::configureStillMore() 2850 { 2851 int32_t rc = NO_ERROR; 2852 uint8_t burst_cnt = 0; 2853 cam_still_more_t stillmore_config; 2854 cam_still_more_t stillmore_cap; 2855 2856 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */ 2857 if (!mParameters.isSeeMoreEnabled()) { 2858 rc = mParameters.setToneMapMode(false, true); 2859 if (rc != NO_ERROR) { 2860 CDBG_HIGH("%s: Failed to disable tone map during StillMore", __func__); 2861 } 2862 } 2863 2864 /* Lock 3A */ 2865 mParameters.set3ALock(QCameraParameters::VALUE_TRUE); 2866 mIs3ALocked = true; 2867 2868 /* Disable Tintless */ 2869 mParameters.setTintless(false); 2870 2871 /* Configure burst count based on user input */ 2872 char prop[PROPERTY_VALUE_MAX]; 2873 property_get("persist.camera.imglib.stillmore", prop, "0"); 2874 burst_cnt = (uint32_t)atoi(prop); 2875 2876 /* In the case of liveshot, burst should be 1 */ 2877 if (mParameters.isSeeMoreEnabled()) { 2878 burst_cnt = 1; 2879 } 2880 2881 /* Validate burst count */ 2882 stillmore_cap = mParameters.getStillMoreCapability(); 2883 if ((burst_cnt < stillmore_cap.min_burst_count) || 2884 (burst_cnt > stillmore_cap.max_burst_count)) { 2885 burst_cnt = stillmore_cap.max_burst_count; 2886 } 2887 2888 memset(&stillmore_config, 0, sizeof(cam_still_more_t)); 2889 stillmore_config.burst_count = burst_cnt; 2890 mParameters.setStillMoreSettings(stillmore_config); 2891 2892 CDBG_HIGH("%s: Stillmore burst %d", __func__, burst_cnt); 2893 2894 return rc; 2895 } 2896 2897 /*=========================================================================== 2898 * FUNCTION : stopAdvancedCapture 2899 * 2900 * DESCRIPTION: stops advanced capture based on capture type 2901 * 2902 * PARAMETERS : 2903 * @pChannel : channel. 2904 * 2905 * RETURN : int32_t type of status 2906 * NO_ERROR -- success 2907 * none-zero failure code 2908 *==========================================================================*/ 2909 int32_t QCamera2HardwareInterface::stopAdvancedCapture( 2910 QCameraPicChannel *pChannel) 2911 { 2912 CDBG_HIGH("%s: stop bracketig",__func__); 2913 int32_t rc = NO_ERROR; 2914 2915 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 2916 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING); 2917 } else if (mParameters.isChromaFlashEnabled()) { 2918 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE); 2919 } else if(mParameters.isHDREnabled() 2920 || mParameters.isAEBracketEnabled()) { 2921 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING); 2922 } else if (mParameters.isOptiZoomEnabled()) { 2923 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X); 2924 } else if (mParameters.isStillMoreEnabled()) { 2925 CDBG_HIGH("%s: stopAdvancedCapture not needed for StillMore", __func__); 2926 } else { 2927 ALOGE("%s: No Advanced Capture feature enabled!",__func__); 2928 rc = BAD_VALUE; 2929 } 2930 return rc; 2931 } 2932 2933 /*=========================================================================== 2934 * FUNCTION : startAdvancedCapture 2935 * 2936 * DESCRIPTION: starts advanced capture based on capture type 2937 * 2938 * PARAMETERS : 2939 * @pChannel : channel. 2940 * 2941 * RETURN : int32_t type of status 2942 * NO_ERROR -- success 2943 * none-zero failure code 2944 *==========================================================================*/ 2945 int32_t QCamera2HardwareInterface::startAdvancedCapture( 2946 QCameraPicChannel *pChannel) 2947 { 2948 CDBG_HIGH("%s: Start bracketing",__func__); 2949 int32_t rc = NO_ERROR; 2950 2951 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) { 2952 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING); 2953 } else if (mParameters.isOptiZoomEnabled()) { 2954 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X); 2955 } else if (mParameters.isStillMoreEnabled()) { 2956 CDBG_HIGH("%s: startAdvancedCapture not needed for StillMore", __func__); 2957 } else if (mParameters.isHDREnabled() 2958 || mParameters.isAEBracketEnabled()) { 2959 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING); 2960 } else if (mParameters.isChromaFlashEnabled()) { 2961 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig(); 2962 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config); 2963 } else { 2964 ALOGE("%s: No Advanced Capture feature enabled!",__func__); 2965 rc = BAD_VALUE; 2966 } 2967 return rc; 2968 } 2969 2970 /*=========================================================================== 2971 * FUNCTION : takePicture 2972 * 2973 * DESCRIPTION: take picture impl 2974 * 2975 * PARAMETERS : none 2976 * 2977 * RETURN : int32_t type of status 2978 * NO_ERROR -- success 2979 * none-zero failure code 2980 *==========================================================================*/ 2981 int QCamera2HardwareInterface::takePicture() 2982 { 2983 int rc = NO_ERROR; 2984 2985 // Get total number for snapshots (retro + regular) 2986 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 2987 // Get number of retro-active snapshots 2988 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots(); 2989 CDBG_HIGH("%s: E", __func__); 2990 2991 //Set rotation value from user settings as Jpeg rotation 2992 //to configure back-end modules. 2993 mParameters.setJpegRotation(mParameters.getRotation()); 2994 2995 // Check if retro-active snapshots are not enabled 2996 if (!isRetroPicture() || !mParameters.isZSLMode()) { 2997 numRetroSnapshots = 0; 2998 CDBG_HIGH("%s: [ZSL Retro] Reset retro snaphot count to zero", __func__); 2999 } 3000 if (mParameters.isUbiFocusEnabled() || 3001 mParameters.isUbiRefocus() || 3002 mParameters.isOptiZoomEnabled() || 3003 mParameters.isHDREnabled() || 3004 mParameters.isChromaFlashEnabled() || 3005 mParameters.isAEBracketEnabled() || 3006 mParameters.isStillMoreEnabled()) { 3007 rc = configureAdvancedCapture(); 3008 if (rc == NO_ERROR) { 3009 numSnapshots = mParameters.getBurstCountForAdvancedCapture(); 3010 } 3011 } 3012 CDBG_HIGH("%s: [ZSL Retro] numSnapshots = %d, numRetroSnapshots = %d", 3013 __func__, numSnapshots, numRetroSnapshots); 3014 3015 if (mParameters.isZSLMode()) { 3016 QCameraPicChannel *pZSLChannel = 3017 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 3018 if (NULL != pZSLChannel) { 3019 3020 rc = configureOnlineRotation(*pZSLChannel); 3021 if (rc != NO_ERROR) { 3022 ALOGE("%s: online rotation failed", __func__); 3023 return rc; 3024 } 3025 3026 // start postprocessor 3027 DefferWorkArgs args; 3028 memset(&args, 0, sizeof(DefferWorkArgs)); 3029 3030 args.pprocArgs = pZSLChannel; 3031 mReprocJob = queueDefferedWork(CMD_DEFF_PPROC_START, 3032 args); 3033 3034 if (mParameters.isUbiFocusEnabled() || 3035 mParameters.isUbiRefocus() || 3036 mParameters.isOptiZoomEnabled() || 3037 mParameters.isHDREnabled() || 3038 mParameters.isChromaFlashEnabled() || 3039 mParameters.isAEBracketEnabled() || 3040 mParameters.isStillMoreEnabled()) { 3041 rc = startAdvancedCapture(pZSLChannel); 3042 if (rc != NO_ERROR) { 3043 ALOGE("%s: cannot start zsl advanced capture", __func__); 3044 return rc; 3045 } 3046 } 3047 if (mLongshotEnabled && mPrepSnapRun) { 3048 mCameraHandle->ops->start_zsl_snapshot( 3049 mCameraHandle->camera_handle, 3050 pZSLChannel->getMyHandle()); 3051 } 3052 rc = pZSLChannel->takePicture(numSnapshots, numRetroSnapshots); 3053 if (rc != NO_ERROR) { 3054 ALOGE("%s: cannot take ZSL picture, stop pproc", __func__); 3055 waitDefferedWork(mReprocJob); 3056 m_postprocessor.stop(); 3057 return rc; 3058 } 3059 } else { 3060 ALOGE("%s: ZSL channel is NULL", __func__); 3061 return UNKNOWN_ERROR; 3062 } 3063 } else { 3064 3065 // start snapshot 3066 if (mParameters.isJpegPictureFormat() || 3067 mParameters.isNV16PictureFormat() || 3068 mParameters.isNV21PictureFormat()) { 3069 3070 if (!isLongshotEnabled()) { 3071 3072 rc = addCaptureChannel(); 3073 3074 // normal capture case 3075 // need to stop preview channel 3076 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3077 delChannel(QCAMERA_CH_TYPE_PREVIEW); 3078 3079 if (NO_ERROR == rc) { 3080 rc = declareSnapshotStreams(); 3081 if (NO_ERROR != rc) { 3082 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3083 return rc; 3084 } 3085 } 3086 3087 waitDefferedWork(mSnapshotJob); 3088 waitDefferedWork(mMetadataJob); 3089 waitDefferedWork(mRawdataJob); 3090 3091 { 3092 DefferWorkArgs args; 3093 DefferAllocBuffArgs allocArgs; 3094 3095 memset(&args, 0, sizeof(DefferWorkArgs)); 3096 memset(&allocArgs, 0, sizeof(DefferAllocBuffArgs)); 3097 3098 allocArgs.ch = m_channels[QCAMERA_CH_TYPE_CAPTURE]; 3099 allocArgs.type = CAM_STREAM_TYPE_POSTVIEW; 3100 args.allocArgs = allocArgs; 3101 3102 mPostviewJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF, 3103 args); 3104 3105 if (mPostviewJob == -1) { 3106 rc = UNKNOWN_ERROR; 3107 } 3108 } 3109 3110 waitDefferedWork(mPostviewJob); 3111 } else { 3112 // normal capture case 3113 // need to stop preview channel 3114 3115 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3116 delChannel(QCAMERA_CH_TYPE_PREVIEW); 3117 3118 rc = declareSnapshotStreams(); 3119 if (NO_ERROR != rc) { 3120 return rc; 3121 } 3122 3123 rc = addCaptureChannel(); 3124 } 3125 3126 if ((rc == NO_ERROR) && 3127 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) { 3128 3129 // configure capture channel 3130 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->config(); 3131 if (rc != NO_ERROR) { 3132 ALOGE("%s: cannot configure capture channel", __func__); 3133 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3134 return rc; 3135 } 3136 3137 if (!mParameters.getofflineRAW()) { 3138 rc = configureOnlineRotation( 3139 *m_channels[QCAMERA_CH_TYPE_CAPTURE]); 3140 if (rc != NO_ERROR) { 3141 ALOGE("%s: online rotation failed", __func__); 3142 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3143 return rc; 3144 } 3145 } 3146 3147 DefferWorkArgs args; 3148 memset(&args, 0, sizeof(DefferWorkArgs)); 3149 3150 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE]; 3151 mReprocJob = queueDefferedWork(CMD_DEFF_PPROC_START, 3152 args); 3153 3154 // start catpure channel 3155 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start(); 3156 if (rc != NO_ERROR) { 3157 ALOGE("%s: cannot start capture channel", __func__); 3158 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3159 return rc; 3160 } 3161 3162 QCameraPicChannel *pCapChannel = 3163 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 3164 if (NULL != pCapChannel) { 3165 if (mParameters.isUbiFocusEnabled() || 3166 mParameters.isUbiRefocus() || 3167 mParameters.isChromaFlashEnabled()) { 3168 rc = startAdvancedCapture(pCapChannel); 3169 if (rc != NO_ERROR) { 3170 ALOGE("%s: cannot start advanced capture", __func__); 3171 return rc; 3172 } 3173 } 3174 } 3175 if ( mLongshotEnabled ) { 3176 rc = longShot(); 3177 if (NO_ERROR != rc) { 3178 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3179 return rc; 3180 } 3181 } 3182 } else { 3183 ALOGE("%s: cannot add capture channel", __func__); 3184 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3185 return rc; 3186 } 3187 } else { 3188 3189 stopChannel(QCAMERA_CH_TYPE_PREVIEW); 3190 delChannel(QCAMERA_CH_TYPE_PREVIEW); 3191 3192 rc = mParameters.updateRAW(gCamCaps[mCameraId]->raw_dim[0]); 3193 if (NO_ERROR != rc) { 3194 ALOGE("%s: Raw dimension update failed %d", __func__, rc); 3195 return rc; 3196 } 3197 3198 rc = declareSnapshotStreams(); 3199 if (NO_ERROR != rc) { 3200 ALOGE("%s: RAW stream info configuration failed %d", 3201 __func__, 3202 rc); 3203 return rc; 3204 } 3205 3206 rc = addRawChannel(); 3207 if (rc == NO_ERROR) { 3208 // start postprocessor 3209 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 3210 if (rc != NO_ERROR) { 3211 ALOGE("%s: cannot start postprocessor", __func__); 3212 delChannel(QCAMERA_CH_TYPE_RAW); 3213 return rc; 3214 } 3215 3216 rc = startChannel(QCAMERA_CH_TYPE_RAW); 3217 if (rc != NO_ERROR) { 3218 ALOGE("%s: cannot start raw channel", __func__); 3219 m_postprocessor.stop(); 3220 delChannel(QCAMERA_CH_TYPE_RAW); 3221 return rc; 3222 } 3223 } else { 3224 ALOGE("%s: cannot add raw channel", __func__); 3225 return rc; 3226 } 3227 } 3228 } 3229 CDBG_HIGH("%s: X", __func__); 3230 return rc; 3231 } 3232 3233 /*=========================================================================== 3234 * FUNCTION : configureOnlineRotation 3235 * 3236 * DESCRIPTION: Configure backend with expected rotation for snapshot stream 3237 * 3238 * PARAMETERS : 3239 * @ch : Channel containing a snapshot stream 3240 * 3241 * RETURN : int32_t type of status 3242 * NO_ERROR -- success 3243 * none-zero failure code 3244 *==========================================================================*/ 3245 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch) 3246 { 3247 int rc = NO_ERROR; 3248 uint32_t streamId = 0; 3249 QCameraStream *pStream = NULL; 3250 3251 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) { 3252 QCameraStream *stream = ch.getStreamByIndex(i); 3253 if ((NULL != stream) && 3254 (CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())) { 3255 pStream = stream; 3256 break; 3257 } 3258 } 3259 3260 if (NULL == pStream) { 3261 ALOGE("%s: No snapshot stream found!", __func__); 3262 return BAD_VALUE; 3263 } 3264 3265 streamId = pStream->getMyServerID(); 3266 // Update online rotation configuration 3267 pthread_mutex_lock(&m_parm_lock); 3268 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId, 3269 mParameters.getDeviceRotation()); 3270 if (rc != NO_ERROR) { 3271 ALOGE("%s: addOnlineRotation failed %d", __func__, rc); 3272 pthread_mutex_unlock(&m_parm_lock); 3273 return rc; 3274 } 3275 pthread_mutex_unlock(&m_parm_lock); 3276 3277 return rc; 3278 } 3279 3280 /*=========================================================================== 3281 * FUNCTION : declareSnapshotStreams 3282 * 3283 * DESCRIPTION: Configure backend with expected snapshot streams 3284 * 3285 * PARAMETERS : none 3286 * 3287 * RETURN : int32_t type of status 3288 * NO_ERROR -- success 3289 * none-zero failure code 3290 *==========================================================================*/ 3291 int32_t QCamera2HardwareInterface::declareSnapshotStreams() 3292 { 3293 int rc = NO_ERROR; 3294 3295 // Update stream info configuration 3296 pthread_mutex_lock(&m_parm_lock); 3297 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false); 3298 if (rc != NO_ERROR) { 3299 ALOGE("%s: setStreamConfigure failed %d", __func__, rc); 3300 pthread_mutex_unlock(&m_parm_lock); 3301 return rc; 3302 } 3303 pthread_mutex_unlock(&m_parm_lock); 3304 3305 return rc; 3306 } 3307 3308 /*=========================================================================== 3309 * FUNCTION : longShot 3310 * 3311 * DESCRIPTION: Queue one more ZSL frame 3312 * in the longshot pipe. 3313 * 3314 * PARAMETERS : none 3315 * 3316 * RETURN : int32_t type of status 3317 * NO_ERROR -- success 3318 * none-zero failure code 3319 *==========================================================================*/ 3320 int32_t QCamera2HardwareInterface::longShot() 3321 { 3322 int32_t rc = NO_ERROR; 3323 uint8_t numSnapshots = mParameters.getNumOfSnapshots(); 3324 QCameraPicChannel *pChannel = NULL; 3325 3326 if (mParameters.isZSLMode()) { 3327 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 3328 } else { 3329 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE]; 3330 } 3331 3332 if (NULL != pChannel) { 3333 rc = pChannel->takePicture(numSnapshots, 0); 3334 } else { 3335 ALOGE(" %s : Capture channel not initialized!", __func__); 3336 rc = NO_INIT; 3337 goto end; 3338 } 3339 3340 end: 3341 return rc; 3342 } 3343 3344 /*=========================================================================== 3345 * FUNCTION : stopCaptureChannel 3346 * 3347 * DESCRIPTION: Stops capture channel 3348 * 3349 * PARAMETERS : 3350 * @destroy : Set to true to stop and delete camera channel. 3351 * Set to false to only stop capture channel. 3352 * 3353 * RETURN : int32_t type of status 3354 * NO_ERROR -- success 3355 * none-zero failure code 3356 *==========================================================================*/ 3357 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy) 3358 { 3359 int rc = NO_ERROR; 3360 if (mParameters.isJpegPictureFormat() || 3361 mParameters.isNV16PictureFormat() || 3362 mParameters.isNV21PictureFormat()) { 3363 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE); 3364 if (destroy && (NO_ERROR == rc)) { 3365 // Destroy camera channel but dont release context 3366 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false); 3367 } 3368 } 3369 3370 return rc; 3371 } 3372 3373 /*=========================================================================== 3374 * FUNCTION : cancelPicture 3375 * 3376 * DESCRIPTION: cancel picture impl 3377 * 3378 * PARAMETERS : none 3379 * 3380 * RETURN : int32_t type of status 3381 * NO_ERROR -- success 3382 * none-zero failure code 3383 *==========================================================================*/ 3384 int QCamera2HardwareInterface::cancelPicture() 3385 { 3386 waitDefferedWork(mReprocJob); 3387 3388 //stop post processor 3389 m_postprocessor.stop(); 3390 3391 unconfigureAdvancedCapture(); 3392 3393 mParameters.setDisplayFrame(TRUE); 3394 3395 if (!mLongshotEnabled) { 3396 m_perfLock.lock_rel(); 3397 } 3398 3399 if (mParameters.isZSLMode()) { 3400 QCameraPicChannel *pZSLChannel = 3401 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 3402 if (NULL != pZSLChannel) { 3403 stopAdvancedCapture(pZSLChannel); 3404 pZSLChannel->cancelPicture(); 3405 } 3406 } else { 3407 3408 // normal capture case 3409 if (mParameters.isJpegPictureFormat() || 3410 mParameters.isNV16PictureFormat() || 3411 mParameters.isNV21PictureFormat()) { 3412 stopChannel(QCAMERA_CH_TYPE_CAPTURE); 3413 delChannel(QCAMERA_CH_TYPE_CAPTURE); 3414 } else { 3415 stopChannel(QCAMERA_CH_TYPE_RAW); 3416 delChannel(QCAMERA_CH_TYPE_RAW); 3417 } 3418 } 3419 3420 return NO_ERROR; 3421 } 3422 3423 /*=========================================================================== 3424 * FUNCTION : captureDone 3425 * 3426 * DESCRIPTION: Function called when the capture is completed before encoding 3427 * 3428 * PARAMETERS : none 3429 * 3430 * RETURN : none 3431 *==========================================================================*/ 3432 void QCamera2HardwareInterface::captureDone() 3433 { 3434 qcamera_sm_internal_evt_payload_t *payload = 3435 (qcamera_sm_internal_evt_payload_t *) 3436 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 3437 if (NULL != payload) { 3438 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 3439 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE; 3440 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 3441 if (rc != NO_ERROR) { 3442 ALOGE("%s: processEvt ZSL capture done failed", __func__); 3443 free(payload); 3444 payload = NULL; 3445 } 3446 } else { 3447 ALOGE("%s: No memory for ZSL capture done event", __func__); 3448 } 3449 } 3450 3451 /*=========================================================================== 3452 * FUNCTION : Live_Snapshot_thread 3453 * 3454 * DESCRIPTION: Seperate thread for taking live snapshot during recording 3455 * 3456 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 3457 * 3458 * RETURN : none 3459 *==========================================================================*/ 3460 void* Live_Snapshot_thread (void* data) 3461 { 3462 3463 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 3464 if (!hw) { 3465 ALOGE("take_picture_thread: NULL camera device"); 3466 return (void *)BAD_VALUE; 3467 } 3468 hw->takeLiveSnapshot_internal(); 3469 return (void* )NULL; 3470 } 3471 3472 /*=========================================================================== 3473 * FUNCTION : Int_Pic_thread 3474 * 3475 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend 3476 * 3477 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object 3478 * 3479 * RETURN : none 3480 *==========================================================================*/ 3481 void* Int_Pic_thread (void* data) 3482 { 3483 int rc = NO_ERROR; 3484 3485 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data); 3486 3487 if (!hw) { 3488 ALOGE("take_picture_thread: NULL camera device"); 3489 return (void *)BAD_VALUE; 3490 } 3491 3492 bool JpegMemOpt = false; 3493 char raw_format[PROPERTY_VALUE_MAX]; 3494 3495 memset(raw_format, 0, sizeof(raw_format)); 3496 3497 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]); 3498 if (rc == NO_ERROR) { 3499 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]); 3500 } else { 3501 //Snapshot attempt not successful, we need to do cleanup here 3502 hw->clearIntPendingEvents(); 3503 } 3504 3505 return (void* )NULL; 3506 } 3507 3508 /*=========================================================================== 3509 * FUNCTION : takeLiveSnapshot 3510 * 3511 * DESCRIPTION: take live snapshot during recording 3512 * 3513 * PARAMETERS : none 3514 * 3515 * RETURN : int32_t type of status 3516 * NO_ERROR -- success 3517 * none-zero failure code 3518 *==========================================================================*/ 3519 int QCamera2HardwareInterface::takeLiveSnapshot() 3520 { 3521 int rc = NO_ERROR; 3522 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this); 3523 return rc; 3524 } 3525 3526 /*=========================================================================== 3527 * FUNCTION : takePictureInternal 3528 * 3529 * DESCRIPTION: take snapshot triggered by backend 3530 * 3531 * PARAMETERS : none 3532 * 3533 * RETURN : int32_t type of status 3534 * NO_ERROR -- success 3535 * none-zero failure code 3536 *==========================================================================*/ 3537 int QCamera2HardwareInterface::takePictureInternal() 3538 { 3539 int rc = NO_ERROR; 3540 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this); 3541 return rc; 3542 } 3543 3544 /*=========================================================================== 3545 * FUNCTION : checkIntPicPending 3546 * 3547 * DESCRIPTION: timed wait for jpeg completion event, and send 3548 * back completion event to backend 3549 * 3550 * PARAMETERS : none 3551 * 3552 * RETURN : none 3553 *==========================================================================*/ 3554 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format) 3555 { 3556 bool bSendToBackend = true; 3557 cam_int_evt_params_t params; 3558 int rc = NO_ERROR; 3559 3560 struct timespec ts; 3561 struct timeval tp; 3562 gettimeofday(&tp, NULL); 3563 ts.tv_sec = tp.tv_sec + 5; 3564 ts.tv_nsec = tp.tv_usec * 1000; 3565 3566 if (true == m_bIntJpegEvtPending || 3567 (true == m_bIntRawEvtPending)) { 3568 //Waiting in HAL for snapshot taken notification 3569 pthread_mutex_lock(&m_int_lock); 3570 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts); 3571 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) { 3572 //Hit a timeout, or some spurious activity 3573 bSendToBackend = false; 3574 } 3575 3576 if (true == m_bIntJpegEvtPending) { 3577 params.event_type = 0; 3578 } else if (true == m_bIntRawEvtPending) { 3579 params.event_type = 1; 3580 } 3581 pthread_mutex_unlock(&m_int_lock); 3582 3583 if (true == m_bIntJpegEvtPending) { 3584 //Attempting to restart preview after taking JPEG snapshot 3585 lockAPI(); 3586 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 3587 unlockAPI(); 3588 m_postprocessor.setJpegMemOpt(JpegMemOpt); 3589 } else if (true == m_bIntRawEvtPending) { 3590 //Attempting to restart preview after taking RAW snapshot 3591 stopChannel(QCAMERA_CH_TYPE_RAW); 3592 delChannel(QCAMERA_CH_TYPE_RAW); 3593 //restoring the old raw format 3594 property_set("persist.camera.raw.format", raw_format); 3595 } 3596 3597 if (true == bSendToBackend) { 3598 //send event back to server with the file path 3599 params.dim = m_postprocessor.m_dst_dim; 3600 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH); 3601 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH); 3602 params.size = mBackendFileSize; 3603 pthread_mutex_lock(&m_parm_lock); 3604 rc = mParameters.setIntEvent(params); 3605 pthread_mutex_unlock(&m_parm_lock); 3606 } 3607 3608 clearIntPendingEvents(); 3609 } 3610 3611 return; 3612 } 3613 3614 /*=========================================================================== 3615 * FUNCTION : takeBackendPic_internal 3616 * 3617 * DESCRIPTION: take snapshot triggered by backend 3618 * 3619 * PARAMETERS : none 3620 * 3621 * RETURN : int32_t type of status 3622 * NO_ERROR -- success 3623 * none-zero failure code 3624 *==========================================================================*/ 3625 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format) 3626 { 3627 int rc = NO_ERROR; 3628 qcamera_api_result_t apiResult; 3629 3630 lockAPI(); 3631 //Set rotation value from user settings as Jpeg rotation 3632 //to configure back-end modules. 3633 mParameters.setJpegRotation(mParameters.getRotation()); 3634 3635 setRetroPicture(0); 3636 /* Prepare snapshot in case LED needs to be flashed */ 3637 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) { 3638 // Start Preparing for normal Frames 3639 CDBG_HIGH("%s: Start Prepare Snapshot", __func__); 3640 /* Prepare snapshot in case LED needs to be flashed */ 3641 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL); 3642 if (rc == NO_ERROR) { 3643 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult); 3644 rc = apiResult.status; 3645 CDBG_HIGH("%s: Prep Snapshot done", __func__); 3646 } 3647 mPrepSnapRun = true; 3648 } 3649 unlockAPI(); 3650 3651 if (true == m_bIntJpegEvtPending) { 3652 //Attempting to take JPEG snapshot 3653 *JpegMemOpt = m_postprocessor.getJpegMemOpt(); 3654 m_postprocessor.setJpegMemOpt(false); 3655 3656 /* capture */ 3657 lockAPI(); 3658 CDBG_HIGH("%s: Capturing internal snapshot", __func__); 3659 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL); 3660 if (rc == NO_ERROR) { 3661 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult); 3662 rc = apiResult.status; 3663 } 3664 unlockAPI(); 3665 } else if (true == m_bIntRawEvtPending) { 3666 //Attempting to take RAW snapshot 3667 (void)JpegMemOpt; 3668 stopPreview(); 3669 3670 //getting the existing raw format type 3671 property_get("persist.camera.raw.format", raw_format, "16"); 3672 //setting it to a default know value for this task 3673 property_set("persist.camera.raw.format", "18"); 3674 3675 rc = addRawChannel(); 3676 if (rc == NO_ERROR) { 3677 // start postprocessor 3678 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]); 3679 if (rc != NO_ERROR) { 3680 ALOGE("%s: cannot start postprocessor", __func__); 3681 delChannel(QCAMERA_CH_TYPE_RAW); 3682 return rc; 3683 } 3684 3685 rc = startChannel(QCAMERA_CH_TYPE_RAW); 3686 if (rc != NO_ERROR) { 3687 ALOGE("%s: cannot start raw channel", __func__); 3688 m_postprocessor.stop(); 3689 delChannel(QCAMERA_CH_TYPE_RAW); 3690 return rc; 3691 } 3692 } else { 3693 ALOGE("%s: cannot add raw channel", __func__); 3694 return rc; 3695 } 3696 } 3697 3698 return rc; 3699 } 3700 3701 /*=========================================================================== 3702 * FUNCTION : clearIntPendingEvents 3703 * 3704 * DESCRIPTION: clear internal pending events pertaining to backend 3705 * snapshot requests 3706 * 3707 * PARAMETERS : none 3708 * 3709 * RETURN : int32_t type of status 3710 * NO_ERROR -- success 3711 * none-zero failure code 3712 *==========================================================================*/ 3713 void QCamera2HardwareInterface::clearIntPendingEvents() 3714 { 3715 int rc = NO_ERROR; 3716 3717 if (true == m_bIntRawEvtPending) { 3718 preparePreview(); 3719 startPreview(); 3720 } 3721 if (true == m_bIntJpegEvtPending) { 3722 if (false == mParameters.isZSLMode()) { 3723 lockAPI(); 3724 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL); 3725 unlockAPI(); 3726 } 3727 } 3728 3729 pthread_mutex_lock(&m_int_lock); 3730 if (true == m_bIntJpegEvtPending) { 3731 m_bIntJpegEvtPending = false; 3732 } else if (true == m_bIntRawEvtPending) { 3733 m_bIntRawEvtPending = false; 3734 } 3735 pthread_mutex_unlock(&m_int_lock); 3736 return; 3737 } 3738 3739 /*=========================================================================== 3740 * FUNCTION : takeLiveSnapshot_internal 3741 * 3742 * DESCRIPTION: take live snapshot during recording 3743 * 3744 * PARAMETERS : none 3745 * 3746 * RETURN : int32_t type of status 3747 * NO_ERROR -- success 3748 * none-zero failure code 3749 *==========================================================================*/ 3750 int QCamera2HardwareInterface::takeLiveSnapshot_internal() 3751 { 3752 int rc = NO_ERROR; 3753 3754 QCameraChannel *pChannel = NULL; 3755 3756 //Set rotation value from user settings as Jpeg rotation 3757 //to configure back-end modules. 3758 mParameters.setJpegRotation(mParameters.getRotation()); 3759 3760 // Configure advanced capture 3761 if (mParameters.isUbiFocusEnabled() || 3762 mParameters.isUbiRefocus() || 3763 mParameters.isOptiZoomEnabled() || 3764 mParameters.isHDREnabled() || 3765 mParameters.isChromaFlashEnabled() || 3766 mParameters.isAEBracketEnabled() || 3767 mParameters.isStillMoreEnabled()) { 3768 rc = configureAdvancedCapture(); 3769 if (rc != NO_ERROR) { 3770 CDBG_HIGH("%s: configureAdvancedCapture unsuccessful", __func__); 3771 } 3772 } 3773 3774 // start post processor 3775 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_SNAPSHOT]); 3776 if (NO_ERROR != rc) { 3777 ALOGE("%s: Post-processor start failed %d", __func__, rc); 3778 goto end; 3779 } 3780 3781 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 3782 if (NULL == pChannel) { 3783 ALOGE("%s: Snapshot channel not initialized", __func__); 3784 rc = NO_INIT; 3785 goto end; 3786 } 3787 //Disable reprocess for 4K liveshot case 3788 if (!mParameters.is4k2kVideoResolution()) { 3789 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]); 3790 if (rc != NO_ERROR) { 3791 ALOGE("%s: online rotation failed", __func__); 3792 m_postprocessor.stop(); 3793 return rc; 3794 } 3795 } 3796 // start snapshot channel 3797 if ((rc == NO_ERROR) && (NULL != pChannel)) { 3798 // Do not link metadata stream for 4K2k resolution 3799 // as CPP processing would be done on snapshot stream and not 3800 // reprocess stream 3801 if (!mParameters.is4k2kVideoResolution()) { 3802 // Find and try to link a metadata stream from preview channel 3803 QCameraChannel *pMetaChannel = NULL; 3804 QCameraStream *pMetaStream = NULL; 3805 3806 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 3807 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW]; 3808 uint32_t streamNum = pMetaChannel->getNumOfStreams(); 3809 QCameraStream *pStream = NULL; 3810 for (uint32_t i = 0 ; i < streamNum ; i++ ) { 3811 pStream = pMetaChannel->getStreamByIndex(i); 3812 if ((NULL != pStream) && 3813 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) { 3814 pMetaStream = pStream; 3815 break; 3816 } 3817 } 3818 } 3819 3820 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) { 3821 rc = pChannel->linkStream(pMetaChannel, pMetaStream); 3822 if (NO_ERROR != rc) { 3823 ALOGE("%s : Metadata stream link failed %d", __func__, rc); 3824 } 3825 } 3826 } 3827 3828 rc = pChannel->start(); 3829 } 3830 3831 end: 3832 if (rc != NO_ERROR) { 3833 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL); 3834 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 3835 } 3836 return rc; 3837 } 3838 3839 /*=========================================================================== 3840 * FUNCTION : cancelLiveSnapshot 3841 * 3842 * DESCRIPTION: cancel current live snapshot request 3843 * 3844 * PARAMETERS : none 3845 * 3846 * RETURN : int32_t type of status 3847 * NO_ERROR -- success 3848 * none-zero failure code 3849 *==========================================================================*/ 3850 int QCamera2HardwareInterface::cancelLiveSnapshot() 3851 { 3852 int rc = NO_ERROR; 3853 3854 unconfigureAdvancedCapture(); 3855 if (!mLongshotEnabled) { 3856 m_perfLock.lock_rel(); 3857 } 3858 3859 if (mLiveSnapshotThread != 0) { 3860 pthread_join(mLiveSnapshotThread,NULL); 3861 mLiveSnapshotThread = 0; 3862 } 3863 3864 //stop post processor 3865 m_postprocessor.stop(); 3866 3867 // stop snapshot channel 3868 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT); 3869 3870 return rc; 3871 } 3872 3873 /*=========================================================================== 3874 * FUNCTION : getParameters 3875 * 3876 * DESCRIPTION: get parameters impl 3877 * 3878 * PARAMETERS : none 3879 * 3880 * RETURN : a string containing parameter pairs 3881 *==========================================================================*/ 3882 char* QCamera2HardwareInterface::getParameters() 3883 { 3884 char* strParams = NULL; 3885 String8 str; 3886 3887 int cur_width, cur_height; 3888 pthread_mutex_lock(&m_parm_lock); 3889 //Need take care Scale picture size 3890 if(mParameters.m_reprocScaleParam.isScaleEnabled() && 3891 mParameters.m_reprocScaleParam.isUnderScaling()){ 3892 int scale_width, scale_height; 3893 3894 mParameters.m_reprocScaleParam.getPicSizeFromAPK(scale_width,scale_height); 3895 mParameters.getPictureSize(&cur_width, &cur_height); 3896 3897 String8 pic_size; 3898 char buffer[32]; 3899 snprintf(buffer, sizeof(buffer), "%dx%d", scale_width, scale_height); 3900 pic_size.append(buffer); 3901 mParameters.set(CameraParameters::KEY_PICTURE_SIZE, pic_size); 3902 } 3903 3904 str = mParameters.flatten( ); 3905 strParams = (char *)malloc(sizeof(char)*(str.length()+1)); 3906 if(strParams != NULL){ 3907 memset(strParams, 0, sizeof(char)*(str.length()+1)); 3908 strlcpy(strParams, str.string(), str.length()+1); 3909 strParams[str.length()] = 0; 3910 } 3911 3912 if(mParameters.m_reprocScaleParam.isScaleEnabled() && 3913 mParameters.m_reprocScaleParam.isUnderScaling()){ 3914 //need set back picture size 3915 String8 pic_size; 3916 char buffer[32]; 3917 snprintf(buffer, sizeof(buffer), "%dx%d", cur_width, cur_height); 3918 pic_size.append(buffer); 3919 mParameters.set(CameraParameters::KEY_PICTURE_SIZE, pic_size); 3920 } 3921 pthread_mutex_unlock(&m_parm_lock); 3922 return strParams; 3923 } 3924 3925 /*=========================================================================== 3926 * FUNCTION : putParameters 3927 * 3928 * DESCRIPTION: put parameters string impl 3929 * 3930 * PARAMETERS : 3931 * @parms : parameters string to be released 3932 * 3933 * RETURN : int32_t type of status 3934 * NO_ERROR -- success 3935 * none-zero failure code 3936 *==========================================================================*/ 3937 int QCamera2HardwareInterface::putParameters(char *parms) 3938 { 3939 free(parms); 3940 return NO_ERROR; 3941 } 3942 3943 /*=========================================================================== 3944 * FUNCTION : sendCommand 3945 * 3946 * DESCRIPTION: send command impl 3947 * 3948 * PARAMETERS : 3949 * @command : command to be executed 3950 * @arg1 : optional argument 1 3951 * @arg2 : optional argument 2 3952 * 3953 * RETURN : int32_t type of status 3954 * NO_ERROR -- success 3955 * none-zero failure code 3956 *==========================================================================*/ 3957 int QCamera2HardwareInterface::sendCommand(int32_t command, 3958 int32_t &arg1, int32_t &/*arg2*/) 3959 { 3960 int rc = NO_ERROR; 3961 3962 switch (command) { 3963 #ifndef VANILLA_HAL 3964 case CAMERA_CMD_LONGSHOT_ON: 3965 m_perfLock.lock_acq(); 3966 arg1 = 0; 3967 // Longshot can only be enabled when image capture 3968 // is not active. 3969 if ( !m_stateMachine.isCaptureRunning() ) { 3970 mLongshotEnabled = true; 3971 mParameters.setLongshotEnable(mLongshotEnabled); 3972 3973 // Due to recent buffer count optimizations 3974 // ZSL might run with considerably less buffers 3975 // when not in longshot mode. Preview needs to 3976 // restart in this case. 3977 if (isZSLMode() && m_stateMachine.isPreviewRunning()) { 3978 QCameraChannel *pChannel = NULL; 3979 QCameraStream *pSnapStream = NULL; 3980 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 3981 if (NULL != pChannel) { 3982 QCameraStream *pStream = NULL; 3983 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) { 3984 pStream = pChannel->getStreamByIndex(i); 3985 if (pStream != NULL) { 3986 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 3987 pSnapStream = pStream; 3988 break; 3989 } 3990 } 3991 } 3992 if (NULL != pSnapStream) { 3993 uint8_t required = 0; 3994 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT); 3995 if (pSnapStream->getBufferCount() < required) { 3996 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW; 3997 } 3998 } 3999 } 4000 } 4001 // 4002 mPrepSnapRun = false; 4003 } else { 4004 rc = NO_INIT; 4005 } 4006 break; 4007 case CAMERA_CMD_LONGSHOT_OFF: 4008 m_perfLock.lock_rel(); 4009 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) { 4010 cancelPicture(); 4011 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL); 4012 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL]; 4013 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) { 4014 mCameraHandle->ops->stop_zsl_snapshot( 4015 mCameraHandle->camera_handle, 4016 pZSLChannel->getMyHandle()); 4017 } 4018 } 4019 mPrepSnapRun = false; 4020 mLongshotEnabled = false; 4021 mParameters.setLongshotEnable(mLongshotEnabled); 4022 break; 4023 case CAMERA_CMD_HISTOGRAM_ON: 4024 case CAMERA_CMD_HISTOGRAM_OFF: 4025 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false); 4026 break; 4027 #endif 4028 case CAMERA_CMD_START_FACE_DETECTION: 4029 case CAMERA_CMD_STOP_FACE_DETECTION: 4030 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 4031 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false); 4032 break; 4033 #ifndef VANILLA_HAL 4034 case CAMERA_CMD_HISTOGRAM_SEND_DATA: 4035 #endif 4036 default: 4037 rc = NO_ERROR; 4038 break; 4039 } 4040 return rc; 4041 } 4042 4043 /*=========================================================================== 4044 * FUNCTION : registerFaceImage 4045 * 4046 * DESCRIPTION: register face image impl 4047 * 4048 * PARAMETERS : 4049 * @img_ptr : ptr to image buffer 4050 * @config : ptr to config struct about input image info 4051 * @faceID : [OUT] face ID to uniquely identifiy the registered face image 4052 * 4053 * RETURN : int32_t type of status 4054 * NO_ERROR -- success 4055 * none-zero failure code 4056 *==========================================================================*/ 4057 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr, 4058 cam_pp_offline_src_config_t *config, 4059 int32_t &faceID) 4060 { 4061 int rc = NO_ERROR; 4062 faceID = -1; 4063 4064 if (img_ptr == NULL || config == NULL) { 4065 ALOGE("%s: img_ptr or config is NULL", __func__); 4066 return BAD_VALUE; 4067 } 4068 4069 // allocate ion memory for source image 4070 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE); 4071 if (imgBuf == NULL) { 4072 ALOGE("%s: Unable to new heap memory obj for image buf", __func__); 4073 return NO_MEMORY; 4074 } 4075 4076 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE); 4077 if (rc < 0) { 4078 ALOGE("%s: Unable to allocate heap memory for image buf", __func__); 4079 delete imgBuf; 4080 return NO_MEMORY; 4081 } 4082 4083 void *pBufPtr = imgBuf->getPtr(0); 4084 if (pBufPtr == NULL) { 4085 ALOGE("%s: image buf is NULL", __func__); 4086 imgBuf->deallocate(); 4087 delete imgBuf; 4088 return NO_MEMORY; 4089 } 4090 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len); 4091 4092 cam_pp_feature_config_t pp_feature; 4093 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t)); 4094 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE; 4095 QCameraReprocessChannel *pChannel = 4096 addOfflineReprocChannel(*config, pp_feature, NULL, NULL); 4097 4098 if (pChannel == NULL) { 4099 ALOGE("%s: fail to add offline reprocess channel", __func__); 4100 imgBuf->deallocate(); 4101 delete imgBuf; 4102 return UNKNOWN_ERROR; 4103 } 4104 4105 rc = pChannel->start(); 4106 if (rc != NO_ERROR) { 4107 ALOGE("%s: Cannot start reprocess channel", __func__); 4108 imgBuf->deallocate(); 4109 delete imgBuf; 4110 delete pChannel; 4111 return rc; 4112 } 4113 4114 ssize_t bufSize = imgBuf->getSize(0); 4115 if (BAD_INDEX != bufSize) { 4116 rc = pChannel->doReprocess(imgBuf->getFd(0), (size_t)bufSize, faceID); 4117 } else { 4118 ALOGE("Failed to retrieve buffer size (bad index)"); 4119 return UNKNOWN_ERROR; 4120 } 4121 4122 // done with register face image, free imgbuf and delete reprocess channel 4123 imgBuf->deallocate(); 4124 delete imgBuf; 4125 imgBuf = NULL; 4126 pChannel->stop(); 4127 delete pChannel; 4128 pChannel = NULL; 4129 4130 return rc; 4131 } 4132 4133 /*=========================================================================== 4134 * FUNCTION : release 4135 * 4136 * DESCRIPTION: release camera resource impl 4137 * 4138 * PARAMETERS : none 4139 * 4140 * RETURN : int32_t type of status 4141 * NO_ERROR -- success 4142 * none-zero failure code 4143 *==========================================================================*/ 4144 int QCamera2HardwareInterface::release() 4145 { 4146 // stop and delete all channels 4147 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) { 4148 if (m_channels[i] != NULL) { 4149 stopChannel((qcamera_ch_type_enum_t)i); 4150 delChannel((qcamera_ch_type_enum_t)i); 4151 } 4152 } 4153 4154 return NO_ERROR; 4155 } 4156 4157 /*=========================================================================== 4158 * FUNCTION : dump 4159 * 4160 * DESCRIPTION: camera status dump impl 4161 * 4162 * PARAMETERS : 4163 * @fd : fd for the buffer to be dumped with camera status 4164 * 4165 * RETURN : int32_t type of status 4166 * NO_ERROR -- success 4167 * none-zero failure code 4168 *==========================================================================*/ 4169 int QCamera2HardwareInterface::dump(int fd) 4170 { 4171 dprintf(fd, "\n Camera HAL information Begin \n"); 4172 dprintf(fd, "Camera ID: %d \n", mCameraId); 4173 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame); 4174 dprintf(fd, "\n Configuration: %s", mParameters.dump().string()); 4175 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string()); 4176 dprintf(fd, "\n Camera HAL information End \n"); 4177 4178 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the 4179 debug level property */ 4180 mParameters.updateDebugLevel(); 4181 return NO_ERROR; 4182 } 4183 4184 /*=========================================================================== 4185 * FUNCTION : processAPI 4186 * 4187 * DESCRIPTION: process API calls from upper layer 4188 * 4189 * PARAMETERS : 4190 * @api : API to be processed 4191 * @api_payload : ptr to API payload if any 4192 * 4193 * RETURN : int32_t type of status 4194 * NO_ERROR -- success 4195 * none-zero failure code 4196 *==========================================================================*/ 4197 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload) 4198 { 4199 int ret = DEAD_OBJECT; 4200 4201 if (m_smThreadActive) { 4202 ret = m_stateMachine.procAPI(api, api_payload); 4203 } 4204 4205 return ret; 4206 } 4207 4208 /*=========================================================================== 4209 * FUNCTION : processEvt 4210 * 4211 * DESCRIPTION: process Evt from backend via mm-camera-interface 4212 * 4213 * PARAMETERS : 4214 * @evt : event type to be processed 4215 * @evt_payload : ptr to event payload if any 4216 * 4217 * RETURN : int32_t type of status 4218 * NO_ERROR -- success 4219 * none-zero failure code 4220 *==========================================================================*/ 4221 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 4222 { 4223 return m_stateMachine.procEvt(evt, evt_payload); 4224 } 4225 4226 /*=========================================================================== 4227 * FUNCTION : processSyncEvt 4228 * 4229 * DESCRIPTION: process synchronous Evt from backend 4230 * 4231 * PARAMETERS : 4232 * @evt : event type to be processed 4233 * @evt_payload : ptr to event payload if any 4234 * 4235 * RETURN : int32_t type of status 4236 * NO_ERROR -- success 4237 * none-zero failure code 4238 *==========================================================================*/ 4239 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload) 4240 { 4241 int rc = NO_ERROR; 4242 4243 pthread_mutex_lock(&m_evtLock); 4244 rc = processEvt(evt, evt_payload); 4245 if (rc == NO_ERROR) { 4246 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t)); 4247 while (m_evtResult.request_api != evt) { 4248 pthread_cond_wait(&m_evtCond, &m_evtLock); 4249 } 4250 rc = m_evtResult.status; 4251 } 4252 pthread_mutex_unlock(&m_evtLock); 4253 4254 return rc; 4255 } 4256 4257 /*=========================================================================== 4258 * FUNCTION : evtHandle 4259 * 4260 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events 4261 * 4262 * PARAMETERS : 4263 * @camera_handle : event type to be processed 4264 * @evt : ptr to event 4265 * @user_data : user data ptr 4266 * 4267 * RETURN : none 4268 *==========================================================================*/ 4269 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/, 4270 mm_camera_event_t *evt, 4271 void *user_data) 4272 { 4273 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data; 4274 if (obj && evt) { 4275 mm_camera_event_t *payload = 4276 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t)); 4277 if (NULL != payload) { 4278 *payload = *evt; 4279 //peek into the event, if this is an eztune event from server, 4280 //then we don't need to post it to the SM Qs, we shud directly 4281 //spawn a thread and get the job done (jpeg or raw snapshot) 4282 switch (payload->server_event_type) { 4283 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 4284 //Received JPEG trigger from eztune 4285 if (false == obj->m_bIntJpegEvtPending) { 4286 pthread_mutex_lock(&obj->m_int_lock); 4287 obj->m_bIntJpegEvtPending = true; 4288 pthread_mutex_unlock(&obj->m_int_lock); 4289 obj->takePictureInternal(); 4290 } 4291 free(payload); 4292 break; 4293 case CAM_EVENT_TYPE_INT_TAKE_RAW: 4294 //Received RAW trigger from eztune 4295 if (false == obj->m_bIntRawEvtPending) { 4296 pthread_mutex_lock(&obj->m_int_lock); 4297 obj->m_bIntRawEvtPending = true; 4298 pthread_mutex_unlock(&obj->m_int_lock); 4299 obj->takePictureInternal(); 4300 } 4301 free(payload); 4302 break; 4303 case CAM_EVENT_TYPE_DAEMON_DIED: 4304 { 4305 Mutex::Autolock l(obj->mDeffLock); 4306 obj->mDeffCond.broadcast(); 4307 CDBG_HIGH("%s: broadcast mDeffCond signal\n", __func__); 4308 } 4309 default: 4310 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload); 4311 break; 4312 } 4313 } 4314 } else { 4315 ALOGE("%s: NULL user_data", __func__); 4316 } 4317 } 4318 4319 /*=========================================================================== 4320 * FUNCTION : jpegEvtHandle 4321 * 4322 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events 4323 * 4324 * PARAMETERS : 4325 * @status : status of jpeg job 4326 * @client_hdl: jpeg client handle 4327 * @jobId : jpeg job Id 4328 * @p_ouput : ptr to jpeg output result struct 4329 * @userdata : user data ptr 4330 * 4331 * RETURN : none 4332 *==========================================================================*/ 4333 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status, 4334 uint32_t /*client_hdl*/, 4335 uint32_t jobId, 4336 mm_jpeg_output_t *p_output, 4337 void *userdata) 4338 { 4339 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata; 4340 if (obj) { 4341 qcamera_jpeg_evt_payload_t *payload = 4342 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t)); 4343 if (NULL != payload) { 4344 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t)); 4345 payload->status = status; 4346 payload->jobId = jobId; 4347 if (p_output != NULL) { 4348 payload->out_data = *p_output; 4349 } 4350 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload); 4351 } 4352 } else { 4353 ALOGE("%s: NULL user_data", __func__); 4354 } 4355 } 4356 4357 /*=========================================================================== 4358 * FUNCTION : thermalEvtHandle 4359 * 4360 * DESCRIPTION: routine to handle thermal event notification 4361 * 4362 * PARAMETERS : 4363 * @level : thermal level 4364 * @userdata : userdata passed in during registration 4365 * @data : opaque data from thermal client 4366 * 4367 * RETURN : int32_t type of status 4368 * NO_ERROR -- success 4369 * none-zero failure code 4370 *==========================================================================*/ 4371 int QCamera2HardwareInterface::thermalEvtHandle( 4372 qcamera_thermal_level_enum_t *level, void *userdata, void *data) 4373 { 4374 if (!mCameraOpened) { 4375 CDBG_HIGH("%s: Camera is not opened, no need to handle thermal evt", __func__); 4376 return NO_ERROR; 4377 } 4378 4379 // Make sure thermal events are logged 4380 CDBG_HIGH("%s: level = %d, userdata = %p, data = %p", 4381 __func__, *level, userdata, data); 4382 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY 4383 // becomes an aync call. This also means we can only pass payload 4384 // by value, not by address. 4385 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level); 4386 } 4387 4388 /*=========================================================================== 4389 * FUNCTION : sendEvtNotify 4390 * 4391 * DESCRIPTION: send event notify to notify thread 4392 * 4393 * PARAMETERS : 4394 * @msg_type: msg type to be sent 4395 * @ext1 : optional extension1 4396 * @ext2 : optional extension2 4397 * 4398 * RETURN : int32_t type of status 4399 * NO_ERROR -- success 4400 * none-zero failure code 4401 *==========================================================================*/ 4402 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type, 4403 int32_t ext1, 4404 int32_t ext2) 4405 { 4406 qcamera_callback_argm_t cbArg; 4407 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 4408 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 4409 cbArg.msg_type = msg_type; 4410 cbArg.ext1 = ext1; 4411 cbArg.ext2 = ext2; 4412 return m_cbNotifier.notifyCallback(cbArg); 4413 } 4414 4415 /*=========================================================================== 4416 * FUNCTION : processAEInfo 4417 * 4418 * DESCRIPTION: process AE updates 4419 * 4420 * PARAMETERS : 4421 * @ae_params: current AE parameters 4422 * 4423 * RETURN : None 4424 *==========================================================================*/ 4425 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params) 4426 { 4427 pthread_mutex_lock(&m_parm_lock); 4428 mParameters.updateAEInfo(ae_params); 4429 pthread_mutex_unlock(&m_parm_lock); 4430 return NO_ERROR; 4431 } 4432 4433 /*=========================================================================== 4434 * FUNCTION : processFocusPositionInfo 4435 * 4436 * DESCRIPTION: process AF updates 4437 * 4438 * PARAMETERS : 4439 * @cur_pos_info: current lens position 4440 * 4441 * RETURN : None 4442 *==========================================================================*/ 4443 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info) 4444 { 4445 pthread_mutex_lock(&m_parm_lock); 4446 mParameters.updateCurrentFocusPosition(cur_pos_info); 4447 pthread_mutex_unlock(&m_parm_lock); 4448 return NO_ERROR; 4449 } 4450 4451 /*=========================================================================== 4452 * FUNCTION : processAutoFocusEvent 4453 * 4454 * DESCRIPTION: process auto focus event 4455 * 4456 * PARAMETERS : 4457 * @focus_data: struct containing auto focus result info 4458 * 4459 * RETURN : int32_t type of status 4460 * NO_ERROR -- success 4461 * none-zero failure code 4462 *==========================================================================*/ 4463 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data) 4464 { 4465 int32_t ret = NO_ERROR; 4466 CDBG_HIGH("%s: E",__func__); 4467 4468 m_currentFocusState = focus_data.focus_state; 4469 4470 cam_focus_mode_type focusMode = mParameters.getFocusMode(); 4471 switch (focusMode) { 4472 case CAM_FOCUS_MODE_AUTO: 4473 case CAM_FOCUS_MODE_MACRO: 4474 if (getCancelAutoFocus()) { 4475 // auto focus has canceled, just ignore it 4476 break; 4477 } 4478 // If the HAL focus mode is AUTO and AF focus mode is INFINITY, send event to app 4479 if ((focusMode == CAM_FOCUS_MODE_AUTO) && 4480 (focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 4481 (focus_data.focus_state == CAM_AF_INACTIVE)) { 4482 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0); 4483 break; 4484 } 4485 if (focus_data.focus_state == CAM_AF_SCANNING || 4486 focus_data.focus_state == CAM_AF_INACTIVE) { 4487 // in the middle of focusing, just ignore it 4488 break; 4489 } 4490 // update focus distance 4491 mParameters.updateFocusDistances(&focus_data.focus_dist); 4492 4493 if ((CAM_AF_FOCUSED == focus_data.focus_state) && 4494 mParameters.isZSLMode()) { 4495 QCameraPicChannel *pZSLChannel = 4496 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 4497 if (NULL != pZSLChannel) { 4498 //flush the zsl-buffer 4499 uint32_t flush_frame_idx = focus_data.focused_frame_idx; 4500 CDBG("%s, flush the zsl-buffer before frame = %u.", __func__, flush_frame_idx); 4501 pZSLChannel->flushSuperbuffer(flush_frame_idx); 4502 } 4503 } 4504 4505 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 4506 (focus_data.focus_state == CAM_AF_FOCUSED)? true : false, 4507 0); 4508 break; 4509 case CAM_FOCUS_MODE_CONTINOUS_VIDEO: 4510 case CAM_FOCUS_MODE_CONTINOUS_PICTURE: 4511 4512 // If the HAL focus mode is AUTO and AF focus mode is INFINITY, send event to app 4513 if ((focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE) && 4514 (focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) && 4515 (focus_data.focus_state == CAM_AF_INACTIVE)) { 4516 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0); 4517 break; 4518 } 4519 4520 if (focus_data.focus_state == CAM_AF_FOCUSED || 4521 focus_data.focus_state == CAM_AF_NOT_FOCUSED) { 4522 // update focus distance 4523 mParameters.updateFocusDistances(&focus_data.focus_dist); 4524 4525 if ((focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE) && 4526 (CAM_AF_FOCUSED == focus_data.focus_state) && 4527 mParameters.isZSLMode()) { 4528 QCameraPicChannel *pZSLChannel = 4529 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL]; 4530 if (NULL != pZSLChannel) { 4531 //flush the zsl-buffer 4532 uint32_t flush_frame_idx = focus_data.focused_frame_idx; 4533 CDBG("%s, flush the zsl-buffer before frame = %u.", __func__, flush_frame_idx); 4534 pZSLChannel->flushSuperbuffer(flush_frame_idx); 4535 } 4536 } 4537 4538 ret = sendEvtNotify(CAMERA_MSG_FOCUS, 4539 (focus_data.focus_state == CAM_AF_FOCUSED)? true : false, 4540 0); 4541 } 4542 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE, 4543 (focus_data.focus_state == CAM_AF_SCANNING)? true : false, 4544 0); 4545 break; 4546 case CAM_FOCUS_MODE_INFINITY: 4547 case CAM_FOCUS_MODE_FIXED: 4548 case CAM_FOCUS_MODE_EDOF: 4549 default: 4550 CDBG_HIGH("%s: no ops for autofocus event in focusmode %d", __func__, focusMode); 4551 break; 4552 } 4553 4554 CDBG_HIGH("%s: X",__func__); 4555 return ret; 4556 } 4557 4558 /*=========================================================================== 4559 * FUNCTION : processZoomEvent 4560 * 4561 * DESCRIPTION: process zoom event 4562 * 4563 * PARAMETERS : 4564 * @crop_info : crop info as a result of zoom operation 4565 * 4566 * RETURN : int32_t type of status 4567 * NO_ERROR -- success 4568 * none-zero failure code 4569 *==========================================================================*/ 4570 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info) 4571 { 4572 int32_t ret = NO_ERROR; 4573 4574 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 4575 if (m_channels[i] != NULL) { 4576 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info); 4577 } 4578 } 4579 return ret; 4580 } 4581 4582 /*=========================================================================== 4583 * FUNCTION : processZSLCaptureDone 4584 * 4585 * DESCRIPTION: process ZSL capture done events 4586 * 4587 * PARAMETERS : None 4588 * 4589 * RETURN : int32_t type of status 4590 * NO_ERROR -- success 4591 * none-zero failure code 4592 *==========================================================================*/ 4593 int32_t QCamera2HardwareInterface::processZSLCaptureDone() 4594 { 4595 int rc = NO_ERROR; 4596 4597 pthread_mutex_lock(&m_parm_lock); 4598 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) { 4599 rc = unconfigureAdvancedCapture(); 4600 } 4601 pthread_mutex_unlock(&m_parm_lock); 4602 4603 return rc; 4604 } 4605 4606 /*=========================================================================== 4607 * FUNCTION : processRetroAECUnlock 4608 * 4609 * DESCRIPTION: process retro burst AEC unlock events 4610 * 4611 * PARAMETERS : None 4612 * 4613 * RETURN : int32_t type of status 4614 * NO_ERROR -- success 4615 * none-zero failure code 4616 *==========================================================================*/ 4617 int32_t QCamera2HardwareInterface::processRetroAECUnlock() 4618 { 4619 int rc = NO_ERROR; 4620 4621 CDBG_HIGH("%s : [ZSL Retro] LED assisted AF Release AEC Lock", __func__); 4622 pthread_mutex_lock(&m_parm_lock); 4623 rc = mParameters.setAecLock("false"); 4624 if (NO_ERROR != rc) { 4625 ALOGE("%s: Error setting AEC lock", __func__); 4626 pthread_mutex_unlock(&m_parm_lock); 4627 return rc; 4628 } 4629 4630 rc = mParameters.commitParameters(); 4631 if (NO_ERROR != rc) { 4632 ALOGE("%s: Error during camera parameter commit", __func__); 4633 } else { 4634 m_bLedAfAecLock = FALSE; 4635 } 4636 4637 pthread_mutex_unlock(&m_parm_lock); 4638 4639 return rc; 4640 } 4641 4642 /*=========================================================================== 4643 * FUNCTION : processHDRData 4644 * 4645 * DESCRIPTION: process HDR scene events 4646 * 4647 * PARAMETERS : 4648 * @hdr_scene : HDR scene event data 4649 * 4650 * RETURN : int32_t type of status 4651 * NO_ERROR -- success 4652 * none-zero failure code 4653 *==========================================================================*/ 4654 int32_t QCamera2HardwareInterface::processHDRData(cam_asd_hdr_scene_data_t hdr_scene) 4655 { 4656 int rc = NO_ERROR; 4657 4658 #ifndef VANILLA_HAL 4659 if (hdr_scene.is_hdr_scene && 4660 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) && 4661 mParameters.isAutoHDREnabled()) { 4662 m_HDRSceneEnabled = true; 4663 } else { 4664 m_HDRSceneEnabled = false; 4665 } 4666 pthread_mutex_lock(&m_parm_lock); 4667 mParameters.setHDRSceneEnable(m_HDRSceneEnabled); 4668 pthread_mutex_unlock(&m_parm_lock); 4669 4670 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) { 4671 4672 size_t data_len = sizeof(int); 4673 size_t buffer_len = 1 *sizeof(int) //meta type 4674 + 1 *sizeof(int) //data len 4675 + 1 *sizeof(int); //data 4676 camera_memory_t *hdrBuffer = mGetMemory(-1, 4677 buffer_len, 4678 1, 4679 mCallbackCookie); 4680 if ( NULL == hdrBuffer ) { 4681 ALOGE("%s: Not enough memory for auto HDR data", 4682 __func__); 4683 return NO_MEMORY; 4684 } 4685 4686 int *pHDRData = (int *)hdrBuffer->data; 4687 if (pHDRData == NULL) { 4688 ALOGE("%s: memory data ptr is NULL", __func__); 4689 return UNKNOWN_ERROR; 4690 } 4691 4692 pHDRData[0] = CAMERA_META_DATA_HDR; 4693 pHDRData[1] = (int)data_len; 4694 pHDRData[2] = m_HDRSceneEnabled; 4695 4696 qcamera_callback_argm_t cbArg; 4697 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 4698 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 4699 cbArg.msg_type = CAMERA_MSG_META_DATA; 4700 cbArg.data = hdrBuffer; 4701 cbArg.user_data = hdrBuffer; 4702 cbArg.cookie = this; 4703 cbArg.release_cb = releaseCameraMemory; 4704 rc = m_cbNotifier.notifyCallback(cbArg); 4705 if (rc != NO_ERROR) { 4706 ALOGE("%s: fail sending auto HDR notification", __func__); 4707 hdrBuffer->release(hdrBuffer); 4708 } 4709 } 4710 4711 CDBG_HIGH("%s : hdr_scene_data: processHDRData: %d %f", 4712 __func__, 4713 hdr_scene.is_hdr_scene, 4714 hdr_scene.hdr_confidence); 4715 4716 #endif 4717 return rc; 4718 } 4719 4720 /*=========================================================================== 4721 * FUNCTION : transAwbMetaToParams 4722 * 4723 * DESCRIPTION: translate awb params from metadata callback to QCameraParameters 4724 * 4725 * PARAMETERS : 4726 * @awb_params : awb params from metadata callback 4727 * 4728 * RETURN : int32_t type of status 4729 * NO_ERROR -- success 4730 * none-zero failure code 4731 *==========================================================================*/ 4732 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params) 4733 { 4734 pthread_mutex_lock(&m_parm_lock); 4735 mParameters.updateAWBParams(awb_params); 4736 pthread_mutex_unlock(&m_parm_lock); 4737 return NO_ERROR; 4738 } 4739 4740 /*=========================================================================== 4741 * FUNCTION : processPrepSnapshotDone 4742 * 4743 * DESCRIPTION: process prep snapshot done event 4744 * 4745 * PARAMETERS : 4746 * @prep_snapshot_state : state of prepare snapshot done. In other words, 4747 * i.e. whether need future frames for capture. 4748 * 4749 * RETURN : int32_t type of status 4750 * NO_ERROR -- success 4751 * none-zero failure code 4752 *==========================================================================*/ 4753 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent( 4754 cam_prep_snapshot_state_t prep_snapshot_state) 4755 { 4756 int32_t ret = NO_ERROR; 4757 4758 if (m_channels[QCAMERA_CH_TYPE_ZSL] && 4759 prep_snapshot_state == NEED_FUTURE_FRAME) { 4760 CDBG_HIGH("%s: already handled in mm-camera-intf, no ops here", __func__); 4761 if (isRetroPicture()) { 4762 mParameters.setAecLock("true"); 4763 mParameters.commitParameters(); 4764 m_bLedAfAecLock = TRUE; 4765 } 4766 } 4767 return ret; 4768 } 4769 4770 /*=========================================================================== 4771 * FUNCTION : processASDUpdate 4772 * 4773 * DESCRIPTION: process ASD update event 4774 * 4775 * PARAMETERS : 4776 * @scene: selected scene mode 4777 * 4778 * RETURN : int32_t type of status 4779 * NO_ERROR -- success 4780 * none-zero failure code 4781 *==========================================================================*/ 4782 int32_t QCamera2HardwareInterface::processASDUpdate(cam_auto_scene_t scene) 4783 { 4784 //set ASD parameter 4785 mParameters.set(QCameraParameters::KEY_SELECTED_AUTO_SCENE, mParameters.getASDStateString(scene)); 4786 4787 size_t data_len = sizeof(cam_auto_scene_t); 4788 size_t buffer_len = 1 *sizeof(int) //meta type 4789 + 1 *sizeof(int) //data len 4790 + data_len; //data 4791 camera_memory_t *asdBuffer = mGetMemory(-1, 4792 buffer_len, 4793 1, 4794 mCallbackCookie); 4795 if ( NULL == asdBuffer ) { 4796 ALOGE("%s: Not enough memory for histogram data", __func__); 4797 return NO_MEMORY; 4798 } 4799 4800 int *pASDData = (int *)asdBuffer->data; 4801 if (pASDData == NULL) { 4802 ALOGE("%s: memory data ptr is NULL", __func__); 4803 return UNKNOWN_ERROR; 4804 } 4805 4806 #ifndef VANILLA_HAL 4807 pASDData[0] = CAMERA_META_DATA_ASD; 4808 pASDData[1] = (int)data_len; 4809 pASDData[2] = scene; 4810 4811 qcamera_callback_argm_t cbArg; 4812 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 4813 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 4814 cbArg.msg_type = CAMERA_MSG_META_DATA; 4815 cbArg.data = asdBuffer; 4816 cbArg.user_data = asdBuffer; 4817 cbArg.cookie = this; 4818 cbArg.release_cb = releaseCameraMemory; 4819 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 4820 if (rc != NO_ERROR) { 4821 ALOGE("%s: fail sending notification", __func__); 4822 asdBuffer->release(asdBuffer); 4823 } 4824 #endif 4825 return NO_ERROR; 4826 4827 } 4828 4829 /*=========================================================================== 4830 * FUNCTION : processJpegNotify 4831 * 4832 * DESCRIPTION: process jpeg event 4833 * 4834 * PARAMETERS : 4835 * @jpeg_evt: ptr to jpeg event payload 4836 * 4837 * RETURN : int32_t type of status 4838 * NO_ERROR -- success 4839 * none-zero failure code 4840 *==========================================================================*/ 4841 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt) 4842 { 4843 return m_postprocessor.processJpegEvt(jpeg_evt); 4844 } 4845 4846 /*=========================================================================== 4847 * FUNCTION : lockAPI 4848 * 4849 * DESCRIPTION: lock to process API 4850 * 4851 * PARAMETERS : none 4852 * 4853 * RETURN : none 4854 *==========================================================================*/ 4855 void QCamera2HardwareInterface::lockAPI() 4856 { 4857 pthread_mutex_lock(&m_lock); 4858 } 4859 4860 /*=========================================================================== 4861 * FUNCTION : waitAPIResult 4862 * 4863 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will 4864 * return only cerntain API event type arrives 4865 * 4866 * PARAMETERS : 4867 * @api_evt : API event type 4868 * 4869 * RETURN : none 4870 *==========================================================================*/ 4871 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt, 4872 qcamera_api_result_t *apiResult) 4873 { 4874 CDBG("%s: wait for API result of evt (%d)", __func__, api_evt); 4875 int resultReceived = 0; 4876 while (!resultReceived) { 4877 pthread_cond_wait(&m_cond, &m_lock); 4878 if (m_apiResultList != NULL) { 4879 api_result_list *apiResultList = m_apiResultList; 4880 api_result_list *apiResultListPrevious = m_apiResultList; 4881 while (apiResultList != NULL) { 4882 if (apiResultList->result.request_api == api_evt) { 4883 resultReceived = 1; 4884 *apiResult = apiResultList->result; 4885 apiResultListPrevious->next = apiResultList->next; 4886 if (apiResultList == m_apiResultList) { 4887 m_apiResultList = apiResultList->next; 4888 } 4889 free(apiResultList); 4890 break; 4891 } 4892 else { 4893 apiResultListPrevious = apiResultList; 4894 apiResultList = apiResultList->next; 4895 } 4896 } 4897 } 4898 } 4899 CDBG("%s: return (%d) from API result wait for evt (%d)", 4900 __func__, apiResult->status, api_evt); 4901 } 4902 4903 4904 /*=========================================================================== 4905 * FUNCTION : unlockAPI 4906 * 4907 * DESCRIPTION: API processing is done, unlock 4908 * 4909 * PARAMETERS : none 4910 * 4911 * RETURN : none 4912 *==========================================================================*/ 4913 void QCamera2HardwareInterface::unlockAPI() 4914 { 4915 pthread_mutex_unlock(&m_lock); 4916 } 4917 4918 /*=========================================================================== 4919 * FUNCTION : signalAPIResult 4920 * 4921 * DESCRIPTION: signal condition viarable that cerntain API event type arrives 4922 * 4923 * PARAMETERS : 4924 * @result : API result 4925 * 4926 * RETURN : none 4927 *==========================================================================*/ 4928 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result) 4929 { 4930 4931 pthread_mutex_lock(&m_lock); 4932 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list)); 4933 if (apiResult == NULL) { 4934 ALOGE("%s: ERROR: malloc for api result failed", __func__); 4935 ALOGE("%s: ERROR: api thread will wait forever fot this lost result", __func__); 4936 goto malloc_failed; 4937 } 4938 apiResult->result = *result; 4939 apiResult->next = NULL; 4940 if (m_apiResultList == NULL) m_apiResultList = apiResult; 4941 else { 4942 api_result_list *apiResultList = m_apiResultList; 4943 while(apiResultList->next != NULL) apiResultList = apiResultList->next; 4944 apiResultList->next = apiResult; 4945 } 4946 malloc_failed: 4947 pthread_cond_broadcast(&m_cond); 4948 pthread_mutex_unlock(&m_lock); 4949 } 4950 4951 /*=========================================================================== 4952 * FUNCTION : signalEvtResult 4953 * 4954 * DESCRIPTION: signal condition variable that certain event was processed 4955 * 4956 * PARAMETERS : 4957 * @result : Event result 4958 * 4959 * RETURN : none 4960 *==========================================================================*/ 4961 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result) 4962 { 4963 pthread_mutex_lock(&m_evtLock); 4964 m_evtResult = *result; 4965 pthread_cond_signal(&m_evtCond); 4966 pthread_mutex_unlock(&m_evtLock); 4967 } 4968 4969 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel) 4970 { 4971 int32_t rc = NO_ERROR; 4972 cam_dimension_t str_dim,max_dim; 4973 QCameraChannel *pChannel; 4974 4975 max_dim.width = 0; 4976 max_dim.height = 0; 4977 4978 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) { 4979 if (m_channels[j] != NULL) { 4980 pChannel = m_channels[j]; 4981 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) { 4982 QCameraStream *pStream = pChannel->getStreamByIndex(i); 4983 if (pStream != NULL) { 4984 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 4985 continue; 4986 } 4987 pStream->getFrameDimension(str_dim); 4988 if (str_dim.width > max_dim.width) { 4989 max_dim.width = str_dim.width; 4990 } 4991 if (str_dim.height > max_dim.height) { 4992 max_dim.height = str_dim.height; 4993 } 4994 } 4995 } 4996 } 4997 } 4998 4999 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) { 5000 QCameraStream *pStream = curChannel->getStreamByIndex(i); 5001 if (pStream != NULL) { 5002 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 5003 continue; 5004 } 5005 pStream->getFrameDimension(str_dim); 5006 if (str_dim.width > max_dim.width) { 5007 max_dim.width = str_dim.width; 5008 } 5009 if (str_dim.height > max_dim.height) { 5010 max_dim.height = str_dim.height; 5011 } 5012 } 5013 } 5014 rc = mParameters.updateRAW(max_dim); 5015 return rc; 5016 } 5017 /*=========================================================================== 5018 * FUNCTION : addStreamToChannel 5019 * 5020 * DESCRIPTION: add a stream into a channel 5021 * 5022 * PARAMETERS : 5023 * @pChannel : ptr to channel obj 5024 * @streamType : type of stream to be added 5025 * @streamCB : callback of stream 5026 * @userData : user data ptr to callback 5027 * 5028 * RETURN : int32_t type of status 5029 * NO_ERROR -- success 5030 * none-zero failure code 5031 *==========================================================================*/ 5032 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel, 5033 cam_stream_type_t streamType, 5034 stream_cb_routine streamCB, 5035 void *userData) 5036 { 5037 int32_t rc = NO_ERROR; 5038 5039 if (streamType == CAM_STREAM_TYPE_RAW) { 5040 prepareRawStream(pChannel); 5041 } 5042 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType); 5043 if (pStreamInfo == NULL) { 5044 ALOGE("%s: no mem for stream info buf", __func__); 5045 return NO_MEMORY; 5046 } 5047 uint8_t minStreamBufNum = getBufNumRequired(streamType); 5048 bool bDynAllocBuf = false; 5049 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) { 5050 bDynAllocBuf = true; 5051 } 5052 5053 if ( ( streamType == CAM_STREAM_TYPE_SNAPSHOT || 5054 streamType == CAM_STREAM_TYPE_POSTVIEW || 5055 streamType == CAM_STREAM_TYPE_METADATA || 5056 streamType == CAM_STREAM_TYPE_RAW) && 5057 !isZSLMode() && 5058 !isLongshotEnabled() && 5059 !mParameters.getRecordingHintValue() && 5060 !mParameters.isSecureMode()) { 5061 rc = pChannel->addStream(*this, 5062 pStreamInfo, 5063 NULL, 5064 minStreamBufNum, 5065 &gCamCaps[mCameraId]->padding_info, 5066 streamCB, userData, 5067 bDynAllocBuf, 5068 true); 5069 5070 // Queue buffer allocation for Snapshot and Metadata streams 5071 if ( !rc ) { 5072 DefferWorkArgs args; 5073 DefferAllocBuffArgs allocArgs; 5074 5075 memset(&args, 0, sizeof(DefferWorkArgs)); 5076 memset(&allocArgs, 0, sizeof(DefferAllocBuffArgs)); 5077 allocArgs.type = streamType; 5078 allocArgs.ch = pChannel; 5079 args.allocArgs = allocArgs; 5080 5081 if (streamType == CAM_STREAM_TYPE_SNAPSHOT) { 5082 mSnapshotJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF, 5083 args); 5084 5085 if ( mSnapshotJob == -1) { 5086 rc = UNKNOWN_ERROR; 5087 } 5088 } else if (streamType == CAM_STREAM_TYPE_METADATA) { 5089 mMetadataJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF, 5090 args); 5091 5092 if ( mMetadataJob == -1) { 5093 rc = UNKNOWN_ERROR; 5094 } 5095 } else if (streamType == CAM_STREAM_TYPE_RAW) { 5096 mRawdataJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF, 5097 args); 5098 5099 if ( mRawdataJob == -1) { 5100 rc = UNKNOWN_ERROR; 5101 } 5102 } 5103 } 5104 } else if (streamType == CAM_STREAM_TYPE_ANALYSIS) { 5105 rc = pChannel->addStream(*this, 5106 pStreamInfo, 5107 NULL, 5108 minStreamBufNum, 5109 &gCamCaps[mCameraId]->analysis_padding_info, 5110 streamCB, userData, 5111 bDynAllocBuf, 5112 false); 5113 } else { 5114 rc = pChannel->addStream(*this, 5115 pStreamInfo, 5116 NULL, 5117 minStreamBufNum, 5118 &gCamCaps[mCameraId]->padding_info, 5119 streamCB, userData, 5120 bDynAllocBuf, 5121 false); 5122 } 5123 5124 if (rc != NO_ERROR) { 5125 ALOGE("%s: add stream type (%d) failed, ret = %d", 5126 __func__, streamType, rc); 5127 } 5128 5129 return rc; 5130 } 5131 5132 /*=========================================================================== 5133 * FUNCTION : addPreviewChannel 5134 * 5135 * DESCRIPTION: add a preview channel that contains a preview stream 5136 * 5137 * PARAMETERS : none 5138 * 5139 * RETURN : int32_t type of status 5140 * NO_ERROR -- success 5141 * none-zero failure code 5142 *==========================================================================*/ 5143 int32_t QCamera2HardwareInterface::addPreviewChannel() 5144 { 5145 int32_t rc = NO_ERROR; 5146 QCameraChannel *pChannel = NULL; 5147 5148 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { 5149 // if we had preview channel before, delete it first 5150 delete m_channels[QCAMERA_CH_TYPE_PREVIEW]; 5151 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL; 5152 } 5153 5154 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5155 mCameraHandle->ops); 5156 if (NULL == pChannel) { 5157 ALOGE("%s: no mem for preview channel", __func__); 5158 return NO_MEMORY; 5159 } 5160 5161 // preview only channel, don't need bundle attr and cb 5162 rc = pChannel->init(NULL, NULL, NULL); 5163 if (rc != NO_ERROR) { 5164 ALOGE("%s: init preview channel failed, ret = %d", __func__, rc); 5165 return rc; 5166 } 5167 5168 // meta data stream always coexists with preview if applicable 5169 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5170 metadata_stream_cb_routine, this); 5171 if (rc != NO_ERROR) { 5172 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5173 return rc; 5174 } 5175 5176 if (mParameters.getRecordingHintValue() != true && !mParameters.isSecureMode()) { 5177 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 5178 NULL, this); 5179 if (rc != NO_ERROR) { 5180 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc); 5181 return rc; 5182 } 5183 } 5184 5185 if (isRdiMode()) { 5186 CDBG_HIGH("RDI_DEBUG %s[%d]: Add stream to channel", __func__, __LINE__); 5187 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 5188 rdi_mode_stream_cb_routine, this); 5189 } else { 5190 if (isNoDisplayMode()) { 5191 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5192 nodisplay_preview_stream_cb_routine, this); 5193 } else { 5194 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5195 preview_stream_cb_routine, this); 5196 } 5197 } 5198 5199 if (rc != NO_ERROR) { 5200 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc); 5201 delete pChannel; 5202 return rc; 5203 } 5204 5205 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel; 5206 return rc; 5207 } 5208 5209 /*=========================================================================== 5210 * FUNCTION : addVideoChannel 5211 * 5212 * DESCRIPTION: add a video channel that contains a video stream 5213 * 5214 * PARAMETERS : none 5215 * 5216 * RETURN : int32_t type of status 5217 * NO_ERROR -- success 5218 * none-zero failure code 5219 *==========================================================================*/ 5220 int32_t QCamera2HardwareInterface::addVideoChannel() 5221 { 5222 int32_t rc = NO_ERROR; 5223 QCameraVideoChannel *pChannel = NULL; 5224 5225 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) { 5226 // if we had video channel before, delete it first 5227 delete m_channels[QCAMERA_CH_TYPE_VIDEO]; 5228 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL; 5229 } 5230 5231 pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle, 5232 mCameraHandle->ops); 5233 if (NULL == pChannel) { 5234 ALOGE("%s: no mem for video channel", __func__); 5235 return NO_MEMORY; 5236 } 5237 5238 // preview only channel, don't need bundle attr and cb 5239 rc = pChannel->init(NULL, NULL, NULL); 5240 if (rc != 0) { 5241 ALOGE("%s: init video channel failed, ret = %d", __func__, rc); 5242 delete pChannel; 5243 return rc; 5244 } 5245 5246 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO, 5247 video_stream_cb_routine, this); 5248 if (rc != NO_ERROR) { 5249 ALOGE("%s: add video stream failed, ret = %d", __func__, rc); 5250 delete pChannel; 5251 return rc; 5252 } 5253 5254 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel; 5255 return rc; 5256 } 5257 5258 /*=========================================================================== 5259 * FUNCTION : addSnapshotChannel 5260 * 5261 * DESCRIPTION: add a snapshot channel that contains a snapshot stream 5262 * 5263 * PARAMETERS : none 5264 * 5265 * RETURN : int32_t type of status 5266 * NO_ERROR -- success 5267 * none-zero failure code 5268 * NOTE : Add this channel for live snapshot usecase. Regular capture will 5269 * use addCaptureChannel. 5270 *==========================================================================*/ 5271 int32_t QCamera2HardwareInterface::addSnapshotChannel() 5272 { 5273 int32_t rc = NO_ERROR; 5274 QCameraChannel *pChannel = NULL; 5275 5276 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) { 5277 // if we had ZSL channel before, delete it first 5278 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 5279 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL; 5280 } 5281 5282 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5283 mCameraHandle->ops); 5284 if (NULL == pChannel) { 5285 ALOGE("%s: no mem for snapshot channel", __func__); 5286 return NO_MEMORY; 5287 } 5288 5289 mm_camera_channel_attr_t attr; 5290 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 5291 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 5292 attr.look_back = mParameters.getZSLBackLookCount(); 5293 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 5294 attr.water_mark = mParameters.getZSLQueueDepth(); 5295 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 5296 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW; 5297 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this); 5298 if (rc != NO_ERROR) { 5299 ALOGE("%s: init snapshot channel failed, ret = %d", __func__, rc); 5300 delete pChannel; 5301 return rc; 5302 } 5303 5304 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 5305 NULL, NULL); 5306 if (rc != NO_ERROR) { 5307 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc); 5308 delete pChannel; 5309 return rc; 5310 } 5311 5312 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel; 5313 return rc; 5314 } 5315 5316 /*=========================================================================== 5317 * FUNCTION : addRawChannel 5318 * 5319 * DESCRIPTION: add a raw channel that contains a raw image stream 5320 * 5321 * PARAMETERS : none 5322 * 5323 * RETURN : int32_t type of status 5324 * NO_ERROR -- success 5325 * none-zero failure code 5326 *==========================================================================*/ 5327 int32_t QCamera2HardwareInterface::addRawChannel() 5328 { 5329 int32_t rc = NO_ERROR; 5330 QCameraChannel *pChannel = NULL; 5331 5332 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) { 5333 // if we had raw channel before, delete it first 5334 delete m_channels[QCAMERA_CH_TYPE_RAW]; 5335 m_channels[QCAMERA_CH_TYPE_RAW] = NULL; 5336 } 5337 5338 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5339 mCameraHandle->ops); 5340 if (NULL == pChannel) { 5341 ALOGE("%s: no mem for raw channel", __func__); 5342 return NO_MEMORY; 5343 } 5344 5345 rc = pChannel->init(NULL, NULL, NULL); 5346 if (rc != NO_ERROR) { 5347 ALOGE("%s: init raw channel failed, ret = %d", __func__, rc); 5348 delete pChannel; 5349 return rc; 5350 } 5351 5352 // meta data stream always coexists with snapshot in regular RAW capture case 5353 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5354 metadata_stream_cb_routine, this); 5355 if (rc != NO_ERROR) { 5356 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5357 delete pChannel; 5358 return rc; 5359 } 5360 waitDefferedWork(mMetadataJob); 5361 5362 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW, 5363 raw_stream_cb_routine, this); 5364 if (rc != NO_ERROR) { 5365 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc); 5366 delete pChannel; 5367 return rc; 5368 } 5369 waitDefferedWork(mRawdataJob); 5370 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel; 5371 return rc; 5372 } 5373 5374 /*=========================================================================== 5375 * FUNCTION : addZSLChannel 5376 * 5377 * DESCRIPTION: add a ZSL channel that contains a preview stream and 5378 * a snapshot stream 5379 * 5380 * PARAMETERS : none 5381 * 5382 * RETURN : int32_t type of status 5383 * NO_ERROR -- success 5384 * none-zero failure code 5385 *==========================================================================*/ 5386 int32_t QCamera2HardwareInterface::addZSLChannel() 5387 { 5388 int32_t rc = NO_ERROR; 5389 QCameraPicChannel *pChannel = NULL; 5390 char value[PROPERTY_VALUE_MAX]; 5391 bool raw_yuv = false; 5392 5393 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) { 5394 // if we had ZSL channel before, delete it first 5395 delete m_channels[QCAMERA_CH_TYPE_ZSL]; 5396 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL; 5397 } 5398 5399 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle, 5400 mCameraHandle->ops); 5401 if (NULL == pChannel) { 5402 ALOGE("%s: no mem for ZSL channel", __func__); 5403 return NO_MEMORY; 5404 } 5405 5406 // ZSL channel, init with bundle attr and cb 5407 mm_camera_channel_attr_t attr; 5408 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 5409 if (mParameters.isSceneSelectionEnabled()) { 5410 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 5411 } else { 5412 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 5413 } 5414 attr.look_back = mParameters.getZSLBackLookCount(); 5415 attr.post_frame_skip = mParameters.getZSLBurstInterval(); 5416 attr.water_mark = mParameters.getZSLQueueDepth(); 5417 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 5418 rc = pChannel->init(&attr, 5419 zsl_channel_cb, 5420 this); 5421 if (rc != 0) { 5422 ALOGE("%s: init ZSL channel failed, ret = %d", __func__, rc); 5423 delete pChannel; 5424 return rc; 5425 } 5426 5427 // meta data stream always coexists with preview if applicable 5428 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5429 metadata_stream_cb_routine, this); 5430 if (rc != NO_ERROR) { 5431 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5432 delete pChannel; 5433 return rc; 5434 } 5435 5436 if (isNoDisplayMode()) { 5437 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5438 nodisplay_preview_stream_cb_routine, this); 5439 } else { 5440 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5441 preview_stream_cb_routine, this); 5442 } 5443 if (rc != NO_ERROR) { 5444 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc); 5445 delete pChannel; 5446 return rc; 5447 } 5448 5449 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 5450 NULL, this); 5451 if (rc != NO_ERROR) { 5452 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc); 5453 delete pChannel; 5454 return rc; 5455 } 5456 5457 if (!mParameters.isSecureMode()) { 5458 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 5459 NULL, this); 5460 if (rc != NO_ERROR) { 5461 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc); 5462 delete pChannel; 5463 return rc; 5464 } 5465 } 5466 5467 property_get("persist.camera.raw_yuv", value, "0"); 5468 raw_yuv = atoi(value) > 0 ? true : false; 5469 if ( raw_yuv ) { 5470 rc = addStreamToChannel(pChannel, 5471 CAM_STREAM_TYPE_RAW, 5472 NULL, 5473 this); 5474 if (rc != NO_ERROR) { 5475 ALOGE("%s: add raw stream failed, ret = %d", __func__, rc); 5476 delete pChannel; 5477 return rc; 5478 } 5479 } 5480 5481 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel; 5482 return rc; 5483 } 5484 5485 /*=========================================================================== 5486 * FUNCTION : addCaptureChannel 5487 * 5488 * DESCRIPTION: add a capture channel that contains a snapshot stream 5489 * and a postview stream 5490 * 5491 * PARAMETERS : none 5492 * 5493 * RETURN : int32_t type of status 5494 * NO_ERROR -- success 5495 * none-zero failure code 5496 * NOTE : Add this channel for regular capture usecase. 5497 * For Live snapshot usecase, use addSnapshotChannel. 5498 *==========================================================================*/ 5499 int32_t QCamera2HardwareInterface::addCaptureChannel() 5500 { 5501 int32_t rc = NO_ERROR; 5502 QCameraPicChannel *pChannel = NULL; 5503 char value[PROPERTY_VALUE_MAX]; 5504 bool raw_yuv = false; 5505 5506 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) { 5507 delete m_channels[QCAMERA_CH_TYPE_CAPTURE]; 5508 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL; 5509 } 5510 5511 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle, 5512 mCameraHandle->ops); 5513 if (NULL == pChannel) { 5514 ALOGE("%s: no mem for capture channel", __func__); 5515 return NO_MEMORY; 5516 } 5517 5518 // Capture channel, only need snapshot and postview streams start together 5519 mm_camera_channel_attr_t attr; 5520 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 5521 if ( mLongshotEnabled ) { 5522 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 5523 attr.look_back = mParameters.getZSLBackLookCount(); 5524 attr.water_mark = mParameters.getZSLQueueDepth(); 5525 } else { 5526 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 5527 } 5528 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 5529 5530 rc = pChannel->init(&attr, 5531 capture_channel_cb_routine, 5532 this); 5533 if (rc != NO_ERROR) { 5534 ALOGE("%s: init capture channel failed, ret = %d", __func__, rc); 5535 return rc; 5536 } 5537 5538 // meta data stream always coexists with snapshot in regular capture case 5539 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5540 metadata_stream_cb_routine, this); 5541 if (rc != NO_ERROR) { 5542 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5543 return rc; 5544 } 5545 5546 if (!mLongshotEnabled) { 5547 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW, 5548 NULL, this); 5549 5550 if (rc != NO_ERROR) { 5551 ALOGE("%s: add postview stream failed, ret = %d", __func__, rc); 5552 return rc; 5553 } 5554 } else { 5555 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW, 5556 preview_stream_cb_routine, this); 5557 5558 if (rc != NO_ERROR) { 5559 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc); 5560 return rc; 5561 } 5562 } 5563 5564 if (!mParameters.getofflineRAW()) { 5565 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT, 5566 NULL, this); 5567 if (rc != NO_ERROR) { 5568 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc); 5569 return rc; 5570 } 5571 } 5572 property_get("persist.camera.raw_yuv", value, "0"); 5573 raw_yuv = atoi(value) > 0 ? true : false; 5574 if ( raw_yuv ) { 5575 if (!mParameters.getofflineRAW()) { 5576 rc = addStreamToChannel(pChannel, 5577 CAM_STREAM_TYPE_RAW, 5578 snapshot_raw_stream_cb_routine, 5579 this); 5580 } else { 5581 rc = addStreamToChannel(pChannel, 5582 CAM_STREAM_TYPE_RAW, 5583 NULL, 5584 this); 5585 } 5586 if (rc != NO_ERROR) { 5587 ALOGE("%s: add raw stream failed, ret = %d", __func__, rc); 5588 return rc; 5589 } 5590 } 5591 5592 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel; 5593 return rc; 5594 } 5595 5596 /*=========================================================================== 5597 * FUNCTION : addMetaDataChannel 5598 * 5599 * DESCRIPTION: add a meta data channel that contains a metadata stream 5600 * 5601 * PARAMETERS : none 5602 * 5603 * RETURN : int32_t type of status 5604 * NO_ERROR -- success 5605 * none-zero failure code 5606 *==========================================================================*/ 5607 int32_t QCamera2HardwareInterface::addMetaDataChannel() 5608 { 5609 int32_t rc = NO_ERROR; 5610 QCameraChannel *pChannel = NULL; 5611 5612 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) { 5613 delete m_channels[QCAMERA_CH_TYPE_METADATA]; 5614 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL; 5615 } 5616 5617 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5618 mCameraHandle->ops); 5619 if (NULL == pChannel) { 5620 ALOGE("%s: no mem for metadata channel", __func__); 5621 return NO_MEMORY; 5622 } 5623 5624 rc = pChannel->init(NULL, 5625 NULL, 5626 NULL); 5627 if (rc != NO_ERROR) { 5628 ALOGE("%s: init metadata channel failed, ret = %d", __func__, rc); 5629 delete pChannel; 5630 return rc; 5631 } 5632 5633 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, 5634 metadata_stream_cb_routine, this); 5635 if (rc != NO_ERROR) { 5636 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc); 5637 delete pChannel; 5638 return rc; 5639 } 5640 5641 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel; 5642 return rc; 5643 } 5644 5645 /*=========================================================================== 5646 * FUNCTION : addAnalysisChannel 5647 * 5648 * DESCRIPTION: add a analysis channel that contains a analysis stream 5649 * 5650 * PARAMETERS : none 5651 * 5652 * RETURN : int32_t type of status 5653 * NO_ERROR -- success 5654 * none-zero failure code 5655 *==========================================================================*/ 5656 int32_t QCamera2HardwareInterface::addAnalysisChannel() 5657 { 5658 int32_t rc = NO_ERROR; 5659 QCameraChannel *pChannel = NULL; 5660 5661 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) { 5662 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS]; 5663 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL; 5664 } 5665 5666 pChannel = new QCameraChannel(mCameraHandle->camera_handle, 5667 mCameraHandle->ops); 5668 if (NULL == pChannel) { 5669 ALOGE("%s: no mem for metadata channel", __func__); 5670 return NO_MEMORY; 5671 } 5672 5673 rc = pChannel->init(NULL, NULL, this); 5674 if (rc != NO_ERROR) { 5675 ALOGE("%s: init Analysis channel failed, ret = %d", __func__, rc); 5676 delete pChannel; 5677 return rc; 5678 } 5679 5680 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS, 5681 NULL, this); 5682 if (rc != NO_ERROR) { 5683 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc); 5684 delete pChannel; 5685 return rc; 5686 } 5687 5688 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel; 5689 return rc; 5690 } 5691 5692 5693 /*=========================================================================== 5694 * FUNCTION : getPPConfig 5695 * 5696 * DESCRIPTION: get Post processing configaration data 5697 * 5698 * PARAMETERS : 5699 * @pp config: pp config structure pointer, 5700 * @curCount: current pp pass count 5701 * 5702 * RETURN : int32_t type of status 5703 * NO_ERROR -- success 5704 * none-zero failure code 5705 *==========================================================================*/ 5706 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config, int curCount) 5707 { 5708 int32_t rc = NO_ERROR; 5709 5710 if ( curCount != mParameters.getReprocCount() ) { 5711 ALOGW("%s : Multi pass enabled. Total Pass = %d, cur Pass = %d", __func__, 5712 mParameters.getReprocCount(), curCount); 5713 } 5714 5715 CDBG_HIGH("%s: Minimum pproc feature mask required = %x", __func__, 5716 gCamCaps[mCameraId]->min_required_pp_mask); 5717 uint32_t required_mask = gCamCaps[mCameraId]->min_required_pp_mask; 5718 int32_t zoomLevel = 0; 5719 5720 switch(curCount) { 5721 case 1: 5722 //Configure feature mask for first pass of reprocessing 5723 if (mParameters.isZSLMode() || required_mask & CAM_QCOM_FEATURE_PP_SUPERSET) { 5724 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_EFFECT) { 5725 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT; 5726 pp_config.effect = mParameters.getEffectValue(); 5727 } 5728 if ((gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) && 5729 !mParameters.isOptiZoomEnabled()) { 5730 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS; 5731 pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS); 5732 } 5733 5734 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_CROP) { 5735 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 5736 } 5737 5738 if (mParameters.isWNREnabled()) { 5739 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D; 5740 pp_config.denoise2d.denoise_enable = 1; 5741 pp_config.denoise2d.process_plates = 5742 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE); 5743 } 5744 if (required_mask & CAM_QCOM_FEATURE_ROTATION) { 5745 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 5746 } 5747 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SCALE) { 5748 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 5749 } 5750 } 5751 5752 if (isCACEnabled()) { 5753 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC; 5754 } 5755 5756 if (needRotationReprocess()) { 5757 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 5758 uint32_t rotation = mParameters.getJpegRotation(); 5759 if (rotation == 0) { 5760 pp_config.rotation = ROTATE_0; 5761 } else if (rotation == 90) { 5762 pp_config.rotation = ROTATE_90; 5763 } else if (rotation == 180) { 5764 pp_config.rotation = ROTATE_180; 5765 } else if (rotation == 270) { 5766 pp_config.rotation = ROTATE_270; 5767 } 5768 } 5769 5770 if (mParameters.isHDREnabled()){ 5771 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR; 5772 pp_config.hdr_param.hdr_enable = 1; 5773 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled(); 5774 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME; 5775 } else { 5776 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR; 5777 pp_config.hdr_param.hdr_enable = 0; 5778 } 5779 5780 if(needScaleReprocess()){ 5781 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 5782 mParameters.m_reprocScaleParam.getPicSizeFromAPK( 5783 pp_config.scale_param.output_width, 5784 pp_config.scale_param.output_height); 5785 } 5786 5787 if(mParameters.isUbiFocusEnabled()) { 5788 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS; 5789 } else { 5790 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS; 5791 } 5792 5793 if(mParameters.isUbiRefocus()) { 5794 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS; 5795 pp_config.misc_buf_param.misc_buffer_index = 0; 5796 } else { 5797 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS; 5798 } 5799 5800 if(mParameters.isChromaFlashEnabled()) { 5801 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH; 5802 pp_config.flash_value = CAM_FLASH_ON; 5803 } else { 5804 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH; 5805 } 5806 5807 zoomLevel = mParameters.getParmZoomLevel(); 5808 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) { 5809 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM; 5810 pp_config.zoom_level = (uint8_t) zoomLevel; 5811 } else { 5812 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM; 5813 } 5814 5815 if (mParameters.getofflineRAW()) { 5816 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 5817 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING; 5818 } 5819 5820 if (mParameters.isTruePortraitEnabled()) { 5821 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT; 5822 pp_config.misc_buf_param.misc_buffer_index = 0; 5823 } else { 5824 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT; 5825 } 5826 5827 if(mParameters.isStillMoreEnabled()) { 5828 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE; 5829 } else { 5830 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE; 5831 } 5832 5833 if (curCount != mParameters.getReprocCount()) { 5834 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2; 5835 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION; 5836 pp_config.rotation = ROTATE_0; 5837 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP; 5838 } else { 5839 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE; 5840 } 5841 break; 5842 5843 case 2: 5844 //Configure feature mask for second pass of reprocessing 5845 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2; 5846 if (needRotationReprocess()) { 5847 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION; 5848 uint32_t rotation = mParameters.getJpegRotation(); 5849 if (rotation == 0) { 5850 pp_config.rotation = ROTATE_0; 5851 } else if (rotation == 90) { 5852 pp_config.rotation = ROTATE_90; 5853 } else if (rotation == 180) { 5854 pp_config.rotation = ROTATE_180; 5855 } else if (rotation == 270) { 5856 pp_config.rotation = ROTATE_270; 5857 } 5858 } 5859 break; 5860 5861 } 5862 CDBG_HIGH("%s: pproc feature mask set = %x pass count = %d", 5863 __func__, pp_config.feature_mask,curCount); 5864 return rc; 5865 } 5866 5867 /*=========================================================================== 5868 * FUNCTION : addReprocChannel 5869 * 5870 * DESCRIPTION: add a reprocess channel that will do reprocess on frames 5871 * coming from input channel 5872 * 5873 * PARAMETERS : 5874 * @pInputChannel : ptr to input channel whose frames will be post-processed 5875 * 5876 * RETURN : Ptr to the newly created channel obj. NULL if failed. 5877 *==========================================================================*/ 5878 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel( 5879 QCameraChannel *pInputChannel) 5880 { 5881 int32_t rc = NO_ERROR; 5882 QCameraReprocessChannel *pChannel = NULL; 5883 5884 if (pInputChannel == NULL) { 5885 ALOGE("%s: input channel obj is NULL", __func__); 5886 return NULL; 5887 } 5888 5889 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle, 5890 mCameraHandle->ops); 5891 if (NULL == pChannel) { 5892 ALOGE("%s: no mem for reprocess channel", __func__); 5893 return NULL; 5894 } 5895 5896 // Capture channel, only need snapshot and postview streams start together 5897 mm_camera_channel_attr_t attr; 5898 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 5899 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 5900 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue(); 5901 rc = pChannel->init(&attr, 5902 postproc_channel_cb_routine, 5903 this); 5904 if (rc != NO_ERROR) { 5905 ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc); 5906 delete pChannel; 5907 return NULL; 5908 } 5909 5910 // pp feature config 5911 cam_pp_feature_config_t pp_config; 5912 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t)); 5913 5914 rc = getPPConfig(pp_config, mParameters.getCurPPCount()); 5915 if (rc != NO_ERROR){ 5916 ALOGE("%s: Error while creating PP config",__func__); 5917 delete pChannel; 5918 return NULL; 5919 } 5920 5921 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC); 5922 5923 //WNR and HDR happen inline. No extra buffers needed. 5924 uint32_t temp_feature_mask = pp_config.feature_mask; 5925 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR; 5926 if (temp_feature_mask && mParameters.isHDREnabled()) { 5927 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded()); 5928 } 5929 5930 if (mParameters.isStillMoreEnabled()) { 5931 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings(); 5932 pp_config.burst_cnt = stillmore_config.burst_count; 5933 CDBG_HIGH("%s: Stillmore burst %d", __func__, pp_config.burst_cnt); 5934 5935 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming 5936 // number of capture is already added. In the case of liveshot, 5937 // stillmore burst is 1. This is to account for the premature decrement 5938 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) { 5939 minStreamBufNum += 1; 5940 } 5941 } 5942 5943 // Add non inplace image lib buffers only when ppproc is present, 5944 // becuase pproc is non inplace and input buffers for img lib 5945 // are output for pproc and this number of extra buffers is required 5946 // If pproc is not there, input buffers for imglib are from snapshot stream 5947 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc(); 5948 if (temp_feature_mask && imglib_extra_bufs) { 5949 // 1 is added because getNumOfExtraBuffersForImageProc returns extra 5950 // buffers assuming number of capture is already added 5951 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1); 5952 } 5953 5954 // If input channel is Snapshot Channel, then update feature mask 5955 if (pInputChannel == m_channels[QCAMERA_CH_TYPE_SNAPSHOT]) { 5956 //Mask out features that are already processed in snapshot stream. 5957 uint32_t snapshot_feature_mask = 0; 5958 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask); 5959 5960 pp_config.feature_mask &= ~snapshot_feature_mask; 5961 ALOGI("%s: Snapshot feature mask: 0x%x, reproc feature mask: 0x%x", __func__, 5962 snapshot_feature_mask, pp_config.feature_mask); 5963 } 5964 5965 bool offlineReproc = isRegularCapture(); 5966 rc = pChannel->addReprocStreamsFromSource(*this, 5967 pp_config, 5968 pInputChannel, 5969 minStreamBufNum, 5970 mParameters.getNumOfSnapshots(), 5971 &gCamCaps[mCameraId]->padding_info, 5972 mParameters, 5973 mLongshotEnabled, 5974 offlineReproc); 5975 if (rc != NO_ERROR) { 5976 delete pChannel; 5977 return NULL; 5978 } 5979 5980 return pChannel; 5981 } 5982 5983 /*=========================================================================== 5984 * FUNCTION : addOfflineReprocChannel 5985 * 5986 * DESCRIPTION: add a offline reprocess channel contains one reproc stream, 5987 * that will do reprocess on frames coming from external images 5988 * 5989 * PARAMETERS : 5990 * @img_config : offline reporcess image info 5991 * @pp_feature : pp feature config 5992 * 5993 * RETURN : int32_t type of status 5994 * NO_ERROR -- success 5995 * none-zero failure code 5996 *==========================================================================*/ 5997 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel( 5998 cam_pp_offline_src_config_t &img_config, 5999 cam_pp_feature_config_t &pp_feature, 6000 stream_cb_routine stream_cb, 6001 void *userdata) 6002 { 6003 int32_t rc = NO_ERROR; 6004 QCameraReprocessChannel *pChannel = NULL; 6005 6006 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle, 6007 mCameraHandle->ops); 6008 if (NULL == pChannel) { 6009 ALOGE("%s: no mem for reprocess channel", __func__); 6010 return NULL; 6011 } 6012 6013 rc = pChannel->init(NULL, NULL, NULL); 6014 if (rc != NO_ERROR) { 6015 ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc); 6016 delete pChannel; 6017 return NULL; 6018 } 6019 6020 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 6021 if (pStreamInfo == NULL) { 6022 ALOGE("%s: no mem for stream info buf", __func__); 6023 delete pChannel; 6024 return NULL; 6025 } 6026 6027 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0); 6028 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t)); 6029 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 6030 streamInfoBuf->fmt = img_config.input_fmt; 6031 streamInfoBuf->dim = img_config.input_dim; 6032 streamInfoBuf->buf_planes = img_config.input_buf_planes; 6033 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST; 6034 streamInfoBuf->num_of_burst = img_config.num_of_bufs; 6035 6036 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 6037 streamInfoBuf->reprocess_config.offline = img_config; 6038 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature; 6039 6040 rc = pChannel->addStream(*this, 6041 pStreamInfo, NULL, img_config.num_of_bufs, 6042 &gCamCaps[mCameraId]->padding_info, 6043 stream_cb, userdata, false); 6044 6045 if (rc != NO_ERROR) { 6046 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc); 6047 pStreamInfo->deallocate(); 6048 delete pStreamInfo; 6049 delete pChannel; 6050 return NULL; 6051 } 6052 6053 return pChannel; 6054 } 6055 6056 /*=========================================================================== 6057 * FUNCTION : addChannel 6058 * 6059 * DESCRIPTION: add a channel by its type 6060 * 6061 * PARAMETERS : 6062 * @ch_type : channel type 6063 * 6064 * RETURN : int32_t type of status 6065 * NO_ERROR -- success 6066 * none-zero failure code 6067 *==========================================================================*/ 6068 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type) 6069 { 6070 int32_t rc = UNKNOWN_ERROR; 6071 switch (ch_type) { 6072 case QCAMERA_CH_TYPE_ZSL: 6073 rc = addZSLChannel(); 6074 break; 6075 case QCAMERA_CH_TYPE_CAPTURE: 6076 rc = addCaptureChannel(); 6077 break; 6078 case QCAMERA_CH_TYPE_PREVIEW: 6079 rc = addPreviewChannel(); 6080 break; 6081 case QCAMERA_CH_TYPE_VIDEO: 6082 rc = addVideoChannel(); 6083 break; 6084 case QCAMERA_CH_TYPE_SNAPSHOT: 6085 rc = addSnapshotChannel(); 6086 break; 6087 case QCAMERA_CH_TYPE_RAW: 6088 rc = addRawChannel(); 6089 break; 6090 case QCAMERA_CH_TYPE_METADATA: 6091 rc = addMetaDataChannel(); 6092 break; 6093 case QCAMERA_CH_TYPE_ANALYSIS: 6094 rc = addAnalysisChannel(); 6095 break; 6096 default: 6097 break; 6098 } 6099 return rc; 6100 } 6101 6102 /*=========================================================================== 6103 * FUNCTION : delChannel 6104 * 6105 * DESCRIPTION: delete a channel by its type 6106 * 6107 * PARAMETERS : 6108 * @ch_type : channel type 6109 * @destroy : delete context as well 6110 * 6111 * RETURN : int32_t type of status 6112 * NO_ERROR -- success 6113 * none-zero failure code 6114 *==========================================================================*/ 6115 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type, 6116 bool destroy) 6117 { 6118 if (m_channels[ch_type] != NULL) { 6119 if (destroy) { 6120 delete m_channels[ch_type]; 6121 m_channels[ch_type] = NULL; 6122 } else { 6123 m_channels[ch_type]->deleteChannel(); 6124 } 6125 } 6126 6127 return NO_ERROR; 6128 } 6129 6130 /*=========================================================================== 6131 * FUNCTION : startChannel 6132 * 6133 * DESCRIPTION: start a channel by its type 6134 * 6135 * PARAMETERS : 6136 * @ch_type : channel type 6137 * 6138 * RETURN : int32_t type of status 6139 * NO_ERROR -- success 6140 * none-zero failure code 6141 *==========================================================================*/ 6142 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type) 6143 { 6144 int32_t rc = UNKNOWN_ERROR; 6145 if (m_channels[ch_type] != NULL) { 6146 rc = m_channels[ch_type]->config(); 6147 if (NO_ERROR == rc) { 6148 rc = m_channels[ch_type]->start(); 6149 } 6150 } 6151 6152 return rc; 6153 } 6154 6155 /*=========================================================================== 6156 * FUNCTION : stopChannel 6157 * 6158 * DESCRIPTION: stop a channel by its type 6159 * 6160 * PARAMETERS : 6161 * @ch_type : channel type 6162 * 6163 * RETURN : int32_t type of status 6164 * NO_ERROR -- success 6165 * none-zero failure code 6166 *==========================================================================*/ 6167 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type) 6168 { 6169 int32_t rc = UNKNOWN_ERROR; 6170 if (m_channels[ch_type] != NULL) { 6171 rc = m_channels[ch_type]->stop(); 6172 } 6173 6174 return rc; 6175 } 6176 6177 /*=========================================================================== 6178 * FUNCTION : preparePreview 6179 * 6180 * DESCRIPTION: add channels needed for preview 6181 * 6182 * PARAMETERS : none 6183 * 6184 * RETURN : int32_t type of status 6185 * NO_ERROR -- success 6186 * none-zero failure code 6187 *==========================================================================*/ 6188 int32_t QCamera2HardwareInterface::preparePreview() 6189 { 6190 ATRACE_CALL(); 6191 int32_t rc = NO_ERROR; 6192 6193 pthread_mutex_lock(&m_parm_lock); 6194 rc = mParameters.setStreamConfigure(false, false, false); 6195 if (rc != NO_ERROR) { 6196 ALOGE("%s: setStreamConfigure failed %d", __func__, rc); 6197 pthread_mutex_unlock(&m_parm_lock); 6198 return rc; 6199 } 6200 pthread_mutex_unlock(&m_parm_lock); 6201 6202 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) { 6203 rc = addChannel(QCAMERA_CH_TYPE_ZSL); 6204 if (rc != NO_ERROR) { 6205 ALOGE("%s[%d]: failed!! rc = %d", __func__, __LINE__, rc); 6206 return rc; 6207 } 6208 } else { 6209 bool recordingHint = mParameters.getRecordingHintValue(); 6210 if(!isRdiMode() && recordingHint) { 6211 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6212 if (rc != NO_ERROR) { 6213 return rc; 6214 } 6215 rc = addChannel(QCAMERA_CH_TYPE_VIDEO); 6216 if (rc != NO_ERROR) { 6217 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6218 ALOGE("%s[%d]:failed!! rc = %d", __func__, __LINE__, rc); 6219 return rc; 6220 } 6221 } 6222 6223 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW); 6224 if (!isRdiMode() && (rc != NO_ERROR)) { 6225 if (recordingHint) { 6226 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6227 delChannel(QCAMERA_CH_TYPE_VIDEO); 6228 } 6229 } 6230 6231 if (!recordingHint && !mParameters.isSecureMode()) { 6232 waitDefferedWork(mMetadataJob); 6233 waitDefferedWork(mRawdataJob); 6234 } 6235 6236 if (NO_ERROR != rc) { 6237 delChannel(QCAMERA_CH_TYPE_PREVIEW); 6238 ALOGE("%s[%d]:failed!! rc = %d", __func__, __LINE__, rc); 6239 } 6240 } 6241 6242 return rc; 6243 } 6244 6245 /*=========================================================================== 6246 * FUNCTION : unpreparePreview 6247 * 6248 * DESCRIPTION: delete channels for preview 6249 * 6250 * PARAMETERS : none 6251 * 6252 * RETURN : none 6253 *==========================================================================*/ 6254 void QCamera2HardwareInterface::unpreparePreview() 6255 { 6256 delChannel(QCAMERA_CH_TYPE_ZSL); 6257 delChannel(QCAMERA_CH_TYPE_PREVIEW); 6258 delChannel(QCAMERA_CH_TYPE_VIDEO); 6259 delChannel(QCAMERA_CH_TYPE_SNAPSHOT); 6260 } 6261 6262 /*=========================================================================== 6263 * FUNCTION : playShutter 6264 * 6265 * DESCRIPTION: send request to play shutter sound 6266 * 6267 * PARAMETERS : none 6268 * 6269 * RETURN : none 6270 *==========================================================================*/ 6271 void QCamera2HardwareInterface::playShutter(){ 6272 if (mNotifyCb == NULL || 6273 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){ 6274 CDBG("%s: shutter msg not enabled or NULL cb", __func__); 6275 return; 6276 } 6277 6278 qcamera_callback_argm_t cbArg; 6279 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6280 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 6281 cbArg.msg_type = CAMERA_MSG_SHUTTER; 6282 cbArg.ext1 = 0; 6283 cbArg.ext2 = false; 6284 m_cbNotifier.notifyCallback(cbArg); 6285 } 6286 6287 /*=========================================================================== 6288 * FUNCTION : getChannelByHandle 6289 * 6290 * DESCRIPTION: return a channel by its handle 6291 * 6292 * PARAMETERS : 6293 * @channelHandle : channel handle 6294 * 6295 * RETURN : a channel obj if found, NULL if not found 6296 *==========================================================================*/ 6297 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle) 6298 { 6299 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 6300 if (m_channels[i] != NULL && 6301 m_channels[i]->getMyHandle() == channelHandle) { 6302 return m_channels[i]; 6303 } 6304 } 6305 6306 return NULL; 6307 } 6308 6309 /*=========================================================================== 6310 * FUNCTION : processFaceDetectionReuslt 6311 * 6312 * DESCRIPTION: process face detection reuslt 6313 * 6314 * PARAMETERS : 6315 * @fd_data : ptr to face detection result struct 6316 * 6317 * RETURN : int32_t type of status 6318 * NO_ERROR -- success 6319 * none-zero failure code 6320 *==========================================================================*/ 6321 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_face_detection_data_t *fd_data) 6322 { 6323 if (!mParameters.isFaceDetectionEnabled()) { 6324 CDBG_HIGH("%s: FaceDetection not enabled, no ops here", __func__); 6325 return NO_ERROR; 6326 } 6327 6328 qcamera_face_detect_type_t fd_type = fd_data->fd_type; 6329 if ((NULL == mDataCb) || 6330 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) 6331 #ifndef VANILLA_HAL 6332 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA)) 6333 #endif 6334 ) { 6335 CDBG_HIGH("%s: metadata msgtype not enabled, no ops here", __func__); 6336 return NO_ERROR; 6337 } 6338 6339 cam_dimension_t display_dim; 6340 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim); 6341 if (display_dim.width <= 0 || display_dim.height <= 0) { 6342 ALOGE("%s: Invalid preview width or height (%d x %d)", 6343 __func__, display_dim.width, display_dim.height); 6344 return UNKNOWN_ERROR; 6345 } 6346 6347 // process face detection result 6348 // need separate face detection in preview or snapshot type 6349 size_t faceResultSize = 0; 6350 size_t data_len = 0; 6351 if(fd_type == QCAMERA_FD_PREVIEW){ 6352 //fd for preview frames 6353 faceResultSize = sizeof(camera_frame_metadata_t); 6354 faceResultSize += sizeof(camera_face_t) * MAX_ROI; 6355 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 6356 #ifndef VANILLA_HAL 6357 // fd for snapshot frames 6358 //check if face is detected in this frame 6359 if(fd_data->num_faces_detected > 0){ 6360 data_len = sizeof(camera_frame_metadata_t) + 6361 sizeof(camera_face_t) * fd_data->num_faces_detected; 6362 }else{ 6363 //no face 6364 data_len = 0; 6365 } 6366 #endif 6367 faceResultSize = 1 *sizeof(int) //meta data type 6368 + 1 *sizeof(int) // meta data len 6369 + data_len; //data 6370 } 6371 6372 camera_memory_t *faceResultBuffer = mGetMemory(-1, 6373 faceResultSize, 6374 1, 6375 mCallbackCookie); 6376 if ( NULL == faceResultBuffer ) { 6377 ALOGE("%s: Not enough memory for face result data", 6378 __func__); 6379 return NO_MEMORY; 6380 } 6381 6382 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data; 6383 memset(pFaceResult, 0, faceResultSize); 6384 unsigned char *faceData = NULL; 6385 if(fd_type == QCAMERA_FD_PREVIEW){ 6386 faceData = pFaceResult; 6387 }else if(fd_type == QCAMERA_FD_SNAPSHOT){ 6388 #ifndef VANILLA_HAL 6389 //need fill meta type and meta data len first 6390 int *data_header = (int* )pFaceResult; 6391 data_header[0] = CAMERA_META_DATA_FD; 6392 data_header[1] = (int)data_len; 6393 6394 if(data_len <= 0){ 6395 //if face is not valid or do not have face, return 6396 qcamera_callback_argm_t cbArg; 6397 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6398 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6399 cbArg.msg_type = CAMERA_MSG_META_DATA; 6400 cbArg.data = faceResultBuffer; 6401 cbArg.user_data = faceResultBuffer; 6402 cbArg.cookie = this; 6403 cbArg.release_cb = releaseCameraMemory; 6404 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 6405 if (rc != NO_ERROR) { 6406 ALOGE("%s: fail sending notification", __func__); 6407 faceResultBuffer->release(faceResultBuffer); 6408 } 6409 return rc; 6410 } 6411 #endif 6412 faceData = pFaceResult + 2 *sizeof(int); //skip two int length 6413 } 6414 6415 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData; 6416 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) ); 6417 6418 roiData->number_of_faces = fd_data->num_faces_detected; 6419 roiData->faces = faces; 6420 if (roiData->number_of_faces > 0) { 6421 for (int i = 0; i < roiData->number_of_faces; i++) { 6422 faces[i].id = fd_data->faces[i].face_id; 6423 faces[i].score = fd_data->faces[i].score; 6424 6425 // left 6426 faces[i].rect[0] = 6427 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.left, display_dim.width, 2000, -1000); 6428 6429 // top 6430 faces[i].rect[1] = 6431 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.top, display_dim.height, 2000, -1000); 6432 6433 // right 6434 faces[i].rect[2] = faces[i].rect[0] + 6435 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.width, display_dim.width, 2000, 0); 6436 6437 // bottom 6438 faces[i].rect[3] = faces[i].rect[1] + 6439 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.height, display_dim.height, 2000, 0); 6440 6441 // Center of left eye 6442 faces[i].left_eye[0] = 6443 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.x, display_dim.width, 2000, -1000); 6444 6445 faces[i].left_eye[1] = 6446 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.y, display_dim.height, 2000, -1000); 6447 6448 // Center of right eye 6449 faces[i].right_eye[0] = 6450 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.x, display_dim.width, 2000, -1000); 6451 6452 faces[i].right_eye[1] = 6453 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.y, display_dim.height, 2000, -1000); 6454 6455 // Center of mouth 6456 faces[i].mouth[0] = 6457 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.x, display_dim.width, 2000, -1000); 6458 6459 faces[i].mouth[1] = 6460 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.y, display_dim.height, 2000, -1000); 6461 6462 #ifndef VANILLA_HAL 6463 faces[i].smile_degree = fd_data->faces[i].smile_degree; 6464 faces[i].smile_score = fd_data->faces[i].smile_confidence; 6465 faces[i].blink_detected = fd_data->faces[i].blink_detected; 6466 faces[i].face_recognised = fd_data->faces[i].face_recognised; 6467 faces[i].gaze_angle = fd_data->faces[i].gaze_angle; 6468 6469 // upscale by 2 to recover from demaen downscaling 6470 faces[i].updown_dir = fd_data->faces[i].updown_dir * 2; 6471 faces[i].leftright_dir = fd_data->faces[i].leftright_dir * 2; 6472 faces[i].roll_dir = fd_data->faces[i].roll_dir * 2; 6473 6474 faces[i].leye_blink = fd_data->faces[i].left_blink; 6475 faces[i].reye_blink = fd_data->faces[i].right_blink; 6476 faces[i].left_right_gaze = fd_data->faces[i].left_right_gaze; 6477 faces[i].top_bottom_gaze = fd_data->faces[i].top_bottom_gaze; 6478 #endif 6479 6480 } 6481 } 6482 6483 qcamera_callback_argm_t cbArg; 6484 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6485 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6486 if(fd_type == QCAMERA_FD_PREVIEW){ 6487 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA; 6488 } 6489 #ifndef VANILLA_HAL 6490 else if(fd_type == QCAMERA_FD_SNAPSHOT){ 6491 cbArg.msg_type = CAMERA_MSG_META_DATA; 6492 } 6493 #endif 6494 cbArg.data = faceResultBuffer; 6495 cbArg.metadata = roiData; 6496 cbArg.user_data = faceResultBuffer; 6497 cbArg.cookie = this; 6498 cbArg.release_cb = releaseCameraMemory; 6499 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 6500 if (rc != NO_ERROR) { 6501 ALOGE("%s: fail sending notification", __func__); 6502 faceResultBuffer->release(faceResultBuffer); 6503 } 6504 6505 return rc; 6506 } 6507 6508 /*=========================================================================== 6509 * FUNCTION : releaseCameraMemory 6510 * 6511 * DESCRIPTION: releases camera memory objects 6512 * 6513 * PARAMETERS : 6514 * @data : buffer to be released 6515 * @cookie : context data 6516 * @cbStatus: callback status 6517 * 6518 * RETURN : None 6519 *==========================================================================*/ 6520 void QCamera2HardwareInterface::releaseCameraMemory(void *data, 6521 void */*cookie*/, 6522 int32_t /*cbStatus*/) 6523 { 6524 camera_memory_t *mem = ( camera_memory_t * ) data; 6525 if ( NULL != mem ) { 6526 mem->release(mem); 6527 } 6528 } 6529 6530 /*=========================================================================== 6531 * FUNCTION : returnStreamBuffer 6532 * 6533 * DESCRIPTION: returns back a stream buffer 6534 * 6535 * PARAMETERS : 6536 * @data : buffer to be released 6537 * @cookie : context data 6538 * @cbStatus: callback status 6539 * 6540 * RETURN : None 6541 *==========================================================================*/ 6542 void QCamera2HardwareInterface::returnStreamBuffer(void *data, 6543 void *cookie, 6544 int32_t /*cbStatus*/) 6545 { 6546 QCameraStream *stream = ( QCameraStream * ) cookie; 6547 int idx = *((int *)data); 6548 if ((NULL != stream) && (0 <= idx)) { 6549 stream->bufDone((uint32_t)idx); 6550 } else { 6551 ALOGE("%s: Cannot return buffer %d %p", __func__, idx, cookie); 6552 } 6553 } 6554 6555 /*=========================================================================== 6556 * FUNCTION : processHistogramStats 6557 * 6558 * DESCRIPTION: process histogram stats 6559 * 6560 * PARAMETERS : 6561 * @hist_data : ptr to histogram stats struct 6562 * 6563 * RETURN : int32_t type of status 6564 * NO_ERROR -- success 6565 * none-zero failure code 6566 *==========================================================================*/ 6567 int32_t QCamera2HardwareInterface::processHistogramStats(cam_hist_stats_t &stats_data) 6568 { 6569 #ifndef VANILLA_HAL 6570 if (!mParameters.isHistogramEnabled()) { 6571 CDBG_HIGH("%s: Histogram not enabled, no ops here", __func__); 6572 return NO_ERROR; 6573 } 6574 6575 camera_memory_t *histBuffer = mGetMemory(-1, 6576 sizeof(cam_histogram_data_t), 6577 1, 6578 mCallbackCookie); 6579 if ( NULL == histBuffer ) { 6580 ALOGE("%s: Not enough memory for histogram data", 6581 __func__); 6582 return NO_MEMORY; 6583 } 6584 6585 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data; 6586 if (pHistData == NULL) { 6587 ALOGE("%s: memory data ptr is NULL", __func__); 6588 return UNKNOWN_ERROR; 6589 } 6590 6591 switch (stats_data.type) { 6592 case CAM_HISTOGRAM_TYPE_BAYER: 6593 *pHistData = stats_data.bayer_stats.gb_stats; 6594 break; 6595 case CAM_HISTOGRAM_TYPE_YUV: 6596 *pHistData = stats_data.yuv_stats; 6597 break; 6598 } 6599 6600 qcamera_callback_argm_t cbArg; 6601 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 6602 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 6603 cbArg.msg_type = CAMERA_MSG_STATS_DATA; 6604 cbArg.data = histBuffer; 6605 cbArg.user_data = histBuffer; 6606 cbArg.cookie = this; 6607 cbArg.release_cb = releaseCameraMemory; 6608 int32_t rc = m_cbNotifier.notifyCallback(cbArg); 6609 if (rc != NO_ERROR) { 6610 ALOGE("%s: fail sending notification", __func__); 6611 histBuffer->release(histBuffer); 6612 } 6613 #endif 6614 return NO_ERROR; 6615 } 6616 6617 /*=========================================================================== 6618 * FUNCTION : calcThermalLevel 6619 * 6620 * DESCRIPTION: Calculates the target fps range depending on 6621 * the thermal level. 6622 * 6623 * PARAMETERS : 6624 * @level : received thermal level 6625 * @minFPS : minimum configured fps range 6626 * @maxFPS : maximum configured fps range 6627 * @adjustedRange : target fps range 6628 * @skipPattern : target skip pattern 6629 * 6630 * RETURN : int32_t type of status 6631 * NO_ERROR -- success 6632 * none-zero failure code 6633 *==========================================================================*/ 6634 int QCamera2HardwareInterface::calcThermalLevel( 6635 qcamera_thermal_level_enum_t level, 6636 const int minFPSi, 6637 const int maxFPSi, 6638 cam_fps_range_t &adjustedRange, 6639 enum msm_vfe_frame_skip_pattern &skipPattern) 6640 { 6641 const float minFPS = (float)minFPSi; 6642 const float maxFPS = (float)maxFPSi; 6643 6644 // Initialize video fps to preview fps 6645 float minVideoFps = minFPS, maxVideoFps = maxFPS; 6646 cam_fps_range_t videoFps; 6647 // If HFR mode, update video fps accordingly 6648 if(isHFRMode()) { 6649 mParameters.getHfrFps(videoFps); 6650 minVideoFps = videoFps.video_min_fps; 6651 maxVideoFps = videoFps.video_max_fps; 6652 } 6653 6654 CDBG_HIGH("%s: level: %d, preview minfps %f, preview maxfpS %f, " 6655 "video minfps %f, video maxfpS %f", 6656 __func__, level, minFPS, maxFPS, minVideoFps, maxVideoFps); 6657 6658 switch(level) { 6659 case QCAMERA_THERMAL_NO_ADJUSTMENT: 6660 { 6661 adjustedRange.min_fps = minFPS / 1000.0f; 6662 adjustedRange.max_fps = maxFPS / 1000.0f; 6663 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 6664 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 6665 skipPattern = NO_SKIP; 6666 } 6667 break; 6668 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT: 6669 { 6670 adjustedRange.min_fps = minFPS / 1000.0f; 6671 adjustedRange.max_fps = maxFPS / 1000.0f; 6672 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps; 6673 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps; 6674 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 6675 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 6676 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps; 6677 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps; 6678 if ( adjustedRange.min_fps < 1 ) { 6679 adjustedRange.min_fps = 1; 6680 } 6681 if ( adjustedRange.max_fps < 1 ) { 6682 adjustedRange.max_fps = 1; 6683 } 6684 if ( adjustedRange.video_min_fps < 1 ) { 6685 adjustedRange.video_min_fps = 1; 6686 } 6687 if ( adjustedRange.video_max_fps < 1 ) { 6688 adjustedRange.video_max_fps = 1; 6689 } 6690 skipPattern = EVERY_2FRAME; 6691 } 6692 break; 6693 case QCAMERA_THERMAL_BIG_ADJUSTMENT: 6694 { 6695 adjustedRange.min_fps = minFPS / 1000.0f; 6696 adjustedRange.max_fps = maxFPS / 1000.0f; 6697 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps; 6698 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps; 6699 adjustedRange.video_min_fps = minVideoFps / 1000.0f; 6700 adjustedRange.video_max_fps = maxVideoFps / 1000.0f; 6701 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps; 6702 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps; 6703 if ( adjustedRange.min_fps < 1 ) { 6704 adjustedRange.min_fps = 1; 6705 } 6706 if ( adjustedRange.max_fps < 1 ) { 6707 adjustedRange.max_fps = 1; 6708 } 6709 if ( adjustedRange.video_min_fps < 1 ) { 6710 adjustedRange.video_min_fps = 1; 6711 } 6712 if ( adjustedRange.video_max_fps < 1 ) { 6713 adjustedRange.video_max_fps = 1; 6714 } 6715 skipPattern = EVERY_4FRAME; 6716 } 6717 break; 6718 case QCAMERA_THERMAL_SHUTDOWN: 6719 { 6720 // Stop Preview? 6721 // Set lowest min FPS for now 6722 adjustedRange.min_fps = minFPS/1000.0f; 6723 adjustedRange.max_fps = minFPS/1000.0f; 6724 for (size_t i = 0; i < gCamCaps[mCameraId]->fps_ranges_tbl_cnt; i++) { 6725 if (gCamCaps[mCameraId]->fps_ranges_tbl[i].min_fps < adjustedRange.min_fps) { 6726 adjustedRange.min_fps = gCamCaps[mCameraId]->fps_ranges_tbl[i].min_fps; 6727 adjustedRange.max_fps = adjustedRange.min_fps; 6728 } 6729 } 6730 skipPattern = MAX_SKIP; 6731 adjustedRange.video_min_fps = adjustedRange.min_fps; 6732 adjustedRange.video_max_fps = adjustedRange.max_fps; 6733 } 6734 break; 6735 default: 6736 { 6737 ALOGE("%s: Invalid thermal level %d", __func__, level); 6738 return BAD_VALUE; 6739 } 6740 break; 6741 } 6742 CDBG_HIGH("%s: Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d", 6743 __func__, level, adjustedRange.min_fps, adjustedRange.max_fps, 6744 adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern); 6745 6746 return NO_ERROR; 6747 } 6748 6749 /*=========================================================================== 6750 * FUNCTION : recalcFPSRange 6751 * 6752 * DESCRIPTION: adjust the configured fps range regarding 6753 * the last thermal level. 6754 * 6755 * PARAMETERS : 6756 * @minFPS : minimum configured fps range 6757 * @maxFPS : maximum configured fps range 6758 * @adjustedRange : target fps range 6759 * 6760 * RETURN : int32_t type of status 6761 * NO_ERROR -- success 6762 * none-zero failure code 6763 *==========================================================================*/ 6764 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS, 6765 cam_fps_range_t &adjustedRange) 6766 { 6767 enum msm_vfe_frame_skip_pattern skipPattern; 6768 calcThermalLevel(mThermalLevel, 6769 minFPS, 6770 maxFPS, 6771 adjustedRange, 6772 skipPattern); 6773 return NO_ERROR; 6774 } 6775 6776 /*=========================================================================== 6777 * FUNCTION : updateThermalLevel 6778 * 6779 * DESCRIPTION: update thermal level depending on thermal events 6780 * 6781 * PARAMETERS : 6782 * @level : thermal level 6783 * 6784 * RETURN : int32_t type of status 6785 * NO_ERROR -- success 6786 * none-zero failure code 6787 *==========================================================================*/ 6788 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level) 6789 { 6790 int ret = NO_ERROR; 6791 cam_fps_range_t adjustedRange; 6792 int minFPS, maxFPS; 6793 enum msm_vfe_frame_skip_pattern skipPattern; 6794 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level; 6795 6796 pthread_mutex_lock(&m_parm_lock); 6797 6798 if (!mCameraOpened) { 6799 CDBG_HIGH("%s: Camera is not opened, no need to update camera parameters", __func__); 6800 pthread_mutex_unlock(&m_parm_lock); 6801 return NO_ERROR; 6802 } 6803 6804 mParameters.getPreviewFpsRange(&minFPS, &maxFPS); 6805 qcamera_thermal_mode thermalMode = mParameters.getThermalMode(); 6806 calcThermalLevel(level, minFPS, maxFPS, adjustedRange, skipPattern); 6807 mThermalLevel = level; 6808 6809 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS) 6810 ret = mParameters.adjustPreviewFpsRange(&adjustedRange); 6811 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP) 6812 ret = mParameters.setFrameSkip(skipPattern); 6813 else 6814 ALOGE("%s: Incorrect thermal mode %d", __func__, thermalMode); 6815 6816 pthread_mutex_unlock(&m_parm_lock); 6817 6818 return ret; 6819 6820 } 6821 6822 /*=========================================================================== 6823 * FUNCTION : updateParameters 6824 * 6825 * DESCRIPTION: update parameters 6826 * 6827 * PARAMETERS : 6828 * @parms : input parameters string 6829 * @needRestart : output, flag to indicate if preview restart is needed 6830 * 6831 * RETURN : int32_t type of status 6832 * NO_ERROR -- success 6833 * none-zero failure code 6834 *==========================================================================*/ 6835 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart) 6836 { 6837 int rc = NO_ERROR; 6838 pthread_mutex_lock(&m_parm_lock); 6839 String8 str = String8(parms); 6840 QCameraParameters param(str); 6841 rc = mParameters.updateParameters(param, needRestart); 6842 6843 // update stream based parameter settings 6844 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) { 6845 if (m_channels[i] != NULL) { 6846 m_channels[i]->UpdateStreamBasedParameters(mParameters); 6847 } 6848 } 6849 pthread_mutex_unlock(&m_parm_lock); 6850 6851 return rc; 6852 } 6853 6854 /*=========================================================================== 6855 * FUNCTION : commitParameterChanges 6856 * 6857 * DESCRIPTION: commit parameter changes to the backend to take effect 6858 * 6859 * PARAMETERS : none 6860 * 6861 * RETURN : int32_t type of status 6862 * NO_ERROR -- success 6863 * none-zero failure code 6864 * NOTE : This function must be called after updateParameters. 6865 * Otherwise, no change will be passed to backend to take effect. 6866 *==========================================================================*/ 6867 int QCamera2HardwareInterface::commitParameterChanges() 6868 { 6869 int rc = NO_ERROR; 6870 pthread_mutex_lock(&m_parm_lock); 6871 rc = mParameters.commitParameters(); 6872 if (rc == NO_ERROR) { 6873 // update number of snapshot based on committed parameters setting 6874 rc = mParameters.setNumOfSnapshot(); 6875 } 6876 pthread_mutex_unlock(&m_parm_lock); 6877 return rc; 6878 } 6879 6880 /*=========================================================================== 6881 * FUNCTION : needDebugFps 6882 * 6883 * DESCRIPTION: if fps log info need to be printed out 6884 * 6885 * PARAMETERS : none 6886 * 6887 * RETURN : true: need print out fps log 6888 * false: no need to print out fps log 6889 *==========================================================================*/ 6890 bool QCamera2HardwareInterface::needDebugFps() 6891 { 6892 bool needFps = false; 6893 pthread_mutex_lock(&m_parm_lock); 6894 needFps = mParameters.isFpsDebugEnabled(); 6895 pthread_mutex_unlock(&m_parm_lock); 6896 return needFps; 6897 } 6898 6899 /*=========================================================================== 6900 * FUNCTION : isCACEnabled 6901 * 6902 * DESCRIPTION: if CAC is enabled 6903 * 6904 * PARAMETERS : none 6905 * 6906 * RETURN : true: needed 6907 * false: no need 6908 *==========================================================================*/ 6909 bool QCamera2HardwareInterface::isCACEnabled() 6910 { 6911 char prop[PROPERTY_VALUE_MAX]; 6912 memset(prop, 0, sizeof(prop)); 6913 property_get("persist.camera.feature.cac", prop, "0"); 6914 int enableCAC = atoi(prop); 6915 return enableCAC == 1; 6916 } 6917 6918 /*=========================================================================== 6919 * FUNCTION : is4k2kResolution 6920 * 6921 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k 6922 * 6923 * PARAMETERS : none 6924 * 6925 * RETURN : true: needed 6926 * false: no need 6927 *==========================================================================*/ 6928 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution) 6929 { 6930 bool enabled = false; 6931 if ((resolution->width == 4096 && resolution->height == 2160) || 6932 (resolution->width == 3840 && resolution->height == 2160) ) { 6933 enabled = true; 6934 } 6935 return enabled; 6936 } 6937 6938 6939 /*=========================================================================== 6940 * FUNCTION : isAFRunning 6941 * 6942 * DESCRIPTION: if AF is in progress while in Auto/Macro focus modes 6943 * 6944 * PARAMETERS : none 6945 * 6946 * RETURN : true: AF in progress 6947 * false: AF not in progress 6948 *==========================================================================*/ 6949 bool QCamera2HardwareInterface::isAFRunning() 6950 { 6951 bool isAFInProgress = (m_currentFocusState == CAM_AF_SCANNING && 6952 (mParameters.getFocusMode() == CAM_FOCUS_MODE_AUTO || 6953 mParameters.getFocusMode() == CAM_FOCUS_MODE_MACRO)); 6954 6955 return isAFInProgress; 6956 } 6957 6958 /*=========================================================================== 6959 * FUNCTION : isPreviewRestartEnabled 6960 * 6961 * DESCRIPTION: Check whether preview should be restarted automatically 6962 * during image capture. 6963 * 6964 * PARAMETERS : none 6965 * 6966 * RETURN : true: needed 6967 * false: no need 6968 *==========================================================================*/ 6969 bool QCamera2HardwareInterface::isPreviewRestartEnabled() 6970 { 6971 char prop[PROPERTY_VALUE_MAX]; 6972 memset(prop, 0, sizeof(prop)); 6973 property_get("persist.camera.feature.restart", prop, "0"); 6974 int earlyRestart = atoi(prop); 6975 return earlyRestart == 1; 6976 } 6977 6978 /*=========================================================================== 6979 * FUNCTION : needReprocess 6980 * 6981 * DESCRIPTION: if reprocess is needed 6982 * 6983 * PARAMETERS : none 6984 * 6985 * RETURN : true: needed 6986 * false: no need 6987 *==========================================================================*/ 6988 bool QCamera2HardwareInterface::needReprocess() 6989 { 6990 pthread_mutex_lock(&m_parm_lock); 6991 6992 if (mParameters.getofflineRAW()) { 6993 pthread_mutex_unlock(&m_parm_lock); 6994 return true; 6995 } 6996 if (!mParameters.isJpegPictureFormat() && 6997 !mParameters.isNV21PictureFormat()) { 6998 // RAW image, no need to reprocess 6999 pthread_mutex_unlock(&m_parm_lock); 7000 return false; 7001 } 7002 7003 if (mParameters.isHDREnabled()) { 7004 CDBG_HIGH("%s: need do reprocess for HDR", __func__); 7005 pthread_mutex_unlock(&m_parm_lock); 7006 return true; 7007 } 7008 //Disable reprocess for 4K liveshot case 7009 if (mParameters.is4k2kVideoResolution()&& mParameters.getRecordingHintValue()) { 7010 //Disable reprocess for 4K liveshot case 7011 pthread_mutex_unlock(&m_parm_lock); 7012 return false; 7013 } 7014 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 && 7015 (mParameters.getJpegRotation() > 0)) { 7016 // current rotation is not zero, and pp has the capability to process rotation 7017 CDBG_HIGH("%s: need to do reprocess for rotation=%d", 7018 __func__, mParameters.getJpegRotation()); 7019 pthread_mutex_unlock(&m_parm_lock); 7020 return true; 7021 } 7022 7023 if (isZSLMode()) { 7024 if (((gCamCaps[mCameraId]->min_required_pp_mask > 0) || 7025 mParameters.isWNREnabled() || isCACEnabled())) { 7026 // TODO: add for ZSL HDR later 7027 CDBG_HIGH("%s: need do reprocess for ZSL WNR or min PP reprocess", __func__); 7028 pthread_mutex_unlock(&m_parm_lock); 7029 return true; 7030 } 7031 7032 int snapshot_flipMode = 7033 mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT); 7034 if (snapshot_flipMode > 0) { 7035 CDBG_HIGH("%s: Need do flip for snapshot in ZSL mode", __func__); 7036 pthread_mutex_unlock(&m_parm_lock); 7037 return true; 7038 } 7039 } else { 7040 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_PP_SUPERSET) { 7041 CDBG_HIGH("%s: Need CPP in non-ZSL mode", __func__); 7042 pthread_mutex_unlock(&m_parm_lock); 7043 return true; 7044 } 7045 } 7046 7047 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SCALE) > 0 && 7048 mParameters.m_reprocScaleParam.isScaleEnabled() && 7049 mParameters.m_reprocScaleParam.isUnderScaling()) { 7050 // Reproc Scale is enaled and also need Scaling to current Snapshot 7051 CDBG_HIGH("%s: need do reprocess for scale", __func__); 7052 pthread_mutex_unlock(&m_parm_lock); 7053 return true; 7054 } 7055 7056 if (mParameters.isUbiFocusEnabled() | 7057 mParameters.isUbiRefocus() | 7058 mParameters.isChromaFlashEnabled() | 7059 mParameters.isHDREnabled() | 7060 mParameters.isOptiZoomEnabled() | 7061 mParameters.isStillMoreEnabled()) { 7062 CDBG_HIGH("%s: need reprocess for |UbiFocus=%d|ChramaFlash=%d|OptiZoom=%d|StillMore=%d|", 7063 __func__, 7064 mParameters.isUbiFocusEnabled(), 7065 mParameters.isChromaFlashEnabled(), 7066 mParameters.isOptiZoomEnabled(), 7067 mParameters.isStillMoreEnabled()); 7068 pthread_mutex_unlock(&m_parm_lock); 7069 return true; 7070 } 7071 7072 pthread_mutex_unlock(&m_parm_lock); 7073 return false; 7074 } 7075 7076 /*=========================================================================== 7077 * FUNCTION : needRotationReprocess 7078 * 7079 * DESCRIPTION: if rotation needs to be done by reprocess in pp 7080 * 7081 * PARAMETERS : none 7082 * 7083 * RETURN : true: needed 7084 * false: no need 7085 *==========================================================================*/ 7086 bool QCamera2HardwareInterface::needRotationReprocess() 7087 { 7088 pthread_mutex_lock(&m_parm_lock); 7089 if (!mParameters.isJpegPictureFormat() && 7090 !mParameters.isNV21PictureFormat()) { 7091 // RAW image, no need to reprocess 7092 pthread_mutex_unlock(&m_parm_lock); 7093 return false; 7094 } 7095 7096 if (mParameters.is4k2kVideoResolution()&& mParameters.getRecordingHintValue()) { 7097 //Disable reprocess for 4K liveshot case 7098 pthread_mutex_unlock(&m_parm_lock); 7099 return false; 7100 } 7101 7102 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 && 7103 (mParameters.getJpegRotation() > 0)) { 7104 // current rotation is not zero, and pp has the capability to process rotation 7105 CDBG_HIGH("%s: need to do reprocess for rotation=%d", 7106 __func__, mParameters.getJpegRotation()); 7107 pthread_mutex_unlock(&m_parm_lock); 7108 return true; 7109 } 7110 7111 pthread_mutex_unlock(&m_parm_lock); 7112 return false; 7113 } 7114 7115 /*=========================================================================== 7116 * FUNCTION : needScaleReprocess 7117 * 7118 * DESCRIPTION: if scale needs to be done by reprocess in pp 7119 * 7120 * PARAMETERS : none 7121 * 7122 * RETURN : true: needed 7123 * false: no need 7124 *==========================================================================*/ 7125 bool QCamera2HardwareInterface::needScaleReprocess() 7126 { 7127 pthread_mutex_lock(&m_parm_lock); 7128 if (!mParameters.isJpegPictureFormat() && 7129 !mParameters.isNV21PictureFormat()) { 7130 // RAW image, no need to reprocess 7131 pthread_mutex_unlock(&m_parm_lock); 7132 return false; 7133 } 7134 7135 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SCALE) > 0 && 7136 mParameters.m_reprocScaleParam.isScaleEnabled() && 7137 mParameters.m_reprocScaleParam.isUnderScaling()) { 7138 // Reproc Scale is enaled and also need Scaling to current Snapshot 7139 CDBG_HIGH("%s: need do reprocess for scale", __func__); 7140 pthread_mutex_unlock(&m_parm_lock); 7141 return true; 7142 } 7143 7144 pthread_mutex_unlock(&m_parm_lock); 7145 return false; 7146 } 7147 7148 /*=========================================================================== 7149 * FUNCTION : getThumbnailSize 7150 * 7151 * DESCRIPTION: get user set thumbnail size 7152 * 7153 * PARAMETERS : 7154 * @dim : output of thumbnail dimension 7155 * 7156 * RETURN : none 7157 *==========================================================================*/ 7158 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim) 7159 { 7160 pthread_mutex_lock(&m_parm_lock); 7161 mParameters.getThumbnailSize(&dim.width, &dim.height); 7162 pthread_mutex_unlock(&m_parm_lock); 7163 } 7164 7165 /*=========================================================================== 7166 * FUNCTION : getJpegQuality 7167 * 7168 * DESCRIPTION: get user set jpeg quality 7169 * 7170 * PARAMETERS : none 7171 * 7172 * RETURN : jpeg quality setting 7173 *==========================================================================*/ 7174 uint32_t QCamera2HardwareInterface::getJpegQuality() 7175 { 7176 uint32_t quality = 0; 7177 pthread_mutex_lock(&m_parm_lock); 7178 quality = mParameters.getJpegQuality(); 7179 pthread_mutex_unlock(&m_parm_lock); 7180 return quality; 7181 } 7182 7183 /*=========================================================================== 7184 * FUNCTION : getExifData 7185 * 7186 * DESCRIPTION: get exif data to be passed into jpeg encoding 7187 * 7188 * PARAMETERS : none 7189 * 7190 * RETURN : exif data from user setting and GPS 7191 *==========================================================================*/ 7192 QCameraExif *QCamera2HardwareInterface::getExifData() 7193 { 7194 QCameraExif *exif = new QCameraExif(); 7195 if (exif == NULL) { 7196 ALOGE("%s: No memory for QCameraExif", __func__); 7197 return NULL; 7198 } 7199 7200 int32_t rc = NO_ERROR; 7201 7202 pthread_mutex_lock(&m_parm_lock); 7203 7204 // add exif entries 7205 String8 dateTime, subSecTime; 7206 rc = mParameters.getExifDateTime(dateTime, subSecTime); 7207 if(rc == NO_ERROR) { 7208 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII, 7209 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 7210 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII, 7211 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 7212 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII, 7213 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string()); 7214 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII, 7215 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 7216 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII, 7217 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 7218 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII, 7219 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string()); 7220 } else { 7221 ALOGE("%s: getExifDateTime failed", __func__); 7222 } 7223 7224 rat_t focalLength; 7225 rc = mParameters.getExifFocalLength(&focalLength); 7226 if (rc == NO_ERROR) { 7227 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 7228 EXIF_RATIONAL, 7229 1, 7230 (void *)&(focalLength)); 7231 } else { 7232 ALOGE("%s: getExifFocalLength failed", __func__); 7233 } 7234 7235 uint16_t isoSpeed = mParameters.getExifIsoSpeed(); 7236 if (getSensorType() != CAM_SENSOR_YUV) { 7237 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 7238 EXIF_SHORT, 7239 1, 7240 (void *)&(isoSpeed)); 7241 } 7242 7243 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 7244 uint32_t count = 0; 7245 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count); 7246 if(rc == NO_ERROR) { 7247 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 7248 EXIF_ASCII, 7249 count, 7250 (void *)gpsProcessingMethod); 7251 } else { 7252 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 7253 } 7254 7255 rat_t latitude[3]; 7256 char latRef[2]; 7257 rc = mParameters.getExifLatitude(latitude, latRef); 7258 if(rc == NO_ERROR) { 7259 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 7260 EXIF_RATIONAL, 7261 3, 7262 (void *)latitude); 7263 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 7264 EXIF_ASCII, 7265 2, 7266 (void *)latRef); 7267 } else { 7268 ALOGE("%s: getExifLatitude failed", __func__); 7269 } 7270 7271 rat_t longitude[3]; 7272 char lonRef[2]; 7273 rc = mParameters.getExifLongitude(longitude, lonRef); 7274 if(rc == NO_ERROR) { 7275 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 7276 EXIF_RATIONAL, 7277 3, 7278 (void *)longitude); 7279 7280 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 7281 EXIF_ASCII, 7282 2, 7283 (void *)lonRef); 7284 } else { 7285 ALOGE("%s: getExifLongitude failed", __func__); 7286 } 7287 7288 rat_t altitude; 7289 char altRef; 7290 rc = mParameters.getExifAltitude(&altitude, &altRef); 7291 if(rc == NO_ERROR) { 7292 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 7293 EXIF_RATIONAL, 7294 1, 7295 (void *)&(altitude)); 7296 7297 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 7298 EXIF_BYTE, 7299 1, 7300 (void *)&altRef); 7301 } else { 7302 ALOGE("%s: getExifAltitude failed", __func__); 7303 } 7304 7305 char gpsDateStamp[20]; 7306 rat_t gpsTimeStamp[3]; 7307 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp); 7308 if(rc == NO_ERROR) { 7309 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 7310 EXIF_ASCII, 7311 (uint32_t)(strlen(gpsDateStamp) + 1), 7312 (void *)gpsDateStamp); 7313 7314 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 7315 EXIF_RATIONAL, 7316 3, 7317 (void *)gpsTimeStamp); 7318 } else { 7319 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 7320 } 7321 7322 #ifdef ENABLE_MODEL_INFO_EXIF 7323 7324 char value[PROPERTY_VALUE_MAX]; 7325 if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 7326 exif->addEntry(EXIFTAGID_MAKE, EXIF_ASCII, 7327 (uint32_t)(strlen(value) + 1), (void *)value); 7328 } else { 7329 ALOGE("%s: getExifMaker failed", __func__); 7330 } 7331 7332 if (property_get("ro.product.model", value, "QCAM-AA") > 0) { 7333 exif->addEntry(EXIFTAGID_MODEL, EXIF_ASCII, 7334 (uint32_t)(strlen(value) + 1), (void *)value); 7335 } else { 7336 ALOGE("%s: getExifModel failed", __func__); 7337 } 7338 7339 if (property_get("ro.build.description", value, "QCAM-AA") > 0) { 7340 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII, 7341 (uint32_t)(strlen(value) + 1), (void *)value); 7342 } else { 7343 ALOGE("%s: getExifSoftware failed", __func__); 7344 } 7345 7346 #endif 7347 7348 if (mParameters.useJpegExifRotation()) { 7349 int16_t orientation; 7350 switch (mParameters.getJpegExifRotation()) { 7351 case 0: 7352 orientation = 1; 7353 break; 7354 case 90: 7355 orientation = 6; 7356 break; 7357 case 180: 7358 orientation = 3; 7359 break; 7360 case 270: 7361 orientation = 8; 7362 break; 7363 default: 7364 orientation = 1; 7365 break; 7366 } 7367 exif->addEntry(EXIFTAGID_ORIENTATION, 7368 EXIF_SHORT, 7369 1, 7370 (void *)&orientation); 7371 exif->addEntry(EXIFTAGID_TN_ORIENTATION, 7372 EXIF_SHORT, 7373 1, 7374 (void *)&orientation); 7375 } 7376 7377 pthread_mutex_unlock(&m_parm_lock); 7378 return exif; 7379 } 7380 7381 /*=========================================================================== 7382 * FUNCTION : setHistogram 7383 * 7384 * DESCRIPTION: set if histogram should be enabled 7385 * 7386 * PARAMETERS : 7387 * @histogram_en : bool flag if histogram should be enabled 7388 * 7389 * RETURN : int32_t type of status 7390 * NO_ERROR -- success 7391 * none-zero failure code 7392 *==========================================================================*/ 7393 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en) 7394 { 7395 return mParameters.setHistogram(histogram_en); 7396 } 7397 7398 /*=========================================================================== 7399 * FUNCTION : setFaceDetection 7400 * 7401 * DESCRIPTION: set if face detection should be enabled 7402 * 7403 * PARAMETERS : 7404 * @enabled : bool flag if face detection should be enabled 7405 * 7406 * RETURN : int32_t type of status 7407 * NO_ERROR -- success 7408 * none-zero failure code 7409 *==========================================================================*/ 7410 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled) 7411 { 7412 return mParameters.setFaceDetection(enabled, true); 7413 } 7414 7415 /*=========================================================================== 7416 * FUNCTION : isCaptureShutterEnabled 7417 * 7418 * DESCRIPTION: Check whether shutter should be triggered immediately after 7419 * capture 7420 * 7421 * PARAMETERS : 7422 * 7423 * RETURN : true - regular capture 7424 * false - other type of capture 7425 *==========================================================================*/ 7426 bool QCamera2HardwareInterface::isCaptureShutterEnabled() 7427 { 7428 char prop[PROPERTY_VALUE_MAX]; 7429 memset(prop, 0, sizeof(prop)); 7430 property_get("persist.camera.feature.shutter", prop, "0"); 7431 int enableShutter = atoi(prop); 7432 return enableShutter == 1; 7433 } 7434 7435 /*=========================================================================== 7436 * FUNCTION : needProcessPreviewFrame 7437 * 7438 * DESCRIPTION: returns whether preview frame need to be displayed 7439 * 7440 * PARAMETERS : 7441 * 7442 * RETURN : int32_t type of status 7443 * NO_ERROR -- success 7444 * none-zero failure code 7445 *==========================================================================*/ 7446 bool QCamera2HardwareInterface::needProcessPreviewFrame() 7447 { 7448 return m_stateMachine.isPreviewRunning() 7449 && mParameters.isDisplayFrameNeeded(); 7450 }; 7451 7452 /*=========================================================================== 7453 * FUNCTION : prepareHardwareForSnapshot 7454 * 7455 * DESCRIPTION: prepare hardware for snapshot, such as LED 7456 * 7457 * PARAMETERS : 7458 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation 7459 * 7460 * RETURN : int32_t type of status 7461 * NO_ERROR -- success 7462 * none-zero failure code 7463 *==========================================================================*/ 7464 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded) 7465 { 7466 ATRACE_CALL(); 7467 CDBG_HIGH("[KPI Perf] %s: Prepare hardware such as LED",__func__); 7468 return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle, 7469 afNeeded); 7470 } 7471 7472 /*=========================================================================== 7473 * FUNCTION : needFDMetadata 7474 * 7475 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel 7476 * 7477 * PARAMETERS : 7478 * @channel_type: channel type 7479 * 7480 * RETURN : true: needed 7481 * false: no need 7482 *==========================================================================*/ 7483 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type) 7484 { 7485 //Note: Currently we only process ZSL channel 7486 bool value = false; 7487 if(channel_type == QCAMERA_CH_TYPE_ZSL){ 7488 //check if FD requirement is enabled 7489 if(mParameters.isSnapshotFDNeeded() && 7490 mParameters.isFaceDetectionEnabled()){ 7491 value = true; 7492 CDBG_HIGH("%s: Face Detection metadata is required in ZSL mode.", __func__); 7493 } 7494 } 7495 7496 return value; 7497 } 7498 7499 /*=========================================================================== 7500 * FUNCTION : defferedWorkRoutine 7501 * 7502 * DESCRIPTION: data process routine that executes deffered tasks 7503 * 7504 * PARAMETERS : 7505 * @data : user data ptr (QCamera2HardwareInterface) 7506 * 7507 * RETURN : None 7508 *==========================================================================*/ 7509 void *QCamera2HardwareInterface::defferedWorkRoutine(void *obj) 7510 { 7511 int running = 1; 7512 int ret; 7513 uint8_t is_active = FALSE; 7514 7515 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj; 7516 QCameraCmdThread *cmdThread = &pme->mDefferedWorkThread; 7517 cmdThread->setName("CAM_defrdWrk"); 7518 7519 do { 7520 do { 7521 ret = cam_sem_wait(&cmdThread->cmd_sem); 7522 if (ret != 0 && errno != EINVAL) { 7523 ALOGE("%s: cam_sem_wait error (%s)", 7524 __func__, strerror(errno)); 7525 return NULL; 7526 } 7527 } while (ret != 0); 7528 7529 // we got notified about new cmd avail in cmd queue 7530 camera_cmd_type_t cmd = cmdThread->getCmd(); 7531 switch (cmd) { 7532 case CAMERA_CMD_TYPE_START_DATA_PROC: 7533 CDBG_HIGH("%s: start data proc", __func__); 7534 is_active = TRUE; 7535 break; 7536 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 7537 CDBG_HIGH("%s: stop data proc", __func__); 7538 is_active = FALSE; 7539 // signal cmd is completed 7540 cam_sem_post(&cmdThread->sync_sem); 7541 break; 7542 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 7543 { 7544 DeffWork *dw = 7545 reinterpret_cast<DeffWork *>(pme->mCmdQueue.dequeue()); 7546 7547 if ( NULL == dw ) { 7548 ALOGE("%s : Invalid deferred work", __func__); 7549 break; 7550 } 7551 7552 switch( dw->cmd ) { 7553 case CMD_DEFF_ALLOCATE_BUFF: 7554 { 7555 QCameraChannel * pChannel = dw->args.allocArgs.ch; 7556 7557 if ( NULL == pChannel ) { 7558 ALOGE("%s : Invalid deferred work channel", 7559 __func__); 7560 break; 7561 } 7562 7563 cam_stream_type_t streamType = dw->args.allocArgs.type; 7564 CDBG_HIGH("%s: Deffered buffer allocation started for stream type: %d", 7565 __func__, streamType); 7566 7567 uint32_t iNumOfStreams = pChannel->getNumOfStreams(); 7568 QCameraStream *pStream = NULL; 7569 for ( uint32_t i = 0; i < iNumOfStreams; ++i) { 7570 pStream = pChannel->getStreamByIndex(i); 7571 7572 if ( NULL == pStream ) { 7573 break; 7574 } 7575 7576 if ( pStream->isTypeOf(streamType)) { 7577 if ( pStream->allocateBuffers() ) { 7578 ALOGE("%s: Error allocating buffers !!!", 7579 __func__); 7580 } 7581 break; 7582 } 7583 } 7584 { 7585 Mutex::Autolock l(pme->mDeffLock); 7586 pme->mDeffOngoingJobs[dw->id] = false; 7587 CDBG_HIGH("%s: Deffered buffer allocation done for stream type: %d", 7588 __func__, streamType); 7589 delete dw; 7590 pme->mDeffCond.signal(); 7591 } 7592 7593 } 7594 break; 7595 case CMD_DEFF_PPROC_START: 7596 { 7597 QCameraChannel * pChannel = dw->args.pprocArgs; 7598 assert(pChannel); 7599 7600 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) { 7601 ALOGE("%s: cannot start postprocessor", __func__); 7602 pme->delChannel(QCAMERA_CH_TYPE_CAPTURE); 7603 } 7604 { 7605 Mutex::Autolock l(pme->mDeffLock); 7606 pme->mDeffOngoingJobs[dw->id] = false; 7607 delete dw; 7608 pme->mDeffCond.broadcast(); 7609 } 7610 } 7611 break; 7612 default: 7613 ALOGE("%s[%d]: Incorrect command : %d", 7614 __func__, 7615 __LINE__, 7616 dw->cmd); 7617 } 7618 } 7619 break; 7620 case CAMERA_CMD_TYPE_EXIT: 7621 running = 0; 7622 break; 7623 default: 7624 break; 7625 } 7626 } while (running); 7627 7628 return NULL; 7629 } 7630 7631 /*=========================================================================== 7632 * FUNCTION : queueDefferedWork 7633 * 7634 * DESCRIPTION: function which queues deferred tasks 7635 * 7636 * PARAMETERS : 7637 * @cmd : deferred task 7638 * @args : deffered task arguments 7639 * 7640 * RETURN : int32_t type of status 7641 * NO_ERROR -- success 7642 * none-zero failure code 7643 *==========================================================================*/ 7644 int32_t QCamera2HardwareInterface::queueDefferedWork(DefferedWorkCmd cmd, 7645 DefferWorkArgs args) 7646 { 7647 Mutex::Autolock l(mDeffLock); 7648 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; ++i) { 7649 if (!mDeffOngoingJobs[i]) { 7650 DeffWork *dw = new DeffWork(cmd, i, args); 7651 if (mCmdQueue.enqueue(dw)) { 7652 mDeffOngoingJobs[i] = true; 7653 mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, 7654 FALSE, 7655 FALSE); 7656 return (int32_t)i; 7657 } else { 7658 CDBG("%s: Command queue not active! cmd = %d", __func__, cmd); 7659 delete dw; 7660 return -1; 7661 } 7662 } 7663 } 7664 return -1; 7665 } 7666 7667 /*=========================================================================== 7668 * FUNCTION : waitDefferedWork 7669 * 7670 * DESCRIPTION: waits for a deffered task to finish 7671 * 7672 * PARAMETERS : 7673 * @job_id : deferred task id 7674 * 7675 * RETURN : int32_t type of status 7676 * NO_ERROR -- success 7677 * none-zero failure code 7678 *==========================================================================*/ 7679 int32_t QCamera2HardwareInterface::waitDefferedWork(int32_t &job_id) 7680 { 7681 Mutex::Autolock l(mDeffLock); 7682 7683 if ((MAX_ONGOING_JOBS <= job_id) || (0 > job_id)) { 7684 return NO_ERROR; 7685 } 7686 7687 while ( mDeffOngoingJobs[job_id] == true ) { 7688 mDeffCond.wait(mDeffLock); 7689 } 7690 7691 return NO_ERROR; 7692 } 7693 7694 /*=========================================================================== 7695 * FUNCTION : isRegularCapture 7696 * 7697 * DESCRIPTION: Check configuration for regular catpure 7698 * 7699 * PARAMETERS : 7700 * 7701 * RETURN : true - regular capture 7702 * false - other type of capture 7703 *==========================================================================*/ 7704 bool QCamera2HardwareInterface::isRegularCapture() 7705 { 7706 bool ret = false; 7707 7708 if (numOfSnapshotsExpected() == 1 && 7709 !isLongshotEnabled() && 7710 !mParameters.isHDREnabled() && 7711 !mParameters.getRecordingHintValue() && 7712 !isZSLMode() && !mParameters.getofflineRAW()) { 7713 ret = true; 7714 } 7715 return ret; 7716 } 7717 7718 /*=========================================================================== 7719 * FUNCTION : getLogLevel 7720 * 7721 * DESCRIPTION: Reads the log level property into a variable 7722 * 7723 * PARAMETERS : 7724 * None 7725 * 7726 * RETURN : 7727 * None 7728 *==========================================================================*/ 7729 void QCamera2HardwareInterface::getLogLevel() 7730 { 7731 char prop[PROPERTY_VALUE_MAX]; 7732 uint32_t globalLogLevel = 0; 7733 7734 property_get("persist.camera.hal.debug", prop, "0"); 7735 int val = atoi(prop); 7736 if (0 <= val) { 7737 gCamHalLogLevel = (uint32_t)val; 7738 } 7739 property_get("persist.camera.global.debug", prop, "0"); 7740 val = atoi(prop); 7741 if (0 <= val) { 7742 globalLogLevel = (uint32_t)val; 7743 } 7744 7745 /* Highest log level among hal.logs and global.logs is selected */ 7746 if (gCamHalLogLevel < globalLogLevel) 7747 gCamHalLogLevel = globalLogLevel; 7748 7749 return; 7750 } 7751 7752 /*=========================================================================== 7753 * FUNCTION : getSensorType 7754 * 7755 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer 7756 * 7757 * PARAMETERS : 7758 * None 7759 * 7760 * RETURN : Type of sensor - bayer or YUV 7761 * 7762 *==========================================================================*/ 7763 cam_sensor_t QCamera2HardwareInterface::getSensorType() 7764 { 7765 return gCamCaps[mCameraId]->sensor_type.sens_type; 7766 } 7767 7768 }; // namespace qcamera 7769