Home | History | Annotate | Download | only in camera
      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