/*
** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

/*#error uncomment this for compiler test!*/
#define ALOG_NIDEBUG 0

#define LOG_TAG "QCameraHWI"
#include <utils/Log.h>
#include <utils/threads.h>
#include <cutils/properties.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <dlfcn.h>

#include "QCameraHAL.h"
#include "QCameraHWI.h"

/* QCameraHardwareInterface class implementation goes here*/
/* following code implement the contol logic of this class*/

namespace android {
static void HAL_event_cb(mm_camera_event_t *evt, void *user_data)
{
  QCameraHardwareInterface *obj = (QCameraHardwareInterface *)user_data;
  if (obj) {
    obj->processEvent(evt);
  } else {
    ALOGE("%s: NULL user_data", __func__);
  }
}

int32_t QCameraHardwareInterface::createRecord()
{
    int32_t ret = MM_CAMERA_OK;
    ALOGV("%s : BEGIN",__func__);

    /*
    * Creating Instance of record stream.
    */
    ALOGV("Mymode Record = %d",myMode);
    mStreamRecord = QCameraStream_record::createInstance(mCameraId,
                                                         myMode);

    if (!mStreamRecord) {
        ALOGE("%s: error - can't creat record stream!", __func__);
        return BAD_VALUE;
    }

    /* Store HAL object in record stream Object */
    mStreamRecord->setHALCameraControl(this);

    /*Init Channel */
    ret = mStreamRecord->init();
    if (MM_CAMERA_OK != ret){
        ALOGE("%s: error - can't init Record channel!", __func__);
        return BAD_VALUE;
    }
    ALOGV("%s : END",__func__);
    return ret;
}

int32_t QCameraHardwareInterface::createSnapshot()
{
    int32_t ret = MM_CAMERA_OK;
    ALOGV("%s : BEGIN",__func__);

    /*
    * Creating Instance of Snapshot stream.
    */
    ALOGV("Mymode Snap = %d",myMode);
    mStreamSnap = QCameraStream_Snapshot::createInstance(mCameraId,
                                                         myMode);
    if (!mStreamSnap) {
        ALOGE("%s: error - can't creat snapshot stream!", __func__);
        return BAD_VALUE;
    }

    /* Store HAL object in Snapshot stream Object */
    mStreamSnap->setHALCameraControl(this);

    /*Init Channel */
    ret = mStreamSnap->init();
    if (MM_CAMERA_OK != ret){
        ALOGE("%s: error - can't init Snapshot channel!", __func__);
        return BAD_VALUE;
    }
    ALOGV("%s : END",__func__);
    return ret;
}

int32_t QCameraHardwareInterface::createPreview()
{
    int32_t ret = MM_CAMERA_OK;
    ALOGV("%s : BEGIN",__func__);

    ALOGV("Mymode Preview = %d",myMode);
    mStreamDisplay = QCameraStream_preview::createInstance(mCameraId,
                                                           myMode);
    if (!mStreamDisplay) {
        ALOGE("%s: error - can't creat preview stream!", __func__);
        return BAD_VALUE;
    }

    mStreamDisplay->setHALCameraControl(this);

    /*now init all the buffers and send to steam object*/
    ret = mStreamDisplay->init();
    if (MM_CAMERA_OK != ret){
        ALOGE("%s: error - can't init Preview channel!", __func__);
        return BAD_VALUE;
    }
    ALOGV("%s : END",__func__);
    return ret;
}

/* constructor */
QCameraHardwareInterface::
QCameraHardwareInterface(int cameraId, int mode)
                  : mCameraId(cameraId),
                    mParameters(),
                    mMsgEnabled(0),
                    mNotifyCb(0),
                    mDataCb(0),
                    mDataCbTimestamp(0),
                    mCallbackCookie(0),
                    //mPreviewHeap(0),
                    mStreamDisplay (NULL), mStreamRecord(NULL), mStreamSnap(NULL),
                    mFps(0),
                    mDebugFps(0),
                    mMaxZoom(0),
                    mCurrentZoom(0),
                    mSupportedPictureSizesCount(15),
                    mDumpFrmCnt(0), mDumpSkipCnt(0),
                    mPictureSizeCount(15),
                    mPreviewSizeCount(13),
                    mVideoSizeCount(0),
                    mAutoFocusRunning(false),
                    mNeedToUnlockCaf(false),
                    mHasAutoFocusSupport(false),
                    mInitialized(false),
                    mIs3DModeOn(0),
                    mSmoothZoomRunning(false),
                    mParamStringInitialized(false),
                    mFaceDetectOn(0),
                    mDisEnabled(0),
                    mZoomSupported(false),
                    mFullLiveshotEnabled(false),
                    mRecordingHint(false),
                    mAppRecordingHint(false),
                    mStatsOn(0), mCurrentHisto(-1), mSendData(false), mStatHeap(NULL),
                    mZslLookBackMode(0),
                    mZslLookBackValue(0),
                    mZslEmptyQueueFlag(false),
                    mPictureSizes(NULL),
                    mVideoSizes(NULL),
                    mCameraState(CAMERA_STATE_UNINITED),
                    mPostPreviewHeap(NULL),
                    mHdrMode(HDR_BRACKETING_OFF),
                    mStreamLiveSnap(NULL),
                    mExifTableNumEntries(0),
                    mDenoiseValue(0),
                    mSnapshotFormat(0),
                    mStartRecording(0),
                    mZslInterval(1),
                    mNoDisplayMode(0),
                    mBrightness(0),
                    mContrast(0),
                    mEffects(0),
                    mBestShotMode(0),
                    mHJR(0),
                    mSkinToneEnhancement(0),
                    mRotation(0),
                    mFocusMode(AF_MODE_MAX),
                    mPreviewFormat(CAMERA_YUV_420_NV21),
                    mRestartPreview(false),
                    mReleasedRecordingFrame(false),
                    mStateLiveshot(false),
                    isCameraOpen(false),
                    mPauseFramedispatch(false)
{
    ALOGV("QCameraHardwareInterface: E");
    int32_t result = MM_CAMERA_E_GENERAL;
    char value[PROPERTY_VALUE_MAX];

    pthread_mutex_init(&mAsyncCmdMutex, NULL);
    pthread_cond_init(&mAsyncCmdWait, NULL);
    mFlashCond = false;

    property_get("persist.debug.sf.showfps", value, "0");
    mDebugFps = atoi(value);
    mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
    mPreviewWindow = NULL;
    property_get("camera.hal.fps", value, "0");
    mFps = atoi(value);

    ALOGV("Init mPreviewState = %d", mPreviewState);

    property_get("persist.camera.hal.multitouchaf", value, "0");
    mMultiTouch = atoi(value);

    property_get("persist.camera.full.liveshot", value, "0");
    mFullLiveshotEnabled = atoi(value);

    property_get("persist.camera.hal.dis", value, "0");
    mDisEnabled = atoi(value);

    /* Open camera stack! */
    result=cam_ops_open(mCameraId, MM_CAMERA_OP_MODE_NOTUSED);
    if (result == MM_CAMERA_OK) {
      int i;
      mm_camera_event_type_t evt;
      for (i = 0; i < MM_CAMERA_EVT_TYPE_MAX; i++) {
        evt = (mm_camera_event_type_t) i;
        if (cam_evt_is_event_supported(mCameraId, evt)){
            cam_evt_register_event_notify(mCameraId,
              HAL_event_cb, (void *)this, evt);
        }
      }
    }
    ALOGV("Cam open returned %d",result);
    if(MM_CAMERA_OK != result) {
          ALOGE("startCamera: cam_ops_open failed: id = %d", mCameraId);
          return;
    }

    loadTables();
    /* Setup Picture Size and Preview size tables */
    setPictureSizeTable();
    ALOGV("%s: Picture table size: %d", __func__, mPictureSizeCount);
    ALOGV("%s: Picture table: ", __func__);
    for(unsigned int i=0; i < mPictureSizeCount;i++) {
      ALOGV(" %d  %d", mPictureSizes[i].width, mPictureSizes[i].height);
    }

    setPreviewSizeTable();
    ALOGV("%s: Preview table size: %d", __func__, mPreviewSizeCount);
    ALOGV("%s: Preview table: ", __func__);
    for(unsigned int i=0; i < mPreviewSizeCount;i++) {
      ALOGV(" %d  %d", mPreviewSizes[i].width, mPreviewSizes[i].height);
    }

    setVideoSizeTable();
    ALOGV("%s: Video table size: %d", __func__, mVideoSizeCount);
    ALOGV("%s: Video table: ", __func__);
    for(unsigned int i=0; i < mVideoSizeCount;i++) {
      ALOGV(" %d  %d", mVideoSizes[i].width, mVideoSizes[i].height);
    }

    isCameraOpen = true;
    /* set my mode - update myMode member variable due to difference in
     enum definition between upper and lower layer*/
    setMyMode(mode);
    initDefaultParameters();

    //Create Stream Objects
    //Preview
    result = createPreview();
    if(result != MM_CAMERA_OK) {
        ALOGE("%s X: Failed to create Preview Object",__func__);
        return;
    }

    //Record
    result = createRecord();
    if(result != MM_CAMERA_OK) {
        ALOGE("%s X: Failed to create Record Object",__func__);
        return;
    }

    //Snapshot
    result = createSnapshot();
    if(result != MM_CAMERA_OK) {
        ALOGE("%s X: Failed to create Record Object",__func__);
        return;
    }
    mCameraState = CAMERA_STATE_READY;
    libdnr = dlopen("libmorpho_noise_reduction.so", RTLD_NOW);
    if (libdnr) {
        ALOGV("Open MM camera DL libmorpho_noise_reduction loaded at %p & %p ", libdnr);
        *(void **)&LINK_morpho_DNR_ProcessFrame = dlsym(libdnr, "LINK_mm_camera_morpho_noise_reduction");
    }
    else
        ALOGE("failed to open libmorpho_noise_reduction");

    ALOGV("QCameraHardwareInterface: X");
}

QCameraHardwareInterface::~QCameraHardwareInterface()
{
    ALOGV("~QCameraHardwareInterface: E");
    int result;

    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
        break;
    case QCAMERA_HAL_PREVIEW_START:
        break;
    case QCAMERA_HAL_PREVIEW_STARTED:
        stopPreview();
    break;
    case QCAMERA_HAL_RECORDING_STARTED:
        stopRecordingInternal();
        stopPreview();
        break;
    case QCAMERA_HAL_TAKE_PICTURE:
        cancelPictureInternal();
        break;
    default:
        break;
    }
    mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;

    if (isCameraOpen) {
        freePictureTable();
        freeVideoSizeTable();
        if(mStatHeap != NULL) {
          mStatHeap.clear( );
          mStatHeap = NULL;
        }
    }
    /* Join the threads, complete operations and then delete
       the instances. */
    cam_ops_close(mCameraId);
    if(mStreamDisplay){
        QCameraStream_preview::deleteInstance (mStreamDisplay);
        mStreamDisplay = NULL;
    }
    if(mStreamRecord) {
        QCameraStream_record::deleteInstance (mStreamRecord);
        mStreamRecord = NULL;
    }
    if(mStreamSnap) {
        QCameraStream_Snapshot::deleteInstance (mStreamSnap);
        mStreamSnap = NULL;
    }
    if (libdnr != NULL) {
         dlclose(libdnr);
         libdnr = NULL;
         ALOGV("closed libmorpho_noise_reduction.so");
    }

    if (mStreamLiveSnap){
        QCameraStream_Snapshot::deleteInstance (mStreamLiveSnap);
        mStreamLiveSnap = NULL;
    }

    pthread_mutex_destroy(&mAsyncCmdMutex);
    pthread_cond_destroy(&mAsyncCmdWait);
    isCameraOpen = false;

    ALOGV("~QCameraHardwareInterface: X");
}

bool QCameraHardwareInterface::isCameraReady()
{
    ALOGV("isCameraReady mCameraState %d", mCameraState);
    return (mCameraState == CAMERA_STATE_READY);
}

void QCameraHardwareInterface::release()
{
    ALOGV("release: E");
    Mutex::Autolock l(&mLock);

    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
        break;
    case QCAMERA_HAL_PREVIEW_START:
        break;
    case QCAMERA_HAL_PREVIEW_STARTED:
        stopPreviewInternal();
    break;
    case QCAMERA_HAL_RECORDING_STARTED:
        stopRecordingInternal();
        stopPreviewInternal();
        break;
    case QCAMERA_HAL_TAKE_PICTURE:
        cancelPictureInternal();
        break;
    default:
        break;
    }
#if 0
    if (isRecordingRunning()) {
        stopRecordingInternal();
        ALOGI("release: stopRecordingInternal done.");
    }
    if (isPreviewRunning()) {
        stopPreview(); //stopPreviewInternal();
        ALOGI("release: stopPreviewInternal done.");
    }
    if (isSnapshotRunning()) {
        cancelPictureInternal();
        ALOGI("release: cancelPictureInternal done.");
    }
    if (mCameraState == CAMERA_STATE_ERROR) {
        //TBD: If Error occurs then tear down
        ALOGI("release: Tear down.");
    }
#endif
    mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
    ALOGV("release: X");
}

void QCameraHardwareInterface::setCallbacks(
    camera_notify_callback notify_cb,
    camera_data_callback data_cb,
    camera_data_timestamp_callback data_cb_timestamp,
    camera_request_memory get_memory,
    void *user)
{
    ALOGV("setCallbacks: E");
    Mutex::Autolock lock(mLock);
    mNotifyCb        = notify_cb;
    mDataCb          = data_cb;
    mDataCbTimestamp = data_cb_timestamp;
    mGetMemory       = get_memory;
    mCallbackCookie  = user;
    ALOGV("setCallbacks: X");
}

void QCameraHardwareInterface::enableMsgType(int32_t msgType)
{
    ALOGV("enableMsgType: E, msgType =0x%x", msgType);
    Mutex::Autolock lock(mLock);
    mMsgEnabled |= msgType;
    ALOGV("enableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
}

void QCameraHardwareInterface::disableMsgType(int32_t msgType)
{
    ALOGV("disableMsgType: E");
    Mutex::Autolock lock(mLock);
    mMsgEnabled &= ~msgType;
    ALOGV("disableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
}

int QCameraHardwareInterface::msgTypeEnabled(int32_t msgType)
{
    ALOGV("msgTypeEnabled: E");
    Mutex::Autolock lock(mLock);
    return (mMsgEnabled & msgType);
    ALOGV("msgTypeEnabled: X");
}
#if 0
status_t QCameraHardwareInterface::dump(int fd, const Vector<String16>& args) const
{
    ALOGI("dump: E");
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    AutoMutex lock(&mLock);
    write(fd, result.string(), result.size());
    ALOGI("dump: E");
    return NO_ERROR;
}
#endif

int QCameraHardwareInterface::dump(int fd)
{
    ALOGE("%s: not supported yet", __func__);
    return -1;
}

status_t QCameraHardwareInterface::sendCommand(int32_t command, int32_t arg1,
                                         int32_t arg2)
{
    ALOGV("sendCommand: E");
    status_t rc = NO_ERROR;
    Mutex::Autolock l(&mLock);

    switch (command) {
        case CAMERA_CMD_START_FACE_DETECTION:
           if(supportsFaceDetection() == false){
                ALOGE("Face detection support is not available");
                return NO_ERROR;
           }
           setFaceDetection("on");
           return runFaceDetection();
        case CAMERA_CMD_STOP_FACE_DETECTION:
           if(supportsFaceDetection() == false){
                ALOGE("Face detection support is not available");
                return NO_ERROR;
           }
           setFaceDetection("off");
           return runFaceDetection();

    #if 0
        case CAMERA_CMD_HISTOGRAM_ON:
            ALOGE("histogram set to on");
            rc = setHistogram(1);
            break;
        case CAMERA_CMD_HISTOGRAM_OFF:
            ALOGE("histogram set to off");
            rc = setHistogram(0);
            break;
        case CAMERA_CMD_HISTOGRAM_SEND_DATA:
            ALOGE("histogram send data");
            mSendData = true;
            rc = NO_ERROR;
            break;
       case CAMERA_CMD_SEND_META_DATA:
           mMetaDataWaitLock.lock();
           if(mFaceDetectOn == true) {
               mSendMetaData = true;
           }
           mMetaDataWaitLock.unlock();
           return NO_ERROR;
#endif
#if 0 /* To Do: will enable it later */
        case CAMERA_CMD_START_SMOOTH_ZOOM :
            ALOGV("HAL sendcmd start smooth zoom %d %d", arg1 , arg2);
            /*TO DO: get MaxZoom from parameter*/
            int MaxZoom = 100;

            switch(mCameraState ) {
                case CAMERA_STATE_PREVIEW:
                case CAMERA_STATE_RECORD_CMD_SENT:
                case CAMERA_STATE_RECORD:
                    mTargetSmoothZoom = arg1;
                    mCurrentZoom = mParameters.getInt("zoom");
                    mSmoothZoomStep = (mCurrentZoom > mTargetSmoothZoom)? -1: 1;
                   if(mCurrentZoom == mTargetSmoothZoom) {
                        ALOGV("Smoothzoom target zoom value is same as "
                        "current zoom value, return...");
                        mNotifyCallback(CAMERA_MSG_ZOOM,
                        mCurrentZoom, 1, mCallbackCookie);
                    } else if(mCurrentZoom < 0 || mCurrentZoom > MaxZoom ||
                        mTargetSmoothZoom < 0 || mTargetSmoothZoom > MaxZoom)  {
                        ALOGE(" ERROR : beyond supported zoom values, break..");
                        mNotifyCallback(CAMERA_MSG_ZOOM,
                        mCurrentZoom, 0, mCallbackCookie);
                    } else {
                        mSmoothZoomRunning = true;
                        mCurrentZoom += mSmoothZoomStep;
                        if ((mSmoothZoomStep < 0 && mCurrentZoom < mTargetSmoothZoom)||
                        (mSmoothZoomStep > 0 && mCurrentZoom > mTargetSmoothZoom )) {
                            mCurrentZoom = mTargetSmoothZoom;
                        }
                        mParameters.set("zoom", mCurrentZoom);
                        setZoom(mParameters);
                    }
                    break;
                default:
                    ALOGV(" No preview, no smoothzoom ");
                    break;
            }
            rc = NO_ERROR;
            break;

        case CAMERA_CMD_STOP_SMOOTH_ZOOM:
            if(mSmoothZoomRunning) {
                mSmoothZoomRunning = false;
                /*To Do: send cmd to stop zooming*/
            }
            ALOGV("HAL sendcmd stop smooth zoom");
            rc = NO_ERROR;
            break;
#endif
        default:
            break;
    }
    ALOGV("sendCommand: X");
    return rc;
}

void QCameraHardwareInterface::setMyMode(int mode)
{
    ALOGV("setMyMode: E");
    //if (mode & CAMERA_SUPPORT_MODE_3D) {
    //    myMode = CAMERA_MODE_3D;
    //}else {
        /* default mode is 2D */
        myMode = CAMERA_MODE_2D;
    //}

    //if (mode & CAMERA_SUPPORT_MODE_ZSL) {
    //    myMode = (camera_mode_t)(myMode |CAMERA_ZSL_MODE);
    //}else {
       myMode = (camera_mode_t) (myMode | CAMERA_NONZSL_MODE);
    //}
    ALOGV("setMyMode: Set mode to %d (passed mode: %d)", myMode, mode);
    ALOGV("setMyMode: X");
}
/* static factory function */
QCameraHardwareInterface *QCameraHardwareInterface::createInstance(int cameraId, int mode)
{
    ALOGV("createInstance: E");
    QCameraHardwareInterface *cam = new QCameraHardwareInterface(cameraId, mode);
    if (cam ) {
      if (cam->mCameraState != CAMERA_STATE_READY) {
        ALOGE("createInstance: Failed");
        delete cam;
        cam = NULL;
      }
    }

    if (cam) {
      //sp<CameraHardwareInterface> hardware(cam);
      ALOGV("createInstance: X");
      return cam;
    } else {
      return NULL;
    }
}
/* external plug in function */
extern "C" void *
QCameraHAL_openCameraHardware(int  cameraId, int mode)
{
    ALOGV("QCameraHAL_openCameraHardware: E");
    return (void *) QCameraHardwareInterface::createInstance(cameraId, mode);
}

bool QCameraHardwareInterface::isPreviewRunning() {
    ALOGV("isPreviewRunning: E");
    bool ret = false;
    ALOGV("isPreviewRunning: camera state:%d", mCameraState);

    if((mCameraState == CAMERA_STATE_PREVIEW) ||
       (mCameraState == CAMERA_STATE_PREVIEW_START_CMD_SENT) ||
       (mCameraState == CAMERA_STATE_RECORD) ||
       (mCameraState == CAMERA_STATE_RECORD_START_CMD_SENT) ||
       (mCameraState == CAMERA_STATE_ZSL) ||
       (mCameraState == CAMERA_STATE_ZSL_START_CMD_SENT)){
       return true;
    }
    ALOGV("isPreviewRunning: X");
    return ret;
}

bool QCameraHardwareInterface::isRecordingRunning() {
    ALOGV("isRecordingRunning: E");
    bool ret = false;
    if(QCAMERA_HAL_RECORDING_STARTED == mPreviewState)
      ret = true;
    //if((mCameraState == CAMERA_STATE_RECORD) ||
    //   (mCameraState == CAMERA_STATE_RECORD_START_CMD_SENT)) {
    //   return true;
    //}
    ALOGV("isRecordingRunning: X");
    return ret;
}

bool QCameraHardwareInterface::isSnapshotRunning() {
    ALOGV("isSnapshotRunning: E");
    bool ret = false;
    //if((mCameraState == CAMERA_STATE_SNAP_CMD_ACKED) ||
    //   (mCameraState == CAMERA_STATE_SNAP_START_CMD_SENT)) {
    //    return true;
    //}
    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
    case QCAMERA_HAL_PREVIEW_START:
    case QCAMERA_HAL_PREVIEW_STARTED:
    case QCAMERA_HAL_RECORDING_STARTED:
    default:
        break;
    case QCAMERA_HAL_TAKE_PICTURE:
        ret = true;
        break;
    }
    ALOGV("isSnapshotRunning: X");
    return ret;
}

bool QCameraHardwareInterface::isZSLMode() {
    return (myMode & CAMERA_ZSL_MODE);
}

int QCameraHardwareInterface::getHDRMode() {
    return mHdrMode;
}

void QCameraHardwareInterface::debugShowPreviewFPS() const
{
    static int mFrameCount;
    static int mLastFrameCount = 0;
    static nsecs_t mLastFpsTime = 0;
    static float mFps = 0;
    mFrameCount++;
    nsecs_t now = systemTime();
    nsecs_t diff = now - mLastFpsTime;
    if (diff > ms2ns(250)) {
        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
        ALOGV("Preview Frames Per Second: %.4f", mFps);
        mLastFpsTime = now;
        mLastFrameCount = mFrameCount;
    }
}

void QCameraHardwareInterface::
processPreviewChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
    ALOGV("processPreviewChannelEvent: E");
    switch(channelEvent) {
        case MM_CAMERA_CH_EVT_STREAMING_ON:
            mCameraState =
                isZSLMode() ? CAMERA_STATE_ZSL : CAMERA_STATE_PREVIEW;
            break;
        case MM_CAMERA_CH_EVT_STREAMING_OFF:
            mCameraState = CAMERA_STATE_READY;
            break;
        case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
            break;
        default:
            break;
    }
    ALOGV("processPreviewChannelEvent: X");
    return;
}

void QCameraHardwareInterface::processRecordChannelEvent(
  mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
    ALOGV("processRecordChannelEvent: E");
    switch(channelEvent) {
        case MM_CAMERA_CH_EVT_STREAMING_ON:
            mCameraState = CAMERA_STATE_RECORD;
            break;
        case MM_CAMERA_CH_EVT_STREAMING_OFF:
            mCameraState = CAMERA_STATE_PREVIEW;
            break;
        case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
            break;
        default:
            break;
    }
    ALOGV("processRecordChannelEvent: X");
    return;
}

void QCameraHardwareInterface::
processSnapshotChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
    ALOGV("processSnapshotChannelEvent: E evt=%d state=%d", channelEvent,
      mCameraState);
    switch(channelEvent) {
        case MM_CAMERA_CH_EVT_STREAMING_ON:
          if (!mStateLiveshot) {
            mCameraState =
              isZSLMode() ? CAMERA_STATE_ZSL : CAMERA_STATE_SNAP_CMD_ACKED;
          }
          break;
        case MM_CAMERA_CH_EVT_STREAMING_OFF:
          if (!mStateLiveshot) {
            mCameraState = CAMERA_STATE_READY;
          }
          break;
        case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
            break;
        case MM_CAMERA_CH_EVT_DATA_REQUEST_MORE:
            if (isZSLMode()) {
                /* ZSL Mode: In ZSL Burst Mode, users may request for number of
                snapshots larger than internal size of ZSL queue. So we'll need
                process the remaining frames as they become available.
                In such case, we'll get this event */
                if(NULL != mStreamSnap)
                  mStreamSnap->takePictureZSL();
            }
            break;
        default:
            break;
    }
    ALOGV("processSnapshotChannelEvent: X");
    return;
}

void QCameraHardwareInterface::processChannelEvent(
  mm_camera_ch_event_t *event, app_notify_cb_t *app_cb)
{
    ALOGV("processChannelEvent: E");
    Mutex::Autolock lock(mLock);
    switch(event->ch) {
        case MM_CAMERA_CH_PREVIEW:
            processPreviewChannelEvent(event->evt, app_cb);
            break;
        case MM_CAMERA_CH_VIDEO:
            processRecordChannelEvent(event->evt, app_cb);
            break;
        case MM_CAMERA_CH_SNAPSHOT:
            processSnapshotChannelEvent(event->evt, app_cb);
            break;
        default:
            break;
    }
    ALOGV("processChannelEvent: X");
    return;
}

void QCameraHardwareInterface::processCtrlEvent(mm_camera_ctrl_event_t *event, app_notify_cb_t *app_cb)
{
    ALOGV("processCtrlEvent: %d, E",event->evt);
    Mutex::Autolock lock(mLock);
    switch(event->evt)
    {
        case MM_CAMERA_CTRL_EVT_ZOOM_DONE:
            zoomEvent(&event->status, app_cb);
            break;
        case MM_CAMERA_CTRL_EVT_AUTO_FOCUS_DONE:
            autoFocusEvent(&event->status, app_cb);
            break;
        case MM_CAMERA_CTRL_EVT_AUTO_FOCUS_MOVE:
            autoFocusMoveEvent(&event->status, app_cb);
            break;
        case MM_CAMERA_CTRL_EVT_PREP_SNAPSHOT:
            break;
        case MM_CAMERA_CTRL_EVT_WDN_DONE:
            wdenoiseEvent(event->status, (void *)(event->cookie));
            break;
        case MM_CAMERA_CTRL_EVT_HDR_DONE:
            hdrEvent(event->status, (void *)(event->cookie));
            break;
        case MM_CAMERA_CTRL_EVT_ERROR:
            app_cb->notifyCb  = mNotifyCb;
            app_cb->argm_notify.msg_type = CAMERA_MSG_ERROR;
            app_cb->argm_notify.ext1 = CAMERA_ERROR_UNKNOWN;
            app_cb->argm_notify.cookie =  mCallbackCookie;
            break;
      case MM_CAMERA_CTRL_EVT_SNAPSHOT_CONFIG_DONE:
          ALOGV("%s: MM_CAMERA_CTRL_EVT_SNAPSHOT_CONFIG_DONE", __func__);
          app_cb->notifyCb  = mNotifyCb;
          app_cb->argm_notify.msg_type = CAMERA_MSG_SHUTTER;
          app_cb->argm_notify.ext1 = 0;
          app_cb->argm_notify.ext2 = true;
          app_cb->argm_notify.cookie =  mCallbackCookie;
          mShutterSoundPlayed = true;
       default:
            break;
    }
    ALOGV("processCtrlEvent: X");
    return;
}

void  QCameraHardwareInterface::processStatsEvent(
  mm_camera_stats_event_t *event, app_notify_cb_t *app_cb)
{
    ALOGV("processStatsEvent: E");
    if (!isPreviewRunning( )) {
        ALOGE("preview is not running");
        return;
    }

    switch (event->event_id) {

        case MM_CAMERA_STATS_EVT_HISTO:
        {
        #if 0
            ALOGE("HAL process Histo: mMsgEnabled=0x%x, mStatsOn=%d, mSendData=%d, mDataCb=%p ",
            (mMsgEnabled & CAMERA_MSG_STATS_DATA), mStatsOn, mSendData, mDataCb);
            int msgEnabled = mMsgEnabled;
            /*get stats buffer based on index*/
            camera_preview_histogram_info* hist_info =
                (camera_preview_histogram_info*) mHistServer.camera_memory[event->e.stats_histo.index]->data;

            if(mStatsOn == QCAMERA_PARM_ENABLE && mSendData &&
                            mDataCb && (msgEnabled & CAMERA_MSG_STATS_DATA) ) {
                uint32_t *dest;
                mSendData = false;
                mCurrentHisto = (mCurrentHisto + 1) % 3;
                // The first element of the array will contain the maximum hist value provided by driver.
                *(uint32_t *)((unsigned int)(mStatsMapped[mCurrentHisto]->data)) = hist_info->max_value;
                memcpy((uint32_t *)((unsigned int)mStatsMapped[mCurrentHisto]->data + sizeof(int32_t)),
                                                    (uint32_t *)hist_info->buffer,(sizeof(int32_t) * 256));

                app_cb->dataCb  = mDataCb;
                app_cb->argm_data_cb.msg_type = CAMERA_MSG_STATS_DATA;
                app_cb->argm_data_cb.data = mStatsMapped[mCurrentHisto];
                app_cb->argm_data_cb.index = 0;
                app_cb->argm_data_cb.metadata = NULL;
                app_cb->argm_data_cb.cookie =  mCallbackCookie;
            }
        #endif
            break;

        }
        default:
        break;
    }
  ALOGV("receiveCameraStats X");
}

void  QCameraHardwareInterface::processInfoEvent(
  mm_camera_info_event_t *event, app_notify_cb_t *app_cb) {
    ALOGV("processInfoEvent: %d, E",event->event_id);
    //Mutex::Autolock lock(eventLock);
    switch(event->event_id)
    {
        case MM_CAMERA_INFO_EVT_ROI:
            roiEvent(event->e.roi, app_cb);
            break;
        default:
            break;
    }
    ALOGV("processInfoEvent: X");
    return;
}

void  QCameraHardwareInterface::processEvent(mm_camera_event_t *event)
{
    app_notify_cb_t app_cb;
    ALOGV("processEvent: type :%d E",event->event_type);
    if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED){
	ALOGV("Stop recording issued. Return from process Event");
        return;
    }
    memset(&app_cb, 0, sizeof(app_notify_cb_t));
    switch(event->event_type)
    {
        case MM_CAMERA_EVT_TYPE_CH:
            processChannelEvent(&event->e.ch, &app_cb);
            break;
        case MM_CAMERA_EVT_TYPE_CTRL:
            processCtrlEvent(&event->e.ctrl, &app_cb);
            break;
        case MM_CAMERA_EVT_TYPE_STATS:
            processStatsEvent(&event->e.stats, &app_cb);
            break;
        case MM_CAMERA_EVT_TYPE_INFO:
            processInfoEvent(&event->e.info, &app_cb);
            break;
        default:
            break;
    }
    ALOGV(" App_cb Notify %p, datacb=%p", app_cb.notifyCb, app_cb.dataCb);
    if (app_cb.notifyCb) {
      app_cb.notifyCb(app_cb.argm_notify.msg_type,
        app_cb.argm_notify.ext1, app_cb.argm_notify.ext2,
        app_cb.argm_notify.cookie);
    }
    if (app_cb.dataCb) {
      app_cb.dataCb(app_cb.argm_data_cb.msg_type,
        app_cb.argm_data_cb.data, app_cb.argm_data_cb.index,
        app_cb.argm_data_cb.metadata, app_cb.argm_data_cb.cookie);
    }
    ALOGV("processEvent: X");
    return;
}

bool QCameraHardwareInterface::preview_parm_config (cam_ctrl_dimension_t* dim,
                                   QCameraParameters& parm)
{
    ALOGV("preview_parm_config: E");
    bool matching = true;
    int display_width = 0;  /* width of display      */
    int display_height = 0; /* height of display */
    uint16_t video_width = 0;  /* width of the video  */
    uint16_t video_height = 0; /* height of the video */

    /* First check if the preview resolution is the same, if not, change it*/
    parm.getPreviewSize(&display_width,  &display_height);
    if (display_width && display_height) {
        matching = (display_width == dim->display_width) &&
            (display_height == dim->display_height);

        if (!matching) {
            dim->display_width  = display_width;
            dim->display_height = display_height;
        }
    }
    else
        matching = false;

    cam_format_t value = getPreviewFormat();

    if(value != NOT_FOUND && value != dim->prev_format ) {
        //Setting to Parameter requested by the Upper layer
        dim->prev_format = value;
    } else if (value == NOT_FOUND) {
        //Setting to default Format.
        dim->prev_format = CAMERA_YUV_420_NV21;
    }
    mPreviewFormat = dim->prev_format;

    dim->prev_padding_format =  getPreviewPadding( );

    dim->enc_format = CAMERA_YUV_420_NV12;
    dim->orig_video_width = mDimension.orig_video_width;
    dim->orig_video_height = mDimension.orig_video_height;
    dim->video_width = mDimension.video_width;
    dim->video_height = mDimension.video_height;
    dim->video_chroma_width = mDimension.video_width;
    dim->video_chroma_height  = mDimension.video_height;
    /* Reset the Main image and thumbnail formats here,
     * since they might have been changed when video size
     * livesnapshot was taken. */
    if (mSnapshotFormat == 1)
      dim->main_img_format = CAMERA_YUV_422_NV61;
    else
      dim->main_img_format = CAMERA_YUV_420_NV21;
    dim->thumb_format = CAMERA_YUV_420_NV21;
    ALOGV("preview_parm_config: X");
    return matching;
}

status_t QCameraHardwareInterface::startPreview()
{
    status_t retVal = NO_ERROR;

    ALOGV("%s: mPreviewState =%d", __func__, mPreviewState);
    Mutex::Autolock lock(mLock);

    if(mPauseFramedispatch){
        //In ZSL case after snapshot we need to restart
        //if stop preview not issued.
        stopPreviewInternal();
        mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
        mPauseFramedispatch = false;
    }

    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
    case QCAMERA_HAL_TAKE_PICTURE:
        mPreviewState = QCAMERA_HAL_PREVIEW_START;
        ALOGV("%s:  HAL::startPreview begin", __func__);

        if(QCAMERA_HAL_PREVIEW_START == mPreviewState &&
           (mPreviewWindow || isNoDisplayMode())) {
            ALOGD("%s:  start preview now", __func__);
            retVal = startPreview2();
            if(retVal == NO_ERROR)
                mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
        } else {
            ALOGV("%s:  received startPreview, but preview window = null", __func__);
        }
        break;
    case QCAMERA_HAL_PREVIEW_START:
    case QCAMERA_HAL_PREVIEW_STARTED:
    break;
    case QCAMERA_HAL_RECORDING_STARTED:
        ALOGV("%s: cannot start preview in recording state", __func__);
        break;
    default:
        ALOGE("%s: unknow state %d received", __func__, mPreviewState);
        retVal = UNKNOWN_ERROR;
        break;
    }
    return retVal;
}

status_t QCameraHardwareInterface::startPreview2()
{
    ALOGV("startPreview2: E");
    status_t ret = NO_ERROR;

    cam_ctrl_dimension_t dim;
    mm_camera_dimension_t maxDim;
    bool initPreview = false;

    mPauseFramedispatch = false;
    if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED) { //isPreviewRunning()){
        ALOGE("%s:Preview already started  mCameraState = %d!", __func__, mCameraState);
        ALOGV("%s: X", __func__);
        return NO_ERROR;
    }

    const char *str = mParameters.get(QCameraParameters::KEY_SCENE_MODE);

    if (mRecordingHint || mFlashCond || !strcmp(str, "hdr")) {
        ALOGI("%s:Setting non-ZSL mode",__func__);
        mParameters.set(QCameraParameters::KEY_CAMERA_MODE, 0);
        myMode = (camera_mode_t)(myMode & ~CAMERA_ZSL_MODE);
        mParameters.setPreviewFrameRateMode("frame-rate-auto");
        setPreviewFrameRateMode(mParameters);
     } else {
        ALOGI("%s:Setting ZSL mode",__func__);
        mParameters.set(QCameraParameters::KEY_CAMERA_MODE, 1);
        myMode = (camera_mode_t)(myMode | CAMERA_ZSL_MODE);
        mParameters.setPreviewFrameRateMode("frame-rate-auto");
        setPreviewFrameRateMode(mParameters);

    }

    /*  get existing preview information, by qury mm_camera*/
    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);

    if (MM_CAMERA_OK != ret) {
      ALOGE("%s: error - can't get preview dimension!", __func__);
      ALOGV("%s: X", __func__);
      return BAD_VALUE;
    }

    /* config the parmeters and see if we need to re-init the stream*/
    initPreview = preview_parm_config (&dim, mParameters);

    if (mRecordingHint && mFullLiveshotEnabled) {
#if 0
      /* Camcorder mode and Full resolution liveshot enabled
       * TBD lookup table for correct aspect ratio matching size */
      memset(&maxDim, 0, sizeof(mm_camera_dimension_t));
      getMaxPictureDimension(&maxDim);
      if (!maxDim.width || !maxDim.height) {
        maxDim.width  = DEFAULT_LIVESHOT_WIDTH;
        maxDim.height = DEFAULT_LIVESHOT_HEIGHT;
      }
      /* TODO Remove this hack after adding code to get live shot dimension */
      if (!mCameraId) {
        maxDim.width = DEFAULT_LIVESHOT_WIDTH;
        maxDim.height = DEFAULT_LIVESHOT_HEIGHT;
      }
      dim.picture_width = maxDim.width;
      dim.picture_height = maxDim.height;
      mParameters.setPictureSize(dim.picture_width, dim.picture_height);
      ALOGI("%s Setting Liveshot dimension as %d x %d", __func__,
           maxDim.width, maxDim.height);
#endif
        int mPictureWidth, mPictureHeight;
        bool matching;
        /* First check if the picture resolution is the same, if not, change it*/
        getPictureSize(&mPictureWidth, &mPictureHeight);

        matching = (mPictureWidth == dim.picture_width) &&
            (mPictureHeight == dim.picture_height);

        if (!matching) {
            dim.picture_width  = mPictureWidth;
            dim.picture_height = mPictureHeight;
            //For FullSize snapshot Main image Buffer is used as Thumanail.
            dim.ui_thumbnail_height = mPictureWidth;
            dim.ui_thumbnail_width = mPictureHeight;
        }
        ALOGI("%s: Fullsize Liveshaot Picture size to set: %d x %d", __func__,
             dim.picture_width, dim.picture_height);
        mParameters.setPictureSize(dim.picture_width, dim.picture_height);
    }

    ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
    if (MM_CAMERA_OK != ret) {
      ALOGE("%s X: error - can't config preview parms!", __func__);
      return BAD_VALUE;
    }

    mStreamDisplay->setMode(myMode & CAMERA_ZSL_MODE);
    mStreamSnap->setMode(myMode & CAMERA_ZSL_MODE);
    mStreamRecord->setMode(myMode & CAMERA_ZSL_MODE);
    ALOGV("%s: myMode = %d", __func__, myMode);

    ALOGV("%s: setPreviewWindow", __func__);
    mStreamDisplay->setPreviewWindow(mPreviewWindow);
    ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_INFORM_STARTPRVIEW, NULL);
    if(ret<0)
    {
      ALOGE("%s: Failed to Check MM_CAMERA_PARM_INFORM_STARTPRVIEW, rc %d", __func__, ret);
    }

    if(isZSLMode()) {
        /* Start preview streaming */
        ret = mStreamDisplay->start();
        if (MM_CAMERA_OK != ret){
            ALOGE("%s: X -error - can't start nonZSL stream!", __func__);
            return BAD_VALUE;
        }

        /* Start ZSL stream */
        ret =  mStreamSnap->start();
        if (MM_CAMERA_OK != ret){
            ALOGE("%s: error - can't start Snapshot stream!", __func__);
            mStreamDisplay->stop();
            return BAD_VALUE;
        }
    }else{
        ret = mStreamDisplay->start();
    }

    /*call QCameraStream_noneZSL::start() */
    if (MM_CAMERA_OK != ret){
      ALOGE("%s: X error - can't start stream!", __func__);
      return BAD_VALUE;
    }
    if(MM_CAMERA_OK == ret)
        mCameraState = CAMERA_STATE_PREVIEW_START_CMD_SENT;
    else
        mCameraState = CAMERA_STATE_ERROR;

    if(mPostPreviewHeap != NULL) {
        mPostPreviewHeap.clear();
        mPostPreviewHeap = NULL;
    }

    mRestartPreview = false;

    ALOGV("startPreview: X");
    return ret;
}

void QCameraHardwareInterface::stopPreview()
{
    ALOGV("%s: stopPreview: E", __func__);
    Mutex::Autolock lock(mLock);
    mm_camera_util_profile("HAL: stopPreview(): E");
    mFaceDetectOn = false;

    // reset recording hint to the value passed from Apps
    const char * str = mParameters.get(QCameraParameters::KEY_RECORDING_HINT);
    if((str != NULL) && !strcmp(str, "true")){
        mRecordingHint = true;
    } else {
        mRecordingHint = false;
    }

    const char * str_fd = mParameters.get(QCameraParameters::KEY_FACE_DETECTION);
    if((str_fd != NULL) && !strcmp(str_fd, "on")){
        if(supportsFaceDetection() == false){
         ALOGE("Face detection support is not available");
        }
        setFaceDetection("off");
        runFaceDetection();
    }

    switch(mPreviewState) {
      case QCAMERA_HAL_PREVIEW_START:
          //mPreviewWindow = NULL;
          mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
          break;
      case QCAMERA_HAL_PREVIEW_STARTED:
          stopPreviewInternal();
          mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
          break;
      case QCAMERA_HAL_RECORDING_STARTED:
            stopRecordingInternal();
            stopPreviewInternal();
            mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
            break;
      case QCAMERA_HAL_TAKE_PICTURE:
      case QCAMERA_HAL_PREVIEW_STOPPED:
      default:
            break;
    }
    ALOGV("stopPreview: X, mPreviewState = %d", mPreviewState);
}

#if 0 //mzhu
void QCameraHardwareInterface::stopPreviewZSL()
{
    ALOGI("stopPreviewZSL: E");

    if(!mStreamDisplay || !mStreamSnap) {
        ALOGE("mStreamDisplay/mStreamSnap is null");
        return;
    }
    ALOGI("stopPreview: X, mPreviewState = %d", mPreviewState);
}
#endif
void QCameraHardwareInterface::stopPreviewInternal()
{
    ALOGV("stopPreviewInternal: E");
    status_t ret = NO_ERROR;

    if(!mStreamDisplay) {
        ALOGE("mStreamDisplay is null");
        return;
    }

    if(isZSLMode()) {
        /* take care snapshot object for ZSL mode */
        mStreamSnap->stop();
    }
    mStreamDisplay->stop();

    mPauseFramedispatch = false;
    mCameraState = CAMERA_STATE_PREVIEW_STOP_CMD_SENT;
    ALOGV("stopPreviewInternal: X");
}

int QCameraHardwareInterface::previewEnabled()
{
    ALOGV("previewEnabled: E");
    Mutex::Autolock lock(mLock);
    ALOGV("%s: mCameraState = %d", __func__, mCameraState);
    if (mPauseFramedispatch) {
        return false;
    }
    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
    case QCAMERA_HAL_TAKE_PICTURE:
    default:
        return false;
        break;
    case QCAMERA_HAL_PREVIEW_START:
    case QCAMERA_HAL_PREVIEW_STARTED:
    case QCAMERA_HAL_RECORDING_STARTED:
        return true;
        break;
    }
    return false;
}

status_t QCameraHardwareInterface::startRecording()
{
    ALOGV("startRecording: E");
    status_t ret = NO_ERROR;
    Mutex::Autolock lock(mLock);

    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
        ALOGE("%s: preview has not been started", __func__);
        ret = UNKNOWN_ERROR;
        break;
    case QCAMERA_HAL_PREVIEW_START:
        ALOGE("%s: no preview native window", __func__);
        ret = UNKNOWN_ERROR;
        break;
    case QCAMERA_HAL_PREVIEW_STARTED:
        //remember recordinghint value set by app
        mAppRecordingHint = mRecordingHint;
        pausePreviewForVideo();
        ret =  mStreamRecord->start();
        if (MM_CAMERA_OK != ret){
            ALOGE("%s: error - mStreamRecord->start!", __func__);
            ret = BAD_VALUE;
            break;
        }
        if(MM_CAMERA_OK == ret)
            mCameraState = CAMERA_STATE_RECORD_START_CMD_SENT;
        else
            mCameraState = CAMERA_STATE_ERROR;
        mPreviewState = QCAMERA_HAL_RECORDING_STARTED;
        break;
    case QCAMERA_HAL_RECORDING_STARTED:
        ALOGV("%s: ", __func__);
        break;
    case QCAMERA_HAL_TAKE_PICTURE:
    default:
       ret = BAD_VALUE;
       break;
    }
    ALOGV("startRecording: X");
    return ret;
}

void QCameraHardwareInterface::stopRecording()
{
    ALOGV("stopRecording: E");
    Mutex::Autolock lock(mLock);
    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
    case QCAMERA_HAL_PREVIEW_START:
    case QCAMERA_HAL_PREVIEW_STARTED:
        break;
    case QCAMERA_HAL_RECORDING_STARTED:
        mRecordingHint = mAppRecordingHint;
        stopRecordingInternal();
        mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
        break;
    case QCAMERA_HAL_TAKE_PICTURE:
    default:
        break;
    }
    ALOGV("stopRecording: X");

}
void QCameraHardwareInterface::stopRecordingInternal()
{
    ALOGV("stopRecordingInternal: E");
    status_t ret = NO_ERROR;

    if(!mStreamRecord) {
        ALOGE("mStreamRecord is null");
        return;
    }

    if(mStateLiveshot && mStreamLiveSnap != NULL) {
        mStreamLiveSnap->stop();
        mStateLiveshot = false;
    }
    /*
    * call QCameraStream_record::stop()
    * Unregister Callback, action stop
    */
    mStreamRecord->stop();
    mCameraState = CAMERA_STATE_PREVIEW;  //TODO : Apurva : Hacked for 2nd time Recording
    mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
    ALOGV("stopRecordingInternal: X");
    return;
}

int QCameraHardwareInterface::recordingEnabled()
{
    int ret = 0;
    Mutex::Autolock lock(mLock);
    ALOGV("%s: E", __func__);
    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
    case QCAMERA_HAL_PREVIEW_START:
    case QCAMERA_HAL_PREVIEW_STARTED:
        break;
    case QCAMERA_HAL_RECORDING_STARTED:
        ret = 1;
        break;
    case QCAMERA_HAL_TAKE_PICTURE:
    default:
        break;
    }
    ALOGV("%s: X, ret = %d", __func__, ret);
    return ret;   //isRecordingRunning();
}

/**
* Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
*/
void QCameraHardwareInterface::releaseRecordingFrame(const void *opaque)
{
    ALOGV("%s : BEGIN",__func__);
    if(mStreamRecord == NULL) {
        ALOGE("Record stream Not Initialized");
        return;
    }
    mStreamRecord->releaseRecordingFrame(opaque);
    ALOGV("%s : END",__func__);
    return;
}

status_t QCameraHardwareInterface::autoFocusMoveEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
{
    ALOGV("autoFocusMoveEvent: E");
    int ret = NO_ERROR;

    isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);

    if (afMode == AF_MODE_CAF && mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS_MOVE)){
        ALOGV("%s:Issuing AF Move callback to service",__func__);

        app_cb->notifyCb  = mNotifyCb;
        app_cb->argm_notify.msg_type = CAMERA_MSG_FOCUS_MOVE;
        app_cb->argm_notify.ext2 = 0;
        app_cb->argm_notify.cookie =  mCallbackCookie;

        ALOGV("Auto focus state =%d", *status);
        if(*status == 1) {
            app_cb->argm_notify.ext1 = true;
        }else if(*status == 0){
            app_cb->argm_notify.ext1 = false;
        }else{
            app_cb->notifyCb  = NULL;
            ALOGE("%s:Unknown AF Move Status received (%d) received",__func__,*status);
        }
    }
    ALOGV("autoFocusMoveEvent: X");
    return ret;
}

status_t QCameraHardwareInterface::autoFocusEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
{
    ALOGV("autoFocusEvent: E");
    int ret = NO_ERROR;
/************************************************************
  BEGIN MUTEX CODE
*************************************************************/

    ALOGV("%s:%d: Trying to acquire AF bit lock",__func__,__LINE__);
    mAutofocusLock.lock();
    ALOGV("%s:%d: Acquired AF bit lock",__func__,__LINE__);

    if(mAutoFocusRunning==false) {
      ALOGV("%s:AF not running, discarding stale event",__func__);
      mAutofocusLock.unlock();
      return ret;
    }
    /* If autofocus call has been made during CAF, CAF will be locked.
     * We specifically need to call cancelAutoFocus to unlock CAF.
     * In that sense, AF is still running.*/
    isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);
    if (afMode == AF_MODE_CAF)
        mNeedToUnlockCaf = true;
    mAutoFocusRunning = false;
    mAutofocusLock.unlock();

/************************************************************
  END MUTEX CODE
*************************************************************/
    if(status==NULL) {
      ALOGE("%s:NULL ptr received for status",__func__);
      return BAD_VALUE;
    }

    /* update focus distances after autofocus is done */
    if((*status != CAM_CTRL_FAILED) && updateFocusDistances() != NO_ERROR) {
       ALOGE("%s: updateFocusDistances failed for %d", __FUNCTION__, mFocusMode);
    }

    /*(Do?) we need to make sure that the call back is the
      last possible step in the execution flow since the same
      context might be used if a fail triggers another round
      of AF then the mAutoFocusRunning flag and other state
      variables' validity will be under question*/

    if (mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS)){
      ALOGV("%s:Issuing AF callback to service",__func__);

      /* "Accepted" status is not appropriate it should be used for
        initial cmd, event reporting should only give use SUCCESS/FAIL
        */

      app_cb->notifyCb  = mNotifyCb;
      app_cb->argm_notify.msg_type = CAMERA_MSG_FOCUS;
      app_cb->argm_notify.ext2 = 0;
      app_cb->argm_notify.cookie =  mCallbackCookie;

      ALOGV("Auto focus state =%d", *status);
      if(*status==CAM_CTRL_SUCCESS) {
        app_cb->argm_notify.ext1 = true;
      }
      else if(*status==CAM_CTRL_FAILED){
        app_cb->argm_notify.ext1 = false;
      }
      else{
        app_cb->notifyCb  = NULL;
        ALOGE("%s:Unknown AF status (%d) received",__func__,*status);
      }

    }/*(mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS))*/
    else{
      ALOGE("%s:Call back not enabled",__func__);
    }

    ALOGV("autoFocusEvent: X");
    return ret;

}

status_t QCameraHardwareInterface::cancelPicture()
{
    ALOGV("cancelPicture: E");
    status_t ret = MM_CAMERA_OK;
    Mutex::Autolock lock(mLock);

    switch(mPreviewState) {
        case QCAMERA_HAL_PREVIEW_STOPPED:
        case QCAMERA_HAL_PREVIEW_START:
        case QCAMERA_HAL_PREVIEW_STARTED:
            break;
        case QCAMERA_HAL_RECORDING_STARTED:
            if(mStateLiveshot && (mStreamLiveSnap != NULL)) {
                mStreamLiveSnap->stop();
                mStateLiveshot = false;
            }
            break;
        case QCAMERA_HAL_TAKE_PICTURE:
            ret = cancelPictureInternal();
            break;
        default:
            break;
    }
    ALOGV("cancelPicture: X");
    return ret;
}

status_t QCameraHardwareInterface::cancelPictureInternal()
{
    ALOGV("cancelPictureInternal: E");
    status_t ret = MM_CAMERA_OK;
    if(mCameraState != CAMERA_STATE_READY) {
        if(mStreamSnap) {
            mStreamSnap->stop();
            mCameraState = CAMERA_STATE_SNAP_STOP_CMD_SENT;
        }
    } else {
        ALOGE("%s: Cannot process cancel picture as snapshot is already done",__func__);
    }
    ALOGV("cancelPictureInternal: X");
    return ret;
}

void QCameraHardwareInterface::pausePreviewForSnapshot()
{
    stopPreviewInternal( );
}
status_t QCameraHardwareInterface::resumePreviewAfterSnapshot()
{
    status_t ret = NO_ERROR;
    ret = mStreamDisplay->start();
    return ret;
}

void liveshot_callback(mm_camera_ch_data_buf_t *recvd_frame,
                                void *user_data)
{
    QCameraHardwareInterface *pme = (QCameraHardwareInterface *)user_data;
    cam_ctrl_dimension_t dim;
    int mJpegMaxSize;
    int mNuberOfVFEOutputs = 0;
    status_t ret;
    ALOGV("%s: E", __func__);

    if (!pme->mStateLiveshot) {
        ALOGE("%s: Returning Buffer. Picture Cancelled", __func__);
        return;
    }

    ALOGV("Live Snapshot Enabled");
    if (pme->mStreamLiveSnap){
        ALOGE("%s:Deleting old Snapshot stream instance",__func__);
        QCameraStream_Snapshot::deleteInstance (pme->mStreamLiveSnap);
        pme->mStreamLiveSnap = NULL;
    }

    pme->mStreamLiveSnap = (QCameraStream_Snapshot*)QCameraStream_Snapshot::createInstance(pme->mCameraId,
                                                       pme->myMode);

    if (!pme->mStreamLiveSnap) {
        ALOGE("%s: error - can't creat snapshot stream!", __func__);
        cam_evt_buf_done(pme->mCameraId, recvd_frame);
        return ;
    }
    pme->mStreamLiveSnap->setModeLiveSnapshot(true);
    pme->mStreamLiveSnap->setHALCameraControl(pme);

    ret = ((QCameraStream_Snapshot*)(pme->mStreamLiveSnap))->takePictureLiveshot(recvd_frame);
    if (MM_CAMERA_OK != ret) {
        ALOGE("%s: Error : returned from takePictureLiveshot",__func__);
        return;
    }
    pme->setCAFLockCancel();
    ALOGV("%s: X", __func__);

}

status_t  QCameraHardwareInterface::takePicture()
{
    ALOGV("takePicture: E");
    status_t ret = MM_CAMERA_OK;
    int mNuberOfVFEOutputs = 0;
    Mutex::Autolock lock(mLock);
    bool hdr;
    int  frm_num = 1, rc = 0;
    int  exp[MAX_HDR_EXP_FRAME_NUM];

    if(QCAMERA_HAL_RECORDING_STARTED != mPreviewState){
      isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);
      if (!mFlashCond)
      {
        mFlashCond = getFlashCondition();
      }
      ALOGV("%s: Flash Contidion %d", __func__, mFlashCond);
      if(mFlashCond) {
        mRestartPreview = true;
        pausePreviewForZSL();
      }
      mFlashCond = false;
    }

    rc = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_LG_CAF_LOCK, NULL);
    if(rc<0)
    {
      ALOGE("%s: Failed to Check MM_CAMERA_PARM_LG_CAF_LOCK, rc %d", __func__, rc);
    }
    hdr = getHdrInfoAndSetExp(MAX_HDR_EXP_FRAME_NUM, &frm_num, exp);
    mStreamSnap->resetSnapshotCounters();
    mStreamSnap->InitHdrInfoForSnapshot(hdr, frm_num, exp);
    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STARTED:
        //set the fullsize liveshot to false
        mFullLiveshotEnabled = false;
        setFullLiveshot();
        mStreamSnap->setFullSizeLiveshot(false);
        if (isZSLMode()) {
            if (mStreamSnap != NULL) {
                pausePreviewForZSL();
                ret = mStreamSnap->takePictureZSL();
                if (ret != MM_CAMERA_OK) {
                    ALOGE("%s: Error taking ZSL snapshot!", __func__);
                    ret = BAD_VALUE;
                }
            }
            else {
                ALOGE("%s: ZSL stream not active! Failure!!", __func__);
                ret = BAD_VALUE;
            }
            return ret;
        }
        /*prepare snapshot, e.g LED*/
        takePicturePrepareHardware( );
        /* There's an issue where we have a glimpse of corrupted data between
           a time we stop a preview and display the postview. It happens because
           when we call stopPreview we deallocate the preview buffers hence overlay
           displays garbage value till we enqueue postview buffer to be displayed.
           Hence for temporary fix, we'll do memcopy of the last frame displayed and
           queue it to overlay*/
        // mzhu storePreviewFrameForPostview();

        /* stop preview */
        pausePreviewForSnapshot();

        /* call Snapshot start() :*/
        ret =  mStreamSnap->start();
        if (MM_CAMERA_OK != ret){
            /* mzhu: fix me, restore preview */
            ALOGE("%s: error - can't start Snapshot stream!", __func__);
            return BAD_VALUE;
        }

        if(MM_CAMERA_OK == ret)
            mCameraState = CAMERA_STATE_SNAP_START_CMD_SENT;
        else
            mCameraState = CAMERA_STATE_ERROR;
        mPreviewState = QCAMERA_HAL_TAKE_PICTURE;
        break;
      case QCAMERA_HAL_TAKE_PICTURE:
          break;
    case QCAMERA_HAL_PREVIEW_STOPPED:
    case QCAMERA_HAL_PREVIEW_START:
      ret = UNKNOWN_ERROR;
      break;
    case QCAMERA_HAL_RECORDING_STARTED:
      if(mStateLiveshot) {
          ALOGE("takePicture : Duplicate TakePicture Call");
          return ret;
      }
      if (canTakeFullSizeLiveshot()) {
        ALOGV(" Calling takeFullSizeLiveshot");
        takeFullSizeLiveshot();
      }else{
        ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE,
                     &mNuberOfVFEOutputs);
        if (ret != MM_CAMERA_OK) {
           ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE  failed");
           ret = BAD_VALUE;
        }
        if (mNuberOfVFEOutputs == 1){
           (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
                                                    liveshot_callback,
                                                    MM_CAMERA_REG_BUF_CB_COUNT,
                                                    1,
                                                    this);
        } else {
           (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
                                                    liveshot_callback,
                                                    MM_CAMERA_REG_BUF_CB_COUNT,
                                                    1,
                                                    this);
        }
      }
      mStateLiveshot = true;
      break;
    default:
        ret = UNKNOWN_ERROR;
        break;
    }
    ALOGV("takePicture: X");
    return ret;
}

bool QCameraHardwareInterface::canTakeFullSizeLiveshot() {
    bool ret;
    if (mFullLiveshotEnabled && !isLowPowerCamcorder()) {
      /* Full size liveshot enabled. */

      /* If Picture size is same as video size, switch to Video size
       * live snapshot */
      if ((mDimension.picture_width == mVideoWidth) &&
          (mDimension.picture_height == mVideoHeight)) {
        return false;
      }

      if (mDisEnabled) {
       /* If DIS is enabled and Picture size is
        * less than (video size + 10% DIS Margin)
        * then fall back to Video size liveshot. */
        if ((mDimension.picture_width <
               (int)(mVideoWidth * 1.1)) ||
             (mDimension.picture_height <
               (int)(mVideoHeight * 1.1))) {
          ret = false;
        } else {
          /* Go with Full size live snapshot. */
          ret = true;
        }
      } else {
        /* DIS Disabled. Go with Full size live snapshot */
        ret = true;
      }
    } else {
      /* Full size liveshot disabled. Fallback to Video size liveshot. */
      ret = false;
    }

    return ret;
}

status_t QCameraHardwareInterface::takeFullSizeLiveshot()
{
    status_t ret = NO_ERROR;
    if (mStreamLiveSnap){
        ALOGV("%s:Deleting old Snapshot stream instance",__func__);
        QCameraStream_Snapshot::deleteInstance (mStreamLiveSnap);
        mStreamLiveSnap = NULL;
    }
    mStreamLiveSnap = QCameraStream_Snapshot::createInstance(mCameraId, myMode);

    if (!mStreamLiveSnap) {
        ALOGE("%s: error - can't creat snapshot stream!", __func__);
        /* mzhu: fix me, restore preview */
        return BAD_VALUE;
    }

    /* Store HAL object in snapshot stream Object */
    mStreamLiveSnap->setHALCameraControl(this);

    mStreamLiveSnap->setFullSizeLiveshot(true);

    /* Call snapshot init*/
    ret =  mStreamLiveSnap->init();
    if (MM_CAMERA_OK != ret){
        ALOGE("%s: error - can't init Snapshot stream!", __func__);
        return BAD_VALUE;
    }

    /* call Snapshot start() :*/
    mStreamLiveSnap->resetSnapshotCounters( );
    ret =  mStreamLiveSnap->start();
    if (MM_CAMERA_OK != ret){
        /* mzhu: fix me, restore preview */
        ALOGE("%s: error - can't start Snapshot stream!", __func__);
        return BAD_VALUE;
    }
    return ret;
}

status_t  QCameraHardwareInterface::takeLiveSnapshot()
{
    status_t ret = NO_ERROR;
    ALOGV("takeLiveSnapshot: E");
    mStreamRecord->takeLiveSnapshot();
    ALOGV("takeLiveSnapshot: X");
    return ret;
}

status_t QCameraHardwareInterface::autoFocus()
{
    ALOGV("autoFocus: E");
    status_t ret = NO_ERROR;
    mFlashCond = getFlashCondition();
    ALOGV("autoFocus: mFlashCond = %d", mFlashCond);
    Mutex::Autolock lock(mLock);
    ALOGV("autoFocus: Got lock");
    bool status = true;
    isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);

    if(mAutoFocusRunning==true){
      ALOGV("%s:AF already running should not have got this call",__func__);
      return NO_ERROR;
    }

    if (afMode == AF_MODE_MAX) {
      /* This should never happen. We cannot send a
       * callback notifying error from this place because
       * the CameraService has called this function after
       * acquiring the lock. So if we try to issue a callback
       * from this place, the callback will try to acquire
       * the same lock in CameraService and it will result
       * in deadlock. So, let the call go in to the lower
       * layer. The lower layer will anyway return error if
       * the autofocus is not supported or if the focus
       * value is invalid.
       * Just print out the error. */
      ALOGE("%s:Invalid AF mode (%d)", __func__, afMode);
    }

    ALOGV("%s:AF start (mode %d)", __func__, afMode);
    if(MM_CAMERA_OK != cam_ops_action(mCameraId, true,
                                    MM_CAMERA_OPS_FOCUS, &afMode)) {
      ALOGE("%s: AF command failed err:%d error %s",
           __func__, errno, strerror(errno));
      return UNKNOWN_ERROR;
    }

    mAutoFocusRunning = true;
    ALOGV("autoFocus: X");
    return ret;
}

status_t QCameraHardwareInterface::cancelAutoFocus()
{
    ALOGV("cancelAutoFocus: E");
    status_t ret = NO_ERROR;
    Mutex::Autolock lock(mLock);

/**************************************************************
  BEGIN MUTEX CODE
*************************************************************/

    mAutofocusLock.lock();
    if(mAutoFocusRunning || mNeedToUnlockCaf) {
      mNeedToUnlockCaf = false;
      mAutoFocusRunning = false;
      mAutofocusLock.unlock();

    }else/*(!mAutoFocusRunning)*/{

      mAutofocusLock.unlock();
      ALOGV("%s:Af not running",__func__);
      return NO_ERROR;
    }
/**************************************************************
  END MUTEX CODE
*************************************************************/


    if(MM_CAMERA_OK!=cam_ops_action(mCameraId,false,MM_CAMERA_OPS_FOCUS,NULL )) {
      ALOGE("%s: AF command failed err:%d error %s",__func__, errno,strerror(errno));
    }

    ALOGV("cancelAutoFocus: X");
    return NO_ERROR;
}

#if 0 //mzhu
/*==========================================================================
 * FUNCTION    - prepareSnapshotAndWait -
 *
 * DESCRIPTION:  invoke preparesnapshot and wait for it done
                 it can be called within takepicture, so no need
                 to grab mLock.
 *=========================================================================*/
void QCameraHardwareInterface::prepareSnapshotAndWait()
{
    ALOGI("prepareSnapshotAndWait: E");
    int rc = 0;
    /*To Do: call mm camera preparesnapshot */
    if(!rc ) {
        mPreparingSnapshot = true;
        pthread_mutex_lock(&mAsyncCmdMutex);
        pthread_cond_wait(&mAsyncCmdWait, &mAsyncCmdMutex);
        pthread_mutex_unlock(&mAsyncCmdMutex);
        mPreparingSnapshot = false;
    }
    ALOGI("prepareSnapshotAndWait: X");
}
#endif //mzhu

/*==========================================================================
 * FUNCTION    - processprepareSnapshotEvent -
 *
 * DESCRIPTION:  Process the event of preparesnapshot done msg
                 unblock prepareSnapshotAndWait( )
 *=========================================================================*/
void QCameraHardwareInterface::processprepareSnapshotEvent(cam_ctrl_status_t *status)
{
    ALOGV("processprepareSnapshotEvent: E");
    pthread_mutex_lock(&mAsyncCmdMutex);
    pthread_cond_signal(&mAsyncCmdWait);
    pthread_mutex_unlock(&mAsyncCmdMutex);
    ALOGV("processprepareSnapshotEvent: X");
}

void QCameraHardwareInterface::roiEvent(fd_roi_t roi,app_notify_cb_t *app_cb)
{
    ALOGV("roiEvent: E");

    if(mStreamDisplay) mStreamDisplay->notifyROIEvent(roi);
#if 0 //TODO: move to preview obj
    mCallbackLock.lock();
    data_callback mcb = mDataCb;
    void *mdata = mCallbackCookie;
    int msgEnabled = mMsgEnabled;
    mCallbackLock.unlock();

    mMetaDataWaitLock.lock();
    if (mFaceDetectOn == true && mSendMetaData == true) {
        mSendMetaData = false;
        int faces_detected = roi.rect_num;
        int max_faces_detected = MAX_ROI * 4;
        int array[max_faces_detected + 1];

        array[0] = faces_detected * 4;
        for (int i = 1, j = 0;j < MAX_ROI; j++, i = i + 4) {
            if (j < faces_detected) {
                array[i]   = roi.faces[j].x;
                array[i+1] = roi.faces[j].y;
                array[i+2] = roi.faces[j].dx;
                array[i+3] = roi.faces[j].dy;
            } else {
                array[i]   = -1;
                array[i+1] = -1;
                array[i+2] = -1;
                array[i+3] = -1;
            }
        }
        if(mMetaDataHeap != NULL){
            ALOGV("mMetaDataHEap is non-NULL");
            memcpy((uint32_t *)mMetaDataHeap->mHeap->base(), (uint32_t *)array, (sizeof(int)*(MAX_ROI*4+1)));
            mMetaDataWaitLock.unlock();

            if  (mcb != NULL && (msgEnabled & CAMERA_MSG_META_DATA)) {
                mcb(CAMERA_MSG_META_DATA, mMetaDataHeap->mBuffers[0], mdata);
            }
        } else {
            mMetaDataWaitLock.unlock();
            ALOGE("runPreviewThread mMetaDataHeap is NULL");
        }
    } else {
        mMetaDataWaitLock.unlock();
    }
#endif // mzhu
    ALOGV("roiEvent: X");
}


void QCameraHardwareInterface::handleZoomEventForSnapshot(void)
{
    mm_camera_ch_crop_t v4l2_crop;


    ALOGV("%s: E", __func__);

    memset(&v4l2_crop,0,sizeof(v4l2_crop));
    v4l2_crop.ch_type=MM_CAMERA_CH_SNAPSHOT;

    ALOGV("%s: Fetching crop info", __func__);
    cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop);

    ALOGV("%s: Crop info received for main: %d, %d, %d, %d ", __func__,
         v4l2_crop.snapshot.main_crop.left,
         v4l2_crop.snapshot.main_crop.top,
         v4l2_crop.snapshot.main_crop.width,
         v4l2_crop.snapshot.main_crop.height);
    ALOGV("%s: Crop info received for thumbnail: %d, %d, %d, %d ",__func__,
         v4l2_crop.snapshot.thumbnail_crop.left,
         v4l2_crop.snapshot.thumbnail_crop.top,
         v4l2_crop.snapshot.thumbnail_crop.width,
         v4l2_crop.snapshot.thumbnail_crop.height);

    if(mStreamSnap) {
        ALOGV("%s: Setting crop info for snapshot", __func__);
        memcpy(&(mStreamSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop));
    }
    if(mFullLiveshotEnabled && mStreamLiveSnap){
        ALOGV("%s: Setting crop info for snapshot", __func__);
        memcpy(&(mStreamLiveSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop));
    }
    ALOGV("%s: X", __func__);
}

void QCameraHardwareInterface::handleZoomEventForPreview(app_notify_cb_t *app_cb)
{
    mm_camera_ch_crop_t v4l2_crop;

    ALOGV("%s: E", __func__);

    /*regular zooming or smooth zoom stopped*/
    if (!mSmoothZoomRunning && mPreviewWindow) {
        memset(&v4l2_crop, 0, sizeof(v4l2_crop));
        v4l2_crop.ch_type = MM_CAMERA_CH_PREVIEW;

        ALOGV("%s: Fetching crop info", __func__);
        cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop);

        ALOGV("%s: Crop info received: %d, %d, %d, %d ", __func__,
             v4l2_crop.crop.left,
             v4l2_crop.crop.top,
             v4l2_crop.crop.width,
             v4l2_crop.crop.height);

        mPreviewWindow->set_crop(mPreviewWindow,
                        v4l2_crop.crop.left,
                        v4l2_crop.crop.top,
                        v4l2_crop.crop.left + v4l2_crop.crop.width,
                        v4l2_crop.crop.top + v4l2_crop.crop.height);
        ALOGV("%s: Done setting crop", __func__);
        ALOGV("%s: Currrent zoom :%d",__func__, mCurrentZoom);
    }

    ALOGV("%s: X", __func__);
}

void QCameraHardwareInterface::zoomEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
{
    ALOGV("zoomEvent: state:%d E",mPreviewState);
    switch (mPreviewState) {
    case QCAMERA_HAL_PREVIEW_STOPPED:
        break;
    case QCAMERA_HAL_PREVIEW_START:
        break;
    case QCAMERA_HAL_PREVIEW_STARTED:
        handleZoomEventForPreview(app_cb);
        if (isZSLMode())
          handleZoomEventForSnapshot();
        break;
    case QCAMERA_HAL_RECORDING_STARTED:
        handleZoomEventForPreview(app_cb);
        if (mFullLiveshotEnabled)
            handleZoomEventForSnapshot();
        break;
    case QCAMERA_HAL_TAKE_PICTURE:
        if(isZSLMode())
            handleZoomEventForPreview(app_cb);
        handleZoomEventForSnapshot();
        break;
    default:
        break;
    }
    ALOGV("zoomEvent: X");
}

void QCameraHardwareInterface::dumpFrameToFile(const void * data, uint32_t size, char* name, char* ext, int index)
{
#if 0
    char buf[32], value[PROPERTY_VALUE_MAX];
    int file_fd, enabled = 0;
    static int i = 0 ;
    property_get("persist.camera.dumpimage", value, "0");
    enabled = atoi(value);

    if ( data != NULL && enabled) {
        char * str;
        snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext);
        ALOGE("%s size =%d", buf, size);
        file_fd = open(buf, O_RDWR | O_CREAT, 0777);
        write(file_fd, data, size);
        close(file_fd);
        i++;
    }
#endif
}

void QCameraHardwareInterface::dumpFrameToFile(struct msm_frame* newFrame,
  HAL_cam_dump_frm_type_t frm_type)
{
#if 0
  int32_t enabled = 0;
  int frm_num;
  uint32_t  skip_mode;
  char value[PROPERTY_VALUE_MAX];
  char buf[32];
  int main_422 = 1;
  property_get("persist.camera.dumpimg", value, "0");
  enabled = atoi(value);

  ALOGV(" newFrame =%p, frm_type = %d", newFrame, frm_type);
  if(enabled & HAL_DUMP_FRM_MASK_ALL) {
    if((enabled & frm_type) && newFrame) {
      frm_num = ((enabled & 0xffff0000) >> 16);
      if(frm_num == 0) frm_num = 10; /*default 10 frames*/
      if(frm_num > 256) frm_num = 256; /*256 buffers cycle around*/
      skip_mode = ((enabled & 0x0000ff00) >> 8);
      if(skip_mode == 0) skip_mode = 1; /*no -skip */

      if( mDumpSkipCnt % skip_mode == 0) {
        if (mDumpFrmCnt >= 0 && mDumpFrmCnt <= frm_num) {
          int w, h;
          int file_fd;
          switch (frm_type) {
          case  HAL_DUMP_FRM_PREVIEW:
            w = mDimension.display_width;
            h = mDimension.display_height;
            snprintf(buf, sizeof(buf), "/data/%dp_%dx%d.yuv", mDumpFrmCnt, w, h);
            file_fd = open(buf, O_RDWR | O_CREAT, 0777);
            break;
          case HAL_DUMP_FRM_VIDEO:
            w = mVideoWidth;
            h = mVideoHeight;
            snprintf(buf, sizeof(buf),"/data/%dv_%dx%d.yuv", mDumpFrmCnt, w, h);
            file_fd = open(buf, O_RDWR | O_CREAT, 0777);
            break;
          case HAL_DUMP_FRM_MAIN:
            w = mDimension.picture_width;
            h = mDimension.picture_height;
            snprintf(buf, sizeof(buf), "/data/%dm_%dx%d.yuv", mDumpFrmCnt, w, h);
            file_fd = open(buf, O_RDWR | O_CREAT, 0777);
            if (mDimension.main_img_format == CAMERA_YUV_422_NV16 ||
                mDimension.main_img_format == CAMERA_YUV_422_NV61)
              main_422 = 2;
            break;
          case HAL_DUMP_FRM_THUMBNAIL:
            w = mDimension.ui_thumbnail_width;
            h = mDimension.ui_thumbnail_height;
            snprintf(buf, sizeof(buf),"/data/%dt_%dx%d.yuv", mDumpFrmCnt, w, h);
            file_fd = open(buf, O_RDWR | O_CREAT, 0777);
            break;
          default:
            w = h = 0;
            file_fd = -1;
            break;
          }

          if (file_fd < 0) {
            ALOGE("%s: cannot open file:type=%d\n", __func__, frm_type);
          } else {
            ALOGV("%s: %d %d", __func__, newFrame->y_off, newFrame->cbcr_off);
            write(file_fd, (const void *)(newFrame->buffer+newFrame->y_off), w * h);
            write(file_fd, (const void *)
              (newFrame->buffer + newFrame->cbcr_off), w * h / 2 * main_422);
            close(file_fd);
            ALOGV("dump %s", buf);
          }
        } else if(frm_num == 256){
          mDumpFrmCnt = 0;
        }
        mDumpFrmCnt++;
      }
      mDumpSkipCnt++;
    }
  }  else {
    mDumpFrmCnt = 0;
  }
#endif
}

status_t QCameraHardwareInterface::setPreviewWindow(preview_stream_ops_t* window)
{
    status_t retVal = NO_ERROR;
    ALOGV(" %s: E mPreviewState = %d, mStreamDisplay = %p", __FUNCTION__, mPreviewState, mStreamDisplay);
    if( window == NULL) {
        ALOGE("%s:Received Setting NULL preview window", __func__);
    }
    Mutex::Autolock lock(mLock);
    switch(mPreviewState) {
    case QCAMERA_HAL_PREVIEW_START:
        mPreviewWindow = window;
        if(mPreviewWindow) {
            /* we have valid surface now, start preview */
            retVal = startPreview2();
            if(retVal == NO_ERROR)
                mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
            ALOGV("%s:  startPreview2 done, mPreviewState = %d", __func__, mPreviewState);
        } else
            ALOGE("%s: null window received, mPreviewState = %d", __func__, mPreviewState);
        break;
    case QCAMERA_HAL_PREVIEW_STARTED:
        /* new window comes */
        ALOGE("%s: bug, cannot handle new window in started state", __func__);
        //retVal = UNKNOWN_ERROR;
        break;
    case QCAMERA_HAL_PREVIEW_STOPPED:
    case QCAMERA_HAL_TAKE_PICTURE:
        mPreviewWindow = window;
        ALOGE("%s: mPreviewWindow = 0x%p, mStreamDisplay = 0x%p",
                                    __func__, mPreviewWindow, mStreamDisplay);
        if(mStreamDisplay)
            retVal = mStreamDisplay->setPreviewWindow(window);
        break;
    default:
        ALOGE("%s: bug, cannot handle new window in state %d", __func__, mPreviewState);
        retVal = UNKNOWN_ERROR;
        break;
    }
    ALOGV(" %s : X, mPreviewState = %d", __FUNCTION__, mPreviewState);
    return retVal;
}

int QCameraHardwareInterface::storeMetaDataInBuffers(int enable)
{
    /* this is a dummy func now. fix me later */
    mStoreMetaDataInFrame = enable;
    return 0;
}

status_t QCameraHardwareInterface::sendMappingBuf(int ext_mode, int idx, int fd,
                                                  uint32_t size, int cameraid,
                                                  mm_camera_socket_msg_type msg_type)
{
    cam_sock_packet_t packet;
    memset(&packet, 0, sizeof(cam_sock_packet_t));
    packet.msg_type = msg_type;
    packet.payload.frame_fd_map.ext_mode = ext_mode;
    packet.payload.frame_fd_map.frame_idx = idx;
    packet.payload.frame_fd_map.fd = fd;
    packet.payload.frame_fd_map.size = size;

    if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), packet.payload.frame_fd_map.fd) <= 0 ) {
        ALOGE("%s: sending frame mapping buf msg Failed", __func__);
        return FAILED_TRANSACTION;
    }
    return NO_ERROR;
}

status_t QCameraHardwareInterface::sendUnMappingBuf(int ext_mode, int idx, int cameraid,
                                                    mm_camera_socket_msg_type msg_type)
{
    cam_sock_packet_t packet;
    memset(&packet, 0, sizeof(cam_sock_packet_t));
    packet.msg_type = msg_type;
    packet.payload.frame_fd_unmap.ext_mode = ext_mode;
    packet.payload.frame_fd_unmap.frame_idx = idx;
    if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), 0) <= 0 ) {
        ALOGE("%s: sending frame unmapping buf msg Failed", __func__);
        return FAILED_TRANSACTION;
    }
    return NO_ERROR;
}

int QCameraHardwareInterface::allocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt, int ion_type)
{
  int rc = 0;
  struct ion_handle_data handle_data;

  p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
  if (p_camera_memory->main_ion_fd[cnt] < 0) {
    ALOGE("Ion dev open failed\n");
    ALOGE("Error is %s\n", strerror(errno));
    goto ION_OPEN_FAILED;
  }
  p_camera_memory->alloc[cnt].len = p_camera_memory->size;
  /* to make it page size aligned */
  p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095);
  p_camera_memory->alloc[cnt].align = 4096;
  p_camera_memory->alloc[cnt].flags = ION_FLAG_CACHED;
  p_camera_memory->alloc[cnt].heap_mask = ion_type;

  rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]);
  if (rc < 0) {
    ALOGE("ION allocation failed\n");
    goto ION_ALLOC_FAILED;
  }

  p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle;
  rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]);
  if (rc < 0) {
    ALOGE("ION map failed %s\n", strerror(errno));
    goto ION_MAP_FAILED;
  }
  p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd;
  return 0;

ION_MAP_FAILED:
  handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
  ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
ION_ALLOC_FAILED:
  close(p_camera_memory->main_ion_fd[cnt]);
  p_camera_memory->main_ion_fd[cnt] = -1;
ION_OPEN_FAILED:
  return -1;
}

int QCameraHardwareInterface::deallocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt)
{
  struct ion_handle_data handle_data;
  int rc = 0;

  if (p_camera_memory->main_ion_fd[cnt] > 0) {
      handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
      ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
      close(p_camera_memory->main_ion_fd[cnt]);
      p_camera_memory->main_ion_fd[cnt] = -1;
  }
  return rc;
}

int QCameraHardwareInterface::allocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt, int ion_type)
{
  int rc = 0;
  struct ion_handle_data handle_data;

  p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
  if (p_camera_memory->main_ion_fd[cnt] < 0) {
    ALOGE("Ion dev open failed\n");
    ALOGE("Error is %s\n", strerror(errno));
    goto ION_OPEN_FAILED;
  }
  p_camera_memory->alloc[cnt].len = p_camera_memory->size;
  /* to make it page size aligned */
  p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095);
  p_camera_memory->alloc[cnt].align = 4096;
  p_camera_memory->alloc[cnt].flags = ION_FLAG_CACHED;
  p_camera_memory->alloc[cnt].heap_mask = (0x1 << ion_type | 0x1 << ION_IOMMU_HEAP_ID);

  rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]);
  if (rc < 0) {
    ALOGE("ION allocation failed\n");
    goto ION_ALLOC_FAILED;
  }

  p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle;
  rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]);
  if (rc < 0) {
    ALOGE("ION map failed %s\n", strerror(errno));
    goto ION_MAP_FAILED;
  }
  p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd;
  return 0;

ION_MAP_FAILED:
  handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
  ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
ION_ALLOC_FAILED:
  close(p_camera_memory->main_ion_fd[cnt]);
  p_camera_memory->main_ion_fd[cnt] = -1;
ION_OPEN_FAILED:
  return -1;
}

int QCameraHardwareInterface::cache_ops(int ion_fd,
  struct ion_flush_data *cache_data, int type)
{
  int rc = 0;
  struct ion_custom_data data;
  data.cmd = type;
  data.arg = (unsigned long)cache_data;

  rc = ioctl(ion_fd, ION_IOC_CUSTOM, &data);
  if (rc < 0)
    ALOGE("%s: Cache Invalidate failed\n", __func__);
  else
    ALOGV("%s: Cache OPs type(%d) success", __func__);

  return rc;
}

int QCameraHardwareInterface::deallocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt)
{
  struct ion_handle_data handle_data;
  int rc = 0;

  if (p_camera_memory->main_ion_fd[cnt] > 0) {
      handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
      ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
      close(p_camera_memory->main_ion_fd[cnt]);
      p_camera_memory->main_ion_fd[cnt] = -1;
  }
  return rc;
}

int QCameraHardwareInterface::initHeapMem( QCameraHalHeap_t *heap,
                            int num_of_buf,
                            int buf_len,
                            int y_off,
                            int cbcr_off,
                            int pmem_type,
                            mm_cameara_stream_buf_t *StreamBuf,
                            mm_camera_buf_def_t *buf_def,
                            uint8_t num_planes,
                            uint32_t *planes
)
{
    int rc = 0;
    int i;
    int path;
    int ion_fd;
    struct msm_frame *frame;
    struct ion_flush_data cache_inv_data;
    ALOGV("Init Heap =%p. stream_buf =%p, pmem_type =%d, num_of_buf=%d. buf_len=%d, cbcr_off=%d",
         heap, StreamBuf, pmem_type, num_of_buf, buf_len, cbcr_off);
    if(num_of_buf > MM_CAMERA_MAX_NUM_FRAMES || heap == NULL ||
       mGetMemory == NULL ) {
        ALOGE("Init Heap error");
        rc = -1;
        return rc;
    }
    memset(heap, 0, sizeof(QCameraHalHeap_t));
    for (i=0; i<MM_CAMERA_MAX_NUM_FRAMES;i++) {
        heap->main_ion_fd[i] = -1;
        heap->fd[i] = -1;
    }
    heap->buffer_count = num_of_buf;
    heap->size = buf_len;
    heap->y_offset = y_off;
    heap->cbcr_offset = cbcr_off;

    if (StreamBuf != NULL) {
        StreamBuf->num = num_of_buf;
                StreamBuf->frame_len = buf_len;
        switch (pmem_type) {
            case  MSM_PMEM_MAINIMG:
            case  MSM_PMEM_RAW_MAINIMG:
                path = OUTPUT_TYPE_S;
                break;

            case  MSM_PMEM_THUMBNAIL:
                path = OUTPUT_TYPE_T;
                break;

            default:
                rc = -1;
                return rc;
        }
    }


    for(i = 0; i < num_of_buf; i++) {
#ifdef USE_ION
      if (isZSLMode())
        rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
         (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
      else
        rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ION_HEAP_ID) |
         (0x1 << CAMERA_ION_FALLBACK_HEAP_ID)));

      if (rc < 0) {
        ALOGE("%s: ION allocation failed\n", __func__);
        break;
      }
#else
        if (pmem_type == MSM_PMEM_MAX)
            heap->fd[i] = -1;
        else {
            heap->fd[i] = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
            if ( heap->fd[i] <= 0) {
                rc = -1;
                ALOGE("Open fail: heap->fd[%d] =%d", i, heap->fd[i]);
                break;
            }
        }
#endif
        heap->camera_memory[i] =  mGetMemory( heap->fd[i], buf_len, 1, (void *)this);

        if (heap->camera_memory[i] == NULL ) {
            ALOGE("Getmem fail %d: ", i);
            rc = -1;
            break;
        }

        memset(&cache_inv_data, 0, sizeof(struct ion_flush_data));
        cache_inv_data.vaddr = (void*) heap->camera_memory[i]->data;
        cache_inv_data.fd = heap->ion_info_fd[i].fd;
        cache_inv_data.handle = heap->ion_info_fd[i].handle;
        cache_inv_data.length = heap->alloc[i].len;
        ion_fd = heap->main_ion_fd[i];
        if(ion_fd > 0) {
            if(cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_INV_CACHES) < 0)
                ALOGE("%s: Cache Invalidate failed\n", __func__);
            else {
                ALOGV("%s: Successful cache invalidate\n", __func__);
            }
        }

        if (StreamBuf != NULL) {
            frame = &(StreamBuf->frame[i]);
            memset(frame, 0, sizeof(struct msm_frame));
            frame->fd = heap->fd[i];
            frame->phy_offset = 0;
            frame->buffer = (uint32_t) heap->camera_memory[i]->data;
            frame->path = path;
            frame->cbcr_off =  planes[0]+heap->cbcr_offset;
            frame->y_off =  heap->y_offset;
            frame->fd_data = heap->ion_info_fd[i];
            frame->ion_alloc = heap->alloc[i];
            frame->ion_dev_fd = heap->main_ion_fd[i];
            ALOGV("%s: Buffer idx: %d  addr: %x fd: %d phy_offset: %d"
                 "cbcr_off: %d y_off: %d frame_len: %d", __func__,
                 i, (unsigned int)frame->buffer, frame->fd,
                 frame->phy_offset, cbcr_off, y_off, frame->ion_alloc.len);

            buf_def->buf.mp[i].frame = *frame;
            buf_def->buf.mp[i].frame_offset = 0;
            buf_def->buf.mp[i].num_planes = num_planes;
            /* Plane 0 needs to be set seperately. Set other planes
             * in a loop. */
            buf_def->buf.mp[i].planes[0].length = planes[0];
            buf_def->buf.mp[i].planes[0].m.userptr = frame->fd;
            buf_def->buf.mp[i].planes[0].data_offset = y_off;
            buf_def->buf.mp[i].planes[0].reserved[0] =
              buf_def->buf.mp[i].frame_offset;
            for (int j = 1; j < num_planes; j++) {
                 buf_def->buf.mp[i].planes[j].length = planes[j];
                 buf_def->buf.mp[i].planes[j].m.userptr = frame->fd;
                 buf_def->buf.mp[i].planes[j].data_offset = cbcr_off;
                 buf_def->buf.mp[i].planes[j].reserved[0] =
                     buf_def->buf.mp[i].planes[j-1].reserved[0] +
                     buf_def->buf.mp[i].planes[j-1].length;
            }
        } else {
        }

        ALOGV("heap->fd[%d] =%d, camera_memory=%p", i, heap->fd[i], heap->camera_memory[i]);
        heap->local_flag[i] = 1;
    }
    if( rc < 0) {
        releaseHeapMem(heap);
    }
    return rc;
}

int QCameraHardwareInterface::releaseHeapMem( QCameraHalHeap_t *heap)
{
	int rc = 0;
	ALOGV("Release %p", heap);
	if (heap != NULL) {

		for (int i = 0; i < heap->buffer_count; i++) {
			if(heap->camera_memory[i] != NULL) {
				heap->camera_memory[i]->release( heap->camera_memory[i] );
				heap->camera_memory[i] = NULL;
			} else if (heap->fd[i] <= 0) {
				ALOGE("impossible: amera_memory[%d] = %p, fd = %d",
				i, heap->camera_memory[i], heap->fd[i]);
			}

			if(heap->fd[i] > 0) {
				close(heap->fd[i]);
				heap->fd[i] = -1;
			}
#ifdef USE_ION
            deallocate_ion_memory(heap, i);
#endif
		}
        heap->buffer_count = 0;
        heap->size = 0;
        heap->y_offset = 0;
        heap->cbcr_offset = 0;
	}
	return rc;
}

preview_format_info_t  QCameraHardwareInterface::getPreviewFormatInfo( )
{
  return mPreviewFormatInfo;
}

void QCameraHardwareInterface::wdenoiseEvent(cam_ctrl_status_t status, void *cookie)
{
    ALOGV("wdnEvent: preview state:%d E",mPreviewState);
    if (mStreamSnap != NULL) {
        ALOGV("notifyWDNEvent to snapshot stream");
        mStreamSnap->notifyWDenoiseEvent(status, cookie);
    }
}

bool QCameraHardwareInterface::isWDenoiseEnabled()
{
    return mDenoiseValue;
}

void QCameraHardwareInterface::takePicturePrepareHardware()
{
    ALOGV("%s: E", __func__);

    /* Prepare snapshot*/
    cam_ops_action(mCameraId,
                  true,
                  MM_CAMERA_OPS_PREPARE_SNAPSHOT,
                  this);
    ALOGV("%s: X", __func__);
}

bool QCameraHardwareInterface::isNoDisplayMode()
{
  return (mNoDisplayMode != 0);
}

void QCameraHardwareInterface::pausePreviewForZSL()
{
    ALOGV("%s: mRestartPreview %d", __func__, mRestartPreview);
    if(mRestartPreview) {
        ALOGE("%s: Restarting Preview",__func__);
        stopPreviewInternal();
        mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
        startPreview2();
        mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
    }
}

void QCameraHardwareInterface::pausePreviewForVideo()
{
    status_t ret = NO_ERROR;
    bool restart = false;
    cam_ctrl_dimension_t dim;

    /*  get existing preview information, by qury mm_camera*/
    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);

    if (MM_CAMERA_OK != ret) {
      ALOGE("%s: X error- can't get preview dimension!", __func__);
      return;
    }

    if (mRestartPreview) {
        mRestartPreview = false;
        ALOGV("%s: Restarting Preview. Video Size changed",__func__);
        restart |= false;
    }
    if (mRecordingHint == false) {
        ALOGV("%s: Restarting Preview. Hint not set",__func__);
        restart |= true;
    }

    if(dim.video_width != mVideoWidth || dim.video_height != mVideoHeight){
        ALOGV("%s: Restarting Preview. New Video Size set",__func__);
        restart |= true;
    }

    //VFE output1 shouldn't be greater than VFE output2.
    if( (mPreviewWidth > mVideoWidth) || (mPreviewHeight > mVideoHeight)) {
        //Set preview sizes as record sizes.
        ALOGV("Preview size %dx%d is greater than record size %dx%d,\
                resetting preview size to record size",mPreviewWidth,
                        mPreviewHeight, mVideoWidth, mVideoHeight);
        mPreviewWidth = mVideoWidth;
        mPreviewHeight = mVideoHeight;
        mParameters.setPreviewSize(mPreviewWidth, mPreviewHeight);
        restart |= true;
    }
    if (restart) {
        stopPreviewInternal();
        mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;

        // Set recording hint to true
        mRecordingHint = true;
        setRecordingHintValue(mRecordingHint);

        mDimension.display_width = mPreviewWidth;
        mDimension.display_height= mPreviewHeight;
        mDimension.orig_video_width = mVideoWidth;
        mDimension.orig_video_height = mVideoHeight;
        mDimension.video_width = mVideoWidth;
        mDimension.video_height = mVideoHeight;

        // start preview again
        mPreviewState = QCAMERA_HAL_PREVIEW_START;
        if (startPreview2() == NO_ERROR){
            mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
        }else{
            ALOGE("%s: Restart for Video Failed",__func__);
        }
    }
}

/**/
bool QCameraHardwareInterface::getHdrInfoAndSetExp( int max_num_frm, int *num_frame, int *exp)
{
    bool rc = false;

    if (mHdrMode == HDR_MODE && num_frame != NULL && exp != NULL &&
      mRecordingHint != true &&
      mPreviewState != QCAMERA_HAL_RECORDING_STARTED ) {
        int ret = 0;
        *num_frame = 1;
        exp_bracketing_t temp;
        memset(&temp, 0, sizeof(exp_bracketing_t));
        ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HDR, (void *)&temp );
        if (ret == NO_ERROR && max_num_frm > 0) {
            /*set as AE Bracketing mode*/
            temp.hdr_enable = false;
            temp.mode = HDR_MODE;
            temp.total_hal_frames = temp.total_frames;
            ret = native_set_parms(MM_CAMERA_PARM_HDR,
                                   sizeof(exp_bracketing_t), (void *)&temp);
            if (ret) {
                char *val, *exp_value, *prev_value;
                int i;
                exp_value = (char *) temp.values;
                i = 0;
                val = strtok_r(exp_value,",", &prev_value);
                while (val != NULL ){
                  exp[i++] = atoi(val);
                  if(i >= max_num_frm )
                    break;
                  val = strtok_r(NULL, ",", &prev_value);
                }
                *num_frame =temp.total_frames;
                rc = true;
            }
        } else {
            temp.total_frames = 1;
        }
        /* Application waits until this many snapshots before restarting preview */
        mParameters.set("num-snaps-per-shutter", 2);
    }
    return rc;
}

void QCameraHardwareInterface::hdrEvent(cam_ctrl_status_t status, void *cookie)
{
    QCameraStream * snapStream = (QCameraStream *)cookie;
    ALOGV("HdrEvent: preview state: E");
    if (snapStream != NULL && mStreamSnap != NULL) {
        ALOGV("HdrEvent to snapshot stream");
        snapStream->notifyHdrEvent(status, cookie);
    }
}

}; // namespace android
