1 /* 2 ** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 /*#error uncomment this for compiler test!*/ 18 #define ALOG_NIDEBUG 0 19 20 #define LOG_TAG "QCameraHWI" 21 #include <utils/Log.h> 22 #include <utils/threads.h> 23 #include <cutils/properties.h> 24 #include <fcntl.h> 25 #include <sys/mman.h> 26 #include <string.h> 27 #include <dlfcn.h> 28 29 #include "QCameraHAL.h" 30 #include "QCameraHWI.h" 31 32 /* QCameraHardwareInterface class implementation goes here*/ 33 /* following code implement the contol logic of this class*/ 34 35 namespace android { 36 static void HAL_event_cb(mm_camera_event_t *evt, void *user_data) 37 { 38 QCameraHardwareInterface *obj = (QCameraHardwareInterface *)user_data; 39 if (obj) { 40 obj->processEvent(evt); 41 } else { 42 ALOGE("%s: NULL user_data", __func__); 43 } 44 } 45 46 int32_t QCameraHardwareInterface::createRecord() 47 { 48 int32_t ret = MM_CAMERA_OK; 49 ALOGV("%s : BEGIN",__func__); 50 51 /* 52 * Creating Instance of record stream. 53 */ 54 ALOGV("Mymode Record = %d",myMode); 55 mStreamRecord = QCameraStream_record::createInstance(mCameraId, 56 myMode); 57 58 if (!mStreamRecord) { 59 ALOGE("%s: error - can't creat record stream!", __func__); 60 return BAD_VALUE; 61 } 62 63 /* Store HAL object in record stream Object */ 64 mStreamRecord->setHALCameraControl(this); 65 66 /*Init Channel */ 67 ret = mStreamRecord->init(); 68 if (MM_CAMERA_OK != ret){ 69 ALOGE("%s: error - can't init Record channel!", __func__); 70 return BAD_VALUE; 71 } 72 ALOGV("%s : END",__func__); 73 return ret; 74 } 75 76 int32_t QCameraHardwareInterface::createSnapshot() 77 { 78 int32_t ret = MM_CAMERA_OK; 79 ALOGV("%s : BEGIN",__func__); 80 81 /* 82 * Creating Instance of Snapshot stream. 83 */ 84 ALOGV("Mymode Snap = %d",myMode); 85 mStreamSnap = QCameraStream_Snapshot::createInstance(mCameraId, 86 myMode); 87 if (!mStreamSnap) { 88 ALOGE("%s: error - can't creat snapshot stream!", __func__); 89 return BAD_VALUE; 90 } 91 92 /* Store HAL object in Snapshot stream Object */ 93 mStreamSnap->setHALCameraControl(this); 94 95 /*Init Channel */ 96 ret = mStreamSnap->init(); 97 if (MM_CAMERA_OK != ret){ 98 ALOGE("%s: error - can't init Snapshot channel!", __func__); 99 return BAD_VALUE; 100 } 101 ALOGV("%s : END",__func__); 102 return ret; 103 } 104 105 int32_t QCameraHardwareInterface::createPreview() 106 { 107 int32_t ret = MM_CAMERA_OK; 108 ALOGV("%s : BEGIN",__func__); 109 110 ALOGV("Mymode Preview = %d",myMode); 111 mStreamDisplay = QCameraStream_preview::createInstance(mCameraId, 112 myMode); 113 if (!mStreamDisplay) { 114 ALOGE("%s: error - can't creat preview stream!", __func__); 115 return BAD_VALUE; 116 } 117 118 mStreamDisplay->setHALCameraControl(this); 119 120 /*now init all the buffers and send to steam object*/ 121 ret = mStreamDisplay->init(); 122 if (MM_CAMERA_OK != ret){ 123 ALOGE("%s: error - can't init Preview channel!", __func__); 124 return BAD_VALUE; 125 } 126 ALOGV("%s : END",__func__); 127 return ret; 128 } 129 130 /* constructor */ 131 QCameraHardwareInterface:: 132 QCameraHardwareInterface(int cameraId, int mode) 133 : mCameraId(cameraId), 134 mParameters(), 135 mMsgEnabled(0), 136 mNotifyCb(0), 137 mDataCb(0), 138 mDataCbTimestamp(0), 139 mCallbackCookie(0), 140 //mPreviewHeap(0), 141 mStreamDisplay (NULL), mStreamRecord(NULL), mStreamSnap(NULL), 142 mFps(0), 143 mDebugFps(0), 144 mMaxZoom(0), 145 mCurrentZoom(0), 146 mSupportedPictureSizesCount(15), 147 mDumpFrmCnt(0), mDumpSkipCnt(0), 148 mPictureSizeCount(15), 149 mPreviewSizeCount(13), 150 mVideoSizeCount(0), 151 mAutoFocusRunning(false), 152 mNeedToUnlockCaf(false), 153 mHasAutoFocusSupport(false), 154 mInitialized(false), 155 mIs3DModeOn(0), 156 mSmoothZoomRunning(false), 157 mParamStringInitialized(false), 158 mFaceDetectOn(0), 159 mDisEnabled(0), 160 mZoomSupported(false), 161 mFullLiveshotEnabled(false), 162 mRecordingHint(false), 163 mAppRecordingHint(false), 164 mStatsOn(0), mCurrentHisto(-1), mSendData(false), mStatHeap(NULL), 165 mZslLookBackMode(0), 166 mZslLookBackValue(0), 167 mZslEmptyQueueFlag(false), 168 mPictureSizes(NULL), 169 mVideoSizes(NULL), 170 mCameraState(CAMERA_STATE_UNINITED), 171 mPostPreviewHeap(NULL), 172 mHdrMode(HDR_BRACKETING_OFF), 173 mStreamLiveSnap(NULL), 174 mExifTableNumEntries(0), 175 mDenoiseValue(0), 176 mSnapshotFormat(0), 177 mStartRecording(0), 178 mZslInterval(1), 179 mNoDisplayMode(0), 180 mBrightness(0), 181 mContrast(0), 182 mEffects(0), 183 mBestShotMode(0), 184 mHJR(0), 185 mSkinToneEnhancement(0), 186 mRotation(0), 187 mFocusMode(AF_MODE_MAX), 188 mPreviewFormat(CAMERA_YUV_420_NV21), 189 mRestartPreview(false), 190 mReleasedRecordingFrame(false), 191 mStateLiveshot(false), 192 isCameraOpen(false), 193 mPauseFramedispatch(false), 194 mSnapJpegCbRunning(false), 195 mSnapCbDisabled(false) 196 { 197 ALOGV("QCameraHardwareInterface: E"); 198 int32_t result = MM_CAMERA_E_GENERAL; 199 char value[PROPERTY_VALUE_MAX]; 200 201 pthread_mutex_init(&mAsyncCmdMutex, NULL); 202 pthread_cond_init(&mAsyncCmdWait, NULL); 203 mFlashCond = false; 204 205 property_get("persist.debug.sf.showfps", value, "0"); 206 mDebugFps = atoi(value); 207 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 208 mPreviewWindow = NULL; 209 property_get("camera.hal.fps", value, "0"); 210 mFps = atoi(value); 211 212 ALOGV("Init mPreviewState = %d", mPreviewState); 213 214 property_get("persist.camera.hal.multitouchaf", value, "0"); 215 mMultiTouch = atoi(value); 216 217 property_get("persist.camera.full.liveshot", value, "0"); 218 mFullLiveshotEnabled = atoi(value); 219 220 property_get("persist.camera.hal.dis", value, "0"); 221 mDisEnabled = atoi(value); 222 223 /* Open camera stack! */ 224 result=cam_ops_open(mCameraId, MM_CAMERA_OP_MODE_NOTUSED); 225 if (result == MM_CAMERA_OK) { 226 int i; 227 mm_camera_event_type_t evt; 228 for (i = 0; i < MM_CAMERA_EVT_TYPE_MAX; i++) { 229 evt = (mm_camera_event_type_t) i; 230 if (cam_evt_is_event_supported(mCameraId, evt)){ 231 cam_evt_register_event_notify(mCameraId, 232 HAL_event_cb, (void *)this, evt); 233 } 234 } 235 } 236 ALOGV("Cam open returned %d",result); 237 if(MM_CAMERA_OK != result) { 238 ALOGE("startCamera: cam_ops_open failed: id = %d", mCameraId); 239 return; 240 } 241 242 loadTables(); 243 /* Setup Picture Size and Preview size tables */ 244 setPictureSizeTable(); 245 ALOGV("%s: Picture table size: %d", __func__, mPictureSizeCount); 246 ALOGV("%s: Picture table: ", __func__); 247 for(unsigned int i=0; i < mPictureSizeCount;i++) { 248 ALOGV(" %d %d", mPictureSizes[i].width, mPictureSizes[i].height); 249 } 250 251 setPreviewSizeTable(); 252 ALOGV("%s: Preview table size: %d", __func__, mPreviewSizeCount); 253 ALOGV("%s: Preview table: ", __func__); 254 for(unsigned int i=0; i < mPreviewSizeCount;i++) { 255 ALOGV(" %d %d", mPreviewSizes[i].width, mPreviewSizes[i].height); 256 } 257 258 setVideoSizeTable(); 259 ALOGV("%s: Video table size: %d", __func__, mVideoSizeCount); 260 ALOGV("%s: Video table: ", __func__); 261 for(unsigned int i=0; i < mVideoSizeCount;i++) { 262 ALOGV(" %d %d", mVideoSizes[i].width, mVideoSizes[i].height); 263 } 264 265 isCameraOpen = true; 266 /* set my mode - update myMode member variable due to difference in 267 enum definition between upper and lower layer*/ 268 setMyMode(mode); 269 initDefaultParameters(); 270 271 //Create Stream Objects 272 //Preview 273 result = createPreview(); 274 if(result != MM_CAMERA_OK) { 275 ALOGE("%s X: Failed to create Preview Object",__func__); 276 return; 277 } 278 279 //Record 280 result = createRecord(); 281 if(result != MM_CAMERA_OK) { 282 ALOGE("%s X: Failed to create Record Object",__func__); 283 return; 284 } 285 286 //Snapshot 287 result = createSnapshot(); 288 if(result != MM_CAMERA_OK) { 289 ALOGE("%s X: Failed to create Record Object",__func__); 290 return; 291 } 292 mCameraState = CAMERA_STATE_READY; 293 libdnr = dlopen("libmorpho_noise_reduction.so", RTLD_NOW); 294 if (libdnr) { 295 ALOGV("Open MM camera DL libmorpho_noise_reduction loaded at %p & %p ", libdnr); 296 *(void **)&LINK_morpho_DNR_ProcessFrame = dlsym(libdnr, "LINK_mm_camera_morpho_noise_reduction"); 297 } 298 else 299 ALOGE("failed to open libmorpho_noise_reduction"); 300 301 ALOGV("QCameraHardwareInterface: X"); 302 } 303 304 QCameraHardwareInterface::~QCameraHardwareInterface() 305 { 306 ALOGV("~QCameraHardwareInterface: E"); 307 int result; 308 309 switch(mPreviewState) { 310 case QCAMERA_HAL_PREVIEW_STOPPED: 311 break; 312 case QCAMERA_HAL_PREVIEW_START: 313 break; 314 case QCAMERA_HAL_PREVIEW_STARTED: 315 stopPreview(); 316 break; 317 case QCAMERA_HAL_RECORDING_STARTED: 318 stopRecordingInternal(); 319 stopPreview(); 320 break; 321 case QCAMERA_HAL_TAKE_PICTURE: 322 cancelPictureInternal(); 323 break; 324 default: 325 break; 326 } 327 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 328 329 if (isCameraOpen) { 330 freePictureTable(); 331 freeVideoSizeTable(); 332 if(mStatHeap != NULL) { 333 mStatHeap.clear( ); 334 mStatHeap = NULL; 335 } 336 } 337 /*First stop the polling threads*/ 338 ALOGI("%s First stop the polling threads before deleting instances", __func__); 339 cam_ops_stop(mCameraId); 340 /* Join the threads, complete operations and then delete 341 the instances. */ 342 if(mStreamDisplay){ 343 QCameraStream_preview::deleteInstance (mStreamDisplay); 344 mStreamDisplay = NULL; 345 } 346 if(mStreamRecord) { 347 QCameraStream_record::deleteInstance (mStreamRecord); 348 mStreamRecord = NULL; 349 } 350 if(mStreamSnap) { 351 QCameraStream_Snapshot::deleteInstance (mStreamSnap); 352 mStreamSnap = NULL; 353 } 354 if (libdnr != NULL) { 355 dlclose(libdnr); 356 libdnr = NULL; 357 ALOGV("closed libmorpho_noise_reduction.so"); 358 } 359 360 if (mStreamLiveSnap){ 361 QCameraStream_Snapshot::deleteInstance (mStreamLiveSnap); 362 mStreamLiveSnap = NULL; 363 } 364 365 /* Now close the camera after deleting all the instances */ 366 cam_ops_close(mCameraId); 367 pthread_mutex_destroy(&mAsyncCmdMutex); 368 pthread_cond_destroy(&mAsyncCmdWait); 369 isCameraOpen = false; 370 371 ALOGV("~QCameraHardwareInterface: X"); 372 } 373 374 bool QCameraHardwareInterface::isCameraReady() 375 { 376 ALOGV("isCameraReady mCameraState %d", mCameraState); 377 return (mCameraState == CAMERA_STATE_READY); 378 } 379 380 void QCameraHardwareInterface::release() 381 { 382 ALOGV("release: E"); 383 Mutex::Autolock l(&mLock); 384 385 switch(mPreviewState) { 386 case QCAMERA_HAL_PREVIEW_STOPPED: 387 break; 388 case QCAMERA_HAL_PREVIEW_START: 389 break; 390 case QCAMERA_HAL_PREVIEW_STARTED: 391 stopPreviewInternal(); 392 break; 393 case QCAMERA_HAL_RECORDING_STARTED: 394 stopRecordingInternal(); 395 stopPreviewInternal(); 396 break; 397 case QCAMERA_HAL_TAKE_PICTURE: 398 cancelPictureInternal(); 399 break; 400 default: 401 break; 402 } 403 #if 0 404 if (isRecordingRunning()) { 405 stopRecordingInternal(); 406 ALOGI("release: stopRecordingInternal done."); 407 } 408 if (isPreviewRunning()) { 409 stopPreview(); //stopPreviewInternal(); 410 ALOGI("release: stopPreviewInternal done."); 411 } 412 if (isSnapshotRunning()) { 413 cancelPictureInternal(); 414 ALOGI("release: cancelPictureInternal done."); 415 } 416 if (mCameraState == CAMERA_STATE_ERROR) { 417 //TBD: If Error occurs then tear down 418 ALOGI("release: Tear down."); 419 } 420 #endif 421 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 422 ALOGV("release: X"); 423 } 424 425 void QCameraHardwareInterface::setCallbacks( 426 camera_notify_callback notify_cb, 427 camera_data_callback data_cb, 428 camera_data_timestamp_callback data_cb_timestamp, 429 camera_request_memory get_memory, 430 void *user) 431 { 432 ALOGV("setCallbacks: E"); 433 Mutex::Autolock lock(mLock); 434 mNotifyCb = notify_cb; 435 mDataCb = data_cb; 436 mDataCbTimestamp = data_cb_timestamp; 437 mGetMemory = get_memory; 438 mCallbackCookie = user; 439 ALOGV("setCallbacks: X"); 440 } 441 442 void QCameraHardwareInterface::enableMsgType(int32_t msgType) 443 { 444 ALOGV("enableMsgType: E, msgType =0x%x", msgType); 445 Mutex::Autolock lock(mLock); 446 mMsgEnabled |= msgType; 447 ALOGV("enableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled); 448 } 449 450 void QCameraHardwareInterface::disableMsgType(int32_t msgType) 451 { 452 ALOGV("disableMsgType: E"); 453 Mutex::Autolock lock(mLock); 454 mMsgEnabled &= ~msgType; 455 ALOGV("disableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled); 456 } 457 458 int QCameraHardwareInterface::msgTypeEnabled(int32_t msgType) 459 { 460 ALOGV("msgTypeEnabled: E"); 461 Mutex::Autolock lock(mLock); 462 return (mMsgEnabled & msgType); 463 ALOGV("msgTypeEnabled: X"); 464 } 465 #if 0 466 status_t QCameraHardwareInterface::dump(int fd, const Vector<String16>& args) const 467 { 468 ALOGI("dump: E"); 469 const size_t SIZE = 256; 470 char buffer[SIZE]; 471 String8 result; 472 AutoMutex lock(&mLock); 473 write(fd, result.string(), result.size()); 474 ALOGI("dump: E"); 475 return NO_ERROR; 476 } 477 #endif 478 479 int QCameraHardwareInterface::dump(int fd) 480 { 481 ALOGE("%s: not supported yet", __func__); 482 return -1; 483 } 484 485 status_t QCameraHardwareInterface::sendCommand(int32_t command, int32_t arg1, 486 int32_t arg2) 487 { 488 ALOGV("sendCommand: E"); 489 status_t rc = NO_ERROR; 490 Mutex::Autolock l(&mLock); 491 492 switch (command) { 493 case CAMERA_CMD_START_FACE_DETECTION: 494 if(supportsFaceDetection() == false){ 495 ALOGE("Face detection support is not available"); 496 return NO_ERROR; 497 } 498 setFaceDetection("on"); 499 return runFaceDetection(); 500 case CAMERA_CMD_STOP_FACE_DETECTION: 501 if(supportsFaceDetection() == false){ 502 ALOGE("Face detection support is not available"); 503 return NO_ERROR; 504 } 505 setFaceDetection("off"); 506 return runFaceDetection(); 507 508 #if 0 509 case CAMERA_CMD_HISTOGRAM_ON: 510 ALOGE("histogram set to on"); 511 rc = setHistogram(1); 512 break; 513 case CAMERA_CMD_HISTOGRAM_OFF: 514 ALOGE("histogram set to off"); 515 rc = setHistogram(0); 516 break; 517 case CAMERA_CMD_HISTOGRAM_SEND_DATA: 518 ALOGE("histogram send data"); 519 mSendData = true; 520 rc = NO_ERROR; 521 break; 522 case CAMERA_CMD_SEND_META_DATA: 523 mMetaDataWaitLock.lock(); 524 if(mFaceDetectOn == true) { 525 mSendMetaData = true; 526 } 527 mMetaDataWaitLock.unlock(); 528 return NO_ERROR; 529 #endif 530 #if 0 /* To Do: will enable it later */ 531 case CAMERA_CMD_START_SMOOTH_ZOOM : 532 ALOGV("HAL sendcmd start smooth zoom %d %d", arg1 , arg2); 533 /*TO DO: get MaxZoom from parameter*/ 534 int MaxZoom = 100; 535 536 switch(mCameraState ) { 537 case CAMERA_STATE_PREVIEW: 538 case CAMERA_STATE_RECORD_CMD_SENT: 539 case CAMERA_STATE_RECORD: 540 mTargetSmoothZoom = arg1; 541 mCurrentZoom = mParameters.getInt("zoom"); 542 mSmoothZoomStep = (mCurrentZoom > mTargetSmoothZoom)? -1: 1; 543 if(mCurrentZoom == mTargetSmoothZoom) { 544 ALOGV("Smoothzoom target zoom value is same as " 545 "current zoom value, return..."); 546 mNotifyCallback(CAMERA_MSG_ZOOM, 547 mCurrentZoom, 1, mCallbackCookie); 548 } else if(mCurrentZoom < 0 || mCurrentZoom > MaxZoom || 549 mTargetSmoothZoom < 0 || mTargetSmoothZoom > MaxZoom) { 550 ALOGE(" ERROR : beyond supported zoom values, break.."); 551 mNotifyCallback(CAMERA_MSG_ZOOM, 552 mCurrentZoom, 0, mCallbackCookie); 553 } else { 554 mSmoothZoomRunning = true; 555 mCurrentZoom += mSmoothZoomStep; 556 if ((mSmoothZoomStep < 0 && mCurrentZoom < mTargetSmoothZoom)|| 557 (mSmoothZoomStep > 0 && mCurrentZoom > mTargetSmoothZoom )) { 558 mCurrentZoom = mTargetSmoothZoom; 559 } 560 mParameters.set("zoom", mCurrentZoom); 561 setZoom(mParameters); 562 } 563 break; 564 default: 565 ALOGV(" No preview, no smoothzoom "); 566 break; 567 } 568 rc = NO_ERROR; 569 break; 570 571 case CAMERA_CMD_STOP_SMOOTH_ZOOM: 572 if(mSmoothZoomRunning) { 573 mSmoothZoomRunning = false; 574 /*To Do: send cmd to stop zooming*/ 575 } 576 ALOGV("HAL sendcmd stop smooth zoom"); 577 rc = NO_ERROR; 578 break; 579 #endif 580 default: 581 break; 582 } 583 ALOGV("sendCommand: X"); 584 return rc; 585 } 586 587 void QCameraHardwareInterface::setMyMode(int mode) 588 { 589 ALOGV("setMyMode: E"); 590 //if (mode & CAMERA_SUPPORT_MODE_3D) { 591 // myMode = CAMERA_MODE_3D; 592 //}else { 593 /* default mode is 2D */ 594 myMode = CAMERA_MODE_2D; 595 //} 596 597 //if (mode & CAMERA_SUPPORT_MODE_ZSL) { 598 // myMode = (camera_mode_t)(myMode |CAMERA_ZSL_MODE); 599 //}else { 600 myMode = (camera_mode_t) (myMode | CAMERA_NONZSL_MODE); 601 //} 602 ALOGV("setMyMode: Set mode to %d (passed mode: %d)", myMode, mode); 603 ALOGV("setMyMode: X"); 604 } 605 /* static factory function */ 606 QCameraHardwareInterface *QCameraHardwareInterface::createInstance(int cameraId, int mode) 607 { 608 ALOGV("createInstance: E"); 609 QCameraHardwareInterface *cam = new QCameraHardwareInterface(cameraId, mode); 610 if (cam ) { 611 if (cam->mCameraState != CAMERA_STATE_READY) { 612 ALOGE("createInstance: Failed"); 613 delete cam; 614 cam = NULL; 615 } 616 } 617 618 if (cam) { 619 //sp<CameraHardwareInterface> hardware(cam); 620 ALOGV("createInstance: X"); 621 return cam; 622 } else { 623 return NULL; 624 } 625 } 626 /* external plug in function */ 627 extern "C" void * 628 QCameraHAL_openCameraHardware(int cameraId, int mode) 629 { 630 ALOGV("QCameraHAL_openCameraHardware: E"); 631 return (void *) QCameraHardwareInterface::createInstance(cameraId, mode); 632 } 633 634 bool QCameraHardwareInterface::isPreviewRunning() { 635 ALOGV("isPreviewRunning: E"); 636 bool ret = false; 637 ALOGV("isPreviewRunning: camera state:%d", mCameraState); 638 639 if((mCameraState == CAMERA_STATE_PREVIEW) || 640 (mCameraState == CAMERA_STATE_PREVIEW_START_CMD_SENT) || 641 (mCameraState == CAMERA_STATE_RECORD) || 642 (mCameraState == CAMERA_STATE_RECORD_START_CMD_SENT) || 643 (mCameraState == CAMERA_STATE_ZSL) || 644 (mCameraState == CAMERA_STATE_ZSL_START_CMD_SENT)){ 645 return true; 646 } 647 ALOGV("isPreviewRunning: X"); 648 return ret; 649 } 650 651 bool QCameraHardwareInterface::isRecordingRunning() { 652 ALOGV("isRecordingRunning: E"); 653 bool ret = false; 654 if(QCAMERA_HAL_RECORDING_STARTED == mPreviewState) 655 ret = true; 656 //if((mCameraState == CAMERA_STATE_RECORD) || 657 // (mCameraState == CAMERA_STATE_RECORD_START_CMD_SENT)) { 658 // return true; 659 //} 660 ALOGV("isRecordingRunning: X"); 661 return ret; 662 } 663 664 bool QCameraHardwareInterface::isSnapshotRunning() { 665 ALOGV("isSnapshotRunning: E"); 666 bool ret = false; 667 //if((mCameraState == CAMERA_STATE_SNAP_CMD_ACKED) || 668 // (mCameraState == CAMERA_STATE_SNAP_START_CMD_SENT)) { 669 // return true; 670 //} 671 switch(mPreviewState) { 672 case QCAMERA_HAL_PREVIEW_STOPPED: 673 case QCAMERA_HAL_PREVIEW_START: 674 case QCAMERA_HAL_PREVIEW_STARTED: 675 case QCAMERA_HAL_RECORDING_STARTED: 676 default: 677 break; 678 case QCAMERA_HAL_TAKE_PICTURE: 679 ret = true; 680 break; 681 } 682 ALOGV("isSnapshotRunning: X"); 683 return ret; 684 } 685 686 bool QCameraHardwareInterface::isZSLMode() { 687 return (myMode & CAMERA_ZSL_MODE); 688 } 689 690 int QCameraHardwareInterface::getHDRMode() { 691 return mHdrMode; 692 } 693 694 void QCameraHardwareInterface::debugShowPreviewFPS() const 695 { 696 static int mFrameCount; 697 static int mLastFrameCount = 0; 698 static nsecs_t mLastFpsTime = 0; 699 static float mFps = 0; 700 mFrameCount++; 701 nsecs_t now = systemTime(); 702 nsecs_t diff = now - mLastFpsTime; 703 if (diff > ms2ns(250)) { 704 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 705 ALOGV("Preview Frames Per Second: %.4f", mFps); 706 mLastFpsTime = now; 707 mLastFrameCount = mFrameCount; 708 } 709 } 710 711 void QCameraHardwareInterface:: 712 processPreviewChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) { 713 ALOGV("processPreviewChannelEvent: E"); 714 switch(channelEvent) { 715 case MM_CAMERA_CH_EVT_STREAMING_ON: 716 mCameraState = 717 isZSLMode() ? CAMERA_STATE_ZSL : CAMERA_STATE_PREVIEW; 718 break; 719 case MM_CAMERA_CH_EVT_STREAMING_OFF: 720 mCameraState = CAMERA_STATE_READY; 721 break; 722 case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE: 723 break; 724 default: 725 break; 726 } 727 ALOGV("processPreviewChannelEvent: X"); 728 return; 729 } 730 731 void QCameraHardwareInterface::processRecordChannelEvent( 732 mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) { 733 ALOGV("processRecordChannelEvent: E"); 734 switch(channelEvent) { 735 case MM_CAMERA_CH_EVT_STREAMING_ON: 736 mCameraState = CAMERA_STATE_RECORD; 737 break; 738 case MM_CAMERA_CH_EVT_STREAMING_OFF: 739 mCameraState = CAMERA_STATE_PREVIEW; 740 break; 741 case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE: 742 break; 743 default: 744 break; 745 } 746 ALOGV("processRecordChannelEvent: X"); 747 return; 748 } 749 750 void QCameraHardwareInterface:: 751 processSnapshotChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) { 752 ALOGV("processSnapshotChannelEvent: E evt=%d state=%d", channelEvent, 753 mCameraState); 754 switch(channelEvent) { 755 case MM_CAMERA_CH_EVT_STREAMING_ON: 756 if (!mStateLiveshot) { 757 mCameraState = 758 isZSLMode() ? CAMERA_STATE_ZSL : CAMERA_STATE_SNAP_CMD_ACKED; 759 } 760 break; 761 case MM_CAMERA_CH_EVT_STREAMING_OFF: 762 if (!mStateLiveshot) { 763 mCameraState = CAMERA_STATE_READY; 764 } 765 break; 766 case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE: 767 break; 768 case MM_CAMERA_CH_EVT_DATA_REQUEST_MORE: 769 if (isZSLMode()) { 770 /* ZSL Mode: In ZSL Burst Mode, users may request for number of 771 snapshots larger than internal size of ZSL queue. So we'll need 772 process the remaining frames as they become available. 773 In such case, we'll get this event */ 774 if(NULL != mStreamSnap) 775 mStreamSnap->takePictureZSL(); 776 } 777 break; 778 default: 779 break; 780 } 781 ALOGV("processSnapshotChannelEvent: X"); 782 return; 783 } 784 785 void QCameraHardwareInterface::processChannelEvent( 786 mm_camera_ch_event_t *event, app_notify_cb_t *app_cb) 787 { 788 ALOGV("processChannelEvent: E"); 789 Mutex::Autolock lock(mLock); 790 switch(event->ch) { 791 case MM_CAMERA_CH_PREVIEW: 792 processPreviewChannelEvent(event->evt, app_cb); 793 break; 794 case MM_CAMERA_CH_VIDEO: 795 processRecordChannelEvent(event->evt, app_cb); 796 break; 797 case MM_CAMERA_CH_SNAPSHOT: 798 processSnapshotChannelEvent(event->evt, app_cb); 799 break; 800 default: 801 break; 802 } 803 ALOGV("processChannelEvent: X"); 804 return; 805 } 806 807 void QCameraHardwareInterface::processCtrlEvent(mm_camera_ctrl_event_t *event, app_notify_cb_t *app_cb) 808 { 809 ALOGV("processCtrlEvent: %d, E",event->evt); 810 Mutex::Autolock lock(mLock); 811 switch(event->evt) 812 { 813 case MM_CAMERA_CTRL_EVT_ZOOM_DONE: 814 zoomEvent(&event->status, app_cb); 815 break; 816 case MM_CAMERA_CTRL_EVT_AUTO_FOCUS_DONE: 817 autoFocusEvent(&event->status, app_cb); 818 break; 819 case MM_CAMERA_CTRL_EVT_AUTO_FOCUS_MOVE: 820 autoFocusMoveEvent(&event->status, app_cb); 821 break; 822 case MM_CAMERA_CTRL_EVT_PREP_SNAPSHOT: 823 break; 824 case MM_CAMERA_CTRL_EVT_WDN_DONE: 825 wdenoiseEvent(event->status, (void *)(event->cookie)); 826 break; 827 case MM_CAMERA_CTRL_EVT_HDR_DONE: 828 hdrEvent(event->status, (void *)(event->cookie)); 829 break; 830 case MM_CAMERA_CTRL_EVT_ERROR: 831 app_cb->notifyCb = mNotifyCb; 832 app_cb->argm_notify.msg_type = CAMERA_MSG_ERROR; 833 app_cb->argm_notify.ext1 = CAMERA_ERROR_UNKNOWN; 834 app_cb->argm_notify.cookie = mCallbackCookie; 835 break; 836 case MM_CAMERA_CTRL_EVT_SNAPSHOT_CONFIG_DONE: 837 ALOGV("%s: MM_CAMERA_CTRL_EVT_SNAPSHOT_CONFIG_DONE", __func__); 838 app_cb->notifyCb = mNotifyCb; 839 app_cb->argm_notify.msg_type = CAMERA_MSG_SHUTTER; 840 app_cb->argm_notify.ext1 = 0; 841 app_cb->argm_notify.ext2 = true; 842 app_cb->argm_notify.cookie = mCallbackCookie; 843 mShutterSoundPlayed = true; 844 default: 845 break; 846 } 847 ALOGV("processCtrlEvent: X"); 848 return; 849 } 850 851 void QCameraHardwareInterface::processStatsEvent( 852 mm_camera_stats_event_t *event, app_notify_cb_t *app_cb) 853 { 854 ALOGV("processStatsEvent: E"); 855 if (!isPreviewRunning( )) { 856 ALOGE("preview is not running"); 857 return; 858 } 859 860 switch (event->event_id) { 861 862 case MM_CAMERA_STATS_EVT_HISTO: 863 { 864 #if 0 865 ALOGE("HAL process Histo: mMsgEnabled=0x%x, mStatsOn=%d, mSendData=%d, mDataCb=%p ", 866 (mMsgEnabled & CAMERA_MSG_STATS_DATA), mStatsOn, mSendData, mDataCb); 867 int msgEnabled = mMsgEnabled; 868 /*get stats buffer based on index*/ 869 camera_preview_histogram_info* hist_info = 870 (camera_preview_histogram_info*) mHistServer.camera_memory[event->e.stats_histo.index]->data; 871 872 if(mStatsOn == QCAMERA_PARM_ENABLE && mSendData && 873 mDataCb && (msgEnabled & CAMERA_MSG_STATS_DATA) ) { 874 uint32_t *dest; 875 mSendData = false; 876 mCurrentHisto = (mCurrentHisto + 1) % 3; 877 // The first element of the array will contain the maximum hist value provided by driver. 878 *(uint32_t *)((unsigned int)(mStatsMapped[mCurrentHisto]->data)) = hist_info->max_value; 879 memcpy((uint32_t *)((unsigned int)mStatsMapped[mCurrentHisto]->data + sizeof(int32_t)), 880 (uint32_t *)hist_info->buffer,(sizeof(int32_t) * 256)); 881 882 app_cb->dataCb = mDataCb; 883 app_cb->argm_data_cb.msg_type = CAMERA_MSG_STATS_DATA; 884 app_cb->argm_data_cb.data = mStatsMapped[mCurrentHisto]; 885 app_cb->argm_data_cb.index = 0; 886 app_cb->argm_data_cb.metadata = NULL; 887 app_cb->argm_data_cb.cookie = mCallbackCookie; 888 } 889 #endif 890 break; 891 892 } 893 default: 894 break; 895 } 896 ALOGV("receiveCameraStats X"); 897 } 898 899 void QCameraHardwareInterface::processInfoEvent( 900 mm_camera_info_event_t *event, app_notify_cb_t *app_cb) { 901 ALOGV("processInfoEvent: %d, E",event->event_id); 902 //Mutex::Autolock lock(eventLock); 903 switch(event->event_id) 904 { 905 case MM_CAMERA_INFO_EVT_ROI: 906 roiEvent(event->e.roi, app_cb); 907 break; 908 default: 909 break; 910 } 911 ALOGV("processInfoEvent: X"); 912 return; 913 } 914 915 void QCameraHardwareInterface::processEvent(mm_camera_event_t *event) 916 { 917 app_notify_cb_t app_cb; 918 ALOGV("processEvent: type :%d E",event->event_type); 919 if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED){ 920 ALOGV("Stop recording issued. Return from process Event"); 921 return; 922 } 923 memset(&app_cb, 0, sizeof(app_notify_cb_t)); 924 switch(event->event_type) 925 { 926 case MM_CAMERA_EVT_TYPE_CH: 927 processChannelEvent(&event->e.ch, &app_cb); 928 break; 929 case MM_CAMERA_EVT_TYPE_CTRL: 930 processCtrlEvent(&event->e.ctrl, &app_cb); 931 break; 932 case MM_CAMERA_EVT_TYPE_STATS: 933 processStatsEvent(&event->e.stats, &app_cb); 934 break; 935 case MM_CAMERA_EVT_TYPE_INFO: 936 processInfoEvent(&event->e.info, &app_cb); 937 break; 938 default: 939 break; 940 } 941 ALOGV(" App_cb Notify %p, datacb=%p", app_cb.notifyCb, app_cb.dataCb); 942 if (app_cb.notifyCb) { 943 app_cb.notifyCb(app_cb.argm_notify.msg_type, 944 app_cb.argm_notify.ext1, app_cb.argm_notify.ext2, 945 app_cb.argm_notify.cookie); 946 } 947 if (app_cb.dataCb) { 948 app_cb.dataCb(app_cb.argm_data_cb.msg_type, 949 app_cb.argm_data_cb.data, app_cb.argm_data_cb.index, 950 app_cb.argm_data_cb.metadata, app_cb.argm_data_cb.cookie); 951 } 952 ALOGV("processEvent: X"); 953 return; 954 } 955 956 bool QCameraHardwareInterface::preview_parm_config (cam_ctrl_dimension_t* dim, 957 QCameraParameters& parm) 958 { 959 ALOGV("preview_parm_config: E"); 960 bool matching = true; 961 int display_width = 0; /* width of display */ 962 int display_height = 0; /* height of display */ 963 uint16_t video_width = 0; /* width of the video */ 964 uint16_t video_height = 0; /* height of the video */ 965 966 /* First check if the preview resolution is the same, if not, change it*/ 967 parm.getPreviewSize(&display_width, &display_height); 968 if (display_width && display_height) { 969 matching = (display_width == dim->display_width) && 970 (display_height == dim->display_height); 971 972 if (!matching) { 973 dim->display_width = display_width; 974 dim->display_height = display_height; 975 } 976 } 977 else 978 matching = false; 979 980 cam_format_t value = getPreviewFormat(); 981 982 if(value != NOT_FOUND && value != dim->prev_format ) { 983 //Setting to Parameter requested by the Upper layer 984 dim->prev_format = value; 985 } else if (value == NOT_FOUND) { 986 //Setting to default Format. 987 dim->prev_format = CAMERA_YUV_420_NV21; 988 } 989 mPreviewFormat = dim->prev_format; 990 991 dim->prev_padding_format = getPreviewPadding( ); 992 993 dim->enc_format = CAMERA_YUV_420_NV12; 994 dim->orig_video_width = mDimension.orig_video_width; 995 dim->orig_video_height = mDimension.orig_video_height; 996 dim->video_width = mDimension.video_width; 997 dim->video_height = mDimension.video_height; 998 dim->video_chroma_width = mDimension.video_width; 999 dim->video_chroma_height = mDimension.video_height; 1000 /* Reset the Main image and thumbnail formats here, 1001 * since they might have been changed when video size 1002 * livesnapshot was taken. */ 1003 if (mSnapshotFormat == 1) 1004 dim->main_img_format = CAMERA_YUV_422_NV61; 1005 else 1006 dim->main_img_format = CAMERA_YUV_420_NV21; 1007 dim->thumb_format = CAMERA_YUV_420_NV21; 1008 ALOGV("preview_parm_config: X"); 1009 return matching; 1010 } 1011 1012 status_t QCameraHardwareInterface::startPreview() 1013 { 1014 status_t retVal = NO_ERROR; 1015 1016 ALOGV("%s: mPreviewState =%d", __func__, mPreviewState); 1017 Mutex::Autolock lock(mLock); 1018 1019 if(mPauseFramedispatch){ 1020 //In ZSL case after snapshot we need to restart 1021 //if stop preview not issued. 1022 stopPreviewInternal(); 1023 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 1024 mPauseFramedispatch = false; 1025 } 1026 1027 switch(mPreviewState) { 1028 case QCAMERA_HAL_PREVIEW_STOPPED: 1029 case QCAMERA_HAL_TAKE_PICTURE: 1030 mPreviewState = QCAMERA_HAL_PREVIEW_START; 1031 ALOGV("%s: HAL::startPreview begin", __func__); 1032 1033 if(QCAMERA_HAL_PREVIEW_START == mPreviewState && 1034 (mPreviewWindow || isNoDisplayMode())) { 1035 ALOGD("%s: start preview now", __func__); 1036 retVal = startPreview2(); 1037 if(retVal == NO_ERROR) 1038 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 1039 } else { 1040 ALOGV("%s: received startPreview, but preview window = null", __func__); 1041 } 1042 break; 1043 case QCAMERA_HAL_PREVIEW_START: 1044 case QCAMERA_HAL_PREVIEW_STARTED: 1045 break; 1046 case QCAMERA_HAL_RECORDING_STARTED: 1047 ALOGV("%s: cannot start preview in recording state", __func__); 1048 break; 1049 default: 1050 ALOGE("%s: unknow state %d received", __func__, mPreviewState); 1051 retVal = UNKNOWN_ERROR; 1052 break; 1053 } 1054 return retVal; 1055 } 1056 1057 status_t QCameraHardwareInterface::startPreview2() 1058 { 1059 ALOGV("startPreview2: E"); 1060 status_t ret = NO_ERROR; 1061 1062 cam_ctrl_dimension_t dim; 1063 mm_camera_dimension_t maxDim; 1064 bool initPreview = false; 1065 1066 mPauseFramedispatch = false; 1067 if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED) { //isPreviewRunning()){ 1068 ALOGE("%s:Preview already started mCameraState = %d!", __func__, mCameraState); 1069 ALOGV("%s: X", __func__); 1070 return NO_ERROR; 1071 } 1072 1073 const char *str = mParameters.get(QCameraParameters::KEY_SCENE_MODE); 1074 1075 if (mRecordingHint || mFlashCond || !strcmp(str, "hdr")) { 1076 ALOGI("%s:Setting non-ZSL mode",__func__); 1077 mParameters.set(QCameraParameters::KEY_CAMERA_MODE, 0); 1078 myMode = (camera_mode_t)(myMode & ~CAMERA_ZSL_MODE); 1079 mParameters.setPreviewFrameRateMode("frame-rate-auto"); 1080 setPreviewFrameRateMode(mParameters); 1081 } else { 1082 ALOGI("%s:Setting ZSL mode",__func__); 1083 mParameters.set(QCameraParameters::KEY_CAMERA_MODE, 1); 1084 myMode = (camera_mode_t)(myMode | CAMERA_ZSL_MODE); 1085 mParameters.setPreviewFrameRateMode("frame-rate-auto"); 1086 setPreviewFrameRateMode(mParameters); 1087 1088 } 1089 1090 /* get existing preview information, by qury mm_camera*/ 1091 memset(&dim, 0, sizeof(cam_ctrl_dimension_t)); 1092 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim); 1093 1094 if (MM_CAMERA_OK != ret) { 1095 ALOGE("%s: error - can't get preview dimension!", __func__); 1096 ALOGV("%s: X", __func__); 1097 return BAD_VALUE; 1098 } 1099 1100 /* config the parmeters and see if we need to re-init the stream*/ 1101 initPreview = preview_parm_config (&dim, mParameters); 1102 1103 if (mRecordingHint && mFullLiveshotEnabled) { 1104 #if 0 1105 /* Camcorder mode and Full resolution liveshot enabled 1106 * TBD lookup table for correct aspect ratio matching size */ 1107 memset(&maxDim, 0, sizeof(mm_camera_dimension_t)); 1108 getMaxPictureDimension(&maxDim); 1109 if (!maxDim.width || !maxDim.height) { 1110 maxDim.width = DEFAULT_LIVESHOT_WIDTH; 1111 maxDim.height = DEFAULT_LIVESHOT_HEIGHT; 1112 } 1113 /* TODO Remove this hack after adding code to get live shot dimension */ 1114 if (!mCameraId) { 1115 maxDim.width = DEFAULT_LIVESHOT_WIDTH; 1116 maxDim.height = DEFAULT_LIVESHOT_HEIGHT; 1117 } 1118 dim.picture_width = maxDim.width; 1119 dim.picture_height = maxDim.height; 1120 mParameters.setPictureSize(dim.picture_width, dim.picture_height); 1121 ALOGI("%s Setting Liveshot dimension as %d x %d", __func__, 1122 maxDim.width, maxDim.height); 1123 #endif 1124 int mPictureWidth, mPictureHeight; 1125 bool matching; 1126 /* First check if the picture resolution is the same, if not, change it*/ 1127 getPictureSize(&mPictureWidth, &mPictureHeight); 1128 1129 matching = (mPictureWidth == dim.picture_width) && 1130 (mPictureHeight == dim.picture_height); 1131 1132 if (!matching) { 1133 dim.picture_width = mPictureWidth; 1134 dim.picture_height = mPictureHeight; 1135 //For FullSize snapshot Main image Buffer is used as Thumanail. 1136 dim.ui_thumbnail_height = mPictureWidth; 1137 dim.ui_thumbnail_width = mPictureHeight; 1138 } 1139 ALOGI("%s: Fullsize Liveshaot Picture size to set: %d x %d", __func__, 1140 dim.picture_width, dim.picture_height); 1141 mParameters.setPictureSize(dim.picture_width, dim.picture_height); 1142 } 1143 1144 ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim); 1145 if (MM_CAMERA_OK != ret) { 1146 ALOGE("%s X: error - can't config preview parms!", __func__); 1147 return BAD_VALUE; 1148 } 1149 1150 mStreamDisplay->setMode(myMode & CAMERA_ZSL_MODE); 1151 mStreamSnap->setMode(myMode & CAMERA_ZSL_MODE); 1152 mStreamRecord->setMode(myMode & CAMERA_ZSL_MODE); 1153 ALOGV("%s: myMode = %d", __func__, myMode); 1154 1155 ALOGV("%s: setPreviewWindow", __func__); 1156 mStreamDisplay->setPreviewWindow(mPreviewWindow); 1157 ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_INFORM_STARTPRVIEW, NULL); 1158 if(ret<0) 1159 { 1160 ALOGE("%s: Failed to Check MM_CAMERA_PARM_INFORM_STARTPRVIEW, rc %d", __func__, ret); 1161 } 1162 1163 if(isZSLMode()) { 1164 /* Start preview streaming */ 1165 ret = mStreamDisplay->start(); 1166 if (MM_CAMERA_OK != ret){ 1167 ALOGE("%s: X -error - can't start nonZSL stream!", __func__); 1168 return BAD_VALUE; 1169 } 1170 1171 /* Start ZSL stream */ 1172 ret = mStreamSnap->start(); 1173 if (MM_CAMERA_OK != ret){ 1174 ALOGE("%s: error - can't start Snapshot stream!", __func__); 1175 mStreamDisplay->stop(); 1176 return BAD_VALUE; 1177 } 1178 }else{ 1179 ret = mStreamDisplay->start(); 1180 } 1181 1182 /*call QCameraStream_noneZSL::start() */ 1183 if (MM_CAMERA_OK != ret){ 1184 ALOGE("%s: X error - can't start stream!", __func__); 1185 return BAD_VALUE; 1186 } 1187 if(MM_CAMERA_OK == ret) 1188 mCameraState = CAMERA_STATE_PREVIEW_START_CMD_SENT; 1189 else 1190 mCameraState = CAMERA_STATE_ERROR; 1191 1192 if(mPostPreviewHeap != NULL) { 1193 mPostPreviewHeap.clear(); 1194 mPostPreviewHeap = NULL; 1195 } 1196 1197 mRestartPreview = false; 1198 1199 ALOGV("startPreview: X"); 1200 return ret; 1201 } 1202 1203 void QCameraHardwareInterface::stopPreview() 1204 { 1205 ALOGV("%s: stopPreview: E", __func__); 1206 Mutex::Autolock lock(mLock); 1207 mm_camera_util_profile("HAL: stopPreview(): E"); 1208 mFaceDetectOn = false; 1209 1210 // reset recording hint to the value passed from Apps 1211 const char * str = mParameters.get(QCameraParameters::KEY_RECORDING_HINT); 1212 if((str != NULL) && !strcmp(str, "true")){ 1213 mRecordingHint = true; 1214 } else { 1215 mRecordingHint = false; 1216 } 1217 1218 const char * str_fd = mParameters.get(QCameraParameters::KEY_FACE_DETECTION); 1219 if((str_fd != NULL) && !strcmp(str_fd, "on")){ 1220 if(supportsFaceDetection() == false){ 1221 ALOGE("Face detection support is not available"); 1222 } 1223 setFaceDetection("off"); 1224 runFaceDetection(); 1225 } 1226 1227 switch(mPreviewState) { 1228 case QCAMERA_HAL_PREVIEW_START: 1229 //mPreviewWindow = NULL; 1230 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 1231 break; 1232 case QCAMERA_HAL_PREVIEW_STARTED: 1233 stopPreviewInternal(); 1234 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 1235 break; 1236 case QCAMERA_HAL_RECORDING_STARTED: 1237 stopRecordingInternal(); 1238 stopPreviewInternal(); 1239 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 1240 break; 1241 case QCAMERA_HAL_TAKE_PICTURE: 1242 cancelPictureInternal(); 1243 stopPreviewInternal(); 1244 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 1245 break; 1246 case QCAMERA_HAL_PREVIEW_STOPPED: 1247 default: 1248 break; 1249 } 1250 ALOGV("stopPreview: X, mPreviewState = %d", mPreviewState); 1251 } 1252 1253 #if 0 //mzhu 1254 void QCameraHardwareInterface::stopPreviewZSL() 1255 { 1256 ALOGI("stopPreviewZSL: E"); 1257 1258 if(!mStreamDisplay || !mStreamSnap) { 1259 ALOGE("mStreamDisplay/mStreamSnap is null"); 1260 return; 1261 } 1262 ALOGI("stopPreview: X, mPreviewState = %d", mPreviewState); 1263 } 1264 #endif 1265 void QCameraHardwareInterface::stopPreviewInternal() 1266 { 1267 ALOGV("stopPreviewInternal: E"); 1268 status_t ret = NO_ERROR; 1269 1270 if(!mStreamDisplay) { 1271 ALOGE("mStreamDisplay is null"); 1272 return; 1273 } 1274 1275 if(isZSLMode()) { 1276 /* take care snapshot object for ZSL mode */ 1277 mStreamSnap->stop(); 1278 } 1279 mStreamDisplay->stop(); 1280 1281 mPauseFramedispatch = false; 1282 mCameraState = CAMERA_STATE_PREVIEW_STOP_CMD_SENT; 1283 ALOGV("stopPreviewInternal: X"); 1284 } 1285 1286 int QCameraHardwareInterface::previewEnabled() 1287 { 1288 ALOGV("previewEnabled: E"); 1289 Mutex::Autolock lock(mLock); 1290 ALOGV("%s: mCameraState = %d", __func__, mCameraState); 1291 if (mPauseFramedispatch) { 1292 return false; 1293 } 1294 switch(mPreviewState) { 1295 case QCAMERA_HAL_PREVIEW_STOPPED: 1296 case QCAMERA_HAL_TAKE_PICTURE: 1297 default: 1298 return false; 1299 break; 1300 case QCAMERA_HAL_PREVIEW_START: 1301 case QCAMERA_HAL_PREVIEW_STARTED: 1302 case QCAMERA_HAL_RECORDING_STARTED: 1303 return true; 1304 break; 1305 } 1306 return false; 1307 } 1308 1309 status_t QCameraHardwareInterface::startRecording() 1310 { 1311 ALOGV("startRecording: E"); 1312 status_t ret = NO_ERROR; 1313 Mutex::Autolock lock(mLock); 1314 1315 switch(mPreviewState) { 1316 case QCAMERA_HAL_PREVIEW_STOPPED: 1317 ALOGE("%s: preview has not been started", __func__); 1318 ret = UNKNOWN_ERROR; 1319 break; 1320 case QCAMERA_HAL_PREVIEW_START: 1321 ALOGE("%s: no preview native window", __func__); 1322 ret = UNKNOWN_ERROR; 1323 break; 1324 case QCAMERA_HAL_PREVIEW_STARTED: 1325 //remember recordinghint value set by app 1326 mAppRecordingHint = mRecordingHint; 1327 pausePreviewForVideo(); 1328 ret = mStreamRecord->start(); 1329 if (MM_CAMERA_OK != ret){ 1330 ALOGE("%s: error - mStreamRecord->start!", __func__); 1331 ret = BAD_VALUE; 1332 break; 1333 } 1334 if(MM_CAMERA_OK == ret) 1335 mCameraState = CAMERA_STATE_RECORD_START_CMD_SENT; 1336 else 1337 mCameraState = CAMERA_STATE_ERROR; 1338 mPreviewState = QCAMERA_HAL_RECORDING_STARTED; 1339 break; 1340 case QCAMERA_HAL_RECORDING_STARTED: 1341 ALOGV("%s: ", __func__); 1342 break; 1343 case QCAMERA_HAL_TAKE_PICTURE: 1344 default: 1345 ret = BAD_VALUE; 1346 break; 1347 } 1348 ALOGV("startRecording: X"); 1349 return ret; 1350 } 1351 1352 void QCameraHardwareInterface::stopRecording() 1353 { 1354 ALOGV("stopRecording: E"); 1355 Mutex::Autolock lock(mLock); 1356 switch(mPreviewState) { 1357 case QCAMERA_HAL_PREVIEW_STOPPED: 1358 case QCAMERA_HAL_PREVIEW_START: 1359 case QCAMERA_HAL_PREVIEW_STARTED: 1360 break; 1361 case QCAMERA_HAL_RECORDING_STARTED: 1362 mRecordingHint = mAppRecordingHint; 1363 stopRecordingInternal(); 1364 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 1365 break; 1366 case QCAMERA_HAL_TAKE_PICTURE: 1367 default: 1368 break; 1369 } 1370 ALOGV("stopRecording: X"); 1371 1372 } 1373 void QCameraHardwareInterface::stopRecordingInternal() 1374 { 1375 ALOGV("stopRecordingInternal: E"); 1376 status_t ret = NO_ERROR; 1377 1378 if(!mStreamRecord) { 1379 ALOGE("mStreamRecord is null"); 1380 return; 1381 } 1382 1383 if(mStateLiveshot && mStreamLiveSnap != NULL) { 1384 mStreamLiveSnap->stop(); 1385 mStateLiveshot = false; 1386 } 1387 /* 1388 * call QCameraStream_record::stop() 1389 * Unregister Callback, action stop 1390 */ 1391 mStreamRecord->stop(); 1392 mCameraState = CAMERA_STATE_PREVIEW; //TODO : Apurva : Hacked for 2nd time Recording 1393 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 1394 ALOGV("stopRecordingInternal: X"); 1395 return; 1396 } 1397 1398 int QCameraHardwareInterface::recordingEnabled() 1399 { 1400 int ret = 0; 1401 Mutex::Autolock lock(mLock); 1402 ALOGV("%s: E", __func__); 1403 switch(mPreviewState) { 1404 case QCAMERA_HAL_PREVIEW_STOPPED: 1405 case QCAMERA_HAL_PREVIEW_START: 1406 case QCAMERA_HAL_PREVIEW_STARTED: 1407 break; 1408 case QCAMERA_HAL_RECORDING_STARTED: 1409 ret = 1; 1410 break; 1411 case QCAMERA_HAL_TAKE_PICTURE: 1412 default: 1413 break; 1414 } 1415 ALOGV("%s: X, ret = %d", __func__, ret); 1416 return ret; //isRecordingRunning(); 1417 } 1418 1419 /** 1420 * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME. 1421 */ 1422 void QCameraHardwareInterface::releaseRecordingFrame(const void *opaque) 1423 { 1424 ALOGV("%s : BEGIN",__func__); 1425 if(mStreamRecord == NULL) { 1426 ALOGE("Record stream Not Initialized"); 1427 return; 1428 } 1429 mStreamRecord->releaseRecordingFrame(opaque); 1430 ALOGV("%s : END",__func__); 1431 return; 1432 } 1433 1434 status_t QCameraHardwareInterface::autoFocusMoveEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb) 1435 { 1436 ALOGV("autoFocusMoveEvent: E"); 1437 int ret = NO_ERROR; 1438 1439 isp3a_af_mode_t afMode = getAutoFocusMode(mParameters); 1440 1441 if (afMode == AF_MODE_CAF && mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS_MOVE)){ 1442 ALOGV("%s:Issuing AF Move callback to service",__func__); 1443 1444 app_cb->notifyCb = mNotifyCb; 1445 app_cb->argm_notify.msg_type = CAMERA_MSG_FOCUS_MOVE; 1446 app_cb->argm_notify.ext2 = 0; 1447 app_cb->argm_notify.cookie = mCallbackCookie; 1448 1449 ALOGV("Auto focus state =%d", *status); 1450 if(*status == 1) { 1451 app_cb->argm_notify.ext1 = true; 1452 }else if(*status == 0){ 1453 app_cb->argm_notify.ext1 = false; 1454 }else{ 1455 app_cb->notifyCb = NULL; 1456 ALOGE("%s:Unknown AF Move Status received (%d) received",__func__,*status); 1457 } 1458 } 1459 ALOGV("autoFocusMoveEvent: X"); 1460 return ret; 1461 } 1462 1463 status_t QCameraHardwareInterface::autoFocusEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb) 1464 { 1465 ALOGV("autoFocusEvent: E"); 1466 int ret = NO_ERROR; 1467 /************************************************************ 1468 BEGIN MUTEX CODE 1469 *************************************************************/ 1470 1471 ALOGV("%s:%d: Trying to acquire AF bit lock",__func__,__LINE__); 1472 mAutofocusLock.lock(); 1473 ALOGV("%s:%d: Acquired AF bit lock",__func__,__LINE__); 1474 1475 if(mAutoFocusRunning==false) { 1476 ALOGV("%s:AF not running, discarding stale event",__func__); 1477 mAutofocusLock.unlock(); 1478 return ret; 1479 } 1480 /* If autofocus call has been made during CAF, CAF will be locked. 1481 * We specifically need to call cancelAutoFocus to unlock CAF. 1482 * In that sense, AF is still running.*/ 1483 isp3a_af_mode_t afMode = getAutoFocusMode(mParameters); 1484 if (afMode == AF_MODE_CAF) 1485 mNeedToUnlockCaf = true; 1486 mAutoFocusRunning = false; 1487 mAutofocusLock.unlock(); 1488 1489 /************************************************************ 1490 END MUTEX CODE 1491 *************************************************************/ 1492 if(status==NULL) { 1493 ALOGE("%s:NULL ptr received for status",__func__); 1494 return BAD_VALUE; 1495 } 1496 1497 /* update focus distances after autofocus is done */ 1498 if((*status != CAM_CTRL_FAILED) && updateFocusDistances() != NO_ERROR) { 1499 ALOGE("%s: updateFocusDistances failed for %d", __FUNCTION__, mFocusMode); 1500 } 1501 1502 /*(Do?) we need to make sure that the call back is the 1503 last possible step in the execution flow since the same 1504 context might be used if a fail triggers another round 1505 of AF then the mAutoFocusRunning flag and other state 1506 variables' validity will be under question*/ 1507 1508 if (mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS)){ 1509 ALOGV("%s:Issuing AF callback to service",__func__); 1510 1511 /* "Accepted" status is not appropriate it should be used for 1512 initial cmd, event reporting should only give use SUCCESS/FAIL 1513 */ 1514 1515 app_cb->notifyCb = mNotifyCb; 1516 app_cb->argm_notify.msg_type = CAMERA_MSG_FOCUS; 1517 app_cb->argm_notify.ext2 = 0; 1518 app_cb->argm_notify.cookie = mCallbackCookie; 1519 1520 ALOGV("Auto focus state =%d", *status); 1521 if(*status==CAM_CTRL_SUCCESS) { 1522 app_cb->argm_notify.ext1 = true; 1523 } 1524 else if(*status==CAM_CTRL_FAILED){ 1525 app_cb->argm_notify.ext1 = false; 1526 } 1527 else{ 1528 app_cb->notifyCb = NULL; 1529 ALOGE("%s:Unknown AF status (%d) received",__func__,*status); 1530 } 1531 1532 }/*(mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS))*/ 1533 else{ 1534 ALOGE("%s:Call back not enabled",__func__); 1535 } 1536 1537 ALOGV("autoFocusEvent: X"); 1538 return ret; 1539 1540 } 1541 1542 status_t QCameraHardwareInterface::cancelPicture() 1543 { 1544 ALOGV("cancelPicture: E"); 1545 status_t ret = MM_CAMERA_OK; 1546 Mutex::Autolock lock(mLock); 1547 1548 switch(mPreviewState) { 1549 case QCAMERA_HAL_PREVIEW_STOPPED: 1550 case QCAMERA_HAL_PREVIEW_START: 1551 case QCAMERA_HAL_PREVIEW_STARTED: 1552 break; 1553 case QCAMERA_HAL_RECORDING_STARTED: 1554 if(mStateLiveshot && (mStreamLiveSnap != NULL)) { 1555 mStreamLiveSnap->stop(); 1556 mStateLiveshot = false; 1557 } 1558 break; 1559 case QCAMERA_HAL_TAKE_PICTURE: 1560 ret = cancelPictureInternal(); 1561 break; 1562 default: 1563 break; 1564 } 1565 ALOGV("cancelPicture: X"); 1566 return ret; 1567 } 1568 1569 status_t QCameraHardwareInterface::cancelPictureInternal() 1570 { 1571 ALOGI("cancelPictureInternal: E"); 1572 status_t ret = MM_CAMERA_OK; 1573 // Do not need Snapshot callback to up layer any more 1574 mSnapCbDisabled = true; 1575 //we should make sure that snap_jpeg_cb has finished 1576 if(mStreamSnap){ 1577 mSnapJpegCbLock.lock(); 1578 if(mSnapJpegCbRunning != false){ 1579 ALOGE("%s: wait snapshot_jpeg_cb() to finish.", __func__); 1580 mSnapJpegCbWait.wait(mSnapJpegCbLock); 1581 ALOGE("%s: finish waiting snapshot_jpeg_cb(). ", __func__); 1582 } 1583 mSnapJpegCbLock.unlock(); 1584 } 1585 ALOGI("%s: mCameraState=%d.", __func__, mCameraState); 1586 if(mCameraState != CAMERA_STATE_READY) { 1587 if(mStreamSnap) { 1588 mStreamSnap->stop(); 1589 mCameraState = CAMERA_STATE_SNAP_STOP_CMD_SENT; 1590 } 1591 } else { 1592 ALOGE("%s: Cannot process cancel picture as snapshot is already done",__func__); 1593 } 1594 ALOGV("cancelPictureInternal: X"); 1595 return ret; 1596 } 1597 1598 void QCameraHardwareInterface::pausePreviewForSnapshot() 1599 { 1600 stopPreviewInternal( ); 1601 } 1602 status_t QCameraHardwareInterface::resumePreviewAfterSnapshot() 1603 { 1604 status_t ret = NO_ERROR; 1605 ret = mStreamDisplay->start(); 1606 return ret; 1607 } 1608 1609 void liveshot_callback(mm_camera_ch_data_buf_t *recvd_frame, 1610 void *user_data) 1611 { 1612 QCameraHardwareInterface *pme = (QCameraHardwareInterface *)user_data; 1613 cam_ctrl_dimension_t dim; 1614 int mJpegMaxSize; 1615 int mNuberOfVFEOutputs = 0; 1616 status_t ret; 1617 ALOGV("%s: E", __func__); 1618 1619 if (!pme->mStateLiveshot) { 1620 ALOGE("%s: Returning Buffer. Picture Cancelled", __func__); 1621 return; 1622 } 1623 1624 ALOGV("Live Snapshot Enabled"); 1625 if (pme->mStreamLiveSnap){ 1626 ALOGE("%s:Deleting old Snapshot stream instance",__func__); 1627 QCameraStream_Snapshot::deleteInstance (pme->mStreamLiveSnap); 1628 pme->mStreamLiveSnap = NULL; 1629 } 1630 1631 pme->mStreamLiveSnap = (QCameraStream_Snapshot*)QCameraStream_Snapshot::createInstance(pme->mCameraId, 1632 pme->myMode); 1633 1634 if (!pme->mStreamLiveSnap) { 1635 ALOGE("%s: error - can't creat snapshot stream!", __func__); 1636 cam_evt_buf_done(pme->mCameraId, recvd_frame); 1637 return ; 1638 } 1639 pme->mStreamLiveSnap->setModeLiveSnapshot(true); 1640 pme->mStreamLiveSnap->setHALCameraControl(pme); 1641 1642 ret = ((QCameraStream_Snapshot*)(pme->mStreamLiveSnap))->takePictureLiveshot(recvd_frame); 1643 if (MM_CAMERA_OK != ret) { 1644 ALOGE("%s: Error : returned from takePictureLiveshot",__func__); 1645 return; 1646 } 1647 pme->setCAFLockCancel(); 1648 ALOGV("%s: X", __func__); 1649 1650 } 1651 1652 status_t QCameraHardwareInterface::takePicture() 1653 { 1654 ALOGV("takePicture: E"); 1655 status_t ret = MM_CAMERA_OK; 1656 int mNuberOfVFEOutputs = 0; 1657 Mutex::Autolock lock(mLock); 1658 bool hdr; 1659 int frm_num = 1, rc = 0; 1660 int exp[MAX_HDR_EXP_FRAME_NUM]; 1661 1662 mSnapJpegCbLock.lock(); 1663 if(mSnapJpegCbRunning==true){ // This flag is set true in snapshot_jpeg_cb 1664 ALOGE("%s: wait snapshot_jpeg_cb() to finish to proceed with the next take picture", __func__); 1665 mSnapJpegCbWait.wait(mSnapJpegCbLock); 1666 ALOGE("%s: finish waiting snapshot_jpeg_cb() ", __func__); 1667 } 1668 mSnapJpegCbLock.unlock(); 1669 1670 // if we have liveSnapshot instance, 1671 // we need to delete it here to release teh channel it acquires 1672 if (NULL != mStreamLiveSnap) { 1673 delete(mStreamLiveSnap); 1674 mStreamLiveSnap = NULL; 1675 } 1676 1677 mSnapCbDisabled = false; 1678 1679 if(QCAMERA_HAL_RECORDING_STARTED != mPreviewState){ 1680 isp3a_af_mode_t afMode = getAutoFocusMode(mParameters); 1681 if (!mFlashCond) 1682 { 1683 mFlashCond = getFlashCondition(); 1684 } 1685 ALOGV("%s: Flash Contidion %d", __func__, mFlashCond); 1686 if(mFlashCond) { 1687 mRestartPreview = true; 1688 pausePreviewForZSL(); 1689 } 1690 mFlashCond = false; 1691 } 1692 1693 rc = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_LG_CAF_LOCK, NULL); 1694 if(rc<0) 1695 { 1696 ALOGE("%s: Failed to Check MM_CAMERA_PARM_LG_CAF_LOCK, rc %d", __func__, rc); 1697 } 1698 hdr = getHdrInfoAndSetExp(MAX_HDR_EXP_FRAME_NUM, &frm_num, exp); 1699 1700 mStreamSnap->resetSnapshotCounters(); 1701 mStreamSnap->InitHdrInfoForSnapshot(hdr, frm_num, exp); 1702 switch(mPreviewState) { 1703 case QCAMERA_HAL_PREVIEW_STARTED: 1704 //set the fullsize liveshot to false 1705 mFullLiveshotEnabled = false; 1706 setFullLiveshot(); 1707 mStreamSnap->setFullSizeLiveshot(false); 1708 if (isZSLMode()) { 1709 if (mStreamSnap != NULL) { 1710 pausePreviewForZSL(); 1711 ret = mStreamSnap->takePictureZSL(); 1712 if (ret != MM_CAMERA_OK) { 1713 ALOGE("%s: Error taking ZSL snapshot!", __func__); 1714 ret = BAD_VALUE; 1715 } 1716 } 1717 else { 1718 ALOGE("%s: ZSL stream not active! Failure!!", __func__); 1719 ret = BAD_VALUE; 1720 } 1721 return ret; 1722 } 1723 /*prepare snapshot, e.g LED*/ 1724 takePicturePrepareHardware( ); 1725 /* There's an issue where we have a glimpse of corrupted data between 1726 a time we stop a preview and display the postview. It happens because 1727 when we call stopPreview we deallocate the preview buffers hence overlay 1728 displays garbage value till we enqueue postview buffer to be displayed. 1729 Hence for temporary fix, we'll do memcopy of the last frame displayed and 1730 queue it to overlay*/ 1731 // mzhu storePreviewFrameForPostview(); 1732 1733 /* stop preview */ 1734 pausePreviewForSnapshot(); 1735 1736 /* call Snapshot start() :*/ 1737 ret = mStreamSnap->start(); 1738 if (MM_CAMERA_OK != ret){ 1739 /* mzhu: fix me, restore preview */ 1740 ALOGE("%s: error - can't start Snapshot stream!", __func__); 1741 return BAD_VALUE; 1742 } 1743 1744 if(MM_CAMERA_OK == ret) 1745 mCameraState = CAMERA_STATE_SNAP_START_CMD_SENT; 1746 else 1747 mCameraState = CAMERA_STATE_ERROR; 1748 mPreviewState = QCAMERA_HAL_TAKE_PICTURE; 1749 break; 1750 case QCAMERA_HAL_TAKE_PICTURE: 1751 break; 1752 case QCAMERA_HAL_PREVIEW_STOPPED: 1753 case QCAMERA_HAL_PREVIEW_START: 1754 ret = UNKNOWN_ERROR; 1755 break; 1756 case QCAMERA_HAL_RECORDING_STARTED: 1757 if(mStateLiveshot) { 1758 ALOGE("takePicture : Duplicate TakePicture Call"); 1759 return ret; 1760 } 1761 if (canTakeFullSizeLiveshot()) { 1762 ALOGV(" Calling takeFullSizeLiveshot"); 1763 takeFullSizeLiveshot(); 1764 }else{ 1765 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, 1766 &mNuberOfVFEOutputs); 1767 if (ret != MM_CAMERA_OK) { 1768 ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE failed"); 1769 ret = BAD_VALUE; 1770 } 1771 if (mNuberOfVFEOutputs == 1){ 1772 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW, 1773 liveshot_callback, 1774 MM_CAMERA_REG_BUF_CB_COUNT, 1775 1, 1776 this); 1777 } else { 1778 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO, 1779 liveshot_callback, 1780 MM_CAMERA_REG_BUF_CB_COUNT, 1781 1, 1782 this); 1783 } 1784 } 1785 mStateLiveshot = true; 1786 break; 1787 default: 1788 ret = UNKNOWN_ERROR; 1789 break; 1790 } 1791 ALOGV("takePicture: X"); 1792 return ret; 1793 } 1794 1795 bool QCameraHardwareInterface::canTakeFullSizeLiveshot() { 1796 bool ret; 1797 if (mFullLiveshotEnabled && !isLowPowerCamcorder()) { 1798 /* Full size liveshot enabled. */ 1799 1800 /* If Picture size is same as video size, switch to Video size 1801 * live snapshot */ 1802 if ((mDimension.picture_width == mVideoWidth) && 1803 (mDimension.picture_height == mVideoHeight)) { 1804 return false; 1805 } 1806 1807 if (mDisEnabled) { 1808 /* If DIS is enabled and Picture size is 1809 * less than (video size + 10% DIS Margin) 1810 * then fall back to Video size liveshot. */ 1811 if ((mDimension.picture_width < 1812 (int)(mVideoWidth * 1.1)) || 1813 (mDimension.picture_height < 1814 (int)(mVideoHeight * 1.1))) { 1815 ret = false; 1816 } else { 1817 /* Go with Full size live snapshot. */ 1818 ret = true; 1819 } 1820 } else { 1821 /* DIS Disabled. Go with Full size live snapshot */ 1822 ret = true; 1823 } 1824 } else { 1825 /* Full size liveshot disabled. Fallback to Video size liveshot. */ 1826 ret = false; 1827 } 1828 1829 return ret; 1830 } 1831 1832 status_t QCameraHardwareInterface::takeFullSizeLiveshot() 1833 { 1834 status_t ret = NO_ERROR; 1835 if (mStreamLiveSnap){ 1836 ALOGV("%s:Deleting old Snapshot stream instance",__func__); 1837 QCameraStream_Snapshot::deleteInstance (mStreamLiveSnap); 1838 mStreamLiveSnap = NULL; 1839 } 1840 mStreamLiveSnap = QCameraStream_Snapshot::createInstance(mCameraId, myMode); 1841 1842 if (!mStreamLiveSnap) { 1843 ALOGE("%s: error - can't creat snapshot stream!", __func__); 1844 /* mzhu: fix me, restore preview */ 1845 return BAD_VALUE; 1846 } 1847 1848 /* Store HAL object in snapshot stream Object */ 1849 mStreamLiveSnap->setHALCameraControl(this); 1850 1851 mStreamLiveSnap->setFullSizeLiveshot(true); 1852 1853 /* Call snapshot init*/ 1854 ret = mStreamLiveSnap->init(); 1855 if (MM_CAMERA_OK != ret){ 1856 ALOGE("%s: error - can't init Snapshot stream!", __func__); 1857 return BAD_VALUE; 1858 } 1859 1860 /* call Snapshot start() :*/ 1861 mStreamLiveSnap->resetSnapshotCounters( ); 1862 ret = mStreamLiveSnap->start(); 1863 if (MM_CAMERA_OK != ret){ 1864 /* mzhu: fix me, restore preview */ 1865 ALOGE("%s: error - can't start Snapshot stream!", __func__); 1866 return BAD_VALUE; 1867 } 1868 return ret; 1869 } 1870 1871 status_t QCameraHardwareInterface::takeLiveSnapshot() 1872 { 1873 status_t ret = NO_ERROR; 1874 ALOGV("takeLiveSnapshot: E"); 1875 mStreamRecord->takeLiveSnapshot(); 1876 ALOGV("takeLiveSnapshot: X"); 1877 return ret; 1878 } 1879 1880 status_t QCameraHardwareInterface::autoFocus() 1881 { 1882 ALOGV("autoFocus: E"); 1883 status_t ret = NO_ERROR; 1884 mFlashCond = getFlashCondition(); 1885 ALOGV("autoFocus: mFlashCond = %d", mFlashCond); 1886 Mutex::Autolock lock(mLock); 1887 ALOGV("autoFocus: Got lock"); 1888 bool status = true; 1889 isp3a_af_mode_t afMode = getAutoFocusMode(mParameters); 1890 1891 Mutex::Autolock afLock(mAutofocusLock); 1892 1893 if(mAutoFocusRunning==true){ 1894 ALOGV("%s:AF already running should not have got this call",__func__); 1895 return NO_ERROR; 1896 } 1897 1898 if (afMode == AF_MODE_MAX) { 1899 /* This should never happen. We cannot send a 1900 * callback notifying error from this place because 1901 * the CameraService has called this function after 1902 * acquiring the lock. So if we try to issue a callback 1903 * from this place, the callback will try to acquire 1904 * the same lock in CameraService and it will result 1905 * in deadlock. So, let the call go in to the lower 1906 * layer. The lower layer will anyway return error if 1907 * the autofocus is not supported or if the focus 1908 * value is invalid. 1909 * Just print out the error. */ 1910 ALOGE("%s:Invalid AF mode (%d)", __func__, afMode); 1911 } 1912 1913 ALOGV("%s:AF start (mode %d)", __func__, afMode); 1914 if(MM_CAMERA_OK != cam_ops_action(mCameraId, true, 1915 MM_CAMERA_OPS_FOCUS, &afMode)) { 1916 ALOGE("%s: AF command failed err:%d error %s", 1917 __func__, errno, strerror(errno)); 1918 return UNKNOWN_ERROR; 1919 } 1920 1921 mAutoFocusRunning = true; 1922 ALOGV("autoFocus: X"); 1923 return ret; 1924 } 1925 1926 status_t QCameraHardwareInterface::cancelAutoFocus() 1927 { 1928 ALOGV("cancelAutoFocus: E"); 1929 status_t ret = NO_ERROR; 1930 Mutex::Autolock lock(mLock); 1931 1932 /************************************************************** 1933 BEGIN MUTEX CODE 1934 *************************************************************/ 1935 1936 mAutofocusLock.lock(); 1937 if(mAutoFocusRunning || mNeedToUnlockCaf) { 1938 ALOGV("%s:Af either running or CAF needs unlocking", __func__); 1939 mNeedToUnlockCaf = false; 1940 mAutoFocusRunning = false; 1941 mAutofocusLock.unlock(); 1942 1943 }else/*(!mAutoFocusRunning)*/{ 1944 1945 mAutofocusLock.unlock(); 1946 ALOGV("%s:Af not running",__func__); 1947 return NO_ERROR; 1948 } 1949 /************************************************************** 1950 END MUTEX CODE 1951 *************************************************************/ 1952 1953 1954 if(MM_CAMERA_OK!=cam_ops_action(mCameraId,false,MM_CAMERA_OPS_FOCUS,NULL )) { 1955 ALOGE("%s: AF command failed err:%d error %s",__func__, errno,strerror(errno)); 1956 } 1957 1958 ALOGV("cancelAutoFocus: X"); 1959 return NO_ERROR; 1960 } 1961 1962 #if 0 //mzhu 1963 /*========================================================================== 1964 * FUNCTION - prepareSnapshotAndWait - 1965 * 1966 * DESCRIPTION: invoke preparesnapshot and wait for it done 1967 it can be called within takepicture, so no need 1968 to grab mLock. 1969 *=========================================================================*/ 1970 void QCameraHardwareInterface::prepareSnapshotAndWait() 1971 { 1972 ALOGI("prepareSnapshotAndWait: E"); 1973 int rc = 0; 1974 /*To Do: call mm camera preparesnapshot */ 1975 if(!rc ) { 1976 mPreparingSnapshot = true; 1977 pthread_mutex_lock(&mAsyncCmdMutex); 1978 pthread_cond_wait(&mAsyncCmdWait, &mAsyncCmdMutex); 1979 pthread_mutex_unlock(&mAsyncCmdMutex); 1980 mPreparingSnapshot = false; 1981 } 1982 ALOGI("prepareSnapshotAndWait: X"); 1983 } 1984 #endif //mzhu 1985 1986 /*========================================================================== 1987 * FUNCTION - processprepareSnapshotEvent - 1988 * 1989 * DESCRIPTION: Process the event of preparesnapshot done msg 1990 unblock prepareSnapshotAndWait( ) 1991 *=========================================================================*/ 1992 void QCameraHardwareInterface::processprepareSnapshotEvent(cam_ctrl_status_t *status) 1993 { 1994 ALOGV("processprepareSnapshotEvent: E"); 1995 pthread_mutex_lock(&mAsyncCmdMutex); 1996 pthread_cond_signal(&mAsyncCmdWait); 1997 pthread_mutex_unlock(&mAsyncCmdMutex); 1998 ALOGV("processprepareSnapshotEvent: X"); 1999 } 2000 2001 void QCameraHardwareInterface::roiEvent(fd_roi_t roi,app_notify_cb_t *app_cb) 2002 { 2003 ALOGV("roiEvent: E"); 2004 2005 if(mStreamDisplay) mStreamDisplay->notifyROIEvent(roi); 2006 #if 0 //TODO: move to preview obj 2007 mCallbackLock.lock(); 2008 data_callback mcb = mDataCb; 2009 void *mdata = mCallbackCookie; 2010 int msgEnabled = mMsgEnabled; 2011 mCallbackLock.unlock(); 2012 2013 mMetaDataWaitLock.lock(); 2014 if (mFaceDetectOn == true && mSendMetaData == true) { 2015 mSendMetaData = false; 2016 int faces_detected = roi.rect_num; 2017 int max_faces_detected = MAX_ROI * 4; 2018 int array[max_faces_detected + 1]; 2019 2020 array[0] = faces_detected * 4; 2021 for (int i = 1, j = 0;j < MAX_ROI; j++, i = i + 4) { 2022 if (j < faces_detected) { 2023 array[i] = roi.faces[j].x; 2024 array[i+1] = roi.faces[j].y; 2025 array[i+2] = roi.faces[j].dx; 2026 array[i+3] = roi.faces[j].dy; 2027 } else { 2028 array[i] = -1; 2029 array[i+1] = -1; 2030 array[i+2] = -1; 2031 array[i+3] = -1; 2032 } 2033 } 2034 if(mMetaDataHeap != NULL){ 2035 ALOGV("mMetaDataHEap is non-NULL"); 2036 memcpy((uint32_t *)mMetaDataHeap->mHeap->base(), (uint32_t *)array, (sizeof(int)*(MAX_ROI*4+1))); 2037 mMetaDataWaitLock.unlock(); 2038 2039 if (mcb != NULL && (msgEnabled & CAMERA_MSG_META_DATA)) { 2040 mcb(CAMERA_MSG_META_DATA, mMetaDataHeap->mBuffers[0], mdata); 2041 } 2042 } else { 2043 mMetaDataWaitLock.unlock(); 2044 ALOGE("runPreviewThread mMetaDataHeap is NULL"); 2045 } 2046 } else { 2047 mMetaDataWaitLock.unlock(); 2048 } 2049 #endif // mzhu 2050 ALOGV("roiEvent: X"); 2051 } 2052 2053 2054 void QCameraHardwareInterface::handleZoomEventForSnapshot(void) 2055 { 2056 mm_camera_ch_crop_t v4l2_crop; 2057 2058 2059 ALOGV("%s: E", __func__); 2060 2061 memset(&v4l2_crop,0,sizeof(v4l2_crop)); 2062 v4l2_crop.ch_type=MM_CAMERA_CH_SNAPSHOT; 2063 2064 ALOGV("%s: Fetching crop info", __func__); 2065 cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop); 2066 2067 ALOGV("%s: Crop info received for main: %d, %d, %d, %d ", __func__, 2068 v4l2_crop.snapshot.main_crop.left, 2069 v4l2_crop.snapshot.main_crop.top, 2070 v4l2_crop.snapshot.main_crop.width, 2071 v4l2_crop.snapshot.main_crop.height); 2072 ALOGV("%s: Crop info received for thumbnail: %d, %d, %d, %d ",__func__, 2073 v4l2_crop.snapshot.thumbnail_crop.left, 2074 v4l2_crop.snapshot.thumbnail_crop.top, 2075 v4l2_crop.snapshot.thumbnail_crop.width, 2076 v4l2_crop.snapshot.thumbnail_crop.height); 2077 2078 if(mStreamSnap) { 2079 ALOGV("%s: Setting crop info for snapshot", __func__); 2080 memcpy(&(mStreamSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop)); 2081 } 2082 if(mFullLiveshotEnabled && mStreamLiveSnap){ 2083 ALOGV("%s: Setting crop info for snapshot", __func__); 2084 memcpy(&(mStreamLiveSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop)); 2085 } 2086 ALOGV("%s: X", __func__); 2087 } 2088 2089 void QCameraHardwareInterface::handleZoomEventForPreview(app_notify_cb_t *app_cb) 2090 { 2091 mm_camera_ch_crop_t v4l2_crop; 2092 2093 ALOGV("%s: E", __func__); 2094 2095 /*regular zooming or smooth zoom stopped*/ 2096 if (!mSmoothZoomRunning && mPreviewWindow) { 2097 memset(&v4l2_crop, 0, sizeof(v4l2_crop)); 2098 v4l2_crop.ch_type = MM_CAMERA_CH_PREVIEW; 2099 2100 ALOGV("%s: Fetching crop info", __func__); 2101 cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop); 2102 2103 ALOGV("%s: Crop info received: %d, %d, %d, %d ", __func__, 2104 v4l2_crop.crop.left, 2105 v4l2_crop.crop.top, 2106 v4l2_crop.crop.width, 2107 v4l2_crop.crop.height); 2108 2109 mPreviewWindow->set_crop(mPreviewWindow, 2110 v4l2_crop.crop.left, 2111 v4l2_crop.crop.top, 2112 v4l2_crop.crop.left + v4l2_crop.crop.width, 2113 v4l2_crop.crop.top + v4l2_crop.crop.height); 2114 ALOGV("%s: Done setting crop", __func__); 2115 ALOGV("%s: Currrent zoom :%d",__func__, mCurrentZoom); 2116 } 2117 2118 ALOGV("%s: X", __func__); 2119 } 2120 2121 void QCameraHardwareInterface::zoomEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb) 2122 { 2123 ALOGV("zoomEvent: state:%d E",mPreviewState); 2124 switch (mPreviewState) { 2125 case QCAMERA_HAL_PREVIEW_STOPPED: 2126 break; 2127 case QCAMERA_HAL_PREVIEW_START: 2128 break; 2129 case QCAMERA_HAL_PREVIEW_STARTED: 2130 handleZoomEventForPreview(app_cb); 2131 if (isZSLMode()) 2132 handleZoomEventForSnapshot(); 2133 break; 2134 case QCAMERA_HAL_RECORDING_STARTED: 2135 handleZoomEventForPreview(app_cb); 2136 if (mFullLiveshotEnabled) 2137 handleZoomEventForSnapshot(); 2138 break; 2139 case QCAMERA_HAL_TAKE_PICTURE: 2140 if(isZSLMode()) 2141 handleZoomEventForPreview(app_cb); 2142 handleZoomEventForSnapshot(); 2143 break; 2144 default: 2145 break; 2146 } 2147 ALOGV("zoomEvent: X"); 2148 } 2149 2150 void QCameraHardwareInterface::dumpFrameToFile(const void * data, uint32_t size, char* name, char* ext, int index) 2151 { 2152 #if 0 2153 char buf[32], value[PROPERTY_VALUE_MAX]; 2154 int file_fd, enabled = 0; 2155 static int i = 0 ; 2156 property_get("persist.camera.dumpimage", value, "0"); 2157 enabled = atoi(value); 2158 2159 if ( data != NULL && enabled) { 2160 char * str; 2161 snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext); 2162 ALOGE("%s size =%d", buf, size); 2163 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2164 write(file_fd, data, size); 2165 close(file_fd); 2166 i++; 2167 } 2168 #endif 2169 } 2170 2171 void QCameraHardwareInterface::dumpFrameToFile(struct msm_frame* newFrame, 2172 HAL_cam_dump_frm_type_t frm_type) 2173 { 2174 #if 0 2175 int32_t enabled = 0; 2176 int frm_num; 2177 uint32_t skip_mode; 2178 char value[PROPERTY_VALUE_MAX]; 2179 char buf[32]; 2180 int main_422 = 1; 2181 property_get("persist.camera.dumpimg", value, "0"); 2182 enabled = atoi(value); 2183 2184 ALOGV(" newFrame =%p, frm_type = %d", newFrame, frm_type); 2185 if(enabled & HAL_DUMP_FRM_MASK_ALL) { 2186 if((enabled & frm_type) && newFrame) { 2187 frm_num = ((enabled & 0xffff0000) >> 16); 2188 if(frm_num == 0) frm_num = 10; /*default 10 frames*/ 2189 if(frm_num > 256) frm_num = 256; /*256 buffers cycle around*/ 2190 skip_mode = ((enabled & 0x0000ff00) >> 8); 2191 if(skip_mode == 0) skip_mode = 1; /*no -skip */ 2192 2193 if( mDumpSkipCnt % skip_mode == 0) { 2194 if (mDumpFrmCnt >= 0 && mDumpFrmCnt <= frm_num) { 2195 int w, h; 2196 int file_fd; 2197 switch (frm_type) { 2198 case HAL_DUMP_FRM_PREVIEW: 2199 w = mDimension.display_width; 2200 h = mDimension.display_height; 2201 snprintf(buf, sizeof(buf), "/data/%dp_%dx%d.yuv", mDumpFrmCnt, w, h); 2202 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2203 break; 2204 case HAL_DUMP_FRM_VIDEO: 2205 w = mVideoWidth; 2206 h = mVideoHeight; 2207 snprintf(buf, sizeof(buf),"/data/%dv_%dx%d.yuv", mDumpFrmCnt, w, h); 2208 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2209 break; 2210 case HAL_DUMP_FRM_MAIN: 2211 w = mDimension.picture_width; 2212 h = mDimension.picture_height; 2213 snprintf(buf, sizeof(buf), "/data/%dm_%dx%d.yuv", mDumpFrmCnt, w, h); 2214 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2215 if (mDimension.main_img_format == CAMERA_YUV_422_NV16 || 2216 mDimension.main_img_format == CAMERA_YUV_422_NV61) 2217 main_422 = 2; 2218 break; 2219 case HAL_DUMP_FRM_THUMBNAIL: 2220 w = mDimension.ui_thumbnail_width; 2221 h = mDimension.ui_thumbnail_height; 2222 snprintf(buf, sizeof(buf),"/data/%dt_%dx%d.yuv", mDumpFrmCnt, w, h); 2223 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2224 break; 2225 default: 2226 w = h = 0; 2227 file_fd = -1; 2228 break; 2229 } 2230 2231 if (file_fd < 0) { 2232 ALOGE("%s: cannot open file:type=%d\n", __func__, frm_type); 2233 } else { 2234 ALOGV("%s: %d %d", __func__, newFrame->y_off, newFrame->cbcr_off); 2235 write(file_fd, (const void *)(newFrame->buffer+newFrame->y_off), w * h); 2236 write(file_fd, (const void *) 2237 (newFrame->buffer + newFrame->cbcr_off), w * h / 2 * main_422); 2238 close(file_fd); 2239 ALOGV("dump %s", buf); 2240 } 2241 } else if(frm_num == 256){ 2242 mDumpFrmCnt = 0; 2243 } 2244 mDumpFrmCnt++; 2245 } 2246 mDumpSkipCnt++; 2247 } 2248 } else { 2249 mDumpFrmCnt = 0; 2250 } 2251 #endif 2252 } 2253 2254 status_t QCameraHardwareInterface::setPreviewWindow(preview_stream_ops_t* window) 2255 { 2256 status_t retVal = NO_ERROR; 2257 ALOGV(" %s: E mPreviewState = %d, mStreamDisplay = %p", __FUNCTION__, mPreviewState, mStreamDisplay); 2258 if( window == NULL) { 2259 ALOGE("%s:Received Setting NULL preview window", __func__); 2260 } 2261 Mutex::Autolock lock(mLock); 2262 switch(mPreviewState) { 2263 case QCAMERA_HAL_PREVIEW_START: 2264 mPreviewWindow = window; 2265 if(mPreviewWindow) { 2266 /* we have valid surface now, start preview */ 2267 retVal = startPreview2(); 2268 if(retVal == NO_ERROR) 2269 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 2270 ALOGV("%s: startPreview2 done, mPreviewState = %d", __func__, mPreviewState); 2271 } else 2272 ALOGE("%s: null window received, mPreviewState = %d", __func__, mPreviewState); 2273 break; 2274 case QCAMERA_HAL_PREVIEW_STARTED: 2275 /* new window comes */ 2276 ALOGE("%s: bug, cannot handle new window in started state", __func__); 2277 //retVal = UNKNOWN_ERROR; 2278 break; 2279 case QCAMERA_HAL_PREVIEW_STOPPED: 2280 case QCAMERA_HAL_TAKE_PICTURE: 2281 mPreviewWindow = window; 2282 ALOGE("%s: mPreviewWindow = 0x%p, mStreamDisplay = 0x%p", 2283 __func__, mPreviewWindow, mStreamDisplay); 2284 if(mStreamDisplay) 2285 retVal = mStreamDisplay->setPreviewWindow(window); 2286 break; 2287 default: 2288 ALOGE("%s: bug, cannot handle new window in state %d", __func__, mPreviewState); 2289 retVal = UNKNOWN_ERROR; 2290 break; 2291 } 2292 ALOGV(" %s : X, mPreviewState = %d", __FUNCTION__, mPreviewState); 2293 return retVal; 2294 } 2295 2296 int QCameraHardwareInterface::storeMetaDataInBuffers(int enable) 2297 { 2298 /* this is a dummy func now. fix me later */ 2299 mStoreMetaDataInFrame = enable; 2300 return 0; 2301 } 2302 2303 status_t QCameraHardwareInterface::sendMappingBuf(int ext_mode, int idx, int fd, 2304 uint32_t size, int cameraid, 2305 mm_camera_socket_msg_type msg_type) 2306 { 2307 cam_sock_packet_t packet; 2308 memset(&packet, 0, sizeof(cam_sock_packet_t)); 2309 packet.msg_type = msg_type; 2310 packet.payload.frame_fd_map.ext_mode = ext_mode; 2311 packet.payload.frame_fd_map.frame_idx = idx; 2312 packet.payload.frame_fd_map.fd = fd; 2313 packet.payload.frame_fd_map.size = size; 2314 2315 if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), packet.payload.frame_fd_map.fd) <= 0 ) { 2316 ALOGE("%s: sending frame mapping buf msg Failed", __func__); 2317 return FAILED_TRANSACTION; 2318 } 2319 return NO_ERROR; 2320 } 2321 2322 status_t QCameraHardwareInterface::sendUnMappingBuf(int ext_mode, int idx, int cameraid, 2323 mm_camera_socket_msg_type msg_type) 2324 { 2325 cam_sock_packet_t packet; 2326 memset(&packet, 0, sizeof(cam_sock_packet_t)); 2327 packet.msg_type = msg_type; 2328 packet.payload.frame_fd_unmap.ext_mode = ext_mode; 2329 packet.payload.frame_fd_unmap.frame_idx = idx; 2330 if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), 0) <= 0 ) { 2331 ALOGE("%s: sending frame unmapping buf msg Failed", __func__); 2332 return FAILED_TRANSACTION; 2333 } 2334 return NO_ERROR; 2335 } 2336 2337 int QCameraHardwareInterface::allocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt, int ion_type) 2338 { 2339 int rc = 0; 2340 struct ion_handle_data handle_data; 2341 2342 p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY); 2343 if (p_camera_memory->main_ion_fd[cnt] < 0) { 2344 ALOGE("Ion dev open failed\n"); 2345 ALOGE("Error is %s\n", strerror(errno)); 2346 goto ION_OPEN_FAILED; 2347 } 2348 p_camera_memory->alloc[cnt].len = p_camera_memory->size; 2349 /* to make it page size aligned */ 2350 p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095); 2351 p_camera_memory->alloc[cnt].align = 4096; 2352 p_camera_memory->alloc[cnt].flags = ION_FLAG_CACHED; 2353 p_camera_memory->alloc[cnt].heap_id_mask = ion_type; 2354 2355 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]); 2356 if (rc < 0) { 2357 ALOGE("ION allocation failed\n"); 2358 goto ION_ALLOC_FAILED; 2359 } 2360 2361 p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle; 2362 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]); 2363 if (rc < 0) { 2364 ALOGE("ION map failed %s\n", strerror(errno)); 2365 goto ION_MAP_FAILED; 2366 } 2367 p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd; 2368 return 0; 2369 2370 ION_MAP_FAILED: 2371 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle; 2372 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data); 2373 ION_ALLOC_FAILED: 2374 close(p_camera_memory->main_ion_fd[cnt]); 2375 p_camera_memory->main_ion_fd[cnt] = -1; 2376 ION_OPEN_FAILED: 2377 return -1; 2378 } 2379 2380 int QCameraHardwareInterface::deallocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt) 2381 { 2382 struct ion_handle_data handle_data; 2383 int rc = 0; 2384 2385 if (p_camera_memory->main_ion_fd[cnt] > 0) { 2386 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle; 2387 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data); 2388 close(p_camera_memory->main_ion_fd[cnt]); 2389 p_camera_memory->main_ion_fd[cnt] = -1; 2390 } 2391 return rc; 2392 } 2393 2394 int QCameraHardwareInterface::allocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt, int ion_type) 2395 { 2396 int rc = 0; 2397 struct ion_handle_data handle_data; 2398 2399 p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY); 2400 if (p_camera_memory->main_ion_fd[cnt] < 0) { 2401 ALOGE("Ion dev open failed\n"); 2402 ALOGE("Error is %s\n", strerror(errno)); 2403 goto ION_OPEN_FAILED; 2404 } 2405 p_camera_memory->alloc[cnt].len = p_camera_memory->size; 2406 /* to make it page size aligned */ 2407 p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095); 2408 p_camera_memory->alloc[cnt].align = 4096; 2409 p_camera_memory->alloc[cnt].flags = ION_FLAG_CACHED; 2410 p_camera_memory->alloc[cnt].heap_id_mask = (0x1 << ion_type | 0x1 << ION_IOMMU_HEAP_ID); 2411 2412 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]); 2413 if (rc < 0) { 2414 ALOGE("ION allocation failed\n"); 2415 goto ION_ALLOC_FAILED; 2416 } 2417 2418 p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle; 2419 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]); 2420 if (rc < 0) { 2421 ALOGE("ION map failed %s\n", strerror(errno)); 2422 goto ION_MAP_FAILED; 2423 } 2424 p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd; 2425 return 0; 2426 2427 ION_MAP_FAILED: 2428 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle; 2429 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data); 2430 ION_ALLOC_FAILED: 2431 close(p_camera_memory->main_ion_fd[cnt]); 2432 p_camera_memory->main_ion_fd[cnt] = -1; 2433 ION_OPEN_FAILED: 2434 return -1; 2435 } 2436 2437 int QCameraHardwareInterface::cache_ops(int ion_fd, 2438 struct ion_flush_data *cache_data, int type) 2439 { 2440 int rc = 0; 2441 struct ion_custom_data data; 2442 data.cmd = type; 2443 data.arg = (unsigned long)cache_data; 2444 2445 rc = ioctl(ion_fd, ION_IOC_CUSTOM, &data); 2446 if (rc < 0) 2447 ALOGE("%s: Cache Invalidate failed\n", __func__); 2448 else 2449 ALOGV("%s: Cache OPs type(%d) success", __func__); 2450 2451 return rc; 2452 } 2453 2454 int QCameraHardwareInterface::deallocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt) 2455 { 2456 struct ion_handle_data handle_data; 2457 int rc = 0; 2458 2459 if (p_camera_memory->main_ion_fd[cnt] > 0) { 2460 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle; 2461 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data); 2462 close(p_camera_memory->main_ion_fd[cnt]); 2463 p_camera_memory->main_ion_fd[cnt] = -1; 2464 } 2465 return rc; 2466 } 2467 2468 int QCameraHardwareInterface::initHeapMem( QCameraHalHeap_t *heap, 2469 int num_of_buf, 2470 int buf_len, 2471 int y_off, 2472 int cbcr_off, 2473 int pmem_type, 2474 mm_cameara_stream_buf_t *StreamBuf, 2475 mm_camera_buf_def_t *buf_def, 2476 uint8_t num_planes, 2477 uint32_t *planes 2478 ) 2479 { 2480 int rc = 0; 2481 int i; 2482 int path; 2483 int ion_fd; 2484 struct msm_frame *frame; 2485 struct ion_flush_data cache_inv_data; 2486 ALOGV("Init Heap =%p. stream_buf =%p, pmem_type =%d, num_of_buf=%d. buf_len=%d, cbcr_off=%d", 2487 heap, StreamBuf, pmem_type, num_of_buf, buf_len, cbcr_off); 2488 if(num_of_buf > MM_CAMERA_MAX_NUM_FRAMES || heap == NULL || 2489 mGetMemory == NULL ) { 2490 ALOGE("Init Heap error"); 2491 rc = -1; 2492 return rc; 2493 } 2494 memset(heap, 0, sizeof(QCameraHalHeap_t)); 2495 for (i=0; i<MM_CAMERA_MAX_NUM_FRAMES;i++) { 2496 heap->main_ion_fd[i] = -1; 2497 heap->fd[i] = -1; 2498 } 2499 heap->buffer_count = num_of_buf; 2500 heap->size = buf_len; 2501 heap->y_offset = y_off; 2502 heap->cbcr_offset = cbcr_off; 2503 2504 if (StreamBuf != NULL) { 2505 StreamBuf->num = num_of_buf; 2506 StreamBuf->frame_len = buf_len; 2507 switch (pmem_type) { 2508 case MSM_PMEM_MAINIMG: 2509 case MSM_PMEM_RAW_MAINIMG: 2510 path = OUTPUT_TYPE_S; 2511 break; 2512 2513 case MSM_PMEM_THUMBNAIL: 2514 path = OUTPUT_TYPE_T; 2515 break; 2516 2517 default: 2518 rc = -1; 2519 return rc; 2520 } 2521 } 2522 2523 2524 for(i = 0; i < num_of_buf; i++) { 2525 #ifdef USE_ION 2526 if (isZSLMode()) 2527 rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ZSL_ION_HEAP_ID) | 2528 (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID))); 2529 else 2530 rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ION_HEAP_ID) | 2531 (0x1 << CAMERA_ION_FALLBACK_HEAP_ID))); 2532 2533 if (rc < 0) { 2534 ALOGE("%s: ION allocation failed\n", __func__); 2535 break; 2536 } 2537 #else 2538 if (pmem_type == MSM_PMEM_MAX) 2539 heap->fd[i] = -1; 2540 else { 2541 heap->fd[i] = open("/dev/pmem_adsp", O_RDWR|O_SYNC); 2542 if ( heap->fd[i] <= 0) { 2543 rc = -1; 2544 ALOGE("Open fail: heap->fd[%d] =%d", i, heap->fd[i]); 2545 break; 2546 } 2547 } 2548 #endif 2549 heap->camera_memory[i] = mGetMemory( heap->fd[i], buf_len, 1, (void *)this); 2550 2551 if (heap->camera_memory[i] == NULL ) { 2552 ALOGE("Getmem fail %d: ", i); 2553 rc = -1; 2554 break; 2555 } 2556 2557 memset(&cache_inv_data, 0, sizeof(struct ion_flush_data)); 2558 cache_inv_data.vaddr = (void*) heap->camera_memory[i]->data; 2559 cache_inv_data.fd = heap->ion_info_fd[i].fd; 2560 cache_inv_data.handle = heap->ion_info_fd[i].handle; 2561 cache_inv_data.length = heap->alloc[i].len; 2562 ion_fd = heap->main_ion_fd[i]; 2563 if(ion_fd > 0) { 2564 if(cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_INV_CACHES) < 0) 2565 ALOGE("%s: Cache Invalidate failed\n", __func__); 2566 else { 2567 ALOGV("%s: Successful cache invalidate\n", __func__); 2568 } 2569 } 2570 2571 if (StreamBuf != NULL) { 2572 frame = &(StreamBuf->frame[i]); 2573 memset(frame, 0, sizeof(struct msm_frame)); 2574 frame->fd = heap->fd[i]; 2575 frame->phy_offset = 0; 2576 frame->buffer = (uint32_t) heap->camera_memory[i]->data; 2577 frame->path = path; 2578 frame->cbcr_off = planes[0]+heap->cbcr_offset; 2579 frame->y_off = heap->y_offset; 2580 frame->fd_data = heap->ion_info_fd[i]; 2581 frame->ion_alloc = heap->alloc[i]; 2582 frame->ion_dev_fd = heap->main_ion_fd[i]; 2583 ALOGV("%s: Buffer idx: %d addr: %x fd: %d phy_offset: %d" 2584 "cbcr_off: %d y_off: %d frame_len: %d", __func__, 2585 i, (unsigned int)frame->buffer, frame->fd, 2586 frame->phy_offset, cbcr_off, y_off, frame->ion_alloc.len); 2587 2588 buf_def->buf.mp[i].frame = *frame; 2589 buf_def->buf.mp[i].frame_offset = 0; 2590 buf_def->buf.mp[i].num_planes = num_planes; 2591 /* Plane 0 needs to be set seperately. Set other planes 2592 * in a loop. */ 2593 buf_def->buf.mp[i].planes[0].length = planes[0]; 2594 buf_def->buf.mp[i].planes[0].m.userptr = frame->fd; 2595 buf_def->buf.mp[i].planes[0].data_offset = y_off; 2596 buf_def->buf.mp[i].planes[0].reserved[0] = 2597 buf_def->buf.mp[i].frame_offset; 2598 for (int j = 1; j < num_planes; j++) { 2599 buf_def->buf.mp[i].planes[j].length = planes[j]; 2600 buf_def->buf.mp[i].planes[j].m.userptr = frame->fd; 2601 buf_def->buf.mp[i].planes[j].data_offset = cbcr_off; 2602 buf_def->buf.mp[i].planes[j].reserved[0] = 2603 buf_def->buf.mp[i].planes[j-1].reserved[0] + 2604 buf_def->buf.mp[i].planes[j-1].length; 2605 } 2606 } else { 2607 } 2608 2609 ALOGV("heap->fd[%d] =%d, camera_memory=%p", i, heap->fd[i], heap->camera_memory[i]); 2610 heap->local_flag[i] = 1; 2611 } 2612 if( rc < 0) { 2613 releaseHeapMem(heap); 2614 } 2615 return rc; 2616 } 2617 2618 int QCameraHardwareInterface::releaseHeapMem( QCameraHalHeap_t *heap) 2619 { 2620 int rc = 0; 2621 ALOGV("Release %p", heap); 2622 if (heap != NULL) { 2623 2624 for (int i = 0; i < heap->buffer_count; i++) { 2625 if(heap->camera_memory[i] != NULL) { 2626 heap->camera_memory[i]->release( heap->camera_memory[i] ); 2627 heap->camera_memory[i] = NULL; 2628 } else if (heap->fd[i] <= 0) { 2629 ALOGE("impossible: amera_memory[%d] = %p, fd = %d", 2630 i, heap->camera_memory[i], heap->fd[i]); 2631 } 2632 2633 if(heap->fd[i] > 0) { 2634 close(heap->fd[i]); 2635 heap->fd[i] = -1; 2636 } 2637 #ifdef USE_ION 2638 deallocate_ion_memory(heap, i); 2639 #endif 2640 } 2641 heap->buffer_count = 0; 2642 heap->size = 0; 2643 heap->y_offset = 0; 2644 heap->cbcr_offset = 0; 2645 } 2646 return rc; 2647 } 2648 2649 preview_format_info_t QCameraHardwareInterface::getPreviewFormatInfo( ) 2650 { 2651 return mPreviewFormatInfo; 2652 } 2653 2654 void QCameraHardwareInterface::wdenoiseEvent(cam_ctrl_status_t status, void *cookie) 2655 { 2656 ALOGV("wdnEvent: preview state:%d E",mPreviewState); 2657 if (mStreamSnap != NULL) { 2658 ALOGV("notifyWDNEvent to snapshot stream"); 2659 mStreamSnap->notifyWDenoiseEvent(status, cookie); 2660 } 2661 } 2662 2663 bool QCameraHardwareInterface::isWDenoiseEnabled() 2664 { 2665 return mDenoiseValue; 2666 } 2667 2668 void QCameraHardwareInterface::takePicturePrepareHardware() 2669 { 2670 ALOGV("%s: E", __func__); 2671 2672 /* Prepare snapshot*/ 2673 cam_ops_action(mCameraId, 2674 true, 2675 MM_CAMERA_OPS_PREPARE_SNAPSHOT, 2676 this); 2677 ALOGV("%s: X", __func__); 2678 } 2679 2680 bool QCameraHardwareInterface::isNoDisplayMode() 2681 { 2682 return (mNoDisplayMode != 0); 2683 } 2684 2685 void QCameraHardwareInterface::pausePreviewForZSL() 2686 { 2687 ALOGV("%s: mRestartPreview %d", __func__, mRestartPreview); 2688 if(mRestartPreview) { 2689 ALOGE("%s: Restarting Preview",__func__); 2690 stopPreviewInternal(); 2691 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 2692 startPreview2(); 2693 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 2694 } 2695 } 2696 2697 void QCameraHardwareInterface::pausePreviewForVideo() 2698 { 2699 status_t ret = NO_ERROR; 2700 bool restart = false; 2701 cam_ctrl_dimension_t dim; 2702 2703 /* get existing preview information, by qury mm_camera*/ 2704 memset(&dim, 0, sizeof(cam_ctrl_dimension_t)); 2705 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim); 2706 2707 if (MM_CAMERA_OK != ret) { 2708 ALOGE("%s: X error- can't get preview dimension!", __func__); 2709 return; 2710 } 2711 2712 if (mRestartPreview) { 2713 mRestartPreview = false; 2714 ALOGV("%s: Restarting Preview. Video Size changed",__func__); 2715 restart |= false; 2716 } 2717 if (mRecordingHint == false) { 2718 ALOGV("%s: Restarting Preview. Hint not set",__func__); 2719 restart |= true; 2720 } 2721 2722 if(dim.video_width != mVideoWidth || dim.video_height != mVideoHeight){ 2723 ALOGV("%s: Restarting Preview. New Video Size set",__func__); 2724 restart |= true; 2725 } 2726 2727 //VFE output1 shouldn't be greater than VFE output2. 2728 if( (mPreviewWidth > mVideoWidth) || (mPreviewHeight > mVideoHeight)) { 2729 //Set preview sizes as record sizes. 2730 ALOGV("Preview size %dx%d is greater than record size %dx%d,\ 2731 resetting preview size to record size",mPreviewWidth, 2732 mPreviewHeight, mVideoWidth, mVideoHeight); 2733 mPreviewWidth = mVideoWidth; 2734 mPreviewHeight = mVideoHeight; 2735 mParameters.setPreviewSize(mPreviewWidth, mPreviewHeight); 2736 restart |= true; 2737 } 2738 if (restart) { 2739 stopPreviewInternal(); 2740 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 2741 2742 // Set recording hint to true 2743 mRecordingHint = true; 2744 setRecordingHintValue(mRecordingHint); 2745 2746 mDimension.display_width = mPreviewWidth; 2747 mDimension.display_height= mPreviewHeight; 2748 mDimension.orig_video_width = mVideoWidth; 2749 mDimension.orig_video_height = mVideoHeight; 2750 mDimension.video_width = mVideoWidth; 2751 mDimension.video_height = mVideoHeight; 2752 2753 // start preview again 2754 mPreviewState = QCAMERA_HAL_PREVIEW_START; 2755 if (startPreview2() == NO_ERROR){ 2756 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 2757 }else{ 2758 ALOGE("%s: Restart for Video Failed",__func__); 2759 } 2760 } 2761 } 2762 2763 /**/ 2764 bool QCameraHardwareInterface::getHdrInfoAndSetExp( int max_num_frm, int *num_frame, int *exp) 2765 { 2766 bool rc = false; 2767 2768 if (mHdrMode == HDR_MODE && num_frame != NULL && exp != NULL && 2769 mRecordingHint != true && 2770 mPreviewState != QCAMERA_HAL_RECORDING_STARTED ) { 2771 int ret = 0; 2772 *num_frame = 1; 2773 exp_bracketing_t temp; 2774 memset(&temp, 0, sizeof(exp_bracketing_t)); 2775 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HDR, (void *)&temp ); 2776 if (ret == NO_ERROR && max_num_frm > 0) { 2777 /*set as AE Bracketing mode*/ 2778 temp.hdr_enable = false; 2779 temp.mode = HDR_MODE; 2780 temp.total_hal_frames = temp.total_frames; 2781 ret = native_set_parms(MM_CAMERA_PARM_HDR, 2782 sizeof(exp_bracketing_t), (void *)&temp); 2783 if (ret) { 2784 char *val, *exp_value, *prev_value; 2785 int i; 2786 exp_value = (char *) temp.values; 2787 i = 0; 2788 val = strtok_r(exp_value,",", &prev_value); 2789 while (val != NULL ){ 2790 exp[i++] = atoi(val); 2791 if(i >= max_num_frm ) 2792 break; 2793 val = strtok_r(NULL, ",", &prev_value); 2794 } 2795 *num_frame =temp.total_frames; 2796 rc = true; 2797 } 2798 } else { 2799 temp.total_frames = 1; 2800 } 2801 /* Application waits until this many snapshots before restarting preview */ 2802 mParameters.set("num-snaps-per-shutter", 2); 2803 } 2804 return rc; 2805 } 2806 2807 void QCameraHardwareInterface::hdrEvent(cam_ctrl_status_t status, void *cookie) 2808 { 2809 QCameraStream * snapStream = (QCameraStream *)cookie; 2810 ALOGV("HdrEvent: preview state: E"); 2811 if (snapStream != NULL && mStreamSnap != NULL) { 2812 ALOGV("HdrEvent to snapshot stream"); 2813 snapStream->notifyHdrEvent(status, cookie); 2814 } 2815 } 2816 2817 }; // namespace android 2818