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