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 if(mAutoFocusRunning==true){ 1892 ALOGV("%s:AF already running should not have got this call",__func__); 1893 return NO_ERROR; 1894 } 1895 1896 if (afMode == AF_MODE_MAX) { 1897 /* This should never happen. We cannot send a 1898 * callback notifying error from this place because 1899 * the CameraService has called this function after 1900 * acquiring the lock. So if we try to issue a callback 1901 * from this place, the callback will try to acquire 1902 * the same lock in CameraService and it will result 1903 * in deadlock. So, let the call go in to the lower 1904 * layer. The lower layer will anyway return error if 1905 * the autofocus is not supported or if the focus 1906 * value is invalid. 1907 * Just print out the error. */ 1908 ALOGE("%s:Invalid AF mode (%d)", __func__, afMode); 1909 } 1910 1911 ALOGV("%s:AF start (mode %d)", __func__, afMode); 1912 if(MM_CAMERA_OK != cam_ops_action(mCameraId, true, 1913 MM_CAMERA_OPS_FOCUS, &afMode)) { 1914 ALOGE("%s: AF command failed err:%d error %s", 1915 __func__, errno, strerror(errno)); 1916 return UNKNOWN_ERROR; 1917 } 1918 1919 mAutoFocusRunning = true; 1920 ALOGV("autoFocus: X"); 1921 return ret; 1922 } 1923 1924 status_t QCameraHardwareInterface::cancelAutoFocus() 1925 { 1926 ALOGV("cancelAutoFocus: E"); 1927 status_t ret = NO_ERROR; 1928 Mutex::Autolock lock(mLock); 1929 1930 /************************************************************** 1931 BEGIN MUTEX CODE 1932 *************************************************************/ 1933 1934 mAutofocusLock.lock(); 1935 if(mAutoFocusRunning || mNeedToUnlockCaf) { 1936 mNeedToUnlockCaf = false; 1937 mAutoFocusRunning = false; 1938 mAutofocusLock.unlock(); 1939 1940 }else/*(!mAutoFocusRunning)*/{ 1941 1942 mAutofocusLock.unlock(); 1943 ALOGV("%s:Af not running",__func__); 1944 return NO_ERROR; 1945 } 1946 /************************************************************** 1947 END MUTEX CODE 1948 *************************************************************/ 1949 1950 1951 if(MM_CAMERA_OK!=cam_ops_action(mCameraId,false,MM_CAMERA_OPS_FOCUS,NULL )) { 1952 ALOGE("%s: AF command failed err:%d error %s",__func__, errno,strerror(errno)); 1953 } 1954 1955 ALOGV("cancelAutoFocus: X"); 1956 return NO_ERROR; 1957 } 1958 1959 #if 0 //mzhu 1960 /*========================================================================== 1961 * FUNCTION - prepareSnapshotAndWait - 1962 * 1963 * DESCRIPTION: invoke preparesnapshot and wait for it done 1964 it can be called within takepicture, so no need 1965 to grab mLock. 1966 *=========================================================================*/ 1967 void QCameraHardwareInterface::prepareSnapshotAndWait() 1968 { 1969 ALOGI("prepareSnapshotAndWait: E"); 1970 int rc = 0; 1971 /*To Do: call mm camera preparesnapshot */ 1972 if(!rc ) { 1973 mPreparingSnapshot = true; 1974 pthread_mutex_lock(&mAsyncCmdMutex); 1975 pthread_cond_wait(&mAsyncCmdWait, &mAsyncCmdMutex); 1976 pthread_mutex_unlock(&mAsyncCmdMutex); 1977 mPreparingSnapshot = false; 1978 } 1979 ALOGI("prepareSnapshotAndWait: X"); 1980 } 1981 #endif //mzhu 1982 1983 /*========================================================================== 1984 * FUNCTION - processprepareSnapshotEvent - 1985 * 1986 * DESCRIPTION: Process the event of preparesnapshot done msg 1987 unblock prepareSnapshotAndWait( ) 1988 *=========================================================================*/ 1989 void QCameraHardwareInterface::processprepareSnapshotEvent(cam_ctrl_status_t *status) 1990 { 1991 ALOGV("processprepareSnapshotEvent: E"); 1992 pthread_mutex_lock(&mAsyncCmdMutex); 1993 pthread_cond_signal(&mAsyncCmdWait); 1994 pthread_mutex_unlock(&mAsyncCmdMutex); 1995 ALOGV("processprepareSnapshotEvent: X"); 1996 } 1997 1998 void QCameraHardwareInterface::roiEvent(fd_roi_t roi,app_notify_cb_t *app_cb) 1999 { 2000 ALOGV("roiEvent: E"); 2001 2002 if(mStreamDisplay) mStreamDisplay->notifyROIEvent(roi); 2003 #if 0 //TODO: move to preview obj 2004 mCallbackLock.lock(); 2005 data_callback mcb = mDataCb; 2006 void *mdata = mCallbackCookie; 2007 int msgEnabled = mMsgEnabled; 2008 mCallbackLock.unlock(); 2009 2010 mMetaDataWaitLock.lock(); 2011 if (mFaceDetectOn == true && mSendMetaData == true) { 2012 mSendMetaData = false; 2013 int faces_detected = roi.rect_num; 2014 int max_faces_detected = MAX_ROI * 4; 2015 int array[max_faces_detected + 1]; 2016 2017 array[0] = faces_detected * 4; 2018 for (int i = 1, j = 0;j < MAX_ROI; j++, i = i + 4) { 2019 if (j < faces_detected) { 2020 array[i] = roi.faces[j].x; 2021 array[i+1] = roi.faces[j].y; 2022 array[i+2] = roi.faces[j].dx; 2023 array[i+3] = roi.faces[j].dy; 2024 } else { 2025 array[i] = -1; 2026 array[i+1] = -1; 2027 array[i+2] = -1; 2028 array[i+3] = -1; 2029 } 2030 } 2031 if(mMetaDataHeap != NULL){ 2032 ALOGV("mMetaDataHEap is non-NULL"); 2033 memcpy((uint32_t *)mMetaDataHeap->mHeap->base(), (uint32_t *)array, (sizeof(int)*(MAX_ROI*4+1))); 2034 mMetaDataWaitLock.unlock(); 2035 2036 if (mcb != NULL && (msgEnabled & CAMERA_MSG_META_DATA)) { 2037 mcb(CAMERA_MSG_META_DATA, mMetaDataHeap->mBuffers[0], mdata); 2038 } 2039 } else { 2040 mMetaDataWaitLock.unlock(); 2041 ALOGE("runPreviewThread mMetaDataHeap is NULL"); 2042 } 2043 } else { 2044 mMetaDataWaitLock.unlock(); 2045 } 2046 #endif // mzhu 2047 ALOGV("roiEvent: X"); 2048 } 2049 2050 2051 void QCameraHardwareInterface::handleZoomEventForSnapshot(void) 2052 { 2053 mm_camera_ch_crop_t v4l2_crop; 2054 2055 2056 ALOGV("%s: E", __func__); 2057 2058 memset(&v4l2_crop,0,sizeof(v4l2_crop)); 2059 v4l2_crop.ch_type=MM_CAMERA_CH_SNAPSHOT; 2060 2061 ALOGV("%s: Fetching crop info", __func__); 2062 cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop); 2063 2064 ALOGV("%s: Crop info received for main: %d, %d, %d, %d ", __func__, 2065 v4l2_crop.snapshot.main_crop.left, 2066 v4l2_crop.snapshot.main_crop.top, 2067 v4l2_crop.snapshot.main_crop.width, 2068 v4l2_crop.snapshot.main_crop.height); 2069 ALOGV("%s: Crop info received for thumbnail: %d, %d, %d, %d ",__func__, 2070 v4l2_crop.snapshot.thumbnail_crop.left, 2071 v4l2_crop.snapshot.thumbnail_crop.top, 2072 v4l2_crop.snapshot.thumbnail_crop.width, 2073 v4l2_crop.snapshot.thumbnail_crop.height); 2074 2075 if(mStreamSnap) { 2076 ALOGV("%s: Setting crop info for snapshot", __func__); 2077 memcpy(&(mStreamSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop)); 2078 } 2079 if(mFullLiveshotEnabled && mStreamLiveSnap){ 2080 ALOGV("%s: Setting crop info for snapshot", __func__); 2081 memcpy(&(mStreamLiveSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop)); 2082 } 2083 ALOGV("%s: X", __func__); 2084 } 2085 2086 void QCameraHardwareInterface::handleZoomEventForPreview(app_notify_cb_t *app_cb) 2087 { 2088 mm_camera_ch_crop_t v4l2_crop; 2089 2090 ALOGV("%s: E", __func__); 2091 2092 /*regular zooming or smooth zoom stopped*/ 2093 if (!mSmoothZoomRunning && mPreviewWindow) { 2094 memset(&v4l2_crop, 0, sizeof(v4l2_crop)); 2095 v4l2_crop.ch_type = MM_CAMERA_CH_PREVIEW; 2096 2097 ALOGV("%s: Fetching crop info", __func__); 2098 cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop); 2099 2100 ALOGV("%s: Crop info received: %d, %d, %d, %d ", __func__, 2101 v4l2_crop.crop.left, 2102 v4l2_crop.crop.top, 2103 v4l2_crop.crop.width, 2104 v4l2_crop.crop.height); 2105 2106 mPreviewWindow->set_crop(mPreviewWindow, 2107 v4l2_crop.crop.left, 2108 v4l2_crop.crop.top, 2109 v4l2_crop.crop.left + v4l2_crop.crop.width, 2110 v4l2_crop.crop.top + v4l2_crop.crop.height); 2111 ALOGV("%s: Done setting crop", __func__); 2112 ALOGV("%s: Currrent zoom :%d",__func__, mCurrentZoom); 2113 } 2114 2115 ALOGV("%s: X", __func__); 2116 } 2117 2118 void QCameraHardwareInterface::zoomEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb) 2119 { 2120 ALOGV("zoomEvent: state:%d E",mPreviewState); 2121 switch (mPreviewState) { 2122 case QCAMERA_HAL_PREVIEW_STOPPED: 2123 break; 2124 case QCAMERA_HAL_PREVIEW_START: 2125 break; 2126 case QCAMERA_HAL_PREVIEW_STARTED: 2127 handleZoomEventForPreview(app_cb); 2128 if (isZSLMode()) 2129 handleZoomEventForSnapshot(); 2130 break; 2131 case QCAMERA_HAL_RECORDING_STARTED: 2132 handleZoomEventForPreview(app_cb); 2133 if (mFullLiveshotEnabled) 2134 handleZoomEventForSnapshot(); 2135 break; 2136 case QCAMERA_HAL_TAKE_PICTURE: 2137 if(isZSLMode()) 2138 handleZoomEventForPreview(app_cb); 2139 handleZoomEventForSnapshot(); 2140 break; 2141 default: 2142 break; 2143 } 2144 ALOGV("zoomEvent: X"); 2145 } 2146 2147 void QCameraHardwareInterface::dumpFrameToFile(const void * data, uint32_t size, char* name, char* ext, int index) 2148 { 2149 #if 0 2150 char buf[32], value[PROPERTY_VALUE_MAX]; 2151 int file_fd, enabled = 0; 2152 static int i = 0 ; 2153 property_get("persist.camera.dumpimage", value, "0"); 2154 enabled = atoi(value); 2155 2156 if ( data != NULL && enabled) { 2157 char * str; 2158 snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext); 2159 ALOGE("%s size =%d", buf, size); 2160 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2161 write(file_fd, data, size); 2162 close(file_fd); 2163 i++; 2164 } 2165 #endif 2166 } 2167 2168 void QCameraHardwareInterface::dumpFrameToFile(struct msm_frame* newFrame, 2169 HAL_cam_dump_frm_type_t frm_type) 2170 { 2171 #if 0 2172 int32_t enabled = 0; 2173 int frm_num; 2174 uint32_t skip_mode; 2175 char value[PROPERTY_VALUE_MAX]; 2176 char buf[32]; 2177 int main_422 = 1; 2178 property_get("persist.camera.dumpimg", value, "0"); 2179 enabled = atoi(value); 2180 2181 ALOGV(" newFrame =%p, frm_type = %d", newFrame, frm_type); 2182 if(enabled & HAL_DUMP_FRM_MASK_ALL) { 2183 if((enabled & frm_type) && newFrame) { 2184 frm_num = ((enabled & 0xffff0000) >> 16); 2185 if(frm_num == 0) frm_num = 10; /*default 10 frames*/ 2186 if(frm_num > 256) frm_num = 256; /*256 buffers cycle around*/ 2187 skip_mode = ((enabled & 0x0000ff00) >> 8); 2188 if(skip_mode == 0) skip_mode = 1; /*no -skip */ 2189 2190 if( mDumpSkipCnt % skip_mode == 0) { 2191 if (mDumpFrmCnt >= 0 && mDumpFrmCnt <= frm_num) { 2192 int w, h; 2193 int file_fd; 2194 switch (frm_type) { 2195 case HAL_DUMP_FRM_PREVIEW: 2196 w = mDimension.display_width; 2197 h = mDimension.display_height; 2198 snprintf(buf, sizeof(buf), "/data/%dp_%dx%d.yuv", mDumpFrmCnt, w, h); 2199 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2200 break; 2201 case HAL_DUMP_FRM_VIDEO: 2202 w = mVideoWidth; 2203 h = mVideoHeight; 2204 snprintf(buf, sizeof(buf),"/data/%dv_%dx%d.yuv", mDumpFrmCnt, w, h); 2205 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2206 break; 2207 case HAL_DUMP_FRM_MAIN: 2208 w = mDimension.picture_width; 2209 h = mDimension.picture_height; 2210 snprintf(buf, sizeof(buf), "/data/%dm_%dx%d.yuv", mDumpFrmCnt, w, h); 2211 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2212 if (mDimension.main_img_format == CAMERA_YUV_422_NV16 || 2213 mDimension.main_img_format == CAMERA_YUV_422_NV61) 2214 main_422 = 2; 2215 break; 2216 case HAL_DUMP_FRM_THUMBNAIL: 2217 w = mDimension.ui_thumbnail_width; 2218 h = mDimension.ui_thumbnail_height; 2219 snprintf(buf, sizeof(buf),"/data/%dt_%dx%d.yuv", mDumpFrmCnt, w, h); 2220 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2221 break; 2222 default: 2223 w = h = 0; 2224 file_fd = -1; 2225 break; 2226 } 2227 2228 if (file_fd < 0) { 2229 ALOGE("%s: cannot open file:type=%d\n", __func__, frm_type); 2230 } else { 2231 ALOGV("%s: %d %d", __func__, newFrame->y_off, newFrame->cbcr_off); 2232 write(file_fd, (const void *)(newFrame->buffer+newFrame->y_off), w * h); 2233 write(file_fd, (const void *) 2234 (newFrame->buffer + newFrame->cbcr_off), w * h / 2 * main_422); 2235 close(file_fd); 2236 ALOGV("dump %s", buf); 2237 } 2238 } else if(frm_num == 256){ 2239 mDumpFrmCnt = 0; 2240 } 2241 mDumpFrmCnt++; 2242 } 2243 mDumpSkipCnt++; 2244 } 2245 } else { 2246 mDumpFrmCnt = 0; 2247 } 2248 #endif 2249 } 2250 2251 status_t QCameraHardwareInterface::setPreviewWindow(preview_stream_ops_t* window) 2252 { 2253 status_t retVal = NO_ERROR; 2254 ALOGV(" %s: E mPreviewState = %d, mStreamDisplay = %p", __FUNCTION__, mPreviewState, mStreamDisplay); 2255 if( window == NULL) { 2256 ALOGE("%s:Received Setting NULL preview window", __func__); 2257 } 2258 Mutex::Autolock lock(mLock); 2259 switch(mPreviewState) { 2260 case QCAMERA_HAL_PREVIEW_START: 2261 mPreviewWindow = window; 2262 if(mPreviewWindow) { 2263 /* we have valid surface now, start preview */ 2264 retVal = startPreview2(); 2265 if(retVal == NO_ERROR) 2266 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 2267 ALOGV("%s: startPreview2 done, mPreviewState = %d", __func__, mPreviewState); 2268 } else 2269 ALOGE("%s: null window received, mPreviewState = %d", __func__, mPreviewState); 2270 break; 2271 case QCAMERA_HAL_PREVIEW_STARTED: 2272 /* new window comes */ 2273 ALOGE("%s: bug, cannot handle new window in started state", __func__); 2274 //retVal = UNKNOWN_ERROR; 2275 break; 2276 case QCAMERA_HAL_PREVIEW_STOPPED: 2277 case QCAMERA_HAL_TAKE_PICTURE: 2278 mPreviewWindow = window; 2279 ALOGE("%s: mPreviewWindow = 0x%p, mStreamDisplay = 0x%p", 2280 __func__, mPreviewWindow, mStreamDisplay); 2281 if(mStreamDisplay) 2282 retVal = mStreamDisplay->setPreviewWindow(window); 2283 break; 2284 default: 2285 ALOGE("%s: bug, cannot handle new window in state %d", __func__, mPreviewState); 2286 retVal = UNKNOWN_ERROR; 2287 break; 2288 } 2289 ALOGV(" %s : X, mPreviewState = %d", __FUNCTION__, mPreviewState); 2290 return retVal; 2291 } 2292 2293 int QCameraHardwareInterface::storeMetaDataInBuffers(int enable) 2294 { 2295 /* this is a dummy func now. fix me later */ 2296 mStoreMetaDataInFrame = enable; 2297 return 0; 2298 } 2299 2300 status_t QCameraHardwareInterface::sendMappingBuf(int ext_mode, int idx, int fd, 2301 uint32_t size, int cameraid, 2302 mm_camera_socket_msg_type msg_type) 2303 { 2304 cam_sock_packet_t packet; 2305 memset(&packet, 0, sizeof(cam_sock_packet_t)); 2306 packet.msg_type = msg_type; 2307 packet.payload.frame_fd_map.ext_mode = ext_mode; 2308 packet.payload.frame_fd_map.frame_idx = idx; 2309 packet.payload.frame_fd_map.fd = fd; 2310 packet.payload.frame_fd_map.size = size; 2311 2312 if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), packet.payload.frame_fd_map.fd) <= 0 ) { 2313 ALOGE("%s: sending frame mapping buf msg Failed", __func__); 2314 return FAILED_TRANSACTION; 2315 } 2316 return NO_ERROR; 2317 } 2318 2319 status_t QCameraHardwareInterface::sendUnMappingBuf(int ext_mode, int idx, int cameraid, 2320 mm_camera_socket_msg_type msg_type) 2321 { 2322 cam_sock_packet_t packet; 2323 memset(&packet, 0, sizeof(cam_sock_packet_t)); 2324 packet.msg_type = msg_type; 2325 packet.payload.frame_fd_unmap.ext_mode = ext_mode; 2326 packet.payload.frame_fd_unmap.frame_idx = idx; 2327 if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), 0) <= 0 ) { 2328 ALOGE("%s: sending frame unmapping buf msg Failed", __func__); 2329 return FAILED_TRANSACTION; 2330 } 2331 return NO_ERROR; 2332 } 2333 2334 int QCameraHardwareInterface::allocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt, int ion_type) 2335 { 2336 int rc = 0; 2337 struct ion_handle_data handle_data; 2338 2339 p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY); 2340 if (p_camera_memory->main_ion_fd[cnt] < 0) { 2341 ALOGE("Ion dev open failed\n"); 2342 ALOGE("Error is %s\n", strerror(errno)); 2343 goto ION_OPEN_FAILED; 2344 } 2345 p_camera_memory->alloc[cnt].len = p_camera_memory->size; 2346 /* to make it page size aligned */ 2347 p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095); 2348 p_camera_memory->alloc[cnt].align = 4096; 2349 p_camera_memory->alloc[cnt].flags = ION_FLAG_CACHED; 2350 p_camera_memory->alloc[cnt].heap_mask = ion_type; 2351 2352 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]); 2353 if (rc < 0) { 2354 ALOGE("ION allocation failed\n"); 2355 goto ION_ALLOC_FAILED; 2356 } 2357 2358 p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle; 2359 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]); 2360 if (rc < 0) { 2361 ALOGE("ION map failed %s\n", strerror(errno)); 2362 goto ION_MAP_FAILED; 2363 } 2364 p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd; 2365 return 0; 2366 2367 ION_MAP_FAILED: 2368 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle; 2369 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data); 2370 ION_ALLOC_FAILED: 2371 close(p_camera_memory->main_ion_fd[cnt]); 2372 p_camera_memory->main_ion_fd[cnt] = -1; 2373 ION_OPEN_FAILED: 2374 return -1; 2375 } 2376 2377 int QCameraHardwareInterface::deallocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt) 2378 { 2379 struct ion_handle_data handle_data; 2380 int rc = 0; 2381 2382 if (p_camera_memory->main_ion_fd[cnt] > 0) { 2383 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle; 2384 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data); 2385 close(p_camera_memory->main_ion_fd[cnt]); 2386 p_camera_memory->main_ion_fd[cnt] = -1; 2387 } 2388 return rc; 2389 } 2390 2391 int QCameraHardwareInterface::allocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt, int ion_type) 2392 { 2393 int rc = 0; 2394 struct ion_handle_data handle_data; 2395 2396 p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY); 2397 if (p_camera_memory->main_ion_fd[cnt] < 0) { 2398 ALOGE("Ion dev open failed\n"); 2399 ALOGE("Error is %s\n", strerror(errno)); 2400 goto ION_OPEN_FAILED; 2401 } 2402 p_camera_memory->alloc[cnt].len = p_camera_memory->size; 2403 /* to make it page size aligned */ 2404 p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095); 2405 p_camera_memory->alloc[cnt].align = 4096; 2406 p_camera_memory->alloc[cnt].flags = ION_FLAG_CACHED; 2407 p_camera_memory->alloc[cnt].heap_mask = (0x1 << ion_type | 0x1 << ION_IOMMU_HEAP_ID); 2408 2409 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]); 2410 if (rc < 0) { 2411 ALOGE("ION allocation failed\n"); 2412 goto ION_ALLOC_FAILED; 2413 } 2414 2415 p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle; 2416 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]); 2417 if (rc < 0) { 2418 ALOGE("ION map failed %s\n", strerror(errno)); 2419 goto ION_MAP_FAILED; 2420 } 2421 p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd; 2422 return 0; 2423 2424 ION_MAP_FAILED: 2425 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle; 2426 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data); 2427 ION_ALLOC_FAILED: 2428 close(p_camera_memory->main_ion_fd[cnt]); 2429 p_camera_memory->main_ion_fd[cnt] = -1; 2430 ION_OPEN_FAILED: 2431 return -1; 2432 } 2433 2434 int QCameraHardwareInterface::cache_ops(int ion_fd, 2435 struct ion_flush_data *cache_data, int type) 2436 { 2437 int rc = 0; 2438 struct ion_custom_data data; 2439 data.cmd = type; 2440 data.arg = (unsigned long)cache_data; 2441 2442 rc = ioctl(ion_fd, ION_IOC_CUSTOM, &data); 2443 if (rc < 0) 2444 ALOGE("%s: Cache Invalidate failed\n", __func__); 2445 else 2446 ALOGV("%s: Cache OPs type(%d) success", __func__); 2447 2448 return rc; 2449 } 2450 2451 int QCameraHardwareInterface::deallocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt) 2452 { 2453 struct ion_handle_data handle_data; 2454 int rc = 0; 2455 2456 if (p_camera_memory->main_ion_fd[cnt] > 0) { 2457 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle; 2458 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data); 2459 close(p_camera_memory->main_ion_fd[cnt]); 2460 p_camera_memory->main_ion_fd[cnt] = -1; 2461 } 2462 return rc; 2463 } 2464 2465 int QCameraHardwareInterface::initHeapMem( QCameraHalHeap_t *heap, 2466 int num_of_buf, 2467 int buf_len, 2468 int y_off, 2469 int cbcr_off, 2470 int pmem_type, 2471 mm_cameara_stream_buf_t *StreamBuf, 2472 mm_camera_buf_def_t *buf_def, 2473 uint8_t num_planes, 2474 uint32_t *planes 2475 ) 2476 { 2477 int rc = 0; 2478 int i; 2479 int path; 2480 int ion_fd; 2481 struct msm_frame *frame; 2482 struct ion_flush_data cache_inv_data; 2483 ALOGV("Init Heap =%p. stream_buf =%p, pmem_type =%d, num_of_buf=%d. buf_len=%d, cbcr_off=%d", 2484 heap, StreamBuf, pmem_type, num_of_buf, buf_len, cbcr_off); 2485 if(num_of_buf > MM_CAMERA_MAX_NUM_FRAMES || heap == NULL || 2486 mGetMemory == NULL ) { 2487 ALOGE("Init Heap error"); 2488 rc = -1; 2489 return rc; 2490 } 2491 memset(heap, 0, sizeof(QCameraHalHeap_t)); 2492 for (i=0; i<MM_CAMERA_MAX_NUM_FRAMES;i++) { 2493 heap->main_ion_fd[i] = -1; 2494 heap->fd[i] = -1; 2495 } 2496 heap->buffer_count = num_of_buf; 2497 heap->size = buf_len; 2498 heap->y_offset = y_off; 2499 heap->cbcr_offset = cbcr_off; 2500 2501 if (StreamBuf != NULL) { 2502 StreamBuf->num = num_of_buf; 2503 StreamBuf->frame_len = buf_len; 2504 switch (pmem_type) { 2505 case MSM_PMEM_MAINIMG: 2506 case MSM_PMEM_RAW_MAINIMG: 2507 path = OUTPUT_TYPE_S; 2508 break; 2509 2510 case MSM_PMEM_THUMBNAIL: 2511 path = OUTPUT_TYPE_T; 2512 break; 2513 2514 default: 2515 rc = -1; 2516 return rc; 2517 } 2518 } 2519 2520 2521 for(i = 0; i < num_of_buf; i++) { 2522 #ifdef USE_ION 2523 if (isZSLMode()) 2524 rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ZSL_ION_HEAP_ID) | 2525 (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID))); 2526 else 2527 rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ION_HEAP_ID) | 2528 (0x1 << CAMERA_ION_FALLBACK_HEAP_ID))); 2529 2530 if (rc < 0) { 2531 ALOGE("%s: ION allocation failed\n", __func__); 2532 break; 2533 } 2534 #else 2535 if (pmem_type == MSM_PMEM_MAX) 2536 heap->fd[i] = -1; 2537 else { 2538 heap->fd[i] = open("/dev/pmem_adsp", O_RDWR|O_SYNC); 2539 if ( heap->fd[i] <= 0) { 2540 rc = -1; 2541 ALOGE("Open fail: heap->fd[%d] =%d", i, heap->fd[i]); 2542 break; 2543 } 2544 } 2545 #endif 2546 heap->camera_memory[i] = mGetMemory( heap->fd[i], buf_len, 1, (void *)this); 2547 2548 if (heap->camera_memory[i] == NULL ) { 2549 ALOGE("Getmem fail %d: ", i); 2550 rc = -1; 2551 break; 2552 } 2553 2554 memset(&cache_inv_data, 0, sizeof(struct ion_flush_data)); 2555 cache_inv_data.vaddr = (void*) heap->camera_memory[i]->data; 2556 cache_inv_data.fd = heap->ion_info_fd[i].fd; 2557 cache_inv_data.handle = heap->ion_info_fd[i].handle; 2558 cache_inv_data.length = heap->alloc[i].len; 2559 ion_fd = heap->main_ion_fd[i]; 2560 if(ion_fd > 0) { 2561 if(cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_INV_CACHES) < 0) 2562 ALOGE("%s: Cache Invalidate failed\n", __func__); 2563 else { 2564 ALOGV("%s: Successful cache invalidate\n", __func__); 2565 } 2566 } 2567 2568 if (StreamBuf != NULL) { 2569 frame = &(StreamBuf->frame[i]); 2570 memset(frame, 0, sizeof(struct msm_frame)); 2571 frame->fd = heap->fd[i]; 2572 frame->phy_offset = 0; 2573 frame->buffer = (uint32_t) heap->camera_memory[i]->data; 2574 frame->path = path; 2575 frame->cbcr_off = planes[0]+heap->cbcr_offset; 2576 frame->y_off = heap->y_offset; 2577 frame->fd_data = heap->ion_info_fd[i]; 2578 frame->ion_alloc = heap->alloc[i]; 2579 frame->ion_dev_fd = heap->main_ion_fd[i]; 2580 ALOGV("%s: Buffer idx: %d addr: %x fd: %d phy_offset: %d" 2581 "cbcr_off: %d y_off: %d frame_len: %d", __func__, 2582 i, (unsigned int)frame->buffer, frame->fd, 2583 frame->phy_offset, cbcr_off, y_off, frame->ion_alloc.len); 2584 2585 buf_def->buf.mp[i].frame = *frame; 2586 buf_def->buf.mp[i].frame_offset = 0; 2587 buf_def->buf.mp[i].num_planes = num_planes; 2588 /* Plane 0 needs to be set seperately. Set other planes 2589 * in a loop. */ 2590 buf_def->buf.mp[i].planes[0].length = planes[0]; 2591 buf_def->buf.mp[i].planes[0].m.userptr = frame->fd; 2592 buf_def->buf.mp[i].planes[0].data_offset = y_off; 2593 buf_def->buf.mp[i].planes[0].reserved[0] = 2594 buf_def->buf.mp[i].frame_offset; 2595 for (int j = 1; j < num_planes; j++) { 2596 buf_def->buf.mp[i].planes[j].length = planes[j]; 2597 buf_def->buf.mp[i].planes[j].m.userptr = frame->fd; 2598 buf_def->buf.mp[i].planes[j].data_offset = cbcr_off; 2599 buf_def->buf.mp[i].planes[j].reserved[0] = 2600 buf_def->buf.mp[i].planes[j-1].reserved[0] + 2601 buf_def->buf.mp[i].planes[j-1].length; 2602 } 2603 } else { 2604 } 2605 2606 ALOGV("heap->fd[%d] =%d, camera_memory=%p", i, heap->fd[i], heap->camera_memory[i]); 2607 heap->local_flag[i] = 1; 2608 } 2609 if( rc < 0) { 2610 releaseHeapMem(heap); 2611 } 2612 return rc; 2613 } 2614 2615 int QCameraHardwareInterface::releaseHeapMem( QCameraHalHeap_t *heap) 2616 { 2617 int rc = 0; 2618 ALOGV("Release %p", heap); 2619 if (heap != NULL) { 2620 2621 for (int i = 0; i < heap->buffer_count; i++) { 2622 if(heap->camera_memory[i] != NULL) { 2623 heap->camera_memory[i]->release( heap->camera_memory[i] ); 2624 heap->camera_memory[i] = NULL; 2625 } else if (heap->fd[i] <= 0) { 2626 ALOGE("impossible: amera_memory[%d] = %p, fd = %d", 2627 i, heap->camera_memory[i], heap->fd[i]); 2628 } 2629 2630 if(heap->fd[i] > 0) { 2631 close(heap->fd[i]); 2632 heap->fd[i] = -1; 2633 } 2634 #ifdef USE_ION 2635 deallocate_ion_memory(heap, i); 2636 #endif 2637 } 2638 heap->buffer_count = 0; 2639 heap->size = 0; 2640 heap->y_offset = 0; 2641 heap->cbcr_offset = 0; 2642 } 2643 return rc; 2644 } 2645 2646 preview_format_info_t QCameraHardwareInterface::getPreviewFormatInfo( ) 2647 { 2648 return mPreviewFormatInfo; 2649 } 2650 2651 void QCameraHardwareInterface::wdenoiseEvent(cam_ctrl_status_t status, void *cookie) 2652 { 2653 ALOGV("wdnEvent: preview state:%d E",mPreviewState); 2654 if (mStreamSnap != NULL) { 2655 ALOGV("notifyWDNEvent to snapshot stream"); 2656 mStreamSnap->notifyWDenoiseEvent(status, cookie); 2657 } 2658 } 2659 2660 bool QCameraHardwareInterface::isWDenoiseEnabled() 2661 { 2662 return mDenoiseValue; 2663 } 2664 2665 void QCameraHardwareInterface::takePicturePrepareHardware() 2666 { 2667 ALOGV("%s: E", __func__); 2668 2669 /* Prepare snapshot*/ 2670 cam_ops_action(mCameraId, 2671 true, 2672 MM_CAMERA_OPS_PREPARE_SNAPSHOT, 2673 this); 2674 ALOGV("%s: X", __func__); 2675 } 2676 2677 bool QCameraHardwareInterface::isNoDisplayMode() 2678 { 2679 return (mNoDisplayMode != 0); 2680 } 2681 2682 void QCameraHardwareInterface::pausePreviewForZSL() 2683 { 2684 ALOGV("%s: mRestartPreview %d", __func__, mRestartPreview); 2685 if(mRestartPreview) { 2686 ALOGE("%s: Restarting Preview",__func__); 2687 stopPreviewInternal(); 2688 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 2689 startPreview2(); 2690 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 2691 } 2692 } 2693 2694 void QCameraHardwareInterface::pausePreviewForVideo() 2695 { 2696 status_t ret = NO_ERROR; 2697 bool restart = false; 2698 cam_ctrl_dimension_t dim; 2699 2700 /* get existing preview information, by qury mm_camera*/ 2701 memset(&dim, 0, sizeof(cam_ctrl_dimension_t)); 2702 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim); 2703 2704 if (MM_CAMERA_OK != ret) { 2705 ALOGE("%s: X error- can't get preview dimension!", __func__); 2706 return; 2707 } 2708 2709 if (mRestartPreview) { 2710 mRestartPreview = false; 2711 ALOGV("%s: Restarting Preview. Video Size changed",__func__); 2712 restart |= false; 2713 } 2714 if (mRecordingHint == false) { 2715 ALOGV("%s: Restarting Preview. Hint not set",__func__); 2716 restart |= true; 2717 } 2718 2719 if(dim.video_width != mVideoWidth || dim.video_height != mVideoHeight){ 2720 ALOGV("%s: Restarting Preview. New Video Size set",__func__); 2721 restart |= true; 2722 } 2723 2724 //VFE output1 shouldn't be greater than VFE output2. 2725 if( (mPreviewWidth > mVideoWidth) || (mPreviewHeight > mVideoHeight)) { 2726 //Set preview sizes as record sizes. 2727 ALOGV("Preview size %dx%d is greater than record size %dx%d,\ 2728 resetting preview size to record size",mPreviewWidth, 2729 mPreviewHeight, mVideoWidth, mVideoHeight); 2730 mPreviewWidth = mVideoWidth; 2731 mPreviewHeight = mVideoHeight; 2732 mParameters.setPreviewSize(mPreviewWidth, mPreviewHeight); 2733 restart |= true; 2734 } 2735 if (restart) { 2736 stopPreviewInternal(); 2737 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 2738 2739 // Set recording hint to true 2740 mRecordingHint = true; 2741 setRecordingHintValue(mRecordingHint); 2742 2743 mDimension.display_width = mPreviewWidth; 2744 mDimension.display_height= mPreviewHeight; 2745 mDimension.orig_video_width = mVideoWidth; 2746 mDimension.orig_video_height = mVideoHeight; 2747 mDimension.video_width = mVideoWidth; 2748 mDimension.video_height = mVideoHeight; 2749 2750 // start preview again 2751 mPreviewState = QCAMERA_HAL_PREVIEW_START; 2752 if (startPreview2() == NO_ERROR){ 2753 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED; 2754 }else{ 2755 ALOGE("%s: Restart for Video Failed",__func__); 2756 } 2757 } 2758 } 2759 2760 /**/ 2761 bool QCameraHardwareInterface::getHdrInfoAndSetExp( int max_num_frm, int *num_frame, int *exp) 2762 { 2763 bool rc = false; 2764 2765 if (mHdrMode == HDR_MODE && num_frame != NULL && exp != NULL && 2766 mRecordingHint != true && 2767 mPreviewState != QCAMERA_HAL_RECORDING_STARTED ) { 2768 int ret = 0; 2769 *num_frame = 1; 2770 exp_bracketing_t temp; 2771 memset(&temp, 0, sizeof(exp_bracketing_t)); 2772 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HDR, (void *)&temp ); 2773 if (ret == NO_ERROR && max_num_frm > 0) { 2774 /*set as AE Bracketing mode*/ 2775 temp.hdr_enable = false; 2776 temp.mode = HDR_MODE; 2777 temp.total_hal_frames = temp.total_frames; 2778 ret = native_set_parms(MM_CAMERA_PARM_HDR, 2779 sizeof(exp_bracketing_t), (void *)&temp); 2780 if (ret) { 2781 char *val, *exp_value, *prev_value; 2782 int i; 2783 exp_value = (char *) temp.values; 2784 i = 0; 2785 val = strtok_r(exp_value,",", &prev_value); 2786 while (val != NULL ){ 2787 exp[i++] = atoi(val); 2788 if(i >= max_num_frm ) 2789 break; 2790 val = strtok_r(NULL, ",", &prev_value); 2791 } 2792 *num_frame =temp.total_frames; 2793 rc = true; 2794 } 2795 } else { 2796 temp.total_frames = 1; 2797 } 2798 /* Application waits until this many snapshots before restarting preview */ 2799 mParameters.set("num-snaps-per-shutter", 2); 2800 } 2801 return rc; 2802 } 2803 2804 void QCameraHardwareInterface::hdrEvent(cam_ctrl_status_t status, void *cookie) 2805 { 2806 QCameraStream * snapStream = (QCameraStream *)cookie; 2807 ALOGV("HdrEvent: preview state: E"); 2808 if (snapStream != NULL && mStreamSnap != NULL) { 2809 ALOGV("HdrEvent to snapshot stream"); 2810 snapStream->notifyHdrEvent(status, cookie); 2811 } 2812 } 2813 2814 }; // namespace android 2815