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