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