/*
 * Copyright (C) Texas Instruments - http://www.ti.com/
 *
 * 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.
 */

/**
* @file CameraHal.cpp
*
* This file maps the Camera Hardware Interface to V4L2.
*
*/

#define LOG_TAG "CameraHAL"

#include "CameraHal.h"
#include "ANativeWindowDisplayAdapter.h"
#include "TICameraParameters.h"
#include "CameraProperties.h"
#include <cutils/properties.h>

#include <poll.h>
#include <math.h>

namespace android {

extern "C" CameraAdapter* CameraAdapter_Factory(size_t);

/*****************************************************************************/

////Constant definitions and declarations
////@todo Have a CameraProperties class to store these parameters as constants for every camera
////       Currently, they are hard-coded

const int CameraHal::NO_BUFFERS_PREVIEW = MAX_CAMERA_BUFFERS;
const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE = 2;

const uint32_t MessageNotifier::EVENT_BIT_FIELD_POSITION = 0;
const uint32_t MessageNotifier::FRAME_BIT_FIELD_POSITION = 0;

/******************************************************************************/

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

struct timeval CameraHal::mStartPreview;
struct timeval CameraHal::mStartFocus;
struct timeval CameraHal::mStartCapture;

#endif

static void orientation_cb(uint32_t orientation, uint32_t tilt, void* cookie) {
    CameraHal *camera = NULL;

    if (cookie) {
        camera = (CameraHal*) cookie;
        camera->onOrientationEvent(orientation, tilt);
    }

}
/*-------------Camera Hal Interface Method definitions STARTS here--------------------*/

/**
  Callback function to receive orientation events from SensorListener
 */
void CameraHal::onOrientationEvent(uint32_t orientation, uint32_t tilt) {
    LOG_FUNCTION_NAME;

    if ( NULL != mCameraAdapter ) {
        mCameraAdapter->onOrientationEvent(orientation, tilt);
    }

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Set the notification and data callbacks

   @param[in] notify_cb Notify callback for notifying the app about events and errors
   @param[in] data_cb   Buffer callback for sending the preview/raw frames to the app
   @param[in] data_cb_timestamp Buffer callback for sending the video frames w/ timestamp
   @param[in] user  Callback cookie
   @return none

 */
void CameraHal::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)
{
    LOG_FUNCTION_NAME;

    if ( NULL != mAppCallbackNotifier.get() )
    {
            mAppCallbackNotifier->setCallbacks(this,
                                                notify_cb,
                                                data_cb,
                                                data_cb_timestamp,
                                                get_memory,
                                                user);
    }

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Enable a message, or set of messages.

   @param[in] msgtype Bitmask of the messages to enable (defined in include/ui/Camera.h)
   @return none

 */
void CameraHal::enableMsgType(int32_t msgType)
{
    LOG_FUNCTION_NAME;

    if ( ( msgType & CAMERA_MSG_SHUTTER ) && ( !mShutterEnabled ) )
        {
        msgType &= ~CAMERA_MSG_SHUTTER;
        }

    // ignoring enable focus message from camera service
    // we will enable internally in autoFocus call
    if (msgType & CAMERA_MSG_FOCUS) {
        msgType &= ~CAMERA_MSG_FOCUS;
    }

    {
    Mutex::Autolock lock(mLock);
    mMsgEnabled |= msgType;
    }

    if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
    {
        if(mDisplayPaused)
        {
            CAMHAL_LOGDA("Preview currently paused...will enable preview callback when restarted");
            msgType &= ~CAMERA_MSG_PREVIEW_FRAME;
        }else
        {
            CAMHAL_LOGDA("Enabling Preview Callback");
        }
    }
    else
    {
        CAMHAL_LOGDB("Preview callback not enabled %x", msgType);
    }


    ///Configure app callback notifier with the message callback required
    mAppCallbackNotifier->enableMsgType (msgType);

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Disable a message, or set of messages.

   @param[in] msgtype Bitmask of the messages to disable (defined in include/ui/Camera.h)
   @return none

 */
void CameraHal::disableMsgType(int32_t msgType)
{
    LOG_FUNCTION_NAME;

        {
        Mutex::Autolock lock(mLock);
        mMsgEnabled &= ~msgType;
        }

    if( msgType & CAMERA_MSG_PREVIEW_FRAME)
        {
        CAMHAL_LOGDA("Disabling Preview Callback");
        }

    ///Configure app callback notifier
    mAppCallbackNotifier->disableMsgType (msgType);

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Query whether a message, or a set of messages, is enabled.

   Note that this is operates as an AND, if any of the messages queried are off, this will
   return false.

   @param[in] msgtype Bitmask of the messages to query (defined in include/ui/Camera.h)
   @return true If all message types are enabled
          false If any message type

 */
int CameraHal::msgTypeEnabled(int32_t msgType)
{
    LOG_FUNCTION_NAME;
    Mutex::Autolock lock(mLock);
    LOG_FUNCTION_NAME_EXIT;
    return (mMsgEnabled & msgType);
}

/**
   @brief Set the camera parameters.

   @param[in] params Camera parameters to configure the camera
   @return NO_ERROR
   @todo Define error codes

 */
int CameraHal::setParameters(const char* parameters)
{

   LOG_FUNCTION_NAME;

    CameraParameters params;

    String8 str_params(parameters);
    params.unflatten(str_params);

    LOG_FUNCTION_NAME_EXIT;

    return setParameters(params);
}

/**
   @brief Set the camera parameters.

   @param[in] params Camera parameters to configure the camera
   @return NO_ERROR
   @todo Define error codes

 */
int CameraHal::setParameters(const CameraParameters& params)
{

   LOG_FUNCTION_NAME;

    int w, h;
    int w_orig, h_orig;
    int framerate,minframerate;
    int maxFPS, minFPS;
    int error;
    int base;
    const char *valstr = NULL;
    const char *prevFormat;
    char *af_coord;
    TIUTILS::Message msg;
    status_t ret = NO_ERROR;
    // Needed for KEY_RECORDING_HINT
    bool restartPreviewRequired = false;
    bool updateRequired = false;
    CameraParameters oldParams(mParameters.flatten());
    bool videoMode = false;
    char range[MAX_PROP_VALUE_LENGTH];

    {
        Mutex::Autolock lock(mLock);

        ///Ensure that preview is not enabled when the below parameters are changed.
        if(!previewEnabled())
            {

            CAMHAL_LOGDB("PreviewFormat %s", params.getPreviewFormat());

            if ((valstr = params.getPreviewFormat()) != NULL) {
                if ( isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS))) {
                    mParameters.setPreviewFormat(valstr);
                } else {
                    CAMHAL_LOGEB("Invalid preview format.Supported: %s",  mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
                    return -EINVAL;
                }
            }

            if ((valstr = params.get(TICameraParameters::KEY_VNF)) != NULL) {
                if ( (params.getInt(TICameraParameters::KEY_VNF)==0) || (params.getInt(TICameraParameters::KEY_VNF)==1) ) {
                    CAMHAL_LOGDB("VNF set %s", params.get(TICameraParameters::KEY_VNF));
                    mParameters.set(TICameraParameters::KEY_VNF, valstr);
                } else {
                    CAMHAL_LOGEB("ERROR: Invalid VNF: %s", valstr);
                    ret = -EINVAL;
                }
            }

            if ((valstr = params.get(CameraParameters::KEY_VIDEO_STABILIZATION)) != NULL) {
                // make sure we support vstab...if we don't and application is trying to set
                // vstab then return an error
                if (strcmp(mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED),
                           CameraParameters::TRUE) == 0) {
                    CAMHAL_LOGDB("VSTAB %s",
                                  params.get(CameraParameters::KEY_VIDEO_STABILIZATION));
                    mParameters.set(CameraParameters::KEY_VIDEO_STABILIZATION,
                                    params.get(CameraParameters::KEY_VIDEO_STABILIZATION));
                } else if (strcmp(valstr, CameraParameters::TRUE) == 0) {
                    CAMHAL_LOGEB("ERROR: Invalid VSTAB: %s", valstr);
                    ret = -EINVAL;
                } else {
                    mParameters.set(CameraParameters::KEY_VIDEO_STABILIZATION,
                                    CameraParameters::FALSE);
                }
            }

            if( (valstr = params.get(TICameraParameters::KEY_CAP_MODE)) != NULL)
                {
                CAMHAL_LOGDB("Capture mode set %s", params.get(TICameraParameters::KEY_CAP_MODE));
                mParameters.set(TICameraParameters::KEY_CAP_MODE, valstr);
                }

            if ((valstr = params.get(TICameraParameters::KEY_IPP)) != NULL) {
                if (isParameterValid(valstr,mCameraProperties->get(CameraProperties::SUPPORTED_IPP_MODES))) {
                    CAMHAL_LOGDB("IPP mode set %s", params.get(TICameraParameters::KEY_IPP));
                    mParameters.set(TICameraParameters::KEY_IPP, valstr);
                } else {
                    CAMHAL_LOGEB("ERROR: Invalid IPP mode: %s", valstr);
                    ret = -EINVAL;
                }
            }

            if((valstr = params.get(TICameraParameters::KEY_S3D2D_PREVIEW)) != NULL)
                {
                CAMHAL_LOGDB("Stereo 3D->2D Preview mode is %s", params.get(TICameraParameters::KEY_S3D2D_PREVIEW));
                mParameters.set(TICameraParameters::KEY_S3D2D_PREVIEW, valstr);
                }

            if((valstr = params.get(TICameraParameters::KEY_AUTOCONVERGENCE)) != NULL)
                {
                CAMHAL_LOGDB("AutoConvergence mode is %s", params.get(TICameraParameters::KEY_AUTOCONVERGENCE));
                mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE, valstr);
                }

            }

            params.getPreviewSize(&w, &h);
            if (w == -1 && h == -1) {
                CAMHAL_LOGEA("Unable to get preview size");
                return -EINVAL;
              }

            int oldWidth, oldHeight;
            mParameters.getPreviewSize(&oldWidth, &oldHeight);

            int orientation =0;
            if((valstr = params.get(TICameraParameters::KEY_SENSOR_ORIENTATION)) != NULL)
                {
                CAMHAL_LOGDB("Sensor Orientation is set to %s", params.get(TICameraParameters::KEY_SENSOR_ORIENTATION));
                mParameters.set(TICameraParameters::KEY_SENSOR_ORIENTATION, valstr);
                orientation = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
                }

            if(orientation ==90 || orientation ==270)
           {
              if ( !isResolutionValid(h,w, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES)))
               {
                CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
                return -EINVAL;
               }
              else
              {
                mParameters.setPreviewSize(w, h);
                mVideoWidth = w;
                mVideoHeight = h;
               }
           }
           else
           {
            if ( !isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES)))
                {
                CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
                return -EINVAL;
                }
            else
                {
                mParameters.setPreviewSize(w, h);
                }
           }

            if ( ( oldWidth != w ) || ( oldHeight != h ) )
                {
                restartPreviewRequired |= true;
                }

            CAMHAL_LOGDB("PreviewResolution by App %d x %d", w, h);

        // Handle RECORDING_HINT to Set/Reset Video Mode Parameters
        valstr = params.get(CameraParameters::KEY_RECORDING_HINT);
        if(valstr != NULL)
            {
            if(strcmp(valstr, CameraParameters::TRUE) == 0)
                {
                CAMHAL_LOGDB("Recording Hint is set to %s", valstr);
                mParameters.set(CameraParameters::KEY_RECORDING_HINT, valstr);
                videoMode = true;
                int w, h;

                params.getPreviewSize(&w, &h);
                CAMHAL_LOGVB("%s Preview Width=%d Height=%d\n", __FUNCTION__, w, h);
                //HACK FOR MMS
                mVideoWidth = w;
                mVideoHeight = h;
                CAMHAL_LOGVB("%s Video Width=%d Height=%d\n", __FUNCTION__, mVideoWidth, mVideoHeight);

                setPreferredPreviewRes(w, h);
                mParameters.getPreviewSize(&w, &h);
                CAMHAL_LOGVB("%s Preview Width=%d Height=%d\n", __FUNCTION__, w, h);
                //Avoid restarting preview for MMS HACK
                if ((w != mVideoWidth) && (h != mVideoHeight))
                    {
                    restartPreviewRequired = false;
                    }

                restartPreviewRequired |= setVideoModeParameters(params);
                }
            else if(strcmp(valstr, CameraParameters::FALSE) == 0)
                {
                CAMHAL_LOGDB("Recording Hint is set to %s", valstr);
                mParameters.set(CameraParameters::KEY_RECORDING_HINT, valstr);
                restartPreviewRequired |= resetVideoModeParameters();
                params.getPreviewSize(&mVideoWidth, &mVideoHeight);
                }
            else
                {
                CAMHAL_LOGEA("Invalid RECORDING_HINT");
                return -EINVAL;
                }
            }
        else
            {
            // This check is required in following case.
            // If VideoRecording activity sets KEY_RECORDING_HINT to TRUE and
            // ImageCapture activity doesnot set KEY_RECORDING_HINT to FALSE (i.e. simply NULL),
            // then Video Mode parameters may remain present in ImageCapture activity as well.
            CAMHAL_LOGDA("Recording Hint is set to NULL");
            mParameters.set(CameraParameters::KEY_RECORDING_HINT, "");
            restartPreviewRequired |= resetVideoModeParameters();
            params.getPreviewSize(&mVideoWidth, &mVideoHeight);
            }

        if ((valstr = params.get(CameraParameters::KEY_FOCUS_MODE)) != NULL) {
            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES))) {
                CAMHAL_LOGDB("Focus mode set %s", params.get(CameraParameters::KEY_FOCUS_MODE));

                // we need to take a decision on the capture mode based on whether CAF picture or
                // video is chosen so the behavior of each is consistent to the application
                if(strcmp(valstr, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) == 0){
                    restartPreviewRequired |= resetVideoModeParameters();
                } else if (strcmp(valstr, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) == 0){
                    restartPreviewRequired |= setVideoModeParameters(params);
                }

                mParameters.set(CameraParameters::KEY_FOCUS_MODE, valstr);
             } else {
                CAMHAL_LOGEB("ERROR: Invalid FOCUS mode = %s", valstr);
                ret = -EINVAL;
             }
        }

        ///Below parameters can be changed when the preview is running
        if ( (valstr = params.getPictureFormat()) != NULL ) {
            if (isParameterValid(params.getPictureFormat(),mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS))) {
                mParameters.setPictureFormat(valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid picture format: %s",valstr);
                ret = -EINVAL;
            }
            }

        params.getPictureSize(&w, &h);
        if ( isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES))) {
            mParameters.setPictureSize(w, h);
        } else {
            CAMHAL_LOGEB("ERROR: Invalid picture resolution %dx%d", w, h);
            ret = -EINVAL;
        }

        CAMHAL_LOGDB("Picture Size by App %d x %d", w, h);

        if ((valstr = params.get(TICameraParameters::KEY_BURST)) != NULL) {
            if (params.getInt(TICameraParameters::KEY_BURST) >=0) {
                CAMHAL_LOGDB("Burst set %s", params.get(TICameraParameters::KEY_BURST));
                mParameters.set(TICameraParameters::KEY_BURST, valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid Burst value: %s",valstr);
                ret = -EINVAL;
            }
        }

        framerate = params.getPreviewFrameRate();
        valstr = params.get(CameraParameters::KEY_PREVIEW_FPS_RANGE);
        CAMHAL_LOGDB("FRAMERATE %d", framerate);

        CAMHAL_LOGVB("Passed FRR: %s, Supported FRR %s", valstr
                        , mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED));
        CAMHAL_LOGVB("Passed FR: %d, Supported FR %s", framerate
                        , mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES));


        //Perform parameter validation
        if(!isParameterValid(valstr
                        , mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED))
                        || !isParameterValid(framerate,
                                      mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES)))
        {
            CAMHAL_LOGEA("Invalid frame rate range or frame rate");
            return -EINVAL;
        }

        // Variable framerate ranges have higher priority over
        // deprecated constant FPS. "KEY_PREVIEW_FPS_RANGE" should
        // be cleared by the client in order for constant FPS to get
        // applied.
        if ( strcmp(valstr, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE))  != 0)
          {
            // APP wants to set FPS range
            //Set framerate = MAXFPS
            CAMHAL_LOGDA("APP IS CHANGING FRAME RATE RANGE");
            params.getPreviewFpsRange(&minFPS, &maxFPS);

            if ( ( 0 > minFPS ) || ( 0 > maxFPS ) )
              {
                CAMHAL_LOGEA("ERROR: FPS Range is negative!");
                return -EINVAL;
              }

            framerate = maxFPS /CameraHal::VFR_SCALE;

          }
        else
          {
              if ( framerate != atoi(mCameraProperties->get(CameraProperties::PREVIEW_FRAME_RATE)) )
              {

                selectFPSRange(framerate, &minFPS, &maxFPS);
                CAMHAL_LOGDB("Select FPS Range %d %d", minFPS, maxFPS);
              }
              else
                {
                    if (videoMode) {
                        valstr = mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_VIDEO);
                        CameraParameters temp;
                        temp.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, valstr);
                        temp.getPreviewFpsRange(&minFPS, &maxFPS);
                    }
                    else {
                        valstr = mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_IMAGE);
                        CameraParameters temp;
                        temp.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, valstr);
                        temp.getPreviewFpsRange(&minFPS, &maxFPS);
                    }

                    framerate = maxFPS / CameraHal::VFR_SCALE;
                }

          }

        CAMHAL_LOGDB("FPS Range = %s", valstr);
        CAMHAL_LOGDB("DEFAULT FPS Range = %s", mCameraProperties->get(CameraProperties::FRAMERATE_RANGE));

        minFPS /= CameraHal::VFR_SCALE;
        maxFPS /= CameraHal::VFR_SCALE;

        if ( ( 0 == minFPS ) || ( 0 == maxFPS ) )
          {
            CAMHAL_LOGEA("ERROR: FPS Range is invalid!");
            ret = -EINVAL;
          }

        if ( maxFPS < minFPS )
          {
            CAMHAL_LOGEA("ERROR: Max FPS is smaller than Min FPS!");
            ret = -EINVAL;
          }
        CAMHAL_LOGDB("SET FRAMERATE %d", framerate);
        mParameters.setPreviewFrameRate(framerate);
        mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, params.get(CameraParameters::KEY_PREVIEW_FPS_RANGE));

        CAMHAL_LOGDB("FPS Range [%d, %d]", minFPS, maxFPS);
        mParameters.set(TICameraParameters::KEY_MINFRAMERATE, minFPS);
        mParameters.set(TICameraParameters::KEY_MAXFRAMERATE, maxFPS);

        if( ( valstr = params.get(TICameraParameters::KEY_GBCE) ) != NULL )
            {
            CAMHAL_LOGDB("GBCE Value = %s", valstr);
            mParameters.set(TICameraParameters::KEY_GBCE, valstr);
            }

        if( ( valstr = params.get(TICameraParameters::KEY_GLBCE) ) != NULL )
            {
            CAMHAL_LOGDB("GLBCE Value = %s", valstr);
            mParameters.set(TICameraParameters::KEY_GLBCE, valstr);
            }

        ///Update the current parameter set
        if( (valstr = params.get(TICameraParameters::KEY_AUTOCONVERGENCE)) != NULL)
            {
            CAMHAL_LOGDB("AutoConvergence Mode is set = %s", params.get(TICameraParameters::KEY_AUTOCONVERGENCE));
            mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE, valstr);
            }

        if( (valstr = params.get(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES)) !=NULL )
            {
            CAMHAL_LOGDB("ManualConvergence Value = %s", params.get(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES));
            mParameters.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, valstr);
            }

        if ((valstr = params.get(TICameraParameters::KEY_EXPOSURE_MODE)) != NULL) {
            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES))) {
                CAMHAL_LOGDB("Exposure set = %s", valstr);
                mParameters.set(TICameraParameters::KEY_EXPOSURE_MODE, valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid Exposure  = %s", valstr);
                ret = -EINVAL;
            }
        }

        if ((valstr = params.get(CameraParameters::KEY_WHITE_BALANCE)) != NULL) {
           if ( isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE))) {
               CAMHAL_LOGDB("White balance set %s", valstr);
               mParameters.set(CameraParameters::KEY_WHITE_BALANCE, valstr);
            } else {
               CAMHAL_LOGEB("ERROR: Invalid white balance  = %s", valstr);
               ret = -EINVAL;
            }
        }

        if ((valstr = params.get(TICameraParameters::KEY_CONTRAST)) != NULL) {
            if (params.getInt(TICameraParameters::KEY_CONTRAST) >= 0 ) {
                CAMHAL_LOGDB("Contrast set %s", valstr);
                mParameters.set(TICameraParameters::KEY_CONTRAST, valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid Contrast  = %s", valstr);
                ret = -EINVAL;
            }
        }

        if ((valstr =params.get(TICameraParameters::KEY_SHARPNESS)) != NULL) {
            if (params.getInt(TICameraParameters::KEY_SHARPNESS) >= 0 ) {
                CAMHAL_LOGDB("Sharpness set %s", valstr);
                mParameters.set(TICameraParameters::KEY_SHARPNESS, valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid Sharpness = %s", valstr);
                ret = -EINVAL;
            }
        }

        if ((valstr = params.get(TICameraParameters::KEY_SATURATION)) != NULL) {
            if (params.getInt(TICameraParameters::KEY_SATURATION) >= 0 ) {
                CAMHAL_LOGDB("Saturation set %s", valstr);
                mParameters.set(TICameraParameters::KEY_SATURATION, valstr);
             } else {
                CAMHAL_LOGEB("ERROR: Invalid Saturation = %s", valstr);
                ret = -EINVAL;
            }
        }

        if ((valstr = params.get(TICameraParameters::KEY_BRIGHTNESS)) != NULL) {
            if (params.getInt(TICameraParameters::KEY_BRIGHTNESS) >= 0 ) {
                CAMHAL_LOGDB("Brightness set %s", valstr);
                mParameters.set(TICameraParameters::KEY_BRIGHTNESS, valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid Brightness = %s", valstr);
                ret = -EINVAL;
            }
         }

        if ((valstr = params.get(CameraParameters::KEY_ANTIBANDING)) != NULL) {
            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING))) {
                CAMHAL_LOGDB("Antibanding set %s", valstr);
                mParameters.set(CameraParameters::KEY_ANTIBANDING, valstr);
             } else {
                CAMHAL_LOGEB("ERROR: Invalid Antibanding = %s", valstr);
                ret = -EINVAL;
             }
         }

        if ((valstr = params.get(TICameraParameters::KEY_ISO)) != NULL) {
            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES))) {
                CAMHAL_LOGDB("ISO set %s", valstr);
                mParameters.set(TICameraParameters::KEY_ISO, valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid ISO = %s", valstr);
                ret = -EINVAL;
            }
        }

        if( (valstr = params.get(CameraParameters::KEY_FOCUS_AREAS)) != NULL )
            {
            CAMHAL_LOGI("Focus areas position set %s", params.get(CameraParameters::KEY_FOCUS_AREAS));
            mParameters.set(CameraParameters::KEY_FOCUS_AREAS, valstr);
            }

        if( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL )
            {
            CAMHAL_LOGDB("Measurements set to %s", params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE));
            mParameters.set(TICameraParameters::KEY_MEASUREMENT_ENABLE, valstr);

            if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_ENABLE) == 0)
                {
                mMeasurementEnabled = true;
                }
            else if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_DISABLE) == 0)
                {
                mMeasurementEnabled = false;
                }
            else
                {
                mMeasurementEnabled = false;
                }

            }

        if( (valstr = params.get(CameraParameters::KEY_EXPOSURE_COMPENSATION)) != NULL)
            {
            CAMHAL_LOGDB("Exposure compensation set %s", params.get(CameraParameters::KEY_EXPOSURE_COMPENSATION));
            mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, valstr);
            }

        if ((valstr = params.get(CameraParameters::KEY_SCENE_MODE)) != NULL) {
            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES))) {
                CAMHAL_LOGDB("Scene mode set %s", valstr);
                doesSetParameterNeedUpdate(valstr,
                                           mParameters.get(CameraParameters::KEY_SCENE_MODE),
                                           updateRequired);
                mParameters.set(CameraParameters::KEY_SCENE_MODE, valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid Scene mode = %s", valstr);
                ret = -EINVAL;
            }
        }

        if ((valstr = params.get(CameraParameters::KEY_FLASH_MODE)) != NULL) {
            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES))) {
                CAMHAL_LOGDB("Flash mode set %s", valstr);
                mParameters.set(CameraParameters::KEY_FLASH_MODE, valstr);
            } else {
                CAMHAL_LOGEB("ERROR: Invalid Flash mode = %s", valstr);
                ret = -EINVAL;
            }
        }

        if ((valstr = params.get(CameraParameters::KEY_EFFECT)) != NULL) {
            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS))) {
                CAMHAL_LOGDB("Effect set %s", valstr);
                mParameters.set(CameraParameters::KEY_EFFECT, valstr);
             } else {
                CAMHAL_LOGEB("ERROR: Invalid Effect = %s", valstr);
                ret = -EINVAL;
             }
        }

        if(( (valstr = params.get(CameraParameters::KEY_ROTATION)) != NULL)
            && (params.getInt(CameraParameters::KEY_ROTATION) >=0))
            {
            CAMHAL_LOGDB("Rotation set %s", params.get(CameraParameters::KEY_ROTATION));
            mParameters.set(CameraParameters::KEY_ROTATION, valstr);
            }

        if(( (valstr = params.get(CameraParameters::KEY_JPEG_QUALITY)) != NULL)
            && (params.getInt(CameraParameters::KEY_JPEG_QUALITY) >=0))
            {
            CAMHAL_LOGDB("Jpeg quality set %s", params.get(CameraParameters::KEY_JPEG_QUALITY));
            mParameters.set(CameraParameters::KEY_JPEG_QUALITY, valstr);
            }

        if(( (valstr = params.get(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH)) != NULL)
            && (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH) >=0))
            {
            CAMHAL_LOGDB("Thumbnail width set %s", params.get(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH));
            mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, valstr);
            }

        if(( (valstr = params.get(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT)) != NULL)
            && (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT) >=0))
            {
            CAMHAL_LOGDB("Thumbnail width set %s", params.get(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT));
            mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, valstr);
            }

        if(( (valstr = params.get(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY)) != NULL )
            && (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY) >=0))
            {
            CAMHAL_LOGDB("Thumbnail quality set %s", params.get(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY));
            mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, valstr);
            }

        if( (valstr = params.get(CameraParameters::KEY_GPS_LATITUDE)) != NULL )
            {
            CAMHAL_LOGDB("GPS latitude set %s", params.get(CameraParameters::KEY_GPS_LATITUDE));
            mParameters.set(CameraParameters::KEY_GPS_LATITUDE, valstr);
            }else{
                mParameters.remove(CameraParameters::KEY_GPS_LATITUDE);
            }

        if( (valstr = params.get(CameraParameters::KEY_GPS_LONGITUDE)) != NULL )
            {
            CAMHAL_LOGDB("GPS longitude set %s", params.get(CameraParameters::KEY_GPS_LONGITUDE));
            mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, valstr);
            }else{
                mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE);
            }

        if( (valstr = params.get(CameraParameters::KEY_GPS_ALTITUDE)) != NULL )
            {
            CAMHAL_LOGDB("GPS altitude set %s", params.get(CameraParameters::KEY_GPS_ALTITUDE));
            mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, valstr);
            }else{
                mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE);
            }

        if( (valstr = params.get(CameraParameters::KEY_GPS_TIMESTAMP)) != NULL )
            {
            CAMHAL_LOGDB("GPS timestamp set %s", params.get(CameraParameters::KEY_GPS_TIMESTAMP));
            mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, valstr);
            }else{
                mParameters.remove(CameraParameters::KEY_GPS_TIMESTAMP);
            }

        if( (valstr = params.get(TICameraParameters::KEY_GPS_DATESTAMP)) != NULL )
            {
            CAMHAL_LOGDB("GPS datestamp set %s", params.get(TICameraParameters::KEY_GPS_DATESTAMP));
            mParameters.set(TICameraParameters::KEY_GPS_DATESTAMP, valstr);
            }else{
                mParameters.remove(TICameraParameters::KEY_GPS_DATESTAMP);
            }

        if( (valstr = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD)) != NULL )
            {
            CAMHAL_LOGDB("GPS processing method set %s", params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD));
            mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, valstr);
            }else{
                mParameters.remove(CameraParameters::KEY_GPS_PROCESSING_METHOD);
            }

        if( (valstr = params.get(TICameraParameters::KEY_GPS_MAPDATUM )) != NULL )
            {
            CAMHAL_LOGDB("GPS MAPDATUM set %s", params.get(TICameraParameters::KEY_GPS_MAPDATUM));
            mParameters.set(TICameraParameters::KEY_GPS_MAPDATUM, valstr);
            }else{
                mParameters.remove(TICameraParameters::KEY_GPS_MAPDATUM);
            }

        if( (valstr = params.get(TICameraParameters::KEY_GPS_VERSION)) != NULL )
            {
            CAMHAL_LOGDB("GPS MAPDATUM set %s", params.get(TICameraParameters::KEY_GPS_VERSION));
            mParameters.set(TICameraParameters::KEY_GPS_VERSION, valstr);
            }else{
                mParameters.remove(TICameraParameters::KEY_GPS_VERSION);
            }

        if( (valstr = params.get(TICameraParameters::KEY_EXIF_MODEL)) != NULL )
            {
            CAMHAL_LOGDB("EXIF Model set %s", params.get(TICameraParameters::KEY_EXIF_MODEL));
            mParameters.set(TICameraParameters::KEY_EXIF_MODEL, valstr);
            }

        if( (valstr = params.get(TICameraParameters::KEY_EXIF_MAKE)) != NULL )
            {
            CAMHAL_LOGDB("EXIF Make set %s", params.get(TICameraParameters::KEY_EXIF_MAKE));
            mParameters.set(TICameraParameters::KEY_EXIF_MAKE, valstr);
            }

        if( (valstr = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE)) != NULL )
            {
            CAMHAL_LOGDB("Exposure Bracketing set %s", params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE));
            mParameters.set(TICameraParameters::KEY_EXP_BRACKETING_RANGE, valstr);
            }
        else
            {
            mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
            }

        if ((valstr = params.get(CameraParameters::KEY_ZOOM)) != NULL ) {
            if ((params.getInt(CameraParameters::KEY_ZOOM) >= 0 ) &&
                (params.getInt(CameraParameters::KEY_ZOOM) <= mMaxZoomSupported )) {
                CAMHAL_LOGDB("Zoom set %s", valstr);
                doesSetParameterNeedUpdate(valstr,
                                           mParameters.get(CameraParameters::KEY_ZOOM),
                                           updateRequired);
                mParameters.set(CameraParameters::KEY_ZOOM, valstr);
             } else {
                CAMHAL_LOGEB("ERROR: Invalid Zoom: %s", valstr);
                ret = -EINVAL;
            }
        }

        if( (valstr = params.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK)) != NULL )
          {
            CAMHAL_LOGDB("Auto Exposure Lock set %s", params.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
            doesSetParameterNeedUpdate(valstr,
                                       mParameters.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK),
                                       updateRequired);
            mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, valstr);
          }

        if( (valstr = params.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)) != NULL )
          {
            CAMHAL_LOGDB("Auto WhiteBalance Lock set %s", params.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
            doesSetParameterNeedUpdate(valstr,
                                       mParameters.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK),
                                       updateRequired);
            mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, valstr);
          }
        if( (valstr = params.get(CameraParameters::KEY_METERING_AREAS)) != NULL )
            {
            CAMHAL_LOGI("Metering areas position set %s", params.get(CameraParameters::KEY_METERING_AREAS));
            mParameters.set(CameraParameters::KEY_METERING_AREAS, valstr);
            }

        CameraParameters adapterParams = mParameters;

        // Only send parameters to adapter if preview is already
        // enabled or doesSetParameterNeedUpdate says so. Initial setParameters to camera adapter,
        // will be called in startPreview()
        // TODO(XXX): Need to identify other parameters that need update from camera adapter
        if ( (NULL != mCameraAdapter) && (mPreviewEnabled || updateRequired) ) {
            ret |= mCameraAdapter->setParameters(adapterParams);
        }

        if( NULL != params.get(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_POS) )
            {
            int posBracketRange = params.getInt(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_POS);
            if ( 0 < posBracketRange )
                {
                mBracketRangePositive = posBracketRange;
                }
            }
        CAMHAL_LOGDB("Positive bracketing range %d", mBracketRangePositive);


        if( NULL != params.get(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_NEG) )
            {
            int negBracketRange = params.getInt(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_NEG);
            if ( 0 < negBracketRange )
                {
                mBracketRangeNegative = negBracketRange;
                }
            }
        CAMHAL_LOGDB("Negative bracketing range %d", mBracketRangeNegative);

        if( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL) &&
            ( strcmp(valstr, TICameraParameters::BRACKET_ENABLE) == 0 ))
            {
            if ( !mBracketingEnabled )
                {
                CAMHAL_LOGDA("Enabling bracketing");
                mBracketingEnabled = true;

                //Wait for AF events to enable bracketing
                if ( NULL != mCameraAdapter )
                    {
                    setEventProvider( CameraHalEvent::ALL_EVENTS, mCameraAdapter );
                    }
                }
            else
                {
                CAMHAL_LOGDA("Bracketing already enabled");
                }
            }
        else if ( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL ) &&
            ( strcmp(valstr, TICameraParameters::BRACKET_DISABLE) == 0 ))
            {
            CAMHAL_LOGDA("Disabling bracketing");

            mBracketingEnabled = false;
            stopImageBracketing();

            //Remove AF events subscription
            if ( NULL != mEventProvider )
                {
                mEventProvider->disableEventNotification( CameraHalEvent::ALL_EVENTS );
                delete mEventProvider;
                mEventProvider = NULL;
                }

            }

        if( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
            ( strcmp(valstr, TICameraParameters::SHUTTER_ENABLE) == 0 ))
            {
            CAMHAL_LOGDA("Enabling shutter sound");

            mShutterEnabled = true;
            mMsgEnabled |= CAMERA_MSG_SHUTTER;
            mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
            }
        else if ( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
            ( strcmp(valstr, TICameraParameters::SHUTTER_DISABLE) == 0 ))
            {
            CAMHAL_LOGDA("Disabling shutter sound");

            mShutterEnabled = false;
            mMsgEnabled &= ~CAMERA_MSG_SHUTTER;
            mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
            }

    }

    //On fail restore old parameters
    if ( NO_ERROR != ret ) {
        mParameters.unflatten(oldParams.flatten());
    }

    // Restart Preview if needed by KEY_RECODING_HINT only if preview is already running.
    // If preview is not started yet, Video Mode parameters will take effect on next startPreview()
    if (restartPreviewRequired && previewEnabled() && !mRecordingEnabled) {
        CAMHAL_LOGDA("Restarting Preview");
        ret = restartPreview();
    } else if (restartPreviewRequired && !previewEnabled() &&
                mDisplayPaused && !mRecordingEnabled) {
        CAMHAL_LOGDA("Stopping Preview");
        forceStopPreview();
    }

    if (ret != NO_ERROR)
        {
        CAMHAL_LOGEA("Failed to restart Preview");
        return ret;
        }

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

status_t CameraHal::allocPreviewBufs(int width, int height, const char* previewFormat,
                                        unsigned int buffercount, unsigned int &max_queueable)
{
    status_t ret = NO_ERROR;

    LOG_FUNCTION_NAME;

    if(mDisplayAdapter.get() == NULL)
    {
        // Memory allocation of preview buffers is now placed in gralloc
        // CameraHal should not allocate preview buffers without DisplayAdapter
        return NO_MEMORY;
    }

    if(!mPreviewBufs)
    {
        ///@todo Pluralise the name of this method to allocateBuffers
        mPreviewLength = 0;
        mPreviewBufs = (int32_t *) mDisplayAdapter->allocateBuffer(width, height,
                                                                    previewFormat,
                                                                    mPreviewLength,
                                                                    buffercount);

	if (NULL == mPreviewBufs ) {
            CAMHAL_LOGEA("Couldn't allocate preview buffers");
            return NO_MEMORY;
         }

        mPreviewOffsets = (uint32_t *) mDisplayAdapter->getOffsets();
        if ( NULL == mPreviewOffsets ) {
            CAMHAL_LOGEA("Buffer mapping failed");
            return BAD_VALUE;
         }

        mPreviewFd = mDisplayAdapter->getFd();
        if ( -1 == mPreviewFd ) {
            CAMHAL_LOGEA("Invalid handle");
            return BAD_VALUE;
          }

        mBufProvider = (BufferProvider*) mDisplayAdapter.get();

        ret = mDisplayAdapter->maxQueueableBuffers(max_queueable);
        if (ret != NO_ERROR) {
            return ret;
         }

    }

    LOG_FUNCTION_NAME_EXIT;

    return ret;

}

status_t CameraHal::freePreviewBufs()
{
    status_t ret = NO_ERROR;
    LOG_FUNCTION_NAME;

    CAMHAL_LOGDB("mPreviewBufs = 0x%x", (unsigned int)mPreviewBufs);
    if(mPreviewBufs)
        {
        ///@todo Pluralise the name of this method to freeBuffers
        ret = mBufProvider->freeBuffer(mPreviewBufs);
        mPreviewBufs = NULL;
        LOG_FUNCTION_NAME_EXIT;
        return ret;
        }
    LOG_FUNCTION_NAME_EXIT;
    return ret;
}


status_t CameraHal::allocPreviewDataBufs(size_t size, size_t bufferCount)
{
    status_t ret = NO_ERROR;
    int bytes;

    LOG_FUNCTION_NAME;

    bytes = size;

    if ( NO_ERROR == ret )
        {
        if( NULL != mPreviewDataBufs )
            {
            ret = freePreviewDataBufs();
            }
        }

    if ( NO_ERROR == ret )
        {
        bytes = ((bytes+4095)/4096)*4096;
        mPreviewDataBufs = (int32_t *)mMemoryManager->allocateBuffer(0, 0, NULL, bytes, bufferCount);

        CAMHAL_LOGDB("Size of Preview data buffer = %d", bytes);
        if( NULL == mPreviewDataBufs )
            {
            CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
            ret = -NO_MEMORY;
            }
        else
            {
            bytes = size;
            }
        }

    if ( NO_ERROR == ret )
        {
        mPreviewDataFd = mMemoryManager->getFd();
        mPreviewDataLength = bytes;
        mPreviewDataOffsets = mMemoryManager->getOffsets();
        }
    else
        {
        mPreviewDataFd = -1;
        mPreviewDataLength = 0;
        mPreviewDataOffsets = NULL;
        }

    LOG_FUNCTION_NAME;

    return ret;
}

status_t CameraHal::freePreviewDataBufs()
{
    status_t ret = NO_ERROR;

    LOG_FUNCTION_NAME;

    if ( NO_ERROR == ret )
        {

        if( NULL != mPreviewDataBufs )
            {

            ///@todo Pluralise the name of this method to freeBuffers
            ret = mMemoryManager->freeBuffer(mPreviewDataBufs);
            mPreviewDataBufs = NULL;

            }
        }

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

status_t CameraHal::allocImageBufs(unsigned int width, unsigned int height, size_t size, const char* previewFormat, unsigned int bufferCount)
{
    status_t ret = NO_ERROR;
    int bytes;

    LOG_FUNCTION_NAME;

    bytes = size;

    // allocate image buffers only if not already allocated
    if(NULL != mImageBufs) {
        return NO_ERROR;
    }

    if ( NO_ERROR == ret )
        {
        bytes = ((bytes+4095)/4096)*4096;
        mImageBufs = (int32_t *)mMemoryManager->allocateBuffer(0, 0, previewFormat, bytes, bufferCount);

        CAMHAL_LOGDB("Size of Image cap buffer = %d", bytes);
        if( NULL == mImageBufs )
            {
            CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
            ret = -NO_MEMORY;
            }
        else
            {
            bytes = size;
            }
        }

    if ( NO_ERROR == ret )
        {
        mImageFd = mMemoryManager->getFd();
        mImageLength = bytes;
        mImageOffsets = mMemoryManager->getOffsets();
        }
    else
        {
        mImageFd = -1;
        mImageLength = 0;
        mImageOffsets = NULL;
        }

    LOG_FUNCTION_NAME;

    return ret;
}

status_t CameraHal::allocVideoBufs(uint32_t width, uint32_t height, uint32_t bufferCount)
{
  status_t ret = NO_ERROR;
  LOG_FUNCTION_NAME;

  if( NULL != mVideoBufs ){
    ret = freeVideoBufs(mVideoBufs);
    mVideoBufs = NULL;
  }

  if ( NO_ERROR == ret ){
    int32_t stride;
    buffer_handle_t *bufsArr = new buffer_handle_t [bufferCount];

    if (bufsArr != NULL){
      for (int i = 0; i< bufferCount; i++){
        GraphicBufferAllocator &GrallocAlloc = GraphicBufferAllocator::get();
        buffer_handle_t buf;
        ret = GrallocAlloc.alloc(width, height, HAL_PIXEL_FORMAT_NV12, CAMHAL_GRALLOC_USAGE, &buf, &stride);
        if (ret != NO_ERROR){
          CAMHAL_LOGEA("Couldn't allocate video buffers using Gralloc");
          ret = -NO_MEMORY;
          for (int j=0; j< i; j++){
            buf = (buffer_handle_t)bufsArr[j];
            CAMHAL_LOGEB("Freeing Gralloc Buffer 0x%x", buf);
            GrallocAlloc.free(buf);
          }
          delete [] bufsArr;
          goto exit;
        }
        bufsArr[i] = buf;
        CAMHAL_LOGVB("*** Gralloc Handle =0x%x ***", buf);
      }

      mVideoBufs = (int32_t *)bufsArr;
    }
    else{
      CAMHAL_LOGEA("Couldn't allocate video buffers ");
      ret = -NO_MEMORY;
    }
  }

 exit:
  LOG_FUNCTION_NAME;

  return ret;
}

void endImageCapture( void *userData)
{
    LOG_FUNCTION_NAME;

    if ( NULL != userData )
        {
        CameraHal *c = reinterpret_cast<CameraHal *>(userData);
        c->signalEndImageCapture();
        }

    LOG_FUNCTION_NAME_EXIT;
}

void releaseImageBuffers(void *userData)
{
    LOG_FUNCTION_NAME;

    if (NULL != userData) {
        CameraHal *c = reinterpret_cast<CameraHal *>(userData);
        c->freeImageBufs();
    }

    LOG_FUNCTION_NAME_EXIT;
}

status_t CameraHal::signalEndImageCapture()
{
    status_t ret = NO_ERROR;
    int w,h;
    CameraParameters adapterParams = mParameters;
    Mutex::Autolock lock(mLock);

    LOG_FUNCTION_NAME;

    if ( mBracketingRunning ) {
        stopImageBracketing();
    } else {
        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
    }

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

status_t CameraHal::freeImageBufs()
{
    status_t ret = NO_ERROR;

    LOG_FUNCTION_NAME;

    if ( NO_ERROR == ret )
        {

        if( NULL != mImageBufs )
            {

            ///@todo Pluralise the name of this method to freeBuffers
            ret = mMemoryManager->freeBuffer(mImageBufs);
            mImageBufs = NULL;

            }
        else
            {
            ret = -EINVAL;
            }

        }

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

status_t CameraHal::freeVideoBufs(void *bufs)
{
  status_t ret = NO_ERROR;

  LOG_FUNCTION_NAME;

  buffer_handle_t *pBuf = (buffer_handle_t*)bufs;
  int count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
  if(pBuf == NULL)
    {
      CAMHAL_LOGEA("NULL pointer passed to freeVideoBuffer");
      LOG_FUNCTION_NAME_EXIT;
      return BAD_VALUE;
    }

  GraphicBufferAllocator &GrallocAlloc = GraphicBufferAllocator::get();

  for(int i = 0; i < count; i++){
    buffer_handle_t ptr = *pBuf++;
    CAMHAL_LOGVB("Free Video Gralloc Handle 0x%x", ptr);
    GrallocAlloc.free(ptr);
  }

  LOG_FUNCTION_NAME_EXIT;

  return ret;
}

/**
   @brief Start preview mode.

   @param none
   @return NO_ERROR Camera switched to VF mode
   @todo Update function header with the different errors that are possible

 */
status_t CameraHal::startPreview()
{

    status_t ret = NO_ERROR;
    CameraAdapter::BuffersDescriptor desc;
    CameraFrame frame;
    const char *valstr = NULL;
    unsigned int required_buffer_count;
    unsigned int max_queueble_buffers;

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
        gettimeofday(&mStartPreview, NULL);
#endif

    LOG_FUNCTION_NAME;

    if ( mPreviewEnabled ){
      CAMHAL_LOGDA("Preview already running");
      LOG_FUNCTION_NAME_EXIT;
      return ALREADY_EXISTS;
    }

    if ( NULL != mCameraAdapter ) {
      ret = mCameraAdapter->setParameters(mParameters);
    }

    if ((mPreviewStartInProgress == false) && (mDisplayPaused == false)){
      ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_RESOLUTION_PREVIEW,( int ) &frame);
      if ( NO_ERROR != ret ){
        CAMHAL_LOGEB("Error: CAMERA_QUERY_RESOLUTION_PREVIEW %d", ret);
        return ret;
      }

      ///Update the current preview width and height
      mPreviewWidth = frame.mWidth;
      mPreviewHeight = frame.mHeight;
      //Update the padded width and height - required for VNF and VSTAB
      mParameters.set(TICameraParameters::KEY_PADDED_WIDTH, mPreviewWidth);
      mParameters.set(TICameraParameters::KEY_PADDED_HEIGHT, mPreviewHeight);

    }

    ///If we don't have the preview callback enabled and display adapter,
    if(!mSetPreviewWindowCalled || (mDisplayAdapter.get() == NULL)){
      CAMHAL_LOGI("Preview not started. Preview in progress flag set");
      mPreviewStartInProgress = true;
      ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_SWITCH_TO_EXECUTING);
      if ( NO_ERROR != ret ){
        CAMHAL_LOGEB("Error: CAMERA_SWITCH_TO_EXECUTING %d", ret);
        return ret;
      }
      return NO_ERROR;
    }

    if( (mDisplayAdapter.get() != NULL) && ( !mPreviewEnabled ) && ( mDisplayPaused ) )
        {
        CAMHAL_LOGDA("Preview is in paused state");

        mDisplayPaused = false;
        mPreviewEnabled = true;
        if ( NO_ERROR == ret )
            {
            ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);

            if ( NO_ERROR != ret )
                {
                CAMHAL_LOGEB("Display adapter resume failed %x", ret);
                }
            }
        //restart preview callbacks
        if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
        {
            mAppCallbackNotifier->enableMsgType (CAMERA_MSG_PREVIEW_FRAME);
        }
        return ret;
        }


    required_buffer_count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));

    ///Allocate the preview buffers
    ret = allocPreviewBufs(mPreviewWidth, mPreviewHeight, mParameters.getPreviewFormat(), required_buffer_count, max_queueble_buffers);

    if ( NO_ERROR != ret )
        {
        CAMHAL_LOGEA("Couldn't allocate buffers for Preview");
        goto error;
        }

    if ( mMeasurementEnabled )
        {

        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA,
                                          ( int ) &frame,
                                          required_buffer_count);
        if ( NO_ERROR != ret )
            {
            return ret;
            }

         ///Allocate the preview data buffers
        ret = allocPreviewDataBufs(frame.mLength, required_buffer_count);
        if ( NO_ERROR != ret ) {
            CAMHAL_LOGEA("Couldn't allocate preview data buffers");
            goto error;
           }

        if ( NO_ERROR == ret )
            {
            desc.mBuffers = mPreviewDataBufs;
            desc.mOffsets = mPreviewDataOffsets;
            desc.mFd = mPreviewDataFd;
            desc.mLength = mPreviewDataLength;
            desc.mCount = ( size_t ) required_buffer_count;
            desc.mMaxQueueable = (size_t) required_buffer_count;

            mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW_DATA,
                                        ( int ) &desc);
            }

        }

    ///Pass the buffers to Camera Adapter
    desc.mBuffers = mPreviewBufs;
    desc.mOffsets = mPreviewOffsets;
    desc.mFd = mPreviewFd;
    desc.mLength = mPreviewLength;
    desc.mCount = ( size_t ) required_buffer_count;
    desc.mMaxQueueable = (size_t) max_queueble_buffers;

    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW,
                                      ( int ) &desc);

    if ( NO_ERROR != ret )
        {
        CAMHAL_LOGEB("Failed to register preview buffers: 0x%x", ret);
        freePreviewBufs();
        return ret;
        }

    mAppCallbackNotifier->startPreviewCallbacks(mParameters, mPreviewBufs, mPreviewOffsets, mPreviewFd, mPreviewLength, required_buffer_count);

    ///Start the callback notifier
    ret = mAppCallbackNotifier->start();

    if( ALREADY_EXISTS == ret )
        {
        //Already running, do nothing
        CAMHAL_LOGDA("AppCallbackNotifier already running");
        ret = NO_ERROR;
        }
    else if ( NO_ERROR == ret ) {
        CAMHAL_LOGDA("Started AppCallbackNotifier..");
        mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);
        }
    else
        {
        CAMHAL_LOGDA("Couldn't start AppCallbackNotifier");
        goto error;
        }

    ///Enable the display adapter if present, actual overlay enable happens when we post the buffer
    if(mDisplayAdapter.get() != NULL)
        {
        CAMHAL_LOGDA("Enabling display");
        bool isS3d = false;
        DisplayAdapter::S3DParameters s3dParams;
        int width, height;
        mParameters.getPreviewSize(&width, &height);
#if 0 //TODO: s3d is not part of bringup...will reenable
        if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D_SUPPORTED)) != NULL) {
            isS3d = (strcmp(valstr, "true") == 0);
        }
        if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D2D_PREVIEW)) != NULL) {
            if (strcmp(valstr, "off") == 0)
                {
                CAMHAL_LOGEA("STEREO 3D->2D PREVIEW MODE IS OFF");
                //TODO: obtain the frame packing configuration from camera or user settings
                //once side by side configuration is supported
                s3dParams.mode = OVERLAY_S3D_MODE_ON;
                s3dParams.framePacking = OVERLAY_S3D_FORMAT_OVERUNDER;
                s3dParams.order = OVERLAY_S3D_ORDER_LF;
                s3dParams.subSampling = OVERLAY_S3D_SS_NONE;
                }
            else
                {
                CAMHAL_LOGEA("STEREO 3D->2D PREVIEW MODE IS ON");
                s3dParams.mode = OVERLAY_S3D_MODE_OFF;
                s3dParams.framePacking = OVERLAY_S3D_FORMAT_OVERUNDER;
                s3dParams.order = OVERLAY_S3D_ORDER_LF;
                s3dParams.subSampling = OVERLAY_S3D_SS_NONE;
                }
        }
#endif //if 0

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

        ret = mDisplayAdapter->enableDisplay(width, height, &mStartPreview, isS3d ? &s3dParams : NULL);

#else

        ret = mDisplayAdapter->enableDisplay(width, height, NULL, isS3d ? &s3dParams : NULL);

#endif

        if ( ret != NO_ERROR )
            {
            CAMHAL_LOGEA("Couldn't enable display");
            goto error;
            }

        }

    ///Send START_PREVIEW command to adapter
    CAMHAL_LOGDA("Starting CameraAdapter preview mode");

    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW);

    if(ret!=NO_ERROR)
        {
        CAMHAL_LOGEA("Couldn't start preview w/ CameraAdapter");
        goto error;
        }
    CAMHAL_LOGDA("Started preview");

    mPreviewEnabled = true;
    mPreviewStartInProgress = false;
    return ret;

    error:

        CAMHAL_LOGEA("Performing cleanup after error");

        //Do all the cleanup
        freePreviewBufs();
        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_PREVIEW);
        if(mDisplayAdapter.get() != NULL)
            {
            mDisplayAdapter->disableDisplay(false);
            }
        mAppCallbackNotifier->stop();
        mPreviewStartInProgress = false;
        mPreviewEnabled = false;
        LOG_FUNCTION_NAME_EXIT;

        return ret;
}

/**
   @brief Sets ANativeWindow object.

   Preview buffers provided to CameraHal via this object. DisplayAdapter will be interfacing with it
   to render buffers to display.

   @param[in] window The ANativeWindow object created by Surface flinger
   @return NO_ERROR If the ANativeWindow object passes validation criteria
   @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios

 */
status_t CameraHal::setPreviewWindow(struct preview_stream_ops *window)
{
    status_t ret = NO_ERROR;
    CameraAdapter::BuffersDescriptor desc;

    LOG_FUNCTION_NAME;
    mSetPreviewWindowCalled = true;

   ///If the Camera service passes a null window, we destroy existing window and free the DisplayAdapter
    if(!window)
    {
        if(mDisplayAdapter.get() != NULL)
        {
            ///NULL window passed, destroy the display adapter if present
            CAMHAL_LOGI("NULL window passed, destroying display adapter");
            mDisplayAdapter.clear();
            ///@remarks If there was a window previously existing, we usually expect another valid window to be passed by the client
            ///@remarks so, we will wait until it passes a valid window to begin the preview again
            mSetPreviewWindowCalled = false;
        }
        CAMHAL_LOGI("NULL ANativeWindow passed to setPreviewWindow");
        return NO_ERROR;
    }else if(mDisplayAdapter.get() == NULL)
    {
        // Need to create the display adapter since it has not been created
        // Create display adapter
        mDisplayAdapter = new ANativeWindowDisplayAdapter();
        ret = NO_ERROR;
        if(!mDisplayAdapter.get() || ((ret=mDisplayAdapter->initialize())!=NO_ERROR))
        {
            if(ret!=NO_ERROR)
            {
                mDisplayAdapter.clear();
                CAMHAL_LOGEA("DisplayAdapter initialize failed");
                LOG_FUNCTION_NAME_EXIT;
                return ret;
            }
            else
            {
                CAMHAL_LOGEA("Couldn't create DisplayAdapter");
                LOG_FUNCTION_NAME_EXIT;
                return NO_MEMORY;
            }
        }

        // DisplayAdapter needs to know where to get the CameraFrames from inorder to display
        // Since CameraAdapter is the one that provides the frames, set it as the frame provider for DisplayAdapter
        mDisplayAdapter->setFrameProvider(mCameraAdapter);

        // Any dynamic errors that happen during the camera use case has to be propagated back to the application
        // via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that  notifies such errors to the application
        // Set it as the error handler for the DisplayAdapter
        mDisplayAdapter->setErrorHandler(mAppCallbackNotifier.get());

        // Update the display adapter with the new window that is passed from CameraService
        ret  = mDisplayAdapter->setPreviewWindow(window);
        if(ret!=NO_ERROR)
            {
            CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
            }

        if(mPreviewStartInProgress)
        {
            CAMHAL_LOGDA("setPreviewWindow called when preview running");
            // Start the preview since the window is now available
            ret = startPreview();
        }
    } else {
        // Update the display adapter with the new window that is passed from CameraService
        ret = mDisplayAdapter->setPreviewWindow(window);
        if ( (NO_ERROR == ret) && previewEnabled() ) {
            restartPreview();
        } else if (ret == ALREADY_EXISTS) {
            // ALREADY_EXISTS should be treated as a noop in this case
            ret = NO_ERROR;
        }
    }
    LOG_FUNCTION_NAME_EXIT;

    return ret;

}


/**
   @brief Stop a previously started preview.

   @param none
   @return none

 */
void CameraHal::stopPreview()
{
    LOG_FUNCTION_NAME;

    if( (!previewEnabled() && !mDisplayPaused) || mRecordingEnabled)
        {
        LOG_FUNCTION_NAME_EXIT;
        return;
        }

    bool imageCaptureRunning = (mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE) &&
                                    (mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE);
    if(mDisplayPaused && !imageCaptureRunning)
        {
        // Display is paused, which essentially means there is no preview active.
        // Note: this is done so that when stopPreview is called by client after
        // an image capture, we do not de-initialize the camera adapter and
        // restart over again.

        return;
        }

    forceStopPreview();

    // Reset Capture-Mode to default, so that when we switch from VideoRecording
    // to ImageCapture, CAPTURE_MODE is not left to VIDEO_MODE.
    CAMHAL_LOGDA("Resetting Capture-Mode to default");
    mParameters.set(TICameraParameters::KEY_CAP_MODE, "");

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Returns true if preview is enabled

   @param none
   @return true If preview is running currently
         false If preview has been stopped

 */
bool CameraHal::previewEnabled()
{
    LOG_FUNCTION_NAME;

    return (mPreviewEnabled || mPreviewStartInProgress);
}

/**
   @brief Start record mode.

  When a record image is available a CAMERA_MSG_VIDEO_FRAME message is sent with
  the corresponding frame. Every record frame must be released by calling
  releaseRecordingFrame().

   @param none
   @return NO_ERROR If recording could be started without any issues
   @todo Update the header with possible error values in failure scenarios

 */
status_t CameraHal::startRecording( )
{
    int w, h;
    const char *valstr = NULL;
    bool restartPreviewRequired = false;
    status_t ret = NO_ERROR;

    LOG_FUNCTION_NAME;


#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

            gettimeofday(&mStartPreview, NULL);

#endif

    if(!previewEnabled())
        {
        return NO_INIT;
        }

    // set internal recording hint in case camera adapter needs to make some
    // decisions....(will only be sent to camera adapter if camera restart is required)
    mParameters.set(TICameraParameters::KEY_RECORDING_HINT, CameraParameters::TRUE);

    // if application starts recording in continuous focus picture mode...
    // then we need to force default capture mode (as opposed to video mode)
    if ( ((valstr = mParameters.get(CameraParameters::KEY_FOCUS_MODE)) != NULL) &&
         (strcmp(valstr, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) == 0) ){
        restartPreviewRequired = resetVideoModeParameters();
    }

    // only need to check recording hint if preview restart is not already needed
    valstr = mParameters.get(CameraParameters::KEY_RECORDING_HINT);
    if ( !restartPreviewRequired &&
         (!valstr || (valstr && (strcmp(valstr, CameraParameters::TRUE) != 0))) ) {
        restartPreviewRequired = setVideoModeParameters(mParameters);
    }

    if (restartPreviewRequired) {
        ret = restartPreview();
    }

    if ( NO_ERROR == ret )
      {
        int count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
        mParameters.getPreviewSize(&w, &h);
        CAMHAL_LOGDB("%s Video Width=%d Height=%d", __FUNCTION__, mVideoWidth, mVideoHeight);

        if ((w != mVideoWidth) && (h != mVideoHeight))
          {
            ret = allocVideoBufs(mVideoWidth, mVideoHeight, count);
            if ( NO_ERROR != ret )
              {
                CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
                mParameters.remove(TICameraParameters::KEY_RECORDING_HINT);
                return ret;
              }

            mAppCallbackNotifier->useVideoBuffers(true);
            mAppCallbackNotifier->setVideoRes(mVideoWidth, mVideoHeight);
            ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBufs, mPreviewOffsets, mPreviewFd, mPreviewLength, count, mVideoBufs);
          }
        else
          {
            mAppCallbackNotifier->useVideoBuffers(false);
            mAppCallbackNotifier->setVideoRes(mPreviewWidth, mPreviewHeight);
            ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBufs, mPreviewOffsets, mPreviewFd, mPreviewLength, count, NULL);
          }
      }

    if ( NO_ERROR == ret )
        {
         ret = mAppCallbackNotifier->startRecording();
        }

    if ( NO_ERROR == ret )
        {
        ///Buffers for video capture (if different from preview) are expected to be allocated within CameraAdapter
         ret =  mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_VIDEO);
        }

    if ( NO_ERROR == ret )
        {
        mRecordingEnabled = true;
        }

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

/**
   @brief Set the camera parameters specific to Video Recording.

   This function checks for the camera parameters which have to be set for recording.
   Video Recording needs CAPTURE_MODE to be VIDEO_MODE. This function sets it.
   This function also enables Video Recording specific functions like VSTAB & VNF.

   @param none
   @return true if preview needs to be restarted for VIDEO_MODE parameters to take effect.
   @todo Modify the policies for enabling VSTAB & VNF usecase based later.

 */
bool CameraHal::setVideoModeParameters(const CameraParameters& params)
{
    const char *valstr = NULL;
    bool restartPreviewRequired = false;
    status_t ret = NO_ERROR;

    LOG_FUNCTION_NAME;

    // Set CAPTURE_MODE to VIDEO_MODE, if not set already and Restart Preview
    valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
    if ( (valstr == NULL) ||
        ( (valstr != NULL) && (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) != 0) ) )
        {
        CAMHAL_LOGDA("Set CAPTURE_MODE to VIDEO_MODE");
        mParameters.set(TICameraParameters::KEY_CAP_MODE, (const char *) TICameraParameters::VIDEO_MODE);
        restartPreviewRequired = true;
        }

    // Check if CAPTURE_MODE is VIDEO_MODE, since VSTAB & VNF work only in VIDEO_MODE.
    valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
    if (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) == 0) {
       // set VSTAB. restart is required if vstab value has changed
       if (params.get(CameraParameters::KEY_VIDEO_STABILIZATION) != NULL) {
            // make sure we support vstab
            if (strcmp(mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED),
                       CameraParameters::TRUE) == 0) {
                valstr = mParameters.get(CameraParameters::KEY_VIDEO_STABILIZATION);
                // vstab value has changed
                if ((valstr != NULL) &&
                     strcmp(valstr, params.get(CameraParameters::KEY_VIDEO_STABILIZATION)) != 0) {
                    restartPreviewRequired = true;
                }
                mParameters.set(CameraParameters::KEY_VIDEO_STABILIZATION,
                                params.get(CameraParameters::KEY_VIDEO_STABILIZATION));
            }
        } else if (mParameters.get(CameraParameters::KEY_VIDEO_STABILIZATION)) {
            // vstab was configured but now unset
            restartPreviewRequired = true;
            mParameters.remove(CameraParameters::KEY_VIDEO_STABILIZATION);
        }

        // Set VNF
        if (params.get(TICameraParameters::KEY_VNF) == NULL) {
            CAMHAL_LOGDA("Enable VNF");
            mParameters.set(TICameraParameters::KEY_VNF, "1");
            restartPreviewRequired = true;
        } else {
            valstr = mParameters.get(TICameraParameters::KEY_VNF);
            if (valstr && strcmp(valstr, params.get(TICameraParameters::KEY_VNF)) != 0) {
                restartPreviewRequired = true;
            }
            mParameters.set(TICameraParameters::KEY_VNF, params.get(TICameraParameters::KEY_VNF));
        }

        // For VSTAB alone for 1080p resolution, padded width goes > 2048, which cannot be rendered by GPU.
        // In such case, there is support in Ducati for combination of VSTAB & VNF requiring padded width < 2048.
        // So we are forcefully enabling VNF, if VSTAB is enabled for 1080p resolution.
        valstr = mParameters.get(CameraParameters::KEY_VIDEO_STABILIZATION);
        if (valstr && (strcmp(valstr, CameraParameters::TRUE) == 0) && (mPreviewWidth == 1920)) {
            CAMHAL_LOGDA("Force Enable VNF for 1080p");
            mParameters.set(TICameraParameters::KEY_VNF, "1");
            restartPreviewRequired = true;
        }
    }
    LOG_FUNCTION_NAME_EXIT;

    return restartPreviewRequired;
}

/**
   @brief Reset the camera parameters specific to Video Recording.

   This function resets CAPTURE_MODE and disables Recording specific functions like VSTAB & VNF.

   @param none
   @return true if preview needs to be restarted for VIDEO_MODE parameters to take effect.

 */
bool CameraHal::resetVideoModeParameters()
{
    const char *valstr = NULL;
    bool restartPreviewRequired = false;
    status_t ret = NO_ERROR;

    LOG_FUNCTION_NAME;

    // ignore this if we are already recording
    if (mRecordingEnabled) {
        return false;
    }

    // Set CAPTURE_MODE to VIDEO_MODE, if not set already and Restart Preview
    valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
    if ((valstr != NULL) && (strcmp(valstr, TICameraParameters::VIDEO_MODE) == 0)) {
        CAMHAL_LOGDA("Reset Capture-Mode to default");
        mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
        restartPreviewRequired = true;
    }

    LOG_FUNCTION_NAME_EXIT;

    return restartPreviewRequired;
}

/**
   @brief Restart the preview with setParameter.

   This function restarts preview, for some VIDEO_MODE parameters to take effect.

   @param none
   @return NO_ERROR If recording parameters could be set without any issues

 */
status_t CameraHal::restartPreview()
{
    const char *valstr = NULL;
    char tmpvalstr[30];
    status_t ret = NO_ERROR;

    LOG_FUNCTION_NAME;

    // Retain CAPTURE_MODE before calling stopPreview(), since it is reset in stopPreview().
    tmpvalstr[0] = 0;
    valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
    if(valstr != NULL)
        {
        if(sizeof(tmpvalstr) < (strlen(valstr)+1))
            {
            return -EINVAL;
            }

        strncpy(tmpvalstr, valstr, sizeof(tmpvalstr));
        tmpvalstr[sizeof(tmpvalstr)-1] = 0;
        }

    forceStopPreview();

    {
        Mutex::Autolock lock(mLock);
        mParameters.set(TICameraParameters::KEY_CAP_MODE, tmpvalstr);
        mCameraAdapter->setParameters(mParameters);
    }

    ret = startPreview();

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

/**
   @brief Stop a previously started recording.

   @param none
   @return none

 */
void CameraHal::stopRecording()
{
    CameraAdapter::AdapterState currentState;

    LOG_FUNCTION_NAME;

    Mutex::Autolock lock(mLock);

    if (!mRecordingEnabled )
        {
        return;
        }

    currentState = mCameraAdapter->getState();
    if (currentState == CameraAdapter::VIDEO_CAPTURE_STATE) {
        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
    }

    mAppCallbackNotifier->stopRecording();

    mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_VIDEO);

    mRecordingEnabled = false;

    if ( mAppCallbackNotifier->getUesVideoBuffers() ){
      freeVideoBufs(mVideoBufs);
      if (mVideoBufs){
        CAMHAL_LOGVB(" FREEING mVideoBufs 0x%x", mVideoBufs);
        delete [] mVideoBufs;
      }
      mVideoBufs = NULL;
    }

    // reset internal recording hint in case camera adapter needs to make some
    // decisions....(will only be sent to camera adapter if camera restart is required)
    mParameters.remove(TICameraParameters::KEY_RECORDING_HINT);

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Returns true if recording is enabled.

   @param none
   @return true If recording is currently running
         false If recording has been stopped

 */
int CameraHal::recordingEnabled()
{
    LOG_FUNCTION_NAME;

    LOG_FUNCTION_NAME_EXIT;

    return mRecordingEnabled;
}

/**
   @brief Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.

   @param[in] mem MemoryBase pointer to the frame being released. Must be one of the buffers
               previously given by CameraHal
   @return none

 */
void CameraHal::releaseRecordingFrame(const void* mem)
{
    LOG_FUNCTION_NAME;

    //CAMHAL_LOGDB(" 0x%x", mem->pointer());

    if ( ( mRecordingEnabled ) && mem != NULL)
    {
        mAppCallbackNotifier->releaseRecordingFrame(mem);
    }

    LOG_FUNCTION_NAME_EXIT;

    return;
}

/**
   @brief Start auto focus

   This call asynchronous.
   The notification callback routine is called with CAMERA_MSG_FOCUS once when
   focusing is complete. autoFocus() will be called again if another auto focus is
   needed.

   @param none
   @return NO_ERROR
   @todo Define the error codes if the focus is not locked

 */
status_t CameraHal::autoFocus()
{
    status_t ret = NO_ERROR;

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

    gettimeofday(&mStartFocus, NULL);

#endif

    LOG_FUNCTION_NAME;

    Mutex::Autolock lock(mLock);

    mMsgEnabled |= CAMERA_MSG_FOCUS;

    if ( NULL == mCameraAdapter )
        {
            ret = -1;
            goto EXIT;
        }

    CameraAdapter::AdapterState state;
    ret = mCameraAdapter->getState(state);
    if (ret != NO_ERROR)
        {
            goto EXIT;
        }

    if (state == CameraAdapter::AF_STATE)
        {
            CAMHAL_LOGI("Ignoring start-AF (already in progress)");
            goto EXIT;
        }

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

    //pass the autoFocus timestamp along with the command to camera adapter
    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_PERFORM_AUTOFOCUS, ( int ) &mStartFocus);

#else

    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_PERFORM_AUTOFOCUS);

#endif

EXIT:
    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

/**
   @brief Cancels auto-focus function.

   If the auto-focus is still in progress, this function will cancel it.
   Whether the auto-focus is in progress or not, this function will return the
   focus position to the default. If the camera does not support auto-focus, this is a no-op.


   @param none
   @return NO_ERROR If the cancel succeeded
   @todo Define error codes if cancel didnt succeed

 */
status_t CameraHal::cancelAutoFocus()
{
    LOG_FUNCTION_NAME;

    Mutex::Autolock lock(mLock);
    CameraParameters adapterParams = mParameters;
    mMsgEnabled &= ~CAMERA_MSG_FOCUS;

    if( NULL != mCameraAdapter )
    {
        adapterParams.set(TICameraParameters::KEY_AUTO_FOCUS_LOCK, CameraParameters::FALSE);
        mCameraAdapter->setParameters(adapterParams);
        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_CANCEL_AUTOFOCUS);
        mAppCallbackNotifier->flushEventQueue();
    }

    LOG_FUNCTION_NAME_EXIT;
    return NO_ERROR;
}

void CameraHal::setEventProvider(int32_t eventMask, MessageNotifier * eventNotifier)
{

    LOG_FUNCTION_NAME;

    if ( NULL != mEventProvider )
        {
        mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
        delete mEventProvider;
        mEventProvider = NULL;
        }

    mEventProvider = new EventProvider(eventNotifier, this, eventCallbackRelay);
    if ( NULL == mEventProvider )
        {
        CAMHAL_LOGEA("Error in creating EventProvider");
        }
    else
        {
        mEventProvider->enableEventNotification(eventMask);
        }

    LOG_FUNCTION_NAME_EXIT;
}

void CameraHal::eventCallbackRelay(CameraHalEvent* event)
{
    LOG_FUNCTION_NAME;

    CameraHal *appcbn = ( CameraHal * ) (event->mCookie);
    appcbn->eventCallback(event );

    LOG_FUNCTION_NAME_EXIT;
}

void CameraHal::eventCallback(CameraHalEvent* event)
{
    LOG_FUNCTION_NAME;

    if ( NULL != event )
        {
        switch( event->mEventType )
            {
            case CameraHalEvent::EVENT_FOCUS_LOCKED:
            case CameraHalEvent::EVENT_FOCUS_ERROR:
                {
                if ( mBracketingEnabled )
                    {
                    startImageBracketing();
                    }
                break;
                }
            default:
                {
                break;
                }
            };
        }

    LOG_FUNCTION_NAME_EXIT;
}

status_t CameraHal::startImageBracketing()
{
        status_t ret = NO_ERROR;
        CameraFrame frame;
        CameraAdapter::BuffersDescriptor desc;

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

        gettimeofday(&mStartCapture, NULL);

#endif

        LOG_FUNCTION_NAME;

        if(!previewEnabled() && !mDisplayPaused)
            {
            LOG_FUNCTION_NAME_EXIT;
            return NO_INIT;
            }

        if ( !mBracketingEnabled )
            {
            return ret;
            }

        if ( NO_ERROR == ret )
            {
            mBracketingRunning = true;
            }

        if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
            {
            ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
                                              ( int ) &frame,
                                              ( mBracketRangeNegative + 1 ));

            if ( NO_ERROR != ret )
                {
                CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
                }
            }

        if ( NO_ERROR == ret )
            {
            if ( NULL != mAppCallbackNotifier.get() )
                 {
                 mAppCallbackNotifier->setBurst(true);
                 }
            }

        if ( NO_ERROR == ret )
            {
            mParameters.getPictureSize(( int * ) &frame.mWidth,
                                       ( int * ) &frame.mHeight);

            ret = allocImageBufs(frame.mWidth,
                                 frame.mHeight,
                                 frame.mLength,
                                 mParameters.getPictureFormat(),
                                 ( mBracketRangeNegative + 1 ));
            if ( NO_ERROR != ret )
              {
                CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
              }
            }

        if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
            {

            desc.mBuffers = mImageBufs;
            desc.mOffsets = mImageOffsets;
            desc.mFd = mImageFd;
            desc.mLength = mImageLength;
            desc.mCount = ( size_t ) ( mBracketRangeNegative + 1 );
            desc.mMaxQueueable = ( size_t ) ( mBracketRangeNegative + 1 );

            ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
                                              ( int ) &desc);

            if ( NO_ERROR == ret )
                {

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

                 //pass capture timestamp along with the camera adapter command
                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_BRACKET_CAPTURE,  ( mBracketRangePositive + 1 ),  (int) &mStartCapture);

#else

                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_BRACKET_CAPTURE, ( mBracketRangePositive + 1 ));

#endif

                }
            }

        return ret;
}

status_t CameraHal::stopImageBracketing()
{
        status_t ret = NO_ERROR;

        LOG_FUNCTION_NAME;

        if( !previewEnabled() )
            {
            return NO_INIT;
            }

        mBracketingRunning = false;

        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_BRACKET_CAPTURE);

        LOG_FUNCTION_NAME_EXIT;

        return ret;
}

/**
   @brief Take a picture.

   @param none
   @return NO_ERROR If able to switch to image capture
   @todo Define error codes if unable to switch to image capture

 */
status_t CameraHal::takePicture( )
{
    status_t ret = NO_ERROR;
    CameraFrame frame;
    CameraAdapter::BuffersDescriptor desc;
    int burst;
    const char *valstr = NULL;
    unsigned int bufferCount = 1;

    Mutex::Autolock lock(mLock);

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

    gettimeofday(&mStartCapture, NULL);

#endif

    LOG_FUNCTION_NAME;

    if(!previewEnabled() && !mDisplayPaused)
        {
        LOG_FUNCTION_NAME_EXIT;
        CAMHAL_LOGEA("Preview not started...");
        return NO_INIT;
        }

    // return error if we are already capturing
    if ( (mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE &&
          mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) ||
         (mCameraAdapter->getState() == CameraAdapter::VIDEO_CAPTURE_STATE &&
          mCameraAdapter->getNextState() != CameraAdapter::VIDEO_STATE) ) {
        CAMHAL_LOGEA("Already capturing an image...");
        return NO_INIT;
    }

    // we only support video snapshot if we are in video mode (recording hint is set)
    valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
    if ( (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE) &&
         (valstr && strcmp(valstr, TICameraParameters::VIDEO_MODE)) ) {
        CAMHAL_LOGEA("Trying to capture while recording without recording hint set...");
        return INVALID_OPERATION;
    }

    if ( !mBracketingRunning )
        {

         if ( NO_ERROR == ret )
            {
            burst = mParameters.getInt(TICameraParameters::KEY_BURST);
            }

         //Allocate all buffers only in burst capture case
         if ( burst > 1 )
             {
             bufferCount = CameraHal::NO_BUFFERS_IMAGE_CAPTURE;
             if ( NULL != mAppCallbackNotifier.get() )
                 {
                 mAppCallbackNotifier->setBurst(true);
                 }
             }
         else
             {
             if ( NULL != mAppCallbackNotifier.get() )
                 {
                 mAppCallbackNotifier->setBurst(false);
                 }
             }

        // pause preview during normal image capture
        // do not pause preview if recording (video state)
        if (NO_ERROR == ret &&
                NULL != mDisplayAdapter.get() &&
                burst < 1) {
            if (mCameraAdapter->getState() != CameraAdapter::VIDEO_STATE) {
                mDisplayPaused = true;
                mPreviewEnabled = false;
                ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
                // since preview is paused we should stop sending preview frames too
                if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
                    mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME);
                }
            }

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
            mDisplayAdapter->setSnapshotTimeRef(&mStartCapture);
#endif
        }

        // if we taking video snapshot...
        if ((NO_ERROR == ret) && (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE)) {
            // enable post view frames if not already enabled so we can internally
            // save snapshot frames for generating thumbnail
            if((mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME) == 0) {
                mAppCallbackNotifier->enableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
            }
        }

        if ( (NO_ERROR == ret) && (NULL != mCameraAdapter) )
            {
            if ( NO_ERROR == ret )
                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
                                                  ( int ) &frame,
                                                  bufferCount);

            if ( NO_ERROR != ret )
                {
                CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
                }
            }

        if ( NO_ERROR == ret )
            {
            mParameters.getPictureSize(( int * ) &frame.mWidth,
                                       ( int * ) &frame.mHeight);

            ret = allocImageBufs(frame.mWidth,
                                 frame.mHeight,
                                 frame.mLength,
                                 mParameters.getPictureFormat(),
                                 bufferCount);
            if ( NO_ERROR != ret )
                {
                CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
                }
            }

        if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
            {
            desc.mBuffers = mImageBufs;
            desc.mOffsets = mImageOffsets;
            desc.mFd = mImageFd;
            desc.mLength = mImageLength;
            desc.mCount = ( size_t ) bufferCount;
            desc.mMaxQueueable = ( size_t ) bufferCount;

            ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
                                              ( int ) &desc);
            }
        }

    if ( ( NO_ERROR == ret ) && ( NULL != mCameraAdapter ) )
        {

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

         //pass capture timestamp along with the camera adapter command
        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE,  (int) &mStartCapture);

#else

        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE);

#endif

        }

    return ret;
}

/**
   @brief Cancel a picture that was started with takePicture.

   Calling this method when no picture is being taken is a no-op.

   @param none
   @return NO_ERROR If cancel succeeded. Cancel can succeed if image callback is not sent
   @todo Define error codes

 */
status_t CameraHal::cancelPicture( )
{
    LOG_FUNCTION_NAME;

    Mutex::Autolock lock(mLock);

    mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);

    return NO_ERROR;
}

/**
   @brief Return the camera parameters.

   @param none
   @return Currently configured camera parameters

 */
char* CameraHal::getParameters()
{
    String8 params_str8;
    char* params_string;
    const char * valstr = NULL;

    LOG_FUNCTION_NAME;

    if( NULL != mCameraAdapter )
    {
        mCameraAdapter->getParameters(mParameters);
    }

    CameraParameters mParams = mParameters;

    // Handle RECORDING_HINT to Set/Reset Video Mode Parameters
    valstr = mParameters.get(CameraParameters::KEY_RECORDING_HINT);
    if(valstr != NULL)
      {
        if(strcmp(valstr, CameraParameters::TRUE) == 0)
          {
            //HACK FOR MMS MODE
            resetPreviewRes(&mParams, mVideoWidth, mVideoHeight);
          }
      }

    // do not send internal parameters to upper layers
    mParams.remove(TICameraParameters::KEY_RECORDING_HINT);
    mParams.remove(TICameraParameters::KEY_AUTO_FOCUS_LOCK);

    params_str8 = mParams.flatten();

    // camera service frees this string...
    params_string = (char*) malloc(sizeof(char) * (params_str8.length()+1));
    strcpy(params_string, params_str8.string());

    LOG_FUNCTION_NAME_EXIT;

    ///Return the current set of parameters

    return params_string;
}

void CameraHal::putParameters(char *parms)
{
    free(parms);
}

/**
   @brief Send command to camera driver.

   @param none
   @return NO_ERROR If the command succeeds
   @todo Define the error codes that this function can return

 */
status_t CameraHal::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
{
    status_t ret = NO_ERROR;

    LOG_FUNCTION_NAME;


    if ( ( NO_ERROR == ret ) && ( NULL == mCameraAdapter ) )
        {
        CAMHAL_LOGEA("No CameraAdapter instance");
        ret = -EINVAL;
        }

    if ( ( NO_ERROR == ret ) && ( !previewEnabled() ))
        {
        CAMHAL_LOGEA("Preview is not running");
        ret = -EINVAL;
        }

    if ( NO_ERROR == ret )
        {
        switch(cmd)
            {
            case CAMERA_CMD_START_SMOOTH_ZOOM:

                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_SMOOTH_ZOOM, arg1);

                break;
            case CAMERA_CMD_STOP_SMOOTH_ZOOM:

                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_SMOOTH_ZOOM);

            case CAMERA_CMD_START_FACE_DETECTION:

                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_FD);

                break;

            case CAMERA_CMD_STOP_FACE_DETECTION:

                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);

                break;

            default:
                break;
            };
        }

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

/**
   @brief Release the hardware resources owned by this object.

   Note that this is *not* done in the destructor.

   @param none
   @return none

 */
void CameraHal::release()
{
    LOG_FUNCTION_NAME;
    ///@todo Investigate on how release is used by CameraService. Vaguely remember that this is called
    ///just before CameraHal object destruction
    deinitialize();
    LOG_FUNCTION_NAME_EXIT;
}


/**
   @brief Dump state of the camera hardware

   @param[in] fd    File descriptor
   @param[in] args  Arguments
   @return NO_ERROR Dump succeeded
   @todo  Error codes for dump fail

 */
status_t  CameraHal::dump(int fd) const
{
    LOG_FUNCTION_NAME;
    ///Implement this method when the h/w dump function is supported on Ducati side
    return NO_ERROR;
}

/*-------------Camera Hal Interface Method definitions ENDS here--------------------*/




/*-------------Camera Hal Internal Method definitions STARTS here--------------------*/

/**
   @brief Constructor of CameraHal

   Member variables are initialized here.  No allocations should be done here as we
   don't use c++ exceptions in the code.

 */
CameraHal::CameraHal(int cameraId)
{
    LOG_FUNCTION_NAME;

    ///Initialize all the member variables to their defaults
    mPreviewEnabled = false;
    mPreviewBufs = NULL;
    mImageBufs = NULL;
    mBufProvider = NULL;
    mPreviewStartInProgress = false;
    mVideoBufs = NULL;
    mVideoBufProvider = NULL;
    mRecordingEnabled = false;
    mDisplayPaused = false;
    mSetPreviewWindowCalled = false;
    mMsgEnabled = 0;
    mAppCallbackNotifier = NULL;
    mMemoryManager = NULL;
    mCameraAdapter = NULL;
    mBracketingEnabled = false;
    mBracketingRunning = false;
    mEventProvider = NULL;
    mBracketRangePositive = 1;
    mBracketRangeNegative = 1;
    mMaxZoomSupported = 0;
    mShutterEnabled = true;
    mMeasurementEnabled = false;
    mPreviewDataBufs = NULL;
    mCameraProperties = NULL;
    mCurrentTime = 0;
    mFalsePreview = 0;
    mImageOffsets = NULL;
    mImageLength = 0;
    mImageFd = 0;
    mVideoOffsets = NULL;
    mVideoFd = 0;
    mVideoLength = 0;
    mPreviewDataOffsets = NULL;
    mPreviewDataFd = 0;
    mPreviewDataLength = 0;
    mPreviewFd = 0;
    mPreviewWidth = 0;
    mPreviewHeight = 0;
    mPreviewLength = 0;
    mPreviewOffsets = NULL;
    mPreviewRunning = 0;
    mPreviewStateOld = 0;
    mRecordingEnabled = 0;
    mRecordEnabled = 0;
    mSensorListener = NULL;
    mVideoWidth = 0;
    mVideoHeight = 0;

#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

    //Initialize the CameraHAL constructor timestamp, which is used in the
    // PPM() method as time reference if the user does not supply one.
    gettimeofday(&ppm_start, NULL);

#endif

    mCameraIndex = cameraId;

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Destructor of CameraHal

   This function simply calls deinitialize() to free up memory allocate during construct
   phase
 */
CameraHal::~CameraHal()
{
    LOG_FUNCTION_NAME;

    ///Call de-initialize here once more - it is the last chance for us to relinquish all the h/w and s/w resources
    deinitialize();

    if ( NULL != mEventProvider )
        {
        mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
        delete mEventProvider;
        mEventProvider = NULL;
        }

    /// Free the callback notifier
    mAppCallbackNotifier.clear();

    /// Free the display adapter
    mDisplayAdapter.clear();

    if ( NULL != mCameraAdapter ) {
        int strongCount = mCameraAdapter->getStrongCount();

        mCameraAdapter->decStrong(mCameraAdapter);

        mCameraAdapter = NULL;
    }

    freeImageBufs();

    /// Free the memory manager
    mMemoryManager.clear();

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Initialize the Camera HAL

   Creates CameraAdapter, AppCallbackNotifier, DisplayAdapter and MemoryManager

   @param None
   @return NO_ERROR - On success
         NO_MEMORY - On failure to allocate memory for any of the objects
   @remarks Camera Hal internal function

 */

status_t CameraHal::initialize(CameraProperties::Properties* properties)
{
    LOG_FUNCTION_NAME;

    int sensor_index = 0;

    ///Initialize the event mask used for registering an event provider for AppCallbackNotifier
    ///Currently, registering all events as to be coming from CameraAdapter
    int32_t eventMask = CameraHalEvent::ALL_EVENTS;

    // Get my camera properties
    mCameraProperties = properties;

    if(!mCameraProperties)
    {
        goto fail_loop;
    }

    // Dump the properties of this Camera
    // will only print if DEBUG macro is defined
    mCameraProperties->dump();

    if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX)) != 0 )
        {
        sensor_index = atoi(mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX));
        }

    CAMHAL_LOGDB("Sensor index %d", sensor_index);

    mCameraAdapter = CameraAdapter_Factory(sensor_index);
    if ( ( NULL == mCameraAdapter ) || (mCameraAdapter->initialize(properties)!=NO_ERROR))
        {
        CAMHAL_LOGEA("Unable to create or initialize CameraAdapter");
        mCameraAdapter = NULL;
        goto fail_loop;
        }

    mCameraAdapter->incStrong(mCameraAdapter);
    mCameraAdapter->registerImageReleaseCallback(releaseImageBuffers, (void *) this);
    mCameraAdapter->registerEndCaptureCallback(endImageCapture, (void *)this);

    if(!mAppCallbackNotifier.get())
        {
        /// Create the callback notifier
        mAppCallbackNotifier = new AppCallbackNotifier();
        if( ( NULL == mAppCallbackNotifier.get() ) || ( mAppCallbackNotifier->initialize() != NO_ERROR))
            {
            CAMHAL_LOGEA("Unable to create or initialize AppCallbackNotifier");
            goto fail_loop;
            }
        }

    if(!mMemoryManager.get())
        {
        /// Create Memory Manager
        mMemoryManager = new MemoryManager();
        if( ( NULL == mMemoryManager.get() ) || ( mMemoryManager->initialize() != NO_ERROR))
            {
            CAMHAL_LOGEA("Unable to create or initialize MemoryManager");
            goto fail_loop;
            }
        }

    ///Setup the class dependencies...

    ///AppCallbackNotifier has to know where to get the Camera frames and the events like auto focus lock etc from.
    ///CameraAdapter is the one which provides those events
    ///Set it as the frame and event providers for AppCallbackNotifier
    ///@remarks  setEventProvider API takes in a bit mask of events for registering a provider for the different events
    ///         That way, if events can come from DisplayAdapter in future, we will be able to add it as provider
    ///         for any event
    mAppCallbackNotifier->setEventProvider(eventMask, mCameraAdapter);
    mAppCallbackNotifier->setFrameProvider(mCameraAdapter);

    ///Any dynamic errors that happen during the camera use case has to be propagated back to the application
    ///via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that  notifies such errors to the application
    ///Set it as the error handler for CameraAdapter
    mCameraAdapter->setErrorHandler(mAppCallbackNotifier.get());

    ///Start the callback notifier
    if(mAppCallbackNotifier->start() != NO_ERROR)
      {
        CAMHAL_LOGEA("Couldn't start AppCallbackNotifier");
        goto fail_loop;
      }

    CAMHAL_LOGDA("Started AppCallbackNotifier..");
    mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);

    ///Initialize default parameters
    initDefaultParameters();


    if ( setParameters(mParameters) != NO_ERROR )
        {
        CAMHAL_LOGEA("Failed to set default parameters?!");
        }

    // register for sensor events
    mSensorListener = new SensorListener();
    if (mSensorListener.get()) {
        if (mSensorListener->initialize() == NO_ERROR) {
            mSensorListener->setCallbacks(orientation_cb, this);
            mSensorListener->enableSensor(SensorListener::SENSOR_ORIENTATION);
        } else {
            CAMHAL_LOGEA("Error initializing SensorListener. not fatal, continuing");
            mSensorListener.clear();
            mSensorListener = NULL;
        }
    }

    LOG_FUNCTION_NAME_EXIT;

    return NO_ERROR;

    fail_loop:

        ///Free up the resources because we failed somewhere up
        deinitialize();
        LOG_FUNCTION_NAME_EXIT;

        return NO_MEMORY;

}

bool CameraHal::isResolutionValid(unsigned int width, unsigned int height, const char *supportedResolutions)
{
    bool ret = true;
    status_t status = NO_ERROR;
    char tmpBuffer[PARAM_BUFFER + 1];
    char *pos = NULL;

    LOG_FUNCTION_NAME;

    if ( NULL == supportedResolutions )
        {
        CAMHAL_LOGEA("Invalid supported resolutions string");
        ret = false;
        goto exit;
        }

    status = snprintf(tmpBuffer, PARAM_BUFFER, "%dx%d", width, height);
    if ( 0 > status )
        {
        CAMHAL_LOGEA("Error encountered while generating validation string");
        ret = false;
        goto exit;
        }

    pos = strstr(supportedResolutions, tmpBuffer);
    if ( NULL == pos )
        {
        ret = false;
        }
    else
        {
        ret = true;
        }

exit:

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

bool CameraHal::isParameterValid(const char *param, const char *supportedParams)
{
    bool ret = true;
    char *pos = NULL;

    LOG_FUNCTION_NAME;

    if ( NULL == supportedParams )
        {
        CAMHAL_LOGEA("Invalid supported parameters string");
        ret = false;
        goto exit;
        }

    if ( NULL == param )
        {
        CAMHAL_LOGEA("Invalid parameter string");
        ret = false;
        goto exit;
        }

    pos = strstr(supportedParams, param);
    if ( NULL == pos )
        {
        ret = false;
        }
    else
        {
        ret = true;
        }

exit:

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

bool CameraHal::isParameterValid(int param, const char *supportedParams)
{
    bool ret = true;
    char *pos = NULL;
    status_t status;
    char tmpBuffer[PARAM_BUFFER + 1];

    LOG_FUNCTION_NAME;

    if ( NULL == supportedParams )
        {
        CAMHAL_LOGEA("Invalid supported parameters string");
        ret = false;
        goto exit;
        }

    status = snprintf(tmpBuffer, PARAM_BUFFER, "%d", param);
    if ( 0 > status )
        {
        CAMHAL_LOGEA("Error encountered while generating validation string");
        ret = false;
        goto exit;
        }

    pos = strstr(supportedParams, tmpBuffer);
    if ( NULL == pos )
        {
        ret = false;
        }
    else
        {
        ret = true;
        }

exit:

    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

status_t CameraHal::doesSetParameterNeedUpdate(const char* new_param, const char* old_param, bool& update) {
    if (!new_param || !old_param) {
        return -EINVAL;
    }

    // if params mismatch we should update parameters for camera adapter
    if ((strcmp(new_param, old_param) != 0)) {
       update = true;
    }

   return NO_ERROR;
}

status_t CameraHal::parseResolution(const char *resStr, int &width, int &height)
{
    status_t ret = NO_ERROR;
    char *ctx, *pWidth, *pHeight;
    const char *sep = "x";
    char *tmp = NULL;

    LOG_FUNCTION_NAME;

    if ( NULL == resStr )
        {
        return -EINVAL;
        }

    //This fixes "Invalid input resolution"
    char *resStr_copy = (char *)malloc(strlen(resStr) + 1);
    if ( NULL!=resStr_copy ) {
    if ( NO_ERROR == ret )
        {
        strcpy(resStr_copy, resStr);
        pWidth = strtok_r( (char *) resStr_copy, sep, &ctx);

        if ( NULL != pWidth )
            {
            width = atoi(pWidth);
            }
        else
            {
            CAMHAL_LOGEB("Invalid input resolution %s", resStr);
            ret = -EINVAL;
            }
        }

    if ( NO_ERROR == ret )
        {
        pHeight = strtok_r(NULL, sep, &ctx);

        if ( NULL != pHeight )
            {
            height = atoi(pHeight);
            }
        else
            {
            CAMHAL_LOGEB("Invalid input resolution %s", resStr);
            ret = -EINVAL;
            }
        }

        free(resStr_copy);
        resStr_copy = NULL;
     }
    LOG_FUNCTION_NAME_EXIT;

    return ret;
}

void CameraHal::insertSupportedParams()
{
    char tmpBuffer[PARAM_BUFFER + 1];

    LOG_FUNCTION_NAME;

    CameraParameters &p = mParameters;

    ///Set the name of the camera
    p.set(TICameraParameters::KEY_CAMERA_NAME, mCameraProperties->get(CameraProperties::CAMERA_NAME));

    mMaxZoomSupported = atoi(mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));

    p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES));
    p.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS));
    p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES));
    p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
    p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES));
    p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_THUMBNAIL_SIZES));
    p.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE));
    p.set(CameraParameters::KEY_SUPPORTED_EFFECTS, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS));
    p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES));
    p.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES));
    p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES));
    p.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING));
    p.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MAX));
    p.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MIN));
    p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_EV_STEP));
    p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES));
    p.set(TICameraParameters::KEY_SUPPORTED_EXPOSURE, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES));
    p.set(TICameraParameters::KEY_SUPPORTED_ISO_VALUES, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES));
    p.set(CameraParameters::KEY_ZOOM_RATIOS, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_RATIOS));
    p.set(CameraParameters::KEY_MAX_ZOOM, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));
    p.set(CameraParameters::KEY_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::ZOOM_SUPPORTED));
    p.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::SMOOTH_ZOOM_SUPPORTED));
    p.set(TICameraParameters::KEY_SUPPORTED_IPP, mCameraProperties->get(CameraProperties::SUPPORTED_IPP_MODES));
    p.set(TICameraParameters::KEY_S3D_SUPPORTED,mCameraProperties->get(CameraProperties::S3D_SUPPORTED));
    p.set(TICameraParameters::KEY_S3D2D_PREVIEW_MODE,mCameraProperties->get(CameraProperties::S3D2D_PREVIEW_MODES));
    p.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE_MODE));
    p.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, mCameraProperties->get(CameraProperties::MANUALCONVERGENCE_VALUES));
    p.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED, mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED));
    p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED));
    p.set(TICameraParameters::KEY_SENSOR_ORIENTATION, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION));
    p.set(TICameraParameters::KEY_SENSOR_ORIENTATION_VALUES, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION_VALUES));
    p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK_SUPPORTED));
    p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK_SUPPORTED));
    p.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED, mCameraProperties->get(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED));

    LOG_FUNCTION_NAME_EXIT;

}

void CameraHal::initDefaultParameters()
{
    //Purpose of this function is to initialize the default current and supported parameters for the currently
    //selected camera.

    CameraParameters &p = mParameters;
    int currentRevision, adapterRevision;
    status_t ret = NO_ERROR;
    int width, height;

    LOG_FUNCTION_NAME;

    ret = parseResolution(mCameraProperties->get(CameraProperties::PREVIEW_SIZE), width, height);

    if ( NO_ERROR == ret )
        {
        p.setPreviewSize(width, height);
        }
    else
        {
        p.setPreviewSize(MIN_WIDTH, MIN_HEIGHT);
        }

    ret = parseResolution(mCameraProperties->get(CameraProperties::PICTURE_SIZE), width, height);

    if ( NO_ERROR == ret )
        {
        p.setPictureSize(width, height);
        }
    else
        {
        p.setPictureSize(PICTURE_WIDTH, PICTURE_HEIGHT);
        }

    ret = parseResolution(mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_SIZE), width, height);

    if ( NO_ERROR == ret )
        {
        p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
        p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
        }
    else
        {
        p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, MIN_WIDTH);
        p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, MIN_HEIGHT);
        }

    insertSupportedParams();

    //Insert default values
    p.setPreviewFrameRate(atoi(mCameraProperties->get(CameraProperties::PREVIEW_FRAME_RATE)));
    p.setPreviewFormat(mCameraProperties->get(CameraProperties::PREVIEW_FORMAT));
    p.setPictureFormat(mCameraProperties->get(CameraProperties::PICTURE_FORMAT));
    p.set(CameraParameters::KEY_JPEG_QUALITY, mCameraProperties->get(CameraProperties::JPEG_QUALITY));
    p.set(CameraParameters::KEY_WHITE_BALANCE, mCameraProperties->get(CameraProperties::WHITEBALANCE));
    p.set(CameraParameters::KEY_EFFECT,  mCameraProperties->get(CameraProperties::EFFECT));
    p.set(CameraParameters::KEY_ANTIBANDING, mCameraProperties->get(CameraProperties::ANTIBANDING));
    p.set(CameraParameters::KEY_FLASH_MODE, mCameraProperties->get(CameraProperties::FLASH_MODE));
    p.set(CameraParameters::KEY_FOCUS_MODE, mCameraProperties->get(CameraProperties::FOCUS_MODE));
    p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::EV_COMPENSATION));
    p.set(CameraParameters::KEY_SCENE_MODE, mCameraProperties->get(CameraProperties::SCENE_MODE));
    p.set(CameraParameters::KEY_FLASH_MODE, mCameraProperties->get(CameraProperties::FLASH_MODE));
    p.set(CameraParameters::KEY_ZOOM, mCameraProperties->get(CameraProperties::ZOOM));
    p.set(TICameraParameters::KEY_CONTRAST, mCameraProperties->get(CameraProperties::CONTRAST));
    p.set(TICameraParameters::KEY_SATURATION, mCameraProperties->get(CameraProperties::SATURATION));
    p.set(TICameraParameters::KEY_BRIGHTNESS, mCameraProperties->get(CameraProperties::BRIGHTNESS));
    p.set(TICameraParameters::KEY_SHARPNESS, mCameraProperties->get(CameraProperties::SHARPNESS));
    p.set(TICameraParameters::KEY_EXPOSURE_MODE, mCameraProperties->get(CameraProperties::EXPOSURE_MODE));
    p.set(TICameraParameters::KEY_ISO, mCameraProperties->get(CameraProperties::ISO_MODE));
    p.set(TICameraParameters::KEY_IPP, mCameraProperties->get(CameraProperties::IPP));
    p.set(TICameraParameters::KEY_GBCE, mCameraProperties->get(CameraProperties::GBCE));
    p.set(TICameraParameters::KEY_S3D2D_PREVIEW, mCameraProperties->get(CameraProperties::S3D2D_PREVIEW));
    p.set(TICameraParameters::KEY_AUTOCONVERGENCE, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE));
    p.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, mCameraProperties->get(CameraProperties::MANUALCONVERGENCE_VALUES));
    p.set(CameraParameters::KEY_VIDEO_STABILIZATION, mCameraProperties->get(CameraProperties::VSTAB));
    p.set(CameraParameters::KEY_FOCAL_LENGTH, mCameraProperties->get(CameraProperties::FOCAL_LENGTH));
    p.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::HOR_ANGLE));
    p.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::VER_ANGLE));
    p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,mCameraProperties->get(CameraProperties::FRAMERATE_RANGE));
    p.set(TICameraParameters::KEY_SENSOR_ORIENTATION, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION));
    p.set(TICameraParameters::KEY_SENSOR_ORIENTATION_VALUES, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION_VALUES));
    p.set(TICameraParameters::KEY_EXIF_MAKE, mCameraProperties->get(CameraProperties::EXIF_MAKE));
    p.set(TICameraParameters::KEY_EXIF_MODEL, mCameraProperties->get(CameraProperties::EXIF_MODEL));
    p.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_QUALITY));
    p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar");
    p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, mCameraProperties->get(CameraProperties::MAX_FD_HW_FACES));
    p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, mCameraProperties->get(CameraProperties::MAX_FD_SW_FACES));

    // Only one area a.k.a Touch AF for now.
    // TODO: Add support for multiple focus areas.
    p.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, mCameraProperties->get(CameraProperties::MAX_FOCUS_AREAS));
    p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK));
    p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK));
    p.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS, mCameraProperties->get(CameraProperties::MAX_NUM_METERING_AREAS));

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Stop a previously started preview.
   @param none
   @return none

 */
void CameraHal::forceStopPreview()
{
    LOG_FUNCTION_NAME;

    // stop bracketing if it is running
    stopImageBracketing();

    if(mDisplayAdapter.get() != NULL) {
        ///Stop the buffer display first
        mDisplayAdapter->disableDisplay();
    }

    if(mAppCallbackNotifier.get() != NULL) {
        //Stop the callback sending
        mAppCallbackNotifier->stop();
        mAppCallbackNotifier->flushAndReturnFrames();
        mAppCallbackNotifier->stopPreviewCallbacks();
    }

    if ( NULL != mCameraAdapter ) {
        // only need to send these control commands to state machine if we are
        // passed the LOADED_PREVIEW_STATE
        if (mCameraAdapter->getState() > CameraAdapter::LOADED_PREVIEW_STATE) {
           // according to javadoc...FD should be stopped in stopPreview
           // and application needs to call startFaceDection again
           // to restart FD
           mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
        }

        mCameraAdapter->rollbackToInitializedState();

    }

    freePreviewBufs();
    freePreviewDataBufs();

    mPreviewEnabled = false;
    mDisplayPaused = false;
    mPreviewStartInProgress = false;

    LOG_FUNCTION_NAME_EXIT;
}

/**
   @brief Deallocates memory for all the resources held by Camera HAL.

   Frees the following objects- CameraAdapter, AppCallbackNotifier, DisplayAdapter,
   and Memory Manager

   @param none
   @return none

 */
void CameraHal::deinitialize()
{
    LOG_FUNCTION_NAME;

    if ( mPreviewEnabled || mDisplayPaused ) {
        forceStopPreview();
    }

    mSetPreviewWindowCalled = false;

    if (mSensorListener.get()) {
        mSensorListener->disableSensor(SensorListener::SENSOR_ORIENTATION);
        mSensorListener.clear();
        mSensorListener = NULL;
    }

    LOG_FUNCTION_NAME_EXIT;

}

status_t CameraHal::storeMetaDataInBuffers(bool enable)
{
    LOG_FUNCTION_NAME;

    return mAppCallbackNotifier->useMetaDataBufferMode(enable);

    LOG_FUNCTION_NAME_EXIT;
}

void CameraHal::selectFPSRange(int framerate, int *min_fps, int *max_fps)
{
  char * ptr;
  char supported[MAX_PROP_VALUE_LENGTH];
  int fpsrangeArray[2];
  int i = 0;

  LOG_FUNCTION_NAME;
  size_t size = strlen(mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED))+1;
  strncpy(supported, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED), size);

  ptr = strtok (supported," (,)");

  while (ptr != NULL)
    {
      fpsrangeArray[i]= atoi(ptr)/CameraHal::VFR_SCALE;
      if (i == 1)
        {
          if (framerate == fpsrangeArray[i])
            {
              CAMHAL_LOGDB("SETTING FPS RANGE min = %d max = %d \n", fpsrangeArray[0], fpsrangeArray[1]);
              *min_fps = fpsrangeArray[0]*CameraHal::VFR_SCALE;
              *max_fps = fpsrangeArray[1]*CameraHal::VFR_SCALE;
              break;
            }
        }
      ptr = strtok (NULL, " (,)");
      i++;
      i%=2;
    }

  LOG_FUNCTION_NAME_EXIT;

}

void CameraHal::setPreferredPreviewRes(int width, int height)
{
  LOG_FUNCTION_NAME;

  if ( (width == 320) && (height == 240)){
    mParameters.setPreviewSize(640,480);
  }
  if ( (width == 176) && (height == 144)){
    mParameters.setPreviewSize(704,576);
  }

  LOG_FUNCTION_NAME_EXIT;
}

void CameraHal::resetPreviewRes(CameraParameters *mParams, int width, int height)
{
  LOG_FUNCTION_NAME;

  if ( (width <= 320) && (height <= 240)){
    mParams->setPreviewSize(mVideoWidth, mVideoHeight);
  }

  LOG_FUNCTION_NAME_EXIT;
}

};


