camera: Mako camera hal upgrade

- Restructure of mm-camera-interface and HAL.
- Change to disable FS live snap if H/W doesn't support.
- Fix Ghosting effect in JPEG on zoom and rot.
- Support double buf padding for rotation in ZSL case.
- Fix buffer corruption for FS live snap shot.

Change-Id: If1667f0c185e2e341dd2dac586510659ea2743d7
diff --git a/camera/Android.mk b/camera/Android.mk
index 7730ec8..befb25f 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -15,6 +15,7 @@
       endif
 
       LOCAL_PATH:= $(call my-dir)
+      LOCAL_PATH1:= $(call my-dir)
 
       include $(CLEAR_VARS)
 
@@ -138,4 +139,8 @@
 include $(LOCAL_PATH)/mm-camera-interface/Android.mk
 endif
 
+#Enable only to compile new interafece and HAL files.
+ifeq ($(V4L2_BASED_LIBCAM),true)
+include $(LOCAL_PATH1)/QCamera/Android.mk
+endif
 endif
diff --git a/camera/QCamera/Android.mk b/camera/QCamera/Android.mk
new file mode 100755
index 0000000..c36c538
--- /dev/null
+++ b/camera/QCamera/Android.mk
@@ -0,0 +1,3 @@
+ifeq ($(TARGET_ARCH),arm)
+  include $(call all-subdir-makefiles)
+endif
diff --git a/camera/QCamera/HAL/Android.mk b/camera/QCamera/HAL/Android.mk
new file mode 100755
index 0000000..e520431
--- /dev/null
+++ b/camera/QCamera/HAL/Android.mk
@@ -0,0 +1,3 @@
+LOCAL_PATH:= $(call my-dir)
+#include $(LOCAL_PATH)/core/Android.mk
+#include $(LOCAL_PATH)/test/Android.mk
diff --git a/camera/QCamera/HAL/core/Android.mk b/camera/QCamera/HAL/core/Android.mk
new file mode 100755
index 0000000..367313a
--- /dev/null
+++ b/camera/QCamera/HAL/core/Android.mk
@@ -0,0 +1,91 @@
+

+#ifeq ($(call is-board-platform,msm8960),true)

+OLD_LOCAL_PATH := $(LOCAL_PATH)

+LOCAL_PATH := $(call my-dir)

+

+include $(CLEAR_VARS)

+

+ifeq ($(strip $(TARGET_USES_ION)),true)

+LOCAL_CFLAGS += -DUSE_ION

+endif

+

+DLOPEN_LIBMMCAMERA:=0

+

+LOCAL_CFLAGS:= -DDLOPEN_LIBMMCAMERA=$(DLOPEN_LIBMMCAMERA)

+

+LOCAL_CFLAGS += -DCAMERA_ION_HEAP_ID=ION_CP_MM_HEAP_ID # 8660=SMI, Rest=EBI

+LOCAL_CFLAGS += -DCAMERA_ZSL_ION_HEAP_ID=ION_CP_MM_HEAP_ID

+

+LOCAL_CFLAGS+= -DHW_ENCODE

+LOCAL_CFLAGS+= -DUSE_NEON_CONVERSION

+

+ifeq ($(call is-board-platform,msm8960),true)

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_HEAP_ID=GRALLOC_USAGE_PRIVATE_MM_HEAP

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_FALLBACK_HEAP_ID=GRALLOC_USAGE_PRIVATE_IOMMU_HEAP

+        LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID

+        LOCAL_CFLAGS += -DCAMERA_ZSL_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0

+else ifeq ($(call is-chipset-prefix-in-board-platform,msm8660),true)

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_HEAP_ID=GRALLOC_USAGE_PRIVATE_CAMERA_HEAP

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_FALLBACK_HEAP_ID=GRALLOC_USAGE_PRIVATE_CAMERA_HEAP # Don't Care

+        LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_CAMERA_HEAP_ID # EBI

+        LOCAL_CFLAGS += -DCAMERA_ZSL_ION_FALLBACK_HEAP_ID=ION_CAMERA_HEAP_ID

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0

+else

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_HEAP_ID=GRALLOC_USAGE_PRIVATE_ADSP_HEAP

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_FALLBACK_HEAP_ID=GRALLOC_USAGE_PRIVATE_ADSP_HEAP # Don't Care

+        LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=GRALLOC_USAGE_PRIVATE_UNCACHED #uncached

+endif

+

+LOCAL_HAL_FILES := \

+        src/QCameraHAL.cpp \

+        src/QCameraHWI_Parm.cpp \

+        src/QCameraHWI.cpp \

+        src/QCameraHWI_Preview.cpp \

+        src/QCameraHWI_Record.cpp \

+        src/QCameraHWI_Still.cpp \

+        src/QCameraHWI_Mem.cpp \

+        src/QCameraStream.cpp

+

+LOCAL_HAL_WRAPPER_FILES := ../wrapper/QualcommCamera.cpp

+

+LOCAL_C_INCLUDES := \

+        $(LOCAL_PATH)/../wrapper \

+        $(LOCAL_PATH)/inc \

+        $(TARGET_OUT_INTERMEDIATES)/include/mm-camera-interface_badger \

+

+# may need remove this includes 

+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-camera 

+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-still \

+                    $(TARGET_OUT_HEADERS)/mm-still/jpeg 

+#end

+

+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include

+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/media

+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr

+

+LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc \

+        hardware/qcom/display/libgenlock \

+        hardware/qcom/media/libstagefrighthw

+

+# if debug service layer and up , use stub camera!

+LOCAL_C_INCLUDES += \

+        frameworks/base/services/camera/libcameraservice

+

+LOCAL_SRC_FILES := \

+        $(LOCAL_HAL_WRAPPER_FILES) \

+        $(LOCAL_HAL_FILES)

+

+LOCAL_SHARED_LIBRARIES := libutils libui libcamera_client liblog libcutils

+LOCAL_SHARED_LIBRARIES += libmmcamera_interface_badger

+LOCAL_SHARED_LIBRARIES+= libgenlock libbinder

+

+LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/socket.h

+

+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw

+LOCAL_MODULE:= camera_badger.$(TARGET_BOARD_PLATFORM)

+LOCAL_MODULE_TAGS := optional

+include $(BUILD_SHARED_LIBRARY)

+

+LOCAL_PATH := $(OLD_LOCAL_PATH)

+

diff --git a/camera/QCamera/HAL/core/inc/QCameraHAL.h b/camera/QCamera/HAL/core/inc/QCameraHAL.h
new file mode 100755
index 0000000..c13d9bc
--- /dev/null
+++ b/camera/QCamera/HAL/core/inc/QCameraHAL.h
@@ -0,0 +1,37 @@
+/*
+** Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_HARDWARE_QCAMERA_HAL_H
+#define ANDROID_HARDWARE_QCAMERA_HAL_H
+
+
+#include "QCameraHWI.h"
+
+extern "C" {
+#include <mm_camera_interface2.h>
+}
+namespace android {
+
+/* HAL should return NULL if it fails to open camera hardware. */
+extern "C" void *
+       QCameraHAL_openCameraHardware(int  cameraId, int mode);
+extern "C" int HAL_getNumberOfCameras();
+extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo);
+
+}; // namespace android
+
+#endif
+
diff --git a/camera/QCamera/HAL/core/inc/QCameraHWI.h b/camera/QCamera/HAL/core/inc/QCameraHWI.h
new file mode 100755
index 0000000..eb02d0a
--- /dev/null
+++ b/camera/QCamera/HAL/core/inc/QCameraHWI.h
@@ -0,0 +1,836 @@
+/*
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_HARDWARE_QCAMERA_HARDWARE_INTERFACE_H
+#define ANDROID_HARDWARE_QCAMERA_HARDWARE_INTERFACE_H
+
+
+#include <utils/threads.h>
+//#include <camera/CameraHardwareInterface.h>
+#include <hardware/camera.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/MemoryHeapPmem.h>
+#include <utils/threads.h>
+#include <cutils/properties.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
+#include <system/window.h>
+#include <system/camera.h>
+#include <hardware/camera.h>
+#include <gralloc_priv.h>
+#include <QComOMXMetadata.h>
+
+extern "C" {
+#include <linux/android_pmem.h>
+#include <linux/ion.h>
+//#include <camera.h>
+//#include <camera_defs_i.h>
+#include <mm_camera_interface2.h>
+
+#include "mm_omx_jpeg_encoder.h"
+
+} //extern C
+
+#include "QCameraHWI_Mem.h"
+#include "QCameraStream.h"
+
+//Error codes
+#define  NOT_FOUND -1
+#define MAX_ZOOM_RATIOS 62
+
+#ifdef Q12
+#undef Q12
+#endif
+
+#define Q12 4096
+#define QCAMERA_PARM_ENABLE   1
+#define QCAMERA_PARM_DISABLE  0
+#define PREVIEW_TBL_MAX_SIZE  14
+#define VIDEO_TBL_MAX_SIZE    14
+#define THUMB_TBL_MAX_SIZE    16
+#define HFR_TBL_MAX_SIZE      2
+
+struct str_map {
+    const char *const desc;
+    int val;
+};
+
+struct preview_format_info_t {
+   int Hal_format;
+   cam_format_t mm_cam_format;
+   cam_pad_format_t padding;
+   int num_planar;
+};
+
+typedef enum {
+  CAMERA_STATE_UNINITED,
+  CAMERA_STATE_READY,
+  CAMERA_STATE_PREVIEW_START_CMD_SENT,
+  CAMERA_STATE_PREVIEW_STOP_CMD_SENT,
+  CAMERA_STATE_PREVIEW,
+  CAMERA_STATE_RECORD_START_CMD_SENT,  /*5*/
+  CAMERA_STATE_RECORD_STOP_CMD_SENT,
+  CAMERA_STATE_RECORD,
+  CAMERA_STATE_SNAP_START_CMD_SENT,
+  CAMERA_STATE_SNAP_STOP_CMD_SENT,
+  CAMERA_STATE_SNAP_CMD_ACKED,  /*10 - snapshot comd acked, snapshot not done yet*/
+  CAMERA_STATE_ZSL_START_CMD_SENT,
+  CAMERA_STATE_ZSL,
+  CAMERA_STATE_AF_START_CMD_SENT,
+  CAMERA_STATE_AF_STOP_CMD_SENT,
+  CAMERA_STATE_ERROR, /*15*/
+
+  /*Add any new state above*/
+  CAMERA_STATE_MAX
+} HAL_camera_state_type_t;
+
+enum {
+  BUFFER_NOT_OWNED,
+  BUFFER_UNLOCKED,
+  BUFFER_LOCKED,
+};
+
+typedef enum {
+  HAL_DUMP_FRM_PREVIEW = 1,
+  HAL_DUMP_FRM_VIDEO = 1<<1,
+  HAL_DUMP_FRM_MAIN = 1<<2,
+  HAL_DUMP_FRM_THUMBNAIL = 1<<3,
+
+  /*8 bits mask*/
+  HAL_DUMP_FRM_MAX = 1 << 8
+} HAL_cam_dump_frm_type_t;
+
+
+typedef enum {
+  HAL_CAM_MODE_ZSL = 1,
+
+  /*add new entry before and update the max entry*/
+  HAL_CAM_MODE_MAX = HAL_CAM_MODE_ZSL << 1,
+} qQamera_mode_t;
+
+#define HAL_DUMP_FRM_MASK_ALL ( HAL_DUMP_FRM_PREVIEW + HAL_DUMP_FRM_VIDEO + \
+    HAL_DUMP_FRM_MAIN + HAL_DUMP_FRM_THUMBNAIL)
+#define QCAMERA_HAL_PREVIEW_STOPPED    0
+#define QCAMERA_HAL_PREVIEW_START      1
+#define QCAMERA_HAL_PREVIEW_STARTED    2
+#define QCAMERA_HAL_RECORDING_STARTED  3
+#define QCAMERA_HAL_TAKE_PICTURE       4
+
+
+typedef struct {
+     int                     buffer_count;
+	 buffer_handle_t        *buffer_handle[MM_CAMERA_MAX_NUM_FRAMES];
+	 struct private_handle_t *private_buffer_handle[MM_CAMERA_MAX_NUM_FRAMES];
+	 int                     stride[MM_CAMERA_MAX_NUM_FRAMES];
+	 uint32_t                addr_offset[MM_CAMERA_MAX_NUM_FRAMES];
+	 uint8_t                 local_flag[MM_CAMERA_MAX_NUM_FRAMES];
+	 camera_memory_t        *camera_memory[MM_CAMERA_MAX_NUM_FRAMES];
+     int                     main_ion_fd[MM_CAMERA_MAX_NUM_FRAMES];
+     struct ion_fd_data      ion_info_fd[MM_CAMERA_MAX_NUM_FRAMES];
+} QCameraHalMemory_t;
+
+
+typedef struct {
+     int                     buffer_count;
+     uint32_t                size;
+     uint32_t                y_offset;
+     uint32_t                cbcr_offset;
+	 int                     fd[MM_CAMERA_MAX_NUM_FRAMES];
+	 int                     local_flag[MM_CAMERA_MAX_NUM_FRAMES];
+	 camera_memory_t*        camera_memory[MM_CAMERA_MAX_NUM_FRAMES];
+     camera_memory_t*        metadata_memory[MM_CAMERA_MAX_NUM_FRAMES];
+     int main_ion_fd[MM_CAMERA_MAX_NUM_FRAMES];
+     struct ion_allocation_data alloc[MM_CAMERA_MAX_NUM_FRAMES];
+     struct ion_fd_data ion_info_fd[MM_CAMERA_MAX_NUM_FRAMES];
+} QCameraHalHeap_t;
+
+typedef struct {
+     camera_memory_t*  camera_memory[3];
+     int main_ion_fd[3];
+     struct ion_allocation_data alloc[3];
+     struct ion_fd_data ion_info_fd[3];
+     int fd[3];
+     int size;
+} QCameraStatHeap_t;
+
+typedef struct {
+  int32_t msg_type;
+  int32_t ext1;
+  int32_t ext2;
+  void    *cookie;
+} argm_notify_t;
+
+typedef struct {
+  int32_t                  msg_type;
+  camera_memory_t         *data;
+  unsigned int             index;
+  camera_frame_metadata_t *metadata;
+  void                    *cookie;
+} argm_data_cb_t;
+
+typedef struct {
+  camera_notify_callback notifyCb;
+  camera_data_callback   dataCb;
+  argm_notify_t argm_notify;
+  argm_data_cb_t        argm_data_cb;
+} app_notify_cb_t;
+
+/* camera_area_t
+ * rectangle with weight to store the focus and metering areas.
+ * x1, y1, x2, y2: from -1000 to 1000
+ * weight: 0 to 1000
+ */
+typedef struct {
+    int x1, y1, x2, y2;
+    int weight;
+} camera_area_t;
+
+//EXIF globals
+static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };          // "ASCII\0\0\0"
+static const char ExifUndefinedPrefix[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };   // "\0\0\0\0\0\0\0\0"
+
+//EXIF detfines
+#define MAX_EXIF_TABLE_ENTRIES           14
+#define GPS_PROCESSING_METHOD_SIZE       101
+#define FOCAL_LENGTH_DECIMAL_PRECISION   100
+#define EXIF_ASCII_PREFIX_SIZE           8   //(sizeof(ExifAsciiPrefix))
+
+typedef struct{
+    //GPS tags
+    rat_t       latitude[3];
+    rat_t       longitude[3];
+    char        lonRef[2];
+    char        latRef[2];
+    rat_t       altitude;
+    rat_t       gpsTimeStamp[3];
+    char        gpsDateStamp[20];
+    char        gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE+GPS_PROCESSING_METHOD_SIZE];
+    //Other tags
+    char        dateTime[20];
+    rat_t       focalLength;
+    uint16_t    flashMode;
+    uint16_t    isoSpeed;
+
+    bool        mAltitude;
+    bool        mLongitude;
+    bool        mLatitude;
+    bool        mTimeStamp;
+    bool        mGpsProcess;
+
+    int         mAltitude_ref;
+    long        mGPSTimestamp;
+
+} exif_values_t;
+
+namespace android {
+
+class QCameraStream;
+
+class QCameraHardwareInterface : public virtual RefBase {
+public:
+
+    QCameraHardwareInterface(int  cameraId, int mode);
+
+    /** Set the ANativeWindow to which preview frames are sent */
+    int setPreviewWindow(preview_stream_ops_t* window);
+
+    /** Set the notification and data callbacks */
+    void 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);
+
+    /**
+     * The following three functions all take a msg_type, which is a bitmask of
+     * the messages defined in include/ui/Camera.h
+     */
+
+    /**
+     * Enable a message, or set of messages.
+     */
+    void enableMsgType(int32_t msg_type);
+
+    /**
+     * Disable a message, or a set of messages.
+     *
+     * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera
+     * HAL should not rely on its client to call releaseRecordingFrame() to
+     * release video recording frames sent out by the cameral HAL before and
+     * after the disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera HAL
+     * clients must not modify/access any video recording frame after calling
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
+     */
+    void disableMsgType(int32_t msg_type);
+
+    /**
+     * 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.
+     */
+    int msgTypeEnabled(int32_t msg_type);
+
+    /**
+     * Start preview mode.
+     */
+    int startPreview();
+    int startPreview2();
+
+    /**
+     * Stop a previously started preview.
+     */
+    void stopPreview();
+
+    /**
+     * Returns true if preview is enabled.
+     */
+    int previewEnabled();
+
+
+    /**
+     * Request the camera HAL to store meta data or real YUV data in the video
+     * buffers sent out via CAMERA_MSG_VIDEO_FRAME for a recording session. If
+     * it is not called, the default camera HAL behavior is to store real YUV
+     * data in the video buffers.
+     *
+     * This method should be called before startRecording() in order to be
+     * effective.
+     *
+     * If meta data is stored in the video buffers, it is up to the receiver of
+     * the video buffers to interpret the contents and to find the actual frame
+     * data with the help of the meta data in the buffer. How this is done is
+     * outside of the scope of this method.
+     *
+     * Some camera HALs may not support storing meta data in the video buffers,
+     * but all camera HALs should support storing real YUV data in the video
+     * buffers. If the camera HAL does not support storing the meta data in the
+     * video buffers when it is requested to do do, INVALID_OPERATION must be
+     * returned. It is very useful for the camera HAL to pass meta data rather
+     * than the actual frame data directly to the video encoder, since the
+     * amount of the uncompressed frame data can be very large if video size is
+     * large.
+     *
+     * @param enable if true to instruct the camera HAL to store
+     *        meta data in the video buffers; false to instruct
+     *        the camera HAL to store real YUV data in the video
+     *        buffers.
+     *
+     * @return OK on success.
+     */
+    int storeMetaDataInBuffers(int enable);
+
+    /**
+     * 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 a camera HAL client via
+     * releaseRecordingFrame() before the client calls
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's
+     * responsibility to manage the life-cycle of the video recording frames,
+     * and the client must not modify/access any video recording frames.
+     */
+    int startRecording();
+
+    /**
+     * Stop a previously started recording.
+     */
+    void stopRecording();
+
+    /**
+     * Returns true if recording is enabled.
+     */
+    int recordingEnabled();
+
+    /**
+     * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
+     *
+     * It is camera HAL client's responsibility to release video recording
+     * frames sent out by the camera HAL before the camera HAL receives a call
+     * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's
+     * responsibility to manage the life-cycle of the video recording frames.
+     */
+    void releaseRecordingFrame(const void *opaque);
+
+    /**
+     * Start auto focus, 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.
+     */
+    int autoFocus();
+
+    /**
+     * 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.
+     */
+    int cancelAutoFocus();
+
+    /**
+     * Take a picture.
+     */
+    int takePicture();
+
+    /**
+     * Cancel a picture that was started with takePicture. Calling this method
+     * when no picture is being taken is a no-op.
+     */
+    int cancelPicture();
+
+    /**
+     * Set the camera parameters. This returns BAD_VALUE if any parameter is
+     * invalid or not supported.
+     */
+    int setParameters(const char *parms);
+
+    //status_t setParameters(const CameraParameters& params);
+    /** Retrieve the camera parameters.  The buffer returned by the camera HAL
+        must be returned back to it with put_parameters, if put_parameters
+        is not NULL.
+     */
+    int getParameters(char **parms);
+
+    /** The camera HAL uses its own memory to pass us the parameters when we
+        call get_parameters.  Use this function to return the memory back to
+        the camera HAL, if put_parameters is not NULL.  If put_parameters
+        is NULL, then you have to use free() to release the memory.
+    */
+    void putParameters(char *);
+
+    /**
+     * Send command to camera driver.
+     */
+    int sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
+
+    /**
+     * Release the hardware resources owned by this object.  Note that this is
+     * *not* done in the destructor.
+     */
+    void release();
+
+    /**
+     * Dump state of the camera hardware
+     */
+    int dump(int fd);
+
+    //virtual sp<IMemoryHeap> getPreviewHeap() const;
+    //virtual sp<IMemoryHeap> getRawHeap() const;
+
+
+    status_t    takeLiveSnapshot();
+    status_t    takeFullSizeLiveshot();
+    bool        canTakeFullSizeLiveshot();
+
+    //virtual status_t          getBufferInfo( sp<IMemory>& Frame,
+    //size_t *alignedSize);
+    void         getPictureSize(int *picture_width, int *picture_height) const;
+    void         getPreviewSize(int *preview_width, int *preview_height) const;
+    cam_format_t getPreviewFormat() const;
+
+    cam_pad_format_t getPreviewPadding() const;
+
+    //bool     useOverlay(void);
+    //virtual status_t setOverlay(const sp<Overlay> &overlay);
+    void processEvent(mm_camera_event_t *);
+    int  getJpegQuality() const;
+    int  getNumOfSnapshots(void) const;
+    int  getNumOfSnapshots(const CameraParameters& params);
+    int  getThumbSizesFromAspectRatio(uint32_t aspect_ratio,
+                                     int *picture_width,
+                                     int *picture_height);
+    bool isRawSnapshot();
+    bool mShutterSoundPlayed;
+    void dumpFrameToFile(struct msm_frame*, HAL_cam_dump_frm_type_t);
+
+    static QCameraHardwareInterface *createInstance(int, int);
+    status_t setZSLBurstLookBack(const CameraParameters& params);
+    status_t setZSLBurstInterval(const CameraParameters& params);
+    int getZSLBurstInterval(void);
+    int getZSLQueueDepth(void) const;
+    int getZSLBackLookCount(void) const;
+
+    ~QCameraHardwareInterface();
+    int initHeapMem(QCameraHalHeap_t *heap, int num_of_buf, int pmem_type,
+      int frame_len, int cbcr_off, int y_off, mm_cameara_stream_buf_t *StreamBuf,
+      mm_camera_buf_def_t *buf_def, uint8_t num_planes, uint32_t *planes);
+
+    int releaseHeapMem( QCameraHalHeap_t *heap);
+    status_t sendMappingBuf(int ext_mode, int idx, int fd, uint32_t size,
+      int cameraid, mm_camera_socket_msg_type msg_type);
+    status_t sendUnMappingBuf(int ext_mode, int idx, int cameraid,
+      mm_camera_socket_msg_type msg_type);
+
+    int allocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt,
+      int ion_type);
+    int deallocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt);
+
+    int allocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt,
+      int ion_type);
+    int deallocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt);
+
+    int cache_ops(int ion_fd, struct ion_flush_data *cache_inv_data, int type);
+
+    void dumpFrameToFile(const void * data, uint32_t size, char* name,
+      char* ext, int index);
+    preview_format_info_t getPreviewFormatInfo( );
+    bool isCameraReady();
+    bool isNoDisplayMode();
+
+private:
+    int16_t  zoomRatios[MAX_ZOOM_RATIOS];
+    struct camera_size_type default_preview_sizes[PREVIEW_TBL_MAX_SIZE];
+    struct camera_size_type default_video_sizes[VIDEO_TBL_MAX_SIZE];
+    struct camera_size_type default_hfr_sizes[HFR_TBL_MAX_SIZE];
+    struct camera_size_type default_thumbnail_sizes[THUMB_TBL_MAX_SIZE];
+    unsigned int preview_sizes_count;
+    unsigned int video_sizes_count;
+    unsigned int thumbnail_sizes_count;
+    unsigned int hfr_sizes_count;
+
+
+    bool mUseOverlay;
+
+    void loadTables();
+    void initDefaultParameters();
+    bool getMaxPictureDimension(mm_camera_dimension_t *dim);
+
+    status_t updateFocusDistances();
+
+    bool native_set_parms(mm_camera_parm_type_t type, uint16_t length, void *value);
+    bool native_set_parms( mm_camera_parm_type_t type, uint16_t length, void *value, int *result);
+
+    void hasAutoFocusSupport();
+    void debugShowPreviewFPS() const;
+    //void prepareSnapshotAndWait();
+
+    bool isPreviewRunning();
+    bool isRecordingRunning();
+    bool isSnapshotRunning();
+
+    void processChannelEvent(mm_camera_ch_event_t *, app_notify_cb_t *);
+    void processPreviewChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *);
+    void processRecordChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *);
+    void processSnapshotChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *);
+    void processCtrlEvent(mm_camera_ctrl_event_t *, app_notify_cb_t *);
+    void processStatsEvent(mm_camera_stats_event_t *, app_notify_cb_t *);
+    void processInfoEvent(mm_camera_info_event_t *event, app_notify_cb_t *);
+    void processprepareSnapshotEvent(cam_ctrl_status_t *);
+    void roiEvent(fd_roi_t roi, app_notify_cb_t *);
+    void zoomEvent(cam_ctrl_status_t *status, app_notify_cb_t *);
+    void autofocusevent(cam_ctrl_status_t *status, app_notify_cb_t *);
+    void handleZoomEventForPreview(app_notify_cb_t *);
+    void handleZoomEventForSnapshot(void);
+    status_t autoFocusEvent(cam_ctrl_status_t *, app_notify_cb_t *);
+
+    void filterPictureSizes();
+    bool supportsSceneDetection();
+    bool supportsSelectableZoneAf();
+    bool supportsFaceDetection();
+    bool supportsRedEyeReduction();
+    bool preview_parm_config (cam_ctrl_dimension_t* dim,CameraParameters& parm);
+
+    void stopPreviewInternal();
+    void stopRecordingInternal();
+    //void stopPreviewZSL();
+    status_t cancelPictureInternal();
+    //status_t startPreviewZSL();
+    void pausePreviewForSnapshot();
+    void pausePreviewForZSL();
+    status_t resumePreviewAfterSnapshot();
+
+    status_t runFaceDetection();
+
+    status_t           setParameters(const CameraParameters& params);
+    CameraParameters&  getParameters() ;
+
+    status_t setCameraMode(const CameraParameters& params);
+    status_t setPictureSizeTable(void);
+    status_t setPreviewSizeTable(void);
+    status_t setVideoSizeTable(void);
+    status_t setPreviewSize(const CameraParameters& params);
+    status_t setJpegThumbnailSize(const CameraParameters& params);
+    status_t setPreviewFpsRange(const CameraParameters& params);
+    status_t setPreviewFrameRate(const CameraParameters& params);
+    status_t setPreviewFrameRateMode(const CameraParameters& params);
+    status_t setVideoSize(const CameraParameters& params);
+    status_t setPictureSize(const CameraParameters& params);
+    status_t setJpegQuality(const CameraParameters& params);
+    status_t setNumOfSnapshot(const CameraParameters& params);
+    status_t setJpegRotation(int isZSL);
+    int getJpegRotation(void);
+    int getISOSpeedValue();
+    status_t setAntibanding(const CameraParameters& params);
+    status_t setEffect(const CameraParameters& params);
+    status_t setExposureCompensation(const CameraParameters &params);
+    status_t setAutoExposure(const CameraParameters& params);
+    status_t setWhiteBalance(const CameraParameters& params);
+    status_t setFlash(const CameraParameters& params);
+    status_t setGpsLocation(const CameraParameters& params);
+    status_t setRotation(const CameraParameters& params);
+    status_t setZoom(const CameraParameters& params);
+    status_t setFocusMode(const CameraParameters& params);
+    status_t setBrightness(const CameraParameters& params);
+    status_t setSkinToneEnhancement(const CameraParameters& params);
+    status_t setOrientation(const CameraParameters& params);
+    status_t setLensshadeValue(const CameraParameters& params);
+    status_t setMCEValue(const CameraParameters& params);
+    status_t setISOValue(const CameraParameters& params);
+    status_t setPictureFormat(const CameraParameters& params);
+    status_t setSharpness(const CameraParameters& params);
+    status_t setContrast(const CameraParameters& params);
+    status_t setSaturation(const CameraParameters& params);
+    status_t setWaveletDenoise(const CameraParameters& params);
+    status_t setSceneMode(const CameraParameters& params);
+    status_t setContinuousAf(const CameraParameters& params);
+    status_t setFaceDetection(const char *str);
+    status_t setSceneDetect(const CameraParameters& params);
+    status_t setStrTextures(const CameraParameters& params);
+    status_t setPreviewFormat(const CameraParameters& params);
+    status_t setSelectableZoneAf(const CameraParameters& params);
+    status_t setOverlayFormats(const CameraParameters& params);
+    status_t setHighFrameRate(const CameraParameters& params);
+    status_t setRedeyeReduction(const CameraParameters& params);
+    status_t setAEBracket(const CameraParameters& params);
+    status_t setFaceDetect(const CameraParameters& params);
+    status_t setDenoise(const CameraParameters& params);
+    status_t setAecAwbLock(const CameraParameters & params);
+    status_t setHistogram(int histogram_en);
+    status_t setRecordingHint(const CameraParameters& params);
+    status_t setRecordingHintValue(const int32_t value);
+    status_t setFocusAreas(const CameraParameters& params);
+    status_t setMeteringAreas(const CameraParameters& params);
+    status_t setFullLiveshot(void);
+    status_t setDISMode(void);
+    status_t setCaptureBurstExp(void);
+    status_t setPowerMode(const CameraParameters& params);
+    void takePicturePrepareHardware( );
+    status_t setNoDisplayMode(const CameraParameters& params);
+
+    isp3a_af_mode_t getAutoFocusMode(const CameraParameters& params);
+    bool isValidDimension(int w, int h);
+
+    String8 create_values_str(const str_map *values, int len);
+
+    void setMyMode(int mode);
+    bool isZSLMode();
+    bool isWDenoiseEnabled();
+    void wdenoiseEvent(cam_ctrl_status_t status, void *cookie);
+    bool isLowPowerCamcorder();
+    void freePictureTable(void);
+    void freeVideoSizeTable(void);
+
+    int32_t createPreview();
+    int32_t createRecord();
+    int32_t createSnapshot();
+
+    int getHDRMode();
+    //EXIF
+    void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
+                        uint32_t count, uint8_t copy, void *data);
+    void setExifTags();
+    void initExifData();
+    void deinitExifData();
+    void setExifTagsGPS();
+    exif_tags_info_t* getExifData(){ return mExifData; }
+    int getExifTableNumEntries() { return mExifTableNumEntries; }
+    void parseGPSCoordinate(const char *latlonString, rat_t* coord);
+
+    int           mCameraId;
+    camera_mode_t myMode;
+
+    CameraParameters    mParameters;
+    //sp<Overlay>         mOverlay;
+    int32_t             mMsgEnabled;
+
+    camera_notify_callback         mNotifyCb;
+    camera_data_callback           mDataCb;
+    camera_data_timestamp_callback mDataCbTimestamp;
+    camera_request_memory          mGetMemory;
+    void                           *mCallbackCookie;
+
+    //sp<MemoryHeapBase>  mPreviewHeap;  //@Guru : Need to remove
+    sp<AshmemPool>      mMetaDataHeap;
+
+    mutable Mutex       mLock;
+    //mutable Mutex       eventLock;
+    Mutex         mCallbackLock;
+    Mutex         mPreviewMemoryLock;
+    Mutex         mRecordingMemoryLock;
+    Mutex         mAutofocusLock;
+    Mutex         mMetaDataWaitLock;
+    Mutex         mRecordFrameLock;
+    Mutex         mRecordLock;
+    Condition     mRecordWait;
+    pthread_mutex_t     mAsyncCmdMutex;
+    pthread_cond_t      mAsyncCmdWait;
+
+    QCameraStream       *mStreamDisplay;
+    QCameraStream       *mStreamRecord;
+    QCameraStream       *mStreamSnap;
+    QCameraStream       *mStreamLiveSnap;
+
+    cam_ctrl_dimension_t mDimension;
+    int  mPreviewWidth, mPreviewHeight;
+    int  videoWidth, videoHeight;
+    int  thumbnailWidth, thumbnailHeight;
+    int  maxSnapshotWidth, maxSnapshotHeight;
+    int  mPreviewFormat;
+    int  mFps;
+    int  mDebugFps;
+    int  mBrightness;
+    int  mContrast;
+    int  mBestShotMode;
+    int  mEffects;
+    int  mSkinToneEnhancement;
+    int  mDenoiseValue;
+    int  mHJR;
+    int  mRotation;
+    int  mJpegQuality;
+    int  mThumbnailQuality;
+    int  mTargetSmoothZoom;
+    int  mSmoothZoomStep;
+    int  mMaxZoom;
+    int  mCurrentZoom;
+    int  mSupportedPictureSizesCount;
+    int  mFaceDetectOn;
+    int  mDumpFrmCnt;
+    int  mDumpSkipCnt;
+    int  mFocusMode;
+
+    unsigned int mPictureSizeCount;
+    unsigned int mPreviewSizeCount;
+    int mPowerMode;
+    unsigned int mVideoSizeCount;
+
+    bool mAutoFocusRunning;
+    bool mMultiTouch;
+    bool mHasAutoFocusSupport;
+    bool mInitialized;
+    bool mDisEnabled;
+    bool strTexturesOn;
+    bool mIs3DModeOn;
+    bool mSmoothZoomRunning;
+    bool mPreparingSnapshot;
+    bool mParamStringInitialized;
+    bool mZoomSupported;
+    bool mSendMetaData;
+    bool mFullLiveshotEnabled;
+    bool mRecordingHint;
+    bool mStartRecording;
+    bool mReleasedRecordingFrame;
+    int mHdrMode;
+    int mSnapshotFormat;
+    int mZslInterval;
+    bool mRestartPreview;
+
+/*for histogram*/
+    int            mStatsOn;
+    int            mCurrentHisto;
+    bool           mSendData;
+    sp<AshmemPool> mStatHeap;
+    camera_memory_t *mStatsMapped[3];
+    QCameraStatHeap_t mHistServer;
+    int32_t        mStatSize;
+
+    bool mZslLookBackMode;
+    int mZslLookBackValue;
+	int mHFRLevel;
+    bool mZslEmptyQueueFlag;
+    String8 mEffectValues;
+    String8 mIsoValues;
+    String8 mSceneModeValues;
+    String8 mSceneDetectValues;
+    String8 mFocusModeValues;
+    String8 mSelectableZoneAfValues;
+    String8 mAutoExposureValues;
+    String8 mWhitebalanceValues;
+    String8 mAntibandingValues;
+    String8 mFrameRateModeValues;
+    String8 mTouchAfAecValues;
+    String8 mPreviewSizeValues;
+    String8 mPictureSizeValues;
+    String8 mVideoSizeValues;
+    String8 mFlashValues;
+    String8 mLensShadeValues;
+    String8 mMceValues;
+    String8 mHistogramValues;
+    String8 mSkinToneEnhancementValues;
+    String8 mPictureFormatValues;
+    String8 mDenoiseValues;
+    String8 mZoomRatioValues;
+    String8 mPreviewFrameRateValues;
+    String8 mPreviewFormatValues;
+    String8 mFaceDetectionValues;
+    String8 mHfrValues;
+    String8 mHfrSizeValues;
+    String8 mRedeyeReductionValues;
+    String8 denoise_value;
+    String8 mFpsRangesSupportedValues;
+    String8 mZslValues;
+    String8 mFocusDistance;
+
+    friend class QCameraStream;
+    friend class QCameraStream_record;
+    friend class QCameraStream_preview;
+    friend class QCameraStream_Snapshot;
+
+    camera_size_type* mPictureSizes;
+    camera_size_type* mPreviewSizes;
+    camera_size_type* mVideoSizes;
+    const camera_size_type * mPictureSizesPtr;
+    HAL_camera_state_type_t mCameraState;
+
+     /* Temporary - can be removed after Honeycomb*/
+#ifdef USE_ION
+    sp<IonPool>  mPostPreviewHeap;
+#else
+    sp<PmemPool> mPostPreviewHeap;
+#endif
+     mm_cameara_stream_buf_t mPrevForPostviewBuf;
+     int mStoreMetaDataInFrame;
+     preview_stream_ops_t *mPreviewWindow;
+     Mutex                mStateLock;
+     int                  mPreviewState;
+     /*preview memory with display case: memory is allocated and freed via
+     gralloc */
+     QCameraHalMemory_t   mPreviewMemory;
+
+     /*preview memory without display case: memory is allocated
+      directly by camera */
+     QCameraHalHeap_t     mNoDispPreviewMemory;
+
+     QCameraHalHeap_t     mSnapshotMemory;
+     QCameraHalHeap_t     mThumbnailMemory;
+     QCameraHalHeap_t     mRecordingMemory;
+     QCameraHalHeap_t     mJpegMemory;
+     QCameraHalHeap_t     mRawMemory;
+     camera_frame_metadata_t mMetadata;
+     camera_face_t           mFace[MAX_ROI];
+     preview_format_info_t  mPreviewFormatInfo;
+     friend void liveshot_callback(mm_camera_ch_data_buf_t *frame,void *user_data);
+
+     //EXIF
+     exif_tags_info_t       mExifData[MAX_EXIF_TABLE_ENTRIES];  //Exif tags for JPEG encoder
+     exif_values_t          mExifValues;                        //Exif values in usable format
+     int                    mExifTableNumEntries;            //NUmber of entries in mExifData
+     int                 mNoDisplayMode;
+};
+
+}; // namespace android
+
+#endif
diff --git a/camera/QCamera/HAL/core/inc/QCameraHWI_Mem.h b/camera/QCamera/HAL/core/inc/QCameraHWI_Mem.h
new file mode 100755
index 0000000..079b0f9
--- /dev/null
+++ b/camera/QCamera/HAL/core/inc/QCameraHWI_Mem.h
@@ -0,0 +1,111 @@
+/*
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+
+#ifndef __QCAMERAHWI_MEM_H
+#define __QCAMERAHWI_MEM_H
+
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <utils/threads.h>
+#include <stdint.h>
+
+extern "C" {
+#include <linux/android_pmem.h>
+#include <linux/ion.h>
+#include <camera.h>
+#include <camera_defs_i.h>
+
+}
+
+
+#define VIDEO_BUFFER_COUNT 5
+#define VIDEO_BUFFER_COUNT_LOW_POWER_CAMCORDER 9
+
+#define PREVIEW_BUFFER_COUNT 5
+
+namespace android {
+
+// This class represents a heap which maintains several contiguous
+// buffers.  The heap may be backed by pmem (when pmem_pool contains
+// the name of a /dev/pmem* file), or by ashmem (when pmem_pool == NULL).
+
+struct MemPool : public RefBase {
+    MemPool(int buffer_size, int num_buffers,
+            int frame_size,
+            const char *name);
+
+    virtual ~MemPool() = 0;
+
+    void completeInitialization();
+    bool initialized() const {
+        return mHeap != NULL && mHeap->base() != MAP_FAILED;
+    }
+
+    virtual status_t dump(int fd, const Vector<String16>& args) const;
+
+    int mBufferSize;
+    int mAlignedBufferSize;
+    int mNumBuffers;
+    int mFrameSize;
+    sp<MemoryHeapBase> mHeap;
+    sp<MemoryBase> *mBuffers;
+
+    const char *mName;
+};
+
+class AshmemPool : public MemPool {
+public:
+    AshmemPool(int buffer_size, int num_buffers,
+               int frame_size,
+               const char *name);
+};
+
+class PmemPool : public MemPool {
+public:
+    PmemPool(const char *pmem_pool,
+             int flags, int pmem_type,
+             int buffer_size, int num_buffers,
+             int frame_size, int cbcr_offset,
+             int yoffset, const char *name);
+    virtual ~PmemPool();
+    int mFd;
+    int mPmemType;
+    int mCbCrOffset;
+    int myOffset;
+    int mCameraControlFd;
+    uint32_t mAlignedSize;
+    struct pmem_region mSize;
+};
+
+class IonPool : public MemPool {
+public:
+    IonPool( int flags,
+             int buffer_size, int num_buffers,
+             int frame_size, int cbcr_offset,
+             int yoffset, const char *name);
+    virtual ~IonPool();
+    int mFd;
+    int mCbCrOffset;
+    int myOffset;
+    int mCameraControlFd;
+    uint32_t mAlignedSize;
+private:
+    static const char mIonDevName[];
+};
+
+};
+#endif
diff --git a/camera/QCamera/HAL/core/inc/QCameraStream.h b/camera/QCamera/HAL/core/inc/QCameraStream.h
new file mode 100755
index 0000000..8c416e4
--- /dev/null
+++ b/camera/QCamera/HAL/core/inc/QCameraStream.h
@@ -0,0 +1,377 @@
+/*
+** Copyright 2008, Google Inc.
+** Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_HARDWARE_QCAMERA_STREAM_H
+#define ANDROID_HARDWARE_QCAMERA_STREAM_H
+
+
+#include <utils/threads.h>
+
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <utils/threads.h>
+
+#include "QCameraHWI.h"
+#include "QCameraHWI_Mem.h"
+
+extern "C" {
+
+#include <camera.h>
+#include <camera_defs_i.h>
+#include <mm_camera_interface2.h>
+
+#define DEFAULT_STREAM_WIDTH 320
+#define DEFAULT_STREAM_HEIGHT 240
+#define DEFAULT_LIVESHOT_WIDTH 2592
+#define DEFAULT_LIVESHOT_HEIGHT 1944
+
+#define MM_CAMERA_CH_PREVIEW_MASK    (0x01 << MM_CAMERA_CH_PREVIEW)
+#define MM_CAMERA_CH_VIDEO_MASK      (0x01 << MM_CAMERA_CH_VIDEO)
+#define MM_CAMERA_CH_SNAPSHOT_MASK   (0x01 << MM_CAMERA_CH_SNAPSHOT)
+
+} /* extern C*/
+
+
+namespace android {
+
+class QCameraHardwareInterface;
+
+class StreamQueue {
+private:
+    Mutex mQueueLock;
+    Condition mQueueWait;
+    bool mInitialized;
+
+    //Vector<struct msm_frame *> mContainer;
+    Vector<void *> mContainer;
+public:
+    StreamQueue();
+    virtual ~StreamQueue();
+    bool enqueue(void *element);
+    void flush();
+    void* dequeue();
+    void init();
+    void deinit();
+    bool isInitialized();
+bool isEmpty();
+};
+
+
+class QCameraStream { //: public virtual RefBase{
+
+public:
+    bool mInit;
+    bool mActive;
+
+    virtual status_t    init();
+    virtual status_t    start();
+    virtual void        stop();
+    virtual void        release();
+
+    status_t setFormat(uint8_t ch_type_mask);
+    status_t setMode(int enable);
+
+    virtual void        setHALCameraControl(QCameraHardwareInterface* ctrl);
+
+    //static status_t     openChannel(mm_camera_t *, mm_camera_channel_type_t ch_type);
+    virtual status_t    initChannel(int cameraId, uint32_t ch_type_mask);
+    virtual status_t    deinitChannel(int cameraId, mm_camera_channel_type_t ch_type);
+    virtual void releaseRecordingFrame(const void *opaque)
+    {
+      ;
+    }
+#if 0 // mzhu
+    virtual status_t getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize)
+    {
+      return NO_ERROR;
+    }
+#endif // mzhu
+    virtual void prepareHardware()
+    {
+      ;
+    }
+    virtual sp<IMemoryHeap> getHeap() const{return NULL;}
+    virtual status_t    initDisplayBuffers(){return NO_ERROR;}
+    virtual status_t initPreviewOnlyBuffers(){return NO_ERROR;}
+    virtual sp<IMemoryHeap> getRawHeap() const {return NULL;}
+    virtual void *getLastQueuedFrame(void){return NULL;}
+    virtual status_t takePictureZSL(void){return NO_ERROR;}
+    virtual status_t takeLiveSnapshot(){return NO_ERROR;}
+    virtual status_t takePictureLiveshot(mm_camera_ch_data_buf_t* recvd_frame,
+                                 cam_ctrl_dimension_t *dim,
+                                 int frame_len){return NO_ERROR;}
+	virtual void setModeLiveSnapshot(bool){;}
+    virtual status_t initSnapshotBuffers(cam_ctrl_dimension_t *dim,
+                                 int num_of_buf){return NO_ERROR;}
+
+    virtual void setFullSizeLiveshot(bool){};
+    /* Set the ANativeWindow */
+    virtual int setPreviewWindow(preview_stream_ops_t* window) {return NO_ERROR;}
+    virtual void notifyROIEvent(fd_roi_t roi) {;}
+    virtual void notifyWDenoiseEvent(cam_ctrl_status_t status, void * cookie) {;}
+    virtual void resetSnapshotCounters(void ){};
+
+    QCameraStream();
+    QCameraStream(int, camera_mode_t);
+    virtual             ~QCameraStream();
+    QCameraHardwareInterface*  mHalCamCtrl;
+    mm_camera_ch_crop_t mCrop;
+
+    int mCameraId;
+    camera_mode_t myMode;
+
+    mutable Mutex mStopCallbackLock;
+private:
+   StreamQueue mBusyQueue;
+   StreamQueue mFreeQueue;
+public:
+     friend void liveshot_callback(mm_camera_ch_data_buf_t *frame,void *user_data);
+};
+
+/*
+*   Record Class
+*/
+class QCameraStream_record : public QCameraStream {
+public:
+  status_t    init();
+  status_t    start() ;
+  void        stop()  ;
+  void        release() ;
+
+  static QCameraStream*  createInstance(int cameraId, camera_mode_t);
+  static void            deleteInstance(QCameraStream *p);
+
+  QCameraStream_record() {};
+  virtual             ~QCameraStream_record();
+
+  status_t processRecordFrame(void *data);
+  status_t initEncodeBuffers();
+  status_t getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize);
+  //sp<IMemoryHeap> getHeap() const;
+
+  void releaseRecordingFrame(const void *opaque);
+  void debugShowVideoFPS() const;
+
+  status_t takeLiveSnapshot();
+private:
+  QCameraStream_record(int, camera_mode_t);
+  void releaseEncodeBuffer();
+
+  cam_ctrl_dimension_t             dim;
+  bool mDebugFps;
+
+  mm_camera_reg_buf_t              mRecordBuf;
+  //int                              record_frame_len;
+  //static const int                 maxFrameCnt = 16;
+  //camera_memory_t                 *mCameraMemoryPtr[maxFrameCnt];
+  //int                              mNumRecordFrames;
+  //sp<PmemPool>                     mRecordHeap[maxFrameCnt];
+  struct msm_frame                *recordframes;
+  //uint32_t                         record_offset[VIDEO_BUFFER_COUNT];
+  mm_camera_ch_data_buf_t          mRecordedFrames[MM_CAMERA_MAX_NUM_FRAMES];
+  //Mutex                            mRecordFreeQueueLock;
+  //Vector<mm_camera_ch_data_buf_t>  mRecordFreeQueue;
+
+  int mJpegMaxSize;
+  QCameraStream *mStreamSnap;
+
+};
+
+class QCameraStream_preview : public QCameraStream {
+public:
+    status_t    init();
+    status_t    start() ;
+    void        stop()  ;
+    void        release() ;
+
+    static QCameraStream*  createInstance(int, camera_mode_t);
+    static void            deleteInstance(QCameraStream *p);
+
+    QCameraStream_preview() {};
+    virtual             ~QCameraStream_preview();
+    void *getLastQueuedFrame(void);
+    /*init preview buffers with display case*/
+    status_t initDisplayBuffers();
+    /*init preview buffers without display case*/
+    status_t initPreviewOnlyBuffers();
+
+    status_t processPreviewFrame(mm_camera_ch_data_buf_t *frame);
+
+    /*init preview buffers with display case*/
+    status_t processPreviewFrameWithDisplay(mm_camera_ch_data_buf_t *frame);
+    /*init preview buffers without display case*/
+    status_t processPreviewFrameWithOutDisplay(mm_camera_ch_data_buf_t *frame);
+
+    int setPreviewWindow(preview_stream_ops_t* window);
+    void notifyROIEvent(fd_roi_t roi);
+    friend class QCameraHardwareInterface;
+
+private:
+    QCameraStream_preview(int cameraId, camera_mode_t);
+    /*allocate and free buffers with display case*/
+    status_t                 getBufferFromSurface();
+    status_t                 putBufferToSurface();
+
+    /*allocate and free buffers without display case*/
+    status_t                 getBufferNoDisplay();
+    status_t                 freeBufferNoDisplay();
+
+    void                     dumpFrameToFile(struct msm_frame* newFrame);
+    bool                     mFirstFrameRcvd;
+
+    int8_t                   my_id;
+    mm_camera_op_mode_type_t op_mode;
+    cam_ctrl_dimension_t     dim;
+    struct msm_frame        *mLastQueuedFrame;
+    mm_camera_reg_buf_t      mDisplayBuf;
+    mm_cameara_stream_buf_t  mDisplayStreamBuf;
+    Mutex                   mDisplayLock;
+    preview_stream_ops_t   *mPreviewWindow;
+    static const int        kPreviewBufferCount = PREVIEW_BUFFER_COUNT;
+    mm_camera_ch_data_buf_t mNotifyBuffer[16];
+    int8_t                  mNumFDRcvd;
+    int                     mVFEOutputs;
+    int                     mHFRFrameCnt;
+    int                     mHFRFrameSkip;
+};
+
+/* Snapshot Class - handle data flow*/
+class QCameraStream_Snapshot : public QCameraStream {
+public:
+    status_t    init();
+    status_t    start();
+    void        stop();
+    void        release();
+    void        prepareHardware();
+    static QCameraStream* createInstance(int cameraId, camera_mode_t);
+    static void deleteInstance(QCameraStream *p);
+
+    status_t takePictureZSL(void);
+    status_t takePictureLiveshot(mm_camera_ch_data_buf_t* recvd_frame,
+                                 cam_ctrl_dimension_t *dim,
+                                 int frame_len);
+    status_t receiveRawPicture(mm_camera_ch_data_buf_t* recvd_frame);
+    void receiveCompleteJpegPicture(jpeg_event_t event);
+    void receiveJpegFragment(uint8_t *ptr, uint32_t size);
+    void deInitBuffer(void);
+    sp<IMemoryHeap> getRawHeap() const;
+    int getSnapshotState();
+    /*Temp: to be removed once event handling is enabled in mm-camera*/
+    void runSnapshotThread(void *data);
+    bool isZSLMode();
+    void setFullSizeLiveshot(bool);
+    void notifyWDenoiseEvent(cam_ctrl_status_t status, void * cookie);
+    friend void liveshot_callback(mm_camera_ch_data_buf_t *frame,void *user_data);
+    void resetSnapshotCounters(void );
+
+private:
+    QCameraStream_Snapshot(int, camera_mode_t);
+    virtual ~QCameraStream_Snapshot();
+
+    /* snapshot related private members */
+    status_t initJPEGSnapshot(int num_of_snapshots);
+    status_t initRawSnapshot(int num_of_snapshots);
+    status_t initZSLSnapshot(void);
+    status_t initFullLiveshot(void);
+	status_t cancelPicture();
+    void notifyShutter(common_crop_t *crop,
+                       bool play_shutter_sound);
+    status_t initSnapshotBuffers(cam_ctrl_dimension_t *dim,
+                                 int num_of_buf);
+    status_t initRawSnapshotBuffers(cam_ctrl_dimension_t *dim,
+                                    int num_of_buf);
+    status_t deinitRawSnapshotBuffers(void);
+    status_t deinitSnapshotBuffers(void);
+    status_t initRawSnapshotChannel(cam_ctrl_dimension_t* dim,
+                                    int num_snapshots);
+    status_t initSnapshotFormat(cam_ctrl_dimension_t *dim);
+    status_t takePictureRaw(void);
+    status_t takePictureJPEG(void);
+    status_t startStreamZSL(void);
+    void deinitSnapshotChannel(mm_camera_channel_type_t);
+    status_t configSnapshotDimension(cam_ctrl_dimension_t* dim);
+    status_t encodeData(mm_camera_ch_data_buf_t* recvd_frame,
+                        common_crop_t *crop_info,
+                        int frame_len,
+                        bool enqueued);
+    status_t encodeDisplayAndSave(mm_camera_ch_data_buf_t* recvd_frame,
+                                  bool enqueued);
+    status_t setZSLChannelAttribute(void);
+    void handleError();
+    void setSnapshotState(int state);
+    void setModeLiveSnapshot(bool);
+    bool isLiveSnapshot(void);
+    void stopPolling(void);
+    bool isFullSizeLiveshot(void);
+    status_t doWaveletDenoise(mm_camera_ch_data_buf_t* frame);
+    status_t sendWDenoiseStartMsg(mm_camera_ch_data_buf_t * frame);
+    void lauchNextWDenoiseFromQueue();
+
+    /* Member variables */
+
+    int mSnapshotFormat;
+    int mPictureWidth;
+    int mPictureHeight;
+    cam_format_t mPictureFormat;
+    int mPostviewWidth;
+    int mPostviewHeight;
+    int mThumbnailWidth;
+    int mThumbnailHeight;
+    cam_format_t mThumbnailFormat;
+	int mJpegOffset;
+    int mSnapshotState;
+    int mNumOfSnapshot;
+	int mNumOfRecievedJPEG;
+    bool mModeLiveSnapshot;
+    bool mBurstModeFlag;
+	int mActualPictureWidth;
+    int mActualPictureHeight;
+    bool mJpegDownscaling;
+    sp<AshmemPool> mJpegHeap;
+    /*TBD:Bikas: This is defined in HWI too.*/
+#ifdef USE_ION
+    sp<IonPool>  mDisplayHeap;
+    sp<IonPool>  mPostviewHeap;
+#else
+    sp<PmemPool>  mDisplayHeap;
+    sp<PmemPool>  mPostviewHeap;
+#endif
+    mm_camera_ch_data_buf_t *mCurrentFrameEncoded;
+    mm_cameara_stream_buf_t mSnapshotStreamBuf;
+    mm_cameara_stream_buf_t mPostviewStreamBuf;
+    StreamQueue             mSnapshotQueue;
+    static const int        mMaxSnapshotBufferCount = 16;
+    int                     mSnapshotBufferNum;
+    int                     mMainfd[mMaxSnapshotBufferCount];
+    int                     mThumbfd[mMaxSnapshotBufferCount];
+    int                     mMainSize;
+    int                     mThumbSize;
+	camera_memory_t        *mCameraMemoryPtrMain[mMaxSnapshotBufferCount];
+	camera_memory_t        *mCameraMemoryPtrThumb[mMaxSnapshotBufferCount];
+    int                     mJpegSessionId;
+	int                     dump_fd;
+    bool mFullLiveshot;
+    StreamQueue             mWDNQueue; // queue to hold frames while one frame is sent out for WDN
+    bool                    mIsDoingWDN; // flag to indicate if WDN is going on (one frame is sent out for WDN)
+	bool                    mDropThumbnail;
+	int                     mJpegQuality;
+}; // QCameraStream_Snapshot
+
+
+}; // namespace android
+
+#endif
diff --git a/camera/QCamera/HAL/core/src/QCameraHAL.cpp b/camera/QCamera/HAL/core/src/QCameraHAL.cpp
new file mode 100755
index 0000000..993405e
--- /dev/null
+++ b/camera/QCamera/HAL/core/src/QCameraHAL.cpp
@@ -0,0 +1,133 @@
+/*
+** Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+//#define LOG_NDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG "QCameraHAL"
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+
+/* include QCamera Hardware Interface Header*/
+#include "QCameraHAL.h"
+
+int HAL_numOfCameras = 0;
+camera_info_t HAL_cameraInfo[MSM_MAX_CAMERA_SENSORS];
+mm_camera_t * HAL_camerahandle[MSM_MAX_CAMERA_SENSORS];
+int HAL_currentCameraMode;
+
+namespace android {
+/* HAL function implementation goes here*/
+
+/**
+ * The functions need to be provided by the camera HAL.
+ *
+ * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
+ * and openCameraHardware() is 0 to N-1.
+ */
+extern "C" int HAL_getNumberOfCameras()
+{
+    /* try to query every time we get the call!*/
+    uint8_t num_camera = 0;
+    mm_camera_t * handle_base = 0;
+    LOGV("%s: E", __func__);
+
+    handle_base= mm_camera_query(&num_camera);
+
+    if (!handle_base) {
+        HAL_numOfCameras = 0;
+    }
+    else
+    {
+        camera_info_t* p_camera_info = 0;
+        HAL_numOfCameras=num_camera;
+
+        LOGI("Handle base =0x%p",handle_base);
+        LOGI("getCameraInfo: numOfCameras = %d", HAL_numOfCameras);
+        for(int i = 0; i < HAL_numOfCameras; i++) {
+            LOGI("Handle [%d]=0x%p",i,handle_base+i);
+            HAL_camerahandle[i]=handle_base + i;
+            p_camera_info = &(HAL_camerahandle[i]->camera_info);
+            if (p_camera_info) {
+                LOGI("Camera sensor %d info:", i);
+                LOGI("camera_id: %d", p_camera_info->camera_id);
+                LOGI("modes_supported: %x", p_camera_info->modes_supported);
+                LOGI("position: %d", p_camera_info->position);
+                LOGI("sensor_mount_angle: %d", p_camera_info->sensor_mount_angle);
+            }
+        }
+    }
+
+    LOGV("%s: X", __func__);
+
+    return HAL_numOfCameras;
+}
+
+extern "C" int HAL_isIn3DMode()
+{
+    return HAL_currentCameraMode == CAMERA_MODE_3D;
+}
+
+extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo)
+{
+    mm_camera_t *mm_camer_obj = 0;
+    LOGV("%s: E", __func__);
+
+    if (!HAL_numOfCameras || HAL_numOfCameras < cameraId || !cameraInfo)
+        return;
+    else
+        mm_camer_obj = HAL_camerahandle[cameraId];
+
+    if (!mm_camer_obj)
+        return;
+    else {
+        cameraInfo->facing =
+            (FRONT_CAMERA == mm_camer_obj->camera_info.position)?
+            CAMERA_FACING_FRONT : CAMERA_FACING_BACK;
+
+        cameraInfo->orientation = mm_camer_obj->camera_info.sensor_mount_angle;
+#if 0
+        // TODO: fix me
+        /* We always supprot ZSL in our stack*/
+        cameraInfo->mode = CAMERA_SUPPORT_MODE_ZSL;
+        if (mm_camer_obj->camera_info.modes_supported & CAMERA_MODE_2D) {
+            cameraInfo->mode |= CAMERA_SUPPORT_MODE_2D;
+        }
+        if (mm_camer_obj->camera_info.modes_supported & CAMERA_MODE_3D) {
+            cameraInfo->mode |= CAMERA_SUPPORT_MODE_3D;
+        }
+#endif
+    }
+   LOGV("%s: X", __func__);
+   return;
+}
+
+/* HAL should return NULL if it fails to open camera hardware. */
+extern "C" void * HAL_openCameraHardware(int cameraId, int mode)
+{
+    LOGV("%s: E", __func__);
+    if (!HAL_numOfCameras || HAL_numOfCameras < cameraId ||cameraId < 0) {
+      return NULL;
+    }
+    return QCameraHAL_openCameraHardware(cameraId, mode);
+}
+
+
+}; // namespace android
diff --git a/camera/QCamera/HAL/core/src/QCameraHWI.cpp b/camera/QCamera/HAL/core/src/QCameraHWI.cpp
new file mode 100755
index 0000000..64ef663
--- /dev/null
+++ b/camera/QCamera/HAL/core/src/QCameraHWI.cpp
@@ -0,0 +1,2497 @@
+/*
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+#define LOG_NIDEBUG 0
+
+#define LOG_TAG "QCameraHWI"
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "QCameraHAL.h"
+#include "QCameraHWI.h"
+
+/* QCameraHardwareInterface class implementation goes here*/
+/* following code implement the contol logic of this class*/
+
+namespace android {
+static void HAL_event_cb(mm_camera_event_t *evt, void *user_data)
+{
+  QCameraHardwareInterface *obj = (QCameraHardwareInterface *)user_data;
+  if (obj) {
+    obj->processEvent(evt);
+  } else {
+    LOGE("%s: NULL user_data", __func__);
+  }
+}
+
+int32_t QCameraHardwareInterface::createRecord()
+{
+    int32_t ret = MM_CAMERA_OK;
+    LOGV("%s : BEGIN",__func__);
+
+    /*
+    * Creating Instance of record stream.
+    */
+    LOGE("Mymode Record = %d",myMode);
+    mStreamRecord = QCameraStream_record::createInstance(mCameraId,
+                                                         myMode);
+
+    if (!mStreamRecord) {
+        LOGE("%s: error - can't creat record stream!", __func__);
+        return BAD_VALUE;
+    }
+
+    /* Store HAL object in record stream Object */
+    mStreamRecord->setHALCameraControl(this);
+
+    /*Init Channel */
+    ret = mStreamRecord->init();
+    if (MM_CAMERA_OK != ret){
+        LOGE("%s: error - can't init Record channel!", __func__);
+        return BAD_VALUE;
+    }
+    LOGV("%s : END",__func__);
+    return ret;
+}
+
+int32_t QCameraHardwareInterface::createSnapshot()
+{
+    int32_t ret = MM_CAMERA_OK;
+    LOGV("%s : BEGIN",__func__);
+
+    /*
+    * Creating Instance of Snapshot stream.
+    */
+    LOGE("Mymode Snap = %d",myMode);
+    mStreamSnap = QCameraStream_Snapshot::createInstance(mCameraId,
+                                                         myMode);
+    if (!mStreamSnap) {
+        LOGE("%s: error - can't creat snapshot stream!", __func__);
+        return BAD_VALUE;
+    }
+
+    /* Store HAL object in Snapshot stream Object */
+    mStreamSnap->setHALCameraControl(this);
+
+    /*Init Channel */
+    ret = mStreamSnap->init();
+    if (MM_CAMERA_OK != ret){
+        LOGE("%s: error - can't init Snapshot channel!", __func__);
+        return BAD_VALUE;
+    }
+    LOGV("%s : END",__func__);
+    return ret;
+}
+
+int32_t QCameraHardwareInterface::createPreview()
+{
+    int32_t ret = MM_CAMERA_OK;
+    LOGV("%s : BEGIN",__func__);
+
+    LOGE("Mymode Preview = %d",myMode);
+    mStreamDisplay = QCameraStream_preview::createInstance(mCameraId,
+                                                           myMode);
+    if (!mStreamDisplay) {
+        LOGE("%s: error - can't creat preview stream!", __func__);
+        return BAD_VALUE;
+    }
+
+    mStreamDisplay->setHALCameraControl(this);
+
+    /*now init all the buffers and send to steam object*/
+    ret = mStreamDisplay->init();
+    if (MM_CAMERA_OK != ret){
+        LOGE("%s: error - can't init Preview channel!", __func__);
+        return BAD_VALUE;
+    }
+    LOGV("%s : END",__func__);
+    return ret;
+}
+
+/* constructor */
+QCameraHardwareInterface::
+QCameraHardwareInterface(int cameraId, int mode)
+                  : mCameraId(cameraId),
+                    mParameters(),
+                    mMsgEnabled(0),
+                    mNotifyCb(0),
+                    mDataCb(0),
+                    mDataCbTimestamp(0),
+                    mCallbackCookie(0),
+                    //mPreviewHeap(0),
+                    mStreamDisplay (NULL), mStreamRecord(NULL), mStreamSnap(NULL),
+                    mFps(0),
+                    mDebugFps(0),
+                    mMaxZoom(0),
+                    mCurrentZoom(0),
+                    mSupportedPictureSizesCount(15),
+                    mDumpFrmCnt(0), mDumpSkipCnt(0),
+                    mPictureSizeCount(15),
+                    mPreviewSizeCount(13),
+                    mVideoSizeCount(0),
+                    mAutoFocusRunning(false),
+                    mHasAutoFocusSupport(false),
+                    mInitialized(false),
+                    mIs3DModeOn(0),
+                    mSmoothZoomRunning(false),
+                    mParamStringInitialized(false),
+                    mFaceDetectOn(0),
+                    mDisEnabled(0),
+                    mZoomSupported(false),
+                    mFullLiveshotEnabled(true),
+                    mRecordingHint(0),
+                    mStatsOn(0), mCurrentHisto(-1), mSendData(false), mStatHeap(NULL),
+                    mZslLookBackMode(0),
+                    mZslLookBackValue(0),
+                    mZslEmptyQueueFlag(FALSE),
+                    mPictureSizes(NULL),
+                    mVideoSizes(NULL),
+                    mCameraState(CAMERA_STATE_UNINITED),
+                    mPostPreviewHeap(NULL),
+                    mHdrMode(HDR_BRACKETING_OFF),
+                    mStreamLiveSnap(NULL),
+                    mExifTableNumEntries(0),
+                    mDenoiseValue(0),
+                    mSnapshotFormat(0),
+                    mStartRecording(0),
+                    mZslInterval(1),
+                    mNoDisplayMode(0),
+                    mBrightness(0),
+                    mContrast(0),
+                    mEffects(0),
+                    mBestShotMode(0),
+                    mHJR(0),
+                    mSkinToneEnhancement(0),
+                    mRotation(0),
+                    mFocusMode(AF_MODE_MAX),
+                    mPreviewFormat(CAMERA_YUV_420_NV21),
+                    mRestartPreview(false),
+                    mReleasedRecordingFrame(false)
+{
+    LOGI("QCameraHardwareInterface: E");
+    int32_t result = MM_CAMERA_E_GENERAL;
+    char value[PROPERTY_VALUE_MAX];
+
+    pthread_mutex_init(&mAsyncCmdMutex, NULL);
+    pthread_cond_init(&mAsyncCmdWait, NULL);
+
+    property_get("persist.debug.sf.showfps", value, "0");
+    mDebugFps = atoi(value);
+    mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+    mPreviewWindow = NULL;
+    property_get("camera.hal.fps", value, "0");
+    mFps = atoi(value);
+
+    LOGI("Init mPreviewState = %d", mPreviewState);
+
+    property_get("persist.camera.hal.multitouchaf", value, "0");
+    mMultiTouch = atoi(value);
+
+    property_get("persist.camera.full.liveshot", value, "1");
+    mFullLiveshotEnabled = atoi(value);
+
+    property_get("persist.camera.hal.dis", value, "0");
+    mDisEnabled = atoi(value);
+
+    /* Open camera stack! */
+    result=cam_ops_open(mCameraId, MM_CAMERA_OP_MODE_NOTUSED);
+    if (result == MM_CAMERA_OK) {
+      int i;
+      mm_camera_event_type_t evt;
+      for (i = 0; i < MM_CAMERA_EVT_TYPE_MAX; i++) {
+        evt = (mm_camera_event_type_t) i;
+        if (cam_evt_is_event_supported(mCameraId, evt)){
+            cam_evt_register_event_notify(mCameraId,
+              HAL_event_cb, (void *)this, evt);
+        }
+      }
+    }
+    LOGV("Cam open returned %d",result);
+    if(MM_CAMERA_OK != result) {
+          LOGE("startCamera: cam_ops_open failed: id = %d", mCameraId);
+          return;
+    }
+
+    loadTables();
+    /* Setup Picture Size and Preview size tables */
+    setPictureSizeTable();
+    LOGD("%s: Picture table size: %d", __func__, mPictureSizeCount);
+    LOGD("%s: Picture table: ", __func__);
+    for(unsigned int i=0; i < mPictureSizeCount;i++) {
+      LOGD(" %d  %d", mPictureSizes[i].width, mPictureSizes[i].height);
+    }
+
+    setPreviewSizeTable();
+    LOGD("%s: Preview table size: %d", __func__, mPreviewSizeCount);
+    LOGD("%s: Preview table: ", __func__);
+    for(unsigned int i=0; i < mPreviewSizeCount;i++) {
+      LOGD(" %d  %d", mPreviewSizes[i].width, mPreviewSizes[i].height);
+    }
+
+    setVideoSizeTable();
+    LOGD("%s: Video table size: %d", __func__, mVideoSizeCount);
+    LOGD("%s: Video table: ", __func__);
+    for(unsigned int i=0; i < mVideoSizeCount;i++) {
+      LOGD(" %d  %d", mVideoSizes[i].width, mVideoSizes[i].height);
+    }
+
+    /* set my mode - update myMode member variable due to difference in
+     enum definition between upper and lower layer*/
+    setMyMode(mode);
+    initDefaultParameters();
+
+    //Create Stream Objects
+    //Preview
+    result = createPreview();
+    if(result != MM_CAMERA_OK) {
+        LOGE("%s X: Failed to create Preview Object",__func__);
+        return;
+    }
+
+    //Record
+    result = createRecord();
+    if(result != MM_CAMERA_OK) {
+        LOGE("%s X: Failed to create Record Object",__func__);
+        return;
+    }
+
+    //Snapshot
+    result = createSnapshot();
+    if(result != MM_CAMERA_OK) {
+        LOGE("%s X: Failed to create Record Object",__func__);
+        return;
+    }
+    mCameraState = CAMERA_STATE_READY;
+
+    LOGI("QCameraHardwareInterface: X");
+}
+
+QCameraHardwareInterface::~QCameraHardwareInterface()
+{
+    LOGI("~QCameraHardwareInterface: E");
+    int result;
+
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+        break;
+    case QCAMERA_HAL_PREVIEW_START:
+        break;
+    case QCAMERA_HAL_PREVIEW_STARTED:
+        stopPreview();
+    break;
+    case QCAMERA_HAL_RECORDING_STARTED:
+        stopRecordingInternal();
+        stopPreview();
+        break;
+    case QCAMERA_HAL_TAKE_PICTURE:
+        cancelPictureInternal();
+        break;
+    default:
+        break;
+    }
+    mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+
+    freePictureTable();
+    freeVideoSizeTable();
+    if(mStatHeap != NULL) {
+      mStatHeap.clear( );
+      mStatHeap = NULL;
+    }
+    /* Join the threads, complete operations and then delete
+       the instances. */
+    cam_ops_close(mCameraId);
+    if(mStreamDisplay){
+        QCameraStream_preview::deleteInstance (mStreamDisplay);
+        mStreamDisplay = NULL;
+    }
+    if(mStreamRecord) {
+        QCameraStream_record::deleteInstance (mStreamRecord);
+        mStreamRecord = NULL;
+    }
+    if(mStreamSnap) {
+        QCameraStream_Snapshot::deleteInstance (mStreamSnap);
+        mStreamSnap = NULL;
+    }
+
+    if (mStreamLiveSnap){
+        QCameraStream_Snapshot::deleteInstance (mStreamLiveSnap);
+        mStreamLiveSnap = NULL;
+    }
+
+    pthread_mutex_destroy(&mAsyncCmdMutex);
+    pthread_cond_destroy(&mAsyncCmdWait);
+
+    LOGI("~QCameraHardwareInterface: X");
+}
+
+bool QCameraHardwareInterface::isCameraReady()
+{
+    LOGE("isCameraReady mCameraState %d", mCameraState);
+    return (mCameraState == CAMERA_STATE_READY);
+}
+
+void QCameraHardwareInterface::release()
+{
+    LOGI("release: E");
+    Mutex::Autolock l(&mLock);
+
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+        break;
+    case QCAMERA_HAL_PREVIEW_START:
+        break;
+    case QCAMERA_HAL_PREVIEW_STARTED:
+        stopPreviewInternal();
+    break;
+    case QCAMERA_HAL_RECORDING_STARTED:
+        stopRecordingInternal();
+        stopPreviewInternal();
+        break;
+    case QCAMERA_HAL_TAKE_PICTURE:
+        cancelPictureInternal();
+        break;
+    default:
+        break;
+    }
+#if 0
+    if (isRecordingRunning()) {
+        stopRecordingInternal();
+        LOGI("release: stopRecordingInternal done.");
+    }
+    if (isPreviewRunning()) {
+        stopPreview(); //stopPreviewInternal();
+        LOGI("release: stopPreviewInternal done.");
+    }
+    if (isSnapshotRunning()) {
+        cancelPictureInternal();
+        LOGI("release: cancelPictureInternal done.");
+    }
+    if (mCameraState == CAMERA_STATE_ERROR) {
+        //TBD: If Error occurs then tear down
+        LOGI("release: Tear down.");
+    }
+#endif
+    mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+    LOGI("release: X");
+}
+
+void QCameraHardwareInterface::setCallbacks(
+    camera_notify_callback notify_cb,
+    camera_data_callback data_cb,
+    camera_data_timestamp_callback data_cb_timestamp,
+    camera_request_memory get_memory,
+    void *user)
+{
+    LOGE("setCallbacks: E");
+    Mutex::Autolock lock(mLock);
+    mNotifyCb        = notify_cb;
+    mDataCb          = data_cb;
+    mDataCbTimestamp = data_cb_timestamp;
+    mGetMemory       = get_memory;
+    mCallbackCookie  = user;
+    LOGI("setCallbacks: X");
+}
+
+void QCameraHardwareInterface::enableMsgType(int32_t msgType)
+{
+    LOGI("enableMsgType: E, msgType =0x%x", msgType);
+    Mutex::Autolock lock(mLock);
+    mMsgEnabled |= msgType;
+    LOGI("enableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
+}
+
+void QCameraHardwareInterface::disableMsgType(int32_t msgType)
+{
+    LOGI("disableMsgType: E");
+    Mutex::Autolock lock(mLock);
+    mMsgEnabled &= ~msgType;
+    LOGI("disableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
+}
+
+int QCameraHardwareInterface::msgTypeEnabled(int32_t msgType)
+{
+    LOGI("msgTypeEnabled: E");
+    Mutex::Autolock lock(mLock);
+    return (mMsgEnabled & msgType);
+    LOGI("msgTypeEnabled: X");
+}
+#if 0
+status_t QCameraHardwareInterface::dump(int fd, const Vector<String16>& args) const
+{
+    LOGI("dump: E");
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    AutoMutex lock(&mLock);
+    write(fd, result.string(), result.size());
+    LOGI("dump: E");
+    return NO_ERROR;
+}
+#endif
+
+int QCameraHardwareInterface::dump(int fd)
+{
+    LOGE("%s: not supported yet", __func__);
+    return -1;
+}
+
+status_t QCameraHardwareInterface::sendCommand(int32_t command, int32_t arg1,
+                                         int32_t arg2)
+{
+    LOGI("sendCommand: E");
+    status_t rc = NO_ERROR;
+    Mutex::Autolock l(&mLock);
+
+    switch (command) {
+        case CAMERA_CMD_HISTOGRAM_ON:
+            LOGE("histogram set to on");
+            rc = setHistogram(1);
+            break;
+        case CAMERA_CMD_HISTOGRAM_OFF:
+            LOGE("histogram set to off");
+            rc = setHistogram(0);
+            break;
+        case CAMERA_CMD_HISTOGRAM_SEND_DATA:
+            LOGE("histogram send data");
+            mSendData = true;
+            rc = NO_ERROR;
+            break;
+        case CAMERA_CMD_START_FACE_DETECTION:
+           if(supportsFaceDetection() == false){
+                LOGE("Face detection support is not available");
+                return NO_ERROR;
+           }
+           setFaceDetection("on");
+           return runFaceDetection();
+        case CAMERA_CMD_STOP_FACE_DETECTION:
+           if(supportsFaceDetection() == false){
+                LOGE("Face detection support is not available");
+                return NO_ERROR;
+           }
+           setFaceDetection("off");
+           return runFaceDetection();
+#if 0
+        case CAMERA_CMD_SEND_META_DATA:
+           mMetaDataWaitLock.lock();
+           if(mFaceDetectOn == true) {
+               mSendMetaData = true;
+           }
+           mMetaDataWaitLock.unlock();
+           return NO_ERROR;
+#endif
+#if 0 /* To Do: will enable it later */
+        case CAMERA_CMD_START_SMOOTH_ZOOM :
+            LOGV("HAL sendcmd start smooth zoom %d %d", arg1 , arg2);
+            /*TO DO: get MaxZoom from parameter*/
+            int MaxZoom = 100;
+
+            switch(mCameraState ) {
+                case CAMERA_STATE_PREVIEW:
+                case CAMERA_STATE_RECORD_CMD_SENT:
+                case CAMERA_STATE_RECORD:
+                    mTargetSmoothZoom = arg1;
+                    mCurrentZoom = mParameters.getInt("zoom");
+                    mSmoothZoomStep = (mCurrentZoom > mTargetSmoothZoom)? -1: 1;
+                   if(mCurrentZoom == mTargetSmoothZoom) {
+                        LOGV("Smoothzoom target zoom value is same as "
+                        "current zoom value, return...");
+                        mNotifyCallback(CAMERA_MSG_ZOOM,
+                        mCurrentZoom, 1, mCallbackCookie);
+                    } else if(mCurrentZoom < 0 || mCurrentZoom > MaxZoom ||
+                        mTargetSmoothZoom < 0 || mTargetSmoothZoom > MaxZoom)  {
+                        LOGE(" ERROR : beyond supported zoom values, break..");
+                        mNotifyCallback(CAMERA_MSG_ZOOM,
+                        mCurrentZoom, 0, mCallbackCookie);
+                    } else {
+                        mSmoothZoomRunning = true;
+                        mCurrentZoom += mSmoothZoomStep;
+                        if ((mSmoothZoomStep < 0 && mCurrentZoom < mTargetSmoothZoom)||
+                        (mSmoothZoomStep > 0 && mCurrentZoom > mTargetSmoothZoom )) {
+                            mCurrentZoom = mTargetSmoothZoom;
+                        }
+                        mParameters.set("zoom", mCurrentZoom);
+                        setZoom(mParameters);
+                    }
+                    break;
+                default:
+                    LOGV(" No preview, no smoothzoom ");
+                    break;
+            }
+            rc = NO_ERROR;
+            break;
+
+        case CAMERA_CMD_STOP_SMOOTH_ZOOM:
+            if(mSmoothZoomRunning) {
+                mSmoothZoomRunning = false;
+                /*To Do: send cmd to stop zooming*/
+            }
+            LOGV("HAL sendcmd stop smooth zoom");
+            rc = NO_ERROR;
+            break;
+#endif
+        default:
+            break;
+    }
+    LOGI("sendCommand: X");
+    return rc;
+}
+
+void QCameraHardwareInterface::setMyMode(int mode)
+{
+    LOGI("setMyMode: E");
+    if (mode & CAMERA_SUPPORT_MODE_3D) {
+        myMode = CAMERA_MODE_3D;
+    }else {
+        /* default mode is 2D */
+        myMode = CAMERA_MODE_2D;
+    }
+
+    if (mode & CAMERA_SUPPORT_MODE_ZSL) {
+        myMode = (camera_mode_t)(myMode |CAMERA_ZSL_MODE);
+    }else {
+        myMode = (camera_mode_t) (myMode | CAMERA_NONZSL_MODE);
+    }
+    LOGI("setMyMode: Set mode to %d (passed mode: %d)", myMode, mode);
+    LOGI("setMyMode: X");
+}
+/* static factory function */
+QCameraHardwareInterface *QCameraHardwareInterface::createInstance(int cameraId, int mode)
+{
+    LOGI("createInstance: E");
+    QCameraHardwareInterface *cam = new QCameraHardwareInterface(cameraId, mode);
+    if (cam ) {
+      if (cam->mCameraState != CAMERA_STATE_READY) {
+        LOGE("createInstance: Failed");
+        delete cam;
+        cam = NULL;
+      }
+    }
+
+    if (cam) {
+      //sp<CameraHardwareInterface> hardware(cam);
+      LOGI("createInstance: X");
+      return cam;
+    } else {
+      return NULL;
+    }
+}
+/* external plug in function */
+extern "C" void *
+QCameraHAL_openCameraHardware(int  cameraId, int mode)
+{
+    LOGI("QCameraHAL_openCameraHardware: E");
+    return (void *) QCameraHardwareInterface::createInstance(cameraId, mode);
+}
+
+#if 0
+bool QCameraHardwareInterface::useOverlay(void)
+{
+    LOGI("useOverlay: E");
+    mUseOverlay = TRUE;
+    LOGI("useOverlay: X");
+    return mUseOverlay;
+}
+#endif
+
+bool QCameraHardwareInterface::isPreviewRunning() {
+    LOGI("isPreviewRunning: E");
+    bool ret = false;
+    LOGI("isPreviewRunning: camera state:%d", mCameraState);
+
+    if((mCameraState == CAMERA_STATE_PREVIEW) ||
+       (mCameraState == CAMERA_STATE_PREVIEW_START_CMD_SENT) ||
+       (mCameraState == CAMERA_STATE_RECORD) ||
+       (mCameraState == CAMERA_STATE_RECORD_START_CMD_SENT) ||
+       (mCameraState == CAMERA_STATE_ZSL) ||
+       (mCameraState == CAMERA_STATE_ZSL_START_CMD_SENT)){
+       return true;
+    }
+    LOGI("isPreviewRunning: X");
+    return ret;
+}
+
+bool QCameraHardwareInterface::isRecordingRunning() {
+    LOGE("isRecordingRunning: E");
+    bool ret = false;
+    if(QCAMERA_HAL_RECORDING_STARTED == mPreviewState)
+      ret = true;
+    //if((mCameraState == CAMERA_STATE_RECORD) ||
+    //   (mCameraState == CAMERA_STATE_RECORD_START_CMD_SENT)) {
+    //   return true;
+    //}
+    LOGE("isRecordingRunning: X");
+    return ret;
+}
+
+bool QCameraHardwareInterface::isSnapshotRunning() {
+    LOGE("isSnapshotRunning: E");
+    bool ret = false;
+    //if((mCameraState == CAMERA_STATE_SNAP_CMD_ACKED) ||
+    //   (mCameraState == CAMERA_STATE_SNAP_START_CMD_SENT)) {
+    //    return true;
+    //}
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+    case QCAMERA_HAL_PREVIEW_START:
+    case QCAMERA_HAL_PREVIEW_STARTED:
+    case QCAMERA_HAL_RECORDING_STARTED:
+    default:
+        break;
+    case QCAMERA_HAL_TAKE_PICTURE:
+        ret = true;
+        break;
+    }
+    LOGI("isSnapshotRunning: X");
+    return ret;
+}
+
+bool QCameraHardwareInterface::isZSLMode() {
+    return (myMode & CAMERA_ZSL_MODE);
+}
+
+int QCameraHardwareInterface::getHDRMode() {
+    return mHdrMode;
+}
+
+void QCameraHardwareInterface::debugShowPreviewFPS() const
+{
+    static int mFrameCount;
+    static int mLastFrameCount = 0;
+    static nsecs_t mLastFpsTime = 0;
+    static float mFps = 0;
+    mFrameCount++;
+    nsecs_t now = systemTime();
+    nsecs_t diff = now - mLastFpsTime;
+    if (diff > ms2ns(250)) {
+        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
+        LOGI("Preview Frames Per Second: %.4f", mFps);
+        mLastFpsTime = now;
+        mLastFrameCount = mFrameCount;
+    }
+}
+
+void QCameraHardwareInterface::
+processPreviewChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
+    LOGI("processPreviewChannelEvent: E");
+    switch(channelEvent) {
+        case MM_CAMERA_CH_EVT_STREAMING_ON:
+            mCameraState =
+                isZSLMode() ? CAMERA_STATE_ZSL : CAMERA_STATE_PREVIEW;
+            break;
+        case MM_CAMERA_CH_EVT_STREAMING_OFF:
+            mCameraState = CAMERA_STATE_READY;
+            break;
+        case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
+            break;
+        default:
+            break;
+    }
+    LOGI("processPreviewChannelEvent: X");
+    return;
+}
+
+void QCameraHardwareInterface::processRecordChannelEvent(
+  mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
+    LOGI("processRecordChannelEvent: E");
+    switch(channelEvent) {
+        case MM_CAMERA_CH_EVT_STREAMING_ON:
+            mCameraState = CAMERA_STATE_RECORD;
+            break;
+        case MM_CAMERA_CH_EVT_STREAMING_OFF:
+            mCameraState = CAMERA_STATE_PREVIEW;
+            break;
+        case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
+            break;
+        default:
+            break;
+    }
+    LOGI("processRecordChannelEvent: X");
+    return;
+}
+
+void QCameraHardwareInterface::
+processSnapshotChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
+    LOGI("processSnapshotChannelEvent: E evt=%d state=%d", channelEvent,
+      mCameraState);
+    switch(channelEvent) {
+        case MM_CAMERA_CH_EVT_STREAMING_ON:
+          if (!mFullLiveshotEnabled) {
+            mCameraState =
+              isZSLMode() ? CAMERA_STATE_ZSL : CAMERA_STATE_SNAP_CMD_ACKED;
+          }
+          break;
+        case MM_CAMERA_CH_EVT_STREAMING_OFF:
+          if (!mFullLiveshotEnabled) {
+            mCameraState = CAMERA_STATE_READY;
+          }
+          break;
+        case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
+            break;
+        case MM_CAMERA_CH_EVT_DATA_REQUEST_MORE:
+            if (isZSLMode()) {
+                /* ZSL Mode: In ZSL Burst Mode, users may request for number of
+                snapshots larger than internal size of ZSL queue. So we'll need
+                process the remaining frames as they become available.
+                In such case, we'll get this event */
+                if(NULL != mStreamSnap)
+                  mStreamSnap->takePictureZSL();
+            }
+            break;
+        default:
+            break;
+    }
+    LOGI("processSnapshotChannelEvent: X");
+    return;
+}
+
+void QCameraHardwareInterface::processChannelEvent(
+  mm_camera_ch_event_t *event, app_notify_cb_t *app_cb)
+{
+    LOGI("processChannelEvent: E");
+    Mutex::Autolock lock(mLock);
+    switch(event->ch) {
+        case MM_CAMERA_CH_PREVIEW:
+            processPreviewChannelEvent(event->evt, app_cb);
+            break;
+        case MM_CAMERA_CH_VIDEO:
+            processRecordChannelEvent(event->evt, app_cb);
+            break;
+        case MM_CAMERA_CH_SNAPSHOT:
+            processSnapshotChannelEvent(event->evt, app_cb);
+            break;
+        default:
+            break;
+    }
+    LOGI("processChannelEvent: X");
+    return;
+}
+
+void QCameraHardwareInterface::processCtrlEvent(mm_camera_ctrl_event_t *event, app_notify_cb_t *app_cb)
+{
+    LOGI("processCtrlEvent: %d, E",event->evt);
+    Mutex::Autolock lock(mLock);
+    switch(event->evt)
+    {
+        case MM_CAMERA_CTRL_EVT_ZOOM_DONE:
+            zoomEvent(&event->status, app_cb);
+            break;
+        case MM_CAMERA_CTRL_EVT_AUTO_FOCUS_DONE:
+            autoFocusEvent(&event->status, app_cb);
+            break;
+        case MM_CAMERA_CTRL_EVT_PREP_SNAPSHOT:
+            break;
+        case MM_CAMERA_CTRL_EVT_WDN_DONE:
+            wdenoiseEvent(event->status, (void *)(event->cookie));
+            break;
+        case MM_CAMERA_CTRL_EVT_ERROR:
+            app_cb->notifyCb  = mNotifyCb;
+            app_cb->argm_notify.msg_type = CAMERA_MSG_ERROR;
+            app_cb->argm_notify.ext1 = CAMERA_ERROR_UNKNOWN;
+            app_cb->argm_notify.cookie =  mCallbackCookie;
+            break;
+       default:
+            break;
+    }
+    LOGI("processCtrlEvent: X");
+    return;
+}
+
+void  QCameraHardwareInterface::processStatsEvent(
+  mm_camera_stats_event_t *event, app_notify_cb_t *app_cb)
+{
+    LOGI("processStatsEvent: E");
+    if (!isPreviewRunning( )) {
+        LOGE("preview is not running");
+        return;
+    }
+
+    switch (event->event_id) {
+        case MM_CAMERA_STATS_EVT_HISTO:
+        {
+            LOGE("HAL process Histo: mMsgEnabled=0x%x, mStatsOn=%d, mSendData=%d, mDataCb=%p ",
+            (mMsgEnabled & CAMERA_MSG_STATS_DATA), mStatsOn, mSendData, mDataCb);
+            int msgEnabled = mMsgEnabled;
+            /*get stats buffer based on index*/
+            camera_preview_histogram_info* hist_info =
+                (camera_preview_histogram_info*) mHistServer.camera_memory[event->e.stats_histo.index]->data;
+
+            if(mStatsOn == QCAMERA_PARM_ENABLE && mSendData &&
+                            mDataCb && (msgEnabled & CAMERA_MSG_STATS_DATA) ) {
+                uint32_t *dest;
+                mSendData = false;
+                mCurrentHisto = (mCurrentHisto + 1) % 3;
+                // The first element of the array will contain the maximum hist value provided by driver.
+                *(uint32_t *)((unsigned int)(mStatsMapped[mCurrentHisto]->data)) = hist_info->max_value;
+                memcpy((uint32_t *)((unsigned int)mStatsMapped[mCurrentHisto]->data + sizeof(int32_t)),
+                                                    (uint32_t *)hist_info->buffer,(sizeof(int32_t) * 256));
+
+                app_cb->dataCb  = mDataCb;
+                app_cb->argm_data_cb.msg_type = CAMERA_MSG_STATS_DATA;
+                app_cb->argm_data_cb.data = mStatsMapped[mCurrentHisto];
+                app_cb->argm_data_cb.index = 0;
+                app_cb->argm_data_cb.metadata = NULL;
+                app_cb->argm_data_cb.cookie =  mCallbackCookie;
+            }
+            break;
+        }
+        default:
+        break;
+    }
+  LOGV("receiveCameraStats X");
+}
+
+void  QCameraHardwareInterface::processInfoEvent(
+  mm_camera_info_event_t *event, app_notify_cb_t *app_cb) {
+    LOGI("processInfoEvent: %d, E",event->event_id);
+    //Mutex::Autolock lock(eventLock);
+    switch(event->event_id)
+    {
+        case MM_CAMERA_INFO_EVT_ROI:
+            roiEvent(event->e.roi, app_cb);
+            break;
+        default:
+            break;
+    }
+    LOGI("processInfoEvent: X");
+    return;
+}
+
+void  QCameraHardwareInterface::processEvent(mm_camera_event_t *event)
+{
+    app_notify_cb_t app_cb;
+    LOGE("processEvent: type :%d E",event->event_type);
+    if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED){
+	LOGE("Stop recording issued. Return from process Event");
+        return;
+    }
+    memset(&app_cb, 0, sizeof(app_notify_cb_t));
+    switch(event->event_type)
+    {
+        case MM_CAMERA_EVT_TYPE_CH:
+            processChannelEvent(&event->e.ch, &app_cb);
+            break;
+        case MM_CAMERA_EVT_TYPE_CTRL:
+            processCtrlEvent(&event->e.ctrl, &app_cb);
+            break;
+        case MM_CAMERA_EVT_TYPE_STATS:
+            processStatsEvent(&event->e.stats, &app_cb);
+            break;
+        case MM_CAMERA_EVT_TYPE_INFO:
+            processInfoEvent(&event->e.info, &app_cb);
+            break;
+        default:
+            break;
+    }
+    LOGE(" App_cb Notify %p, datacb=%p", app_cb.notifyCb, app_cb.dataCb);
+    if (app_cb.notifyCb) {
+      app_cb.notifyCb(app_cb.argm_notify.msg_type,
+        app_cb.argm_notify.ext1, app_cb.argm_notify.ext2,
+        app_cb.argm_notify.cookie);
+    }
+    if (app_cb.dataCb) {
+      app_cb.dataCb(app_cb.argm_data_cb.msg_type,
+        app_cb.argm_data_cb.data, app_cb.argm_data_cb.index,
+        app_cb.argm_data_cb.metadata, app_cb.argm_data_cb.cookie);
+    }
+    LOGI("processEvent: X");
+    return;
+}
+
+bool QCameraHardwareInterface::preview_parm_config (cam_ctrl_dimension_t* dim,
+                                   CameraParameters& parm)
+{
+    LOGI("preview_parm_config: E");
+    bool matching = true;
+    int display_width = 0;  /* width of display      */
+    int display_height = 0; /* height of display */
+    uint16_t video_width = 0;  /* width of the video  */
+    uint16_t video_height = 0; /* height of the video */
+
+    /* First check if the preview resolution is the same, if not, change it*/
+    parm.getPreviewSize(&display_width,  &display_height);
+    if (display_width && display_height) {
+        matching = (display_width == dim->display_width) &&
+            (display_height == dim->display_height);
+
+        if (!matching) {
+            dim->display_width  = display_width;
+            dim->display_height = display_height;
+        }
+    }
+    else
+        matching = false;
+
+    cam_format_t value = getPreviewFormat();
+
+    if(value != NOT_FOUND && value != dim->prev_format ) {
+        //Setting to Parameter requested by the Upper layer
+        dim->prev_format = value;
+    }else{
+        //Setting to default Format.
+        dim->prev_format = CAMERA_YUV_420_NV21;
+    }
+    mPreviewFormat = dim->prev_format;
+
+    dim->prev_padding_format =  getPreviewPadding( );
+
+    dim->enc_format = CAMERA_YUV_420_NV12;
+    dim->orig_video_width = mDimension.orig_video_width;
+    dim->orig_video_height = mDimension.orig_video_height;
+    dim->video_width = mDimension.video_width;
+    dim->video_height = mDimension.video_height;
+    dim->video_chroma_width = mDimension.video_width;
+    dim->video_chroma_height  = mDimension.video_height;
+    /* Reset the Main image and thumbnail formats here,
+     * since they might have been changed when video size
+     * livesnapshot was taken. */
+    if (mSnapshotFormat == 1)
+      dim->main_img_format = CAMERA_YUV_422_NV61;
+    else
+      dim->main_img_format = CAMERA_YUV_420_NV21;
+    dim->thumb_format = CAMERA_YUV_420_NV21;
+    LOGI("preview_parm_config: X");
+    return matching;
+}
+
+status_t QCameraHardwareInterface::startPreview()
+{
+    status_t retVal = NO_ERROR;
+
+    LOGE("%s: mPreviewState =%d", __func__, mPreviewState);
+    Mutex::Autolock lock(mLock);
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+    case QCAMERA_HAL_TAKE_PICTURE:
+        mPreviewState = QCAMERA_HAL_PREVIEW_START;
+        LOGE("%s:  HAL::startPreview begin", __func__);
+
+        if(QCAMERA_HAL_PREVIEW_START == mPreviewState &&
+           (mPreviewWindow || isNoDisplayMode())) {
+            LOGE("%s:  start preview now", __func__);
+            retVal = startPreview2();
+            if(retVal == NO_ERROR)
+                mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
+        } else {
+            LOGE("%s:  received startPreview, but preview window = null", __func__);
+        }
+        break;
+    case QCAMERA_HAL_PREVIEW_START:
+    case QCAMERA_HAL_PREVIEW_STARTED:
+    break;
+    case QCAMERA_HAL_RECORDING_STARTED:
+        LOGE("%s: cannot start preview in recording state", __func__);
+        break;
+    default:
+        LOGE("%s: unknow state %d received", __func__, mPreviewState);
+        retVal = UNKNOWN_ERROR;
+        break;
+    }
+    return retVal;
+}
+
+status_t QCameraHardwareInterface::startPreview2()
+{
+    LOGI("startPreview2: E");
+    status_t ret = NO_ERROR;
+
+    cam_ctrl_dimension_t dim;
+    mm_camera_dimension_t maxDim;
+    bool initPreview = false;
+
+    if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED) { //isPreviewRunning()){
+        LOGE("%s:Preview already started  mCameraState = %d!", __func__, mCameraState);
+        LOGE("%s: X", __func__);
+        return NO_ERROR;
+    }
+
+    /*  get existing preview information, by qury mm_camera*/
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+
+    if (MM_CAMERA_OK != ret) {
+      LOGE("%s: error - can't get preview dimension!", __func__);
+      LOGE("%s: X", __func__);
+      return BAD_VALUE;
+    }
+
+    /* config the parmeters and see if we need to re-init the stream*/
+    initPreview = preview_parm_config (&dim, mParameters);
+
+    if (mRecordingHint && mFullLiveshotEnabled) {
+#if 0
+      /* Camcorder mode and Full resolution liveshot enabled
+       * TBD lookup table for correct aspect ratio matching size */
+      memset(&maxDim, 0, sizeof(mm_camera_dimension_t));
+      getMaxPictureDimension(&maxDim);
+      if (!maxDim.width || !maxDim.height) {
+        maxDim.width  = DEFAULT_LIVESHOT_WIDTH;
+        maxDim.height = DEFAULT_LIVESHOT_HEIGHT;
+      }
+      /* TODO Remove this hack after adding code to get live shot dimension */
+      if (!mCameraId) {
+        maxDim.width = DEFAULT_LIVESHOT_WIDTH;
+        maxDim.height = DEFAULT_LIVESHOT_HEIGHT;
+      }
+      dim.picture_width = maxDim.width;
+      dim.picture_height = maxDim.height;
+      mParameters.setPictureSize(dim.picture_width, dim.picture_height);
+      LOGI("%s Setting Liveshot dimension as %d x %d", __func__,
+           maxDim.width, maxDim.height);
+#endif
+        int mPictureWidth, mPictureHeight;
+        bool matching;
+        /* First check if the picture resolution is the same, if not, change it*/
+        getPictureSize(&mPictureWidth, &mPictureHeight);
+
+        matching = (mPictureWidth == dim.picture_width) &&
+            (mPictureHeight == dim.picture_height);
+
+        if (!matching) {
+            dim.picture_width  = mPictureWidth;
+            dim.picture_height = mPictureHeight;
+            dim.ui_thumbnail_height = dim.display_height;
+            dim.ui_thumbnail_width = dim.display_width;
+        }
+        LOGE("%s: Fullsize Liveshaot Picture size to set: %d x %d", __func__,
+             dim.picture_width, dim.picture_height);
+        mParameters.setPictureSize(dim.picture_width, dim.picture_height);
+    }
+
+    ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+    if (MM_CAMERA_OK != ret) {
+      LOGE("%s X: error - can't config preview parms!", __func__);
+      return BAD_VALUE;
+    }
+
+    mStreamDisplay->setMode(myMode & CAMERA_ZSL_MODE);
+    mStreamSnap->setMode(myMode & CAMERA_ZSL_MODE);
+    mStreamRecord->setMode(myMode & CAMERA_ZSL_MODE);
+    LOGE("%s: myMode = %d", __func__, myMode);
+
+    LOGE("%s: setPreviewWindow", __func__);
+    mStreamDisplay->setPreviewWindow(mPreviewWindow);
+
+    if(isZSLMode()) {
+        /* Start preview streaming */
+        ret = mStreamDisplay->start();
+        if (MM_CAMERA_OK != ret){
+            LOGE("%s: X -error - can't start nonZSL stream!", __func__);
+            return BAD_VALUE;
+        }
+
+        /* Start ZSL stream */
+        ret =  mStreamSnap->start();
+        if (MM_CAMERA_OK != ret){
+            LOGE("%s: error - can't start Snapshot stream!", __func__);
+            mStreamDisplay->stop();
+            return BAD_VALUE;
+        }
+    }else{
+        ret = mStreamDisplay->start();
+    }
+
+    /*call QCameraStream_noneZSL::start() */
+    if (MM_CAMERA_OK != ret){
+      LOGE("%s: X error - can't start stream!", __func__);
+      return BAD_VALUE;
+    }
+    if(MM_CAMERA_OK == ret)
+        mCameraState = CAMERA_STATE_PREVIEW_START_CMD_SENT;
+    else
+        mCameraState = CAMERA_STATE_ERROR;
+
+    if(mPostPreviewHeap != NULL) {
+        mPostPreviewHeap.clear();
+        mPostPreviewHeap = NULL;
+    }
+
+    LOGI("startPreview: X");
+    return ret;
+}
+
+void QCameraHardwareInterface::stopPreview()
+{
+    LOGI("%s: stopPreview: E", __func__);
+    Mutex::Autolock lock(mLock);
+    mm_camera_util_profile("HAL: stopPreview(): E");
+    mFaceDetectOn = false;
+
+    // reset recording hint to the value passed from Apps
+    const char * str = mParameters.get(CameraParameters::KEY_RECORDING_HINT);
+    if((str != NULL) && !strcmp(str, "true")){
+        mRecordingHint = TRUE;
+    } else {
+        mRecordingHint = FALSE;
+    }
+
+    switch(mPreviewState) {
+      case QCAMERA_HAL_PREVIEW_START:
+          //mPreviewWindow = NULL;
+          mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+          break;
+      case QCAMERA_HAL_PREVIEW_STARTED:
+          stopPreviewInternal();
+          mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+          break;
+      case QCAMERA_HAL_RECORDING_STARTED:
+            stopRecordingInternal();
+            stopPreviewInternal();
+            mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+            break;
+      case QCAMERA_HAL_TAKE_PICTURE:
+      case QCAMERA_HAL_PREVIEW_STOPPED:
+      default:
+            break;
+    }
+    LOGI("stopPreview: X, mPreviewState = %d", mPreviewState);
+}
+
+#if 0 //mzhu
+void QCameraHardwareInterface::stopPreviewZSL()
+{
+    LOGI("stopPreviewZSL: E");
+
+    if(!mStreamDisplay || !mStreamSnap) {
+        LOGE("mStreamDisplay/mStreamSnap is null");
+        return;
+    }
+    LOGI("stopPreview: X, mPreviewState = %d", mPreviewState);
+}
+#endif
+void QCameraHardwareInterface::stopPreviewInternal()
+{
+    LOGI("stopPreviewInternal: E");
+    status_t ret = NO_ERROR;
+
+    if(!mStreamDisplay) {
+        LOGE("mStreamDisplay is null");
+        return;
+    }
+
+    if(isZSLMode()) {
+        /* take care snapshot object for ZSL mode */
+        mStreamSnap->stop();
+    }
+    mStreamDisplay->stop();
+
+    mCameraState = CAMERA_STATE_PREVIEW_STOP_CMD_SENT;
+    LOGI("stopPreviewInternal: X");
+}
+
+int QCameraHardwareInterface::previewEnabled()
+{
+    LOGI("previewEnabled: E");
+    Mutex::Autolock lock(mLock);
+    LOGE("%s: mCameraState = %d", __func__, mCameraState);
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+    case QCAMERA_HAL_TAKE_PICTURE:
+    default:
+        return false;
+        break;
+    case QCAMERA_HAL_PREVIEW_START:
+    case QCAMERA_HAL_PREVIEW_STARTED:
+    case QCAMERA_HAL_RECORDING_STARTED:
+        return true;
+        break;
+    }
+    return false;
+}
+
+status_t QCameraHardwareInterface::startRecording()
+{
+    LOGI("startRecording: E");
+    status_t ret = NO_ERROR;
+    Mutex::Autolock lock(mLock);
+
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+        LOGE("%s: preview has not been started", __func__);
+        ret = UNKNOWN_ERROR;
+        break;
+    case QCAMERA_HAL_PREVIEW_START:
+        LOGE("%s: no preview native window", __func__);
+        ret = UNKNOWN_ERROR;
+        break;
+    case QCAMERA_HAL_PREVIEW_STARTED:
+        if (mRecordingHint == FALSE) {
+            LOGE("%s: start recording when hint is false, stop preview first", __func__);
+            stopPreviewInternal();
+            mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+
+            // Set recording hint to TRUE
+            mRecordingHint = TRUE;
+            setRecordingHintValue(mRecordingHint);
+
+            // start preview again
+            mPreviewState = QCAMERA_HAL_PREVIEW_START;
+            if (startPreview2() == NO_ERROR)
+                mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
+        }
+        ret =  mStreamRecord->start();
+        if (MM_CAMERA_OK != ret){
+            LOGE("%s: error - mStreamRecord->start!", __func__);
+            ret = BAD_VALUE;
+            break;
+        }
+        if(MM_CAMERA_OK == ret)
+            mCameraState = CAMERA_STATE_RECORD_START_CMD_SENT;
+        else
+            mCameraState = CAMERA_STATE_ERROR;
+        mPreviewState = QCAMERA_HAL_RECORDING_STARTED;
+        break;
+    case QCAMERA_HAL_RECORDING_STARTED:
+        LOGE("%s: ", __func__);
+        break;
+    case QCAMERA_HAL_TAKE_PICTURE:
+    default:
+       ret = BAD_VALUE;
+       break;
+    }
+    LOGI("startRecording: X");
+    return ret;
+}
+
+void QCameraHardwareInterface::stopRecording()
+{
+    LOGI("stopRecording: E");
+    Mutex::Autolock lock(mLock);
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+    case QCAMERA_HAL_PREVIEW_START:
+    case QCAMERA_HAL_PREVIEW_STARTED:
+        break;
+    case QCAMERA_HAL_RECORDING_STARTED:
+        stopRecordingInternal();
+        mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
+        break;
+    case QCAMERA_HAL_TAKE_PICTURE:
+    default:
+        break;
+    }
+    LOGI("stopRecording: X");
+
+}
+void QCameraHardwareInterface::stopRecordingInternal()
+{
+    LOGI("stopRecordingInternal: E");
+    status_t ret = NO_ERROR;
+
+    if(!mStreamRecord) {
+        LOGE("mStreamRecord is null");
+        return;
+    }
+
+    /*
+    * call QCameraStream_record::stop()
+    * Unregister Callback, action stop
+    */
+    mStreamRecord->stop();
+    mCameraState = CAMERA_STATE_PREVIEW;  //TODO : Apurva : Hacked for 2nd time Recording
+    mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
+    LOGI("stopRecordingInternal: X");
+    return;
+}
+
+int QCameraHardwareInterface::recordingEnabled()
+{
+    int ret = 0;
+    Mutex::Autolock lock(mLock);
+    LOGV("%s: E", __func__);
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+    case QCAMERA_HAL_PREVIEW_START:
+    case QCAMERA_HAL_PREVIEW_STARTED:
+        break;
+    case QCAMERA_HAL_RECORDING_STARTED:
+        ret = 1;
+        break;
+    case QCAMERA_HAL_TAKE_PICTURE:
+    default:
+        break;
+    }
+    LOGV("%s: X, ret = %d", __func__, ret);
+    return ret;   //isRecordingRunning();
+}
+
+/**
+* Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
+*/
+void QCameraHardwareInterface::releaseRecordingFrame(const void *opaque)
+{
+    LOGV("%s : BEGIN",__func__);
+    if(mStreamRecord == NULL) {
+        LOGE("Record stream Not Initialized");
+        return;
+    }
+    mStreamRecord->releaseRecordingFrame(opaque);
+    LOGV("%s : END",__func__);
+    return;
+}
+
+status_t QCameraHardwareInterface::autoFocusEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
+{
+    LOGE("autoFocusEvent: E");
+    int ret = NO_ERROR;
+/************************************************************
+  BEGIN MUTEX CODE
+*************************************************************/
+
+    LOGE("%s:%d: Trying to acquire AF bit lock",__func__,__LINE__);
+    mAutofocusLock.lock();
+    LOGE("%s:%d: Acquired AF bit lock",__func__,__LINE__);
+
+    if(mAutoFocusRunning==false) {
+      LOGE("%s:AF not running, discarding stale event",__func__);
+      mAutofocusLock.unlock();
+      return ret;
+    }
+
+    mAutoFocusRunning = false;
+    mAutofocusLock.unlock();
+
+/************************************************************
+  END MUTEX CODE
+*************************************************************/
+    if(status==NULL) {
+      LOGE("%s:NULL ptr received for status",__func__);
+      return BAD_VALUE;
+    }
+
+    /* update focus distances after autofocus is done */
+    if(updateFocusDistances() != NO_ERROR) {
+       LOGE("%s: updateFocusDistances failed for %d", __FUNCTION__, mFocusMode);
+    }
+
+    /*(Do?) we need to make sure that the call back is the
+      last possible step in the execution flow since the same
+      context might be used if a fail triggers another round
+      of AF then the mAutoFocusRunning flag and other state
+      variables' validity will be under question*/
+
+    if (mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS)){
+      LOGE("%s:Issuing callback to service",__func__);
+
+      /* "Accepted" status is not appropriate it should be used for
+        initial cmd, event reporting should only give use SUCCESS/FAIL
+        */
+
+      app_cb->notifyCb  = mNotifyCb;
+      app_cb->argm_notify.msg_type = CAMERA_MSG_FOCUS;
+      app_cb->argm_notify.ext2 = 0;
+      app_cb->argm_notify.cookie =  mCallbackCookie;
+
+      LOGE("Auto foucs state =%d", *status);
+      if(*status==CAM_CTRL_SUCCESS) {
+        app_cb->argm_notify.ext1 = true;
+      }
+      else if(*status==CAM_CTRL_FAILED){
+        app_cb->argm_notify.ext1 = false;
+      }
+      else{
+        app_cb->notifyCb  = NULL;
+        LOGE("%s:Unknown AF status (%d) received",__func__,*status);
+      }
+
+    }/*(mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS))*/
+    else{
+      LOGE("%s:Call back not enabled",__func__);
+    }
+
+    LOGE("autoFocusEvent: X");
+    return ret;
+
+}
+
+status_t QCameraHardwareInterface::cancelPicture()
+{
+    LOGI("cancelPicture: E");
+    status_t ret = MM_CAMERA_OK;
+    Mutex::Autolock lock(mLock);
+
+    switch(mPreviewState) {
+        case QCAMERA_HAL_PREVIEW_STOPPED:
+        case QCAMERA_HAL_PREVIEW_START:
+        case QCAMERA_HAL_PREVIEW_STARTED:
+        case QCAMERA_HAL_RECORDING_STARTED:
+        default:
+            break;
+        case QCAMERA_HAL_TAKE_PICTURE:
+            ret = cancelPictureInternal();
+            break;
+    }
+    LOGI("cancelPicture: X");
+    return ret;
+}
+
+status_t QCameraHardwareInterface::cancelPictureInternal()
+{
+    LOGI("cancelPictureInternal: E");
+    status_t ret = MM_CAMERA_OK;
+    if(mCameraState != CAMERA_STATE_READY) {
+        if(mStreamSnap) {
+            mStreamSnap->stop();
+            mCameraState = CAMERA_STATE_SNAP_STOP_CMD_SENT;
+        }
+    } else {
+        LOGE("%s: Cannot process cancel picture as snapshot is already done",__func__);
+    }
+    LOGI("cancelPictureInternal: X");
+    return ret;
+}
+
+void QCameraHardwareInterface::pausePreviewForSnapshot()
+{
+    stopPreviewInternal( );
+}
+status_t QCameraHardwareInterface::resumePreviewAfterSnapshot()
+{
+    status_t ret = NO_ERROR;
+    ret = mStreamDisplay->start();
+    return ret;
+}
+
+void liveshot_callback(mm_camera_ch_data_buf_t *recvd_frame,
+                                void *user_data)
+{
+    QCameraHardwareInterface *pme = (QCameraHardwareInterface *)user_data;
+    cam_ctrl_dimension_t dim;
+    int mJpegMaxSize;
+    status_t ret;
+    LOGE("%s: E", __func__);
+
+
+    mm_camera_ch_data_buf_t* frame =
+         (mm_camera_ch_data_buf_t *)malloc(sizeof(mm_camera_ch_data_buf_t));
+    if (frame == NULL) {
+        LOGE("%s: Error allocating memory to save received_frame structure.", __func__);
+        cam_evt_buf_done(pme->mCameraId, recvd_frame);
+		return ;
+    }
+    memcpy(frame, recvd_frame, sizeof(mm_camera_ch_data_buf_t));
+
+   LOGE("<DEBUG> Liveshot buffer idx:%d",frame->video.video.idx);
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    ret = cam_config_get_parm(pme->mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+    if (MM_CAMERA_OK != ret) {
+        LOGE("%s: error - can't get dimension!", __func__);
+        LOGE("%s: X", __func__);
+    }
+
+#if 1
+    LOGE("Live Snapshot Enabled");
+    frame->snapshot.main.frame = frame->video.video.frame;
+    frame->snapshot.main.idx = frame->video.video.idx;
+    frame->snapshot.thumbnail.frame = frame->video.video.frame;
+    frame->snapshot.thumbnail.idx = frame->video.video.idx;
+
+    dim.picture_width = pme->mDimension.video_width;
+    dim.picture_height = pme->mDimension.video_height;
+    dim.ui_thumbnail_width = pme->mDimension.video_width;
+    dim.ui_thumbnail_height = pme->mDimension.video_height;
+    dim.main_img_format = pme->mDimension.enc_format;
+    dim.thumb_format = pme->mDimension.enc_format;
+
+    mJpegMaxSize = pme->mDimension.video_width * pme->mDimension.video_width * 1.5;
+
+    LOGE("Picture w = %d , h = %d, size = %d",dim.picture_width,dim.picture_height,mJpegMaxSize);
+     if (pme->mStreamLiveSnap){
+        LOGE("%s:Deleting old Snapshot stream instance",__func__);
+        QCameraStream_Snapshot::deleteInstance (pme->mStreamLiveSnap);
+        pme->mStreamLiveSnap = NULL;
+    }
+
+    pme->mStreamLiveSnap = (QCameraStream_Snapshot*)QCameraStream_Snapshot::createInstance(pme->mCameraId,
+                                                       pme->myMode);
+
+    if (!pme->mStreamLiveSnap) {
+        LOGE("%s: error - can't creat snapshot stream!", __func__);
+        return ;
+    }
+    pme->mStreamLiveSnap->setModeLiveSnapshot(true);
+    pme->mStreamLiveSnap->setHALCameraControl(pme);
+    pme->mStreamLiveSnap->initSnapshotBuffers(&dim,1);
+    LOGE("Calling live shot");
+
+
+    ((QCameraStream_Snapshot*)(pme->mStreamLiveSnap))->takePictureLiveshot(frame,&dim,mJpegMaxSize);
+
+#else
+
+
+
+
+  if(MM_CAMERA_OK != cam_evt_buf_done(pme->mCameraId,frame )) {
+    LOGE(" BUF DONE FAILED");
+  }
+#endif
+  LOGE("%s: X", __func__);
+
+}
+
+status_t  QCameraHardwareInterface::takePicture()
+{
+    LOGI("takePicture: E");
+    status_t ret = MM_CAMERA_OK;
+    Mutex::Autolock lock(mLock);
+
+    mStreamSnap->resetSnapshotCounters( );
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STARTED:
+        mStreamSnap->setFullSizeLiveshot(false);
+        if (isZSLMode()) {
+            if (mStreamSnap != NULL) {
+                pausePreviewForZSL();
+                ret = mStreamSnap->takePictureZSL();
+                if (ret != MM_CAMERA_OK) {
+                    LOGE("%s: Error taking ZSL snapshot!", __func__);
+                    ret = BAD_VALUE;
+                }
+            }
+            else {
+                LOGE("%s: ZSL stream not active! Failure!!", __func__);
+                ret = BAD_VALUE;
+            }
+            return ret;
+        }
+
+        /*prepare snapshot, e.g LED*/
+        takePicturePrepareHardware( );
+        /* There's an issue where we have a glimpse of corrupted data between
+           a time we stop a preview and display the postview. It happens because
+           when we call stopPreview we deallocate the preview buffers hence overlay
+           displays garbage value till we enqueue postview buffer to be displayed.
+           Hence for temporary fix, we'll do memcopy of the last frame displayed and
+           queue it to overlay*/
+        // mzhu storePreviewFrameForPostview();
+
+        /* stop preview */
+        pausePreviewForSnapshot();
+
+        /* call Snapshot start() :*/
+        ret =  mStreamSnap->start();
+        if (MM_CAMERA_OK != ret){
+            /* mzhu: fix me, restore preview */
+            LOGE("%s: error - can't start Snapshot stream!", __func__);
+            return BAD_VALUE;
+        }
+
+        if(MM_CAMERA_OK == ret)
+            mCameraState = CAMERA_STATE_SNAP_START_CMD_SENT;
+        else
+            mCameraState = CAMERA_STATE_ERROR;
+        mPreviewState = QCAMERA_HAL_TAKE_PICTURE;
+        break;
+      case QCAMERA_HAL_TAKE_PICTURE:
+          break;
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+    case QCAMERA_HAL_PREVIEW_START:
+      ret = UNKNOWN_ERROR;
+      break;
+    case QCAMERA_HAL_RECORDING_STARTED:
+      if (canTakeFullSizeLiveshot()) {
+        LOGD(" Calling takeFullSizeLiveshot");
+        takeFullSizeLiveshot();
+      }else{
+          (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
+                                                    liveshot_callback,
+                                                    MM_CAMERA_REG_BUF_CB_COUNT,
+                                                    1,
+                                                    this);
+      }
+
+      break;
+    default:
+        ret = UNKNOWN_ERROR;
+        break;
+    }
+    LOGI("takePicture: X");
+    return ret;
+}
+
+bool QCameraHardwareInterface::canTakeFullSizeLiveshot() {
+    bool ret;
+    if (mFullLiveshotEnabled && !isLowPowerCamcorder()) {
+      /* Full size liveshot enabled. */
+
+      /* If Picture size is same as video size, switch to Video size
+       * live snapshot */
+      if ((mDimension.picture_width == mDimension.video_width) &&
+          (mDimension.picture_height == mDimension.video_height)) {
+        return FALSE;
+      }
+
+      if (mDisEnabled) {
+       /* If DIS is enabled and Picture size is
+        * less than (video size + 10% DIS Margin)
+        * then fall back to Video size liveshot. */
+        if ((mDimension.picture_width <
+               (int)(mDimension.video_width * 1.1)) ||
+             (mDimension.picture_height <
+               (int)(mDimension.video_height * 1.1))) {
+          ret = FALSE;
+        } else {
+          /* Go with Full size live snapshot. */
+          ret = TRUE;
+        }
+      } else {
+        /* DIS Disabled. Go with Full size live snapshot */
+        ret = TRUE;
+      }
+    } else {
+      /* Full size liveshot disabled. Fallback to Video size liveshot. */
+      ret = FALSE;
+    }
+
+    return ret;
+}
+
+status_t QCameraHardwareInterface::takeFullSizeLiveshot()
+{
+    status_t ret = NO_ERROR;
+    if (mStreamLiveSnap){
+        LOGE("%s:Deleting old Snapshot stream instance",__func__);
+        QCameraStream_Snapshot::deleteInstance (mStreamLiveSnap);
+        mStreamLiveSnap = NULL;
+    }
+    mStreamLiveSnap = QCameraStream_Snapshot::createInstance(mCameraId, myMode);
+
+    if (!mStreamLiveSnap) {
+        LOGE("%s: error - can't creat snapshot stream!", __func__);
+        /* mzhu: fix me, restore preview */
+        return BAD_VALUE;
+    }
+
+    /* Store HAL object in snapshot stream Object */
+    mStreamLiveSnap->setHALCameraControl(this);
+
+    mStreamLiveSnap->setFullSizeLiveshot(true);
+
+    /* Call snapshot init*/
+    ret =  mStreamLiveSnap->init();
+    if (MM_CAMERA_OK != ret){
+        LOGE("%s: error - can't init Snapshot stream!", __func__);
+        return BAD_VALUE;
+    }
+
+    /* call Snapshot start() :*/
+    mStreamLiveSnap->resetSnapshotCounters( );
+    ret =  mStreamLiveSnap->start();
+    if (MM_CAMERA_OK != ret){
+        /* mzhu: fix me, restore preview */
+        LOGE("%s: error - can't start Snapshot stream!", __func__);
+        return BAD_VALUE;
+    }
+    return ret;
+}
+
+status_t  QCameraHardwareInterface::takeLiveSnapshot()
+{
+    status_t ret = NO_ERROR;
+    LOGI("takeLiveSnapshot: E");
+    mStreamRecord->takeLiveSnapshot();
+    LOGI("takeLiveSnapshot: X");
+    return ret;
+}
+
+status_t QCameraHardwareInterface::autoFocus()
+{
+    LOGI("autoFocus: E");
+    status_t ret = NO_ERROR;
+    Mutex::Autolock lock(mLock);
+    LOGI("autoFocus: Got lock");
+    bool status = true;
+    isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);
+
+    if(mAutoFocusRunning==true){
+      LOGE("%s:AF already running should not have got this call",__func__);
+      return NO_ERROR;
+    }
+
+    if (afMode == AF_MODE_MAX) {
+      /* This should never happen. We cannot send a
+       * callback notifying error from this place because
+       * the CameraService has called this function after
+       * acquiring the lock. So if we try to issue a callback
+       * from this place, the callback will try to acquire
+       * the same lock in CameraService and it will result
+       * in deadlock. So, let the call go in to the lower
+       * layer. The lower layer will anyway return error if
+       * the autofocus is not supported or if the focus
+       * value is invalid.
+       * Just print out the error. */
+      LOGE("%s:Invalid AF mode (%d)", __func__, afMode);
+    }
+
+    LOGI("%s:AF start (mode %d)", __func__, afMode);
+    if(MM_CAMERA_OK != cam_ops_action(mCameraId, TRUE,
+                                    MM_CAMERA_OPS_FOCUS, &afMode)) {
+      LOGE("%s: AF command failed err:%d error %s",
+           __func__, errno, strerror(errno));
+      return UNKNOWN_ERROR;
+    }
+
+    mAutoFocusRunning = true;
+    LOGI("autoFocus: X");
+    return ret;
+}
+
+status_t QCameraHardwareInterface::cancelAutoFocus()
+{
+    LOGE("cancelAutoFocus: E");
+    status_t ret = NO_ERROR;
+    Mutex::Autolock lock(mLock);
+
+/**************************************************************
+  BEGIN MUTEX CODE
+*************************************************************/
+
+    mAutofocusLock.lock();
+    if(mAutoFocusRunning) {
+
+      mAutoFocusRunning = false;
+      mAutofocusLock.unlock();
+
+    }else/*(!mAutoFocusRunning)*/{
+
+      mAutofocusLock.unlock();
+      LOGE("%s:Af not running",__func__);
+      return NO_ERROR;
+    }
+/**************************************************************
+  END MUTEX CODE
+*************************************************************/
+
+
+    if(MM_CAMERA_OK!=cam_ops_action(mCameraId,FALSE,MM_CAMERA_OPS_FOCUS,NULL )) {
+      LOGE("%s: AF command failed err:%d error %s",__func__, errno,strerror(errno));
+    }
+
+    LOGE("cancelAutoFocus: X");
+    return NO_ERROR;
+}
+
+#if 0 //mzhu
+/*==========================================================================
+ * FUNCTION    - prepareSnapshotAndWait -
+ *
+ * DESCRIPTION:  invoke preparesnapshot and wait for it done
+                 it can be called within takepicture, so no need
+                 to grab mLock.
+ *=========================================================================*/
+void QCameraHardwareInterface::prepareSnapshotAndWait()
+{
+    LOGI("prepareSnapshotAndWait: E");
+    int rc = 0;
+    /*To Do: call mm camera preparesnapshot */
+    if(!rc ) {
+        mPreparingSnapshot = true;
+        pthread_mutex_lock(&mAsyncCmdMutex);
+        pthread_cond_wait(&mAsyncCmdWait, &mAsyncCmdMutex);
+        pthread_mutex_unlock(&mAsyncCmdMutex);
+        mPreparingSnapshot = false;
+    }
+    LOGI("prepareSnapshotAndWait: X");
+}
+#endif //mzhu
+
+/*==========================================================================
+ * FUNCTION    - processprepareSnapshotEvent -
+ *
+ * DESCRIPTION:  Process the event of preparesnapshot done msg
+                 unblock prepareSnapshotAndWait( )
+ *=========================================================================*/
+void QCameraHardwareInterface::processprepareSnapshotEvent(cam_ctrl_status_t *status)
+{
+    LOGI("processprepareSnapshotEvent: E");
+    pthread_mutex_lock(&mAsyncCmdMutex);
+    pthread_cond_signal(&mAsyncCmdWait);
+    pthread_mutex_unlock(&mAsyncCmdMutex);
+    LOGI("processprepareSnapshotEvent: X");
+}
+
+void QCameraHardwareInterface::roiEvent(fd_roi_t roi,app_notify_cb_t *app_cb)
+{
+    LOGE("roiEvent: E");
+
+    if(mStreamDisplay) mStreamDisplay->notifyROIEvent(roi);
+#if 0 //TODO: move to preview obj
+    mCallbackLock.lock();
+    data_callback mcb = mDataCb;
+    void *mdata = mCallbackCookie;
+    int msgEnabled = mMsgEnabled;
+    mCallbackLock.unlock();
+
+    mMetaDataWaitLock.lock();
+    if (mFaceDetectOn == true && mSendMetaData == true) {
+        mSendMetaData = false;
+        int faces_detected = roi.rect_num;
+        int max_faces_detected = MAX_ROI * 4;
+        int array[max_faces_detected + 1];
+
+        array[0] = faces_detected * 4;
+        for (int i = 1, j = 0;j < MAX_ROI; j++, i = i + 4) {
+            if (j < faces_detected) {
+                array[i]   = roi.faces[j].x;
+                array[i+1] = roi.faces[j].y;
+                array[i+2] = roi.faces[j].dx;
+                array[i+3] = roi.faces[j].dy;
+            } else {
+                array[i]   = -1;
+                array[i+1] = -1;
+                array[i+2] = -1;
+                array[i+3] = -1;
+            }
+        }
+        if(mMetaDataHeap != NULL){
+            LOGV("mMetaDataHEap is non-NULL");
+            memcpy((uint32_t *)mMetaDataHeap->mHeap->base(), (uint32_t *)array, (sizeof(int)*(MAX_ROI*4+1)));
+            mMetaDataWaitLock.unlock();
+
+            if  (mcb != NULL && (msgEnabled & CAMERA_MSG_META_DATA)) {
+                mcb(CAMERA_MSG_META_DATA, mMetaDataHeap->mBuffers[0], mdata);
+            }
+        } else {
+            mMetaDataWaitLock.unlock();
+            LOGE("runPreviewThread mMetaDataHeap is NULL");
+        }
+    } else {
+        mMetaDataWaitLock.unlock();
+    }
+#endif // mzhu
+    LOGE("roiEvent: X");
+}
+
+
+void QCameraHardwareInterface::handleZoomEventForSnapshot(void)
+{
+    mm_camera_ch_crop_t v4l2_crop;
+
+
+    LOGI("%s: E", __func__);
+
+    memset(&v4l2_crop,0,sizeof(v4l2_crop));
+    v4l2_crop.ch_type=MM_CAMERA_CH_SNAPSHOT;
+
+    LOGI("%s: Fetching crop info", __func__);
+    cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop);
+
+    LOGI("%s: Crop info received for main: %d, %d, %d, %d ", __func__,
+         v4l2_crop.snapshot.main_crop.left,
+         v4l2_crop.snapshot.main_crop.top,
+         v4l2_crop.snapshot.main_crop.width,
+         v4l2_crop.snapshot.main_crop.height);
+    LOGI("%s: Crop info received for thumbnail: %d, %d, %d, %d ",__func__,
+         v4l2_crop.snapshot.thumbnail_crop.left,
+         v4l2_crop.snapshot.thumbnail_crop.top,
+         v4l2_crop.snapshot.thumbnail_crop.width,
+         v4l2_crop.snapshot.thumbnail_crop.height);
+
+    if(mStreamSnap) {
+        LOGD("%s: Setting crop info for snapshot", __func__);
+        memcpy(&(mStreamSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop));
+    }
+    if(mFullLiveshotEnabled && mStreamLiveSnap){
+        LOGD("%s: Setting crop info for snapshot", __func__);
+        memcpy(&(mStreamLiveSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop));
+    }
+    LOGD("%s: X", __func__);
+}
+
+void QCameraHardwareInterface::handleZoomEventForPreview(app_notify_cb_t *app_cb)
+{
+    mm_camera_ch_crop_t v4l2_crop;
+
+    LOGI("%s: E", __func__);
+
+    /*regular zooming or smooth zoom stopped*/
+    if (!mSmoothZoomRunning && mPreviewWindow) {
+        memset(&v4l2_crop, 0, sizeof(v4l2_crop));
+        v4l2_crop.ch_type = MM_CAMERA_CH_PREVIEW;
+
+        LOGI("%s: Fetching crop info", __func__);
+        cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop);
+
+        LOGI("%s: Crop info received: %d, %d, %d, %d ", __func__,
+             v4l2_crop.crop.left,
+             v4l2_crop.crop.top,
+             v4l2_crop.crop.width,
+             v4l2_crop.crop.height);
+
+        mPreviewWindow->set_crop(mPreviewWindow,
+                        v4l2_crop.crop.left,
+                        v4l2_crop.crop.top,
+                        v4l2_crop.crop.left + v4l2_crop.crop.width,
+                        v4l2_crop.crop.top + v4l2_crop.crop.height);
+        LOGI("%s: Done setting crop", __func__);
+        LOGI("%s: Currrent zoom :%d",__func__, mCurrentZoom);
+    }
+
+    LOGI("%s: X", __func__);
+}
+
+void QCameraHardwareInterface::zoomEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
+{
+    LOGI("zoomEvent: state:%d E",mPreviewState);
+    switch (mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+        break;
+    case QCAMERA_HAL_PREVIEW_START:
+        break;
+    case QCAMERA_HAL_PREVIEW_STARTED:
+        handleZoomEventForPreview(app_cb);
+        if (isZSLMode())
+          handleZoomEventForSnapshot();
+        break;
+    case QCAMERA_HAL_RECORDING_STARTED:
+        handleZoomEventForPreview(app_cb);
+        if (mFullLiveshotEnabled)
+            handleZoomEventForSnapshot();
+        break;
+    case QCAMERA_HAL_TAKE_PICTURE:
+        if(isZSLMode())
+            handleZoomEventForPreview(app_cb);
+        handleZoomEventForSnapshot();
+        break;
+    default:
+        break;
+    }
+    LOGI("zoomEvent: X");
+}
+
+void QCameraHardwareInterface::dumpFrameToFile(const void * data, uint32_t size, char* name, char* ext, int index)
+{
+    char buf[32];
+    int file_fd;
+    if ( data != NULL) {
+        char * str;
+        snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext);
+        LOGE("marvin, %s size =%d", buf, size);
+        file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+        write(file_fd, data, size);
+        close(file_fd);
+    }
+}
+
+void QCameraHardwareInterface::dumpFrameToFile(struct msm_frame* newFrame,
+  HAL_cam_dump_frm_type_t frm_type)
+{
+  int32_t enabled = 0;
+  int frm_num;
+  uint32_t  skip_mode;
+  char value[PROPERTY_VALUE_MAX];
+  char buf[32];
+  int main_422 = 1;
+  property_get("persist.camera.dumpimg", value, "0");
+  enabled = atoi(value);
+
+  LOGV(" newFrame =%p, frm_type = %d", newFrame, frm_type);
+  if(enabled & HAL_DUMP_FRM_MASK_ALL) {
+    if((enabled & frm_type) && newFrame) {
+      frm_num = ((enabled & 0xffff0000) >> 16);
+      if(frm_num == 0) frm_num = 10; /*default 10 frames*/
+      if(frm_num > 256) frm_num = 256; /*256 buffers cycle around*/
+      skip_mode = ((enabled & 0x0000ff00) >> 8);
+      if(skip_mode == 0) skip_mode = 1; /*no -skip */
+
+      if( mDumpSkipCnt % skip_mode == 0) {
+        if (mDumpFrmCnt >= 0 && mDumpFrmCnt <= frm_num) {
+          int w, h;
+          int file_fd;
+          switch (frm_type) {
+          case  HAL_DUMP_FRM_PREVIEW:
+            w = mDimension.display_width;
+            h = mDimension.display_height;
+            snprintf(buf, sizeof(buf), "/data/%dp_%dx%d.yuv", mDumpFrmCnt, w, h);
+            file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+            break;
+          case HAL_DUMP_FRM_VIDEO:
+            w = mDimension.video_width;
+            h = mDimension.video_height;
+            snprintf(buf, sizeof(buf),"/data/%dv_%dx%d.yuv", mDumpFrmCnt, w, h);
+            file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+            break;
+          case HAL_DUMP_FRM_MAIN:
+            w = mDimension.picture_width;
+            h = mDimension.picture_height;
+            snprintf(buf, sizeof(buf), "/data/%dm_%dx%d.yuv", mDumpFrmCnt, w, h);
+            file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+            if (mDimension.main_img_format == CAMERA_YUV_422_NV16 ||
+                mDimension.main_img_format == CAMERA_YUV_422_NV61)
+              main_422 = 2;
+            break;
+          case HAL_DUMP_FRM_THUMBNAIL:
+            w = mDimension.ui_thumbnail_width;
+            h = mDimension.ui_thumbnail_height;
+            snprintf(buf, sizeof(buf),"/data/%dt_%dx%d.yuv", mDumpFrmCnt, w, h);
+            file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+            break;
+          default:
+            w = h = 0;
+            file_fd = -1;
+            break;
+          }
+
+          if (file_fd < 0) {
+            LOGE("%s: cannot open file:type=%d\n", __func__, frm_type);
+          } else {
+            LOGE("%s: %d %d", __func__, newFrame->y_off, newFrame->cbcr_off);
+            write(file_fd, (const void *)(newFrame->buffer+newFrame->y_off), w * h);
+            write(file_fd, (const void *)
+              (newFrame->buffer + newFrame->cbcr_off), w * h / 2 * main_422);
+            close(file_fd);
+            LOGE("dump %s", buf);
+          }
+        } else if(frm_num == 256){
+          mDumpFrmCnt = 0;
+        }
+        mDumpFrmCnt++;
+      }
+      mDumpSkipCnt++;
+    }
+  }  else {
+    mDumpFrmCnt = 0;
+  }
+}
+
+status_t QCameraHardwareInterface::setPreviewWindow(preview_stream_ops_t* window)
+{
+    status_t retVal = NO_ERROR;
+    LOGE(" %s: E mPreviewState = %d, mStreamDisplay = %p", __FUNCTION__, mPreviewState, mStreamDisplay);
+    if( window == NULL) {
+        LOGE("%s:Received Setting NULL preview window", __func__);
+    }
+    Mutex::Autolock lock(mLock);
+    switch(mPreviewState) {
+    case QCAMERA_HAL_PREVIEW_START:
+        mPreviewWindow = window;
+        if(mPreviewWindow) {
+            /* we have valid surface now, start preview */
+            LOGE("%s:  calling startPreview2", __func__);
+            retVal = startPreview2();
+            if(retVal == NO_ERROR)
+                mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
+            LOGE("%s:  startPreview2 done, mPreviewState = %d", __func__, mPreviewState);
+        } else
+            LOGE("%s: null window received, mPreviewState = %d", __func__, mPreviewState);
+        break;
+    case QCAMERA_HAL_PREVIEW_STARTED:
+        /* new window comes */
+        LOGE("%s: bug, cannot handle new window in started state", __func__);
+        //retVal = UNKNOWN_ERROR;
+        break;
+    case QCAMERA_HAL_PREVIEW_STOPPED:
+    case QCAMERA_HAL_TAKE_PICTURE:
+        mPreviewWindow = window;
+        LOGE("%s: mPreviewWindow = 0x%p, mStreamDisplay = 0x%p",
+                                    __func__, mPreviewWindow, mStreamDisplay);
+        if(mStreamDisplay)
+            retVal = mStreamDisplay->setPreviewWindow(window);
+        break;
+    default:
+        LOGE("%s: bug, cannot handle new window in state %d", __func__, mPreviewState);
+        retVal = UNKNOWN_ERROR;
+        break;
+    }
+    LOGE(" %s : X, mPreviewState = %d", __FUNCTION__, mPreviewState);
+    return retVal;
+}
+
+int QCameraHardwareInterface::storeMetaDataInBuffers(int enable)
+{
+    /* this is a dummy func now. fix me later */
+    mStoreMetaDataInFrame = enable;
+    return 0;
+}
+
+status_t QCameraHardwareInterface::sendMappingBuf(int ext_mode, int idx, int fd,
+                                                  uint32_t size, int cameraid,
+                                                  mm_camera_socket_msg_type msg_type)
+{
+    cam_sock_packet_t packet;
+    memset(&packet, 0, sizeof(cam_sock_packet_t));
+    packet.msg_type = msg_type;
+    packet.payload.frame_fd_map.ext_mode = ext_mode;
+    packet.payload.frame_fd_map.frame_idx = idx;
+    packet.payload.frame_fd_map.fd = fd;
+    packet.payload.frame_fd_map.size = size;
+
+    if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), packet.payload.frame_fd_map.fd) <= 0 ) {
+        LOGE("%s: sending frame mapping buf msg Failed", __func__);
+        return FAILED_TRANSACTION;
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::sendUnMappingBuf(int ext_mode, int idx, int cameraid,
+                                                    mm_camera_socket_msg_type msg_type)
+{
+    cam_sock_packet_t packet;
+    memset(&packet, 0, sizeof(cam_sock_packet_t));
+    packet.msg_type = msg_type;
+    packet.payload.frame_fd_unmap.ext_mode = ext_mode;
+    packet.payload.frame_fd_unmap.frame_idx = idx;
+    if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), 0) <= 0 ) {
+        LOGE("%s: sending frame unmapping buf msg Failed", __func__);
+        return FAILED_TRANSACTION;
+    }
+    return NO_ERROR;
+}
+
+int QCameraHardwareInterface::allocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt, int ion_type)
+{
+  int rc = 0;
+  struct ion_handle_data handle_data;
+
+  p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
+  if (p_camera_memory->main_ion_fd[cnt] < 0) {
+    LOGE("Ion dev open failed\n");
+    LOGE("Error is %s\n", strerror(errno));
+    goto ION_OPEN_FAILED;
+  }
+  p_camera_memory->alloc[cnt].len = p_camera_memory->size;
+  /* to make it page size aligned */
+  p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095);
+  p_camera_memory->alloc[cnt].align = 4096;
+  p_camera_memory->alloc[cnt].flags = ion_type;
+
+  rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]);
+  if (rc < 0) {
+    LOGE("ION allocation failed\n");
+    goto ION_ALLOC_FAILED;
+  }
+
+  p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle;
+  rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]);
+  if (rc < 0) {
+    LOGE("ION map failed %s\n", strerror(errno));
+    goto ION_MAP_FAILED;
+  }
+  p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd;
+  return 0;
+
+ION_MAP_FAILED:
+  handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
+  ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
+ION_ALLOC_FAILED:
+  close(p_camera_memory->main_ion_fd[cnt]);
+  p_camera_memory->main_ion_fd[cnt] = -1;
+ION_OPEN_FAILED:
+  return -1;
+}
+
+int QCameraHardwareInterface::deallocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt)
+{
+  struct ion_handle_data handle_data;
+  int rc = 0;
+
+  if (p_camera_memory->main_ion_fd[cnt] > 0) {
+      handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
+      ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
+      close(p_camera_memory->main_ion_fd[cnt]);
+      p_camera_memory->main_ion_fd[cnt] = -1;
+  }
+  return rc;
+}
+
+int QCameraHardwareInterface::allocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt, int ion_type)
+{
+  int rc = 0;
+  struct ion_handle_data handle_data;
+
+  p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
+  if (p_camera_memory->main_ion_fd[cnt] < 0) {
+    LOGE("Ion dev open failed\n");
+    LOGE("Error is %s\n", strerror(errno));
+    goto ION_OPEN_FAILED;
+  }
+  p_camera_memory->alloc[cnt].len = p_camera_memory->size;
+  /* to make it page size aligned */
+  p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095);
+  p_camera_memory->alloc[cnt].align = 4096;
+  p_camera_memory->alloc[cnt].flags = (0x1 << ion_type | 0x1 << ION_IOMMU_HEAP_ID);
+
+  rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]);
+  if (rc < 0) {
+    LOGE("ION allocation failed\n");
+    goto ION_ALLOC_FAILED;
+  }
+
+  p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle;
+  rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]);
+  if (rc < 0) {
+    LOGE("ION map failed %s\n", strerror(errno));
+    goto ION_MAP_FAILED;
+  }
+  p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd;
+  return 0;
+
+ION_MAP_FAILED:
+  handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
+  ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
+ION_ALLOC_FAILED:
+  close(p_camera_memory->main_ion_fd[cnt]);
+  p_camera_memory->main_ion_fd[cnt] = -1;
+ION_OPEN_FAILED:
+  return -1;
+}
+
+int QCameraHardwareInterface::cache_ops(int ion_fd,
+  struct ion_flush_data *cache_data, int type)
+{
+  int rc = 0;
+
+  rc = ioctl(ion_fd, type, cache_data);
+  if (rc < 0)
+    LOGE("%s: Cache Invalidate failed\n", __func__);
+  else
+    LOGV("%s: Cache OPs type(%d) success", __func__);
+
+  return rc;
+}
+
+int QCameraHardwareInterface::deallocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt)
+{
+  struct ion_handle_data handle_data;
+  int rc = 0;
+
+  if (p_camera_memory->main_ion_fd[cnt] > 0) {
+      handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
+      ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
+      close(p_camera_memory->main_ion_fd[cnt]);
+      p_camera_memory->main_ion_fd[cnt] = -1;
+  }
+  return rc;
+}
+
+int QCameraHardwareInterface::initHeapMem( QCameraHalHeap_t *heap,
+                            int num_of_buf,
+                            int buf_len,
+                            int y_off,
+                            int cbcr_off,
+                            int pmem_type,
+                            mm_cameara_stream_buf_t *StreamBuf,
+                            mm_camera_buf_def_t *buf_def,
+                            uint8_t num_planes,
+                            uint32_t *planes
+)
+{
+    int rc = 0;
+    int i;
+    int path;
+    struct msm_frame *frame;
+    LOGE("Init Heap =%p. stream_buf =%p, pmem_type =%d, num_of_buf=%d. buf_len=%d, cbcr_off=%d",
+         heap, StreamBuf, pmem_type, num_of_buf, buf_len, cbcr_off);
+    if(num_of_buf > MM_CAMERA_MAX_NUM_FRAMES || heap == NULL ||
+       mGetMemory == NULL ) {
+        LOGE("Init Heap error");
+        rc = -1;
+        return rc;
+    }
+    memset(heap, 0, sizeof(QCameraHalHeap_t));
+    for (i=0; i<MM_CAMERA_MAX_NUM_FRAMES;i++) {
+        heap->main_ion_fd[i] = -1;
+        heap->fd[i] = -1;
+    }
+    heap->buffer_count = num_of_buf;
+    heap->size = buf_len;
+    heap->y_offset = y_off;
+    heap->cbcr_offset = cbcr_off;
+
+    if (StreamBuf != NULL) {
+        StreamBuf->num = num_of_buf;
+                StreamBuf->frame_len = buf_len;
+        switch (pmem_type) {
+            case  MSM_PMEM_MAINIMG:
+            case  MSM_PMEM_RAW_MAINIMG:
+                path = OUTPUT_TYPE_S;
+                break;
+
+            case  MSM_PMEM_THUMBNAIL:
+                path = OUTPUT_TYPE_T;
+                break;
+
+            default:
+                rc = -1;
+                return rc;
+        }
+    }
+
+
+    for(i = 0; i < num_of_buf; i++) {
+#ifdef USE_ION
+      if (isZSLMode())
+        rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
+         (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
+      else
+        rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ION_HEAP_ID) |
+         (0x1 << CAMERA_ION_FALLBACK_HEAP_ID)));
+
+      if (rc < 0) {
+        LOGE("%sION allocation failed\n", __func__);
+        break;
+      }
+#else
+        if (pmem_type == MSM_PMEM_MAX)
+            heap->fd[i] = -1;
+        else {
+            heap->fd[i] = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
+            if ( heap->fd[i] <= 0) {
+                rc = -1;
+                LOGE("Open fail: heap->fd[%d] =%d", i, heap->fd[i]);
+                break;
+            }
+        }
+#endif
+        heap->camera_memory[i] =  mGetMemory( heap->fd[i], buf_len, 1, (void *)this);
+
+        if (heap->camera_memory[i] == NULL ) {
+            LOGE("Getmem fail %d: ", i);
+            rc = -1;
+            break;
+        }
+        if (StreamBuf != NULL) {
+            frame = &(StreamBuf->frame[i]);
+            memset(frame, 0, sizeof(struct msm_frame));
+            frame->fd = heap->fd[i];
+            frame->phy_offset = 0;
+            frame->buffer = (uint32_t) heap->camera_memory[i]->data;
+            frame->path = path;
+            frame->cbcr_off =  planes[0]+heap->cbcr_offset;
+            frame->y_off =  heap->y_offset;
+            frame->fd_data = heap->ion_info_fd[i];
+            frame->ion_alloc = heap->alloc[i];
+            frame->ion_dev_fd = heap->main_ion_fd[i];
+            LOGD("%s: Buffer idx: %d  addr: %x fd: %d phy_offset: %d"
+                 "cbcr_off: %d y_off: %d frame_len: %d", __func__,
+                 i, (unsigned int)frame->buffer, frame->fd,
+                 frame->phy_offset, cbcr_off, y_off, frame->ion_alloc.len);
+
+            buf_def->buf.mp[i].frame = *frame;
+            buf_def->buf.mp[i].frame_offset = 0;
+            buf_def->buf.mp[i].num_planes = num_planes;
+            /* Plane 0 needs to be set seperately. Set other planes
+             * in a loop. */
+            buf_def->buf.mp[i].planes[0].length = planes[0];
+            buf_def->buf.mp[i].planes[0].m.userptr = frame->fd;
+            buf_def->buf.mp[i].planes[0].data_offset = y_off;
+            buf_def->buf.mp[i].planes[0].reserved[0] =
+              buf_def->buf.mp[i].frame_offset;
+            for (int j = 1; j < num_planes; j++) {
+                 buf_def->buf.mp[i].planes[j].length = planes[j];
+                 buf_def->buf.mp[i].planes[j].m.userptr = frame->fd;
+                 buf_def->buf.mp[i].planes[j].data_offset = cbcr_off;
+                 buf_def->buf.mp[i].planes[j].reserved[0] =
+                     buf_def->buf.mp[i].planes[j-1].reserved[0] +
+                     buf_def->buf.mp[i].planes[j-1].length;
+            }
+        } else {
+        }
+
+        LOGE("heap->fd[%d] =%d, camera_memory=%p", i, heap->fd[i], heap->camera_memory[i]);
+        heap->local_flag[i] = 1;
+    }
+    if( rc < 0) {
+        releaseHeapMem(heap);
+    }
+    return rc;
+
+}
+
+int QCameraHardwareInterface::releaseHeapMem( QCameraHalHeap_t *heap)
+{
+	int rc = 0;
+	LOGE("Release %p", heap);
+	if (heap != NULL) {
+
+		for (int i = 0; i < heap->buffer_count; i++) {
+			if(heap->camera_memory[i] != NULL) {
+				heap->camera_memory[i]->release( heap->camera_memory[i] );
+				heap->camera_memory[i] = NULL;
+			} else if (heap->fd[i] <= 0) {
+				LOGE("impossible: amera_memory[%d] = %p, fd = %d",
+				i, heap->camera_memory[i], heap->fd[i]);
+			}
+
+			if(heap->fd[i] > 0) {
+				close(heap->fd[i]);
+				heap->fd[i] = -1;
+			}
+#ifdef USE_ION
+            deallocate_ion_memory(heap, i);
+#endif
+		}
+        heap->buffer_count = 0;
+        heap->size = 0;
+        heap->y_offset = 0;
+        heap->cbcr_offset = 0;
+	}
+	return rc;
+}
+
+preview_format_info_t  QCameraHardwareInterface::getPreviewFormatInfo( )
+{
+  return mPreviewFormatInfo;
+}
+
+void QCameraHardwareInterface::wdenoiseEvent(cam_ctrl_status_t status, void *cookie)
+{
+    LOGI("wdnEvent: preview state:%d E",mPreviewState);
+    if (mStreamSnap != NULL) {
+        LOGI("notifyWDNEvent to snapshot stream");
+        mStreamSnap->notifyWDenoiseEvent(status, cookie);
+    }
+}
+
+bool QCameraHardwareInterface::isWDenoiseEnabled()
+{
+    return mDenoiseValue;
+}
+
+void QCameraHardwareInterface::takePicturePrepareHardware()
+{
+    LOGV("%s: E", __func__);
+
+    /* Prepare snapshot*/
+    cam_ops_action(mCameraId,
+                  TRUE,
+                  MM_CAMERA_OPS_PREPARE_SNAPSHOT,
+                  this);
+    LOGV("%s: X", __func__);
+}
+
+bool QCameraHardwareInterface::isNoDisplayMode()
+{
+  return (mNoDisplayMode != 0);
+}
+
+void QCameraHardwareInterface::pausePreviewForZSL()
+{
+    if(mRestartPreview) {
+        stopPreviewInternal();
+        mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+        startPreview2();
+        mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
+        mRestartPreview = false;
+    }
+}
+}; // namespace android
+
diff --git a/camera/QCamera/HAL/core/src/QCameraHWI_Mem.cpp b/camera/QCamera/HAL/core/src/QCameraHWI_Mem.cpp
new file mode 100755
index 0000000..fbd7180
--- /dev/null
+++ b/camera/QCamera/HAL/core/src/QCameraHWI_Mem.cpp
@@ -0,0 +1,402 @@
+/*
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+//#define LOG_NDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG "QCameraHWI_Mem"
+#include <utils/Log.h>
+
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <binder/MemoryHeapPmem.h>
+#include <utils/String16.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <cutils/properties.h>
+#include <math.h>
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+#include <linux/ioctl.h>
+#include <camera/CameraParameters.h>
+#include <media/mediarecorder.h>
+#include <gralloc_priv.h>
+
+#include "QCameraHWI_Mem.h"
+
+#define CAMERA_HAL_UNUSED(expr) do { (void)(expr); } while (0)
+
+/* QCameraHardwareInterface class implementation goes here*/
+/* following code implement the contol logic of this class*/
+
+namespace android {
+
+
+static bool register_buf(int size,
+                         int frame_size,
+                         int cbcr_offset,
+                         int yoffset,
+                         int pmempreviewfd,
+                         uint32_t offset,
+                         uint8_t *buf,
+                         int pmem_type,
+                         bool vfe_can_write,
+                         bool register_buffer = true);
+
+#if 0
+MMCameraDL::MMCameraDL(){
+    LOGV("MMCameraDL: E");
+    libmmcamera = NULL;
+#if DLOPEN_LIBMMCAMERA
+    libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
+#endif
+    LOGV("Open MM camera DL libeomcamera loaded at %p ", libmmcamera);
+    LOGV("MMCameraDL: X");
+}
+
+void * MMCameraDL::pointer(){
+    return libmmcamera;
+}
+
+MMCameraDL::~MMCameraDL(){
+    LOGV("~MMCameraDL: E");
+    LINK_mm_camera_destroy();
+    if (libmmcamera != NULL) {
+        ::dlclose(libmmcamera);
+        LOGV("closed MM Camera DL ");
+    }
+    libmmcamera = NULL;
+    LOGV("~MMCameraDL: X");
+}
+
+
+wp<MMCameraDL> MMCameraDL::instance;
+Mutex MMCameraDL::singletonLock;
+
+
+sp<MMCameraDL> MMCameraDL::getInstance(){
+    Mutex::Autolock instanceLock(singletonLock);
+    sp<MMCameraDL> mmCamera = instance.promote();
+    if(mmCamera == NULL){
+        mmCamera = new MMCameraDL();
+        instance = mmCamera;
+    }
+    return mmCamera;
+}
+#endif
+
+MemPool::MemPool(int buffer_size, int num_buffers,
+                                         int frame_size,
+                                         const char *name) :
+    mBufferSize(buffer_size),
+    mNumBuffers(num_buffers),
+    mFrameSize(frame_size),
+    mBuffers(NULL), mName(name)
+{
+    int page_size_minus_1 = getpagesize() - 1;
+    mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1);
+}
+
+void MemPool::completeInitialization()
+{
+    // If we do not know how big the frame will be, we wait to allocate
+    // the buffers describing the individual frames until we do know their
+    // size.
+
+    if (mFrameSize > 0) {
+        mBuffers = new sp<MemoryBase>[mNumBuffers];
+        for (int i = 0; i < mNumBuffers; i++) {
+            mBuffers[i] = new
+                MemoryBase(mHeap,
+                           i * mAlignedBufferSize,
+                           mFrameSize);
+        }
+    }
+}
+
+AshmemPool::AshmemPool(int buffer_size, int num_buffers,
+                                               int frame_size,
+                                               const char *name) :
+    MemPool(buffer_size,
+                                    num_buffers,
+                                    frame_size,
+                                    name)
+{
+    LOGV("constructing MemPool %s backed by ashmem: "
+         "%d frames @ %d uint8_ts, "
+         "buffer size %d",
+         mName,
+         num_buffers, frame_size, buffer_size);
+
+    int page_mask = getpagesize() - 1;
+    int ashmem_size = buffer_size * num_buffers;
+    ashmem_size += page_mask;
+    ashmem_size &= ~page_mask;
+
+    mHeap = new MemoryHeapBase(ashmem_size);
+
+    completeInitialization();
+}
+
+static bool register_buf(int size,
+                         int frame_size,
+                         int cbcr_offset,
+                         int yoffset,
+                         int pmempreviewfd,
+                         uint32_t offset,
+                         uint8_t *buf,
+                         int pmem_type,
+                         bool vfe_can_write,
+                         bool register_buffer)
+{
+    struct msm_pmem_info pmemBuf;
+    CAMERA_HAL_UNUSED(frame_size);
+
+    pmemBuf.type     = pmem_type;
+    pmemBuf.fd       = pmempreviewfd;
+    pmemBuf.offset   = offset;
+    pmemBuf.len      = size;
+    pmemBuf.vaddr    = buf;
+    pmemBuf.y_off    = yoffset;
+    pmemBuf.cbcr_off = cbcr_offset;
+
+    pmemBuf.active   = vfe_can_write;
+
+    LOGV("register_buf:  reg = %d buffer = %p",
+         !register_buffer, buf);
+    /*TODO*/
+    /*if(native_start_ops(register_buffer ? CAMERA_OPS_REGISTER_BUFFER :
+        CAMERA_OPS_UNREGISTER_BUFFER ,(void *)&pmemBuf) < 0) {
+         LOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM  error %s",
+               strerror(errno));
+         return false;
+         }*/
+
+    return true;
+
+}
+
+#if 0
+bool register_record_buffers(bool register_buffer) {
+    LOGI("%s: (%d) E", __FUNCTION__, register_buffer);
+    struct msm_pmem_info pmemBuf;
+
+    for (int cnt = 0; cnt < VIDEO_BUFFER_COUNT; ++cnt) {
+        pmemBuf.type     = MSM_PMEM_VIDEO;
+        pmemBuf.fd       = mRecordHeap->mHeap->getHeapID();
+        pmemBuf.offset   = mRecordHeap->mAlignedBufferSize * cnt;
+        pmemBuf.len      = mRecordHeap->mBufferSize;
+        pmemBuf.vaddr    = (uint8_t *)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt;
+        pmemBuf.y_off    = 0;
+        pmemBuf.cbcr_off = recordframes[0].cbcr_off;
+        if(register_buffer == true) {
+            pmemBuf.active   = (cnt<ACTIVE_VIDEO_BUFFERS);
+            if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
+                pmemBuf.type = MSM_PMEM_VIDEO_VPE;
+                pmemBuf.active = 1;
+            }
+        } else {
+            pmemBuf.active   = false;
+        }
+
+        LOGV("register_buf:  reg = %d buffer = %p", !register_buffer,
+          (void *)pmemBuf.vaddr);
+        if(native_start_ops(register_buffer ? CAMERA_OPS_REGISTER_BUFFER :
+                CAMERA_OPS_UNREGISTER_BUFFER ,(void *)&pmemBuf) < 0) {
+            LOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM  error %s",
+                strerror(errno));
+            return false;
+        }
+    }
+    return true;
+}
+#endif
+PmemPool::PmemPool(const char *pmem_pool,
+                                           int flags,
+                                           int pmem_type,
+                                           int buffer_size, int num_buffers,
+                                           int frame_size, int cbcr_offset,
+                                           int yOffset, const char *name) :
+    MemPool(buffer_size,num_buffers,frame_size,name),
+    mPmemType(pmem_type),
+    mCbCrOffset(cbcr_offset),
+    myOffset(yOffset)
+{
+    LOGI("constructing MemPool %s backed by pmem pool %s: "
+         "%d frames @ %d bytes, buffer size %d",
+         mName,
+         pmem_pool, num_buffers, frame_size,
+         buffer_size);
+
+    //mMMCameraDLRef = MMCameraDL::getInstance();
+
+
+    // Make a new mmap'ed heap that can be shared across processes.
+    // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
+    mAlignedSize = mAlignedBufferSize * num_buffers;
+
+    sp<MemoryHeapBase> masterHeap =
+        new MemoryHeapBase(pmem_pool, mAlignedSize, flags);
+
+    if (masterHeap->getHeapID() < 0) {
+        LOGE("failed to construct master heap for pmem pool %s", pmem_pool);
+        masterHeap.clear();
+        return;
+    }
+
+    sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
+    if (pmemHeap->getHeapID() >= 0) {
+        pmemHeap->slap();
+        masterHeap.clear();
+        mHeap = pmemHeap;
+        pmemHeap.clear();
+
+        mFd = mHeap->getHeapID();
+        if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
+            LOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
+                 pmem_pool,
+                 ::strerror(errno), errno);
+            mHeap.clear();
+            return;
+        }
+
+        LOGE("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld",
+             pmem_pool,
+             mFd,
+             mSize.len);
+        LOGE("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize);
+
+#if 0
+        // Unregister preview buffers with the camera drivers.  Allow the VFE to write
+        // to all preview buffers except for the last one.
+        // Only Register the preview, snapshot and thumbnail buffers with the kernel.
+        if( (strcmp("postview", mName) != 0) ){
+            int num_buf = num_buffers;
+            if(!strcmp("preview", mName)) num_buf = kPreviewBufferCount;
+            LOGD("num_buffers = %d", num_buf);
+            for (int cnt = 0; cnt < num_buf; ++cnt) {
+                int active = 1;
+                if(pmem_type == MSM_PMEM_VIDEO){
+                     active = (cnt<ACTIVE_VIDEO_BUFFERS);
+                     //When VPE is enabled, set the last record
+                     //buffer as active and pmem type as PMEM_VIDEO_VPE
+                     //as this is a requirement from VPE operation.
+                     //No need to set this pmem type to VIDEO_VPE while unregistering,
+                     //because as per camera stack design: "the VPE AXI is also configured
+                     //when VFE is configured for VIDEO, which is as part of preview
+                     //initialization/start. So during this VPE AXI config camera stack
+                     //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and
+                     //change it's type to PMEM_VIDEO".
+                     if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
+                         active = 1;
+                         pmem_type = MSM_PMEM_VIDEO_VPE;
+                     }
+                     LOGV(" pmempool creating video buffers : active %d ", active);
+                }
+                else if (pmem_type == MSM_PMEM_PREVIEW){
+                    active = (cnt < ACTIVE_PREVIEW_BUFFERS);
+                }
+                else if ((pmem_type == MSM_PMEM_MAINIMG)
+                     || (pmem_type == MSM_PMEM_THUMBNAIL)){
+                    active = (cnt < ACTIVE_ZSL_BUFFERS);
+                }
+                register_buf(mBufferSize,
+                         mFrameSize, mCbCrOffset, myOffset,
+                         mHeap->getHeapID(),
+                         mAlignedBufferSize * cnt,
+                         (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
+                         pmem_type,
+                         active);
+            }
+        }
+#endif
+        completeInitialization();
+    }
+    else LOGE("pmem pool %s error: could not create master heap!",
+              pmem_pool);
+    LOGI("%s: (%s) X ", __FUNCTION__, mName);
+}
+
+PmemPool::~PmemPool()
+{
+    LOGI("%s: %s E", __FUNCTION__, mName);
+#if 0
+    if (mHeap != NULL) {
+        // Unregister preview buffers with the camera drivers.
+        //  Only Unregister the preview, snapshot and thumbnail
+        //  buffers with the kernel.
+        if( (strcmp("postview", mName) != 0) ){
+            int num_buffers = mNumBuffers;
+            if(!strcmp("preview", mName)) num_buffers = PREVIEW_BUFFER_COUNT;
+            for (int cnt = 0; cnt < num_buffers; ++cnt) {
+                register_buf(mBufferSize,
+                         mFrameSize,
+                         mCbCrOffset,
+                         myOffset,
+                         mHeap->getHeapID(),
+                         mAlignedBufferSize * cnt,
+                         (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
+                         mPmemType,
+                         false,
+                         false /* unregister */);
+            }
+        }
+    }
+    mMMCameraDLRef.clear();
+#endif
+    LOGI("%s: %s X", __FUNCTION__, mName);
+}
+MemPool::~MemPool()
+{
+    LOGV("destroying MemPool %s", mName);
+    if (mFrameSize > 0)
+        delete [] mBuffers;
+    mHeap.clear();
+    LOGV("destroying MemPool %s completed", mName);
+}
+
+
+status_t MemPool::dump(int fd, const Vector<String16>& args) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    CAMERA_HAL_UNUSED(args);
+    snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
+    result.append(buffer);
+    if (mName) {
+        snprintf(buffer, 255, "mem pool name (%s)\n", mName);
+        result.append(buffer);
+    }
+    if (mHeap != 0) {
+        snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
+                 mHeap->getBase(), mHeap->getSize(),
+                 mHeap->getFlags(), mHeap->getDevice());
+        result.append(buffer);
+    }
+    snprintf(buffer, 255,
+             "buffer size (%d), number of buffers (%d), frame size(%d)",
+             mBufferSize, mNumBuffers, mFrameSize);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+};
diff --git a/camera/QCamera/HAL/core/src/QCameraHWI_Parm.cpp b/camera/QCamera/HAL/core/src/QCameraHWI_Parm.cpp
new file mode 100755
index 0000000..564a481
--- /dev/null
+++ b/camera/QCamera/HAL/core/src/QCameraHWI_Parm.cpp
@@ -0,0 +1,4073 @@
+/*
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG "QCameraHWI_Parm"
+#include <utils/Log.h>
+
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <binder/MemoryHeapPmem.h>
+#include <utils/String16.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <cutils/properties.h>
+#include <math.h>
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+#include <linux/ioctl.h>
+#include <camera/CameraParameters.h>
+#include <media/mediarecorder.h>
+#include <gralloc_priv.h>
+
+#include "linux/msm_mdp.h"
+#include <linux/fb.h>
+#include <limits>
+
+
+extern "C" {
+#include <fcntl.h>
+#include <time.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <termios.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/system_properties.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <linux/ion.h>
+#include <camera.h>
+#include <cam_fifo.h>
+#include <jpege.h>
+
+} // extern "C"
+
+#include "QCameraHWI.h"
+
+/* QCameraHardwareInterface class implementation goes here*/
+/* following code implements the parameter logic of this class*/
+#define EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR 12
+#define EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR -12
+#define EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR 0
+#define EXPOSURE_COMPENSATION_DENOMINATOR 6
+#define EXPOSURE_COMPENSATION_STEP ((float (1))/EXPOSURE_COMPENSATION_DENOMINATOR)
+#define DEFAULT_CAMERA_AREA "(0, 0, 0, 0, 0)"
+
+#define HDR_HAL_FRAME 2
+
+#define BURST_INTREVAL_MIN 1
+#define BURST_INTREVAL_MAX 10
+#define BURST_INTREVAL_DEFAULT 1
+
+//Default FPS
+#define MINIMUM_FPS 5
+#define MAXIMUM_FPS 120
+#define DEFAULT_FIXED_FPS 30
+#define DEFAULT_FPS MAXIMUM_FPS
+
+//Default Picture Width
+#define DEFAULT_PICTURE_WIDTH  640
+#define DEFAULT_PICTURE_HEIGHT 480
+
+//Default Video Width
+#define DEFAULT_VIDEO_WIDTH 1920
+#define DEFAULT_VIDEO_HEIGHT 1088
+
+#define THUMBNAIL_SIZE_COUNT (sizeof(thumbnail_sizes)/sizeof(thumbnail_size_type))
+#define DEFAULT_THUMBNAIL_SETTING 4
+#define THUMBNAIL_WIDTH_STR "512"
+#define THUMBNAIL_HEIGHT_STR "384"
+#define THUMBNAIL_SMALL_HEIGHT 144
+
+#define DONT_CARE_COORDINATE -1
+
+//for histogram stats
+#define HISTOGRAM_STATS_SIZE 257
+
+//Supported preview fps ranges should be added to this array in the form (minFps,maxFps)
+static  android::FPSRange FpsRangesSupported[] = {
+            android::FPSRange(MINIMUM_FPS*1000,MAXIMUM_FPS*1000)
+        };
+#define FPS_RANGES_SUPPORTED_COUNT (sizeof(FpsRangesSupported)/sizeof(FpsRangesSupported[0]))
+
+
+typedef struct {
+    uint32_t aspect_ratio;
+    uint32_t width;
+    uint32_t height;
+} thumbnail_size_type;
+
+static thumbnail_size_type thumbnail_sizes[] = {
+{ 7281, 512, 288 }, //1.777778
+{ 6826, 480, 288 }, //1.666667
+{ 6808, 256, 154 }, //1.66233
+{ 6144, 432, 288 }, //1.5
+{ 5461, 512, 384 }, //1.333333
+{ 5006, 352, 288 }, //1.222222
+{ 5461, 320, 240 }, //1.33333
+{ 5006, 176, 144 }, //1.222222
+
+};
+
+static struct camera_size_type zsl_picture_sizes[] = {
+  { 1024, 768}, // 1MP XGA
+  { 800, 600}, //SVGA
+  { 800, 480}, // WVGA
+  { 640, 480}, // VGA
+  { 352, 288}, //CIF
+  { 320, 240}, // QVGA
+  { 176, 144} // QCIF
+};
+
+static camera_size_type default_picture_sizes[] = {
+  { 4000, 3000}, // 12MP
+  { 3200, 2400}, // 8MP
+  { 2592, 1944}, // 5MP
+  { 2048, 1536}, // 3MP QXGA
+  { 1920, 1088}, //HD1080
+  { 1600, 1200}, // 2MP UXGA
+  { 1280, 768}, //WXGA
+  { 1280, 720}, //HD720
+  { 1024, 768}, // 1MP XGA
+  { 800, 600}, //SVGA
+  { 800, 480}, // WVGA
+  { 640, 480}, // VGA
+  { 352, 288}, //CIF
+  { 320, 240}, // QVGA
+  { 176, 144} // QCIF
+};
+
+static int iso_speed_values[] = {
+    0, 1, 100, 200, 400, 800, 1600
+};
+
+extern int HAL_numOfCameras;
+extern camera_info_t HAL_cameraInfo[MSM_MAX_CAMERA_SENSORS];
+extern mm_camera_t * HAL_camerahandle[MSM_MAX_CAMERA_SENSORS];
+
+namespace android {
+
+static uint32_t  HFR_SIZE_COUNT=2;
+static const int PICTURE_FORMAT_JPEG = 1;
+static const int PICTURE_FORMAT_RAW = 2;
+
+/********************************************************************/
+static const str_map effects[] = {
+    { CameraParameters::EFFECT_NONE,       CAMERA_EFFECT_OFF },
+    { CameraParameters::EFFECT_MONO,       CAMERA_EFFECT_MONO },
+    { CameraParameters::EFFECT_NEGATIVE,   CAMERA_EFFECT_NEGATIVE },
+    { CameraParameters::EFFECT_SOLARIZE,   CAMERA_EFFECT_SOLARIZE },
+    { CameraParameters::EFFECT_SEPIA,      CAMERA_EFFECT_SEPIA },
+    { CameraParameters::EFFECT_POSTERIZE,  CAMERA_EFFECT_POSTERIZE },
+    { CameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
+    { CameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
+    { CameraParameters::EFFECT_AQUA,       CAMERA_EFFECT_AQUA },
+    { CameraParameters::EFFECT_EMBOSS,     CAMERA_EFFECT_EMBOSS },
+    { CameraParameters::EFFECT_SKETCH,     CAMERA_EFFECT_SKETCH },
+    { CameraParameters::EFFECT_NEON,       CAMERA_EFFECT_NEON }
+};
+
+static const str_map iso[] = {
+    { CameraParameters::ISO_AUTO,  CAMERA_ISO_AUTO},
+    { CameraParameters::ISO_HJR,   CAMERA_ISO_DEBLUR},
+    { CameraParameters::ISO_100,   CAMERA_ISO_100},
+    { CameraParameters::ISO_200,   CAMERA_ISO_200},
+    { CameraParameters::ISO_400,   CAMERA_ISO_400},
+    { CameraParameters::ISO_800,   CAMERA_ISO_800 },
+    { CameraParameters::ISO_1600,  CAMERA_ISO_1600 }
+};
+
+static const str_map scenemode[] = {
+    { CameraParameters::SCENE_MODE_AUTO,           CAMERA_BESTSHOT_OFF },
+    { CameraParameters::SCENE_MODE_ASD,            CAMERA_BESTSHOT_AUTO },
+    { CameraParameters::SCENE_MODE_ACTION,         CAMERA_BESTSHOT_ACTION },
+    { CameraParameters::SCENE_MODE_PORTRAIT,       CAMERA_BESTSHOT_PORTRAIT },
+    { CameraParameters::SCENE_MODE_LANDSCAPE,      CAMERA_BESTSHOT_LANDSCAPE },
+    { CameraParameters::SCENE_MODE_NIGHT,          CAMERA_BESTSHOT_NIGHT },
+    { CameraParameters::SCENE_MODE_NIGHT_PORTRAIT, CAMERA_BESTSHOT_NIGHT_PORTRAIT },
+    { CameraParameters::SCENE_MODE_THEATRE,        CAMERA_BESTSHOT_THEATRE },
+    { CameraParameters::SCENE_MODE_BEACH,          CAMERA_BESTSHOT_BEACH },
+    { CameraParameters::SCENE_MODE_SNOW,           CAMERA_BESTSHOT_SNOW },
+    { CameraParameters::SCENE_MODE_SUNSET,         CAMERA_BESTSHOT_SUNSET },
+    { CameraParameters::SCENE_MODE_STEADYPHOTO,    CAMERA_BESTSHOT_ANTISHAKE },
+    { CameraParameters::SCENE_MODE_FIREWORKS ,     CAMERA_BESTSHOT_FIREWORKS },
+    { CameraParameters::SCENE_MODE_SPORTS ,        CAMERA_BESTSHOT_SPORTS },
+    { CameraParameters::SCENE_MODE_PARTY,          CAMERA_BESTSHOT_PARTY },
+    { CameraParameters::SCENE_MODE_CANDLELIGHT,    CAMERA_BESTSHOT_CANDLELIGHT },
+    { CameraParameters::SCENE_MODE_BACKLIGHT,      CAMERA_BESTSHOT_BACKLIGHT },
+    { CameraParameters::SCENE_MODE_FLOWERS,        CAMERA_BESTSHOT_FLOWERS },
+    { CameraParameters::SCENE_MODE_AR,             CAMERA_BESTSHOT_AR },
+};
+
+static const str_map scenedetect[] = {
+    { CameraParameters::SCENE_DETECT_OFF, FALSE  },
+    { CameraParameters::SCENE_DETECT_ON, TRUE },
+};
+
+#define DONT_CARE AF_MODE_MAX
+static const str_map focus_modes[] = {
+    { CameraParameters::FOCUS_MODE_AUTO,     AF_MODE_AUTO},
+    { CameraParameters::FOCUS_MODE_INFINITY, AF_MODE_INFINITY },
+    { CameraParameters::FOCUS_MODE_NORMAL,   AF_MODE_NORMAL },
+    { CameraParameters::FOCUS_MODE_MACRO,    AF_MODE_MACRO },
+    { CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE, AF_MODE_CAF},
+    { CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, AF_MODE_CAF }
+};
+
+static const str_map selectable_zone_af[] = {
+    { CameraParameters::SELECTABLE_ZONE_AF_AUTO,  AUTO },
+    { CameraParameters::SELECTABLE_ZONE_AF_SPOT_METERING, SPOT },
+    { CameraParameters::SELECTABLE_ZONE_AF_CENTER_WEIGHTED, CENTER_WEIGHTED },
+    { CameraParameters::SELECTABLE_ZONE_AF_FRAME_AVERAGE, AVERAGE }
+};
+
+// from qcamera/common/camera.h
+static const str_map autoexposure[] = {
+    { CameraParameters::AUTO_EXPOSURE_FRAME_AVG,  CAMERA_AEC_FRAME_AVERAGE },
+    { CameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
+    { CameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
+};
+
+// from aeecamera.h
+static const str_map whitebalance[] = {
+    { CameraParameters::WHITE_BALANCE_AUTO,            CAMERA_WB_AUTO },
+    { CameraParameters::WHITE_BALANCE_INCANDESCENT,    CAMERA_WB_INCANDESCENT },
+    { CameraParameters::WHITE_BALANCE_FLUORESCENT,     CAMERA_WB_FLUORESCENT },
+    { CameraParameters::WHITE_BALANCE_DAYLIGHT,        CAMERA_WB_DAYLIGHT },
+    { CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
+};
+
+static const str_map antibanding[] = {
+    { CameraParameters::ANTIBANDING_OFF,  CAMERA_ANTIBANDING_OFF },
+    { CameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
+    { CameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
+    { CameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
+};
+
+static const str_map frame_rate_modes[] = {
+        {CameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE, FPS_MODE_AUTO},
+        {CameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE, FPS_MODE_FIXED}
+};
+
+static const str_map touchafaec[] = {
+    { CameraParameters::TOUCH_AF_AEC_OFF, FALSE },
+    { CameraParameters::TOUCH_AF_AEC_ON, TRUE }
+};
+
+static const str_map hfr[] = {
+    { CameraParameters::VIDEO_HFR_OFF, CAMERA_HFR_MODE_OFF },
+    { CameraParameters::VIDEO_HFR_2X, CAMERA_HFR_MODE_60FPS },
+    { CameraParameters::VIDEO_HFR_3X, CAMERA_HFR_MODE_90FPS },
+    { CameraParameters::VIDEO_HFR_4X, CAMERA_HFR_MODE_120FPS },
+};
+static const int HFR_VALUES_COUNT = (sizeof(hfr)/sizeof(str_map));
+
+static const str_map flash[] = {
+    { CameraParameters::FLASH_MODE_OFF,  LED_MODE_OFF },
+    { CameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
+    { CameraParameters::FLASH_MODE_ON, LED_MODE_ON },
+    { CameraParameters::FLASH_MODE_TORCH, LED_MODE_TORCH}
+};
+
+static const str_map lensshade[] = {
+    { CameraParameters::LENSSHADE_ENABLE, TRUE },
+    { CameraParameters::LENSSHADE_DISABLE, FALSE }
+};
+
+static const str_map mce[] = {
+    { CameraParameters::MCE_ENABLE, TRUE },
+    { CameraParameters::MCE_DISABLE, FALSE }
+};
+
+static const str_map histogram[] = {
+    { CameraParameters::HISTOGRAM_ENABLE, TRUE },
+    { CameraParameters::HISTOGRAM_DISABLE, FALSE }
+};
+
+static const str_map skinToneEnhancement[] = {
+    { CameraParameters::SKIN_TONE_ENHANCEMENT_ENABLE, TRUE },
+    { CameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE, FALSE }
+};
+
+static const str_map denoise[] = {
+    { CameraParameters::DENOISE_OFF, FALSE },
+    { CameraParameters::DENOISE_ON, TRUE }
+};
+
+static const str_map facedetection[] = {
+    { CameraParameters::FACE_DETECTION_OFF, FALSE },
+    { CameraParameters::FACE_DETECTION_ON, TRUE }
+};
+
+static const str_map redeye_reduction[] = {
+    { CameraParameters::REDEYE_REDUCTION_ENABLE, TRUE },
+    { CameraParameters::REDEYE_REDUCTION_DISABLE, FALSE }
+};
+
+static const str_map picture_formats[] = {
+        {CameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
+        {CameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
+};
+
+static const str_map recording_Hints[] = {
+        {"false", FALSE},
+        {"true",  TRUE}
+};
+
+static const str_map preview_formats[] = {
+        {CameraParameters::PIXEL_FORMAT_YUV420SP,   HAL_PIXEL_FORMAT_YCrCb_420_SP},
+        {CameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO},
+        {CameraParameters::PIXEL_FORMAT_YV12, HAL_PIXEL_FORMAT_YV12},
+        {CameraParameters::PIXEL_FORMAT_YUV420P,HAL_PIXEL_FORMAT_YV12},
+        {CameraParameters::PIXEL_FORMAT_NV12, HAL_PIXEL_FORMAT_YCbCr_420_SP}
+};
+
+static const preview_format_info_t preview_format_info_list[] = {
+  {HAL_PIXEL_FORMAT_YCrCb_420_SP, CAMERA_YUV_420_NV21, CAMERA_PAD_TO_WORD, 2},
+  {HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO, CAMERA_YUV_420_NV21, CAMERA_PAD_TO_4K, 2},
+  {HAL_PIXEL_FORMAT_YCbCr_420_SP, CAMERA_YUV_420_NV12, CAMERA_PAD_TO_WORD, 2},
+  {HAL_PIXEL_FORMAT_YV12,         CAMERA_YUV_420_YV12, CAMERA_PAD_TO_WORD, 3}
+};
+
+static const str_map zsl_modes[] = {
+    { CameraParameters::ZSL_OFF, FALSE },
+    { CameraParameters::ZSL_ON, TRUE },
+};
+
+
+static const str_map hdr_bracket[] = {
+    { CameraParameters::AE_BRACKET_HDR_OFF,HDR_BRACKETING_OFF},
+    { CameraParameters::AE_BRACKET_HDR,HDR_MODE },
+    { CameraParameters::AE_BRACKET,EXP_BRACKETING_MODE }
+};
+
+typedef enum {
+    NORMAL_POWER,
+    LOW_POWER
+} power_mode;
+
+static const str_map power_modes[] = {
+    { CameraParameters::NORMAL_POWER,NORMAL_POWER },
+    { CameraParameters::LOW_POWER,LOW_POWER }
+};
+
+/**************************************************************************/
+static int attr_lookup(const str_map arr[], int len, const char *name)
+{
+    if (name) {
+        for (int i = 0; i < len; i++) {
+            if (!strcmp(arr[i].desc, name))
+                return arr[i].val;
+        }
+    }
+    return NOT_FOUND;
+}
+
+bool QCameraHardwareInterface::native_set_parms(
+    mm_camera_parm_type_t type, uint16_t length, void *value)
+{
+    LOGE("%s : type : %d Value : %d",__func__,type,*((int *)value));
+    if(MM_CAMERA_OK != cam_config_set_parm(mCameraId, type,value )) {
+        LOGE("native_set_parms failed: type %d length %d error %s",
+            type, length, strerror(errno));
+        return false;
+    }
+
+    return true;
+
+}
+
+bool QCameraHardwareInterface::native_set_parms(
+    mm_camera_parm_type_t type, uint16_t length, void *value, int *result)
+{
+    *result= cam_config_set_parm(mCameraId, type,value );
+    if(MM_CAMERA_OK == *result) {
+        LOGE("native_set_parms: succeeded : %d", *result);
+        return true;
+    }
+
+    LOGE("native_set_parms failed: type %d length %d error str %s error# %d",
+        type, length, strerror(errno), errno);
+    return false;
+}
+
+//Filter Picture sizes based on max width and height
+/* TBD: do we still need this - except for ZSL? */
+void QCameraHardwareInterface::filterPictureSizes(){
+    unsigned int i;
+    if(mPictureSizeCount <= 0)
+        return;
+    maxSnapshotWidth = mPictureSizes[0].width;
+    maxSnapshotHeight = mPictureSizes[0].height;
+   // Iterate through all the width and height to find the max value
+    for(i =0; i<mPictureSizeCount;i++){
+        if(((maxSnapshotWidth < mPictureSizes[i].width) &&
+            (maxSnapshotHeight <= mPictureSizes[i].height))){
+            maxSnapshotWidth = mPictureSizes[i].width;
+            maxSnapshotHeight = mPictureSizes[i].height;
+        }
+    }
+    if(myMode & CAMERA_ZSL_MODE){
+        // due to lack of PMEM we restrict to lower resolution
+        mPictureSizesPtr = zsl_picture_sizes;
+        mSupportedPictureSizesCount = 7;
+    }else{
+        mPictureSizesPtr = mPictureSizes;
+        mSupportedPictureSizesCount = mPictureSizeCount;
+    }
+}
+
+static String8 create_sizes_str(const camera_size_type *sizes, int len) {
+    String8 str;
+    char buffer[32];
+
+    if (len > 0) {
+        snprintf(buffer, sizeof(buffer), "%dx%d", sizes[0].width, sizes[0].height);
+        str.append(buffer);
+    }
+    for (int i = 1; i < len; i++) {
+        snprintf(buffer, sizeof(buffer), ",%dx%d", sizes[i].width, sizes[i].height);
+        str.append(buffer);
+    }
+    return str;
+}
+
+String8 QCameraHardwareInterface::create_values_str(const str_map *values, int len) {
+    String8 str;
+
+    if (len > 0) {
+        str.append(values[0].desc);
+    }
+    for (int i = 1; i < len; i++) {
+        str.append(",");
+        str.append(values[i].desc);
+    }
+    return str;
+}
+
+static String8 create_fps_str(const android:: FPSRange* fps, int len) {
+    String8 str;
+    char buffer[32];
+
+    if (len > 0) {
+        snprintf(buffer, sizeof(buffer), "(%d,%d)", fps[0].minFPS, fps[0].maxFPS);
+        str.append(buffer);
+    }
+    for (int i = 1; i < len; i++) {
+        snprintf(buffer, sizeof(buffer), ",(%d,%d)", fps[i].minFPS, fps[i].maxFPS);
+        str.append(buffer);
+    }
+    return str;
+}
+
+static String8 create_values_range_str(int min, int max){
+    String8 str;
+    char buffer[32];
+
+    if(min <= max){
+        snprintf(buffer, sizeof(buffer), "%d", min);
+        str.append(buffer);
+
+        for (int i = min + 1; i <= max; i++) {
+            snprintf(buffer, sizeof(buffer), ",%d", i);
+            str.append(buffer);
+        }
+    }
+    return str;
+}
+
+static int parse_size(const char *str, int &width, int &height)
+{
+    // Find the width.
+    char *end;
+    int w = (int)strtol(str, &end, 10);
+    // If an 'x' or 'X' does not immediately follow, give up.
+    if ( (*end != 'x') && (*end != 'X') )
+        return -1;
+
+    // Find the height, immediately after the 'x'.
+    int h = (int)strtol(end+1, 0, 10);
+
+    width = w;
+    height = h;
+
+    return 0;
+}
+
+bool QCameraHardwareInterface::isValidDimension(int width, int height) {
+    bool retVal = FALSE;
+    /* This function checks if a given resolution is valid or not.
+     * A particular resolution is considered valid if it satisfies
+     * the following conditions:
+     * 1. width & height should be multiple of 16.
+     * 2. width & height should be less than/equal to the dimensions
+     *    supported by the camera sensor.
+     * 3. the aspect ratio is a valid aspect ratio and is among the
+     *    commonly used aspect ratio as determined by the thumbnail_sizes
+     *    data structure.
+     */
+
+    if( (width == CEILING16(width)) && (height == CEILING16(height))
+     && (width <= maxSnapshotWidth)
+    && (height <= maxSnapshotHeight) )
+    {
+        uint32_t pictureAspectRatio = (uint32_t)((width * Q12)/height);
+        for(uint32_t i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ) {
+            if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio) {
+                retVal = TRUE;
+                break;
+            }
+        }
+    }
+    return retVal;
+}
+
+void QCameraHardwareInterface::hasAutoFocusSupport(){
+
+    LOGV("%s",__func__);
+
+    if(isZSLMode()){
+        mHasAutoFocusSupport = false;
+        return;
+    }
+
+    if(cam_ops_is_op_supported (mCameraId, MM_CAMERA_OPS_FOCUS )) {
+        mHasAutoFocusSupport = true;
+    }
+    else {
+        LOGE("AutoFocus is not supported");
+        mHasAutoFocusSupport = false;
+    }
+
+    LOGV("%s:rc= %d",__func__, mHasAutoFocusSupport);
+
+}
+
+bool QCameraHardwareInterface::supportsSceneDetection() {
+   bool rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_ASD_ENABLE);
+   return rc;
+}
+
+bool QCameraHardwareInterface::supportsFaceDetection() {
+    bool rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_FD);
+    return rc;
+}
+
+bool QCameraHardwareInterface::supportsSelectableZoneAf() {
+   bool rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_FOCUS_RECT);
+   return rc;
+}
+
+bool QCameraHardwareInterface::supportsRedEyeReduction() {
+   bool rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_REDEYE_REDUCTION);
+   return rc;
+}
+
+static String8 create_str(int16_t *arr, int length){
+    String8 str;
+    char buffer[32] = {0};
+
+    if(length > 0){
+        snprintf(buffer, sizeof(buffer), "%d", arr[0]);
+        str.append(buffer);
+    }
+
+    for (int i =1;i<length;i++){
+        snprintf(buffer, sizeof(buffer), ",%d",arr[i]);
+        str.append(buffer);
+    }
+    return str;
+}
+
+bool QCameraHardwareInterface::getMaxPictureDimension(mm_camera_dimension_t *maxDim)
+{
+    bool ret = NO_ERROR;
+    mm_camera_dimension_t dim;
+
+    ret = cam_config_get_parm(mCameraId,
+                              MM_CAMERA_PARM_MAX_PICTURE_SIZE, &dim);
+    if (ret != NO_ERROR)
+        return ret;
+
+    /* Find the first dimension in the mPictureSizes
+     * array which is smaller than the max dimension.
+     * This will be the valid max picture resolution */
+    for (unsigned int i = 0; i < mPictureSizeCount; i++) {
+        if ((mPictureSizes[i].width <= dim.width) &&
+            (mPictureSizes[i].height <= dim.height)) {
+            maxDim->height = mPictureSizes[i].height;
+            maxDim->width  = mPictureSizes[i].width;
+            break;
+        }
+    }
+    LOGD("%s: Found Max Picture dimension: %d x %d", __func__,
+          maxDim->width, maxDim->height);
+    return ret;
+}
+void QCameraHardwareInterface::loadTables()
+{
+
+    bool ret = NO_ERROR;
+    LOGE("%s: E", __func__);
+
+    ret = cam_config_get_parm(mCameraId,
+            MM_CAMERA_PARM_PREVIEW_SIZES_CNT, &preview_sizes_count);
+
+    default_sizes_tbl_t preview_sizes_tbl;
+    preview_sizes_tbl.tbl_size=preview_sizes_count;
+    preview_sizes_tbl.sizes_tbl=&default_preview_sizes[0];
+    if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
+                            MM_CAMERA_PARM_DEF_PREVIEW_SIZES, &preview_sizes_tbl)){
+        LOGE("%s:Failed to get default preview sizes",__func__);
+    }
+    ret = cam_config_get_parm(mCameraId,
+                MM_CAMERA_PARM_VIDEO_SIZES_CNT, &video_sizes_count);
+
+    default_sizes_tbl_t video_sizes_tbl;
+    video_sizes_tbl.tbl_size=video_sizes_count;
+    video_sizes_tbl.sizes_tbl=&default_video_sizes[0];
+    if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
+                            MM_CAMERA_PARM_DEF_VIDEO_SIZES, &video_sizes_tbl)){
+        LOGE("%s:Failed to get default video sizes",__func__);
+    }
+
+    ret = cam_config_get_parm(mCameraId,
+                MM_CAMERA_PARM_THUMB_SIZES_CNT, &thumbnail_sizes_count);
+
+    default_sizes_tbl_t thumbnail_sizes_tbl;
+    thumbnail_sizes_tbl.tbl_size=thumbnail_sizes_count;
+    thumbnail_sizes_tbl.sizes_tbl=&default_thumbnail_sizes[0];
+    if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
+                            MM_CAMERA_PARM_DEF_THUMB_SIZES, &thumbnail_sizes_tbl)){
+        LOGE("%s:Failed to get default thumbnail sizes",__func__);
+    }
+
+    ret = cam_config_get_parm(mCameraId,
+                MM_CAMERA_PARM_HFR_SIZES_CNT, &hfr_sizes_count);
+
+    default_sizes_tbl_t hfr_sizes_tbl;
+    hfr_sizes_tbl.tbl_size=hfr_sizes_count;
+    hfr_sizes_tbl.sizes_tbl=&default_hfr_sizes[0];
+    if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
+                            MM_CAMERA_PARM_DEF_HFR_SIZES, &hfr_sizes_tbl)){
+        LOGE("%s:Failed to get default HFR  sizes",__func__);
+    }
+    LOGE("%s: X", __func__);
+}
+void QCameraHardwareInterface::initDefaultParameters()
+{
+    bool ret;
+    char prop[PROPERTY_VALUE_MAX];
+    mm_camera_dimension_t maxDim;
+    int rc = MM_CAMERA_OK;
+    LOGI("%s: E", __func__);
+
+    memset(&maxDim, 0, sizeof(mm_camera_dimension_t));
+    ret = getMaxPictureDimension(&maxDim);
+
+    if (ret != NO_ERROR) {
+        LOGE("%s: Cannot get Max picture size supported", __func__);
+        return;
+    }
+    if (!maxDim.width || !maxDim.height) {
+        maxDim.width = DEFAULT_LIVESHOT_WIDTH;
+        maxDim.height = DEFAULT_LIVESHOT_HEIGHT;
+    }
+
+    memset(prop, 0, sizeof(prop));
+    property_get("persist.camera.snap.format", prop, "0");
+    mSnapshotFormat = atoi(prop);
+    LOGV("%s: prop =(%s), snap_format=%d", __func__, prop, mSnapshotFormat);
+
+    //cam_ctrl_dimension_t dim;
+    mHFRLevel = 0;
+    memset(&mDimension, 0, sizeof(cam_ctrl_dimension_t));
+    memset(&mPreviewFormatInfo, 0, sizeof(preview_format_info_t));
+    mDimension.video_width     = DEFAULT_VIDEO_WIDTH;
+    mDimension.video_height    = DEFAULT_VIDEO_HEIGHT;
+    // mzhu mDimension.picture_width   = DEFAULT_STREAM_WIDTH;
+    // mzhu mDimension.picture_height  = DEFAULT_STREAM_HEIGHT;
+    mDimension.picture_width   = maxDim.width;
+    mDimension.picture_height  = maxDim.height;
+    mDimension.display_width   = DEFAULT_STREAM_WIDTH;
+    mDimension.display_height  = DEFAULT_STREAM_HEIGHT;
+    mDimension.orig_picture_dx = mDimension.picture_width;
+    mDimension.orig_picture_dy = mDimension.picture_height;
+    mDimension.ui_thumbnail_width = DEFAULT_STREAM_WIDTH;
+    mDimension.ui_thumbnail_height = DEFAULT_STREAM_HEIGHT;
+    mDimension.orig_video_width = DEFAULT_STREAM_WIDTH;
+    mDimension.orig_video_height = DEFAULT_STREAM_HEIGHT;
+
+    mDimension.prev_format     = CAMERA_YUV_420_NV21;
+    mDimension.enc_format      = CAMERA_YUV_420_NV12;
+    if (mSnapshotFormat == 1) {
+      mDimension.main_img_format = CAMERA_YUV_422_NV61;
+    } else {
+      mDimension.main_img_format = CAMERA_YUV_420_NV21;
+    }
+    mDimension.thumb_format    = CAMERA_YUV_420_NV21;
+    LOGV("%s: main_img_format =%d, thumb_format=%d", __func__,
+         mDimension.main_img_format, mDimension.thumb_format);
+    mDimension.prev_padding_format = CAMERA_PAD_TO_WORD;
+
+    ret = native_set_parms(MM_CAMERA_PARM_DIMENSION,
+                              sizeof(cam_ctrl_dimension_t), (void *) &mDimension);
+    if(!ret) {
+      LOGE("MM_CAMERA_PARM_DIMENSION Failed.");
+      return;
+    }
+
+    hasAutoFocusSupport();
+
+    // Initialize constant parameter strings. This will happen only once in the
+    // lifetime of the mediaserver process.
+    if (true/*!mParamStringInitialized*/) {
+        //filter picture sizes
+        filterPictureSizes();
+        mPictureSizeValues = create_sizes_str(
+                mPictureSizesPtr, mSupportedPictureSizesCount);
+        mPreviewSizeValues = create_sizes_str(
+                mPreviewSizes,  mPreviewSizeCount);
+        mVideoSizeValues = create_sizes_str(
+                mVideoSizes,  mVideoSizeCount);
+
+        //Query for max HFR value
+        camera_hfr_mode_t maxHFR;
+        cam_config_get_parm(mCameraId, MM_CAMERA_PARM_MAX_HFR_MODE, (void *)&maxHFR);
+        //Filter HFR values and build parameter string
+        String8 str;
+        for(int i=0; i<HFR_VALUES_COUNT; i++){
+            if(hfr[i].val <= maxHFR){
+                if(i>0)	str.append(",");
+                str.append(hfr[i].desc);
+            }
+        }
+        mHfrValues = str;
+        mHfrSizeValues = create_sizes_str(
+                default_hfr_sizes, hfr_sizes_count);
+        mFpsRangesSupportedValues = create_fps_str(
+            FpsRangesSupported,FPS_RANGES_SUPPORTED_COUNT );
+        mParameters.set(
+            CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
+            mFpsRangesSupportedValues);
+        mParameters.setPreviewFpsRange(MINIMUM_FPS*1000,MAXIMUM_FPS*1000);
+        mFlashValues = create_values_str(
+            flash, sizeof(flash) / sizeof(str_map));
+        mLensShadeValues = create_values_str(
+            lensshade,sizeof(lensshade)/sizeof(str_map));
+        mMceValues = create_values_str(
+            mce,sizeof(mce)/sizeof(str_map));
+        mEffectValues = create_values_str(effects, sizeof(effects) / sizeof(str_map));
+        mAntibandingValues = create_values_str(
+            antibanding, sizeof(antibanding) / sizeof(str_map));
+        mIsoValues = create_values_str(iso,sizeof(iso)/sizeof(str_map));
+        mAutoExposureValues = create_values_str(
+            autoexposure, sizeof(autoexposure) / sizeof(str_map));
+        mWhitebalanceValues = create_values_str(
+            whitebalance, sizeof(whitebalance) / sizeof(str_map));
+
+        if(mHasAutoFocusSupport){
+            mFocusModeValues = create_values_str(
+                    focus_modes, sizeof(focus_modes) / sizeof(str_map));
+        }
+
+        mSceneModeValues = create_values_str(scenemode, sizeof(scenemode) / sizeof(str_map));
+
+        if(mHasAutoFocusSupport){
+            mTouchAfAecValues = create_values_str(
+                touchafaec,sizeof(touchafaec)/sizeof(str_map));
+        }
+        //Currently Enabling Histogram for 8x60
+        mHistogramValues = create_values_str(
+            histogram,sizeof(histogram)/sizeof(str_map));
+
+        mSkinToneEnhancementValues = create_values_str(
+            skinToneEnhancement,sizeof(skinToneEnhancement)/sizeof(str_map));
+
+        mPictureFormatValues = create_values_str(
+            picture_formats, sizeof(picture_formats)/sizeof(str_map));
+
+        mZoomSupported=false;
+        mMaxZoom=0;
+        mm_camera_zoom_tbl_t zmt;
+        if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
+                             MM_CAMERA_PARM_MAXZOOM, &mMaxZoom)){
+            LOGE("%s:Failed to get max zoom",__func__);
+        }else{
+
+            LOGE("Max Zoom:%d",mMaxZoom);
+            /* Kernel driver limits the max amount of data that can be retreived through a control
+            command to 260 bytes hence we conservatively limit to 110 zoom ratios */
+            if(mMaxZoom>MAX_ZOOM_RATIOS) {
+                LOGE("%s:max zoom is larger than sizeof zoomRatios table",__func__);
+                mMaxZoom=MAX_ZOOM_RATIOS-1;
+            }
+            zmt.size=mMaxZoom;
+            zmt.zoom_ratio_tbl=&zoomRatios[0];
+            if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
+                                 MM_CAMERA_PARM_ZOOM_RATIO, &zmt)){
+                LOGE("%s:Failed to get max zoom ratios",__func__);
+            }else{
+                mZoomSupported=true;
+                mZoomRatioValues =  create_str(zoomRatios, mMaxZoom);
+            }
+        }
+
+        LOGE("Zoom supported:%d",mZoomSupported);
+
+        denoise_value = create_values_str(
+            denoise, sizeof(denoise) / sizeof(str_map));
+
+       if(supportsFaceDetection()) {
+            mFaceDetectionValues = create_values_str(
+                facedetection, sizeof(facedetection) / sizeof(str_map));
+        }
+
+        if(mHasAutoFocusSupport){
+            mSelectableZoneAfValues = create_values_str(
+                selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map));
+        }
+
+        mSceneDetectValues = create_values_str(scenedetect, sizeof(scenedetect) / sizeof(str_map));
+
+        mRedeyeReductionValues = create_values_str(
+            redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map));
+
+        mZslValues = create_values_str(
+            zsl_modes,sizeof(zsl_modes)/sizeof(str_map));
+
+        mParamStringInitialized = true;
+    }
+
+    //set supported video sizes
+    mParameters.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES, mVideoSizeValues.string());
+
+    //set default video size to first one in supported table
+    String8 vSize = create_sizes_str(&mVideoSizes[0], 1);
+    mParameters.set(CameraParameters::KEY_VIDEO_SIZE, vSize.string());
+
+    //Set Preview size
+    int default_preview_width, default_preview_height;
+    cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DEFAULT_PREVIEW_WIDTH,
+            &default_preview_width);
+    cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DEFAULT_PREVIEW_HEIGHT,
+            &default_preview_height);
+    mParameters.setPreviewSize(default_preview_width, default_preview_height);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
+                    mPreviewSizeValues.string());
+    mDimension.display_width = default_preview_width;
+    mDimension.display_height = default_preview_height;
+
+    //Set Preview Frame Rate
+    if(mFps >= MINIMUM_FPS && mFps <= MAXIMUM_FPS) {
+        mPreviewFrameRateValues = create_values_range_str(
+        MINIMUM_FPS, mFps);
+    }else{
+        mPreviewFrameRateValues = create_values_range_str(
+        MINIMUM_FPS, MAXIMUM_FPS);
+    }
+
+
+    if (cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS)) {
+        mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
+                        mPreviewFrameRateValues.string());
+     } else {
+        mParameters.set(
+            CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
+            DEFAULT_FIXED_FPS);
+    }
+
+    //Set Preview Frame Rate Modes
+    mParameters.setPreviewFrameRateMode("frame-rate-auto");
+    mFrameRateModeValues = create_values_str(
+            frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map));
+      if(cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS_MODE)){
+        mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES,
+                    mFrameRateModeValues.string());
+    }
+
+    //Set Preview Format
+    //mParameters.setPreviewFormat("yuv420sp"); // informative
+    mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
+
+    mPreviewFormatValues = create_values_str(
+        preview_formats, sizeof(preview_formats) / sizeof(str_map));
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
+            mPreviewFormatValues.string());
+
+    //Set Overlay Format
+    mParameters.set("overlay-format", HAL_PIXEL_FORMAT_YCbCr_420_SP);
+    mParameters.set("max-num-detected-faces-hw", "2");
+
+    //Set Picture Size
+    mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
+                    mPictureSizeValues.string());
+
+    //Set Preview Frame Rate
+    if(mFps >= MINIMUM_FPS && mFps <= MAXIMUM_FPS) {
+        mParameters.setPreviewFrameRate(mFps);
+    }else{
+        mParameters.setPreviewFrameRate(DEFAULT_FPS);
+    }
+
+    //Set Picture Format
+    mParameters.setPictureFormat("jpeg"); // informative
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
+                    mPictureFormatValues);
+
+    mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "85"); // max quality
+    mJpegQuality = 85;
+    //Set Video Format
+    mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, "yuv420sp");
+
+    //Set Thumbnail parameters
+    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
+                    THUMBNAIL_WIDTH_STR); // informative
+    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
+                    THUMBNAIL_HEIGHT_STR); // informative
+    mDimension.ui_thumbnail_width =
+            thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
+    mDimension.ui_thumbnail_height =
+            thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
+    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
+    String8 valuesStr = create_sizes_str(default_thumbnail_sizes, thumbnail_sizes_count);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
+                valuesStr.string());
+    // Define CAMERA_SMOOTH_ZOOM in Android.mk file , to enable smoothzoom
+#ifdef CAMERA_SMOOTH_ZOOM
+    mParameters.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, "true");
+#endif
+    if(mZoomSupported){
+        mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, "true");
+        LOGE("max zoom is %d", mMaxZoom-1);
+        /* mMaxZoom value that the query interface returns is the size
+        LOGV("max zoom is %d", mMaxZoom-1);
+        * mMaxZoom value that the query interface returns is the size
+         * of zoom table. So the actual max zoom value will be one
+         * less than that value.          */
+
+        mParameters.set("max-zoom",mMaxZoom-1);
+        mParameters.set(CameraParameters::KEY_ZOOM_RATIOS,
+                            mZoomRatioValues);
+    } else
+        {
+        mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, "false");
+    }
+
+    /* Enable zoom support for video application if VPE enabled */
+    if(mZoomSupported) {
+        mParameters.set("video-zoom-support", "true");
+    } else {
+        mParameters.set("video-zoom-support", "false");
+    }
+
+    //8960 supports Power modes : Low power, Normal Power.
+    mParameters.set("power-mode-supported", "true");
+    //Set Live shot support
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_LIVESHOT_MAIN);
+    if(!rc) {
+        LOGE("%s:LIVESHOT is  not supported", __func__);
+        mParameters.set("video-snapshot-supported", "false");
+    } else {
+        mParameters.set("video-snapshot-supported", "true");
+    }
+
+    //Set default power mode
+    mParameters.set(CameraParameters::KEY_POWER_MODE,"Normal_Power");
+
+    //Set Camera Mode
+    mParameters.set(CameraParameters::KEY_CAMERA_MODE,0);
+    mParameters.set(CameraParameters::KEY_AE_BRACKET_HDR,"Off");
+
+    //Set Antibanding
+    mParameters.set(CameraParameters::KEY_ANTIBANDING,
+                    CameraParameters::ANTIBANDING_OFF);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
+                    mAntibandingValues);
+
+    //Set Effect
+    mParameters.set(CameraParameters::KEY_EFFECT,
+                    CameraParameters::EFFECT_NONE);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, mEffectValues);
+
+    //Set Auto Exposure
+    mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE,
+                    CameraParameters::AUTO_EXPOSURE_FRAME_AVG);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, mAutoExposureValues);
+
+    //Set WhiteBalance
+    mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
+                    CameraParameters::WHITE_BALANCE_AUTO);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,mWhitebalanceValues);
+
+    //Set AEC_LOCK
+    mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, "false");
+    if(cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_AEC_LOCK)){
+        mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, "true");
+    } else {
+        mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, "false");
+    }
+    //Set AWB_LOCK
+    mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, "false");
+    if(cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_AWB_LOCK))
+        mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, "true");
+    else
+        mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, "false");
+
+    //Set Focus Mode
+    if(mHasAutoFocusSupport){
+       mParameters.set(CameraParameters::KEY_FOCUS_MODE,
+                          CameraParameters::FOCUS_MODE_AUTO);
+       mFocusMode = AF_MODE_AUTO;
+       mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
+                          mFocusModeValues);
+       mParameters.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
+       mParameters.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS, "1");
+   } else {
+       mParameters.set(CameraParameters::KEY_FOCUS_MODE,
+       CameraParameters::FOCUS_MODE_INFINITY);
+       mFocusMode = DONT_CARE;
+       mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
+       CameraParameters::FOCUS_MODE_INFINITY);
+       mParameters.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "0");
+       mParameters.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS, "0");
+   }
+
+    mParameters.set(CameraParameters::KEY_FOCUS_AREAS, DEFAULT_CAMERA_AREA);
+    mParameters.set(CameraParameters::KEY_METERING_AREAS, DEFAULT_CAMERA_AREA);
+
+    //Set Flash
+    if (cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_LED_MODE)) {
+        mParameters.set(CameraParameters::KEY_FLASH_MODE,
+                        CameraParameters::FLASH_MODE_OFF);
+        mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
+                        mFlashValues);
+    }
+
+    //Set Sharpness
+    mParameters.set(CameraParameters::KEY_MAX_SHARPNESS,
+            CAMERA_MAX_SHARPNESS);
+    mParameters.set(CameraParameters::KEY_SHARPNESS,
+                    CAMERA_DEF_SHARPNESS);
+
+    //Set Contrast
+    mParameters.set(CameraParameters::KEY_MAX_CONTRAST,
+            CAMERA_MAX_CONTRAST);
+    mParameters.set(CameraParameters::KEY_CONTRAST,
+                    CAMERA_DEF_CONTRAST);
+
+    //Set Saturation
+    mParameters.set(CameraParameters::KEY_MAX_SATURATION,
+            CAMERA_MAX_SATURATION);
+    mParameters.set(CameraParameters::KEY_SATURATION,
+                    CAMERA_DEF_SATURATION);
+
+    //Set Brightness/luma-adaptaion
+    mParameters.set("luma-adaptation", "3");
+
+    mParameters.set(CameraParameters::KEY_PICTURE_FORMAT,
+                    CameraParameters::PIXEL_FORMAT_JPEG);
+
+    //Set Lensshading
+    mParameters.set(CameraParameters::KEY_LENSSHADE,
+                    CameraParameters::LENSSHADE_ENABLE);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
+                    mLensShadeValues);
+
+    //Set ISO Mode
+    mParameters.set(CameraParameters::KEY_ISO_MODE,
+                    CameraParameters::ISO_AUTO);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_ISO_MODES,
+                    mIsoValues);
+
+    //Set MCE
+    mParameters.set(CameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT,
+                    CameraParameters::MCE_ENABLE);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_MEM_COLOR_ENHANCE_MODES,
+                    mMceValues);
+    //Set HFR
+    if (cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_HFR)) {
+        mParameters.set(CameraParameters::KEY_VIDEO_HIGH_FRAME_RATE,
+                    CameraParameters::VIDEO_HFR_OFF);
+        mParameters.set(CameraParameters::KEY_SUPPORTED_HFR_SIZES,
+                    mHfrSizeValues.string());
+        mParameters.set(CameraParameters::KEY_SUPPORTED_VIDEO_HIGH_FRAME_RATE_MODES,
+                    mHfrValues);
+    } else{
+        mParameters.set(CameraParameters::KEY_SUPPORTED_HFR_SIZES,"");
+    }
+
+    //Set Histogram
+    mParameters.set(CameraParameters::KEY_HISTOGRAM,
+                    CameraParameters::HISTOGRAM_DISABLE);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_HISTOGRAM_MODES,
+                    mHistogramValues);
+
+    //Set SkinTone Enhancement
+    mParameters.set(CameraParameters::KEY_SKIN_TONE_ENHANCEMENT,
+                    CameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE);
+    mParameters.set("skinToneEnhancement", "0");
+    mParameters.set(CameraParameters::KEY_SUPPORTED_SKIN_TONE_ENHANCEMENT_MODES,
+                    mSkinToneEnhancementValues);
+
+    //Set Scene Mode
+    mParameters.set(CameraParameters::KEY_SCENE_MODE,
+                    CameraParameters::SCENE_MODE_AUTO);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
+                    mSceneModeValues);
+
+    //Set Streaming Textures
+    mParameters.set("strtextures", "OFF");
+
+    //Set Denoise
+    mParameters.set(CameraParameters::KEY_DENOISE,
+                    CameraParameters::DENOISE_OFF);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_DENOISE,
+                        denoise_value);
+    //Set Touch AF/AEC
+    mParameters.set(CameraParameters::KEY_TOUCH_AF_AEC,
+                    CameraParameters::TOUCH_AF_AEC_OFF);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC,
+                    mTouchAfAecValues);
+    mParameters.set("touchAfAec-dx","100");
+    mParameters.set("touchAfAec-dy","100");
+
+    //Set Scene Detection
+    mParameters.set(CameraParameters::KEY_SCENE_DETECT,
+                   CameraParameters::SCENE_DETECT_OFF);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_DETECT,
+                    mSceneDetectValues);
+
+    //Set Selectable Zone AF
+    mParameters.set(CameraParameters::KEY_SELECTABLE_ZONE_AF,
+                    CameraParameters::SELECTABLE_ZONE_AF_AUTO);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_SELECTABLE_ZONE_AF,
+                    mSelectableZoneAfValues);
+
+    //Set Face Detection
+    mParameters.set(CameraParameters::KEY_FACE_DETECTION,
+                    CameraParameters::FACE_DETECTION_OFF);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_FACE_DETECTION,
+                    mFaceDetectionValues);
+
+    //Set Red Eye Reduction
+    mParameters.set(CameraParameters::KEY_REDEYE_REDUCTION,
+                    CameraParameters::REDEYE_REDUCTION_DISABLE);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_REDEYE_REDUCTION,
+                    mRedeyeReductionValues);
+
+    //Set ZSL
+    mParameters.set(CameraParameters::KEY_ZSL,
+                    CameraParameters::ZSL_OFF);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_ZSL_MODES,
+                    mZslValues);
+
+    //Set Focal length, horizontal and vertical view angles
+    float focalLength = 0.0f;
+    float horizontalViewAngle = 0.0f;
+    float verticalViewAngle = 0.0f;
+    cam_config_get_parm(mCameraId, MM_CAMERA_PARM_FOCAL_LENGTH,
+            (void *)&focalLength);
+    mParameters.setFloat(CameraParameters::KEY_FOCAL_LENGTH,
+                    focalLength);
+    cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE,
+            (void *)&horizontalViewAngle);
+    mParameters.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
+                    horizontalViewAngle);
+    cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE,
+            (void *)&verticalViewAngle);
+    mParameters.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE,
+                    verticalViewAngle);
+
+    //Set Exposure Compensation
+    mParameters.set(
+            CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
+            EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR);
+    mParameters.set(
+            CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
+            EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR);
+    mParameters.set(
+            CameraParameters::KEY_EXPOSURE_COMPENSATION,
+            EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR);
+    mParameters.setFloat(
+            CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
+            EXPOSURE_COMPENSATION_STEP);
+
+    mParameters.set("num-snaps-per-shutter", 1);
+
+    mParameters.set("capture-burst-captures-values", getZSLQueueDepth());
+    mParameters.set("capture-burst-interval-supported", "true");
+    mParameters.set("capture-burst-interval-max", BURST_INTREVAL_MAX); /*skip frames*/
+    mParameters.set("capture-burst-interval-min", BURST_INTREVAL_MIN); /*skip frames*/
+    mParameters.set("capture-burst-interval", BURST_INTREVAL_DEFAULT); /*skip frames*/
+    mParameters.set("capture-burst-retroactive", 0);
+    mParameters.set("capture-burst-retroactive-max", getZSLQueueDepth());
+    mParameters.set("capture-burst-exposures", "");
+    mParameters.set("capture-burst-exposures-values",
+      "-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12");
+    {
+      String8 CamModeStr;
+      char buffer[32];
+      int flag = 0;
+
+      for (int i = 0; i < HAL_CAM_MODE_MAX; i++) {
+        if ( 0 ) { /*exclude some conflicting case*/
+        } else {
+          if (flag == 0) { /*first item*/
+          snprintf(buffer, sizeof(buffer), "%d", i);
+          } else {
+            snprintf(buffer, sizeof(buffer), ",%d", i);
+          }
+          flag = 1;
+          CamModeStr.append(buffer);
+        }
+      }
+      mParameters.set("camera-mode-values", CamModeStr);
+    }
+
+    mParameters.set("ae-bracket-hdr-values",
+      create_values_str(hdr_bracket, sizeof(hdr_bracket)/sizeof(str_map) ));
+
+// if(mIs3DModeOn)
+//     mParameters.set("3d-frame-format", "left-right");
+    mParameters.set("no-display-mode", 0);
+    //mUseOverlay = useOverlay();
+    mParameters.set("zoom", 0);
+
+    int mNuberOfVFEOutputs;
+    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, &mNuberOfVFEOutputs);
+    if(ret != MM_CAMERA_OK) {
+        LOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE  failed");
+        ret = BAD_VALUE;
+    }
+    if(mNuberOfVFEOutputs == 1)
+    {
+       mParameters.set(CameraParameters::KEY_SINGLE_ISP_OUTPUT_ENABLED, "true");
+    } else {
+       mParameters.set(CameraParameters::KEY_SINGLE_ISP_OUTPUT_ENABLED, "false");
+    }
+
+    if (setParameters(mParameters) != NO_ERROR) {
+        LOGE("Failed to set default parameters?!");
+    }  
+    mInitialized = true;
+    strTexturesOn = false;
+
+    LOGI("%s: X", __func__);
+    return;
+}
+
+/**
+ * Set the camera parameters. This returns BAD_VALUE if any parameter is
+ * invalid or not supported.
+ */
+
+int QCameraHardwareInterface::setParameters(const char *parms)
+{
+    CameraParameters param;
+    String8 str = String8(parms);
+    param.unflatten(str);
+    status_t ret = setParameters(param);
+	if(ret == NO_ERROR)
+		return 0;
+	else
+		return -1;
+}
+
+/**
+ * Set the camera parameters. This returns BAD_VALUE if any parameter is
+ * invalid or not supported. */
+status_t QCameraHardwareInterface::setParameters(const CameraParameters& params)
+{
+    status_t ret = NO_ERROR;
+
+    LOGI("%s: E", __func__);
+//    Mutex::Autolock l(&mLock);
+    status_t rc, final_rc = NO_ERROR;
+
+    if ((rc = setCameraMode(params)))                   final_rc = rc;
+    if ((rc = setPowerMode(params)))                    final_rc = rc;
+    if ((rc = setPreviewSize(params)))                  final_rc = rc;
+    if ((rc = setVideoSize(params)))                    final_rc = rc;
+    if ((rc = setPictureSize(params)))                  final_rc = rc;
+    if ((rc = setJpegThumbnailSize(params)))            final_rc = rc;
+    if ((rc = setJpegQuality(params)))                  final_rc = rc;
+    if ((rc = setEffect(params)))                       final_rc = rc;
+    if ((rc = setGpsLocation(params)))                  final_rc = rc;
+    if ((rc = setRotation(params)))                     final_rc = rc;
+    if ((rc = setZoom(params)))                         final_rc = rc;
+    if ((rc = setOrientation(params)))                  final_rc = rc;
+    if ((rc = setLensshadeValue(params)))               final_rc = rc;
+    if ((rc = setMCEValue(params)))                     final_rc = rc;
+    if ((rc = setPictureFormat(params)))                final_rc = rc;
+    if ((rc = setSharpness(params)))                    final_rc = rc;
+    if ((rc = setSaturation(params)))                   final_rc = rc;
+    if ((rc = setSceneMode(params)))                    final_rc = rc;
+    if ((rc = setContrast(params)))                     final_rc = rc;
+    if ((rc = setFaceDetect(params)))                   final_rc = rc;
+    if ((rc = setStrTextures(params)))                  final_rc = rc;
+    if ((rc = setPreviewFormat(params)))                final_rc = rc;
+    if ((rc = setSkinToneEnhancement(params)))          final_rc = rc;
+    if ((rc = setWaveletDenoise(params)))               final_rc = rc;
+    if ((rc = setAntibanding(params)))                  final_rc = rc;
+    //    if ((rc = setOverlayFormats(params)))         final_rc = rc;
+    if ((rc = setRedeyeReduction(params)))              final_rc = rc;
+    if ((rc = setCaptureBurstExp()))                    final_rc = rc;
+
+    const char *str_val = params.get("capture-burst-exposures");
+    if ( str_val == NULL || strlen(str_val)==0 ) {
+        char burst_exp[PROPERTY_VALUE_MAX];
+        memset(burst_exp, 0, sizeof(burst_exp));
+        property_get("persist.capture.burst.exposures", burst_exp, "");
+        if ( strlen(burst_exp)>0 ) {
+            mParameters.set("capture-burst-exposures", burst_exp);
+        }
+    } else {
+      mParameters.set("capture-burst-exposures", str_val);
+    }
+    mParameters.set("num-snaps-per-shutter", params.get("num-snaps-per-shutter"));
+
+    if ((rc = setAEBracket(params)))              final_rc = rc;
+    //    if ((rc = setDenoise(params)))                final_rc = rc;
+    if ((rc = setPreviewFpsRange(params)))              final_rc = rc;
+    if((rc = setRecordingHint(params)))                 final_rc = rc;
+    if ((rc = setNumOfSnapshot(params)))                final_rc = rc;
+    if ((rc = setAecAwbLock(params)))                   final_rc = rc;
+
+    const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
+    int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
+
+    if((value != NOT_FOUND) && (value == CAMERA_BESTSHOT_OFF )) {
+        //if ((rc = setPreviewFrameRateMode(params)))     final_rc = rc;
+        if ((rc = setPreviewFrameRate(params)))         final_rc = rc;
+        if ((rc = setAutoExposure(params)))             final_rc = rc;
+        if ((rc = setExposureCompensation(params)))     final_rc = rc;
+        if ((rc = setWhiteBalance(params)))             final_rc = rc;
+        if ((rc = setFlash(params)))                    final_rc = rc;
+        if ((rc = setFocusMode(params)))                final_rc = rc;
+        if ((rc = setBrightness(params)))               final_rc = rc;
+        if ((rc = setISOValue(params)))                 final_rc = rc;
+        if ((rc = setFocusAreas(params)))               final_rc = rc;
+        if ((rc = setMeteringAreas(params)))            final_rc = rc;
+    }
+    //selectableZoneAF needs to be invoked after continuous AF
+    if ((rc = setSelectableZoneAf(params)))             final_rc = rc;
+    // setHighFrameRate needs to be done at end, as there can
+    // be a preview restart, and need to use the updated parameters
+    if ((rc = setHighFrameRate(params)))  final_rc = rc;
+    if ((rc = setZSLBurstLookBack(params))) final_rc = rc;
+    if ((rc = setZSLBurstInterval(params))) final_rc = rc;
+    if ((rc = setNoDisplayMode(params))) final_rc = rc;
+    
+    //Update Exiftag values.
+    setExifTags();
+
+   LOGI("%s: X", __func__);
+   return final_rc;
+}
+
+/** Retrieve the camera parameters.  The buffer returned by the camera HAL
+	must be returned back to it with put_parameters, if put_parameters
+	is not NULL.
+ */
+int QCameraHardwareInterface::getParameters(char **parms)
+{
+    char* rc = NULL;
+    String8 str;
+    CameraParameters param = getParameters();
+    //param.dump();
+    str = param.flatten( );
+    rc = (char *)malloc(sizeof(char)*(str.length()+1));
+    if(rc != NULL){
+        memset(rc, 0, sizeof(char)*(str.length()+1));
+        strncpy(rc, str.string(), str.length());
+	rc[str.length()] = 0;
+	*parms = rc;
+    }
+    return 0;
+}
+
+/** The camera HAL uses its own memory to pass us the parameters when we
+	call get_parameters.  Use this function to return the memory back to
+	the camera HAL, if put_parameters is not NULL.  If put_parameters
+	is NULL, then you have to use free() to release the memory.
+*/
+void QCameraHardwareInterface::putParameters(char *rc)
+{
+    free(rc);
+    rc = NULL;
+}
+
+CameraParameters& QCameraHardwareInterface::getParameters()
+{
+    Mutex::Autolock lock(mLock);
+    mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistance.string());
+    return mParameters;
+}
+
+status_t QCameraHardwareInterface::runFaceDetection()
+{
+    bool ret = true;
+
+    const char *str = mParameters.get(CameraParameters::KEY_FACE_DETECTION);
+    if (str != NULL) {
+        int value = attr_lookup(facedetection,
+                sizeof(facedetection) / sizeof(str_map), str);
+#if 0
+        mMetaDataWaitLock.lock();
+        if (value == true) {
+            if(mMetaDataHeap != NULL)
+                mMetaDataHeap.clear();
+
+            mMetaDataHeap =
+                new AshmemPool((sizeof(int)*(MAX_ROI*4+1)),
+                        1,
+                        (sizeof(int)*(MAX_ROI*4+1)),
+                        "metadata");
+            if (!mMetaDataHeap->initialized()) {
+                LOGE("Meta Data Heap allocation failed ");
+                mMetaDataHeap.clear();
+                LOGE("runFaceDetection X: error initializing mMetaDataHeap");
+                mMetaDataWaitLock.unlock();
+                return UNKNOWN_ERROR;
+            }
+            mSendMetaData = true;
+        } else {
+            if(mMetaDataHeap != NULL)
+                mMetaDataHeap.clear();
+        }
+        mMetaDataWaitLock.unlock();
+#endif
+        cam_ctrl_dimension_t dim;
+        cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+        preview_parm_config (&dim, mParameters);
+        LOGE("%s: why set_dimension everytime?", __func__);
+        ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+        ret = native_set_parms(MM_CAMERA_PARM_FD, sizeof(int8_t), (void *)&value);
+        return ret ? NO_ERROR : UNKNOWN_ERROR;
+    }
+    LOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setSharpness(const CameraParameters& params)
+{
+    bool ret = false;
+    int rc = MM_CAMERA_OK;
+    LOGE("%s",__func__);
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_SHARPNESS);
+    if(!rc) {
+        LOGE("%s:CONTRAST not supported", __func__);
+        return NO_ERROR;
+    }
+    int sharpness = params.getInt(CameraParameters::KEY_SHARPNESS);
+    if((sharpness < CAMERA_MIN_SHARPNESS
+            || sharpness > CAMERA_MAX_SHARPNESS))
+        return UNKNOWN_ERROR;
+
+    LOGV("setting sharpness %d", sharpness);
+    mParameters.set(CameraParameters::KEY_SHARPNESS, sharpness);
+    ret = native_set_parms(MM_CAMERA_PARM_SHARPNESS, sizeof(sharpness),
+                               (void *)&sharpness);
+    return ret ? NO_ERROR : UNKNOWN_ERROR;
+}
+
+status_t QCameraHardwareInterface::setSaturation(const CameraParameters& params)
+{
+    bool ret = false;
+    int rc = MM_CAMERA_OK;
+    LOGE("%s",__func__);
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_SATURATION);
+    if(!rc) {
+        LOGE("%s:MM_CAMERA_PARM_SATURATION not supported", __func__);
+        return NO_ERROR;
+    }
+    int result;
+    int saturation = params.getInt(CameraParameters::KEY_SATURATION);
+
+    if((saturation < CAMERA_MIN_SATURATION)
+        || (saturation > CAMERA_MAX_SATURATION))
+    return UNKNOWN_ERROR;
+
+    LOGV("Setting saturation %d", saturation);
+    mParameters.set(CameraParameters::KEY_SATURATION, saturation);
+    ret = native_set_parms(MM_CAMERA_PARM_SATURATION, sizeof(saturation),
+        (void *)&saturation, (int *)&result);
+    if(result != MM_CAMERA_OK)
+        LOGI("Saturation Value: %d is not set as the selected value is not supported", saturation);
+    return ret ? NO_ERROR : UNKNOWN_ERROR;
+}
+
+status_t QCameraHardwareInterface::setContrast(const CameraParameters& params)
+{
+   LOGE("%s E", __func__ );
+   int rc = MM_CAMERA_OK;
+   rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_CONTRAST);
+   if(!rc) {
+        LOGE("%s:CONTRAST not supported", __func__);
+        return NO_ERROR;
+    }
+   const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
+   LOGE("Contrast : %s",str);
+   int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
+   if(value == CAMERA_BESTSHOT_OFF) {
+        int contrast = params.getInt(CameraParameters::KEY_CONTRAST);
+        if((contrast < CAMERA_MIN_CONTRAST)
+                || (contrast > CAMERA_MAX_CONTRAST))
+        {
+            LOGE("Contrast Value not matching");
+            return UNKNOWN_ERROR;
+        }
+        LOGV("setting contrast %d", contrast);
+        mParameters.set(CameraParameters::KEY_CONTRAST, contrast);
+        LOGE("Calling Contrast set on Lower layer");
+        bool ret = native_set_parms(MM_CAMERA_PARM_CONTRAST, sizeof(contrast),
+                                   (void *)&contrast);
+        LOGE("Lower layer returned %d", ret);
+        int bestshot_reconfigure;
+        cam_config_get_parm(mCameraId, MM_CAMERA_PARM_BESTSHOT_RECONFIGURE,
+                            &bestshot_reconfigure);
+        if(bestshot_reconfigure) {
+             if (mContrast != contrast) {
+                  mContrast = contrast;
+                 if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED && ret) {
+                      mRestartPreview = 1;
+                      pausePreviewForZSL();
+                  }
+             }
+        }
+        return ret ? NO_ERROR : UNKNOWN_ERROR;
+    } else {
+          LOGI(" Contrast value will not be set " \
+          "when the scenemode selected is %s", str);
+          return NO_ERROR;
+    }
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setSceneDetect(const CameraParameters& params)
+{
+    LOGE("%s",__func__);
+    bool retParm;
+    int rc = MM_CAMERA_OK;
+
+    rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_ASD_ENABLE);
+    if(!rc) {
+        LOGE("%s:MM_CAMERA_PARM_ASD_ENABLE not supported", __func__);
+        return NO_ERROR;
+    }
+
+    const char *str = params.get(CameraParameters::KEY_SCENE_DETECT);
+    LOGE("Scene Detect string : %s",str);
+    if (str != NULL) {
+        int32_t value = attr_lookup(scenedetect, sizeof(scenedetect) / sizeof(str_map), str);
+        LOGE("Scenedetect Value : %d",value);
+        if (value != NOT_FOUND) {
+            mParameters.set(CameraParameters::KEY_SCENE_DETECT, str);
+
+            retParm = native_set_parms(MM_CAMERA_PARM_ASD_ENABLE, sizeof(value),
+                                       (void *)&value);
+
+            return retParm ? NO_ERROR : UNKNOWN_ERROR;
+        }
+    }
+   return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setZoom(const CameraParameters& params)
+{
+    status_t rc = NO_ERROR;
+
+    LOGE("%s: E",__func__);
+
+
+    if( !( cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_ZOOM))) {
+        LOGE("%s:MM_CAMERA_PARM_ZOOM not supported", __func__);
+        return NO_ERROR;
+    }
+    // No matter how many different zoom values the driver can provide, HAL
+    // provides applictations the same number of zoom levels. The maximum driver
+    // zoom value depends on sensor output (VFE input) and preview size (VFE
+    // output) because VFE can only crop and cannot upscale. If the preview size
+    // is bigger, the maximum zoom ratio is smaller. However, we want the
+    // zoom ratio of each zoom level is always the same whatever the preview
+    // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
+    // we need to have a fixed maximum zoom value and do read it from the
+    // driver.
+    static const int ZOOM_STEP = 1;
+    int32_t zoom_level = params.getInt("zoom");
+    if(zoom_level >= 0 && zoom_level <= mMaxZoom-1) {
+        mParameters.set("zoom", zoom_level);
+        int32_t zoom_value = ZOOM_STEP * zoom_level;
+        bool ret = native_set_parms(MM_CAMERA_PARM_ZOOM,
+            sizeof(zoom_value), (void *)&zoom_value);
+        if(ret) {
+            mCurrentZoom=zoom_level;
+        }
+        rc = ret ? NO_ERROR : UNKNOWN_ERROR;
+    } else {
+        rc = BAD_VALUE;
+    }
+    LOGE("%s X",__func__);
+    return rc;
+
+}
+
+status_t  QCameraHardwareInterface::setISOValue(const CameraParameters& params) {
+
+    status_t rc = NO_ERROR;
+    LOGE("%s",__func__);
+
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_ISO);
+    if(!rc) {
+        LOGE("%s:MM_CAMERA_PARM_ISO not supported", __func__);
+        return NO_ERROR;
+    }
+    const char *str = params.get(CameraParameters::KEY_ISO_MODE);
+    LOGE("ISO string : %s",str);
+    int8_t temp_hjr;
+    if (str != NULL) {
+        int value = (camera_iso_mode_type)attr_lookup(
+          iso, sizeof(iso) / sizeof(str_map), str);
+        LOGE("ISO Value : %d",value);
+        if (value != NOT_FOUND) {
+            camera_iso_mode_type temp = (camera_iso_mode_type) value;
+            if (value == CAMERA_ISO_DEBLUR) {
+               temp_hjr = true;
+               native_set_parms(MM_CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
+               mHJR = value;
+            }
+            else {
+               if (mHJR == CAMERA_ISO_DEBLUR) {
+                   temp_hjr = false;
+                   native_set_parms(MM_CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
+                   mHJR = value;
+               }
+            }
+
+            mParameters.set(CameraParameters::KEY_ISO_MODE, str);
+            native_set_parms(MM_CAMERA_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
+            return NO_ERROR;
+        }
+    }
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::updateFocusDistances()
+{
+    LOGV("%s: IN", __FUNCTION__);
+    focus_distances_info_t focusDistances;
+    if(cam_config_get_parm(mCameraId, MM_CAMERA_PARM_FOCUS_DISTANCES,
+      &focusDistances) == MM_CAMERA_OK) {
+        String8 str;
+        char buffer[32] = {0};
+        //set all distances to infinity if focus mode is infinity
+        if(mFocusMode == AF_MODE_INFINITY) {
+            snprintf(buffer, sizeof(buffer), "Infinity,");
+            str.append(buffer);
+            snprintf(buffer, sizeof(buffer), "Infinity,");
+            str.append(buffer);
+            snprintf(buffer, sizeof(buffer), "Infinity");
+            str.append(buffer);
+        } else {
+            snprintf(buffer, sizeof(buffer), "%f", focusDistances.focus_distance[0]);
+            str.append(buffer);
+            snprintf(buffer, sizeof(buffer), ",%f", focusDistances.focus_distance[1]);
+            str.append(buffer);
+            snprintf(buffer, sizeof(buffer), ",%f", focusDistances.focus_distance[2]);
+            str.append(buffer);
+        }
+        LOGE("%s: setting KEY_FOCUS_DISTANCES as %s", __FUNCTION__, str.string());
+        mFocusDistance = str;
+        return NO_ERROR;
+    }
+    LOGE("%s: get CAMERA_PARM_FOCUS_DISTANCES failed!!!", __FUNCTION__);
+    return BAD_VALUE;
+}
+
+// Parse string like "(1, 2, 3, 4, ..., N)"
+// num is pointer to an allocated array of size N
+static int parseNDimVector(const char *str, int *num, int N, char delim = ',')
+{
+    char *start, *end;
+    if(num == NULL) {
+        LOGE("Invalid output array (num == NULL)");
+        return -1;
+    }
+    //check if string starts and ends with parantheses
+    if(str[0] != '(' || str[strlen(str)-1] != ')') {
+        LOGE("Invalid format of string %s, valid format is (n1, n2, n3, n4 ...)", str);
+        return -1;
+    }
+    start = (char*) str;
+    start++;
+    for(int i=0; i<N; i++) {
+        *(num+i) = (int) strtol(start, &end, 10);
+        if(*end != delim && i < N-1) {
+            LOGE("Cannot find delimeter '%c' in string \"%s\". end = %c", delim, str, *end);
+            return -1;
+        }
+        start = end+1;
+    }
+    return 0;
+}
+
+// parse string like "(1, 2, 3, 4, 5),(1, 2, 3, 4, 5),..."
+static int parseCameraAreaString(const char* str, int max_num_areas,
+                                 camera_area_t *pAreas, int *num_areas_found)
+{
+    char area_str[32];
+    const char *start, *end, *p;
+    start = str; end = NULL;
+    int values[5], index=0;
+    *num_areas_found = 0;
+
+    while(start != NULL) {
+       if(*start != '(') {
+            LOGE("%s: error: Ill formatted area string: %s", __func__, str);
+            return -1;
+       }
+       end = strchr(start, ')');
+       if(end == NULL) {
+            LOGE("%s: error: Ill formatted area string: %s", __func__, str);
+            return -1;
+       }
+       int i;
+       for (i=0,p=start; p<=end; p++, i++) {
+           area_str[i] = *p;
+       }
+       area_str[i] = '\0';
+       if(parseNDimVector(area_str, values, 5) < 0){
+            LOGE("%s: error: Failed to parse the area string: %s", __func__, area_str);
+            return -1;
+       }
+       // no more areas than max_num_areas are accepted.
+       if(index >= max_num_areas) {
+            LOGE("%s: error: too many areas specified %s", __func__, str);
+            return -1;
+       }
+       pAreas[index].x1 = values[0];
+       pAreas[index].y1 = values[1];
+       pAreas[index].x2 = values[2];
+       pAreas[index].y2 = values[3];
+       pAreas[index].weight = values[4];
+
+       index++;
+       start = strchr(end, '('); // serach for next '('
+    }
+    (*num_areas_found) = index;
+    return 0;
+}
+static bool validateCameraAreas(camera_area_t *areas, int num_areas)
+{
+    for(int i=0; i<num_areas; i++) {
+
+        // handle special case (0, 0, 0, 0, 0)
+        if((areas[i].x1 == 0) && (areas[i].y1 == 0)
+            && (areas[i].x2 == 0) && (areas[i].y2 == 0) && (areas[i].weight == 0)) {
+            continue;
+        }
+        if(areas[i].x1 < -1000) return false;               // left should be >= -1000
+        if(areas[i].y1 < -1000) return false;               // top  should be >= -1000
+        if(areas[i].x2 > 1000) return false;                // right  should be <= 1000
+        if(areas[i].y2 > 1000) return false;                // bottom should be <= 1000
+        if(areas[i].weight <= 0 || areas[i].weight > 1000)  // weight should be in [1, 1000]
+            return false;
+        if(areas[i].x1 >= areas[i].x2) {                    // left should be < right
+            return false;
+        }
+        if(areas[i].y1 >= areas[i].y2)                      // top should be < bottom
+            return false;
+    }
+    return true;
+}
+
+status_t QCameraHardwareInterface::setFocusAreas(const CameraParameters& params)
+{
+    LOGE("%s: E", __func__);
+    status_t rc;
+    int max_num_af_areas = mParameters.getInt(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS);
+    if(max_num_af_areas == 0) {
+        return NO_ERROR;
+    }
+    const char *str = params.get(CameraParameters::KEY_FOCUS_AREAS);
+    if (str == NULL) {
+        LOGE("%s: Parameter string is null", __func__);
+        rc = NO_ERROR;
+    } else {
+        camera_area_t *areas = new camera_area_t[max_num_af_areas];
+        int num_areas_found=0;
+        if(parseCameraAreaString(str, max_num_af_areas, areas, &num_areas_found) < 0) {
+            LOGE("%s: Failed to parse the string: %s", __func__, str);
+            delete areas;
+            return BAD_VALUE;
+        }
+        for(int i=0; i<num_areas_found; i++) {
+            LOGD("FocusArea[%d] = (%d, %d, %d, %d, %d)", i, (areas[i].x1), (areas[i].y1),
+                        (areas[i].x2), (areas[i].y2), (areas[i].weight));
+        }
+        if(validateCameraAreas(areas, num_areas_found) == false) {
+            LOGE("%s: invalid areas specified : %s", __func__, str);
+            delete areas;
+            return BAD_VALUE;
+        }
+        mParameters.set(CameraParameters::KEY_FOCUS_AREAS, str);
+        num_areas_found = 1; //temp; need to change after the multi-roi is enabled
+
+        //if the native_set_parms is called when preview is not started, it
+        //crashes in lower layer, so return of preview is not started
+        if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED) {
+            delete areas;
+            return NO_ERROR;
+        }
+
+        //for special area string (0, 0, 0, 0, 0), set the num_areas_found to 0,
+        //so no action is takenby the lower layer
+        if(num_areas_found == 1 && (areas[0].x1 == 0) && (areas[0].y1 == 0)
+            && (areas[0].x2 == 0) && (areas[0].y2 == 0) && (areas[0].weight == 0)) {
+            num_areas_found = 0;
+        }
+#if 1 //temp solution
+
+        roi_info_t af_roi_value;
+        memset(&af_roi_value, 0, sizeof(roi_info_t));
+        uint16_t x1, x2, y1, y2, dx, dy;
+        int previewWidth, previewHeight;
+        this->getPreviewSize(&previewWidth, &previewHeight);
+        //transform the coords from (-1000, 1000) to (0, previewWidth or previewHeight)
+        x1 = (uint16_t)((areas[0].x1 + 1000.0f)*(previewWidth/2000.0f));
+        y1 = (uint16_t)((areas[0].y1 + 1000.0f)*(previewHeight/2000.0f));
+        x2 = (uint16_t)((areas[0].x2 + 1000.0f)*(previewWidth/2000.0f));
+        y2 = (uint16_t)((areas[0].y2 + 1000.0f)*(previewHeight/2000.0f));
+        dx = x2 - x1;
+        dy = y2 - y1;
+
+        af_roi_value.num_roi = num_areas_found;
+        af_roi_value.roi[0].x = x1;
+        af_roi_value.roi[0].y = y1;
+        af_roi_value.roi[0].dx = dx;
+        af_roi_value.roi[0].dy = dy;
+        af_roi_value.is_multiwindow = 0;
+        if (native_set_parms(MM_CAMERA_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value))
+            rc = NO_ERROR;
+        else
+            rc = BAD_VALUE;
+        delete areas;
+#endif
+#if 0   //better solution with multi-roi, to be enabled later
+        af_mtr_area_t afArea;
+        afArea.num_area = num_areas_found;
+
+        uint16_t x1, x2, y1, y2, dx, dy;
+        int previewWidth, previewHeight;
+        this->getPreviewSize(&previewWidth, &previewHeight);
+
+        for(int i=0; i<num_areas_found; i++) {
+            //transform the coords from (-1000, 1000) to (0, previewWidth or previewHeight)
+            x1 = (uint16_t)((areas[i].x1 + 1000.0f)*(previewWidth/2000.0f));
+            y1 = (uint16_t)((areas[i].y1 + 1000.0f)*(previewHeight/2000.0f));
+            x2 = (uint16_t)((areas[i].x2 + 1000.0f)*(previewWidth/2000.0f));
+            y2 = (uint16_t)((areas[i].y2 + 1000.0f)*(previewHeight/2000.0f));
+            dx = x2 - x1;
+            dy = y2 - y1;
+            afArea.mtr_area[i].x = x1;
+            afArea.mtr_area[i].y = y1;
+            afArea.mtr_area[i].dx = dx;
+            afArea.mtr_area[i].dy = dy;
+            afArea.weight[i] = areas[i].weight;
+        }
+
+        if(native_set_parms(MM_CAMERA_PARM_AF_MTR_AREA, sizeof(af_mtr_area_t), (void*)&afArea))
+            rc = NO_ERROR;
+        else
+            rc = BAD_VALUE;*/
+#endif
+    }
+    LOGE("%s: X", __func__);
+    return rc;
+}
+
+status_t QCameraHardwareInterface::setMeteringAreas(const CameraParameters& params)
+{
+    LOGE("%s: E", __func__);
+    status_t rc;
+    int max_num_mtr_areas = mParameters.getInt(CameraParameters::KEY_MAX_NUM_METERING_AREAS);
+    if(max_num_mtr_areas == 0) {
+        return NO_ERROR;
+    }
+
+    const char *str = params.get(CameraParameters::KEY_METERING_AREAS);
+    if (str == NULL) {
+        LOGE("%s: Parameter string is null", __func__);
+        rc = NO_ERROR;
+    } else {
+        camera_area_t *areas = new camera_area_t[max_num_mtr_areas];
+        int num_areas_found=0;
+        if(parseCameraAreaString(str, max_num_mtr_areas, areas, &num_areas_found) < 0) {
+            LOGE("%s: Failed to parse the string: %s", __func__, str);
+            delete areas;
+            return BAD_VALUE;
+        }
+        for(int i=0; i<num_areas_found; i++) {
+            LOGD("MeteringArea[%d] = (%d, %d, %d, %d, %d)", i, (areas[i].x1), (areas[i].y1),
+                        (areas[i].x2), (areas[i].y2), (areas[i].weight));
+        }
+        if(validateCameraAreas(areas, num_areas_found) == false) {
+            LOGE("%s: invalid areas specified : %s", __func__, str);
+            delete areas;
+            return BAD_VALUE;
+        }
+        mParameters.set(CameraParameters::KEY_METERING_AREAS, str);
+
+        //if the native_set_parms is called when preview is not started, it
+        //crashes in lower layer, so return of preview is not started
+        if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED) {
+            delete areas;
+            return NO_ERROR;
+        }
+
+        num_areas_found = 1; //temp; need to change after the multi-roi is enabled
+
+        //for special area string (0, 0, 0, 0, 0), set the num_areas_found to 0,
+        //so no action is takenby the lower layer
+        if(num_areas_found == 1 && (areas[0].x1 == 0) && (areas[0].y1 == 0)
+             && (areas[0].x2 == 0) && (areas[0].y2 == 0) && (areas[0].weight == 0)) {
+            num_areas_found = 0;
+        }
+#if 1
+        cam_set_aec_roi_t aec_roi_value;
+        uint16_t x1, x2, y1, y2;
+        int previewWidth, previewHeight;
+        this->getPreviewSize(&previewWidth, &previewHeight);
+        //transform the coords from (-1000, 1000) to (0, previewWidth or previewHeight)
+        x1 = (uint16_t)((areas[0].x1 + 1000.0f)*(previewWidth/2000.0f));
+        y1 = (uint16_t)((areas[0].y1 + 1000.0f)*(previewHeight/2000.0f));
+        x2 = (uint16_t)((areas[0].x2 + 1000.0f)*(previewWidth/2000.0f));
+        y2 = (uint16_t)((areas[0].y2 + 1000.0f)*(previewHeight/2000.0f));
+        delete areas;
+
+        if(num_areas_found == 1) {
+            aec_roi_value.aec_roi_enable = AEC_ROI_ON;
+            aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
+            aec_roi_value.aec_roi_position.coordinate.x = (x1+x2)/2;
+            aec_roi_value.aec_roi_position.coordinate.y = (y1+y2)/2;
+        } else {
+            aec_roi_value.aec_roi_enable = AEC_ROI_OFF;
+            aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
+            aec_roi_value.aec_roi_position.coordinate.x = DONT_CARE_COORDINATE;
+            aec_roi_value.aec_roi_position.coordinate.y = DONT_CARE_COORDINATE;
+        }
+
+        if(native_set_parms(MM_CAMERA_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value))
+            rc = NO_ERROR;
+        else
+            rc = BAD_VALUE;
+#endif
+#if 0   //solution including multi-roi, to be enabled later
+        aec_mtr_area_t aecArea;
+        aecArea.num_area = num_areas_found;
+
+        uint16_t x1, x2, y1, y2, dx, dy;
+        int previewWidth, previewHeight;
+        this->getPreviewSize(&previewWidth, &previewHeight);
+
+        for(int i=0; i<num_areas_found; i++) {
+            //transform the coords from (-1000, 1000) to (0, previewWidth or previewHeight)
+            x1 = (uint16_t)((areas[i].x1 + 1000.0f)*(previewWidth/2000.0f));
+            y1 = (uint16_t)((areas[i].y1 + 1000.0f)*(previewHeight/2000.0f));
+            x2 = (uint16_t)((areas[i].x2 + 1000.0f)*(previewWidth/2000.0f));
+            y2 = (uint16_t)((areas[i].y2 + 1000.0f)*(previewHeight/2000.0f));
+            dx = x2 - x1;
+            dy = y2 - y1;
+            aecArea.mtr_area[i].x = x1;
+            aecArea.mtr_area[i].y = y1;
+            aecArea.mtr_area[i].dx = dx;
+            aecArea.mtr_area[i].dy = dy;
+            aecArea.weight[i] = areas[i].weight;
+        }
+        delete areas;
+
+        if(native_set_parms(MM_CAMERA_PARM_AEC_MTR_AREA, sizeof(aec_mtr_area_t), (void*)&aecArea))
+            rc = NO_ERROR;
+        else
+            rc = BAD_VALUE;
+#endif
+    }
+    LOGE("%s: X", __func__);
+    return rc;
+}
+
+status_t QCameraHardwareInterface::setFocusMode(const CameraParameters& params)
+{
+    const char *str = params.get(CameraParameters::KEY_FOCUS_MODE);
+    const char *prev_str = mParameters.get(CameraParameters::KEY_FOCUS_MODE);
+    LOGE("%s",__func__);
+    if (str != NULL) {
+        LOGE("Focus mode %s",str);
+        int32_t value = attr_lookup(focus_modes,
+                                    sizeof(focus_modes) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            mParameters.set(CameraParameters::KEY_FOCUS_MODE, str);
+            mFocusMode = value;
+
+            if(updateFocusDistances() != NO_ERROR) {
+               LOGE("%s: updateFocusDistances failed for %s", __FUNCTION__, str);
+               return UNKNOWN_ERROR;
+            }
+            mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistance.string());
+            if(mHasAutoFocusSupport){
+                bool ret = native_set_parms(MM_CAMERA_PARM_FOCUS_MODE,
+                                      sizeof(value),
+                                      (void *)&value);
+
+                int cafSupport = FALSE;
+                if(!strcmp(str, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ||
+                   !strcmp(str, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)){
+                    cafSupport = TRUE;
+                }
+                LOGE("Continuous Auto Focus %d", cafSupport);
+                ret = native_set_parms(MM_CAMERA_PARM_CONTINUOUS_AF, sizeof(cafSupport),
+                                       (void *)&cafSupport);
+            }
+
+            return NO_ERROR;
+        }
+        LOGE("%s:Could not look up str value",__func__);
+    }
+    LOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setSceneMode(const CameraParameters& params)
+{
+    status_t rc = NO_ERROR;
+    LOGE("%s",__func__);
+
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_BESTSHOT_MODE);
+    if(!rc) {
+        LOGE("%s:Parameter Scenemode is not supported for this sensor", __func__);
+        return NO_ERROR;
+    }
+    const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
+    LOGE("Scene Mode string : %s",str);
+
+    if (str != NULL) {
+        int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
+        LOGE("Setting Scenemode value = %d",value );
+        if (value != NOT_FOUND) {
+            mParameters.set(CameraParameters::KEY_SCENE_MODE, str);
+            bool ret = native_set_parms(MM_CAMERA_PARM_BESTSHOT_MODE, sizeof(value),
+                                       (void *)&value);
+            int bestshot_reconfigure;
+            cam_config_get_parm(mCameraId, MM_CAMERA_PARM_BESTSHOT_RECONFIGURE,
+                                &bestshot_reconfigure);
+            if(bestshot_reconfigure) {
+                if (mBestShotMode != value) {
+                     mBestShotMode = value;
+                     if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED && ret) {
+                           mRestartPreview = 1;
+                           pausePreviewForZSL();
+                      }
+                 }
+            }
+            return ret ? NO_ERROR : UNKNOWN_ERROR;
+        }
+    }
+    LOGE("Invalid scenemode value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setSelectableZoneAf(const CameraParameters& params)
+{
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    if(mHasAutoFocusSupport) {
+        const char *str = params.get(CameraParameters::KEY_SELECTABLE_ZONE_AF);
+        if (str != NULL) {
+            int32_t value = attr_lookup(selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map), str);
+            if (value != NOT_FOUND) {
+                 rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FOCUS_RECT);
+                 if(!rc) {
+                    LOGE("SelectableZoneAF  is not supported for this sensor");
+                    return NO_ERROR;
+                 }else {
+                    mParameters.set(CameraParameters::KEY_SELECTABLE_ZONE_AF, str);
+                    bool ret = native_set_parms(MM_CAMERA_PARM_FOCUS_RECT, sizeof(value),
+                            (void *)&value);
+                    return ret ? NO_ERROR : UNKNOWN_ERROR;
+                 }
+            }
+        }
+        LOGE("Invalid selectable zone af value: %s", (str == NULL) ? "NULL" : str);
+        return BAD_VALUE;
+
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setEffect(const CameraParameters& params)
+{
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    const char *str = params.get(CameraParameters::KEY_EFFECT);
+    int result;
+    if (str != NULL) {
+        LOGE("Setting effect %s",str);
+        int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+           rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_EFFECT);
+           if(!rc) {
+               LOGE("Camera Effect - %s mode is not supported for this sensor",str);
+               return NO_ERROR;
+           }else {
+               mParameters.set(CameraParameters::KEY_EFFECT, str);
+               LOGE("Setting effect to lower HAL : %d",value);
+               bool ret = native_set_parms(MM_CAMERA_PARM_EFFECT, sizeof(value),
+                                           (void *)&value,(int *)&result);
+                if(result != MM_CAMERA_OK) {
+                    LOGI("Camera Effect: %s is not set as the selected value is not supported ", str);
+                }
+                int bestshot_reconfigure;
+                cam_config_get_parm(mCameraId, MM_CAMERA_PARM_BESTSHOT_RECONFIGURE,
+                                    &bestshot_reconfigure);
+                if(bestshot_reconfigure) {
+                     if (mEffects != value) {
+                         mEffects = value;
+                         if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED && ret) {
+                               mRestartPreview = 1;
+                               pausePreviewForZSL();
+                          }
+                   }
+               }
+               return ret ? NO_ERROR : UNKNOWN_ERROR;
+          }
+        }
+    }
+    LOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
+    LOGE("setEffect X");
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setBrightness(const CameraParameters& params) {
+
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_BRIGHTNESS);
+   if(!rc) {
+       LOGE("MM_CAMERA_PARM_BRIGHTNESS mode is not supported for this sensor");
+       return NO_ERROR;
+   }
+   int brightness = params.getInt("luma-adaptation");
+   if (mBrightness !=  brightness) {
+       LOGV(" new brightness value : %d ", brightness);
+       mBrightness =  brightness;
+       mParameters.set("luma-adaptation", brightness);
+       bool ret = native_set_parms(MM_CAMERA_PARM_BRIGHTNESS, sizeof(mBrightness),
+                                   (void *)&mBrightness);
+        return ret ? NO_ERROR : UNKNOWN_ERROR;
+   }
+
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setAutoExposure(const CameraParameters& params)
+{
+
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_EXPOSURE);
+   if(!rc) {
+       LOGE("MM_CAMERA_PARM_EXPOSURE mode is not supported for this sensor");
+       return NO_ERROR;
+   }
+   const char *str = params.get(CameraParameters::KEY_AUTO_EXPOSURE);
+    if (str != NULL) {
+        int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE, str);
+            bool ret = native_set_parms(MM_CAMERA_PARM_EXPOSURE, sizeof(value),
+                                       (void *)&value);
+            return ret ? NO_ERROR : UNKNOWN_ERROR;
+        }
+    }
+    LOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setExposureCompensation(
+        const CameraParameters & params){
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_EXPOSURE_COMPENSATION);
+    if(!rc) {
+       LOGE("MM_CAMERA_PARM_EXPOSURE_COMPENSATION mode is not supported for this sensor");
+       return NO_ERROR;
+    }
+    int numerator = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
+    if(EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR <= numerator &&
+            numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){
+        int16_t  numerator16 = (int16_t)(numerator & 0x0000ffff);
+        uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR;
+        uint32_t  value = 0;
+        value = numerator16 << 16 | denominator16;
+
+        mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
+                            numerator);
+       bool ret = native_set_parms(MM_CAMERA_PARM_EXPOSURE_COMPENSATION,
+                                    sizeof(value), (void *)&value);
+        return ret ? NO_ERROR : UNKNOWN_ERROR;
+    }
+    LOGE("Invalid Exposure Compensation");
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setWhiteBalance(const CameraParameters& params)
+{
+
+     LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_WHITE_BALANCE);
+    if(!rc) {
+       LOGE("MM_CAMERA_PARM_WHITE_BALANCE mode is not supported for this sensor");
+       return NO_ERROR;
+    }
+     int result;
+
+    const char *str = params.get(CameraParameters::KEY_WHITE_BALANCE);
+    if (str != NULL) {
+        int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            mParameters.set(CameraParameters::KEY_WHITE_BALANCE, str);
+            bool ret = native_set_parms(MM_CAMERA_PARM_WHITE_BALANCE, sizeof(value),
+                                       (void *)&value, (int *)&result);
+            if(result != MM_CAMERA_OK) {
+                LOGI("WhiteBalance Value: %s is not set as the selected value is not supported ", str);
+            }
+            return ret ? NO_ERROR : UNKNOWN_ERROR;
+        }
+    }
+    LOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+status_t QCameraHardwareInterface::setAntibanding(const CameraParameters& params)
+{
+    int result;
+
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_ANTIBANDING);
+    if(!rc) {
+       LOGE("ANTIBANDING mode is not supported for this sensor");
+       return NO_ERROR;
+    }
+    const char *str = params.get(CameraParameters::KEY_ANTIBANDING);
+    if (str != NULL) {
+        int value = (camera_antibanding_type)attr_lookup(
+          antibanding, sizeof(antibanding) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            camera_antibanding_type temp = (camera_antibanding_type) value;
+            LOGE("Antibanding Value : %d",value);
+            mParameters.set(CameraParameters::KEY_ANTIBANDING, str);
+            bool ret = native_set_parms(MM_CAMERA_PARM_ANTIBANDING,
+                       sizeof(camera_antibanding_type), (void *)&value ,(int *)&result);
+            if(result != MM_CAMERA_OK) {
+                LOGI("AntiBanding Value: %s is not supported for the given BestShot Mode", str);
+            }
+            return ret ? NO_ERROR : UNKNOWN_ERROR;
+        }
+    }
+    LOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
+
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setPreviewFrameRate(const CameraParameters& params)
+{
+    LOGE("%s: E",__func__);
+    status_t rc = NO_ERROR;
+    uint16_t fps = (uint16_t)params.getPreviewFrameRate();
+    LOGV("%s: requested preview frame rate  is %d", __func__, fps);
+
+    mParameters.setPreviewFrameRate(fps);
+    LOGE("%s: X",__func__);
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setPreviewFrameRateMode(const CameraParameters& params) {
+
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS);
+    if(!rc) {
+       LOGE(" CAMERA FPS mode is not supported for this sensor");
+       return NO_ERROR;
+    }
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS_MODE);
+    if(!rc) {
+       LOGE("CAMERA FPS MODE mode is not supported for this sensor");
+       return NO_ERROR;
+    }
+
+    const char *previousMode = mParameters.getPreviewFrameRateMode();
+    const char *str = params.getPreviewFrameRateMode();
+    if (NULL == previousMode) {
+        LOGE("Preview Frame Rate Mode is NULL\n");
+        return NO_ERROR;
+    }
+    if (NULL == str) {
+        LOGE("Preview Frame Rate Mode is NULL\n");
+        return NO_ERROR;
+    }
+    if( mInitialized && !strcmp(previousMode, str)) {
+        LOGE("frame rate mode same as previous mode %s", previousMode);
+        return NO_ERROR;
+    }
+    int32_t frameRateMode = attr_lookup(frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map),str);
+    if(frameRateMode != NOT_FOUND) {
+        LOGV("setPreviewFrameRateMode: %s ", str);
+        mParameters.setPreviewFrameRateMode(str);
+        bool ret = native_set_parms(MM_CAMERA_PARM_FPS_MODE, sizeof(frameRateMode), (void *)&frameRateMode);
+        if(!ret) return ret;
+        //set the fps value when chaging modes
+        int16_t fps = (uint16_t)params.getPreviewFrameRate();
+        if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
+            mParameters.setPreviewFrameRate(fps);
+            ret = native_set_parms(MM_CAMERA_PARM_FPS,
+                                        sizeof(fps), (void *)&fps);
+            return ret ? NO_ERROR : UNKNOWN_ERROR;
+        }
+        LOGE("Invalid preview frame rate value: %d", fps);
+        return BAD_VALUE;
+    }
+    LOGE("Invalid preview frame rate mode value: %s", (str == NULL) ? "NULL" : str);
+
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setSkinToneEnhancement(const CameraParameters& params) {
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_SCE_FACTOR);
+    if(!rc) {
+       LOGE("SkinToneEnhancement is not supported for this sensor");
+       return NO_ERROR;
+    }
+     int skinToneValue = params.getInt("skinToneEnhancement");
+     if (mSkinToneEnhancement != skinToneValue) {
+          LOGV(" new skinTone correction value : %d ", skinToneValue);
+          mSkinToneEnhancement = skinToneValue;
+          mParameters.set("skinToneEnhancement", skinToneValue);
+          bool ret = native_set_parms(MM_CAMERA_PARM_SCE_FACTOR, sizeof(mSkinToneEnhancement),
+                        (void *)&mSkinToneEnhancement);
+          return ret ? NO_ERROR : UNKNOWN_ERROR;
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setWaveletDenoise(const CameraParameters& params) {
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_WAVELET_DENOISE);
+    if(rc != MM_CAMERA_PARM_SUPPORT_SET) {
+        LOGE("Wavelet Denoise is not supported for this sensor");
+        /* TO DO */
+//        return NO_ERROR;
+    }
+    const char *str = params.get(CameraParameters::KEY_DENOISE);
+    if (str != NULL) {
+        int value = attr_lookup(denoise,
+                sizeof(denoise) / sizeof(str_map), str);
+        if ((value != NOT_FOUND) &&  (mDenoiseValue != value)) {
+            mDenoiseValue =  value;
+            mParameters.set(CameraParameters::KEY_DENOISE, str);
+
+            char prop[PROPERTY_VALUE_MAX];
+            memset(prop, 0, sizeof(prop));
+            property_get("persist.denoise.process.plates", prop, "0");
+
+            denoise_param_t temp;
+            memset(&temp, 0, sizeof(denoise_param_t));
+            temp.denoise_enable = value;
+            temp.process_plates = atoi(prop);
+            LOGE("Denoise enable=%d, plates=%d", temp.denoise_enable, temp.process_plates);
+            bool ret = native_set_parms(MM_CAMERA_PARM_WAVELET_DENOISE, sizeof(temp),
+                    (void *)&temp);
+            return ret ? NO_ERROR : UNKNOWN_ERROR;
+        }
+        return NO_ERROR;
+    }
+    LOGE("Invalid Denoise value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setVideoSize(const CameraParameters& params)
+{
+    const char *str= NULL;
+    LOGE("%s: E", __func__);
+    str = params.get(CameraParameters::KEY_VIDEO_SIZE);
+    if(!str) {
+        mParameters.set(CameraParameters::KEY_VIDEO_SIZE, "");
+        //If application didn't set this parameter string, use the values from
+        //getPreviewSize() as video dimensions.
+        LOGE("No Record Size requested, use the preview dimensions");
+        videoWidth = mPreviewWidth;
+        videoHeight = mPreviewHeight;
+    } else {
+        //Extract the record witdh and height that application requested.
+        LOGI("%s: requested record size %s", __func__, str);
+        if(!parse_size(str, videoWidth, videoHeight)) {
+            mParameters.set(CameraParameters::KEY_VIDEO_SIZE, str);
+            //VFE output1 shouldn't be greater than VFE output2.
+            if( (mPreviewWidth > videoWidth) || (mPreviewHeight > videoHeight)) {
+                //Set preview sizes as record sizes.
+                LOGE("Preview size %dx%d is greater than record size %dx%d,\
+                   resetting preview size to record size",mPreviewWidth,
+                     mPreviewHeight, videoWidth, videoHeight);
+                mPreviewWidth = videoWidth;
+                mPreviewHeight = videoHeight;
+                mParameters.setPreviewSize(mPreviewWidth, mPreviewHeight);
+            }
+
+            if(mIs3DModeOn == true) {
+                /* As preview and video frames are same in 3D mode,
+                 * preview size should be same as video size. This
+                 * cahnge is needed to take of video resolutions
+                 * like 720P and 1080p where the application can
+                 * request different preview sizes like 768x432
+                 */
+                LOGE("3D mod is on");
+                mPreviewWidth = videoWidth;
+                mPreviewHeight = videoHeight;
+                mParameters.setPreviewSize(mPreviewWidth, mPreviewHeight);
+            }
+        } else {
+            mParameters.set(CameraParameters::KEY_VIDEO_SIZE, "");
+            LOGE("%s: error :failed to parse parameter record-size (%s)", __func__, str);
+            return BAD_VALUE;
+        }
+    }
+    LOGE("%s: preview dimensions: %dx%d", __func__, mPreviewWidth, mPreviewHeight);
+    LOGE("%s: video dimensions: %dx%d", __func__, videoWidth, videoHeight);
+    mDimension.display_width = mPreviewWidth;
+    mDimension.display_height= mPreviewHeight;
+    mDimension.orig_video_width = videoWidth;
+    mDimension.orig_video_height = videoHeight;
+    mDimension.video_width = videoWidth;
+    mDimension.video_height = videoHeight;
+
+    LOGE("%s: X", __func__);
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setCameraMode(const CameraParameters& params) {
+    int32_t value = params.getInt(CameraParameters::KEY_CAMERA_MODE);
+    mParameters.set(CameraParameters::KEY_CAMERA_MODE,value);
+
+    LOGI("ZSL is enabled  %d", value);
+    if (value == 1) {
+        myMode = (camera_mode_t)(myMode | CAMERA_ZSL_MODE);
+    } else {
+        myMode = (camera_mode_t)(myMode & ~CAMERA_ZSL_MODE);
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setPowerMode(const CameraParameters& params) {
+    uint32_t value = NORMAL_POWER;
+    const char *powermode = NULL;
+
+    powermode = params.get(CameraParameters::KEY_POWER_MODE);
+    if (powermode != NULL) {
+        value = attr_lookup(power_modes,
+                sizeof(power_modes) / sizeof(str_map), powermode);
+        if((value == LOW_POWER) || mHFRLevel > 1) {
+            LOGI("Enable Low Power Mode");
+            value = LOW_POWER;
+            mPowerMode = value;
+            mParameters.set(CameraParameters::KEY_POWER_MODE,"Low_Power");
+        } else {
+            LOGE("Enable Normal Power Mode");
+            mPowerMode = value;
+            mParameters.set(CameraParameters::KEY_POWER_MODE,"Normal_Power");
+        }
+    }
+
+    LOGI("%s Low power mode %s value = %d", __func__,
+          value ? "Enabled" : "Disabled", value);
+    native_set_parms(MM_CAMERA_PARM_LOW_POWER_MODE, sizeof(value),
+                                               (void *)&value);
+    return NO_ERROR;
+}
+
+
+status_t QCameraHardwareInterface::setPreviewSize(const CameraParameters& params)
+{
+    int width, height;
+    params.getPreviewSize(&width, &height);
+    LOGE("################requested preview size %d x %d", width, height);
+
+    // Validate the preview size
+    for (size_t i = 0; i <  mPreviewSizeCount; ++i) {
+        if (width ==  mPreviewSizes[i].width
+           && height ==  mPreviewSizes[i].height) {
+            mParameters.setPreviewSize(width, height);
+            LOGE("setPreviewSize:  width: %d   heigh: %d", width, height);
+            mPreviewWidth = width;
+            mPreviewHeight = height;
+            mDimension.display_width = width;
+            mDimension.display_height = height;
+            return NO_ERROR;
+        }
+    }
+    LOGE("Invalid preview size requested: %dx%d", width, height);
+    return BAD_VALUE;
+}
+status_t QCameraHardwareInterface::setPreviewFpsRange(const CameraParameters& params)
+{
+    LOGV("%s: E", __func__);
+    int minFps,maxFps;
+    int prevMinFps, prevMaxFps;
+    int rc = NO_ERROR;
+    bool found = false;
+
+    mParameters.getPreviewFpsRange(&prevMinFps, &prevMaxFps);
+    LOGE("%s: Existing FpsRange Values:(%d, %d)", __func__, prevMinFps, prevMaxFps);
+    params.getPreviewFpsRange(&minFps,&maxFps);
+    LOGE("%s: Requested FpsRange Values:(%d, %d)", __func__, minFps, maxFps);
+
+    if(mInitialized && (minFps == prevMinFps && maxFps == prevMaxFps)) {
+        LOGE("%s: No change in FpsRange", __func__);
+        rc = NO_ERROR;
+        goto end;
+    }
+    for(size_t i=0; i<FPS_RANGES_SUPPORTED_COUNT; i++) {
+        // if the value is in the supported list
+        if(minFps==FpsRangesSupported[i].minFPS && maxFps == FpsRangesSupported[i].maxFPS){
+            found = true;
+            LOGE("FPS: i=%d : minFps = %d, maxFps = %d ",i,FpsRangesSupported[i].minFPS,FpsRangesSupported[i].maxFPS );
+            mParameters.setPreviewFpsRange(minFps,maxFps);
+            // validate the values
+            bool valid = true;
+            // FPS can not be negative
+            if(minFps < 0 || maxFps < 0) valid = false;
+            // minFps must be >= maxFps
+            if(minFps > maxFps) valid = false;
+
+            if(valid) {
+                //Set the FPS mode
+                const char *str = (minFps == maxFps) ?
+                    CameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE:
+                    CameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE;
+                LOGE("%s FPS_MODE = %s", __func__, str);
+                int32_t frameRateMode = attr_lookup(frame_rate_modes,
+                        sizeof(frame_rate_modes) / sizeof(str_map),str);
+                bool ret;
+                ret = native_set_parms(MM_CAMERA_PARM_FPS_MODE, sizeof(int32_t),
+                            (void *)&frameRateMode);
+
+                //set FPS values
+                uint32_t fps;  //lower 2 bytes specify maxFps and higher 2 bytes specify minFps
+                fps = ((uint32_t)(minFps/1000) << 16) + ((uint16_t)(maxFps/1000));
+                ret = native_set_parms(MM_CAMERA_PARM_FPS, sizeof(uint32_t), (void *)&fps);
+                mParameters.setPreviewFpsRange(minFps, maxFps);
+                if(ret)
+                    rc = NO_ERROR;
+                else {
+                    rc = BAD_VALUE;
+                    LOGE("%s: error: native_set_params failed", __func__);
+                }
+            } else {
+                LOGE("%s: error: invalid FPS range value", __func__);
+                rc = BAD_VALUE;
+            }
+        }
+    }
+    if(found == false){
+            LOGE("%s: error: FPS range value not supported", __func__);
+            rc = BAD_VALUE;
+    }
+end:
+    LOGV("%s: X", __func__);
+    return rc;
+}
+
+status_t QCameraHardwareInterface::setJpegThumbnailSize(const CameraParameters& params){
+    int width = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
+    int height = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
+
+    LOGE("requested jpeg thumbnail size %d x %d", width, height);
+
+    // Validate the picture size
+    for (unsigned int i = 0; i < thumbnail_sizes_count; ++i) {
+       if (width == default_thumbnail_sizes[i].width
+         && height == default_thumbnail_sizes[i].height) {
+           thumbnailWidth = width;
+           thumbnailHeight = height;
+           mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
+           mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
+           return NO_ERROR;
+       }
+    }
+    LOGE("error: setting jpeg thumbnail size");
+    return BAD_VALUE;
+}
+status_t QCameraHardwareInterface::setPictureSize(const CameraParameters& params)
+{
+    int width, height;
+    LOGE("QualcommCameraHardware::setPictureSize E");
+    params.getPictureSize(&width, &height);
+    LOGE("requested picture size %d x %d", width, height);
+
+    // Validate the picture size
+    for (int i = 0; i < mSupportedPictureSizesCount; ++i) {
+        if (width == mPictureSizesPtr[i].width
+          && height == mPictureSizesPtr[i].height) {
+            int old_width, old_height;
+            mParameters.getPictureSize(&old_width,&old_height);
+            if(width != old_width || height != old_height) {
+                mRestartPreview = true;
+            }
+            mParameters.setPictureSize(width, height);
+            mDimension.picture_width = width;
+            mDimension.picture_height = height;
+            return NO_ERROR;
+        }
+    }
+    /* Dimension not among the ones in the list. Check if
+     * its a valid dimension, if it is, then configure the
+     * camera accordingly. else reject it.
+     */
+    if( isValidDimension(width, height) ) {
+        mParameters.setPictureSize(width, height);
+        mDimension.picture_width = width;
+        mDimension.picture_height = height;
+        return NO_ERROR;
+    } else
+        LOGE("Invalid picture size requested: %dx%d", width, height);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setJpegRotation(int isZsl) {
+    return mm_jpeg_encoder_setRotation(mRotation, isZsl);
+}
+
+int QCameraHardwareInterface::getJpegRotation(void) {
+    return mRotation;
+}
+
+int QCameraHardwareInterface::getISOSpeedValue()
+{
+    const char *iso_str = mParameters.get(CameraParameters::KEY_ISO_MODE);
+    int iso_index = attr_lookup(iso, sizeof(iso) / sizeof(str_map), iso_str);
+    int iso_value = iso_speed_values[iso_index];
+    return iso_value;
+}
+
+
+status_t QCameraHardwareInterface::setJpegQuality(const CameraParameters& params) {
+    status_t rc = NO_ERROR;
+    int quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
+    LOGE("setJpegQuality E");
+    if (quality >= 0 && quality <= 100) {
+        mParameters.set(CameraParameters::KEY_JPEG_QUALITY, quality);
+        mJpegQuality = quality;
+    } else {
+        LOGE("Invalid jpeg quality=%d", quality);
+        rc = BAD_VALUE;
+    }
+
+    quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
+    if (quality >= 0 && quality <= 100) {
+        mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality);
+    } else {
+        LOGE("Invalid jpeg thumbnail quality=%d", quality);
+        rc = BAD_VALUE;
+    }
+    LOGE("setJpegQuality X");
+    return rc;
+}
+
+status_t QCameraHardwareInterface::
+setNumOfSnapshot(const CameraParameters& params) {
+    status_t rc = NO_ERROR;
+
+    int num_of_snapshot = getNumOfSnapshots(params);
+
+    if (num_of_snapshot <= 0) {
+        num_of_snapshot = 1;
+    }
+    LOGI("number of snapshots = %d", num_of_snapshot);
+    mParameters.set("num-snaps-per-shutter", num_of_snapshot);
+
+    bool result = native_set_parms(MM_CAMERA_PARM_SNAPSHOT_BURST_NUM,
+                                   sizeof(int),
+                                   (void *)&num_of_snapshot);
+    if(!result)
+        LOGI("%s:Failure setting number of snapshots!!!", __func__);
+    return rc;
+}
+
+status_t QCameraHardwareInterface::setPreviewFormat(const CameraParameters& params) {
+    const char *str = params.getPreviewFormat();
+    int32_t previewFormat = attr_lookup(preview_formats, sizeof(preview_formats) / sizeof(str_map), str);
+    if(previewFormat != NOT_FOUND) {
+        int num = sizeof(preview_format_info_list)/sizeof(preview_format_info_t);
+        int i;
+
+        for (i = 0; i < num; i++) {
+          if (preview_format_info_list[i].Hal_format == previewFormat) {
+            mPreviewFormatInfo = preview_format_info_list[i];
+            break;
+          }
+        }
+
+        if (i == num) {
+          mPreviewFormatInfo.mm_cam_format = CAMERA_YUV_420_NV21;
+          mPreviewFormatInfo.padding = CAMERA_PAD_TO_WORD;
+          return BAD_VALUE;
+        }
+        bool ret = native_set_parms(MM_CAMERA_PARM_PREVIEW_FORMAT, sizeof(cam_format_t),
+                                   (void *)&mPreviewFormatInfo.mm_cam_format);
+        mParameters.set(CameraParameters::KEY_PREVIEW_FORMAT, str);
+        mPreviewFormat = mPreviewFormatInfo.mm_cam_format;
+        LOGI("Setting preview format to %d, i =%d, num=%d, hal_format=%d",
+             mPreviewFormat, i, num, mPreviewFormatInfo.Hal_format);
+        return NO_ERROR;
+    } else if ( strTexturesOn ) {
+      mPreviewFormatInfo.mm_cam_format = CAMERA_YUV_420_NV21;
+      mPreviewFormatInfo.padding = CAMERA_PAD_TO_4K;
+    } else {
+      mPreviewFormatInfo.mm_cam_format = CAMERA_YUV_420_NV21;
+      mPreviewFormatInfo.padding = CAMERA_PAD_TO_WORD;
+    }
+    LOGE("Invalid preview format value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setStrTextures(const CameraParameters& params) {
+    const char *str = params.get("strtextures");
+    const char *prev_str = mParameters.get("strtextures");
+
+    if(str != NULL) {
+        if(!strcmp(str,prev_str)) {
+            return NO_ERROR;
+        }
+        int str_size = strlen(str);
+        mParameters.set("strtextures", str);
+        if(str_size == 2) {
+            if(!strncmp(str, "on", str_size) || !strncmp(str, "ON", str_size)){
+                LOGI("Resetting mUseOverlay to false");
+                strTexturesOn = true;
+                mUseOverlay = false;
+            }
+        }else if(str_size == 3){
+            if (!strncmp(str, "off", str_size) || !strncmp(str, "OFF", str_size)) {
+                strTexturesOn = false;
+                mUseOverlay = true;
+            }
+        }
+
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setFlash(const CameraParameters& params)
+{
+    LOGI("%s: E",__func__);
+    int rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_LED_MODE);
+    if(!rc) {
+        LOGE("%s:LED FLASH not supported", __func__);
+        return NO_ERROR;
+    }
+
+    const char *str = params.get(CameraParameters::KEY_FLASH_MODE);
+    if (str != NULL) {
+        int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            mParameters.set(CameraParameters::KEY_FLASH_MODE, str);
+            bool ret = native_set_parms(MM_CAMERA_PARM_LED_MODE,
+                                       sizeof(value), (void *)&value);
+            return ret ? NO_ERROR : UNKNOWN_ERROR;
+        }
+    }
+    LOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str);
+
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setAecAwbLock(const CameraParameters & params)
+{
+    LOGD("%s : E", __func__);
+    status_t rc = NO_ERROR;
+    int32_t value;
+    const char* str;
+
+    //for AEC lock
+    str = params.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK);
+    value = (strcmp(str, "true") == 0)? 1 : 0;
+    mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, str);
+    rc = (native_set_parms(MM_CAMERA_PARM_AEC_LOCK, sizeof(int32_t), (void *)(&value))) ?
+                            NO_ERROR : UNKNOWN_ERROR;
+
+    //for AWB lock
+    str = params.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK);
+    value = (strcmp(str, "true") == 0)? 1 : 0;
+    mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, str);
+    rc = (native_set_parms(MM_CAMERA_PARM_AWB_LOCK, sizeof(int32_t), (void *)(&value))) ?
+                        NO_ERROR : UNKNOWN_ERROR;
+    LOGD("%s : X", __func__);
+    return rc;
+}
+
+status_t QCameraHardwareInterface::setOverlayFormats(const CameraParameters& params)
+{
+    mParameters.set("overlay-format", HAL_PIXEL_FORMAT_YCbCr_420_SP);
+    if(mIs3DModeOn == true) {
+       int ovFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP|HAL_3D_IN_SIDE_BY_SIDE_L_R|HAL_3D_OUT_SIDE_BY_SIDE;
+        mParameters.set("overlay-format", ovFormat);
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setMCEValue(const CameraParameters& params)
+{
+    LOGE("%s",__func__);
+    status_t rc = NO_ERROR;
+    rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_MCE);
+   if(!rc) {
+       LOGE("MM_CAMERA_PARM_MCE mode is not supported for this sensor");
+       return NO_ERROR;
+   }
+   const char *str = params.get(CameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT);
+    if (str != NULL) {
+        int value = attr_lookup(mce, sizeof(mce) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            int temp = (int8_t)value;
+            LOGI("%s: setting MCE value of %s", __FUNCTION__, str);
+            mParameters.set(CameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT, str);
+
+            native_set_parms(MM_CAMERA_PARM_MCE, sizeof(int8_t), (void *)&temp);
+            return NO_ERROR;
+        }
+    }
+    LOGE("Invalid MCE value: %s", (str == NULL) ? "NULL" : str);
+
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setHighFrameRate(const CameraParameters& params)
+{
+
+    bool mCameraRunning;
+
+    int rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_HFR);
+    if(!rc) {
+        LOGE("%s: MM_CAMERA_PARM_HFR not supported", __func__);
+        return NO_ERROR;
+    }
+
+    const char *str = params.get(CameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
+    if (str != NULL) {
+        int value = attr_lookup(hfr, sizeof(hfr) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            mHFRLevel = (int32_t)value;
+            //Check for change in HFR value
+            const char *oldHfr = mParameters.get(CameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
+            if(strcmp(oldHfr, str)){
+                mParameters.set(CameraParameters::KEY_VIDEO_HIGH_FRAME_RATE, str);
+//              mHFRMode = true;
+		mCameraRunning=isPreviewRunning();
+                if(mCameraRunning == true) {
+//                    mHFRThreadWaitLock.lock();
+//                    pthread_attr_t pattr;
+//                    pthread_attr_init(&pattr);
+//                    pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
+//                    mHFRThreadRunning = !pthread_create(&mHFRThread,
+//                                      &pattr,
+//                                      hfr_thread,
+//                                      (void*)NULL);
+//                    mHFRThreadWaitLock.unlock();
+                    stopPreviewInternal();
+                    mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
+                    native_set_parms(MM_CAMERA_PARM_HFR, sizeof(int32_t), (void *)&mHFRLevel);
+                    mPreviewState = QCAMERA_HAL_PREVIEW_START;
+                    if (startPreview2() == NO_ERROR)
+                        mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
+                    return NO_ERROR;
+                }
+            }
+            native_set_parms(MM_CAMERA_PARM_HFR, sizeof(int32_t), (void *)&mHFRLevel);
+            return NO_ERROR;
+        }
+    }
+    LOGE("Invalid HFR value: %s", (str == NULL) ? "NULL" : str);
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setLensshadeValue(const CameraParameters& params)
+{
+
+    int rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_ROLLOFF);
+    if(!rc) {
+        LOGE("%s:LENS SHADING not supported", __func__);
+        return NO_ERROR;
+    }
+
+    const char *str = params.get(CameraParameters::KEY_LENSSHADE);
+    if (str != NULL) {
+        int value = attr_lookup(lensshade,
+                                    sizeof(lensshade) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            int8_t temp = (int8_t)value;
+            mParameters.set(CameraParameters::KEY_LENSSHADE, str);
+            native_set_parms(MM_CAMERA_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp);
+            return NO_ERROR;
+        }
+    }
+    LOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setFaceDetect(const CameraParameters& params)
+{
+    const char *str = params.get(CameraParameters::KEY_FACE_DETECTION);
+    LOGE("setFaceDetect: %s", str);
+    if (str != NULL) {
+        int value = attr_lookup(facedetection,
+                sizeof(facedetection) / sizeof(str_map), str);
+        mFaceDetectOn = value;
+        LOGE("%s Face detection value = %d",__func__, value);
+        cam_ctrl_dimension_t dim;
+//        cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+//        preview_parm_config (&dim, mParameters);
+//        cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+        native_set_parms(MM_CAMERA_PARM_FD, sizeof(int8_t), (void *)&value);
+        mParameters.set(CameraParameters::KEY_FACE_DETECTION, str);
+        return NO_ERROR;
+    }
+    LOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+status_t QCameraHardwareInterface::setFaceDetection(const char *str)
+{
+    if(supportsFaceDetection() == false){
+        LOGE("Face detection is not enabled");
+        return NO_ERROR;
+    }
+    if (str != NULL) {
+        int value = attr_lookup(facedetection,
+                                    sizeof(facedetection) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            mMetaDataWaitLock.lock();
+            mFaceDetectOn = value;
+            mMetaDataWaitLock.unlock();
+            mParameters.set(CameraParameters::KEY_FACE_DETECTION, str);
+            native_set_parms(MM_CAMERA_PARM_FD, sizeof(int8_t), (void *)&value);
+            mParameters.set(CameraParameters::KEY_FACE_DETECTION, str);
+            return NO_ERROR;
+        }
+    }
+    LOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setAEBracket(const CameraParameters& params)
+{
+    if(!cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_HDR) || (myMode & CAMERA_ZSL_MODE)) {
+        LOGI("Parameter HDR is not supported for this sensor/ ZSL mode");
+
+        if (myMode & CAMERA_ZSL_MODE) {
+            LOGE("In ZSL mode, reset AEBBracket to HDR_OFF mode");
+            exp_bracketing_t temp;
+            memset(&temp, 0, sizeof(temp));
+            mHdrMode = HDR_BRACKETING_OFF;
+            temp.hdr_enable= FALSE;
+            temp.mode = HDR_BRACKETING_OFF;
+            native_set_parms(MM_CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp);
+        }
+        return NO_ERROR;
+    }
+    const char *str = params.get(CameraParameters::KEY_AE_BRACKET_HDR);
+
+    if (str != NULL) {
+        int value = attr_lookup(hdr_bracket,
+                                    sizeof(hdr_bracket) / sizeof(str_map), str);
+        exp_bracketing_t temp;
+        memset(&temp, 0, sizeof(temp));
+        switch (value) {
+            case HDR_MODE:
+                {
+                    mHdrMode = HDR_MODE;
+                    temp.hdr_enable= TRUE;
+                    temp.mode = HDR_MODE;
+                    temp.total_frames = 3;
+                    temp.total_hal_frames = getNumOfSnapshots();
+                    LOGI("%s: setting HDR frames (%d)", __FUNCTION__, temp.total_hal_frames);
+                    native_set_parms(MM_CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp);
+                }
+                break;
+            case EXP_BRACKETING_MODE:
+                {
+                    int numFrames = getNumOfSnapshots();
+                    const char *str_val = params.get("capture-burst-exposures");
+                    if ((str_val != NULL) && (strlen(str_val)>0)) {
+                        LOGI("%s: capture-burst-exposures %s", __FUNCTION__, str_val);
+
+                        mHdrMode = EXP_BRACKETING_MODE;
+                        temp.hdr_enable = FALSE;
+                        temp.mode = EXP_BRACKETING_MODE;
+                        temp.total_frames = (numFrames >  MAX_SNAPSHOT_BUFFERS -2) ? MAX_SNAPSHOT_BUFFERS -2 : numFrames;
+                        temp.total_hal_frames = temp.total_frames;
+                        strlcpy(temp.values, str_val, MAX_EXP_BRACKETING_LENGTH);
+                        LOGI("%s: setting Exposure Bracketing value of %s, frame (%d)", __FUNCTION__, temp.values, temp.total_hal_frames);
+                        native_set_parms(MM_CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp);
+                    }
+                    else {
+                        /* Apps not set capture-burst-exposures, error case fall into bracketing off mode */
+                        LOGI("%s: capture-burst-exposures not set, back to HDR OFF mode", __FUNCTION__);
+                        mHdrMode = HDR_BRACKETING_OFF;
+                        temp.hdr_enable= FALSE;
+                        temp.mode = HDR_BRACKETING_OFF;
+                        native_set_parms(MM_CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp);
+                    }
+                }
+                break;
+            case HDR_BRACKETING_OFF:
+            default:
+                {
+                    mHdrMode = HDR_BRACKETING_OFF;
+                    temp.hdr_enable= FALSE;
+                    temp.mode = HDR_BRACKETING_OFF;
+                    native_set_parms(MM_CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp);
+                }
+                break;
+        }
+
+        /* save the value*/
+        mParameters.set(CameraParameters::KEY_AE_BRACKET_HDR, str);
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setCaptureBurstExp()
+{
+    char burst_exp[PROPERTY_VALUE_MAX];
+    memset(burst_exp, 0, sizeof(burst_exp));
+    property_get("persist.capture.burst.exposures", burst_exp, "");
+    if (NULL != burst_exp)
+      mParameters.set("capture-burst-exposures", burst_exp);
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setRedeyeReduction(const CameraParameters& params)
+{
+    if(supportsRedEyeReduction() == false) {
+        LOGE("Parameter Redeye Reduction is not supported for this sensor");
+        return NO_ERROR;
+    }
+
+    const char *str = params.get(CameraParameters::KEY_REDEYE_REDUCTION);
+    if (str != NULL) {
+        int value = attr_lookup(redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map), str);
+        if (value != NOT_FOUND) {
+            int8_t temp = (int8_t)value;
+            LOGI("%s: setting Redeye Reduction value of %s", __FUNCTION__, str);
+            mParameters.set(CameraParameters::KEY_REDEYE_REDUCTION, str);
+
+            native_set_parms(MM_CAMERA_PARM_REDEYE_REDUCTION, sizeof(int8_t), (void *)&temp);
+            return NO_ERROR;
+        }
+    }
+    LOGE("Invalid Redeye Reduction value: %s", (str == NULL) ? "NULL" : str);
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setGpsLocation(const CameraParameters& params)
+{
+    const char *method = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
+    if (method) {
+        mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, method);
+    }else {
+         mParameters.remove(CameraParameters::KEY_GPS_PROCESSING_METHOD);
+    }
+
+    const char *latitude = params.get(CameraParameters::KEY_GPS_LATITUDE);
+    if (latitude) {
+        LOGE("latitude %s",latitude);
+        mParameters.set(CameraParameters::KEY_GPS_LATITUDE, latitude);
+    }else {
+         mParameters.remove(CameraParameters::KEY_GPS_LATITUDE);
+    }
+
+    const char *latitudeRef = params.get(CameraParameters::KEY_GPS_LATITUDE_REF);
+    if (latitudeRef) {
+        mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF, latitudeRef);
+    }else {
+         mParameters.remove(CameraParameters::KEY_GPS_LATITUDE_REF);
+    }
+
+    const char *longitude = params.get(CameraParameters::KEY_GPS_LONGITUDE);
+    if (longitude) {
+        mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, longitude);
+    }else {
+         mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE);
+    }
+
+    const char *longitudeRef = params.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
+    if (longitudeRef) {
+        mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, longitudeRef);
+    }else {
+         mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE_REF);
+    }
+
+    const char *altitudeRef = params.get(CameraParameters::KEY_GPS_ALTITUDE_REF);
+    if (altitudeRef) {
+        mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, altitudeRef);
+    }else {
+         mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE_REF);
+    }
+
+    const char *altitude = params.get(CameraParameters::KEY_GPS_ALTITUDE);
+    if (altitude) {
+        mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, altitude);
+    }else {
+         mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE);
+    }
+
+    const char *status = params.get(CameraParameters::KEY_GPS_STATUS);
+    if (status) {
+        mParameters.set(CameraParameters::KEY_GPS_STATUS, status);
+    }
+
+    const char *dateTime = params.get(CameraParameters::KEY_EXIF_DATETIME);
+    if (dateTime) {
+        mParameters.set(CameraParameters::KEY_EXIF_DATETIME, dateTime);
+    }else {
+         mParameters.remove(CameraParameters::KEY_EXIF_DATETIME);
+    }
+
+    const char *timestamp = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
+    if (timestamp) {
+        mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, timestamp);
+    }else {
+         mParameters.remove(CameraParameters::KEY_GPS_TIMESTAMP);
+    }
+    LOGE("setGpsLocation X");
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setRotation(const CameraParameters& params)
+{
+    status_t rc = NO_ERROR;
+    int rotation = params.getInt(CameraParameters::KEY_ROTATION);
+    if (rotation != NOT_FOUND) {
+        if (rotation == 0 || rotation == 90 || rotation == 180
+            || rotation == 270) {
+          mParameters.set(CameraParameters::KEY_ROTATION, rotation);
+          mRotation = rotation;
+        } else {
+            LOGE("Invalid rotation value: %d", rotation);
+            rc = BAD_VALUE;
+        }
+    }
+    LOGE("setRotation");
+    return rc;
+}
+
+status_t QCameraHardwareInterface::setDenoise(const CameraParameters& params)
+{
+#if 0
+    if(!mCfgControl.mm_camera_is_supported(MM_CAMERA_PARM_WAVELET_DENOISE)) {
+        LOGE("Wavelet Denoise is not supported for this sensor");
+        return NO_ERROR;
+    }
+    const char *str = params.get(CameraParameters::KEY_DENOISE);
+    if (str != NULL) {
+        int value = attr_lookup(denoise,
+        sizeof(denoise) / sizeof(str_map), str);
+        if ((value != NOT_FOUND) &&  (mDenoiseValue != value)) {
+        mDenoiseValue =  value;
+        mParameters.set(CameraParameters::KEY_DENOISE, str);
+        bool ret = native_set_parms(MM_CAMERA_PARM_WAVELET_DENOISE, sizeof(value),
+                                               (void *)&value);
+        return ret ? NO_ERROR : UNKNOWN_ERROR;
+        }
+        return NO_ERROR;
+    }
+    LOGE("Invalid Denoise value: %s", (str == NULL) ? "NULL" : str);
+#endif
+    return BAD_VALUE;
+}
+
+status_t QCameraHardwareInterface::setOrientation(const CameraParameters& params)
+{
+    const char *str = params.get("orientation");
+
+    if (str != NULL) {
+        if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) {
+            // Camera service needs this to decide if the preview frames and raw
+            // pictures should be rotated.
+            mParameters.set("orientation", str);
+        } else {
+            LOGE("Invalid orientation value: %s", str);
+            return BAD_VALUE;
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setPictureFormat(const CameraParameters& params)
+{
+    const char * str = params.get(CameraParameters::KEY_PICTURE_FORMAT);
+
+    if(str != NULL){
+        int32_t value = attr_lookup(picture_formats,
+                                    sizeof(picture_formats) / sizeof(str_map), str);
+        if(value != NOT_FOUND){
+            mParameters.set(CameraParameters::KEY_PICTURE_FORMAT, str);
+        } else {
+            LOGE("Invalid Picture Format value: %s", str);
+            return BAD_VALUE;
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setRecordingHintValue(const int32_t value)
+{
+    native_set_parms(MM_CAMERA_PARM_RECORDING_HINT, sizeof(value),
+                                           (void *)&value);
+    if (value == TRUE){
+        native_set_parms(MM_CAMERA_PARM_CAF_ENABLE, sizeof(value),
+                                           (void *)&value);
+    }
+    setDISMode();
+    setFullLiveshot();
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setRecordingHint(const CameraParameters& params)
+{
+
+  const char * str = params.get(CameraParameters::KEY_RECORDING_HINT);
+
+  if(str != NULL){
+      int32_t value = attr_lookup(recording_Hints,
+                                  sizeof(recording_Hints) / sizeof(str_map), str);
+      if(value != NOT_FOUND){
+          mRecordingHint = value;
+          setRecordingHintValue(mRecordingHint);
+          mParameters.set(CameraParameters::KEY_RECORDING_HINT, str);
+          return NO_ERROR;
+      } else {
+          LOGE("Invalid Picture Format value: %s", str);
+          setDISMode();
+          setFullLiveshot();
+          return BAD_VALUE;
+      }
+  }
+  setDISMode();
+  setFullLiveshot();
+  return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setDISMode() {
+  /* Enable DIS only if
+   * - Camcorder mode AND
+   * - DIS property is set AND
+   * - Not in Low power mode. */
+  uint32_t value = mRecordingHint && mDisEnabled
+                   && !isLowPowerCamcorder();
+
+  LOGI("%s DIS is %s value = %d", __func__,
+          value ? "Enabled" : "Disabled", value);
+  native_set_parms(MM_CAMERA_PARM_DIS_ENABLE, sizeof(value),
+                                               (void *)&value);
+  return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setFullLiveshot()
+{
+  /* Enable full size liveshot only if
+   * - Camcorder mode AND
+   * - Full size liveshot is enabled. */
+  uint32_t value = mRecordingHint && mFullLiveshotEnabled
+                   && !isLowPowerCamcorder();
+
+  if (((mDimension.picture_width == mDimension.video_width) &&
+      (mDimension.picture_height == mDimension.video_height))) {
+    /* If video size matches the live snapshot size
+     * turn off full size liveshot to get higher fps. */
+    value = 0;
+  }
+
+  LOGI("%s Full size liveshot %s value = %d", __func__,
+          value ? "Enabled" : "Disabled", value);
+  native_set_parms(MM_CAMERA_PARM_FULL_LIVESHOT, sizeof(value),
+                                               (void *)&value);
+  return NO_ERROR;
+}
+
+
+isp3a_af_mode_t QCameraHardwareInterface::getAutoFocusMode(
+  const CameraParameters& params)
+{
+  isp3a_af_mode_t afMode = AF_MODE_MAX;
+  afMode = (isp3a_af_mode_t)mFocusMode;
+  return afMode;
+}
+
+void QCameraHardwareInterface::getPictureSize(int *picture_width,
+                                              int *picture_height) const
+{
+    mParameters.getPictureSize(picture_width, picture_height);
+}
+
+void QCameraHardwareInterface::getPreviewSize(int *preview_width,
+                                              int *preview_height) const
+{
+    mParameters.getPreviewSize(preview_width, preview_height);
+}
+
+cam_format_t QCameraHardwareInterface::getPreviewFormat() const
+{
+    cam_format_t foramt = CAMERA_YUV_420_NV21;
+    const char *str = mParameters.getPreviewFormat();
+    int32_t value = attr_lookup(preview_formats,
+                                sizeof(preview_formats)/sizeof(str_map),
+                                str);
+
+    if(value != NOT_FOUND) {
+        int num = sizeof(preview_format_info_list)/sizeof(preview_format_info_t);
+        int i;
+        for (i = 0; i < num; i++) {
+          if (preview_format_info_list[i].Hal_format == value) {
+            foramt = preview_format_info_list[i].mm_cam_format;
+            break;
+          }
+        }
+    }
+
+    return foramt;
+}
+
+cam_pad_format_t QCameraHardwareInterface::getPreviewPadding() const
+{
+  return mPreviewFormatInfo.padding;
+}
+
+int QCameraHardwareInterface::getJpegQuality() const
+{
+    return mJpegQuality;
+}
+
+int QCameraHardwareInterface::getNumOfSnapshots(void) const
+{
+    char prop[PROPERTY_VALUE_MAX];
+    memset(prop, 0, sizeof(prop));
+    property_get("persist.camera.snapshot.number", prop, "0");
+    LOGI("%s: prop enable/disable = %d", __func__, atoi(prop));
+    if (atoi(prop)) {
+        LOGE("%s: Reading maximum no of snapshots = %d"
+             "from properties", __func__, atoi(prop));
+        return atoi(prop);
+    } else {
+        return mParameters.getInt("num-snaps-per-shutter");
+    }
+}
+
+int QCameraHardwareInterface::getNumOfSnapshots(const CameraParameters& params)
+{
+    char prop[PROPERTY_VALUE_MAX];
+    memset(prop, 0, sizeof(prop));
+    property_get("persist.camera.snapshot.number", prop, "0");
+    LOGI("%s: prop enable/disable = %d", __func__, atoi(prop));
+    if (atoi(prop)) {
+        LOGI("%s: Reading maximum no of snapshots = %d"
+             "from properties", __func__, atoi(prop));
+        return atoi(prop);
+    } else {
+        return params.getInt("num-snaps-per-shutter");
+    }
+
+}
+
+int QCameraHardwareInterface::
+getThumbSizesFromAspectRatio(uint32_t aspect_ratio,
+                             int *picture_width,
+                             int *picture_height)
+{
+    for(unsigned int i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ){
+        if(thumbnail_sizes[i].aspect_ratio == aspect_ratio)
+        {
+            *picture_width = thumbnail_sizes[i].width;
+            *picture_height = thumbnail_sizes[i].height;
+            return NO_ERROR;
+        }
+    }
+
+    return BAD_VALUE;
+}
+
+bool QCameraHardwareInterface::isRawSnapshot()
+{
+  const char *format = mParameters.getPictureFormat();
+    if( format!= NULL &&
+       !strcmp(format, CameraParameters::PIXEL_FORMAT_RAW)){
+        return true;
+    }
+    else{
+        return false;
+    }
+}
+
+status_t QCameraHardwareInterface::setPreviewSizeTable(void)
+{
+    status_t ret = NO_ERROR;
+    mm_camera_dimension_t dim;
+    struct camera_size_type* preview_size_table;
+    int preview_table_size;
+    int i = 0;
+    char str[10] = {0};
+
+    /* Initialize table with default values */
+    preview_size_table = default_preview_sizes;
+    preview_table_size = preview_sizes_count;
+
+
+    /* Get maximum preview size supported by sensor*/
+    memset(&dim, 0, sizeof(mm_camera_dimension_t));
+    ret = cam_config_get_parm(mCameraId,
+                              MM_CAMERA_PARM_MAX_PREVIEW_SIZE, &dim);
+    if (ret != NO_ERROR) {
+        LOGE("%s: Failure getting Max Preview Size supported by camera",
+             __func__);
+        goto end;
+    }
+
+    LOGD("%s: Max Preview Sizes Supported: %d X %d", __func__,
+         dim.width, dim.height);
+
+    for (i = 0; i < preview_table_size; i++) {
+        if ((preview_size_table->width <= dim.width) &&
+            (preview_size_table->height <= dim.height)) {
+            LOGD("%s: Camera Preview Size Table "
+                 "Max width: %d height %d table_size: %d",
+                 __func__, preview_size_table->width,
+                 preview_size_table->height, preview_table_size - i);
+            break;
+        }
+        preview_size_table++;
+    }
+    //set preferred preview size to maximum preview size
+    sprintf(str, "%dx%d", preview_size_table->width, preview_size_table->height);
+    mParameters.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, str);
+    LOGD("KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO = %s", str);
+
+end:
+    /* Save the table in global member*/
+    mPreviewSizes = preview_size_table;
+    mPreviewSizeCount = preview_table_size - i;
+
+    return ret;
+}
+
+status_t QCameraHardwareInterface::setPictureSizeTable(void)
+{
+    status_t ret = NO_ERROR;
+    mm_camera_dimension_t dim;
+    struct camera_size_type* picture_size_table;
+    int picture_table_size;
+    int i = 0, count = 0;
+
+    /* Initialize table with default values */
+    picture_table_size = sizeof(default_picture_sizes)/
+        sizeof(default_picture_sizes[0]);
+    picture_size_table = default_picture_sizes;
+    mPictureSizes =
+        ( struct camera_size_type *)malloc(picture_table_size *
+                                           sizeof(struct camera_size_type));
+    if (mPictureSizes == NULL) {
+        LOGE("%s: Failre allocating memory to store picture size table",__func__);
+        goto end;
+    }
+
+    /* Get maximum picture size supported by sensor*/
+    memset(&dim, 0, sizeof(mm_camera_dimension_t));
+    ret = cam_config_get_parm(mCameraId,
+                              MM_CAMERA_PARM_MAX_PICTURE_SIZE, &dim);
+    if (ret != NO_ERROR) {
+        LOGE("%s: Failure getting Max Picture Size supported by camera",
+             __func__);
+        ret = NO_MEMORY;
+        free(mPictureSizes);
+        mPictureSizes = NULL;
+        goto end;
+    }
+
+    LOGD("%s: Max Picture Sizes Supported: %d X %d", __func__,
+         dim.width, dim.height);
+
+    for (i = 0; i < picture_table_size; i++) {
+        /* We'll store those dimensions whose width AND height
+           are less than or equal to maximum supported */
+        if ((picture_size_table->width <= dim.width) &&
+            (picture_size_table->height <= dim.height)) {
+            LOGD("%s: Camera Picture Size Table "
+                 "Max width: %d height %d table_size: %d",
+                 __func__, picture_size_table->width,
+                 picture_size_table->height, count+1);
+            mPictureSizes[count].height = picture_size_table->height;
+            mPictureSizes[count].width = picture_size_table->width;
+            count++;
+        }
+        picture_size_table++;
+    }
+    mPictureSizeCount = count;
+
+end:
+     /* In case of error, we use default picture sizes */
+     if (ret != NO_ERROR) {
+        mPictureSizes = default_picture_sizes;
+        mPictureSizeCount = picture_table_size;
+    }
+    return ret;
+}
+
+status_t QCameraHardwareInterface::setVideoSizeTable(void)
+{
+    status_t ret = NO_ERROR;
+    mm_camera_dimension_t dim;
+    struct camera_size_type* video_size_table;
+    int video_table_size;
+    int i = 0, count = 0;
+    LOGE("%s: E", __func__);
+
+    /* Initialize table with default values */
+    video_table_size = video_sizes_count;
+    video_size_table = default_video_sizes;
+    mVideoSizes =
+        (struct camera_size_type *)malloc(video_table_size *
+                                           sizeof(struct camera_size_type));
+    if(mVideoSizes == NULL) {
+        LOGE("%s: error allocating memory to store video size table",__func__);
+        ret = BAD_VALUE;
+        goto end;
+    }
+
+    /* Get maximum video size supported by sensor*/
+    memset(&dim, 0, sizeof(mm_camera_dimension_t));
+    ret = cam_config_get_parm(mCameraId,
+                              MM_CAMERA_PARM_MAX_VIDEO_SIZE, &dim);
+    if(ret != NO_ERROR) {
+        LOGE("%s: error getting Max Video Size supported by camera",
+             __func__);
+        ret = NO_MEMORY;
+        free(mVideoSizes);
+        mVideoSizes = NULL;
+        ret = BAD_VALUE;
+        goto end;
+    }
+
+    LOGD("%s: Max Video Size Supported: %d X %d", __func__,
+         dim.width, dim.height);
+
+    for(i=0; i < video_table_size; i++) {
+        /* We'll store those dimensions whose width AND height
+           are less than or equal to maximum supported */
+        if((video_size_table->width <= dim.width) &&
+            (video_size_table->height <= dim.height)) {
+            LOGD("%s: Supported Video Size [%d] = %dx%d", __func__, count, video_size_table->width,
+                                    video_size_table->height);
+            mVideoSizes[count].height = video_size_table->height;
+            mVideoSizes[count].width = video_size_table->width;
+            count++;
+        }
+        video_size_table++;
+    }
+    mVideoSizeCount = count;
+
+end:
+    LOGE("%s: X", __func__);
+    return ret;
+}
+
+void QCameraHardwareInterface::freeVideoSizeTable(void)
+{
+    if(mVideoSizes != NULL)
+    {
+        free(mVideoSizes);
+    }
+    mVideoSizeCount = 0;
+}
+
+
+void QCameraHardwareInterface::freePictureTable(void)
+{
+    /* If we couldn't allocate memory to store picture table
+       we use the picture table pointer to point to default
+       picture table array. In that case we cannot free it.*/
+    if ((mPictureSizes != default_picture_sizes) && mPictureSizes) {
+        free(mPictureSizes);
+    }
+}
+
+status_t QCameraHardwareInterface::setHistogram(int histogram_en)
+{
+    LOGE("setHistogram: E");
+    if(mStatsOn == histogram_en) {
+        return NO_ERROR;
+    }
+
+    mSendData = histogram_en;
+    mStatsOn = histogram_en;
+    mCurrentHisto = -1;
+    mStatSize = sizeof(uint32_t)* HISTOGRAM_STATS_SIZE;
+
+    if (histogram_en == QCAMERA_PARM_ENABLE) {
+        /*Currently the Ashmem is multiplying the buffer size with total number
+        of buffers and page aligning. This causes a crash in JNI as each buffer
+        individually expected to be page aligned  */
+        int page_size_minus_1 = getpagesize() - 1;
+        int statSize = sizeof (camera_preview_histogram_info );
+        int32_t mAlignedStatSize = ((statSize + page_size_minus_1) & (~page_size_minus_1));
+#if 0
+        mStatHeap =
+        new AshmemPool(mAlignedStatSize, 3, statSize, "stat");
+        if (!mStatHeap->initialized()) {
+            LOGE("Stat Heap X failed ");
+            mStatHeap.clear();
+            mStatHeap = NULL;
+            return UNKNOWN_ERROR;
+        }
+#endif
+        for(int cnt = 0; cnt<3; cnt++) {
+                mStatsMapped[cnt]=mGetMemory(-1, mStatSize, 1, mCallbackCookie);
+                if(mStatsMapped[cnt] == NULL) {
+                    LOGE("Failed to get camera memory for stats heap index: %d", cnt);
+                    return(-1);
+                } else {
+                   LOGE("Received following info for stats mapped data:%p,handle:%p, size:%d,release:%p",
+                   mStatsMapped[cnt]->data ,mStatsMapped[cnt]->handle, mStatsMapped[cnt]->size, mStatsMapped[cnt]->release);
+                }
+                mHistServer.size = sizeof(camera_preview_histogram_info);
+#ifdef USE_ION
+                if(allocate_ion_memory(&mHistServer, cnt, ION_CP_MM_HEAP_ID) < 0) {
+                  LOGE("%s ION alloc failed\n", __func__);
+                  return -1;
+                }
+#else
+		        mHistServer.fd[cnt] = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
+		        if(mHistServer.fd[cnt] <= 0) {
+			      LOGE("%s: no pmem for frame %d", __func__, cnt);
+			      return -1;
+		        }
+#endif
+                mHistServer.camera_memory[cnt]=mGetMemory(mHistServer.fd[cnt],mHistServer.size, 1, mCallbackCookie);
+                if(mHistServer.camera_memory[cnt] == NULL) {
+                    LOGE("Failed to get camera memory for server side histogram index: %d", cnt);
+                    return(-1);
+                } else {
+                   LOGE("Received following info for server side histogram data:%p,handle:%p, size:%d,release:%p",
+                   mHistServer.camera_memory[cnt]->data ,mHistServer.camera_memory[cnt]->handle,
+                        mHistServer.camera_memory[cnt]->size, mHistServer.camera_memory[cnt]->release);
+                }
+                /*Register buffer at back-end*/
+                if (NO_ERROR != sendMappingBuf(0, cnt, mHistServer.fd[cnt],
+                                                   mHistServer.size, mCameraId,
+                                               CAM_SOCK_MSG_TYPE_HIST_MAPPING)) {
+                    LOGE("%s could not send buffer to back-end\n", __func__);
+                }
+        }
+    }
+    LOGV("Setting histogram = %d", histogram_en);
+    native_set_parms(MM_CAMERA_PARM_HISTOGRAM, sizeof(int), &histogram_en);
+    if(histogram_en == QCAMERA_PARM_DISABLE)
+    {
+        //release memory
+        for(int i=0; i<3; i++){
+            if(mStatsMapped[i] != NULL) {
+                mStatsMapped[i]->release(mStatsMapped[i]);
+            }
+            /*Unregister buffer at back-end */
+            if (NO_ERROR != sendUnMappingBuf(0, i, mCameraId, CAM_SOCK_MSG_TYPE_HIST_UNMAPPING)) {
+              LOGE("%s could not unregister buffer from back-end\n", __func__);
+            }
+            if(mHistServer.camera_memory[i] != NULL) {
+                mHistServer.camera_memory[i]->release(mHistServer.camera_memory[i]);
+            }
+            close(mHistServer.fd[i]);
+#ifdef USE_ION
+            deallocate_ion_memory(&mHistServer, i);
+#endif
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setZSLBurstLookBack(const CameraParameters& params)
+{
+  const char *v = params.get("capture-burst-retroactive");
+  if (v) {
+    int look_back = atoi(v);
+    LOGI("%s: look_back =%d", __func__, look_back);
+    mParameters.set("capture-burst-retroactive", look_back);
+  }
+  return NO_ERROR;
+}
+
+status_t QCameraHardwareInterface::setZSLBurstInterval(const CameraParameters& params)
+{
+  mZslInterval = BURST_INTREVAL_DEFAULT;
+  const char *v = params.get("capture-burst-interval");
+  if (v) {
+    int interval = atoi(v);
+    LOGI("%s: Interval =%d", __func__, interval);
+    if(interval < BURST_INTREVAL_MIN ||interval > BURST_INTREVAL_MAX ) {
+      return BAD_VALUE;
+    }
+    mZslInterval =  interval;
+  }
+  return NO_ERROR;
+}
+
+int QCameraHardwareInterface::getZSLBurstInterval( void )
+{
+  int val;
+
+  if (mZslInterval == BURST_INTREVAL_DEFAULT) {
+    char prop[PROPERTY_VALUE_MAX];
+    memset(prop, 0, sizeof(prop));
+    property_get("persist.camera.zsl.interval", prop, "1");
+    val = atoi(prop);
+    LOGD("%s: prop interval = %d", __func__, val);
+  } else {
+    val = mZslInterval;
+  }
+  return val;
+}
+
+
+int QCameraHardwareInterface::getZSLQueueDepth(void) const
+{
+    char prop[PROPERTY_VALUE_MAX];
+    memset(prop, 0, sizeof(prop));
+    property_get("persist.camera.zsl.queuedepth", prop, "2");
+    LOGI("%s: prop = %d", __func__, atoi(prop));
+    return atoi(prop);
+}
+
+int QCameraHardwareInterface::getZSLBackLookCount(void) const
+{
+    int look_back;
+    char prop[PROPERTY_VALUE_MAX];
+    memset(prop, 0, sizeof(prop));
+    property_get("persist.camera.zsl.backlookcnt", prop, "0");
+    LOGI("%s: prop = %d", __func__, atoi(prop));
+    look_back = atoi(prop);
+    if (look_back == 0 ) {
+      look_back = mParameters.getInt("capture-burst-retroactive");
+      LOGE("%s: look_back = %d", __func__, look_back);
+    }
+    return look_back;
+}
+
+//EXIF functions
+void QCameraHardwareInterface::deinitExifData()
+{
+    LOGD("Clearing EXIF data");
+    for(int i=0; i<MAX_EXIF_TABLE_ENTRIES; i++)
+    {
+        //clear all data
+        memset(&mExifData[i], 0x00, sizeof(exif_tags_info_t));
+    }
+    mExifTableNumEntries = 0;
+}
+
+void QCameraHardwareInterface::addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
+                        uint32_t count, uint8_t copy, void *data) {
+
+    if(mExifTableNumEntries >= MAX_EXIF_TABLE_ENTRIES) {
+        LOGE("%s: Number of entries exceeded limit", __func__);
+        return;
+    }
+    int index = mExifTableNumEntries;
+    mExifData[index].tag_id = tagid;
+    mExifData[index].tag_entry.type = type;
+    mExifData[index].tag_entry.count = count;
+    mExifData[index].tag_entry.copy = copy;
+    if((type == EXIF_RATIONAL) && (count > 1))
+        mExifData[index].tag_entry.data._rats = (rat_t *)data;
+    if((type == EXIF_RATIONAL) && (count == 1))
+        mExifData[index].tag_entry.data._rat = *(rat_t *)data;
+    else if(type == EXIF_ASCII)
+        mExifData[index].tag_entry.data._ascii = (char *)data;
+    else if(type == EXIF_BYTE)
+        mExifData[index].tag_entry.data._byte = *(uint8_t *)data;
+    else if((type == EXIF_SHORT) && (count > 1))
+        mExifData[index].tag_entry.data._shorts = (uint16_t *)data;
+    else if((type == EXIF_SHORT) && (count == 1))
+        mExifData[index].tag_entry.data._short = *(uint16_t *)data;
+    // Increase number of entries
+    mExifTableNumEntries++;
+}
+
+rat_t getRational(int num, int denom)
+{
+    rat_t temp = {num, denom};
+    return temp;
+}
+
+void QCameraHardwareInterface::initExifData(){
+    if(mExifValues.dateTime) {
+        addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
+                  20, 1, (void *)mExifValues.dateTime);
+    }
+    addExifTag(EXIFTAGID_FOCAL_LENGTH, EXIF_RATIONAL, 1, 1, (void *)&(mExifValues.focalLength));
+    addExifTag(EXIFTAGID_ISO_SPEED_RATING,EXIF_SHORT,1,1,(void *)&(mExifValues.isoSpeed));
+
+    if(mExifValues.mGpsProcess) {
+        addExifTag(EXIFTAGID_GPS_PROCESSINGMETHOD, EXIF_ASCII,
+           EXIF_ASCII_PREFIX_SIZE + strlen(mExifValues.gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE) + 1,
+           1, (void *)mExifValues.gpsProcessingMethod);
+    }
+
+    if(mExifValues.mLatitude) {
+        addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3, 1, (void *)mExifValues.latitude);
+
+        if(mExifValues.latRef) {
+            addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
+                                    1, (void *)mExifValues.latRef);
+        }
+    }
+
+    if(mExifValues.mLongitude) {
+        addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3, 1, (void *)mExifValues.longitude);
+
+        if(mExifValues.lonRef) {
+            addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
+                                1, (void *)mExifValues.lonRef);
+        }
+    }
+
+    if(mExifValues.mAltitude) {
+        addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
+                    1, (void *)&(mExifValues.altitude));
+
+        addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1, 1, (void *)&mExifValues.mAltitude_ref);
+    }
+
+    if(mExifValues.mTimeStamp) {
+        time_t unixTime;
+        struct tm *UTCTimestamp;
+
+        unixTime = (time_t)mExifValues.mGPSTimestamp;
+        UTCTimestamp = gmtime(&unixTime);
+
+        strftime(mExifValues.gpsDateStamp, sizeof(mExifValues.gpsDateStamp), "%Y:%m:%d", UTCTimestamp);
+        addExifTag(EXIFTAGID_GPS_DATESTAMP, EXIF_ASCII,
+                          strlen(mExifValues.gpsDateStamp)+1 , 1, (void *)mExifValues.gpsDateStamp);
+
+        mExifValues.gpsTimeStamp[0] = getRational(UTCTimestamp->tm_hour, 1);
+        mExifValues.gpsTimeStamp[1] = getRational(UTCTimestamp->tm_min, 1);
+        mExifValues.gpsTimeStamp[2] = getRational(UTCTimestamp->tm_sec, 1);
+
+        addExifTag(EXIFTAGID_GPS_TIMESTAMP, EXIF_RATIONAL,
+                  3, 1, (void *)mExifValues.gpsTimeStamp);
+        LOGE("EXIFTAGID_GPS_TIMESTAMP set");
+    }
+
+}
+
+//Add all exif tags in this function
+void QCameraHardwareInterface::setExifTags()
+{
+    const char *str;
+
+    //set TimeStamp
+    str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
+    if(str != NULL) {
+      strncpy(mExifValues.dateTime, str, 19);
+      mExifValues.dateTime[19] = '\0';
+    }
+
+    //Set focal length
+    int focalLengthValue = (int) (mParameters.getFloat(
+                CameraParameters::KEY_FOCAL_LENGTH) * FOCAL_LENGTH_DECIMAL_PRECISION);
+
+    mExifValues.focalLength = getRational(focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION);
+
+    //Set ISO Speed
+    mExifValues.isoSpeed = getISOSpeedValue();
+
+    //set gps tags
+    setExifTagsGPS();
+}
+
+void QCameraHardwareInterface::setExifTagsGPS()
+{
+    const char *str = NULL;
+
+    //Set GPS processing method
+    str = mParameters.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
+    if(str != NULL) {
+       memcpy(mExifValues.gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
+       strncpy(mExifValues.gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str,
+           GPS_PROCESSING_METHOD_SIZE - 1);
+       mExifValues.gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE-1] = '\0';
+       LOGE("EXIFTAGID_GPS_PROCESSINGMETHOD = %s %s", mExifValues.gpsProcessingMethod,
+                                                    mExifValues.gpsProcessingMethod+8);
+       mExifValues.mGpsProcess  = true;
+    }else{
+        mExifValues.mGpsProcess = false;
+    }
+    str = NULL;
+
+    //Set Latitude
+    str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE);
+    if(str != NULL) {
+        parseGPSCoordinate(str, mExifValues.latitude);
+        LOGE("EXIFTAGID_GPS_LATITUDE = %s", str);
+
+        //set Latitude Ref
+        float latitudeValue = mParameters.getFloat(CameraParameters::KEY_GPS_LATITUDE);
+        if(latitudeValue < 0.0f) {
+            mExifValues.latRef[0] = 'S';
+        } else {
+            mExifValues.latRef[0] = 'N';
+        }
+        mExifValues.latRef[1] = '\0';
+        mExifValues.mLatitude = true;
+        mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF,mExifValues.latRef);
+        LOGE("EXIFTAGID_GPS_LATITUDE_REF = %s", mExifValues.latRef);
+    }else{
+        mExifValues.mLatitude = false;
+    }
+
+    //set Longitude
+    str = NULL;
+    str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE);
+    if(str != NULL) {
+        parseGPSCoordinate(str, mExifValues.longitude);
+        LOGE("EXIFTAGID_GPS_LONGITUDE = %s", str);
+
+        //set Longitude Ref
+        float longitudeValue = mParameters.getFloat(CameraParameters::KEY_GPS_LONGITUDE);
+        if(longitudeValue < 0.0f) {
+            mExifValues.lonRef[0] = 'W';
+        } else {
+            mExifValues.lonRef[0] = 'E';
+        }
+        mExifValues.lonRef[1] = '\0';
+        mExifValues.mLongitude = true;
+        LOGE("EXIFTAGID_GPS_LONGITUDE_REF = %s", mExifValues.lonRef);
+        mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, mExifValues.lonRef);
+    }else{
+        mExifValues.mLongitude = false;
+    }
+
+    //set Altitude
+    str = mParameters.get(CameraParameters::KEY_GPS_ALTITUDE);
+    if(str != NULL) {
+        double value = atof(str);
+        mExifValues.mAltitude_ref = 0;
+        if(value < 0){
+            mExifValues.mAltitude_ref = 1;
+            value = -value;
+        }
+        mExifValues.altitude = getRational(value*1000, 1000);
+        mExifValues.mAltitude = true;
+        //set AltitudeRef
+        mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, mExifValues.mAltitude_ref);
+        LOGE("EXIFTAGID_GPS_ALTITUDE = %f", value);
+    }else{
+        mExifValues.mAltitude = false;
+    }
+
+    //set Gps TimeStamp
+    str = NULL;
+    str = mParameters.get(CameraParameters::KEY_GPS_TIMESTAMP);
+    if(str != NULL) {
+      mExifValues.mTimeStamp = true;
+      mExifValues.mGPSTimestamp = atol(str);
+    }else{
+         mExifValues.mTimeStamp = false;
+    }
+}
+
+//latlonString is string formatted coordinate
+//coord is rat_t[3]
+void QCameraHardwareInterface::parseGPSCoordinate(const char *latlonString, rat_t* coord)
+{
+    if(coord == NULL) {
+        LOGE("%s: error, invalid argument coord == NULL", __func__);
+        return;
+    }
+    float degF = fabs(atof(latlonString));
+    float minF = (degF- (int) degF) * 60;
+    float secF = (minF - (int) minF) * 60;
+
+    coord[0] = getRational((int) degF, 1);
+    coord[1] = getRational((int) minF, 1);
+    coord[2] = getRational((int) (secF * 10000), 10000);
+}
+
+bool QCameraHardwareInterface::isLowPowerCamcorder() {
+
+    if (mPowerMode == LOW_POWER)
+        return true;
+
+    if(mHFRLevel > 1) /* hard code the value now. Need to move tgtcommon to camear.h */
+      return true;
+
+      return false;
+}
+
+status_t QCameraHardwareInterface::setNoDisplayMode(const CameraParameters& params)
+{
+  char prop[PROPERTY_VALUE_MAX];
+  memset(prop, 0, sizeof(prop));
+  property_get("persist.camera.nodisplay", prop, "0");
+  int prop_val = atoi(prop);
+
+  if (prop_val == 0) {
+    const char *str_val  = params.get("no-display-mode");
+    if(str_val && strlen(str_val) > 0) {
+      mNoDisplayMode = atoi(str_val);
+    } else {
+      mNoDisplayMode = 0;
+    }
+    LOGD("Param mNoDisplayMode =%d", mNoDisplayMode);
+  } else {
+    mNoDisplayMode = prop_val;
+    LOGD("prop mNoDisplayMode =%d", mNoDisplayMode);
+  }
+  return NO_ERROR;
+}
+
+}; /*namespace android */
diff --git a/camera/QCamera/HAL/core/src/QCameraHWI_Preview.cpp b/camera/QCamera/HAL/core/src/QCameraHWI_Preview.cpp
new file mode 100755
index 0000000..9ecb85f
--- /dev/null
+++ b/camera/QCamera/HAL/core/src/QCameraHWI_Preview.cpp
@@ -0,0 +1,1434 @@
+/*
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+#define LOG_TAG "QCameraHWI_Preview"
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include "QCameraHAL.h"
+#include "QCameraHWI.h"
+#include <gralloc_priv.h>
+#include <genlock.h>
+
+#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
+
+/* QCameraHWI_Preview class implementation goes here*/
+/* following code implement the preview mode's image capture & display logic of this class*/
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+// Preview Callback
+// ---------------------------------------------------------------------------
+static void preview_notify_cb(mm_camera_ch_data_buf_t *frame,
+                                void *user_data)
+{
+  QCameraStream_preview *pme = (QCameraStream_preview *)user_data;
+  mm_camera_ch_data_buf_t *bufs_used = 0;
+  LOGV("%s: E", __func__);
+  /* for peview data, there is no queue, so directly use*/
+  if(pme==NULL) {
+    LOGE("%s: X : Incorrect cookie",__func__);
+    /*Call buf done*/
+    return;
+  }
+
+  pme->processPreviewFrame(frame);
+  LOGV("%s: X", __func__);
+}
+
+status_t QCameraStream_preview::setPreviewWindow(preview_stream_ops_t* window)
+{
+    status_t retVal = NO_ERROR;
+    LOGE(" %s: E ", __FUNCTION__);
+    if( window == NULL) {
+        LOGW(" Setting NULL preview window ");
+        /* TODO: Current preview window will be invalidated.
+         * Release all the buffers back */
+       // relinquishBuffers();
+    }
+    Mutex::Autolock lock(mStopCallbackLock);
+    mPreviewWindow = window;
+    LOGV(" %s : X ", __FUNCTION__ );
+    return retVal;
+}
+
+status_t QCameraStream_preview::getBufferFromSurface() {
+    int err = 0;
+    int numMinUndequeuedBufs = 0;
+  int format = 0;
+  status_t ret = NO_ERROR;
+  int gralloc_usage;
+
+    LOGI(" %s : E ", __FUNCTION__);
+
+    if( mPreviewWindow == NULL) {
+    LOGE("%s: mPreviewWindow = NULL", __func__);
+        return INVALID_OPERATION;
+  }
+    cam_ctrl_dimension_t dim;
+
+  //mDisplayLock.lock();
+    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+
+	format = mHalCamCtrl->getPreviewFormatInfo().Hal_format;
+	if(ret != NO_ERROR) {
+        LOGE("%s: display format %d is not supported", __func__, dim.prev_format);
+    goto end;
+  }
+  numMinUndequeuedBufs = 0;
+  if(mPreviewWindow->get_min_undequeued_buffer_count) {
+    err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &numMinUndequeuedBufs);
+    if (err != 0) {
+       LOGE("get_min_undequeued_buffer_count  failed: %s (%d)",
+            strerror(-err), -err);
+       ret = UNKNOWN_ERROR;
+       goto end;
+    }
+  }
+    mHalCamCtrl->mPreviewMemoryLock.lock();
+    mHalCamCtrl->mPreviewMemory.buffer_count = kPreviewBufferCount + numMinUndequeuedBufs;
+    if(mHalCamCtrl->isZSLMode()) {
+      if(mHalCamCtrl->getZSLQueueDepth() > numMinUndequeuedBufs)
+        mHalCamCtrl->mPreviewMemory.buffer_count +=
+            mHalCamCtrl->getZSLQueueDepth() - numMinUndequeuedBufs;
+    }
+    err = mPreviewWindow->set_buffer_count(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_count );
+    if (err != 0) {
+         LOGE("set_buffer_count failed: %s (%d)",
+                    strerror(-err), -err);
+         ret = UNKNOWN_ERROR;
+     goto end;
+    }
+    err = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
+                dim.display_width, dim.display_height, format);
+    if (err != 0) {
+         LOGE("set_buffers_geometry failed: %s (%d)",
+                    strerror(-err), -err);
+         ret = UNKNOWN_ERROR;
+     goto end;
+    }
+
+    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, &mVFEOutputs);
+    if(ret != MM_CAMERA_OK) {
+        LOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE  failed");
+        ret = BAD_VALUE;
+        goto end;
+    }
+
+    //as software encoder is used to encode 720p, to enhance the performance
+    //cashed pmem is used here
+    if(mVFEOutputs == 1 && dim.display_height == 720)
+        gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID;
+    else
+        gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID |
+                    CAMERA_GRALLOC_CACHING_ID;
+    err = mPreviewWindow->set_usage(mPreviewWindow, gralloc_usage);
+    if(err != 0) {
+    /* set_usage error out */
+        LOGE("%s: set_usage rc = %d", __func__, err);
+        ret = UNKNOWN_ERROR;
+        goto end;
+    }
+    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HFR_FRAME_SKIP, &mHFRFrameSkip);
+    if(ret != MM_CAMERA_OK) {
+        LOGE("get parm MM_CAMERA_PARM_HFR_FRAME_SKIP  failed");
+        ret = BAD_VALUE;
+        goto end;
+    }
+	for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
+		int stride;
+		err = mPreviewWindow->dequeue_buffer(mPreviewWindow,
+										&mHalCamCtrl->mPreviewMemory.buffer_handle[cnt],
+										&mHalCamCtrl->mPreviewMemory.stride[cnt]);
+		if(!err) {
+          LOGE("%s: dequeue buf hdl =%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+                    err = mPreviewWindow->lock_buffer(this->mPreviewWindow,
+                                       mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+                    // lock the buffer using genlock
+                    LOGE("%s: camera call genlock_lock, hdl=%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
+                    if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]),
+                                                      GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
+                       LOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
+                       mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
+	                //mHalCamCtrl->mPreviewMemoryLock.unlock();
+                       //return -EINVAL;
+                   } else {
+                     LOGE("%s: genlock_lock_buffer hdl =%p", __FUNCTION__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+                     mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED;
+                   }
+		} else {
+          mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED;
+          LOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
+        }
+
+		LOGE("%s: dequeue buf: %p\n", __func__, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+
+		if(err != 0) {
+            LOGE("%s: dequeue_buffer failed: %s (%d)", __func__,
+                    strerror(-err), -err);
+            ret = UNKNOWN_ERROR;
+			for(int i = 0; i < cnt; i++) {
+                if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) {
+                      LOGE("%s: camera call genlock_unlock", __FUNCTION__);
+                     if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
+                                                  (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) {
+                        LOGE("%s: genlock_unlock_buffer failed: hdl =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])) );
+                         //mHalCamCtrl->mPreviewMemoryLock.unlock();
+                        //return -EINVAL;
+                     } else {
+                       mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
+                     }
+                }
+                if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) {
+                  err = mPreviewWindow->cancel_buffer(mPreviewWindow,
+                                          mHalCamCtrl->mPreviewMemory.buffer_handle[i]);
+                }
+                mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED;
+                LOGE("%s: cancel_buffer: hdl =%p", __func__,  (*mHalCamCtrl->mPreviewMemory.buffer_handle[i]));
+				mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL;
+			}
+            memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
+			goto end;
+		}
+
+		mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] =
+		    (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+#ifdef USE_ION
+        mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
+        if (mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt] < 0) {
+            LOGE("%s: failed: could not open ion device\n", __func__);
+        } else {
+            mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt].fd =
+                mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd;
+            if (ioctl(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt],
+              ION_IOC_IMPORT, &mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt]) < 0)
+              LOGE("ION import failed\n");
+        }
+#endif
+		mHalCamCtrl->mPreviewMemory.camera_memory[cnt] =
+		    mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
+			mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 1, (void *)this);
+		LOGE("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__,
+            cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
+      mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size,
+      mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset);
+  }
+
+
+  memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
+  memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
+
+    LOGI(" %s : X ",__FUNCTION__);
+end:
+  //mDisplayLock.unlock();
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+
+    return ret;
+}
+
+status_t QCameraStream_preview::putBufferToSurface() {
+    int err = 0;
+    status_t ret = NO_ERROR;
+
+    LOGI(" %s : E ", __FUNCTION__);
+
+    mHalCamCtrl->mPreviewMemoryLock.lock();
+	for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
+        if (cnt < mHalCamCtrl->mPreviewMemory.buffer_count) {
+            if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW, cnt, mCameraId,
+                                                          CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
+                LOGE("%s: sending data Msg Failed", __func__);
+            }
+        }
+
+        mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]);
+#ifdef USE_ION
+        struct ion_handle_data ion_handle;
+        ion_handle.handle = mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt].handle;
+        if (ioctl(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt], ION_IOC_FREE, &ion_handle)
+            < 0)
+            LOGE("%s: ion free failed\n", __func__);
+        close(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt]);
+#endif
+            if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[cnt]) {
+                LOGD("%s: camera call genlock_unlock", __FUNCTION__);
+	        if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
+                                                    (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])))) {
+                    LOGE("%s: genlock_unlock_buffer failed, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])));
+                    continue;
+	                //mHalCamCtrl->mPreviewMemoryLock.unlock();
+                    //return -EINVAL;
+                } else {
+
+                    LOGD("%s: genlock_unlock_buffer, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])));
+                    mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
+                }
+            }
+             if( mHalCamCtrl->mPreviewMemory.local_flag[cnt] != BUFFER_NOT_OWNED) {
+               err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+               LOGD("%s: cancel_buffer: hdl =%p", __func__,  (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
+             }
+             mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED;
+
+		LOGD(" put buffer %d successfully", cnt);
+	}
+
+    if (mDisplayBuf.preview.buf.mp != NULL) {
+        delete[] mDisplayBuf.preview.buf.mp;
+        mDisplayBuf.preview.buf.mp = NULL;
+    }
+
+    mHalCamCtrl->mPreviewMemoryLock.unlock();
+	memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
+    LOGI(" %s : X ",__FUNCTION__);
+    return NO_ERROR;
+}
+
+
+status_t  QCameraStream_preview::getBufferNoDisplay( )
+{
+  int err = 0;
+  status_t ret = NO_ERROR;
+  int i, num_planes, frame_len, y_off, cbcr_off;
+  cam_ctrl_dimension_t dim;
+  uint32_t planes[VIDEO_MAX_PLANES];
+
+  LOGI("%s : E ", __FUNCTION__);
+
+
+  ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+  if(ret != NO_ERROR) {
+      LOGE("%s: display format %d is not supported", __func__, dim.prev_format);
+    goto end;
+  }
+  mHalCamCtrl->mPreviewMemoryLock.lock();
+  mHalCamCtrl->mNoDispPreviewMemory.buffer_count = kPreviewBufferCount;
+  if(mHalCamCtrl->isZSLMode()) {
+    if(mHalCamCtrl->getZSLQueueDepth() > kPreviewBufferCount - 3)
+      mHalCamCtrl->mNoDispPreviewMemory.buffer_count =
+      mHalCamCtrl->getZSLQueueDepth() + 3;
+  }
+
+  num_planes = dim.display_frame_offset.num_planes;
+  for ( i = 0; i < num_planes; i++) {
+    planes[i] = dim.display_frame_offset.mp[i].len;
+  }
+
+  frame_len = dim.picture_frame_offset.frame_len;
+  y_off = dim.picture_frame_offset.mp[0].offset;
+  cbcr_off = dim.picture_frame_offset.mp[1].offset;
+  LOGE("%s: main image: rotation = %d, yoff = %d, cbcroff = %d, size = %d, width = %d, height = %d",
+       __func__, dim.rotation, y_off, cbcr_off, frame_len,
+       dim.display_width, dim.display_height);
+  if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mNoDispPreviewMemory,
+     mHalCamCtrl->mNoDispPreviewMemory.buffer_count,
+     frame_len, y_off, cbcr_off, MSM_PMEM_MAINIMG,
+     NULL,NULL, num_planes, planes) < 0) {
+              ret = NO_MEMORY;
+              goto end;
+  };
+
+  memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
+  memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
+
+  LOGI(" %s : X ",__FUNCTION__);
+end:
+  //mDisplayLock.unlock();
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+
+  return NO_ERROR;
+}
+
+status_t   QCameraStream_preview::freeBufferNoDisplay()
+{
+  int err = 0;
+  status_t ret = NO_ERROR;
+
+  LOGI(" %s : E ", __FUNCTION__);
+
+  //mDisplayLock.lock();
+  mHalCamCtrl->mPreviewMemoryLock.lock();
+  for (int cnt = 0; cnt < mHalCamCtrl->mNoDispPreviewMemory.buffer_count; cnt++) {
+      if (cnt < mHalCamCtrl->mNoDispPreviewMemory.buffer_count) {
+          if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
+                       cnt, mCameraId, CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
+              LOGE("%s: sending data Msg Failed", __func__);
+          }
+      }
+  }
+  mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mNoDispPreviewMemory);
+  memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory));
+  if (mDisplayBuf.preview.buf.mp != NULL) {
+      delete[] mDisplayBuf.preview.buf.mp;
+      mDisplayBuf.preview.buf.mp = NULL;
+  }
+
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+  LOGI(" %s : X ",__FUNCTION__);
+  return NO_ERROR;
+}
+
+void QCameraStream_preview::notifyROIEvent(fd_roi_t roi)
+{
+    switch (roi.type) {
+    case FD_ROI_TYPE_HEADER:
+        {
+            mDisplayLock.lock();
+            mNumFDRcvd = 0;
+            memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
+            mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace;
+            mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected;
+            if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI)
+              mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI;
+            mDisplayLock.unlock();
+
+            if (mHalCamCtrl->mMetadata.number_of_faces == 0) {
+                // Clear previous faces
+                mHalCamCtrl->mCallbackLock.lock();
+                camera_data_callback pcb = mHalCamCtrl->mDataCb;
+                mHalCamCtrl->mCallbackLock.unlock();
+
+                if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
+                    LOGE("%s: Face detection RIO callback", __func__);
+                    pcb(CAMERA_MSG_PREVIEW_METADATA, NULL, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
+                }
+            }
+        }
+        break;
+    case FD_ROI_TYPE_DATA:
+        {
+            mDisplayLock.lock();
+            int idx = roi.d.data.idx;
+            if (idx >= mHalCamCtrl->mMetadata.number_of_faces) {
+                mDisplayLock.unlock();
+                LOGE("%s: idx %d out of boundary %d", __func__, idx, mHalCamCtrl->mMetadata.number_of_faces);
+                break;
+            }
+
+            mHalCamCtrl->mFace[idx].id = roi.d.data.face.id;
+            mHalCamCtrl->mFace[idx].score = roi.d.data.face.score;
+
+            // top
+            mHalCamCtrl->mFace[idx].rect[0] =
+               roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000;
+            //right
+            mHalCamCtrl->mFace[idx].rect[1] =
+               roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000;
+            //bottom
+            mHalCamCtrl->mFace[idx].rect[2] =  mHalCamCtrl->mFace[idx].rect[0] +
+               roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width;
+            //left
+            mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] +
+               roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height;
+
+            // Center of left eye
+            mHalCamCtrl->mFace[idx].left_eye[0] =
+              roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
+            mHalCamCtrl->mFace[idx].left_eye[1] =
+              roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
+
+            // Center of right eye
+            mHalCamCtrl->mFace[idx].right_eye[0] =
+              roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
+            mHalCamCtrl->mFace[idx].right_eye[1] =
+              roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
+
+            // Center of mouth
+            mHalCamCtrl->mFace[idx].mouth[0] =
+              roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
+            mHalCamCtrl->mFace[idx].mouth[1] =
+              roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
+
+            mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree;
+            mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence;
+            mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected;
+            mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised;
+            mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle;
+            /* newly added */
+            mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir;
+            mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir;
+            mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir;
+            mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink;
+            mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink;
+            mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze;
+            mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze;
+            LOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), face_recg(%d)", __func__,
+               mHalCamCtrl->mFace[idx].rect[0],  mHalCamCtrl->mFace[idx].rect[1],
+               mHalCamCtrl->mFace[idx].rect[2],  mHalCamCtrl->mFace[idx].rect[3],
+               mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1],
+               mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1],
+               mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1],
+               mHalCamCtrl->mFace[idx].smile_degree, mHalCamCtrl->mFace[idx].smile_score,
+               mHalCamCtrl->mFace[idx].face_recognised);
+            LOGE("%s: gaze(%d, %d, %d), updown(%d), leftright(%d), roll(%d), blink(%d, %d, %d)", __func__,
+               mHalCamCtrl->mFace[idx].gaze_angle,  mHalCamCtrl->mFace[idx].left_right_gaze,
+               mHalCamCtrl->mFace[idx].top_bottom_gaze,  mHalCamCtrl->mFace[idx].updown_dir,
+               mHalCamCtrl->mFace[idx].leftright_dir, mHalCamCtrl->mFace[idx].roll_dir,
+               mHalCamCtrl->mFace[idx].blink_detected,
+               mHalCamCtrl->mFace[idx].leye_blink, mHalCamCtrl->mFace[idx].reye_blink);
+
+             mNumFDRcvd++;
+             mDisplayLock.unlock();
+
+             if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) {
+                 mHalCamCtrl->mCallbackLock.lock();
+                 camera_data_callback pcb = mHalCamCtrl->mDataCb;
+                 mHalCamCtrl->mCallbackLock.unlock();
+
+                 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
+                     LOGE("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score);
+                     pcb(CAMERA_MSG_PREVIEW_METADATA, NULL, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
+                 }
+             }
+        }
+        break;
+    }
+}
+
+status_t QCameraStream_preview::initDisplayBuffers()
+{
+  status_t ret = NO_ERROR;
+  int width = 0;  /* width of channel  */
+  int height = 0; /* height of channel */
+  uint32_t frame_len = 0; /* frame planner length */
+  int buffer_num = 4; /* number of buffers for display */
+  const char *pmem_region;
+  uint8_t num_planes = 0;
+  uint32_t planes[VIDEO_MAX_PLANES];
+  void *vaddr = NULL;
+  cam_ctrl_dimension_t dim;
+
+  LOGE("%s:BEGIN",__func__);
+  memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
+  mHalCamCtrl->mPreviewMemoryLock.lock();
+  memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+  memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer));
+
+/* get preview size, by qury mm_camera*/
+  memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+
+  memset(&(this->mDisplayStreamBuf),0, sizeof(this->mDisplayStreamBuf));
+
+  ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+  if (MM_CAMERA_OK != ret) {
+    LOGE("%s: error - can't get camera dimension!", __func__);
+    LOGE("%s: X", __func__);
+    return BAD_VALUE;
+  }else {
+    width =  dim.display_width,
+    height = dim.display_height;
+  }
+
+  ret = getBufferFromSurface();
+  if(ret != NO_ERROR) {
+    LOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
+    return ret;
+  }
+
+  /* set 4 buffers for display */
+  mHalCamCtrl->mPreviewMemoryLock.lock();
+  memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
+  this->mDisplayStreamBuf.num = mHalCamCtrl->mPreviewMemory.buffer_count;
+  this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
+  num_planes = 2;
+  planes[0] = dim.display_frame_offset.mp[0].len;
+  planes[1] = dim.display_frame_offset.mp[1].len;
+  this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
+
+  memset(&mDisplayBuf, 0, sizeof(mDisplayBuf));
+  mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
+  if (!mDisplayBuf.preview.buf.mp) {
+    LOGE("%s Error allocating memory for mplanar struct ", __func__);
+    ret = NO_MEMORY;
+    goto error;
+  }
+  memset(mDisplayBuf.preview.buf.mp, 0,
+    mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
+
+  /*allocate memory for the buffers*/
+  for(int i = 0; i < mDisplayStreamBuf.num; i++){
+	  if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL)
+		  continue;
+      mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
+      mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
+      mDisplayStreamBuf.frame[i].y_off = 0;
+      mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
+	  mHalCamCtrl->mPreviewMemory.addr_offset[i] =
+	      mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset;
+      mDisplayStreamBuf.frame[i].buffer =
+          (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data;
+      mDisplayStreamBuf.frame[i].ion_alloc.len = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size;
+      mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mPreviewMemory.main_ion_fd[i];
+      mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mPreviewMemory.ion_info_fd[i];
+
+    LOGE("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, "
+      "offset = %d, vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd,
+      mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
+      mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off,
+      mHalCamCtrl->mPreviewMemory.addr_offset[i],
+      (uint32_t)mDisplayStreamBuf.frame[i].buffer);
+
+    ret = mHalCamCtrl->sendMappingBuf(
+                        MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
+                        i,
+                        mDisplayStreamBuf.frame[i].fd,
+                        mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
+                        mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING);
+    if (NO_ERROR != ret) {
+      LOGE("%s: sending mapping data Msg Failed", __func__);
+      goto error;
+    }
+
+    mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
+    mDisplayBuf.preview.buf.mp[i].frame_offset = mHalCamCtrl->mPreviewMemory.addr_offset[i];
+    mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
+
+    /* Plane 0 needs to be set seperately. Set other planes
+     * in a loop. */
+    mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
+    mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
+    mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
+    mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
+      mDisplayBuf.preview.buf.mp[i].frame_offset;
+    for (int j = 1; j < num_planes; j++) {
+      mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
+      mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
+        mDisplayStreamBuf.frame[i].fd;
+      mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
+      mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
+        mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
+        mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
+    }
+
+    for (int j = 0; j < num_planes; j++)
+      LOGE("Planes: %d length: %d userptr: %lu offset: %d\n", j,
+        mDisplayBuf.preview.buf.mp[i].planes[j].length,
+        mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
+        mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
+  }/*end of for loop*/
+
+ /* register the streaming buffers for the channel*/
+  mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
+  mDisplayBuf.preview.num = mDisplayStreamBuf.num;
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+  LOGE("%s:END",__func__);
+  return NO_ERROR;
+
+error:
+    mHalCamCtrl->mPreviewMemoryLock.unlock();
+    putBufferToSurface();
+
+    LOGV("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_preview::initPreviewOnlyBuffers()
+{
+  status_t ret = NO_ERROR;
+  int width = 0;  /* width of channel  */
+  int height = 0; /* height of channel */
+  uint32_t frame_len = 0; /* frame planner length */
+  int buffer_num = 4; /* number of buffers for display */
+  const char *pmem_region;
+  uint8_t num_planes = 0;
+  uint32_t planes[VIDEO_MAX_PLANES];
+
+  cam_ctrl_dimension_t dim;
+
+  LOGE("%s:BEGIN",__func__);
+  memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
+  mHalCamCtrl->mPreviewMemoryLock.lock();
+  memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory));
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+  memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer));
+
+/* get preview size, by qury mm_camera*/
+  memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+  ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+  if (MM_CAMERA_OK != ret) {
+    LOGE("%s: error - can't get camera dimension!", __func__);
+    LOGE("%s: X", __func__);
+    return BAD_VALUE;
+  }else {
+    width =  dim.display_width;
+    height = dim.display_height;
+  }
+
+  ret = getBufferNoDisplay( );
+  if(ret != NO_ERROR) {
+    LOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
+    return ret;
+  }
+
+  /* set 4 buffers for display */
+  memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
+  mHalCamCtrl->mPreviewMemoryLock.lock();
+  this->mDisplayStreamBuf.num = mHalCamCtrl->mNoDispPreviewMemory.buffer_count;
+  this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
+  num_planes = dim.display_frame_offset.num_planes;
+  for (int i = 0; i < num_planes; i++) {
+    planes[i] = dim.display_frame_offset.mp[i].len;
+  }
+  this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
+
+  memset(&mDisplayBuf, 0, sizeof(mDisplayBuf));
+  mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
+  if (!mDisplayBuf.preview.buf.mp) {
+    LOGE("%s Error allocating memory for mplanar struct ", __func__);
+  }
+  memset(mDisplayBuf.preview.buf.mp, 0,
+    mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
+
+  /*allocate memory for the buffers*/
+  void *vaddr = NULL;
+  for(int i = 0; i < mDisplayStreamBuf.num; i++){
+	  if (mHalCamCtrl->mNoDispPreviewMemory.camera_memory[i] == NULL)
+		  continue;
+      mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mNoDispPreviewMemory.fd[i];
+      mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
+      mDisplayStreamBuf.frame[i].y_off = 0;
+      mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
+      mDisplayStreamBuf.frame[i].buffer =
+          (long unsigned int)mHalCamCtrl->mNoDispPreviewMemory.camera_memory[i]->data;
+      mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mNoDispPreviewMemory.main_ion_fd[i];
+      mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mNoDispPreviewMemory.ion_info_fd[i];
+
+    LOGE("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, "
+      "vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd,
+      frame_len,
+      mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off,
+      (uint32_t)mDisplayStreamBuf.frame[i].buffer);
+
+    if (NO_ERROR != mHalCamCtrl->sendMappingBuf(
+                        MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
+                        i,
+                        mDisplayStreamBuf.frame[i].fd,
+                        mHalCamCtrl->mNoDispPreviewMemory.size,
+                        mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
+      LOGE("%s: sending mapping data Msg Failed", __func__);
+    }
+
+    mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
+    mDisplayBuf.preview.buf.mp[i].frame_offset = mDisplayStreamBuf.frame[i].y_off;
+    mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
+
+    /* Plane 0 needs to be set seperately. Set other planes
+     * in a loop. */
+    mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
+    mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
+    mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
+    mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
+      mDisplayBuf.preview.buf.mp[i].frame_offset;
+    for (int j = 1; j < num_planes; j++) {
+      mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
+      mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
+        mDisplayStreamBuf.frame[i].fd;
+      mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
+      mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
+        mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
+        mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
+    }
+
+    for (int j = 0; j < num_planes; j++)
+      LOGE("Planes: %d length: %d userptr: %lu offset: %d\n", j,
+        mDisplayBuf.preview.buf.mp[i].planes[j].length,
+        mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
+        mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
+  }/*end of for loop*/
+
+ /* register the streaming buffers for the channel*/
+  mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
+  mDisplayBuf.preview.num = mDisplayStreamBuf.num;
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+  LOGE("%s:END",__func__);
+  return NO_ERROR;
+
+end:
+  if (MM_CAMERA_OK == ret ) {
+    LOGV("%s: X - NO_ERROR ", __func__);
+    return NO_ERROR;
+  }
+
+    LOGV("%s: out of memory clean up", __func__);
+  /* release the allocated memory */
+
+  LOGV("%s: X - BAD_VALUE ", __func__);
+  return BAD_VALUE;
+}
+
+
+void QCameraStream_preview::dumpFrameToFile(struct msm_frame* newFrame)
+{
+  int32_t enabled = 0;
+  int frm_num;
+  uint32_t  skip_mode;
+  char value[PROPERTY_VALUE_MAX];
+  char buf[32];
+  int w, h;
+  static int count = 0;
+  cam_ctrl_dimension_t dim;
+  int file_fd;
+  int rc = 0;
+  int len;
+  unsigned long addr;
+  unsigned long * tmp = (unsigned long *)newFrame->buffer;
+  addr = *tmp;
+  status_t ret = cam_config_get_parm(mHalCamCtrl->mCameraId,
+                 MM_CAMERA_PARM_DIMENSION, &dim);
+
+  w = dim.display_width;
+  h = dim.display_height;
+  len = (w * h)*3/2;
+  count++;
+  if(count < 100) {
+    snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count);
+    file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+
+    rc = write(file_fd, (const void *)addr, len);
+    LOGE("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d",
+          __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc);
+    close(file_fd);
+    LOGE("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len);
+  }
+}
+
+status_t QCameraStream_preview::processPreviewFrameWithDisplay(
+  mm_camera_ch_data_buf_t *frame)
+{
+  LOGV("%s",__func__);
+  int err = 0;
+  int msgType = 0;
+  int i;
+  camera_memory_t *data = NULL;
+  camera_frame_metadata_t *metadata = NULL;
+
+  Mutex::Autolock lock(mStopCallbackLock);
+  if(!mActive) {
+    LOGE("Preview Stopped. Returning callback");
+    return NO_ERROR;
+  }
+
+  if(mHalCamCtrl==NULL) {
+    LOGE("%s: X: HAL control object not set",__func__);
+    /*Call buf done*/
+    return BAD_VALUE;
+  }
+  mHalCamCtrl->mCallbackLock.lock();
+  camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
+  void *rdata = mHalCamCtrl->mCallbackCookie;
+  mHalCamCtrl->mCallbackLock.unlock();
+  nsecs_t timeStamp = seconds_to_nanoseconds(frame->def.frame->ts.tv_sec) ;
+  timeStamp += frame->def.frame->ts.tv_nsec;
+
+  if(mFirstFrameRcvd == false) {
+  mm_camera_util_profile("HAL: First preview frame received");
+  mFirstFrameRcvd = true;
+  }
+
+  if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
+      mHalCamCtrl->debugShowPreviewFPS();
+  }
+  //dumpFrameToFile(frame->def.frame);
+  mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
+
+  mHalCamCtrl->mPreviewMemoryLock.lock();
+  mNotifyBuffer[frame->def.idx] = *frame;
+
+  LOGI("Enqueue buf handle %p\n",
+  mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+  LOGD("%s: camera call genlock_unlock", __FUNCTION__);
+    if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx]) {
+      LOGD("%s: genlock_unlock_buffer hdl =%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]));
+        if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)
+	            (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]))) {
+            LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+	        //mHalCamCtrl->mPreviewMemoryLock.unlock();
+            //return -EINVAL;
+        } else {
+            mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_UNLOCKED;
+        }
+    } else {
+        LOGE("%s: buffer to be enqueued is not locked", __FUNCTION__);
+	    //mHalCamCtrl->mPreviewMemoryLock.unlock();
+        //return -EINVAL;
+    }
+
+#ifdef USE_ION
+  struct ion_flush_data cache_inv_data;
+  int ion_fd;
+  ion_fd = frame->def.frame->ion_dev_fd;
+  cache_inv_data.vaddr = (void *)frame->def.frame->buffer;
+  cache_inv_data.fd = frame->def.frame->fd;
+  cache_inv_data.handle = frame->def.frame->fd_data.handle;
+  cache_inv_data.length = frame->def.frame->ion_alloc.len;
+
+  if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_CACHES) < 0)
+    LOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__,
+      cache_inv_data.vaddr, cache_inv_data.fd);
+#endif
+
+  if(mHFRFrameSkip == 1)
+  {
+      const char *str = mHalCamCtrl->mParameters.get(
+                          CameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
+      if(str != NULL){
+      int is_hfr_off = 0;
+      mHFRFrameCnt++;
+      if(!strcmp(str, CameraParameters::VIDEO_HFR_OFF)) {
+          is_hfr_off = 1;
+          err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
+            (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+      } else if (!strcmp(str, CameraParameters::VIDEO_HFR_2X)) {
+          mHFRFrameCnt %= 2;
+      } else if (!strcmp(str, CameraParameters::VIDEO_HFR_3X)) {
+          mHFRFrameCnt %= 3;
+      } else if (!strcmp(str, CameraParameters::VIDEO_HFR_4X)) {
+          mHFRFrameCnt %= 4;
+      }
+      if(mHFRFrameCnt == 0)
+          err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
+            (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+      else if(!is_hfr_off)
+          err = this->mPreviewWindow->cancel_buffer(this->mPreviewWindow,
+            (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+      } else
+          err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
+            (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+  } else {
+      err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
+          (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+  }
+  if(err != 0) {
+    LOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
+  } else {
+   LOGD("%s: enqueue_buffer hdl=%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+    mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_NOT_OWNED;
+  }
+  buffer_handle_t *buffer_handle = NULL;
+  int tmp_stride = 0;
+  err = this->mPreviewWindow->dequeue_buffer(this->mPreviewWindow,
+              &buffer_handle, &tmp_stride);
+  if (err == NO_ERROR && buffer_handle != NULL) {
+
+    LOGD("%s: dequed buf hdl =%p", __func__, *buffer_handle);
+    for(i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) {
+        if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) {
+          mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
+          break;
+        }
+    }
+     if (i < mHalCamCtrl->mPreviewMemory.buffer_count ) {
+      err = this->mPreviewWindow->lock_buffer(this->mPreviewWindow, buffer_handle);
+      LOGD("%s: camera call genlock_lock: hdl =%p", __FUNCTION__, *buffer_handle);
+      if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK,
+                                                 GENLOCK_MAX_TIMEOUT)) {
+            LOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
+	    //mHalCamCtrl->mPreviewMemoryLock.unlock();
+           // return -EINVAL;
+      } else  {
+        mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED;
+
+        if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[i])) {
+            LOGE("BUF DONE FAILED");
+        }
+      }
+     }
+  } else
+      LOGE("%s: error in dequeue_buffer, enqueue_buffer idx = %d, no free buffer now", __func__, frame->def.idx);
+  /* Save the last displayed frame. We'll be using it to fill the gap between
+     when preview stops and postview start during snapshot.*/
+  mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+
+  mHalCamCtrl->mCallbackLock.lock();
+  camera_data_callback pcb = mHalCamCtrl->mDataCb;
+  mHalCamCtrl->mCallbackLock.unlock();
+  LOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
+
+  camera_memory_t *previewMem = NULL;
+
+  if (pcb != NULL) {
+       LOGD("%s: mMsgEnabled =0x%x, preview format =%d", __func__,
+            mHalCamCtrl->mMsgEnabled, mHalCamCtrl->mPreviewFormat);
+      //Sending preview callback if corresponding Msgs are enabled
+      if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
+          LOGE("Q%s: PCB callback enabled", __func__);
+          msgType |=  CAMERA_MSG_PREVIEW_FRAME;
+          int previewBufSize;
+          /* The preview buffer size sent back in the callback should be (width*height*bytes_per_pixel)
+           * As all preview formats we support, use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2.
+           * We need to put a check if some other formats are supported in future. (punits) */
+          if((mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) || (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV12) ||
+                    (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12))
+          {
+              previewBufSize = mHalCamCtrl->mPreviewWidth * mHalCamCtrl->mPreviewHeight * 3/2;
+              if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) {
+                  previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd,
+                  previewBufSize, 1, mHalCamCtrl->mCallbackCookie);
+                  if (!previewMem || !previewMem->data) {
+                      LOGE("%s: mGetMemory failed.\n", __func__);
+                  } else {
+                      data = previewMem;
+                  }
+              } else
+                    data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];
+          } else {
+                data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];
+                LOGE("Invalid preview format, buffer size in preview callback may be wrong.");
+          }
+      } else {
+          data = NULL;
+      }
+      if(msgType) {
+          mStopCallbackLock.unlock();
+          if(mActive)
+            pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
+          if (previewMem)
+              previewMem->release(previewMem);
+      }
+	  LOGD("end of cb");
+  } else {
+    LOGD("%s PCB is not enabled", __func__);
+  }
+  if(rcb != NULL && mVFEOutputs == 1)
+  {
+      int flagwait = 1;
+      if(mHalCamCtrl->mStartRecording == true &&
+              ( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
+      {
+        if (mHalCamCtrl->mStoreMetaDataInFrame)
+        {
+          if(mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx])
+          {
+              flagwait = 1;
+              mStopCallbackLock.unlock();
+              rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
+                      mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx],
+                      0, mHalCamCtrl->mCallbackCookie);
+          }else
+              flagwait = 0;
+      }
+      else
+      {
+              mStopCallbackLock.unlock();
+              rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
+                      mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx],
+                      0, mHalCamCtrl->mCallbackCookie);
+      }
+
+      if(flagwait){
+          Mutex::Autolock rLock(&mHalCamCtrl->mRecordFrameLock);
+          if (mHalCamCtrl->mReleasedRecordingFrame != true) {
+              mHalCamCtrl->mRecordWait.wait(mHalCamCtrl->mRecordFrameLock);
+          }
+          mHalCamCtrl->mReleasedRecordingFrame = false;
+      }
+      }
+  }
+  /* Save the last displayed frame. We'll be using it to fill the gap between
+     when preview stops and postview start during snapshot.*/
+  //mLastQueuedFrame = frame->def.frame;
+/*
+  if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame))
+  {
+      LOGE("BUF DONE FAILED");
+      return BAD_VALUE;
+  }
+*/
+  return NO_ERROR;
+}
+
+
+status_t QCameraStream_preview::processPreviewFrameWithOutDisplay(
+  mm_camera_ch_data_buf_t *frame)
+{
+  LOGV("%s",__func__);
+  int err = 0;
+  int msgType = 0;
+  int i;
+  camera_memory_t *data = NULL;
+  camera_frame_metadata_t *metadata = NULL;
+
+  Mutex::Autolock lock(mStopCallbackLock);
+  if(!mActive) {
+    LOGE("Preview Stopped. Returning callback");
+    return NO_ERROR;
+  }
+  if(mHalCamCtrl==NULL) {
+    LOGE("%s: X: HAL control object not set",__func__);
+    /*Call buf done*/
+    return BAD_VALUE;
+  }
+
+  if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
+      mHalCamCtrl->debugShowPreviewFPS();
+  }
+  //dumpFrameToFile(frame->def.frame);
+  mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
+
+  mHalCamCtrl->mPreviewMemoryLock.lock();
+  mNotifyBuffer[frame->def.idx] = *frame;
+
+  /* Save the last displayed frame. We'll be using it to fill the gap between
+     when preview stops and postview start during snapshot.*/
+  mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
+  mHalCamCtrl->mPreviewMemoryLock.unlock();
+
+  mHalCamCtrl->mCallbackLock.lock();
+  camera_data_callback pcb = mHalCamCtrl->mDataCb;
+  mHalCamCtrl->mCallbackLock.unlock();
+  LOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
+
+  camera_memory_t *previewMem = NULL;
+  int previewWidth, previewHeight;
+  mHalCamCtrl->mParameters.getPreviewSize(&previewWidth, &previewHeight);
+
+#ifdef USE_ION
+  struct ion_flush_data cache_inv_data;
+  int ion_fd;
+  ion_fd = frame->def.frame->ion_dev_fd;
+  cache_inv_data.vaddr = (void *)frame->def.frame->buffer;
+  cache_inv_data.fd = frame->def.frame->fd;
+  cache_inv_data.handle = frame->def.frame->fd_data.handle;
+  cache_inv_data.length = frame->def.frame->ion_alloc.len;
+
+  if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_CACHES) < 0)
+    LOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__,
+      cache_inv_data.vaddr, cache_inv_data.fd);
+#endif
+
+  if (pcb != NULL) {
+      //Sending preview callback if corresponding Msgs are enabled
+      if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
+          msgType |=  CAMERA_MSG_PREVIEW_FRAME;
+          int previewBufSize;
+          /* For CTS : Forcing preview memory buffer lenth to be
+             'previewWidth * previewHeight * 3/2'.
+              Needed when gralloc allocated extra memory.*/
+          //Can add this check for other formats as well.
+          if( mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) {
+              previewBufSize = previewWidth * previewHeight * 3/2;
+              if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) {
+                  previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd,
+                  previewBufSize, 1, mHalCamCtrl->mCallbackCookie);
+                  if (!previewMem || !previewMem->data) {
+                      LOGE("%s: mGetMemory failed.\n", __func__);
+                  } else {
+                      data = previewMem;
+                  }
+              } else
+                    data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx];
+          } else
+                data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx];
+      } else {
+          data = NULL;
+      }
+
+      if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA){
+          msgType  |= CAMERA_MSG_PREVIEW_METADATA;
+          metadata = &mHalCamCtrl->mMetadata;
+      } else {
+          metadata = NULL;
+      }
+      if(msgType) {
+          mStopCallbackLock.unlock();
+          if(mActive)
+            pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
+          if (previewMem)
+              previewMem->release(previewMem);
+      }
+
+      if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[frame->def.idx])) {
+          LOGE("BUF DONE FAILED");
+      }
+
+      LOGD("end of cb");
+  }
+
+  return NO_ERROR;
+}
+
+status_t QCameraStream_preview::processPreviewFrame (
+  mm_camera_ch_data_buf_t *frame)
+{
+  if (mHalCamCtrl->isNoDisplayMode()) {
+    return processPreviewFrameWithOutDisplay(frame);
+  } else {
+    return processPreviewFrameWithDisplay(frame);
+  }
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+QCameraStream_preview::
+QCameraStream_preview(int cameraId, camera_mode_t mode)
+  : QCameraStream(cameraId,mode),
+    mLastQueuedFrame(NULL),
+    mNumFDRcvd(0),
+    mFirstFrameRcvd(false)
+  {
+    mHalCamCtrl = NULL;
+    LOGE("%s: E", __func__);
+    LOGE("%s: X", __func__);
+  }
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+QCameraStream_preview::~QCameraStream_preview() {
+    LOGV("%s: E", __func__);
+	if(mActive) {
+		stop();
+	}
+	if(mInit) {
+		release();
+	}
+	mInit = false;
+	mActive = false;
+    LOGV("%s: X", __func__);
+
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+status_t QCameraStream_preview::init() {
+
+  status_t ret = NO_ERROR;
+  LOGV("%s: E", __func__);
+
+  ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_PREVIEW_MASK);
+  if (NO_ERROR!=ret) {
+    LOGE("%s E: can't init native cammera preview ch\n",__func__);
+    return ret;
+  }
+
+  LOGE("Debug : %s : initChannel",__func__);
+  /* register a notify into the mmmm_camera_t object*/
+  (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
+                                     preview_notify_cb,
+                                     MM_CAMERA_REG_BUF_CB_INFINITE,
+                                     0,this);
+  LOGE("Debug : %s : cam_evt_register_buf_notify",__func__);
+  buffer_handle_t *buffer_handle = NULL;
+  int tmp_stride = 0;
+  mInit = true;
+  return ret;
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+status_t QCameraStream_preview::start()
+{
+    LOGV("%s: E", __func__);
+    status_t ret = NO_ERROR;
+
+    Mutex::Autolock lock(mStopCallbackLock);
+
+    /* call start() in parent class to start the monitor thread*/
+    //QCameraStream::start ();
+    setFormat(MM_CAMERA_CH_PREVIEW_MASK);
+
+    if (mHalCamCtrl->isNoDisplayMode()) {
+        if(NO_ERROR!=initPreviewOnlyBuffers()){
+            return BAD_VALUE;
+        }
+    } else {
+        if(NO_ERROR!=initDisplayBuffers()){
+            return BAD_VALUE;
+        }
+    }
+    LOGE("Debug : %s : initDisplayBuffers",__func__);
+
+    ret = cam_config_prepare_buf(mCameraId, &mDisplayBuf);
+    LOGE("Debug : %s : cam_config_prepare_buf",__func__);
+    if(ret != MM_CAMERA_OK) {
+        LOGV("%s:reg preview buf err=%d\n", __func__, ret);
+        ret = BAD_VALUE;
+        goto error;
+    }else {
+        ret = NO_ERROR;
+    }
+
+	/* For preview, the OP_MODE we set is dependent upon whether we are
+       starting camera or camcorder. For snapshot, anyway we disable preview.
+       However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not
+       OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of
+       ZSL we skip setting Mode here */
+
+    if (!(myMode & CAMERA_ZSL_MODE)) {
+        LOGE("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO");
+        mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
+        ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
+                                        &op_mode);
+        LOGE("OP Mode Set");
+
+        if(MM_CAMERA_OK != ret) {
+          LOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret);
+          ret = BAD_VALUE;
+          goto error;
+        }
+    }else {
+        LOGE("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL");
+        mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL;
+        ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
+                                        &op_mode);
+        if(MM_CAMERA_OK != ret) {
+          LOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret);
+          ret = BAD_VALUE;
+          goto error;
+        }
+     }
+
+    /* call mm_camera action start(...)  */
+    LOGE("Starting Preview/Video Stream. ");
+    mFirstFrameRcvd = false;
+    ret = cam_ops_action(mCameraId, TRUE, MM_CAMERA_OPS_PREVIEW, 0);
+
+    if (MM_CAMERA_OK != ret) {
+      LOGE ("%s: preview streaming start err=%d\n", __func__, ret);
+      ret = BAD_VALUE;
+      goto error;
+    }
+
+    LOGE("Debug : %s : Preview streaming Started",__func__);
+    ret = NO_ERROR;
+
+    mActive =  true;
+    goto end;
+
+error:
+    putBufferToSurface();
+end:
+    LOGE("%s: X", __func__);
+    return ret;
+  }
+
+
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+  void QCameraStream_preview::stop() {
+    LOGE("%s: E", __func__);
+    int ret=MM_CAMERA_OK;
+
+    if(!mActive) {
+      return;
+    }
+    Mutex::Autolock lock(mStopCallbackLock);
+    mActive =  false;
+    /* unregister the notify fn from the mmmm_camera_t object*/
+
+    LOGI("%s: Stop the thread \n", __func__);
+    /* call stop() in parent class to stop the monitor thread*/
+    ret = cam_ops_action(mCameraId, FALSE, MM_CAMERA_OPS_PREVIEW, 0);
+    if(MM_CAMERA_OK != ret) {
+      LOGE ("%s: camera preview stop err=%d\n", __func__, ret);
+    }
+    ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW);
+    if(ret != MM_CAMERA_OK) {
+      LOGE("%s:Unreg preview buf err=%d\n", __func__, ret);
+      //ret = BAD_VALUE;
+    }
+
+    /* In case of a clean stop, we need to clean all buffers*/
+    LOGE("Debug : %s : Buffer Unprepared",__func__);
+    /*free camera_memory handles and return buffer back to surface*/
+    if (! mHalCamCtrl->isNoDisplayMode() ) {
+      putBufferToSurface();
+    } else {
+      freeBufferNoDisplay( );
+    }
+
+    LOGE("%s: X", __func__);
+
+  }
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+  void QCameraStream_preview::release() {
+
+    LOGE("%s : BEGIN",__func__);
+    int ret=MM_CAMERA_OK,i;
+
+    if(!mInit)
+    {
+      LOGE("%s : Stream not Initalized",__func__);
+      return;
+    }
+
+    if(mActive) {
+      this->stop();
+    }
+
+    ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW);
+    LOGE("Debug : %s : De init Channel",__func__);
+    if(ret != MM_CAMERA_OK) {
+      LOGE("%s:Deinit preview channel failed=%d\n", __func__, ret);
+      //ret = BAD_VALUE;
+    }
+
+    (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
+                                      NULL,
+                                      (mm_camera_register_buf_cb_type_t)NULL,
+                                      NULL,
+                                      NULL);
+    mInit = false;
+    LOGE("%s: END", __func__);
+
+  }
+
+QCameraStream*
+QCameraStream_preview::createInstance(int cameraId,
+                                      camera_mode_t mode)
+{
+  QCameraStream* pme = new QCameraStream_preview(cameraId, mode);
+  return pme;
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+void QCameraStream_preview::deleteInstance(QCameraStream *p)
+{
+  if (p){
+    LOGV("%s: BEGIN", __func__);
+    p->release();
+    delete p;
+    p = NULL;
+    LOGV("%s: END", __func__);
+  }
+}
+
+
+/* Temp helper function */
+void *QCameraStream_preview::getLastQueuedFrame(void)
+{
+    return mLastQueuedFrame;
+}
+
+// ---------------------------------------------------------------------------
+// No code beyone this line
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/camera/QCamera/HAL/core/src/QCameraHWI_Record.cpp b/camera/QCamera/HAL/core/src/QCameraHWI_Record.cpp
new file mode 100755
index 0000000..c2e0084
--- /dev/null
+++ b/camera/QCamera/HAL/core/src/QCameraHWI_Record.cpp
@@ -0,0 +1,582 @@
+/*
+** Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+//#define LOG_NDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG "QCameraHWI_Record"
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "QCameraStream.h"
+
+
+#define LIKELY(exp)   __builtin_expect(!!(exp), 1)
+#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
+
+/* QCameraStream_record class implementation goes here*/
+/* following code implement the video streaming capture & encoding logic of this class*/
+// ---------------------------------------------------------------------------
+// QCameraStream_record createInstance()
+// ---------------------------------------------------------------------------
+namespace android {
+
+
+QCameraStream* QCameraStream_record::createInstance(int cameraId,
+                                      camera_mode_t mode)
+{
+  LOGV("%s: BEGIN", __func__);
+  QCameraStream* pme = new QCameraStream_record(cameraId, mode);
+  LOGV("%s: END", __func__);
+  return pme;
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record deleteInstance()
+// ---------------------------------------------------------------------------
+void QCameraStream_record::deleteInstance(QCameraStream *ptr)
+{
+  LOGV("%s: BEGIN", __func__);
+  if (ptr){
+    ptr->release();
+    delete ptr;
+    ptr = NULL;
+  }
+  LOGV("%s: END", __func__);
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record Constructor
+// ---------------------------------------------------------------------------
+QCameraStream_record::QCameraStream_record(int cameraId,
+                                           camera_mode_t mode)
+  :QCameraStream(cameraId,mode),
+  mDebugFps(false)
+{
+  mHalCamCtrl = NULL;
+  char value[PROPERTY_VALUE_MAX];
+  LOGV("%s: BEGIN", __func__);
+
+  property_get("persist.debug.sf.showfps", value, "0");
+  mDebugFps = atoi(value);
+
+  LOGV("%s: END", __func__);
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record Destructor
+// ---------------------------------------------------------------------------
+QCameraStream_record::~QCameraStream_record() {
+  LOGV("%s: BEGIN", __func__);
+  if(mActive) {
+    stop();
+  }
+  if(mInit) {
+    release();
+  }
+  mInit = false;
+  mActive = false;
+  LOGV("%s: END", __func__);
+
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record Callback from mm_camera
+// ---------------------------------------------------------------------------
+static void record_notify_cb(mm_camera_ch_data_buf_t *bufs_new,
+                              void *user_data)
+{
+  QCameraStream_record *pme = (QCameraStream_record *)user_data;
+  mm_camera_ch_data_buf_t *bufs_used = 0;
+  LOGV("%s: BEGIN", __func__);
+
+  /*
+  * Call Function Process Video Data
+  */
+  pme->processRecordFrame(bufs_new);
+  LOGV("%s: END", __func__);
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record
+// ---------------------------------------------------------------------------
+status_t QCameraStream_record::init()
+{
+  status_t ret = NO_ERROR;
+  LOGV("%s: BEGIN", __func__);
+
+  /*
+  *  Acquiring Video Channel
+  */
+  ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_VIDEO_MASK);
+  if (NO_ERROR!=ret) {
+    LOGE("%s ERROR: Can't init native cammera preview ch\n",__func__);
+    return ret;
+  }
+
+  /*
+  * Register the Callback with camera
+  */
+  (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
+                                            record_notify_cb,
+                                            MM_CAMERA_REG_BUF_CB_INFINITE,
+                                            0,
+                                            this);
+
+  mInit = true;
+  LOGV("%s: END", __func__);
+  return ret;
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_record
+// ---------------------------------------------------------------------------
+
+status_t QCameraStream_record::start()
+{
+  status_t ret = NO_ERROR;
+  LOGV("%s: BEGIN", __func__);
+
+  Mutex::Autolock lock(mStopCallbackLock);
+  if(!mInit) {
+    LOGE("%s ERROR: Record buffer not registered",__func__);
+    return BAD_VALUE;
+  }
+
+  setFormat(MM_CAMERA_CH_VIDEO_MASK);
+  //mRecordFreeQueueLock.lock();
+  //mRecordFreeQueue.clear();
+  //mRecordFreeQueueLock.unlock();
+  /*
+  *  Allocating Encoder Frame Buffers
+  */
+  ret = initEncodeBuffers();
+  if (NO_ERROR!=ret) {
+    LOGE("%s ERROR: Buffer Allocation Failed\n",__func__);
+    goto error;
+  }
+
+  ret = cam_config_prepare_buf(mCameraId, &mRecordBuf);
+  if(ret != MM_CAMERA_OK) {
+    LOGV("%s ERROR: Reg Record buf err=%d\n", __func__, ret);
+    ret = BAD_VALUE;
+    goto error;
+  }else{
+    ret = NO_ERROR;
+  }
+
+  /*
+  * Start Video Streaming
+  */
+  ret = cam_ops_action(mCameraId, TRUE, MM_CAMERA_OPS_VIDEO, 0);
+  if (MM_CAMERA_OK != ret) {
+    LOGE ("%s ERROR: Video streaming start err=%d\n", __func__, ret);
+    ret = BAD_VALUE;
+    goto error;
+  }else{
+    LOGE("%s : Video streaming Started",__func__);
+    ret = NO_ERROR;
+  }
+  mActive = true;
+  LOGV("%s: END", __func__);
+  return ret;
+
+error:
+  releaseEncodeBuffer();
+  LOGV("%s: END", __func__);
+  return ret;
+}
+
+void QCameraStream_record::releaseEncodeBuffer() {
+  for(int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
+    if (NO_ERROR !=
+      mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_VIDEO, cnt,
+      mCameraId, CAM_SOCK_MSG_TYPE_FD_UNMAPPING))
+      LOGE("%s: Unmapping Video Data Failed", __func__);
+
+    if (mHalCamCtrl->mStoreMetaDataInFrame) {
+      struct encoder_media_buffer_type * packet =
+          (struct encoder_media_buffer_type  *)
+          mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
+      native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
+      mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->release(
+        mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]);
+
+    }
+    mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->release(
+      mHalCamCtrl->mRecordingMemory.camera_memory[cnt]);
+    close(mHalCamCtrl->mRecordingMemory.fd[cnt]);
+    mHalCamCtrl->mRecordingMemory.fd[cnt] = -1;
+
+#ifdef USE_ION
+    mHalCamCtrl->deallocate_ion_memory(&mHalCamCtrl->mRecordingMemory, cnt);
+#endif
+  }
+  memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
+  //mNumRecordFrames = 0;
+  delete[] recordframes;
+  if (mRecordBuf.video.video.buf.mp)
+    delete[] mRecordBuf.video.video.buf.mp;
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record
+// ---------------------------------------------------------------------------
+void QCameraStream_record::stop()
+{
+  status_t ret = NO_ERROR;
+  LOGV("%s: BEGIN", __func__);
+
+  if(!mActive) {
+    LOGE("%s : Record stream not started",__func__);
+    return;
+  }
+  mActive =  false;
+  Mutex::Autolock lock(mStopCallbackLock);
+#if 0 //mzhu, when stop recording, all frame will be dirty. no need to queue frame back to kernel any more
+  mRecordFreeQueueLock.lock();
+  while(!mRecordFreeQueue.isEmpty()) {
+    LOGV("%s : Pre-releasing of Encoder buffers!\n", __FUNCTION__);
+    mm_camera_ch_data_buf_t releasedBuf = mRecordFreeQueue.itemAt(0);
+    mRecordFreeQueue.removeAt(0);
+    mRecordFreeQueueLock.unlock();
+    LOGV("%s (%d): releasedBuf.idx = %d\n", __FUNCTION__, __LINE__,
+                                              releasedBuf.video.video.idx);
+    if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId,&releasedBuf))
+        LOGE("%s : Buf Done Failed",__func__);
+  }
+  mRecordFreeQueueLock.unlock();
+#if 0
+  while (!mRecordFreeQueue.isEmpty()) {
+        LOGE("%s : Waiting for Encoder to release all buffer!\n", __FUNCTION__);
+  }
+#endif
+#endif // mzhu
+  /* unregister the notify fn from the mmmm_camera_t object
+   *  call stop() in parent class to stop the monitor thread */
+
+  ret = cam_ops_action(mCameraId, FALSE, MM_CAMERA_OPS_VIDEO, 0);
+  if (MM_CAMERA_OK != ret) {
+    LOGE ("%s ERROR: Video streaming Stop err=%d\n", __func__, ret);
+  }
+
+  ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_VIDEO);
+  if(ret != MM_CAMERA_OK){
+    LOGE("%s ERROR: Ureg video buf \n", __func__);
+  }
+
+  releaseEncodeBuffer();
+
+  mActive = false;
+  LOGV("%s: END", __func__);
+
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_record
+// ---------------------------------------------------------------------------
+void QCameraStream_record::release()
+{
+  status_t ret = NO_ERROR;
+  LOGV("%s: BEGIN", __func__);
+
+  if(mActive) {
+    stop();
+  }
+  if(!mInit) {
+    LOGE("%s : Record stream not initialized",__func__);
+    return;
+  }
+
+  ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_VIDEO);
+  if(ret != MM_CAMERA_OK) {
+    LOGE("%s:Deinit Video channel failed=%d\n", __func__, ret);
+  }
+  (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
+                                            NULL,
+                                            (mm_camera_register_buf_cb_type_t)NULL,
+                                            NULL,
+                                            NULL);
+  mInit = false;
+  LOGV("%s: END", __func__);
+}
+
+status_t QCameraStream_record::processRecordFrame(void *data)
+{
+    LOGV("%s : BEGIN",__func__);
+    mm_camera_ch_data_buf_t* frame = (mm_camera_ch_data_buf_t*) data;
+
+    Mutex::Autolock lock(mStopCallbackLock);
+    if(!mActive) {
+      LOGE("Recording Stopped. Returning callback");
+      return NO_ERROR;
+    }
+
+    if (UNLIKELY(mDebugFps)) {
+        debugShowVideoFPS();
+    }
+
+    mHalCamCtrl->dumpFrameToFile(frame->video.video.frame, HAL_DUMP_FRM_VIDEO);
+    mHalCamCtrl->mCallbackLock.lock();
+    camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
+    void *rdata = mHalCamCtrl->mCallbackCookie;
+    mHalCamCtrl->mCallbackLock.unlock();
+
+	nsecs_t timeStamp = nsecs_t(frame->video.video.frame->ts.tv_sec)*1000000000LL + \
+                      frame->video.video.frame->ts.tv_nsec;
+
+  LOGE("Send Video frame to services/encoder TimeStamp : %lld",timeStamp);
+  mRecordedFrames[frame->video.video.idx] = *frame;
+
+#ifdef USE_ION
+  struct ion_flush_data cache_inv_data;
+  int ion_fd;
+  ion_fd = frame->video.video.frame->ion_dev_fd;
+  cache_inv_data.vaddr = (void *)frame->video.video.frame->buffer;
+  cache_inv_data.fd = frame->video.video.frame->fd;
+  cache_inv_data.handle = frame->video.video.frame->fd_data.handle;
+  cache_inv_data.length = frame->video.video.frame->ion_alloc.len;
+
+  if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_CACHES) < 0)
+    LOGE("%s: Cache clean for Video buffer %p fd = %d failed", __func__,
+      cache_inv_data.vaddr, cache_inv_data.fd);
+#endif
+
+  if (mHalCamCtrl->mStoreMetaDataInFrame) {
+    mStopCallbackLock.unlock();
+    if(mActive && (rcb != NULL) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
+      rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
+              mHalCamCtrl->mRecordingMemory.metadata_memory[frame->video.video.idx],
+              0, mHalCamCtrl->mCallbackCookie);
+    }
+  } else {
+    mStopCallbackLock.unlock();
+    if(mActive && (rcb != NULL) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
+      rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
+              mHalCamCtrl->mRecordingMemory.camera_memory[frame->video.video.idx],
+              0, mHalCamCtrl->mCallbackCookie);
+    }
+  }
+
+  LOGV("%s : END",__func__);
+  return NO_ERROR;
+}
+
+//Record Related Functions
+status_t QCameraStream_record::initEncodeBuffers()
+{
+  LOGE("%s : BEGIN",__func__);
+  status_t ret = NO_ERROR;
+  const char *pmem_region;
+  uint32_t frame_len;
+  uint8_t num_planes;
+  uint32_t planes[VIDEO_MAX_PLANES];
+  //cam_ctrl_dimension_t dim;
+  int width = 0;  /* width of channel  */
+  int height = 0; /* height of channel */
+  int buf_cnt;
+  pmem_region = "/dev/pmem_adsp";
+
+
+  memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
+  memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+  ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+  if (MM_CAMERA_OK != ret) {
+    LOGE("%s: ERROR - can't get camera dimension!", __func__);
+    return BAD_VALUE;
+  }
+  else {
+    width =  dim.video_width;
+    height = dim.video_height;
+  }
+  num_planes = 2;
+  planes[0] = dim.video_frame_offset.mp[0].len;
+  planes[1] = dim.video_frame_offset.mp[1].len;
+  frame_len = dim.video_frame_offset.frame_len;
+
+  buf_cnt = VIDEO_BUFFER_COUNT;
+  if(mHalCamCtrl->isLowPowerCamcorder()) {
+    LOGE("%s: lower power camcorder selected", __func__);
+    buf_cnt = VIDEO_BUFFER_COUNT_LOW_POWER_CAMCORDER;
+  }
+    recordframes = new msm_frame[buf_cnt];
+    memset(recordframes,0,sizeof(struct msm_frame) * buf_cnt);
+
+		mRecordBuf.video.video.buf.mp = new mm_camera_mp_buf_t[buf_cnt *
+                                  sizeof(mm_camera_mp_buf_t)];
+		if (!mRecordBuf.video.video.buf.mp) {
+			LOGE("%s Error allocating memory for mplanar struct ", __func__);
+			return BAD_VALUE;
+		}
+		memset(mRecordBuf.video.video.buf.mp, 0,
+					 buf_cnt * sizeof(mm_camera_mp_buf_t));
+
+    memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
+    for (int i=0; i<MM_CAMERA_MAX_NUM_FRAMES;i++) {
+        mHalCamCtrl->mRecordingMemory.main_ion_fd[i] = -1;
+        mHalCamCtrl->mRecordingMemory.fd[i] = -1;
+    }
+
+    mHalCamCtrl->mRecordingMemory.buffer_count = buf_cnt;
+
+		mHalCamCtrl->mRecordingMemory.size = frame_len;
+		mHalCamCtrl->mRecordingMemory.cbcr_offset = planes[0];
+
+    for (int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
+#ifdef USE_ION
+      if(mHalCamCtrl->allocate_ion_memory(&mHalCamCtrl->mRecordingMemory, cnt,
+        ((0x1 << CAMERA_ION_HEAP_ID) | (0x1 << CAMERA_ION_FALLBACK_HEAP_ID))) < 0) {
+        LOGE("%s ION alloc failed\n", __func__);
+        return UNKNOWN_ERROR;
+      }
+#else
+		  mHalCamCtrl->mRecordingMemory.fd[cnt] = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
+		  if(mHalCamCtrl->mRecordingMemory.fd[cnt] <= 0) {
+			  LOGE("%s: no pmem for frame %d", __func__, cnt);
+			  return UNKNOWN_ERROR;
+		  }
+#endif
+		  mHalCamCtrl->mRecordingMemory.camera_memory[cnt] =
+		    mHalCamCtrl->mGetMemory(mHalCamCtrl->mRecordingMemory.fd[cnt],
+		    mHalCamCtrl->mRecordingMemory.size, 1, (void *)this);
+
+      if (mHalCamCtrl->mStoreMetaDataInFrame) {
+        mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] =
+          mHalCamCtrl->mGetMemory(-1,
+          sizeof(struct encoder_media_buffer_type), 1, (void *)this);
+        struct encoder_media_buffer_type * packet =
+          (struct encoder_media_buffer_type  *)
+          mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
+        packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
+        packet->buffer_type = kMetadataBufferTypeCameraSource;
+        native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
+        nh->data[0] = mHalCamCtrl->mRecordingMemory.fd[cnt];
+        nh->data[1] = 0;
+        nh->data[2] = mHalCamCtrl->mRecordingMemory.size;
+      }
+    	recordframes[cnt].fd = mHalCamCtrl->mRecordingMemory.fd[cnt];
+    	recordframes[cnt].buffer = (uint32_t)mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->data;
+	    recordframes[cnt].y_off = 0;
+	    recordframes[cnt].cbcr_off = mHalCamCtrl->mRecordingMemory.cbcr_offset;
+	    recordframes[cnt].path = OUTPUT_TYPE_V;
+      recordframes[cnt].fd_data = mHalCamCtrl->mRecordingMemory.ion_info_fd[cnt];
+      recordframes[cnt].ion_alloc = mHalCamCtrl->mRecordingMemory.alloc[cnt];
+      recordframes[cnt].ion_dev_fd = mHalCamCtrl->mRecordingMemory.main_ion_fd[cnt];
+
+      if (NO_ERROR !=
+        mHalCamCtrl->sendMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_VIDEO, cnt,
+        recordframes[cnt].fd, mHalCamCtrl->mRecordingMemory.size, mCameraId,
+        CAM_SOCK_MSG_TYPE_FD_MAPPING))
+        LOGE("%s: sending mapping data Msg Failed", __func__);
+
+      LOGE ("initRecord :  record heap , video buffers  buffer=%lu fd=%d y_off=%d cbcr_off=%d\n",
+		    (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].y_off,
+		    recordframes[cnt].cbcr_off);
+	    //mNumRecordFrames++;
+
+			mRecordBuf.video.video.buf.mp[cnt].frame = recordframes[cnt];
+      mRecordBuf.video.video.buf.mp[cnt].frame_offset = 0;
+      mRecordBuf.video.video.buf.mp[cnt].num_planes = num_planes;
+      /* Plane 0 needs to be set seperately. Set other planes
+       * in a loop. */
+      mRecordBuf.video.video.buf.mp[cnt].planes[0].reserved[0] =
+        mRecordBuf.video.video.buf.mp[cnt].frame_offset;
+      mRecordBuf.video.video.buf.mp[cnt].planes[0].length = planes[0];
+      mRecordBuf.video.video.buf.mp[cnt].planes[0].m.userptr =
+        recordframes[cnt].fd;
+      for (int j = 1; j < num_planes; j++) {
+        mRecordBuf.video.video.buf.mp[cnt].planes[j].length = planes[j];
+        mRecordBuf.video.video.buf.mp[cnt].planes[j].m.userptr =
+          recordframes[cnt].fd;
+        mRecordBuf.video.video.buf.mp[cnt].planes[j].reserved[0] =
+          mRecordBuf.video.video.buf.mp[cnt].planes[j-1].reserved[0] +
+          mRecordBuf.video.video.buf.mp[cnt].planes[j-1].length;
+      }
+    }
+
+    //memset(&mRecordBuf, 0, sizeof(mRecordBuf));
+    mRecordBuf.ch_type = MM_CAMERA_CH_VIDEO;
+    mRecordBuf.video.video.num = mHalCamCtrl->mRecordingMemory.buffer_count;//kRecordBufferCount;
+    //mRecordBuf.video.video.frame_offset = &record_offset[0];
+    //mRecordBuf.video.video.frame = &recordframes[0];
+    LOGE("%s : END",__func__);
+    return NO_ERROR;
+}
+
+void QCameraStream_record::releaseRecordingFrame(const void *opaque)
+{
+    LOGV("%s : BEGIN, opaque = 0x%p",__func__, opaque);
+    if(!mActive)
+    {
+        LOGE("%s : Recording already stopped!!! Leak???",__func__);
+        return;
+    }
+    for(int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
+      if (mHalCamCtrl->mStoreMetaDataInFrame) {
+        if(mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] &&
+                mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data == opaque) {
+            /* found the match */
+            if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mRecordedFrames[cnt]))
+                LOGE("%s : Buf Done Failed",__func__);
+            LOGV("%s : END",__func__);
+            return;
+        }
+      } else {
+        if(mHalCamCtrl->mRecordingMemory.camera_memory[cnt] &&
+                mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->data == opaque) {
+            /* found the match */
+            if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mRecordedFrames[cnt]))
+                LOGE("%s : Buf Done Failed",__func__);
+            LOGV("%s : END",__func__);
+            return;
+        }
+      }
+    }
+	LOGE("%s: cannot find the matched frame with opaue = 0x%p", __func__, opaque);
+}
+
+void QCameraStream_record::debugShowVideoFPS() const
+{
+  static int mFrameCount;
+  static int mLastFrameCount = 0;
+  static nsecs_t mLastFpsTime = 0;
+  static float mFps = 0;
+  mFrameCount++;
+  nsecs_t now = systemTime();
+  nsecs_t diff = now - mLastFpsTime;
+  if (diff > ms2ns(250)) {
+    mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
+    LOGI("Video Frames Per Second: %.4f", mFps);
+    mLastFpsTime = now;
+    mLastFrameCount = mFrameCount;
+  }
+}
+
+#if 0
+sp<IMemoryHeap> QCameraStream_record::getHeap() const
+{
+  return mRecordHeap != NULL ? mRecordHeap->mHeap : NULL;
+}
+
+#endif
+status_t  QCameraStream_record::takeLiveSnapshot(){
+	return true;
+}
+
+}//namespace android
+
diff --git a/camera/QCamera/HAL/core/src/QCameraHWI_Still.cpp b/camera/QCamera/HAL/core/src/QCameraHWI_Still.cpp
new file mode 100755
index 0000000..f569741
--- /dev/null
+++ b/camera/QCamera/HAL/core/src/QCameraHWI_Still.cpp
@@ -0,0 +1,2507 @@
+/*
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+#define LOG_NDEBUG 0
+#define LOG_NDDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG "QCameraHWI_Still"
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <media/mediarecorder.h>
+#include <math.h>
+#include "QCameraHAL.h"
+#include "QCameraHWI.h"
+
+#define THUMBNAIL_DEFAULT_WIDTH 512
+#define THUMBNAIL_DEFAULT_HEIGHT 384
+
+/* following code implement the still image capture & encoding logic of this class*/
+namespace android {
+
+typedef enum {
+    SNAPSHOT_STATE_ERROR,
+    SNAPSHOT_STATE_UNINIT,
+    SNAPSHOT_STATE_CH_ACQUIRED,
+    SNAPSHOT_STATE_BUF_NOTIF_REGD,
+    SNAPSHOT_STATE_BUF_INITIALIZED,
+    SNAPSHOT_STATE_INITIALIZED,
+    SNAPSHOT_STATE_IMAGE_CAPTURE_STRTD,
+    SNAPSHOT_STATE_YUV_RECVD,
+    SNAPSHOT_STATE_JPEG_ENCODING,
+    SNAPSHOT_STATE_JPEG_ENCODE_DONE,
+    SNAPSHOT_STATE_JPEG_COMPLETE_ENCODE_DONE,
+
+    /*Add any new state above*/
+    SNAPSHOT_STATE_MAX
+} snapshot_state_type_t;
+
+
+//-----------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------
+static const int PICTURE_FORMAT_JPEG = 1;
+static const int PICTURE_FORMAT_RAW = 2;
+static const int POSTVIEW_SMALL_HEIGHT = 144;
+
+// ---------------------------------------------------------------------------
+/* static functions*/
+// ---------------------------------------------------------------------------
+
+
+
+/* TBD: Temp: to be removed*/
+static pthread_mutex_t g_s_mutex;
+static int g_status = 0;
+static pthread_cond_t g_s_cond_v;
+
+static void mm_app_snapshot_done()
+{
+  pthread_mutex_lock(&g_s_mutex);
+  g_status = TRUE;
+  pthread_cond_signal(&g_s_cond_v);
+  pthread_mutex_unlock(&g_s_mutex);
+}
+
+static void mm_app_snapshot_wait()
+{
+        pthread_mutex_lock(&g_s_mutex);
+        if(FALSE == g_status) pthread_cond_wait(&g_s_cond_v, &g_s_mutex);
+        pthread_mutex_unlock(&g_s_mutex);
+    g_status = FALSE;
+}
+
+static int mm_app_dump_snapshot_frame(char *filename,
+                                      const void *buffer,
+                                      uint32_t len)
+{
+    char bufp[128];
+    int file_fdp;
+    int rc = 0;
+
+    file_fdp = open(filename, O_RDWR | O_CREAT, 0777);
+
+    if (file_fdp < 0) {
+        rc = -1;
+        goto end;
+    }
+    write(file_fdp,
+        (const void *)buffer, len);
+    close(file_fdp);
+end:
+    return rc;
+}
+
+/* Callback received when a frame is available after snapshot*/
+static void snapshot_notify_cb(mm_camera_ch_data_buf_t *recvd_frame,
+                               void *user_data)
+{
+    QCameraStream_Snapshot *pme = (QCameraStream_Snapshot *)user_data;
+
+    LOGD("%s: E", __func__);
+
+    if (pme != NULL) {
+        pme->receiveRawPicture(recvd_frame);
+    }
+    else{
+        LOGW("%s: Snapshot obj NULL in callback", __func__);
+    }
+
+    LOGD("%s: X", __func__);
+
+}
+
+/* Once we give frame for encoding, we get encoded jpeg image
+   fragments by fragment. We'll need to store them in a buffer
+   to form complete JPEG image */
+static void snapshot_jpeg_fragment_cb(uint8_t *ptr,
+                                      uint32_t size,
+                                      void *user_data)
+{
+    QCameraStream_Snapshot *pme = (QCameraStream_Snapshot *)user_data;
+
+    LOGE("%s: E",__func__);
+    if (pme != NULL) {
+        pme->receiveJpegFragment(ptr,size);
+    }
+    else
+        LOGW("%s: Receive jpeg fragment cb obj Null", __func__);
+
+    LOGD("%s: X",__func__);
+}
+
+/* This callback is received once the complete JPEG encoding is done */
+static void snapshot_jpeg_cb(jpeg_event_t event, void *user_data)
+{
+    QCameraStream_Snapshot *pme = (QCameraStream_Snapshot *)user_data;
+    LOGE("%s: E ",__func__);
+
+    if (event != JPEG_EVENT_DONE) {
+        if (event == JPEG_EVENT_THUMBNAIL_DROPPED) {
+            LOGE("%s: Error in thumbnail encoding (event: %d)!!!",
+                 __func__, event);
+            LOGD("%s: X",__func__);
+            return;
+        }
+        else {
+            LOGE("%s: Error (event: %d) while jpeg encoding!!!",
+                 __func__, event);
+        }
+    }
+
+    if (pme != NULL) {
+       pme->receiveCompleteJpegPicture(event);
+       LOGE(" Completed issuing JPEG callback");
+       /* deinit only if we are done taking requested number of snapshots */
+       if (pme->getSnapshotState() == SNAPSHOT_STATE_JPEG_COMPLETE_ENCODE_DONE) {
+           LOGE(" About to issue deinit callback");
+       /* If it's ZSL Mode, we don't deinit now. We'll stop the polling thread and
+          deinit the channel/buffers only when we change the mode from zsl to
+          non-zsl. */
+           if (!(pme->isZSLMode())) {
+               pme->stop();
+           }
+        }
+    }
+    else
+        LOGW("%s: Receive jpeg cb Obj Null", __func__);
+
+
+    LOGD("%s: X",__func__);
+
+}
+
+// ---------------------------------------------------------------------------
+/* private functions*/
+// ---------------------------------------------------------------------------
+
+void QCameraStream_Snapshot::
+receiveJpegFragment(uint8_t *ptr, uint32_t size)
+{
+    LOGE("%s: E", __func__);
+#if 0
+    if (mJpegHeap != NULL) {
+        LOGE("%s: Copy jpeg...", __func__);
+        memcpy((uint8_t *)mJpegHeap->mHeap->base()+ mJpegOffset, ptr, size);
+        mJpegOffset += size;
+    }
+    else {
+        LOGE("%s: mJpegHeap is NULL!", __func__);
+    }
+    #else
+    if(mHalCamCtrl->mJpegMemory.camera_memory[0] != NULL && ptr != NULL && size > 0) {
+        memcpy((uint8_t *)((uint32_t)mHalCamCtrl->mJpegMemory.camera_memory[0]->data + mJpegOffset), ptr, size);
+        mJpegOffset += size;
+
+
+        /*
+                memcpy((uint8_t *)((uint32_t)mHalCamCtrl->mJpegMemory.camera_memory[0]->data + mJpegOffset), ptr, size);
+                mJpegOffset += size;
+        */
+    } else {
+        LOGE("%s: mJpegHeap is NULL!", __func__);
+    }
+
+
+    #endif
+
+    LOGD("%s: X", __func__);
+}
+
+
+void QCameraStream_Snapshot::
+receiveCompleteJpegPicture(jpeg_event_t event)
+{
+    int msg_type = CAMERA_MSG_COMPRESSED_IMAGE;
+    LOGE("%s: E", __func__);
+    camera_memory_t *encodedMem = NULL;
+    camera_data_callback jpg_data_cb = NULL;
+    bool fail_cb_flag = false;
+
+    //Mutex::Autolock l(&snapshotLock);
+    mStopCallbackLock.lock( );
+    if(!mActive && !isLiveSnapshot()) {
+        LOGE("%s : Cancel Picture",__func__);
+        fail_cb_flag = true;
+        goto end;
+    }
+
+    if(mCurrentFrameEncoded!=NULL /*&& !isLiveSnapshot()*/){
+        LOGV("<DEBUG>: Calling buf done for snapshot buffer");
+        cam_evt_buf_done(mCameraId, mCurrentFrameEncoded);
+    }
+    mHalCamCtrl->dumpFrameToFile(mHalCamCtrl->mJpegMemory.camera_memory[0]->data, mJpegOffset, (char *)"debug", (char *)"jpg", 0);
+
+end:
+    msg_type = CAMERA_MSG_COMPRESSED_IMAGE;
+    if (mHalCamCtrl->mDataCb && (mHalCamCtrl->mMsgEnabled & msg_type)) {
+        jpg_data_cb = mHalCamCtrl->mDataCb;
+    }else{
+        LOGE("%s: JPEG callback was cancelled--not delivering image.", __func__);
+    }
+    setSnapshotState(SNAPSHOT_STATE_JPEG_ENCODE_DONE);
+    mNumOfRecievedJPEG++;
+    mHalCamCtrl->deinitExifData();
+
+    /* free the resource we allocated to maintain the structure */
+    //mm_camera_do_munmap(main_fd, (void *)main_buffer_addr, mSnapshotStreamBuf.frame_len);
+    if(mCurrentFrameEncoded) {
+        free(mCurrentFrameEncoded);
+        mCurrentFrameEncoded = NULL;
+    }
+
+    /* Before leaving check the jpeg queue. If it's not empty give the available
+       frame for encoding*/
+    if (!mSnapshotQueue.isEmpty()) {
+        LOGI("%s: JPEG Queue not empty. Dequeue and encode.", __func__);
+        mm_camera_ch_data_buf_t* buf =
+            (mm_camera_ch_data_buf_t *)mSnapshotQueue.dequeue();
+        //encodeDisplayAndSave(buf, 1);
+        if ( NO_ERROR != encodeDisplayAndSave(buf, 1)){
+          fail_cb_flag = true;
+        }
+    }  else if (mNumOfSnapshot == mNumOfRecievedJPEG )  { /* finished */
+      LOGD("%s: Before omxJpegFinish", __func__);
+      omxJpegFinish();
+      LOGD("%s: After omxJpegFinish", __func__);
+        /* getRemainingSnapshots call will give us number of snapshots still
+           remaining after flushing current zsl buffer once*/
+      LOGD("%s: Complete JPEG Encoding Done!", __func__);
+      setSnapshotState(SNAPSHOT_STATE_JPEG_COMPLETE_ENCODE_DONE);
+      mBurstModeFlag = false;
+      mSnapshotQueue.flush();
+      mNumOfRecievedJPEG = 0;
+      /* in case of zsl, we need to reset some of the zsl attributes */
+      if (isZSLMode()){
+          LOGD("%s: Resetting the ZSL attributes", __func__);
+          setZSLChannelAttribute();
+      }
+      if (!isZSLMode() && !isLiveSnapshot()){
+         //Stop polling before calling datacb for if not ZSL mode
+         stopPolling();
+      }
+
+    } else {
+        LOGD("%s: mNumOfRecievedJPEG(%d), mNumOfSnapshot(%d)", __func__, mNumOfRecievedJPEG, mNumOfSnapshot);
+    }
+    if(fail_cb_flag && mHalCamCtrl->mDataCb &&
+        (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
+        /* get picture failed. Give jpeg callback with NULL data
+         * to the application to restore to preview mode
+         */
+        jpg_data_cb  = mHalCamCtrl->mDataCb;
+    }
+    if(!fail_cb_flag) {
+        camera_memory_t *encodedMem = mHalCamCtrl->mGetMemory(
+            mHalCamCtrl->mJpegMemory.fd[0], mJpegOffset, 1, mHalCamCtrl);
+        if (!encodedMem || !encodedMem->data) {
+            LOGE("%s: mGetMemory failed.\n", __func__);
+        }
+        memcpy(encodedMem->data, mHalCamCtrl->mJpegMemory.camera_memory[0]->data, mJpegOffset );
+        mStopCallbackLock.unlock( );
+        if ((mActive || isLiveSnapshot()) && jpg_data_cb != NULL) {
+            LOGV("%s: Calling upperlayer callback to store JPEG image", __func__);
+            jpg_data_cb (msg_type,encodedMem, 0, NULL,mHalCamCtrl->mCallbackCookie);
+        }
+        encodedMem->release( encodedMem );
+        jpg_data_cb = NULL;
+    }else{
+        LOGV("Image Encoding Failed... Notify Upper layer");
+        mStopCallbackLock.unlock( );
+        if((mActive || isLiveSnapshot()) && jpg_data_cb != NULL) {
+            jpg_data_cb (CAMERA_MSG_COMPRESSED_IMAGE,NULL, 0, NULL,
+                         mHalCamCtrl->mCallbackCookie);
+        }
+    }
+    //reset jpeg_offset
+    mJpegOffset = 0;
+    LOGD("%s: X", __func__);
+}
+
+status_t QCameraStream_Snapshot::
+configSnapshotDimension(cam_ctrl_dimension_t* dim)
+{
+    bool matching = true;
+    cam_format_t img_format;
+    status_t ret = NO_ERROR;
+    LOGD("%s: E", __func__);
+
+    LOGI("%s:Passed picture size: %d X %d", __func__,
+         dim->picture_width, dim->picture_height);
+    LOGI("%s:Passed postview size: %d X %d", __func__,
+         dim->ui_thumbnail_width, dim->ui_thumbnail_height);
+
+    /* First check if the picture resolution is the same, if not, change it*/
+    mHalCamCtrl->getPictureSize(&mPictureWidth, &mPictureHeight);
+    LOGD("%s: Picture size received: %d x %d", __func__,
+         mPictureWidth, mPictureHeight);
+    /*Current VFE software design requires picture size >= display size for ZSL*/
+    if (isZSLMode()){
+      mPostviewWidth = dim->display_width;
+      mPostviewHeight = dim->display_height;
+    } else {
+      mPostviewWidth = mHalCamCtrl->mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
+      mPostviewHeight =  mHalCamCtrl->mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
+    }
+    /*If application requested thumbnail size to be (0,0) 
+       then configure second outout to a default size.
+       Jpeg encoder will drop thumbnail as reflected in encodeParams.
+    */
+    mDropThumbnail = false;
+    if (mPostviewWidth == 0 && mPostviewHeight == 0) {
+         mPostviewWidth = THUMBNAIL_DEFAULT_WIDTH;
+         mPostviewHeight = THUMBNAIL_DEFAULT_HEIGHT;
+         mDropThumbnail = true;
+    }
+
+    LOGD("%s: Postview size received: %d x %d", __func__,
+         mPostviewWidth, mPostviewHeight);
+
+    matching = (mPictureWidth == dim->picture_width) &&
+        (mPictureHeight == dim->picture_height);
+    matching &= (dim->ui_thumbnail_width == mPostviewWidth) &&
+        (dim->ui_thumbnail_height == mPostviewHeight);
+
+    /* picture size currently set do not match with the one wanted
+       by user.*/
+    if (!matching) {
+        if (mPictureWidth < mPostviewWidth || mPictureHeight < mPostviewHeight) {
+            //Changes to Handle VFE limitation.
+            mActualPictureWidth = mPictureWidth;
+            mActualPictureHeight = mPictureHeight;
+            mPictureWidth = mPostviewWidth;
+            mPictureHeight = mPostviewHeight;
+            mJpegDownscaling = TRUE;
+        }else{
+            mJpegDownscaling = FALSE;
+        }
+        dim->picture_width  = mPictureWidth;
+        dim->picture_height = mPictureHeight;
+        dim->ui_thumbnail_height = mThumbnailHeight = mPostviewHeight;
+        dim->ui_thumbnail_width = mThumbnailWidth = mPostviewWidth;
+    }
+    #if 0
+    img_format = mHalCamCtrl->getPreviewFormat();
+    if (img_format) {
+        matching &= (img_format == dim->main_img_format);
+        if (!matching) {
+            dim->main_img_format = img_format;
+            dim->thumb_format = img_format;
+        }
+    }
+    #endif
+    if (!matching) {
+         LOGD("%s: Image Sizes before set parm call: main: %dx%d thumbnail: %dx%d",
+              __func__,
+              dim->picture_width, dim->picture_height,
+              dim->ui_thumbnail_width, dim->ui_thumbnail_height);
+
+        ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,dim);
+        if (NO_ERROR != ret) {
+            LOGE("%s: error - can't config snapshot parms!", __func__);
+            ret = FAILED_TRANSACTION;
+            goto end;
+        }
+    }
+    /* set_parm will return corrected dimension based on aspect ratio and
+       ceiling size */
+    mPictureWidth = dim->picture_width;
+    mPictureHeight = dim->picture_height;
+    mPostviewHeight = mThumbnailHeight = dim->ui_thumbnail_height;
+    mPostviewWidth = mThumbnailWidth = dim->ui_thumbnail_width;
+    mPictureFormat= dim->main_img_format;
+    mThumbnailFormat = dim->thumb_format;
+
+    LOGD("%s: Image Format: %d", __func__, dim->main_img_format);
+    LOGI("%s: Image Sizes: main: %dx%d thumbnail: %dx%d", __func__,
+         dim->picture_width, dim->picture_height,
+         dim->ui_thumbnail_width, dim->ui_thumbnail_height);
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::
+initRawSnapshotChannel(cam_ctrl_dimension_t *dim,
+                       int num_of_snapshots)
+{
+    status_t ret = NO_ERROR;
+    mm_camera_ch_image_fmt_parm_t fmt;
+    mm_camera_channel_attr_t ch_attr;
+
+    mm_camera_raw_streaming_type_t raw_stream_type =
+        MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE;
+
+    LOGD("%s: E", __func__);
+
+    /* Initialize stream - set format, acquire channel */
+    /*TBD: Currently we only support single raw capture*/
+    LOGE("num_of_snapshots = %d",num_of_snapshots);
+    if (num_of_snapshots == 1) {
+        raw_stream_type = MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE;
+    }
+
+    /* Set channel attribute */
+    LOGD("%s: Set Raw Snapshot Channel attribute", __func__);
+    memset(&ch_attr, 0, sizeof(ch_attr));
+    ch_attr.type = MM_CAMERA_CH_ATTR_RAW_STREAMING_TYPE;
+    ch_attr.raw_streaming_mode = raw_stream_type;
+
+    if( NO_ERROR !=
+        cam_ops_ch_set_attr(mCameraId, MM_CAMERA_CH_RAW, &ch_attr)) {
+        LOGD("%s: Failure setting Raw channel attribute.", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+    memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
+    fmt.ch_type = MM_CAMERA_CH_RAW;
+    fmt.def.fmt = CAMERA_BAYER_SBGGR10;
+    fmt.def.dim.width = dim->raw_picture_width;
+    fmt.def.dim.height = dim->raw_picture_height;
+
+
+    LOGV("%s: Raw snapshot channel fmt: %d", __func__,
+         fmt.def.fmt);
+    LOGV("%s: Raw snapshot resolution: %dX%d", __func__,
+         dim->raw_picture_width, dim->raw_picture_height);
+
+    LOGD("%s: Set Raw Snapshot channel image format", __func__);
+    ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
+    if (NO_ERROR != ret) {
+        LOGE("%s: Set Raw Snapshot Channel format err=%d\n", __func__, ret);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+end:
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+    LOGE("%s: X", __func__);
+    return ret;
+
+}
+
+status_t QCameraStream_Snapshot::
+setZSLChannelAttribute(void)
+{
+    status_t ret = NO_ERROR;
+    mm_camera_channel_attr_t ch_attr;
+    LOGD("%s: E", __func__);
+
+    memset(&ch_attr, 0, sizeof(mm_camera_channel_attr_t));
+    ch_attr.type = MM_CAMERA_CH_ATTR_BUFFERING_FRAME;
+    ch_attr.buffering_frame.look_back = mHalCamCtrl->getZSLBackLookCount();
+    ch_attr.buffering_frame.water_mark = mHalCamCtrl->getZSLQueueDepth();
+    ch_attr.buffering_frame.interval = mHalCamCtrl->getZSLBurstInterval( );
+    LOGE("%s: ZSL queue_depth = %d, back_look_count = %d", __func__,
+         ch_attr.buffering_frame.water_mark,
+         ch_attr.buffering_frame.look_back);
+    if( NO_ERROR !=
+        cam_ops_ch_set_attr(mCameraId, MM_CAMERA_CH_SNAPSHOT, &ch_attr)) {
+        LOGD("%s: Failure setting ZSL channel attribute.", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::
+initSnapshotFormat(cam_ctrl_dimension_t *dim)
+{
+    status_t ret = NO_ERROR;
+    mm_camera_ch_image_fmt_parm_t fmt;
+
+    LOGD("%s: E", __func__);
+
+    /* For ZSL mode we'll need to set channel attribute */
+    if (isZSLMode()) {
+        ret = setZSLChannelAttribute();
+        if (ret != NO_ERROR) {
+            goto end;
+        }
+    }
+
+    memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
+    fmt.ch_type = MM_CAMERA_CH_SNAPSHOT;
+    fmt.snapshot.main.fmt = dim->main_img_format;
+    fmt.snapshot.main.dim.width = dim->picture_width;
+    fmt.snapshot.main.dim.height = dim->picture_height;
+
+    fmt.snapshot.thumbnail.fmt = dim->thumb_format;
+    fmt.snapshot.thumbnail.dim.width = dim->ui_thumbnail_width;
+    fmt.snapshot.thumbnail.dim.height = dim->ui_thumbnail_height;
+
+    LOGV("%s: Snapshot channel fmt = main: %d thumbnail: %d", __func__,
+         dim->main_img_format, dim->thumb_format);
+    LOGV("%s: Snapshot channel resolution = main: %dX%d  thumbnail: %dX%d",
+         __func__, dim->picture_width, dim->picture_height,
+         dim->ui_thumbnail_width, dim->ui_thumbnail_height);
+
+    LOGD("%s: Set Snapshot channel image format", __func__);
+    ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
+    if (NO_ERROR != ret) {
+        LOGE("%s: Set Snapshot Channel format err=%d\n", __func__, ret);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+end:
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+    LOGE("%s: X", __func__);
+    return ret;
+
+}
+
+void QCameraStream_Snapshot::
+deinitSnapshotChannel(mm_camera_channel_type_t ch_type)
+{
+    LOGD("%s: E", __func__);
+
+    /* unreg buf notify*/
+    if (getSnapshotState() >= SNAPSHOT_STATE_BUF_NOTIF_REGD){
+        if (NO_ERROR != cam_evt_register_buf_notify(mCameraId,
+                        ch_type, NULL,(mm_camera_register_buf_cb_type_t)NULL,NULL, this)) {
+            LOGE("%s: Failure to unregister buf notification", __func__);
+        }
+    }
+
+    if (getSnapshotState() >= SNAPSHOT_STATE_CH_ACQUIRED) {
+        LOGD("%s: Release snapshot channel", __func__);
+        cam_ops_ch_release(mCameraId, ch_type);
+    }
+
+    LOGD("%s: X",__func__);
+}
+
+status_t QCameraStream_Snapshot::
+initRawSnapshotBuffers(cam_ctrl_dimension_t *dim, int num_of_buf)
+{
+    status_t ret = NO_ERROR;
+    struct msm_frame *frame;
+    uint32_t frame_len;
+    uint8_t num_planes;
+    uint32_t planes[VIDEO_MAX_PLANES];
+    mm_camera_reg_buf_t reg_buf;
+
+    LOGD("%s: E", __func__);
+    memset(&reg_buf,  0,  sizeof(mm_camera_reg_buf_t));
+    memset(&mSnapshotStreamBuf, 0, sizeof(mSnapshotStreamBuf));
+
+    if ((num_of_buf == 0) || (num_of_buf > MM_CAMERA_MAX_NUM_FRAMES)) {
+        LOGE("%s: Invalid number of buffers (=%d) requested!", __func__, num_of_buf);
+        ret = BAD_VALUE;
+        goto end;
+    }
+
+    reg_buf.def.buf.mp = new mm_camera_mp_buf_t[num_of_buf];
+    if (!reg_buf.def.buf.mp) {
+      LOGE("%s Error allocating memory for mplanar struct ", __func__);
+      ret = NO_MEMORY;
+      goto end;
+    }
+    memset(reg_buf.def.buf.mp, 0, num_of_buf * sizeof(mm_camera_mp_buf_t));
+
+    /* Get a frame len for buffer to be allocated*/
+    frame_len = mm_camera_get_msm_frame_len(CAMERA_BAYER_SBGGR10,
+                                            myMode,
+                                            dim->raw_picture_width,
+                                            dim->raw_picture_height,
+                                            OUTPUT_TYPE_S,
+                                            &num_planes, planes);
+
+    if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mRawMemory, num_of_buf,
+                                        frame_len, 0, planes[0], MSM_PMEM_RAW_MAINIMG,
+                                        &mSnapshotStreamBuf, &reg_buf.def,
+                                        num_planes, planes) < 0) {
+        ret = NO_MEMORY;
+        goto end;
+    }
+
+    /* register the streaming buffers for the channel*/
+    reg_buf.ch_type = MM_CAMERA_CH_RAW;
+    reg_buf.def.num = mSnapshotStreamBuf.num;
+
+    ret = cam_config_prepare_buf(mCameraId, &reg_buf);
+    if(ret != NO_ERROR) {
+        LOGV("%s:reg snapshot buf err=%d\n", __func__, ret);
+        ret = FAILED_TRANSACTION;
+        mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mRawMemory);
+        goto end;
+    }
+
+    /* If we have reached here successfully, we have allocated buffer.
+       Set state machine.*/
+    setSnapshotState(SNAPSHOT_STATE_BUF_INITIALIZED);
+
+end:
+    /* If it's error, we'll need to do some needful */
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+    if (reg_buf.def.buf.mp)
+      delete []reg_buf.def.buf.mp;
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::deinitRawSnapshotBuffers(void)
+{
+    int ret = NO_ERROR;
+
+    LOGD("%s: E", __func__);
+
+    /* deinit buffers only if we have already allocated */
+    if (getSnapshotState() >= SNAPSHOT_STATE_BUF_INITIALIZED ){
+
+        LOGD("%s: Unpreparing Snapshot Buffer", __func__);
+        ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_RAW);
+        if(ret != NO_ERROR) {
+            LOGE("%s:Unreg Raw snapshot buf err=%d\n", __func__, ret);
+            ret = FAILED_TRANSACTION;
+            goto end;
+        }
+        mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mRawMemory);
+    }
+
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::
+initSnapshotBuffers(cam_ctrl_dimension_t *dim, int num_of_buf)
+{
+    status_t ret = NO_ERROR;
+    struct msm_frame *frame;
+    uint32_t frame_len, y_off, cbcr_off;
+    uint8_t num_planes;
+    uint32_t planes[VIDEO_MAX_PLANES];
+    mm_camera_reg_buf_t reg_buf;
+    int rotation = 0;
+
+    LOGD("%s: E", __func__);
+    memset(&reg_buf,  0,  sizeof(mm_camera_reg_buf_t));
+    memset(&mSnapshotStreamBuf, 0, sizeof(mSnapshotStreamBuf));
+
+    if ((num_of_buf == 0) || (num_of_buf > MM_CAMERA_MAX_NUM_FRAMES)) {
+        LOGE("%s: Invalid number of buffers (=%d) requested!",
+             __func__, num_of_buf);
+        ret = BAD_VALUE;
+        goto end;
+    }
+
+    LOGD("%s: Mode: %d Num_of_buf: %d ImageSizes: main: %dx%d thumb: %dx%d",
+         __func__, myMode, num_of_buf,
+         dim->picture_width, dim->picture_height,
+         dim->ui_thumbnail_width, dim->ui_thumbnail_height);
+
+    reg_buf.snapshot.main.buf.mp = new mm_camera_mp_buf_t[num_of_buf];
+    if (!reg_buf.snapshot.main.buf.mp) {
+          LOGE("%s Error allocating memory for mplanar struct ", __func__);
+          ret = NO_MEMORY;
+          goto end;
+    }
+    memset(reg_buf.snapshot.main.buf.mp, 0,
+      num_of_buf * sizeof(mm_camera_mp_buf_t));
+    if (!isFullSizeLiveshot()) {
+      reg_buf.snapshot.thumbnail.buf.mp = new mm_camera_mp_buf_t[num_of_buf];
+      if (!reg_buf.snapshot.thumbnail.buf.mp) {
+        LOGE("%s Error allocating memory for mplanar struct ", __func__);
+        ret = NO_MEMORY;
+        goto end;
+      }
+      memset(reg_buf.snapshot.thumbnail.buf.mp, 0,
+        num_of_buf * sizeof(mm_camera_mp_buf_t));
+    }
+    /* Number of buffers to be set*/
+    /* Set the JPEG Rotation here since get_buffer_offset needs
+     * the value of rotation.*/
+    mHalCamCtrl->setJpegRotation(isZSLMode());
+    if(!isZSLMode())
+        rotation = mHalCamCtrl->getJpegRotation();
+    else
+        rotation = 0;
+    if(rotation != dim->rotation) {
+        dim->rotation = rotation;
+        ret = cam_config_set_parm(mHalCamCtrl->mCameraId, MM_CAMERA_PARM_DIMENSION, dim);
+    }
+
+    if(isLiveSnapshot()) {
+        ret = cam_config_set_parm(mHalCamCtrl->mCameraId, MM_CAMERA_PARM_DIMENSION, dim);
+    }
+    num_planes = 2;
+    planes[0] = dim->picture_frame_offset.mp[0].len;
+    planes[1] = dim->picture_frame_offset.mp[1].len;
+    frame_len = dim->picture_frame_offset.frame_len;
+    y_off = dim->picture_frame_offset.mp[0].offset;
+    cbcr_off = dim->picture_frame_offset.mp[1].offset;
+    LOGE("%s: main image: rotation = %d, yoff = %d, cbcroff = %d, size = %d, width = %d, height = %d",
+         __func__, dim->rotation, y_off, cbcr_off, frame_len, dim->picture_width, dim->picture_height);
+    if (mHalCamCtrl->initHeapMem (&mHalCamCtrl->mJpegMemory, 1, frame_len, 0, cbcr_off,
+                                  MSM_PMEM_MAX, NULL, NULL, num_planes, planes) < 0) {
+		LOGE("%s: Error allocating JPEG memory", __func__);
+		ret = NO_MEMORY;
+		goto end;
+    }
+    if(!isLiveSnapshot()) {
+        if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mSnapshotMemory, num_of_buf,
+    	   frame_len, y_off, cbcr_off, MSM_PMEM_MAINIMG, &mSnapshotStreamBuf,
+                                     &reg_buf.snapshot.main, num_planes, planes) < 0) {
+    				ret = NO_MEMORY;
+                    mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mJpegMemory);
+    				goto end;
+    	};
+        num_planes = 2;
+        planes[0] = dim->thumb_frame_offset.mp[0].len;
+        planes[1] = dim->thumb_frame_offset.mp[1].len;
+        frame_len = planes[0] + planes[1];
+        if (!isFullSizeLiveshot()) {
+    	    y_off = dim->thumb_frame_offset.mp[0].offset;
+                cbcr_off = dim->thumb_frame_offset.mp[1].offset;
+    	    LOGE("%s: thumbnail: rotation = %d, yoff = %d, cbcroff = %d, size = %d, width = %d, height = %d",
+    		__func__, dim->rotation, y_off, cbcr_off, frame_len,
+    		dim->thumbnail_width, dim->thumbnail_height);
+
+    	    if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mThumbnailMemory, num_of_buf,
+    		    frame_len, y_off, cbcr_off, MSM_PMEM_THUMBNAIL, &mPostviewStreamBuf,
+    		    &reg_buf.snapshot.thumbnail, num_planes, planes) < 0) {
+    	        ret = NO_MEMORY;
+                    mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mSnapshotMemory);
+                    mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mJpegMemory);
+    	        goto end;
+    	    }
+        } 
+        /* register the streaming buffers for the channel*/
+        reg_buf.ch_type = MM_CAMERA_CH_SNAPSHOT;
+        reg_buf.snapshot.main.num = mSnapshotStreamBuf.num;
+
+        if (!isFullSizeLiveshot())
+            reg_buf.snapshot.thumbnail.num = mPostviewStreamBuf.num;
+        else
+            reg_buf.snapshot.thumbnail.num = 0;
+    
+        ret = cam_config_prepare_buf(mCameraId, &reg_buf);
+        if(ret != NO_ERROR) {
+            LOGV("%s:reg snapshot buf err=%d\n", __func__, ret);
+            ret = FAILED_TRANSACTION;
+            if (!isFullSizeLiveshot()){
+                mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mThumbnailMemory);
+            }
+            mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mSnapshotMemory);
+            mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mJpegMemory);
+            goto end;
+        }
+    }
+
+    /* If we have reached here successfully, we have allocated buffer.
+       Set state machine.*/
+    setSnapshotState(SNAPSHOT_STATE_BUF_INITIALIZED);
+end:
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+    if (reg_buf.snapshot.main.buf.mp)
+      delete []reg_buf.snapshot.main.buf.mp;
+    if (reg_buf.snapshot.thumbnail.buf.mp)
+      delete []reg_buf.snapshot.thumbnail.buf.mp;
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::
+deinitSnapshotBuffers(void)
+{
+    int ret = NO_ERROR;
+
+    LOGD("%s: E", __func__);
+
+    /* Deinit only if we have already initialized*/
+    if (getSnapshotState() >= SNAPSHOT_STATE_BUF_INITIALIZED ){
+
+        if(!isLiveSnapshot()) {
+            LOGD("%s: Unpreparing Snapshot Buffer", __func__);
+            ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_SNAPSHOT);
+            if(ret != NO_ERROR) {
+                LOGE("%s:unreg snapshot buf err=%d\n", __func__, ret);
+                ret = FAILED_TRANSACTION;
+                goto end;
+            }
+        }
+
+        /* Clear main and thumbnail heap*/
+        if(!isLiveSnapshot()) {
+            mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mSnapshotMemory);
+            if (!isFullSizeLiveshot())
+              mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mThumbnailMemory);
+        }
+        mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mJpegMemory);
+    }
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+void QCameraStream_Snapshot::deInitBuffer(void)
+{
+    mm_camera_channel_type_t ch_type;
+
+    LOGI("%s: E", __func__);
+
+    if( getSnapshotState() == SNAPSHOT_STATE_UNINIT) {
+        LOGD("%s: Already deinit'd!", __func__);
+        return;
+    }
+
+    if (mSnapshotFormat == PICTURE_FORMAT_RAW) {
+      /* deinit buffer */
+      deinitRawSnapshotBuffers();
+    }
+    else
+    {
+      if (!isZSLMode() &&
+      ((mHalCamCtrl->getHDRMode() == HDR_MODE) || (mHalCamCtrl->isWDenoiseEnabled()))) {
+        /*register main and thumbnail buffers at back-end for frameproc*/
+        for (int i = 0; i < mHalCamCtrl->mSnapshotMemory.buffer_count; i++) {
+          if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_MAIN, i, mCameraId,
+                                                        CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
+            LOGE("%s: sending unmapping data Msg Failed", __func__);
+          }
+          if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, i, mCameraId,
+                                                        CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
+            LOGE("%s: sending unmapping data Msg Failed", __func__);
+          }
+        }
+      }
+
+      deinitSnapshotBuffers();
+    }
+
+
+    /* deinit jpeg buffer if allocated */
+    if(mJpegHeap != NULL) mJpegHeap.clear();
+    mJpegHeap = NULL;
+
+    /* memset some global structure */
+    memset(&mSnapshotStreamBuf, 0, sizeof(mSnapshotStreamBuf));
+    memset(&mPostviewStreamBuf, 0, sizeof(mPostviewStreamBuf));
+    mSnapshotQueue.flush();
+    mWDNQueue.flush();
+
+    setSnapshotState(SNAPSHOT_STATE_UNINIT);
+
+    LOGD("%s: X", __func__);
+}
+
+/*Temp: to be removed once event handling is enabled in mm-camera.
+  We need an event - one event for
+  stream-off to disable OPS_SNAPSHOT*/
+void QCameraStream_Snapshot::runSnapshotThread(void *data)
+{
+    LOGD("%s: E", __func__);
+
+    if (mSnapshotFormat == PICTURE_FORMAT_RAW) {
+       /* TBD: Temp: Needs to be removed once event handling is enabled.
+          We cannot call mm-camera interface to stop snapshot from callback
+          function as it causes deadlock. Hence handling it here temporarily
+          in this thread. Later mm-camera intf will give us event in separate
+          thread context */
+        mm_app_snapshot_wait();
+        /* Send command to stop snapshot polling thread*/
+        stop();
+    }
+    LOGD("%s: X", __func__);
+}
+
+/*Temp: to be removed once event handling is enabled in mm-camera*/
+static void *snapshot_thread(void *obj)
+{
+    QCameraStream_Snapshot *pme = (QCameraStream_Snapshot *)obj;
+    LOGD("%s: E", __func__);
+    if (pme != 0) {
+        pme->runSnapshotThread(obj);
+    }
+    else LOGW("not starting snapshot thread: the object went away!");
+    LOGD("%s: X", __func__);
+    return NULL;
+}
+
+/*Temp: to be removed later*/
+static pthread_t mSnapshotThread;
+
+status_t QCameraStream_Snapshot::initJPEGSnapshot(int num_of_snapshots)
+{
+    status_t ret = NO_ERROR;
+    cam_ctrl_dimension_t dim;
+    mm_camera_op_mode_type_t op_mode;
+
+    LOGV("%s: E", __func__);
+
+    if (isFullSizeLiveshot())
+      goto end;
+
+    LOGD("%s: Get current dimension", __func__);
+    /* Query mm_camera to get current dimension */
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    ret = cam_config_get_parm(mCameraId,
+                              MM_CAMERA_PARM_DIMENSION, &dim);
+    if (NO_ERROR != ret) {
+        LOGE("%s: error - can't get preview dimension!", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+    /* Set camera op mode to MM_CAMERA_OP_MODE_CAPTURE */
+    LOGD("Setting OP_MODE_CAPTURE");
+    op_mode = MM_CAMERA_OP_MODE_CAPTURE;
+    if( NO_ERROR != cam_config_set_parm(mCameraId,
+            MM_CAMERA_PARM_OP_MODE, &op_mode)) {
+        LOGE("%s: MM_CAMERA_OP_MODE_CAPTURE failed", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+    /* config the parmeters and see if we need to re-init the stream*/
+    LOGI("%s: Configure Snapshot Dimension", __func__);
+    ret = configSnapshotDimension(&dim);
+    if (ret != NO_ERROR) {
+        LOGE("%s: Setting snapshot dimension failed", __func__);
+        goto end;
+    }
+
+    /* Initialize stream - set format, acquire channel */
+    ret = initSnapshotFormat(&dim);
+    if (NO_ERROR != ret) {
+        LOGE("%s: error - can't init nonZSL stream!", __func__);
+        goto end;
+    }
+
+    ret = initSnapshotBuffers(&dim, num_of_snapshots);
+    if ( NO_ERROR != ret ){
+        LOGE("%s: Failure allocating memory for Snapshot buffers", __func__);
+        goto end;
+    }
+
+    if (!isZSLMode() &&
+    ((mHalCamCtrl->getHDRMode() == HDR_MODE) || (mHalCamCtrl->isWDenoiseEnabled()))) {
+      /*register main and thumbnail buffers at back-end for frameproc*/
+        for (int i = 0; i < num_of_snapshots; i++) {
+          if (NO_ERROR != mHalCamCtrl->sendMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_MAIN, i,
+          mSnapshotStreamBuf.frame[i].fd, mHalCamCtrl->mSnapshotMemory.size, mCameraId,
+                                                      CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
+            LOGE("%s: sending mapping data Msg Failed", __func__);
+          }
+          if (NO_ERROR != mHalCamCtrl->sendMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, i,
+          mPostviewStreamBuf.frame[i].fd, mHalCamCtrl->mThumbnailMemory.size, mCameraId,
+                                                      CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
+            LOGE("%s: sending mapping data Msg Failed", __func__);
+          }
+        }
+    }
+
+end:
+    /* Based on what state we are in, we'll need to handle error -
+       like deallocating memory if we have already allocated */
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+    LOGV("%s: X", __func__);
+    return ret;
+
+}
+
+status_t QCameraStream_Snapshot::initRawSnapshot(int num_of_snapshots)
+{
+    status_t ret = NO_ERROR;
+    cam_ctrl_dimension_t dim;
+    bool initSnapshot = false;
+    mm_camera_op_mode_type_t op_mode;
+
+    LOGV("%s: E", __func__);
+
+    /* Set camera op mode to MM_CAMERA_OP_MODE_CAPTURE */
+    LOGD("%s: Setting OP_MODE_CAPTURE", __func__);
+    op_mode = MM_CAMERA_OP_MODE_CAPTURE;
+    if( NO_ERROR != cam_config_set_parm(mCameraId,
+            MM_CAMERA_PARM_OP_MODE, &op_mode)) {
+        LOGE("%s: MM_CAMERA_OP_MODE_CAPTURE failed", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+    /* For raw snapshot, we do not know the dimension as it
+       depends on sensor to sensor. We call getDimension which will
+       give us raw width and height */
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+    if (MM_CAMERA_OK != ret) {
+      LOGE("%s: error - can't get dimension!", __func__);
+      LOGE("%s: X", __func__);
+      goto end;
+    }
+    LOGD("%s: Raw Snapshot dimension: %dx%d", __func__,
+         dim.raw_picture_width,
+         dim.raw_picture_height);
+
+
+    ret = initRawSnapshotChannel(&dim, num_of_snapshots);
+    if (NO_ERROR != ret) {
+        LOGE("%s: error - can't init nonZSL stream!", __func__);
+        goto end;
+    }
+
+    ret = initRawSnapshotBuffers(&dim, num_of_snapshots);
+    if ( NO_ERROR != ret ){
+        LOGE("%s: Failure allocating memory for Raw Snapshot buffers",
+             __func__);
+        goto end;
+    }
+    setSnapshotState(SNAPSHOT_STATE_INITIALIZED);
+
+end:
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+    LOGV("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::initFullLiveshot(void)
+{
+    status_t ret = NO_ERROR;
+    cam_ctrl_dimension_t dim;
+    bool matching = true;
+
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+    if (MM_CAMERA_OK != ret) {
+      LOGE("%s: error - can't get dimension!", __func__);
+      return ret;
+    }
+#if 1
+    /* First check if the picture resolution is the same, if not, change it*/
+    mHalCamCtrl->getPictureSize(&mPictureWidth, &mPictureHeight);
+    LOGD("%s: Picture size received: %d x %d", __func__,
+         mPictureWidth, mPictureHeight);
+
+    //Use main image as input to encoder to generate thumbnail
+    mThumbnailWidth = dim.picture_width;
+    mThumbnailHeight = dim.picture_height;
+    matching = (mPictureWidth == dim.picture_width) &&
+        (mPictureHeight == dim.picture_height);
+
+    //Actual thumbnail size requested
+    mPostviewWidth = mHalCamCtrl->mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
+    mPostviewHeight =  mHalCamCtrl->mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
+
+    mDropThumbnail = false;
+    if (mPostviewWidth == 0 && mPostviewHeight == 0) {
+         mPostviewWidth = THUMBNAIL_DEFAULT_WIDTH;
+         mPostviewHeight = THUMBNAIL_DEFAULT_HEIGHT;
+         mDropThumbnail = true;
+    }
+
+    if (!matching) {
+        dim.picture_width  = mPictureWidth;
+        dim.picture_height = mPictureHeight;
+        dim.ui_thumbnail_height = mThumbnailHeight;
+        dim.ui_thumbnail_width = mThumbnailWidth;
+    }
+    LOGD("%s: Picture size to set: %d x %d", __func__,
+         dim.picture_width, dim.picture_height);
+    ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+#endif
+    /* Initialize stream - set format, acquire channel */
+    ret = initSnapshotFormat(&dim);
+    if (NO_ERROR != ret) {
+        LOGE("%s: error - can't init nonZSL stream!", __func__);
+        return ret;
+    }
+    ret = initSnapshotBuffers(&dim, 1);
+    if ( NO_ERROR != ret ){
+        LOGE("%s: Failure allocating memory for Snapshot buffers", __func__);
+        return ret;
+    }
+
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::initZSLSnapshot(void)
+{
+    status_t ret = NO_ERROR;
+    cam_ctrl_dimension_t dim;
+    mm_camera_op_mode_type_t op_mode;
+
+    LOGV("%s: E", __func__);
+
+    LOGD("%s: Get current dimension", __func__);
+    /* Query mm_camera to get current dimension */
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    ret = cam_config_get_parm(mCameraId,
+                              MM_CAMERA_PARM_DIMENSION, &dim);
+    if (NO_ERROR != ret) {
+        LOGE("%s: error - can't get preview dimension!", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+    /* config the parmeters and see if we need to re-init the stream*/
+    LOGD("%s: Configure Snapshot Dimension", __func__);
+    ret = configSnapshotDimension(&dim);
+    if (ret != NO_ERROR) {
+        LOGE("%s: Setting snapshot dimension failed", __func__);
+        goto end;
+    }
+
+    /* Initialize stream - set format, acquire channel */
+    ret = initSnapshotFormat(&dim);
+    if (NO_ERROR != ret) {
+        LOGE("%s: error - can't init nonZSL stream!", __func__);
+        goto end;
+    }
+
+    /* For ZSL we'll have to allocate buffers for internal queue
+       maintained by mm-camera lib plus around 3 buffers used for
+       data handling by lower layer.*/
+
+    ret = initSnapshotBuffers(&dim, mHalCamCtrl->getZSLQueueDepth() + 3);
+    if ( NO_ERROR != ret ){
+        LOGE("%s: Failure allocating memory for Snapshot buffers", __func__);
+        goto end;
+    }
+
+end:
+    /* Based on what state we are in, we'll need to handle error -
+       like deallocating memory if we have already allocated */
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+    LOGV("%s: X", __func__);
+    return ret;
+
+}
+
+status_t QCameraStream_Snapshot::
+takePictureJPEG(void)
+{
+    status_t ret = NO_ERROR;
+
+    LOGD("%s: E", __func__);
+
+    /* Take snapshot */
+    LOGD("%s: Call MM_CAMERA_OPS_SNAPSHOT", __func__);
+    if (NO_ERROR != cam_ops_action(mCameraId,
+                                              TRUE,
+                                              MM_CAMERA_OPS_SNAPSHOT,
+                                              this)) {
+           LOGE("%s: Failure taking snapshot", __func__);
+           ret = FAILED_TRANSACTION;
+           goto end;
+    }
+
+    /* TBD: Temp: to be removed once event callback
+       is implemented in mm-camera lib  */
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_create(&mSnapshotThread,&attr,
+                   snapshot_thread, (void *)this);
+
+end:
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+
+    LOGD("%s: X", __func__);
+    return ret;
+
+}
+
+status_t QCameraStream_Snapshot::
+takePictureRaw(void)
+{
+    status_t ret = NO_ERROR;
+
+    LOGD("%s: E", __func__);
+
+    /* Take snapshot */
+    LOGD("%s: Call MM_CAMERA_OPS_SNAPSHOT", __func__);
+    if (NO_ERROR != cam_ops_action(mCameraId,
+                                  TRUE,
+                                  MM_CAMERA_OPS_RAW,
+                                  this)) {
+           LOGE("%s: Failure taking snapshot", __func__);
+           ret = FAILED_TRANSACTION;
+           goto end;
+    }
+
+    /* TBD: Temp: to be removed once event callback
+       is implemented in mm-camera lib  */
+    /* Wait for snapshot frame callback to return*/
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_create(&mSnapshotThread,&attr,
+                   snapshot_thread, (void *)this);
+
+end:
+    if (ret != NO_ERROR) {
+        handleError();
+    }
+    LOGD("%s: X", __func__);
+    return ret;
+
+}
+
+/* This is called from vide stream object */
+status_t QCameraStream_Snapshot::
+takePictureLiveshot(mm_camera_ch_data_buf_t* recvd_frame,
+                    cam_ctrl_dimension_t *dim,
+                    int frame_len)
+{
+    status_t ret = NO_ERROR;
+    common_crop_t crop_info;
+    //common_crop_t crop;
+    uint32_t aspect_ratio;
+    camera_notify_callback notifyCb;
+    camera_data_callback dataCb;
+
+    LOGI("%s: E", __func__);
+
+    /* set flag to indicate we are doing livesnapshot */
+    resetSnapshotCounters( );
+    setModeLiveSnapshot(true);
+
+    if(!mHalCamCtrl->mShutterSoundPlayed) {
+        notifyShutter(&crop_info, TRUE);
+    }
+    notifyShutter(&crop_info, FALSE);
+    mHalCamCtrl->mShutterSoundPlayed = FALSE;
+
+    // send upperlayer callback for raw image (data or notify, not both)
+    if((mHalCamCtrl->mDataCb) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_RAW_IMAGE)){
+      dataCb = mHalCamCtrl->mDataCb;
+    } else {
+      dataCb = NULL;
+    }
+    if((mHalCamCtrl->mNotifyCb) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_RAW_IMAGE_NOTIFY)){
+      notifyCb = mHalCamCtrl->mNotifyCb;
+    } else {
+      notifyCb = NULL;
+    }
+
+    LOGI("%s:Passed picture size: %d X %d", __func__,
+         dim->picture_width, dim->picture_height);
+    LOGI("%s:Passed thumbnail size: %d X %d", __func__,
+         dim->ui_thumbnail_width, dim->ui_thumbnail_height);
+
+    mPictureWidth = dim->picture_width;
+    mPictureHeight = dim->picture_height;
+    mThumbnailWidth = dim->ui_thumbnail_width;
+    mThumbnailHeight = dim->ui_thumbnail_height;
+    mPictureFormat = dim->main_img_format;
+    mThumbnailFormat = dim->thumb_format;
+
+    memset(&crop_info, 0, sizeof(common_crop_t));
+    crop_info.in1_w = mPictureWidth;
+    crop_info.in1_h = mPictureHeight;
+    /* For low power live snapshot the thumbnail output size is set to default size.
+       In case of live snapshot video buffer = thumbnail buffer. For higher resolutions
+       the thumnail will be dropped if its more than 64KB. To avoid thumbnail drop
+       set thumbnail as configured by application. This will be a size lower than video size*/
+    mDropThumbnail = false;
+    if(mHalCamCtrl->thumbnailWidth == 0 &&  mHalCamCtrl->thumbnailHeight == 0) {
+        LOGE("Live Snapshot thumbnail will be dropped as indicated by application");
+        mDropThumbnail = true;
+   }
+    crop_info.out1_w = mHalCamCtrl->thumbnailWidth;
+    crop_info.out1_h =  mHalCamCtrl->thumbnailHeight;
+    ret = encodeData(recvd_frame, &crop_info, frame_len, 0);
+    if (ret != NO_ERROR) {
+        LOGE("%s: Failure configuring JPEG encoder", __func__);
+
+        /* Failure encoding this frame. Just notify upper layer
+           about it.*/
+        if(mHalCamCtrl->mDataCb &&
+            (mHalCamCtrl->mMsgEnabled & MEDIA_RECORDER_MSG_COMPRESSED_IMAGE)) {
+            /* get picture failed. Give jpeg callback with NULL data
+             * to the application to restore to preview mode
+             */
+        }
+        setModeLiveSnapshot(false);
+        goto end;
+    }
+
+    if (dataCb) {
+      dataCb(CAMERA_MSG_RAW_IMAGE, mHalCamCtrl->mSnapshotMemory.camera_memory[0],
+                           1, NULL, mHalCamCtrl->mCallbackCookie);
+    }
+    if (notifyCb) {
+      notifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mHalCamCtrl->mCallbackCookie);
+    }
+
+end:
+    LOGI("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::
+takePictureZSL(void)
+{
+    status_t ret = NO_ERROR;
+    mm_camera_ops_parm_get_buffered_frame_t param;
+
+    LOGE("%s: E", __func__);
+
+    memset(&param, 0, sizeof(param));
+    param.ch_type = MM_CAMERA_CH_SNAPSHOT;
+
+    /* Take snapshot */
+    LOGE("%s: Call MM_CAMERA_OPS_GET_BUFFERED_FRAME", __func__);
+
+    mNumOfSnapshot = mHalCamCtrl->getNumOfSnapshots();
+    if (NO_ERROR != cam_ops_action(mCameraId,
+                                          TRUE,
+                                          MM_CAMERA_OPS_GET_BUFFERED_FRAME,
+                                          &param)) {
+           LOGE("%s: Failure getting zsl frame(s)", __func__);
+           ret = FAILED_TRANSACTION;
+           goto end;
+    }
+
+    /* TBD: Temp: to be removed once event callback
+       is implemented in mm-camera lib  */
+/*    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_create(&mSnapshotThread,&attr,
+                   snapshot_thread, (void *)this);
+*/
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::
+startStreamZSL(void)
+{
+    status_t ret = NO_ERROR;
+
+    LOGD("%s: E", __func__);
+
+    /* Start ZSL - it'll start queuing the frames */
+    LOGD("%s: Call MM_CAMERA_OPS_ZSL", __func__);
+    if (NO_ERROR != cam_ops_action(mCameraId,
+                                          TRUE,
+                                          MM_CAMERA_OPS_ZSL,
+                                          this)) {
+           LOGE("%s: Failure starting ZSL stream", __func__);
+           ret = FAILED_TRANSACTION;
+           goto end;
+    }
+
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+
+}
+
+status_t  QCameraStream_Snapshot::
+encodeData(mm_camera_ch_data_buf_t* recvd_frame,
+           common_crop_t *crop_info,
+           int frame_len,
+           bool enqueued)
+{
+    status_t ret = NO_ERROR;
+    cam_ctrl_dimension_t dimension;
+    struct msm_frame *postviewframe;
+    struct msm_frame *mainframe;
+    common_crop_t crop;
+    cam_point_t main_crop_offset;
+    cam_point_t thumb_crop_offset;
+    int width, height;
+    uint8_t *thumbnail_buf;
+    uint32_t thumbnail_fd;
+
+    omx_jpeg_encode_params encode_params;
+
+    /* If it's the only frame, we directly pass to encoder.
+       If not, we'll queue it and check during next jpeg .
+       Also, if the queue isn't empty then we need to queue this
+       one too till its turn comes (only if it's not already
+       queued up there)*/
+    LOGD("%s: getSnapshotState()=%d, enqueued =%d, Q empty=%d", __func__, getSnapshotState(), enqueued, mSnapshotQueue.isEmpty());
+    LOGD("%s: mNumOfRecievedJPEG=%d, mNumOfSnapshot =%d", __func__, mNumOfRecievedJPEG, mNumOfSnapshot);
+    if((getSnapshotState() == SNAPSHOT_STATE_JPEG_ENCODING) ||
+       (!mSnapshotQueue.isEmpty() && !enqueued)){ /*busy and new buffer*/
+        /* encoding is going on. Just queue the frame for now.*/
+        LOGD("%s: JPEG encoding in progress."
+             "Enqueuing frame id(%d) for later processing.", __func__,
+             recvd_frame->snapshot.main.idx);
+        mSnapshotQueue.enqueue((void *)recvd_frame);
+    } else if (enqueued ||
+       (mNumOfRecievedJPEG != mNumOfSnapshot  && mNumOfRecievedJPEG != 0)) { /*not busy, not first*/
+      LOGD("%s: JPG not busy, not first frame.", __func__);
+
+      // For full-size live shot, use mainimage to generate thumbnail
+      if (isFullSizeLiveshot()) {
+          postviewframe = recvd_frame->snapshot.main.frame;
+      } else {
+          postviewframe = recvd_frame->snapshot.thumbnail.frame;
+      }
+      mainframe = recvd_frame->snapshot.main.frame;
+      cam_config_get_parm(mHalCamCtrl->mCameraId, MM_CAMERA_PARM_DIMENSION, &dimension);
+      LOGD("%s: main_fmt =%d, tb_fmt =%d", __func__, dimension.main_img_format, dimension.thumb_format);
+      /*since this is the continue job, we only care about the input buffer*/
+      encode_params.thumbnail_buf = (uint8_t *)postviewframe->buffer;
+      encode_params.thumbnail_fd = postviewframe->fd;
+      encode_params.snapshot_buf = (uint8_t *)mainframe->buffer;
+      encode_params.snapshot_fd = mainframe->fd;
+      encode_params.dimension = &dimension;
+      /*update exif parameters in HAL*/
+      mHalCamCtrl->setExifTags();
+
+      encode_params.exif_data = mHalCamCtrl->getExifData();
+      encode_params.exif_numEntries = mHalCamCtrl->getExifTableNumEntries();
+      if (!omxJpegEncodeNext(&encode_params)){
+          LOGE("%s: Failure! JPEG encoder returned error.", __func__);
+          ret = FAILED_TRANSACTION;
+          goto end;
+      }
+      /* Save the pointer to the frame sent for encoding. we'll need it to
+         tell kernel that we are done with the frame.*/
+      mCurrentFrameEncoded = recvd_frame;
+      setSnapshotState(SNAPSHOT_STATE_JPEG_ENCODING);
+    } else {  /*not busy and new buffer (first job)*/
+
+      LOGD("%s: JPG Idle and  first frame.", __func__);
+
+        // For full-size live shot, use mainimage to generate thumbnail
+        if (isFullSizeLiveshot()){
+            postviewframe = recvd_frame->snapshot.main.frame;
+        } else {
+            postviewframe = recvd_frame->snapshot.thumbnail.frame;
+        }
+        mainframe = recvd_frame->snapshot.main.frame;
+        cam_config_get_parm(mHalCamCtrl->mCameraId, MM_CAMERA_PARM_DIMENSION, &dimension);
+        LOGD("%s: main_fmt =%d, tb_fmt =%d", __func__, dimension.main_img_format, dimension.thumb_format);
+
+        dimension.orig_picture_dx = mPictureWidth;
+        dimension.orig_picture_dy = mPictureHeight;
+
+        if(!mDropThumbnail) {
+            if(isZSLMode()) {
+                LOGI("Setting input thumbnail size to previewWidth= %d   previewheight= %d in ZSL mode",
+                     mHalCamCtrl->mPreviewWidth, mHalCamCtrl->mPreviewHeight);
+                dimension.thumbnail_width = width = mHalCamCtrl->mPreviewWidth;
+                dimension.thumbnail_height = height = mHalCamCtrl->mPreviewHeight;
+            } else {
+                dimension.thumbnail_width = width = mThumbnailWidth;
+                dimension.thumbnail_height = height = mThumbnailHeight;
+            }
+        } else {
+            dimension.thumbnail_width = width = 0;
+            dimension.thumbnail_height = height = 0;
+        }
+        dimension.main_img_format = mPictureFormat;
+        dimension.thumb_format = mThumbnailFormat;
+
+        /*TBD: Move JPEG handling to the mm-camera library */
+        LOGD("Setting callbacks, initializing encoder and start encoding.");
+        LOGD(" Passing my obj: %x", (unsigned int) this);
+        set_callbacks(snapshot_jpeg_fragment_cb, snapshot_jpeg_cb, this,
+             mHalCamCtrl->mJpegMemory.camera_memory[0]->data, &mJpegOffset);
+        omxJpegStart();
+	if (mHalCamCtrl->getJpegQuality())
+          mm_jpeg_encoder_setMainImageQuality(mHalCamCtrl->getJpegQuality());
+	else
+	   mm_jpeg_encoder_setMainImageQuality(85);
+
+        LOGE("%s: Dimension to encode: main: %dx%d thumbnail: %dx%d", __func__,
+             dimension.orig_picture_dx, dimension.orig_picture_dy,
+             dimension.thumbnail_width, dimension.thumbnail_height);
+
+        /*TBD: Pass 0 as cropinfo for now as v4l2 doesn't provide
+          cropinfo. It'll be changed later.*/
+        memset(&crop,0,sizeof(common_crop_t));
+        memset(&main_crop_offset,0,sizeof(cam_point_t));
+        memset(&thumb_crop_offset,0,sizeof(cam_point_t));
+
+        /* Setting crop info */
+
+        /*Main image*/
+        crop.in2_w=mCrop.snapshot.main_crop.width;// dimension.picture_width
+        crop.in2_h=mCrop.snapshot.main_crop.height;// dimension.picture_height;
+        if (!mJpegDownscaling) {
+            crop.out2_w = mPictureWidth;
+            crop.out2_h = mPictureHeight;
+        } else {
+            crop.out2_w = mActualPictureWidth;
+            crop.out2_h = mActualPictureHeight;
+            if (!crop.in2_w || !crop.in2_h) {
+                crop.in2_w = mPictureWidth;
+                crop.in2_h = mPictureHeight;
+            }
+        }
+        main_crop_offset.x=mCrop.snapshot.main_crop.left;
+        main_crop_offset.y=mCrop.snapshot.main_crop.top;
+        /*Thumbnail image*/
+        crop.in1_w=mCrop.snapshot.thumbnail_crop.width; //dimension.thumbnail_width;
+        crop.in1_h=mCrop.snapshot.thumbnail_crop.height; // dimension.thumbnail_height;
+        if(isLiveSnapshot() || isFullSizeLiveshot()) {
+            crop.out1_w= mHalCamCtrl->thumbnailWidth;
+            crop.out1_h=  mHalCamCtrl->thumbnailHeight;
+            LOGD("Thumbnail width= %d  height= %d for livesnapshot", crop.out1_w, crop.out1_h);
+        } else {
+            crop.out1_w = width;
+            crop.out1_h = height;
+        }
+        thumb_crop_offset.x=mCrop.snapshot.thumbnail_crop.left;
+        thumb_crop_offset.y=mCrop.snapshot.thumbnail_crop.top;
+
+        //update exif parameters in HAL
+        mHalCamCtrl->initExifData();
+
+        /*Fill in the encode parameters*/
+        encode_params.dimension = (const cam_ctrl_dimension_t *)&dimension;
+        //if (!isFullSizeLiveshot()) {
+            encode_params.thumbnail_buf = (uint8_t *)postviewframe->buffer;
+            encode_params.thumbnail_fd = postviewframe->fd;
+            encode_params.thumbnail_offset = postviewframe->phy_offset;
+            encode_params.thumb_crop_offset = &thumb_crop_offset;
+        //}
+        encode_params.snapshot_buf = (uint8_t *)mainframe->buffer;
+        encode_params.snapshot_fd = mainframe->fd;
+        encode_params.snapshot_offset = mainframe->phy_offset;
+        encode_params.scaling_params = &crop;
+        encode_params.exif_data = mHalCamCtrl->getExifData();
+        encode_params.exif_numEntries = mHalCamCtrl->getExifTableNumEntries();
+
+        if (isLiveSnapshot() && !isFullSizeLiveshot())
+            encode_params.a_cbcroffset = mainframe->cbcr_off;
+        else
+            encode_params.a_cbcroffset = -1;
+        encode_params.main_crop_offset = &main_crop_offset;
+
+	    if (mDropThumbnail)
+            encode_params.hasThumbnail = 0;
+        else
+            encode_params.hasThumbnail = 1;
+        encode_params.thumb_crop_offset = &thumb_crop_offset;
+        encode_params.main_format = dimension.main_img_format;
+        encode_params.thumbnail_format = dimension.thumb_format;
+
+        if (!omxJpegEncode(&encode_params)){
+            LOGE("%s: Failure! JPEG encoder returned error.", __func__);
+            ret = FAILED_TRANSACTION;
+            goto end;
+        }
+
+        /* Save the pointer to the frame sent for encoding. we'll need it to
+           tell kernel that we are done with the frame.*/
+        mCurrentFrameEncoded = recvd_frame;
+        setSnapshotState(SNAPSHOT_STATE_JPEG_ENCODING);
+    }
+
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+/* Called twice - 1st to play shutter sound and 2nd to configure
+   overlay/surfaceflinger for postview */
+void QCameraStream_Snapshot::notifyShutter(common_crop_t *crop,
+                                           bool mPlayShutterSoundOnly)
+{
+    LOGD("%s: E", __func__);
+    if(!mActive && !isLiveSnapshot()) {
+      LOGE("__debbug: Snapshot thread stopped \n");
+      return;
+    }
+    if(mHalCamCtrl->mNotifyCb)
+      mHalCamCtrl->mNotifyCb(CAMERA_MSG_SHUTTER, 0, mPlayShutterSoundOnly,
+                                 mHalCamCtrl->mCallbackCookie);
+    LOGD("%s: X", __func__);
+}
+
+status_t  QCameraStream_Snapshot::
+encodeDisplayAndSave(mm_camera_ch_data_buf_t* recvd_frame,
+                     bool enqueued)
+{
+    status_t ret = NO_ERROR;
+    struct msm_frame *postview_frame;
+    struct ion_flush_data cache_inv_data;
+    int ion_fd;
+    int buf_index = 0;
+    ssize_t offset_addr = 0;
+    common_crop_t dummy_crop;
+    /* send frame for encoding */
+    LOGE("%s: Send frame for encoding", __func__);
+    /*TBD: Pass 0 as cropinfo for now as v4l2 doesn't provide
+      cropinfo. It'll be changed later.*/
+    if(!mActive) {
+        LOGE("Cancel Picture.. Stop is called");
+        return NO_ERROR;
+    }
+    if(isZSLMode()){
+      LOGE("%s: set JPEG rotation in ZSL mode", __func__);
+      mHalCamCtrl->setJpegRotation(isZSLMode());
+    }
+#ifdef USE_ION
+    /*Clean out(Write-back) cache before sending for JPEG*/
+    memset(&cache_inv_data, 0, sizeof(struct ion_flush_data));
+
+    cache_inv_data.vaddr = (void*)recvd_frame->snapshot.main.frame->buffer;
+    cache_inv_data.fd = recvd_frame->snapshot.main.frame->fd;
+    cache_inv_data.handle = recvd_frame->snapshot.main.frame->fd_data.handle;
+    cache_inv_data.length = recvd_frame->snapshot.main.frame->ion_alloc.len;
+    ion_fd = recvd_frame->snapshot.main.frame->ion_dev_fd;
+    if(ion_fd > 0) {
+      if(ioctl(ion_fd, ION_IOC_CLEAN_INV_CACHES, &cache_inv_data) < 0)
+          LOGE("%s: Cache Invalidate failed\n", __func__);
+      else {
+          LOGD("%s: Successful cache invalidate\n", __func__);
+	  if(!isFullSizeLiveshot()) {
+            ion_fd = recvd_frame->snapshot.thumbnail.frame->ion_dev_fd;
+            cache_inv_data.vaddr = (void*)recvd_frame->snapshot.thumbnail.frame->buffer;
+            cache_inv_data.fd = recvd_frame->snapshot.thumbnail.frame->fd;
+            cache_inv_data.handle = recvd_frame->snapshot.thumbnail.frame->fd_data.handle;
+            cache_inv_data.length = recvd_frame->snapshot.thumbnail.frame->ion_alloc.len;
+            if(ioctl(ion_fd, ION_IOC_CLEAN_INV_CACHES, &cache_inv_data) < 0)
+              LOGE("%s: Cache Invalidate failed\n", __func__);
+            else
+              LOGD("%s: Successful cache invalidate\n", __func__);
+          }
+      }
+    }
+#endif
+    memset(&dummy_crop,0,sizeof(common_crop_t));
+    ret = encodeData(recvd_frame, &dummy_crop, mSnapshotStreamBuf.frame_len,
+                     enqueued);
+    if (ret != NO_ERROR) {
+        LOGE("%s: Failure configuring JPEG encoder", __func__);
+
+        goto end;
+    }
+
+    /* Display postview image*/
+    /* If it's burst mode, we won't be displaying postview of all the captured
+       images - only the first one */
+    LOGD("%s: Burst mode flag  %d", __func__, mBurstModeFlag);
+
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recvd_frame)
+{
+    int buf_index = 0;
+    common_crop_t crop;
+    int rc = NO_ERROR;
+
+    camera_notify_callback         notifyCb;
+    camera_data_callback           dataCb, jpgDataCb;
+
+    LOGD("%s: E ", __func__);
+    mStopCallbackLock.lock( );
+    if(!mActive) {
+        mStopCallbackLock.unlock();
+        LOGD("%s: Stop receiving raw pic ", __func__);
+        return NO_ERROR;
+    }
+
+    mHalCamCtrl->dumpFrameToFile(recvd_frame->snapshot.main.frame, HAL_DUMP_FRM_MAIN);
+    if (!isFullSizeLiveshot())
+        mHalCamCtrl->dumpFrameToFile(recvd_frame->snapshot.thumbnail.frame,
+                                     HAL_DUMP_FRM_THUMBNAIL);
+
+    /* If it's raw snapshot, we just want to tell upperlayer to save the image*/
+    if(mSnapshotFormat == PICTURE_FORMAT_RAW) {
+        LOGD("%s: Call notifyShutter 2nd time in case of RAW", __func__);
+        mStopCallbackLock.unlock();
+        if(!mHalCamCtrl->mShutterSoundPlayed) {
+            notifyShutter(&crop, TRUE);
+        }
+        notifyShutter(&crop, FALSE);
+        mHalCamCtrl->mShutterSoundPlayed = FALSE;
+
+        mStopCallbackLock.lock( );
+        LOGD("%s: Sending Raw Snapshot Callback to Upperlayer", __func__);
+        buf_index = recvd_frame->def.idx;
+
+        if (mHalCamCtrl->mDataCb && mActive &&
+            (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)){
+          dataCb = mHalCamCtrl->mDataCb;
+        } else {
+          dataCb = NULL;
+        }
+        mStopCallbackLock.unlock();
+
+        if(dataCb) {
+            dataCb(
+                CAMERA_MSG_COMPRESSED_IMAGE,
+                mHalCamCtrl->mRawMemory.camera_memory[buf_index], 0, NULL,
+                mHalCamCtrl->mCallbackCookie);
+        }
+        /* TBD: Temp: To be removed once event handling is enabled */
+        mm_app_snapshot_done();
+    } else {
+        /*TBD: v4l2 doesn't have support to provide cropinfo along with
+          frame. We'll need to query.*/
+        memset(&crop, 0, sizeof(common_crop_t));
+
+        /*maftab*/
+        #if 0
+        crop.in1_w=mCrop.snapshot.thumbnail_crop.width;
+        crop.in1_h=mCrop.snapshot.thumbnail_crop.height;
+        crop.out1_w=mThumbnailWidth;
+        crop.out1_h=mThumbnailHeight;
+        #endif
+
+        LOGD("%s: Call notifyShutter 2nd time", __func__);
+        /* The recvd_frame structre we receive from lower library is a local
+           variable. So we'll need to save this structure so that we won't
+           be later pointing to garbage data when that variable goes out of
+           scope */
+        mm_camera_ch_data_buf_t* frame =
+            (mm_camera_ch_data_buf_t *)malloc(sizeof(mm_camera_ch_data_buf_t));
+        if (frame == NULL) {
+            LOGE("%s: Error allocating memory to save received_frame structure.", __func__);
+            cam_evt_buf_done(mCameraId, recvd_frame);
+            mStopCallbackLock.unlock();
+            return BAD_VALUE;
+        }
+        memcpy(frame, recvd_frame, sizeof(mm_camera_ch_data_buf_t));
+
+        //mStopCallbackLock.lock();
+
+        // only in ZSL mode and Wavelet Denoise is enabled, we will send frame to deamon to do WDN
+        if (isZSLMode() && mHalCamCtrl->isWDenoiseEnabled()) {
+            if(mIsDoingWDN){
+                mWDNQueue.enqueue((void *)frame);
+                LOGD("%s: Wavelet denoise is going on, queue frame", __func__);
+                rc = NO_ERROR;
+            } else {
+                LOGD("%s: Start Wavelet denoise", __func__);
+                mIsDoingWDN = TRUE; // set the falg to TRUE because we are going to do WDN
+
+                // No WDN is going on so far, we will start it here
+                rc = doWaveletDenoise(frame);
+                if ( NO_ERROR != rc ) {
+                    LOGE("%s: Error while doing wavelet denoise", __func__);
+                    mIsDoingWDN = FALSE;
+                }
+            }
+        }
+        else {
+          LOGD("%s: encodeDisplayAndSave ", __func__);
+            rc = encodeDisplayAndSave(frame, 0);
+        }
+
+
+        // send upperlayer callback for raw image (data or notify, not both)
+        if((mHalCamCtrl->mDataCb) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_RAW_IMAGE)){
+          dataCb = mHalCamCtrl->mDataCb;
+        } else {
+          dataCb = NULL;
+        }
+        if((mHalCamCtrl->mNotifyCb) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_RAW_IMAGE_NOTIFY)){
+          notifyCb = mHalCamCtrl->mNotifyCb;
+        } else {
+          notifyCb = NULL;
+        }
+
+        mStopCallbackLock.unlock();
+        if(!mHalCamCtrl->mShutterSoundPlayed) {
+            notifyShutter(&crop, TRUE);
+        }
+        notifyShutter(&crop, FALSE);
+        mHalCamCtrl->mShutterSoundPlayed = FALSE;
+
+
+        if (rc != NO_ERROR)
+        {
+            LOGE("%s: Error while encoding/displaying/saving image", __func__);
+            cam_evt_buf_done(mCameraId, recvd_frame);
+
+            if(mHalCamCtrl->mDataCb &&
+                (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
+                /* get picture failed. Give jpeg callback with NULL data
+                 * to the application to restore to preview mode
+                 */
+                jpgDataCb = mHalCamCtrl->mDataCb;
+            } else {
+              jpgDataCb = NULL;
+           	}
+            LOGE("%s: encode err so data cb", __func__);
+            //mStopCallbackLock.unlock();
+            if (dataCb) {
+              dataCb(CAMERA_MSG_RAW_IMAGE, mHalCamCtrl->mSnapshotMemory.camera_memory[0],
+                                   1, NULL, mHalCamCtrl->mCallbackCookie);
+            }
+            if (notifyCb) {
+              notifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mHalCamCtrl->mCallbackCookie);
+            }
+            if (jpgDataCb) {
+              jpgDataCb(CAMERA_MSG_COMPRESSED_IMAGE,
+                                       NULL, 0, NULL,
+                                       mHalCamCtrl->mCallbackCookie);
+            }
+
+            if (frame != NULL) {
+                free(frame);
+            }
+        } else {
+
+          //mStopCallbackLock.unlock();
+          if (dataCb) {
+            dataCb(CAMERA_MSG_RAW_IMAGE, mHalCamCtrl->mSnapshotMemory.camera_memory[0],
+                                 1, NULL, mHalCamCtrl->mCallbackCookie);
+          }
+          if (notifyCb) {
+            notifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mHalCamCtrl->mCallbackCookie);
+          }
+        }
+    }
+
+    LOGD("%s: X", __func__);
+    return NO_ERROR;
+}
+
+//-------------------------------------------------------------------
+// Helper Functions
+//-------------------------------------------------------------------
+void QCameraStream_Snapshot::handleError()
+{
+    mm_camera_channel_type_t ch_type;
+    LOGD("%s: E", __func__);
+
+    /* Depending upon the state we'll have to
+       handle error */
+    switch(getSnapshotState()) {
+    case SNAPSHOT_STATE_JPEG_ENCODING:
+        if(mJpegHeap != NULL) mJpegHeap.clear();
+        mJpegHeap = NULL;
+
+    case SNAPSHOT_STATE_YUV_RECVD:
+    case SNAPSHOT_STATE_IMAGE_CAPTURE_STRTD:
+        stopPolling();
+    case SNAPSHOT_STATE_INITIALIZED:
+    case SNAPSHOT_STATE_BUF_INITIALIZED:
+        if (mSnapshotFormat == PICTURE_FORMAT_JPEG) {
+            deinitSnapshotBuffers();
+        }else
+        {
+            deinitRawSnapshotBuffers();
+        }
+    case SNAPSHOT_STATE_BUF_NOTIF_REGD:
+    case SNAPSHOT_STATE_CH_ACQUIRED:
+        if (mSnapshotFormat == PICTURE_FORMAT_JPEG) {
+            deinitSnapshotChannel(MM_CAMERA_CH_SNAPSHOT);
+        }else
+        {
+            deinitSnapshotChannel(MM_CAMERA_CH_RAW);
+        }
+    default:
+        /* Set the state to ERROR */
+        setSnapshotState(SNAPSHOT_STATE_ERROR);
+        break;
+    }
+
+    LOGD("%s: X", __func__);
+}
+
+void QCameraStream_Snapshot::setSnapshotState(int state)
+{
+    LOGD("%s: Setting snapshot state to: %d",
+         __func__, state);
+    mSnapshotState = state;
+}
+
+int QCameraStream_Snapshot::getSnapshotState()
+{
+    return mSnapshotState;
+}
+
+void QCameraStream_Snapshot::setModeLiveSnapshot(bool value)
+{
+    mModeLiveSnapshot = value;
+}
+
+bool QCameraStream_Snapshot::isLiveSnapshot(void)
+{
+    return mModeLiveSnapshot;
+}
+bool QCameraStream_Snapshot::isZSLMode()
+{
+    return (myMode & CAMERA_ZSL_MODE);
+}
+
+void QCameraStream_Snapshot::setFullSizeLiveshot(bool value)
+{
+    mFullLiveshot = value;
+}
+
+bool QCameraStream_Snapshot::isFullSizeLiveshot()
+{
+    return mFullLiveshot;
+}
+
+void QCameraStream_Snapshot::resetSnapshotCounters(void )
+{
+  mNumOfSnapshot = mHalCamCtrl->getNumOfSnapshots();
+  if (mNumOfSnapshot <= 0) {
+      mNumOfSnapshot = 1;
+  }
+  mNumOfRecievedJPEG = 0;
+  LOGD("%s: Number of images to be captured: %d", __func__, mNumOfSnapshot);
+}
+
+//------------------------------------------------------------------
+// Constructor and Destructor
+//------------------------------------------------------------------
+QCameraStream_Snapshot::
+QCameraStream_Snapshot(int cameraId, camera_mode_t mode)
+  : QCameraStream(cameraId,mode),
+    mSnapshotFormat(PICTURE_FORMAT_JPEG),
+    mPictureWidth(0), mPictureHeight(0),
+    mPictureFormat(CAMERA_YUV_420_NV21),
+    mPostviewWidth(0), mPostviewHeight(0),
+    mThumbnailWidth(0), mThumbnailHeight(0),
+    mThumbnailFormat(CAMERA_YUV_420_NV21),
+    mJpegOffset(0),
+    mSnapshotState(SNAPSHOT_STATE_UNINIT),
+    mNumOfSnapshot(1),
+    mModeLiveSnapshot(false),
+    mBurstModeFlag(false),
+    mActualPictureWidth(0),
+    mActualPictureHeight(0),
+    mJpegDownscaling(false),
+    mJpegHeap(NULL),
+    mDisplayHeap(NULL),
+    mPostviewHeap(NULL),
+    mCurrentFrameEncoded(NULL),
+    mJpegSessionId(0),
+    mFullLiveshot(false),
+    mDropThumbnail(false)
+  {
+    LOGV("%s: E", __func__);
+
+    /*initialize snapshot queue*/
+    mSnapshotQueue.init();
+
+    /*initialize WDN queue*/
+    mWDNQueue.init();
+    mIsDoingWDN = FALSE;
+
+    memset(&mSnapshotStreamBuf, 0, sizeof(mSnapshotStreamBuf));
+    memset(&mPostviewStreamBuf, 0, sizeof(mPostviewStreamBuf));
+    mSnapshotBufferNum = 0;
+    mMainSize = 0;
+    mThumbSize = 0;
+    for(int i = 0; i < mMaxSnapshotBufferCount; i++) {
+        mMainfd[i] = 0;
+        mThumbfd[i] = 0;
+        mCameraMemoryPtrMain[i] = NULL;
+        mCameraMemoryPtrThumb[i] = NULL;
+    }
+    /*load the jpeg lib*/
+    mJpegSessionId = omxJpegOpen( );
+    LOGV("%s: X", __func__);
+  }
+
+
+QCameraStream_Snapshot::~QCameraStream_Snapshot() {
+    LOGV("%s: E", __func__);
+
+    /* deinit snapshot queue */
+    if (mSnapshotQueue.isInitialized()) {
+        mSnapshotQueue.deinit();
+    }
+    /* deinit snapshot queue */
+    if (mWDNQueue.isInitialized()) {
+        mWDNQueue.deinit();
+    }
+
+    if(mActive) {
+        stop();
+    }
+    if(mInit) {
+        release();
+    }
+    mInit = false;
+    mActive = false;
+    if (mJpegSessionId > 0) {
+      omxJpegClose( );
+      mJpegSessionId = 0;
+    }
+    LOGV("%s: X", __func__);
+
+}
+
+//------------------------------------------------------------------
+// Public Members
+//------------------------------------------------------------------
+status_t QCameraStream_Snapshot::init()
+{
+    status_t ret = NO_ERROR;
+    mm_camera_op_mode_type_t op_mode;
+
+    LOGV("%s: E", __func__);
+    /* Check the state. If we have already started snapshot
+       process just return*/
+    if (getSnapshotState() != SNAPSHOT_STATE_UNINIT) {
+        ret = isZSLMode() ? NO_ERROR : INVALID_OPERATION;
+        LOGE("%s: Trying to take picture while snapshot is in progress",
+             __func__);
+        goto end;
+    }
+    mInit = true;
+
+end:
+    /*if (ret == NO_ERROR) {
+        setSnapshotState(SNAPSHOT_STATE_INITIALIZED);
+    }*/
+    LOGV("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::start(void) {
+    status_t ret = NO_ERROR;
+
+    LOGV("%s: E", __func__);
+
+    Mutex::Autolock lock(mStopCallbackLock);
+
+    /* Keep track of number of snapshots to take - in case of
+       multiple snapshot/burst mode */
+
+	if(mHalCamCtrl->isRawSnapshot()) {
+        LOGD("%s: Acquire Raw Snapshot Channel", __func__);
+        ret = cam_ops_ch_acquire(mCameraId, MM_CAMERA_CH_RAW);
+        if (NO_ERROR != ret) {
+            LOGE("%s: Failure Acquiring Raw Snapshot Channel error =%d\n",
+                 __func__, ret);
+            ret = FAILED_TRANSACTION;
+            goto end;
+        }
+        /* Snapshot channel is acquired */
+        setSnapshotState(SNAPSHOT_STATE_CH_ACQUIRED);
+        LOGD("%s: Register buffer notification. My object: %x",
+             __func__, (unsigned int) this);
+        (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_RAW,
+                                        snapshot_notify_cb,
+                                        MM_CAMERA_REG_BUF_CB_INFINITE,
+                                        0,
+                                        this);
+        /* Set the state to buffer notification completed */
+        setSnapshotState(SNAPSHOT_STATE_BUF_NOTIF_REGD);
+    }else{
+        LOGD("%s: Acquire Snapshot Channel", __func__);
+        ret = cam_ops_ch_acquire(mCameraId, MM_CAMERA_CH_SNAPSHOT);
+        if (NO_ERROR != ret) {
+            LOGE("%s: Failure Acquiring Snapshot Channel error =%d\n", __func__, ret);
+            ret = FAILED_TRANSACTION;
+            goto end;
+        }
+        /* Snapshot channel is acquired */
+        setSnapshotState(SNAPSHOT_STATE_CH_ACQUIRED);
+        LOGD("%s: Register buffer notification. My object: %x",
+             __func__, (unsigned int) this);
+        (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_SNAPSHOT,
+                                        snapshot_notify_cb,
+                                        MM_CAMERA_REG_BUF_CB_INFINITE,
+                                        0,
+                                        this);
+        /* Set the state to buffer notification completed */
+        setSnapshotState(SNAPSHOT_STATE_BUF_NOTIF_REGD);
+    }
+
+    if (isZSLMode()) {
+        prepareHardware();
+        ret = initZSLSnapshot();
+        if(ret != NO_ERROR) {
+            LOGE("%s : Error while Initializing ZSL snapshot",__func__);
+            goto end;
+        }
+        mHalCamCtrl->setExifTags();
+        /* In case of ZSL, start will only start snapshot stream and
+           continuously queue the frames in a queue. When user clicks
+           shutter we'll call get buffer from the queue and pass it on */
+        ret = startStreamZSL();
+        goto end;
+    }
+
+    if (isFullSizeLiveshot())
+      ret = initFullLiveshot();
+
+    /* Check if it's a raw snapshot or JPEG*/
+    if(mHalCamCtrl->isRawSnapshot()) {
+        mSnapshotFormat = PICTURE_FORMAT_RAW;
+        ret = initRawSnapshot(mNumOfSnapshot);
+    }else{
+        //JPEG
+        mSnapshotFormat = PICTURE_FORMAT_JPEG;
+        ret = initJPEGSnapshot(mNumOfSnapshot);
+    }
+    if(ret != NO_ERROR) {
+        LOGE("%s : Error while Initializing snapshot",__func__);
+        goto end;
+    }
+
+    //Update Exiftag values.
+    mHalCamCtrl->setExifTags();
+
+    if (mSnapshotFormat == PICTURE_FORMAT_RAW) {
+        ret = takePictureRaw();
+        goto end;
+    }
+    else{
+        ret = takePictureJPEG();
+        goto end;
+    }
+
+end:
+    if (ret == NO_ERROR) {
+        setSnapshotState(SNAPSHOT_STATE_IMAGE_CAPTURE_STRTD);
+        mActive = true;
+    } else {
+        deInitBuffer();
+    }
+
+    LOGV("%s: X", __func__);
+    return ret;
+  }
+
+void QCameraStream_Snapshot::stopPolling(void)
+{
+    mm_camera_ops_type_t ops_type;
+
+    if (mSnapshotFormat == PICTURE_FORMAT_JPEG) {
+        ops_type = isZSLMode() ? MM_CAMERA_OPS_ZSL : MM_CAMERA_OPS_SNAPSHOT;
+    }else
+        ops_type = MM_CAMERA_OPS_RAW;
+
+    if( NO_ERROR != cam_ops_action(mCameraId, FALSE,
+                                          ops_type, this)) {
+        LOGE("%s: Failure stopping snapshot", __func__);
+    }
+}
+
+void QCameraStream_Snapshot::stop(void)
+{
+    mm_camera_ops_type_t ops_type;
+    status_t ret = NO_ERROR;
+
+    LOGV("%s: E", __func__);
+    //Mutex::Autolock l(&snapshotLock);
+
+    if(!mActive) {
+      LOGV("%s: Not Active return now", __func__);
+      return;
+    }
+    mActive = false;
+    Mutex::Autolock lock(mStopCallbackLock);
+    if (getSnapshotState() != SNAPSHOT_STATE_UNINIT) {
+        /* Stop polling for further frames */
+        stopPolling();
+
+        if(getSnapshotState() == SNAPSHOT_STATE_JPEG_ENCODING) {
+            LOGV("Destroy Jpeg Instance");
+            omxJpegAbort();
+        }
+
+        /* Depending upon current state, we'll need to allocate-deallocate-deinit*/
+        deInitBuffer();
+    }
+
+    if(mSnapshotFormat == PICTURE_FORMAT_RAW) {
+        ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_RAW);
+        if(ret != MM_CAMERA_OK) {
+          LOGE("%s:Deinit RAW channel failed=%d\n", __func__, ret);
+        }
+        (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_RAW,
+                                            NULL,
+                                            (mm_camera_register_buf_cb_type_t)NULL,
+                                            NULL,
+                                            NULL);
+    } else {
+        ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_SNAPSHOT);
+        if(ret != MM_CAMERA_OK) {
+          LOGE("%s:Deinit Snapshot channel failed=%d\n", __func__, ret);
+        }
+        (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_SNAPSHOT,
+                                            NULL,
+                                            (mm_camera_register_buf_cb_type_t)NULL,
+                                            NULL,
+                                            NULL);
+    }
+
+    /* release is generally called in case of explicit call from
+       upper-layer during disconnect. So we need to deinit everything
+       whatever state we are in */
+    LOGV("Calling omxjpegjoin from release\n");
+    omxJpegFinish();
+#if 0
+    omxJpegClose();
+#endif
+    mFullLiveshot = false;
+    LOGV("%s: X", __func__);
+
+}
+
+void QCameraStream_Snapshot::release()
+{
+    status_t ret = NO_ERROR;
+    LOGV("%s: E", __func__);
+    //Mutex::Autolock l(&snapshotLock);
+
+    if(isLiveSnapshot()) {
+        deInitBuffer();
+    }
+    if(!mInit){
+        LOGE("%s : Stream not Initalized",__func__);
+        return;
+    }
+
+    if(mActive) {
+      this->stop();
+      mActive = FALSE;
+    }
+
+    /* release is generally called in case of explicit call from
+       upper-layer during disconnect. So we need to deinit everything
+       whatever state we are in */
+
+    //deinit();
+    mInit = false;
+    LOGV("%s: X", __func__);
+
+}
+
+void QCameraStream_Snapshot::prepareHardware()
+{
+    LOGV("%s: E", __func__);
+
+    /* Prepare snapshot*/
+    cam_ops_action(mCameraId,
+                          TRUE,
+                          MM_CAMERA_OPS_PREPARE_SNAPSHOT,
+                          this);
+    LOGV("%s: X", __func__);
+}
+
+sp<IMemoryHeap> QCameraStream_Snapshot::getRawHeap() const
+{
+    return ((mDisplayHeap != NULL) ? mDisplayHeap->mHeap : NULL);
+}
+
+QCameraStream*
+QCameraStream_Snapshot::createInstance(int cameraId,
+                                      camera_mode_t mode)
+{
+
+  QCameraStream* pme = new QCameraStream_Snapshot(cameraId, mode);
+
+  return pme;
+}
+
+void QCameraStream_Snapshot::deleteInstance(QCameraStream *p)
+{
+  if (p){
+    p->release();
+    delete p;
+    p = NULL;
+  }
+}
+
+void QCameraStream_Snapshot::notifyWDenoiseEvent(cam_ctrl_status_t status, void * cookie)
+{
+    camera_notify_callback         notifyCb;
+    camera_data_callback           dataCb, jpgDataCb;
+    int rc = NO_ERROR;
+    mm_camera_ch_data_buf_t *frame = (mm_camera_ch_data_buf_t *)cookie;
+
+    LOGI("%s: WDN Done status (%d) received",__func__,status);
+    Mutex::Autolock lock(mStopCallbackLock);
+    if (frame == NULL) {
+        LOGE("%s: cookie is returned NULL", __func__);
+    } else {
+        // first unmapping the fds
+        mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_MAIN, frame->snapshot.main.idx, mCameraId,
+                                      CAM_SOCK_MSG_TYPE_FD_UNMAPPING);
+        mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, frame->snapshot.thumbnail.idx, mCameraId,
+                                      CAM_SOCK_MSG_TYPE_FD_UNMAPPING);
+
+        // then do JPEG encoding
+        rc = encodeDisplayAndSave(frame, 0);
+    }
+
+    // send upperlayer callback for raw image (data or notify, not both)
+    if((mHalCamCtrl->mDataCb) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_RAW_IMAGE)){
+      dataCb = mHalCamCtrl->mDataCb;
+    } else {
+      dataCb = NULL;
+    }
+    if((mHalCamCtrl->mNotifyCb) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_RAW_IMAGE_NOTIFY)){
+      notifyCb = mHalCamCtrl->mNotifyCb;
+    } else {
+      notifyCb = NULL;
+    }
+    if(mHalCamCtrl->mDataCb &&
+        (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
+        /* get picture failed. Give jpeg callback with NULL data
+         * to the application to restore to preview mode
+         */
+        jpgDataCb = mHalCamCtrl->mDataCb;
+    } else {
+      jpgDataCb = NULL;
+    }
+
+    // launch next WDN if there is more in WDN Queue
+    lauchNextWDenoiseFromQueue();
+
+    mStopCallbackLock.unlock();
+
+    if (rc != NO_ERROR)
+    {
+        LOGE("%s: Error while encoding/displaying/saving image", __func__);
+        if (frame) {
+            cam_evt_buf_done(mCameraId, frame);
+        }
+
+        if (dataCb) {
+          dataCb(CAMERA_MSG_RAW_IMAGE, mHalCamCtrl->mSnapshotMemory.camera_memory[0],
+                               1, NULL, mHalCamCtrl->mCallbackCookie);
+        }
+        if (notifyCb) {
+          notifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mHalCamCtrl->mCallbackCookie);
+        }
+        if (jpgDataCb) {
+          jpgDataCb(CAMERA_MSG_COMPRESSED_IMAGE,
+                                   NULL, 0, NULL,
+                                   mHalCamCtrl->mCallbackCookie);
+        }
+
+        if (frame != NULL) {
+            free(frame);
+        }
+    }
+}
+
+void QCameraStream_Snapshot::lauchNextWDenoiseFromQueue()
+{
+    do {
+        mm_camera_ch_data_buf_t *frame = NULL;
+        if ( mWDNQueue.isEmpty() ||
+             (NULL == (frame = (mm_camera_ch_data_buf_t *)mWDNQueue.dequeue())) ) {
+            // set the flag back to FALSE when no WDN going on
+            mIsDoingWDN = FALSE;
+            break;
+        }
+
+        if ( NO_ERROR != doWaveletDenoise(frame) ) {
+            LOGE("%s: Error while doing wavelet denoise", __func__);
+            if (frame != NULL) {
+                free(frame);
+            }
+        } else {
+            // we sent out req for WDN, so we can break here
+            LOGD("%s: Send out req for doing wavelet denoise, return here", __func__);
+            break;
+        }
+    } while (TRUE);
+}
+
+status_t QCameraStream_Snapshot::doWaveletDenoise(mm_camera_ch_data_buf_t* frame)
+{
+    status_t ret = NO_ERROR;
+    cam_sock_packet_t packet;
+    cam_ctrl_dimension_t dim;
+
+    LOGD("%s: E", __func__);
+
+    // get dim on the fly
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+    if (NO_ERROR != ret) {
+        LOGE("%s: error - can't get dimension!", __func__);
+        return FAILED_TRANSACTION;
+    }
+
+    // send main frame mapping through domain socket
+    if (NO_ERROR != mHalCamCtrl->sendMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_MAIN,
+                                                frame->snapshot.main.idx,
+                                                frame->snapshot.main.frame->fd,
+                                                dim.picture_frame_offset.frame_len, mCameraId,
+                                                CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
+        LOGE("%s: sending main frame mapping buf msg Failed", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+    // send thumbnail frame mapping through domain socket
+    if (NO_ERROR != mHalCamCtrl->sendMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL,
+                                                frame->snapshot.thumbnail.idx,
+                                                frame->snapshot.thumbnail.frame->fd,
+                                                dim.display_frame_offset.frame_len, mCameraId,
+                                                CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
+        LOGE("%s: sending thumbnail frame mapping buf msg Failed", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+    // ask deamon to start wdn operation
+    if (NO_ERROR != sendWDenoiseStartMsg(frame)) {
+        LOGE("%s: sending thumbnail frame mapping buf msg Failed", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
+end:
+    LOGD("%s: X", __func__);
+    return ret;
+}
+
+status_t QCameraStream_Snapshot::sendWDenoiseStartMsg(mm_camera_ch_data_buf_t * frame)
+{
+    cam_sock_packet_t packet;
+    memset(&packet, 0, sizeof(cam_sock_packet_t));
+    packet.msg_type = CAM_SOCK_MSG_TYPE_WDN_START;
+    packet.payload.wdn_start.cookie = (unsigned long)frame;
+    packet.payload.wdn_start.num_frames = MM_MAX_WDN_NUM;
+    packet.payload.wdn_start.ext_mode[0] = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+    packet.payload.wdn_start.ext_mode[1] = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
+    packet.payload.wdn_start.frame_idx[0] = frame->snapshot.main.idx;
+    packet.payload.wdn_start.frame_idx[1] = frame->snapshot.thumbnail.idx;
+    if ( cam_ops_sendmsg(mCameraId, &packet, sizeof(packet), 0) <= 0 ) {
+        LOGE("%s: sending start wavelet denoise msg failed", __func__);
+        return FAILED_TRANSACTION;
+    }
+    return NO_ERROR;
+}
+
+}; // namespace android
+
diff --git a/camera/QCamera/HAL/core/src/QCameraStream.cpp b/camera/QCamera/HAL/core/src/QCameraStream.cpp
new file mode 100755
index 0000000..48c2363
--- /dev/null
+++ b/camera/QCamera/HAL/core/src/QCameraStream.cpp
@@ -0,0 +1,364 @@
+/*
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+#define LOG_NDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG __FILE__
+#include <utils/Log.h>
+#include <utils/threads.h>
+
+
+#include "QCameraStream.h"
+
+/* QCameraStream class implementation goes here*/
+/* following code implement the control logic of this class*/
+
+namespace android {
+
+StreamQueue::StreamQueue(){
+    mInitialized = false;
+}
+
+StreamQueue::~StreamQueue(){
+    flush();
+}
+
+void StreamQueue::init(){
+    Mutex::Autolock l(&mQueueLock);
+    mInitialized = true;
+    mQueueWait.signal();
+}
+
+void StreamQueue::deinit(){
+    Mutex::Autolock l(&mQueueLock);
+    mInitialized = false;
+    mQueueWait.signal();
+}
+
+bool StreamQueue::isInitialized(){
+   Mutex::Autolock l(&mQueueLock);
+   return mInitialized;
+}
+
+bool StreamQueue::enqueue(
+                 void * element){
+    Mutex::Autolock l(&mQueueLock);
+    if(mInitialized == false)
+        return false;
+
+    mContainer.add(element);
+    mQueueWait.signal();
+    return true;
+}
+
+bool StreamQueue::isEmpty(){
+    return (mInitialized && mContainer.isEmpty());
+}
+void* StreamQueue::dequeue(){
+
+    void *frame;
+    mQueueLock.lock();
+    while(mInitialized && mContainer.isEmpty()){
+        mQueueWait.wait(mQueueLock);
+    }
+
+    if(!mInitialized){
+        mQueueLock.unlock();
+        return NULL;
+    }
+
+    frame = mContainer.itemAt(0);
+    mContainer.removeAt(0);
+    mQueueLock.unlock();
+    return frame;
+}
+
+void StreamQueue::flush(){
+    Mutex::Autolock l(&mQueueLock);
+    mContainer.clear();
+}
+
+
+// ---------------------------------------------------------------------------
+// QCameraStream
+// ---------------------------------------------------------------------------
+
+/* initialize a streaming channel*/
+status_t QCameraStream::initChannel(int cameraId,
+                                    uint32_t ch_type_mask)
+{
+#if 0
+    int rc = MM_CAMERA_OK;
+    int i;
+    status_t ret = NO_ERROR;
+    int width = 0;  /* width of channel      */
+    int height = 0; /* height of channel */
+    cam_ctrl_dimension_t dim;
+    mm_camera_ch_image_fmt_parm_t fmt;
+
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    rc = cam_config_get_parm(cameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+    if (MM_CAMERA_OK != rc) {
+      LOGE("%s: error - can't get camera dimension!", __func__);
+      LOGE("%s: X", __func__);
+      return BAD_VALUE;
+    }
+
+    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask) {
+        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_PREVIEW);
+        LOGV("%s:ch_acquire MM_CAMERA_CH_PREVIEW, rc=%d\n",__func__, rc);
+
+        if(MM_CAMERA_OK != rc) {
+                LOGE("%s: preview channel acquir error =%d\n", __func__, rc);
+                LOGE("%s: X", __func__);
+                return BAD_VALUE;
+        }
+        else{
+            memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
+            fmt.ch_type = MM_CAMERA_CH_PREVIEW;
+            fmt.def.fmt = CAMERA_YUV_420_NV12; //dim.prev_format;
+            fmt.def.dim.width = dim.display_width;
+            fmt.def.dim.height =  dim.display_height;
+            LOGV("%s: preview channel fmt = %d", __func__,
+                     dim.prev_format);
+            LOGV("%s: preview channel resolution = %d X %d", __func__,
+                     dim.display_width, dim.display_height);
+
+            rc = cam_config_set_parm(cameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
+            LOGV("%s: preview MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
+            if(MM_CAMERA_OK != rc) {
+                    LOGE("%s:set preview channel format err=%d\n", __func__, ret);
+                    LOGE("%s: X", __func__);
+                    ret = BAD_VALUE;
+            }
+        }
+    }
+
+
+    if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask)
+    {
+        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_VIDEO);
+        LOGV("%s:ch_acquire MM_CAMERA_CH_VIDEO, rc=%d\n",__func__, rc);
+
+        if(MM_CAMERA_OK != rc) {
+                LOGE("%s: video channel acquir error =%d\n", __func__, rc);
+                LOGE("%s: X", __func__);
+                ret = BAD_VALUE;
+        }
+        else {
+            memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
+            fmt.ch_type = MM_CAMERA_CH_VIDEO;
+            fmt.video.video.fmt = CAMERA_YUV_420_NV12; //dim.enc_format;
+            fmt.video.video.dim.width = dim.video_width;
+            fmt.video.video.dim.height = dim.video_height;
+            LOGV("%s: video channel fmt = %d", __func__,
+                     dim.enc_format);
+            LOGV("%s: video channel resolution = %d X %d", __func__,
+                 dim.video_width, dim.video_height);
+
+            rc = cam_config_set_parm(cameraId,  MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
+
+            LOGV("%s: video MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
+            if(MM_CAMERA_OK != rc) {
+                LOGE("%s:set video channel format err=%d\n", __func__, rc);
+                LOGE("%s: X", __func__);
+                ret= BAD_VALUE;
+            }
+        }
+
+  } /*MM_CAMERA_CH_VIDEO*/
+#endif
+
+    int rc = MM_CAMERA_OK;
+    status_t ret = NO_ERROR;
+    mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
+    int i;
+
+    LOGV("QCameraStream::initChannel : E");
+    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
+        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_PREVIEW);
+        LOGV("%s:ch_acquire MM_CAMERA_CH_PREVIEW, rc=%d\n",__func__, rc);
+        if(MM_CAMERA_OK != rc) {
+                LOGE("%s: preview channel acquir error =%d\n", __func__, rc);
+                LOGE("%s: X", __func__);
+                return BAD_VALUE;
+        }
+        /*Callback register*/
+        /* register a notify into the mmmm_camera_t object*/
+       /* ret = cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
+                                                preview_notify_cb,
+                                                this);
+        LOGV("Buf notify MM_CAMERA_CH_PREVIEW, rc=%d\n",rc);*/
+    }else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
+        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_VIDEO);
+        LOGV("%s:ch_acquire MM_CAMERA_CH_VIDEO, rc=%d\n",__func__, rc);
+        if(MM_CAMERA_OK != rc) {
+                LOGE("%s: preview channel acquir error =%d\n", __func__, rc);
+                LOGE("%s: X", __func__);
+                return BAD_VALUE;
+        }
+        /*Callback register*/
+        /* register a notify into the mmmm_camera_t object*/
+        /*ret = cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
+                                                record_notify_cb,
+                                                this);
+        LOGV("Buf notify MM_CAMERA_CH_VIDEO, rc=%d\n",rc);*/
+    }
+
+    ret = (MM_CAMERA_OK==rc)? NO_ERROR : BAD_VALUE;
+    LOGV("%s: X, ret = %d", __func__, ret);
+    return ret;
+}
+
+status_t QCameraStream::deinitChannel(int cameraId,
+                                    mm_camera_channel_type_t ch_type)
+{
+
+    int rc = MM_CAMERA_OK;
+
+    LOGV("%s: E, channel = %d\n", __func__, ch_type);
+
+    if (MM_CAMERA_CH_MAX <= ch_type) {
+        LOGE("%s: X: BAD_VALUE", __func__);
+        return BAD_VALUE;
+    }
+
+    cam_ops_ch_release(cameraId, ch_type);
+
+    LOGV("%s: X, channel = %d\n", __func__, ch_type);
+    return NO_ERROR;
+}
+
+status_t QCameraStream::setMode(int enable) {
+  LOGE("%s :myMode %x ", __func__, myMode);
+  if (enable) {
+      myMode = (camera_mode_t)(myMode | CAMERA_ZSL_MODE);
+  } else {
+      myMode = (camera_mode_t)(myMode & ~CAMERA_ZSL_MODE);
+  }
+  return NO_ERROR;
+}
+
+status_t QCameraStream::setFormat(uint8_t ch_type_mask)
+{
+    int rc = MM_CAMERA_OK;
+    status_t ret = NO_ERROR;
+    int width = 0;  /* width of channel      */
+    int height = 0; /* height of channel */
+    cam_ctrl_dimension_t dim;
+    mm_camera_ch_image_fmt_parm_t fmt;
+    int preview_format;
+    LOGE("%s: E",__func__);
+
+    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+    rc = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+    if (MM_CAMERA_OK != rc) {
+      LOGE("%s: error - can't get camera dimension!", __func__);
+      LOGE("%s: X", __func__);
+      return BAD_VALUE;
+    }
+    char mDeviceName[PROPERTY_VALUE_MAX];
+    property_get("ro.product.device",mDeviceName," ");
+    memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
+    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
+        fmt.ch_type = MM_CAMERA_CH_PREVIEW;
+        ret = cam_config_get_parm(mCameraId,
+                  MM_CAMERA_PARM_PREVIEW_FORMAT, &preview_format);
+        fmt.def.fmt = (cam_format_t)preview_format;
+        fmt.def.dim.width = dim.display_width;
+        fmt.def.dim.height =  dim.display_height;
+    }else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
+        fmt.ch_type = MM_CAMERA_CH_VIDEO;
+        fmt.video.video.fmt = CAMERA_YUV_420_NV21; //dim.enc_format;
+        fmt.video.video.dim.width = dim.video_width;
+        fmt.video.video.dim.height = dim.video_height;
+    }/*else if(MM_CAMERA_CH_SNAPSHOT_MASK & ch_type_mask){
+        if(mHalCamCtrl->isRawSnapshot()) {
+            fmt.ch_type = MM_CAMERA_CH_RAW;
+            fmt.def.fmt = CAMERA_BAYER_SBGGR10;
+            fmt.def.dim.width = dim.raw_picture_width;
+            fmt.def.dim.height = dim.raw_picture_height;
+        }else{
+            //Jpeg???
+            fmt.ch_type = MM_CAMERA_CH_SNAPSHOT;
+            fmt.snapshot.main.fmt = dim.main_img_format;
+            fmt.snapshot.main.dim.width = dim.picture_width;
+            fmt.snapshot.main.dim.height = dim.picture_height;
+
+            fmt.snapshot.thumbnail.fmt = dim.thumb_format;
+            fmt.snapshot.thumbnail.dim.width = dim.ui_thumbnail_width;
+            fmt.snapshot.thumbnail.dim.height = dim.ui_thumbnail_height;
+        }
+    }*/
+
+    rc = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
+    LOGV("%s: Stream MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
+    if(MM_CAMERA_OK != rc) {
+        LOGE("%s:set stream channel format err=%d\n", __func__, ret);
+        LOGE("%s: X", __func__);
+        ret = BAD_VALUE;
+    }
+    LOGE("%s: X",__func__);
+    return ret;
+}
+
+QCameraStream::QCameraStream (){
+    mInit = false;
+    mActive = false;
+    /* memset*/
+    memset(&mCrop, 0, sizeof(mm_camera_ch_crop_t));
+}
+
+QCameraStream::QCameraStream (int cameraId, camera_mode_t mode)
+              :mCameraId(cameraId),
+               myMode(mode)
+{
+    mInit = false;
+    mActive = false;
+
+    /* memset*/
+    memset(&mCrop, 0, sizeof(mm_camera_ch_crop_t));
+}
+
+QCameraStream::~QCameraStream () {;}
+
+
+status_t QCameraStream::init() {
+    return NO_ERROR;
+}
+
+status_t QCameraStream::start() {
+    return NO_ERROR;
+}
+
+void QCameraStream::stop() {
+    return;
+}
+
+void QCameraStream::release() {
+    return;
+}
+
+void QCameraStream::setHALCameraControl(QCameraHardwareInterface* ctrl) {
+
+    /* provide a frame data user,
+    for the  queue monitor thread to call the busy queue is not empty*/
+    mHalCamCtrl = ctrl;
+}
+
+}; // namespace android
diff --git a/camera/QCamera/HAL/test/Android.mk b/camera/QCamera/HAL/test/Android.mk
new file mode 100755
index 0000000..d3f5a12
--- /dev/null
+++ b/camera/QCamera/HAL/test/Android.mk
@@ -0,0 +1 @@
+

diff --git a/camera/QCamera/HAL/wrapper/QualcommCamera.cpp b/camera/QCamera/HAL/wrapper/QualcommCamera.cpp
new file mode 100755
index 0000000..2875e27
--- /dev/null
+++ b/camera/QCamera/HAL/wrapper/QualcommCamera.cpp
@@ -0,0 +1,506 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*#error uncomment this for compiler test!*/
+
+//#define LOG_NDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG "QualcommCamera"
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "QCameraHAL.h"
+/* include QCamera Hardware Interface Header*/
+#include "QualcommCamera.h"
+//#include "QualcommCameraHardware.h"
+//#include <camera/CameraHardwareInterface.h>
+
+extern "C" {
+#include <sys/time.h>
+}
+
+/* HAL function implementation goes here*/
+
+/**
+ * The functions need to be provided by the camera HAL.
+ *
+ * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
+ * and openCameraHardware() is 0 to N-1.
+ */
+
+static hw_module_methods_t camera_module_methods = {
+    open: camera_device_open,
+};
+
+static hw_module_t camera_common  = {
+  tag: HARDWARE_MODULE_TAG,
+  version_major: 0,
+  version_minor: 01,
+  id: CAMERA_HARDWARE_MODULE_ID,
+  name: "Qcamera",
+  author:"Qcom",
+  methods: &camera_module_methods,
+  dso: NULL,
+  //reserved[0]:  0,
+};
+camera_module_t HAL_MODULE_INFO_SYM = {
+  common: camera_common,
+  get_number_of_cameras: get_number_of_cameras,
+  get_camera_info: get_camera_info,
+};
+
+camera_device_ops_t camera_ops = {
+  set_preview_window:         android::set_preview_window,
+  set_callbacks:              android::set_CallBacks,
+  enable_msg_type:            android::enable_msg_type,
+  disable_msg_type:           android::disable_msg_type,
+  msg_type_enabled:           android::msg_type_enabled,
+
+  start_preview:              android::start_preview,
+  stop_preview:               android::stop_preview,
+  preview_enabled:            android::preview_enabled,
+  store_meta_data_in_buffers: android::store_meta_data_in_buffers,
+
+  start_recording:            android::start_recording,
+  stop_recording:             android::stop_recording,
+  recording_enabled:          android::recording_enabled,
+  release_recording_frame:    android::release_recording_frame,
+
+  auto_focus:                 android::auto_focus,
+  cancel_auto_focus:          android::cancel_auto_focus,
+
+  take_picture:               android::take_picture,
+  cancel_picture:             android::cancel_picture,
+
+  set_parameters:             android::set_parameters,
+  get_parameters:             android::get_parameters,
+  put_parameters:             android::put_parameters,
+  send_command:               android::send_command,
+
+  release:                    android::release,
+  dump:                       android::dump,
+};
+
+namespace android {
+
+typedef struct {
+  camera_device hw_dev;
+  //sp<CameraHardwareInterface> hardware;
+  QCameraHardwareInterface *hardware;
+  int camera_released;
+  int cameraId;
+  //CameraParameters parameters;
+} camera_hardware_t;
+
+typedef struct {
+  camera_memory_t mem;
+  int32_t msgType;
+  sp<IMemory> dataPtr;
+  void* user;
+  unsigned int index;
+} q_cam_memory_t;
+
+QCameraHardwareInterface *util_get_Hal_obj( struct camera_device * device)
+{
+    QCameraHardwareInterface *hardware = NULL;
+    if(device && device->priv){
+        camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
+        hardware = camHal->hardware;
+    }
+    return hardware;
+}
+
+#if 0 //mzhu
+CameraParameters* util_get_HAL_parameter( struct camera_device * device)
+{
+    CameraParameters *param = NULL;
+    if(device && device->priv){
+        camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
+        param = &(camHal->parameters);
+    }
+    return param;
+}
+#endif //mzhu
+
+extern "C" int get_number_of_cameras()
+{
+    /* try to query every time we get the call!*/
+
+    LOGE("Q%s: E", __func__);
+    return android::HAL_getNumberOfCameras( );
+}
+
+extern "C" int get_camera_info(int camera_id, struct camera_info *info)
+{
+    int rc = -1;
+    LOGE("Q%s: E", __func__);
+    if(info) {
+        struct CameraInfo camInfo;
+        memset(&camInfo, -1, sizeof (struct CameraInfo));
+        android::HAL_getCameraInfo(camera_id, &camInfo);
+        if (camInfo.facing >= 0) {
+            rc = 0;
+            info->facing = camInfo.facing;
+            info->orientation = camInfo.orientation;
+        }
+    }
+    LOGV("Q%s: X", __func__);
+    return rc;
+}
+
+
+/* HAL should return NULL if it fails to open camera hardware. */
+extern "C" int  camera_device_open(
+  const struct hw_module_t* module, const char* id,
+          struct hw_device_t** hw_device)
+{
+    int rc = -1;
+	int mode = 0; // TODO: need to add 3d/2d mode, etc
+    camera_device *device = NULL;
+    if(module && id && hw_device) {
+        int cameraId = atoi(id);
+
+        if (!strcmp(module->name, camera_common.name)) {
+            camera_hardware_t *camHal =
+                (camera_hardware_t *) malloc(sizeof (camera_hardware_t));
+            if(!camHal) {
+                *hw_device = NULL;
+				    LOGE("%s:  end in no mem", __func__);
+				    return rc;
+		    }
+            /* we have the camera_hardware obj malloced */
+            memset(camHal, 0, sizeof (camera_hardware_t));
+            camHal->hardware = new QCameraHardwareInterface(cameraId, mode); //HAL_openCameraHardware(cameraId);
+            if (camHal->hardware && camHal->hardware->isCameraReady()) {
+				camHal->cameraId = cameraId;
+		        device = &camHal->hw_dev;
+                device->common.close = close_camera_device;
+                device->ops = &camera_ops;
+                device->priv = (void *)camHal;
+                rc =  0;
+            } else {
+                if (camHal->hardware) {
+                    delete camHal->hardware;
+                    camHal->hardware = NULL;
+                }
+                free(camHal);
+                device = NULL;
+            }
+        }
+    }
+	/* pass actual hw_device ptr to framework. This amkes that we actally be use memberof() macro */
+    *hw_device = (hw_device_t*)&device->common;
+    LOGE("%s:  end rc %d", __func__, rc);
+    return rc;
+}
+
+extern "C"  int close_camera_device( hw_device_t *hw_dev)
+{
+    LOGE("Q%s: device =%p E", __func__, hw_dev);
+    int rc =  -1;
+    camera_device_t *device = (camera_device_t *)hw_dev;
+
+    if(device) {
+        camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
+        if(camHal ) {
+            QCameraHardwareInterface *hardware = util_get_Hal_obj( device);
+            if(!camHal->camera_released) {
+                if(hardware != NULL) {
+                    hardware->release( );
+                }
+            }
+            if(hardware != NULL)
+                delete hardware;
+            free(camHal);
+        }
+        rc = 0;
+    }
+    return rc;
+}
+
+
+int set_preview_window(struct camera_device * device,
+        struct preview_stream_ops *window)
+{
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+
+    if(hardware != NULL) {
+        rc = hardware->setPreviewWindow(window);
+    }
+    return rc;
+}
+
+void set_CallBacks(struct camera_device * device,
+        camera_notify_callback notify_cb,
+        camera_data_callback data_cb,
+        camera_data_timestamp_callback data_cb_timestamp,
+        camera_request_memory get_memory,
+        void *user)
+{
+    LOGE("Q%s: E", __func__);
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        hardware->setCallbacks(notify_cb,data_cb, data_cb_timestamp, get_memory, user);
+    }
+}
+
+void enable_msg_type(struct camera_device * device, int32_t msg_type)
+{
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        hardware->enableMsgType(msg_type);
+    }
+}
+
+void disable_msg_type(struct camera_device * device, int32_t msg_type)
+{
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    LOGE("Q%s: E", __func__);
+    if(hardware != NULL){
+        hardware->disableMsgType(msg_type);
+    }
+}
+
+int msg_type_enabled(struct camera_device * device, int32_t msg_type)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->msgTypeEnabled(msg_type);
+    }
+    return rc;
+}
+
+int start_preview(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->startPreview( );
+    }
+    LOGE("Q%s: X", __func__);
+    return rc;
+}
+
+void stop_preview(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        hardware->stopPreview( );
+    }
+}
+
+int preview_enabled(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->previewEnabled( );
+    }
+    return rc;
+}
+
+int store_meta_data_in_buffers(struct camera_device * device, int enable)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+      rc = hardware->storeMetaDataInBuffers(enable);
+    }
+    return rc;
+}
+
+int start_recording(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->startRecording( );
+    }
+    return rc;
+}
+
+void stop_recording(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        hardware->stopRecording( );
+    }
+}
+
+int recording_enabled(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->recordingEnabled( );
+    }
+    return rc;
+}
+
+void release_recording_frame(struct camera_device * device,
+                const void *opaque)
+{
+    LOGV("Q%s: E", __func__);
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        hardware->releaseRecordingFrame(opaque);
+    }
+}
+
+int auto_focus(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->autoFocus( );
+    }
+    return rc;
+}
+
+int cancel_auto_focus(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->cancelAutoFocus( );
+    }
+    return rc;
+}
+
+int take_picture(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->takePicture( );
+    }
+    return rc;
+}
+
+int cancel_picture(struct camera_device * device)
+
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->cancelPicture( );
+    }
+    return rc;
+}
+
+int set_parameters(struct camera_device * device, const char *parms)
+
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL && parms){
+        //CameraParameters param;// = util_get_HAL_parameter(device);
+        //String8 str = String8(parms);
+
+        //param.unflatten(str);
+        rc = hardware->setParameters(parms);
+        //rc = 0;
+  }
+  return rc;
+}
+
+char* get_parameters(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+		char *parms = NULL;
+        hardware->getParameters(&parms);
+		return parms;
+    }
+    return NULL;
+}
+
+void put_parameters(struct camera_device * device, char *parm)
+
+{
+    LOGE("Q%s: E", __func__);
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+      hardware->putParameters(parm);
+    }
+}
+
+int send_command(struct camera_device * device,
+            int32_t cmd, int32_t arg1, int32_t arg2)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->sendCommand( cmd, arg1, arg2);
+    }
+    return rc;
+}
+
+void release(struct camera_device * device)
+{
+    LOGE("Q%s: E", __func__);
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
+        hardware->release( );
+        camHal->camera_released = true;
+    }
+}
+
+int dump(struct camera_device * device, int fd)
+{
+    LOGE("Q%s: E", __func__);
+    int rc = -1;
+    QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
+    if(hardware != NULL){
+        rc = hardware->dump( fd );
+      //rc = 0;
+    }
+    return rc;
+}
+
+}; // namespace android
diff --git a/camera/QCamera/HAL/wrapper/QualcommCamera.h b/camera/QCamera/HAL/wrapper/QualcommCamera.h
new file mode 100755
index 0000000..81dbf93
--- /dev/null
+++ b/camera/QCamera/HAL/wrapper/QualcommCamera.h
@@ -0,0 +1,108 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef ANDROID_HARDWARE_QUALCOMM_CAMERA_H
+#define ANDROID_HARDWARE_QUALCOMM_CAMERA_H
+
+
+#include "QCameraHWI.h"
+
+extern "C" {
+/*#include <hardware/camera.h>*/
+
+  int get_number_of_cameras();
+  int get_camera_info(int camera_id, struct camera_info *info);
+
+  int camera_device_open(const struct hw_module_t* module, const char* id,
+          struct hw_device_t** device);
+
+  hw_device_t * open_camera_device(int cameraId);
+
+  int close_camera_device( hw_device_t *);
+
+namespace android {
+  int set_preview_window(struct camera_device *,
+          struct preview_stream_ops *window);
+  void set_CallBacks(struct camera_device *,
+          camera_notify_callback notify_cb,
+          camera_data_callback data_cb,
+          camera_data_timestamp_callback data_cb_timestamp,
+          camera_request_memory get_memory,
+          void *user);
+
+  void enable_msg_type(struct camera_device *, int32_t msg_type);
+
+  void disable_msg_type(struct camera_device *, int32_t msg_type);
+  int msg_type_enabled(struct camera_device *, int32_t msg_type);
+
+  int start_preview(struct camera_device *);
+
+  void stop_preview(struct camera_device *);
+
+  int preview_enabled(struct camera_device *);
+  int store_meta_data_in_buffers(struct camera_device *, int enable);
+
+  int start_recording(struct camera_device *);
+
+  void stop_recording(struct camera_device *);
+
+  int recording_enabled(struct camera_device *);
+
+  void release_recording_frame(struct camera_device *,
+                  const void *opaque);
+
+  int auto_focus(struct camera_device *);
+
+  int cancel_auto_focus(struct camera_device *);
+
+  int take_picture(struct camera_device *);
+
+  int cancel_picture(struct camera_device *);
+
+  int set_parameters(struct camera_device *, const char *parms);
+
+  char* get_parameters(struct camera_device *);
+
+  void put_parameters(struct camera_device *, char *);
+
+  int send_command(struct camera_device *,
+              int32_t cmd, int32_t arg1, int32_t arg2);
+
+  void release(struct camera_device *);
+
+  int dump(struct camera_device *, int fd);
+
+
+
+}; // namespace android
+
+} //extern "C"
+
+#endif
+
diff --git a/camera/QCamera/stack/Android.mk b/camera/QCamera/stack/Android.mk
new file mode 100755
index 0000000..c7307a7
--- /dev/null
+++ b/camera/QCamera/stack/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH:= $(call my-dir)
+include $(LOCAL_PATH)/mm-camera-interface/Android.mk
+include $(LOCAL_PATH)/mm-camera-test/Android.mk
+#include $(LOCAL_PATH)/mm-jpeg-interface/Android.mk
diff --git a/camera/QCamera/stack/common/cam_list.h b/camera/QCamera/stack/common/cam_list.h
new file mode 100755
index 0000000..87ad6cf
--- /dev/null
+++ b/camera/QCamera/stack/common/cam_list.h
@@ -0,0 +1,74 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* This file is a slave copy from /vendor/qcom/propreitary/mm-cammera/common,
+ * Please do not modify it directly here. */
+
+#ifndef __CAMLIST_H
+#define __CAMLIST_H
+
+#include <stddef.h>
+
+#define member_of(ptr, type, member) ({ \
+  const typeof(((type *)0)->member) *__mptr = (ptr); \
+  (type *)((char *)__mptr - offsetof(type,member));})
+
+struct cam_list {
+  struct cam_list *next, *prev;
+};
+
+static inline void cam_list_init(struct cam_list *ptr)
+{
+  ptr->next = ptr;
+  ptr->prev = ptr;
+}
+
+static inline void cam_list_add_tail_node(struct cam_list *item,
+  struct cam_list *head)
+{
+  struct cam_list *prev = head->prev;
+
+  head->prev = item;
+  item->next = head;
+  item->prev = prev;
+  prev->next = item;
+}
+
+static inline void cam_list_del_node(struct cam_list *ptr)
+{
+  struct cam_list *prev = ptr->prev;
+  struct cam_list *next = ptr->next;
+
+  next->prev = ptr->prev;
+  prev->next = ptr->next;
+  ptr->next = ptr;
+  ptr->prev = ptr;
+}
+
+#endif /* __CAMLIST_H */
diff --git a/camera/QCamera/stack/mm-camera-interface/Android.mk b/camera/QCamera/stack/mm-camera-interface/Android.mk
new file mode 100755
index 0000000..1464eff
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/Android.mk
@@ -0,0 +1,61 @@
+#ifeq ($(call is-board-platform,msm8960),true)

+OLD_LOCAL_PATH := $(LOCAL_PATH)

+LOCAL_PATH := $(call my-dir)

+USE_BIONIC_HEADER:=true

+

+include $(CLEAR_VARS)

+

+MM_CAM_FILES := \

+        src/mm_camera_interface.c \

+        src/mm_camera_stream.c \

+        src/mm_camera_channel.c \

+        src/mm_camera.c \

+        src/mm_camera_thread.c \

+        src/mm_camera_data.c \

+        src/mm_camera_sock.c \

+        src/mm_camera_helper.c

+

+LOCAL_CFLAGS += -D_ANDROID_

+LOCAL_COPY_HEADERS_TO := mm-camera-interface_badger

+LOCAL_COPY_HEADERS := inc/mm_camera_interface.h

+

+LOCAL_C_INCLUDES := \

+    $(LOCAL_PATH)/inc \

+    $(LOCAL_PATH)/../common \

+    $(LOCAL_PATH)/../../../ \

+    $(TARGET_OUT_HEADERS)/mm-camera \

+    $(TARGET_OUT_HEADERS)/mm-camera/common

+

+ifneq ($(strip $(USE_BIONIC_HEADER)),true)

+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include

+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/media

+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr

+endif

+

+# (BEGIN) Need to remove later once dependency on jpeg removed

+LOCAL_C_INCLUDES += \

+    $(TARGET_OUT_HEADERS)/mm-still \

+    $(TARGET_OUT_HEADERS)/mm-still/jpeg \

+    $(TARGET_OUT_HEADERS)/mm-core/omxcore \

+    $(TARGET_OUT_HEADERS)/mm-still/mm-omx

+# (END) Need to remove later once dependency on jpeg removed

+

+LOCAL_C_INCLUDES+= hardware/qcom/media/mm-core/inc

+LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/socket.h

+LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/un.h

+

+LOCAL_SRC_FILES := $(MM_CAM_FILES)

+

+LOCAL_MODULE           := libmmcamera_interface_badger

+LOCAL_PRELINK_MODULE   := false

+LOCAL_SHARED_LIBRARIES := libdl libcutils liblog

+LOCAL_MODULE_TAGS := optional

+

+# (BEGIN) Need to remove later once dependency on jpeg removed

+# LOCAL_SHARED_LIBRARIES += libmmjpeg_interface

+# (END) Need to remove later once dependency on jpeg removed

+

+include $(BUILD_SHARED_LIBRARY)

+

+LOCAL_PATH := $(OLD_LOCAL_PATH)

+#endif

diff --git a/camera/QCamera/stack/mm-camera-interface/inc/mm_camera.h b/camera/QCamera/stack/mm-camera-interface/inc/mm_camera.h
new file mode 100755
index 0000000..1a46acf
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/inc/mm_camera.h
@@ -0,0 +1,619 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MM_CAMERA_H__
+#define __MM_CAMERA_H__
+
+#include "mm_camera_interface.h"
+
+/**********************************************************************************
+* Data structure declare
+***********************************************************************************/
+/* num of streams allowed in a channel obj */
+#define MM_CAMEAR_STRAEM_NUM_MAX 8
+/* num of channels allowed in a camera obj */
+#define MM_CAMERA_CHANNEL_MAX 1
+/* num of callbacks allowed for an event type */
+#define MM_CAMERA_EVT_ENTRY_MAX 4
+/* num of data callbacks allowed in a stream obj */
+#define MM_CAMERA_STREAM_BUF_CB_MAX 4
+/* num of data poll threads allowed in a channel obj */
+#define MM_CAMERA_CHANNEL_POLL_THREAD_MAX 1
+
+#define MM_CAMERA_DEV_NAME_LEN 32
+#define MM_CAMERA_DEV_OPEN_TRIES 2
+#define MM_CAMERA_DEV_OPEN_RETRY_SLEEP 20
+
+struct mm_channel;
+struct mm_stream;
+struct mm_camera_obj;
+
+/* common use */
+typedef struct {
+    struct cam_list list;
+    void* data;
+} mm_camera_q_node_t;
+
+typedef struct {
+    mm_camera_q_node_t head; /* dummy head */
+    uint32_t size;
+    pthread_mutex_t lock;
+} mm_camera_queue_t;
+
+typedef enum 
+{
+    MM_CAMERA_ASYNC_CMD_TYPE_STOP,    /* async stop */
+    MM_CAMERA_ASYNC_CMD_TYPE_MAX
+} mm_camera_async_cmd_type_t;
+
+typedef struct {
+    struct mm_channel* ch_obj;
+    uint8_t num_streams;
+    uint32_t stream_ids[MM_CAMEAR_STRAEM_NUM_MAX];
+} mm_camera_async_stop_cmd_t;
+
+typedef struct {
+    mm_camera_async_cmd_type_t cmd_type;
+    union {
+        mm_camera_async_stop_cmd_t stop_cmd;
+    } u;
+} mm_camera_async_cmd_t;
+
+typedef enum 
+{
+    MM_CAMERA_CMD_TYPE_DATA_CB,    /* dataB CMD */
+    MM_CAMERA_CMD_TYPE_EVT_CB,     /* evtCB CMD */
+    MM_CAMERA_CMD_TYPE_ASYNC_CB,   /* asyncCB CMD */
+    MM_CAMERA_CMD_TYPE_EXIT,       /* EXIT */
+    MM_CAMERA_CMD_TYPE_REQ_DATA_CB,/* request data */
+    MM_CAMERA_CMD_TYPE_MAX
+} mm_camera_cmdcb_type_t;
+
+typedef struct {
+    uint32_t stream_id;
+    uint32_t frame_idx;
+    uint8_t need_pp; /* flag if pp needed on this buf */
+    mm_camera_buf_def_t *buf; /* ref to buf */
+} mm_camera_buf_info_t;
+
+typedef struct {
+    mm_camera_cmdcb_type_t cmd_type;
+    union {
+        mm_camera_buf_info_t buf;    /* frame buf if dataCB */
+        mm_camera_event_t evt;       /* evt if evtCB */
+        mm_camera_async_cmd_t async; /* async cmd */
+    } u;
+} mm_camera_cmdcb_t;
+
+typedef void (*mm_camera_cmd_cb_t)(mm_camera_cmdcb_t * cmd_cb, void* user_data);
+
+typedef struct {
+    mm_camera_queue_t cmd_queue; /* cmd queue (queuing dataCB, asyncCB, or exitCMD) */
+    pthread_t cmd_pid;           /* cmd thread ID */
+    sem_t cmd_sem;               /* semaphore for cmd thread */
+    mm_camera_cmd_cb_t cb;       /* cb for cmd */
+    void* user_data;             /* user_data for cb */
+} mm_camera_cmd_thread_t;
+
+typedef enum {
+    MM_CAMERA_POLL_TYPE_EVT,
+    MM_CAMERA_POLL_TYPE_CH,
+    MM_CAMERA_POLL_TYPE_MAX

+} mm_camera_poll_thread_type_t;
+

+/* function ptr defined for poll notify CB,
+ * registered at poll thread with poll fd */
+typedef void (*mm_camera_poll_notify_t)(void *user_data);
+
+typedef struct {
+    int32_t fd;
+    mm_camera_poll_notify_t notify_cb;
+    uint32_t handler;
+    void* user_data;
+} mm_camera_poll_entry_t;
+
+typedef struct {
+    mm_camera_poll_thread_type_t poll_type;
+    /* array to store poll fd and cb info
+     * for MM_CAMERA_POLL_TYPE_EVT, only index 0 is valid;
+     * for MM_CAMERA_POLL_TYPE_CH, depends on valid stream fd */
+    mm_camera_poll_entry_t poll_entries[MM_CAMEAR_STRAEM_NUM_MAX];
+    int32_t pfds[2];
+    pthread_t pid;
+    int32_t state;
+    int timeoutms;
+    uint32_t cmd;
+    struct pollfd poll_fds[MM_CAMEAR_STRAEM_NUM_MAX+1];
+    uint8_t num_fds;
+    pthread_mutex_t mutex;
+    pthread_cond_t cond_v;
+    int32_t status;
+    //void *my_obj;
+} mm_camera_poll_thread_t;
+
+/* mm_stream */
+typedef enum {
+    MM_STREAM_STATE_NOTUSED = 0,      /* not used */
+    MM_STREAM_STATE_INITED,           /* inited  */
+    MM_STREAM_STATE_ACQUIRED,         /* acquired, fd opened  */
+    MM_STREAM_STATE_CFG,              /* fmt & dim configured */
+    MM_STREAM_STATE_BUFFED,           /* buf allocated */
+    MM_STREAM_STATE_REG,              /* buf regged, stream off */
+    MM_STREAM_STATE_ACTIVE_STREAM_ON, /* active with stream on */
+    MM_STREAM_STATE_ACTIVE_STREAM_OFF, /* active with stream off */
+    MM_STREAM_STATE_MAX
+} mm_stream_state_type_t;
+
+typedef enum {
+    MM_STREAM_EVT_ACQUIRE,
+    MM_STREAM_EVT_RELEASE,
+    MM_STREAM_EVT_SET_FMT,
+    MM_STREAM_EVT_GET_BUF,
+    MM_STREAM_EVT_PUT_BUF,
+    MM_STREAM_EVT_REG_BUF,
+    MM_STREAM_EVT_UNREG_BUF,
+    MM_STREAM_EVT_START,
+    MM_STREAM_EVT_STOP,
+    MM_STREAM_EVT_QBUF,
+    MM_STREAM_EVT_SET_PARM,
+    MM_STREAM_EVT_GET_PARM,
+    MM_STREAM_EVT_MAX
+} mm_stream_evt_type_t;
+
+typedef struct {
+    mm_camera_buf_notify_t cb;
+    void *user_data;
+    /* cb_count = -1: infinite
+     * cb_count > 0: register only for required times */
+    int8_t cb_count;
+} mm_stream_data_cb_t;
+
+typedef struct {
+    /* buf reference count */
+    uint8_t buf_refcnt;
+
+    /* This flag is to indicate if after allocation,
+     * the corresponding buf needs to qbuf into kernel
+     * (e.g. for preview usecase, display needs to hold two bufs,
+     * so no need to qbuf these two bufs initially) */
+    uint8_t initial_reg_flag;
+
+    /* indicate if buf is in kernel(1) or client(0) */
+    uint8_t in_kernel;
+} mm_stream_buf_status_t;
+
+typedef struct mm_stream {
+    uint32_t my_hdl;
+    uint32_t inst_hdl;
+    int32_t fd;
+    mm_stream_state_type_t state;
+
+    /* ext_image_mode used as id for stream obj */
+    uint32_t ext_image_mode;
+
+    /* sensor index used */
+    uint32_t sensor_idx;
+
+    mm_camera_image_fmt_t fmt;
+
+    mm_camera_cmd_thread_t cmd_thread;
+
+    /* dataCB registered on this stream obj */
+    pthread_mutex_t cb_lock; /* cb lock to protect buf_cb */
+    mm_stream_data_cb_t buf_cb[MM_CAMERA_STREAM_BUF_CB_MAX];
+
+    /* stream buffer management */
+    pthread_mutex_t buf_lock;
+    uint8_t buf_num; /* num of buffers allocated */
+    mm_camera_buf_def_t* buf; /* ptr to buf array */
+    mm_stream_buf_status_t* buf_status; /* ptr to buf status array */
+
+    /* reference to parent channel_obj */
+    struct mm_channel* ch_obj;
+
+    uint8_t is_bundled; /* flag if stream is bundled */
+    uint8_t is_pp_needed; /* flag if need to do post processing, set when streamon */
+    uint8_t is_local_buf; /* flag if buf is local copy, no need to qbuf to kernel */
+    uint8_t hal_requested_num_bufs;
+    uint8_t need_stream_on; /* flag if stream need streamon when start */
+
+    mm_camera_frame_len_offset frame_offset; /*Stream buffer offset information*/
+} mm_stream_t;
+
+/* mm_channel */
+typedef enum {
+    MM_CHANNEL_STATE_NOTUSED = 0,   /* not used */
+    MM_CHANNEL_STATE_STOPPED,       /* stopped */
+    MM_CHANNEL_STATE_ACTIVE,        /* active, at least one stream active */
+    MM_CHANNEL_STATE_PAUSED,        /* paused */
+    MM_CHANNEL_STATE_MAX
+} mm_channel_state_type_t;
+
+typedef enum {
+    MM_CHANNEL_EVT_ADD_STREAM,
+    MM_CHANNEL_EVT_DEL_STREAM,
+    MM_CHANNEL_EVT_START_STREAM,
+    MM_CHANNEL_EVT_STOP_STREAM,
+    MM_CHANNEL_EVT_TEARDOWN_STREAM,
+    MM_CHANNEL_EVT_CONFIG_STREAM,
+    MM_CHANNEL_EVT_PAUSE,
+    MM_CHANNEL_EVT_RESUME,
+    MM_CHANNEL_EVT_INIT_BUNDLE,
+    MM_CHANNEL_EVT_DESTROY_BUNDLE,
+    MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
+    MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
+    MM_CHANNEL_EVT_START_FOCUS,
+    MM_CHANNEL_EVT_ABORT_FOCUS,
+    MM_CHANNEL_EVT_PREPARE_SNAPSHOT,
+    MM_CHANNEL_EVT_SET_STREAM_PARM,
+    MM_CHANNEL_EVT_GET_STREAM_PARM,
+    MM_CHANNEL_EVT_DELETE,
+    MM_CHANNEL_EVT_MAX
+} mm_channel_evt_type_t;
+
+typedef struct {
+    mm_camera_buf_notify_t buf_cb;
+    void *user_data;
+    uint32_t ext_image_mode;
+    uint32_t sensor_idx;
+} mm_evt_paylod_add_stream_t;
+
+typedef struct {
+    uint32_t stream_id;
+    mm_camera_stream_config_t *config;
+} mm_evt_paylod_config_stream_t;
+
+typedef struct {
+    mm_camera_stream_parm_t parm_type;
+    void *value;
+} mm_evt_paylod_stream_parm_t;
+
+typedef struct {
+    mm_camera_buf_notify_t super_frame_notify_cb;
+    void *user_data;
+    mm_camera_bundle_attr_t *attr;
+    uint8_t num_streams;
+    uint32_t *stream_ids;
+} mm_evt_payload_bundle_stream_t;
+
+typedef struct {
+    uint8_t num_streams;
+    uint32_t *stream_ids;
+} mm_evt_payload_start_stream_t;
+
+typedef struct {
+    uint8_t num_streams;
+    uint32_t *stream_ids;
+} mm_evt_payload_stop_stream_t;
+
+typedef struct {
+    uint32_t sensor_idx;
+    uint32_t focus_mode;
+} mm_evt_payload_start_focus_t;
+
+typedef struct {
+    uint8_t num_of_bufs;
+    mm_camera_buf_info_t super_buf[MM_CAMEAR_MAX_STRAEM_BUNDLE];
+    uint8_t matched;
+} mm_channel_queue_node_t;
+
+typedef struct {
+    mm_camera_queue_t que;
+    uint8_t num_streams;
+    /* container for bundled stream handlers */
+    uint32_t bundled_streams[MM_CAMEAR_MAX_STRAEM_BUNDLE];
+    mm_camera_bundle_attr_t attr;
+    uint32_t expected_frame_id;
+    uint32_t match_cnt;
+} mm_channel_queue_t;
+
+typedef struct {
+    /* queue to store bundled super buffers */
+    mm_channel_queue_t superbuf_queue;
+    mm_camera_buf_notify_t super_buf_notify_cb;
+    void *user_data;
+} mm_channel_bundle_t;
+
+typedef struct mm_channel {
+    uint32_t my_hdl;
+    mm_channel_state_type_t state;
+    pthread_mutex_t ch_lock; /* channel lock */
+
+    /* stream bundle info in the channel */
+    mm_channel_bundle_t bundle;
+
+    /* num of pending suferbuffers */
+    uint32_t pending_cnt;
+    uint32_t pending_pp_cnt; /*pending cnt for post processing frames */
+
+    /* cmd thread for superbuffer dataCB and async stop*/
+    mm_camera_cmd_thread_t cmd_thread;
+
+    /* data poll thread
+    * currently one data poll thread per channel
+    * could extended to support one data poll thread per stream in the channel */
+    mm_camera_poll_thread_t poll_thread[MM_CAMERA_CHANNEL_POLL_THREAD_MAX];
+
+    /* container for all streams in channel
+    * stream is indexed by ext_image_mode */
+    mm_stream_t streams[MM_CAMEAR_STRAEM_NUM_MAX];
+
+    /* reference to parent cam_obj */
+    struct mm_camera_obj* cam_obj;
+} mm_channel_t;
+
+/* struct to store information about pp cookie*/
+typedef struct {
+    uint32_t cam_hdl;
+    uint32_t ch_hdl;
+    uint32_t stream_hdl;
+    mm_channel_queue_node_t* super_buf;
+} mm_channel_pp_info_t;
+
+/* mm_camera */
+typedef struct {
+    mm_camera_event_notify_t evt_cb;
+    void *user_data;
+} mm_camera_evt_entry_t;
+
+typedef struct {
+    mm_camera_evt_entry_t evt[MM_CAMERA_EVT_ENTRY_MAX];
+    /* reg_count <=0: infinite
+     * reg_count > 0: register only for required times */
+    int reg_count;
+} mm_camera_evt_obj_t;
+
+typedef struct mm_camera_obj {
+    uint32_t my_hdl;
+    int ref_count;
+    int32_t ctrl_fd;
+    int32_t ds_fd; /* domain socket fd */
+    cam_prop_t properties;
+    mm_camera_2nd_sensor_t second_sensor; /*second sensor info */
+    pthread_mutex_t cam_lock;
+    pthread_mutex_t cb_lock; /* lock for evt cb */
+    mm_channel_t ch[MM_CAMERA_CHANNEL_MAX];
+    mm_camera_evt_obj_t evt[MM_CAMERA_EVT_TYPE_MAX];
+    uint32_t evt_type_mask;
+    mm_camear_mem_vtbl_t *mem_vtbl; /* vtable for memory management */
+    mm_camera_poll_thread_t evt_poll_thread; /* evt poll thread */
+    mm_camera_cmd_thread_t evt_thread;       /* thread for evt CB */
+    mm_camera_cmd_thread_t async_cmd_thread; /* thread for async cmd */
+    mm_camera_vtbl_t vtbl;
+
+    /* some local variables */
+    uint32_t snap_burst_num_by_user;
+    camera_mode_t current_mode;
+    uint8_t need_pp;
+    uint32_t op_mode;
+    cam_ctrl_dimension_t dim;
+} mm_camera_obj_t;
+
+typedef struct {
+    mm_camera_info_t camera[MSM_MAX_CAMERA_SENSORS];
+    int8_t num_cam;
+    char video_dev_name[MSM_MAX_CAMERA_SENSORS][MM_CAMERA_DEV_NAME_LEN];
+    mm_camera_obj_t *cam_obj[MSM_MAX_CAMERA_SENSORS];
+} mm_camera_ctrl_t;
+
+/**********************************************************************************
+* external function declare
+***********************************************************************************/
+/* utility functions */
+/* set int32_t value */
+extern int32_t mm_camera_util_s_ctrl(int32_t fd,
+                                     uint32_t id,
+                                     int32_t value);
+
+extern int32_t mm_camera_util_private_s_ctrl( int32_t fd,
+                                              uint32_t id, void* value);
+
+/* get int32_t value */
+extern int32_t mm_camera_util_g_ctrl(int32_t fd,
+                                     uint32_t id,int32_t *value);
+
+/* send msg throught domain socket for fd mapping */
+extern int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
+                                      void *msg,
+                                      uint32_t buf_size,
+                                      int sendfd);
+
+/* mm-camera */
+extern int32_t mm_camera_open(mm_camera_obj_t *my_obj);
+extern int32_t mm_camera_close(mm_camera_obj_t *my_obj);
+extern uint8_t mm_camera_is_event_supported(mm_camera_obj_t *my_obj,
+                                            mm_camera_event_type_t evt_type);
+extern int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
+                                               mm_camera_event_notify_t evt_cb,
+                                               void * user_data,
+                                               mm_camera_event_type_t evt_type);
+extern int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
+                              uint32_t ch_id,
+                              mm_camera_buf_def_t *buf);
+extern mm_camera_2nd_sensor_t * mm_camera_query_2nd_sensor_info(mm_camera_obj_t *my_obj);
+extern int32_t mm_camera_sync(mm_camera_obj_t *my_obj);
+extern int32_t mm_camera_is_parm_supported(mm_camera_obj_t *my_obj,
+                                           mm_camera_parm_type_t parm_type,
+                                           uint8_t *support_set_parm,
+                                           uint8_t *support_get_parm);
+extern int32_t mm_camera_set_parm(mm_camera_obj_t *my_obj,
+                                  mm_camera_parm_type_t parm_type,
+                                  void* p_value);
+extern int32_t mm_camera_get_parm(mm_camera_obj_t *my_obj,
+                                  mm_camera_parm_type_t parm_type,
+                                  void* p_value);
+extern uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj);
+extern void mm_camera_del_channel(mm_camera_obj_t *my_obj,
+                                  uint32_t ch_id);
+extern uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
+                                     uint32_t ch_id,
+                                     mm_camera_buf_notify_t buf_cb, void *user_data,
+                                     uint32_t ext_image_mode, uint32_t sensor_idx);
+extern int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
+                                    uint32_t ch_id,
+                                    uint32_t stream_id);
+extern int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
+                                       uint32_t ch_id,
+                                       uint32_t stream_id,
+                                       mm_camera_stream_config_t *config);
+extern int32_t mm_camera_bundle_streams(mm_camera_obj_t *my_obj,
+                                        uint32_t ch_id,
+                                        mm_camera_buf_notify_t super_frame_notify_cb,
+                                        void *user_data,
+                                        mm_camera_bundle_attr_t *attr,
+                                        uint8_t num_streams,
+                                        uint32_t *stream_ids);
+extern int32_t mm_camera_destroy_bundle(mm_camera_obj_t *my_obj,
+                                        uint32_t ch_id);
+extern int32_t mm_camera_start_streams(mm_camera_obj_t *my_obj,
+                                       uint32_t ch_id,
+                                       uint8_t num_streams,
+                                       uint32_t *stream_ids);
+extern int32_t mm_camera_stop_streams(mm_camera_obj_t *my_obj,
+                                      uint32_t ch_id,
+                                      uint8_t num_streams,
+                                      uint32_t *stream_ids);
+extern int32_t mm_camera_async_teardown_streams(mm_camera_obj_t *my_obj,
+                                                uint32_t ch_id,
+                                                uint8_t num_streams,
+                                                uint32_t *stream_ids);
+extern int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
+                                           uint32_t ch_id);
+extern int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj,
+                                                  uint32_t ch_id);
+extern int32_t mm_camera_start_focus(mm_camera_obj_t *my_obj,
+                                     uint32_t ch_id,
+                                     uint32_t sensor_idx,
+                                     uint32_t focus_mode);
+extern int32_t mm_camera_abort_focus(mm_camera_obj_t *my_obj,
+                                     uint32_t ch_id,
+                                     uint32_t sensor_idx);
+extern int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
+                                          uint32_t ch_id,
+                                          uint32_t sensor_idx);
+extern int32_t mm_camera_set_stream_parm(mm_camera_obj_t *my_obj,
+                                  uint32_t ch_id,
+                                  uint32_t s_id,
+                                  mm_camera_stream_parm_t parm_type,
+                                  void* p_value);
+
+extern int32_t mm_camera_get_stream_parm(mm_camera_obj_t *my_obj,
+                                  uint32_t ch_id,
+                                  uint32_t s_id,
+                                  mm_camera_stream_parm_t parm_type,
+                                  void* p_value);
+
+extern int32_t mm_camera_register_event_notify_internal(
+                                   mm_camera_obj_t *my_obj,
+                                   mm_camera_event_notify_t evt_cb,
+                                   void * user_data,
+                                   mm_camera_event_type_t evt_type);
+extern int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
+                                 int ext_mode,
+                                 int idx,
+                                 int fd,
+                                 uint32_t size);
+extern int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
+                                   int ext_mode,
+                                   int idx);
+extern int32_t mm_camera_send_ch_event(mm_camera_obj_t *my_obj,
+                                       uint32_t ch_id,
+                                       uint32_t stream_id,
+                                       mm_camera_ch_event_type_t evt);
+
+
+/* mm_channel */
+extern int32_t mm_channel_fsm_fn(mm_channel_t *my_obj,
+                                 mm_channel_evt_type_t evt,
+                                 void * in_val,
+                                 void * out_val);
+
+/* qbuf is a special case that not going through state machine.
+ * This is to avoid deadlock when trying to aquire ch_lock,
+ * from the context of dataCB, but async stop is holding ch_lock */
+extern int32_t mm_channel_qbuf(mm_channel_t *my_obj,
+                               mm_camera_buf_def_t *buf);
+
+/* Allow other stream to register dataCB at certain stream.
+ * This is for use case of video sized live snapshot,
+ * because snapshot stream need register one time CB at video stream.
+ * ext_image_mode and sensor_idx are used to identify the destinate stream
+ * to be register with dataCB. */
+extern int32_t mm_channel_reg_stream_cb(mm_channel_t *my_obj,
+                                        mm_stream_data_cb_t *cb,
+                                        uint32_t ext_image_mode,
+                                        uint32_t sensor_idx);
+
+/* mm_stream */
+extern int32_t mm_stream_fsm_fn(mm_stream_t *my_obj,
+                                mm_stream_evt_type_t evt,
+                                void * in_val,
+                                void * out_val);
+/* Allow other stream to register dataCB at certain stream.
+ * This is for use case of video sized live snapshot,
+ * because snapshot stream need register one time CB at video stream.
+ * ext_image_mode and sensor_idx are used to identify the destinate stream
+ * to be register with dataCB. */
+extern int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
+                                    mm_stream_data_cb_t *val);
+
+/* utiltity fucntion declared in mm-camera-inteface2.c
+ * and need be used by mm-camera and below*/
+uint32_t mm_camera_util_generate_handler(uint8_t index);
+const char * mm_camera_util_get_dev_name(uint32_t cam_handler);
+uint8_t mm_camera_util_get_index_by_handler(uint32_t handler);
+
+/* queue functions */
+extern int32_t mm_camera_queue_init(mm_camera_queue_t* queue);
+extern int32_t mm_camera_queue_enq(mm_camera_queue_t* queue, void* node);
+extern void* mm_camera_queue_deq(mm_camera_queue_t* queue);
+extern int32_t mm_camera_queue_deinit(mm_camera_queue_t* queue);
+extern int32_t mm_camera_queue_flush(mm_camera_queue_t* queue);
+
+/* poll/cmd thread functions */
+extern int32_t mm_camera_poll_thread_launch(
+                                mm_camera_poll_thread_t * poll_cb,
+                                mm_camera_poll_thread_type_t poll_type);
+extern int32_t mm_camera_poll_thread_release(mm_camera_poll_thread_t *poll_cb);
+extern int32_t mm_camera_poll_thread_add_poll_fd(
+                                mm_camera_poll_thread_t * poll_cb,
+                                uint32_t handler,
+                                int32_t fd,
+                                mm_camera_poll_notify_t nofity_cb,
+                                void *userdata);
+extern int32_t mm_camera_poll_thread_del_poll_fd(
+                                mm_camera_poll_thread_t * poll_cb,
+                                uint32_t handler);
+extern int32_t mm_camera_cmd_thread_launch(
+                                mm_camera_cmd_thread_t * cmd_thread,
+                                mm_camera_cmd_cb_t cb,
+                                void* user_data);
+extern int32_t mm_camera_cmd_thread_release(mm_camera_cmd_thread_t * cmd_thread);
+
+#endif /* __MM_CAMERA_H__ */
diff --git a/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_dbg.h b/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_dbg.h
new file mode 100755
index 0000000..f701658
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_dbg.h
@@ -0,0 +1,70 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MM_CAMERA_DBG_H__
+#define __MM_CAMERA_DBG_H__
+
+#define LOG_DEBUG 1
+
+#ifndef LOG_DEBUG
+  #ifdef _ANDROID_
+    #undef LOG_NIDEBUG
+    #undef LOG_TAG
+    #define LOG_NIDEBUG 0
+    #define LOG_TAG "mm-libcamera2"
+    #include <utils/Log.h>
+  #else
+    #include <stdio.h>
+    #define ALOGE CDBG
+  #endif
+  #undef CDBG
+  #define CDBG(fmt, args...) do{}while(0)
+#else
+  #ifdef _ANDROID_
+    #undef LOG_NIDEBUG
+    #undef LOG_TAG
+    #define LOG_NIDEBUG 0
+    #define LOG_TAG "mm-libcamera2"
+    #include <utils/Log.h>
+    #define CDBG(fmt, args...) ALOGE(fmt, ##args)
+  #else
+    #include <stdio.h>
+    #define CDBG(fmt, args...) fprintf(stderr, fmt, ##args)
+    #define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args)
+  #endif
+#endif
+
+#ifdef _ANDROID_
+  #define CDBG_HIGH(fmt, args...)  ALOGE(fmt, ##args)
+  #define CDBG_ERROR(fmt, args...)  ALOGE(fmt, ##args)
+#else
+  #define CDBG_HIGH(fmt, args...) fprintf(stderr, fmt, ##args)
+  #define CDBG_ERROR(fmt, args...) fprintf(stderr, fmt, ##args)
+#endif
+#endif /* __MM_CAMERA_DBG_H__ */
diff --git a/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_interface.h b/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_interface.h
new file mode 100755
index 0000000..53d9b03
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_interface.h
@@ -0,0 +1,343 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MM_CAMERA_INTERFACE_H__
+#define __MM_CAMERA_INTERFACE_H__
+#include <linux/ion.h>
+#include <camera.h>
+#include <QCamera_Intf.h>
+#include "cam_list.h"
+
+#define MM_CAMERA_MAX_NUM_FRAMES 16
+#define MM_CAMEAR_MAX_STRAEM_BUNDLE 4
+#define MM_CAMERA_MAX_2ND_SENSORS 4
+
+typedef enum {
+    MM_CAMERA_WHITE_BALANCE_AUTO,
+    MM_CAMERA_WHITE_BALANCE_OFF,
+    MM_CAMERA_WHITE_BALANCE_DAYLIGHT,
+    MM_CAMERA_WHITE_BALANCE_INCANDESCENT,
+    MM_CAMERA_WHITE_BALANCE_FLUORESCENT,
+    MM_CAMERA_WHITE_BALANCE_CLOUDY,
+    MM_CAMERA_WHITE_BALANCE_MAX
+} mm_camera_white_balance_mode_type_t;
+
+typedef enum {
+    MM_CAMERA_STREAM_OFFSET,
+    MM_CAMERA_STREAM_CID,
+    MM_CAMERA_STREAM_CROP
+}mm_camera_stream_parm_t;
+
+typedef struct {
+   int32_t width;
+   int32_t height;
+} mm_camera_dimension_t;
+
+typedef struct{
+    uint32_t tbl_size;
+    struct camera_size_type *sizes_tbl;
+}default_sizes_tbl_t;
+
+typedef struct  {
+    int32_t left;
+    int32_t top;
+    int32_t width;
+    int32_t height;
+} mm_camera_rect_t;
+
+/* TBD: meta header needs to move to msm_camear.h */
+typedef enum {
+    /* no meta data header used */
+    MM_CAMEAR_META_DATA_TYPE_DEF,
+    /* has focus flag, exposure idx,
+     * flash flag, etc. TBD */
+    MM_CAMEAR_META_DATA_TYPE_BRACKETING,
+    MM_CAMEAR_META_DATA_TYPE_MAX,
+} mm_camera_meta_header_t;
+
+typedef struct {
+    cam_format_t fmt;
+    mm_camera_meta_header_t meta_header;
+    uint32_t width;
+    uint32_t height;
+    uint8_t rotation;
+} mm_camera_image_fmt_t;
+
+typedef struct {
+    /* image format */
+    mm_camera_image_fmt_t fmt;
+
+    /* num of buffers needed */
+    uint8_t num_of_bufs;
+
+    /* flag to indicate if this stream need stream on */
+    uint8_t need_stream_on;
+} mm_camera_stream_config_t;
+
+typedef struct {
+    uint8_t name[32];
+    int32_t min_value;
+    int32_t max_value;
+    int32_t step;
+    int32_t default_value;
+} mm_camera_ctrl_cap_sharpness_t;
+
+typedef struct {
+    int16_t *zoom_ratio_tbl;
+    int32_t size;
+} mm_camera_zoom_tbl_t;
+
+typedef enum {
+    /* ZSL use case: get burst of frames */
+    MM_CAMERA_SUPER_BUF_NOTIFY_BURST = 0,
+    /* get continuous frames: when the super buf is
+     * ready dispatch it to HAL */
+    MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS,
+    MM_CAMERA_SUPER_BUF_NOTIFY_MAX
+}mm_camera_super_buf_notify_mode_t;
+
+typedef enum {
+    /* save the frame. No matter focused or not */
+    MM_CAMERA_SUPER_BUF_PRIORITY_NORMAL = 0,
+    /* only queue the frame that is focused. Will enable
+     * meta data header to carry focus info*/
+    MM_CAMERA_SUPER_BUF_PRIORITY_FOCUS,
+    /* after shutter, only queue matched exposure index */
+    MM_CAMERA_SUPER_BUF_PRIORITY_EXPOSURE_BRACKETING,
+    MM_CAMERA_SUPER_BUF_PRIORITY_MAX
+}mm_camera_super_buf_priority_t;
+
+typedef struct {
+    mm_camera_super_buf_notify_mode_t notify_mode;
+    /* queue depth. Only for burst mode */
+    uint8_t water_mark;
+    /* look back how many frames from last buf */
+    uint8_t look_back;
+    /* after send first frame to HAL, how many frames
+     * needing to be skipped for next delivery? */
+    uint8_t post_frame_skip;
+    /* save matched priority frames only */
+    mm_camera_super_buf_priority_t priority;
+    /* in burst mode, how many super
+     * bufs for each shutter press? */
+    uint8_t burst_num;
+} mm_camera_bundle_attr_t;
+
+typedef struct {
+    uint8_t camera_id;                   /* camera id */
+    camera_info_t camera_info;           /* postion, mount_angle, etc. */
+    enum sensor_type_t main_sensor_type; /* BAYER, YUV, JPEG_SOC, etc. */
+    char *video_dev_name;                /* device node name, e.g. /dev/video1 */
+} mm_camera_info_t;
+
+typedef struct {
+  uint8_t cid;
+  uint8_t dt;
+}stream_cid_t;
+
+/* the stats struct will need rework after
+ * defining the stats buf sharing logic */
+typedef struct {
+    int type;
+    uint32_t length;
+    void *value;
+} mm_camera_stats_t;
+
+typedef struct {
+    uint32_t stream_id; /* stream handler */
+    int8_t buf_idx; /* buf idx within the stream bufs */
+
+    struct timespec ts; /* time stamp, to be filled when DQBUF*/
+    uint32_t frame_idx; /* frame sequence num, to be filled when DQBUF */
+
+    int8_t num_planes; /* num of planes, to be filled during mem allocation */
+    struct v4l2_plane planes[VIDEO_MAX_PLANES]; /* plane info, to be filled during mem allocation*/
+    int fd; /* fd of the frame, to be filled during mem allocation */
+    void* buffer; /* ptr to real frame buffer, to be filled during mem allocation */
+    uint32_t frame_len; /* len of the whole frame, to be filled during mem allocation */
+} mm_camera_buf_def_t;
+
+typedef struct {
+    uint32_t camera_handle;
+    uint32_t ch_id;
+    uint8_t num_bufs;
+    mm_camera_buf_def_t* bufs[MM_CAMEAR_MAX_STRAEM_BUNDLE];
+} mm_camera_super_buf_t;
+
+typedef void (*mm_camera_event_notify_t)(uint32_t camera_handle,
+                                         mm_camera_event_t *evt,
+                                         void *user_data);
+
+typedef void (*mm_camera_buf_notify_t) (mm_camera_super_buf_t *bufs,
+                                        void *user_data);
+typedef cam_frame_len_offset_t mm_camera_frame_len_offset;
+
+typedef struct {
+  void *user_data;
+  int32_t (*get_buf) (uint32_t camera_handle,
+                      uint32_t ch_id, uint32_t stream_id,
+                      void *user_data,
+                      mm_camera_frame_len_offset *frame_offset_info,
+                      uint8_t num_bufs,
+                      uint8_t *initial_reg_flag,
+                      mm_camera_buf_def_t *bufs);
+  int32_t (*put_buf) (uint32_t camera_handle,
+                      uint32_t ch_id, uint32_t stream_id,
+                      void *user_data, uint8_t num_bufs,
+                      mm_camera_buf_def_t *bufs);
+} mm_camear_mem_vtbl_t;
+
+typedef struct {
+    uint8_t num_2nd_sensors;
+    uint8_t sensor_idxs[MM_CAMERA_MAX_2ND_SENSORS];
+} mm_camera_2nd_sensor_t;
+
+typedef struct {
+	int32_t (*sync) (uint32_t camera_handle);
+	uint8_t (*is_event_supported) (uint32_t camera_handle,
+                                 mm_camera_event_type_t evt_type);
+    int32_t (*register_event_notify) (uint32_t camera_handle,
+                                 mm_camera_event_notify_t evt_cb,
+                                 void * user_data,
+                                 mm_camera_event_type_t evt_type);
+    int32_t (*qbuf) (uint32_t camera_handle, uint32_t ch_id,
+                                 mm_camera_buf_def_t *buf);
+    void (*camera_close) (uint32_t camera_handle);
+    /* Only fo supporting advanced 2nd sensors. If no secondary sensor needed
+     * HAL can ignore this function */
+    mm_camera_2nd_sensor_t * (*query_2nd_sensor_info) (uint32_t camera_handle);
+    /* if the parm is supported: TRUE - support, FALSE - not support */
+    int32_t (*is_parm_supported) (uint32_t camera_handle,
+                                 mm_camera_parm_type_t parm_type,
+                                 uint8_t *support_set_parm,
+                                 uint8_t *support_get_parm);
+    /* set a parmÂ’s current value */
+    int32_t (*set_parm) (uint32_t camera_handle,
+                         mm_camera_parm_type_t parm_type,
+                         void* p_value);
+    /* get a parmÂ’s current value */
+    int32_t (*get_parm) (uint32_t camera_handle,
+                         mm_camera_parm_type_t parm_type,
+                         void* p_value);
+    /* ch_id returned, zero is invalid ch_id */
+    uint32_t (*ch_acquire) (uint32_t camera_handle);
+    /* relaese channel */
+    void (*ch_release) (uint32_t camera_handle, uint32_t ch_id);
+    /* return stream_id. zero is invalid stream_id
+     * default set to preview: ext_image_mode = 0
+     * default set to primary sensor: sensor_idx = 0
+     * value of ext_image_mode is defined in msm_camera.h
+     */
+    uint32_t (*add_stream) (uint32_t camera_handle, uint32_t ch_id,
+                           mm_camera_buf_notify_t buf_cb, void *user_data,
+                           uint32_t ext_image_mode, uint32_t sensor_idx);
+    /* delete stream */
+    int32_t (*del_stream) (uint32_t camera_handle, uint32_t ch_id,
+                           uint32_t stream_id);
+    /* set straem format This will trigger getting bufs from HAL */
+    int32_t (*config_stream) (uint32_t camera_handle, uint32_t ch_id,
+                              uint32_t stream_id,
+                              mm_camera_stream_config_t *config);
+    /* setup super buf bundle for ZSL */
+    int32_t (*init_stream_bundle) (uint32_t camera_handle, uint32_t ch_id,
+                                   mm_camera_buf_notify_t super_frame_notify_cb,
+                                   void *user_data,  mm_camera_bundle_attr_t *attr,
+                                   uint8_t num_streams, uint32_t *stream_ids);
+    /* remove the super buf bundle */
+    int32_t (*destroy_stream_bundle) (uint32_t camera_handle, uint32_t ch_id);
+    /* start streaming */
+    int32_t (*start_streams) (uint32_t camera_handle, uint32_t ch_id,
+                              uint8_t num_streams, uint32_t *stream_ids);
+    /* stop streaming */
+    int32_t (*stop_streams) (uint32_t camera_handle, uint32_t ch_id,
+                             uint8_t num_streams, uint32_t *stream_ids);
+    /* tear down streams asyncly */
+    int32_t (*async_teardown_streams) (uint32_t camera_handle, uint32_t ch_id,
+                                       uint8_t num_streams, uint32_t *stream_ids);
+    /* get super bufs. for burst mode only */
+    int32_t (*request_super_buf) (uint32_t camera_handle, uint32_t ch_id);
+    /* abort the super buf dispatching. for burst mode only  */
+    int32_t (*cancel_super_buf_request) (uint32_t camera_handle,
+                                         uint32_t ch_id);
+    /* start focus: by default sensor_idx=0 */
+    int32_t (*start_focus) (uint32_t camera_handle,
+                            uint32_t ch_id,
+                            uint32_t sensor_idx,
+                            uint32_t focus_mode);
+    /* abort focus: by default sensor_idx=0 */
+    int32_t (*abort_focus) (uint32_t camera_handle,
+                            uint32_t ch_id,
+                            uint32_t sensor_idx);
+    /* prepare hardware will settle aec and flash.
+     * by default sensor_idx=0 */
+    int32_t (*prepare_snapshot) (uint32_t camera_handle,
+                                 uint32_t ch_id,
+                                 uint32_t sensor_idx);
+    /* set a parmÂ’s current value */
+    int32_t (*set_stream_parm) (uint32_t camera_handle,
+                                uint32_t ch_id,
+                                uint32_t s_id,
+                                mm_camera_stream_parm_t parm_type,
+                                void* p_value);
+    /* get a parmÂ’s current value */
+    int32_t (*get_stream_parm) (uint32_t camera_handle,
+                                uint32_t ch_id,
+                                uint32_t s_id,
+                                mm_camera_stream_parm_t parm_type,
+                                void* p_value);
+} mm_camera_ops_t;
+
+typedef struct {
+    uint32_t camera_handle;        /* camera object handle */
+    mm_camera_info_t *camera_info; /* reference pointer of camear info */
+    mm_camera_ops_t *ops;          /* API call table */
+} mm_camera_vtbl_t;
+
+mm_camera_info_t * camera_query(uint8_t *num_cameras);
+mm_camera_vtbl_t * camera_open(uint8_t camera_idx,
+                               mm_camear_mem_vtbl_t *mem_vtbl);
+
+typedef enum {
+    MM_CAMERA_PREVIEW,
+    MM_CAMERA_VIDEO,
+    MM_CAMERA_SNAPSHOT_MAIN,
+    MM_CAMERA_SNAPSHOT_THUMBNAIL,
+    MM_CAMERA_SNAPSHOT_RAW,
+    MM_CAMERA_RDI
+}mm_camera_img_mode;
+
+/* may remove later */
+typedef enum {
+    MM_CAMERA_OP_MODE_NOTUSED,
+    MM_CAMERA_OP_MODE_CAPTURE,
+    MM_CAMERA_OP_MODE_VIDEO,
+    MM_CAMERA_OP_MODE_ZSL,
+    MM_CAMERA_OP_MODE_MAX
+} mm_camera_op_mode_type_t;
+#endif /*__MM_CAMERA_INTERFACE_H__*/
diff --git a/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_sock.h b/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_sock.h
new file mode 100755
index 0000000..9519754
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/inc/mm_camera_sock.h
@@ -0,0 +1,57 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MM_CAMERA_SOCKET_H__
+#define __MM_CAMERA_SOCKET_H__
+
+#include <inttypes.h>
+
+typedef enum {
+    MM_CAMERA_SOCK_TYPE_UDP,
+    MM_CAMERA_SOCK_TYPE_TCP,
+} mm_camera_sock_type_t;
+
+int mm_camera_socket_create(int cam_id, mm_camera_sock_type_t sock_type);
+
+int mm_camera_socket_sendmsg(
+  int fd,
+  void *msg,
+  uint32_t buf_size,
+  int sendfd);
+
+int mm_camera_socket_recvmsg(
+  int fd,
+  void *msg,
+  uint32_t buf_size,
+  int *rcvdfd);
+
+void mm_camera_socket_close(int fd);
+
+#endif /*__MM_CAMERA_SOCKET_H__*/
+
diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera.c
new file mode 100755
index 0000000..826b5dd
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera.c
@@ -0,0 +1,1774 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <semaphore.h>
+
+#include "mm_camera_dbg.h"
+#include "mm_camera_sock.h"
+#include "mm_camera_interface.h"
+#include "mm_camera.h"
+
+#define SET_PARM_BIT32(parm, parm_arr) \
+    (parm_arr[parm/32] |= (1<<(parm%32)))
+
+#define GET_PARM_BIT32(parm, parm_arr) \
+    ((parm_arr[parm/32]>>(parm%32))& 0x1)
+
+/* internal function declare */
+int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
+                                       cam_ctrl_type type,
+                                       uint32_t length,
+                                       void *value);
+int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj,
+                                               cam_ctrl_type type,
+                                               uint32_t length,
+                                               void *value,
+                                               int timeout);
+int mm_camera_evt_sub(mm_camera_obj_t * my_obj,
+                      mm_camera_event_type_t evt_type,
+                      int reg_count);
+int32_t mm_camera_set_general_parm(mm_camera_obj_t * my_obj,
+                                   mm_camera_parm_type_t parm_type,
+                                   void* p_value);
+int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
+                              mm_camera_event_t *event);
+extern int32_t mm_channel_init(mm_channel_t *my_obj);
+
+mm_channel_t * mm_camera_util_get_channel_by_handler(
+                                    mm_camera_obj_t * cam_obj,
+                                    uint32_t handler)
+{
+    int i;
+    mm_channel_t *ch_obj = NULL;
+    uint8_t ch_idx = mm_camera_util_get_index_by_handler(handler);
+
+    for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
+        if (handler == cam_obj->ch[i].my_hdl) {
+            ch_obj = &cam_obj->ch[i];
+            break;
+        }
+    }
+    return ch_obj;
+}
+
+static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
+                                         void* user_data)
+{
+    int i;
+    mm_camera_event_type_t evt_type = cmd_cb->u.evt.event_type;
+    mm_camera_event_t *event = &cmd_cb->u.evt;
+    mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
+    if (NULL != my_obj) {
+        if (evt_type < MM_CAMERA_EVT_TYPE_MAX) {
+            pthread_mutex_lock(&my_obj->cb_lock);
+            for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
+                if(my_obj->evt[evt_type].evt[i].evt_cb) {
+                    my_obj->evt[evt_type].evt[i].evt_cb(
+                        my_obj->my_hdl,
+                        event,
+                        my_obj->evt[evt_type].evt[i].user_data);
+                }
+            }
+            pthread_mutex_unlock(&my_obj->cb_lock);
+        }
+    }
+}
+
+static void mm_camera_handle_async_cmd(mm_camera_cmdcb_t *cmd_cb,
+                                       void* user_data)
+{
+    int i;
+    mm_camera_async_cmd_t *async_cmd = &cmd_cb->u.async;
+    mm_camera_obj_t * my_obj = NULL;
+    mm_evt_payload_stop_stream_t payload;
+
+    my_obj = (mm_camera_obj_t *)user_data;
+    if (NULL != my_obj) {
+        if (MM_CAMERA_ASYNC_CMD_TYPE_STOP == async_cmd->cmd_type) {
+            memset(&payload, 0, sizeof(mm_evt_payload_stop_stream_t));
+            payload.num_streams = async_cmd->u.stop_cmd.num_streams;
+            payload.stream_ids = async_cmd->u.stop_cmd.stream_ids;
+            mm_channel_fsm_fn(async_cmd->u.stop_cmd.ch_obj,
+                                   MM_CHANNEL_EVT_TEARDOWN_STREAM,
+                                   (void*)&payload,
+                                   NULL);
+        }
+    }
+}
+
+static void mm_camera_event_notify(void* user_data)
+{
+    struct v4l2_event ev;
+    int rc;
+    mm_camera_event_t *evt = NULL;
+    mm_camera_cmdcb_t *node = NULL;
+
+    mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
+    if (NULL != my_obj) {
+        /* read evt */
+        memset(&ev, 0, sizeof(ev));
+        rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
+        evt = (mm_camera_event_t *)ev.u.data;
+
+        if (rc >= 0) {
+            if(ev.type == V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT) {
+                evt->event_type = MM_CAMERA_EVT_TYPE_CTRL;
+                evt->e.ctrl.evt = MM_CAMERA_CTRL_EVT_ERROR;
+            }
+
+            mm_camera_enqueue_evt(my_obj, evt);
+        }
+    }
+}
+
+int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
+                              mm_camera_event_t *event)
+{
+    int32_t rc = 0;
+    mm_camera_cmdcb_t *node = NULL;
+
+    node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
+    if (NULL != node) {
+        memset(node, 0, sizeof(mm_camera_cmdcb_t));
+        node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
+        memcpy(&node->u.evt, event, sizeof(mm_camera_event_t));
+
+        /* enqueue to evt cmd thread */
+        mm_camera_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
+        /* wake up evt cmd thread */
+        sem_post(&(my_obj->evt_thread.cmd_sem));
+    } else {
+        CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
+        rc = -1;
+    }
+
+    return rc;
+}
+
+/* send local CH evt to HAL
+ * may not needed since we have return val for each channel/stream operation */
+int32_t mm_camera_send_ch_event(mm_camera_obj_t *my_obj,
+                                uint32_t ch_id,
+                                uint32_t stream_id,
+                                mm_camera_ch_event_type_t evt)
+{
+    int rc = 0;
+    mm_camera_event_t event;
+    event.event_type = MM_CAMERA_EVT_TYPE_CH;
+    event.e.ch.evt = evt;
+    /* TODO: need to change the ch evt struct to include ch_id and stream_id. */
+    event.e.ch.ch = stream_id;
+    CDBG("%s: stream on event, type=0x%x, ch=%d, evt=%d",
+         __func__, event.event_type, event.e.ch.ch, event.e.ch.evt);
+    rc = mm_camera_enqueue_evt(my_obj, &event);
+    return rc;
+}
+
+int32_t mm_camera_open(mm_camera_obj_t *my_obj)
+{
+    char dev_name[MM_CAMERA_DEV_NAME_LEN];
+    int32_t rc = 0;
+    int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
+    uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
+    uint8_t i;
+    uint8_t cam_idx = mm_camera_util_get_index_by_handler(my_obj->my_hdl);
+
+    CDBG("%s:  begin\n", __func__);
+
+    snprintf(dev_name, sizeof(dev_name), "/dev/%s",
+             mm_camera_util_get_dev_name(my_obj->my_hdl));
+
+    do{
+        n_try--;
+        my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
+        CDBG("%s:  ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno);
+        if((my_obj->ctrl_fd > 0) || (errno != EIO) || (n_try <= 0 )) {
+            CDBG_ERROR("%s:  opened, break out while loop", __func__);
+            break;
+        }
+        CDBG("%s:failed with I/O error retrying after %d milli-seconds",
+             __func__,sleep_msec);
+        usleep(sleep_msec*1000);
+    }while(n_try>0);
+
+    if (my_obj->ctrl_fd <= 0) {
+        CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n",
+                 __func__, dev_name, strerror(errno));
+        rc = -1;
+        goto on_error;
+    }
+
+    /* open domain socket*/
+    n_try=MM_CAMERA_DEV_OPEN_TRIES;
+    do{
+        n_try--;
+        my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
+        CDBG("%s:  ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno);
+        if((my_obj->ds_fd > 0) || (n_try <= 0 )) {
+            CDBG("%s:  opened, break out while loop", __func__);
+            break;
+        }
+        CDBG("%s:failed with I/O error retrying after %d milli-seconds",
+             __func__,sleep_msec);
+        usleep(sleep_msec*1000);
+    }while(n_try>0);
+
+    if (my_obj->ds_fd <= 0) {
+        CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n",
+                 __func__, dev_name, strerror(errno));
+        rc = -1;
+        goto on_error;
+    }
+
+    /* set ctrl_fd to be the mem_mapping fd */
+    rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                        MSM_V4L2_PID_MMAP_INST, 0);
+    if (rc < 0) {
+        CDBG_ERROR("error: ioctl VIDIOC_S_CTRL MSM_V4L2_PID_MMAP_INST failed: %s\n",
+                   strerror(errno));
+        goto on_error;
+    }
+
+    /* set geo mode to 2D by default */
+    my_obj->current_mode = CAMERA_MODE_2D;
+
+    /* TODO:
+    * We need to remove function call once we consider sync as saperate API 
+    * and HAL needs to call after each camera open call. 
+    */
+    mm_camera_sync(my_obj);
+
+    pthread_mutex_init(&my_obj->cb_lock, NULL);
+
+    CDBG("%s : Launch async cmd Thread in Cam Open",__func__);
+    mm_camera_cmd_thread_launch(&my_obj->async_cmd_thread,
+                                mm_camera_handle_async_cmd,
+                                (void *)my_obj);
+
+    CDBG("%s : Launch evt Thread in Cam Open",__func__);
+    mm_camera_cmd_thread_launch(&my_obj->evt_thread,
+                                mm_camera_dispatch_app_event,
+                                (void *)my_obj);
+
+    /* launch event poll thread
+     * we will add evt fd into event poll thread upon user first register for evt */
+    CDBG("%s : Launch evt Poll Thread in Cam Open",__func__);
+    mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
+                                 MM_CAMERA_POLL_TYPE_EVT);
+   
+    CDBG("%s:  end (rc = %d)\n", __func__, rc);
+    /* we do not need to unlock cam_lock here before return
+     * because for open, it's done within intf_lock */
+    return rc;
+
+on_error:
+    if (my_obj->ctrl_fd > 0) {
+        close(my_obj->ctrl_fd);
+        my_obj->ctrl_fd = -1;
+    }
+    if (my_obj->ds_fd > 0) {
+        mm_camera_socket_close(my_obj->ds_fd);
+       my_obj->ds_fd = -1;
+    }
+
+    /* we do not need to unlock cam_lock here before return
+     * because for open, it's done within intf_lock */
+    return rc;
+}
+
+int32_t mm_camera_close(mm_camera_obj_t *my_obj)
+{
+    CDBG("%s : Close evt Poll Thread in Cam Close",__func__);
+    mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
+
+    CDBG("%s : Close evt cmd Thread in Cam Close",__func__);
+    mm_camera_cmd_thread_release(&my_obj->evt_thread);
+
+    CDBG("%s : Close asyn cmd Thread in Cam Close",__func__);
+    mm_camera_cmd_thread_release(&my_obj->async_cmd_thread);
+
+    if(my_obj->ctrl_fd > 0) {
+        close(my_obj->ctrl_fd);
+        my_obj->ctrl_fd = -1;
+    }
+    if(my_obj->ds_fd > 0) {
+        mm_camera_socket_close(my_obj->ds_fd);
+        my_obj->ds_fd = -1;
+    }
+
+    pthread_mutex_destroy(&my_obj->cb_lock);
+
+    pthread_mutex_unlock(&my_obj->cam_lock);
+    return 0;
+}
+
+uint8_t mm_camera_is_event_supported(mm_camera_obj_t *my_obj, mm_camera_event_type_t evt_type)
+{
+    switch(evt_type) {
+    case MM_CAMERA_EVT_TYPE_CH:
+    case MM_CAMERA_EVT_TYPE_CTRL:
+    case MM_CAMERA_EVT_TYPE_STATS:
+    case MM_CAMERA_EVT_TYPE_INFO:
+      return 1;
+    default:
+      return 0;
+    }
+    return 0;
+}
+
+int32_t mm_camera_register_event_notify_internal(
+                                   mm_camera_obj_t *my_obj,
+                                   mm_camera_event_notify_t evt_cb,
+                                   void * user_data,
+                                   mm_camera_event_type_t evt_type)
+{
+    int i;
+    int rc = -1;
+    mm_camera_evt_obj_t *evt_array = NULL;
+
+    pthread_mutex_lock(&my_obj->cb_lock);
+    evt_array = &my_obj->evt[evt_type];
+    if(evt_cb) {
+        /* this is reg case */
+        for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
+            if(evt_array->evt[i].user_data == NULL) {
+                evt_array->evt[i].evt_cb = evt_cb;
+                evt_array->evt[i].user_data = user_data;
+                evt_array->reg_count++;
+                rc = 0;
+                break;
+            }
+        }
+    } else {
+        /* this is unreg case */
+        for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
+            if(evt_array->evt[i].user_data == user_data) {
+                evt_array->evt[i].evt_cb = NULL;
+                evt_array->evt[i].user_data = NULL;
+                evt_array->reg_count--;
+                rc = 0;
+                break;
+            }
+        }
+    }
+
+    if(rc == 0 && evt_array->reg_count <= 1) {
+        /* subscribe/unsubscribe event to kernel */
+        rc = mm_camera_evt_sub(my_obj, evt_type, evt_array->reg_count);
+    }
+
+    pthread_mutex_unlock(&my_obj->cb_lock);
+    return rc;
+}
+
+int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
+                                   mm_camera_event_notify_t evt_cb,
+                                   void * user_data,
+                                   mm_camera_event_type_t evt_type)
+{
+    int i;
+    int rc = -1;
+    mm_camera_evt_obj_t *evt_array = &my_obj->evt[evt_type];
+
+    rc = mm_camera_register_event_notify_internal(my_obj, evt_cb,
+                                                  user_data, evt_type);
+
+    pthread_mutex_unlock(&my_obj->cam_lock);
+    return rc;
+}
+
+int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
+                       uint32_t ch_id,
+                       mm_camera_buf_def_t *buf)
+{
+    int rc = -1;
+    mm_channel_t * ch_obj = NULL;
+    ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    pthread_mutex_unlock(&my_obj->cam_lock);
+
+    /* we always assume qbuf will be done before channel/stream is fully stopped
+     * because qbuf is done within dataCB context
+     * in order to avoid deadlock, we are not locking ch_lock for qbuf */
+    if (NULL != ch_obj) {
+        rc = mm_channel_qbuf(ch_obj, buf);
+    }
+
+    return rc;
+}
+
+mm_camera_2nd_sensor_t * mm_camera_query_2nd_sensor_info(mm_camera_obj_t *my_obj)
+{
+    /* TODO: need to sync with backend how to get 2nd sensor info */
+    return NULL;
+}
+
+int32_t mm_camera_sync(mm_camera_obj_t *my_obj)
+{
+    int32_t rc = 0;
+
+    /* get camera capabilities */
+    memset(&my_obj->properties, 0, sizeof(cam_prop_t));
+    rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                        CAMERA_GET_CAPABILITIES,
+                                        sizeof(cam_prop_t),
+                                        (void *)&my_obj->properties);
+    if (rc != 0) {
+        CDBG_ERROR("%s: cannot get camera capabilities\n", __func__);
+        goto on_error;
+    }
+
+    /* TODO */
+    /* after kernel/backend support query of offline pp capability
+     * we can get the value from capabilities.
+     * for now, hard-coded to 1, meaning always need post processing */
+    //my_obj->need_pp = 1;
+    my_obj->need_pp = 0;
+
+on_error:
+    /* TODO:
+    * We need to enable below lock once we consider sync as saperate API 
+    * and HAL needs to call after each camera open call. 
+    */
+    //pthread_mutex_unlock(&my_obj->cam_lock);
+    return rc;
+
+}
+
+int32_t mm_camera_is_parm_supported(mm_camera_obj_t *my_obj,
+                                   mm_camera_parm_type_t parm_type,
+                                   uint8_t *support_set_parm,
+                                   uint8_t *support_get_parm)
+{
+    /* TODO: need to sync with backend if it can support set/get */
+    int32_t rc = 0;
+    *support_set_parm = GET_PARM_BIT32(parm_type,
+                                       my_obj->properties.parm);
+    *support_get_parm = GET_PARM_BIT32(parm_type,
+                                       my_obj->properties.parm);
+    pthread_mutex_unlock(&my_obj->cam_lock);
+
+    return rc;
+}
+
+int32_t mm_camera_util_set_op_mode(mm_camera_obj_t * my_obj,
+                                   mm_camera_op_mode_type_t *op_mode)
+{
+    int32_t rc = 0;
+    int32_t v4l2_op_mode = MSM_V4L2_CAM_OP_DEFAULT;
+
+    if (my_obj->op_mode == *op_mode)
+        goto end;
+    switch(*op_mode) {
+    case MM_CAMERA_OP_MODE_ZSL:
+        v4l2_op_mode = MSM_V4L2_CAM_OP_ZSL;
+            break;
+    case MM_CAMERA_OP_MODE_CAPTURE:
+        v4l2_op_mode = MSM_V4L2_CAM_OP_CAPTURE;
+            break;
+    case MM_CAMERA_OP_MODE_VIDEO:
+        v4l2_op_mode = MSM_V4L2_CAM_OP_VIDEO;
+            break;
+    default:
+        rc = - 1;
+        goto end;
+        break;
+    }
+    if(0 != (rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+            MSM_V4L2_PID_CAM_MODE, v4l2_op_mode))){
+        CDBG_ERROR("%s: input op_mode=%d, s_ctrl rc=%d\n", __func__, *op_mode, rc);
+        goto end;
+    }
+    /* if success update mode field */
+    my_obj->op_mode = *op_mode;
+end:
+    CDBG("%s: op_mode=%d,rc=%d\n", __func__, *op_mode, rc);
+    return rc;
+}
+
+int32_t mm_camera_set_parm(mm_camera_obj_t *my_obj,
+                           mm_camera_parm_type_t parm_type,
+                           void* p_value)
+{
+    int32_t rc = 0;
+    CDBG("%s type =%d", __func__, parm_type);
+    switch(parm_type) {
+    case MM_CAMERA_PARM_OP_MODE:
+        rc = mm_camera_util_set_op_mode(my_obj,
+                        (mm_camera_op_mode_type_t *)p_value);
+        break;
+    case MM_CAMERA_PARM_DIMENSION:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                    CAMERA_SET_PARM_DIMENSION, sizeof(cam_ctrl_dimension_t), p_value);
+        if(rc != 0) {
+            CDBG("%s: mm_camera_send_native_ctrl_cmd err=%d\n", __func__, rc);
+            break;
+        }
+        memcpy(&my_obj->dim, (cam_ctrl_dimension_t *)p_value,
+                     sizeof(cam_ctrl_dimension_t));
+        CDBG("%s: dw=%d,dh=%d,vw=%d,vh=%d,pw=%d,ph=%d,tw=%d,th=%d,raw_w=%d,raw_h=%d\n",
+                 __func__,
+                 my_obj->dim.display_width,my_obj->dim.display_height,
+                 my_obj->dim.video_width, my_obj->dim.video_height,
+                 my_obj->dim.picture_width,my_obj->dim.picture_height,
+                 my_obj->dim.ui_thumbnail_width,my_obj->dim.ui_thumbnail_height,
+                 my_obj->dim.raw_picture_width,my_obj->dim.raw_picture_height);
+        break;
+    case MM_CAMERA_PARM_SNAPSHOT_BURST_NUM:
+        my_obj->snap_burst_num_by_user = *((uint32_t *)p_value);
+        break;
+    default:
+        rc = mm_camera_set_general_parm(my_obj, parm_type, p_value);
+        break;
+    }
+    pthread_mutex_unlock(&my_obj->cam_lock);
+    return rc;
+}
+
+int32_t mm_camera_get_parm(mm_camera_obj_t *my_obj,
+                           mm_camera_parm_type_t parm_type,
+                           void* p_value)
+{
+    int32_t rc = 0;
+
+    switch(parm_type) {
+    case MM_CAMERA_PARM_MAX_PICTURE_SIZE:
+        {
+            mm_camera_dimension_t *dim =
+                (mm_camera_dimension_t *)p_value;
+            dim->height = my_obj->properties.max_pict_height;
+            dim->width = my_obj->properties.max_pict_width;
+            CDBG("%s: Max Picture Size: %d X %d\n", __func__,
+                 dim->width, dim->height);
+        }
+        break;
+    case MM_CAMERA_PARM_PREVIEW_FORMAT:
+        *((int *)p_value) = my_obj->properties.preview_format;
+        break;
+    case MM_CAMERA_PARM_PREVIEW_SIZES_CNT:
+        *((int *)p_value) = my_obj->properties.preview_sizes_cnt;
+        break;
+    case MM_CAMERA_PARM_VIDEO_SIZES_CNT:
+        *((int *)p_value) = my_obj->properties.video_sizes_cnt;
+        break;
+    case MM_CAMERA_PARM_THUMB_SIZES_CNT:
+        *((int *)p_value) = my_obj->properties.thumb_sizes_cnt;
+        break;
+    case MM_CAMERA_PARM_HFR_SIZES_CNT:
+        *((int *)p_value) = my_obj->properties.hfr_sizes_cnt;
+        break;
+    case MM_CAMERA_PARM_HFR_FRAME_SKIP:
+        *((int *)p_value) = my_obj->properties.hfr_frame_skip;
+        break;
+    case MM_CAMERA_PARM_DEFAULT_PREVIEW_WIDTH:
+        *((int *)p_value) = my_obj->properties.default_preview_width;
+        break;
+    case MM_CAMERA_PARM_DEFAULT_PREVIEW_HEIGHT:
+        *((int *)p_value) = my_obj->properties.default_preview_height;
+        break;
+    case MM_CAMERA_PARM_MAX_PREVIEW_SIZE:
+        {
+            mm_camera_dimension_t *dim =
+                (mm_camera_dimension_t *)p_value;
+            dim->height = my_obj->properties.max_preview_height;
+            dim->width = my_obj->properties.max_preview_width;
+            CDBG("%s: Max Preview Size: %d X %d\n", __func__,
+                 dim->width, dim->height);
+        }
+        break;
+    case MM_CAMERA_PARM_MAX_VIDEO_SIZE:
+        {
+            mm_camera_dimension_t *dim =
+                (mm_camera_dimension_t *)p_value;
+            dim->height = my_obj->properties.max_video_height;
+            dim->width = my_obj->properties.max_video_width;
+            CDBG("%s: Max Video Size: %d X %d\n", __func__,
+                 dim->width, dim->height);
+        }
+        break;
+    case MM_CAMERA_PARM_MAX_HFR_MODE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_MAX_HFR_MODE,
+                                            sizeof(camera_hfr_mode_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_FOCAL_LENGTH:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_FOCAL_LENGTH,
+                                            sizeof(float),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_HORIZONTAL_VIEW_ANGLE,
+                                            sizeof(float),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_VERTICAL_VIEW_ANGLE,
+                                            sizeof(float),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_FOCUS_DISTANCES:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_FOCUS_DISTANCES,
+                                            sizeof(focus_distances_info_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_QUERY_FALSH4SNAP:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_QUERY_FLASH_FOR_SNAPSHOT,
+                                            sizeof(int),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_3D_FRAME_FORMAT:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_3D_FRAME_FORMAT,
+                                            sizeof(camera_3d_frame_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_MAXZOOM:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_MAXZOOM,
+                                            sizeof(int),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_ZOOM_RATIO:
+        {
+            mm_camera_zoom_tbl_t *tbl = (mm_camera_zoom_tbl_t *)p_value;
+            rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                                CAMERA_GET_PARM_ZOOMRATIOS,
+                                                sizeof(int16_t)*tbl->size,
+                                                (void *)(tbl->zoom_ratio_tbl));
+        }
+        break;
+    case MM_CAMERA_PARM_DEF_PREVIEW_SIZES:
+        {
+            default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
+            rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                                CAMERA_GET_PARM_DEF_PREVIEW_SIZES,
+                                                sizeof(struct camera_size_type)*tbl->tbl_size,
+                                                (void* )(tbl->sizes_tbl));
+        }
+        break;
+    case MM_CAMERA_PARM_DEF_VIDEO_SIZES:
+        {
+            default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
+            rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                                CAMERA_GET_PARM_DEF_VIDEO_SIZES,
+                                                sizeof(struct camera_size_type)*tbl->tbl_size,
+                                                (void *)(tbl->sizes_tbl));
+        }
+        break;
+    case MM_CAMERA_PARM_DEF_THUMB_SIZES:
+        {
+            default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
+            rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                                CAMERA_GET_PARM_DEF_THUMB_SIZES,
+                                                sizeof(struct camera_size_type)*tbl->tbl_size,
+                                                (void *)(tbl->sizes_tbl));
+        }
+        break;
+    case MM_CAMERA_PARM_DEF_HFR_SIZES:
+        {
+            default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
+            rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                                CAMERA_GET_PARM_DEF_HFR_SIZES,
+                                                sizeof(struct camera_size_type)*tbl->tbl_size,
+                                                (void *)(tbl->sizes_tbl));
+        }
+        break;
+    case MM_CAMERA_PARM_SNAPSHOT_BURST_NUM:
+        *((int *)p_value) = my_obj->snap_burst_num_by_user;
+        break;
+    case MM_CAMERA_PARM_VFE_OUTPUT_ENABLE:
+        *((int *)p_value) = my_obj->properties.vfe_output_enable;
+        break;
+    case MM_CAMERA_PARM_DIMENSION:
+        memcpy(p_value, &my_obj->dim, sizeof(my_obj->dim));
+        CDBG("%s: dw=%d,dh=%d,vw=%d,vh=%d,pw=%d,ph=%d,tw=%d,th=%d,ovx=%x,ovy=%d,opx=%d,opy=%d, m_fmt=%d, t_ftm=%d\n",
+                 __func__,
+                 my_obj->dim.display_width,my_obj->dim.display_height,
+                 my_obj->dim.video_width,my_obj->dim.video_height,
+                 my_obj->dim.picture_width,my_obj->dim.picture_height,
+                 my_obj->dim.ui_thumbnail_width,my_obj->dim.ui_thumbnail_height,
+                 my_obj->dim.orig_video_width,my_obj->dim.orig_video_height,
+                 my_obj->dim.orig_picture_width,my_obj->dim.orig_picture_height,
+                 my_obj->dim.main_img_format, my_obj->dim.thumb_format);
+        break;
+    case MM_CAMERA_PARM_OP_MODE:
+        *((mm_camera_op_mode_type_t *)p_value) = my_obj->op_mode;
+        break;
+    default:
+        /* needs to add more implementation */
+        rc = -1;
+        break;
+    }
+
+    pthread_mutex_unlock(&my_obj->cam_lock);
+    return rc;
+}
+
+uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj)
+{
+    mm_channel_t *ch_obj = NULL;
+    uint8_t ch_idx = 0;
+    uint32_t ch_hdl = 0;
+
+    for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
+        if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
+            ch_obj = &my_obj->ch[ch_idx];
+            break;
+        }
+    }
+
+    if (NULL != ch_obj) {
+        /* initialize channel obj */
+        memset(ch_obj, 0, sizeof(mm_channel_t));
+        ch_hdl = mm_camera_util_generate_handler(ch_idx);
+        ch_obj->my_hdl = ch_hdl;
+        ch_obj->state = MM_CHANNEL_STATE_STOPPED;
+        ch_obj->cam_obj = my_obj;
+        pthread_mutex_init(&ch_obj->ch_lock, NULL);
+    }
+
+    mm_channel_init(ch_obj);
+    pthread_mutex_unlock(&my_obj->cam_lock);
+
+    return ch_hdl;
+}
+
+void mm_camera_del_channel(mm_camera_obj_t *my_obj,
+                           uint32_t ch_id)
+{
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_DELETE,
+                               NULL,
+                               NULL);
+
+        pthread_mutex_destroy(&ch_obj->ch_lock);
+        memset(ch_obj, 0, sizeof(mm_channel_t));
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+}
+
+uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
+                              uint32_t ch_id,
+                              mm_camera_buf_notify_t buf_cb, void *user_data,
+                              uint32_t ext_image_mode, uint32_t sensor_idx)
+{
+    uint32_t s_hdl = 0;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+    mm_evt_paylod_add_stream_t payload;
+    void* out_val = NULL;
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        memset(&payload, 0, sizeof(mm_evt_paylod_add_stream_t));
+        payload.buf_cb = buf_cb;
+        payload.user_data = user_data;
+        payload.ext_image_mode = ext_image_mode;
+        payload.sensor_idx = sensor_idx;
+        mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_ADD_STREAM,
+                               (void*)&payload,
+                               (void*)&s_hdl);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return s_hdl;
+}
+
+int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
+                             uint32_t ch_id,
+                             uint32_t stream_id)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_DEL_STREAM,
+                               (void*)&stream_id,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
+                                uint32_t ch_id,
+                                uint32_t stream_id,
+                                mm_camera_stream_config_t *config)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+    mm_evt_paylod_config_stream_t payload;
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
+        payload.stream_id = stream_id;
+        payload.config = config;
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_CONFIG_STREAM,
+                               (void*)&payload,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_bundle_streams(mm_camera_obj_t *my_obj,
+                                 uint32_t ch_id,
+                                 mm_camera_buf_notify_t super_frame_notify_cb,
+                                 void *user_data,
+                                 mm_camera_bundle_attr_t *attr,
+                                 uint8_t num_streams,
+                                 uint32_t *stream_ids)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+    mm_evt_payload_bundle_stream_t payload;
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        memset(&payload, 0, sizeof(mm_evt_payload_bundle_stream_t));
+        payload.super_frame_notify_cb = super_frame_notify_cb;
+        payload.user_data = user_data;
+        payload.attr = attr;
+        payload.num_streams = num_streams;
+        payload.stream_ids = stream_ids;
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_INIT_BUNDLE,
+                               (void*)&payload,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_destroy_bundle(mm_camera_obj_t *my_obj, uint32_t ch_id)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_DESTROY_BUNDLE,
+                               NULL,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_start_streams(mm_camera_obj_t *my_obj,
+                                uint32_t ch_id,
+                                uint8_t num_streams,
+                                uint32_t *stream_ids)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+    mm_evt_payload_start_stream_t payload;
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        memset(&payload, 0, sizeof(mm_evt_payload_start_stream_t));
+        payload.num_streams = num_streams;
+        payload.stream_ids = stream_ids;
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_START_STREAM,
+                               (void*)&payload,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_stop_streams(mm_camera_obj_t *my_obj,
+                               uint32_t ch_id,
+                               uint8_t num_streams,
+                               uint32_t *stream_ids)
+{
+    int32_t rc = 0;
+    mm_evt_payload_stop_stream_t payload;
+    mm_camera_cmdcb_t * node = NULL;
+
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        memset(&payload, 0, sizeof(mm_evt_payload_stop_stream_t));
+        payload.num_streams = num_streams;
+        payload.stream_ids = stream_ids;
+
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_STOP_STREAM,
+                               (void*)&payload,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+    return rc;
+}
+
+int32_t mm_camera_async_teardown_streams(mm_camera_obj_t *my_obj,
+                                          uint32_t ch_id,
+                                          uint8_t num_streams,
+                                          uint32_t *stream_ids)
+{
+    int32_t rc = 0;
+    mm_evt_payload_stop_stream_t payload;
+    mm_camera_cmdcb_t * node = NULL;
+
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        /* enqueu asyn stop cmd to async_cmd_thread */
+        node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
+        if (NULL != node) {
+            memset(node, 0, sizeof(mm_camera_cmdcb_t));
+            node->cmd_type = MM_CAMERA_CMD_TYPE_ASYNC_CB;
+            node->u.async.cmd_type = MM_CAMERA_ASYNC_CMD_TYPE_STOP;
+            node->u.async.u.stop_cmd.ch_obj = ch_obj;
+            node->u.async.u.stop_cmd.num_streams = num_streams;
+            memcpy(node->u.async.u.stop_cmd.stream_ids, stream_ids, sizeof(uint32_t)*num_streams);
+
+            /* enqueue to async cmd thread */
+            mm_camera_queue_enq(&(my_obj->async_cmd_thread.cmd_queue), node);
+            /* wake up async cmd thread */
+            sem_post(&(my_obj->async_cmd_thread.cmd_sem));
+        } else {
+            CDBG_ERROR("%s: No memory for mm_camera_cmdcb_t", __func__);
+            pthread_mutex_unlock(&ch_obj->ch_lock);
+            rc = -1;
+            return rc;
+        }
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+    return rc;
+}
+
+int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj, uint32_t ch_id)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
+                               NULL,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
+                               NULL,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_start_focus(mm_camera_obj_t *my_obj,
+                              uint32_t ch_id,
+                              uint32_t sensor_idx,
+                              uint32_t focus_mode)
+{
+    int32_t rc = -1;
+    mm_evt_payload_start_focus_t payload;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        memset(&payload, 0, sizeof(mm_evt_payload_start_focus_t));
+        payload.sensor_idx = sensor_idx;
+        payload.focus_mode = focus_mode;
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_START_FOCUS,
+                               (void *)&payload,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_abort_focus(mm_camera_obj_t *my_obj,
+                              uint32_t ch_id,
+                              uint32_t sensor_idx)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_ABORT_FOCUS,
+                               (void*)sensor_idx,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
+                                   uint32_t ch_id,
+                                   uint32_t sensor_idx)
+{
+    int32_t rc = -1;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_PREPARE_SNAPSHOT,
+                               (void *)sensor_idx,
+                               NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_set_stream_parm(mm_camera_obj_t *my_obj,
+                                  uint32_t ch_id,
+                                  uint32_t s_id,
+                                  mm_camera_stream_parm_t parm_type,
+                                  void* p_value)
+{
+    int32_t rc = -1;
+    mm_evt_paylod_stream_parm_t payload;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        memset(&payload,0,sizeof(mm_evt_paylod_stream_parm_t));
+        payload.parm_type = parm_type;
+        payload.value = p_value;
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_SET_STREAM_PARM,
+                               (void *)s_id,
+                               &payload);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_get_stream_parm(mm_camera_obj_t *my_obj,
+                                  uint32_t ch_id,
+                                  uint32_t s_id,
+                                  mm_camera_stream_parm_t parm_type,
+                                  void* p_value)
+{
+    int32_t rc = -1;
+    mm_evt_paylod_stream_parm_t payload;
+    mm_channel_t * ch_obj =
+        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+
+        memset(&payload,0,sizeof(mm_evt_paylod_stream_parm_t));
+        payload.parm_type = parm_type;
+        payload.value = p_value;
+        rc = mm_channel_fsm_fn(ch_obj,
+                               MM_CHANNEL_EVT_GET_STREAM_PARM,
+                               (void *)s_id,
+                               &payload);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_ctrl_set_specialEffect (mm_camera_obj_t *my_obj, int32_t effect) {
+    struct v4l2_control ctrl;
+    if (effect == CAMERA_EFFECT_MAX)
+        effect = CAMERA_EFFECT_OFF;
+    int rc = 0;
+
+    ctrl.id = MSM_V4L2_PID_EFFECT;
+    ctrl.value = effect;
+    rc = ioctl(my_obj->ctrl_fd, VIDIOC_S_CTRL, &ctrl);
+    return rc;
+}
+
+int32_t mm_camera_ctrl_set_auto_focus (mm_camera_obj_t *my_obj, int32_t value)
+{
+    int32_t rc = 0;
+    struct v4l2_queryctrl queryctrl;
+
+    memset (&queryctrl, 0, sizeof (queryctrl));
+    queryctrl.id = V4L2_CID_FOCUS_AUTO;
+
+    if(value != 0 && value != 1) {
+        CDBG("%s:boolean required, invalid value = %d\n",__func__, value);
+        return -1;
+    }
+    if (-1 == ioctl (my_obj->ctrl_fd, VIDIOC_QUERYCTRL, &queryctrl)) {
+        CDBG ("V4L2_CID_FOCUS_AUTO is not supported\n");
+    } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+        CDBG ("%s:V4L2_CID_FOCUS_AUTO is not supported\n", __func__);
+    } else {
+        if(0 != (rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                V4L2_CID_FOCUS_AUTO, value))){
+            CDBG("%s: error, id=0x%x, value=%d, rc = %d\n",
+                     __func__, V4L2_CID_FOCUS_AUTO, value, rc);
+            rc = -1;
+        }
+    }
+    return rc;
+}
+
+int32_t mm_camera_ctrl_set_whitebalance (mm_camera_obj_t *my_obj, int32_t mode) {
+
+    int32_t rc = 0, value;
+    uint32_t id;
+
+    switch(mode) {
+    case MM_CAMERA_WHITE_BALANCE_AUTO:
+        id = V4L2_CID_AUTO_WHITE_BALANCE;
+        value = 1; /* TRUE */
+        break;
+    case MM_CAMERA_WHITE_BALANCE_OFF:
+        id = V4L2_CID_AUTO_WHITE_BALANCE;
+        value = 0; /* FALSE */
+        break;
+    case MM_CAMERA_WHITE_BALANCE_DAYLIGHT:
+        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
+        value = 6500;
+        break;
+    case MM_CAMERA_WHITE_BALANCE_INCANDESCENT:
+        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
+        value = 2800;
+        break;
+    case MM_CAMERA_WHITE_BALANCE_FLUORESCENT:
+        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
+        value = 4200;
+        break;
+    case MM_CAMERA_WHITE_BALANCE_CLOUDY:
+        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
+        value = 7500;
+        break;
+    default:
+        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
+        value = 4200;
+        break;
+    }
+    rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd, id, value);
+    if(0 != rc){
+        CDBG("%s: error, exp_metering_action_param=%d, rc = %d\n", __func__, value, rc);
+    }
+    return rc;
+}
+
+int32_t mm_camera_set_general_parm(mm_camera_obj_t * my_obj,
+                                   mm_camera_parm_type_t parm_type,
+                                   void* p_value)
+{
+    int rc = -1;
+    int isZSL =0;
+
+    switch(parm_type)  {
+    case MM_CAMERA_PARM_EXPOSURE:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   MSM_V4L2_PID_EXP_METERING,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_SHARPNESS:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   V4L2_CID_SHARPNESS,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_CONTRAST:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   V4L2_CID_CONTRAST,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_SATURATION:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   V4L2_CID_SATURATION,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_BRIGHTNESS:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   V4L2_CID_BRIGHTNESS,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_WHITE_BALANCE:
+        rc = mm_camera_ctrl_set_whitebalance (my_obj, *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_ISO:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   MSM_V4L2_PID_ISO,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_ZOOM:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   V4L2_CID_ZOOM_ABSOLUTE,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_LUMA_ADAPTATION:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   MSM_V4L2_PID_LUMA_ADAPTATION,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_ANTIBANDING:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   V4L2_CID_POWER_LINE_FREQUENCY,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_CONTINUOUS_AF:
+        rc = mm_camera_ctrl_set_auto_focus(my_obj,
+                                           *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_HJR:
+        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
+                                   MSM_V4L2_PID_HJR,
+                                   *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_EFFECT:
+        rc = mm_camera_ctrl_set_specialEffect (my_obj,
+                                               *((int32_t *)p_value));
+        break;
+    case MM_CAMERA_PARM_FPS:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_FPS,
+                                            sizeof(uint32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_FPS_MODE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_FPS_MODE,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_EXPOSURE_COMPENSATION:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_EXPOSURE_COMPENSATION,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_LED_MODE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_LED_MODE,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_ROLLOFF:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_ROLLOFF,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_MODE:
+        my_obj->current_mode = *((camera_mode_t *)p_value);
+        break;
+    case MM_CAMERA_PARM_FOCUS_RECT:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_FOCUS_RECT,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_AEC_ROI:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_AEC_ROI,
+                                            sizeof(cam_set_aec_roi_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_AF_ROI:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_AF_ROI,
+                                            sizeof(roi_info_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_FOCUS_MODE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_AF_MODE,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+#if 0 /* to be enabled later: @punits */
+    case MM_CAMERA_PARM_AF_MTR_AREA:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_AF_MTR_AREA,
+                                            sizeof(af_mtr_area_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_AEC_MTR_AREA:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_AEC_MTR_AREA,
+                                            sizeof(aec_mtr_area_t),
+                                            p_value);
+        break;
+#endif
+    case MM_CAMERA_PARM_CAF_ENABLE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_CAF,
+                                            sizeof(uint32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_BESTSHOT_MODE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_BESTSHOT_MODE,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_VIDEO_DIS:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_VIDEO_DIS_PARAMS,
+                                            sizeof(video_dis_param_ctrl_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_VIDEO_ROT:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_VIDEO_ROT_PARAMS,
+                                            sizeof(video_rotation_param_ctrl_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_SCE_FACTOR:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_SCE_FACTOR,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_FD:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_FD,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_AEC_LOCK:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_AEC_LOCK,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_AWB_LOCK:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_AWB_LOCK,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_MCE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_MCE,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_HORIZONTAL_VIEW_ANGLE,
+                                            sizeof(focus_distances_info_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_VERTICAL_VIEW_ANGLE,
+                                            sizeof(focus_distances_info_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_RESET_LENS_TO_INFINITY:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_RESET_LENS_TO_INFINITY,
+                                            0, NULL);
+        break;
+    case MM_CAMERA_PARM_SNAPSHOTDATA:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_GET_PARM_SNAPSHOTDATA,
+                                            sizeof(snapshotData_info_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_HFR:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_HFR,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_REDEYE_REDUCTION:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_REDEYE_REDUCTION,
+                                            sizeof(int32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_WAVELET_DENOISE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_WAVELET_DENOISE,
+                                            sizeof(denoise_param_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_3D_DISPLAY_DISTANCE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_3D_DISPLAY_DISTANCE,
+                                            sizeof(float),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_3D_VIEW_ANGLE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_3D_VIEW_ANGLE,
+                                            sizeof(uint32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_ZOOM_RATIO:
+        break;
+    case MM_CAMERA_PARM_HISTOGRAM:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_HISTOGRAM,
+                                            sizeof(int8_t),
+                                            p_value);
+        break;
+    /* Moved to mm-jpeg-interface */
+    /* case MM_CAMERA_PARM_JPEG_ROTATION:
+        break; */
+    case MM_CAMERA_PARM_ASD_ENABLE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                          CAMERA_SET_ASD_ENABLE,
+                                          sizeof(uint32_t),
+                                          p_value);
+        break;
+    case MM_CAMERA_PARM_RECORDING_HINT:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_RECORDING_HINT,
+                                            sizeof(uint32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_PREVIEW_FORMAT:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_PREVIEW_FORMAT,
+                                            sizeof(uint32_t),
+                                            p_value);
+        break;
+    /* TODO: need code review to determine any of the three is redundent
+     * MM_CAMERA_PARM_DIS_ENABLE,
+     * MM_CAMERA_PARM_FULL_LIVESHOT,
+     * MM_CAMERA_PARM_LOW_POWER_MODE*/
+    case MM_CAMERA_PARM_DIS_ENABLE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_DIS_ENABLE,
+                                            sizeof(uint32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_FULL_LIVESHOT:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_FULL_LIVESHOT,
+                                            sizeof(uint32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_LOW_POWER_MODE:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_LOW_POWER_MODE,
+                                            sizeof(uint32_t),
+                                            p_value);
+        break;
+    case MM_CAMERA_PARM_HDR:
+        rc = mm_camera_send_native_ctrl_cmd(my_obj,
+                                            CAMERA_SET_PARM_HDR,
+                                            sizeof(exp_bracketing_t),
+                                            p_value);
+        break;
+    default:
+        CDBG("%s: default: parm %d not supported\n", __func__, parm_type);
+        break;
+    }
+    return rc;
+}
+
+int32_t mm_camera_util_private_s_ctrl(int32_t fd, uint32_t id, void* value)
+{
+    int rc = -1;
+    struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
+
+    memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl));
+    v4l2_ioctl.id = id;
+    v4l2_ioctl.ioctl_ptr = value;
+    rc = ioctl (fd, MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL, &v4l2_ioctl);
+
+    if(rc) {
+        CDBG_ERROR("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
+                   __func__, fd, id, (uint32_t)value, rc);
+        rc = 1;
+    }
+    return rc;
+}
+
+int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
+                                              cam_ctrl_type type,
+                                              uint32_t length,
+                                              void *value)
+{
+    return mm_camera_send_native_ctrl_timeout_cmd(my_obj, type,
+                                                  length, value,
+                                                  1000);
+}
+
+int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj,
+                                                      cam_ctrl_type type,
+                                                      uint32_t length,
+                                                      void *value,
+                                                      int timeout)
+{
+    int rc = -1;
+    struct msm_ctrl_cmd ctrl_cmd;
+
+    memset(&ctrl_cmd, 0, sizeof(ctrl_cmd));
+    ctrl_cmd.type = type;
+    ctrl_cmd.length = (uint16_t)length;
+    ctrl_cmd.timeout_ms = timeout;
+    ctrl_cmd.value = value;
+    ctrl_cmd.status = (uint16_t)CAM_CTRL_SUCCESS;
+    rc = mm_camera_util_private_s_ctrl(my_obj->ctrl_fd,
+                               MSM_V4L2_PID_CTRL_CMD,
+                               (void*)&ctrl_cmd);
+    CDBG("%s: type=%d, rc = %d, status = %d\n",
+        __func__, type, rc, ctrl_cmd.status);
+    if(rc != 0 || ((ctrl_cmd.status != CAM_CTRL_ACCEPTED) &&
+        (ctrl_cmd.status != CAM_CTRL_SUCCESS) &&
+        (ctrl_cmd.status != CAM_CTRL_INVALID_PARM)))
+        rc = -1;
+    return rc;
+}
+
+int mm_camera_evt_sub(mm_camera_obj_t * my_obj,
+                      mm_camera_event_type_t evt_type,
+                      int reg_count)
+{
+    int rc = 0;
+    struct v4l2_event_subscription sub;
+
+    memset(&sub, 0, sizeof(sub));
+    sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_EVENT;
+    if(reg_count == 0) {
+        /* unsubscribe */
+        if(my_obj->evt_type_mask == (uint32_t)(1 << evt_type)) {
+            rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
+            CDBG("%s: unsubscribe event 0x%x, rc = %d", __func__, sub.type, rc);
+            sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT;
+            rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
+            CDBG("%s: unsubscribe event 0x%x, rc = %d", __func__, sub.type, rc);
+        }
+        my_obj->evt_type_mask &= ~(1 << evt_type);
+        if(my_obj->evt_type_mask == 0) {
+            /* remove evt fd from the polling thraed when unreg the last event */
+            mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread, my_obj->my_hdl);
+        }
+    } else {
+        if(!my_obj->evt_type_mask) {
+            /* this is the first reg event */
+            rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
+            CDBG("%s: subscribe event 0x%x, rc = %d", __func__, sub.type, rc);
+            if (rc < 0)
+                goto end;
+            sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT;
+            rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
+            CDBG("%s: subscribe event 0x%x, rc = %d", __func__, sub.type, rc);
+            if (rc < 0)
+                goto end;
+        }
+        my_obj->evt_type_mask |= (1 << evt_type);
+        if(my_obj->evt_type_mask == (uint32_t)(1 << evt_type)) {
+            /* add evt fd to polling thread when subscribe the first event */
+            rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
+                                                   my_obj->my_hdl,
+                                                   my_obj->ctrl_fd,
+                                                   mm_camera_event_notify,
+                                                   (void*)my_obj);
+        }
+    }
+end:
+    return rc;
+}
+
+int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj, void *msg, uint32_t buf_size, int sendfd)
+{
+    return mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd);
+}
+
+int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
+                          int ext_mode,
+                          int idx,
+                          int fd,
+                          uint32_t size)
+{
+    cam_sock_packet_t packet;
+    memset(&packet, 0, sizeof(cam_sock_packet_t));
+    packet.msg_type = CAM_SOCK_MSG_TYPE_FD_MAPPING;
+    packet.payload.frame_fd_map.ext_mode = ext_mode;
+    packet.payload.frame_fd_map.frame_idx = idx;
+    packet.payload.frame_fd_map.fd = fd;
+    packet.payload.frame_fd_map.size = size;
+
+    return mm_camera_util_sendmsg(my_obj, &packet,
+                                  sizeof(cam_sock_packet_t),
+                                  packet.payload.frame_fd_map.fd);
+}
+
+int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
+                            int ext_mode,
+                            int idx)
+{
+    cam_sock_packet_t packet;
+    memset(&packet, 0, sizeof(cam_sock_packet_t));
+    packet.msg_type = CAM_SOCK_MSG_TYPE_FD_UNMAPPING;
+    packet.payload.frame_fd_unmap.ext_mode = ext_mode;
+    packet.payload.frame_fd_unmap.frame_idx = idx;
+    return mm_camera_util_sendmsg(my_obj, &packet,
+                                  sizeof(cam_sock_packet_t),
+                                  packet.payload.frame_fd_map.fd);
+}
+
+int32_t mm_camera_util_s_ctrl(int32_t fd,  uint32_t id, int32_t value)
+{
+    int rc = 0;
+    struct v4l2_control control;
+
+    memset(&control, 0, sizeof(control));
+    control.id = id;
+    control.value = value;
+    rc = ioctl (fd, VIDIOC_S_CTRL, &control);
+
+    if(rc) {
+        CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
+                 __func__, fd, id, (uint32_t)value, rc);
+    }
+    return rc;
+}
+
+int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
+{
+    int rc = 0;
+    struct v4l2_control control;
+
+    memset(&control, 0, sizeof(control));
+    control.id = id;
+    control.value = (int32_t)value;
+    rc = ioctl (fd, VIDIOC_G_CTRL, &control);
+    if(rc) {
+        CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
+    }
+    *value = control.value;
+    return rc;
+}
diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera_channel.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_channel.c
new file mode 100755
index 0000000..81c3585
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_channel.c
@@ -0,0 +1,1536 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <semaphore.h>
+
+#include "mm_camera_dbg.h"
+#include "mm_camera_interface.h"
+#include "mm_camera.h"
+
+extern mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler);
+extern mm_channel_t * mm_camera_util_get_channel_by_handler(
+                                    mm_camera_obj_t * cam_obj,
+                                    uint32_t handler);
+extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
+                                       cam_ctrl_type type,
+                                       uint32_t length,
+                                       void *value);
+extern int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj,
+                                               cam_ctrl_type type,
+                                               uint32_t length,
+                                               void *value,
+                                               int timeout);
+
+/* internal function declare goes here */
+int32_t mm_channel_qbuf(mm_channel_t *my_obj,
+                        mm_camera_buf_def_t *buf);
+int32_t mm_channel_init(mm_channel_t *my_obj);
+void mm_channel_release(mm_channel_t *my_obj);
+uint32_t mm_channel_add_stream(mm_channel_t *my_obj,
+                                   mm_camera_buf_notify_t buf_cb, void *user_data,
+                                   uint32_t ext_image_mode, uint32_t sensor_idx);
+int32_t mm_channel_del_stream(mm_channel_t *my_obj,
+                                   uint32_t stream_id);
+int32_t mm_channel_config_stream(mm_channel_t *my_obj,
+                                 uint32_t stream_id,
+                                 mm_camera_stream_config_t *config);
+int32_t mm_channel_bundle_stream(mm_channel_t *my_obj,
+                                 mm_camera_buf_notify_t super_frame_notify_cb,
+                                 void *user_data,
+                                 mm_camera_bundle_attr_t *attr,
+                                 uint8_t num_streams,
+                                 uint32_t *stream_ids);
+int32_t mm_channel_destroy_bundle(mm_channel_t *my_obj);
+int32_t mm_channel_start_streams(mm_channel_t *my_obj,
+                                 uint8_t num_streams,
+                                 uint32_t *stream_ids);
+int32_t mm_channel_stop_streams(mm_channel_t *my_obj,
+                                uint8_t num_streams,
+                                uint32_t *stream_ids,
+                                uint8_t tear_down_flag);
+int32_t mm_channel_request_super_buf(mm_channel_t *my_obj);
+int32_t mm_channel_cancel_super_buf_request(mm_channel_t *my_obj);
+int32_t mm_channel_start_focus(mm_channel_t *my_obj,
+                               uint32_t sensor_idx,
+                               uint32_t focus_mode);
+int32_t mm_channel_abort_focus(mm_channel_t *my_obj,
+                               uint32_t sensor_idx);
+int32_t mm_channel_prepare_snapshot(mm_channel_t *my_obj,
+                                    uint32_t sensor_idx);
+int32_t mm_channel_set_stream_parm(mm_channel_t *my_obj,
+                                   uint32_t s_id,
+                                   void *value);
+int32_t mm_channel_get_stream_parm(mm_channel_t *my_obj,
+                                   uint32_t s_id,
+                                   void *value);
+uint8_t mm_channel_need_do_pp(mm_channel_t *my_obj,
+                              mm_channel_queue_node_t *super_buf);
+int32_t mm_channel_do_post_processing(mm_channel_t *my_obj,
+                                      mm_channel_queue_node_t *super_buf);
+int32_t mm_channel_cancel_post_processing(mm_channel_t *my_obj);
+int32_t mm_channel_superbuf_bufdone_overflow(mm_channel_t* my_obj,
+                                             mm_channel_queue_t * queue);
+int32_t mm_channel_superbuf_skip(mm_channel_t* my_obj,
+                                 mm_channel_queue_t * queue);
+
+/* state machine function declare */
+int32_t mm_channel_fsm_fn_notused(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val);
+int32_t mm_channel_fsm_fn_stopped(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val);
+int32_t mm_channel_fsm_fn_active(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val);
+int32_t mm_channel_fsm_fn_paused(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val);
+
+/* channel super queue functions */
+int32_t mm_channel_superbuf_queue_init(mm_channel_queue_t * queue);
+int32_t mm_channel_superbuf_queue_deinit(mm_channel_queue_t * queue);
+int32_t mm_channel_superbuf_comp_and_enqueue(mm_channel_t *ch_obj,
+                                             mm_channel_queue_t * queue,
+                                             mm_camera_buf_info_t *buf);
+mm_channel_queue_node_t* mm_channel_superbuf_dequeue(mm_channel_queue_t * queue);
+
+/* channel utility function */
+mm_stream_t * mm_channel_util_get_stream_by_handler(
+                                    mm_channel_t * ch_obj,
+                                    uint32_t handler)
+{
+    int i;
+    mm_stream_t *s_obj = NULL;
+    uint8_t ch_idx = mm_camera_util_get_index_by_handler(handler);
+
+    for(i = 0; i < MM_CAMEAR_STRAEM_NUM_MAX; i++) {
+        if (handler == ch_obj->streams[i].my_hdl) {
+            s_obj = &ch_obj->streams[i];
+            break;
+        }
+    }
+    return s_obj;
+}
+
+/* CB for handling post processing result from ctrl evt */
+static void mm_channel_pp_result_notify(uint32_t camera_handler,
+                                        mm_camera_event_t *evt,
+                                        void *user_data)
+{
+    uint32_t ch_hdl = (uint32_t)user_data;
+    mm_camera_obj_t *cam_obj = NULL;
+    mm_channel_t *ch_obj = NULL;
+    mm_channel_queue_node_t * node = NULL;
+    mm_channel_pp_info_t* pp_info = NULL;
+
+    cam_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+    if (NULL == cam_obj) {
+        CDBG("%s: No matching camera handler", __func__);
+        return;
+    }
+
+    ch_obj = mm_camera_util_get_channel_by_handler(cam_obj, ch_hdl);
+    if (NULL == ch_obj) {
+        CDBG("%s: No matching channel handler", __func__);
+        return;
+    }
+
+    pthread_mutex_lock(&ch_obj->ch_lock);
+    if (ch_obj->pending_pp_cnt > 0) {
+        if (MM_CAMERA_EVT_TYPE_CTRL == evt->event_type) {
+            /* PP result is sent as CTRL event
+             * currently we only have WNR */
+            if (MM_CAMERA_CTRL_EVT_WDN_DONE == evt->e.ctrl.evt) {
+                /* WNR result */
+                pp_info = (mm_channel_pp_info_t *)evt->e.ctrl.cookie;
+                if (NULL != pp_info) {
+                    node = pp_info->super_buf;
+                }
+            }
+        }
+
+        if (NULL != node) {
+            uint8_t pp_done = 1;
+            if (CAM_CTRL_SUCCESS == evt->e.ctrl.status) {
+                uint8_t i;
+                /* 1) update need_pp flag as action done */
+                for (i=0; i<node->num_of_bufs; i++) {
+                    if (node->super_buf[i].stream_id == pp_info->stream_hdl) {
+                        /* stream pp is done, set the flag to 0*/
+                        node->super_buf[i].need_pp = 0;
+                        break;
+                    }
+                }
+
+                /* 2) check if all bufs done with pp */
+                for (i=0; i<node->num_of_bufs; i++) {
+                    if (node->super_buf[i].need_pp) {
+                        pp_done = 0;
+                        break;
+                    }
+                }
+            }
+
+            if (pp_done) {
+                /* send super buf to CB */
+                if (NULL != ch_obj->bundle.super_buf_notify_cb) {
+                    mm_camera_super_buf_t super_buf;
+                    uint8_t i;
+
+                    memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
+                    super_buf.num_bufs = node->num_of_bufs;
+                    for (i=0; i<node->num_of_bufs; i++) {
+                        super_buf.bufs[i] = node->super_buf[i].buf;
+                    }
+                    super_buf.camera_handle = ch_obj->cam_obj->my_hdl;
+                    super_buf.ch_id = ch_obj->my_hdl;
+
+                    ch_obj->bundle.super_buf_notify_cb(&super_buf,
+                                                       ch_obj->bundle.user_data);
+                    ch_obj->pending_pp_cnt--;
+                } else {
+                    /* buf done with the nonuse super buf */
+                    uint8_t i;
+                    for (i=0; i<node->num_of_bufs; i++) {
+                        mm_channel_qbuf(ch_obj, node->super_buf[i].buf);
+                    }
+                }
+
+                /* done with node, free it */
+                free(node);
+            }
+        }
+    }
+    pthread_mutex_unlock(&ch_obj->ch_lock);
+}
+
+/* CB for processing stream buffer */
+static void mm_channel_process_stream_buf(mm_camera_cmdcb_t * cmd_cb,
+                                          void *user_data)
+{
+    mm_camera_super_buf_notify_mode_t notify_mode;
+    mm_channel_queue_node_t *node = NULL;
+    mm_channel_t *ch_obj = (mm_channel_t *)user_data;
+    if (NULL == ch_obj) {
+        return;
+    }
+
+    if (MM_CAMERA_CMD_TYPE_DATA_CB  == cmd_cb->cmd_type) {
+        /* comp_and_enqueue */
+        mm_channel_superbuf_comp_and_enqueue(
+                        ch_obj,
+                        &ch_obj->bundle.superbuf_queue,
+                        &cmd_cb->u.buf);
+    }
+
+    notify_mode = ch_obj->bundle.superbuf_queue.attr.notify_mode;
+
+    /* bufdone for overflowed bufs */
+    mm_channel_superbuf_bufdone_overflow(ch_obj, &ch_obj->bundle.superbuf_queue);
+
+    /* lock ch_lock */
+    pthread_mutex_lock(&ch_obj->ch_lock);
+
+    /* dispatch frame if pending_cnt>0 or is in continuous streaming mode */
+    while ( (ch_obj->pending_cnt > 0) ||
+            (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == notify_mode) ) {
+
+        /* skip frames if needed */
+        mm_channel_superbuf_skip(ch_obj, &ch_obj->bundle.superbuf_queue);
+
+        /* dequeue */
+        node = mm_channel_superbuf_dequeue(&ch_obj->bundle.superbuf_queue);
+        if (NULL != node) {
+            /* decrease pending_cnt */
+            CDBG("%s: Super Buffer received, Call client callback",__func__);
+            if (MM_CAMERA_SUPER_BUF_NOTIFY_BURST == notify_mode) {
+                ch_obj->pending_cnt--;
+            }
+
+            if (mm_channel_need_do_pp(ch_obj, node)) {
+                /* do post processing */
+                ch_obj->pending_pp_cnt++;
+                mm_channel_do_post_processing(ch_obj, node);
+                /* no need to free node here
+                 * node will be as cookie sent to backend doing pp */
+            } else {
+                /* dispatch superbuf */
+                if (NULL != ch_obj->bundle.super_buf_notify_cb) {
+                    mm_camera_super_buf_t super_buf;
+                    uint8_t i;
+
+                    memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
+                    super_buf.num_bufs = node->num_of_bufs;
+                    for (i=0; i<node->num_of_bufs; i++) {
+                        super_buf.bufs[i] = node->super_buf[i].buf;
+                    }
+                    super_buf.camera_handle = ch_obj->cam_obj->my_hdl;
+                    super_buf.ch_id = ch_obj->my_hdl;
+
+                    ch_obj->bundle.super_buf_notify_cb(&super_buf,
+                                                       ch_obj->bundle.user_data);
+                } else {
+                    /* buf done with the nonuse super buf */
+                    uint8_t i;
+                    for (i=0; i<node->num_of_bufs; i++) {
+                        mm_channel_qbuf(ch_obj, node->super_buf[i].buf);
+                    }
+                }
+                free(node);
+            }
+        } else {
+            /* no superbuf avail, break the loop */
+            CDBG_ERROR("%s : Superbuffer not available",__func__);
+            break;
+        }
+    }
+
+    /* unlock ch_lock */
+    pthread_mutex_unlock(&ch_obj->ch_lock);
+}
+
+/* state machine entry */
+int32_t mm_channel_fsm_fn(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val)
+{
+    int32_t rc = -1;
+
+    CDBG("%s : E state = %d",__func__,my_obj->state);
+    switch (my_obj->state) {
+    case MM_CHANNEL_STATE_NOTUSED:
+        rc = mm_channel_fsm_fn_notused(my_obj, evt, in_val, out_val);
+        break;
+    case MM_CHANNEL_STATE_STOPPED:
+        rc = mm_channel_fsm_fn_stopped(my_obj, evt, in_val, out_val);
+        break;
+    case MM_CHANNEL_STATE_ACTIVE:
+        rc = mm_channel_fsm_fn_active(my_obj, evt, in_val, out_val);
+        break;
+    case MM_CHANNEL_STATE_PAUSED:
+        rc = mm_channel_fsm_fn_paused(my_obj, evt, in_val, out_val);
+        break;
+    default:
+        CDBG("%s: Not a valid state (%d)", __func__, my_obj->state);
+        break;
+    }
+
+    /* unlock ch_lock */
+    pthread_mutex_unlock(&my_obj->ch_lock);
+    CDBG("%s : X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_channel_fsm_fn_notused(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val)
+{
+    int32_t rc = -1;
+
+    switch (evt) {
+    default:
+        CDBG_ERROR("%s: invalid state (%d) for evt (%d)",
+                   __func__, my_obj->state, evt);
+        break;
+    }
+
+    return rc;
+}
+
+int32_t mm_channel_fsm_fn_stopped(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val)
+{
+    int32_t rc = -1;
+    CDBG("%s : E evt = %d",__func__,evt);
+    switch (evt) {
+    case MM_CHANNEL_EVT_ADD_STREAM:
+        {
+            uint32_t s_hdl = 0;
+            mm_evt_paylod_add_stream_t *payload =
+                (mm_evt_paylod_add_stream_t *)in_val;
+            s_hdl = mm_channel_add_stream(my_obj,
+                                          payload->buf_cb,
+                                          payload->user_data,
+                                          payload->ext_image_mode,
+                                          payload->sensor_idx);
+            *((uint32_t*)out_val) = s_hdl;
+            rc = 0;
+        }
+        break;
+    case MM_CHANNEL_EVT_DEL_STREAM:
+        {
+            uint32_t s_id = *((uint32_t *)in_val);
+            rc = mm_channel_del_stream(my_obj, s_id);
+        }
+        break;
+    case MM_CHANNEL_EVT_START_STREAM:
+        {
+            mm_evt_payload_start_stream_t *payload =
+                (mm_evt_payload_start_stream_t *)in_val;
+            rc = mm_channel_start_streams(my_obj,
+                                          payload->num_streams,
+                                          payload->stream_ids);
+            /* first stream started in stopped state
+             * move to active state */
+            if (0 == rc) {
+                my_obj->state = MM_CHANNEL_STATE_ACTIVE;
+            }
+        }
+        break;
+    case MM_CHANNEL_EVT_CONFIG_STREAM:
+        {
+            mm_evt_paylod_config_stream_t *payload =
+                (mm_evt_paylod_config_stream_t *)in_val;
+            rc = mm_channel_config_stream(my_obj,
+                                          payload->stream_id,
+                                          payload->config);
+        }
+        break;
+    case MM_CHANNEL_EVT_INIT_BUNDLE:
+        {
+            mm_evt_payload_bundle_stream_t *payload =
+                (mm_evt_payload_bundle_stream_t *)in_val;
+            rc = mm_channel_bundle_stream(my_obj,
+                                          payload->super_frame_notify_cb,
+                                          payload->user_data,
+                                          payload->attr,
+                                          payload->num_streams,
+                                          payload->stream_ids);
+        }
+        break;
+    case MM_CHANNEL_EVT_DESTROY_BUNDLE:
+        rc = mm_channel_destroy_bundle(my_obj);
+        break;
+    case MM_CHANNEL_EVT_PREPARE_SNAPSHOT:
+        {
+            uint32_t sensor_idx = (uint32_t)in_val;
+            rc = mm_channel_prepare_snapshot(my_obj, sensor_idx);
+        }
+        break;
+    case MM_CHANNEL_EVT_DELETE:
+        mm_channel_release(my_obj);
+        rc = 0;
+        break;
+    case MM_CHANNEL_EVT_SET_STREAM_PARM:
+        {
+            uint32_t s_id = (uint32_t)in_val;
+            rc = mm_channel_set_stream_parm(my_obj, s_id, out_val);
+        }
+        break;
+    case MM_CHANNEL_EVT_GET_STREAM_PARM:
+        {
+            uint32_t s_id = (uint32_t)in_val;
+            rc = mm_channel_get_stream_parm(my_obj, s_id, out_val);
+        }
+        break;
+    default:
+        CDBG_ERROR("%s: invalid state (%d) for evt (%d)",
+                   __func__, my_obj->state, evt);
+        break;
+    }
+    CDBG("%s : E rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_channel_fsm_fn_active(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val)
+{
+    int32_t rc = -1;
+
+    CDBG("%s : E evt = %d",__func__,evt);
+    switch (evt) {
+    case MM_CHANNEL_EVT_CONFIG_STREAM:
+        {
+            mm_evt_paylod_config_stream_t *payload =
+                (mm_evt_paylod_config_stream_t *)in_val;
+            rc = mm_channel_config_stream(my_obj,
+                                          payload->stream_id,
+                                          payload->config);
+        }
+        break;
+    case MM_CHANNEL_EVT_START_STREAM:
+        {
+            mm_evt_payload_start_stream_t *payload =
+                (mm_evt_payload_start_stream_t *)in_val;
+            rc = mm_channel_start_streams(my_obj,
+                                          payload->num_streams,
+                                          payload->stream_ids);
+        }
+        break;
+    case MM_CHANNEL_EVT_STOP_STREAM:
+    case MM_CHANNEL_EVT_TEARDOWN_STREAM:
+        {
+            int i;
+            uint8_t tear_down_flag = (MM_CHANNEL_EVT_TEARDOWN_STREAM == evt)? 1:0;
+            uint8_t all_stopped = 1;
+            mm_evt_payload_stop_stream_t *payload =
+                (mm_evt_payload_stop_stream_t *)in_val;
+
+            rc = mm_channel_stop_streams(my_obj,
+                                         payload->num_streams,
+                                         payload->stream_ids,
+                                         tear_down_flag);
+
+            /* check if all streams are stopped
+             * then we move to stopped state */
+
+            for (i=0; i<MM_CAMEAR_STRAEM_NUM_MAX; i++) {
+                if (MM_STREAM_STATE_ACTIVE_STREAM_ON == my_obj->streams[i].state ||
+                    MM_STREAM_STATE_ACTIVE_STREAM_OFF == my_obj->streams[i].state) {
+                    all_stopped = 0;
+                    break;
+                }
+            }
+            if (all_stopped) {
+                my_obj->state = MM_CHANNEL_STATE_STOPPED;
+            }
+
+        }
+        break;
+    case MM_CHANNEL_EVT_INIT_BUNDLE:
+        {
+            mm_evt_payload_bundle_stream_t *payload =
+                (mm_evt_payload_bundle_stream_t *)in_val;
+            rc = mm_channel_bundle_stream(my_obj,
+                                          payload->super_frame_notify_cb,
+                                          payload->user_data,
+                                          payload->attr,
+                                          payload->num_streams,
+                                          payload->stream_ids);
+        }
+        break;
+    case MM_CHANNEL_EVT_DESTROY_BUNDLE:
+        rc = mm_channel_destroy_bundle(my_obj);
+        break;
+    case MM_CHANNEL_EVT_REQUEST_SUPER_BUF:
+        rc = mm_channel_request_super_buf(my_obj);
+        break;
+    case MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF:
+        rc = mm_channel_cancel_super_buf_request(my_obj);
+        break;
+    case MM_CHANNEL_EVT_START_FOCUS:
+        {
+            mm_evt_payload_start_focus_t* payload =
+                (mm_evt_payload_start_focus_t *)in_val;
+            rc = mm_channel_start_focus(my_obj,
+                                        payload->sensor_idx,
+                                        payload->focus_mode);
+        }
+        break;
+    case MM_CHANNEL_EVT_ABORT_FOCUS:
+        {
+            uint32_t sensor_idx = (uint32_t)in_val;
+            rc = mm_channel_abort_focus(my_obj, sensor_idx);
+        }
+        break;
+    case MM_CHANNEL_EVT_PREPARE_SNAPSHOT:
+        {
+            uint32_t sensor_idx = (uint32_t)in_val;
+            rc = mm_channel_prepare_snapshot(my_obj, sensor_idx);
+        }
+        break;
+    case MM_CHANNEL_EVT_SET_STREAM_PARM:
+        {
+            uint32_t s_id = (uint32_t)in_val;
+            rc = mm_channel_set_stream_parm(my_obj, s_id, out_val);
+        }
+        break;
+    case MM_CHANNEL_EVT_GET_STREAM_PARM:
+        {
+            uint32_t s_id = (uint32_t)in_val;
+            rc = mm_channel_get_stream_parm(my_obj, s_id, out_val);
+        }
+        break;
+
+    case MM_CHANNEL_EVT_DEL_STREAM:
+        {
+            uint32_t s_id = *((uint32_t *)in_val);
+            rc = mm_channel_del_stream(my_obj, s_id);
+        }
+        break;
+    default:
+        CDBG_ERROR("%s: invalid state (%d) for evt (%d)",
+                   __func__, my_obj->state, evt);
+        break;
+    }
+    CDBG("%s : X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_channel_fsm_fn_paused(mm_channel_t *my_obj,
+                          mm_channel_evt_type_t evt,
+                          void * in_val,
+                          void * out_val)
+{
+    int32_t rc = -1;
+
+    /* currently we are not supporting pause/resume channel */
+    CDBG_ERROR("%s: evt (%d) not supported in state (%d)",
+               __func__, evt, my_obj->state);
+
+    return rc;
+}
+
+int32_t mm_channel_init(mm_channel_t *my_obj)
+{
+    int32_t rc = 0;
+    CDBG("%s : Launch data poll thread in channel open",__func__);
+    mm_camera_poll_thread_launch(&my_obj->poll_thread[0],
+                                 MM_CAMERA_POLL_TYPE_CH);
+
+    /* change state to stopped state */
+    my_obj->state = MM_CHANNEL_STATE_STOPPED;
+    return rc;
+}
+
+void mm_channel_release(mm_channel_t *my_obj)
+{
+    /* stop data poll thread */
+    mm_camera_poll_thread_release(&my_obj->poll_thread[0]);
+
+    /* change state to notused state */
+    my_obj->state = MM_CHANNEL_STATE_NOTUSED;
+}
+
+uint32_t mm_channel_add_stream(mm_channel_t *my_obj,
+                              mm_camera_buf_notify_t buf_cb, void *user_data,
+                              uint32_t ext_image_mode, uint32_t sensor_idx)
+{
+    int32_t rc = 0;
+    uint8_t idx = 0;
+    uint32_t s_hdl = 0;
+    mm_stream_t *stream_obj = NULL;
+
+    CDBG("%s : image mode = %d",__func__,ext_image_mode);
+    /* check available stream */
+    for (idx = 0; idx < MM_CAMEAR_STRAEM_NUM_MAX; idx++) {
+        if (MM_STREAM_STATE_NOTUSED == my_obj->streams[idx].state) {
+            stream_obj = &my_obj->streams[idx];
+            break;
+        }
+    }
+    if (NULL == stream_obj) {
+        CDBG_ERROR("%s: streams reach max, no more stream allowed to add", __func__);
+        return s_hdl;
+    }
+
+    /* initialize stream object */
+    memset(stream_obj, 0, sizeof(mm_stream_t));
+    stream_obj->my_hdl = mm_camera_util_generate_handler(idx);
+    stream_obj->ch_obj = my_obj;
+    /* cd through intf always palced at idx 0 of buf_cb */
+    stream_obj->buf_cb[0].cb = buf_cb;
+    stream_obj->buf_cb[0].user_data = user_data;
+    stream_obj->buf_cb[0].cb_count = -1; /* infinite by default */
+    stream_obj->ext_image_mode = ext_image_mode + 1;
+    stream_obj->sensor_idx = sensor_idx;
+    stream_obj->fd = -1;
+    pthread_mutex_init(&stream_obj->buf_lock, NULL);
+    pthread_mutex_init(&stream_obj->cb_lock, NULL);
+    stream_obj->state = MM_STREAM_STATE_INITED;
+
+    /* acquire stream */
+    rc = mm_stream_fsm_fn(stream_obj, MM_STREAM_EVT_ACQUIRE, NULL, NULL);
+    if (0 == rc) {
+        s_hdl = stream_obj->my_hdl;
+    } else {
+        /* error during acquire, de-init */
+        pthread_mutex_destroy(&stream_obj->buf_lock);
+        pthread_mutex_destroy(&stream_obj->cb_lock);
+        memset(stream_obj, 0, sizeof(mm_stream_t));
+    }
+    CDBG("%s : stream handle = %d",__func__,s_hdl);
+    return s_hdl;
+}
+
+int32_t mm_channel_del_stream(mm_channel_t *my_obj,
+                              uint32_t stream_id)
+{
+    int rc = -1;
+    mm_stream_t * stream_obj = NULL;
+    stream_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id);
+
+    if (NULL == stream_obj) {
+        CDBG_ERROR("%s :Invalid Stream Object",__func__);
+        return rc;
+    }
+
+    rc = mm_stream_fsm_fn(stream_obj,
+                          MM_STREAM_EVT_RELEASE,
+                          NULL,
+                          NULL);
+
+    return rc;
+}
+
+int32_t mm_channel_config_stream(mm_channel_t *my_obj,
+                                   uint32_t stream_id,
+                                   mm_camera_stream_config_t *config)
+{
+    int rc = -1;
+    mm_stream_t * stream_obj = NULL;
+    CDBG("%s : E stream ID = %d",__func__,stream_id);
+    stream_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id);
+
+    if (NULL == stream_obj) {
+        CDBG_ERROR("%s : X rc = %d",__func__,rc);
+        return rc;
+    }
+
+    /* set stream fmt */
+    rc = mm_stream_fsm_fn(stream_obj,
+                          MM_STREAM_EVT_SET_FMT,
+                          (void *)config,
+                          NULL);
+    CDBG("%s : X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_channel_bundle_stream(mm_channel_t *my_obj,
+                                 mm_camera_buf_notify_t super_frame_notify_cb,
+                                 void *user_data,
+                                 mm_camera_bundle_attr_t *attr,
+                                 uint8_t num_streams,
+                                 uint32_t *stream_ids)
+{
+    int32_t rc = 0;
+    int i;
+    mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL};
+
+    /* first check if all streams to be bundled are valid */
+    for (i=0; i < num_streams; i++) {
+        s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, stream_ids[i]);
+        if (NULL == s_objs[i]) {
+            CDBG_ERROR("%s: invalid stream handler %d (idx=%d) to be bundled",
+                       __func__, stream_ids[i], i);
+            return -1;
+        }
+    }
+
+    /* init superbuf queue */
+    mm_channel_superbuf_queue_init(&my_obj->bundle.superbuf_queue);
+
+    /* save bundle config */
+    memcpy(&my_obj->bundle.superbuf_queue.attr, attr, sizeof(mm_camera_bundle_attr_t));
+    my_obj->bundle.super_buf_notify_cb = super_frame_notify_cb;
+    my_obj->bundle.user_data = user_data;
+    my_obj->bundle.superbuf_queue.num_streams = num_streams;
+    my_obj->bundle.superbuf_queue.expected_frame_id = 0;
+
+    for (i=0; i < num_streams; i++) {
+        /* set bundled flag to streams */
+        s_objs[i]->is_bundled = 1;
+        /* init bundled streams to invalid value -1 */
+        //my_obj->bundle.superbuf_queue.bundled_streams[i] = -1;
+        my_obj->bundle.superbuf_queue.bundled_streams[i] = stream_ids[i];
+    }
+
+    /* launch cmd thread for super buf dataCB */
+    mm_camera_cmd_thread_launch(&my_obj->cmd_thread,
+                                mm_channel_process_stream_buf,
+                                (void*)my_obj);
+
+    /* check if we need to do post-processing */
+    if (my_obj->cam_obj->need_pp) {
+        /* register postProcessingCB at camera evt polling thread
+         * because pp result is coming from ctrl evt */
+        mm_camera_register_event_notify_internal(my_obj->cam_obj,
+                                                 mm_channel_pp_result_notify,
+                                                 (void *)my_obj->my_hdl,
+                                                 MM_CAMERA_EVT_TYPE_CTRL);
+    }
+
+    return rc;
+}
+
+/* bundled streams must all be stopped before bundle can be destroyed */
+int32_t mm_channel_destroy_bundle(mm_channel_t *my_obj)
+{
+
+    mm_camera_cmd_thread_release(&my_obj->cmd_thread);
+
+    /* deinit superbuf queue */
+    mm_channel_superbuf_queue_deinit(&my_obj->bundle.superbuf_queue);
+
+    /* memset bundle info */
+    memset(&my_obj->bundle, 0, sizeof(mm_channel_bundle_t));
+    return 0;
+}
+
+int32_t mm_channel_start_streams(mm_channel_t *my_obj,
+                                 uint8_t num_streams,
+                                 uint32_t *stream_ids)
+{
+    int32_t rc = 0;
+    int i, j;
+    mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL};
+    uint8_t num_streams_to_start = num_streams;
+    uint32_t streams_to_start[MM_CAMEAR_MAX_STRAEM_BUNDLE];
+    uint8_t bundle_to_start = 0;
+
+    /* check if any bundled stream to be start,
+     * then all bundled stream should be started */
+    memcpy(streams_to_start, stream_ids, sizeof(uint32_t) * num_streams);
+    for (i=0; i < num_streams; i++) {
+        for (j=0; j < my_obj->bundle.superbuf_queue.num_streams; j++) {
+            if (stream_ids[i] == my_obj->bundle.superbuf_queue.bundled_streams[j]) {
+                bundle_to_start = 1;
+                break;
+            }
+        }
+    }
+
+    if (bundle_to_start) {
+        uint8_t need_add;
+        /* add bundled streams into the start list if not already added*/
+        for (i=0; i<my_obj->bundle.superbuf_queue.num_streams; i++) {
+            need_add = 1;
+            for (j=0; j<num_streams; j++) {
+                if (stream_ids[j] == my_obj->bundle.superbuf_queue.bundled_streams[i]) {
+                    need_add = 0;
+                    break;
+                }
+            }
+            if (need_add) {
+                streams_to_start[num_streams_to_start++] =
+                    my_obj->bundle.superbuf_queue.bundled_streams[i];
+            }
+        }
+    }
+
+    /* check if all streams to be started are valid */
+    for (i=0; i<num_streams_to_start; i++) {
+        s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, streams_to_start[i]);
+
+        if (NULL == s_objs[i]) {
+            CDBG_ERROR("%s: invalid stream handler %d (idx=%d) to be started",
+                       __func__, streams_to_start[i], i);
+            return -1;
+        }
+    }
+
+    for (i=0; i<num_streams_to_start; i++) {
+        /* allocate buf */
+        rc = mm_stream_fsm_fn(s_objs[i],
+                              MM_STREAM_EVT_GET_BUF,
+                              NULL,
+                              NULL);
+        if (0 != rc) {
+            CDBG_ERROR("%s: get buf failed at idx(%d)", __func__, i);
+            break;
+        }
+
+        /* reg buf */
+        rc = mm_stream_fsm_fn(s_objs[i],
+                              MM_STREAM_EVT_REG_BUF,
+                              NULL,
+                              NULL);
+        if (0 != rc) {
+            CDBG_ERROR("%s: reg buf failed at idx(%d)", __func__, i);
+            break;
+        }
+
+        /* TODO */
+        /* for now, hard-coded to 1 for main image stream */
+        /* Query if stream need to do pp under current hardware configuration,
+         * when camera has offline pp capability */
+        if (my_obj->cam_obj->need_pp) {
+            if (MSM_V4L2_EXT_CAPTURE_MODE_MAIN == s_objs[i]->ext_image_mode) {
+                s_objs[i]->is_pp_needed = 1;
+            } else {
+                s_objs[i]->is_pp_needed = 0;
+            }
+        }
+
+        /* start stream */
+        rc = mm_stream_fsm_fn(s_objs[i],
+                              MM_STREAM_EVT_START,
+                              NULL,
+                              NULL);
+        if (0 != rc) {
+            CDBG_ERROR("%s: start stream failed at idx(%d)", __func__, i);
+            break;
+        }
+    }
+
+    /* error handling */
+    if (0 != rc) {
+        for (j=0; j<=i; j++) {
+            /* stop streams*/
+            mm_stream_fsm_fn(s_objs[i],
+                             MM_STREAM_EVT_STOP,
+                             NULL,
+                             NULL);
+
+            /* unreg buf */
+            mm_stream_fsm_fn(s_objs[i],
+                             MM_STREAM_EVT_UNREG_BUF,
+                             NULL,
+                             NULL);
+
+            /* put buf back */
+            mm_stream_fsm_fn(s_objs[i],
+                             MM_STREAM_EVT_PUT_BUF,
+                             NULL,
+                             NULL);
+        }
+    }
+
+    return rc;
+}
+
+/* Required: bundled streams need to be stopped together */
+int32_t mm_channel_stop_streams(mm_channel_t *my_obj,
+                                uint8_t num_streams,
+                                uint32_t *stream_ids,
+                                uint8_t tear_down_flag)
+{
+    int32_t rc = 0;
+    int i, j;
+    mm_stream_t* s_objs[MM_CAMEAR_MAX_STRAEM_BUNDLE] = {NULL};
+    uint8_t num_streams_to_stop = num_streams;
+    uint32_t streams_to_stop[MM_CAMEAR_MAX_STRAEM_BUNDLE];
+    uint8_t bundle_to_stop = 0;
+
+    /* make sure bundled streams are stopped together */
+    memcpy(streams_to_stop, stream_ids, sizeof(uint32_t) * num_streams);
+    for (i=0; i<num_streams; i++) {
+        for (j=0; j<my_obj->bundle.superbuf_queue.num_streams; j++) {
+            if (stream_ids[i] == my_obj->bundle.superbuf_queue.bundled_streams[j]) {
+                bundle_to_stop = 1;
+                break;
+            }
+        }
+    }
+    if (bundle_to_stop) {
+        uint8_t need_add;
+        /* add bundled streams into the start list if not already added*/
+        for (i=0; i<my_obj->bundle.superbuf_queue.num_streams; i++) {
+            need_add = 1;
+            for (j=0; j<num_streams; j++) {
+                if (stream_ids[j] == my_obj->bundle.superbuf_queue.bundled_streams[i]) {
+                    need_add = 0;
+                    break;
+                }
+            }
+            if (need_add) {
+                streams_to_stop[num_streams_to_stop++] =
+                    my_obj->bundle.superbuf_queue.bundled_streams[i];
+            }
+        }
+    }
+
+    for (i=0; i<num_streams_to_stop; i++) {
+        s_objs[i] = mm_channel_util_get_stream_by_handler(my_obj, streams_to_stop[i]);
+
+        if (NULL != s_objs[i]) {
+            /* stream off */
+            mm_stream_fsm_fn(s_objs[i],
+                             MM_STREAM_EVT_STOP,
+                             NULL,
+                             NULL);
+
+            /* unreg buf at kernel */
+            mm_stream_fsm_fn(s_objs[i],
+                             MM_STREAM_EVT_UNREG_BUF,
+                             NULL,
+                             NULL);
+        }
+    }
+
+    /* since all streams are stopped, we are safe to
+     * release all buffers allocated in stream */
+    for (i=0; i<num_streams_to_stop; i++) {
+        if (NULL != s_objs[i]) {
+            /* put buf back */
+            mm_stream_fsm_fn(s_objs[i],
+                             MM_STREAM_EVT_PUT_BUF,
+                             NULL,
+                             NULL);
+
+            if (tear_down_flag) {
+                /* to tear down stream totally, stream needs to be released */
+                mm_stream_fsm_fn(s_objs[i],
+                                 MM_STREAM_EVT_RELEASE,
+                                 NULL,
+                                 NULL);
+            }
+        }
+    }
+
+    return rc;
+}
+
+int32_t mm_channel_request_super_buf(mm_channel_t *my_obj)
+{
+    int32_t rc = 0;
+    mm_camera_cmdcb_t* node = NULL;
+
+    /* set pending_cnt
+     * will trigger dispatching super frames if pending_cnt > 0 */
+    my_obj->pending_cnt = my_obj->bundle.superbuf_queue.attr.burst_num;
+
+    /* send sem_post to wake up cmd thread to dispatch super buffer */
+    node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
+    if (NULL != node) {
+        memset(node, 0, sizeof(mm_camera_cmdcb_t));
+        node->cmd_type = MM_CAMERA_CMD_TYPE_REQ_DATA_CB;
+
+        /* enqueue to cmd thread */
+        mm_camera_queue_enq(&(my_obj->cmd_thread.cmd_queue), node);
+
+        /* wake up cmd thread */
+        sem_post(&(my_obj->cmd_thread.cmd_sem));
+    } else {
+        CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
+        rc = -1;
+    }
+
+    return rc;
+}
+
+int32_t mm_channel_cancel_super_buf_request(mm_channel_t *my_obj)
+{
+    int32_t rc = 0;
+    /* reset pending_cnt */
+    my_obj->pending_cnt = 0;
+
+    if (my_obj->pending_pp_cnt > 0) {
+        rc = mm_channel_cancel_post_processing(my_obj);
+    }
+    my_obj->pending_pp_cnt = 0;
+    return rc;
+}
+
+int32_t mm_channel_qbuf(mm_channel_t *my_obj,
+                        mm_camera_buf_def_t *buf)
+{
+    int32_t rc = -1;
+    struct ion_flush_data cache_inv_data;
+    int ion_fd;
+    struct msm_frame *cache_frame;
+    struct msm_frame *cache_frame1 = NULL;
+
+    mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, buf->stream_id);
+
+    if (NULL != s_obj) {
+        rc = mm_stream_fsm_fn(s_obj,
+                              MM_STREAM_EVT_QBUF,
+                              (void *)buf,
+                              NULL);
+    }
+
+#ifdef USE_ION
+    cache_inv_data.vaddr = cache_frame->buffer;
+    cache_inv_data.fd = cache_frame->fd;
+    cache_inv_data.handle = cache_frame->fd_data.handle;
+    cache_inv_data.length = cache_frame->ion_alloc.len;
+    ion_fd = cache_frame->ion_dev_fd;
+    if(ion_fd > 0) {
+        if(ioctl(ion_fd, ION_IOC_INV_CACHES, &cache_inv_data) < 0)
+            CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
+        else {
+            CDBG("%s: Successful cache invalidate\n", __func__);
+            if(cache_frame1) {
+                ion_fd = cache_frame1->ion_dev_fd;
+                cache_inv_data.vaddr = cache_frame1->buffer;
+                cache_inv_data.fd = cache_frame1->fd;
+                cache_inv_data.handle = cache_frame1->fd_data.handle;
+                cache_inv_data.length = cache_frame1->ion_alloc.len;
+                if(ioctl(ion_fd, ION_IOC_INV_CACHES, &cache_inv_data) < 0)
+                    CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
+                else
+                    CDBG("%s: Successful cache invalidate\n", __func__);
+            }
+        }
+    }
+#endif
+
+    return rc;
+}
+
+int32_t mm_channel_start_focus(mm_channel_t *my_obj,
+                               uint32_t sensor_idx,
+                               uint32_t focus_mode)
+{
+    return mm_camera_send_native_ctrl_cmd(my_obj->cam_obj,
+                                          CAMERA_SET_PARM_AUTO_FOCUS,
+                                          sizeof(uint32_t), (void*)focus_mode);
+}
+
+int32_t mm_channel_abort_focus(mm_channel_t *my_obj, uint32_t sensor_idx)
+{
+    return mm_camera_send_native_ctrl_cmd(my_obj->cam_obj,
+                                          CAMERA_AUTO_FOCUS_CANCEL,
+                                          0, NULL);
+}
+
+int32_t mm_channel_prepare_snapshot(mm_channel_t *my_obj, uint32_t sensor_idx)
+{
+    return mm_camera_send_native_ctrl_timeout_cmd(my_obj->cam_obj,
+                                                CAMERA_PREPARE_SNAPSHOT,
+                                                0, NULL, 2000);
+}
+
+int32_t mm_channel_set_stream_parm(mm_channel_t *my_obj,
+                                   uint32_t s_id,
+                                   void *value)
+{
+    int32_t rc = -1;
+    mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, s_id);
+    if (NULL != s_obj) {
+        rc = mm_stream_fsm_fn(s_obj,
+                              MM_STREAM_EVT_SET_PARM,
+                              value,
+                              NULL);
+    }
+
+    return rc;
+}
+
+int32_t mm_channel_get_stream_parm(mm_channel_t *my_obj,
+                                   uint32_t s_id,
+                                   void *value)
+{
+    int32_t rc = -1;
+    mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, s_id);
+    if (NULL != s_obj) {
+        rc = mm_stream_fsm_fn(s_obj,
+                              MM_STREAM_EVT_GET_PARM,
+                              NULL,
+                              value);
+    }
+
+    return rc;
+}
+
+uint8_t mm_channel_need_do_pp(mm_channel_t *my_obj,
+                              mm_channel_queue_node_t *super_buf)
+{
+    uint8_t need_pp = 0;
+    uint8_t i;
+
+    for (i=0; i<super_buf->num_of_bufs; i++) {
+        if (super_buf->super_buf[i].need_pp) {
+            need_pp = 1;
+            break;
+        }
+    }
+    return need_pp;
+}
+
+int32_t mm_channel_do_post_processing(mm_channel_t *my_obj,
+                                      mm_channel_queue_node_t *super_buf)
+{
+    int32_t rc = 0;
+    cam_sock_packet_t packet;
+    uint8_t i;
+    mm_stream_t* s_obj = NULL;
+    mm_channel_pp_info_t *cookie = NULL;
+
+    /* TODO : currently we only do WNR, may need extended PP */
+    /* send cmd to backend to start pp */
+    for (i=0; i<super_buf->num_of_bufs; i++) {
+        if (super_buf->super_buf[i].need_pp) {
+            s_obj = mm_channel_util_get_stream_by_handler(my_obj, super_buf->super_buf[i].stream_id);
+            if (NULL != s_obj) {
+                cookie = (mm_channel_pp_info_t*)malloc(sizeof(mm_channel_pp_info_t));
+                if (NULL != cookie) {
+                    memset(&packet, 0, sizeof(cam_sock_packet_t));
+                    memset(cookie, 0, sizeof(mm_channel_pp_info_t));
+                    cookie->cam_hdl = my_obj->cam_obj->my_hdl;
+                    cookie->ch_hdl = my_obj->my_hdl;
+                    cookie->stream_hdl = s_obj->my_hdl;
+                    cookie->super_buf = super_buf;
+
+                    packet.msg_type = CAM_SOCK_MSG_TYPE_WDN_START;
+                    packet.payload.wdn_start.cookie = (unsigned long)cookie;
+                    packet.payload.wdn_start.num_frames = 1;
+                    packet.payload.wdn_start.ext_mode[0] = s_obj->ext_image_mode;
+                    packet.payload.wdn_start.frame_idx[0] = super_buf->super_buf[i].buf->buf_idx;
+                    rc = mm_camera_util_sendmsg(my_obj->cam_obj, &packet, sizeof(packet), 0);
+                    if (0 != rc) {
+                        CDBG_ERROR("%s: Send DoPP msg failed (rc=%d)", __func__, rc);
+                        free(cookie);
+                        break;
+                    }
+                } else {
+                    CDBG_ERROR("%s: No memory for mm_channel_pp_info_t", __func__);
+                    break;
+                }
+            }
+        }
+    }
+
+    return rc;
+}
+
+int32_t mm_channel_cancel_post_processing(mm_channel_t *my_obj)
+{
+    int32_t rc = 0;
+    /* TODO */
+    /* need send cmd to backend to cancel all pp request */
+
+    return rc;
+}
+
+int32_t mm_channel_reg_stream_cb(mm_channel_t *my_obj,
+                                 mm_stream_data_cb_t *cb,
+                                 uint32_t ext_image_mode,
+                                 uint32_t sensor_idx)
+{
+    uint8_t idx;
+    mm_stream_t *dest_stream = NULL;
+    int32_t rc = -1;
+
+    /* browse all streams in channel to find the destination */
+    for (idx=0; idx < MM_CAMEAR_STRAEM_NUM_MAX; idx++) {
+        if (my_obj->streams[idx].state != MM_STREAM_STATE_NOTUSED &&
+            my_obj->streams[idx].ext_image_mode == ext_image_mode &&
+            my_obj->streams[idx].sensor_idx == sensor_idx) {
+            /* find matching stream as the destination */
+            dest_stream = &my_obj->streams[idx];
+            break;
+        }
+    }
+
+    if (NULL != dest_stream) {
+        rc = mm_stream_reg_buf_cb(dest_stream, cb);
+    }
+
+    return rc;
+}
+
+int32_t mm_channel_superbuf_queue_init(mm_channel_queue_t * queue)
+{
+    return mm_camera_queue_init(&queue->que);
+}
+
+int32_t mm_channel_superbuf_queue_deinit(mm_channel_queue_t * queue)
+{
+    return mm_camera_queue_deinit(&queue->que);
+}
+
+int8_t mm_channel_util_seq_comp_w_rollover(uint32_t v1,
+                                           uint32_t v2)
+{
+    int8_t ret = 0;
+
+    /* TODO: need to handle the case if v2 roll over to 0 */
+    if (v1 > v2) {
+        ret = 1;
+    } else if (v1 < v2) {
+        ret = -1;
+    }
+
+    return ret;
+}
+
+int32_t mm_channel_superbuf_comp_and_enqueue(
+                        mm_channel_t* ch_obj,
+                        mm_channel_queue_t * queue,
+                        mm_camera_buf_info_t *buf_info)
+{
+    mm_camera_q_node_t* node = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+    mm_channel_queue_node_t* super_buf = NULL;
+    uint8_t buf_s_idx, i;
+
+    for (buf_s_idx=0; buf_s_idx < queue->num_streams; buf_s_idx++) {
+        if (buf_info->stream_id == queue->bundled_streams[buf_s_idx]) {
+            break;
+        }
+    }
+    if (buf_s_idx == queue->num_streams) {
+        CDBG_ERROR("%s: buf from stream (%d) not bundled", __func__, buf_info->stream_id);
+        return -1;
+    }
+
+    if (mm_channel_util_seq_comp_w_rollover(buf_info->frame_idx,
+                                            queue->expected_frame_id) < 0) {
+        /* incoming buf is older than expected buf id, will discard it */
+        mm_channel_qbuf(ch_obj, buf_info->buf);
+        return 0;
+    }
+
+    if (MM_CAMERA_SUPER_BUF_PRIORITY_NORMAL != queue->attr.priority) {
+        /* TODO */
+        /* need to decide if we want to queue the frame based on focus or exposure
+         * if frame not to be queued, we need to qbuf it back */
+    }
+
+    /* comp */
+    pthread_mutex_lock(&queue->que.lock);
+    head = &queue->que.head.list;
+    /* get the last one in the queue which is possibly having no matching */
+    pos = head->next;
+    while (pos != head) {
+        node = member_of(pos, mm_camera_q_node_t, list);
+        super_buf = (mm_channel_queue_node_t*)node->data;
+        if (NULL != super_buf) {
+            if (super_buf->matched) {
+                /* find a matched super buf, move to next one */
+                pos = pos->next;
+                continue;
+            } else {
+                /* have an unmatched super buf, break the loop */
+                break;
+            }
+        }
+    }
+
+    if (pos == head) {
+        /* all nodes in queue are mtached, or no node in queue
+         * create a new node */
+        mm_channel_queue_node_t *new_buf = NULL;
+        mm_camera_q_node_t* new_node = NULL;
+
+        new_buf = (mm_channel_queue_node_t*)malloc(sizeof(mm_channel_queue_node_t));
+        new_node = (mm_camera_q_node_t*)malloc(sizeof(mm_camera_q_node_t));
+        if (NULL != new_buf && NULL != new_node) {
+            memset(new_buf, 0, sizeof(mm_channel_queue_node_t));
+            memset(new_node, 0, sizeof(mm_camera_q_node_t));
+            new_node->data = (void *)new_buf;
+            new_buf->num_of_bufs = queue->num_streams;
+            memcpy(&new_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t));
+
+            /* enqueue */
+            //cam_list_add_tail_node(&node->list, &queue->que.head.list);
+            cam_list_add_tail_node(&new_node->list, &queue->que.head.list);
+            queue->que.size++;
+
+            if(queue->num_streams == 1) {
+                //TODO : Check. Live snapshot will have one stream in bundle?
+                new_buf->matched = 1;
+
+                if (new_buf->matched) {
+                    queue->expected_frame_id = buf_info->frame_idx + queue->attr.post_frame_skip;
+                    queue->match_cnt++;
+                }
+            }
+        } else {
+            /* No memory */
+            if (NULL != new_buf) {
+                free(new_buf);
+            }
+            if (NULL != new_node) {
+                free(new_node);
+            }
+            /* qbuf the new buf since we cannot enqueue */
+            mm_channel_qbuf(ch_obj, buf_info->buf);
+        }
+    } else {
+        /* find an unmatched super buf */
+        if (super_buf->super_buf[buf_s_idx].frame_idx == 0) {
+            /* new frame from the stream_id */
+            uint8_t is_new = 1;
+            uint32_t frame_idx;
+
+            for (i=0; i < super_buf->num_of_bufs; i++) {
+            //for (i=0; i < buf_s_idx; i++) {
+                if(super_buf->super_buf[i].buf == NULL) {
+                    continue;
+                }
+                frame_idx = super_buf->super_buf[i].buf->frame_idx;
+                if (frame_idx == 0) {
+                    continue;
+                }
+                if (frame_idx < buf_info->frame_idx) {
+                    /* existing frame is older than the new frame, qbuf it */
+                    mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf);
+                    memset(&super_buf->super_buf[i], 0, sizeof(mm_camera_buf_info_t));
+                } else if (frame_idx > buf_info->frame_idx) {
+                    /* new frame is older */
+                    is_new = 0;
+                    break;
+                }else{
+                    //TODO: reveiw again
+                    break;
+                }
+            }
+            if (is_new) {
+                memcpy(&super_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t));
+
+                /* check if superbuf is all matched */
+                super_buf->matched = 1;
+                for (i=0; i < super_buf->num_of_bufs; i++) {
+                    if (super_buf->super_buf[i].frame_idx == 0) {
+                        super_buf->matched = 0;
+                        break;
+                    }
+                }
+
+                if (super_buf->matched) {
+                    queue->expected_frame_id = buf_info->frame_idx + queue->attr.post_frame_skip;
+                    queue->match_cnt++;
+                }
+            } else {
+                mm_channel_qbuf(ch_obj, buf_info->buf);
+            }
+        } else {
+            if (super_buf->super_buf[buf_s_idx].frame_idx < buf_info->frame_idx) {
+                /* current frames in superbuf are older than the new frame
+                 * qbuf all current frames */
+                for (i=0; i<super_buf->num_of_bufs; i++) {
+                    if (super_buf->super_buf[i].frame_idx != 0) {
+                            mm_channel_qbuf(ch_obj, super_buf->super_buf[i].buf);
+                            memset(&super_buf->super_buf[i], 0, sizeof(mm_camera_buf_info_t));
+                    }
+                }
+                /* add the new frame into the superbuf */
+                memcpy(&super_buf->super_buf[buf_s_idx], buf_info, sizeof(mm_camera_buf_info_t));
+            } else {
+                /* the new frame is older, just ignor */
+                mm_channel_qbuf(ch_obj, buf_info->buf);
+            }
+        }
+    }
+    pthread_mutex_unlock(&queue->que.lock);
+
+    return 0;
+}
+
+mm_channel_queue_node_t* mm_channel_superbuf_dequeue_internal(mm_channel_queue_t * queue)
+{
+    mm_camera_q_node_t* node = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+    mm_channel_queue_node_t* super_buf = NULL;
+
+    head = &queue->que.head.list;
+    pos = head->next;
+    if (pos != head) {
+        /* get the first node */
+        node = member_of(pos, mm_camera_q_node_t, list);
+        super_buf = (mm_channel_queue_node_t*)node->data;
+        if (NULL != super_buf) {
+            if (super_buf->matched) {
+                /* we found a mtaching super buf, dequeue it */
+                cam_list_del_node(&node->list);
+                queue->que.size--;
+                queue->match_cnt--;
+                free(node);
+            } else {
+                super_buf = NULL;
+            }
+        }
+    }
+
+    return super_buf;
+}
+
+mm_channel_queue_node_t* mm_channel_superbuf_dequeue(mm_channel_queue_t * queue)
+{
+    mm_camera_q_node_t* node = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+    mm_channel_queue_node_t* super_buf = NULL;
+
+    pthread_mutex_lock(&queue->que.lock);
+    super_buf = mm_channel_superbuf_dequeue_internal(queue);
+    pthread_mutex_unlock(&queue->que.lock);
+
+    return super_buf;
+}
+
+int32_t mm_channel_superbuf_bufdone_overflow(mm_channel_t* my_obj,
+                                             mm_channel_queue_t * queue)
+{
+    int32_t rc = 0, i;
+    mm_channel_queue_node_t* super_buf = NULL;
+    if (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == queue->attr.notify_mode) {
+        /* for continuous streaming mode, no overflow is needed */
+        return 0;
+    }
+
+    /* bufdone overflowed bufs */
+    pthread_mutex_lock(&queue->que.lock);
+    while (queue->match_cnt > queue->attr.water_mark) {
+        super_buf = mm_channel_superbuf_dequeue_internal(queue);
+        if (NULL != super_buf) {
+            for (i=0; i<super_buf->num_of_bufs; i++) {
+                if (NULL != super_buf->super_buf[i].buf) {
+                    mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf);
+                }
+            }
+            free(super_buf);
+        }
+    }
+    pthread_mutex_unlock(&queue->que.lock);
+
+    return rc;
+}
+
+int32_t mm_channel_superbuf_skip(mm_channel_t* my_obj,
+                                 mm_channel_queue_t * queue)
+{
+    int32_t rc = 0, i, count;
+    mm_channel_queue_node_t* super_buf = NULL;
+    if (MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS == queue->attr.notify_mode) {
+        /* for continuous streaming mode, no skip is needed */
+        return 0;
+    }
+
+    /* bufdone overflowed bufs */
+    pthread_mutex_lock(&queue->que.lock);
+    while (queue->match_cnt > queue->attr.look_back) {
+        super_buf = mm_channel_superbuf_dequeue_internal(queue);
+        if (NULL != super_buf) {
+            for (i=0; i<super_buf->num_of_bufs; i++) {
+                if (NULL != super_buf->super_buf[i].buf) {
+                    mm_channel_qbuf(my_obj, super_buf->super_buf[i].buf);
+                }
+            }
+            free(super_buf);
+        }
+    }
+    pthread_mutex_unlock(&queue->que.lock);
+
+    return rc;
+}
+
diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera_data.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_data.c
new file mode 100755
index 0000000..b55e617
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_data.c
@@ -0,0 +1,228 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <camera.h>
+#include <semaphore.h>
+
+#include "mm_camera_dbg.h"
+#include "mm_camera_interface.h"
+#include "mm_camera.h"
+
+#if 0
+#undef CDBG
+#undef LOG_TAG
+#define CDBG ALOGE
+#define LOG_TAG "NotifyLogs"
+#endif
+
+int32_t mm_camera_queue_init(mm_camera_queue_t* queue)
+{
+    pthread_mutex_init(&queue->lock, NULL);
+    cam_list_init(&queue->head.list);
+    queue->size = 0;
+    return 0;
+}
+
+int32_t mm_camera_queue_enq(mm_camera_queue_t* queue, void* data)
+{
+    mm_camera_q_node_t* node =
+        (mm_camera_q_node_t *)malloc(sizeof(mm_camera_q_node_t));
+    if (NULL == node) {
+        CDBG_ERROR("%s: No memory for mm_camera_q_node_t", __func__);
+        return -1;
+    }
+
+    memset(node, 0, sizeof(mm_camera_q_node_t));
+    node->data = data;
+
+    pthread_mutex_lock(&queue->lock);
+    cam_list_add_tail_node(&node->list, &queue->head.list);
+    queue->size++;
+    pthread_mutex_unlock(&queue->lock);
+
+    return 0;
+
+}
+
+void* mm_camera_queue_deq(mm_camera_queue_t* queue)
+{
+    mm_camera_q_node_t* node = NULL;
+    void* data = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+
+    pthread_mutex_lock(&queue->lock);
+    head = &queue->head.list;
+    pos = head->next;
+    if (pos != head) {
+        node = member_of(pos, mm_camera_q_node_t, list);
+        cam_list_del_node(&node->list);
+        queue->size--;
+    }
+    pthread_mutex_unlock(&queue->lock);
+
+    if (NULL != node) {
+        data = node->data;
+        free(node);
+    }
+
+    return data;
+}
+
+int32_t mm_camera_queue_deinit(mm_camera_queue_t* queue)
+{
+    mm_camera_queue_flush(queue);
+    pthread_mutex_destroy(&queue->lock);
+    return 0;
+}
+
+int32_t mm_camera_queue_flush(mm_camera_queue_t* queue)
+{
+    mm_camera_q_node_t* node = NULL;
+    void* data = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+
+    pthread_mutex_lock(&queue->lock);
+    head = &queue->head.list;
+    pos = head->next;
+
+    while(pos != head) {
+        node = member_of(pos, mm_camera_q_node_t, list);
+        cam_list_del_node(&node->list);
+        queue->size--;
+
+        /* TODO later to consider ptr inside data */
+        /* for now we only assume there is no ptr inside data
+         * so we free data directly */
+        if (NULL != node->data) {
+            free(node->data);
+        }
+        free(node);
+        pos = pos->next;
+    }
+    queue->size = 0;
+    pthread_mutex_unlock(&queue->lock);
+    return 0;
+}
+
+static void *mm_camera_cmd_thread(void *data)
+{
+    int rc = 0;
+    int running = 1;
+    int ret;
+    mm_camera_cmd_thread_t *cmd_thread =
+                (mm_camera_cmd_thread_t *)data;
+    mm_camera_cmdcb_t* node = NULL;
+
+    do {
+        do {
+            ret = sem_wait(&cmd_thread->cmd_sem);
+            if (ret != 0 && errno != EINVAL) {
+                CDBG_ERROR("%s: sem_wait error (%s)",
+                           __func__, strerror(errno));
+                return NULL;
+            }
+        } while (ret != 0);
+
+        /* we got notified about new cmd avail in cmd queue */
+        node = (mm_camera_cmdcb_t*)mm_camera_queue_deq(&cmd_thread->cmd_queue);
+        if (node != NULL) {
+            switch (node->cmd_type) {
+            case MM_CAMERA_CMD_TYPE_EVT_CB:
+            case MM_CAMERA_CMD_TYPE_DATA_CB:
+            case MM_CAMERA_CMD_TYPE_ASYNC_CB:
+            case MM_CAMERA_CMD_TYPE_REQ_DATA_CB:
+                if (NULL != cmd_thread->cb) {
+                    cmd_thread->cb(node, cmd_thread->user_data);
+                }
+                break;
+            case MM_CAMERA_CMD_TYPE_EXIT:
+            default:
+                running = 0;
+                break;
+            }
+            free(node);
+        }
+    } while (running);
+    return NULL;
+}
+
+int32_t mm_camera_cmd_thread_launch(mm_camera_cmd_thread_t * cmd_thread,
+                                    mm_camera_cmd_cb_t cb,
+                                    void* user_data)
+{
+    int32_t rc = 0;
+
+    sem_init(&cmd_thread->cmd_sem, 0, 0);
+    mm_camera_queue_init(&cmd_thread->cmd_queue);
+    cmd_thread->cb = cb;
+    cmd_thread->user_data = user_data;
+
+    /* launch the thread */
+    pthread_create(&cmd_thread->cmd_pid,
+                   NULL,
+                   mm_camera_cmd_thread,
+                   (void *)cmd_thread);
+    return rc;
+}
+
+int32_t mm_camera_cmd_thread_release(mm_camera_cmd_thread_t * cmd_thread)
+{
+    int32_t rc = 0;
+    mm_camera_buf_info_t  buf_info;
+    mm_camera_cmdcb_t* node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
+    if (NULL == node) {
+        CDBG_ERROR("%s: No memory for mm_camera_cmdcb_t", __func__);
+        return -1;
+    }
+
+    memset(node, 0, sizeof(mm_camera_cmdcb_t));
+    node->cmd_type = MM_CAMERA_CMD_TYPE_EXIT;
+
+    mm_camera_queue_enq(&cmd_thread->cmd_queue, node);
+    sem_post(&cmd_thread->cmd_sem);
+
+    /* wait until cmd thread exits */
+    if (pthread_join(cmd_thread->cmd_pid, NULL) != 0) {
+        CDBG("%s: pthread dead already\n", __func__);
+    }
+    mm_camera_queue_deinit(&cmd_thread->cmd_queue);
+
+    sem_destroy(&cmd_thread->cmd_sem);
+    memset(cmd_thread, 0, sizeof(mm_camera_cmd_thread_t));
+    return rc;
+}
+
diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera_helper.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_helper.c
new file mode 100755
index 0000000..da5b61d
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_helper.c
@@ -0,0 +1,318 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include "mm_camera_dbg.h"
+#include <time.h>
+#include "mm_camera_interface.h"
+#include <linux/ion.h>
+
+#define MM_CAMERA_PROFILE 1
+
+struct file;
+struct inode;
+struct vm_area_struct;
+
+/*===========================================================================
+ * FUNCTION    - do_mmap -
+ *
+ * DESCRIPTION:  retured virtual addresss
+ *==========================================================================*/
+uint8_t *mm_camera_do_mmap(uint32_t size, int *pmemFd)
+{
+    void *ret; /* returned virtual address */
+    int  pmem_fd = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
+
+    if (pmem_fd <= 0) {
+        CDBG("do_mmap: Open device /dev/pmem_adsp failed!\n");
+        return NULL;
+    }
+    /* to make it page size aligned */
+    size = (size + 4095) & (~4095);
+  ret = mmap(NULL,
+    size,
+    PROT_READ  | PROT_WRITE,
+    MAP_SHARED,
+    pmem_fd,
+    0);
+    if (ret == MAP_FAILED) {
+        CDBG("do_mmap: pmem mmap() failed: %s (%d)\n", strerror(errno), errno);
+        close(pmem_fd);
+        return NULL;
+    }
+    CDBG("do_mmap: pmem mmap fd %d ptr %p len %u\n", pmem_fd, ret, size);
+    *pmemFd = pmem_fd;
+    return(uint8_t *)ret;
+}
+
+/*===========================================================================
+ * FUNCTION    - do_munmap -
+ *
+ * DESCRIPTION:
+ *==========================================================================*/
+int mm_camera_do_munmap(int pmem_fd, void *addr, size_t size)
+{
+    int rc;
+
+    if (pmem_fd <= 0) {
+        CDBG("%s:invalid fd=%d\n", __func__, pmem_fd);
+        return -1;
+    }
+    size = (size + 4095) & (~4095);
+    CDBG("munmapped size = %d, virt_addr = 0x%p\n",
+    size, addr);
+    rc = (munmap(addr, size));
+    close(pmem_fd);
+    CDBG("do_mmap: pmem munmap fd %d ptr %p len %u rc %d\n", pmem_fd, addr,
+    size, rc);
+    return rc;
+}
+
+#ifdef USE_ION
+uint8_t *mm_camera_do_mmap_ion(int ion_fd, struct ion_allocation_data *alloc,
+                               struct ion_fd_data *ion_info_fd, int *mapFd)
+{
+  void *ret; /* returned virtual address */
+  int rc = 0;
+  struct ion_handle_data handle_data;
+
+  /* to make it page size aligned */
+  alloc->len = (alloc->len + 4095) & (~4095);
+
+  rc = ioctl(ion_fd, ION_IOC_ALLOC, alloc);
+  if (rc < 0) {
+    CDBG_ERROR("ION allocation failed\n");
+    goto ION_ALLOC_FAILED;
+  }
+
+  ion_info_fd->handle = alloc->handle;
+  rc = ioctl(ion_fd, ION_IOC_SHARE, ion_info_fd);
+  if (rc < 0) {
+    CDBG_ERROR("ION map failed %s\n", strerror(errno));
+    goto ION_MAP_FAILED;
+  }
+  *mapFd = ion_info_fd->fd;
+  /*ret = mmap(NULL,
+    alloc->len,
+    PROT_READ  | PROT_WRITE,
+    MAP_SHARED,
+    *mapFd,
+    0);
+
+  if (ret == MAP_FAILED) {
+    CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno);
+    goto ION_MAP_FAILED;
+  }*/
+
+  return ret;
+
+ION_MAP_FAILED:
+  handle_data.handle = ion_info_fd->handle;
+  ioctl(ion_fd, ION_IOC_FREE, &handle_data);
+ION_ALLOC_FAILED:
+  return NULL;
+}
+
+int mm_camera_do_munmap_ion (int ion_fd, struct ion_fd_data *ion_info_fd,
+                   void *addr, size_t size)
+{
+  int rc = 0;
+  rc = munmap(addr, size);
+  close(ion_info_fd->fd);
+
+  struct ion_handle_data handle_data;
+  handle_data.handle = ion_info_fd->handle;
+  ioctl(ion_fd, ION_IOC_FREE, &handle_data);
+  return rc;
+}
+#endif
+
+/*============================================================
+   FUNCTION mm_camera_dump_image
+   DESCRIPTION:
+==============================================================*/
+int mm_camera_dump_image(void *addr, uint32_t size, char *filename)
+{
+  int file_fd = open(filename, O_RDWR | O_CREAT, 0777);
+
+  if (file_fd < 0) {
+    CDBG_HIGH("%s: cannot open file\n", __func__);
+    return -1;
+  } else
+    write(file_fd, addr, size);
+  close(file_fd);
+  CDBG("%s: %s, size=%d\n", __func__, filename, size);
+  return 0;
+}
+
+uint32_t mm_camera_get_msm_frame_len(cam_format_t fmt_type,
+                                     camera_mode_t mode,
+                                     int width,
+                                     int height,
+                                     int image_type,
+                                     uint8_t *num_planes,
+                                     uint32_t plane[])
+{
+    uint32_t size;
+    *num_planes = 0;
+    int local_height;
+
+    switch (fmt_type) {
+    case CAMERA_YUV_420_NV12:
+    case CAMERA_YUV_420_NV21:
+        *num_planes = 2;
+        if(CAMERA_MODE_3D == mode) {
+            size = (uint32_t)(PAD_TO_2K(width*height)*3/2);
+            plane[0] = PAD_TO_WORD(width*height);
+        } else {
+            if (image_type == OUTPUT_TYPE_V) {
+                plane[0] = PAD_TO_2K(width * height);
+                plane[1] = PAD_TO_2K(width * height/2);
+            } else if (image_type == OUTPUT_TYPE_P) {
+                plane[0] = PAD_TO_WORD(width * height);
+                plane[1] = PAD_TO_WORD(width * height/2);
+            } else {
+                plane[0] = PAD_TO_WORD(width * CEILING16(height));
+                plane[1] = PAD_TO_WORD(width * CEILING16(height)/2);
+            }
+            size = plane[0] + plane[1];
+        }
+        break;
+    case CAMERA_BAYER_SBGGR10:
+        *num_planes = 1;
+        plane[0] = PAD_TO_WORD(width * height);
+        size = plane[0];
+        break;
+    case CAMERA_YUV_422_NV16:
+    case CAMERA_YUV_422_NV61:
+      if( image_type == OUTPUT_TYPE_S || image_type == OUTPUT_TYPE_V) {
+        local_height = CEILING16(height);
+      } else {
+        local_height = height;
+      }
+        *num_planes = 2;
+        plane[0] = PAD_TO_WORD(width * height);
+        plane[1] = PAD_TO_WORD(width * height);
+        size = plane[0] + plane[1];
+        break;
+    default:
+        CDBG("%s: format %d not supported.\n",
+            __func__, fmt_type);
+        size = 0;
+    }
+    CDBG("%s:fmt=%d,image_type=%d,width=%d,height=%d,frame_len=%d\n",
+        __func__, fmt_type, image_type, width, height, size);
+    return size;
+}
+
+void mm_camera_util_profile(const char *str)
+{
+#if (MM_CAMERA_PROFILE)
+    struct timespec cur_time;
+
+    clock_gettime(CLOCK_REALTIME, &cur_time);
+    CDBG_HIGH("PROFILE %s: %ld.%09ld\n", str,
+    cur_time.tv_sec, cur_time.tv_nsec);
+#endif
+}
+
+/*===========================================================================
+ * FUNCTION    - mm_camera_do_mmap_ion -
+ *
+ * DESCRIPTION:
+ *==========================================================================*/
+uint8_t *mm_camera_do_mmap_ion(int ion_fd, struct ion_allocation_data *alloc,
+  struct ion_fd_data *ion_info_fd, int *mapFd)
+{
+  void *ret; /* returned virtual address */
+  int rc = 0;
+  struct ion_handle_data handle_data;
+
+  /* to make it page size aligned */
+  alloc->len = (alloc->len + 4095) & (~4095);
+  alloc->align = 4096;
+
+  rc = ioctl(ion_fd, ION_IOC_ALLOC, alloc);
+  if (rc < 0) {
+    CDBG_ERROR("ION allocation failed %s\n", strerror(errno));
+    goto ION_ALLOC_FAILED;
+  }
+
+  ion_info_fd->handle = alloc->handle;
+  rc = ioctl(ion_fd, ION_IOC_SHARE, ion_info_fd);
+  if (rc < 0) {
+    CDBG_ERROR("ION map failed %s\n", strerror(errno));
+    goto ION_MAP_FAILED;
+  }
+  *mapFd = ion_info_fd->fd;
+  ret = mmap(NULL,
+    alloc->len,
+    PROT_READ  | PROT_WRITE,
+    MAP_SHARED,
+    *mapFd,
+    0);
+
+  if (ret == MAP_FAILED) {
+    CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno);
+    goto ION_MAP_FAILED;
+  }
+
+  return ret;
+
+ION_MAP_FAILED:
+  handle_data.handle = ion_info_fd->handle;
+  ioctl(ion_fd, ION_IOC_FREE, &handle_data);
+ION_ALLOC_FAILED:
+  return NULL;
+}
+
+/*===========================================================================
+ * FUNCTION    - mm_camera_do_munmap_ion -
+ *
+ * DESCRIPTION:
+ *==========================================================================*/
+int mm_camera_do_munmap_ion (int ion_fd, struct ion_fd_data *ion_info_fd,
+                   void *addr, size_t size)
+{
+  int rc = 0;
+  rc = munmap(addr, size);
+  close(ion_info_fd->fd);
+
+  struct ion_handle_data handle_data;
+  handle_data.handle = ion_info_fd->handle;
+  ioctl(ion_fd, ION_IOC_FREE, &handle_data);
+  return rc;
+}
diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera_interface.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_interface.c
new file mode 100755
index 0000000..54cf3ac
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_interface.c
@@ -0,0 +1,951 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <linux/media.h>
+#include <semaphore.h>
+
+#include "mm_camera_dbg.h"
+#include "mm_camera_interface.h"
+#include "mm_camera.h"
+
+static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static mm_camera_ctrl_t g_cam_ctrl = {{{0, {0, 0, 0, 0}, 0, 0}}, 0, {{0}}, {0}};
+
+static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
+static uint16_t g_handler_history_count = 0; /* history count for handler */
+
+/* utility function to generate handler */
+uint32_t mm_camera_util_generate_handler(uint8_t index)
+{
+    uint32_t handler = 0;
+    pthread_mutex_lock(&g_handler_lock);
+    g_handler_history_count++;
+    if (0 == g_handler_history_count) {
+        g_handler_history_count++;
+    }
+    handler = g_handler_history_count;
+    handler = (handler<<8) | index;
+    pthread_mutex_unlock(&g_handler_lock);
+    return handler;
+}
+
+uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
+{
+    return (handler&0x000000ff);
+}
+
+const char *mm_camera_util_get_dev_name(uint32_t cam_handler)
+{
+    char *dev_name = NULL;
+    uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler);
+    dev_name = g_cam_ctrl.camera[cam_idx].video_dev_name;
+    return dev_name;
+}
+
+mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler)
+{
+    mm_camera_obj_t *cam_obj = NULL;
+    uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler);
+
+    if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
+        (cam_handler == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
+        cam_obj = g_cam_ctrl.cam_obj[cam_idx];
+    }
+    return cam_obj;
+}
+
+static int32_t mm_camera_intf_sync(uint32_t camera_handler)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s E: camera_handler = %d ",__func__,camera_handler);
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_sync(my_obj);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+/* check if the parm is supported */
+static int32_t mm_camera_intf_is_parm_supported(uint32_t camera_handler,
+                                   mm_camera_parm_type_t parm_type,
+                                   uint8_t *support_set_parm,
+                                   uint8_t *support_get_parm)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+    *support_set_parm = 0;
+    *support_get_parm = 0;
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_is_parm_supported(my_obj, parm_type, support_set_parm, support_get_parm);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    return rc;
+}
+
+/* set a parmÂ’s current value */
+static int32_t mm_camera_intf_set_parm(uint32_t camera_handler,
+                                   mm_camera_parm_type_t parm_type,
+                                   void* p_value)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_set_parm(my_obj, parm_type, p_value);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    return rc;
+}
+
+/* get a parmÂ’s current value */
+static int32_t mm_camera_intf_get_parm(uint32_t camera_handler,
+                                mm_camera_parm_type_t parm_type,
+                                void* p_value)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_get_parm(my_obj, parm_type, p_value);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    return rc;
+}
+
+static void mm_camera_intf_close(uint32_t camera_handler)
+{
+    int32_t rc = -1;
+    uint8_t cam_idx = camera_handler & 0x00ff;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s E: camera_handler = %d ",__func__,camera_handler);
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if (my_obj){
+        my_obj->ref_count--;
+
+        if(my_obj->ref_count > 0) {
+            /* still have reference to obj, return here */
+            CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
+            pthread_mutex_unlock(&g_intf_lock);
+            return;
+        }
+
+        /* need close camera here as no other reference
+         * first empty g_cam_ctrl's referent to cam_obj */
+        g_cam_ctrl.cam_obj[cam_idx] = NULL;
+
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+
+        mm_camera_close(my_obj);
+
+        pthread_mutex_destroy(&my_obj->cam_lock);
+        free(my_obj);
+
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+}
+
+static uint32_t mm_camera_intf_add_channel(uint32_t camera_handler)
+{
+    uint32_t ch_id = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E camera_handler = %d",__func__,camera_handler);
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        ch_id = mm_camera_add_channel(my_obj);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X ch_id = %d",__func__,ch_id);
+    return ch_id;
+}
+
+static void mm_camera_intf_del_channel(uint32_t camera_handler, uint32_t ch_id)
+{
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E ch_id = %d",__func__,ch_id);
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        mm_camera_del_channel(my_obj, ch_id);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X",__func__);
+}
+
+static uint8_t mm_camera_intf_is_event_supported(uint32_t camera_handler,
+                                    mm_camera_event_type_t evt_type)
+{
+    switch(evt_type) {
+    case MM_CAMERA_EVT_TYPE_CH:
+    case MM_CAMERA_EVT_TYPE_CTRL:
+    case MM_CAMERA_EVT_TYPE_STATS:
+    case MM_CAMERA_EVT_TYPE_INFO:
+        return 1;
+    default:
+        return 0;
+    }
+    return 0;
+}
+
+static int32_t mm_camera_intf_register_event_notify(
+                                    uint32_t camera_handler,
+                                    mm_camera_event_notify_t evt_cb,
+                                    void * user_data,
+                                    mm_camera_event_type_t evt_type)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E evt_type = %d",__func__,evt_type);
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data, evt_type);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :E rc = %d",__func__,rc);
+    return rc;
+}
+
+static mm_camera_2nd_sensor_t * mm_camera_intf_query_2nd_sensor_info(uint32_t camera_handler)
+{
+    mm_camera_2nd_sensor_t *sensor_info = NULL;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E camera_handler = %d",__func__,camera_handler);
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        sensor_info = mm_camera_query_2nd_sensor_info(my_obj);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X",__func__);
+    return sensor_info;
+}
+
+static int32_t mm_camera_intf_qbuf(uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    mm_camera_buf_def_t *buf)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_qbuf(my_obj, ch_id, buf);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X evt_type = %d",__func__,rc);
+    return rc;
+}
+
+static uint32_t mm_camera_intf_add_stream(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    mm_camera_buf_notify_t buf_cb, void *user_data,
+                                    uint32_t ext_image_mode, uint32_t sensor_idx)
+{
+    uint32_t stream_id = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s : E handle = %d ch_id = %d",__func__,camera_handler,
+         ch_id);
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        stream_id = mm_camera_add_stream(my_obj, ch_id, buf_cb,
+                                  user_data, ext_image_mode, sensor_idx);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X stream_id = %d",__func__,stream_id);
+    return stream_id;
+}
+
+static int32_t mm_camera_intf_del_stream(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    uint32_t stream_id)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s : E handle = %d ch_id = %d stream_id = %d",__func__,camera_handler,
+         ch_id,stream_id);
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_config_stream(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    uint32_t stream_id,
+                                    mm_camera_stream_config_t *config)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",__func__,
+         camera_handler,ch_id,stream_id);
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_bundle_streams(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    mm_camera_buf_notify_t super_frame_notify_cb,
+                                    void *user_data,
+                                    mm_camera_bundle_attr_t *attr,
+                                    uint8_t num_streams,
+                                    uint32_t *stream_ids)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E handle = %d, ch_id = %d",__func__,
+         camera_handler,ch_id);
+
+    if (MM_CAMEAR_MAX_STRAEM_BUNDLE < num_streams) {
+        CDBG_ERROR("%s: number of streams (%d) exceeds max (%d)",
+                   __func__, num_streams, MM_CAMEAR_MAX_STRAEM_BUNDLE);
+        return rc;
+    }
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_bundle_streams(my_obj, ch_id,
+                                      super_frame_notify_cb,
+                                      user_data, attr,
+                                      num_streams, stream_ids);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_destroy_bundle(uint32_t camera_handler,
+                                    uint32_t ch_id)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E handle = %d, ch_id = %d",__func__,
+         camera_handler,ch_id);
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_destroy_bundle(my_obj, ch_id);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_start_streams(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    uint8_t num_streams,
+                                    uint32_t *stream_ids)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
+         __func__,camera_handler,ch_id,num_streams);
+    if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
+        CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
+                   __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
+        return rc;
+    }
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_start_streams(my_obj, ch_id, num_streams, stream_ids);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_stop_streams(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    uint8_t num_streams,
+                                    uint32_t *stream_ids)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
+         __func__,camera_handler,ch_id,num_streams);
+
+    if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
+        CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
+                   __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
+        return rc;
+    }
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_stop_streams(my_obj, ch_id,
+                                    num_streams, stream_ids);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_async_teardown_streams(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    uint8_t num_streams,
+                                    uint32_t *stream_ids)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
+         __func__,camera_handler,ch_id,num_streams);
+
+    if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
+        CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
+                   __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
+        return rc;
+    }
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_async_teardown_streams(my_obj, ch_id,
+                                              num_streams, stream_ids);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_request_super_buf(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id)
+{
+    int32_t rc = -1;
+    CDBG("%s :E camera_handler = %d,ch_id = %d",
+         __func__,camera_handler,ch_id);
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_request_super_buf(my_obj, ch_id);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_cancel_super_buf_request(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E camera_handler = %d,ch_id = %d",
+         __func__,camera_handler,ch_id);
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_start_focus(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    uint32_t sensor_idx,
+                                    uint32_t focus_mode)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    CDBG("%s :E camera_handler = %d,ch_id = %d, focus_mode = %d",
+         __func__,camera_handler,ch_id,focus_mode);
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_start_focus(my_obj, ch_id, sensor_idx, focus_mode);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_abort_focus(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    uint32_t sensor_idx)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_abort_focus(my_obj, ch_id, sensor_idx);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_prepare_snapshot(
+                                    uint32_t camera_handler,
+                                    uint32_t ch_id,
+                                    uint32_t sensor_idx)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_prepare_snapshot(my_obj, ch_id, sensor_idx);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_set_stream_parm(
+                                     uint32_t camera_handle,
+                                     uint32_t ch_id,
+                                     uint32_t s_id,
+                                     mm_camera_stream_parm_t parm_type,
+                                     void* p_value)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+
+    CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__,
+            camera_handle,ch_id,s_id,parm_type);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_set_stream_parm(my_obj,ch_id,s_id,
+                                       parm_type,
+                                       p_value);
+    }else{
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static int32_t mm_camera_intf_get_stream_parm(
+                                     uint32_t camera_handle,
+                                     uint32_t ch_id,
+                                     uint32_t s_id,
+                                     mm_camera_stream_parm_t parm_type,
+                                     void* p_value)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+
+    CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__,
+            camera_handle,ch_id,s_id,parm_type);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_get_stream_parm(my_obj,ch_id,s_id,
+                                       parm_type,
+                                       p_value);
+    }else{
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+mm_camera_info_t * camera_query(uint8_t *num_cameras)
+{
+    int i = 0, rc = 0;
+    int dev_fd = 0;
+    struct media_device_info mdev_info;
+    int num_media_devices = 0;
+    if (!num_cameras) {
+        CDBG_ERROR("%s: num_cameras is NULL\n", __func__);
+        return NULL;
+    }
+
+    CDBG("%s : E",__func__);
+    /* lock the mutex */
+    pthread_mutex_lock(&g_intf_lock);
+    *num_cameras = 0;
+    while (1) {
+        char dev_name[32];
+        snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
+        dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
+        if (dev_fd < 0) {
+            CDBG("Done discovering media devices\n");
+            break;
+        }
+        num_media_devices++;
+        rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
+        if (rc < 0) {
+            CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
+            close(dev_fd);
+            break;
+        }
+
+        if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) {
+            close(dev_fd);
+            continue;
+        }
+
+        char * mdev_cfg;
+        int cam_type = 0, mount_angle = 0, info_index = 0;
+        mdev_cfg = strtok(mdev_info.serial, "-");
+        while(mdev_cfg != NULL) {
+            if(info_index == 0) {
+                if(strcmp(mdev_cfg, QCAMERA_NAME))
+                  break;
+            } else if(info_index == 1) {
+                mount_angle = atoi(mdev_cfg);
+            } else if(info_index == 2) {
+                cam_type = atoi(mdev_cfg);
+            }
+            mdev_cfg = strtok(NULL, "-");
+            info_index++;
+        }
+
+        if(info_index == 0) {
+            close(dev_fd);
+            continue;
+        }
+
+        int num_entities = 1;
+        while (1) {
+            struct media_entity_desc entity;
+            memset(&entity, 0, sizeof(entity));
+            entity.id = num_entities++;
+            rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
+            if (rc < 0) {
+                CDBG("Done enumerating media entities\n");
+                rc = 0;
+                break;
+            }
+            if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
+                strncpy(g_cam_ctrl.video_dev_name[*num_cameras],
+                     entity.name, sizeof(entity.name));
+                g_cam_ctrl.camera[*num_cameras].video_dev_name =
+                    &g_cam_ctrl.video_dev_name[*num_cameras][0];
+                break;
+            }
+        }
+
+        //g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras;
+        g_cam_ctrl.camera[*num_cameras].camera_id = *num_cameras;
+
+        g_cam_ctrl.camera[*num_cameras].
+            camera_info.modes_supported = CAMERA_MODE_2D;
+
+        if(cam_type > 1) {
+            g_cam_ctrl.camera[*num_cameras].
+                camera_info.modes_supported |= CAMERA_MODE_3D;
+        }
+
+        g_cam_ctrl.camera[*num_cameras].camera_info.position =
+            (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA;
+
+        g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle =
+            mount_angle;
+
+        g_cam_ctrl.camera[*num_cameras].main_sensor_type = 0;
+
+        CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d mount_angle = %d]\n",
+            __func__, *num_cameras,
+            g_cam_ctrl.camera[*num_cameras].video_dev_name,
+            g_cam_ctrl.camera[*num_cameras].camera_info.position,
+            g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported,
+            g_cam_ctrl.camera[*num_cameras].main_sensor_type,
+            g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle);
+
+        *num_cameras += 1;
+        if (dev_fd > 0) {
+            close(dev_fd);
+        }
+    }
+    *num_cameras = *num_cameras;
+    g_cam_ctrl.num_cam = *num_cameras;
+
+    /* unlock the mutex */
+    pthread_mutex_unlock(&g_intf_lock);
+    CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
+    if(rc == 0)
+        return &g_cam_ctrl.camera[0];
+    else
+        return NULL;
+}
+
+/* camera ops v-table */
+static mm_camera_ops_t mm_camera_ops = {
+    .sync = mm_camera_intf_sync,
+    .is_event_supported = mm_camera_intf_is_event_supported,
+    .register_event_notify = mm_camera_intf_register_event_notify,
+    .qbuf = mm_camera_intf_qbuf,
+    .camera_close = mm_camera_intf_close,
+    .query_2nd_sensor_info = mm_camera_intf_query_2nd_sensor_info,
+    .is_parm_supported = mm_camera_intf_is_parm_supported,
+    .set_parm = mm_camera_intf_set_parm,
+    .get_parm = mm_camera_intf_get_parm,
+    .ch_acquire = mm_camera_intf_add_channel,
+    .ch_release = mm_camera_intf_del_channel,
+    .add_stream = mm_camera_intf_add_stream,
+    .del_stream = mm_camera_intf_del_stream,
+    .config_stream = mm_camera_intf_config_stream,
+    .init_stream_bundle = mm_camera_intf_bundle_streams,
+    .destroy_stream_bundle = mm_camera_intf_destroy_bundle,
+    .start_streams = mm_camera_intf_start_streams,
+    .stop_streams = mm_camera_intf_stop_streams,
+    .async_teardown_streams = mm_camera_intf_async_teardown_streams,
+    .request_super_buf = mm_camera_intf_request_super_buf,
+    .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
+    .start_focus = mm_camera_intf_start_focus,
+    .abort_focus = mm_camera_intf_abort_focus,
+    .prepare_snapshot = mm_camera_intf_prepare_snapshot,
+    .set_stream_parm = mm_camera_intf_set_stream_parm,
+    .get_stream_parm = mm_camera_intf_get_stream_parm
+};
+
+/* open camera. */
+mm_camera_vtbl_t * camera_open(uint8_t camera_idx,
+                               mm_camear_mem_vtbl_t *mem_vtbl)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t* cam_obj = NULL;
+
+    CDBG("%s: E camera_idx = %d\n", __func__,camera_idx);
+    if (MSM_MAX_CAMERA_SENSORS <= camera_idx) {
+        CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
+        return NULL;
+    }
+
+    pthread_mutex_lock(&g_intf_lock);
+    /* opened already */
+    if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
+        /* Add reference */
+        g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
+        pthread_mutex_unlock(&g_intf_lock);
+        CDBG("%s:  opened alreadyn", __func__);
+        return &cam_obj->vtbl;
+    }
+
+    cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
+    if(NULL == cam_obj) {
+        pthread_mutex_unlock(&g_intf_lock);
+        CDBG("%s:  no mem", __func__);
+        return NULL;
+    }
+
+    /* initialize camera obj */
+    memset(cam_obj, 0, sizeof(mm_camera_obj_t));
+    cam_obj->ctrl_fd = -1;
+    cam_obj->ds_fd = -1;
+    cam_obj->ref_count++;
+    cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
+    cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
+    cam_obj->vtbl.camera_info = &g_cam_ctrl.camera[camera_idx];
+    cam_obj->vtbl.ops = &mm_camera_ops;
+    cam_obj->mem_vtbl = mem_vtbl; /* save mem_vtbl */
+    pthread_mutex_init(&cam_obj->cam_lock, NULL);
+
+    rc = mm_camera_open(cam_obj);
+    if(rc != 0) {
+        CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
+        pthread_mutex_destroy(&cam_obj->cam_lock);
+        g_cam_ctrl.cam_obj[camera_idx] = NULL;
+        free(cam_obj);
+        cam_obj = NULL;
+        pthread_mutex_unlock(&g_intf_lock);
+        return NULL;
+    }else{
+        CDBG("%s: Open succeded\n", __func__);
+        g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
+        pthread_mutex_unlock(&g_intf_lock);
+        return &cam_obj->vtbl;
+    }
+}
diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera_sock.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_sock.c
new file mode 100755
index 0000000..2f68d1d
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_sock.c
@@ -0,0 +1,224 @@
+/*

+Copyright (c) 2012, Code Aurora Forum. All rights reserved.

+

+Redistribution and use in source and binary forms, with or without

+modification, are permitted provided that the following conditions are

+met:

+    * Redistributions of source code must retain the above copyright

+      notice, this list of conditions and the following disclaimer.

+    * Redistributions in binary form must reproduce the above

+      copyright notice, this list of conditions and the following

+      disclaimer in the documentation and/or other materials provided

+      with the distribution.

+    * Neither the name of Code Aurora Forum, Inc. nor the names of its

+      contributors may be used to endorse or promote products derived

+      from this software without specific prior written permission.

+

+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED

+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT

+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS

+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR

+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE

+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN

+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+*/

+

+#include <stdio.h>

+#include <unistd.h>

+#include <stdlib.h>

+#include <errno.h>

+#include <string.h>

+#include <sys/socket.h>

+#include <sys/uio.h>

+#include <linux/un.h>

+

+#include "mm_camera_dbg.h"

+#include "mm_camera_sock.h"

+

+/*===========================================================================

+ * FUNCTION    - mm_camera_socket_create -

+ *

+ * DESCRIPTION: opens a domain socket tied to camera ID and socket type

+ *                        int cam_id: camera ID

+  *                       mm_camera_sock_type_t sock_type: socket type, TCP/UDP

+ * retured fd related to the domain socket

+ *==========================================================================*/

+int mm_camera_socket_create(int cam_id, mm_camera_sock_type_t sock_type)

+{

+    int socket_fd;

+    struct sockaddr_un sock_addr;

+    int sktype;

+    int rc;

+

+    switch (sock_type)

+    {

+      case MM_CAMERA_SOCK_TYPE_UDP:

+        sktype = SOCK_DGRAM;

+        break;

+      case MM_CAMERA_SOCK_TYPE_TCP:

+        sktype = SOCK_STREAM;

+        break;

+      default:

+        CDBG_ERROR("%s: unknown socket type =%d", __func__, sock_type);

+        return -1;

+    }

+    socket_fd = socket(AF_UNIX, sktype, 0);

+    if (socket_fd < 0) {

+        CDBG_ERROR("%s: error create socket fd =%d", __func__, socket_fd);

+        return socket_fd;

+    }

+

+    memset(&sock_addr, 0, sizeof(sock_addr));

+    sock_addr.sun_family = AF_UNIX;

+    snprintf(sock_addr.sun_path, UNIX_PATH_MAX, "/data/cam_socket%d", cam_id);

+    if((rc = connect(socket_fd, (struct sockaddr *) &sock_addr,

+      sizeof(sock_addr))) != 0) {

+      close(socket_fd);

+      socket_fd = -1;

+      CDBG_ERROR("%s: socket_fd=%d %s ", __func__, socket_fd, strerror(errno));

+    }

+

+    CDBG("%s: socket_fd=%d %s", __func__, socket_fd, sock_addr.sun_path);

+    return socket_fd;

+}

+

+/*===========================================================================

+ * FUNCTION    - mm_camera_socket_close -

+ *

+ * DESCRIPTION:  close domain socket by its fd

+ *==========================================================================*/

+void mm_camera_socket_close(int fd)

+{

+    if (fd > 0) {

+      close(fd);

+    }

+}

+

+/*===========================================================================

+ * FUNCTION    - mm_camera_socket_sendmsg -

+ *

+ * DESCRIPTION:  send msg through domain socket

+ *                         int fd: socket fd

+ *                         mm_camera_sock_msg_packet_t *msg: pointer to msg to be sent over domain socket

+ *                         int sendfd: file descriptors to be sent

+ * return the total bytes of sent msg

+ *==========================================================================*/

+int mm_camera_socket_sendmsg(

+  int fd,

+  void *msg,

+  uint32_t buf_size,

+  int sendfd)

+{

+    struct msghdr msgh;

+    struct iovec iov[1];

+    struct cmsghdr * cmsghp = NULL;

+    char control[CMSG_SPACE(sizeof(int))];

+

+    if (msg == NULL) {

+      CDBG("%s: msg is NULL", __func__);

+      return -1;

+    }

+    memset(&msgh, 0, sizeof(msgh));

+    msgh.msg_name = NULL;

+    msgh.msg_namelen = 0;

+

+    iov[0].iov_base = msg;

+    iov[0].iov_len = buf_size;

+    msgh.msg_iov = iov;

+    msgh.msg_iovlen = 1;

+    CDBG("%s: iov_len=%d", __func__, iov[0].iov_len);

+

+    msgh.msg_control = NULL;

+    msgh.msg_controllen = 0;

+

+    /* if sendfd is vlaid, we need to pass it through control msg */

+    if( sendfd > 0) {

+      msgh.msg_control = control;

+      msgh.msg_controllen = sizeof(control);

+      cmsghp = CMSG_FIRSTHDR(&msgh);

+      if (cmsghp != NULL) {

+        CDBG("%s: Got ctrl msg pointer", __func__);

+        cmsghp->cmsg_level = SOL_SOCKET;

+        cmsghp->cmsg_type = SCM_RIGHTS;

+        cmsghp->cmsg_len = CMSG_LEN(sizeof(int));

+        *((int *)CMSG_DATA(cmsghp)) = sendfd;

+        CDBG("%s: cmsg data=%d", __func__, *((int *) CMSG_DATA(cmsghp)));

+      } else {

+        CDBG("%s: ctrl msg NULL", __func__);

+        return -1;

+      }

+    }

+

+    return sendmsg(fd, &(msgh), 0);

+}

+

+/*===========================================================================

+ * FUNCTION    - mm_camera_socket_recvmsg -

+ *

+ * DESCRIPTION:  receive msg from domain socket.

+ *                         int fd: socket fd

+ *                         void *msg: pointer to mm_camera_sock_msg_packet_t to hold incoming msg,

+ *                                    need be allocated by the caller

+ *                         uint32_t buf_size: the size of the buf that holds incoming msg

+ *                         int *rcvdfd: pointer to hold recvd file descriptor if not NULL.

+ * return the total bytes of received msg

+ *==========================================================================*/

+int mm_camera_socket_recvmsg(

+  int fd,

+  void *msg,

+  uint32_t buf_size,

+  int *rcvdfd)

+{

+    struct msghdr msgh;

+    struct iovec iov[1];

+    struct cmsghdr *cmsghp = NULL;

+    char control[CMSG_SPACE(sizeof(int))];

+    int rcvd_fd = -1;

+    int rcvd_len = 0;

+

+    if ( (msg == NULL) || (buf_size <= 0) ) {

+      CDBG_ERROR(" %s: msg buf is NULL", __func__);

+      return -1;

+    }

+

+    memset(&msgh, 0, sizeof(msgh));

+    msgh.msg_name = NULL;

+    msgh.msg_namelen = 0;

+    msgh.msg_control = control;

+    msgh.msg_controllen = sizeof(control);

+

+    iov[0].iov_base = msg;

+    iov[0].iov_len = buf_size;

+    msgh.msg_iov = iov;

+    msgh.msg_iovlen = 1;

+

+    if ( (rcvd_len = recvmsg(fd, &(msgh), 0)) <= 0) {

+      CDBG_ERROR(" %s: recvmsg failed", __func__);

+      return rcvd_len;

+    }

+

+    CDBG("%s:  msg_ctrl %p len %d", __func__, msgh.msg_control, msgh.msg_controllen);

+

+    if( ((cmsghp = CMSG_FIRSTHDR(&msgh)) != NULL) &&

+        (cmsghp->cmsg_len == CMSG_LEN(sizeof(int))) ) {

+      if (cmsghp->cmsg_level == SOL_SOCKET &&

+        cmsghp->cmsg_type == SCM_RIGHTS) {

+        CDBG("%s:  CtrlMsg is valid", __func__);

+        rcvd_fd = *((int *) CMSG_DATA(cmsghp));

+        CDBG("%s:  Receieved fd=%d", __func__, rcvd_fd);

+      } else {

+        CDBG_ERROR("%s:  Unexpected Control Msg. Line=%d", __func__, __LINE__);

+      }

+    }

+

+    if (rcvdfd) {

+      *rcvdfd = rcvd_fd;

+    }

+

+    return rcvd_len;

+}

+

diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera_stream.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_stream.c
new file mode 100755
index 0000000..88dc9c1
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_stream.c
@@ -0,0 +1,1563 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <time.h>
+#include <semaphore.h>
+
+#include "mm_camera_dbg.h"
+#include "mm_camera_interface.h"
+#include "mm_camera.h"
+
+#define MM_CAMERA_MAX_NUM_FRAMES     16
+
+/* internal function decalre */
+int32_t mm_stream_qbuf(mm_stream_t *my_obj,
+                       mm_camera_buf_def_t *buf);
+int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj);
+int32_t mm_stream_set_fmt(mm_stream_t * my_obj);
+int32_t mm_stream_get_offset(mm_stream_t *my_obj);
+int32_t mm_stream_set_cid(mm_stream_t *my_obj,stream_cid_t *in_value);
+int32_t mm_stream_init_bufs(mm_stream_t * my_obj);
+int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj);
+int32_t mm_stream_request_buf(mm_stream_t * my_obj);
+int32_t mm_stream_unreg_buf(mm_stream_t * my_obj);
+int32_t mm_stream_release(mm_stream_t *my_obj);
+int32_t mm_stream_get_crop(mm_stream_t *my_obj,
+                         mm_camera_rect_t *crop);
+int32_t mm_stream_get_cid(mm_stream_t *my_obj,
+                          stream_cid_t *out_value);
+int32_t mm_stream_set_parm_acquire(mm_stream_t *my_obj,
+                         void *value);
+int32_t mm_stream_get_parm_acquire(mm_stream_t *my_obj,
+                         void *value);
+int32_t mm_stream_set_parm_config(mm_stream_t *my_obj,
+                         void *value);
+int32_t mm_stream_get_parm_config(mm_stream_t *my_obj,
+                         void *value);
+int32_t mm_stream_set_parm_start(mm_stream_t *my_obj,
+                         void *value);
+int32_t mm_stream_get_parm_start(mm_stream_t *my_obj,
+                         void *value);
+int32_t mm_stream_streamon(mm_stream_t *my_obj);
+int32_t mm_stream_streamoff(mm_stream_t *my_obj);
+int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
+                                 mm_camera_buf_info_t* buf_info);
+int32_t mm_stream_config(mm_stream_t *my_obj,
+                         mm_camera_stream_config_t *config);
+uint8_t mm_stream_need_stream_on(mm_stream_t *my_obj);
+int32_t mm_stream_reg_buf(mm_stream_t * my_obj);
+int32_t mm_stream_buf_done(mm_stream_t * my_obj,
+                           mm_camera_buf_def_t *frame);
+
+
+/* state machine function declare */
+int32_t mm_stream_fsm_inited(mm_stream_t * my_obj,

+                             mm_stream_evt_type_t evt,
+                             void * in_val,
+                             void * out_val);
+int32_t mm_stream_fsm_acquired(mm_stream_t * my_obj,

+                               mm_stream_evt_type_t evt,
+                               void * in_val,
+                               void * out_val);
+int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,

+                          mm_stream_evt_type_t evt,
+                          void * in_val,
+                          void * out_val);
+int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
+                             mm_stream_evt_type_t evt,
+                             void * in_val,
+                             void * out_val);
+int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,

+                          mm_stream_evt_type_t evt,
+                          void * in_val,
+                          void * out_val);
+int32_t mm_stream_fsm_active_stream_on(mm_stream_t * my_obj,

+                                       mm_stream_evt_type_t evt,
+                                       void * in_val,
+                                       void * out_val);
+int32_t mm_stream_fsm_active_stream_off(mm_stream_t * my_obj,

+                                        mm_stream_evt_type_t evt,
+                                        void * in_val,
+                                        void * out_val);
+
+extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
+                                       cam_ctrl_type type,
+                                       uint32_t length,
+                                       void *value);
+
+static int get_stream_inst_handle(mm_stream_t *my_obj)
+{
+  int rc = 0;
+  uint32_t inst_handle;
+  struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
+
+  v4l2_ioctl.id = MSM_V4L2_PID_INST_HANDLE;
+  v4l2_ioctl.ioctl_ptr = &inst_handle;
+  v4l2_ioctl.len = sizeof(inst_handle);
+  rc = ioctl(my_obj->fd, MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL, &v4l2_ioctl);
+  if (rc) {
+    CDBG_ERROR("%s Error getting mctl pp inst handle", __func__);
+    return rc;
+  }
+
+  my_obj->inst_hdl = inst_handle;
+  CDBG("%s: inst handle = %x rc = %d\n", __func__,
+    my_obj->inst_hdl, rc);
+  return rc;
+}
+
+void mm_stream_handle_rcvd_buf(mm_stream_t *my_obj,
+                                  mm_camera_buf_info_t *buf_info)
+{
+    int32_t i;
+    uint8_t has_cb = 0;
+
+    /* enqueue to super buf thread */
+    if (my_obj->is_bundled) {
+        mm_camera_cmdcb_t* node = NULL;
+
+        /* send sem_post to wake up channel cmd thread to enqueue to super buffer */
+        node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
+        if (NULL != node) {
+            memset(node, 0, sizeof(mm_camera_cmdcb_t));
+            node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
+            memcpy(&node->u.buf, buf_info, sizeof(mm_camera_buf_info_t));
+
+            /* enqueue to cmd thread */
+            mm_camera_queue_enq(&(my_obj->ch_obj->cmd_thread.cmd_queue), node);
+
+            /* wake up cmd thread */
+            sem_post(&(my_obj->ch_obj->cmd_thread.cmd_sem));
+        } else {
+            CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
+        }
+    }
+
+    /* check if has CB */
+    for (i=0 ; i< MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
+        if(NULL != my_obj->buf_cb[i].cb) {
+            has_cb = 1;
+        }
+    }
+    if(has_cb) {
+        mm_camera_cmdcb_t* node = NULL;
+
+        /* send sem_post to wake up cmd thread to dispatch dataCB */
+        node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
+        if (NULL != node) {
+            memset(node, 0, sizeof(mm_camera_cmdcb_t));
+            node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
+            memcpy(&node->u.buf, buf_info, sizeof(mm_camera_buf_info_t));
+
+            /* enqueue to cmd thread */
+            mm_camera_queue_enq(&(my_obj->cmd_thread.cmd_queue), node);
+
+            /* wake up cmd thread */
+            sem_post(&(my_obj->cmd_thread.cmd_sem));
+        } else {
+            CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
+        }
+    }
+}
+
+static void mm_stream_data_notify(void* user_data)
+{
+    mm_stream_t *my_obj = (mm_stream_t*)user_data;
+    int32_t idx = -1, i, rc;
+    uint8_t has_cb = 0;
+    mm_camera_buf_info_t buf_info;
+
+    if (NULL == my_obj) {
+        return;
+    }
+
+    if (MM_STREAM_STATE_ACTIVE_STREAM_ON != my_obj->state) {
+        /* this Cb will only received in active_stream_on state
+         * if not so, return here */
+        CDBG_ERROR("%s: ERROR!! Wrong state (%d) to receive data notify!",
+                   __func__, my_obj->state);
+        return;
+    }
+
+    memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
+
+    pthread_mutex_lock(&my_obj->buf_lock);
+    rc = mm_stream_read_msm_frame(my_obj, &buf_info);
+    if (rc != 0) {
+        pthread_mutex_unlock(&my_obj->buf_lock);
+        return;
+    }
+    idx = buf_info.buf->buf_idx;
+
+    /* update buffer location */
+    my_obj->buf_status[idx].in_kernel = 0;
+
+    /* update buf ref count */
+    if (my_obj->is_bundled) {
+        /* need to add into super buf since bundled, add ref count */
+        my_obj->buf_status[idx].buf_refcnt++;
+    }
+
+    for (i=0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
+        if(NULL != my_obj->buf_cb[i].cb) {
+            /* for every CB, add ref count */
+            my_obj->buf_status[idx].buf_refcnt++;
+            has_cb = 1;
+        }
+    }
+    pthread_mutex_unlock(&my_obj->buf_lock);
+
+    mm_stream_handle_rcvd_buf(my_obj, &buf_info);
+}
+
+/* special function for dataCB registered at other stream */
+static void mm_stream_buf_notify(mm_camera_super_buf_t *super_buf,
+                                 void *user_data)
+{
+    mm_stream_t * my_obj = (mm_stream_t*)user_data;
+    mm_camera_buf_info_t buf_info;
+    int8_t i;
+    mm_camera_buf_def_t *buf = super_buf->bufs[0];
+
+    CDBG("%s : E",__func__);
+    if (my_obj == NULL) {
+        return;
+    }
+
+    if (MM_STREAM_STATE_ACTIVE_STREAM_OFF != my_obj->state) {
+        /* this CB will only received in active_stream_off state
+         * if not so, return here */
+        return;
+    }
+
+    /* 1) copy buf into local buf */
+    if (my_obj->buf_num <= 0) {
+        CDBG_ERROR("%s: Local buf is not allocated yet", __func__);
+        return;
+    }
+
+    my_obj->buf[0].buf_idx = 0;
+    my_obj->buf[0].stream_id = my_obj->my_hdl;
+    my_obj->buf[0].frame_idx = buf->frame_idx;
+
+    memcpy(&my_obj->buf[0].ts, &buf->ts, sizeof(buf->ts));
+
+    memcpy(&my_obj->buf[0].planes,&buf->planes,buf->num_planes * sizeof(struct v4l2_plane));
+
+    /* set flag to indicate buf be to sent out is from local */
+    my_obj->is_local_buf = 1;
+
+    /* 2) buf_done the buf from other stream */
+    mm_channel_qbuf(my_obj->ch_obj, buf);
+
+    /* 3) handle received buf */
+    memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
+    buf_info.frame_idx =my_obj->buf[0].frame_idx;
+    buf_info.buf = &my_obj->buf[0];
+    buf_info.stream_id = my_obj->my_hdl;
+    mm_stream_handle_rcvd_buf(my_obj, &buf_info);
+}
+
+static void mm_stream_dispatch_app_data(mm_camera_cmdcb_t *cmd_cb,
+                                        void* user_data)
+{
+    int i;
+    mm_stream_t * my_obj = (mm_stream_t *)user_data;
+    mm_camera_buf_info_t* buf_info = NULL;
+    mm_camera_super_buf_t super_buf;
+
+    if (NULL == my_obj) {
+        return;
+    }
+
+    if (MM_CAMERA_CMD_TYPE_DATA_CB != cmd_cb->cmd_type) {
+        CDBG_ERROR("%s: Wrong cmd_type (%d) for dataCB",
+                   __func__, cmd_cb->cmd_type);
+        return;
+    }
+
+    buf_info = &cmd_cb->u.buf;
+    memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
+    super_buf.num_bufs = 1;
+    super_buf.bufs[0] = buf_info->buf;
+    super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
+    super_buf.ch_id = my_obj->ch_obj->my_hdl;
+
+
+    pthread_mutex_lock(&my_obj->cb_lock);
+    for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
+        if(NULL != my_obj->buf_cb[i].cb) {
+            if (my_obj->buf_cb[i].cb_count != 0) {
+                /* if <0, means infinite CB
+                 * if >0, means CB for certain times
+                 * both case we need to call CB */
+                my_obj->buf_cb[i].cb(&super_buf,
+                                     my_obj->buf_cb[i].user_data);
+            }
+
+            /* if >0, reduce count by 1 every time we called CB until reaches 0
+             * when count reach 0, reset the buf_cb to have no CB */
+            if (my_obj->buf_cb[i].cb_count > 0) {
+                my_obj->buf_cb[i].cb_count--;
+                if (0 == my_obj->buf_cb[i].cb_count) {
+                    my_obj->buf_cb[i].cb = NULL;
+                    my_obj->buf_cb[i].user_data = NULL;
+                }
+            }
+        }
+    }
+    pthread_mutex_unlock(&my_obj->cb_lock);
+}
+
+/* state machine entry */
+int32_t mm_stream_fsm_fn(mm_stream_t *my_obj,
+                         mm_stream_evt_type_t evt,
+                         void * in_val,
+                         void * out_val)
+{
+    int32_t rc = -1;
+
+    CDBG("%s : E - evt = %d, my_obj->state = %d",__func__,evt,my_obj->state);
+    switch (my_obj->state) {
+    case MM_STREAM_STATE_NOTUSED:
+        CDBG("%s: Not handling evt in unused state", __func__);
+        break;
+    case MM_STREAM_STATE_INITED:
+        rc = mm_stream_fsm_inited(my_obj, evt, in_val, out_val);
+        break;
+    case MM_STREAM_STATE_ACQUIRED:
+        rc = mm_stream_fsm_acquired(my_obj, evt, in_val, out_val);
+        break;
+    case MM_STREAM_STATE_CFG:
+        rc = mm_stream_fsm_cfg(my_obj, evt, in_val, out_val);
+        break;
+    case MM_STREAM_STATE_BUFFED:
+        rc = mm_stream_fsm_buffed(my_obj, evt, in_val, out_val);
+        break;
+    case MM_STREAM_STATE_REG:
+        rc = mm_stream_fsm_reg(my_obj, evt, in_val, out_val);
+        break;
+    case MM_STREAM_STATE_ACTIVE_STREAM_ON:
+        rc = mm_stream_fsm_active_stream_on(my_obj, evt, in_val, out_val);
+        break;
+    case MM_STREAM_STATE_ACTIVE_STREAM_OFF:
+        rc = mm_stream_fsm_active_stream_off(my_obj, evt, in_val, out_val);
+        break;
+    default:
+        CDBG("%s: Not a valid state (%d)", __func__, my_obj->state);
+        break;
+    }
+    CDBG("%s : X rc =%d",__func__,rc);
+    return rc;
+}

+
+int32_t mm_stream_fsm_inited(mm_stream_t *my_obj,
+                             mm_stream_evt_type_t evt,
+                             void * in_val,
+                             void * out_val)
+{

+    int32_t rc = 0;
+    char dev_name[MM_CAMERA_DEV_NAME_LEN];
+
+    CDBG("%s :E evt = %d",__func__,evt);
+    switch(evt) {
+    case MM_STREAM_EVT_ACQUIRE:
+        if ((NULL == my_obj->ch_obj) || (NULL == my_obj->ch_obj->cam_obj)) {
+            CDBG_ERROR("%s: NULL channel or camera obj\n", __func__);
+            rc = -1;
+            break;
+        }
+

+        snprintf(dev_name, sizeof(dev_name), "/dev/%s",
+                 mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl));
+
+        my_obj->fd = open(dev_name, O_RDWR | O_NONBLOCK);
+        if (my_obj->fd <= 0) {
+            CDBG_ERROR("%s: open dev returned %d\n", __func__, my_obj->fd);
+            rc = -1;
+            break;
+        }

+        CDBG("%s: open dev fd = %d, ext_image_mode = %d, sensor_idx = %d\n",
+                 __func__, my_obj->fd, my_obj->ext_image_mode, my_obj->sensor_idx);
+        rc = mm_stream_set_ext_mode(my_obj);
+        if (0 == rc) {
+            my_obj->state = MM_STREAM_STATE_ACQUIRED;
+        } else {
+            /* failed setting ext_mode
+             * close fd */
+            if(my_obj->fd > 0) {
+                close(my_obj->fd);
+                my_obj->fd = -1;
+            }
+            break;
+        }
+        rc = get_stream_inst_handle(my_obj);
+        if(rc) {
+            if(my_obj->fd > 0) {
+                close(my_obj->fd);
+                my_obj->fd = -1;
+            }
+        }
+        break;
+    default:

+        CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
+                   __func__,evt,my_obj->state);

+        rc = -1;
+        break;
+    }
+    return rc;
+}
+
+int32_t mm_stream_fsm_acquired(mm_stream_t *my_obj,
+                               mm_stream_evt_type_t evt,
+                               void * in_val,
+                               void * out_val)
+{
+    int32_t rc = 0;
+
+    CDBG("%s :E evt = %d",__func__,evt);
+    switch(evt) {
+    case MM_STREAM_EVT_SET_FMT:
+        {
+            mm_camera_stream_config_t *config =
+                (mm_camera_stream_config_t *)in_val;
+
+            rc = mm_stream_config(my_obj, config);
+
+            /* change state to configed */
+            my_obj->state = MM_STREAM_STATE_CFG;
+
+            break;
+        }
+    case MM_STREAM_EVT_RELEASE:
+        rc = mm_stream_release(my_obj);
+        /* change state to not used */
+         my_obj->state = MM_STREAM_STATE_NOTUSED;
+        break;
+    case MM_STREAM_EVT_SET_PARM:
+        rc = mm_stream_set_parm_acquire(my_obj, in_val);
+        break;
+    case MM_STREAM_EVT_GET_PARM:
+        rc = mm_stream_get_parm_acquire(my_obj,out_val);
+        break;
+    default:
+        CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
+                   __func__, evt, my_obj->state);
+        rc = -1;
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,

+                          mm_stream_evt_type_t evt,
+                          void * in_val,
+                          void * out_val)
+{
+    int32_t rc = 0;
+    CDBG("%s :E evt = %d",__func__,evt);
+    switch(evt) {
+    case MM_STREAM_EVT_SET_FMT:
+        {
+            mm_camera_stream_config_t *config =
+                (mm_camera_stream_config_t *)in_val;
+
+            rc = mm_stream_config(my_obj, config);
+
+            /* change state to configed */
+            my_obj->state = MM_STREAM_STATE_CFG;
+
+            break;
+        }
+    case MM_STREAM_EVT_RELEASE:
+        rc = mm_stream_release(my_obj);
+        my_obj->state = MM_STREAM_STATE_NOTUSED;
+        break;
+    case MM_STREAM_EVT_SET_PARM:
+        rc = mm_stream_set_parm_config(my_obj, in_val);
+        break;
+    case MM_STREAM_EVT_GET_PARM:
+        rc = mm_stream_get_parm_config(my_obj, out_val);
+        break;
+    case MM_STREAM_EVT_GET_BUF:
+        rc = mm_stream_init_bufs(my_obj);
+        /* change state to buff allocated */
+        if(0 == rc) {
+            my_obj->state = MM_STREAM_STATE_BUFFED;
+        }
+        break;
+    default:
+        CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
+                   __func__, evt, my_obj->state);
+        rc = -1;
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
+                             mm_stream_evt_type_t evt,
+                             void * in_val,
+                             void * out_val)
+{
+    int32_t rc = 0;
+    CDBG("%s :E evt = %d",__func__,evt);
+    switch(evt) {
+    case MM_STREAM_EVT_PUT_BUF:
+        rc = mm_stream_deinit_bufs(my_obj);
+        /* change state to configed */
+        if(0 == rc) {
+            my_obj->state = MM_STREAM_STATE_CFG;
+        }
+        break;
+    case MM_STREAM_EVT_REG_BUF:
+        rc = mm_stream_reg_buf(my_obj);
+        /* change state to regged */
+        if(0 == rc) {
+            my_obj->state = MM_STREAM_STATE_REG;
+        }
+        break;
+    case MM_STREAM_EVT_SET_PARM:
+        rc = mm_stream_set_parm_config(my_obj, in_val);
+        break;
+    case MM_STREAM_EVT_GET_PARM:
+        rc = mm_stream_get_parm_config(my_obj, out_val);
+        break;
+    default:
+        CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
+                   __func__, evt, my_obj->state);
+        rc = -1;
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,

+                          mm_stream_evt_type_t evt,
+                          void * in_val,
+                          void * out_val)
+{
+    int32_t rc = 0;
+    CDBG("%s :E evt = %d",__func__,evt);
+
+    switch(evt) {
+    case MM_STREAM_EVT_UNREG_BUF:
+        rc = mm_stream_unreg_buf(my_obj);
+
+        /* change state to buffed */
+        my_obj->state = MM_STREAM_STATE_BUFFED;
+        break;
+    case MM_STREAM_EVT_START:
+        {
+            /* launch cmd thread if CB is not null */
+            if (NULL != my_obj->buf_cb) {
+                mm_camera_cmd_thread_launch(&my_obj->cmd_thread,
+                                mm_stream_dispatch_app_data,
+                                (void *)my_obj);
+
+            }
+
+            if(mm_stream_need_stream_on(my_obj)) {
+                rc = mm_stream_streamon(my_obj);
+                if (0 != rc) {
+                    /* failed stream on, need to release cmd thread if it's launched */
+                    if (NULL != my_obj->buf_cb) {
+                        mm_camera_cmd_thread_release(&my_obj->cmd_thread);
+
+                    }
+                    break;
+                }
+                my_obj->state = MM_STREAM_STATE_ACTIVE_STREAM_ON;
+            } else {
+                /* register one time CB at video fd */
+                CDBG("%s : Video Size snapshot Enabled",__func__);
+                mm_stream_data_cb_t cb;
+                memset(&cb, 0, sizeof(mm_stream_data_cb_t));
+                cb.cb_count = 1; /* one time reigstration */
+                cb.user_data = (void*)my_obj;
+                cb.cb = mm_stream_buf_notify;
+                rc = mm_channel_reg_stream_cb(my_obj->ch_obj, &cb,
+                                              MSM_V4L2_EXT_CAPTURE_MODE_VIDEO,
+                                              my_obj->sensor_idx);
+                my_obj->state = MM_STREAM_STATE_ACTIVE_STREAM_OFF;
+            }
+        }
+        break;
+    case MM_STREAM_EVT_SET_PARM:
+        rc = mm_stream_set_parm_config(my_obj, in_val);
+        break;
+    case MM_STREAM_EVT_GET_PARM:
+        rc = mm_stream_get_parm_config(my_obj, out_val);
+        break;
+    default:
+        CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
+                   __func__, evt, my_obj->state);
+        rc = -1;
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_fsm_active_stream_on(mm_stream_t * my_obj,

+                                              mm_stream_evt_type_t evt,
+                                              void * in_val,
+                                              void * out_val)
+{
+    int32_t rc = 0;
+    CDBG("%s :E evt = %d",__func__,evt);
+    switch(evt) {
+    case MM_STREAM_EVT_QBUF:
+        rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
+        break;
+    case MM_STREAM_EVT_STOP:
+        {
+            rc = mm_stream_streamoff(my_obj);
+            if (NULL != my_obj->buf_cb) {
+                mm_camera_cmd_thread_release(&my_obj->cmd_thread);
+
+            }
+            my_obj->state = MM_STREAM_STATE_REG;
+        }
+        break;
+    case MM_STREAM_EVT_SET_PARM:
+        rc = mm_stream_set_parm_start(my_obj, in_val);
+        break;
+    case MM_STREAM_EVT_GET_PARM:
+        rc = mm_stream_get_parm_start(my_obj, out_val);
+        break;
+    default:
+        CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
+                   __func__, evt, my_obj->state);
+        return -1;
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_fsm_active_stream_off(mm_stream_t * my_obj,

+                                               mm_stream_evt_type_t evt,
+                                               void * in_val,
+                                               void * out_val)
+{
+    int32_t rc = 0;
+    CDBG("%s :E evt = %d",__func__,evt);
+    switch(evt) {
+    case MM_STREAM_EVT_QBUF:
+        rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
+        break;
+    case MM_STREAM_EVT_STOP:
+        {
+            if (NULL != my_obj->buf_cb) {
+                rc = mm_camera_cmd_thread_release(&my_obj->cmd_thread);
+
+            }
+            my_obj->state = MM_STREAM_STATE_REG;
+        }
+        break;
+   case MM_STREAM_EVT_SET_PARM:
+        rc = mm_stream_set_parm_config(my_obj, in_val);
+        break;
+    case MM_STREAM_EVT_GET_PARM:
+        rc = mm_stream_get_parm_config(my_obj, out_val);
+        break;
+    default:
+        CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
+                   __func__, evt, my_obj->state);
+        return -1;
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_config(mm_stream_t *my_obj,
+                         mm_camera_stream_config_t *config)
+{
+    int32_t rc = 0;
+    memcpy(&my_obj->fmt, &config->fmt, sizeof(mm_camera_image_fmt_t));
+    my_obj->hal_requested_num_bufs = config->num_of_bufs;
+    my_obj->need_stream_on = config->need_stream_on;
+
+    rc = mm_stream_get_offset(my_obj);
+    if(rc != 0) {
+        CDBG_ERROR("%s: Error in offset query",__func__);
+        return rc;
+    }
+    if(mm_stream_need_stream_on(my_obj)) {
+        /* only send fmt to backend if we need streamon */
+        rc = mm_stream_set_fmt(my_obj);
+    }
+    return rc;
+}
+
+int32_t mm_stream_release(mm_stream_t *my_obj)
+{
+    int32_t rc;
+
+    /* close fd */
+    if(my_obj->fd > 0)
+    {
+        close(my_obj->fd);
+    }
+
+    /* destroy mutex */
+    pthread_mutex_destroy(&my_obj->buf_lock);
+    pthread_mutex_destroy(&my_obj->cb_lock);
+
+    /* reset stream obj */
+    memset(my_obj, 0, sizeof(mm_stream_t));
+    my_obj->fd = -1;
+
+    return 0;
+}
+
+uint8_t mm_stream_need_stream_on(mm_stream_t *my_obj)
+{
+    return my_obj->need_stream_on;
+}
+
+int32_t mm_stream_streamon(mm_stream_t *my_obj)
+{
+    int32_t rc;
+    enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+    CDBG("%s :E",__func__);
+    /* Add fd to data poll thread */
+    rc = mm_camera_poll_thread_add_poll_fd(&my_obj->ch_obj->poll_thread[0],
+                                           my_obj->my_hdl,
+                                           my_obj->fd,
+                                           mm_stream_data_notify,
+                                           (void*)my_obj);
+    if (rc < 0) {
+        return rc;
+    }
+    rc = ioctl(my_obj->fd, VIDIOC_STREAMON, &buf_type);
+    if (rc < 0) {
+        CDBG_ERROR("%s: ioctl VIDIOC_STREAMON failed: rc=%d\n",
+                   __func__, rc);
+        /* remove fd from data poll thread in case of failure */
+        mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_streamoff(mm_stream_t *my_obj)
+{
+    int32_t rc;
+    enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+    /* step1: remove fd from data poll thread */
+    mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl);
+
+    /* step2: stream off */
+    rc = ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type);
+    if (rc < 0) {
+        CDBG_ERROR("%s: STREAMOFF failed: %s\n",
+                __func__, strerror(errno));
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+static uint32_t mm_stream_util_get_v4l2_fmt(cam_format_t fmt,
+                                            uint8_t *num_planes)
+{
+    uint32_t val;
+    switch(fmt) {
+    case CAMERA_YUV_420_NV12:
+        val = V4L2_PIX_FMT_NV12;
+        *num_planes = 2;
+        break;
+    case CAMERA_YUV_420_NV21:
+        val = V4L2_PIX_FMT_NV21;
+        *num_planes = 2;
+        break;
+    case CAMERA_BAYER_SBGGR10:
+    case CAMERA_RDI:
+        val= V4L2_PIX_FMT_SBGGR10;
+        *num_planes = 1;
+        break;
+    case CAMERA_YUV_422_NV61:
+        val= V4L2_PIX_FMT_NV61;
+        *num_planes = 2;
+        break;
+    default:
+        val = 0;
+        *num_planes = 0;
+        break;
+    }
+    return val;
+}
+
+int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
+                                 mm_camera_buf_info_t* buf_info)
+{
+    int32_t idx = -1, rc = 0;
+    struct v4l2_buffer vb;
+    struct v4l2_plane planes[VIDEO_MAX_PLANES];
+    uint32_t i = 0;
+    uint8_t num_planes = 0;
+
+    mm_stream_util_get_v4l2_fmt(my_obj->fmt.fmt,
+                                &num_planes);
+
+    memset(&vb,  0,  sizeof(vb));
+    vb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    vb.memory = V4L2_MEMORY_USERPTR;
+    vb.m.planes = &planes[0];
+    vb.length = num_planes;
+
+    rc = ioctl(my_obj->fd, VIDIOC_DQBUF, &vb);
+    if (rc < 0) {
+        CDBG_ERROR("%s: VIDIOC_DQBUF ioctl call failed (rc=%d)\n",
+                   __func__, rc);
+    } else {
+        int8_t idx = vb.index;
+        buf_info->buf = &my_obj->buf[idx];
+        buf_info->frame_idx = vb.sequence;
+        buf_info->stream_id = my_obj->my_hdl;
+        buf_info->need_pp = my_obj->is_pp_needed;
+
+        buf_info->buf->stream_id = my_obj->my_hdl;
+        buf_info->buf->buf_idx = idx;
+        buf_info->buf->frame_idx = vb.sequence;
+        buf_info->buf->ts.tv_sec  = vb.timestamp.tv_sec;
+        buf_info->buf->ts.tv_nsec = vb.timestamp.tv_usec * 1000;
+
+        for(i = 0; i < vb.length; i++) {
+            CDBG("%s plane %d addr offset: %d data offset:%d\n",
+                 __func__, i, vb.m.planes[i].reserved[0],
+                 vb.m.planes[i].data_offset);
+            buf_info->buf->planes[i].reserved[0] =
+                vb.m.planes[i].reserved[0];
+            buf_info->buf->planes[i].data_offset =
+                vb.m.planes[i].data_offset;
+        }
+
+
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_get_crop(mm_stream_t *my_obj,
+                           mm_camera_rect_t *crop)
+{
+    struct v4l2_crop crop_info;
+    int32_t rc = 0;
+
+    memset(&crop_info, 0, sizeof(crop_info));
+    crop_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    rc = ioctl(my_obj->fd, VIDIOC_G_CROP, &crop_info);
+    if (0 == rc) {
+        crop->left = crop_info.c.left;
+        crop->top = crop_info.c.top;
+        crop->width = crop_info.c.width;
+        crop->height = crop_info.c.height;
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_set_parm_acquire(mm_stream_t *my_obj,
+                         void *in_value)
+{
+    int32_t rc = 0;
+    mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
+    mm_camera_stream_parm_t parm_type = payload->parm_type;
+
+    CDBG("%s: parm_type = %d",__func__,(int)parm_type);
+    switch(parm_type) {
+    case MM_CAMERA_STREAM_CID:{
+            stream_cid_t *value = (stream_cid_t *)in_value;
+            mm_stream_set_cid(my_obj,value);
+            break;
+        }
+        default:
+            CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
+            break;
+    }
+    return rc;
+}
+int32_t mm_stream_get_parm_acquire(mm_stream_t *my_obj,
+                         void *out_value)
+{
+    int32_t rc = 0;
+    mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
+    mm_camera_stream_parm_t parm_type = payload->parm_type;
+
+    CDBG("%s: parm_type = %d",__func__,(int)parm_type);
+    switch(parm_type) {
+    case MM_CAMERA_STREAM_CID:{
+            stream_cid_t *value = (stream_cid_t *)out_value;
+            rc = mm_stream_get_cid(my_obj,value);
+            break;
+        }
+        case MM_CAMERA_STREAM_CROP:{
+            mm_camera_rect_t *crop = (mm_camera_rect_t *)out_value;
+            rc = mm_stream_get_crop(my_obj, crop);
+            break;
+        }
+        default:
+            CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)parm_type);
+            break;
+    }
+    return rc;
+}
+
+int32_t mm_stream_set_parm_config(mm_stream_t *my_obj,
+                         void *in_value)
+{
+    int32_t rc = 0;
+    mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
+    mm_camera_stream_parm_t parm_type = payload->parm_type;
+    void *value = payload->value;
+
+    CDBG("%s: parm_type = %d",__func__,(int)parm_type);
+    switch(parm_type) {
+        default:
+            CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
+            break;
+    }
+    return rc;
+}
+int32_t mm_stream_get_parm_config(mm_stream_t *my_obj,
+                         void *out_value)
+{
+    int32_t rc = 0;
+    mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
+
+    if(payload == NULL) {
+        CDBG_ERROR("%s : Invalid Argument",__func__);
+        return -1;
+    }
+    CDBG("%s: parm_type = %d",__func__,(int)payload->parm_type);
+    switch(payload->parm_type) {
+        case MM_CAMERA_STREAM_OFFSET:
+            memcpy(payload->value,(void *)&my_obj->frame_offset,sizeof(mm_camera_frame_len_offset));
+            break;
+        case MM_CAMERA_STREAM_CROP:{
+            mm_camera_rect_t *crop = (mm_camera_rect_t *)payload->value;
+            rc = mm_stream_get_crop(my_obj, crop);
+            break;
+        }
+        default:
+            CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)payload->parm_type);
+            break;
+    }
+    return rc;
+}
+
+int32_t mm_stream_set_parm_start(mm_stream_t *my_obj,
+                         void *in_value)
+{
+    int32_t rc = 0;
+    mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
+    mm_camera_stream_parm_t parm_type = payload->parm_type;
+    void *value = payload->value;
+
+    CDBG("%s: parm_type = %d",__func__,(int)parm_type);
+    switch(parm_type) {
+        default:
+            CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
+            break;
+    }
+    return rc;
+}
+int32_t mm_stream_get_parm_start(mm_stream_t *my_obj,
+                         void *out_value)
+{
+    int32_t rc = 0;
+    mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
+
+    if(payload == NULL) {
+        CDBG_ERROR("%s : Invalid Argument",__func__);
+        return -1;
+    }
+    CDBG("%s: parm_type = %d",__func__,(int)payload->parm_type);
+    switch(payload->parm_type) {
+        case MM_CAMERA_STREAM_OFFSET:
+            memcpy(payload->value,(void *)&my_obj->frame_offset,sizeof(mm_camera_frame_len_offset));
+            break;
+        case MM_CAMERA_STREAM_CROP:{
+            mm_camera_rect_t *crop = (mm_camera_rect_t *)payload->value;
+            rc = mm_stream_get_crop(my_obj, crop);
+            break;
+        }
+        default:
+            CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)payload->parm_type);
+            break;
+    }
+    return rc;
+}
+int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj)
+{
+    int32_t rc = 0;
+    struct v4l2_streamparm s_parm;
+
+    s_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    s_parm.parm.capture.extendedmode = my_obj->ext_image_mode;
+
+    rc = ioctl(my_obj->fd, VIDIOC_S_PARM, &s_parm);
+        CDBG("%s:stream fd=%d, rc=%d, extended_mode=%d\n",
+                 __func__, my_obj->fd, rc,
+                 s_parm.parm.capture.extendedmode);
+    return rc;
+}
+
+int32_t mm_stream_qbuf(mm_stream_t *my_obj, mm_camera_buf_def_t *buf)
+{
+    int32_t i, rc = 0;
+    int *ret;
+    struct v4l2_buffer buffer;
+
+    memset(&buffer, 0, sizeof(buffer));
+    buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    buffer.memory = V4L2_MEMORY_USERPTR;
+    buffer.index = buf->buf_idx;
+    buffer.m.planes = &buf->planes[0];
+    buffer.length = buf->num_planes;
+
+    CDBG("%s:stream_hdl=%d,fd=%d,frame idx=%d,num_planes = %d\n", __func__,
+         buf->stream_id, buf->fd, buffer.index, buffer.length);
+
+    rc = ioctl(my_obj->fd, VIDIOC_QBUF, &buffer);
+    CDBG("%s: qbuf idx:%d, rc:%d", __func__, buffer.index, rc);
+    return rc;
+}
+
+/* This function let kernel know amount of buffers will be registered */
+int32_t mm_stream_request_buf(mm_stream_t * my_obj)
+{
+    int32_t rc = 0;
+    uint8_t i,reg = 0;
+    struct v4l2_requestbuffers bufreq;
+    uint8_t buf_num = my_obj->buf_num;
+
+    if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) {
+        CDBG_ERROR("%s: buf num %d > max limit %d\n",
+                 __func__, buf_num, MM_CAMERA_MAX_NUM_FRAMES);
+        return -1;
+    }
+    pthread_mutex_lock(&my_obj->buf_lock);
+    for(i = 0; i < buf_num; i++){
+        if (my_obj->buf_status[i].initial_reg_flag){
+            reg = 1;
+            break;
+        }
+    }
+    pthread_mutex_unlock(&my_obj->buf_lock);
+    if(!reg) {
+        //No need to register a buffer
+        CDBG_ERROR("No Need to register this buffer");
+        return rc;
+    }
+    memset(&bufreq, 0, sizeof(bufreq));
+    bufreq.count = buf_num;
+    bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    bufreq.memory = V4L2_MEMORY_USERPTR;
+    rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
+    if (rc < 0) {
+      CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n",
+           __func__, my_obj->fd, rc);
+    }
+    CDBG("%s :X rc = %d",__func__,rc);
+    return rc;
+}
+
+int32_t mm_stream_get_frame_len_offset(mm_camera_image_fmt_t* img_fmt,
+                                       camera_mode_t mode,
+                                       int image_type,
+                                       mm_camera_frame_len_offset * frame_offset)
+{
+    /* TODO : this function should query the frame len from backend using cmd */
+    /* for now, it's still use hardcoded value */
+    uint32_t width, height;
+    int local_height;
+
+    width = img_fmt->width;
+    height = img_fmt->height;
+
+    switch (img_fmt->fmt) {
+    case CAMERA_YUV_420_NV12:
+    case CAMERA_YUV_420_NV21:
+        frame_offset->num_planes = 2;
+        if (image_type == OUTPUT_TYPE_V) {
+            frame_offset->mp[0].len = PAD_TO_2K(width * height);
+            frame_offset->mp[1].len = PAD_TO_2K(width * height/2);
+            /* TODO: offset to count in meta header*/
+            frame_offset->mp[0].offset = 0;
+            frame_offset->mp[1].offset = 0;
+        } else if (image_type == OUTPUT_TYPE_P) {
+            frame_offset->mp[0].len = PAD_TO_WORD(width * height);
+            frame_offset->mp[1].len = PAD_TO_WORD(width * height/2);
+            /* TODO: offset to count in meta header*/
+            frame_offset->mp[0].offset = 0;
+            frame_offset->mp[1].offset = 0;
+        } else {
+            frame_offset->mp[0].len = PAD_TO_WORD(width * CEILING16(height));
+            frame_offset->mp[1].len = PAD_TO_WORD(width * CEILING16(height)/2);
+            /* TODO: offset to count in meta header*/
+            frame_offset->mp[0].offset = 0;
+            frame_offset->mp[1].offset = 0;
+        }
+        frame_offset->frame_len =
+            PAD_TO_4K(frame_offset->mp[0].len + frame_offset->mp[1].len);
+        break;
+    case CAMERA_BAYER_SBGGR10:
+        frame_offset->num_planes = 1;
+        frame_offset->mp[0].len = PAD_TO_WORD(width * height);
+        frame_offset->frame_len = frame_offset->mp[0].len;
+        break;
+    case CAMERA_YUV_422_NV16:
+    case CAMERA_YUV_422_NV61:
+        if( image_type == OUTPUT_TYPE_S || image_type == OUTPUT_TYPE_V) {
+            local_height = CEILING16(height);
+        } else {
+            local_height = height;
+        }
+        frame_offset->num_planes = 2;
+        frame_offset->mp[0].len = PAD_TO_WORD(width * height);
+        frame_offset->mp[1].len = PAD_TO_WORD(width * height);
+        /* TODO: offset to count in meta header*/
+        frame_offset->mp[0].offset = 0;
+        frame_offset->mp[1].offset = 0;
+        frame_offset->frame_len =
+            frame_offset->mp[0].len + frame_offset->mp[1].len;
+        break;
+    default:
+        CDBG("%s: format %d not supported.\n",
+            __func__, img_fmt->fmt);
+        frame_offset->frame_len = 0;
+    }
+    CDBG("%s:fmt=%d,image_type=%d,width=%d,height=%d,frame_len=%d\n",
+        __func__, img_fmt->fmt, image_type, width, height, frame_offset->frame_len);
+    return 0;
+}
+
+int32_t mm_stream_init_bufs(mm_stream_t * my_obj)
+{
+    int32_t i, rc = 0, j;
+    int image_type;
+    mm_camear_mem_vtbl_t *mem_vtbl = NULL;
+    mm_camera_frame_len_offset frame_offset;
+    uint8_t *reg_flags = NULL;
+
+    /* deinit buf if it's not NULL*/
+    if (NULL != my_obj->buf) {
+        mm_stream_deinit_bufs(my_obj);
+    }
+
+    my_obj->buf_num = my_obj->hal_requested_num_bufs;
+    /* if stream needs do pp, allocate extra one buf for pp*/
+    if (my_obj->is_pp_needed) {
+        my_obj->buf_num++;
+    }
+
+    my_obj->buf =
+        (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t) * my_obj->buf_num);
+    my_obj->buf_status =
+        (mm_stream_buf_status_t*)malloc(sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
+    reg_flags = (uint8_t *)malloc(sizeof(uint8_t) * my_obj->buf_num);
+
+    if (NULL == my_obj->buf ||
+        NULL == my_obj->buf_status ||
+        NULL == reg_flags) {
+        CDBG_ERROR("%s: No memory for buf", __func__);
+        rc = -1;
+        goto error_malloc;
+    }
+
+    memset(my_obj->buf, 0, sizeof(mm_camera_buf_def_t) * my_obj->buf_num);
+    memset(my_obj->buf_status, 0, sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
+    memset(reg_flags, 0, sizeof(uint8_t) * my_obj->buf_num);
+
+    mem_vtbl = my_obj->ch_obj->cam_obj->mem_vtbl;
+    rc = mem_vtbl->get_buf(my_obj->ch_obj->cam_obj->my_hdl,
+                           my_obj->ch_obj->my_hdl,
+                           my_obj->my_hdl,
+                           mem_vtbl->user_data,
+                           &my_obj->frame_offset,
+                           my_obj->buf_num,
+                           reg_flags,
+                           my_obj->buf);
+
+    if (0 != rc) {
+        CDBG_ERROR("%s: Error get buf, rc = %d\n", __func__, rc);
+        goto error_malloc;
+    }
+
+    for (i=0; i < my_obj->buf_num; i++) {
+        my_obj->buf_status[i].initial_reg_flag = reg_flags[i];
+        my_obj->buf[i].stream_id = my_obj->my_hdl;
+    }
+
+    free(reg_flags);
+    reg_flags = NULL;
+
+    for (i=0; i < my_obj->buf_num; i++) {
+        if (my_obj->buf[i].fd > 0) {
+            if(0 >= (rc = mm_camera_map_buf(my_obj->ch_obj->cam_obj,
+                          my_obj->ext_image_mode,
+                          i,
+                          my_obj->buf[i].fd,
+                          my_obj->buf[i].frame_len)))
+            {
+                CDBG_ERROR("%s: Error mapping buf (rc = %d)", __func__, rc);
+                goto error_map;
+            }
+        } else {
+            CDBG_ERROR("%s: Invalid fd for buf idx (%d)", __func__, i);
+        }
+    }
+
+    return 0;
+
+error_map:
+    /* error, unmapping previously mapped bufs */
+    for (j=0; j<i; j++) {
+        if (my_obj->buf[j].fd > 0) {
+            mm_camera_unmap_buf(my_obj->ch_obj->cam_obj,
+                                my_obj->ext_image_mode,
+                                j);
+        }
+    }
+
+    /* put buf back */
+    mem_vtbl->put_buf(my_obj->ch_obj->cam_obj->my_hdl,
+                      my_obj->ch_obj->my_hdl,
+                      my_obj->my_hdl,
+                      mem_vtbl->user_data,
+                      my_obj->buf_num,
+                      my_obj->buf);
+
+error_malloc:
+    if (NULL != my_obj->buf) {
+        free(my_obj->buf);
+        my_obj->buf = NULL;
+    }
+    if (NULL != my_obj->buf_status) {
+        free(my_obj->buf_status);
+        my_obj->buf_status = NULL;
+    }
+    if (NULL != reg_flags) {
+        free(reg_flags);
+        reg_flags = NULL;
+    }
+
+    return rc;
+}
+
+/* return buffers to surface or release buffers allocated */
+int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj)
+{
+    int32_t rc = 0, i;
+    mm_camear_mem_vtbl_t *mem_vtbl = NULL;
+
+    if (NULL == my_obj->buf) {
+        CDBG("%s: Buf is NULL, no need to deinit", __func__);
+        return rc;
+    }
+
+    /* IOMMU unmapping */
+    for (i=0; i<my_obj->buf_num; i++) {
+        if (my_obj->buf[i].fd > 0) {
+            rc = mm_camera_unmap_buf(my_obj->ch_obj->cam_obj,
+                                     my_obj->ext_image_mode,
+                                     i);
+            if (rc < 0 ) {
+                CDBG_ERROR("%s: Error unmapping bufs at idx(%d) rc=%d",
+                           __func__, i, rc);
+            }
+        }
+    }
+
+    /* release bufs */
+    mem_vtbl = my_obj->ch_obj->cam_obj->mem_vtbl;
+    if (NULL != mem_vtbl) {
+        rc = mem_vtbl->put_buf(my_obj->ch_obj->cam_obj->my_hdl,
+                          my_obj->ch_obj->my_hdl,
+                          my_obj->my_hdl,
+                          mem_vtbl->user_data,
+                          my_obj->buf_num,
+                          my_obj->buf);
+    } else {
+        CDBG_ERROR("%s: mem table is NULL, cannot release buf", __func__);
+        rc = -1;
+    }
+
+    free(my_obj->buf);
+    my_obj->buf = NULL;
+    free(my_obj->buf_status);
+    my_obj->buf_status = NULL;
+
+    return rc;
+}
+
+int32_t mm_stream_reg_buf(mm_stream_t * my_obj)
+{
+    int32_t rc = 0;
+    uint8_t i;
+
+    rc = mm_stream_request_buf(my_obj);
+    if (rc != 0) {
+        return rc;
+    }
+
+    pthread_mutex_lock(&my_obj->buf_lock);
+    for(i = 0; i < my_obj->buf_num; i++){
+        my_obj->buf[i].buf_idx = i;
+
+        /* check if need to qbuf initially */
+        if (my_obj->buf_status[i].initial_reg_flag) {
+            rc = mm_stream_qbuf(my_obj, &my_obj->buf[i]);
+            if (rc != 0) {
+                CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc);
+                return rc;
+            }
+        }
+
+        my_obj->buf_status[i].buf_refcnt = 0;
+        my_obj->buf_status[i].in_kernel = 1;
+    }
+    pthread_mutex_unlock(&my_obj->buf_lock);
+    return rc;
+}
+
+int32_t mm_stream_unreg_buf(mm_stream_t * my_obj)
+{
+    struct v4l2_requestbuffers bufreq;
+    int32_t i, rc = 0,reg = 0;
+
+    pthread_mutex_lock(&my_obj->buf_lock);
+    if (NULL != my_obj->buf_status) {
+        for(i = 0; i < my_obj->buf_num; i++){
+            if (my_obj->buf_status[i].initial_reg_flag){
+                reg = 1;
+                break;
+            }
+        }
+    }
+    pthread_mutex_unlock(&my_obj->buf_lock);
+    if(!reg) {
+        //No need to unregister a buffer
+        goto end;
+    }
+    bufreq.count = 0;
+    bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    bufreq.memory = V4L2_MEMORY_USERPTR;
+    rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
+    if (rc < 0) {
+        CDBG_ERROR("%s: fd=%d, VIDIOC_REQBUFS failed, rc=%d\n",
+              __func__, my_obj->fd, rc);
+    }
+
+end:
+    /* reset buf reference count */
+    pthread_mutex_lock(&my_obj->buf_lock);
+    if (NULL != my_obj->buf_status) {
+        for(i = 0; i < my_obj->buf_num; i++){
+            my_obj->buf_status[i].buf_refcnt = 0;
+            my_obj->buf_status[i].in_kernel = 0;
+        }
+    }
+    pthread_mutex_unlock(&my_obj->buf_lock);
+
+    return rc;
+}
+
+int32_t mm_stream_set_fmt(mm_stream_t *my_obj)
+{
+    int32_t rc = 0;
+    struct v4l2_format fmt;
+
+    if(my_obj->fmt.width == 0 || my_obj->fmt.height == 0) {
+        CDBG_ERROR("%s:invalid input[w=%d,h=%d,fmt=%d]\n",
+                 __func__, my_obj->fmt.width, my_obj->fmt.height, my_obj->fmt.fmt);
+        return -1;
+    }
+
+    memset(&fmt, 0, sizeof(fmt));
+    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    fmt.fmt.pix_mp.width = my_obj->fmt.width;
+    fmt.fmt.pix_mp.height= my_obj->fmt.height;
+    fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+    fmt.fmt.pix_mp.pixelformat =
+            mm_stream_util_get_v4l2_fmt(my_obj->fmt.fmt,
+                                      &(fmt.fmt.pix_mp.num_planes));
+    rc = ioctl(my_obj->fd, VIDIOC_S_FMT, &fmt);
+    CDBG("%s:fd=%d, ext_image_mode=%d, rc=%d\n",
+             __func__, my_obj->fd, my_obj->ext_image_mode, rc);
+
+    return rc;
+}
+
+int32_t mm_stream_get_offset(mm_stream_t *my_obj)
+{
+    int32_t rc = 0;
+    cam_frame_resolution_t frame_offset;
+
+    memset(&my_obj->frame_offset,0,sizeof(mm_camera_frame_len_offset));
+
+    frame_offset.format = my_obj->fmt.fmt;
+    frame_offset.image_mode = my_obj->ext_image_mode;
+    frame_offset.rotation = my_obj->fmt.rotation;
+    frame_offset.width = my_obj->fmt.width;
+    frame_offset.height = my_obj->fmt.height;
+
+    switch (my_obj->ext_image_mode) {
+    case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW:
+    case MSM_V4L2_EXT_CAPTURE_MODE_MAIN:
+    case MSM_V4L2_EXT_CAPTURE_MODE_RAW:
+    case MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL:
+    case MSM_V4L2_EXT_CAPTURE_MODE_RDI:
+        frame_offset.padding_format = CAMERA_PAD_TO_WORD;
+        break;
+    case MSM_V4L2_EXT_CAPTURE_MODE_VIDEO:
+    default:
+        frame_offset.padding_format = CAMERA_PAD_TO_2K;
+        break;
+    }
+
+    CDBG("%s: format = %d, image_mode = %d, padding_format = %d, rotation = %d,"
+            "width = %d height = %d",
+             __func__,frame_offset.format,frame_offset.image_mode,frame_offset.padding_format,
+             frame_offset.rotation,frame_offset.width,frame_offset.height);
+
+    rc = mm_camera_send_native_ctrl_cmd(my_obj->ch_obj->cam_obj,
+                                            CAMERA_GET_PARM_FRAME_RESOLUTION,
+                                            sizeof(cam_frame_resolution_t),
+                                            &frame_offset);
+    if(rc != 0) {
+        CDBG_ERROR("%s: Failed to get the stream offset and frame length",__func__);
+        return rc;
+    }
+    my_obj->fmt.width = frame_offset.width;
+    my_obj->fmt.height = frame_offset.height;
+    memcpy(&my_obj->frame_offset,&frame_offset.frame_offset,sizeof(mm_camera_frame_len_offset));
+    CDBG("%s: Frame length = %d width = %d, height = %d, rc = %d",
+         __func__,my_obj->frame_offset.frame_len,my_obj->fmt.width,my_obj->fmt.height,rc);
+    return rc;
+}
+
+
+int32_t mm_stream_set_cid(mm_stream_t *my_obj,stream_cid_t *value)
+{
+    int32_t rc = 0;
+    cam_cid_info_t cam_cid_info;
+
+    cam_cid_info.num_cids = 1;
+    cam_cid_info.cid_entries[0].cid = value->cid;
+    cam_cid_info.cid_entries[0].dt = value->dt;
+    cam_cid_info.cid_entries[0].inst_handle = my_obj->inst_hdl;
+
+    rc = mm_camera_send_native_ctrl_cmd(my_obj->ch_obj->cam_obj,
+                                            CAMERA_SET_PARM_CID,
+                                            sizeof(cam_cid_info_t),
+                                            &cam_cid_info);
+    if(rc != 0) {
+        CDBG_ERROR("%s: Failed to set the CID",__func__);
+        return rc;
+    }
+    return rc;
+}
+
+int32_t mm_stream_get_cid(mm_stream_t *my_obj,stream_cid_t *out_value)
+{
+    //TODO: Need to use sensor structure init in camera query
+    int32_t rc = 0;
+    return rc;
+}
+
+int32_t mm_stream_buf_done(mm_stream_t * my_obj,
+                           mm_camera_buf_def_t *frame)
+{
+    int32_t rc = 0;
+
+    if (my_obj->is_local_buf) {
+        /* special case for video-sized live snapshot
+         * buf is local, no need to qbuf to kernel */
+        return 0;
+    }
+
+    pthread_mutex_lock(&my_obj->buf_lock);
+
+    if(my_obj->buf_status[frame->buf_idx].buf_refcnt == 0) {
+        CDBG("%s: Error Trying to free second time?(idx=%d) count=%d, ext_image_mode=%d\n",
+                   __func__, frame->buf_idx,
+                   my_obj->buf_status[frame->buf_idx].buf_refcnt,
+                   my_obj->ext_image_mode);
+        rc = -1;
+    }else{
+        my_obj->buf_status[frame->buf_idx].buf_refcnt--;
+        if (0 == my_obj->buf_status[frame->buf_idx].buf_refcnt) {
+            CDBG("<DEBUG> : Buf done for buffer:%d:%d", my_obj->ext_image_mode, frame->buf_idx);
+            rc = mm_stream_qbuf(my_obj, frame);
+            if(rc < 0) {
+                CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
+                     __func__, frame->buf_idx, rc);
+            } else {
+                my_obj->buf_status[frame->buf_idx].in_kernel = 1;
+            }
+        }else{
+            CDBG("<DEBUG> : Still ref count pending count :%d",
+                 my_obj->buf_status[frame->buf_idx].buf_refcnt);
+            CDBG("<DEBUG> : for buffer:%p:%d, ext_image_mode=%d",
+                 my_obj, frame->buf_idx, my_obj->ext_image_mode);
+        }
+    }
+    pthread_mutex_unlock(&my_obj->buf_lock);
+    return rc;
+}
+
+int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
+                             mm_stream_data_cb_t *val)
+{
+    int32_t rc = -1;
+    uint8_t i;
+
+    pthread_mutex_lock(&my_obj->cb_lock);
+    for (i=0 ;i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
+        if(NULL == my_obj->buf_cb[i].cb) {
+            memcpy(&my_obj->buf_cb[i], val, sizeof(mm_stream_data_cb_t));
+            rc = 0;
+            break;
+        }
+    }
+    pthread_mutex_unlock(&my_obj->cb_lock);
+
+    return rc;
+}
diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera_thread.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_thread.c
new file mode 100755
index 0000000..7d45d4d
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera_thread.c
@@ -0,0 +1,361 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <semaphore.h>
+
+#include "mm_camera_dbg.h"
+#include "mm_camera_interface.h"
+#include "mm_camera.h"
+
+typedef enum {
+    /* poll entries updated */
+    MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED,
+    /* exit */
+    MM_CAMERA_PIPE_CMD_EXIT,
+    /* max count */
+    MM_CAMERA_PIPE_CMD_MAX
+} mm_camera_pipe_cmd_type_t;
+
+typedef enum {
+    MM_CAMERA_POLL_TASK_STATE_STOPPED,
+    MM_CAMERA_POLL_TASK_STATE_POLL,     /* polling pid in polling state. */
+    MM_CAMERA_POLL_TASK_STATE_MAX
+} mm_camera_poll_task_state_type_t;
+
+typedef struct {
+    uint8_t cmd;
+    mm_camera_event_t event;
+} mm_camera_sig_evt_t;
+
+static int32_t mm_camera_poll_sig(mm_camera_poll_thread_t *poll_cb,
+                                  uint32_t cmd)
+{
+    /* send through pipe */
+    /* get the mutex */
+    mm_camera_sig_evt_t cmd_evt;
+    int len;
+
+    CDBG("%s: E cmd = %d", __func__,cmd);
+    memset(&cmd_evt, 0, sizeof(cmd_evt));
+    cmd_evt.cmd = cmd;
+    pthread_mutex_lock(&poll_cb->mutex);
+    /* reset the statue to false */
+    poll_cb->status = FALSE;
+    /* send cmd to worker */
+
+    len = write(poll_cb->pfds[1], &cmd_evt, sizeof(cmd_evt));
+    if(len < 1) {
+        CDBG_ERROR("%s: len = %d, errno = %d", __func__, len, errno);
+    }
+    CDBG("%s: begin IN mutex write done, len = %d", __func__, len);
+    /* wait till worker task gives positive signal */
+    if (FALSE == poll_cb->status) {
+        CDBG("%s: wait", __func__);
+        pthread_cond_wait(&poll_cb->cond_v, &poll_cb->mutex);
+    }
+    /* done */
+    pthread_mutex_unlock(&poll_cb->mutex);
+    CDBG("%s: X", __func__);
+    return 0;
+}
+
+static void mm_camera_poll_sig_done(mm_camera_poll_thread_t *poll_cb)
+{
+    pthread_mutex_lock(&poll_cb->mutex);
+    poll_cb->status = TRUE;
+    pthread_cond_signal(&poll_cb->cond_v);
+    CDBG("%s: done, in mutex", __func__);
+    pthread_mutex_unlock(&poll_cb->mutex);
+}
+
+static void mm_camera_poll_set_state(mm_camera_poll_thread_t *poll_cb,
+                                     mm_camera_poll_task_state_type_t state)
+{
+    poll_cb->state = state;
+}
+
+static void mm_camera_poll_proc_pipe(mm_camera_poll_thread_t *poll_cb)
+{
+    ssize_t read_len;
+    int i;
+    mm_camera_sig_evt_t cmd_evt;
+    read_len = read(poll_cb->pfds[0], &cmd_evt, sizeof(cmd_evt));
+    CDBG("%s: read_fd = %d, read_len = %d, expect_len = %d cmd = %d",
+         __func__, poll_cb->pfds[0], (int)read_len, (int)sizeof(cmd_evt), cmd_evt.cmd);
+    switch (cmd_evt.cmd) {
+    case MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED:
+        /* we always have index 0 for pipe read */
+        poll_cb->num_fds = 0;
+        poll_cb->poll_fds[poll_cb->num_fds].fd = poll_cb->pfds[0];
+        poll_cb->poll_fds[poll_cb->num_fds].events = POLLIN|POLLRDNORM|POLLPRI;
+        poll_cb->num_fds++;
+
+        if (MM_CAMERA_POLL_TYPE_EVT == poll_cb->poll_type) {
+            if (poll_cb->poll_entries[0].fd > 0) {
+                /* fd is valid, we update poll_fds */
+                poll_cb->poll_fds[poll_cb->num_fds].fd = poll_cb->poll_entries[0].fd;
+                poll_cb->poll_fds[poll_cb->num_fds].events = POLLIN|POLLRDNORM|POLLPRI;
+                poll_cb->num_fds++;
+            }
+        } else if (MM_CAMERA_POLL_TYPE_CH == poll_cb->poll_type) {
+            for(i = 0; i < MM_CAMEAR_STRAEM_NUM_MAX; i++) {
+                if(poll_cb->poll_entries[i].fd > 0) {
+                    /* fd is valid, we update poll_fds to this fd */
+                    poll_cb->poll_fds[poll_cb->num_fds].fd = poll_cb->poll_entries[i].fd;
+                    poll_cb->poll_fds[poll_cb->num_fds].events = POLLIN|POLLRDNORM|POLLPRI;
+                    poll_cb->num_fds++;
+                } else {
+                    /* fd is invalid, we set the entry to -1 to prevent polling.
+                     * According to spec, polling will not poll on entry with fd=-1.
+                     * If this is not the case, we need to skip these invalid fds
+                     * when updating this array.
+                     * We still keep fd=-1 in this array because this makes easier to
+                     * map cb associated with this fd once incoming data avail by directly
+                     * using the index-1(0 is reserved for pipe read, so need to reduce index by 1) */
+                    poll_cb->poll_fds[poll_cb->num_fds].fd = -1;
+                    poll_cb->poll_fds[poll_cb->num_fds].events = 0;
+                    poll_cb->num_fds++;
+                }
+            }
+        }
+        mm_camera_poll_sig_done(poll_cb);
+        break;
+
+    case MM_CAMERA_PIPE_CMD_EXIT:
+    default:
+        mm_camera_poll_set_state(poll_cb, MM_CAMERA_POLL_TASK_STATE_STOPPED);
+        mm_camera_poll_sig_done(poll_cb);
+        break;
+    }
+}
+
+static void *mm_camera_poll_fn(mm_camera_poll_thread_t *poll_cb)
+{
+    int rc = 0, i;
+
+    CDBG("%s: poll type = %d, num_fd = %d poll_cb = %p\n",
+         __func__, poll_cb->poll_type, poll_cb->num_fds,poll_cb);
+    do {
+         for(i = 0; i < poll_cb->num_fds; i++) {
+            poll_cb->poll_fds[i].events = POLLIN|POLLRDNORM|POLLPRI;
+         }
+
+         rc = poll(poll_cb->poll_fds, poll_cb->num_fds, poll_cb->timeoutms);
+         if(rc > 0) {
+            if ((poll_cb->poll_fds[0].revents & POLLIN) &&
+                (poll_cb->poll_fds[0].revents & POLLRDNORM)) {
+                /* if we have data on pipe, we only process pipe in this iteration */
+                CDBG("%s: cmd received on pipe\n", __func__);
+                mm_camera_poll_proc_pipe(poll_cb);
+            } else {
+                for(i=1; i<poll_cb->num_fds; i++) {
+                    /* Checking for ctrl events */
+                    if ((poll_cb->poll_type == MM_CAMERA_POLL_TYPE_EVT) &&
+                        (poll_cb->poll_fds[i].revents & POLLPRI)) {
+                        CDBG("%s: mm_camera_evt_notify\n", __func__);
+                        if (NULL != poll_cb->poll_entries[i-1].notify_cb) {
+                            poll_cb->poll_entries[i-1].notify_cb(poll_cb->poll_entries[i-1].user_data);
+                        }
+                    }
+
+                    if ((poll_cb->poll_type == MM_CAMERA_POLL_TYPE_CH) &&
+                        (poll_cb->poll_fds[i].revents & POLLIN) &&
+                        (poll_cb->poll_fds[i].revents & POLLRDNORM)) {
+                        CDBG("%s: mm_stream_data_notify\n", __func__);
+                        if (NULL != poll_cb->poll_entries[i-1].notify_cb) {
+                            poll_cb->poll_entries[i-1].notify_cb(poll_cb->poll_entries[i-1].user_data);
+                        }
+                    }
+                }
+            }
+        } else {
+            /* in error case sleep 10 us and then continue. hard coded here */
+            usleep(10);
+            continue;
+        }
+    } while (poll_cb->state == MM_CAMERA_POLL_TASK_STATE_POLL);
+    return NULL;
+}
+
+static void *mm_camera_poll_thread(void *data)
+{
+    int rc = 0;
+    int i;
+    void *ret = NULL;
+    mm_camera_poll_thread_t *poll_cb = (mm_camera_poll_thread_t *)data;
+
+    /* add pipe read fd into poll first */
+    poll_cb->poll_fds[poll_cb->num_fds++].fd = poll_cb->pfds[0];
+
+    //poll_cb->poll_fds[poll_cb->num_fds++].fd = (((mm_camera_obj_t *)poll_cb->my_obj)->ctrl_fd);
+
+    mm_camera_poll_sig_done(poll_cb);
+    mm_camera_poll_set_state(poll_cb, MM_CAMERA_POLL_TASK_STATE_POLL);
+    ret = mm_camera_poll_fn(poll_cb);
+    return ret;
+}
+
+int32_t mm_camera_poll_thread_notify_entries_updated(mm_camera_poll_thread_t * poll_cb)
+{
+    /* send poll entries updated signal to poll thread */
+    return mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED);
+}
+
+int32_t mm_camera_poll_thread_add_poll_fd(mm_camera_poll_thread_t * poll_cb,
+                                          uint32_t handler,
+                                          int32_t fd,
+                                          mm_camera_poll_notify_t notify_cb,
+                                          void* userdata)
+{
+    int32_t rc = -1;
+    uint8_t idx = 0;
+
+    if (MM_CAMERA_POLL_TYPE_CH == poll_cb->poll_type) {
+        /* get stream idx from handler if CH type */
+        idx = mm_camera_util_get_index_by_handler(handler);
+    } else {
+        /* for EVT type, only idx=0 is valid */
+        idx = 0;
+    }
+
+    if (MM_CAMEAR_STRAEM_NUM_MAX > idx) {
+        poll_cb->poll_entries[idx].fd = fd;
+        poll_cb->poll_entries[idx].handler = handler;
+        poll_cb->poll_entries[idx].notify_cb = notify_cb;
+        poll_cb->poll_entries[idx].user_data = userdata;
+        /* send poll entries updated signal to poll thread */
+        rc = mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED);
+    } else {
+        CDBG_ERROR("%s: invalid handler %d (%d)",
+                   __func__, handler, idx);
+    }
+    return rc;
+}
+
+int32_t mm_camera_poll_thread_del_poll_fd(mm_camera_poll_thread_t * poll_cb,
+                                          uint32_t handler)
+{
+    int32_t rc = -1;
+    uint8_t idx = 0;
+
+    if (MM_CAMERA_POLL_TYPE_CH == poll_cb->poll_type) {
+        /* get stream idx from handler if CH type */
+        idx = mm_camera_util_get_index_by_handler(handler);
+    } else {
+        /* for EVT type, only idx=0 is valid */
+        idx = 0;
+    }
+
+    if ((MM_CAMEAR_STRAEM_NUM_MAX > idx) &&
+        (handler == poll_cb->poll_entries[idx].handler)) {
+        /* reset poll entry */
+        poll_cb->poll_entries[idx].fd = -1; /* set fd to invalid */
+        poll_cb->poll_entries[idx].handler = 0;
+        poll_cb->poll_entries[idx].notify_cb = NULL;
+
+        /* send poll entries updated signal to poll thread */
+        rc = mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED);
+    } else {
+        CDBG_ERROR("%s: invalid handler %d (%d)",
+                   __func__, handler, idx);
+    }
+
+    return rc;
+}
+
+int32_t mm_camera_poll_thread_launch(mm_camera_poll_thread_t * poll_cb,
+                                     mm_camera_poll_thread_type_t poll_type)
+{
+    int32_t rc = 0;
+    poll_cb->poll_type = poll_type;
+
+    poll_cb->pfds[0] = 0;
+    poll_cb->pfds[1] = 0;
+    rc = pipe(poll_cb->pfds);
+    if(rc < 0) {
+        CDBG_ERROR("%s: pipe open rc=%d\n", __func__, rc);
+        return -1;
+    }
+
+    poll_cb->timeoutms = -1;  /* Infinite seconds */
+
+    CDBG("%s: poll_type = %d, read fd = %d, write fd = %d timeout = %d",
+        __func__, poll_cb->poll_type,
+        poll_cb->pfds[0], poll_cb->pfds[1],poll_cb->timeoutms);
+
+    pthread_mutex_init(&poll_cb->mutex, NULL);
+    pthread_cond_init(&poll_cb->cond_v, NULL);
+
+    /* launch the thread */
+    pthread_mutex_lock(&poll_cb->mutex);
+    poll_cb->status = 0;
+    pthread_create(&poll_cb->pid, NULL, mm_camera_poll_thread, (void *)poll_cb);
+    if(!poll_cb->status) {
+        pthread_cond_wait(&poll_cb->cond_v, &poll_cb->mutex);
+    }
+    pthread_mutex_unlock(&poll_cb->mutex);
+    CDBG("%s: End",__func__);
+    return rc;
+}
+
+int32_t mm_camera_poll_thread_release(mm_camera_poll_thread_t *poll_cb)
+{
+    int32_t rc = 0;
+    if(MM_CAMERA_POLL_TASK_STATE_STOPPED == poll_cb->state) {
+        CDBG_ERROR("%s: err, poll thread is not running.\n", __func__);
+        return rc;
+    }
+
+    /* send exit signal to poll thread */
+    mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_EXIT);
+    /* wait until poll thread exits */
+    if (pthread_join(poll_cb->pid, NULL) != 0) {
+        CDBG_ERROR("%s: pthread dead already\n", __func__);
+    }
+
+    /* close pipe */
+    if(poll_cb->pfds[0]) {
+        close(poll_cb->pfds[0]);
+    }
+    if(poll_cb->pfds[1]) {
+        close(poll_cb->pfds[1]);
+    }
+
+    pthread_mutex_destroy(&poll_cb->mutex);
+    pthread_cond_destroy(&poll_cb->cond_v);
+    memset(poll_cb, 0, sizeof(mm_camera_poll_thread_t));
+    return rc;
+}
diff --git a/camera/QCamera/stack/mm-camera-test/Android.mk b/camera/QCamera/stack/mm-camera-test/Android.mk
new file mode 100755
index 0000000..1228680
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/Android.mk
@@ -0,0 +1,63 @@
+LOCAL_PATH:=$(call my-dir)
+USE_BIONIC_HEADER:=true
+include $(CLEAR_VARS)
+
+ifeq ($(call is-board-platform,msm8960),true)
+LOCAL_CFLAGS:= \
+        -DAMSS_VERSION=$(AMSS_VERSION) \
+        $(mmcamera_debug_defines) \
+        $(mmcamera_debug_cflags) \
+        $(USE_SERVER_TREE) \
+        -include camera_defs_i.h
+
+ifneq ($(strip $(USE_BIONIC_HEADER)),true)
+LOCAL_CFLAGS += -include $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/linux/ion.h
+endif
+
+ifeq ($(strip $(TARGET_USES_ION)),true)
+LOCAL_CFLAGS += -DUSE_ION
+endif
+
+LOCAL_CFLAGS += -D_ANDROID_
+
+LOCAL_SRC_FILES:= \
+        src/mm_qcamera_main_menu.c \
+        src/mm_qcamera_display.c \
+        src/mm_qcamera_app.c \
+        src/mm_qcamera_snapshot.c \
+        src/mm_qcamera_video.c \
+        src/mm_qcamera_preview.c \
+        src/mm_qcamera_rdi.c \
+        src/mm_qcamera_unit_test.c \
+        src/mm_qcamera_dual_test.c
+
+LOCAL_C_INCLUDES:=$(LOCAL_PATH)/inc
+LOCAL_C_INCLUDES+= \
+        $(TARGET_OUT_INTERMEDIATES)/include/mm-camera-interface_badger \
+	      $(TARGET_OUT_INTERMEDIATES)/include/mm-still/jpeg \
+        $(TARGET_OUT_INTERMEDIATES)/include/mm-camera \
+        $(LOCAL_PATH)/../mm-camera-interface/inc \
+        $(LOCAL_PATH)/../common \
+        $(LOCAL_PATH)/../../../ \
+
+ifneq ($(strip $(USE_BIONIC_HEADER)),true)
+LOCAL_C_INCLUDES+= $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/media
+LOCAL_C_INCLUDES+= $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
+
+ifeq ($(call is-board-platform,msm8960),true)
+LOCAL_CFLAGS += -DCAMERA_ION_HEAP_ID=ION_CP_MM_HEAP_ID
+else
+LOCAL_CFLAGS += -DCAMERA_ION_HEAP_ID=ION_CAMERA_HEAP_ID
+endif
+
+LOCAL_SHARED_LIBRARIES:= \
+         libcutils libdl
+
+LOCAL_MODULE:= mm-qcamera-app-badger
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
+endif
diff --git a/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_app.h b/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_app.h
new file mode 100755
index 0000000..524a4b5
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_app.h
@@ -0,0 +1,212 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MM_QCAMERA_APP_H__
+#define __MM_QCAMERA_APP_H__
+
+#define DISABLE_JPEG_ENCODING
+
+#include "camera.h"
+#include "mm_qcamera_main_menu.h"
+#include "mm_camera_interface.h"
+#ifndef DISABLE_JPEG_ENCODING
+#include "mm_omx_jpeg_encoder.h"
+#endif
+
+#define MM_APP_MAX_DUMP_FRAME_NUM 1000
+
+#define PREVIEW_BUF_NUM 7
+#define VIDEO_BUF_NUM 7
+
+typedef enum {
+    MM_CAMERA_OK,
+    MM_CAMERA_E_GENERAL,
+    MM_CAMERA_E_NO_MEMORY,
+    MM_CAMERA_E_NOT_SUPPORTED,
+    MM_CAMERA_E_INVALID_INPUT,
+    MM_CAMERA_E_INVALID_OPERATION, /* 5 */
+    MM_CAMERA_E_ENCODE,
+    MM_CAMERA_E_BUFFER_REG,
+    MM_CAMERA_E_PMEM_ALLOC,
+    MM_CAMERA_E_CAPTURE_FAILED,
+    MM_CAMERA_E_CAPTURE_TIMEOUT, /* 10 */
+}mm_camera_status_type_t;
+
+typedef struct {
+    int num;
+    uint32_t frame_len;
+    struct msm_frame frame[MM_CAMERA_MAX_NUM_FRAMES];
+
+    uint32_t fd[MM_CAMERA_MAX_NUM_FRAMES];
+    int main_ion_fd[MM_CAMERA_MAX_NUM_FRAMES];
+    struct ion_allocation_data alloc[MM_CAMERA_MAX_NUM_FRAMES];
+    struct ion_fd_data ion_info_fd[MM_CAMERA_MAX_NUM_FRAMES];
+    int reg[MM_CAMERA_MAX_NUM_FRAMES];
+} mm_camear_app_buf_t;
+
+typedef struct {
+    int id;
+    mm_camera_stream_config_t str_config;
+}mm_camear_stream_t;
+
+typedef enum{
+    CAMERA_STATE_OPEN,
+    CAMERA_STATE_PREVIEW,
+    CAMERA_STATE_RECORD,
+    CAMERA_STATE_SNAPSHOT,
+    CAMERA_STATE_RDI
+}camera_state;
+
+typedef enum{
+    CAMERA_MODE,
+    RECORDER_MODE,
+    ZSL_MODE,
+    RDI_MODE
+}camera_mode;
+
+typedef struct {
+    mm_camera_vtbl_t *cam;
+    mm_camear_mem_vtbl_t *mem_cam;
+    int8_t my_id;
+    //mm_camera_op_mode_type_t op_mode;
+    uint32_t ch_id;
+    cam_ctrl_dimension_t dim;
+    int open_flag;
+    int ionfd;
+    mm_camear_stream_t stream[8];
+    camera_mode cam_mode;
+    camera_state cam_state;
+    int fullSizeSnapshot;
+} mm_camera_app_obj_t;
+
+typedef struct {
+  void *ptr;
+  mm_camera_info_t *(*mm_camera_query) (uint8_t *num_cameras);
+  mm_camera_vtbl_t *(*mm_camera_open) (uint8_t camera_idx,
+                               mm_camear_mem_vtbl_t *mem_vtbl);
+
+  /*uint8_t *(*mm_camera_do_mmap)(uint32_t size, int *pmemFd);
+  int (*mm_camera_do_munmap)(int pmem_fd, void *addr, size_t size);
+
+   uint8_t *(*mm_camera_do_mmap_ion)(int ion_fd, struct ion_allocation_data *alloc,
+             struct ion_fd_data *ion_info_fd, int *mapFd);
+  int (*mm_camera_do_munmap_ion) (int ion_fd, struct ion_fd_data *ion_info_fd,
+                   void *addr, size_t size);*/
+#if 0
+  uint32_t (*mm_camera_get_msm_frame_len)(cam_format_t fmt_type,
+                                            camera_mode_t mode,
+                                            int width,
+                                            int height,
+                                            int image_type,
+                                            uint8_t *num_planes,
+                                            uint32_t planes[]);
+#ifndef DISABLE_JPEG_ENCODING
+  void (*set_callbacks)(jpegfragment_callback_t fragcallback,
+    jpeg_callback_t eventcallback, void* userdata, void* output_buffer,
+    int * outBufferSize);
+  int8_t (*omxJpegOpen)(void);
+  void (*omxJpegClose)(void);
+  int8_t (*omxJpegStart)(void);
+  int8_t (*omxJpegEncode)(omx_jpeg_encode_params *encode_params);
+  void (*omxJpegFinish)(void);
+  int8_t (*mm_jpeg_encoder_setMainImageQuality)(uint32_t quality);
+#endif
+#endif
+} hal_interface_lib_t;
+
+typedef struct {
+    //mm_camera_vtbl_t *cam;
+    uint8_t num_cameras;
+    mm_camera_app_obj_t *obj[2];
+    mm_camera_info_t *cam_info;
+    int use_overlay;
+    int use_user_ptr;
+    hal_interface_lib_t hal_lib;
+    int cam_open;
+    int run_sanity;
+} mm_camera_app_t;
+
+extern mm_camera_app_t my_cam_app;
+extern USER_INPUT_DISPLAY_T input_display;
+extern int mm_app_dl_render(int frame_fd, struct crop_info * cropinfo);
+extern mm_camera_app_obj_t *mm_app_get_cam_obj(int8_t cam_id);
+extern int mm_app_load_hal();
+extern int mm_app_init();
+extern void mm_app_user_ptr(int use_user_ptr);
+extern int mm_app_open_ch(int cam_id);
+extern void mm_app_close_ch(int cam_id, int ch_type);
+extern int mm_app_set_dim(int8_t cam_id, cam_ctrl_dimension_t *dim);
+extern int mm_app_run_unit_test();
+extern int mm_app_unit_test_entry(mm_camera_app_t *cam_app);
+extern int mm_app_unit_test();
+extern void mm_app_set_dim_def(cam_ctrl_dimension_t *dim);
+extern int mm_app_open(uint8_t camera_idx);
+extern int mm_app_close(int8_t cam_id);
+extern int startPreview(int cam_id);
+extern int mm_app_stop_preview(int cam_id);
+extern int mm_app_stop_video(int cam_id);
+extern int startRecording(int cam_id);
+extern int stopRecording(int cam_id);
+extern int mm_app_take_picture(int cam_id);
+extern int mm_app_take_raw_picture(int cam_id);
+extern int mm_app_get_dim(int8_t cam_id, cam_ctrl_dimension_t *dim);
+extern int mm_app_streamon_preview(int cam_id);
+extern int mm_app_set_snapshot_fmt(int cam_id,mm_camera_image_fmt_t *fmt);
+
+extern int mm_app_dual_test_entry(mm_camera_app_t *cam_app);
+extern int mm_app_dual_test();
+
+extern int mm_camera_app_wait();
+extern void mm_camera_app_done();
+
+extern int mm_stream_initbuf(uint32_t camera_handle,
+                             uint32_t ch_id, uint32_t stream_id,
+                             void *user_data,
+                             mm_camera_frame_len_offset *frame_offset_info,
+                             uint8_t num_bufs,
+                             uint8_t *initial_reg_flag,
+                             mm_camera_buf_def_t *bufs);
+
+extern int mm_stream_deinitbuf(uint32_t camera_handle,
+                             uint32_t ch_id, uint32_t stream_id,
+                             void *user_data, uint8_t num_bufs,
+                             mm_camera_buf_def_t *bufs);
+
+extern void mm_app_preview_notify_cb(mm_camera_super_buf_t *bufs,
+                                     void *user_data);
+#endif /* __MM_QCAMERA_APP_H__ */
+
+
+
+
+
+
+
+
+
diff --git a/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_display_dimensions.h b/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_display_dimensions.h
new file mode 100755
index 0000000..231fecc
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_display_dimensions.h
@@ -0,0 +1,43 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __MM_QCAMERA_DISPLAY_DIMENSIONS__
+#define __MM_QCAMERA_DISPLAY_DIMENSIONS__
+
+#define PREVIEW_WIDTH     800
+#define PREVIEW_HEIGHT    480
+#define DISPLAY_WIDTH     800
+#define DISPLAY_HEIGHT    480
+#define THUMBNAIL_WIDTH   192
+#define THUMBNAIL_HEIGHT  144
+#define PICTURE_WIDTH     1280
+#define PICTURE_HEIGHT    960
+
+#endif /* __MM_QCAMERA_DISPLAY_DIMENSIONS__ */
diff --git a/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_main_menu.h b/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_main_menu.h
new file mode 100755
index 0000000..076b2f6
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_main_menu.h
@@ -0,0 +1,465 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MM_QCAMERA_MAIN_MENU_H__
+#define __MM_QCAMERA_MAIN_MENU_H__
+
+#include "camera.h"
+#include "mm_camera_interface.h"
+
+
+#define VIDEO_BUFFER_SIZE       (PREVIEW_WIDTH * PREVIEW_HEIGHT * 3/2)
+#define THUMBNAIL_BUFFER_SIZE   (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
+#define SNAPSHOT_BUFFER_SIZE    (PICTURE_WIDTH * PICTURE_HEIGHT * 3/2)
+
+/*===========================================================================
+ * Macro
+ *===========================================================================*/
+#define PREVIEW_FRAMES_NUM    4
+#define VIDEO_FRAMES_NUM      4
+#define THUMBNAIL_FRAMES_NUM  1
+#define SNAPSHOT_FRAMES_NUM   1
+#define MAX_NUM_FORMAT        32
+
+typedef enum
+{
+  STOP_CAMERA = 1,
+  PREVIEW_VIDEO_RESOLUTION = 2,
+  TAKE_YUV_SNAPSHOT = 3,
+  TAKE_RAW_SNAPSHOT = 4,
+  TAKE_ZSL_SNAPSHOT = 5,
+  //TAKE_LIVE_SNAPSHOT = 17,
+  START_RECORDING = 6,
+  START_RDI = 7,
+  STOP_RDI = 8,
+  SWITCH_CAMERA = 9,
+  //STOP_RECORDING = 7,
+  //SET_WHITE_BALANCE = 3,
+  //SET_EXP_METERING = 4,
+  //GET_CTRL_VALUE = 5,
+  //TOGGLE_AFR = 6,
+  //SET_ISO = 7,
+  //BRIGHTNESS_GOTO_SUBMENU = 8,
+  //CONTRAST_GOTO_SUBMENU = 9,
+  //EV_GOTO_SUBMENU = 10,
+  //SATURATION_GOTO_SUBMENU = 11,
+  //SET_ZOOM = 12,
+  //SET_SHARPNESS = 13,
+} Camera_main_menu_t;
+
+typedef enum
+{
+  ACTION_NO_ACTION,
+  ACTION_STOP_CAMERA,
+  ACTION_PREVIEW_VIDEO_RESOLUTION,
+  ACTION_TAKE_YUV_SNAPSHOT,
+  ACTION_TAKE_RAW_SNAPSHOT,
+  ACTION_TAKE_ZSL_SNAPSHOT,
+  ACTION_TAKE_LIVE_SNAPSHOT,
+  ACTION_START_RECORDING,
+  ACTION_STOP_RECORDING,
+  ACTION_START_RDI,
+  ACTION_STOP_RDI,
+  ACTION_SWITCH_CAMERA,
+  ACTION_SET_WHITE_BALANCE,
+  ACTION_SET_EXP_METERING,
+  ACTION_GET_CTRL_VALUE,
+  ACTION_TOGGLE_AFR,
+  ACTION_SET_ISO,
+  ACTION_BRIGHTNESS_INCREASE,
+  ACTION_BRIGHTNESS_DECREASE,
+  ACTION_CONTRAST_INCREASE,
+  ACTION_CONTRAST_DECREASE,
+  ACTION_EV_INCREASE,
+  ACTION_EV_DECREASE,
+  ACTION_SATURATION_INCREASE,
+  ACTION_SATURATION_DECREASE,
+  ACTION_SET_ZOOM,
+  ACTION_SHARPNESS_INCREASE,
+  ACTION_SHARPNESS_DECREASE,
+} camera_action_t;
+
+#define INVALID_KEY_PRESS 0
+#define BASE_OFFSET  ('Z' - 'A' + 1)
+#define BASE_OFFSET_NUM  ('Z' - 'A' + 2)
+#define PAD_TO_WORD(a)  (((a)+3)&~3)
+
+
+#define SQCIF_WIDTH     128
+#define SQCIF_HEIGHT     96
+#define QCIF_WIDTH      176
+#define QCIF_HEIGHT     144
+#define QVGA_WIDTH      320
+#define QVGA_HEIGHT     240
+#define HD_THUMBNAIL_WIDTH      256
+#define HD_THUMBNAIL_HEIGHT     144
+#define CIF_WIDTH       352
+#define CIF_HEIGHT      288
+#define VGA_WIDTH       640
+#define VGA_HEIGHT      480
+#define WVGA_WIDTH      800
+#define WVGA_HEIGHT     480
+
+#define MP1_WIDTH      1280
+#define MP1_HEIGHT      960
+#define MP2_WIDTH      1600
+#define MP2_HEIGHT     1200
+#define MP3_WIDTH      2048
+#define MP3_HEIGHT     1536
+#define MP5_WIDTH      2592
+#define MP5_HEIGHT     1944
+
+#define SVGA_WIDTH      800
+#define SVGA_HEIGHT     600
+#define XGA_WIDTH      1024
+#define XGA_HEIGHT      768
+#define HD720_WIDTH    1280
+#define HD720_HEIGHT    720
+#define WXGA_WIDTH     1280
+#define WXGA_HEIGHT     768
+#define HD1080_WIDTH   1920
+#define HD1080_HEIGHT  1080
+
+typedef enum
+{
+  RESOLUTION_MIN         = 1,
+  SQCIF                  = RESOLUTION_MIN,
+  QCIF                   = 2,
+  QVGA                   = 3,
+  CIF                    = 4,
+  VGA                    = 5,
+  WVGA                   = 6,
+  SVGA                   = 7,
+  XGA                    = 8,
+  HD720                  = 9,
+  RESOLUTION_PREVIEW_VIDEO_MAX = HD720,
+  WXGA                   = 10,
+  MP1                    = 11,
+  MP2                    = 12,
+  HD1080                 = 13,
+  MP3                    = 14,
+  MP5                    = 15,
+  RESOLUTION_MAX         = MP5,
+} Camera_Resolution;
+
+
+typedef enum {
+    WHITE_BALANCE_STATE = 1,
+    WHITE_BALANCE_TEMPERATURE = 2,
+    BRIGHTNESS_CTRL = 3,
+    EV = 4,
+    CONTRAST_CTRL = 5,
+    SATURATION_CTRL = 6,
+    SHARPNESS_CTRL = 7,
+} Get_Ctrl_modes;
+
+typedef enum {
+  WHITE_BALANCE_AUTO         = 1,
+  WHITE_BALANCE_OFF          = 2,
+  WHITE_BALANCE_DAYLIGHT     = 3,
+  WHITE_BALANCE_INCANDESCENT = 4,
+  WHITE_BALANCE_FLUORESCENT  = 5,
+} White_Balance_modes;
+
+typedef enum {
+	EXP_METERING_FRAME_AVERAGE   = 1,
+	EXP_METERING_CENTER_WEIGHTED = 2,
+  EXP_METERING_SPOT_METERING   = 3,
+} Exp_Metering_modes;
+
+typedef enum {
+  ISO_AUTO = 1,
+  ISO_DEBLUR = 2,
+  ISO_100 = 3,
+  ISO_200 = 4,
+  ISO_400 = 5,
+  ISO_800 = 6,
+  ISO_1600 = 7,
+} ISO_modes;
+
+typedef enum
+{
+  MENU_ID_MAIN,
+  MENU_ID_PREVIEWVIDEORESOLUTIONCHANGE,
+  MENU_ID_WHITEBALANCECHANGE,
+  MENU_ID_EXPMETERINGCHANGE,
+  MENU_ID_GET_CTRL_VALUE,
+  MENU_ID_TOGGLEAFR,
+  MENU_ID_ISOCHANGE,
+  MENU_ID_BRIGHTNESSCHANGE,
+  MENU_ID_CONTRASTCHANGE,
+  MENU_ID_EVCHANGE,
+  MENU_ID_SATURATIONCHANGE,
+  MENU_ID_ZOOMCHANGE,
+  MENU_ID_SHARPNESSCHANGE,
+  MENU_ID_SWITCHCAMERA,
+  MENU_ID_RECORD,
+  MENU_ID_INVALID,
+} menu_id_change_t;
+
+typedef enum
+{
+  INCREASE_ZOOM      = 1,
+  DECREASE_ZOOM      = 2,
+  INCREASE_STEP_ZOOM = 3,
+  DECREASE_STEP_ZOOM = 4,
+} Camera_Zoom;
+
+typedef enum
+{
+  INC_CONTRAST = 1,
+  DEC_CONTRAST = 2,
+} Camera_Contrast_changes;
+
+typedef enum
+{
+  INC_BRIGHTNESS = 1,
+  DEC_BRIGHTNESS = 2,
+} Camera_Brightness_changes;
+
+typedef enum
+{
+  INCREASE_EV = 1,
+  DECREASE_EV = 2,
+} Camera_EV_changes;
+
+typedef enum {
+  INC_SATURATION = 1,
+  DEC_SATURATION = 2,
+} Camera_Saturation_changes;
+
+typedef enum
+{
+  INC_ISO = 1,
+  DEC_ISO = 2,
+} Camera_ISO_changes;
+
+typedef enum
+{
+  INC_SHARPNESS = 1,
+  DEC_SHARPNESS = 2,
+} Camera_Sharpness_changes;
+
+typedef enum {
+  ZOOM_IN = 1,
+  ZOOM_OUT = 2,
+} Zoom_direction;
+
+typedef enum
+{
+  LIVE_SNAPSHOT_MENU = 1,
+  STOP_RECORDING_MENU = 2,
+} Record_changes;
+
+typedef struct{
+    Camera_main_menu_t main_menu;
+    char * menu_name;
+} CAMERA_MAIN_MENU_TBL_T;
+
+typedef struct{
+    Camera_Resolution cs_id;
+    uint16_t width;
+    uint16_t  height;
+    char * name;
+    char * str_name;
+} PREVIEW_DIMENSION_TBL_T;
+
+typedef struct {
+  White_Balance_modes wb_id;
+  char * wb_name;
+} WHITE_BALANCE_TBL_T;
+
+typedef struct {
+  int cam_id;
+  char * cam_name;
+} CAMERA_TBL_T;
+
+typedef struct {
+  int act_id;
+  char * act_name;
+} RECORD_TBL_T;
+
+typedef struct {
+  Get_Ctrl_modes get_ctrl_id;
+  char * get_ctrl_name;
+} GET_CTRL_TBL_T;
+
+typedef struct{
+  Exp_Metering_modes exp_metering_id;
+  char * exp_metering_name;
+} EXP_METERING_TBL_T;
+
+typedef struct {
+  ISO_modes iso_modes;
+  char *iso_modes_name;
+} ISO_TBL_T;
+
+typedef struct {
+  Zoom_direction zoom_direction;
+  char * zoom_direction_name;
+} ZOOM_TBL_T;
+
+typedef struct {
+  Camera_Sharpness_changes sharpness_change;
+  char *sharpness_change_name;
+} SHARPNESS_TBL_T;
+
+typedef struct {
+  Camera_Brightness_changes bc_id;
+  char * brightness_name;
+} CAMERA_BRIGHTNESS_TBL_T;
+
+typedef struct {
+  Camera_Contrast_changes cc_id;
+  char * contrast_name;
+} CAMERA_CONTRST_TBL_T;
+
+typedef struct {
+  Camera_EV_changes ec_id;
+  char * EV_name;
+} CAMERA_EV_TBL_T;
+
+typedef struct {
+  Camera_Saturation_changes sc_id;
+  char * saturation_name;
+} CAMERA_SATURATION_TBL_T;
+
+typedef struct {
+  Camera_Sharpness_changes bc_id;
+  char * sharpness_name;
+} CAMERA_SHARPNESS_TBL_T;
+
+
+typedef struct {
+  void    *frameThread;
+  int8_t (*setDimension)(int , void *);
+  int8_t (*setDefaultParams)(int );
+  int8_t (*registerPreviewBuf)(int , void *, uint32_t, struct msm_frame *, int8_t );
+  int8_t (*unregisterPreviewBuf)(int , void *, uint32_t, int , unsigned char *);
+  int8_t (*registerVideoBuf)(int , void *, uint32_t, struct msm_frame *, int8_t );
+  int8_t (*unregisterVideoBuf)(int , void *, uint32_t, int , unsigned char *);
+  int8_t (*startPreview)(int );
+  int8_t (*stopPreview)(int );
+  int8_t (*startVideo)(int );
+  int8_t (*stopVideo)(int );
+  int8_t (*startRecording)(int );
+  int8_t (*stopRecording)(int );
+  int8_t (*startSnapshot)(int );
+  int8_t (*startRawSnapshot)(int );
+
+  int8_t (*registerSnapshotBuf)(int , void *, int , int ,
+    unsigned char *, unsigned char *);
+
+  int8_t (*registerRawSnapshotBuf)(int , void *, int , unsigned char *);
+
+  int8_t (*unregisterSnapshotBuf)(int , void *, int , int ,
+    unsigned char *, unsigned char *);
+
+  int8_t (*unregisterRawSnapshotBuf)(int , void *, int , unsigned char *);
+  int8_t (*getPicture)(int fd, struct crop_info *cropInfo );
+  int8_t (*stopSnapshot)(int );
+  int8_t (*jpegEncode)(const char *path, void *, int, int , unsigned char *,
+    unsigned char *, void *, camera_encoding_rotate_t rotate);
+  int8_t (*setZoom)(int , void *);
+  int8_t (*getMaxZoom)(int fd, void *pZm);
+  int8_t (*setSpecialEffect)(int, int effect);
+  int8_t (*setBrightness)(int, int);
+  int8_t (*setContrast)(int, int);
+  int8_t (*setSaturation)(int, int);
+  int8_t (*setEV)(int , int );
+  int8_t (*setAntiBanding)(int , int32_t antibanding);
+  int8_t (*setWhiteBalance)(int , int32_t );
+  int8_t (*setAecMode)(int , camera_auto_exposure_mode_type );
+  int8_t (*setIso)(int , camera_iso_mode_type );
+  int8_t (*setSharpness)(int , int );
+  int8_t (*setAutoFocus)(int , isp3a_af_mode_t, cam_af_ctrl_t *);
+  int8_t (*sethjr) (int fd, int8_t hjr_status);
+  int8_t (*setLensShading) (int fd, int8_t rolloff_status);
+  int8_t (*setLedMode) (int fd, led_mode_t led_mode);
+  int8_t (*getSharpness_AF) (int fd, int32_t *sharpness);
+  int8_t (*setMotionIso) (int fd, motion_iso_t motion_iso);
+  int8_t (*setHue) (int fd, int32_t hue);
+  int8_t (*cancelAF) (int fd);
+  int8_t (*getAfStep) (int fd, int32_t *afStep);
+  int8_t (*setAfStep) (int fd, int32_t afStep);
+  int8_t (*enableAFD) (int fd);
+  int8_t (*prepareSnapshot) (int fd);
+  int8_t (*setFpsMode) (int fd, fps_mode_t fps_mode);
+  int8_t (*setFps) (int fd, uint16_t fps);
+  int8_t (*setAFFocusRect) (int fd, cam_af_focusrect_t af_focus_rect);
+} interface_ctrl_t;
+
+int8_t native_interface_init(interface_ctrl_t *intrfcCtrl, int *camfd);
+int8_t v4l2_interface_init(interface_ctrl_t *intrfcCtrl, int *videofd);
+
+int set_zoom (int zoom_action_param);
+int set_hjr (void);
+int LensShading (void);
+int decrease_contrast (void);
+int increase_contrast (void);
+int decrease_saturation (void);
+int increase_saturation (void);
+int decrease_brightness (void);
+int increase_brightness (void);
+int decrease_EV (void);
+int increase_EV (void);
+int set_iso (int iso_action_param);
+int decrease_sharpness (void);
+int increase_sharpness (void);
+int SpecialEffect (void);
+int set_exp_metering (int exp_metering_action_param);
+int LED_mode_change (void);
+int set_sharpness_AF (void);
+int set_auto_focus (void);
+int set_antibanding (void);
+int set_whitebalance (int wb_action_param);
+int print_current_menu ();
+int set_MotionIso (void);
+int start_preview (void);
+int stop_preview (void);
+static int start_video (void);
+static int stop_video (void);
+int start_recording (void);
+int stop_recording (void);
+int snapshot_resolution (int);
+int preview_video_resolution (int);
+int system_init(void);
+int system_destroy(void);
+int toggle_hue(void);
+int cancel_af(void);
+int get_af_step();
+int set_af_step();
+int enable_afd();
+int prepare_snapshot();
+int set_fps_mode(void);
+int get_ctrl_value (int ctrl_value_mode_param);
+int toggle_afr ();
+int take_yuv_snapshot(int cam_id);
+int take_raw_snapshot();
+#endif /* __MM_QCAMERA_MAIN_MENU_H__ */
diff --git a/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_unit_test.h b/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_unit_test.h
new file mode 100755
index 0000000..2a95120
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/inc/mm_qcamera_unit_test.h
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MM_QCAMERA_APP_UNIT_TEST_H__
+#define __MM_QCAMERA_APP_UNIT_TEST_H__
+
+#include "camera.h"
+#include "mm_qcamera_main_menu.h"
+#include "mm_camera_interface.h"
+#include "mm_qcamera_app.h"
+
+typedef int (*mm_app_test_t) (mm_camera_app_t *cam_apps);
+typedef struct {
+    mm_app_test_t f;
+    int r;
+} mm_app_tc_t;
+
+#endif
+
+/* __MM_QCAMERA_APP_UNIT_TEST_H__ */
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_app.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_app.c
new file mode 100755
index 0000000..6f89fcc
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_app.c
@@ -0,0 +1,405 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include "mm_camera_dbg.h"
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <dlfcn.h>
+#include "mm_qcamera_main_menu.h"
+#include "mm_qcamera_app.h"
+
+
+mm_camera_app_t my_cam_app;
+
+static pthread_mutex_t app_mutex;
+static int thread_status = 0;
+static pthread_cond_t app_cond_v;
+
+#define MM_QCAMERA_APP_WAIT_TIME 1000000000
+
+int mm_camera_app_timedwait()
+{
+    int rc = 0;
+    pthread_mutex_lock(&app_mutex);
+    if(FALSE == thread_status) {
+        struct timespec tw;
+        memset(&tw, 0, sizeof tw);
+        tw.tv_sec = 0;
+        tw.tv_nsec = time(0) + MM_QCAMERA_APP_WAIT_TIME;
+
+        //pthread_cond_wait(&app_cond_v, &app_mutex);
+        rc = pthread_cond_timedwait(&app_cond_v, &app_mutex,&tw);
+        thread_status = FALSE;
+    }
+    pthread_mutex_unlock(&app_mutex);
+    return rc;
+}
+
+int mm_camera_app_wait()
+{
+    int rc = 0;
+    pthread_mutex_lock(&app_mutex);
+    if(FALSE == thread_status){
+        pthread_cond_wait(&app_cond_v, &app_mutex);
+        thread_status = FALSE;
+    }
+    pthread_mutex_unlock(&app_mutex);
+    return rc;
+}
+
+void mm_camera_app_done()
+{
+  pthread_mutex_lock(&app_mutex);
+  thread_status = TRUE;
+  pthread_cond_signal(&app_cond_v);
+  pthread_mutex_unlock(&app_mutex);
+}
+
+
+mm_camera_app_obj_t *mm_app_get_cam_obj(int8_t cam_id)
+{
+    mm_camera_app_obj_t *temp = my_cam_app.obj[cam_id];
+    return temp;
+}
+
+void mm_app_user_ptr(int use_user_ptr)
+{
+    my_cam_app.use_user_ptr = use_user_ptr;
+}
+
+void mm_app_set_dim_def(cam_ctrl_dimension_t *dim)
+{
+    dim->display_width = WVGA_WIDTH;
+    dim->display_height = WVGA_HEIGHT;
+    input_display.user_input_display_width = dim->display_width;
+    input_display.user_input_display_height = dim->display_height;
+    dim->video_width = WVGA_WIDTH;
+    dim->video_width = CEILING32(dim->video_width);
+    dim->video_height = WVGA_HEIGHT;
+    dim->orig_video_width = dim->video_width;
+    dim->orig_video_height = dim->video_height;
+    dim->picture_width = MP1_WIDTH;
+    dim->picture_height = MP1_HEIGHT;
+    dim->orig_picture_dx = dim->picture_width;
+    dim->orig_picture_dy = dim->picture_height;
+    dim->ui_thumbnail_height = QVGA_HEIGHT;
+    dim->ui_thumbnail_width = QVGA_WIDTH;
+    dim->thumbnail_height = dim->ui_thumbnail_height;
+    dim->thumbnail_width = dim->ui_thumbnail_width;
+    dim->orig_picture_width = dim->picture_width;
+    dim->orig_picture_height = dim->picture_height;
+    dim->orig_thumb_width = dim->thumbnail_width;
+    dim->orig_thumb_height = dim->thumbnail_height;
+    dim->raw_picture_height = MP1_HEIGHT;
+    dim->raw_picture_width = MP1_WIDTH;
+    dim->hjr_xtra_buff_for_bayer_filtering;
+    dim->prev_format = CAMERA_YUV_420_NV21;
+    dim->enc_format = CAMERA_YUV_420_NV12;
+    dim->thumb_format = CAMERA_YUV_420_NV21;
+    dim->main_img_format = CAMERA_YUV_420_NV21;
+    dim->prev_padding_format = CAMERA_PAD_TO_4K;
+    dim->display_luma_width = dim->display_width;
+    dim->display_luma_height = dim->display_height;
+    dim->display_chroma_width = dim->display_width;
+    dim->display_chroma_height = dim->display_height;
+    dim->video_luma_width = dim->orig_video_width;
+    dim->video_luma_height = dim->orig_video_height;
+    dim->video_chroma_width = dim->orig_video_width;
+    dim->video_chroma_height = dim->orig_video_height;
+    dim->thumbnail_luma_width = dim->thumbnail_width;
+    dim->thumbnail_luma_height = dim->thumbnail_height;
+    dim->thumbnail_chroma_width = dim->thumbnail_width;
+    dim->thumbnail_chroma_height = dim->thumbnail_height;
+    dim->main_img_luma_width = dim->picture_width;
+    dim->main_img_luma_height = dim->picture_height;
+    dim->main_img_chroma_width = dim->picture_width;
+    dim->main_img_chroma_height = dim->picture_height;
+}
+
+int mm_app_load_hal()
+{
+  memset(&my_cam_app, 0, sizeof(my_cam_app));
+  memset(&my_cam_app.hal_lib, 0, sizeof(hal_interface_lib_t));
+#if defined(_MSM7630_)
+   my_cam_app.hal_lib.ptr = dlopen("/usr/lib/hw/camera.msm7630.so", RTLD_LAZY);
+#elif defined(_MSM7627A_)
+   my_cam_app.hal_lib.ptr = dlopen("/usr/lib/hw/camera.msm7627A.so", RTLD_LAZY);
+#else
+  //my_cam_app.hal_lib.ptr = dlopen("hw/camera.msm8960.so", RTLD_NOW);
+   my_cam_app.hal_lib.ptr = dlopen("libmmcamera_interface_badger.so", RTLD_NOW);
+#endif
+  if (!my_cam_app.hal_lib.ptr) {
+    CDBG_ERROR("%s Error opening HAL library %s\n", __func__, dlerror());
+    return -1;
+  }
+  *(void **)&(my_cam_app.hal_lib.mm_camera_query) =
+        dlsym(my_cam_app.hal_lib.ptr,
+              "camera_query");
+  *(void **)&(my_cam_app.hal_lib.mm_camera_open) =
+        dlsym(my_cam_app.hal_lib.ptr,
+              "camera_open");
+  return 0;
+}
+
+int mm_app_init()
+{
+    int rc = MM_CAMERA_OK;
+    CDBG("%s:BEGIN\n", __func__);
+    my_cam_app.cam_info =  (mm_camera_info_t *)my_cam_app.hal_lib.mm_camera_query(&my_cam_app.num_cameras);
+    if(my_cam_app.cam_info == NULL) {
+        CDBG_ERROR("%s: Failed to query camera\n", __func__);
+        rc = -1;
+    }
+    CDBG("%s:END, num_cameras = %d\n", __func__, my_cam_app.num_cameras);
+    return rc;
+}
+
+static void notify_evt_cb(uint32_t camera_handle,
+                         mm_camera_event_t *evt,void *user_data)
+{
+    CDBG("%s:E evt = %d",__func__,evt->event_type);
+
+    switch(evt->event_type)
+    {
+        case MM_CAMERA_EVT_TYPE_CH:
+        break;
+        case MM_CAMERA_EVT_TYPE_CTRL:
+            break;
+        case MM_CAMERA_EVT_TYPE_STATS:
+            break;
+        case MM_CAMERA_EVT_TYPE_INFO:
+        break;
+        default:
+            break;
+    }
+    CDBG("%s:X",__func__);
+}
+
+int mm_app_open(uint8_t cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = NULL;
+    int i;
+    mm_camera_event_type_t evt;
+
+    pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s:BEGIN\n", __func__);
+    if(pme != NULL) {
+        CDBG("%s:cam already open.nop\n",__func__);
+        goto end;
+    }
+    my_cam_app.cam_open = cam_id;
+    my_cam_app.obj[cam_id] = (mm_camera_app_obj_t *)malloc(sizeof(mm_camera_app_obj_t));
+    pme = my_cam_app.obj[cam_id];
+
+    pme->mem_cam = (mm_camear_mem_vtbl_t *)malloc(sizeof(mm_camear_mem_vtbl_t));
+    memset(pme->mem_cam,0,sizeof(mm_camear_mem_vtbl_t));
+    pme->mem_cam->user_data = pme;
+
+    pme->cam = my_cam_app.hal_lib.mm_camera_open(cam_id,pme->mem_cam);
+    if(pme->cam == NULL) {
+        CDBG("%s:dev open error=%d\n", __func__, rc);
+        memset(pme,0, sizeof(pme));
+        return -1;
+    }
+    CDBG("Open Camera id = %d handle = %d",cam_id,pme->cam->camera_handle);
+
+    pme->ch_id = cam_id;
+    pme->open_flag = TRUE;
+    mm_app_set_dim_def(&pme->dim);
+
+    for (i = 0; i < MM_CAMERA_EVT_TYPE_MAX; i++) {
+        evt = (mm_camera_event_type_t) i;
+        pme->cam->ops->register_event_notify(pme->cam->camera_handle,notify_evt_cb,pme,evt);
+    }
+    pme->cam_state = CAMERA_STATE_OPEN;
+    pme->cam_mode = CAMERA_MODE;
+    pme->fullSizeSnapshot = 0;
+
+    pme->ch_id = pme->cam->ops->ch_acquire(pme->cam->camera_handle);
+    CDBG("Channel Acquired Successfully %d",pme->ch_id);
+end:
+    CDBG("%s:END, rc=%d\n", __func__, rc); 
+    return rc;
+}
+
+int mm_app_close(int8_t cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s:BEGIN\n", __func__);
+    if(!pme->cam) {
+        CDBG("%s:cam already closed. nop\n",__func__);
+        goto end;
+    }
+
+    pme->cam->ops->ch_release(pme->cam->camera_handle,pme->ch_id);
+    pme->cam->ops->camera_close(pme->cam->camera_handle);
+    pme->open_flag = FALSE;
+    pme->cam = NULL;
+    pme->my_id = 0;
+    free(pme->mem_cam);
+    pme->mem_cam = NULL;
+    memset(&pme->dim, 0, sizeof(pme->dim));
+    memset(&pme->dim, 0, sizeof(pme->dim));
+
+    free(pme);
+    pme = NULL;
+    my_cam_app.obj[cam_id] = NULL;
+    
+end:
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+void switchRes(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    switch(pme->cam_state) {
+    case CAMERA_STATE_RECORD:
+    if(MM_CAMERA_OK != stopRecording(cam_id)){
+        CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
+        return -1;
+    }
+    case CAMERA_STATE_PREVIEW:
+        if(MM_CAMERA_OK !=  mm_app_stop_preview(cam_id)){
+            CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__);
+            return -1;
+        }
+        break;
+    case CAMERA_STATE_SNAPSHOT:
+    default:
+        break;
+    }
+}
+void switchCamera(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    if(my_cam_app.cam_open == cam_id){
+        return;
+    }
+
+    switch(pme->cam_state) {
+        case CAMERA_STATE_RECORD:
+            if(MM_CAMERA_OK != stopRecording(cam_id)){
+                CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
+                return -1;
+            }
+        case CAMERA_STATE_PREVIEW:
+            if(MM_CAMERA_OK !=  mm_app_stop_preview(cam_id)){
+                CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__);
+                return -1;
+            }
+            break;
+        case CAMERA_STATE_SNAPSHOT:
+        default:
+            break;
+    }
+
+    mm_app_close(my_cam_app.cam_open);
+    mm_app_open(cam_id);
+}
+
+int mm_app_set_dim(int8_t cam_id, cam_ctrl_dimension_t *dim)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s:BEGIN\n", __func__);
+
+    memcpy(&pme->dim, dim, sizeof(cam_ctrl_dimension_t));
+    if(MM_CAMERA_OK != (rc = pme->cam->ops->set_parm(
+            pme->cam->camera_handle,MM_CAMERA_PARM_DIMENSION, &pme->dim)))
+    {
+        CDBG_ERROR("%s: set dimension err=%d\n", __func__, rc);
+    }
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_get_dim(int8_t cam_id, cam_ctrl_dimension_t *dim)
+{
+    int rc = MM_CAMERA_OK;
+#if 0
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    CDBG("%s:BEGIN\n", __func__);
+    if(pme->open_flag != TRUE) {
+        CDBG("%s: dev not open yet\n", __func__);
+        rc = -MM_CAMERA_E_INVALID_OPERATION;
+        goto end;
+    }
+    /* now we only use the upper portion. TBD: needs to be fixed later */
+    //memcpy(&pme->dim, dim, sizeof(cam_ctrl_dimension_t));
+    if(MM_CAMERA_OK != (rc = pme->cam->cfg->get_parm(pme->cam,
+                                                    MM_CAMERA_PARM_DIMENSION, &pme->dim))) {
+        CDBG("%s: set dimension err=%d\n", __func__, rc);
+    }
+    CDBG("%s: raw_w=%d,raw_h=%d\n",
+            __func__, pme->dim.orig_picture_width, pme->dim.orig_picture_height);
+    if(dim)
+    memcpy(dim, &pme->dim, sizeof(cam_ctrl_dimension_t));
+
+end:
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+#endif
+    return rc;
+}
+
+void mm_app_close_ch(int cam_id, int ch_type)
+{
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    pme->cam->ops->ch_release(pme->cam->camera_handle,pme->ch_id);
+    CDBG("%s:END,cam_id = %d, ch = %d\n", __func__, cam_id, ch_type);
+
+}
+
+int mm_app_unit_test()
+{
+    my_cam_app.run_sanity = 1;
+    mm_app_unit_test_entry(&my_cam_app);
+    return 0;
+}
+
+int mm_app_dual_test()
+{
+    my_cam_app.run_sanity = 1;
+    mm_app_dual_test_entry(&my_cam_app);
+    return 0;
+}
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_display.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_display.c
new file mode 100755
index 0000000..da3399d
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_display.c
@@ -0,0 +1,572 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/ioctl.h>
+struct file;
+struct inode;
+#include <linux/android_pmem.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <string.h>
+
+#include <inttypes.h>
+#include <linux/msm_mdp.h>
+#include <linux/fb.h>
+#include "camera.h"
+#include "mm_camera_dbg.h"
+
+#ifdef DRAW_RECTANGLES
+extern roi_info_t camframe_roi;
+
+#undef CAM_FRM_DRAW_RECT
+#define CAM_FRM_DRAW_RECT
+#endif
+
+#ifdef CAM_FRM_DRAW_FD_RECT
+#undef CAM_FRM_DRAW_RECT
+#define CAM_FRM_DRAW_RECT
+#endif
+
+struct fb_var_screeninfo vinfo;
+struct fb_fix_screeninfo finfo;
+int fb_fd = 0;
+union {
+  char dummy[sizeof(struct mdp_blit_req_list) +
+    sizeof(struct mdp_blit_req) * 1];
+  struct mdp_blit_req_list list;
+} yuv;
+
+static pthread_t cam_frame_fb_thread_id;
+static int camframe_fb_exit;
+
+static int is_camframe_fb_thread_ready;
+USER_INPUT_DISPLAY_T input_display;
+
+unsigned use_overlay = 0;
+struct msmfb_overlay_data ov_front, ov_back, *ovp_front, *ovp_back;
+struct mdp_overlay overlay, *overlayp;
+int vid_buf_front_id, vid_buf_back_id;
+static unsigned char please_initialize = 1;
+int num_of_ready_frames = 0;
+
+static pthread_cond_t  sub_thread_ready_cond  = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t sub_thread_ready_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t  camframe_fb_cond  = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t camframe_fb_mutex = PTHREAD_MUTEX_INITIALIZER;
+static void notify_camframe_fb_thread();
+
+void use_overlay_fb_display_driver(void)
+{
+  use_overlay = 1;
+}
+
+void overlay_set_params(struct mdp_blit_req *e)
+{
+  int result;
+
+  if (please_initialize) {
+    overlayp = &overlay;
+    ovp_front = &ov_front;
+    ovp_back = &ov_back;
+
+    overlayp->id = MSMFB_NEW_REQUEST;
+  }
+
+  overlayp->src.width  = e->src.width;
+  overlayp->src.height = e->src.height;
+  overlayp->src.format = e->src.format;
+
+  overlayp->src_rect.x = e->src_rect.x;
+  overlayp->src_rect.y = e->src_rect.y;
+  overlayp->src_rect.w = e->src_rect.w;
+  overlayp->src_rect.h = e->src_rect.h;
+
+  overlayp->dst_rect.x = e->dst_rect.x;
+  overlayp->dst_rect.y = e->dst_rect.y;
+  /* ROTATOR is enabled in overlay library, swap dimensions
+     here to take care of that */
+  overlayp->dst_rect.w = e->dst_rect.h;
+  overlayp->dst_rect.h = e->dst_rect.w;
+
+  if (overlayp->dst_rect.w > 480)
+    overlayp->dst_rect.w = 480;
+  if (overlayp->dst_rect.h > 800)
+    overlayp->dst_rect.h = 800;
+
+  overlayp->z_order = 0; // FB_OVERLAY_VID_0;
+  overlayp->alpha = e->alpha;
+  overlayp->transp_mask = 0; /* 0xF81F */
+  overlayp->flags = e->flags;
+  overlayp->is_fg = 1;
+
+  if (please_initialize) {
+    CDBG("src.width %d height %d; src_rect.x %d y %d w %d h %d; dst_rect.x %d y %d w %d h %d\n",
+      overlayp->src.width, overlayp->src.height,
+      overlayp->src_rect.x, overlayp->src_rect.y, overlayp->src_rect.w, overlayp->src_rect.h,
+      overlayp->dst_rect.x, overlayp->dst_rect.y, overlayp->dst_rect.w, overlayp->dst_rect.h
+      );
+
+    result = ioctl(fb_fd, MSMFB_OVERLAY_SET, overlayp);
+    if (result < 0) {
+      CDBG("ERROR: MSMFB_OVERLAY_SET failed!, result =%d\n", result);
+    }
+  }
+
+  if (please_initialize) {
+    vid_buf_front_id = overlayp->id; /* keep return id */
+
+    ov_front.id = overlayp->id;
+    ov_back.id = overlayp->id;
+    please_initialize = 0;
+  }
+
+  return;
+}
+
+void overlay_set_frame(struct msm_frame *frame)
+{
+  ov_front.data.offset = 0;
+  ov_front.data.memory_id = frame->fd;
+  return;
+}
+
+/*===========================================================================
+ * FUNCTION     test_app_camframe_callback
+ * DESCRIPTION  display frame
+ *==========================================================================*/
+void test_app_camframe_callback(struct msm_frame *frame)
+{
+  int result = 0;
+  struct mdp_blit_req *e;
+  struct timeval td1, td2;
+  struct timezone tz;
+
+  common_crop_t *crop = (common_crop_t *) (frame->cropinfo);
+
+  /* Initialize yuv structure */
+  yuv.list.count = 1;
+
+  e = &yuv.list.req[0];
+
+  e->src.width = input_display.user_input_display_width;
+  e->src.height = input_display.user_input_display_height;
+  e->src.format = MDP_Y_CRCB_H2V2;
+  e->src.offset = 0;
+  e->src.memory_id = frame->fd;
+
+  e->dst.width = vinfo.xres;
+  e->dst.height = vinfo.yres;
+  e->dst.format = MDP_RGB_565;
+  e->dst.offset = 0;
+  e->dst.memory_id = fb_fd;
+
+  e->transp_mask = 0xffffffff;
+  e->flags = 0;
+  e->alpha = 0xff;
+
+  /* Starting doing MDP Cropping */
+  if (frame->path == OUTPUT_TYPE_P) {
+
+    if (crop->in2_w != 0 || crop->in2_h != 0) {
+
+      e->src_rect.x = (crop->out2_w - crop->in2_w + 1) / 2 - 1;
+
+      e->src_rect.y = (crop->out2_h - crop->in2_h + 1) / 2 - 1;
+
+      e->src_rect.w = crop->in2_w;
+      e->src_rect.h = crop->in2_h;
+
+      CDBG("e->src_rect.x = %d\n", e->src_rect.x);
+      CDBG("e->src_rect.y = %d\n", e->src_rect.y);
+      CDBG("e->src_rect.w = %d\n", e->src_rect.w);
+      CDBG("e->src_rect.h = %d\n", e->src_rect.h);
+
+      e->dst_rect.x = 0;
+      e->dst_rect.y = 0;
+      e->dst_rect.w = input_display.user_input_display_width;
+      e->dst_rect.h = input_display.user_input_display_height;
+    } else {
+      e->src_rect.x = 0;
+      e->src_rect.y = 0;
+      e->src_rect.w = input_display.user_input_display_width;
+      e->src_rect.h = input_display.user_input_display_height;
+
+      e->dst_rect.x = 0;
+      e->dst_rect.y = 0;
+      e->dst_rect.w = input_display.user_input_display_width;
+      e->dst_rect.h = input_display.user_input_display_height;
+    }
+    if (use_overlay) overlay_set_params(e);
+  } else {
+
+  }
+
+  gettimeofday(&td1, &tz);
+
+  if (use_overlay) overlay_set_frame(frame);
+  else {
+    result = ioctl(fb_fd, MSMFB_BLIT, &yuv.list);
+    if (result < 0) {
+      CDBG("MSM_FBIOBLT failed! line=%d\n", __LINE__);
+    }
+  }
+
+  gettimeofday(&td2, &tz);
+  CDBG("Profiling: MSMFB_BLIT takes %ld microseconds\n",
+    ((td2.tv_sec - td1.tv_sec) * 1000000 + (td2.tv_usec - td1.tv_usec)));
+
+  td1 = td2;
+  notify_camframe_fb_thread();
+  /* add frame back to the free queue*/
+  //camframe_add_frame(CAM_PREVIEW_FRAME, frame);
+}
+
+void notify_camframe_fb_thread()
+{
+  pthread_mutex_lock(&camframe_fb_mutex);
+
+  num_of_ready_frames ++;
+  pthread_cond_signal(&camframe_fb_cond);
+
+  pthread_mutex_unlock(&camframe_fb_mutex);
+}
+
+void camframe_fb_thread_ready_signal(void);
+
+void *camframe_fb_thread(void *data)
+{
+  int result = 0;
+  static struct timeval td1, td2;
+  struct timezone tz;
+
+#ifdef _ANDROID_
+  fb_fd = open(ANDROID_FB0, O_RDWR);
+  CDBG("%s:android dl '%s', fd=%d\n", __func__, ANDROID_FB0, fb_fd);
+#else
+  fb_fd = open(LE_FB0, O_RDWR);
+  CDBG("%s:LE_FB0 dl, '%s', fd=%d\n", __func__, LE_FB0, fb_fd);
+#endif
+  if (fb_fd < 0) {
+    CDBG_ERROR("cannot open framebuffer %s or %s file node\n",
+      ANDROID_FB0, LE_FB0);
+    goto fail1;
+  }
+
+  if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
+    CDBG_ERROR("cannot retrieve vscreenInfo!\n");
+    goto fail;
+  }
+
+  if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
+    CDBG_ERROR("can't retrieve fscreenInfo!\n");
+    goto fail;
+  }
+
+  vinfo.activate = FB_ACTIVATE_VBL;
+
+  camframe_fb_thread_ready_signal();
+
+  pthread_mutex_lock(&camframe_fb_mutex);
+  while (!camframe_fb_exit) {
+    CDBG("cam_frame_fb_thread: num_of_ready_frames: %d\n", num_of_ready_frames);
+    if (num_of_ready_frames <= 0) {
+      pthread_cond_wait(&camframe_fb_cond, &camframe_fb_mutex);
+    }
+    if (num_of_ready_frames > 0) {
+      num_of_ready_frames --;
+
+      gettimeofday(&td1, &tz);
+      if (use_overlay) {
+        result = ioctl(fb_fd, MSMFB_OVERLAY_PLAY, ovp_front);
+      } else {
+        result = ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo);
+      }
+
+      gettimeofday(&td2, &tz);
+
+      CDBG("Profiling: frame timestamp after FBIO display = %ld ms\n",
+        (td2.tv_sec*1000) + (td2.tv_usec/1000));
+
+      CDBG("cam_frame_fb_thread: elapse time for FBIOPAN_DISPLAY = %ld, return = %d\n",
+        (td2.tv_sec - td1.tv_sec) * 1000000 + td2.tv_usec - td1.tv_usec, result);
+
+      if (result < 0) {
+        CDBG("DISPLAY: Failed\n");
+      }
+    }
+  }
+
+  pthread_mutex_unlock(&camframe_fb_mutex);
+
+  if (use_overlay) {
+    if (ioctl(fb_fd, MSMFB_OVERLAY_UNSET, &vid_buf_front_id)) {
+      CDBG("\nERROR! MSMFB_OVERLAY_UNSET failed! (Line %d)\n", __LINE__);
+      goto fail;
+    }
+  }
+
+  return NULL;
+
+  fail:
+  close(fb_fd);
+  fail1:
+  camframe_fb_exit = -1;
+  camframe_fb_thread_ready_signal();
+  return NULL;
+}
+
+int launch_camframe_fb_thread(void)
+{
+
+  camframe_fb_exit = 0;
+  is_camframe_fb_thread_ready = 0;
+  pthread_create(&cam_frame_fb_thread_id, NULL, camframe_fb_thread, NULL);
+
+  /* Waiting for launching sub thread ready signal. */
+  CDBG("launch_camframe_fb_thread(), call pthread_cond_wait\n");
+
+  pthread_mutex_lock(&sub_thread_ready_mutex);
+  if (!is_camframe_fb_thread_ready) {
+    pthread_cond_wait(&sub_thread_ready_cond, &sub_thread_ready_mutex);
+  }
+  pthread_mutex_unlock(&sub_thread_ready_mutex);
+
+  CDBG("launch_camframe_fb_thread(), call pthread_cond_wait done\n");
+  CDBG("%s:fb rc=%d\n", __func__, camframe_fb_exit);
+  return camframe_fb_exit;
+}
+
+void release_camframe_fb_thread(void)
+{
+  camframe_fb_exit = 1;
+  please_initialize = 1;
+
+  /* Notify the camframe fb thread to wake up */
+  if (cam_frame_fb_thread_id != 0) {
+     pthread_mutex_lock(&camframe_fb_mutex);
+     pthread_cond_signal(&camframe_fb_cond);
+     pthread_mutex_unlock(&camframe_fb_mutex);
+     if (pthread_join(cam_frame_fb_thread_id, NULL) != 0) {
+       CDBG("cam_frame_fb_thread exit failure!\n");
+     }
+     close(fb_fd);
+  }
+}
+
+void camframe_fb_thread_ready_signal(void)
+{
+  /* Send the signal to control thread to indicate that the cam frame fb
+   * ready.
+   */
+  CDBG("cam_frame_fb_thread() is ready, call pthread_cond_signal\n");
+
+  pthread_mutex_lock(&sub_thread_ready_mutex);
+  is_camframe_fb_thread_ready = 1;
+  pthread_cond_signal(&sub_thread_ready_cond);
+  pthread_mutex_unlock(&sub_thread_ready_mutex);
+
+  CDBG("cam_frame_fb_thread() is ready, call pthread_cond_signal done\n");
+}
+
+#ifdef CAM_FRM_DRAW_RECT
+void draw_rect(char *buf, int buf_w,
+  int x, int y, int dx, int dy)
+{
+  int i;
+  int left   = x;
+  int right  = x+dx;
+  int top    = y;
+  int bottom = y+dy;
+
+  for (i = left; i < right; i++) {
+    buf[top*buf_w+i] = 0xff;
+    buf[bottom*buf_w+i] = 0xff;
+  }
+  for (i = top; i < bottom; i++) {
+    buf[i*buf_w+left] = 0xff;
+    buf[i*buf_w+right] = 0xff;
+  }
+}
+#endif
+
+void draw_rectangles(struct msm_frame* newFrame)
+{
+  struct fd_roi_t *p_fd_roi;
+#ifdef DRAW_RECTANGLES
+  uint8_t i;
+  for (i = 0; i < camframe_roi.num_roi; i++) {
+    CDBG("%s: camframe_roi: i=%d, x=%d, y=%d, dx=%d, dy=%d\n", __func__,
+      i, camframe_roi.roi[i].x, camframe_roi.roi[i].y,
+      camframe_roi.roi[i].dx, camframe_roi.roi[i].dy);
+    draw_rect((char*)newFrame->buffer, 640,
+      camframe_roi.roi[i].x, camframe_roi.roi[i].y,
+      camframe_roi.roi[i].dx, camframe_roi.roi[i].dy);
+  }
+#endif
+
+#ifdef CAM_FRM_DRAW_FD_RECT
+  p_fd_roi = (struct fd_roi_t *)newFrame->roi_info.info;
+  if(p_fd_roi && p_fd_roi->rect_num > 0){
+    int i;
+    for(i =0; i < p_fd_roi->rect_num; i++)
+    {
+      draw_rect((char*)newFrame->buffer, 800,
+        p_fd_roi->faces[i].x, p_fd_roi->faces[i].y,
+        p_fd_roi->faces[i].dx, p_fd_roi->faces[i].dy);
+    }
+  }
+#endif
+}
+
+/*===========================================================================
+ * FUNCTION    - v4l2_render -
+ *
+ * DESCRIPTION:
+ *==========================================================================*/
+int v4l2_render(int frame_fd, struct v4l2_buffer *vb, struct v4l2_crop *crop)
+{
+  struct mdp_blit_req *e;
+  /* Initialize yuv structure */
+  yuv.list.count = 1;
+  e = &yuv.list.req[0];
+
+  e->src.width = input_display.user_input_display_width;
+  e->src.height = input_display.user_input_display_height;
+  e->src.format = MDP_Y_CBCR_H2V2;
+  e->src.offset = 0;
+  e->src.memory_id = frame_fd;
+
+  e->dst.width = vinfo.xres;
+  e->dst.height = vinfo.yres;
+  e->dst.format = MDP_RGB_565;
+  e->dst.offset = 0;
+  e->dst.memory_id = fb_fd;
+
+  e->transp_mask = 0xffffffff;
+  e->flags = 0;
+  e->alpha = 0xff;
+
+ if (crop != NULL && (crop->c.width != 0 || crop->c.height != 0)) {
+    e->src_rect.x = crop->c.left;
+    e->src_rect.y = crop->c.top;
+    e->src_rect.w = crop->c.width;
+    e->src_rect.h = crop->c.height;
+
+    e->dst_rect.x = 0;
+    e->dst_rect.y = 0;
+    e->dst_rect.w = input_display.user_input_display_width;
+    e->dst_rect.h = input_display.user_input_display_height;
+  } else {
+    e->dst_rect.x = 0;
+    e->dst_rect.y = 0;
+    e->dst_rect.w  = input_display.user_input_display_width;
+    e->dst_rect.h  = input_display.user_input_display_height;
+
+    e->src_rect.x = 0;
+    e->src_rect.y = 0;
+    e->src_rect.w  = input_display.user_input_display_width;
+    e->src_rect.h  = input_display.user_input_display_height;
+  }
+  overlay_set_params(e);
+  ov_front.data.offset = 0;
+  ov_front.data.memory_id = frame_fd;
+  notify_camframe_fb_thread();
+
+  return TRUE;
+}
+
+int mm_app_dl_render(int frame_fd, struct crop_info * cropinfo)
+{
+  struct mdp_blit_req *e;
+  int croplen = 0;
+  //struct crop_info *cropinfo;
+  common_crop_t *crop;
+
+  //cropinfo = (struct crop_info *)vb->input;
+  if(cropinfo != NULL) {
+    crop = (common_crop_t *)cropinfo->info;
+  }
+  /* Initialize yuv structure */
+  yuv.list.count = 1;
+  e = &yuv.list.req[0];
+
+  e->src.width = input_display.user_input_display_width;
+  e->src.height = input_display.user_input_display_height;
+  e->src.format = MDP_Y_CRCB_H2V2;
+  e->src.offset = 0;
+  e->src.memory_id = frame_fd;
+
+  e->dst.width = vinfo.xres;
+  e->dst.height = vinfo.yres;
+  e->dst.format = MDP_RGB_565;
+  e->dst.offset = 0;
+  e->dst.memory_id = fb_fd;
+
+  e->transp_mask = 0xffffffff;
+  e->flags = 0;
+  e->alpha = 0xff;
+
+  if (cropinfo != NULL && (crop->in2_w != 0 || crop->in2_h != 0)) {
+    e->src_rect.x = (crop->out2_w - crop->in2_w + 1) / 2 - 1;
+    e->src_rect.y = (crop->out2_h - crop->in2_h + 1) / 2 - 1;
+    e->src_rect.w = crop->in2_w;
+    e->src_rect.h = crop->in2_h;
+
+    e->dst_rect.x = 0;
+    e->dst_rect.y = 0;
+    e->dst_rect.w = input_display.user_input_display_width;
+    e->dst_rect.h = input_display.user_input_display_height;
+  } else {
+    e->dst_rect.x = 0;
+    e->dst_rect.y = 0;
+    e->dst_rect.w  = input_display.user_input_display_width;
+    e->dst_rect.h  = input_display.user_input_display_height;
+
+    e->src_rect.x = 0;
+    e->src_rect.y = 0;
+    e->src_rect.w  = input_display.user_input_display_width;
+    e->src_rect.h  = input_display.user_input_display_height;
+  }
+
+  overlay_set_params(e);
+
+  ov_front.data.offset = 0;
+  ov_front.data.memory_id = frame_fd;
+  notify_camframe_fb_thread();
+
+  return TRUE;
+}
+
+
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_dual_test.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_dual_test.c
new file mode 100755
index 0000000..37f0144
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_dual_test.c
@@ -0,0 +1,565 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include "mm_camera_dbg.h"
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include "mm_qcamera_unit_test.h"
+
+#define MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP 4
+#define MM_QCAM_APP_TEST_NUM 128
+
+#define MM_QCAMERA_APP_INTERATION 5
+#define MM_QCAMERA_APP_WAIT_TIME 1000000000
+
+static mm_app_tc_t mm_app_tc[MM_QCAM_APP_TEST_NUM];
+static int num_test_cases = 0;
+
+int mm_app_dtc_0(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i,j;
+    int result = 0;
+    int front_camera = 1;
+    int back_camera = 0;
+
+    printf("\n Verifying Preview on back Camera and RDI on Front camera...\n");
+
+    if(mm_app_open(back_camera) != MM_CAMERA_OK) {
+        CDBG_ERROR("%s:mm_app_open() back camera err=%d\n",__func__, rc);
+        rc = -1;
+        goto end;
+    }
+    if(system_dimension_set(back_camera) != MM_CAMERA_OK){
+    CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+    if( MM_CAMERA_OK != (rc = startPreview(back_camera))) {
+        CDBG_ERROR("%s: back camera startPreview() err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    mm_camera_app_wait();
+    if(mm_app_open(front_camera) != MM_CAMERA_OK) {
+        CDBG_ERROR("%s:mm_app_open() front camera err=%d\n",__func__, rc);
+        rc = -1;
+        goto end;
+    }
+    if(system_dimension_set(front_camera) != MM_CAMERA_OK){
+        CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+    if( MM_CAMERA_OK != (rc = startRdi(front_camera))) {
+        CDBG_ERROR("%s: startPreview() backcamera err=%d\n", __func__, rc);
+        goto end;
+    }
+    mm_camera_app_wait();
+
+    if( MM_CAMERA_OK != (rc = stopRdi(front_camera))) {
+        CDBG_ERROR("%s: startPreview() backcamera err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    if( MM_CAMERA_OK != (rc = stopPreview(my_cam_app.cam_open))) {
+        CDBG("%s: startPreview() err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    if( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
+        CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
+        rc = -1;
+        goto end;
+    }
+end:
+    if(rc == 0) {
+        printf("\nPassed\n");
+    }else{
+        printf("\nFailed\n");
+    }
+    CDBG("%s:END, rc = %d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_dtc_1(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i,j;
+    int result = 0;
+
+    printf("\n Verifying Snapshot on front and back camera...\n");
+    for(i = 0; i < cam_apps->num_cameras; i++) {
+        if( mm_app_open(i) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if(system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK){
+            CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+
+        if( MM_CAMERA_OK != (rc = startPreview(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: startPreview() err=%d\n", __func__, rc);
+                break;
+        }
+        for(j = 0; j < MM_QCAMERA_APP_INTERATION; j++) {
+            if( MM_CAMERA_OK != (rc = takePicture_yuv(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: TakePicture() err=%d\n", __func__, rc);
+                break;
+            }
+            /*if(mm_camera_app_timedwait() == ETIMEDOUT) {
+                CDBG_ERROR("%s: Snapshot/Preview Callback not received in time or qbuf Faile\n", __func__);
+                break;
+            }*/
+            mm_camera_app_wait();
+            result++;
+        }
+        if( MM_CAMERA_OK != (rc = stopPreview(my_cam_app.cam_open))) {
+            CDBG("%s: startPreview() err=%d\n", __func__, rc);
+            break;
+        }
+        if( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if(result != MM_QCAMERA_APP_INTERATION) {
+            printf("%s: Snapshot Start/Stop Fails for Camera %d in %d iteration", __func__, i,j);
+            rc = -1;
+            break;
+        }
+
+        result = 0;
+    }
+end:
+    if(rc == 0) {
+        printf("\t***Passed***\n");
+    }else{
+        printf("\t***Failed***\n");
+    }
+    CDBG("%s:END, rc = %d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_dtc_2(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i,j;
+    int result = 0;
+
+    printf("\n Verifying Video on front and back camera...\n");
+    for(i = 0; i < cam_apps->num_cameras; i++) {
+        if( mm_app_open(i) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if(system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK){
+            CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+
+        if( MM_CAMERA_OK != (rc = startPreview(my_cam_app.cam_open))) {
+            CDBG_ERROR("%s: startPreview() err=%d\n", __func__, rc);
+            break;
+        }
+        for(j = 0; j < MM_QCAMERA_APP_INTERATION; j++) {
+            if( MM_CAMERA_OK != (rc = startRecording(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: StartVideorecording() err=%d\n", __func__, rc);
+                break;
+            }
+
+            /*if(mm_camera_app_timedwait() == ETIMEDOUT) {
+            CDBG_ERROR("%s: Video Callback not received in time\n", __func__);
+            break;
+            }*/
+            mm_camera_app_wait();
+            if( MM_CAMERA_OK != (rc = stopRecording(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: Stopvideorecording() err=%d\n", __func__, rc);
+                break;
+            }
+            result++;
+        }
+        if( MM_CAMERA_OK != (rc = stopPreview(my_cam_app.cam_open))) {
+            CDBG("%s: startPreview() err=%d\n", __func__, rc);
+            break;
+        }
+        if( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if(result != MM_QCAMERA_APP_INTERATION) {
+            printf("%s: Video Start/Stop Fails for Camera %d in %d iteration", __func__, i,j);
+            rc = -1;
+            break;
+        }
+
+        result = 0;
+    }
+end:
+    if(rc == 0) {
+        printf("\nPassed\n");
+    }else{
+        printf("\nFailed\n");
+    }
+    CDBG("%s:END, rc = %d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_dtc_3(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i,j;
+    int result = 0;
+
+    printf("\n Verifying RDI Stream on front and back camera...\n");
+    if(cam_apps->num_cameras == 0) {
+        CDBG_ERROR("%s:Query Failed: Num of cameras = %d\n",__func__, cam_apps->num_cameras);
+        rc = -1;
+        goto end;
+    }
+    for(i = 0; i < cam_apps->num_cameras; i++) {
+        if( mm_app_open(i) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if(system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK){
+            CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        for(j = 0; j < MM_QCAMERA_APP_INTERATION; j++) {
+            if( MM_CAMERA_OK != (rc = startRdi(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: StartVideorecording() err=%d\n", __func__, rc);
+                break;
+            }
+
+            /*if(mm_camera_app_timedwait() == ETIMEDOUT) {
+            CDBG_ERROR("%s: Video Callback not received in time\n", __func__);
+            break;
+            }*/
+            mm_camera_app_wait();
+            if( MM_CAMERA_OK != (rc = stopRdi(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: Stopvideorecording() err=%d\n", __func__, rc);
+                break;
+            }
+            result++;
+        }
+        if( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if(result != MM_QCAMERA_APP_INTERATION) {
+            printf("%s: Video Start/Stop Fails for Camera %d in %d iteration", __func__, i,j);
+            rc = -1;
+            break;
+        }
+
+        result = 0;
+    }
+end:
+    if(rc == 0) {
+        printf("\nPassed\n");
+    }else{
+        printf("\nFailed\n");
+    }
+    CDBG("%s:END, rc = %d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_dtc_4(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - open/close ,video0, open/close preview channel only\n", __func__); 
+#if 0
+    for(i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+            CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n", __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+            goto end;
+        }
+        if(0 != (rc = mm_app_open_preview(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc = mm_app_close_preview(cam_id))) {
+            goto end;
+        }
+        if ( 0 != (rc = mm_app_close(cam_id))) {
+            CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n", __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+            goto end;
+        }
+        }
+end:
+#endif 
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+
+
+int mm_app_dtc_5(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - open/close ,video0, open/close snapshot channel only\n", __func__); 
+#if 0
+    for(i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+            CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n",
+                __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc);
+            goto end;
+        }
+        if(0 != (rc = mm_app_open_snapshot(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc = mm_app_close_snapshot(cam_id))) {
+            goto end;
+        }
+        if ( 0 != (rc = mm_app_close(cam_id))) {
+            CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n",
+                    __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc);
+            goto end;
+        }
+    }
+end:
+#endif
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_dtc_6(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - simple preview \n", __func__); 
+#if 0
+    if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+        CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n",
+                __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc);
+        goto end;
+    }
+
+    for(i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if(0 != (rc = mm_app_init_preview(cam_id))) {
+                goto end;
+        }
+        if(0 != (rc = mm_app_start_preview(cam_id))) {
+            goto end;
+        }
+        /* sleep 8 seconds */
+        usleep(8000000);
+        if(0 != (rc = mm_app_stop_preview(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc=mm_app_deinit_preview(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc = mm_app_close_preview(cam_id))) {
+            goto end;
+        }
+    }
+    if ( 0 != (rc = mm_app_close(cam_id))) {
+        CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n",
+                __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc);
+        goto end;
+    }
+end:
+#endif 
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_dtc_7(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - simple preview and recording \n", __func__); 
+#if 0
+    if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+        CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n",
+                __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc);
+        goto end;
+    }
+
+    for(i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if(0 != (rc = mm_app_init_preview(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc = mm_app_start_preview(cam_id))) {
+            goto end;
+        }
+        /* sleep 8 seconds */
+        usleep(8000000);
+        if(0 != (rc = mm_app_start_recording(cam_id))) {
+                goto end;
+    }
+        usleep(1000000);
+    if(0 != (rc = mm_app_stop_recording(cam_id))) {
+        goto end;
+    }
+    usleep(8000000);
+    if(0 != (rc = mm_app_stop_preview(cam_id))) {
+            goto end;
+    }
+    if(0 != (rc=mm_app_deinit_preview(cam_id))) {
+        goto end;
+    }
+    if(0 != (rc = mm_app_close_preview(cam_id))) {
+        goto end;
+    }
+    }
+    if ( 0 != (rc = mm_app_close(cam_id))) {
+        CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n",
+                __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc);
+        goto end;
+    }
+end:
+#endif 
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_dtc_8(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - preview, recording, and snapshot, then preview again \n", __func__); 
+#if 0
+    if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+        CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n",
+                __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc);
+        goto end;
+    }
+
+    for(i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if(0 != (rc = mm_app_init_preview(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc = mm_app_start_preview(cam_id))) {
+            goto end;
+        }
+        /* sleep 8 seconds */
+        usleep(8000000);
+        if(0 != (rc = mm_app_start_recording(cam_id))) {
+            goto end;
+        }
+        usleep(1000000);
+        if(0 != (rc = mm_app_stop_recording(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc = mm_app_stop_preview(cam_id))) {
+            goto end;
+        }
+        if(0!=(rc=mm_app_init_snapshot(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc=mm_app_take_picture(cam_id))) {
+            goto end;
+        }
+        if( 0 != (rc = mm_app_deinit_snahspot(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc = mm_app_start_preview(cam_id))) {
+            goto end;
+        }
+        usleep(8000000);
+        if(0 != (rc=mm_app_deinit_preview(cam_id))) {
+            goto end;
+        }
+        if(0 != (rc = mm_app_close_preview(cam_id))) {
+            goto end;
+        }
+    }
+    if ( 0 != (rc = mm_app_close(cam_id))) {
+        CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n", 
+                __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+        goto end;
+    }
+end:
+#endif
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+
+int mm_app_gen_dual_test_cases()
+{
+    int tc = 0;
+    memset(mm_app_tc, 0, sizeof(mm_app_tc));
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_0;
+    /*if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_1;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_2;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_3;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_4;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_5;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_6;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_7;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_dtc_8;*/
+    return tc;
+}
+
+int mm_app_dual_test_entry(mm_camera_app_t *cam_app)
+{
+    int rc = MM_CAMERA_OK;
+    int i, tc = 0;
+    int cam_id = 0;
+
+    tc = mm_app_gen_dual_test_cases();
+    CDBG("Running %d test cases\n",tc);
+    for(i = 0; i < tc; i++) {
+        mm_app_tc[i].r = mm_app_tc[i].f(cam_app);
+        if(mm_app_tc[i].r != MM_CAMERA_OK) {
+            printf("%s: test case %d error = %d, abort unit testing engine!!!!\n", 
+                    __func__, i, mm_app_tc[i].r); 
+            rc = mm_app_tc[i].r;
+            goto end;
+        }
+    }
+end:
+    printf("nTOTAL_TSET_CASE = %d, NUM_TEST_RAN = %d, rc=%d\n", tc, i, rc);
+    return rc;
+}
+
+
+
+
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_main_menu.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_main_menu.c
new file mode 100755
index 0000000..89fca13
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_main_menu.c
@@ -0,0 +1,1930 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <termios.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+#ifdef _ANDROID_
+#include <cutils/log.h>
+#endif
+#include <dlfcn.h>
+
+#include "camera.h"
+#include "mm_camera_dbg.h"
+#include "mm_qcamera_main_menu.h"
+#include "mm_qcamera_display_dimensions.h"
+#include "camera_defs_i.h"
+#include "mm_qcamera_app.h"
+
+#define CAMERA_OPENED 0
+
+#define VIDEO_BUFFER_SIZE       (PREVIEW_WIDTH * PREVIEW_HEIGHT * 3/2)
+#define THUMBNAIL_BUFFER_SIZE   (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
+#define SNAPSHOT_BUFFER_SIZE    (PICTURE_WIDTH * PICTURE_HEIGHT * 3/2)
+/*===========================================================================
+ * Macro
+ *===========================================================================*/
+#define PREVIEW_FRAMES_NUM    4
+#define VIDEO_FRAMES_NUM      4
+#define THUMBNAIL_FRAMES_NUM  1
+#define SNAPSHOT_FRAMES_NUM   1
+#define MAX_NUM_FORMAT        32
+/*===========================================================================
+ * Defines
+ *===========================================================================*/
+
+const CAMERA_MAIN_MENU_TBL_T camera_main_menu_tbl[] = {
+  {STOP_CAMERA,                   "Stop preview/video and exit camera."},
+  {PREVIEW_VIDEO_RESOLUTION,      "Preview/Video Resolution: SQCIF/QCIF/"
+                              "QVGA/CIF/VGA/WVGA... Default WVGA."},
+  {TAKE_YUV_SNAPSHOT,       "Take a snapshot"},
+  {TAKE_RAW_SNAPSHOT,       "Take a raw snapshot"},
+  {TAKE_ZSL_SNAPSHOT,       "Take a ZSL snapshot"},
+  {START_RECORDING,       "Start RECORDING"},
+  {START_RDI, "Start RDI stream"},
+  {STOP_RDI, "Stop RDI stream"},
+  {SWITCH_CAMERA,       "Switch Camera"},
+#if 0
+  {SET_WHITE_BALANCE,          "Set white balance mode: Auto/Off/Daylight/Incandescent/Fluorescent. Default Auto."},
+  {SET_EXP_METERING,          "Set exposure metering mode: FrameAverage/CenterWeighted/SpotMetering. Default CenterWeighted"},
+  {GET_CTRL_VALUE,              "Get control value menu"},
+  {TOGGLE_AFR,                 "Toggle auto frame rate. Default fixed frame rate"},
+  {SET_ISO,                 "ISO changes."},
+  {BRIGHTNESS_GOTO_SUBMENU,                               "Brightness changes."},
+  {CONTRAST_GOTO_SUBMENU,                                 "Contrast changes."},
+  {EV_GOTO_SUBMENU,                                       "EV changes."},
+  {SATURATION_GOTO_SUBMENU,                               "Saturation changes."},
+  {SET_ZOOM,          "Set Digital Zoom."},
+  {SET_SHARPNESS,          "Set Sharpness."},
+#endif
+};
+
+const PREVIEW_DIMENSION_TBL_T preview_video_dimension_tbl[] = {
+   { SQCIF, SQCIF_WIDTH, SQCIF_HEIGHT, "SQCIF",  "Preview/Video Resolution: SQCIF <128x96>"},
+   {  QCIF,  QCIF_WIDTH,  QCIF_HEIGHT,  "QCIF",  "Preview/Video Resolution: QCIF <176x144>"},
+   {  QVGA,  QVGA_WIDTH,  QVGA_HEIGHT,  "QVGA",  "Preview/Video Resolution: QVGA <320x240>"},
+   {   CIF,   CIF_WIDTH,   CIF_HEIGHT,   "CIF",  "Preview/Video Resolution: CIF <352x288>"},
+   {   VGA,   VGA_WIDTH,   VGA_HEIGHT,   "VGA",  "Preview/Video Resolution: VGA <640x480>"},
+   {  WVGA,  WVGA_WIDTH,  WVGA_HEIGHT,  "WVGA",  "Preview/Video Resolution: WVGA <800x480>"},
+   {  SVGA,  SVGA_WIDTH,  SVGA_HEIGHT,  "SVGA",  "Preview/Video Resolution: SVGA <800x600>"},
+   {   XGA,   XGA_WIDTH,   XGA_HEIGHT,    "XGA", "Preview/Video Resolution: XGA <1024x768>"},
+   { HD720, HD720_WIDTH, HD720_HEIGHT,  "HD720", "Preview/Video Resolution: HD720 <1280x720>"},
+};
+
+const CAMERA_BRIGHTNESS_TBL_T brightness_change_tbl[] = {
+  {INC_BRIGHTNESS, "Increase Brightness by one step."},
+  {DEC_BRIGHTNESS, "Decrease Brightness by one step."},
+};
+
+const CAMERA_CONTRST_TBL_T contrast_change_tbl[] = {
+  {INC_CONTRAST, "Increase Contrast by one step."},
+  {DEC_CONTRAST, "Decrease Contrast by one step."},
+};
+
+const CAMERA_EV_TBL_T camera_EV_tbl[] = {
+  {INCREASE_EV, "Increase EV by one step."},
+  {DECREASE_EV, "Decrease EV by one step."},
+};
+
+const CAMERA_SATURATION_TBL_T camera_saturation_tbl[] = {
+  {INC_SATURATION, "Increase Satuation by one step."},
+  {DEC_SATURATION, "Decrease Satuation by one step."},
+};
+
+const CAMERA_SHARPNESS_TBL_T camera_sharpness_tbl[] = {
+  {INC_SHARPNESS, "Increase Sharpness."},
+  {DEC_SHARPNESS, "Decrease Sharpness."},
+};
+
+const WHITE_BALANCE_TBL_T white_balance_tbl[] = {
+  { 	MM_CAMERA_WHITE_BALANCE_AUTO,         "White Balance - Auto"},
+  { 	MM_CAMERA_WHITE_BALANCE_OFF,          "White Balance - Off"},
+  {   MM_CAMERA_WHITE_BALANCE_DAYLIGHT,     "White Balance - Daylight"},
+  {   MM_CAMERA_WHITE_BALANCE_INCANDESCENT, "White Balance - Incandescent"},
+  {   MM_CAMERA_WHITE_BALANCE_FLUORESCENT,  "White Balance - Fluorescent"},
+};
+
+const CAMERA_TBL_T cam_tbl[] = {
+  { 	1,          "Back Camera"},
+  { 	2,         "Front Camera"},
+};
+
+const RECORD_TBL_T record_tbl[] = {
+  { 	LIVE_SNAPSHOT_MENU,          "Take Live snapshot"},
+  { 	STOP_RECORDING_MENU,         "Stop Recording"},
+};
+
+const GET_CTRL_TBL_T get_ctrl_tbl[] = {
+  {     WHITE_BALANCE_STATE,           "Get white balance state (auto/off)"},
+  {     WHITE_BALANCE_TEMPERATURE,      "Get white balance temperature"},
+  {     BRIGHTNESS_CTRL,      "Get brightness value"},
+  {     EV,      "Get exposure value"},
+  {     CONTRAST_CTRL,      "Get contrast value"},
+  {     SATURATION_CTRL,      "Get saturation value"},
+  {     SHARPNESS_CTRL,      "Get sharpness value"},
+};
+
+const EXP_METERING_TBL_T exp_metering_tbl[] = {
+  {   EXP_METERING_FRAME_AVERAGE,      "Exposure Metering - Frame Average"},
+  {   EXP_METERING_CENTER_WEIGHTED,    "Exposure Metering - Center Weighted"},
+  {   EXP_METERING_SPOT_METERING,      "Exposure Metering - Spot Metering"},
+};
+
+const ISO_TBL_T iso_tbl[] = {
+  {   ISO_AUTO, "ISO: Auto"},
+  {   ISO_DEBLUR, "ISO: Deblur"},
+  {   ISO_100, "ISO: 100"},
+  {   ISO_200, "ISO: 200"},
+  {   ISO_400, "ISO: 400"},
+  {   ISO_800, "ISO: 800"},
+  {   ISO_1600, "ISO: 1600"},
+};
+
+const ZOOM_TBL_T zoom_tbl[] = {
+  {   ZOOM_IN, "Zoom In one step"},
+  {   ZOOM_OUT, "Zoom Out one step"},
+};
+
+
+struct v4l2_fmtdesc enumfmtdesc[MAX_NUM_FORMAT];
+struct v4l2_format current_fmt;
+
+/*===========================================================================
+ * Forward declarations
+ *===========================================================================*/
+static int set_fps(int fps);
+static int start_snapshot (void);
+static int stop_snapshot (void);
+/*===========================================================================
+ * Static global variables
+ *===========================================================================*/
+USER_INPUT_DISPLAY_T input_display;
+static int camframe_status = 0;
+
+#ifdef _ANDROID_
+char *sdcard_path = "/data";
+#else
+char *sdcard_path = ".";
+#endif
+
+//void *libqcamera = NULL;
+//void (**LINK_jpegfragment_callback)(uint8_t * buff_ptr , uint32_t buff_size);
+//void (**LINK_jpeg_callback)(void);
+
+int num_supported_fmts = 0;
+int memoryType = V4L2_MEMORY_MMAP; /* default */
+int preview_video_resolution_flag = 0;
+int effect = CAMERA_EFFECT_OFF;
+int brightness = CAMERA_DEF_BRIGHTNESS;
+int contrast = CAMERA_DEF_CONTRAST;
+int saturation = CAMERA_DEF_SATURATION;
+int sharpness = CAMERA_DEF_SHARPNESS;
+int32_t ev_num = 0;
+uint8_t ezTune = FALSE;
+int pmemThumbnailfd = 0;
+int pmemSnapshotfd = 0;
+int pmemRawSnapshotfd = 0;
+int fdSnapshot = 0;
+int fdThumbnail = 0;
+char snapshotBuf[256] = { 0};
+char thumbnailBuf[256] = { 0};
+uint32_t snapshot_buff_size = 0;
+uint32_t raw_snapshot_buffer_size = 0;
+static int thumbnailCntr = 0, snapshotCntr = 0;
+unsigned char *thumbnail_buf = NULL, *main_img_buf = NULL, *raw_img_buf = NULL;
+int32_t *sharpness_AF = NULL;
+struct crop_info cropInfo;
+common_crop_t cropInfo_s;
+
+interface_ctrl_t intrfcCtrl;
+config3a_wb_t autoWB = CAMERA_WB_AUTO;
+isp3a_af_mode_t af_mode = AF_MODE_AUTO;
+cam_af_focusrect_t afFocusRect = AUTO;
+
+cam_af_ctrl_t af_ctrl;
+camera_iso_mode_type iso = CAMERA_ISO_AUTO;
+camera_antibanding_type antibanding = CAMERA_ANTIBANDING_OFF;
+camera_auto_exposure_mode_type aec_mode = CAMERA_AEC_CENTER_WEIGHTED;
+led_mode_t led_mode = LED_MODE_OFF;
+motion_iso_t motion_iso = MOTION_ISO_OFF;
+int32_t hue = CAMERA_DEF_HUE;
+fps_mode_t fps_mode = FPS_MODE_AUTO;
+
+struct v4l2_cropcap cropcap;
+struct v4l2_queryctrl zoom_queryctrl;
+struct v4l2_queryctrl sharpness_queryctrl;
+int zoom_level;
+
+Camera_Resolution Resolution;
+//int32_t g_camParmInfo_current_value = 0;
+//extern unsigned long preview_frames_buf;
+//extern void test_app_mmcamera_videoframe_callback(struct msm_frame *frame); // video_cam.c
+
+/* To flush free video buffers queue */
+//void (*LINK_cam_frame_flush_free_video)(void);
+static int submain();
+
+//struct v4l2_frame_buffer frames[PREVIEW_FRAMES_NUM];
+//struct v4l2_frame_buffer video_frames[VIDEO_FRAMES_NUM];
+
+//pthread_t frame_thread;
+
+void test_app_camframe_timeout_callback(void)
+{
+  camframe_status = -1;
+}
+
+/*===========================================================================
+ * FUNCTION    - keypress_to_event -
+ *
+ * DESCRIPTION:
+ *==========================================================================*/
+int keypress_to_event(char keypress)
+{
+  char out_buf = INVALID_KEY_PRESS;
+  if ((keypress >= 'A' && keypress <= 'Z') ||
+    (keypress >= 'a' && keypress <= 'z')) {
+    out_buf = tolower(keypress);
+    out_buf = out_buf - 'a' + 1;
+  } else if (keypress >= '1' && keypress <= '9') {
+    out_buf = keypress;
+    out_buf = keypress - '1' + BASE_OFFSET_NUM;
+  }
+  return out_buf;
+}
+
+int next_menu(menu_id_change_t current_menu_id, char keypress, camera_action_t * action_id_ptr, int * action_param)
+{
+  char output_to_event;
+  menu_id_change_t next_menu_id = MENU_ID_INVALID;
+  * action_id_ptr = ACTION_NO_ACTION;
+
+  output_to_event = keypress_to_event(keypress);
+  CDBG("current_menu_id=%d\n",current_menu_id);
+  CDBG("output_to_event=%d\n",output_to_event);
+  switch(current_menu_id) {
+    case MENU_ID_MAIN:
+      switch(output_to_event) {
+        case STOP_CAMERA:
+          * action_id_ptr = ACTION_STOP_CAMERA;
+          CDBG("STOP_CAMERA\n");
+          break;
+
+        case PREVIEW_VIDEO_RESOLUTION:
+          next_menu_id = MENU_ID_PREVIEWVIDEORESOLUTIONCHANGE;
+          CDBG("next_menu_id = MENU_ID_PREVIEWVIDEORESOLUTIONCHANGE = %d\n", next_menu_id);
+          break;
+#if 0
+        case SET_WHITE_BALANCE:
+          next_menu_id = MENU_ID_WHITEBALANCECHANGE;
+          CDBG("next_menu_id = MENU_ID_WHITEBALANCECHANGE = %d\n", next_menu_id);
+          break;
+
+        case SET_EXP_METERING:
+          next_menu_id = MENU_ID_EXPMETERINGCHANGE;
+          CDBG("next_menu_id = MENU_ID_EXPMETERINGCHANGE = %d\n", next_menu_id);
+          break;
+
+        case GET_CTRL_VALUE:
+          next_menu_id = MENU_ID_GET_CTRL_VALUE;
+          CDBG("next_menu_id = MENU_ID_GET_CTRL_VALUE = %d\n", next_menu_id);
+          break;
+
+        case BRIGHTNESS_GOTO_SUBMENU:
+          next_menu_id = MENU_ID_BRIGHTNESSCHANGE;
+          CDBG("next_menu_id = MENU_ID_BRIGHTNESSCHANGE = %d\n", next_menu_id);
+          break;
+
+        case CONTRAST_GOTO_SUBMENU:
+          next_menu_id = MENU_ID_CONTRASTCHANGE;
+          break;
+
+        case EV_GOTO_SUBMENU:
+          next_menu_id = MENU_ID_EVCHANGE;
+          break;
+
+        case SATURATION_GOTO_SUBMENU:
+          next_menu_id = MENU_ID_SATURATIONCHANGE;
+          break;
+
+        case TOGGLE_AFR:
+          * action_id_ptr = ACTION_TOGGLE_AFR;
+          CDBG("next_menu_id = MENU_ID_TOGGLEAFR = %d\n", next_menu_id);
+          break;
+
+        case SET_ISO:
+          next_menu_id = MENU_ID_ISOCHANGE;
+          CDBG("next_menu_id = MENU_ID_ISOCHANGE = %d\n", next_menu_id);
+          break;
+
+        case SET_ZOOM:
+          next_menu_id = MENU_ID_ZOOMCHANGE;
+          CDBG("next_menu_id = MENU_ID_ZOOMCHANGE = %d\n", next_menu_id);
+          break;
+
+        case SET_SHARPNESS:
+          next_menu_id = MENU_ID_SHARPNESSCHANGE;
+          CDBG("next_menu_id = MENU_ID_SHARPNESSCHANGE = %d\n", next_menu_id);
+          break;
+#endif
+        case TAKE_YUV_SNAPSHOT:
+          * action_id_ptr = ACTION_TAKE_YUV_SNAPSHOT;
+          CDBG("Taking YUV snapshot\n");
+          break;
+
+        case TAKE_RAW_SNAPSHOT:
+          * action_id_ptr = ACTION_TAKE_RAW_SNAPSHOT;
+          CDBG("Taking RAW snapshot\n");
+          break;
+        case START_RECORDING:
+          *action_id_ptr = ACTION_START_RECORDING;
+          next_menu_id = MENU_ID_RECORD;
+          CDBG("Start recording\n");
+          break;
+        /*case STOP_RECORDING:
+          * action_id_ptr = ACTION_STOP_RECORDING;
+          CDBG("Stop recording\n");
+          break;*/
+        case SWITCH_CAMERA:
+          next_menu_id = MENU_ID_SWITCHCAMERA;
+          CDBG("SWitch Camera\n");
+          break;
+        case TAKE_ZSL_SNAPSHOT:
+          * action_id_ptr = ACTION_TAKE_ZSL_SNAPSHOT;
+          CDBG("Taking ZSL snapshot\n");
+          break;
+        case START_RDI:
+          * action_id_ptr = ACTION_START_RDI;
+          break;
+        case STOP_RDI:
+          * action_id_ptr = ACTION_STOP_RDI;
+          break;
+        default:
+          next_menu_id = MENU_ID_MAIN;
+          CDBG("next_menu_id = MENU_ID_MAIN = %d\n", next_menu_id);
+          break;
+      }
+      break;
+
+    case MENU_ID_PREVIEWVIDEORESOLUTIONCHANGE:
+      printf("MENU_ID_PREVIEWVIDEORESOLUTIONCHANGE\n");
+      * action_id_ptr = ACTION_PREVIEW_VIDEO_RESOLUTION;
+      if (output_to_event > RESOLUTION_PREVIEW_VIDEO_MAX ||
+        output_to_event < RESOLUTION_MIN) {
+          next_menu_id = current_menu_id;
+      }
+      else {
+        next_menu_id = MENU_ID_MAIN;
+        * action_param = output_to_event;
+      }
+      break;
+
+    case MENU_ID_WHITEBALANCECHANGE:
+      printf("MENU_ID_WHITEBALANCECHANGE\n");
+      * action_id_ptr = ACTION_SET_WHITE_BALANCE;
+      if (output_to_event > 0 &&
+        output_to_event <= sizeof(white_balance_tbl)/sizeof(white_balance_tbl[0])) {
+          next_menu_id = MENU_ID_MAIN;
+          * action_param = output_to_event;
+      }
+      else {
+        next_menu_id = current_menu_id;
+      }
+      break;
+
+    case MENU_ID_EXPMETERINGCHANGE:
+      printf("MENU_ID_EXPMETERINGCHANGE\n");
+      * action_id_ptr = ACTION_SET_EXP_METERING;
+      if (output_to_event > 0 &&
+        output_to_event <= sizeof(exp_metering_tbl)/sizeof(exp_metering_tbl[0])) {
+          next_menu_id = MENU_ID_MAIN;
+          * action_param = output_to_event;
+      }
+      else {
+        next_menu_id = current_menu_id;
+      }
+      break;
+
+    case MENU_ID_GET_CTRL_VALUE:
+      printf("MENU_ID_GET_CTRL_VALUE\n");
+      * action_id_ptr = ACTION_GET_CTRL_VALUE;
+      if (output_to_event > 0 &&
+        output_to_event <= sizeof(get_ctrl_tbl)/sizeof(get_ctrl_tbl[0])) {
+          next_menu_id = MENU_ID_MAIN;
+          * action_param = output_to_event;
+      }
+      else {
+        next_menu_id = current_menu_id;
+      }
+      break;
+
+    case MENU_ID_BRIGHTNESSCHANGE:
+      switch (output_to_event) {
+        case INC_BRIGHTNESS:
+          * action_id_ptr = ACTION_BRIGHTNESS_INCREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+
+        case DEC_BRIGHTNESS:
+          * action_id_ptr = ACTION_BRIGHTNESS_DECREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+
+        default:
+          next_menu_id = MENU_ID_BRIGHTNESSCHANGE;
+          break;
+      }
+      break;
+
+    case MENU_ID_CONTRASTCHANGE:
+      switch (output_to_event) {
+        case INC_CONTRAST:
+          * action_id_ptr = ACTION_CONTRAST_INCREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+
+        case DEC_CONTRAST:
+          * action_id_ptr = ACTION_CONTRAST_DECREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+
+        default:
+          next_menu_id = MENU_ID_CONTRASTCHANGE;
+          break;
+      }
+      break;
+
+    case MENU_ID_EVCHANGE:
+      switch (output_to_event) {
+        case INCREASE_EV:
+          * action_id_ptr = ACTION_EV_INCREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+
+        case DECREASE_EV:
+          * action_id_ptr = ACTION_EV_DECREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+
+        default:
+          next_menu_id = MENU_ID_EVCHANGE;
+          break;
+      }
+      break;
+
+    case MENU_ID_SATURATIONCHANGE:
+      switch (output_to_event) {
+        case INC_SATURATION:
+          * action_id_ptr = ACTION_SATURATION_INCREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+
+        case DEC_SATURATION:
+          * action_id_ptr = ACTION_SATURATION_DECREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+
+        default:
+          next_menu_id = MENU_ID_EVCHANGE;
+          break;
+      }
+      break;
+
+    case MENU_ID_ISOCHANGE:
+      printf("MENU_ID_ISOCHANGE\n");
+      * action_id_ptr = ACTION_SET_ISO;
+      if (output_to_event > 0 &&
+        output_to_event <= sizeof(iso_tbl)/sizeof(iso_tbl[0])) {
+          next_menu_id = MENU_ID_MAIN;
+          * action_param = output_to_event;
+      } else {
+        next_menu_id = current_menu_id;
+      }
+      break;
+
+    case MENU_ID_ZOOMCHANGE:
+      * action_id_ptr = ACTION_SET_ZOOM;
+      if (output_to_event > 0 &&
+        output_to_event <= sizeof(zoom_tbl)/sizeof(zoom_tbl[0])) {
+          next_menu_id = MENU_ID_MAIN;
+          * action_param = output_to_event;
+      } else {
+        next_menu_id = current_menu_id;
+      }
+      break;
+
+    case MENU_ID_SHARPNESSCHANGE:
+      switch (output_to_event) {
+        case INC_SHARPNESS:
+          * action_id_ptr = ACTION_SHARPNESS_INCREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+        case DEC_SHARPNESS:
+          * action_id_ptr = ACTION_SHARPNESS_DECREASE;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+        default:
+          next_menu_id = MENU_ID_SHARPNESSCHANGE;
+          break;
+      }
+      break;
+    case MENU_ID_SWITCHCAMERA:
+      * action_id_ptr = ACTION_SWITCH_CAMERA;
+      if (output_to_event >= 0 &&
+        output_to_event <= sizeof(cam_tbl)/sizeof(cam_tbl[0])) {
+          next_menu_id = MENU_ID_MAIN;
+          * action_param = output_to_event;
+      } else {
+        next_menu_id = current_menu_id;
+      }
+      break;
+   case MENU_ID_RECORD:
+      switch (output_to_event) {
+        case LIVE_SNAPSHOT_MENU:
+          * action_id_ptr = ACTION_TAKE_LIVE_SNAPSHOT;
+          next_menu_id = MENU_ID_RECORD;
+          break;
+
+        default:
+        case STOP_RECORDING_MENU:
+          * action_id_ptr = ACTION_STOP_RECORDING;
+          next_menu_id = MENU_ID_MAIN;
+          break;
+      }
+   default:
+      CDBG("menu id is wrong: %d\n", current_menu_id);
+      break;
+  }
+
+  return next_menu_id;
+}
+
+/*===========================================================================
+ * FUNCTION    - print_menu_preview_video -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+static void print_menu_preview_video(void) {
+  unsigned int i;
+
+  printf("\n");
+  printf("===========================================\n");
+  printf("      Camera is in preview/video mode now        \n");
+  printf("===========================================\n\n");
+
+  char menuNum = 'A';
+  for (i = 0; i < sizeof(camera_main_menu_tbl)/sizeof(camera_main_menu_tbl[0]); i++) {
+    if (i == BASE_OFFSET) {
+      menuNum = '1';
+    }
+
+    printf("%c.  %s\n", menuNum, camera_main_menu_tbl[i].menu_name);
+    menuNum++;
+  }
+
+  printf("\nPlease enter your choice: ");
+
+  return;
+}
+
+static void camera_preview_video_resolution_change_tbl(void) {
+    unsigned int i;
+
+    printf("\n");
+    printf("==========================================================\n");
+    printf("      Camera is in preview/video resolution mode       \n");
+    printf("==========================================================\n\n");
+
+    char previewVideomenuNum = 'A';
+    for (i = 0; i < sizeof(preview_video_dimension_tbl) /
+      sizeof(preview_video_dimension_tbl[0]); i++) {
+        printf("%c.  %s\n", previewVideomenuNum,
+          preview_video_dimension_tbl[i].str_name);
+        previewVideomenuNum++;
+    }
+
+    printf("\nPlease enter your choice for Preview/Video Resolution: ");
+    return;
+}
+
+static void camera_preview_video_wb_change_tbl(void) {
+  unsigned int i;
+  printf("\n");
+  printf("==========================================================\n");
+  printf("      Camera is in white balance change mode       \n");
+  printf("==========================================================\n\n");
+
+  char submenuNum = 'A';
+  for (i = 0 ; i < sizeof(white_balance_tbl) /
+                   sizeof(white_balance_tbl[0]); i++) {
+        //printf("%c.  %s\n", submenuNum, white_balance_tbl[i].wb_name);
+        submenuNum++;
+  }
+  printf("\nPlease enter your choice for White Balance modes: ");
+  return;
+}
+
+static void camera_preview_video_get_ctrl_value_tbl(void) {
+  unsigned int i;
+  printf("\n");
+  printf("==========================================================\n");
+  printf("      Camera is in get control value mode       \n");
+  printf("==========================================================\n\n");
+
+  char submenuNum = 'A';
+  for (i = 0 ; i < sizeof(get_ctrl_tbl) /
+                   sizeof(get_ctrl_tbl[0]); i++) {
+        printf("%c.  %s\n", submenuNum, get_ctrl_tbl[i].get_ctrl_name);
+        submenuNum++;
+  }
+  printf("\nPlease enter your choice for control value you want to get: ");
+  return;
+}
+
+static void camera_preview_video_exp_metering_change_tbl(void) {
+  unsigned int i;
+  printf("\n");
+  printf("==========================================================\n");
+  printf("      Camera is in exposure metering change mode       \n");
+  printf("==========================================================\n\n");
+
+  char submenuNum = 'A';
+  for (i = 0 ; i < sizeof(exp_metering_tbl) /
+                   sizeof(exp_metering_tbl[0]); i++) {
+        printf("%c.  %s\n", submenuNum, exp_metering_tbl[i].exp_metering_name);
+        submenuNum++;
+  }
+  printf("\nPlease enter your choice for exposure metering modes: ");
+  return;
+}
+
+static void camera_contrast_change_tbl(void) {
+    unsigned int i;
+
+    printf("\n");
+    printf("==========================================================\n");
+    printf("      Camera is in change contrast resolution mode       \n");
+    printf("==========================================================\n\n");
+
+    char contrastmenuNum = 'A';
+    for (i = 0; i < sizeof(contrast_change_tbl) /
+                    sizeof(contrast_change_tbl[0]); i++) {
+        printf("%c.  %s\n", contrastmenuNum,
+                            contrast_change_tbl[i].contrast_name);
+        contrastmenuNum++;
+    }
+
+    printf("\nPlease enter your choice for contrast Change: ");
+    return;
+}
+
+static void camera_EV_change_tbl(void) {
+  unsigned int i;
+
+  printf("\n");
+  printf("===========================================\n");
+  printf("      Camera is in EV change mode now       \n");
+  printf("===========================================\n\n");
+
+  char submenuNum = 'A';
+  for (i = 0; i < sizeof(camera_EV_tbl)/sizeof(camera_EV_tbl[0]); i++) {
+    printf("%c.  %s\n", submenuNum, camera_EV_tbl[i].EV_name);
+    submenuNum++;
+  }
+
+  printf("\nPlease enter your choice for EV changes: ");
+  return;
+}
+
+static void camera_preview_video_zoom_change_tbl(void) {
+  unsigned int i;
+  struct v4l2_control ctrl;
+
+  memset(&ctrl, 0, sizeof(ctrl));
+  ctrl.id = V4L2_CID_ZOOM_ABSOLUTE;
+#if 0 /* TBD */
+  if (ioctl(camfd, VIDIOC_G_CTRL, &ctrl) >= 0) {
+    zoom_level = ctrl.value;
+    printf("\n");
+    printf("==========================================================\n");
+    printf("      Camera is in zoom change mode: %d,  [%d..%d]        \n",
+        ctrl.value, zoom_queryctrl.minimum, zoom_queryctrl.maximum);
+    printf("==========================================================\n\n");
+
+    char submenuNum = 'A';
+    for (i = 0 ; i < sizeof(zoom_tbl) /
+                   sizeof(zoom_tbl[0]); i++) {
+        printf("%c.  %s\n", submenuNum, zoom_tbl[i].zoom_direction_name);
+        submenuNum++;
+    }
+    printf("\nPlease enter your choice for zoom change direction: ");
+  } else {
+    printf("\nVIDIOC_G_CTRL error: %d\n", errno);
+  }
+#endif /* TBD */
+  return;
+}
+
+static void camera_brightness_change_tbl(void) {
+    unsigned int i;
+
+    printf("\n");
+    printf("==========================================================\n");
+    printf("      Camera is in change brightness mode       \n");
+    printf("==========================================================\n\n");
+
+    char brightnessmenuNum = 'A';
+    for (i = 0; i < sizeof(brightness_change_tbl) /
+                    sizeof(brightness_change_tbl[0]); i++) {
+        printf("%c.  %s\n", brightnessmenuNum,
+                            brightness_change_tbl[i].brightness_name);
+        brightnessmenuNum++;
+    }
+
+    printf("\nPlease enter your choice for Brightness Change: ");
+    return;
+}
+
+static void camera_saturation_change_tbl(void) {
+    unsigned int i;
+
+    printf("\n");
+    printf("==========================================================\n");
+    printf("      Camera is in change saturation mode       \n");
+    printf("==========================================================\n\n");
+
+    char saturationmenuNum = 'A';
+    for (i = 0; i < sizeof(camera_saturation_tbl) /
+                    sizeof(camera_saturation_tbl[0]); i++) {
+        printf("%c.  %s\n", saturationmenuNum,
+                            camera_saturation_tbl[i].saturation_name);
+        saturationmenuNum++;
+    }
+
+    printf("\nPlease enter your choice for Saturation Change: ");
+    return;
+}
+
+char * set_preview_video_dimension_tbl(Camera_Resolution cs_id, uint16_t * width, uint16_t * height)
+{
+  unsigned int i;
+  char * ptr = NULL;
+  for (i = 0; i < sizeof(preview_video_dimension_tbl) /
+    sizeof(preview_video_dimension_tbl[0]); i++) {
+      if (cs_id == preview_video_dimension_tbl[i].cs_id) {
+        *width = preview_video_dimension_tbl[i].width;
+        *height = preview_video_dimension_tbl[i].height;
+        ptr = preview_video_dimension_tbl[i].name;
+        break;
+      }
+  }
+  return ptr;
+}
+
+static void camera_preview_video_iso_change_tbl(void) {
+  unsigned int i;
+  printf("\n");
+  printf("==========================================================\n");
+  printf("      Camera is in ISO change mode       \n");
+  printf("==========================================================\n\n");
+
+  char submenuNum = 'A';
+  for (i = 0 ; i < sizeof(iso_tbl) /
+                   sizeof(iso_tbl[0]); i++) {
+        printf("%c.  %s\n", submenuNum, iso_tbl[i].iso_modes_name);
+        submenuNum++;
+  }
+  printf("\nPlease enter your choice for iso modes: ");
+  return;
+}
+
+static void camera_preview_video_sharpness_change_tbl(void) {
+  unsigned int i;
+  printf("\n");
+  printf("==========================================================\n");
+  printf("      Camera is in sharpness change mode       \n");
+  printf("==========================================================\n\n");
+
+  char submenuNum = 'A';
+  for (i = 0 ; i < sizeof(camera_sharpness_tbl) /
+                   sizeof(camera_sharpness_tbl[0]); i++) {
+        printf("%c.  %s\n", submenuNum, camera_sharpness_tbl[i].sharpness_name);
+        submenuNum++;
+  }
+  printf("\nPlease enter your choice for sharpness modes: ");
+  return;
+}
+
+static void camera_record_tbl(void) {
+  unsigned int i;
+  printf("\n");
+  printf("==========================================================\n");
+  printf("      Camera is in record mode       \n");
+  printf("==========================================================\n\n");
+
+  char submenuNum = 'A';
+  for (i = 0 ; i < sizeof(record_tbl) /
+                   sizeof(record_tbl[0]); i++) {
+        printf("%c.  %s\n", submenuNum, record_tbl[i].act_name);
+        submenuNum++;
+  }
+  printf("\nPlease enter your choice:  ");
+  return;
+}
+
+static void camera_switch_tbl(void) {
+  unsigned int i;
+  printf("\n");
+  printf("==========================================================\n");
+  printf("      Camera is in switch camera mode       \n");
+  printf("==========================================================\n\n");
+
+  char submenuNum = 'A';
+  for (i = 0 ; i < sizeof(cam_tbl) /
+                   sizeof(cam_tbl[0]); i++) {
+        printf("%c.  %s\n", submenuNum, cam_tbl[i].cam_name);
+        submenuNum++;
+  }
+  printf("\nPlease enter your choice for camera modes: ");
+  return;
+}
+/*===========================================================================
+ * FUNCTION     - increase_contrast -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int increase_contrast (void) {
+  ++contrast;
+  if (contrast > CAMERA_MAX_CONTRAST) {
+    contrast = CAMERA_MAX_CONTRAST;
+    printf("Reached max CONTRAST. \n");
+  } else
+    printf("Increase CONTRAST to %d\n", contrast);
+
+  /*intrfcCtrl.setContrast(camfd, contrast);*/
+
+  struct v4l2_queryctrl queryctrl;
+  struct v4l2_control control;
+
+  memset (&queryctrl, 0, sizeof (queryctrl));
+  queryctrl.id = V4L2_CID_CONTRAST;
+#if 0 /* TBD */
+  if (-1 == ioctl (camfd, VIDIOC_QUERYCTRL, &queryctrl)) {
+    if (errno != EINVAL) {
+      perror ("VIDIOC_QUERYCTRL");
+      exit (EXIT_FAILURE);
+    } else {
+      printf ("V4L2_CID_contrast is not supported\n");
+    }
+  } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+    printf ("V4L2_CID_contrast is not supported\n");
+  } else {
+    memset (&control, 0, sizeof (control));
+    control.id = V4L2_CID_CONTRAST;
+    /* Decreasing the contrast */
+    control.value = contrast;
+
+ //   if (-1 == ioctl (camfd, VIDIOC_S_CTRL, &control)) {
+ //     perror ("VIDIOC_S_CTRL");
+ //     return -1;
+ //   }
+  }
+#endif /* TBD */
+  return 0;
+}
+
+/*===========================================================================
+ * FUNCTION     - decrease_contrast -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int decrease_contrast (void) {
+  --contrast;
+  if (contrast < CAMERA_MIN_CONTRAST) {
+    contrast = CAMERA_MIN_CONTRAST;
+    printf("Reached min CONTRAST. \n");
+  } else
+    printf("Decrease CONTRAST to %d\n", contrast);
+
+  /*intrfcCtrl.setContrast(camfd, contrast);*/
+  struct v4l2_queryctrl queryctrl;
+  struct v4l2_control control;
+
+  memset (&queryctrl, 0, sizeof (queryctrl));
+  queryctrl.id = V4L2_CID_CONTRAST;
+#if 0 /* TBD */
+  if (-1 == ioctl (camfd, VIDIOC_QUERYCTRL, &queryctrl)) {
+    if (errno != EINVAL) {
+      perror ("VIDIOC_QUERYCTRL");
+      exit (EXIT_FAILURE);
+    } else {
+      printf ("V4L2_CID_contrast is not supported\n");
+    }
+  } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+    printf ("V4L2_CID_contrast is not supported\n");
+  } else {
+    memset (&control, 0, sizeof (control));
+    control.id = V4L2_CID_CONTRAST;
+    /* Decreasing the contrast */
+    control.value = contrast;
+
+  //  if (-1 == ioctl (camfd, VIDIOC_S_CTRL, &control)) {
+  //    perror ("VIDIOC_S_CTRL");
+  //    return -1;
+  //  }
+  }
+#endif /* TBD */
+  return 0;
+}
+
+/*===========================================================================
+ * FUNCTION     - decrease_brightness -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int decrease_brightness (void) {
+  brightness -= CAMERA_BRIGHTNESS_STEP;
+  if (brightness < CAMERA_MIN_BRIGHTNESS) {
+    brightness = CAMERA_MIN_BRIGHTNESS;
+    printf("Reached min BRIGHTNESS. \n");
+  } else
+    printf("Decrease BRIGHTNESS to %d\n", brightness);
+
+  struct v4l2_queryctrl queryctrl;
+  struct v4l2_control control;
+
+  memset (&queryctrl, 0, sizeof (queryctrl));
+  queryctrl.id = V4L2_CID_BRIGHTNESS;
+#if 0 /* TBD */
+  if (-1 == ioctl (camfd, VIDIOC_QUERYCTRL, &queryctrl)) {
+    if (errno != EINVAL) {
+      perror ("VIDIOC_QUERYCTRL");
+      exit (EXIT_FAILURE);
+    } else {
+      printf ("V4L2_CID_BRIGHTNESS is not supported\n");
+    }
+  } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+    printf ("V4L2_CID_BRIGHTNESS is not supported\n");
+  } else {
+    memset (&control, 0, sizeof (control));
+    control.id = V4L2_CID_BRIGHTNESS;
+    /* Decreasing the Brightness */
+    control.value = brightness;
+
+    if (-1 == ioctl (camfd, VIDIOC_S_CTRL, &control)) {
+      perror ("VIDIOC_S_CTRL");
+      return -1;
+    }
+  }
+#endif /* TBD */
+  return 0;
+}
+
+/*===========================================================================
+ * FUNCTION     - increase_brightness -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int increase_brightness (void) {
+  brightness += CAMERA_BRIGHTNESS_STEP;
+  if (brightness > CAMERA_MAX_BRIGHTNESS) {
+    brightness = CAMERA_MAX_BRIGHTNESS;
+    printf("Reached max BRIGHTNESS. \n");
+  } else
+    printf("Increase BRIGHTNESS to %d\n", brightness);
+
+  struct v4l2_queryctrl queryctrl;
+  struct v4l2_control control;
+
+  memset (&queryctrl, 0, sizeof (queryctrl));
+  queryctrl.id = V4L2_CID_BRIGHTNESS;
+#if 0 /* TBD */
+  if (-1 == ioctl (camfd, VIDIOC_QUERYCTRL, &queryctrl)) {
+    if (errno != EINVAL) {
+      perror ("VIDIOC_QUERYCTRL");
+      exit (EXIT_FAILURE);
+    } else {
+      printf ("V4L2_CID_BRIGHTNESS is not supported\n");
+    }
+  } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+    printf ("V4L2_CID_BRIGHTNESS is not supported\n");
+  } else {
+    memset (&control, 0, sizeof (control));
+    control.id = V4L2_CID_BRIGHTNESS;
+    /* Increasing the Brightness */
+    control.value = brightness;
+
+    if (-1 == ioctl (camfd, VIDIOC_S_CTRL, &control)) {
+      perror ("VIDIOC_S_CTRL");
+      return -1;
+    }
+  }
+#endif /* TBD */
+  return 0;
+}
+
+/*===========================================================================
+ * FUNCTION     - increase_EV -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int increase_EV (void) {
+  int32_t ev = 0;
+  if (++ev_num <= 12) {
+     ev = (ev_num << 16) | 6;
+    printf("Increase EV to %d\n", ev_num);
+  } else {
+    printf("Reached max EV. \n");
+    ev = ev_num;
+  }
+
+  struct v4l2_queryctrl queryctrl;
+  struct v4l2_control control;
+
+  memset (&queryctrl, 0, sizeof (queryctrl));
+  queryctrl.id = V4L2_CID_EXPOSURE;
+#if 0 /* TBD */
+  if (-1 == ioctl (camfd, VIDIOC_QUERYCTRL, &queryctrl)) {
+    if (errno != EINVAL) {
+      perror ("VIDIOC_QUERYCTRL");
+      exit (EXIT_FAILURE);
+    } else {
+      printf ("V4L2_CID_EXPOSURE is not supported\n");
+    }
+  } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+    printf ("V4L2_CID_EXPOSURE is not supported\n");
+  } else {
+    memset (&control, 0, sizeof (control));
+    control.id = V4L2_CID_EXPOSURE;
+    /* Increasing the EV*/
+    control.value = ev;
+
+    if (-1 == ioctl (camfd, VIDIOC_S_CTRL, &control)) {
+      perror ("VIDIOC_S_CTRL");
+      return -1;
+    }
+  }
+#endif /* TBD */
+  return 0;
+}
+
+/*===========================================================================
+ * FUNCTION     - decrease_EV -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int decrease_EV (void) {
+  int32_t ev = 0;
+  if (--ev_num > -12) {
+    ev = (ev_num << 16) | 6;
+    printf("Decrease EV to %d\n", ev_num);
+  } else {
+    printf("Reached min EV. \n");
+    ev = ev_num;
+  }
+
+  struct v4l2_queryctrl queryctrl;
+  struct v4l2_control control;
+
+  memset (&queryctrl, 0, sizeof (queryctrl));
+  queryctrl.id = V4L2_CID_EXPOSURE;
+#if 0 /* TBD */
+  if (-1 == ioctl (camfd, VIDIOC_QUERYCTRL, &queryctrl)) {
+    if (errno != EINVAL) {
+      perror ("VIDIOC_QUERYCTRL");
+      exit (EXIT_FAILURE);
+    } else {
+      printf ("V4L2_CID_EXPOSURE is not supported\n");
+    }
+  } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+    printf ("V4L2_CID_EXPOSURE is not supported\n");
+  } else {
+    memset (&control, 0, sizeof (control));
+    control.id = V4L2_CID_EXPOSURE;
+    /* Increasing the EV*/
+    control.value = ev;
+
+    if (-1 == ioctl (camfd, VIDIOC_S_CTRL, &control)) {
+      perror ("VIDIOC_S_CTRL");
+      return -1;
+    }
+  }
+#endif /* TBD */
+  return 0;
+}
+
+/*===========================================================================
+ * FUNCTION     - increase_contrast -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int increase_saturation (void) {
+  ++saturation;
+  if (saturation > CAMERA_MAX_SATURATION) {
+    saturation = CAMERA_MAX_SATURATION;
+    printf("Reached max saturation. \n");
+  } else
+    printf("Increase saturation to %d\n", saturation);
+
+  /*intrfcCtrl.setContrast(camfd, contrast);*/
+
+  struct v4l2_queryctrl queryctrl;
+  struct v4l2_control control;
+
+  memset (&queryctrl, 0, sizeof (queryctrl));
+  queryctrl.id = V4L2_CID_SATURATION;
+#if 0 /* TBD */
+  if (-1 == ioctl (camfd, VIDIOC_QUERYCTRL, &queryctrl)) {
+    if (errno != EINVAL) {
+      perror ("VIDIOC_QUERYCTRL");
+      exit (EXIT_FAILURE);
+    } else {
+      printf ("V4L2_CID_saturation is not supported\n");
+    }
+  } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+    printf ("V4L2_CID_saturation is not supported\n");
+  } else {
+    memset (&control, 0, sizeof (control));
+    control.id = V4L2_CID_SATURATION;
+    /* Decreasing the contrast */
+    control.value = saturation;
+
+    if (-1 == ioctl (camfd, VIDIOC_S_CTRL, &control)) {
+      perror ("VIDIOC_S_CTRL");
+      return -1;
+    }
+  }
+#endif /* TBD */
+  return 0;
+}
+
+/*===========================================================================
+ * FUNCTION     - decrease_saturation -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int decrease_saturation (void) {
+  --saturation;
+  if (saturation < CAMERA_MIN_SATURATION) {
+    saturation = CAMERA_MIN_SATURATION;
+    printf("Reached min saturation. \n");
+  } else
+    printf("Decrease saturation to %d\n", saturation);
+
+  /*intrfcCtrl.setContrast(camfd, contrast);*/
+  struct v4l2_queryctrl queryctrl;
+  struct v4l2_control control;
+
+  memset (&queryctrl, 0, sizeof (queryctrl));
+  queryctrl.id = V4L2_CID_SATURATION;
+#if 0 /* TBD */
+  if (-1 == ioctl (camfd, VIDIOC_QUERYCTRL, &queryctrl)) {
+    if (errno != EINVAL) {
+      perror ("VIDIOC_QUERYCTRL");
+      exit (EXIT_FAILURE);
+    } else {
+      printf ("V4L2_CID_saturation is not supported\n");
+    }
+  } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+    printf ("V4L2_CID_saturation is not supported\n");
+  } else {
+    memset (&control, 0, sizeof (control));
+    control.id = V4L2_CID_SATURATION;
+    /* Decreasing the contrast */
+    control.value = saturation;
+
+    if (-1 == ioctl (camfd, VIDIOC_S_CTRL, &control)) {
+      perror ("VIDIOC_S_CTRL");
+      return -1;
+    }
+  }
+#endif /* TBD */
+  return 0;
+}
+
+int takePicture_yuv(int cam_id)
+{
+  int rc = 0;
+  CDBG("%s:BEGIN\n", __func__);
+  if(0 != (rc = mm_app_take_picture(cam_id))) {
+    CDBG_ERROR("%s: mm_app_take_picture() err=%d\n", __func__, rc);
+  }
+  return rc;
+}
+
+int takePicture_zsl(int cam_id)
+{
+  int rc = 0;
+  CDBG("%s:BEGIN\n", __func__);
+  if(0 != (rc = mm_app_take_zsl(cam_id))) {
+    CDBG_ERROR("%s: mm_app_take_picture() err=%d\n", __func__, rc);
+  }
+  return rc;
+}
+
+int takePicture_live(int cam_id)
+{
+  int rc = 0;
+  CDBG("%s:BEGIN\n", __func__);
+  if(0 != (rc = mm_app_take_live_snapshot(cam_id))) {
+    CDBG_ERROR("%s: mm_app_take_picture() err=%d\n", __func__, rc);
+  }
+  return rc;
+}
+
+int takePicture_raw(int cam_id)
+{
+  int rc = 0;
+  CDBG("%s:BEGIN\n", __func__);
+  if(0 != (rc = mm_app_take_raw_picture(cam_id))) {
+    CDBG("%s: mm_app_take_raw_picture() err=%d\n", __func__, rc);
+  }
+  return rc;
+}
+int system_dimension_set(int cam_id)
+{
+  static cam_ctrl_dimension_t dim;
+  int rc = 0;
+
+  if (preview_video_resolution_flag == 0) {
+    mm_app_set_dim_def(&dim);
+  } else {
+    dim.video_width = input_display.user_input_display_width;
+    dim.video_width = CEILING32(dim.video_width);
+    dim.video_height = input_display.user_input_display_height;
+    dim.orig_video_width = dim.video_width;
+    dim.orig_video_height = dim.video_height;
+    dim.display_width = dim.video_width;
+    dim.display_height = dim.video_height;
+  }
+  rc = mm_app_set_dim(cam_id, &dim);
+  return rc;
+}
+
+/*int run_test_harness()
+{
+    int good_test_cnt = 0;
+
+    rc = run_test_1();
+    if(rc < 0) 
+        CDBG_EROR("%s: run_test_1 err = %d", __func__, rc);
+    rc = run_test_2();
+}*/
+/*===========================================================================
+ * FUNCTION    - main -
+ *
+ * DESCRIPTION:
+ *==========================================================================*/
+int main(int argc, char **argv)
+{
+  int keep_on_going = 1;
+  int c, rc = 0, tmp_fd;
+  int run_tc = 0;
+  int run_dual_tc = 0;
+  struct v4l2_capability v4l2_cap;
+
+  /* get v4l2 params - memory type etc */
+  while ((c = getopt(argc, argv, "tdh")) != -1) {
+    //printf("usage: %s [-m] [-u] [-o]\n", argv[1]);
+    switch (c) {
+#if 0
+      case 'm':
+        memoryType = V4L2_MEMORY_MMAP;
+        break;
+
+      case 'o':
+        /*use_overlay_fb_display_driver();*/
+        break;
+      case 'u':
+        memoryType = V4L2_MEMORY_USERPTR;
+        break;
+#endif
+      case 't':
+        run_tc = 1;
+        break;
+      case 'd':
+        run_dual_tc = 1;
+        break;
+      case 'h':
+      default:
+        printf("usage: %s [-m] [-u] [-o]\n", argv[0]);
+        printf("-m:   V4L2_MEMORY_MMAP.      \n");
+        printf("-o:   use overlay fb display driver\n");
+        printf("-u:   V4L2_MEMORY_USERPTR\n");
+        exit(0);
+    }
+  }
+
+  CDBG("\nCamera Test Application\n");
+
+  struct timeval tdBeforePreviewVideo, tdStopCamera;
+  struct timezone tz;
+
+  //return run_test_harness();
+  if((rc = mm_app_load_hal())) {
+    CDBG_ERROR("%s:mm_app_init err=%d\n", __func__, rc);
+    exit(-1);
+  }
+    /* we must init mm_app first */
+  if(mm_app_init() != MM_CAMERA_OK) {
+    CDBG_ERROR("%s:mm_app_init err=%d\n", __func__, rc);
+    exit(-1);
+  }
+
+  if(run_tc) {
+    printf("\tRunning unit test engine only\n");
+    rc = mm_app_unit_test();
+    printf("\tUnit test engine. EXIT(%d)!!!\n", rc);
+    exit(rc);
+  }
+
+  if(run_dual_tc) {
+    printf("\tRunning Dual camera test engine only\n");
+    rc = mm_app_dual_test();
+    printf("\t Dual camera engine. EXIT(%d)!!!\n", rc);
+    exit(rc);
+  }
+
+  gettimeofday(&tdBeforePreviewVideo, &tz);
+
+  CDBG("Profiling: Start Camera timestamp = %ld ms\n",
+    (tdBeforePreviewVideo.tv_sec * 1000) + (tdBeforePreviewVideo.tv_usec/1000));
+
+  /* launch the primary camera in default mode */
+  if( mm_app_open(CAMERA_OPENED)) {
+    CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
+    exit(-2);
+  }
+
+  /* main loop doing the work*/
+  do {
+    keep_on_going = submain();
+  } while ( keep_on_going );
+
+  /* Clean up and exit. */
+  CDBG("Exiting the app\n");
+
+error_ionfd_open:
+  mm_app_close(CAMERA_OPENED);
+
+  gettimeofday(&tdStopCamera, &tz);
+  CDBG("Exiting application\n");
+  CDBG("Profiling: Stop camera end timestamp = %ld ms\n",
+      (tdStopCamera.tv_sec * 1000) + (tdStopCamera.tv_usec/1000));
+
+  return 0;
+}
+
+
+/*===========================================================================
+ * FUNCTION     - submain -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+static int submain()
+{
+  int rc = 0;
+  int back_mainflag = 0;
+  char tc_buf[3];
+  int stop_preview = 1;
+  menu_id_change_t current_menu_id = MENU_ID_MAIN, next_menu_id;
+  camera_action_t action_id;
+  int action_param;
+  int i;
+  int cam_id;
+
+  CDBG("%s:E", __func__);
+  struct timeval tdStopCamera;
+  struct timezone tz;
+
+  cam_id = my_cam_app.cam_open;
+
+  rc = system_dimension_set(cam_id);
+  CDBG("Start Preview");
+  if( 0 != (rc = startPreview(cam_id))) {
+    CDBG("%s: startPreview() err=%d\n", __func__, rc);
+    return 0;
+  }
+
+  do {
+    print_current_menu (current_menu_id);
+    fgets(tc_buf, 3, stdin);
+
+    next_menu_id = next_menu(current_menu_id, tc_buf[0], &action_id, &action_param);
+
+    if (next_menu_id != MENU_ID_INVALID) {
+      current_menu_id = next_menu_id;
+    }
+    if (action_id == ACTION_NO_ACTION) {
+      continue;
+    }
+    if(camframe_status == -1) {
+      printf("Preview/Video ERROR condition reported Closing Camera APP\n");
+      break;
+    }
+
+    switch(action_id) {
+      case ACTION_STOP_CAMERA:
+        CDBG("ACTION_STOP_CAMERA \n");
+        stopPreview(cam_id);
+        break;
+
+      case ACTION_PREVIEW_VIDEO_RESOLUTION:
+        back_mainflag = 1;
+        CDBG("Selection for the preview/video resolution change\n");
+        switchRes(cam_id);
+        preview_video_resolution (action_param);
+        break;
+      case ACTION_SET_WHITE_BALANCE:
+        CDBG("Selection for the White Balance changes\n");
+        set_whitebalance(action_param);
+        break;
+
+      case ACTION_SET_EXP_METERING:
+        CDBG("Selection for the Exposure Metering changes\n");
+        set_exp_metering(action_param);
+        break;
+
+      case ACTION_GET_CTRL_VALUE:
+        CDBG("Selection for getting control value\n");
+        get_ctrl_value(action_param);
+        break;
+
+      case ACTION_BRIGHTNESS_INCREASE:
+        printf("Increase brightness\n");
+        increase_brightness();
+        break;
+
+      case ACTION_BRIGHTNESS_DECREASE:
+        printf("Decrease brightness\n");
+        decrease_brightness();
+        break;
+
+      case ACTION_CONTRAST_INCREASE:
+        CDBG("Selection for the contrast increase\n");
+        increase_contrast ();
+        break;
+
+      case ACTION_CONTRAST_DECREASE:
+        CDBG("Selection for the contrast decrease\n");
+        decrease_contrast ();
+        break;
+
+      case ACTION_EV_INCREASE:
+        CDBG("Selection for the EV increase\n");
+        increase_EV ();
+        break;
+
+      case ACTION_EV_DECREASE:
+        CDBG("Selection for the EV decrease\n");
+        decrease_EV ();
+        break;
+
+      case ACTION_SATURATION_INCREASE:
+        CDBG("Selection for the EV increase\n");
+        increase_saturation ();
+        break;
+
+      case ACTION_SATURATION_DECREASE:
+        CDBG("Selection for the EV decrease\n");
+        decrease_saturation ();
+        break;
+
+      case ACTION_TOGGLE_AFR:
+        CDBG("Select for auto frame rate toggling\n");
+        toggle_afr();
+        break;
+
+      case ACTION_SET_ISO:
+        CDBG("Select for ISO changes\n");
+        set_iso(action_param);
+        break;
+
+      case ACTION_SET_ZOOM:
+        CDBG("Selection for the zoom direction changes\n");
+        set_zoom(action_param);
+        break;
+
+      case ACTION_SHARPNESS_INCREASE:
+        CDBG("Selection for sharpness increase\n");
+        increase_sharpness();
+        break;
+
+      case ACTION_SHARPNESS_DECREASE:
+        CDBG("Selection for sharpness decrease\n");
+        decrease_sharpness();
+        break;
+
+      case ACTION_TAKE_YUV_SNAPSHOT:
+        CDBG("Take YUV snapshot\n");
+        if (takePicture_yuv(cam_id) < 0)
+          goto ERROR;
+        break;
+      case ACTION_TAKE_RAW_SNAPSHOT:
+        CDBG("Take YUV snapshot\n");
+        if (takePicture_raw(cam_id) < 0)
+          goto ERROR;
+        break;
+      case ACTION_START_RECORDING:
+        CDBG("Start recording action\n");
+        if (startRecording(cam_id) < 0)
+          goto ERROR;
+        break;
+      case ACTION_STOP_RECORDING:
+        CDBG("Stop recording action\n");
+        if (stopRecording(cam_id) < 0)
+          goto ERROR;
+        break;
+      case ACTION_NO_ACTION:
+        printf("Go back to main menu");
+        break;
+      case ACTION_SWITCH_CAMERA:
+        CDBG("Toggle Camera action\n");
+        back_mainflag = 1;
+        if (switchCamera(action_param - 1) < 0)
+          goto ERROR;
+        break;
+
+      case ACTION_TAKE_ZSL_SNAPSHOT:
+        CDBG("Take ZSL snapshot\n");
+        if (takePicture_zsl(cam_id) < 0)
+        {
+          CDBG("Error");    
+          goto ERROR;
+        }
+        break;
+      case ACTION_START_RDI:
+		CDBG("Start RDI Stream\n");
+		startRdi(cam_id);
+		break;
+	  case ACTION_STOP_RDI:
+		CDBG("Stop RDI Stream\n");
+		stopRdi(cam_id);
+		break;
+      case ACTION_TAKE_LIVE_SNAPSHOT:
+        CDBG("Take Live snapshot\n");
+        if (takePicture_live(cam_id) < 0)
+        {
+          CDBG("Error");    
+          goto ERROR;
+        }
+        break;
+
+      default:
+        printf("\n\n!!!!!WRONG INPUT: %d!!!!\n", action_id);
+        break;
+    }
+
+    usleep(1000 * 1000);
+    CDBG("action_id = %d\n", action_id);
+    camframe_status = 0;
+
+  } while ((action_id != ACTION_STOP_CAMERA) &&
+      (action_id != ACTION_PREVIEW_VIDEO_RESOLUTION) && (action_id !=ACTION_SWITCH_CAMERA));
+  action_id = ACTION_NO_ACTION;
+
+  //system_destroy();
+
+
+  return back_mainflag;
+
+ERROR:
+  back_mainflag = 0;
+  return back_mainflag;
+}
+
+
+/*===========================================================================
+ * FUNCTION     - preview_resolution -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int preview_video_resolution (int preview_video_action_param) {
+  char * resolution_name;
+  CDBG("Selecting the action for preview/video resolution = %d \n", preview_video_action_param);
+  resolution_name = set_preview_video_dimension_tbl(preview_video_action_param,
+                      & input_display.user_input_display_width,
+                      & input_display.user_input_display_height);
+
+  CDBG("Selected preview/video resolution is %s\n", resolution_name);
+
+  if (resolution_name == NULL) {
+    CDBG("main:%d set_preview_dimension failed!\n", __LINE__);
+    goto ERROR;
+  }
+
+  CDBG("Selected Preview Resolution: display_width = %d, display_height = %d\n",
+    input_display.user_input_display_width, input_display.user_input_display_height);
+
+  preview_video_resolution_flag = 1;
+  return 0;
+
+ERROR:
+  return -1;
+}
+
+/*===========================================================================
+ * FUNCTION     - set_whitebalance -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int set_whitebalance (int wb_action_param) {
+
+	int rc = 0;
+	struct v4l2_control ctrl;
+
+  if (wb_action_param == MM_CAMERA_WHITE_BALANCE_AUTO) {
+		ctrl.id = V4L2_CID_AUTO_WHITE_BALANCE;
+		ctrl.value = TRUE;
+	//	rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+
+	} else if ( wb_action_param == MM_CAMERA_WHITE_BALANCE_OFF) {
+		ctrl.id = V4L2_CID_AUTO_WHITE_BALANCE;
+		ctrl.value = FALSE;
+	//	rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+
+  } else {
+		int temperature = 6500;
+
+		switch (wb_action_param) {
+			case MM_CAMERA_WHITE_BALANCE_DAYLIGHT:
+				temperature = 6500;
+				break;
+			case MM_CAMERA_WHITE_BALANCE_INCANDESCENT:
+				temperature = 2800;
+				break;
+			case MM_CAMERA_WHITE_BALANCE_FLUORESCENT:
+				temperature = 4200;
+				break;
+			default:
+				temperature = 4200;
+				break;
+		}
+
+		ctrl.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
+		ctrl.value = temperature;
+	//	rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+	}
+
+DONE:
+	return rc;
+}
+
+
+/*===========================================================================
+ * FUNCTION     - set_exp_metering -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int set_exp_metering (int exp_metering_action_param) {
+
+	int rc = 0;
+	struct v4l2_control ctrl;
+
+  ctrl.id = MSM_V4L2_PID_EXP_METERING;
+  ctrl.value = exp_metering_action_param;
+ // rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+
+  return rc;
+}
+
+int get_ctrl_value (int ctrl_value_mode_param){
+
+    int rc = 0;
+    struct v4l2_control ctrl;
+
+    if (ctrl_value_mode_param == WHITE_BALANCE_STATE) {
+        printf("You chose WHITE_BALANCE_STATE\n");
+        ctrl.id = V4L2_CID_AUTO_WHITE_BALANCE;
+    }
+    else if (ctrl_value_mode_param == WHITE_BALANCE_TEMPERATURE) {
+        printf("You chose WHITE_BALANCE_TEMPERATURE\n");
+        ctrl.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
+    }
+    else if (ctrl_value_mode_param == BRIGHTNESS_CTRL) {
+        printf("You chose brightness value\n");
+        ctrl.id = V4L2_CID_BRIGHTNESS;
+    }
+    else if (ctrl_value_mode_param == EV) {
+        printf("You chose exposure value\n");
+        ctrl.id = V4L2_CID_EXPOSURE;
+    }
+    else if (ctrl_value_mode_param == CONTRAST_CTRL) {
+        printf("You chose contrast value\n");
+        ctrl.id = V4L2_CID_CONTRAST;
+    }
+    else if (ctrl_value_mode_param == SATURATION_CTRL) {
+        printf("You chose saturation value\n");
+        ctrl.id = V4L2_CID_SATURATION;
+    } else if (ctrl_value_mode_param == SHARPNESS_CTRL) {
+        printf("You chose sharpness value\n");
+        ctrl.id = V4L2_CID_SHARPNESS;
+    }
+
+  //  rc = ioctl(camfd, VIDIOC_G_CTRL, &ctrl);
+
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION     - toggle_afr -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int toggle_afr () {
+  int rc = 0;
+  struct v4l2_control ctrl;
+
+  memset(&ctrl, 0, sizeof(ctrl));
+  ctrl.id = V4L2_CID_EXPOSURE_AUTO;
+//  rc = ioctl(camfd, VIDIOC_G_CTRL, &ctrl);
+  if (rc == -1) {
+    CDBG("%s: VIDIOC_G_CTRL V4L2_CID_EXPOSURE_AUTO failed: %s\n",
+        __func__, strerror(errno));
+    return rc;
+  }
+
+  /* V4L2_CID_EXPOSURE_AUTO needs to be AUTO or SHUTTER_PRIORITY */
+  if (ctrl.value != V4L2_EXPOSURE_AUTO &&
+    ctrl.value != V4L2_EXPOSURE_SHUTTER_PRIORITY) {
+    CDBG("%s: V4L2_CID_EXPOSURE_AUTO needs to be AUTO/SHUTTER_PRIORITY\n",
+        __func__);
+    return -1;
+  }
+
+  /* Get V4L2_CID_EXPOSURE_AUTO_PRIORITY */
+  memset(&ctrl, 0, sizeof(ctrl));
+  ctrl.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY;
+ // rc = ioctl(camfd, VIDIOC_G_CTRL, &ctrl);
+  if (rc == -1) {
+    CDBG("%s: VIDIOC_G_CTRL V4L2_CID_EXPOSURE_AUTO_PRIORITY failed: %s\n",
+        __func__, strerror(errno));
+    return rc;
+  }
+
+  ctrl.value = !ctrl.value;
+  printf("V4L2_CID_EXPOSURE_AUTO_PRIORITY changed to %d\n", ctrl.value);
+ // rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+  if (rc == -1) {
+    CDBG("%s: VIDIOC_S_CTRL V4L2_CID_EXPOSURE_AUTO_PRIORITY failed: %s\n",
+      __func__, strerror(errno));
+  }
+  return rc;
+}
+
+int set_zoom (int zoom_action_param) {
+    int rc = 0;
+    struct v4l2_control ctrl;
+
+    if (zoom_action_param == ZOOM_IN) {
+        zoom_level += zoom_queryctrl.step;
+        if (zoom_level > zoom_queryctrl.maximum)
+            zoom_level = zoom_queryctrl.maximum;
+    } else if (zoom_action_param == ZOOM_OUT) {
+        zoom_level -= zoom_queryctrl.step;
+        if (zoom_level < zoom_queryctrl.minimum)
+            zoom_level = zoom_queryctrl.minimum;
+    } else {
+        CDBG("%s: Invalid zoom_action_param value\n", __func__);
+        return -EINVAL;
+    }
+    ctrl.id = V4L2_CID_ZOOM_ABSOLUTE;
+    ctrl.value = zoom_level;
+  //  rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION     - set_iso -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int set_iso (int iso_action_param) {
+    int rc = 0;
+    struct v4l2_control ctrl;
+
+    ctrl.id = MSM_V4L2_PID_ISO;
+    ctrl.value = iso_action_param - 1;
+  //  rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION     - increase_sharpness -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int increase_sharpness () {
+    int rc = 0;
+    struct v4l2_control ctrl;
+
+    sharpness += sharpness_queryctrl.step;
+    if (sharpness > sharpness_queryctrl.maximum)
+        sharpness = sharpness_queryctrl.maximum;
+
+    ctrl.id = V4L2_CID_SHARPNESS;
+    ctrl.value = sharpness;
+ //   rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION     - decrease_sharpness -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int decrease_sharpness () {
+    int rc = 0;
+    struct v4l2_control ctrl;
+
+    sharpness -= sharpness_queryctrl.step;
+    if (sharpness < sharpness_queryctrl.minimum)
+        sharpness = sharpness_queryctrl.minimum;
+
+    ctrl.id = V4L2_CID_SHARPNESS;
+    ctrl.value = sharpness;
+  //  rc = ioctl(camfd, VIDIOC_S_CTRL, &ctrl);
+
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION     - print_current_menu -
+ *
+ * DESCRIPTION:
+ * ===========================================================================*/
+int print_current_menu (menu_id_change_t current_menu_id) {
+  if (current_menu_id == MENU_ID_MAIN) {
+    print_menu_preview_video ();
+  } else if (current_menu_id == MENU_ID_PREVIEWVIDEORESOLUTIONCHANGE) {
+    camera_preview_video_resolution_change_tbl ();
+  }else if (current_menu_id == MENU_ID_WHITEBALANCECHANGE) {
+    camera_preview_video_wb_change_tbl();
+  } else if (current_menu_id == MENU_ID_EXPMETERINGCHANGE) {
+    camera_preview_video_exp_metering_change_tbl();
+  } else if (current_menu_id == MENU_ID_GET_CTRL_VALUE) {
+    camera_preview_video_get_ctrl_value_tbl();
+  } else if (current_menu_id == MENU_ID_ISOCHANGE) {
+    camera_preview_video_iso_change_tbl();
+  } else if (current_menu_id == MENU_ID_BRIGHTNESSCHANGE) {
+    camera_brightness_change_tbl ();
+  } else if (current_menu_id == MENU_ID_CONTRASTCHANGE) {
+    camera_contrast_change_tbl ();
+  } else if (current_menu_id == MENU_ID_EVCHANGE) {
+    camera_EV_change_tbl ();
+  } else if (current_menu_id == MENU_ID_SATURATIONCHANGE) {
+    camera_saturation_change_tbl ();
+  } else if (current_menu_id == MENU_ID_ZOOMCHANGE) {
+    camera_preview_video_zoom_change_tbl();
+  } else if (current_menu_id == MENU_ID_SHARPNESSCHANGE) {
+    camera_preview_video_sharpness_change_tbl();
+  }else if (current_menu_id == MENU_ID_SWITCHCAMERA) {
+    camera_switch_tbl();
+  }else if (current_menu_id == MENU_ID_RECORD) {
+    camera_record_tbl();
+  }
+
+  return 0;
+}
+
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_preview.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_preview.c
new file mode 100755
index 0000000..f060730
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_preview.c
@@ -0,0 +1,1075 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include "mm_camera_dbg.h"
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <linux/ion.h>
+#include "mm_qcamera_app.h"
+
+
+/*===========================================================================
+ * FUNCTION    - mm_camera_do_mmap_ion -
+ *
+ * DESCRIPTION:
+ *==========================================================================*/
+uint8_t *mm_camera_do_mmap_ion(int ion_fd, struct ion_allocation_data *alloc,
+                               struct ion_fd_data *ion_info_fd, int *mapFd)
+{
+    void *ret; /* returned virtual address */
+    int rc = 0;
+    struct ion_handle_data handle_data;
+
+    /* to make it page size aligned */
+    alloc->len = (alloc->len + 4095) & (~4095);
+
+    rc = ioctl(ion_fd, ION_IOC_ALLOC, alloc);
+    if (rc < 0) {
+        CDBG_ERROR("ION allocation failed %s\n", strerror(errno));
+        goto ION_ALLOC_FAILED;
+    }
+
+    ion_info_fd->handle = alloc->handle;
+    rc = ioctl(ion_fd, ION_IOC_SHARE, ion_info_fd);
+    if (rc < 0) {
+        CDBG_ERROR("ION map failed %s\n", strerror(errno));
+        goto ION_MAP_FAILED;
+    }
+    *mapFd = ion_info_fd->fd;
+    ret = mmap(NULL,
+               alloc->len,
+               PROT_READ  | PROT_WRITE,
+               MAP_SHARED,
+               *mapFd,
+               0);
+
+    if (ret == MAP_FAILED) {
+        CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno);
+        goto ION_MAP_FAILED;
+    }
+
+    return ret;
+
+    ION_MAP_FAILED:
+    handle_data.handle = ion_info_fd->handle;
+    ioctl(ion_fd, ION_IOC_FREE, &handle_data);
+    ION_ALLOC_FAILED:
+    return NULL;
+}
+
+/*===========================================================================
+ * FUNCTION    - mm_camera_do_munmap_ion -
+ *
+ * DESCRIPTION:
+ *==========================================================================*/
+int mm_camera_do_munmap_ion (int ion_fd, struct ion_fd_data *ion_info_fd,
+                             void *addr, size_t size)
+{
+    int rc = 0;
+    rc = munmap(addr, size);
+    close(ion_info_fd->fd);
+
+    struct ion_handle_data handle_data;
+    handle_data.handle = ion_info_fd->handle;
+    ioctl(ion_fd, ION_IOC_FREE, &handle_data);
+    return rc;
+}
+
+
+int mm_app_set_preview_fmt(int cam_id,mm_camera_image_fmt_t *fmt)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
+    fmt->fmt = pme->dim.prev_format;
+    fmt->width = pme->dim.display_width;
+    fmt->height = pme->dim.display_height;
+    return rc;
+}
+
+//void dumpFrameToFile(struct msm_frame* newFrame, int w, int h, char* name, int main_422)
+void dumpFrameToFile(mm_camera_buf_def_t* newFrame, int w, int h, char* name, int main_422)
+{
+    char buf[32];
+    int file_fd;
+    int i;
+    char *ext = "yuv";
+#if 0
+    if ( newFrame != NULL) {
+        char * str;
+        snprintf(buf, sizeof(buf), "/data/%s.%s", name,ext);
+        file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+        if (file_fd < 0) {
+            CDBG_ERROR("%s: cannot open file\n", __func__);
+        } else {
+            CDBG("%s: %d %d", __func__, newFrame->y_off, newFrame->cbcr_off);
+            write(file_fd, (const void *)(newFrame->buffer+newFrame->y_off), w * h);
+            write(file_fd, (const void *)
+                  (newFrame->buffer + newFrame->cbcr_off), w * h / 2 * main_422);
+            close(file_fd);
+            CDBG("dump %s", buf);
+        }
+    }
+#endif
+    if ( newFrame != NULL) {
+        char * str;
+        snprintf(buf, sizeof(buf), "/data/%s.%s", name,ext);
+        file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+        if (file_fd < 0) {
+            CDBG_ERROR("%s: cannot open file\n", __func__);
+        } else {
+            int y_off = newFrame->buffer + newFrame->planes[0].data_offset;
+            //int cbcr_off = newFrame->buffer + newFrame->planes[1].data_offset;//newFrame->buffer + newFrame->planes[0].length;
+            int cbcr_off = newFrame->buffer + newFrame->planes[0].length;
+            CDBG("%s: Y_off = %p cbcr_off = %p", __func__, y_off,cbcr_off);
+            CDBG("%s: Y_off length = %d cbcr_off length = %d", __func__, newFrame->planes[0].length,newFrame->planes[1].length);
+
+            write(file_fd, (const void *)(y_off), newFrame->planes[0].length);
+            write(file_fd, (const void *)(cbcr_off), 
+                  (newFrame->planes[1].length * newFrame->num_planes));
+            /*for(i = 1; i < newFrame->num_planes; i++) {
+                CDBG("%s: CBCR = %d", __func__, newFrame->planes[j].data_offset);
+                write(file_fd, (const void *)
+                  (newFrame->planes[i].data_offset), w * h / 2 * main_422);
+            }*/
+            close(file_fd);
+            CDBG("dump %s", buf);
+        }
+    }
+}
+
+int mm_app_open_camera(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int value = 0;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    if (pme->cam_mode == CAMERA_MODE) {
+        return rc;
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_stop_preview(cam_id))) {
+        CDBG_ERROR("%s:Stop preview err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_RECORDING_HINT, &value);
+
+    if (MM_CAMERA_OK != (rc = mm_app_start_preview(cam_id))) {
+        CDBG_ERROR("%s:Start preview err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    pme->cam_mode = CAMERA_MODE;
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+
+int mm_app_open_zsl(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int value = 0;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    if (pme->cam_mode == ZSL_MODE) {
+        return rc;
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_stop_preview(cam_id))) {
+        CDBG_ERROR("%s:Stop preview err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_RECORDING_HINT, &value);
+
+    if (MM_CAMERA_OK != (rc = mm_app_start_preview_zsl(cam_id))) {
+        CDBG_ERROR("%s:stream on preview err=%d\n", __func__, rc);
+        goto end;
+    }
+    pme->cam_mode = ZSL_MODE;
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
+#if 0
+int mm_stream_deinit_preview_buf(uint32_t camera_handle,
+                                 uint32_t ch_id, uint32_t stream_id,
+                                 void *user_data, uint8_t num_bufs,
+                                 mm_camera_buf_def_t *bufs)
+{
+    int i, rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+    for (i = 0; i < num_bufs; i++) {
+        rc = my_cam_app.hal_lib.mm_camera_do_munmap_ion (pme->ionfd, &(pme->preview_buf.frame[i].fd_data),
+                                                         (void *)pme->preview_buf.frame[i].buffer, bufs[i].frame_len);
+        if (rc != MM_CAMERA_OK) {
+            CDBG("%s: mm_camera_do_munmap err, pmem_fd = %d, rc = %d",
+                 __func__, bufs[i].fd, rc);
+        }
+    }
+    close(pme->ionfd);
+    return rc;
+}
+
+int mm_stream_init_preview_buf(uint32_t camera_handle,
+                               uint32_t ch_id, uint32_t stream_id,
+                               void *user_data,
+                               mm_camera_frame_len_offset *frame_offset_info,
+                               uint8_t num_bufs,
+                               uint8_t *initial_reg_flag,
+                               mm_camera_buf_def_t *bufs)
+{
+    int i,j,num_planes, frame_len, y_off, cbcr_off;
+    uint32_t planes[VIDEO_MAX_PLANES];
+    uint32_t pmem_addr = 0;
+
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+    num_planes = frame_offset_info->num_planes;
+    for ( i = 0; i < num_planes; i++) {
+        planes[i] = frame_offset_info->mp[i].len;
+    }
+
+    frame_len = frame_offset_info->frame_len;
+    y_off = frame_offset_info->mp[0].offset;
+    cbcr_off = frame_offset_info->mp[1].offset;
+
+    CDBG("Allocating Preview Memory for %d buffers frame_len = %d",num_bufs,frame_offset_info->frame_len);
+
+    for (i = 0; i < num_bufs ; i++) {
+        int j;
+        pme->preview_buf.reg[i] = 1;
+        initial_reg_flag[i] = 1;
+
+        pme->preview_buf.frame_len = frame_len;
+        pme->preview_buf.frame[i].ion_alloc.len = pme->preview_buf.frame_len;
+        pme->preview_buf.frame[i].ion_alloc.flags =
+        (0x1 << CAMERA_ION_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID);
+        pme->preview_buf.frame[i].ion_alloc.align = 4096;
+
+        pmem_addr = (unsigned long) my_cam_app.hal_lib.mm_camera_do_mmap_ion(pme->ionfd,
+                                                                             &(pme->preview_buf.frame[i].ion_alloc), &(pme->preview_buf.frame[i].fd_data),
+                                                                             &pme->preview_buf.frame[i].fd);
+
+        pme->preview_buf.frame[i].buffer = pmem_addr;
+        pme->preview_buf.frame[i].path = OUTPUT_TYPE_P;
+        pme->preview_buf.frame[i].y_off = 0;
+        pme->preview_buf.frame[i].cbcr_off = planes[0];
+        pme->preview_buf.frame[i].phy_offset = 0;
+
+        CDBG("Buffer allocated Successfully fd = %d",pme->preview_buf.frame[i].fd);
+
+        bufs[i].fd = pme->preview_buf.frame[i].fd;
+        //bufs[i].buffer = pmem_addr;
+        bufs[i].frame_len = pme->preview_buf.frame[i].ion_alloc.len;
+        bufs[i].num_planes = num_planes;
+
+        bufs[i].frame = &pme->preview_buf.frame[i];
+
+        /* Plane 0 needs to be set seperately. Set other planes
+             * in a loop. */
+        bufs[i].planes[0].length = planes[0];
+        bufs[i].planes[0].m.userptr = bufs[i].fd;
+        bufs[i].planes[0].data_offset = y_off;
+        bufs[i].planes[0].reserved[0] = 0;
+        //buf_def->buf.mp[i].frame_offset;
+        for (j = 1; j < num_planes; j++) {
+            bufs[i].planes[j].length = planes[j];
+            bufs[i].planes[j].m.userptr = bufs[i].fd;
+            bufs[i].planes[j].data_offset = cbcr_off;
+            bufs[i].planes[j].reserved[0] =
+            bufs[i].planes[j-1].reserved[0] +
+            bufs[i].planes[j-1].length;
+        }
+    }
+    return MM_CAMERA_OK;
+}
+#endif
+
+int mm_stream_initbuf(uint32_t camera_handle,
+                      uint32_t ch_id, uint32_t stream_id,
+                      void *user_data,
+                      mm_camera_frame_len_offset *frame_offset_info,
+                      uint8_t num_bufs,
+                      uint8_t *initial_reg_flag,
+                      mm_camera_buf_def_t *bufs)
+{
+    int i,y_off, cbcr_off,num_planes;
+    int plane_len;
+    struct ion_allocation_data ion_alloc;
+    struct ion_fd_data ion_info_fd;
+    uint32_t pmem_addr = 0;
+    uint32_t planes[VIDEO_MAX_PLANES];
+
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+    num_planes = frame_offset_info->num_planes;
+    if (num_planes == 1) {
+        y_off = frame_offset_info->mp[0].offset;;
+        cbcr_off = 0;
+    } else {
+        y_off = frame_offset_info->mp[0].offset;
+        cbcr_off = frame_offset_info->mp[1].offset;
+    }
+
+    CDBG("%s: y_off = %d,cbcr_off = %d,num_planes = %d",__func__,y_off,
+         cbcr_off,num_planes);
+
+    pme->ionfd = open("/dev/ion", O_RDONLY);
+    if (pme->ionfd < 0) {
+        ALOGE("Ion dev open failed\n");
+        ALOGE("Error is %s\n", strerror(errno));
+    }
+
+    for (i = 0; i < num_bufs ; i++) {
+        int j;
+
+        //if(pme->cam_mode != RECORDER_MODE || pme->fullSizeSnapshot) {
+        initial_reg_flag[i] = 1;
+        //}else{
+        //initial_reg_flag[i] = 0;
+        //}
+
+        ion_alloc.len = frame_offset_info->frame_len;
+        ion_alloc.flags =
+        (0x1 << CAMERA_ION_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID);
+        ion_alloc.align = 4096;
+
+        /*bufs[i].buffer = my_cam_app.hal_lib.mm_camera_do_mmap_ion(pme->ionfd,
+                       &ion_alloc, &ion_info_fd,
+                       &bufs[i].fd);*/
+
+        bufs[i].buffer = mm_camera_do_mmap_ion(pme->ionfd,
+                                               &ion_alloc, &ion_info_fd,
+                                               &bufs[i].fd);
+        CDBG(" %s : Buffer allocated fd = %d, length = %d, y_off = %d cdcr_off = %d",
+             __func__,bufs[i].fd,ion_alloc.len,y_off,cbcr_off);
+
+        bufs[i].frame_len = ion_alloc.len;
+        bufs[i].num_planes = num_planes;
+
+        /* Plane 0 needs to be set seperately. Set other planes
+             * in a loop. */
+        bufs[i].planes[0].length = frame_offset_info->mp[0].len;
+        bufs[i].planes[0].m.userptr = bufs[i].fd;
+        bufs[i].planes[0].data_offset = y_off;
+        bufs[i].planes[0].reserved[0] = 0;
+        //buf_def->buf.mp[i].frame_offset;
+        for (j = 1; j < num_planes; j++) {
+            bufs[i].planes[j].length = frame_offset_info->mp[j].len;
+            bufs[i].planes[j].m.userptr = bufs[i].fd;
+            bufs[i].planes[j].data_offset = cbcr_off;
+            bufs[i].planes[j].reserved[0] =
+            bufs[i].planes[j-1].reserved[0] +
+            bufs[i].planes[j-1].length;
+        }
+    }
+    CDBG("%s: X",__func__);
+    return MM_CAMERA_OK;
+}
+
+#if 0
+int mm_stream_initbuf_1(uint32_t camera_handle,
+                        uint32_t ch_id, uint32_t stream_id,
+                        void *user_data,
+                        mm_camera_frame_len_offset *frame_offset_info,
+                        uint8_t num_bufs,
+                        uint8_t *initial_reg_flag,
+                        mm_camera_buf_def_t *bufs)
+{
+    int i;
+    int streamType = 0;
+
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+    CDBG("%s : E ", __FUNCTION__);
+
+    for (i= 0; i < 5; i++) {
+        if (pme->stream[i].id == stream_id) {
+            CDBG("Allocate Memory for Stream %d",i);
+            streamType = i;
+            break;
+        }
+    }
+
+    streamType = MM_CAMERA_PREVIEW;
+    switch (streamType) {
+    case MM_CAMERA_PREVIEW:
+        mm_stream_init_preview_buf( camera_handle,
+                                    ch_id, stream_id,
+                                    user_data,
+                                    frame_offset_info,
+                                    num_bufs,
+                                    initial_reg_flag,
+                                    bufs);
+        break;
+    case MM_CAMERA_VIDEO:
+        mm_stream_init_video_buf( camera_handle,
+                                  ch_id, stream_id,
+                                  user_data,
+                                  frame_offset_info,
+                                  num_bufs,
+                                  initial_reg_flag,
+                                  bufs);
+        break;
+    case MM_CAMERA_SNAPSHOT_MAIN:
+        mm_stream_init_main_buf( camera_handle,
+                                 ch_id, stream_id,
+                                 user_data,
+                                 frame_offset_info,
+                                 num_bufs,
+                                 initial_reg_flag,
+                                 bufs);
+        break;
+    case MM_CAMERA_SNAPSHOT_THUMBNAIL:
+        mm_stream_init_thumbnail_buf( camera_handle,
+                                      ch_id, stream_id,
+                                      user_data,
+                                      frame_offset_info,
+                                      num_bufs,
+                                      initial_reg_flag,
+                                      bufs);
+        break;
+    default:
+        break;
+    }
+
+    CDBG(" %s : X ",__FUNCTION__);
+    return MM_CAMERA_OK;
+}
+#endif
+int mm_stream_deinitbuf(uint32_t camera_handle,
+                        uint32_t ch_id, uint32_t stream_id,
+                        void *user_data, uint8_t num_bufs,
+                        mm_camera_buf_def_t *bufs)
+{
+    int i, rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+    CDBG("%s: E",__func__);
+
+    for (i = 0; i < num_bufs; i++) {
+        /*rc = my_cam_app.hal_lib.mm_camera_do_munmap_ion (pme->ionfd, &bufs[i].fd,
+                   (void *)bufs[i].buffer, bufs[i].frame_len);*/
+        rc = mm_camera_do_munmap_ion (pme->ionfd, &bufs[i].fd,
+                                      (void *)bufs[i].buffer, bufs[i].frame_len);
+    }
+    close(pme->ionfd);
+    CDBG("%s: X",__func__);
+    return rc;
+}
+
+#if 0
+static int mm_stream_deinitbuf_1(uint32_t camera_handle,
+                                 uint32_t ch_id, uint32_t stream_id,
+                                 void *user_data, uint8_t num_bufs,
+                                 mm_camera_buf_def_t *bufs)
+{
+    int i, rc = MM_CAMERA_OK;
+    int streamType = 0;
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+    CDBG("%s: BEGIN",__func__);
+
+    for (i= 0; i < 5; i++) {
+        if (pme->stream[i].id == stream_id) {
+            CDBG("Allocate Memory for Stream %d",i);
+            streamType = i;
+            break;
+        }
+    }
+    streamType = MM_CAMERA_PREVIEW; 
+    switch (streamType) {
+    case MM_CAMERA_PREVIEW:
+        mm_stream_deinit_preview_buf(camera_handle,
+                                     ch_id, stream_id,
+                                     user_data, num_bufs,
+                                     bufs);
+        break;
+    case MM_CAMERA_VIDEO:
+        mm_stream_deinit_video_buf(camera_handle,
+                                   ch_id, stream_id,
+                                   user_data, num_bufs,
+                                   bufs);
+        break;
+    case MM_CAMERA_SNAPSHOT_MAIN:
+        mm_stream_deinit_main_buf(camera_handle,
+                                  ch_id, stream_id,
+                                  user_data, num_bufs,
+                                  bufs);
+        break;
+    case MM_CAMERA_SNAPSHOT_THUMBNAIL:
+        mm_stream_deinit_thumbnail_buf(camera_handle,
+                                       ch_id, stream_id,
+                                       user_data, num_bufs,
+                                       bufs);
+        break;
+    default:
+        break;
+    }
+
+    /* zero out the buf stuct */
+    CDBG("%s: END",__func__);
+    return MM_CAMERA_OK;
+}
+#endif
+
+void preview_cb_signal(mm_camera_app_obj_t *pme)
+{
+    if (pme->cam_state == CAMERA_STATE_PREVIEW) {
+        mm_camera_app_done();
+    }
+}
+
+void mm_app_preview_notify_cb(mm_camera_super_buf_t *bufs,
+                              void *user_data)
+{
+    int rc;
+    mm_camera_buf_def_t *frame = NULL;
+    mm_camera_app_obj_t *pme = NULL;
+    CDBG("%s: BEGIN\n", __func__); 
+    frame = bufs->bufs[MM_CAMERA_PREVIEW] ;
+    pme = (mm_camera_app_obj_t *)user_data;
+
+    CDBG("%s: BEGIN - length=%d, frame idx = %d\n", __func__, frame->frame_len, frame->frame_idx);
+
+    //dumpFrameToFile(frame->frame,pme->dim.display_width,pme->dim.display_height,"preview", 1);
+    dumpFrameToFile(frame,pme->dim.display_width,pme->dim.display_height,"preview", 1);
+    if (!my_cam_app.run_sanity) {
+        if (0 != (rc = mm_app_dl_render(frame->fd, NULL))) {
+            CDBG("%s:DL rendering err=%d, frame fd=%d,frame idx = %d\n",
+                 __func__, rc, frame->fd, frame->frame_idx);
+        }
+    }
+
+    CDBG("In CB function i/p = %p o/p = %p",bufs->bufs[MM_CAMERA_PREVIEW],frame);
+
+    if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,frame)) {
+        CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
+        return;
+    }
+    if (my_cam_app.run_sanity) {
+        preview_cb_signal(pme);
+    }
+    CDBG("%s: END\n", __func__); 
+
+}
+
+static void mm_app_zsl_notify_cb(mm_camera_super_buf_t *bufs,
+                                 void *user_data)
+{
+    int rc;
+    int i = 0;
+    mm_camera_buf_def_t *preview_frame = NULL;
+    mm_camera_buf_def_t *main_frame = NULL;
+    mm_camera_buf_def_t *thumb_frame = NULL;
+    mm_camera_app_obj_t *pme = NULL;
+    CDBG("%s: BEGIN\n", __func__); 
+
+    pme = (mm_camera_app_obj_t *)user_data;
+
+    CDBG("%s : total streams = %d",__func__,bufs->num_bufs);
+    preview_frame = bufs->bufs[0] ;
+    main_frame = bufs->bufs[1];
+    thumb_frame = bufs->bufs[0];
+
+    //dumpFrameToFile(preview_frame->frame,pme->dim.display_width,pme->dim.display_height,"preview", 1);
+    dumpFrameToFile(preview_frame,pme->dim.display_width,pme->dim.display_height,"zsl_preview", 1);
+    if (0 != (rc = mm_app_dl_render(preview_frame->fd, NULL))) {
+        CDBG("%s:DL rendering err=%d, frame fd=%d,frame idx = %d\n",
+             __func__, rc, preview_frame->fd, preview_frame->frame_idx);
+    }
+
+    if (bufs->num_bufs == 2 && main_frame != NULL) {
+        CDBG("mainframe frame_idx = %d fd = %d frame length = %d",main_frame->frame_idx,main_frame->fd,main_frame->frame_len);
+        CDBG("thumnail frame_idx = %d fd = %d frame length = %d",thumb_frame->frame_idx,thumb_frame->fd,thumb_frame->frame_len);
+
+        //dumpFrameToFile(main_frame->frame,pme->dim.picture_width,pme->dim.picture_height,"main", 1);
+        //dumpFrameToFile(thumb_frame->frame,pme->dim.thumbnail_width,pme->dim.thumbnail_height,"thumb", 1);
+
+        dumpFrameToFile(main_frame,pme->dim.picture_width,pme->dim.picture_height,"zsl_main", 1);
+        dumpFrameToFile(thumb_frame,pme->dim.thumbnail_width,pme->dim.thumbnail_height,"zsl_thumb", 1);
+
+        if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,main_frame)) {
+            CDBG_ERROR("%s: Failed in thumbnail Qbuf\n", __func__); 
+        }
+    }
+
+    if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,preview_frame)) {
+        CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__); 
+    }
+    CDBG("%s: END\n", __func__);
+}
+
+int mm_app_prepare_preview(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int op_mode;
+
+    CDBG("%s: E",__func__);
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    pme->mem_cam->get_buf = mm_stream_initbuf;
+    pme->mem_cam->put_buf = mm_stream_deinitbuf;
+    pme->mem_cam->user_data = pme;
+
+    op_mode = MM_CAMERA_OP_MODE_VIDEO;
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->set_parm(
+                                                     pme->cam->camera_handle,MM_CAMERA_PARM_OP_MODE, &op_mode))) {
+        CDBG_ERROR("%s: Set preview op mode error",__func__);
+        goto end;
+    }
+
+    pme->stream[MM_CAMERA_PREVIEW].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+                                                                  mm_app_preview_notify_cb,pme,
+                                                                  MM_CAMERA_PREVIEW, 0);
+
+    if (!pme->stream[MM_CAMERA_PREVIEW].id) {
+        CDBG_ERROR("%s:Add stream preview error =%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+    CDBG("%s :Add stream is successfull stream ID = %d",__func__,pme->stream[MM_CAMERA_PREVIEW].id);
+
+    mm_app_set_preview_fmt(cam_id,&pme->stream[MM_CAMERA_PREVIEW].str_config.fmt);
+    pme->stream[MM_CAMERA_PREVIEW].str_config.need_stream_on = 1;
+    pme->stream[MM_CAMERA_PREVIEW].str_config.num_of_bufs = PREVIEW_BUF_NUM;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_PREVIEW].id,
+                                                           &pme->stream[MM_CAMERA_PREVIEW].str_config))) {
+        CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+        goto end;
+    }
+    end:
+    return rc;
+}
+
+int mm_app_unprepare_preview(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    return rc;
+}
+
+int mm_app_streamon_preview(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    mm_camera_frame_len_offset frame_offset_info;
+
+    stream[0] = pme->stream[MM_CAMERA_PREVIEW].id;
+    stream[1] = 0;
+
+    pme->cam->ops->get_stream_parm(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_PREVIEW].id,MM_CAMERA_STREAM_OFFSET,&frame_offset_info);
+    ALOGE("DEBUG : length = %d",frame_offset_info.frame_len);
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,1,&stream))) {
+        CDBG_ERROR("%s : Start Stream preview Error",__func__);
+        goto end;
+    }
+    pme->cam_state = CAMERA_STATE_PREVIEW;
+    end:
+    CDBG("%s: X rc = %d",__func__,rc);
+    return rc;
+}
+
+int mm_app_prepare_preview_zsl(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_bundle_attr_t attr;
+    int stream[3];
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    int op_mode = 0;
+
+    op_mode = MM_CAMERA_OP_MODE_ZSL;
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->set_parm(
+                                                     pme->cam->camera_handle,MM_CAMERA_PARM_OP_MODE, &op_mode))) {
+        CDBG_ERROR("%s: Set preview op mode error",__func__);
+        goto end;
+    }
+
+    pme->stream[MM_CAMERA_PREVIEW].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+                                                                  mm_app_preview_notify_cb,pme,
+                                                                  MM_CAMERA_PREVIEW, 0);
+
+    if (!pme->stream[MM_CAMERA_PREVIEW].id) {
+        CDBG_ERROR("%s:Add stream preview error =%d\n", __func__, rc);
+        goto end;
+    }
+
+    CDBG("%s :Add stream is successfull stream ID = %d",__func__,pme->stream[MM_CAMERA_PREVIEW].id);
+
+    mm_app_set_preview_fmt(cam_id,&pme->stream[MM_CAMERA_PREVIEW].str_config.fmt);
+    pme->stream[MM_CAMERA_PREVIEW].str_config.need_stream_on = 1;
+    pme->stream[MM_CAMERA_PREVIEW].str_config.num_of_bufs = PREVIEW_BUF_NUM;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_PREVIEW].id,
+                                                           &pme->stream[MM_CAMERA_PREVIEW].str_config))) {
+        CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+                                                                        NULL,pme,
+                                                                        MM_CAMERA_SNAPSHOT_MAIN, 0);
+
+    CDBG("Add Snapshot main is successfull stream ID = %d",pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id);
+    if (!pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id) {
+        CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+    pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.need_stream_on = 1;
+    pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.num_of_bufs = 7;
+
+    mm_app_set_snapshot_fmt(cam_id,&pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.fmt);
+
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id,
+                                                           &pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config))) {
+        CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+        goto end;
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+    return rc;
+}
+
+int mm_app_streamon_preview_zsl(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_bundle_attr_t attr;
+    int stream[3];
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    int op_mode = 0;
+
+
+    stream[0] = pme->stream[MM_CAMERA_PREVIEW].id;
+    stream[1] = pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id;
+
+    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
+    attr.burst_num = 1;
+    attr.look_back = 2;
+    attr.post_frame_skip = 0;
+    attr.water_mark = 2;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->init_stream_bundle(
+                                                               pme->cam->camera_handle,pme->ch_id,mm_app_zsl_notify_cb,pme,&attr,2,stream))) {
+        CDBG_ERROR("%s:init_stream_bundle err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,
+                                                           2, stream))) {
+        CDBG_ERROR("%s:start_streams err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+    pme->cam_state = CAMERA_STATE_PREVIEW;
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+    return rc;
+
+}
+
+int initDisplay()
+{
+    int rc = MM_CAMERA_OK;
+
+    use_overlay_fb_display_driver();
+    if (launch_camframe_fb_thread()) {
+        CDBG_ERROR("%s:launch_camframe_fb_thread failed!\n", __func__);
+        //rc = -MM_CAMERA_E_GENERAL;
+    }
+    CDBG("%s: launch_camframe_fb_thread done\n", __func__);
+    return rc;
+}
+
+int deinitDisplay()
+{
+    /* stop the display thread */
+    release_camframe_fb_thread();
+    return MM_CAMERA_OK;
+}
+
+int mm_app_start_preview(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    int op_mode = 0;
+
+    CDBG("pme = %p, pme->cam =%p, pme->cam->camera_handle = %d",
+         pme,pme->cam,pme->cam->camera_handle);
+
+    if (pme->cam_state == CAMERA_STATE_PREVIEW) {
+        return rc;
+    }
+
+    if (!my_cam_app.run_sanity) {
+        if (MM_CAMERA_OK != initDisplay()) {
+            CDBG_ERROR("%s : Could not initalize display",__func__);
+            goto end;
+        }
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_prepare_preview(cam_id))) {
+        CDBG_ERROR("%s:Stream On Preview failed rc=%d\n", __func__, rc);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_streamon_preview(cam_id))) {
+        CDBG_ERROR("%s:Stream On Preview failed rc=%d\n", __func__, rc);
+        goto end;
+    }
+
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+    return rc;
+}
+
+int mm_app_start_preview_zsl(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("pme = %p, pme->cam =%p, pme->cam->camera_handle = %d",
+         pme,pme->cam,pme->cam->camera_handle);
+
+    if (!my_cam_app.run_sanity) {
+        if (MM_CAMERA_OK != initDisplay()) {
+            CDBG_ERROR("%s : Could not initalize display",__func__);
+            goto end;
+        }
+    }
+
+    pme->mem_cam->get_buf = mm_stream_initbuf;
+    pme->mem_cam->put_buf = mm_stream_deinitbuf;
+    pme->mem_cam->user_data = pme;
+
+    if (MM_CAMERA_OK != (rc = mm_app_prepare_preview_zsl(cam_id))) {
+        CDBG_ERROR("%s:Prepare preview err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_streamon_preview_zsl(cam_id))) {
+        CDBG_ERROR("%s:stream on preview err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    /*if(MM_CAMERA_OK != (rc = mm_app_bundle_zsl_stream(cam_id))){
+        CDBG_ERROR("%s: bundle and start of ZSl err=%d\n", __func__, rc);
+        goto end;
+    }*/
+
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+    return rc;
+}
+
+static int mm_app_streamoff_preview(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    stream[0] = pme->stream[MM_CAMERA_PREVIEW].id;
+    stream[1] = 0;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle,pme->ch_id,1,&stream))) {
+        CDBG_ERROR("%s : Preview Stream off Error",__func__);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_PREVIEW].id))) {
+        CDBG_ERROR("%s : Delete Stream Preview error",__func__);
+        goto end;
+    }
+    CDBG("del_stream successfull");
+    pme->cam_state = CAMERA_STATE_OPEN;
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+
+    return rc;
+}
+
+static int mm_app_streamoff_preview_zsl(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    stream[0] = pme->stream[MM_CAMERA_PREVIEW].id;
+    stream[1] = pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->destroy_stream_bundle(pme->cam->camera_handle,pme->ch_id))) {
+        CDBG_ERROR("%s : ZSL Snapshot destroy_stream_bundle Error",__func__);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle,pme->ch_id,2,&stream))) {
+        CDBG_ERROR("%s : Preview Stream off Error",__func__);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_PREVIEW].id))) {
+        CDBG_ERROR("%s : Delete Stream Preview error",__func__);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id))) {
+        CDBG_ERROR("%s : Delete Stream Preview error",__func__);
+        goto end;
+    }
+    CDBG("del_stream successfull");
+    pme->cam_state = CAMERA_STATE_OPEN;
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+
+    return rc;
+}
+
+int startPreview(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s: Start Preview",__func__);
+
+    if (pme->cam_mode == ZSL_MODE || pme->cam_mode == RECORDER_MODE) {
+        switch (pme->cam_state) {
+        case CAMERA_STATE_RECORD:
+            if (MM_CAMERA_OK != mm_app_stop_video(cam_id)) {
+                CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
+                return -1;
+            }
+        case CAMERA_STATE_PREVIEW:
+            if (MM_CAMERA_OK != mm_app_open_camera(cam_id)) {
+                CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__);
+                return -1;
+            }
+            break;
+        case CAMERA_STATE_SNAPSHOT:
+        default:
+            break;
+        }
+    } else if (pme->cam_mode == CAMERA_MODE && pme->cam_state == CAMERA_STATE_OPEN) {
+
+        if (MM_CAMERA_OK != (rc = mm_app_start_preview(cam_id))) {
+            CDBG_ERROR("%s:preview streaming on err=%d\n", __func__, rc);
+            return -1;
+        }
+    }
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int stopPreview(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s : pme->cam_mode = %d, pme->cam_state = %d",__func__,pme->cam_mode,pme->cam_state);
+
+    if (pme->cam_mode == CAMERA_MODE && pme->cam_state == CAMERA_STATE_PREVIEW) {
+        if (MM_CAMERA_OK != (rc = mm_app_stop_preview(cam_id))) {
+            CDBG("%s:streamoff preview err=%d\n", __func__, rc);
+            goto end;
+        }
+    } else if (pme->cam_mode == ZSL_MODE && pme->cam_state == CAMERA_STATE_PREVIEW) {
+        if (MM_CAMERA_OK != (rc = mm_app_stop_preview_zsl(cam_id))) {
+            CDBG("%s:streamoff preview err=%d\n", __func__, rc);
+            goto end;
+        }
+    } else if (pme->cam_mode == RECORDER_MODE && pme->cam_state == CAMERA_STATE_PREVIEW) {
+        if (MM_CAMERA_OK != (rc = mm_app_stop_preview(cam_id))) {
+            CDBG("%s:streamoff preview err=%d\n", __func__, rc);
+            goto end;
+        }
+        mm_app_unprepare_video(cam_id);
+    }
+    end:
+    return rc;
+}
+
+int mm_app_stop_preview(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    if (MM_CAMERA_OK != (rc = mm_app_streamoff_preview(cam_id))) {
+        CDBG_ERROR("%s : Delete Stream Preview error",__func__);
+        goto end;
+    }
+
+    CDBG("Stop Preview successfull");
+
+    if (!my_cam_app.run_sanity) {
+        deinitDisplay();
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_stop_preview_zsl(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    if (MM_CAMERA_OK != (rc = mm_app_streamoff_preview_zsl(cam_id))) {
+        CDBG_ERROR("%s : Delete Stream Preview error",__func__);
+        goto end;
+    }
+
+    CDBG("Stop Preview successfull");
+    if (!my_cam_app.run_sanity) {
+        deinitDisplay();
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_rdi.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_rdi.c
new file mode 100755
index 0000000..f59f498
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_rdi.c
@@ -0,0 +1,329 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include "mm_camera_dbg.h"
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <linux/ion.h>
+#include "mm_qcamera_app.h"
+
+/*typedef enum {
+  STREAM_IMAGE,
+  STREAM_RAW,
+  STREAM_IMAGE_AND_RAW,
+  STREAM_RAW_AND_RAW,
+  STREAM_MAX,
+} mm_camera_channel_stream_info_t;*/
+
+#define RDI_MASK STREAM_RAW
+mm_camera_channel_stream_info_t rdi_mode;
+
+static int mm_app_set_rdi_fmt(int cam_id,mm_camera_image_fmt_t *fmt)
+{
+    int rc = MM_CAMERA_OK;
+    cam_ctrl_dimension_t dim;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
+    //pme->cam->ops->get_parm(pme->cam->camera_handle,MM_CAMERA_PARM_DIMENSION, &dim);
+    fmt->fmt = CAMERA_BAYER_SBGGR10;//CAMERA_RDI;
+    fmt->width = 0;
+    fmt->height = 0;
+    fmt->rotation = 0;
+
+    CDBG("%s: RDI Dimensions = %d X %d",__func__,fmt->width,fmt->height);
+    return rc;
+}
+
+int mm_app_open_rdi(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int value = RDI_MASK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    if (pme->cam_mode == RDI_MODE) {
+        return rc;
+    }
+
+    if (MM_CAMERA_OK != (rc = stopPreview(cam_id))) {
+        CDBG_ERROR("%s:Stop preview err=%d\n", __func__, rc);
+        goto end;
+    }
+    pme->cam_mode = RDI_MODE;
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+void rdi_cb_signal(mm_camera_app_obj_t *pme)
+{
+    if (pme->cam_mode == RDI_MODE) {
+        mm_camera_app_done();
+    }
+}
+
+static void mm_app_rdi_notify_cb(mm_camera_super_buf_t *bufs,
+                                 void *user_data)
+{
+    int rc;
+    mm_camera_buf_def_t *frame = NULL;
+    mm_camera_app_obj_t *pme = NULL;
+    CDBG("%s: BEGIN\n", __func__); 
+    frame = bufs->bufs[0] ;
+    pme = (mm_camera_app_obj_t *)user_data;
+
+    CDBG("%s: BEGIN - length=%d, frame idx = %d\n", __func__, frame->frame_len, frame->frame_idx);
+
+    //dumpFrameToFile(frame->frame,pme->dim.display_width,pme->dim.display_height,"preview", 1);
+    dumpFrameToFile(frame,pme->dim.rdi0_width,pme->dim.rdi0_height,"rdi", 1);
+
+    if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,frame)) {
+        CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
+        return;
+    }
+    if (my_cam_app.run_sanity) {
+        mm_camera_app_done(pme);
+    }
+    CDBG("%s: END\n", __func__); 
+
+}
+
+int mm_app_prepare_rdi(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int op_mode;
+    int value = RDI_MASK;
+
+    CDBG("%s: E",__func__);
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    pme->mem_cam->get_buf = mm_stream_initbuf;
+    pme->mem_cam->put_buf = mm_stream_deinitbuf;
+    pme->mem_cam->user_data = pme;
+
+    //pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_CH_INTERFACE, &value);
+    //pme->cam->ops->get_parm(pme->cam->camera_handle,MM_CAMERA_PARM_CH_INTERFACE, &rdi_mode);
+
+    pme->stream[MM_CAMERA_RDI].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+                                                              mm_app_rdi_notify_cb,pme,
+                                                              MM_CAMERA_RDI, 0);
+
+    if (!pme->stream[MM_CAMERA_RDI].id) {
+        CDBG_ERROR("%s:Add RDI error =%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+    CDBG("%s :Add RDI stream is successfull stream ID = %d",__func__,pme->stream[MM_CAMERA_RDI].id);
+
+    mm_app_set_rdi_fmt(cam_id,&pme->stream[MM_CAMERA_RDI].str_config.fmt);
+    pme->stream[MM_CAMERA_RDI].str_config.need_stream_on = 1;
+    pme->stream[MM_CAMERA_RDI].str_config.num_of_bufs = 7;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_RDI].id,
+                                                           &pme->stream[MM_CAMERA_RDI].str_config))) {
+        CDBG_ERROR("%s:RDI streaming err=%d\n", __func__, rc);
+        goto end;
+    }
+#if 0
+    if (rdi_mode == STREAM_IMAGE_AND_RAW) {
+        pme->stream[MM_CAMERA_PREVIEW].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+                                                                      mm_app_preview_notify_cb,pme,
+                                                                      MM_CAMERA_PREVIEW, 0);
+
+        if (!pme->stream[MM_CAMERA_PREVIEW].id) {
+            CDBG_ERROR("%s:Add stream preview error =%d\n", __func__, rc);
+            rc = -1;
+            goto end;
+        }
+
+        CDBG("%s :Add stream is successfull stream ID = %d",__func__,pme->stream[MM_CAMERA_PREVIEW].id);
+
+        mm_app_set_preview_fmt(cam_id,&pme->stream[MM_CAMERA_PREVIEW].str_config.fmt);
+        pme->stream[MM_CAMERA_PREVIEW].str_config.need_stream_on = 1;
+        pme->stream[MM_CAMERA_PREVIEW].str_config.num_of_bufs = PREVIEW_BUF_NUM;
+
+        if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_PREVIEW].id,
+                                                               &pme->stream[MM_CAMERA_PREVIEW].str_config))) {
+            CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+            goto end;
+        }
+    }
+#endif
+    end:
+    return rc;
+}
+
+int mm_app_unprepare_rdi(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    return rc;
+}
+
+int mm_app_streamon_rdi(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    int num_of_streams;
+
+    /*if(rdi_mode == STREAM_IMAGE_AND_RAW){
+        num_of_streams = 2;
+        stream[0] = pme->stream[MM_CAMERA_RDI].id;
+        stream[1] = pme->stream[MM_CAMERA_PREVIEW].id;
+    }else */{
+        num_of_streams = 1;
+        stream[0] = pme->stream[MM_CAMERA_RDI].id;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,num_of_streams,&stream))) {
+        CDBG_ERROR("%s : Start RDI Stream preview Error",__func__);
+        goto end;
+    }
+    pme->cam_state = CAMERA_STATE_RDI;
+    end:
+    CDBG("%s: X rc = %d",__func__,rc);
+    return rc;
+}
+
+int mm_app_start_rdi(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    int op_mode = 0;
+
+    CDBG("pme = %p, pme->cam =%p, pme->cam->camera_handle = %d",
+         pme,pme->cam,pme->cam->camera_handle);
+
+    if (pme->cam_state == CAMERA_STATE_RDI) {
+        return rc;
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_prepare_rdi(cam_id))) {
+        CDBG_ERROR("%s:Prepare RDI failed rc=%d\n", __func__, rc);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_streamon_rdi(cam_id))) {
+        CDBG_ERROR("%s:Stream On RDI failed rc=%d\n", __func__, rc);
+        goto end;
+    }
+
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+    return rc;
+}
+
+static int mm_app_streamoff_rdi(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+    int num_of_streams;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    /*if(rdi_mode == STREAM_IMAGE_AND_RAW){
+        num_of_streams = 2;
+        stream[0] = pme->stream[MM_CAMERA_RDI].id;
+        stream[1] = pme->stream[MM_CAMERA_PREVIEW].id;
+    }else*/{
+        num_of_streams = 1;
+        stream[0] = pme->stream[MM_CAMERA_RDI].id;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle,pme->ch_id,num_of_streams,&stream))) {
+        CDBG_ERROR("%s : RDI Stream off Error",__func__);
+        goto end;
+    }
+
+    /*if(rdi_mode == STREAM_IMAGE_AND_RAW) {
+        if(MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_PREVIEW].id)))
+        {
+            CDBG_ERROR("%s : Delete Preview error",__func__);
+            goto end;
+        }
+    }*/
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_RDI].id))) {
+        CDBG_ERROR("%s : Delete Stream RDI error",__func__);
+        goto end;
+    }
+    CDBG("del_stream successfull");
+    pme->cam_state = CAMERA_STATE_OPEN;
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+
+    return rc;
+}
+
+int startRdi(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s: Start Preview",__func__);
+
+    if (pme->cam_mode == ZSL_MODE || pme->cam_mode == RECORDER_MODE || pme->cam_mode == CAMERA_MODE) {
+        switch (pme->cam_state) {
+        case CAMERA_STATE_RECORD:
+            if (MM_CAMERA_OK != mm_app_stop_video(cam_id)) {
+                CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
+                return -1;
+            }
+        case CAMERA_STATE_PREVIEW:
+            if (MM_CAMERA_OK != mm_app_open_rdi(cam_id)) {
+                CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__);
+                return -1;
+            }
+        case CAMERA_STATE_SNAPSHOT:
+        default:
+            break;
+        }
+    }
+    mm_app_start_rdi(cam_id);
+    return rc;
+}
+
+int stopRdi(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    mm_app_streamoff_rdi(cam_id);
+
+    end:
+    return rc;
+}
+
+
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_snapshot.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_snapshot.c
new file mode 100755
index 0000000..eec350d
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_snapshot.c
@@ -0,0 +1,1401 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include "mm_camera_dbg.h"
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include "mm_qcamera_app.h"
+
+#define BUFF_SIZE_128 128
+
+//static mm_camera_ch_data_buf_t *mCurrentFrameEncoded;
+static int JpegOffset = 0;
+static int raw_snapshot_cnt = 0;
+static int snapshot_cnt = 0;
+static pthread_mutex_t g_s_mutex;
+static int g_status = 0;
+static pthread_cond_t g_s_cond_v;
+
+
+static void mm_app_snapshot_done()
+{
+    pthread_mutex_lock(&g_s_mutex);
+    g_status = TRUE;
+    pthread_cond_signal(&g_s_cond_v);
+    pthread_mutex_unlock(&g_s_mutex);
+}
+
+static int mm_app_dump_snapshot_frame(struct msm_frame *frame,
+                                      uint32_t len, int is_main, int is_raw)
+{
+    char bufp[BUFF_SIZE_128];
+    int file_fdp;
+    int rc = 0;
+
+    if (is_raw) {
+        snprintf(bufp, BUFF_SIZE_128, "/data/main_raw_%d.yuv", raw_snapshot_cnt);
+    } else {
+        if (is_main) {
+            snprintf(bufp, BUFF_SIZE_128, "/data/main_%d.yuv", snapshot_cnt);
+        } else {
+            snprintf(bufp, BUFF_SIZE_128, "/data/thumb_%d.yuv", snapshot_cnt);
+        }
+    }
+
+    file_fdp = open(bufp, O_RDWR | O_CREAT, 0777);
+
+    if (file_fdp < 0) {
+        CDBG("cannot open file %s\n", bufp);
+        rc = -1;
+        goto end;
+    }
+    CDBG("%s:dump snapshot frame to '%s'\n", __func__, bufp);
+    write(file_fdp,
+          (const void *)frame->buffer, len);
+    close(file_fdp);
+    end:
+    return rc;
+}
+
+
+static void mm_app_dump_jpeg_frame(const void * data, uint32_t size, char* name, char* ext, int index)
+{
+    char buf[32];
+    int file_fd;
+    if ( data != NULL) {
+        char * str;
+        snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext);
+        CDBG("%s size =%d", buf, size);
+        file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+        write(file_fd, data, size);
+        close(file_fd);
+    }
+}
+
+static int mm_app_set_thumbnail_fmt(int cam_id,mm_camera_image_fmt_t *fmt)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
+    fmt->fmt = pme->dim.thumb_format;
+    fmt->width = pme->dim.thumbnail_width;
+    fmt->height = pme->dim.thumbnail_height;
+    CDBG("Thumbnail Dimension = %dX%d",fmt->width,fmt->height);
+    return rc;
+}
+
+int mm_app_set_snapshot_fmt(int cam_id,mm_camera_image_fmt_t *fmt)
+{
+
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
+    fmt->fmt = pme->dim.main_img_format;
+    fmt->width = pme->dim.picture_width;
+    fmt->height = pme->dim.picture_height;
+    CDBG("Snapshot Dimension = %dX%d",fmt->width,fmt->height);
+    return rc;
+}
+
+int mm_app_set_live_snapshot_fmt(int cam_id,mm_camera_image_fmt_t *fmt)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
+    fmt->fmt = pme->dim.enc_format;
+    fmt->width = pme->dim.video_width;
+    fmt->height = pme->dim.video_height;
+    CDBG("Livesnapshot Dimension = %dX%d",fmt->width,fmt->height);
+    return rc;
+}
+
+int mm_app_set_raw_snapshot_fmt(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+#if 0
+    /* now we hard code format */
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    mm_camera_ch_image_fmt_parm_t fmt;
+
+    CDBG("%s: BEGIN\n", __func__);
+    memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
+    fmt.ch_type = MM_CAMERA_CH_RAW;
+    fmt.def.fmt = CAMERA_BAYER_SBGGR10;
+    fmt.def.dim.width = pme->dim.raw_picture_width;
+    fmt.def.dim.height = pme->dim.raw_picture_height;
+    rc = pme->cam->cfg->set_parm(pme->cam, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
+    if (rc != MM_CAMERA_OK) {
+        CDBG("%s:set raw snapshot format err=%d\n", __func__, rc);
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+#endif 
+    return rc;
+}
+
+int mm_app_prepare_raw_snapshot_buf(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+#if 0
+    int j;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    mm_camera_reg_buf_t reg_buf;
+    uint32_t y_off, cbcr_off;
+    uint8_t num_planes_main;
+    uint32_t planes_main[VIDEO_MAX_PLANES];
+
+    CDBG("%s: BEGIN, raw_w=%d, raw_h=%d\n",
+         __func__, pme->dim.raw_picture_width, pme->dim.raw_picture_height);
+    memset(&reg_buf,  0,  sizeof(reg_buf));
+    reg_buf.def.buf.mp = malloc(sizeof(mm_camera_mp_buf_t));
+    if (!reg_buf.def.buf.mp) {
+        CDBG_ERROR("%s Error allocating memory for mplanar struct ", __func__);
+        rc = -MM_CAMERA_E_NO_MEMORY; 
+        goto end;
+    }
+
+    // setup main buffer
+    memset(&pme->raw_snapshot_buf, 0, sizeof(pme->raw_snapshot_buf));
+    pme->raw_snapshot_buf.num = 1;
+    pme->raw_snapshot_buf.frame_len = 
+    my_cam_app.hal_lib.mm_camera_get_msm_frame_len(CAMERA_BAYER_SBGGR10,
+                                                   CAMERA_MODE_2D,
+                                                   pme->dim.raw_picture_width,
+                                                   pme->dim.raw_picture_height,
+                                                   OUTPUT_TYPE_S,
+                                                   &num_planes_main,
+                                                   planes_main);
+#ifdef USE_ION
+    pme->raw_snapshot_buf.frame[0].ion_alloc.len = pme->raw_snapshot_buf.frame_len;
+    pme->raw_snapshot_buf.frame[0].ion_alloc.flags = (0x1 << CAMERA_ION_HEAP_ID);
+    pme->raw_snapshot_buf.frame[0].ion_alloc.align = 4096;
+#endif
+    pme->raw_snapshot_buf.frame[0].buffer = (unsigned long) my_cam_app.hal_lib.mm_camera_do_mmap(
+                                                                                                pme->raw_snapshot_buf.frame_len, &pme->raw_snapshot_buf.frame[0].fd);
+
+
+    if (!pme->raw_snapshot_buf.frame[0].buffer) {
+        CDBG("%s:no mem for snapshot buf\n", __func__);
+        rc = -MM_CAMERA_E_NO_MEMORY;
+        goto end;
+    }
+    pme->raw_snapshot_buf.frame[0].path = OUTPUT_TYPE_S;
+    pme->preview_buf.frame[0].y_off = 0;
+    pme->raw_snapshot_buf.frame[0].cbcr_off = planes_main[0];
+
+    /*setup registration buffer*/
+    reg_buf.def.buf.mp[0].frame = pme->raw_snapshot_buf.frame[0];
+    reg_buf.def.buf.mp[0].frame_offset = 0;
+    reg_buf.def.buf.mp[0].num_planes = num_planes_main;
+
+    reg_buf.def.buf.mp[0].planes[0].length = planes_main[0];
+    reg_buf.def.buf.mp[0].planes[0].m.userptr = pme->raw_snapshot_buf.frame[0].fd;
+    reg_buf.def.buf.mp[0].planes[0].data_offset = 0;
+    reg_buf.def.buf.mp[0].planes[0].reserved[0] = reg_buf.def.buf.mp[0].frame_offset;
+    for (j = 1; j < num_planes_main; j++) {
+        reg_buf.def.buf.mp[0].planes[j].length = planes_main[j];
+        reg_buf.def.buf.mp[0].planes[j].m.userptr = pme->raw_snapshot_buf.frame[0].fd;
+        reg_buf.def.buf.mp[0].planes[j].data_offset = 0;
+        reg_buf.def.buf.mp[0].planes[j].reserved[0] = reg_buf.def.buf.mp[0].planes[j-1].reserved[0] +
+                                                      reg_buf.def.buf.mp[0].planes[j-1].length;
+    }
+
+    reg_buf.ch_type = MM_CAMERA_CH_RAW;
+    reg_buf.def.num = pme->raw_snapshot_buf.num;
+    rc = pme->cam->cfg->prepare_buf(pme->cam, &reg_buf);
+    if (rc != MM_CAMERA_OK) {
+        CDBG("%s:reg snapshot buf err=%d\n", __func__, rc);
+        goto end;
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+#endif 
+    return rc;
+}
+
+static int mm_app_unprepare_raw_snapshot_buf(int cam_id)
+{
+    int i, rc = MM_CAMERA_OK;
+#if 0
+    /* now we hard code format */
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s: BEGIN\n", __func__);
+    rc = pme->cam->cfg->unprepare_buf(pme->cam, MM_CAMERA_CH_RAW);
+    rc = my_cam_app.hal_lib.mm_camera_do_munmap(pme->raw_snapshot_buf.frame[0].fd,
+                                                (void *)pme->raw_snapshot_buf.frame[0].buffer,
+                                                pme->raw_snapshot_buf.frame_len);
+    rc = my_cam_app.hal_lib.mm_camera_do_munmap(pme->jpeg_buf.frame[0].fd,
+                                                (void *)pme->jpeg_buf.frame[0].buffer,
+                                                pme->jpeg_buf.frame_len);
+    /* zero out the buf stuct */
+    memset(&pme->raw_snapshot_buf, 0, sizeof(pme->raw_snapshot_buf));
+    memset(&pme->jpeg_buf, 0, sizeof(pme->jpeg_buf));
+
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+#endif
+    return rc;
+}
+
+#ifndef DISABLE_JPEG_ENCODING
+/* Once we give frame for encoding, we get encoded jpeg image
+   fragments by fragment. We'll need to store them in a buffer
+   to form complete JPEG image */
+static void snapshot_jpeg_fragment_cb(uint8_t *ptr,
+                                      uint32_t size,
+                                      void *user_data)
+{
+#if 0
+    mm_camera_app_obj_t *pme = user_data;
+
+    CDBG("%s: E",__func__);
+    if (pme) {
+        memcpy((uint8_t *)((uint32_t)pme->jpeg_buf.frame[0].buffer + JpegOffset), ptr, size);
+        JpegOffset += size;
+    }
+    CDBG("%s: X",__func__);
+#endif
+}
+#endif
+/* This callback is received once the complete JPEG encoding is done */
+static void snapshot_raw_cb(mm_camera_super_buf_t *bufs,
+                            void *user_data)
+{
+
+    int rc;
+    int i = 0;
+    mm_camera_buf_def_t *main_frame = NULL;
+    mm_camera_buf_def_t *thumb_frame = NULL;
+    mm_camera_app_obj_t *pme = NULL;
+    CDBG("%s: BEGIN\n", __func__); 
+
+    pme = (mm_camera_app_obj_t *)user_data;
+
+    CDBG("%s : total streams = %d",__func__,bufs->num_bufs);
+    main_frame = bufs->bufs[0];
+    thumb_frame = bufs->bufs[1];
+
+    CDBG("mainframe frame_idx = %d fd = %d frame length = %d",main_frame->frame_idx,main_frame->fd,main_frame->frame_len);
+    CDBG("thumnail frame_idx = %d fd = %d frame length = %d",thumb_frame->frame_idx,thumb_frame->fd,thumb_frame->frame_len);
+
+    //dumpFrameToFile(main_frame->frame,pme->dim.picture_width,pme->dim.picture_height,"main", 1);
+    //dumpFrameToFile(thumb_frame->frame,pme->dim.thumbnail_width,pme->dim.thumbnail_height,"thumb", 1);
+
+    dumpFrameToFile(main_frame,pme->dim.picture_width,pme->dim.picture_height,"main", 1);
+    dumpFrameToFile(thumb_frame,pme->dim.thumbnail_width,pme->dim.thumbnail_height,"thumb", 1);
+
+    if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,main_frame)) {
+        CDBG_ERROR("%s: Failed in thumbnail Qbuf\n", __func__); 
+    }
+    if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,thumb_frame)) {
+        CDBG_ERROR("%s: Failed in thumbnail Qbuf\n", __func__); 
+    }
+
+    mm_app_snapshot_done();
+    CDBG("%s: END\n", __func__); 
+
+
+}
+
+#ifndef DISABLE_JPEG_ENCODING
+static int encodeData(mm_camera_super_buf_t* recvd_frame,
+                      int frame_len,
+                      int enqueued,
+                      mm_camera_app_obj_t *pme)
+{
+    int ret = -1;
+#if 0
+
+    cam_ctrl_dimension_t dimension;
+    struct msm_frame *postviewframe;
+    struct msm_frame *mainframe;
+    common_crop_t crop;
+    cam_point_t main_crop_offset;
+    cam_point_t thumb_crop_offset;
+    int width, height;
+    uint8_t *thumbnail_buf;
+    uint32_t thumbnail_fd;
+
+    omx_jpeg_encode_params encode_params;
+    postviewframe = recvd_frame->snapshot.thumbnail.frame;
+    mainframe = recvd_frame->snapshot.main.frame;
+    dimension.orig_picture_dx = pme->dim.picture_width;
+    dimension.orig_picture_dy = pme->dim.picture_height;
+    dimension.thumbnail_width = pme->dim.ui_thumbnail_width;
+    dimension.thumbnail_height = pme->dim.ui_thumbnail_height;
+    dimension.main_img_format = pme->dim.main_img_format;
+    dimension.thumb_format = pme->dim.thumb_format;
+
+    CDBG("Setting callbacks, initializing encoder and start encoding.");
+    my_cam_app.hal_lib.set_callbacks(snapshot_jpeg_fragment_cb, snapshot_jpeg_cb, pme,
+                                     (void *)pme->jpeg_buf.frame[0].buffer, &JpegOffset);
+    my_cam_app.hal_lib.omxJpegStart();
+    my_cam_app.hal_lib.mm_jpeg_encoder_setMainImageQuality(85);
+
+    /*TBD: Pass 0 as cropinfo for now as v4l2 doesn't provide
+      cropinfo. It'll be changed later.*/
+    memset(&crop,0,sizeof(common_crop_t));
+    memset(&main_crop_offset,0,sizeof(cam_point_t));
+    memset(&thumb_crop_offset,0,sizeof(cam_point_t));
+
+    /*Fill in the encode parameters*/
+    encode_params.dimension = (const cam_ctrl_dimension_t *)&dimension;
+    encode_params.thumbnail_buf = (uint8_t *)postviewframe->buffer;
+    encode_params.thumbnail_fd = postviewframe->fd;
+    encode_params.thumbnail_offset = postviewframe->phy_offset;
+    encode_params.snapshot_buf = (uint8_t *)mainframe->buffer;
+    encode_params.snapshot_fd = mainframe->fd;
+    encode_params.snapshot_offset = mainframe->phy_offset;
+    encode_params.scaling_params = &crop;
+    encode_params.exif_data = NULL;
+    encode_params.exif_numEntries = 0;
+    encode_params.a_cbcroffset = -1;
+    encode_params.main_crop_offset = &main_crop_offset;
+    encode_params.thumb_crop_offset = &thumb_crop_offset;
+
+    if (!my_cam_app.hal_lib.omxJpegEncode(&encode_params)) {
+        CDBG_ERROR("%s: Failure! JPEG encoder returned error.", __func__);
+        ret = -1;
+        goto end;
+    }
+
+    /* Save the pointer to the frame sent for encoding. we'll need it to
+       tell kernel that we are done with the frame.*/
+    mCurrentFrameEncoded = recvd_frame;
+
+    end:
+    CDBG("%s: X", __func__); 
+#endif 
+    return ret;
+}
+
+static int encodeDisplayAndSave(mm_camera_super_buf_t* recvd_frame,
+                                int enqueued, mm_camera_app_obj_t *pme)
+{
+    int ret = -1;
+#if 0
+
+
+    CDBG("%s: Send frame for encoding", __func__);
+    ret = encodeData(recvd_frame, pme->snapshot_buf.frame_len,
+                     enqueued, pme);
+    if (!ret) {
+        CDBG_ERROR("%s: Failure configuring JPEG encoder", __func__);
+    }
+
+    LOGD("%s: X", __func__); 
+#endif 
+    return ret;
+}
+#endif //DISABLE_JPEG_ENCODING
+static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
+                                      void *user_data)
+{
+#if 0
+    mm_camera_app_obj_t *pme = user_data;
+    int rc;
+
+    CDBG("%s: BEGIN\n", __func__);
+    snapshot_cnt++;
+    mm_app_dump_snapshot_frame(bufs->snapshot.main.frame, pme->snapshot_buf.frame_len, TRUE, 0);
+    mm_app_dump_snapshot_frame(bufs->snapshot.thumbnail.frame, pme->thumbnail_buf.frame_len, FALSE, 0);
+#ifndef DISABLE_JPEG_ENCODING
+    /* The recvd_frame structre we receive from lower library is a local
+variable. So we'll need to save this structure so that we won't
+be later pointing to garbage data when that variable goes out of
+scope */
+    mm_camera_ch_data_buf_t* frame =
+    (mm_camera_ch_data_buf_t *)malloc(sizeof(mm_camera_ch_data_buf_t));
+    if (frame == NULL) {
+        CDBG_ERROR("%s: Error allocating memory to save received_frame structure.", __func__);
+        goto error1;
+    }
+    memcpy(frame, bufs, sizeof(mm_camera_ch_data_buf_t));
+    rc = encodeDisplayAndSave(frame, 0, pme);
+    if (!rc) {
+        CDBG_ERROR("%s: Error encoding buffer.", __func__);
+        goto error;
+    }
+#endif //DISABLE_JPEG_ENCODING
+    /* return buffer back for taking next snapshot */
+    pme->cam->evt->buf_done(pme->cam, bufs);
+    mm_app_snapshot_done();
+/*
+        CDBG("%s: calling mm_app_snapshot_done()\n", __func__);
+        mm_app_snapshot_done();
+*/
+    CDBG("%s: END\n", __func__);
+    return;
+    error:
+    /*if (frame != NULL)
+      free(frame);*/
+    error1:
+    pme->cam->evt->buf_done(pme->cam, bufs);
+    mm_app_snapshot_done();   
+#endif 
+    return;
+}
+
+static void mm_app_raw_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
+                                          void *user_data)
+{
+#if 0
+    mm_camera_app_obj_t *pme = user_data;
+    static int loop = 0;
+
+    CDBG("%s: BEGIN\n", __func__);
+    raw_snapshot_cnt++;
+    mm_app_dump_snapshot_frame(bufs->def.frame, pme->raw_snapshot_buf.frame_len, TRUE, 1);
+    /* return buffer back for taking next snapshot */
+    pme->cam->evt->buf_done(pme->cam, bufs);
+    CDBG("%s: calling mm_app_snapshot_done()\n", __func__);
+    mm_app_snapshot_done();
+    CDBG("%s: END\n", __func__); 
+#endif 
+}
+static int mm_app_reg_snapshot_data_cb(int cam_id, int is_reg)
+{
+    int rc = MM_CAMERA_OK;
+#if 0
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+
+    CDBG("%s: BEGIN\n", __func__);
+    if (is_reg) {
+        rc = pme->cam->evt->register_buf_notify(pme->cam,
+                                                MM_CAMERA_CH_SNAPSHOT,
+                                                mm_app_snapshot_notify_cb,
+                                                MM_CAMERA_REG_BUF_CB_INFINITE, 0,
+                                                pme);
+        if (rc != MM_CAMERA_OK) {
+            CDBG("%s:register snapshot data notify cb err=%d\n",
+                 __func__, rc);
+            goto end;
+        }
+    } else {
+        rc = pme->cam->evt->register_buf_notify(pme->cam,
+                                                MM_CAMERA_CH_SNAPSHOT,
+                                                NULL,
+                                                (mm_camera_register_buf_cb_type_t)NULL,
+                                                0, pme);
+        if (rc != MM_CAMERA_OK) {
+            CDBG("%s:unregister snapshot data notify cb err=%d\n",
+                 __func__, rc);
+            goto end;
+        }
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+#endif 
+    return rc;
+}
+static int mm_app_reg_raw_snapshot_data_cb(int cam_id, int is_reg)
+{
+    int rc = MM_CAMERA_OK;
+#if 0
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+
+    CDBG("%s: BEGIN\n", __func__);
+    if (is_reg) {
+        rc = pme->cam->evt->register_buf_notify(pme->cam,
+                                                MM_CAMERA_CH_RAW,
+                                                mm_app_raw_snapshot_notify_cb,
+                                                MM_CAMERA_REG_BUF_CB_INFINITE, 0,
+                                                pme);
+        if (rc != MM_CAMERA_OK) {
+            CDBG("%s:register raw snapshot data notify cb err=%d\n",
+                 __func__, rc);
+            goto end;
+        }
+    } else {
+        rc = pme->cam->evt->register_buf_notify(pme->cam,
+                                                MM_CAMERA_CH_RAW,
+                                                NULL,
+                                                (mm_camera_register_buf_cb_type_t)NULL, 0, pme);
+        if (rc != MM_CAMERA_OK) {
+            CDBG("%s:unregister raw snapshot data notify cb err=%d\n",
+                 __func__, rc);
+            goto end;
+        }
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc); 
+#endif 
+    return rc;
+}
+
+int mm_app_add_snapshot_stream(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+                                                                        NULL,pme,
+                                                                        MM_CAMERA_SNAPSHOT_MAIN, 0);
+
+    CDBG("Add Snapshot main is successfull stream ID = %d",pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id);
+    if (!pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id) {
+        CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+    pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+                                                                             NULL,pme,
+                                                                             MM_CAMERA_SNAPSHOT_THUMBNAIL, 0);
+    if (!pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].id) {
+        CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+void mm_app_set_snapshot_mode(int cam_id,int op_mode)
+{
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_OP_MODE, &op_mode);
+
+}
+
+int mm_app_config_snapshot_format(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    mm_app_set_snapshot_fmt(cam_id,&pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.fmt);
+
+    mm_app_set_thumbnail_fmt(cam_id,&pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].str_config.fmt);
+
+    pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.need_stream_on = 1;
+    pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.num_of_bufs = 1;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id,
+                                                           &pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config))) {
+        CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].str_config.need_stream_on = 1;
+    pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].str_config.num_of_bufs = 1;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].id,
+                                                           &pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].str_config))) {
+        CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+        goto end;
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+
+}
+
+int mm_app_streamon_snapshot(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+    mm_camera_bundle_attr_t attr;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    stream[0] = pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id;
+    stream[1] = pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].id;
+
+    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
+    attr.burst_num = 1;
+    attr.look_back = 2;
+    attr.post_frame_skip = 0;
+    attr.water_mark = 2;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->init_stream_bundle(
+                                                               pme->cam->camera_handle,pme->ch_id,snapshot_raw_cb,pme,&attr,2,stream))) {
+        CDBG_ERROR("%s:init_stream_bundle err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,
+                                                           2, stream))) {
+        CDBG_ERROR("%s:start_streams err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc =pme->cam->ops->request_super_buf(pme->cam->camera_handle,pme->ch_id))) {
+        CDBG_ERROR("%s:request_super_buf err=%d\n", __func__, rc);
+        goto end;
+    }
+    pme->cam_state = CAMERA_STATE_SNAPSHOT;
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_streamoff_snapshot(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    stream[0] = pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id;
+    stream[1] = pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].id;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle,pme->ch_id,2,&stream))) {
+        CDBG_ERROR("%s : Snapshot Stream off Error",__func__);
+        goto end;
+    }
+    CDBG("Stop snapshot main successfull");
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->destroy_stream_bundle(pme->cam->camera_handle,pme->ch_id))) {
+        CDBG_ERROR("%s : Snapshot destroy_stream_bundle Error",__func__);
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id))) {
+        CDBG_ERROR("%s : Snapshot main image del_stream Error",__func__);
+        goto end;
+    }
+    CDBG("del_stream successfull");
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].id))) {
+        CDBG_ERROR("%s : Snapshot thumnail image del_stream Error",__func__);
+        goto end;
+    }
+    CDBG("del_stream successfull");
+
+    end:
+    return rc;
+}
+
+int mm_app_start_snapshot(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+    int op_mode = 0; 
+
+    mm_camera_bundle_attr_t attr;
+
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    if (MM_CAMERA_OK != mm_app_stop_preview(cam_id)) {
+        CDBG_ERROR("%s: Stop preview Failed cam_id=%d\n",__func__,cam_id);
+        return -1;
+    }
+
+    op_mode = MM_CAMERA_OP_MODE_CAPTURE;
+    mm_app_set_snapshot_mode(cam_id,op_mode);
+
+    pme->cam->ops->prepare_snapshot(pme->cam->camera_handle,pme->ch_id,0);
+
+    if (MM_CAMERA_OK != (rc = mm_app_add_snapshot_stream(cam_id))) {
+        CDBG_ERROR("%s : Add Snapshot stream err",__func__);
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_config_snapshot_format(cam_id))) {
+        CDBG_ERROR("%s : Config Snapshot stream err",__func__);
+    }
+
+    if (MM_CAMERA_OK != (rc = mm_app_streamon_snapshot(cam_id))) {
+        CDBG_ERROR("%s : Stream on Snapshot stream err",__func__);
+    }
+
+#if 0
+    /*start OMX Jpeg encoder*/
+#ifndef DISABLE_JPEG_ENCODING
+    my_cam_app.hal_lib.omxJpegOpen();
+#endif
+
+#endif 
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+
+    return rc;
+}
+
+
+int mm_app_stop_snapshot(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[2];
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    stream[0] = pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id;
+    stream[1] = pme->stream[MM_CAMERA_SNAPSHOT_THUMBNAIL].id;
+
+    if (MM_CAMERA_OK != (rc = mm_app_streamoff_snapshot(cam_id))) {
+        CDBG_ERROR("%s : Stream off Snapshot stream err",__func__);
+    }
+    pme->cam_state = CAMERA_STATE_OPEN;
+#if 0
+#ifndef DISABLE_JPEG_ENCODING
+    my_cam_app.hal_lib.omxJpegClose();
+#endif
+#endif 
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+
+    return rc;
+}
+
+int mm_app_start_raw_snapshot(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+#if 0
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    mm_camera_channel_attr_t attr;
+
+
+    attr.type = MM_CAMERA_CH_ATTR_RAW_STREAMING_TYPE;
+    attr.raw_streaming_mode = MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE;
+
+    if (MM_CAMERA_OK != (rc = mm_app_set_op_mode(cam_id, MM_CAMERA_OP_MODE_CAPTURE))) {
+        CDBG("%s:mm_app_set_op_mode(op_mode=%d) err=%d\n", __func__,
+             MM_CAMERA_OP_MODE_CAPTURE, rc);
+        goto end;
+    }
+    if (MM_CAMERA_OK != (rc = mm_app_open_ch(cam_id, MM_CAMERA_CH_RAW))) {
+        CDBG("%s:open raw snapshot channel err=%d\n", __func__, rc);
+        goto end;
+    }
+    if (MM_CAMERA_OK != (rc = mm_app_set_raw_snapshot_fmt(cam_id))) {
+        CDBG("%s:set raw snapshot format err=%d\n", __func__, rc);
+        goto end;
+    }
+    mm_app_get_dim(cam_id, NULL);
+    if (MM_CAMERA_OK != (rc = mm_app_prepare_raw_snapshot_buf(cam_id))) {
+        CDBG("%s:reg raw snapshot buf err=%d\n", __func__, rc);
+        goto end;
+    }
+    if (MM_CAMERA_OK != (rc = mm_app_reg_raw_snapshot_data_cb(cam_id, TRUE))) {
+        CDBG("%s:reg raw snapshot data cb err=%d\n", __func__, rc);
+    }
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->ch_set_attr(pme->cam, MM_CAMERA_CH_RAW, &attr))) {
+        CDBG("%s:set raw capture attribute err=%d\n", __func__, rc);
+        goto end;
+    }
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->action(pme->cam, TRUE, MM_CAMERA_OPS_RAW, 0))) {
+        CDBG("%s:snapshot streaming err=%d\n", __func__, rc);
+        goto end;
+    }
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+#endif
+    return rc;
+}
+
+int mm_app_stop_raw_snapshot(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+#if 0
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+
+    CDBG("%s: BEGIN\n", __func__);
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->action(pme->cam, FALSE, MM_CAMERA_OPS_RAW, 0))) {
+        CDBG("%s:stop raw snapshot streaming err=%d\n", __func__, rc);
+        goto end;
+    }
+    if (MM_CAMERA_OK != (rc = mm_app_unprepare_raw_snapshot_buf(cam_id))) {
+        CDBG("%s:mm_app_unprepare_raw_snapshot_buf err=%d\n", __func__, rc);
+        return rc;
+    }
+    if (MM_CAMERA_OK != (rc = mm_app_reg_raw_snapshot_data_cb(cam_id, FALSE))) {
+        CDBG("%s:mm_app_reg_raw_snapshot_data_cb err=%d\n", __func__, rc);
+        return rc;
+    }
+    mm_app_close_ch(cam_id, MM_CAMERA_CH_RAW);
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+#endif
+    return rc;
+}
+
+static void mm_app_snapshot_wait(int cam_id)
+{
+    pthread_mutex_lock(&g_s_mutex);
+    if (FALSE == g_status) {
+        pthread_cond_wait(&g_s_cond_v, &g_s_mutex);
+        g_status = FALSE;
+    }
+    pthread_mutex_unlock(&g_s_mutex);
+}
+
+#if 0
+int mm_stream_deinit_thumbnail_buf(uint32_t camera_handle,
+                                   uint32_t ch_id, uint32_t stream_id,
+                                   void *user_data, uint8_t num_bufs,
+                                   mm_camera_buf_def_t *bufs)
+{
+    int i, rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+    for (i = 0; i < num_bufs; i++) {
+        rc = my_cam_app.hal_lib.mm_camera_do_munmap_ion (pme->ionfd, &(pme->thumbnail_buf.frame[i].fd_data),
+                                                         (void *)pme->thumbnail_buf.frame[i].buffer, pme->thumbnail_buf.frame_len);
+        if (rc != MM_CAMERA_OK) {
+            CDBG("%s: mm_camera_do_munmap err, pmem_fd = %d, rc = %d",
+                 __func__, bufs[i].fd, rc);
+        }
+    }
+    return rc;
+}
+
+int mm_stream_deinit_main_buf(uint32_t camera_handle,
+                              uint32_t ch_id, uint32_t stream_id,
+                              void *user_data, uint8_t num_bufs,
+                              mm_camera_buf_def_t *bufs)
+{
+    int i, rc = MM_CAMERA_OK;
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+    for (i = 0; i < num_bufs; i++) {
+        rc = my_cam_app.hal_lib.mm_camera_do_munmap_ion (pme->ionfd, &(pme->snapshot_buf.frame[i].fd_data),
+                                                         (void *)pme->snapshot_buf.frame[i].buffer, pme->snapshot_buf.frame_len);
+        if (rc != MM_CAMERA_OK) {
+            CDBG("%s: mm_camera_do_munmap err, pmem_fd = %d, rc = %d",
+                 __func__, bufs[i].fd, rc);
+        }
+    }
+    return rc;
+}
+
+int mm_stream_init_main_buf(uint32_t camera_handle,
+                            uint32_t ch_id, uint32_t stream_id,
+                            void *user_data,
+                            mm_camera_frame_len_offset *frame_offset_info,
+                            uint8_t num_bufs,
+                            uint8_t *initial_reg_flag,
+                            mm_camera_buf_def_t *bufs)
+{
+    int i,j,num_planes, frame_len, y_off, cbcr_off;
+    uint32_t planes[VIDEO_MAX_PLANES];
+    uint32_t pmem_addr = 0;
+
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+    num_planes = frame_offset_info->num_planes;
+    for ( i = 0; i < num_planes; i++) {
+        planes[i] = frame_offset_info->mp[i].len;
+    }
+
+    frame_len = frame_offset_info->frame_len;
+    y_off = frame_offset_info->mp[0].offset;
+    cbcr_off = frame_offset_info->mp[1].offset;
+
+    CDBG("Allocating main image Memory for %d buffers frame_len = %d",num_bufs,frame_offset_info->frame_len);
+
+    for (i = 0; i < num_bufs ; i++) {
+        int j;
+        if (pme->cam_mode != RECORDER_MODE || pme->fullSizeSnapshot) {
+            pme->snapshot_buf.reg[i] = 1;
+            initial_reg_flag[i] = 1;
+        } else {
+            pme->snapshot_buf.reg[i] = 0;
+            initial_reg_flag[i] = 0;
+        }
+
+        pme->snapshot_buf.frame_len = frame_len;
+
+        pme->snapshot_buf.frame[i].ion_alloc.len = pme->snapshot_buf.frame_len;
+        pme->snapshot_buf.frame[i].ion_alloc.flags =
+        (0x1 << CAMERA_ION_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID);
+        pme->snapshot_buf.frame[i].ion_alloc.align = 4096;
+
+        pmem_addr = (unsigned long) my_cam_app.hal_lib.mm_camera_do_mmap_ion(pme->ionfd,
+                                                                             &(pme->snapshot_buf.frame[i].ion_alloc), &(pme->snapshot_buf.frame[i].fd_data),
+                                                                             &pme->snapshot_buf.frame[i].fd);
+
+        pme->snapshot_buf.frame[i].buffer = pmem_addr;
+        pme->snapshot_buf.frame[i].path = OUTPUT_TYPE_S;
+        pme->snapshot_buf.frame[i].y_off = 0;
+        pme->snapshot_buf.frame[i].cbcr_off = planes[0];
+        pme->snapshot_buf.frame[i].phy_offset = 0;
+
+        CDBG("Buffer allocated Successfully fd = %d",pme->snapshot_buf.frame[i].fd);
+
+        bufs[i].fd = pme->snapshot_buf.frame[i].fd;
+        //bufs[i].buffer = pmem_addr;
+        bufs[i].frame_len = pme->snapshot_buf.frame[i].ion_alloc.len;
+        bufs[i].num_planes = num_planes;
+
+        bufs[i].frame = &pme->snapshot_buf.frame[i];
+
+        /* Plane 0 needs to be set seperately. Set other planes
+     * in a loop. */
+        bufs[i].planes[0].length = planes[0];
+        bufs[i].planes[0].m.userptr = bufs[i].fd;
+        bufs[i].planes[0].data_offset = y_off;
+        bufs[i].planes[0].reserved[0] = 0;
+        //buf_def->buf.mp[i].frame_offset;
+        for (j = 1; j < num_planes; j++) {
+            bufs[i].planes[j].length = planes[j];
+            bufs[i].planes[j].m.userptr = bufs[i].fd;
+            bufs[i].planes[j].data_offset = cbcr_off;
+            bufs[i].planes[j].reserved[0] =
+            bufs[i].planes[j-1].reserved[0] +
+            bufs[i].planes[j-1].length;
+        }
+    }
+    return MM_CAMERA_OK;
+}
+
+int mm_stream_init_thumbnail_buf(uint32_t camera_handle,
+                                 uint32_t ch_id, uint32_t stream_id,
+                                 void *user_data,
+                                 mm_camera_frame_len_offset *frame_offset_info,
+                                 uint8_t num_bufs,
+                                 uint8_t *initial_reg_flag,
+                                 mm_camera_buf_def_t *bufs)
+{
+    int i,j,num_planes, frame_len, y_off, cbcr_off;
+    uint32_t planes[VIDEO_MAX_PLANES];
+    uint32_t pmem_addr = 0;
+
+    mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+    num_planes = frame_offset_info->num_planes;
+    for ( i = 0; i < num_planes; i++) {
+        planes[i] = frame_offset_info->mp[i].len;
+    }
+
+    frame_len = frame_offset_info->frame_len;
+    y_off = frame_offset_info->mp[0].offset;
+    cbcr_off = frame_offset_info->mp[1].offset;
+
+    CDBG("Allocating thumanail image  Memory for %d buffers frame_len = %d",num_bufs,frame_offset_info->frame_len);
+
+    for (i = 0; i < num_bufs ; i++) {
+        int j;
+        pme->thumbnail_buf.reg[i] = 1;
+        initial_reg_flag[i] = 1;
+
+        pme->thumbnail_buf.frame_len = frame_len;
+        pme->thumbnail_buf.frame[i].ion_alloc.len = pme->thumbnail_buf.frame_len;
+        pme->thumbnail_buf.frame[i].ion_alloc.flags =
+        (0x1 << CAMERA_ION_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID);
+        pme->thumbnail_buf.frame[i].ion_alloc.align = 4096;
+
+        pmem_addr = (unsigned long) my_cam_app.hal_lib.mm_camera_do_mmap_ion(pme->ionfd,
+                                                                             &(pme->thumbnail_buf.frame[i].ion_alloc), &(pme->thumbnail_buf.frame[i].fd_data),
+                                                                             &pme->thumbnail_buf.frame[i].fd);
+
+        pme->thumbnail_buf.frame[i].buffer = pmem_addr;
+        pme->thumbnail_buf.frame[i].path = OUTPUT_TYPE_S;
+        pme->thumbnail_buf.frame[i].y_off = 0;
+        pme->thumbnail_buf.frame[i].cbcr_off = planes[0];
+        pme->thumbnail_buf.frame[i].phy_offset = 0;
+
+        CDBG("Buffer allocated Successfully fd = %d",pme->thumbnail_buf.frame[i].fd);
+
+        bufs[i].fd = pme->thumbnail_buf.frame[i].fd;
+        //bufs[i].buffer = pmem_addr;
+        bufs[i].frame_len = pme->thumbnail_buf.frame[i].ion_alloc.len;
+        bufs[i].num_planes = num_planes;
+
+        bufs[i].frame = &pme->thumbnail_buf.frame[i];
+
+        /* Plane 0 needs to be set seperately. Set other planes
+     * in a loop. */
+        bufs[i].planes[0].length = planes[0];
+        bufs[i].planes[0].m.userptr = bufs[i].fd;
+        bufs[i].planes[0].data_offset = y_off;
+        bufs[i].planes[0].reserved[0] = 0;
+        //buf_def->buf.mp[i].frame_offset;
+        for (j = 1; j < num_planes; j++) {
+            bufs[i].planes[j].length = planes[j];
+            bufs[i].planes[j].m.userptr = bufs[i].fd;
+            bufs[i].planes[j].data_offset = cbcr_off;
+            bufs[i].planes[j].reserved[0] =
+            bufs[i].planes[j-1].reserved[0] +
+            bufs[i].planes[j-1].length;
+        }
+    }
+    return MM_CAMERA_OK;
+}
+#endif
+#if 0
+int mm_app_bundle_zsl_stream(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int stream[3];
+    mm_camera_bundle_attr_t attr;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    stream[0] = pme->stream[MM_CAMERA_PREVIEW].id;
+    stream[1] = pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id;
+
+    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
+    attr.burst_num = 1;
+    attr.look_back = 2;
+    attr.post_frame_skip = 0;
+    attr.water_mark = 2;
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->init_stream_bundle(
+                                                               pme->cam->camera_handle,pme->ch_id,mm_app_zsl_notify_cb,pme,&attr,2,stream))) {
+        CDBG_ERROR("%s:init_stream_bundle err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,
+                                                           2, stream))) {
+        CDBG_ERROR("%s:start_streams err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+    end:
+    return rc;
+}
+#endif
+
+static void mm_app_live_notify_cb(mm_camera_super_buf_t *bufs,
+                                  void *user_data)
+{
+
+    int rc;
+    int i = 0;
+    mm_camera_buf_def_t *main_frame = NULL;
+    mm_camera_app_obj_t *pme = NULL;
+    CDBG("%s: BEGIN\n", __func__); 
+
+    pme = (mm_camera_app_obj_t *)user_data;
+
+    CDBG("%s : total streams = %d",__func__,bufs->num_bufs);
+    main_frame = bufs->bufs[0];
+    //thumb_frame = bufs->bufs[1];
+
+    CDBG("mainframe frame_idx = %d fd = %d frame length = %d",main_frame->frame_idx,main_frame->fd,main_frame->frame_len);
+    //CDBG("thumnail frame_idx = %d fd = %d frame length = %d",thumb_frame->frame_idx,thumb_frame->fd,thumb_frame->frame_len);
+
+    //dumpFrameToFile(main_frame->frame,pme->dim.picture_width,pme->dim.picture_height,"main", 1);
+
+    dumpFrameToFile(main_frame,pme->dim.picture_width,pme->dim.picture_height,"liveshot_main", 1);
+
+    if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,main_frame)) {
+        CDBG_ERROR("%s: Failed in thumbnail Qbuf\n", __func__); 
+    }
+    /*if(MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,thumb_frame))
+    {
+            CDBG_ERROR("%s: Failed in thumbnail Qbuf\n", __func__); 
+    }*/
+
+    mm_app_snapshot_done();
+    CDBG("%s: END\n", __func__); 
+
+
+}
+
+int mm_app_prepare_live_snapshot(int cam_id)
+{
+    int rc = 0;
+    int stream[1];
+    mm_camera_bundle_attr_t attr;
+    int value = 0;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    CDBG("%s:BEGIN, cam_id=%d\n",__func__,cam_id);
+
+    stream[0] = pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id;
+    //stream[1] = pme->stream[MM_CAMERA_PREVIEW].id;  //Need to clarify
+
+    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
+    attr.burst_num = 1;
+    attr.look_back = 2;
+    attr.post_frame_skip = 0;
+    attr.water_mark = 2;
+
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->set_parm(
+                                                     pme->cam->camera_handle,MM_CAMERA_PARM_FULL_LIVESHOT, (void *)&value))) {
+        CDBG_ERROR("%s: set dimension err=%d\n", __func__, rc);
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->init_stream_bundle(
+                                                               pme->cam->camera_handle,pme->ch_id,mm_app_live_notify_cb,pme,&attr,1,stream))) {
+        CDBG_ERROR("%s:init_stream_bundle err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,
+                                                           1, stream))) {
+        CDBG_ERROR("%s:start_streams err=%d\n", __func__, rc);
+        rc = -1;
+        goto end;
+    }
+
+
+    end:
+    CDBG("%s:END, cam_id=%d\n",__func__,cam_id);
+    return rc;
+}
+
+int mm_app_unprepare_live_snapshot(int cam_id)
+{
+    int rc = 0;
+    int stream[2];
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+    CDBG("%s:BEGIN, cam_id=%d\n",__func__,cam_id);
+
+    stream[0] = pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id;
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle,pme->ch_id,1,&stream))) {
+        CDBG_ERROR("%s : Snapshot Stream off Error",__func__);
+        return -1;
+    }
+
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->destroy_stream_bundle(pme->cam->camera_handle,pme->ch_id))) {
+        CDBG_ERROR("%s : Snapshot destroy_stream_bundle Error",__func__);
+        return -1;
+    }
+    CDBG("%s:END, cam_id=%d\n",__func__,cam_id);
+    return rc;
+}
+
+int mm_app_take_live_snapshot(int cam_id)
+{
+    int rc = 0;
+    int stream[3];
+    mm_camera_bundle_attr_t attr;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s:BEGIN, cam_id=%d\n",__func__,cam_id);
+
+    if (pme->cam_mode == RECORDER_MODE && 
+        pme->cam_state == CAMERA_STATE_RECORD) {
+        //Code to get live shot
+        if (mm_app_prepare_live_snapshot(cam_id) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s: Failed prepare liveshot",__func__);
+            return -1;
+        }
+        if (MM_CAMERA_OK != (rc =pme->cam->ops->request_super_buf(pme->cam->camera_handle,pme->ch_id))) {
+            CDBG_ERROR("%s:request_super_buf err=%d\n", __func__, rc);
+            return -1;
+        }
+        CDBG("%s:waiting images\n",__func__);
+        mm_app_snapshot_wait(cam_id);
+
+        if (MM_CAMERA_OK !=mm_app_unprepare_live_snapshot(cam_id)) {
+            CDBG_ERROR("%s: Snapshot Stop error",__func__);
+        }
+
+    } else {
+        CDBG_ERROR("%s: Should not come here for liveshot",__func__);
+    }
+    return rc;
+}
+
+int mm_app_take_picture_zsl(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+    int value = 1;
+    int op_mode;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s: Take picture ZSL",__func__);
+
+    if (MM_CAMERA_OK != (rc =pme->cam->ops->request_super_buf(pme->cam->camera_handle,pme->ch_id))) {
+        CDBG_ERROR("%s:request_super_buf err=%d\n", __func__, rc);
+        goto end;
+    }
+
+    CDBG("%s: Start ZSL Preview",__func__);
+
+    end:
+    CDBG("%s: END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_take_picture_yuv(int cam_id)
+{
+    int rc;
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s:BEGIN, cam_id=%d\n",__func__,cam_id);
+
+    if (MM_CAMERA_OK != mm_app_start_snapshot(cam_id)) {
+        CDBG_ERROR("%s: cam_id=%d\n",__func__,cam_id);      
+        rc = -1;
+        goto end;
+    }
+
+    CDBG("%s:waiting images\n",__func__);
+    mm_app_snapshot_wait(cam_id);
+
+    if (MM_CAMERA_OK !=mm_app_stop_snapshot(cam_id)) {
+        CDBG_ERROR("%s: Snapshot Stop error",__func__);
+    }
+
+    preview:
+    if (MM_CAMERA_OK != (rc = mm_app_start_preview(cam_id))) {
+        CDBG("%s:preview start stream err=%d\n", __func__, rc);
+    }
+    end:
+    CDBG("%s:END, cam_id=%d\n",__func__,cam_id);
+    return rc;
+}
+
+int mm_app_take_zsl(int cam_id)
+{
+    int rc = MM_CAMERA_OK;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s:BEGIN, cam_id=%d\n",__func__,cam_id);
+
+    if (pme->cam_mode == RECORDER_MODE) {
+        switch (pme->cam_state) {
+        case CAMERA_STATE_RECORD:
+            if (MM_CAMERA_OK != mm_app_stop_video(cam_id)) {
+                CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
+                return -1;
+            }
+        case CAMERA_STATE_PREVIEW:
+            if (MM_CAMERA_OK != mm_app_open_zsl(cam_id)) {
+                CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__);
+                return -1;
+            }
+            break;
+        case CAMERA_STATE_SNAPSHOT:
+        default:
+            CDBG("%s: Cannot normal pciture in record mode\n", __func__);
+            break; 
+        }
+    } else if (pme->cam_mode == CAMERA_MODE) {
+        switch (pme->cam_state) {
+        case CAMERA_STATE_PREVIEW:
+            mm_app_open_zsl(cam_id);
+            break;
+
+        case CAMERA_STATE_SNAPSHOT:
+        case CAMERA_STATE_RECORD:
+        default:
+            CDBG("%s: Cannot normal pciture in record mode\n", __func__);
+            break; 
+        }
+    }
+
+    if (pme->cam_mode == ZSL_MODE && pme->cam_state == CAMERA_STATE_PREVIEW) {
+        mm_app_take_picture_zsl(cam_id);
+    }
+    return rc;
+}
+
+int mm_app_take_picture(int cam_id)
+{
+    int rc = 0;
+
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s:BEGIN, cam_id=%d\n",__func__,cam_id);
+
+    if (pme->cam_mode == RECORDER_MODE) {
+        switch (pme->cam_state) {
+        case CAMERA_STATE_RECORD:
+            if (MM_CAMERA_OK != mm_app_stop_video(cam_id)) {
+                CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
+                return -1;
+            }
+        case CAMERA_STATE_PREVIEW:
+            if (MM_CAMERA_OK != mm_app_open_camera(cam_id)) {
+                CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__,rc);
+                return -1;
+            }
+            break;
+        case CAMERA_STATE_SNAPSHOT:
+        default:
+            CDBG("%s: Cannot normal pciture in record mode\n", __func__);
+            break; 
+        }
+    } else if (pme->cam_mode == ZSL_MODE) {
+        switch (pme->cam_state) {
+        case CAMERA_STATE_PREVIEW:
+            mm_app_open_camera(cam_id);
+            break;
+
+        case CAMERA_STATE_SNAPSHOT:
+        case CAMERA_STATE_RECORD:
+        default:
+            CDBG("%s: Cannot normal pciture in record mode\n", __func__);
+            break; 
+        }
+    }
+
+    CDBG("%s : Takepicture : mode = %d state = %d, rc = %d",__func__,pme->cam_mode,pme->cam_state,rc);
+    if (pme->cam_mode == CAMERA_MODE && pme->cam_state == CAMERA_STATE_PREVIEW) {
+        mm_app_take_picture_yuv(cam_id);
+    }
+    return rc;
+}
+
+int mm_app_take_raw_picture(int cam_id)
+{
+    int rc;
+#if 0
+    mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+    CDBG("%s:BEGIN, cam_id=%d\n",__func__,cam_id);
+    g_status = FALSE;
+    if (MM_CAMERA_OK != (rc = pme->cam->ops->action(pme->cam, TRUE, MM_CAMERA_OPS_PREPARE_SNAPSHOT, 0))) {
+        CDBG("%s:prepare snapshot err=%d\n", __func__, rc);
+        goto end;
+    }
+    if (MM_CAMERA_OK != (rc = mm_app_stop_preview(cam_id))) {
+        CDBG("%s:mm_app_stop_preview err=%d\n", __func__, rc);
+        goto end;
+    }
+    if (MM_CAMERA_OK != mm_app_start_raw_snapshot(cam_id))
+        goto preview;
+    CDBG("%s:waiting images\n",__func__);
+    mm_app_snapshot_wait(cam_id);
+    CDBG("%s:calling mm_app_stop_snapshot() \n",__func__);
+    mm_app_stop_raw_snapshot(cam_id);
+    preview:
+    mm_app_start_preview(cam_id);
+    end:
+    CDBG("%s:END, cam_id=%d\n",__func__,cam_id);
+#endif
+    return rc;
+}
+
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_unit_test.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_unit_test.c
new file mode 100755
index 0000000..1b19181
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_unit_test.c
@@ -0,0 +1,559 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include "mm_camera_dbg.h"
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include "mm_qcamera_unit_test.h"
+
+#define MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP 4
+#define MM_QCAM_APP_TEST_NUM 128
+
+#define MM_QCAMERA_APP_INTERATION 5
+
+static mm_app_tc_t mm_app_tc[MM_QCAM_APP_TEST_NUM];
+static int num_test_cases = 0;
+
+int mm_app_tc_0(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i,j;
+    int result = 0;
+
+    printf("\n Verifying Preview on front and back camera...\n");
+    if (cam_apps->num_cameras == 0) {
+        CDBG_ERROR("%s:Query Failed: Num of cameras = %d\n",__func__, cam_apps->num_cameras);
+        rc = -1;
+        goto end;
+    }
+    for (i = 0; i < cam_apps->num_cameras; i++) {
+        if ( mm_app_open(i) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if (system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+
+        for (j = 0; j < MM_QCAMERA_APP_INTERATION; j++) {
+            if ( MM_CAMERA_OK != (rc = startPreview(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: startPreview() err=%d\n", __func__, rc);
+                break;
+            }
+            /*if(mm_camera_app_timedwait() == ETIMEDOUT) {
+                    CDBG_ERROR("%s: Preview Callback not received in time or qbuf failed\n", __func__);
+                    break;
+            }*/
+            mm_camera_app_wait();
+            if ( MM_CAMERA_OK != (rc = stopPreview(my_cam_app.cam_open))) {
+                CDBG("%s: startPreview() err=%d\n", __func__, rc);
+                break;
+            }
+            result++;
+        }
+        if ( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+
+        if (result != MM_QCAMERA_APP_INTERATION) {
+            printf("%s: Preview Start/Stop Fails for Camera %d in %d iteration", __func__, i,j);
+            rc = -1;
+            break;
+        }
+
+        result = 0;
+    }
+    end:
+    if (rc == 0) {
+        printf("\nPassed\n");
+    } else {
+        printf("\nFailed\n");
+    }
+    CDBG("%s:END, rc = %d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_tc_1(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i,j;
+    int result = 0;
+
+    printf("\n Verifying Snapshot on front and back camera...\n");
+    for (i = 0; i < cam_apps->num_cameras; i++) {
+        if ( mm_app_open(i) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if (system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+
+        if ( MM_CAMERA_OK != (rc = startPreview(my_cam_app.cam_open))) {
+            CDBG_ERROR("%s: startPreview() err=%d\n", __func__, rc);
+            break;
+        }
+        for (j = 0; j < MM_QCAMERA_APP_INTERATION; j++) {
+            if ( MM_CAMERA_OK != (rc = takePicture_yuv(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: TakePicture() err=%d\n", __func__, rc);
+                break;
+            }
+            /*if(mm_camera_app_timedwait() == ETIMEDOUT) {
+                    CDBG_ERROR("%s: Snapshot/Preview Callback not received in time or qbuf Faile\n", __func__);
+                    break;
+            }*/
+            mm_camera_app_wait();
+            result++;
+        }
+        if ( MM_CAMERA_OK != (rc = stopPreview(my_cam_app.cam_open))) {
+            CDBG("%s: startPreview() err=%d\n", __func__, rc);
+            break;
+        }
+        if ( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if (result != MM_QCAMERA_APP_INTERATION) {
+            printf("%s: Snapshot Start/Stop Fails for Camera %d in %d iteration", __func__, i,j);
+            rc = -1;
+            break;
+        }
+
+        result = 0;
+    }
+    end:
+    if (rc == 0) {
+        printf("\t***Passed***\n");
+    } else {
+        printf("\t***Failed***\n");
+    }
+    CDBG("%s:END, rc = %d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_tc_2(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i,j;
+    int result = 0;
+
+    printf("\n Verifying Video on front and back camera...\n");
+    for (i = 0; i < cam_apps->num_cameras; i++) {
+        if ( mm_app_open(i) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if (system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+
+        if ( MM_CAMERA_OK != (rc = startPreview(my_cam_app.cam_open))) {
+            CDBG_ERROR("%s: startPreview() err=%d\n", __func__, rc);
+            break;
+        }
+        for (j = 0; j < MM_QCAMERA_APP_INTERATION; j++) {
+            if ( MM_CAMERA_OK != (rc = startRecording(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: StartVideorecording() err=%d\n", __func__, rc);
+                break;
+            }
+
+            /*if(mm_camera_app_timedwait() == ETIMEDOUT) {
+                    CDBG_ERROR("%s: Video Callback not received in time\n", __func__);
+                    break;
+            }*/
+            mm_camera_app_wait();
+            if ( MM_CAMERA_OK != (rc = stopRecording(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: Stopvideorecording() err=%d\n", __func__, rc);
+                break;
+            }
+            result++;
+        }
+        if ( MM_CAMERA_OK != (rc = stopPreview(my_cam_app.cam_open))) {
+            CDBG("%s: startPreview() err=%d\n", __func__, rc);
+            break;
+        }
+        if ( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if (result != MM_QCAMERA_APP_INTERATION) {
+            printf("%s: Video Start/Stop Fails for Camera %d in %d iteration", __func__, i,j);
+            rc = -1;
+            break;
+        }
+
+        result = 0;
+    }
+    end:
+    if (rc == 0) {
+        printf("\nPassed\n");
+    } else {
+        printf("\nFailed\n");
+    }
+    CDBG("%s:END, rc = %d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_tc_3(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i,j;
+    int result = 0;
+
+    printf("\n Verifying RDI Stream on front and back camera...\n");
+    if (cam_apps->num_cameras == 0) {
+        CDBG_ERROR("%s:Query Failed: Num of cameras = %d\n",__func__, cam_apps->num_cameras);
+        rc = -1;
+        goto end;
+    }
+    for (i = 0; i < cam_apps->num_cameras; i++) {
+        if ( mm_app_open(i) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if (system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        for (j = 0; j < MM_QCAMERA_APP_INTERATION; j++) {
+            if ( MM_CAMERA_OK != (rc = startRdi(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: StartVideorecording() err=%d\n", __func__, rc);
+                break;
+            }
+
+            /*if(mm_camera_app_timedwait() == ETIMEDOUT) {
+                    CDBG_ERROR("%s: Video Callback not received in time\n", __func__);
+                    break;
+            }*/
+            mm_camera_app_wait();
+            if ( MM_CAMERA_OK != (rc = stopRdi(my_cam_app.cam_open))) {
+                CDBG_ERROR("%s: Stopvideorecording() err=%d\n", __func__, rc);
+                break;
+            }
+            result++;
+        }
+        if ( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
+            CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
+            rc = -1;
+            goto end;
+        }
+        if (result != MM_QCAMERA_APP_INTERATION) {
+            printf("%s: Video Start/Stop Fails for Camera %d in %d iteration", __func__, i,j);
+            rc = -1;
+            break;
+        }
+
+        result = 0;
+    }
+    end:
+    if (rc == 0) {
+        printf("\nPassed\n");
+    } else {
+        printf("\nFailed\n");
+    }
+    CDBG("%s:END, rc = %d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_tc_4(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - open/close ,video0, open/close preview channel only\n", __func__); 
+#if 0
+    for (i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+            CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n", __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+            goto end;
+        }
+        if (0 != (rc = mm_app_open_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_close_preview(cam_id))) {
+            goto end;
+        }
+        if ( 0 != (rc = mm_app_close(cam_id))) {
+            CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n", __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+            goto end;
+        }
+    }
+end:
+#endif 
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+
+
+int mm_app_tc_5(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - open/close ,video0, open/close snapshot channel only\n", __func__); 
+#if 0
+    for (i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+            CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n", 
+                 __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+            goto end;
+        }
+        if (0 != (rc = mm_app_open_snapshot(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_close_snapshot(cam_id))) {
+            goto end;
+        }
+        if ( 0 != (rc = mm_app_close(cam_id))) {
+            CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n", 
+                 __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+            goto end;
+        }
+    }
+    end:
+#endif 
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_tc_6(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - simple preview \n", __func__); 
+#if 0
+    if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+        CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n", 
+             __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+        goto end;
+    }
+
+    for (i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if (0 != (rc = mm_app_init_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_start_preview(cam_id))) {
+            goto end;
+        }
+        /* sleep 8 seconds */
+        usleep(8000000);
+        if (0 != (rc = mm_app_stop_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc=mm_app_deinit_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_close_preview(cam_id))) {
+            goto end;
+        }
+    }
+    if ( 0 != (rc = mm_app_close(cam_id))) {
+        CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n", 
+             __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+        goto end;
+    }
+end:
+#endif 
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_tc_7(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - simple preview and recording \n", __func__); 
+#if 0
+    if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+        CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n", 
+             __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+        goto end;
+    }
+
+    for (i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if (0 != (rc = mm_app_init_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_start_preview(cam_id))) {
+            goto end;
+        }
+        /* sleep 8 seconds */
+        usleep(8000000);
+        if (0 != (rc = mm_app_start_recording(cam_id))) {
+            goto end;
+        }
+        usleep(1000000);
+        if (0 != (rc = mm_app_stop_recording(cam_id))) {
+            goto end;
+        }
+        usleep(8000000);
+        if (0 != (rc = mm_app_stop_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc=mm_app_deinit_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_close_preview(cam_id))) {
+            goto end;
+        }
+    }
+    if ( 0 != (rc = mm_app_close(cam_id))) {
+        CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n", 
+             __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+        goto end;
+    }
+end:
+#endif 
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+int mm_app_tc_8(mm_camera_app_t *cam_apps)
+{
+    int rc = MM_CAMERA_OK;
+    int i;
+    printf("Running %s - preview, recording, and snapshot, then preview again \n", __func__); 
+#if 0
+    if ( 0 != (rc = mm_app_open(cam_id, MM_CAMERA_OP_MODE_NOTUSED))) {
+        CDBG("%s: open cam %d at opmode = %d err, loop=%d, rc=%d\n", 
+             __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+        goto end;
+    }
+
+    for (i = 0; i < MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP; i++) {
+        if (0 != (rc = mm_app_init_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_start_preview(cam_id))) {
+            goto end;
+        }
+        /* sleep 8 seconds */
+        usleep(8000000);
+        if (0 != (rc = mm_app_start_recording(cam_id))) {
+            goto end;
+        }
+        usleep(1000000);
+        if (0 != (rc = mm_app_stop_recording(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_stop_preview(cam_id))) {
+            goto end;
+        }
+        if (0!=(rc=mm_app_init_snapshot(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc=mm_app_take_picture(cam_id))) {
+            goto end;
+        }
+        if ( 0 != (rc = mm_app_deinit_snahspot(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_start_preview(cam_id))) {
+            goto end;
+        }
+        usleep(8000000);
+        if (0 != (rc=mm_app_deinit_preview(cam_id))) {
+            goto end;
+        }
+        if (0 != (rc = mm_app_close_preview(cam_id))) {
+            goto end;
+        }
+    }
+    if ( 0 != (rc = mm_app_close(cam_id))) {
+        CDBG("%s: close cam %d at opmode = %d err,loop=%d, rc=%d\n", 
+             __func__, cam_id, MM_CAMERA_OP_MODE_NOTUSED, i, rc); 
+        goto end;
+    }
+end:
+#endif
+    CDBG("%s:END, rc=%d\n", __func__, rc);
+    return rc;
+}
+
+
+int mm_app_gen_test_cases()
+{
+    int tc = 0;
+    memset(mm_app_tc, 0, sizeof(mm_app_tc));
+    if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_0;
+    if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_1;
+    if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_2;
+    if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_3;
+    /*if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_4;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_5;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_6;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_7;
+    if(tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_8;*/
+    return tc;
+}
+
+int mm_app_unit_test_entry(mm_camera_app_t *cam_app)
+{
+    int rc = MM_CAMERA_OK;
+    int i, tc = 0;
+    int cam_id = 0;
+
+    tc = mm_app_gen_test_cases();
+    CDBG("Running %d test cases\n",tc);
+    for (i = 0; i < tc; i++) {
+        mm_app_tc[i].r = mm_app_tc[i].f(cam_app);
+        if (mm_app_tc[i].r != MM_CAMERA_OK) {
+            printf("%s: test case %d error = %d, abort unit testing engine!!!!\n", 
+                   __func__, i, mm_app_tc[i].r); 
+            rc = mm_app_tc[i].r;
+            goto end;
+        }
+    }
+    end:
+    printf("nTOTAL_TSET_CASE = %d, NUM_TEST_RAN = %d, rc=%d\n", tc, i, rc);
+    return rc;
+}
+
+
+
+
diff --git a/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_video.c b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_video.c
new file mode 100755
index 0000000..b23f9b3
--- /dev/null
+++ b/camera/QCamera/stack/mm-camera-test/src/mm_qcamera_video.c
@@ -0,0 +1,484 @@
+/*
+Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include "mm_camera_dbg.h"
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include "mm_qcamera_app.h"
+
+#define BUFF_SIZE_128 128
+static int num_run = 0;
+
+static int mm_app_dump_video_frame(struct msm_frame *frame,
+								   uint32_t len)
+{
+	static int v_cnt = 0;
+	char bufp[BUFF_SIZE_128];
+	int file_fdp;
+	int rc = 0;
+
+	return rc; /* disable dump */
+
+	v_cnt++;
+	if(0 == (v_cnt % 10))
+		snprintf(bufp, BUFF_SIZE_128, "/data/v_%d.yuv", v_cnt);
+	else
+		return 0;
+
+	file_fdp = open(bufp, O_RDWR | O_CREAT, 0777);
+
+	if (file_fdp < 0) {
+		CDBG("cannot open file %s\n", bufp);
+		rc = -1;
+		goto end;
+	}
+	CDBG("%s:dump frame to '%s'\n", __func__, bufp);
+	write(file_fdp,
+		(const void *)frame->buffer, len);
+	close(file_fdp);
+end:
+	return rc;
+}
+
+static int mm_app_set_video_fmt(int cam_id,mm_camera_image_fmt_t *fmt)
+{
+	int rc = MM_CAMERA_OK;
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
+	fmt->fmt = pme->dim.enc_format;
+	fmt->width = pme->dim.video_width;
+	fmt->height = pme->dim.video_height;
+	return rc;
+}
+
+#if 0
+int mm_stream_deinit_video_buf(uint32_t camera_handle,
+                      uint32_t ch_id, uint32_t stream_id,
+                      void *user_data, uint8_t num_bufs,
+                      mm_camera_buf_def_t *bufs)
+{
+	int i, rc = MM_CAMERA_OK;
+	mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+	for(i = 0; i < num_bufs; i++) {
+		rc = my_cam_app.hal_lib.mm_camera_do_munmap_ion (pme->ionfd, &(pme->video_buf.frame[i].fd_data),
+                   (void *)pme->video_buf.frame[i].buffer, pme->video_buf.frame_len);
+		if(rc != MM_CAMERA_OK) {
+		  CDBG_ERROR("%s: mm_camera_do_munmap err, pmem_fd = %d, rc = %d",
+			   __func__, bufs[i].fd, rc);
+		}
+	}
+	return rc;
+}
+
+int mm_stream_init_video_buf(uint32_t camera_handle,
+                      uint32_t ch_id, uint32_t stream_id,
+                      void *user_data,
+                      mm_camera_frame_len_offset *frame_offset_info,
+                      uint8_t num_bufs,
+                      uint8_t *initial_reg_flag,
+                      mm_camera_buf_def_t *bufs)
+{
+	int i,j,num_planes, frame_len, y_off, cbcr_off;
+	uint32_t planes[VIDEO_MAX_PLANES];
+	uint32_t pmem_addr = 0;
+
+	mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;
+
+	num_planes = frame_offset_info->num_planes;
+	for ( i = 0; i < num_planes; i++) {
+		planes[i] = frame_offset_info->mp[i].len;
+	}
+
+	frame_len = frame_offset_info->frame_len;
+	y_off = frame_offset_info->mp[0].offset;
+	cbcr_off = frame_offset_info->mp[1].offset;
+
+	CDBG("Allocating video Memory for %d buffers frame_len = %d",num_bufs,frame_offset_info->frame_len);
+
+	for (i = 0; i < num_bufs ; i++) {
+	    int j;
+		pme->video_buf.reg[i] = 1;
+		initial_reg_flag[i] = 1;
+
+	    pme->video_buf.frame_len = frame_len;
+		pme->video_buf.frame[i].ion_alloc.len = pme->video_buf.frame_len;
+		pme->video_buf.frame[i].ion_alloc.flags =
+			(0x1 << CAMERA_ION_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID);
+		pme->video_buf.frame[i].ion_alloc.align = 4096;
+
+		pmem_addr = (unsigned long) my_cam_app.hal_lib.mm_camera_do_mmap_ion(pme->ionfd,
+                       &(pme->video_buf.frame[i].ion_alloc), &(pme->video_buf.frame[i].fd_data),
+                       &pme->video_buf.frame[i].fd);
+
+		pme->video_buf.frame[i].buffer = pmem_addr;
+		pme->video_buf.frame[i].path = OUTPUT_TYPE_V;
+		pme->video_buf.frame[i].y_off = 0;
+		pme->video_buf.frame[i].cbcr_off = planes[0];
+		pme->video_buf.frame[i].phy_offset = 0;
+
+		CDBG("Buffer allocated Successfully fd = %d",pme->video_buf.frame[i].fd);
+
+		bufs[i].fd = pme->video_buf.frame[i].fd;
+		//bufs[i].buffer = pmem_addr;
+		bufs[i].frame_len = pme->video_buf.frame[i].ion_alloc.len;
+		bufs[i].num_planes = num_planes;
+
+		bufs[i].frame = &pme->video_buf.frame[i];
+
+		/* Plane 0 needs to be set seperately. Set other planes
+             * in a loop. */
+        bufs[i].planes[0].length = planes[0];
+        bufs[i].planes[0].m.userptr = bufs[i].fd;
+        bufs[i].planes[0].data_offset = y_off;
+        bufs[i].planes[0].reserved[0] = 0;
+              //buf_def->buf.mp[i].frame_offset;
+		for (j = 1; j < num_planes; j++) {
+			 bufs[i].planes[j].length = planes[j];
+			 bufs[i].planes[j].m.userptr = bufs[i].fd;
+			 bufs[i].planes[j].data_offset = cbcr_off;
+			 bufs[i].planes[j].reserved[0] =
+				 bufs[i].planes[j-1].reserved[0] +
+				 bufs[i].planes[j-1].length;
+		}
+	}
+    return MM_CAMERA_OK;
+}
+#endif
+
+void video_cb_signal(mm_camera_app_obj_t *pme)
+{
+	if(pme->cam_state == CAMERA_STATE_RECORD) {
+		mm_camera_app_done();
+	}
+}
+
+static void mm_app_video_notify_cb(mm_camera_super_buf_t *bufs,
+	void *user_data)
+{
+	int rc;
+	mm_camera_buf_def_t *frame = NULL;
+	mm_camera_app_obj_t *pme = NULL;
+	CDBG("%s: BEGIN\n", __func__); 
+	frame = bufs->bufs[MM_CAMERA_PREVIEW] ;
+	pme = (mm_camera_app_obj_t *)user_data;
+	
+	CDBG("%s: BEGIN - length=%d, frame idx = %d\n", __func__, frame->frame_len, frame->frame_idx);
+	//Need to code to Send to Encoder .. Simulat
+	CDBG("In CB function i/p = %p o/p = %p",bufs->bufs[MM_CAMERA_PREVIEW],frame);
+
+	dumpFrameToFile(frame,pme->dim.orig_video_width,pme->dim.orig_video_height,"video", 1);
+	if(MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,frame))
+	{
+		CDBG_ERROR("%s: Failed in Snapshot Qbuf\n", __func__);
+		return;
+	}
+    video_cb_signal(pme);
+	CDBG("%s: END\n", __func__); 
+
+}
+
+int mm_app_config_video(int cam_id)
+{
+	int rc = MM_CAMERA_OK;
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	mm_app_set_video_fmt(cam_id,&pme->stream[MM_CAMERA_VIDEO].str_config.fmt);
+	pme->stream[MM_CAMERA_VIDEO].str_config.need_stream_on = 1;
+	pme->stream[MM_CAMERA_VIDEO].str_config.num_of_bufs = VIDEO_BUF_NUM;
+
+	if(MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_VIDEO].id,
+								 &pme->stream[MM_CAMERA_VIDEO].str_config))) {
+		CDBG_ERROR("%s:MM_CAMERA_VIDEO config streaming err=%d\n", __func__, rc);
+		goto end;
+	}
+
+	CDBG("config_stream stream is successfull");
+
+	pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.need_stream_on = pme->fullSizeSnapshot;
+	pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.num_of_bufs = 1;
+
+	mm_app_set_live_snapshot_fmt(cam_id,&pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.fmt);
+
+	if(MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id,
+								 &pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config))) {
+		CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+		goto end;
+	}
+end:
+	return rc;
+
+}
+
+int mm_app_prepare_video(int cam_id)
+{
+	int rc = MM_CAMERA_OK;
+
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	pme->stream[MM_CAMERA_VIDEO].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+													   mm_app_video_notify_cb,pme,
+												       MM_CAMERA_VIDEO, 0);
+
+	if(!pme->stream[MM_CAMERA_VIDEO].id) {
+		CDBG("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc);
+		rc = -1;
+		goto end;
+	}
+
+	CDBG("Add stream is successfull stream ID = %d",pme->stream[MM_CAMERA_PREVIEW].id);
+
+	/* Code to add live snapshot*/
+	pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
+												   NULL,pme,
+												   MM_CAMERA_SNAPSHOT_MAIN, 0);
+
+	CDBG("Add Snapshot main is successfull stream ID = %d",pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id);
+	if(!pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id) {
+		CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
+		rc = -1;
+		goto end;
+	}
+	/*if(mm_app_config_video(cam_id) != MM_CAMERA_OK)
+	{
+		CDBG_ERROR("%s:Video config err=%d\n", __func__, rc);
+	}*/
+end:
+	return rc;
+}
+
+int mm_app_unprepare_video(int cam_id)
+{
+	int rc = MM_CAMERA_OK;
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	if(MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_VIDEO].id))){
+		CDBG_ERROR("%s : Delete Stream Video error",__func__);
+		goto end;
+	}
+
+	if(MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id))){
+		CDBG_ERROR("%s : Delete Stream Video error",__func__);
+		goto end;
+	}
+end:
+	CDBG("del_stream successfull");
+	return rc;
+}
+
+static int mm_app_streamon_video(int cam_id)
+{
+	int stream[2];
+	int rc = MM_CAMERA_OK;
+
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	if(mm_app_config_video(cam_id) != MM_CAMERA_OK)
+	{
+		CDBG_ERROR("%s:Video config err=%d\n", __func__, rc);
+	}
+
+	stream[MM_CAMERA_VIDEO] = pme->stream[MM_CAMERA_VIDEO].id;
+	if(MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,1,&stream[1])))
+	{
+		CDBG_ERROR("%s : Start Stream video Error",__func__);
+		return -1;
+	}
+	CDBG("Start video stream is successfull");
+	pme->cam_state = CAMERA_STATE_RECORD;
+	return rc;
+}
+
+static int mm_app_streamoff_video(int cam_id)
+{
+	int stream[2];
+	int rc = MM_CAMERA_OK;
+
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	stream[0] = pme->stream[MM_CAMERA_VIDEO].id;
+
+	if(MM_CAMERA_OK != (rc =pme->cam->ops->stop_streams(pme->cam->camera_handle,pme->ch_id,1,&stream)))
+	{
+		CDBG_ERROR("%s : stop Stream video Error",__func__);
+		goto end;
+	}
+	CDBG("stop video stream is successfull");
+	pme->cam_state = CAMERA_STATE_PREVIEW;
+end:
+	return rc;
+
+}
+int mm_app_stop_video(int cam_id)
+{
+	int stream[2];
+	int rc = MM_CAMERA_OK;
+
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	stream[0] = pme->stream[MM_CAMERA_VIDEO].id;
+
+	if(MM_CAMERA_OK != (rc = mm_app_streamoff_video(cam_id))){
+		CDBG_ERROR("%s : Video Stream off error",__func__);
+		goto end;
+	}
+end:
+	return rc;
+}
+
+static int mm_app_start_video(int cam_id)
+{
+	int rc = MM_CAMERA_OK;
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	CDBG("pme = %p, pme->cam =%p, pme->ch = %d pme->cam->camera_handle = %d",
+		 pme,pme->cam,pme->ch_id,pme->cam->camera_handle);
+
+	if(MM_CAMERA_OK != (rc =  mm_app_prepare_video(cam_id))){
+		CDBG_ERROR("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc);
+		goto end;
+	}
+	if(MM_CAMERA_OK != (rc =  mm_app_streamon_video(cam_id))){
+		CDBG_ERROR("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc);
+		goto end;
+	}
+	
+end:
+	CDBG("%s: END, rc=%d\n", __func__, rc); 
+
+	return rc;
+}
+
+int mm_app_open_recorder(int cam_id)
+{
+	int rc = MM_CAMERA_OK;
+	int value = 1;
+	int powermode = 1;
+
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	CDBG("%s: mm_app_open_recorder",__func__);
+	if(pme->cam_mode == RECORDER_MODE) {
+		CDBG("%s : Already in record mode",__func__);
+		return rc;
+	}
+
+	if(MM_CAMERA_OK != (rc = mm_app_stop_preview(cam_id))){
+		CDBG_ERROR("%s:Stop preview err=%d\n", __func__, rc);
+		goto end;
+	}
+
+	if(MM_CAMERA_OK != initDisplay())
+	{
+		CDBG_ERROR("%s : Could not initalize display",__func__);
+		goto end;
+	}
+
+	pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_RECORDING_HINT, &value);
+
+	pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_LOW_POWER_MODE, &powermode);
+
+
+	if(MM_CAMERA_OK != (rc = mm_app_prepare_preview(cam_id))){
+		CDBG_ERROR("%s:stream on preview err=%d\n", __func__, rc);
+		goto end;
+	}
+
+	if(MM_CAMERA_OK != (rc = mm_app_prepare_video(cam_id))){
+		CDBG_ERROR("%s:stream on video err=%d\n", __func__, rc);
+		goto end;
+	}
+
+	if(MM_CAMERA_OK != (rc = mm_app_streamon_preview(cam_id))){
+		CDBG_ERROR("%s:start preview err=%d\n", __func__, rc);
+		goto end;
+	}
+	pme->cam_mode = RECORDER_MODE;
+end:
+	CDBG("%s: END, rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int startRecording(int cam_id)
+{
+	int rc = MM_CAMERA_OK;
+	
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	CDBG("%s: Start Recording mode = %d state = %d",__func__,pme->cam_mode,pme->cam_state);
+
+	if(pme->cam_mode == CAMERA_MODE || pme->cam_mode == ZSL_MODE) {
+		switch(pme->cam_state) {
+			case CAMERA_STATE_PREVIEW:
+				if(MM_CAMERA_OK != mm_app_open_recorder(cam_id)){
+					CDBG_ERROR("%s: Open Record Failed \n", __func__);
+					return -1;
+				}
+				break;
+			case CAMERA_STATE_RECORD:
+			case CAMERA_STATE_SNAPSHOT:
+			default:
+				break;
+		}
+	}/*else{
+		mm_app_prepare_video(cam_id);
+	}*/
+	CDBG("%s : startRecording : mode = %d state = %d",__func__,pme->cam_mode,pme->cam_state);
+	if(pme->cam_mode == RECORDER_MODE && pme->cam_state == CAMERA_STATE_PREVIEW){
+		if(MM_CAMERA_OK != mm_app_streamon_video(cam_id)){
+			CDBG_ERROR("%s:start video err=%d\n", __func__, rc);
+			return -1;
+		}
+	}
+	CDBG("%s: END, rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int stopRecording(int cam_id)
+{
+
+	int rc = MM_CAMERA_OK;
+	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
+
+	if(pme->cam_mode != RECORDER_MODE || pme->cam_state != CAMERA_STATE_RECORD) {
+		return rc;
+	}
+	if(MM_CAMERA_OK != mm_app_stop_video(cam_id)){
+		CDBG_ERROR("%s:stop video err=%d\n", __func__, rc);
+		return -1;
+	}
+	return rc;
+}
+
diff --git a/camera/QCamera/stack/mm-jpeg-interface/Android.mk b/camera/QCamera/stack/mm-jpeg-interface/Android.mk
new file mode 100755
index 0000000..a0aef69
--- /dev/null
+++ b/camera/QCamera/stack/mm-jpeg-interface/Android.mk
@@ -0,0 +1,34 @@
+OLD_LOCAL_PATH := $(LOCAL_PATH)
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS+= -D_ANDROID_
+LOCAL_COPY_HEADERS_TO := mm-camera-interface
+LOCAL_COPY_HEADERS = inc/mm_jpeg_interface.h
+
+LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/media
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+LOCAL_C_INCLUDES += \
+    $(LOCAL_PATH)/inc \
+    $(LOCAL_PATH)/../common \
+    $(LOCAL_PATH)/../../../ \
+    $(TARGET_OUT_HEADERS)/mm-still \
+    $(TARGET_OUT_HEADERS)/mm-still/jpeg \
+    $(TARGET_OUT_HEADERS)/mm-core/omxcore \
+    $(TARGET_OUT_HEADERS)/mm-still/mm-omx
+
+LOCAL_SRC_FILES := \
+    src/mm_jpeg_queue.c \
+    src/mm_jpeg.c \
+    src/mm_jpeg_interface.c
+
+LOCAL_MODULE           := libmmjpeg_interface
+LOCAL_PRELINK_MODULE   := false
+LOCAL_SHARED_LIBRARIES := libdl libcutils liblog libmmstillomx libimage-jpeg-enc-omx-comp
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)  
+
+LOCAL_PATH := $(OLD_LOCAL_PATH)
diff --git a/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg.h b/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg.h
new file mode 100755
index 0000000..4147c09
--- /dev/null
+++ b/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg.h
@@ -0,0 +1,166 @@
+
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MM_JPEG_H_
+#define MM_JPEG_H_
+
+#include "mm_jpeg_interface.h"
+#include "cam_list.h"
+#include "OMX_Types.h"
+#include "OMX_Index.h"
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+#include "omx_jpeg_ext.h"
+#include <semaphore.h>
+
+typedef struct {
+    struct cam_list list;
+    void* data;
+} mm_jpeg_q_node_t;
+
+typedef struct {
+    mm_jpeg_q_node_t head; /* dummy head */
+    uint32_t size;
+    pthread_mutex_t lock;
+} mm_jpeg_queue_t;
+
+typedef enum 
+{
+    MM_JPEG_CMD_TYPE_JOB,          /* job cmd */
+    MM_JPEG_CMD_TYPE_EXIT,         /* EXIT cmd for exiting jobMgr thread */
+    MM_JPEG_CMD_TYPE_MAX
+} mm_jpeg_cmd_type_t;
+
+typedef struct {
+    OMX_BUFFERHEADERTYPE* buf_header;
+    uint32_t portIdx;
+} mm_jpeg_omx_buf_info;
+
+typedef struct {
+    uint8_t num_bufs;
+    mm_jpeg_omx_buf_info bufs[MAX_SRC_BUF_NUM];
+} mm_jpeg_omx_src_buf;
+
+typedef struct {
+    uint32_t client_hdl;           /* client handler */
+    uint32_t jobId;                /* job ID */
+    mm_jpeg_job job;               /* job description */
+    pthread_t cb_pid;              /* cb thread heandler*/
+
+    void* jpeg_obj;                /* ptr to mm_jpeg_obj */
+    jpeg_job_status_t job_status;  /* job status */
+    uint8_t thumbnail_dropped;     /* flag indicating if thumbnail is dropped */
+    int32_t jpeg_size;             /* the size of jpeg output after job is done */
+
+    mm_jpeg_omx_src_buf src_bufs[JPEG_SRC_IMAGE_TYPE_MAX];
+    mm_jpeg_omx_buf_info sink_buf;
+} mm_jpeg_job_entry;
+
+typedef struct {
+    mm_jpeg_cmd_type_t type;
+    union {
+        mm_jpeg_job_entry  entry;
+    };
+} mm_jpeg_job_q_node_t;
+
+typedef struct {
+    uint8_t is_used;                /* flag: if is a valid client */
+    uint32_t client_handle;         /* client handle */
+} mm_jpeg_client_t;
+
+typedef struct {
+    pthread_t pid;                  /* job cmd thread ID */
+    sem_t job_sem;                  /* semaphore for job cmd thread */
+    mm_jpeg_queue_t job_queue;      /* queue for job to do */
+} mm_jpeg_job_cmd_thread_t;
+
+typedef enum {
+    MM_JPEG_EVENT_MASK_JPEG_DONE    = 0x00000001, /* jpeg job is done */
+    MM_JPEG_EVENT_MASK_JPEG_ABORT   = 0x00000002, /* jpeg job is aborted */
+    MM_JPEG_EVENT_MASK_JPEG_ERROR   = 0x00000004, /* jpeg job has error */
+    MM_JPEG_EVENT_MASK_CMD_COMPLETE = 0x00000100  /* omx cmd complete evt */
+} mm_jpeg_event_mask_t;
+
+typedef struct {
+    uint32_t evt;
+    int omx_value1;  /* only valid when evt_mask == MM_JPEG_EVENT_MASK_CMD_COMPLETE */
+    int omx_value2;  /* only valid when evt_mask == MM_JPEG_EVENT_MASK_CMD_COMPLETE */
+} mm_jpeg_evt_t;
+
+#define MAX_JPEG_CLIENT_NUM 8
+typedef struct mm_jpeg_obj_t {
+    /* ClientMgr */
+    int num_clients;                                /* num of clients */
+    mm_jpeg_client_t clnt_mgr[MAX_JPEG_CLIENT_NUM]; /* client manager */
+
+    /* JobMkr */
+    pthread_mutex_t job_lock;                       /* job lock */   
+    mm_jpeg_job_cmd_thread_t job_mgr;               /* job mgr thread including todo_q*/            
+    mm_jpeg_queue_t ongoing_job_q;                  /* queue for ongoing jobs */
+
+    /* Notifier */
+    mm_jpeg_queue_t cb_q;                           /* queue for CB threads */
+
+    /* OMX related */
+    OMX_HANDLETYPE omx_handle;                      /* handle to omx engine */
+
+    pthread_mutex_t omx_evt_lock;
+    pthread_cond_t omx_evt_cond;
+    mm_jpeg_evt_t omx_evt_rcvd;
+} mm_jpeg_obj;
+
+extern int32_t mm_jpeg_init(mm_jpeg_obj *my_obj);
+extern int32_t mm_jpeg_deinit(mm_jpeg_obj *my_obj);
+extern uint32_t mm_jpeg_new_client(mm_jpeg_obj *my_obj);
+extern int32_t mm_jpeg_start_job(mm_jpeg_obj *my_obj,
+                                 uint32_t client_hdl,
+                                 mm_jpeg_job* job,
+                                 uint32_t* jobId);
+extern int32_t mm_jpeg_abort_job(mm_jpeg_obj *my_obj,
+                                 uint32_t client_hdl,
+                                 uint32_t jobId);
+extern int32_t mm_jpeg_close(mm_jpeg_obj *my_obj,
+                             uint32_t client_hdl);
+
+/* utiltity fucntion declared in mm-camera-inteface2.c
+ * and need be used by mm-camera and below*/
+uint32_t mm_jpeg_util_generate_handler(uint8_t index);
+uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler);
+
+/* basic queue functions */
+extern int32_t mm_jpeg_queue_init(mm_jpeg_queue_t* queue);
+extern int32_t mm_jpeg_queue_enq(mm_jpeg_queue_t* queue, void* node);
+extern void* mm_jpeg_queue_deq(mm_jpeg_queue_t* queue);
+extern int32_t mm_jpeg_queue_deinit(mm_jpeg_queue_t* queue);
+extern int32_t mm_jpeg_queue_flush(mm_jpeg_queue_t* queue);
+extern uint32_t mm_jpeg_queue_get_size(mm_jpeg_queue_t* queue);
+
+#endif /* MM_JPEG_H_ */
+
+
diff --git a/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg_dbg.h b/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg_dbg.h
new file mode 100755
index 0000000..6c9ebec
--- /dev/null
+++ b/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg_dbg.h
@@ -0,0 +1,70 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MM_JPEG_DBG_H__
+#define __MM_JPEG_DBG_H__
+
+#define LOG_DEBUG 1
+
+#ifndef LOG_DEBUG
+  #ifdef _ANDROID_
+    #undef LOG_NIDEBUG
+    #undef LOG_TAG
+    #define LOG_NIDEBUG 0
+    #define LOG_TAG "mm-jpeg-intf"
+    #include <utils/Log.h>
+  #else
+    #include <stdio.h>
+    #define ALOGE CDBG
+  #endif
+  #undef CDBG
+  #define CDBG(fmt, args...) do{}while(0)
+#else
+  #ifdef _ANDROID_
+    #undef LOG_NIDEBUG
+    #undef LOG_TAG
+    #define LOG_NIDEBUG 0
+    #define LOG_TAG "mm-jpeg-intf"
+    #include <utils/Log.h>
+    #define CDBG(fmt, args...) ALOGE(fmt, ##args)
+  #else
+    #include <stdio.h>
+    #define CDBG(fmt, args...) fprintf(stderr, fmt, ##args)
+    #define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args)
+  #endif
+#endif
+
+#ifdef _ANDROID_
+  #define CDBG_HIGH(fmt, args...)  ALOGE(fmt, ##args)
+  #define CDBG_ERROR(fmt, args...)  ALOGE(fmt, ##args)
+#else
+  #define CDBG_HIGH(fmt, args...) fprintf(stderr, fmt, ##args)
+  #define CDBG_ERROR(fmt, args...) fprintf(stderr, fmt, ##args)
+#endif
+#endif /* __MM_JPEG_DBG_H__ */
diff --git a/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg_interface.h b/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg_interface.h
new file mode 100755
index 0000000..f59febd
--- /dev/null
+++ b/camera/QCamera/stack/mm-jpeg-interface/inc/mm_jpeg_interface.h
@@ -0,0 +1,209 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are

+ * met:

+ *     * Redistributions of source code must retain the above copyright

+ *       notice, this list of conditions and the following disclaimer.

+ *     * Redistributions in binary form must reproduce the above

+ *       copyright notice, this list of conditions and the following

+ *       disclaimer in the documentation and/or other materials provided

+ *       with the distribution.

+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its

+ *       contributors may be used to endorse or promote products derived

+ *       from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED

+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS

+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR

+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE

+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN

+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+#ifndef MM_JPEG_INTERFACE_H_

+#define MM_JPEG_INTERFACE_H_

+#include "QCamera_Intf.h"

+

+typedef struct {

+    int width;

+    int height;

+} image_resolution;

+

+typedef enum {

+    JPEG_SRC_IMAGE_FMT_YUV,

+    JPEG_SRC_IMAGE_FMT_BITSTREAM

+} jpeg_enc_src_img_fmt_t;

+

+typedef enum {

+    JPEG_SRC_IMAGE_TYPE_MAIN,

+    JPEG_SRC_IMAGE_TYPE_THUMB,

+    JPEG_SRC_IMAGE_TYPE_MAX

+} jpeg_enc_src_img_type_t;

+

+typedef struct  {

+    int32_t offset_x;

+    int32_t offset_y;

+    int32_t width;

+    int32_t height;

+} image_crop_t;

+

+typedef struct {

+    uint8_t sequence;                /*for jpeg bit streams, assembling is based on sequence. sequence starts from 0*/ 

+    uint8_t *buf_vaddr;              /*ptr to buf*/

+    int fd;                          /*fd of buf*/

+    uint32_t buf_size;               /* total size of buf (header + image) */ 

+    uint32_t data_offset;            /*data offset*/

+} src_bitstream_buffer_t;

+

+typedef struct {

+    uint8_t *buf_vaddr;              /*ptr to buf*/

+    int fd;                          /*fd of buf*/

+    cam_frame_len_offset_t offset;   /*alway use multi-planar, offset is used to skip the metadata header*/

+} src_image_buffer_t;

+

+typedef enum {

+    MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2,

+    MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V2,

+    MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V1,

+    MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V1,

+    MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V2,

+    MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V2,

+    MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V1,

+    MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V1,

+    MM_JPEG_COLOR_FORMAT_RGB565,

+    MM_JPEG_COLOR_FORMAT_RGB888,

+    MM_JPEG_COLOR_FORMAT_RGBa,

+    MM_JPEG_COLOR_FORMAT_BITSTREAM,

+    MM_JPEG_COLOR_FORMAT_MAX

+} mm_jpeg_color_format;

+

+#define MAX_SRC_BUF_NUM 2

+typedef struct {

+    /* src img format: YUV, Bitstream */

+    jpeg_enc_src_img_fmt_t img_fmt;

+

+	/* num of buf in src img */

+    uint8_t num_bufs;

+

+	/* src img bufs */

+    union {

+        src_bitstream_buffer_t bit_stream[MAX_SRC_BUF_NUM];

+        src_image_buffer_t src_image[MAX_SRC_BUF_NUM];

+    };

+

+    /* src img type: main or thumbnail */

+    jpeg_enc_src_img_type_t type;

+

+    /* color format */ 

+    mm_jpeg_color_format color_format;

+

+    /* src img dimension */

+    image_resolution src_dim;

+

+    /* jpeg output dimension */

+    image_resolution out_dim;

+

+    /* crop information */

+    image_crop_t crop;

+

+    /* jpeg quality: range 0~100 */

+    uint32_t quality;

+} src_image_buffer_info;

+

+typedef struct {

+  uint8_t *buf_vaddr;              /*ptr to buf*/

+  int fd;                          /*fd of buf*/

+  int buf_len;

+} out_image_buffer_info;

+

+typedef struct {

+    /* num of src imgs: e.g. main/thumbnail img

+     * if main img only: src_img_num = 1;

+     * if main+thumbnail: src_img_num = 2; 

+     * No support for thumbnail only case */ 

+    uint8_t src_img_num;

+

+    /* index 0 is always for main image

+     * if thumbnail presented, it will be in index 1 */

+    src_image_buffer_info src_img[JPEG_SRC_IMAGE_TYPE_MAX];

+} src_image_buffer_config;

+

+typedef struct {

+    src_image_buffer_config src_imgs;

+    out_image_buffer_info sink_img;

+} jpeg_image_buffer_config;

+

+typedef struct {

+    /* config for scr images */

+    jpeg_image_buffer_config buf_info;

+

+    /* rotation informaiton */

+    int rotation;

+

+    /* num of exif entries */

+    int exif_numEntries;

+

+    /* buf to exif entries, caller needs to

+     * take care of the memory manage with insider ptr */

+    exif_tags_info_t *exif_data;

+} mm_jpeg_encode_params;

+

+typedef enum {

+  JPEG_JOB_STATUS_DONE = 0,

+  JPEG_JOB_STATUS_ERROR

+} jpeg_job_status_t;

+

+typedef void (*jpeg_encode_callback_t)(jpeg_job_status_t status,

+                                       uint8_t thumbnailDroppedFlag,

+                                       uint32_t client_hdl,

+                                       uint32_t jobId,

+                                       uint8_t* out_data,

+                                       uint32_t data_size,

+                                       void *userData);

+

+typedef struct {

+    mm_jpeg_encode_params encode_parm;

+    jpeg_encode_callback_t jpeg_cb;

+    void* userdata;

+} mm_jpeg_encode_job;

+

+typedef enum {

+    JPEG_JOB_TYPE_ENCODE,

+    //JPEG_JOB_TYPE_DECODE, /*enable decode later*/

+    JPEG_JOB_TYPE_MAX

+} mm_jpeg_job_type_t;

+

+typedef struct {

+    mm_jpeg_job_type_t job_type;

+    union {

+        mm_jpeg_encode_job encode_job;

+    };

+} mm_jpeg_job;

+

+typedef struct {

+    /* start a job -- async call

+     * the result of job (DONE/ERROR) will rcvd through CB */ 

+    int32_t (* start_job) (uint32_t client_hdl, mm_jpeg_job* job, uint32_t* jobId);

+    

+    /* abort a job -- sync call */

+    int32_t  (* abort_job) (uint32_t client_hdl, uint32_t jobId);

+    

+    /* close a jpeg client -- sync call */

+    int32_t  (* close) (uint32_t clientHdl);

+} mm_jpeg_ops_t;

+

+/* open a jpeg client -- sync call

+ * returns client_handle.

+ * failed if client_handle=0

+ * jpeg ops tbl will be filled in if open succeeds */ 

+uint32_t jpeg_open(mm_jpeg_ops_t *ops);

+

+#endif /* MM_JPEG_INTERFACE_H_ */

+

+

diff --git a/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c b/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c
new file mode 100755
index 0000000..48ac062
--- /dev/null
+++ b/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c
@@ -0,0 +1,1297 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <semaphore.h>
+
+#include "mm_jpeg_dbg.h"
+#include "mm_jpeg_interface.h"
+#include "mm_jpeg.h"
+
+/* define max num of supported concurrent jpeg jobs by OMX engine.
+ * Current, only one per time */
+#define NUM_MAX_JPEG_CNCURRENT_JOBS 1
+
+#define INPUT_PORT_MAIN         0
+#define INPUT_PORT_THUMBNAIL    2
+#define OUTPUT_PORT             1
+
+void mm_jpeg_job_wait_for_event(mm_jpeg_obj *my_obj, uint32_t evt_mask);
+void mm_jpeg_job_wait_for_cmd_complete(mm_jpeg_obj *my_obj,
+                                       int cmd,
+                                       int status);
+OMX_ERRORTYPE mm_jpeg_etbdone(OMX_HANDLETYPE hComponent,
+                              OMX_PTR pAppData,
+                              OMX_BUFFERHEADERTYPE* pBuffer);
+OMX_ERRORTYPE mm_jpeg_ftbdone(OMX_HANDLETYPE hComponent,
+                              OMX_PTR pAppData,
+                              OMX_BUFFERHEADERTYPE* pBuffer);
+OMX_ERRORTYPE mm_jpeg_handle_omx_event(OMX_HANDLETYPE hComponent,
+                                       OMX_PTR pAppData,
+                                       OMX_EVENTTYPE eEvent,
+                                       OMX_U32 nData1,
+                                       OMX_U32 nData2,
+                                       OMX_PTR pEventData);
+/* special queue functions for job queue */
+int32_t mm_jpeg_queue_update_flag(mm_jpeg_queue_t* queue, uint32_t job_id, uint8_t flag);
+mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_client_id(mm_jpeg_queue_t* queue, uint32_t client_hdl);
+mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_job_id(mm_jpeg_queue_t* queue, uint32_t job_id);
+
+int32_t mm_jpeg_omx_load(mm_jpeg_obj* my_obj)
+{
+    int32_t rc = 0;
+    OMX_CALLBACKTYPE callbacks;
+
+    callbacks.EmptyBufferDone = mm_jpeg_etbdone;
+    callbacks.FillBufferDone = mm_jpeg_ftbdone;
+    callbacks.EventHandler = mm_jpeg_handle_omx_event;
+    rc = OMX_GetHandle(&my_obj->omx_handle,
+                       "OMX.qcom.image.jpeg.encoder",
+                       (void*)my_obj,
+                       &callbacks);
+
+    if (0 != rc) {
+        CDBG_ERROR("%s : OMX_GetHandle failed (%d)",__func__, rc);
+        return rc;
+    }
+
+    rc = OMX_Init();
+    if (0 != rc) {
+        CDBG_ERROR("%s : OMX_Init failed (%d)",__func__, rc);
+        OMX_FreeHandle(my_obj->omx_handle);
+    }
+
+    return rc;
+}
+
+int32_t mm_jpeg_omx_unload(mm_jpeg_obj *my_obj)
+{
+    int32_t rc = 0;
+    rc = OMX_Deinit();
+    OMX_FreeHandle(my_obj->omx_handle);
+
+    return rc;
+}
+
+int32_t mm_jpeg_omx_abort_job(mm_jpeg_obj *my_obj, mm_jpeg_job_entry* job_entry)
+{
+    int32_t rc = 0;
+    uint8_t i, j;
+
+    OMX_SendCommand(my_obj->omx_handle, OMX_CommandFlush, 0, NULL);
+    mm_jpeg_job_wait_for_event(my_obj,
+        MM_JPEG_EVENT_MASK_JPEG_DONE|MM_JPEG_EVENT_MASK_JPEG_ABORT|MM_JPEG_EVENT_MASK_JPEG_ERROR);
+    CDBG("%s:waitForEvent: OMX_CommandFlush: DONE", __func__);
+
+    OMX_SendCommand(my_obj->omx_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
+    OMX_SendCommand(my_obj->omx_handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
+
+    /* free buffers used in OMX processing */
+    for (i = 0; i < JPEG_SRC_IMAGE_TYPE_MAX; i++) {
+        for (j = 0; j < job_entry->src_bufs[i].num_bufs; j++) {
+            if (NULL != job_entry->src_bufs[i].bufs[j].buf_header) {
+                OMX_FreeBuffer(my_obj->omx_handle,
+                               job_entry->src_bufs[i].bufs[j].portIdx,
+                               job_entry->src_bufs[i].bufs[j].buf_header);
+            }
+        }
+    }
+    OMX_FreeBuffer(my_obj->omx_handle,
+                   job_entry->sink_buf.portIdx,
+                   job_entry->sink_buf.buf_header);
+
+    return rc;
+}
+
+/* TODO: needs revisit after omx lib supports multi src buffers */
+int32_t mm_jpeg_omx_config_main_buffer_offset(mm_jpeg_obj* my_obj, src_image_buffer_info *src_buf)
+{
+    int32_t rc = 0;
+    uint8_t i;
+    OMX_INDEXTYPE buf_offset_idx;
+    omx_jpeg_buffer_offset buffer_offset;
+
+    for (i = 0; i < src_buf->num_bufs; i++) {
+        OMX_GetExtensionIndex(my_obj->omx_handle,
+                              "omx.qcom.jpeg.exttype.buffer_offset",
+                              &buf_offset_idx);
+        memset(&buffer_offset, 0, sizeof(buffer_offset));
+
+        switch (src_buf->img_fmt) {
+        case JPEG_SRC_IMAGE_FMT_YUV:
+            if (1 == src_buf->src_image[i].offset.num_planes) {
+                buffer_offset.yOffset =
+                    src_buf->src_image[i].offset.sp.y_offset;
+                buffer_offset.cbcrOffset =
+                    src_buf->src_image[i].offset.sp.cbcr_offset;
+                buffer_offset.totalSize =
+                    src_buf->src_image[i].offset.sp.len;
+            } else {
+                buffer_offset.yOffset =
+                    src_buf->src_image[i].offset.mp[0].offset;
+                buffer_offset.cbcrOffset =
+                    src_buf->src_image[i].offset.mp[1].offset;
+                buffer_offset.totalSize =
+                    src_buf->src_image[i].offset.frame_len;
+            }
+            CDBG("%s: idx=%d, yOffset =%d, cbcrOffset =%d, totalSize = %d\n",
+                 __func__, i, buffer_offset.yOffset, buffer_offset.cbcrOffset, buffer_offset.totalSize);
+            OMX_SetParameter(my_obj->omx_handle, buf_offset_idx, &buffer_offset);
+            break;
+        case JPEG_SRC_IMAGE_FMT_BITSTREAM:
+            /* TODO: need visit here when bit stream is supported */
+            buffer_offset.yOffset =
+                src_buf->bit_stream[i].data_offset;
+            buffer_offset.totalSize =
+                src_buf->bit_stream[i].buf_size;
+            CDBG("%s: idx=%d, yOffset =%d, cbcrOffset =%d, totalSize = %d\n",
+                 __func__, i, buffer_offset.yOffset, buffer_offset.cbcrOffset, buffer_offset.totalSize);
+            OMX_SetParameter(my_obj->omx_handle, buf_offset_idx, &buffer_offset);
+            break;
+        default:
+            break;
+        }
+    }
+
+    return rc;
+}
+
+/* TODO: needs revisit after omx lib supports multi src buffers */
+int32_t mm_jpeg_omx_config_port(mm_jpeg_obj* my_obj, src_image_buffer_info *src_buf, int port_idx)
+{
+    int32_t rc = 0;
+    uint8_t i;
+    OMX_PARAM_PORTDEFINITIONTYPE input_port;
+
+    for (i = 0; i < src_buf->num_bufs; i++) {
+        memset(&input_port, 0, sizeof(input_port));
+        input_port.nPortIndex = port_idx;
+        OMX_GetParameter(my_obj->omx_handle, OMX_IndexParamPortDefinition, &input_port);
+        input_port.format.image.nFrameWidth = src_buf->src_dim.width;
+        input_port.format.image.nFrameHeight =src_buf->src_dim.height;
+        input_port.format.image.nStride = src_buf->src_dim.width;
+        input_port.format.image.nSliceHeight = src_buf->src_dim.height;
+        switch (src_buf->img_fmt) {
+        case JPEG_SRC_IMAGE_FMT_YUV:
+            input_port.nBufferSize = src_buf->src_image[i].offset.frame_len;
+            break;
+        case JPEG_SRC_IMAGE_FMT_BITSTREAM:
+            input_port.nBufferSize = src_buf->bit_stream[i].buf_size;
+            break;
+        }
+
+        OMX_SetParameter(my_obj->omx_handle, OMX_IndexParamPortDefinition, &input_port);
+    }
+
+    return rc;
+}
+
+omx_jpeg_color_format map_jpeg_format(mm_jpeg_color_format color_fmt)
+{
+    switch (color_fmt) {
+    case MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2:
+        return OMX_YCRCBLP_H2V2;
+    case MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V2:
+        return OMX_YCBCRLP_H2V2;
+    case MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V1:
+        return OMX_YCRCBLP_H2V1;
+    case MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V1:
+        return OMX_YCBCRLP_H2V1;
+    case MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V2:
+        return OMX_YCRCBLP_H1V2;
+    case MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V2:
+        return OMX_YCBCRLP_H1V2;
+    case MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V1:
+        return OMX_YCRCBLP_H1V1;
+    case MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V1:
+        return OMX_YCBCRLP_H1V1;
+    case MM_JPEG_COLOR_FORMAT_RGB565:
+        return OMX_RGB565;
+    case MM_JPEG_COLOR_FORMAT_RGB888:
+        return OMX_RGB888;
+    case MM_JPEG_COLOR_FORMAT_RGBa:
+        return OMX_RGBa;
+    case MM_JPEG_COLOR_FORMAT_BITSTREAM:
+        /* TODO: need to change to new bitstream value once omx interface changes */
+        return OMX_JPEG_BITSTREAM_H2V2;
+    default:
+        return OMX_JPEG_COLOR_FORMAT_MAX;
+    }
+}
+
+int32_t mm_jpeg_omx_config_user_preference(mm_jpeg_obj* my_obj, mm_jpeg_encode_job* job)
+{
+    int32_t rc = 0;
+    OMX_INDEXTYPE user_pref_idx;
+    omx_jpeg_user_preferences user_preferences;
+
+    memset(&user_preferences, 0, sizeof(user_preferences));
+    user_preferences.color_format =
+        map_jpeg_format(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_MAIN].color_format);
+    if (job->encode_parm.buf_info.src_imgs.src_img_num > 1) {
+        user_preferences.thumbnail_color_format =
+            map_jpeg_format(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_THUMB].color_format);
+    }
+    OMX_GetExtensionIndex(my_obj->omx_handle,
+                          "omx.qcom.jpeg.exttype.user_preferences",
+                          &user_pref_idx);
+    CDBG("%s:User Preferences: color_format %d, thumbnail_color_format = %d",
+         __func__, user_preferences.color_format, user_preferences.thumbnail_color_format);
+    OMX_SetParameter(my_obj->omx_handle, user_pref_idx, &user_preferences);
+    return rc;
+}
+
+int32_t mm_jpeg_omx_config_thumbnail(mm_jpeg_obj* my_obj, mm_jpeg_encode_job* job)
+{
+    int32_t rc = -1;
+    OMX_INDEXTYPE thumb_idx, q_idx;
+    omx_jpeg_thumbnail thumbnail;
+    omx_jpeg_thumbnail_quality quality;
+
+    src_image_buffer_info *src_buf =
+        &(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_THUMB]);
+
+    /* config port */
+    rc = mm_jpeg_omx_config_port(my_obj, src_buf, INPUT_PORT_THUMBNAIL);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config port failed", __func__);
+        return rc;
+    }
+
+    /* check crop boundary */
+    if ((src_buf->crop.width == 0) || (src_buf->crop.height == 0) ||
+        (src_buf->crop.width + src_buf->crop.offset_x > src_buf->src_dim.width) ||
+        (src_buf->crop.height + src_buf->crop.offset_y > src_buf->src_dim.height)) {
+        CDBG_ERROR("%s: invalid crop boundary (%d, %d) offset (%d, %d) out of (%d, %d)",
+                   __func__,
+                   src_buf->crop.width,
+                   src_buf->crop.height,
+                   src_buf->crop.offset_x,
+                   src_buf->crop.offset_y,
+                   src_buf->src_dim.width,
+                   src_buf->src_dim.height);
+        return rc;
+    }
+
+    memset(&thumbnail, 0, sizeof(thumbnail));
+
+    /* thumbnail crop info */
+    thumbnail.cropWidth = CEILING2(src_buf->crop.width);
+    thumbnail.cropHeight = CEILING2(src_buf->crop.height);
+    thumbnail.left = src_buf->crop.offset_x;
+    thumbnail.top = src_buf->crop.offset_y;
+
+    /* thumbnail output dimention */
+    thumbnail.width = src_buf->out_dim.width;
+    thumbnail.height = src_buf->out_dim.height;
+
+    /* set scaling flag */
+    if (thumbnail.left > 0 || thumbnail.top > 0 ||
+        src_buf->crop.width != src_buf->out_dim.width ||
+        src_buf->crop.height != src_buf->out_dim.height) {
+        thumbnail.scaling = 1;
+    }
+
+    /* set omx thumbnail info */
+    OMX_GetExtensionIndex(my_obj->omx_handle, "omx.qcom.jpeg.exttype.thumbnail", &thumb_idx);
+    OMX_SetParameter(my_obj->omx_handle, thumb_idx, &thumbnail);
+
+    OMX_GetExtensionIndex(my_obj->omx_handle, "omx.qcom.jpeg.exttype.thumbnail_quality", &q_idx);
+    OMX_GetParameter(my_obj->omx_handle, q_idx, &quality);
+    quality.nQFactor = src_buf->quality;
+    OMX_SetParameter(my_obj->omx_handle, q_idx, &quality);
+
+    rc = 0;
+    return rc;
+}
+
+int32_t mm_jpeg_omx_config_main_crop(mm_jpeg_obj* my_obj, src_image_buffer_info *src_buf)
+{
+    int32_t rc = 0;
+    OMX_CONFIG_RECTTYPE rect_type;
+
+    /* error check first */
+    if (src_buf->crop.width + src_buf->crop.offset_x > src_buf->src_dim.width ||
+        src_buf->crop.height + src_buf->crop.offset_y > src_buf->src_dim.height) {
+        CDBG_ERROR("%s: invalid crop boundary (%d, %d) out of (%d, %d)", __func__,
+                   src_buf->crop.width + src_buf->crop.offset_x,
+                   src_buf->crop.height + src_buf->crop.offset_y,
+                   src_buf->src_dim.width,
+                   src_buf->src_dim.height);
+        return -1;
+    }
+
+    if (src_buf->crop.width && src_buf->crop.width) {
+        /* Scaler information */
+        memset(&rect_type, 0, sizeof(rect_type));
+        rect_type.nWidth = CEILING2(src_buf->crop.width);
+        rect_type.nHeight = CEILING2(src_buf->crop.width);
+        rect_type.nLeft = src_buf->crop.offset_x;
+        rect_type.nTop = src_buf->crop.offset_y;
+        rect_type.nPortIndex = OUTPUT_PORT;
+        OMX_SetConfig(my_obj->omx_handle, OMX_IndexConfigCommonInputCrop, &rect_type);
+
+        if (src_buf->out_dim.width && src_buf->out_dim.height) {
+            memset(&rect_type, 0, sizeof(rect_type));
+            rect_type.nWidth = src_buf->out_dim.width;
+            rect_type.nHeight = src_buf->out_dim.height;
+            rect_type.nPortIndex = OUTPUT_PORT;
+            OMX_SetConfig(my_obj->omx_handle, OMX_IndexConfigCommonOutputCrop, &rect_type);
+        }
+
+    } else {
+        CDBG_ERROR("%s: There is no main image scaling information", __func__);
+        rc = -1;
+    }
+
+    return rc;
+}
+
+int32_t mm_jpeg_omx_config_main(mm_jpeg_obj* my_obj, mm_jpeg_encode_job* job)
+{
+    int32_t rc = 0;
+    src_image_buffer_info *src_buf =
+        &(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_MAIN]);
+    OMX_IMAGE_PARAM_QFACTORTYPE q_factor;
+
+    /* config port */
+    rc = mm_jpeg_omx_config_port(my_obj, src_buf, INPUT_PORT_MAIN);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config port failed", __func__);
+        return rc;
+    }
+
+    /* config buffer offset */
+    rc = mm_jpeg_omx_config_main_buffer_offset(my_obj, src_buf);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config buffer offset failed", __func__);
+        return rc;
+    }
+
+    /* config crop */
+    rc = mm_jpeg_omx_config_main_crop(my_obj, src_buf);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config crop failed", __func__);
+        return rc;
+    }
+
+    /* set quality */
+    memset(&q_factor, 0, sizeof(q_factor));
+    q_factor.nPortIndex = INPUT_PORT_MAIN;
+    OMX_GetParameter(my_obj->omx_handle, OMX_IndexParamQFactor, &q_factor);
+    q_factor.nQFactor = src_buf->quality;
+    OMX_SetParameter(my_obj->omx_handle, OMX_IndexParamQFactor, &q_factor);
+
+    return rc;
+}
+
+int32_t mm_jpeg_omx_config_common(mm_jpeg_obj* my_obj, mm_jpeg_encode_job* job)
+{
+    int32_t rc;
+    int i;
+    OMX_INDEXTYPE exif_idx;
+    omx_jpeg_exif_info_tag tag;
+    OMX_CONFIG_ROTATIONTYPE rotate;
+
+    /* config user prefernces */
+    rc = mm_jpeg_omx_config_user_preference(my_obj, job);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config user preferences failed", __func__);
+        return rc;
+    }
+
+    /* set rotation */
+    memset(&rotate, 0, sizeof(rotate));
+    rotate.nPortIndex = OUTPUT_PORT;
+    rotate.nRotation = job->encode_parm.rotation;
+    OMX_SetConfig(my_obj->omx_handle, OMX_IndexConfigCommonRotate, &rotate);
+    CDBG("%s: Set rotation to %d\n", __func__, job->encode_parm.rotation);
+
+    /* set exif tags */
+    OMX_GetExtensionIndex(my_obj->omx_handle, "omx.qcom.jpeg.exttype.exif", &exif_idx);
+    for(i = 0; i < job->encode_parm.exif_numEntries; i++) {
+        memcpy(&tag, job->encode_parm.exif_data + i, sizeof(omx_jpeg_exif_info_tag));
+        OMX_SetParameter(my_obj->omx_handle, exif_idx, &tag);
+    }
+
+    return rc;
+}
+
+int32_t mm_jpeg_omx_use_buf(mm_jpeg_obj* my_obj,
+                            src_image_buffer_info *src_buf,
+                            mm_jpeg_omx_src_buf* omx_src_buf,
+                            int port_idx)
+{
+    int32_t rc = 0;
+    uint8_t i;
+    omx_jpeg_pmem_info pmem_info;
+
+    omx_src_buf->num_bufs = src_buf->num_bufs;
+    for (i = 0; i < src_buf->num_bufs; i++) {
+        memset(&pmem_info, 0, sizeof(pmem_info));
+        switch (src_buf->img_fmt) {
+        case JPEG_SRC_IMAGE_FMT_YUV:
+            pmem_info.fd = src_buf->src_image[i].fd;
+            pmem_info.offset = 0;
+            omx_src_buf->bufs[i].portIdx = port_idx;
+            OMX_UseBuffer(my_obj->omx_handle,
+                          &omx_src_buf->bufs[i].buf_header,
+                          port_idx,
+                          &pmem_info,
+                          src_buf->src_image[i].offset.frame_len,
+                          (void *)src_buf->src_image[i].buf_vaddr);
+            break;
+        case JPEG_SRC_IMAGE_FMT_BITSTREAM:
+            pmem_info.fd = src_buf->bit_stream[i].fd;
+            pmem_info.offset = 0;
+            omx_src_buf->bufs[i].portIdx = port_idx;
+            OMX_UseBuffer(my_obj->omx_handle,
+                          &omx_src_buf->bufs[i].buf_header,
+                          port_idx,
+                          &pmem_info,
+                          src_buf->bit_stream[i].buf_size,
+                          (void *)src_buf->bit_stream[i].buf_vaddr);
+            break;
+        default:
+            rc = -1;
+            break;
+        }
+    }
+
+    return rc;
+}
+
+int32_t mm_jpeg_omx_encode(mm_jpeg_obj* my_obj, mm_jpeg_job_entry* job_entry)
+{
+    int32_t rc = 0;
+    uint8_t i;
+    mm_jpeg_encode_job* job = &job_entry->job.encode_job;
+    uint8_t has_thumbnail = job->encode_parm.buf_info.src_imgs.src_img_num > 1? 1 : 0;
+    src_image_buffer_info *src_buf[JPEG_SRC_IMAGE_TYPE_MAX];
+    mm_jpeg_omx_src_buf *omx_src_buf[JPEG_SRC_IMAGE_TYPE_MAX];
+
+    /* config main img */
+    rc = mm_jpeg_omx_config_main(my_obj, job);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config main img failed", __func__);
+        return rc;
+    }
+
+    /* config thumbnail */
+    rc = mm_jpeg_omx_config_thumbnail(my_obj, job);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config thumbnail img failed", __func__);
+        return rc;
+    }
+
+    /* common config */
+    rc = mm_jpeg_omx_config_common(my_obj, job);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config common failed", __func__);
+        return rc;
+    }
+
+    /* config input omx buffer for main input */
+    src_buf[JPEG_SRC_IMAGE_TYPE_MAIN] = &(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_MAIN]);
+    omx_src_buf[JPEG_SRC_IMAGE_TYPE_MAIN] = &job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_MAIN];
+    rc = mm_jpeg_omx_use_buf(my_obj,
+                             src_buf[JPEG_SRC_IMAGE_TYPE_MAIN],
+                             omx_src_buf[JPEG_SRC_IMAGE_TYPE_MAIN],
+                             INPUT_PORT_MAIN);
+    if (0 != rc) {
+        CDBG_ERROR("%s: config main input omx buffer failed", __func__);
+        return rc;
+    }
+
+    /* config input omx buffer for thumbnail input if there is thumbnail */
+    if (has_thumbnail) {
+        src_buf[JPEG_SRC_IMAGE_TYPE_THUMB] = &(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_THUMB]);
+        omx_src_buf[JPEG_SRC_IMAGE_TYPE_THUMB] = &job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_THUMB];
+        rc = mm_jpeg_omx_use_buf(my_obj,
+                                 src_buf[JPEG_SRC_IMAGE_TYPE_THUMB],
+                                 omx_src_buf[JPEG_SRC_IMAGE_TYPE_THUMB],
+                                 INPUT_PORT_THUMBNAIL);
+        if (0 != rc) {
+            CDBG_ERROR("%s: config thumbnail input omx buffer failed", __func__);
+            return rc;
+        }
+    }
+
+    /* config output omx buffer */
+    job_entry->sink_buf.portIdx = OUTPUT_PORT;
+    OMX_UseBuffer(my_obj->omx_handle,
+                  &job_entry->sink_buf.buf_header,
+                  job_entry->sink_buf.portIdx,
+                  NULL,
+                  job->encode_parm.buf_info.sink_img.buf_len,
+                  (void *)job->encode_parm.buf_info.sink_img.buf_vaddr);
+
+    /* wait for OMX state ready */
+    mm_jpeg_job_wait_for_cmd_complete(my_obj, OMX_CommandStateSet, OMX_StateIdle);
+    CDBG("%s: State changed to OMX_StateIdle\n", __func__);
+
+    /* start OMX encoding by sending executing cmd */
+    OMX_SendCommand(my_obj->omx_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+    mm_jpeg_job_wait_for_cmd_complete(my_obj, OMX_CommandStateSet, OMX_StateExecuting);
+
+    /* start input fedding and output writing */
+    for (i = 0; i < job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_MAIN].num_bufs; i++) {
+        OMX_EmptyThisBuffer(my_obj->omx_handle,
+                            job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_MAIN].bufs[i].buf_header);
+    }
+    if (has_thumbnail) {
+        for (i = 0; i < job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_THUMB].num_bufs; i++) {
+            OMX_EmptyThisBuffer(my_obj->omx_handle,
+                                job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_THUMB].bufs[i].buf_header);
+        }
+    }
+    OMX_FillThisBuffer(my_obj->omx_handle, job_entry->sink_buf.buf_header);
+
+    return rc;
+}
+
+static void *mm_jpeg_notify_thread(void *data)
+{
+    mm_jpeg_job_q_node_t* job_node = (mm_jpeg_job_q_node_t *)data;
+    mm_jpeg_job_entry * job_entry = &job_node->entry;
+    mm_jpeg_obj* my_obj = (mm_jpeg_obj *)job_entry->jpeg_obj;
+    void* node = NULL;
+    int32_t rc = 0;
+
+    if (NULL == my_obj) {
+        CDBG_ERROR("%s: jpeg obj is NULL", __func__);
+        return NULL;
+    }
+
+    /* Add to cb queue */
+    rc = mm_jpeg_queue_enq(&my_obj->cb_q, data);
+    if (0 != rc) {
+        CDBG_ERROR("%s: enqueue into cb_q failed", __func__);
+        return NULL;
+    }
+
+    /* call cb */
+    if (NULL != job_entry->job.encode_job.jpeg_cb) {
+        /* has callback, send CB */
+        job_entry->job.encode_job.jpeg_cb(job_entry->job_status,
+                                          job_entry->thumbnail_dropped,
+                                          job_entry->client_hdl,
+                                          job_entry->jobId,
+                                          job_entry->job.encode_job.encode_parm.buf_info.sink_img.buf_vaddr,
+                                          job_entry->jpeg_size,
+                                          job_entry->job.encode_job.userdata);
+    } else {
+        CDBG_ERROR("%s: no cb provided, no action", __func__);
+    }
+
+    /* Remove from cb queue */
+    node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->cb_q, job_entry->jobId);
+    if (NULL != node) {
+        free(node);
+    }
+
+    return NULL;
+}
+
+/* process encoding job */
+int32_t mm_jpeg_process_encoding_job(mm_jpeg_obj *my_obj, mm_jpeg_job_q_node_t* job_node)
+{
+    int32_t rc = 0;
+    mm_jpeg_job_entry* job_entry = &job_node->entry;
+
+    /* call OMX_Encode */
+    rc = mm_jpeg_omx_encode(my_obj, job_entry);
+    if (0 == rc) {
+        /* sent encode cmd to OMX, queue job into ongoing queue */
+        rc = mm_jpeg_queue_enq(&my_obj->ongoing_job_q, job_node);
+    } else {
+        /* OMX encode failed, notify error through callback */
+        job_entry->job_status = JPEG_JOB_STATUS_ERROR;
+        if (NULL != job_entry->job.encode_job.jpeg_cb) {
+            /* has callback, create a thread to send CB */
+            pthread_create(&job_entry->cb_pid,
+                           NULL,
+                           mm_jpeg_notify_thread,
+                           (void *)job_node);
+
+        } else {
+            CDBG_ERROR("%s: no cb provided, return here", __func__);
+            free(job_node);
+        }
+    }
+
+    return rc;
+}
+/* process job (encoding/decoding) */
+int32_t mm_jpeg_process_job(mm_jpeg_obj *my_obj, mm_jpeg_job_q_node_t* job_node)
+{
+    int32_t rc = 0;
+
+    switch (job_node->entry.job.job_type) {
+    case JPEG_JOB_TYPE_ENCODE:
+        rc = mm_jpeg_process_encoding_job(my_obj, job_node);
+        break;
+    default:
+        CDBG_ERROR("%s: job type not supported (%d)",
+                   __func__, job_node->entry.job.job_type);
+        rc = -1;
+        break;
+    }
+
+    return rc;
+}
+
+static void *mm_jpeg_jobmgr_thread(void *data)
+{
+    int rc = 0;
+    int running = 1;
+    uint32_t num_ongoing_jobs = 0;
+    mm_jpeg_obj *my_obj = (mm_jpeg_obj*)data;
+    mm_jpeg_job_cmd_thread_t *cmd_thread =
+                (mm_jpeg_job_cmd_thread_t *)data;
+    mm_jpeg_job_q_node_t* node = NULL;
+
+    do {
+        do {
+            rc = sem_wait(&cmd_thread->job_sem);
+            if (rc != 0 && errno != EINVAL) {
+                CDBG_ERROR("%s: sem_wait error (%s)",
+                           __func__, strerror(errno));
+                return NULL;
+            }
+        } while (rc != 0);
+    
+        /* check ongoing q size */
+        num_ongoing_jobs = mm_jpeg_queue_get_size(&my_obj->ongoing_job_q);
+        if (num_ongoing_jobs >= NUM_MAX_JPEG_CNCURRENT_JOBS) {
+            continue;
+        }
+
+        pthread_mutex_lock(&my_obj->job_lock);
+        /* can go ahead with new work */
+        node = (mm_jpeg_job_q_node_t*)mm_jpeg_queue_deq(&cmd_thread->job_queue);
+        if (node != NULL) {
+            switch (node->type) {
+            case MM_JPEG_CMD_TYPE_JOB:
+                rc = mm_jpeg_process_job(my_obj, node);
+                if (0 != rc) {
+                    /* free node in error case */
+                    free(node);
+                }
+                break;
+            case MM_JPEG_CMD_TYPE_EXIT:
+            default:
+                /* free node */
+                free(node);
+                /* set running flag to false */
+                running = 0;
+                break;
+            }
+        }
+        pthread_mutex_unlock(&my_obj->job_lock);
+
+    } while (running);
+    return NULL;
+}
+
+int32_t mm_jpeg_jobmgr_thread_launch(mm_jpeg_obj * my_obj)
+{
+    int32_t rc = 0;
+    mm_jpeg_job_cmd_thread_t * job_mgr = &my_obj->job_mgr;
+
+    sem_init(&job_mgr->job_sem, 0, 0);
+    mm_jpeg_queue_init(&job_mgr->job_queue);
+
+    /* launch the thread */
+    pthread_create(&job_mgr->pid,
+                   NULL,
+                   mm_jpeg_jobmgr_thread,
+                   (void *)my_obj);
+    return rc;
+}
+
+int32_t mm_jpeg_jobmgr_thread_release(mm_jpeg_obj * my_obj)
+{
+    int32_t rc = 0;
+    mm_jpeg_job_cmd_thread_t * cmd_thread = &my_obj->job_mgr;
+    mm_jpeg_job_q_node_t* node =
+        (mm_jpeg_job_q_node_t *)malloc(sizeof(mm_jpeg_job_q_node_t));
+    if (NULL == node) {
+        CDBG_ERROR("%s: No memory for mm_jpeg_job_q_node_t", __func__);
+        return -1;
+    }
+
+    memset(node, 0, sizeof(mm_jpeg_job_q_node_t));
+    node->type = MM_JPEG_CMD_TYPE_EXIT;
+
+    mm_jpeg_queue_enq(&cmd_thread->job_queue, node);
+    sem_post(&cmd_thread->job_sem);
+
+    /* wait until cmd thread exits */
+    if (pthread_join(cmd_thread->pid, NULL) != 0) {
+        CDBG("%s: pthread dead already\n", __func__);
+    }
+    mm_jpeg_queue_deinit(&cmd_thread->job_queue);
+
+    sem_destroy(&cmd_thread->job_sem);
+    memset(cmd_thread, 0, sizeof(mm_jpeg_job_cmd_thread_t));
+    return rc;
+}
+
+int32_t mm_jpeg_init(mm_jpeg_obj *my_obj)
+{
+    int32_t rc = 0;
+
+    /* init locks */
+    pthread_mutex_init(&my_obj->job_lock, NULL);
+    pthread_mutex_init(&my_obj->omx_evt_lock, NULL);
+    pthread_cond_init(&my_obj->omx_evt_cond, NULL);
+
+    /* init ongoing job queue */
+    rc = mm_jpeg_queue_init(&my_obj->ongoing_job_q);
+
+    /* init job semaphore and launch jobmgr thread */
+    CDBG("%s : Launch jobmgr thread",__func__);
+    rc = mm_jpeg_jobmgr_thread_launch(my_obj);
+
+    /* load OMX */
+    rc = mm_jpeg_omx_load(my_obj);
+    if (0 != rc) {
+        /* roll back in error case */
+        mm_jpeg_jobmgr_thread_release(my_obj);
+        mm_jpeg_queue_deinit(&my_obj->ongoing_job_q);
+        pthread_mutex_destroy(&my_obj->job_lock);
+        pthread_mutex_destroy(&my_obj->omx_evt_lock);
+        pthread_cond_destroy(&my_obj->omx_evt_cond);
+    }
+
+    return rc;
+}
+
+int32_t mm_jpeg_deinit(mm_jpeg_obj *my_obj)
+{
+    int32_t rc = 0;
+
+    /* unload OMX engine */
+    rc = mm_jpeg_omx_unload(my_obj);
+
+    /* release jobmgr thread */
+    rc = mm_jpeg_jobmgr_thread_release(my_obj);
+
+    /* deinit ongoing job queue */
+    rc = mm_jpeg_queue_deinit(&my_obj->ongoing_job_q);
+
+    /* destroy locks */
+    pthread_mutex_destroy(&my_obj->job_lock);
+    pthread_mutex_destroy(&my_obj->omx_evt_lock);
+    pthread_cond_destroy(&my_obj->omx_evt_cond);
+
+    return rc;
+}
+
+uint32_t mm_jpeg_new_client(mm_jpeg_obj *my_obj)
+{
+    uint32_t client_hdl = 0;
+    uint8_t idx;
+
+    if (my_obj->num_clients >= MAX_JPEG_CLIENT_NUM) {
+        CDBG_ERROR("%s: num of clients reached limit", __func__);
+        return client_hdl;
+    }
+
+    for (idx = 0; idx < MAX_JPEG_CLIENT_NUM; idx++) {
+        if (0 == my_obj->clnt_mgr[idx].is_used) {
+            break;
+        }
+    }
+
+    if (idx < MAX_JPEG_CLIENT_NUM) {
+        /* client entry avail */
+        /* generate client handler by index */
+        client_hdl = mm_jpeg_util_generate_handler(idx);
+
+        /* update client entry */
+        my_obj->clnt_mgr[idx].is_used = 1;
+        my_obj->clnt_mgr[idx].client_handle = client_hdl;
+
+        /* increse client count */
+        my_obj->num_clients++;
+    }
+
+    return client_hdl;
+}
+
+int32_t mm_jpeg_start_job(mm_jpeg_obj *my_obj,
+                          uint32_t client_hdl,
+                          mm_jpeg_job* job,
+                          uint32_t* jobId)
+{
+    int32_t rc = -1;
+    uint8_t clnt_idx = 0;
+    uint32_t job_id = 0;
+    mm_jpeg_job_q_node_t* node = NULL;
+
+    *jobId = 0;
+
+    /* check if valid client */
+    clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
+    if (clnt_idx >= MAX_JPEG_CLIENT_NUM ) {
+        CDBG_ERROR("%s: invalid client with handler (%d)", __func__, client_hdl);
+        return rc;
+    }
+
+    /* generate client handler by index */
+    job_id = mm_jpeg_util_generate_handler(clnt_idx);
+
+    /* enqueue new job into todo job queue */
+    node = (mm_jpeg_job_q_node_t *)malloc(sizeof(mm_jpeg_job_q_node_t));
+    if (NULL == node) {
+        CDBG_ERROR("%s: No memory for mm_jpeg_job_q_node_t", __func__);
+        return -rc;
+    }
+
+    memset(node, 0, sizeof(mm_jpeg_job_q_node_t));
+    node->type = MM_JPEG_CMD_TYPE_JOB;
+    node->entry.client_hdl = client_hdl;
+    node->entry.jobId = job_id;
+    memcpy(&node->entry.job, job, sizeof(mm_jpeg_job));
+    node->entry.jpeg_obj = (void*)my_obj; /* save a ptr to jpeg_obj */
+
+    rc = mm_jpeg_queue_enq(&my_obj->job_mgr.job_queue, node);
+    if (0 == rc) {
+        sem_post(&my_obj->job_mgr.job_sem);
+        *jobId = job_id;
+    }
+    
+    return rc;
+}
+
+int32_t mm_jpeg_abort_job(mm_jpeg_obj *my_obj,
+                          uint32_t client_hdl,
+                          uint32_t jobId)
+{
+    int32_t rc = -1;
+    uint8_t clnt_idx = 0;
+    void * node = NULL;
+    mm_jpeg_job_entry* job_entry = NULL;
+
+    /* check if valid client */
+    clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
+    if (clnt_idx >= MAX_JPEG_CLIENT_NUM ) {
+        CDBG_ERROR("%s: invalid client with handler (%d)", __func__, client_hdl);
+        return rc;
+    }
+
+    pthread_mutex_lock(&my_obj->job_lock);
+
+    /* abort job if in ongoing queue */
+    node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->ongoing_job_q, jobId);
+    if (NULL != node) {
+        /* find job that is OMX ongoing, ask OMX to abort the job */
+        job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
+        rc = mm_jpeg_omx_abort_job(my_obj, job_entry);
+        free(node);
+        goto abort_done;
+    }
+
+    /* abort job if in todo queue */
+    node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->job_mgr.job_queue, jobId);
+    if (NULL != node) {
+        /* simply delete it */
+        free(node);
+        goto abort_done;
+    }
+
+    /* abort job if in cb queue */
+    node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->cb_q, jobId);
+    if (NULL != node) {
+        /* join cb thread */
+        job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
+        if (pthread_join(job_entry->cb_pid, NULL) != 0) {
+            CDBG("%s: pthread dead already\n", __func__);
+        }
+        free(node);
+    }
+
+abort_done:
+    pthread_mutex_unlock(&my_obj->job_lock);
+
+    /* wake up jobMgr thread to work on new job if there is any */
+    sem_post(&my_obj->job_mgr.job_sem);
+
+    return rc;
+}
+
+int32_t mm_jpeg_close(mm_jpeg_obj *my_obj, uint32_t client_hdl)
+{
+    int32_t rc = -1;
+    uint8_t clnt_idx = 0;
+    void* node = NULL;
+    mm_jpeg_job_entry* job_entry = NULL;
+
+    /* check if valid client */
+    clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
+    if (clnt_idx >= MAX_JPEG_CLIENT_NUM ) {
+        CDBG_ERROR("%s: invalid client with handler (%d)", __func__, client_hdl);
+        return rc;
+    }
+
+    /* abort all jobs from the client */
+    pthread_mutex_lock(&my_obj->job_lock);
+
+    /* abort job if in ongoing queue */
+    node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->ongoing_job_q, client_hdl);
+    while (NULL != node) {
+        /* find job that is OMX ongoing, ask OMX to abort the job */
+        job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
+        rc = mm_jpeg_omx_abort_job(my_obj, job_entry);
+        free(node);
+
+        /* find next job from ongoing queue that belongs to this client */
+        node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->ongoing_job_q, client_hdl);
+    }
+
+    /* abort job if in todo queue */
+    node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->job_mgr.job_queue, client_hdl);
+    while (NULL != node) {
+        /* simply delete the job if in todo queue */
+        free(node);
+
+        /* find next job from todo queue that belongs to this client */
+        node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->job_mgr.job_queue, client_hdl);
+    }
+
+    /* abort job if in cb queue */
+    node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->cb_q, client_hdl);
+    while (NULL != node) {
+        /* join cb thread */
+        job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
+        if (pthread_join(job_entry->cb_pid, NULL) != 0) {
+            CDBG("%s: pthread dead already\n", __func__);
+        }
+        free(node);
+
+        /* find next job from cb queue that belongs to this client */
+        node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->cb_q, client_hdl);
+    }
+
+    pthread_mutex_unlock(&my_obj->job_lock);
+
+    /* invalidate client entry */
+    memset(&my_obj->clnt_mgr[clnt_idx], 0, sizeof(mm_jpeg_client_t));
+
+    return rc;
+}
+
+void mm_jpeg_job_wait_for_event(mm_jpeg_obj *my_obj, uint32_t evt_mask)
+{
+    pthread_mutex_lock(&my_obj->omx_evt_lock);
+    while (!(my_obj->omx_evt_rcvd.evt & evt_mask)) {
+        pthread_cond_wait(&my_obj->omx_evt_cond, &my_obj->omx_evt_lock);
+    }
+    CDBG("%s:done", __func__);
+    pthread_mutex_unlock(&my_obj->omx_evt_lock);
+}
+
+void mm_jpeg_job_wait_for_cmd_complete(mm_jpeg_obj *my_obj,
+                                       int cmd,
+                                       int status)
+{
+    pthread_mutex_lock(&my_obj->omx_evt_lock);
+    while (!((my_obj->omx_evt_rcvd.evt & MM_JPEG_EVENT_MASK_CMD_COMPLETE) &&
+             (my_obj->omx_evt_rcvd.omx_value1 == cmd) &&
+             (my_obj->omx_evt_rcvd.omx_value2 == status))) {
+        pthread_cond_wait(&my_obj->omx_evt_cond, &my_obj->omx_evt_lock);
+    }
+    CDBG("%s:done", __func__);
+    pthread_mutex_unlock(&my_obj->omx_evt_lock);
+}
+
+OMX_ERRORTYPE mm_jpeg_etbdone(OMX_HANDLETYPE hComponent,
+                              OMX_PTR pAppData,
+                              OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    /* no process needed for etbdone, return here */
+    return 0;
+}
+
+OMX_ERRORTYPE mm_jpeg_ftbdone(OMX_HANDLETYPE hComponent,
+                              OMX_PTR pAppData,
+                              OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    int rc = 0;
+    void* node = NULL;
+    mm_jpeg_job_entry* job_entry = NULL;
+    mm_jpeg_obj * my_obj = (mm_jpeg_obj*)pAppData;
+
+    if (NULL != my_obj) {
+        CDBG_ERROR("%s: pAppData is NULL, return here", __func__);
+        return rc;
+    }
+
+    /* signal JPEG_DONE event */
+    pthread_mutex_lock(&my_obj->omx_evt_lock);
+    my_obj->omx_evt_rcvd.evt = MM_JPEG_EVENT_MASK_JPEG_DONE;
+    pthread_cond_signal(&my_obj->omx_evt_cond);
+    pthread_mutex_unlock(&my_obj->omx_evt_lock);
+
+    /* If OMX can support multi encoding, it should provide a way to pass jobID.
+     * then we can find job by jobID from ongoing queue.
+     * For now, since OMX only support one job per time, we simply dequeue it. */
+    pthread_mutex_lock(&my_obj->job_lock);
+    node = mm_jpeg_queue_deq(&my_obj->ongoing_job_q);
+    if (NULL != node) {
+        job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);;
+        /* find job that is OMX ongoing */
+        job_entry->jpeg_size = pBuffer->nFilledLen;
+        job_entry->job_status = JPEG_JOB_STATUS_DONE;
+        CDBG("%s:filled len = %u, status = %d",
+             __func__, job_entry->jpeg_size, job_entry->job_status);
+
+        if (NULL != job_entry->job.encode_job.jpeg_cb) {
+            /* has callback, create a thread to send CB */
+            pthread_create(&job_entry->cb_pid,
+                           NULL,
+                           mm_jpeg_notify_thread,
+                           node);
+
+        } else {
+            CDBG_ERROR("%s: no cb provided, return here", __func__);
+            free(node);
+        }
+    }
+    pthread_mutex_unlock(&my_obj->job_lock);
+
+    /* Wake up jobMgr thread to work on next job if there is any */
+    sem_post(&my_obj->job_mgr.job_sem);
+
+    return rc;
+}
+
+OMX_ERRORTYPE mm_jpeg_handle_omx_event(OMX_HANDLETYPE hComponent,
+                                       OMX_PTR pAppData,
+                                       OMX_EVENTTYPE eEvent,
+                                       OMX_U32 nData1,
+                                       OMX_U32 nData2,
+                                       OMX_PTR pEventData)
+{
+    int rc = 0;
+    void* node = NULL;
+    mm_jpeg_job_entry* job_entry = NULL;
+    mm_jpeg_obj * my_obj = (mm_jpeg_obj*)pAppData;
+    uint32_t jobId = 0;
+
+    if (NULL != my_obj) {
+        CDBG_ERROR("%s: pAppData is NULL, return here", __func__);
+        return rc;
+    }
+
+    /* signal event */
+    switch (eEvent) {
+    case  OMX_EVENT_JPEG_ABORT:
+        {
+            /* signal error evt */
+            pthread_mutex_lock(&my_obj->omx_evt_lock);
+            my_obj->omx_evt_rcvd.evt = MM_JPEG_EVENT_MASK_JPEG_ABORT;
+            pthread_cond_signal(&my_obj->omx_evt_cond);
+            pthread_mutex_unlock(&my_obj->omx_evt_lock);
+        }
+        break;
+    case OMX_EventError:
+        {
+            switch (nData1) {
+            case OMX_EVENT_THUMBNAIL_DROPPED:
+                {
+                    uint8_t thumbnail_dropped_flag = 1;
+                    mm_jpeg_queue_update_flag(&my_obj->ongoing_job_q,
+                                              jobId,
+                                              thumbnail_dropped_flag);
+                }
+                break;
+            case OMX_EVENT_JPEG_ERROR:
+                {
+                    /* signal error evt */
+                    pthread_mutex_lock(&my_obj->omx_evt_lock);
+                    my_obj->omx_evt_rcvd.evt = MM_JPEG_EVENT_MASK_JPEG_ERROR;
+                    pthread_cond_signal(&my_obj->omx_evt_cond);
+                    pthread_mutex_unlock(&my_obj->omx_evt_lock);
+
+                    /* send CB for error case */
+                    /* If OMX can support multi encoding, it should provide a way to pass jobID.
+                     * then we can find job by jobID from ongoing queue.
+                     * For now, since OMX only support one job per time, we simply dequeue it. */
+                    pthread_mutex_lock(&my_obj->job_lock);
+                    node = mm_jpeg_queue_deq(&my_obj->ongoing_job_q);
+                    if (NULL != node) {
+                        job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);;
+
+                        /* find job that is OMX ongoing */
+                        job_entry->job_status = JPEG_JOB_STATUS_ERROR;
+                        if (NULL != job_entry->job.encode_job.jpeg_cb) {
+                            /* has callback, create a thread to send CB */
+                            pthread_create(&job_entry->cb_pid,
+                                           NULL,
+                                           mm_jpeg_notify_thread,
+                                           node);
+
+                        } else {
+                            CDBG_ERROR("%s: no cb provided, return here", __func__);
+                            free(node);
+                        }
+                    }
+                    pthread_mutex_unlock(&my_obj->job_lock);
+
+                    /* Wake up jobMgr thread to work on next job if there is any */
+                    sem_post(&my_obj->job_mgr.job_sem);
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case OMX_EventCmdComplete:
+        {
+            /* signal cmd complete evt */
+            pthread_mutex_lock(&my_obj->omx_evt_lock);
+            my_obj->omx_evt_rcvd.evt = MM_JPEG_EVENT_MASK_CMD_COMPLETE;
+            my_obj->omx_evt_rcvd.omx_value1 = nData1;
+            my_obj->omx_evt_rcvd.omx_value2 = nData2;
+            pthread_cond_signal(&my_obj->omx_evt_cond);
+            pthread_mutex_unlock(&my_obj->omx_evt_lock);
+        }
+        break;
+    default:
+        break;
+    }
+
+    return rc;
+}
+
+/* remove the first job from the queue with matching client handle */
+mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_client_id(mm_jpeg_queue_t* queue, uint32_t client_hdl)
+{
+    mm_jpeg_q_node_t* node = NULL;
+    mm_jpeg_job_q_node_t* data = NULL;
+    mm_jpeg_job_q_node_t* job_node = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+
+    pthread_mutex_lock(&queue->lock);
+    head = &queue->head.list;
+    pos = head->next;
+    while(pos != head) {
+        node = member_of(pos, mm_jpeg_q_node_t, list);
+        data = (mm_jpeg_job_q_node_t *)node->data;
+
+        if (data && (data->entry.client_hdl == client_hdl)) {
+            job_node = data;
+            cam_list_del_node(&node->list);
+            queue->size--;
+            break;
+        }
+        pos = pos->next;
+    }
+
+    pthread_mutex_unlock(&queue->lock);
+
+    return job_node;
+}
+
+/* remove job from the queue with matching job id */
+mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_job_id(mm_jpeg_queue_t* queue, uint32_t job_id)
+{
+    mm_jpeg_q_node_t* node = NULL;
+    mm_jpeg_job_q_node_t* data = NULL;
+    mm_jpeg_job_q_node_t* job_node = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+
+    pthread_mutex_lock(&queue->lock);
+    head = &queue->head.list;
+    pos = head->next;
+    while(pos != head) {
+        node = member_of(pos, mm_jpeg_q_node_t, list);
+        data = (mm_jpeg_job_q_node_t *)node->data;
+
+        if (data && (data->entry.jobId == job_id)) {
+            job_node = data;
+            cam_list_del_node(&node->list);
+            queue->size--;
+            break;
+        }
+        pos = pos->next;
+    }
+
+    pthread_mutex_unlock(&queue->lock);
+
+    return job_node;
+}
+
+/* update thumbnail dropped flag in job queue */
+int32_t mm_jpeg_queue_update_flag(mm_jpeg_queue_t* queue, uint32_t job_id, uint8_t flag)
+{
+    int32_t rc = 0;
+    mm_jpeg_q_node_t* node = NULL;
+    mm_jpeg_job_q_node_t* data = NULL;
+    mm_jpeg_job_q_node_t* job_node = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+
+    pthread_mutex_lock(&queue->lock);
+    head = &queue->head.list;
+    pos = head->next;
+    while(pos != head) {
+        node = member_of(pos, mm_jpeg_q_node_t, list);
+        data = (mm_jpeg_job_q_node_t *)node->data;
+
+        if (data && (data->entry.jobId == job_id)) {
+            job_node = data;
+            break;
+        }
+        pos = pos->next;
+    }
+
+    if (job_node) {
+        /* find matching job for its job id */
+        job_node->entry.thumbnail_dropped = flag;
+    } else {
+        CDBG_ERROR("%s: No entry for jobId = %d", __func__, job_id);
+        rc = -1;
+    }
+    pthread_mutex_unlock(&queue->lock);
+
+    return rc;
+}
diff --git a/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg_interface.c b/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg_interface.c
new file mode 100755
index 0000000..bf998c1
--- /dev/null
+++ b/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg_interface.c
@@ -0,0 +1,202 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <semaphore.h>
+
+#include "mm_jpeg_dbg.h"
+#include "mm_jpeg_interface.h"
+#include "mm_jpeg.h"
+
+static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
+static mm_jpeg_obj* g_jpeg_obj = NULL;
+
+static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
+static uint16_t g_handler_history_count = 0; /* history count for handler */
+
+/* utility function to generate handler */
+uint32_t mm_jpeg_util_generate_handler(uint8_t index)
+{
+    uint32_t handler = 0;
+    pthread_mutex_lock(&g_handler_lock);
+    g_handler_history_count++;
+    if (0 == g_handler_history_count) {
+        g_handler_history_count++;
+    }
+    handler = g_handler_history_count;
+    handler = (handler<<8) | index;
+    pthread_mutex_unlock(&g_handler_lock);
+    return handler;
+}
+
+uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler)
+{
+    return (handler&0x000000ff);
+}
+
+static int32_t mm_jpeg_intf_start_job(uint32_t client_hdl, mm_jpeg_job* job, uint32_t* jobId)
+{
+    int32_t rc = -1;
+
+    if (0 == client_hdl ||
+        NULL == job ||
+        NULL == jobId) {
+        CDBG_ERROR("%s: invalid parameters for client_hdl, job or jobId", __func__);
+        return rc;
+    }
+
+    pthread_mutex_lock(&g_intf_lock);
+    if (NULL == g_jpeg_obj) {
+        /* mm_jpeg obj not exists, return error */
+        CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
+        pthread_mutex_unlock(&g_intf_lock);
+        return rc;
+    }
+
+    rc = mm_jpeg_start_job(g_jpeg_obj, client_hdl, job, jobId);
+    pthread_mutex_unlock(&g_intf_lock);
+    return rc;
+}
+    
+static int32_t mm_jpeg_intf_abort_job(uint32_t client_hdl, uint32_t jobId)
+{
+    int32_t rc = -1;
+
+    if (0 == client_hdl || 0 == jobId) {
+        CDBG_ERROR("%s: invalid client_hdl or jobId", __func__);
+        return rc;
+    }
+
+    pthread_mutex_lock(&g_intf_lock);
+    if (NULL == g_jpeg_obj) {
+        /* mm_jpeg obj not exists, return error */
+        CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
+        pthread_mutex_unlock(&g_intf_lock);
+        return rc;
+    }
+
+    rc = mm_jpeg_abort_job(g_jpeg_obj, client_hdl, jobId);
+    pthread_mutex_unlock(&g_intf_lock);
+    return rc;
+}
+
+static int32_t mm_jpeg_intf_close(uint32_t client_hdl)
+{
+    int32_t rc = -1;
+
+    if (0 == client_hdl) {
+        CDBG_ERROR("%s: invalid client_hdl", __func__);
+        return rc;
+    }
+
+    pthread_mutex_lock(&g_intf_lock);
+    if (NULL == g_jpeg_obj) {
+        /* mm_jpeg obj not exists, return error */
+        CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
+        pthread_mutex_unlock(&g_intf_lock);
+        return rc;
+    }
+
+    rc = mm_jpeg_close(g_jpeg_obj, client_hdl);
+
+    if(0 == rc) {
+        if (0 == g_jpeg_obj->num_clients) {
+            /* No client, close jpeg internally */
+            rc = mm_jpeg_deinit(g_jpeg_obj);
+            free(g_jpeg_obj);
+            g_jpeg_obj = NULL;
+        }
+    }
+
+    pthread_mutex_unlock(&g_intf_lock);
+    return rc;
+}
+
+/* open jpeg client */
+uint32_t jpeg_open(mm_jpeg_ops_t *ops)
+{
+    int32_t rc = 0;
+    uint32_t clnt_hdl = 0;
+    mm_jpeg_obj* jpeg_obj = NULL;
+
+    pthread_mutex_lock(&g_intf_lock);
+    /* first time open */
+    if(NULL == g_jpeg_obj) {
+        jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj));
+        if(NULL == jpeg_obj) {
+            CDBG_ERROR("%s:  no mem", __func__);
+            pthread_mutex_unlock(&g_intf_lock);
+            return clnt_hdl;
+        }
+
+        /* initialize jpeg obj */
+        memset(jpeg_obj, 0, sizeof(mm_jpeg_obj));
+        rc = mm_jpeg_init(jpeg_obj);
+        if(0 != rc) {
+            CDBG_ERROR("%s: mm_jpeg_init err = %d", __func__, rc);
+            free(jpeg_obj);
+            pthread_mutex_unlock(&g_intf_lock);
+            return clnt_hdl;
+        }
+
+        /* remember in global variable */
+        g_jpeg_obj = jpeg_obj;
+    }
+
+    /* open new client */
+    clnt_hdl = mm_jpeg_new_client(g_jpeg_obj);
+    if (clnt_hdl > 0) {
+        /* valid client */
+        if (NULL != ops) {
+            /* fill in ops tbl if ptr not NULL */
+            ops->start_job = mm_jpeg_intf_start_job;
+            ops->abort_job = mm_jpeg_intf_abort_job;
+            //ops->abort_job_all = mm_jpeg_intf_close,
+            ops->close = mm_jpeg_intf_close;
+        }
+    } else {
+        /* failed new client */
+        CDBG_ERROR("%s: mm_jpeg_new_client failed", __func__);
+
+        if (0 == g_jpeg_obj->num_clients) {
+            /* no client, close jpeg */
+            mm_jpeg_deinit(g_jpeg_obj);
+            free(g_jpeg_obj);
+            g_jpeg_obj = NULL;
+        }
+    }
+
+    pthread_mutex_unlock(&g_intf_lock);
+    return clnt_hdl;
+}
diff --git a/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg_queue.c b/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg_queue.c
new file mode 100755
index 0000000..9e9723a
--- /dev/null
+++ b/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg_queue.c
@@ -0,0 +1,134 @@
+/*
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+#include "mm_jpeg_dbg.h"
+#include "mm_jpeg.h"
+
+int32_t mm_jpeg_queue_init(mm_jpeg_queue_t* queue)
+{
+    pthread_mutex_init(&queue->lock, NULL);
+    cam_list_init(&queue->head.list);
+    queue->size = 0;
+    return 0;
+}
+
+int32_t mm_jpeg_queue_enq(mm_jpeg_queue_t* queue, void* data)
+{
+    mm_jpeg_q_node_t* node = 
+        (mm_jpeg_q_node_t *)malloc(sizeof(mm_jpeg_q_node_t));
+    if (NULL == node) {
+        CDBG_ERROR("%s: No memory for mm_jpeg_q_node_t", __func__);
+        return -1;
+    }
+
+    memset(node, 0, sizeof(mm_jpeg_q_node_t));
+    node->data = data;
+
+    pthread_mutex_lock(&queue->lock);
+    cam_list_add_tail_node(&node->list, &queue->head.list);
+    queue->size++;
+    pthread_mutex_unlock(&queue->lock);
+
+    return 0;
+
+}
+
+void* mm_jpeg_queue_deq(mm_jpeg_queue_t* queue)
+{
+    mm_jpeg_q_node_t* node = NULL;
+    void* data = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+
+    pthread_mutex_lock(&queue->lock);
+    head = &queue->head.list;
+    pos = head->next;
+    if (pos != head) {
+        node = member_of(pos, mm_jpeg_q_node_t, list);
+        cam_list_del_node(&node->list);
+        queue->size--;
+    }
+    pthread_mutex_unlock(&queue->lock);
+
+    if (NULL != node) {
+        data = node->data;
+        free(node);
+    }
+
+    return data;
+}
+
+uint32_t mm_jpeg_queue_get_size(mm_jpeg_queue_t* queue)
+{
+    uint32_t size = 0;
+
+    pthread_mutex_lock(&queue->lock);
+    size = queue->size;
+    pthread_mutex_unlock(&queue->lock);
+
+    return size;
+
+}
+
+int32_t mm_jpeg_queue_deinit(mm_jpeg_queue_t* queue)
+{
+    mm_jpeg_queue_flush(queue);
+    pthread_mutex_destroy(&queue->lock);
+    return 0;
+}
+
+int32_t mm_jpeg_queue_flush(mm_jpeg_queue_t* queue)
+{
+    mm_jpeg_q_node_t* node = NULL;
+    void* data = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+
+    pthread_mutex_lock(&queue->lock);
+    head = &queue->head.list;
+    pos = head->next;
+
+    while(pos != head) {
+        node = member_of(pos, mm_jpeg_q_node_t, list);
+        cam_list_del_node(&node->list);
+        queue->size--;
+
+        /* for now we only assume there is no ptr inside data
+         * so we free data directly */
+        if (NULL != node->data) {
+            free(node->data);
+        }
+        free(node);
+        pos = pos->next;
+    }
+    queue->size = 0;
+    pthread_mutex_unlock(&queue->lock);
+    return 0;
+}
diff --git a/camera/QCameraHWI.cpp b/camera/QCameraHWI.cpp
index ff4204a..5bc9e32 100644
--- a/camera/QCameraHWI.cpp
+++ b/camera/QCameraHWI.cpp
@@ -200,7 +200,7 @@
     property_get("camera.hal.fps", value, "0");
     mFps = atoi(value);
 
-    ALOGV("Init mPreviewState = %d", mPreviewState);
+    ALOGI("Init mPreviewState = %d", mPreviewState);
 
     property_get("persist.camera.hal.multitouchaf", value, "0");
     mMultiTouch = atoi(value);
@@ -233,24 +233,24 @@
     loadTables();
     /* Setup Picture Size and Preview size tables */
     setPictureSizeTable();
-    ALOGV("%s: Picture table size: %d", __func__, mPictureSizeCount);
-    ALOGV("%s: Picture table: ", __func__);
+    ALOGD("%s: Picture table size: %d", __func__, mPictureSizeCount);
+    ALOGD("%s: Picture table: ", __func__);
     for(unsigned int i=0; i < mPictureSizeCount;i++) {
-      ALOGV(" %d  %d", mPictureSizes[i].width, mPictureSizes[i].height);
+      ALOGD(" %d  %d", mPictureSizes[i].width, mPictureSizes[i].height);
     }
 
     setPreviewSizeTable();
-    ALOGV("%s: Preview table size: %d", __func__, mPreviewSizeCount);
-    ALOGV("%s: Preview table: ", __func__);
+    ALOGD("%s: Preview table size: %d", __func__, mPreviewSizeCount);
+    ALOGD("%s: Preview table: ", __func__);
     for(unsigned int i=0; i < mPreviewSizeCount;i++) {
-      ALOGV(" %d  %d", mPreviewSizes[i].width, mPreviewSizes[i].height);
+      ALOGD(" %d  %d", mPreviewSizes[i].width, mPreviewSizes[i].height);
     }
 
     setVideoSizeTable();
-    ALOGV("%s: Video table size: %d", __func__, mVideoSizeCount);
-    ALOGV("%s: Video table: ", __func__);
+    ALOGD("%s: Video table size: %d", __func__, mVideoSizeCount);
+    ALOGD("%s: Video table: ", __func__);
     for(unsigned int i=0; i < mVideoSizeCount;i++) {
-      ALOGV(" %d  %d", mVideoSizes[i].width, mVideoSizes[i].height);
+      ALOGD(" %d  %d", mVideoSizes[i].width, mVideoSizes[i].height);
     }
 
     /* set my mode - update myMode member variable due to difference in
@@ -281,12 +281,12 @@
     }
     mCameraState = CAMERA_STATE_READY;
 
-    ALOGV("QCameraHardwareInterface: X");
+    ALOGI("QCameraHardwareInterface: X");
 }
 
 QCameraHardwareInterface::~QCameraHardwareInterface()
 {
-    ALOGV("~QCameraHardwareInterface: E");
+    ALOGI("~QCameraHardwareInterface: E");
     int result;
 
     switch(mPreviewState) {
@@ -339,7 +339,7 @@
     pthread_mutex_destroy(&mAsyncCmdMutex);
     pthread_cond_destroy(&mAsyncCmdWait);
 
-    ALOGV("~QCameraHardwareInterface: X");
+    ALOGI("~QCameraHardwareInterface: X");
 }
 
 bool QCameraHardwareInterface::isCameraReady()
@@ -350,7 +350,7 @@
 
 void QCameraHardwareInterface::release()
 {
-    ALOGV("release: E");
+    ALOGI("release: E");
     Mutex::Autolock l(&mLock);
 
     switch(mPreviewState) {
@@ -374,23 +374,23 @@
 #if 0
     if (isRecordingRunning()) {
         stopRecordingInternal();
-        ALOGV("release: stopRecordingInternal done.");
+        ALOGI("release: stopRecordingInternal done.");
     }
     if (isPreviewRunning()) {
         stopPreview(); //stopPreviewInternal();
-        ALOGV("release: stopPreviewInternal done.");
+        ALOGI("release: stopPreviewInternal done.");
     }
     if (isSnapshotRunning()) {
         cancelPictureInternal();
-        ALOGV("release: cancelPictureInternal done.");
+        ALOGI("release: cancelPictureInternal done.");
     }
     if (mCameraState == CAMERA_STATE_ERROR) {
         //TBD: If Error occurs then tear down
-        ALOGV("release: Tear down.");
+        ALOGI("release: Tear down.");
     }
 #endif
     mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
-    ALOGV("release: X");
+    ALOGI("release: X");
 }
 
 void QCameraHardwareInterface::setCallbacks(
@@ -400,63 +400,63 @@
     camera_request_memory get_memory,
     void *user)
 {
-    ALOGV("setCallbacks: E");
+    ALOGE("setCallbacks: E");
     Mutex::Autolock lock(mLock);
     mNotifyCb        = notify_cb;
     mDataCb          = data_cb;
     mDataCbTimestamp = data_cb_timestamp;
     mGetMemory       = get_memory;
     mCallbackCookie  = user;
-    ALOGV("setCallbacks: X");
+    ALOGI("setCallbacks: X");
 }
 
 void QCameraHardwareInterface::enableMsgType(int32_t msgType)
 {
-    ALOGV("enableMsgType: E, msgType =0x%x", msgType);
+    ALOGI("enableMsgType: E, msgType =0x%x", msgType);
     Mutex::Autolock lock(mLock);
     mMsgEnabled |= msgType;
-    ALOGV("enableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
+    ALOGI("enableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
 }
 
 void QCameraHardwareInterface::disableMsgType(int32_t msgType)
 {
-    ALOGV("disableMsgType: E");
+    ALOGI("disableMsgType: E");
     Mutex::Autolock lock(mLock);
     mMsgEnabled &= ~msgType;
-    ALOGV("disableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
+    ALOGI("disableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
 }
 
 int QCameraHardwareInterface::msgTypeEnabled(int32_t msgType)
 {
-    ALOGV("msgTypeEnabled: E");
+    ALOGI("msgTypeEnabled: E");
     Mutex::Autolock lock(mLock);
     return (mMsgEnabled & msgType);
-    ALOGV("msgTypeEnabled: X");
+    ALOGI("msgTypeEnabled: X");
 }
 #if 0
 status_t QCameraHardwareInterface::dump(int fd, const Vector<String16>& args) const
 {
-    ALOGV("dump: E");
+    ALOGI("dump: E");
     const size_t SIZE = 256;
     char buffer[SIZE];
     String8 result;
     AutoMutex lock(&mLock);
     write(fd, result.string(), result.size());
-    ALOGV("dump: E");
+    ALOGI("dump: E");
     return NO_ERROR;
 }
 #endif
 
 int QCameraHardwareInterface::dump(int fd)
 {
-    ALOGV("%s: not supported yet", __func__);
+    ALOGE("%s: not supported yet", __func__);
     return -1;
 }
 
 status_t QCameraHardwareInterface::sendCommand(int32_t command, int32_t arg1,
                                          int32_t arg2)
 {
-    ALOGV("sendCommand: E");
+    ALOGI("sendCommand: E");
     status_t rc = NO_ERROR;
     Mutex::Autolock l(&mLock);
 
@@ -550,13 +550,13 @@
         default:
             break;
     }
-    ALOGV("sendCommand: X");
+    ALOGI("sendCommand: X");
     return rc;
 }
 
 void QCameraHardwareInterface::setMyMode(int mode)
 {
-    ALOGV("setMyMode: E");
+    ALOGI("setMyMode: E");
     //if (mode & CAMERA_SUPPORT_MODE_3D) {
     //    myMode = CAMERA_MODE_3D;
     //}else {
@@ -569,13 +569,13 @@
     //}else {
        myMode = (camera_mode_t) (myMode | CAMERA_NONZSL_MODE);
     //}
-    ALOGV("setMyMode: Set mode to %d (passed mode: %d)", myMode, mode);
-    ALOGV("setMyMode: X");
+    ALOGI("setMyMode: Set mode to %d (passed mode: %d)", myMode, mode);
+    ALOGI("setMyMode: X");
 }
 /* static factory function */
 QCameraHardwareInterface *QCameraHardwareInterface::createInstance(int cameraId, int mode)
 {
-    ALOGV("createInstance: E");
+    ALOGI("createInstance: E");
     QCameraHardwareInterface *cam = new QCameraHardwareInterface(cameraId, mode);
     if (cam ) {
       if (cam->mCameraState != CAMERA_STATE_READY) {
@@ -587,7 +587,7 @@
 
     if (cam) {
       //sp<CameraHardwareInterface> hardware(cam);
-      ALOGV("createInstance: X");
+      ALOGI("createInstance: X");
       return cam;
     } else {
       return NULL;
@@ -597,24 +597,24 @@
 extern "C" void *
 QCameraHAL_openCameraHardware(int  cameraId, int mode)
 {
-    ALOGV("QCameraHAL_openCameraHardware: E");
+    ALOGI("QCameraHAL_openCameraHardware: E");
     return (void *) QCameraHardwareInterface::createInstance(cameraId, mode);
 }
 
 #if 0
 bool QCameraHardwareInterface::useOverlay(void)
 {
-    ALOGV("useOverlay: E");
+    ALOGI("useOverlay: E");
     mUseOverlay = TRUE;
-    ALOGV("useOverlay: X");
+    ALOGI("useOverlay: X");
     return mUseOverlay;
 }
 #endif
 
 bool QCameraHardwareInterface::isPreviewRunning() {
-    ALOGV("isPreviewRunning: E");
+    ALOGI("isPreviewRunning: E");
     bool ret = false;
-    ALOGV("isPreviewRunning: camera state:%d", mCameraState);
+    ALOGI("isPreviewRunning: camera state:%d", mCameraState);
 
     if((mCameraState == CAMERA_STATE_PREVIEW) ||
        (mCameraState == CAMERA_STATE_PREVIEW_START_CMD_SENT) ||
@@ -624,7 +624,7 @@
        (mCameraState == CAMERA_STATE_ZSL_START_CMD_SENT)){
        return true;
     }
-    ALOGV("isPreviewRunning: X");
+    ALOGI("isPreviewRunning: X");
     return ret;
 }
 
@@ -659,7 +659,7 @@
         ret = true;
         break;
     }
-    ALOGV("isSnapshotRunning: X");
+    ALOGI("isSnapshotRunning: X");
     return ret;
 }
 
@@ -682,7 +682,7 @@
     nsecs_t diff = now - mLastFpsTime;
     if (diff > ms2ns(250)) {
         mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
-        ALOGV("Preview Frames Per Second: %.4f", mFps);
+        ALOGI("Preview Frames Per Second: %.4f", mFps);
         mLastFpsTime = now;
         mLastFrameCount = mFrameCount;
     }
@@ -690,7 +690,7 @@
 
 void QCameraHardwareInterface::
 processPreviewChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
-    ALOGV("processPreviewChannelEvent: E");
+    ALOGI("processPreviewChannelEvent: E");
     switch(channelEvent) {
         case MM_CAMERA_CH_EVT_STREAMING_ON:
             mCameraState =
@@ -704,13 +704,13 @@
         default:
             break;
     }
-    ALOGV("processPreviewChannelEvent: X");
+    ALOGI("processPreviewChannelEvent: X");
     return;
 }
 
 void QCameraHardwareInterface::processRecordChannelEvent(
   mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
-    ALOGV("processRecordChannelEvent: E");
+    ALOGI("processRecordChannelEvent: E");
     switch(channelEvent) {
         case MM_CAMERA_CH_EVT_STREAMING_ON:
             mCameraState = CAMERA_STATE_RECORD;
@@ -723,13 +723,13 @@
         default:
             break;
     }
-    ALOGV("processRecordChannelEvent: X");
+    ALOGI("processRecordChannelEvent: X");
     return;
 }
 
 void QCameraHardwareInterface::
 processSnapshotChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
-    ALOGV("processSnapshotChannelEvent: E evt=%d state=%d", channelEvent,
+    ALOGI("processSnapshotChannelEvent: E evt=%d state=%d", channelEvent,
       mCameraState);
     switch(channelEvent) {
         case MM_CAMERA_CH_EVT_STREAMING_ON:
@@ -758,14 +758,14 @@
         default:
             break;
     }
-    ALOGV("processSnapshotChannelEvent: X");
+    ALOGI("processSnapshotChannelEvent: X");
     return;
 }
 
 void QCameraHardwareInterface::processChannelEvent(
   mm_camera_ch_event_t *event, app_notify_cb_t *app_cb)
 {
-    ALOGV("processChannelEvent: E");
+    ALOGI("processChannelEvent: E");
     Mutex::Autolock lock(mLock);
     switch(event->ch) {
         case MM_CAMERA_CH_PREVIEW:
@@ -780,13 +780,13 @@
         default:
             break;
     }
-    ALOGV("processChannelEvent: X");
+    ALOGI("processChannelEvent: X");
     return;
 }
 
 void QCameraHardwareInterface::processCtrlEvent(mm_camera_ctrl_event_t *event, app_notify_cb_t *app_cb)
 {
-    ALOGV("processCtrlEvent: %d, E",event->evt);
+    ALOGI("processCtrlEvent: %d, E",event->evt);
     Mutex::Autolock lock(mLock);
     switch(event->evt)
     {
@@ -810,14 +810,14 @@
        default:
             break;
     }
-    ALOGV("processCtrlEvent: X");
+    ALOGI("processCtrlEvent: X");
     return;
 }
 
 void  QCameraHardwareInterface::processStatsEvent(
   mm_camera_stats_event_t *event, app_notify_cb_t *app_cb)
 {
-    ALOGV("processStatsEvent: E");
+    ALOGI("processStatsEvent: E");
     if (!isPreviewRunning( )) {
         ALOGE("preview is not running");
         return;
@@ -864,7 +864,7 @@
 
 void  QCameraHardwareInterface::processInfoEvent(
   mm_camera_info_event_t *event, app_notify_cb_t *app_cb) {
-    ALOGV("processInfoEvent: %d, E",event->event_id);
+    ALOGI("processInfoEvent: %d, E",event->event_id);
     //Mutex::Autolock lock(eventLock);
     switch(event->event_id)
     {
@@ -874,16 +874,16 @@
         default:
             break;
     }
-    ALOGV("processInfoEvent: X");
+    ALOGI("processInfoEvent: X");
     return;
 }
 
 void  QCameraHardwareInterface::processEvent(mm_camera_event_t *event)
 {
     app_notify_cb_t app_cb;
-    ALOGV("processEvent: type :%d E",event->event_type);
+    ALOGE("processEvent: type :%d E",event->event_type);
     if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED){
-	ALOGV("Stop recording issued. Return from process Event");
+	ALOGE("Stop recording issued. Return from process Event");
         return;
     }
     memset(&app_cb, 0, sizeof(app_notify_cb_t));
@@ -904,7 +904,7 @@
         default:
             break;
     }
-    ALOGV(" App_cb Notify %p, datacb=%p", app_cb.notifyCb, app_cb.dataCb);
+    ALOGE(" App_cb Notify %p, datacb=%p", app_cb.notifyCb, app_cb.dataCb);
     if (app_cb.notifyCb) {
       app_cb.notifyCb(app_cb.argm_notify.msg_type,
         app_cb.argm_notify.ext1, app_cb.argm_notify.ext2,
@@ -915,14 +915,14 @@
         app_cb.argm_data_cb.data, app_cb.argm_data_cb.index,
         app_cb.argm_data_cb.metadata, app_cb.argm_data_cb.cookie);
     }
-    ALOGV("processEvent: X");
+    ALOGI("processEvent: X");
     return;
 }
 
 bool QCameraHardwareInterface::preview_parm_config (cam_ctrl_dimension_t* dim,
                                    QCameraParameters& parm)
 {
-    ALOGV("preview_parm_config: E");
+    ALOGI("preview_parm_config: E");
     bool matching = true;
     int display_width = 0;  /* width of display      */
     int display_height = 0; /* height of display */
@@ -971,7 +971,7 @@
     else
       dim->main_img_format = CAMERA_YUV_420_NV21;
     dim->thumb_format = CAMERA_YUV_420_NV21;
-    ALOGV("preview_parm_config: X");
+    ALOGI("preview_parm_config: X");
     return matching;
 }
 
@@ -1013,7 +1013,7 @@
 
 status_t QCameraHardwareInterface::startPreview2()
 {
-    ALOGV("startPreview2: E");
+    ALOGI("startPreview2: E");
     status_t ret = NO_ERROR;
 
     cam_ctrl_dimension_t dim;
@@ -1057,7 +1057,7 @@
       dim.picture_width = maxDim.width;
       dim.picture_height = maxDim.height;
       mParameters.setPictureSize(dim.picture_width, dim.picture_height);
-      ALOGV("%s Setting Liveshot dimension as %d x %d", __func__,
+      ALOGI("%s Setting Liveshot dimension as %d x %d", __func__,
            maxDim.width, maxDim.height);
 #endif
         int mPictureWidth, mPictureHeight;
@@ -1127,13 +1127,13 @@
         mPostPreviewHeap = NULL;
     }
 
-    ALOGV("startPreview: X");
+    ALOGI("startPreview: X");
     return ret;
 }
 
 void QCameraHardwareInterface::stopPreview()
 {
-    ALOGV("%s: stopPreview: E", __func__);
+    ALOGI("%s: stopPreview: E", __func__);
     Mutex::Autolock lock(mLock);
     mm_camera_util_profile("HAL: stopPreview(): E");
     mFaceDetectOn = false;
@@ -1165,24 +1165,24 @@
       default:
             break;
     }
-    ALOGV("stopPreview: X, mPreviewState = %d", mPreviewState);
+    ALOGI("stopPreview: X, mPreviewState = %d", mPreviewState);
 }
 
 #if 0 //mzhu
 void QCameraHardwareInterface::stopPreviewZSL()
 {
-    ALOGV("stopPreviewZSL: E");
+    ALOGI("stopPreviewZSL: E");
 
     if(!mStreamDisplay || !mStreamSnap) {
         ALOGE("mStreamDisplay/mStreamSnap is null");
         return;
     }
-    ALOGV("stopPreview: X, mPreviewState = %d", mPreviewState);
+    ALOGI("stopPreview: X, mPreviewState = %d", mPreviewState);
 }
 #endif
 void QCameraHardwareInterface::stopPreviewInternal()
 {
-    ALOGV("stopPreviewInternal: E");
+    ALOGI("stopPreviewInternal: E");
     status_t ret = NO_ERROR;
 
     if(!mStreamDisplay) {
@@ -1197,12 +1197,12 @@
     mStreamDisplay->stop();
 
     mCameraState = CAMERA_STATE_PREVIEW_STOP_CMD_SENT;
-    ALOGV("stopPreviewInternal: X");
+    ALOGI("stopPreviewInternal: X");
 }
 
 int QCameraHardwareInterface::previewEnabled()
 {
-    ALOGV("previewEnabled: E");
+    ALOGI("previewEnabled: E");
     Mutex::Autolock lock(mLock);
     ALOGE("%s: mCameraState = %d", __func__, mCameraState);
     switch(mPreviewState) {
@@ -1222,7 +1222,7 @@
 
 status_t QCameraHardwareInterface::startRecording()
 {
-    ALOGV("startRecording: E");
+    ALOGI("startRecording: E");
     status_t ret = NO_ERROR;
     Mutex::Autolock lock(mLock);
 
@@ -1271,13 +1271,13 @@
        ret = BAD_VALUE;
        break;
     }
-    ALOGV("startRecording: X");
+    ALOGI("startRecording: X");
     return ret;
 }
 
 void QCameraHardwareInterface::stopRecording()
 {
-    ALOGV("stopRecording: E");
+    ALOGI("stopRecording: E");
     Mutex::Autolock lock(mLock);
     switch(mPreviewState) {
     case QCAMERA_HAL_PREVIEW_STOPPED:
@@ -1292,12 +1292,12 @@
     default:
         break;
     }
-    ALOGV("stopRecording: X");
+    ALOGI("stopRecording: X");
 
 }
 void QCameraHardwareInterface::stopRecordingInternal()
 {
-    ALOGV("stopRecordingInternal: E");
+    ALOGI("stopRecordingInternal: E");
     status_t ret = NO_ERROR;
 
     if(!mStreamRecord) {
@@ -1312,7 +1312,7 @@
     mStreamRecord->stop();
     mCameraState = CAMERA_STATE_PREVIEW;  //TODO : Apurva : Hacked for 2nd time Recording
     mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
-    ALOGV("stopRecordingInternal: X");
+    ALOGI("stopRecordingInternal: X");
     return;
 }
 
@@ -1354,18 +1354,18 @@
 
 status_t QCameraHardwareInterface::autoFocusEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
 {
-    ALOGV("autoFocusEvent: E");
+    ALOGE("autoFocusEvent: E");
     int ret = NO_ERROR;
 /************************************************************
   BEGIN MUTEX CODE
 *************************************************************/
 
-    ALOGV("%s:%d: Trying to acquire AF bit lock",__func__,__LINE__);
+    ALOGE("%s:%d: Trying to acquire AF bit lock",__func__,__LINE__);
     mAutofocusLock.lock();
-    ALOGV("%s:%d: Acquired AF bit lock",__func__,__LINE__);
+    ALOGE("%s:%d: Acquired AF bit lock",__func__,__LINE__);
 
     if(mAutoFocusRunning==false) {
-      ALOGV("%s:AF not running, discarding stale event",__func__);
+      ALOGE("%s:AF not running, discarding stale event",__func__);
       mAutofocusLock.unlock();
       return ret;
     }
@@ -1428,7 +1428,7 @@
 
 status_t QCameraHardwareInterface::cancelPicture()
 {
-    ALOGV("cancelPicture: E");
+    ALOGI("cancelPicture: E");
     status_t ret = MM_CAMERA_OK;
     Mutex::Autolock lock(mLock);
 
@@ -1443,13 +1443,13 @@
             ret = cancelPictureInternal();
             break;
     }
-    ALOGV("cancelPicture: X");
+    ALOGI("cancelPicture: X");
     return ret;
 }
 
 status_t QCameraHardwareInterface::cancelPictureInternal()
 {
-    ALOGV("cancelPictureInternal: E");
+    ALOGI("cancelPictureInternal: E");
     status_t ret = MM_CAMERA_OK;
     if(mCameraState != CAMERA_STATE_READY) {
         if(mStreamSnap) {
@@ -1459,7 +1459,7 @@
     } else {
         ALOGE("%s: Cannot process cancel picture as snapshot is already done",__func__);
     }
-    ALOGV("cancelPictureInternal: X");
+    ALOGI("cancelPictureInternal: X");
     return ret;
 }
 
@@ -1480,9 +1480,17 @@
     QCameraHardwareInterface *pme = (QCameraHardwareInterface *)user_data;
     cam_ctrl_dimension_t dim;
     int mJpegMaxSize;
+    int mNuberOfVFEOutputs = 0;
     status_t ret;
     ALOGE("%s: E", __func__);
 
+    ret = cam_config_get_parm(pme->mCameraId,MM_CAMERA_PARM_VFE_OUTPUT_ENABLE,
+                       &mNuberOfVFEOutputs);
+    if (ret != MM_CAMERA_OK) {
+       ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE  failed");
+       cam_evt_buf_done(pme->mCameraId, recvd_frame);
+       return ;
+    }
 
     mm_camera_ch_data_buf_t* frame =
          (mm_camera_ch_data_buf_t *)malloc(sizeof(mm_camera_ch_data_buf_t));
@@ -1493,7 +1501,10 @@
     }
     memcpy(frame, recvd_frame, sizeof(mm_camera_ch_data_buf_t));
 
-   ALOGE("<DEBUG> Liveshot buffer idx:%d",frame->video.video.idx);
+    if (mNuberOfVFEOutputs == 1)
+        ALOGE("<DEBUG> Liveshot buffer idx:%d",frame->def.idx);
+    else
+        ALOGE("<DEBUG> Liveshot buffer idx:%d",frame->video.video.idx);
     memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
     ret = cam_config_get_parm(pme->mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
     if (MM_CAMERA_OK != ret) {
@@ -1503,17 +1514,29 @@
 
 #if 1
     ALOGE("Live Snapshot Enabled");
-    frame->snapshot.main.frame = frame->video.video.frame;
-    frame->snapshot.main.idx = frame->video.video.idx;
-    frame->snapshot.thumbnail.frame = frame->video.video.frame;
-    frame->snapshot.thumbnail.idx = frame->video.video.idx;
+    if (mNuberOfVFEOutputs == 1){
+       frame->snapshot.main.frame = frame->def.frame;
+       frame->snapshot.main.idx = frame->def.idx;
+       frame->snapshot.thumbnail.frame = frame->def.frame;
+       frame->snapshot.thumbnail.idx = frame->def.idx;
+    } else {
+       frame->snapshot.main.frame = frame->video.video.frame;
+       frame->snapshot.main.idx = frame->video.video.idx;
+       frame->snapshot.thumbnail.frame = frame->video.video.frame;
+       frame->snapshot.thumbnail.idx = frame->video.video.idx;
+    }
 
     dim.picture_width = pme->mDimension.video_width;
     dim.picture_height = pme->mDimension.video_height;
     dim.ui_thumbnail_width = pme->mDimension.video_width;
     dim.ui_thumbnail_height = pme->mDimension.video_height;
-    dim.main_img_format = pme->mDimension.enc_format;
-    dim.thumb_format = pme->mDimension.enc_format;
+    if (mNuberOfVFEOutputs == 1){
+       dim.main_img_format = pme->mDimension.prev_format;
+       dim.thumb_format = pme->mDimension.prev_format;
+    } else {
+       dim.main_img_format = pme->mDimension.enc_format;
+       dim.thumb_format = pme->mDimension.enc_format;
+    }
 
     mJpegMaxSize = pme->mDimension.video_width * pme->mDimension.video_width * 1.5;
 
@@ -1554,8 +1577,9 @@
 
 status_t  QCameraHardwareInterface::takePicture()
 {
-    ALOGV("takePicture: E");
+    ALOGI("takePicture: E");
     status_t ret = MM_CAMERA_OK;
+    int mNuberOfVFEOutputs = 0;
     Mutex::Autolock lock(mLock);
 
     mStreamSnap->resetSnapshotCounters( );
@@ -1616,11 +1640,25 @@
         ALOGD(" Calling takeFullSizeLiveshot");
         takeFullSizeLiveshot();
       }else{
-          (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
+        ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE,
+                     &mNuberOfVFEOutputs);
+        if (ret != MM_CAMERA_OK) {
+           ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE  failed");
+           ret = BAD_VALUE;
+        }
+        if (mNuberOfVFEOutputs == 1){
+           (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
                                                     liveshot_callback,
                                                     MM_CAMERA_REG_BUF_CB_COUNT,
                                                     1,
                                                     this);
+        } else {
+           (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
+                                                    liveshot_callback,
+                                                    MM_CAMERA_REG_BUF_CB_COUNT,
+                                                    1,
+                                                    this);
+        }
       }
 
       break;
@@ -1628,7 +1666,7 @@
         ret = UNKNOWN_ERROR;
         break;
     }
-    ALOGV("takePicture: X");
+    ALOGI("takePicture: X");
     return ret;
 }
 
@@ -1711,18 +1749,18 @@
 status_t  QCameraHardwareInterface::takeLiveSnapshot()
 {
     status_t ret = NO_ERROR;
-    ALOGV("takeLiveSnapshot: E");
+    ALOGI("takeLiveSnapshot: E");
     mStreamRecord->takeLiveSnapshot();
-    ALOGV("takeLiveSnapshot: X");
+    ALOGI("takeLiveSnapshot: X");
     return ret;
 }
 
 status_t QCameraHardwareInterface::autoFocus()
 {
-    ALOGV("autoFocus: E");
+    ALOGI("autoFocus: E");
     status_t ret = NO_ERROR;
     Mutex::Autolock lock(mLock);
-    ALOGV("autoFocus: Got lock");
+    ALOGI("autoFocus: Got lock");
     bool status = true;
     isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);
 
@@ -1746,7 +1784,7 @@
       ALOGE("%s:Invalid AF mode (%d)", __func__, afMode);
     }
 
-    ALOGV("%s:AF start (mode %d)", __func__, afMode);
+    ALOGI("%s:AF start (mode %d)", __func__, afMode);
     if(MM_CAMERA_OK != cam_ops_action(mCameraId, TRUE,
                                     MM_CAMERA_OPS_FOCUS, &afMode)) {
       ALOGE("%s: AF command failed err:%d error %s",
@@ -1755,7 +1793,7 @@
     }
 
     mAutoFocusRunning = true;
-    ALOGV("autoFocus: X");
+    ALOGI("autoFocus: X");
     return ret;
 }
 
@@ -1804,7 +1842,7 @@
  *=========================================================================*/
 void QCameraHardwareInterface::prepareSnapshotAndWait()
 {
-    ALOGV("prepareSnapshotAndWait: E");
+    ALOGI("prepareSnapshotAndWait: E");
     int rc = 0;
     /*To Do: call mm camera preparesnapshot */
     if(!rc ) {
@@ -1814,7 +1852,7 @@
         pthread_mutex_unlock(&mAsyncCmdMutex);
         mPreparingSnapshot = false;
     }
-    ALOGV("prepareSnapshotAndWait: X");
+    ALOGI("prepareSnapshotAndWait: X");
 }
 #endif //mzhu
 
@@ -1826,16 +1864,16 @@
  *=========================================================================*/
 void QCameraHardwareInterface::processprepareSnapshotEvent(cam_ctrl_status_t *status)
 {
-    ALOGV("processprepareSnapshotEvent: E");
+    ALOGI("processprepareSnapshotEvent: E");
     pthread_mutex_lock(&mAsyncCmdMutex);
     pthread_cond_signal(&mAsyncCmdWait);
     pthread_mutex_unlock(&mAsyncCmdMutex);
-    ALOGV("processprepareSnapshotEvent: X");
+    ALOGI("processprepareSnapshotEvent: X");
 }
 
 void QCameraHardwareInterface::roiEvent(fd_roi_t roi,app_notify_cb_t *app_cb)
 {
-    ALOGV("roiEvent: E");
+    ALOGE("roiEvent: E");
 
     if(mStreamDisplay) mStreamDisplay->notifyROIEvent(roi);
 #if 0 //TODO: move to preview obj
@@ -1882,7 +1920,7 @@
         mMetaDataWaitLock.unlock();
     }
 #endif // mzhu
-    ALOGV("roiEvent: X");
+    ALOGE("roiEvent: X");
 }
 
 
@@ -1891,20 +1929,20 @@
     mm_camera_ch_crop_t v4l2_crop;
 
 
-    ALOGV("%s: E", __func__);
+    ALOGI("%s: E", __func__);
 
     memset(&v4l2_crop,0,sizeof(v4l2_crop));
     v4l2_crop.ch_type=MM_CAMERA_CH_SNAPSHOT;
 
-    ALOGV("%s: Fetching crop info", __func__);
+    ALOGI("%s: Fetching crop info", __func__);
     cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop);
 
-    ALOGV("%s: Crop info received for main: %d, %d, %d, %d ", __func__,
+    ALOGI("%s: Crop info received for main: %d, %d, %d, %d ", __func__,
          v4l2_crop.snapshot.main_crop.left,
          v4l2_crop.snapshot.main_crop.top,
          v4l2_crop.snapshot.main_crop.width,
          v4l2_crop.snapshot.main_crop.height);
-    ALOGV("%s: Crop info received for thumbnail: %d, %d, %d, %d ",__func__,
+    ALOGI("%s: Crop info received for thumbnail: %d, %d, %d, %d ",__func__,
          v4l2_crop.snapshot.thumbnail_crop.left,
          v4l2_crop.snapshot.thumbnail_crop.top,
          v4l2_crop.snapshot.thumbnail_crop.width,
@@ -1925,17 +1963,17 @@
 {
     mm_camera_ch_crop_t v4l2_crop;
 
-    ALOGV("%s: E", __func__);
+    ALOGI("%s: E", __func__);
 
     /*regular zooming or smooth zoom stopped*/
     if (!mSmoothZoomRunning && mPreviewWindow) {
         memset(&v4l2_crop, 0, sizeof(v4l2_crop));
         v4l2_crop.ch_type = MM_CAMERA_CH_PREVIEW;
 
-        ALOGV("%s: Fetching crop info", __func__);
+        ALOGI("%s: Fetching crop info", __func__);
         cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop);
 
-        ALOGV("%s: Crop info received: %d, %d, %d, %d ", __func__,
+        ALOGI("%s: Crop info received: %d, %d, %d, %d ", __func__,
              v4l2_crop.crop.left,
              v4l2_crop.crop.top,
              v4l2_crop.crop.width,
@@ -1946,16 +1984,16 @@
                         v4l2_crop.crop.top,
                         v4l2_crop.crop.left + v4l2_crop.crop.width,
                         v4l2_crop.crop.top + v4l2_crop.crop.height);
-        ALOGV("%s: Done setting crop", __func__);
-        ALOGV("%s: Currrent zoom :%d",__func__, mCurrentZoom);
+        ALOGI("%s: Done setting crop", __func__);
+        ALOGI("%s: Currrent zoom :%d",__func__, mCurrentZoom);
     }
 
-    ALOGV("%s: X", __func__);
+    ALOGI("%s: X", __func__);
 }
 
 void QCameraHardwareInterface::zoomEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
 {
-    ALOGV("zoomEvent: state:%d E",mPreviewState);
+    ALOGI("zoomEvent: state:%d E",mPreviewState);
     switch (mPreviewState) {
     case QCAMERA_HAL_PREVIEW_STOPPED:
         break;
@@ -1979,13 +2017,14 @@
     default:
         break;
     }
-    ALOGV("zoomEvent: X");
+    ALOGI("zoomEvent: X");
 }
 
 void QCameraHardwareInterface::dumpFrameToFile(const void * data, uint32_t size, char* name, char* ext, int index)
 {
     char buf[32];
     int file_fd;
+    static int i = 0 ;
     if ( data != NULL) {
         char * str;
         snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext);
@@ -1993,6 +2032,7 @@
         file_fd = open(buf, O_RDWR | O_CREAT, 0777);
         write(file_fd, data, size);
         close(file_fd);
+        i++;
     }
 }
 
@@ -2458,9 +2498,9 @@
 
 void QCameraHardwareInterface::wdenoiseEvent(cam_ctrl_status_t status, void *cookie)
 {
-    ALOGV("wdnEvent: preview state:%d E",mPreviewState);
+    ALOGI("wdnEvent: preview state:%d E",mPreviewState);
     if (mStreamSnap != NULL) {
-        ALOGV("notifyWDNEvent to snapshot stream");
+        ALOGI("notifyWDNEvent to snapshot stream");
         mStreamSnap->notifyWDenoiseEvent(status, cookie);
     }
 }
diff --git a/camera/QCameraHWI_Parm.cpp b/camera/QCameraHWI_Parm.cpp
index 6d9fc79..09fe6b0 100644
--- a/camera/QCameraHWI_Parm.cpp
+++ b/camera/QCameraHWI_Parm.cpp
@@ -923,6 +923,27 @@
     mParameters.set("overlay-format", HAL_PIXEL_FORMAT_YCbCr_420_SP);
     mParameters.set("max-num-detected-faces-hw", "2");
 
+    // Set supported max faces
+    int maxNumFaces = 0;
+    if (supportsFaceDetection()) {
+        //Query the maximum number of faces supported by hardware.
+        if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
+                               MM_CAMERA_PARM_MAX_NUM_FACES_DECT, &maxNumFaces)){
+            ALOGE("%s:Failed to get max number of faces supported",__func__);
+        }
+    }
+    mParameters.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, maxNumFaces);
+    //This paramtere is set to default here. This will be changed by application
+    //if it needs to support specific number of faces. See also setParameters.
+    mParameters.set(QCameraParameters::KEY_MAX_NUM_REQUESTED_FACES, 2);
+
+    // Set camera features supported flag
+    int32_t featureFlag = 0;
+    if (supportsFaceDetection()) {
+        featureFlag |= 0x00000001; // bit 0 indicate faciral feature
+    }
+    mParameters.set(QCameraParameters::KEY_SUPPORTED_CAMERA_FEATURES, featureFlag);
+
     //Set Picture Size
     mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
     mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
@@ -1439,36 +1460,11 @@
     if (str != NULL) {
         int value = attr_lookup(facedetection,
                 sizeof(facedetection) / sizeof(str_map), str);
-#if 0
-        mMetaDataWaitLock.lock();
-        if (value == true) {
-            if(mMetaDataHeap != NULL)
-                mMetaDataHeap.clear();
-
-            mMetaDataHeap =
-                new AshmemPool((sizeof(int)*(MAX_ROI*4+1)),
-                        1,
-                        (sizeof(int)*(MAX_ROI*4+1)),
-                        "metadata");
-            if (!mMetaDataHeap->initialized()) {
-                ALOGE("Meta Data Heap allocation failed ");
-                mMetaDataHeap.clear();
-                ALOGE("runFaceDetection X: error initializing mMetaDataHeap");
-                mMetaDataWaitLock.unlock();
-                return UNKNOWN_ERROR;
-            }
-            mSendMetaData = true;
-        } else {
-            if(mMetaDataHeap != NULL)
-                mMetaDataHeap.clear();
-        }
-        mMetaDataWaitLock.unlock();
-#endif
-        cam_ctrl_dimension_t dim;
-        cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
-        preview_parm_config (&dim, mParameters);
-        ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
-        ret = native_set_parms(MM_CAMERA_PARM_FD, sizeof(int8_t), (void *)&value);
+        fd_set_parm_t fd_set_parm;
+        int requested_faces = mParameters.getInt(QCameraParameters::KEY_MAX_NUM_REQUESTED_FACES);
+        fd_set_parm.fd_mode = value;
+        fd_set_parm.num_fd = requested_faces;
+        ret = native_set_parms(MM_CAMERA_PARM_FD, sizeof(fd_set_parm_t), (void *)&fd_set_parm);
         return ret ? NO_ERROR : UNKNOWN_ERROR;
     }
     ALOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str);
@@ -2961,18 +2957,23 @@
 
 status_t QCameraHardwareInterface::setFaceDetect(const QCameraParameters& params)
 {
+    int requested_faces = params.getInt(QCameraParameters::KEY_MAX_NUM_REQUESTED_FACES);
+    int hardware_supported_faces = mParameters.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
+    if (requested_faces > hardware_supported_faces) {
+        requested_faces = hardware_supported_faces;
+    }
+    mParameters.set(QCameraParameters::KEY_MAX_NUM_REQUESTED_FACES, requested_faces);
     const char *str = params.get(QCameraParameters::KEY_FACE_DETECTION);
     ALOGE("setFaceDetect: %s", str);
     if (str != NULL) {
+        fd_set_parm_t fd_set_parm;
         int value = attr_lookup(facedetection,
                 sizeof(facedetection) / sizeof(str_map), str);
         mFaceDetectOn = value;
-        ALOGV("%s Face detection value = %d",__func__, value);
-        cam_ctrl_dimension_t dim;
-//        cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
-//        preview_parm_config (&dim, mParameters);
-//        cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
-        native_set_parms(MM_CAMERA_PARM_FD, sizeof(int8_t), (void *)&value);
+        fd_set_parm.fd_mode = value;
+        fd_set_parm.num_fd = requested_faces;
+        ALOGE("%s Face detection value = %d, num_fd = %d",__func__, value, requested_faces);
+        native_set_parms(MM_CAMERA_PARM_FD, sizeof(fd_set_parm_t), (void *)&fd_set_parm);
         mParameters.set(QCameraParameters::KEY_FACE_DETECTION, str);
         return NO_ERROR;
     }
@@ -2986,14 +2987,18 @@
         return NO_ERROR;
     }
     if (str != NULL) {
+        int requested_faces = mParameters.getInt(QCameraParameters::KEY_MAX_NUM_REQUESTED_FACES);
         int value = attr_lookup(facedetection,
                                     sizeof(facedetection) / sizeof(str_map), str);
         if (value != NOT_FOUND) {
+            fd_set_parm_t fd_set_parm;
             mMetaDataWaitLock.lock();
             mFaceDetectOn = value;
             mMetaDataWaitLock.unlock();
-            mParameters.set(QCameraParameters::KEY_FACE_DETECTION, str);
-            native_set_parms(MM_CAMERA_PARM_FD, sizeof(int8_t), (void *)&value);
+            fd_set_parm.fd_mode = value;
+            fd_set_parm.num_fd = requested_faces;
+            ALOGI("%s Face detection value = %d, num_fd = %d",__func__, value, requested_faces);
+            native_set_parms(MM_CAMERA_PARM_FD, sizeof(fd_set_parm_t), (void *)&fd_set_parm);
             mParameters.set(QCameraParameters::KEY_FACE_DETECTION, str);
             return NO_ERROR;
         }
diff --git a/camera/QCameraHWI_Preview.cpp b/camera/QCameraHWI_Preview.cpp
index 02ec5a4..f2df36f 100644
--- a/camera/QCameraHWI_Preview.cpp
+++ b/camera/QCameraHWI_Preview.cpp
@@ -462,10 +462,13 @@
             mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected;
             mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised;
             mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle;
+
             /* newly added */
-            mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir;
-            mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir;
-            mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir;
+            // upscale by 2 to recover from demaen downscaling
+            mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir*2;
+            mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir*2;
+            mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir*2;
+
             mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink;
             mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink;
             mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze;
diff --git a/camera/QCameraHWI_Preview_7x27A.cpp b/camera/QCameraHWI_Preview_7x27A.cpp
index acb8bc1..a2fa672 100644
--- a/camera/QCameraHWI_Preview_7x27A.cpp
+++ b/camera/QCameraHWI_Preview_7x27A.cpp
@@ -302,9 +302,21 @@
               roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
 
             mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree;
-            mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence / 10; //Keep within range 1~100
+            mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence;
             mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected;
             mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised;
+            mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle;
+
+            /* newly added */
+            // upscale by 2 to recover from demaen downscaling
+            mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir*2;
+            mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir*2;
+            mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir*2;
+
+            mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink;
+            mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink;
+            mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze;
+            mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze;
 
             ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), blinked(%d)", __func__,
                mHalCamCtrl->mFace[idx].rect[0],  mHalCamCtrl->mFace[idx].rect[1],
diff --git a/camera/QCameraHWI_Still.cpp b/camera/QCameraHWI_Still.cpp
index 4b4946a..7d5e16e 100644
--- a/camera/QCameraHWI_Still.cpp
+++ b/camera/QCameraHWI_Still.cpp
@@ -486,6 +486,7 @@
     status_t ret = NO_ERROR;
     mm_camera_ch_image_fmt_parm_t fmt;
     mm_camera_channel_attr_t ch_attr;
+    cam_format_t raw_fmt;
 
     mm_camera_raw_streaming_type_t raw_stream_type =
         MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE;
@@ -512,9 +513,17 @@
         goto end;
     }
 
+    ret = cam_config_get_parm(mCameraId,
+        MM_CAMERA_PARM_RAW_SNAPSHOT_FMT, &raw_fmt);
+    if (NO_ERROR != ret) {
+        ALOGE("%s: error - can't get raw snapshot fmt!", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
     memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
     fmt.ch_type = MM_CAMERA_CH_RAW;
-    fmt.def.fmt = CAMERA_BAYER_SBGGR10;
+    fmt.def.fmt = raw_fmt;
     fmt.def.dim.width = dim->raw_picture_width;
     fmt.def.dim.height = dim->raw_picture_height;
 
@@ -646,6 +655,7 @@
     uint8_t num_planes;
     uint32_t planes[VIDEO_MAX_PLANES];
     mm_camera_reg_buf_t reg_buf;
+    cam_format_t raw_fmt;
 
     ALOGD("%s: E", __func__);
     memset(&reg_buf,  0,  sizeof(mm_camera_reg_buf_t));
@@ -665,8 +675,16 @@
     }
     memset(reg_buf.def.buf.mp, 0, num_of_buf * sizeof(mm_camera_mp_buf_t));
 
+    ret = cam_config_get_parm(mCameraId,
+        MM_CAMERA_PARM_RAW_SNAPSHOT_FMT, &raw_fmt);
+    if (NO_ERROR != ret) {
+        ALOGE("%s: error - can't get raw snapshot fmt!", __func__);
+        ret = FAILED_TRANSACTION;
+        goto end;
+    }
+
     /* Get a frame len for buffer to be allocated*/
-    frame_len = mm_camera_get_msm_frame_len(CAMERA_BAYER_SBGGR10,
+    frame_len = mm_camera_get_msm_frame_len(raw_fmt,
                                             myMode,
                                             dim->raw_picture_width,
                                             dim->raw_picture_height,
@@ -1487,6 +1505,8 @@
     int width, height;
     uint8_t *thumbnail_buf;
     uint32_t thumbnail_fd;
+    uint8_t hw_encode = true;
+    int mNuberOfVFEOutputs = 0;
 
     omx_jpeg_encode_params encode_params;
 
@@ -1577,7 +1597,25 @@
         set_callbacks(snapshot_jpeg_fragment_cb, snapshot_jpeg_cb, this,
              mHalCamCtrl->mJpegMemory.camera_memory[0]->data, &mJpegOffset);
 
-        if(omxJpegStart() != NO_ERROR){
+        if (isLiveSnapshot() || isFullSizeLiveshot()) {
+            /* determine the target type */
+            ret = cam_config_get_parm(mCameraId,MM_CAMERA_PARM_VFE_OUTPUT_ENABLE,
+                                 &mNuberOfVFEOutputs);
+            if (ret != MM_CAMERA_OK) {
+                ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE  failed");
+                ret = BAD_VALUE;
+            }
+            /* VFE 2x has hardware limitation:
+             * It can't support concurrent
+             * video encoding and jpeg encoding
+             * So switch to software for liveshot
+             */
+            if (mNuberOfVFEOutputs == 1)
+                hw_encode = false;
+        }
+        ALOGD("%s: hw_encode: %d\n",__func__, hw_encode);
+
+        if(omxJpegStart(hw_encode) != NO_ERROR){
             ALOGE("Error In omxJpegStart!!! Return");
             ret = FAILED_TRANSACTION;
             goto end;
diff --git a/camera/QCameraParameters.cpp b/camera/QCameraParameters.cpp
index 1d387c6..7405468 100644
--- a/camera/QCameraParameters.cpp
+++ b/camera/QCameraParameters.cpp
@@ -136,6 +136,8 @@
 const char QCameraParameters::KEY_MAX_SATURATION[] = "max-saturation";
 
 const char QCameraParameters::KEY_SINGLE_ISP_OUTPUT_ENABLED[] = "single-isp-output-enabled";
+const char QCameraParameters::KEY_SUPPORTED_CAMERA_FEATURES[] = "qc-camera-features";
+const char QCameraParameters::KEY_MAX_NUM_REQUESTED_FACES[] = "qc-max-num-requested-faces";
 
 //Values for DENOISE
 const char QCameraParameters::DENOISE_OFF[] = "denoise-off";
diff --git a/camera/QCameraParameters.h b/camera/QCameraParameters.h
index 6920413..84cbfec 100644
--- a/camera/QCameraParameters.h
+++ b/camera/QCameraParameters.h
@@ -229,6 +229,8 @@
 
 
    static const char KEY_SINGLE_ISP_OUTPUT_ENABLED[];
+   static const char KEY_SUPPORTED_CAMERA_FEATURES[];
+   static const char KEY_MAX_NUM_REQUESTED_FACES[];
 
     enum {
         CAMERA_ORIENTATION_UNKNOWN = 0,
diff --git a/camera/QCamera_Intf.h b/camera/QCamera_Intf.h
index 22ba919..12c85ac 100644
--- a/camera/QCamera_Intf.h
+++ b/camera/QCamera_Intf.h
@@ -81,7 +81,8 @@
   CAMERA_RDI,
   CAMERA_YUV_420_YV12,
   CAMERA_YUV_422_NV16,
-  CAMERA_YUV_422_NV61
+  CAMERA_YUV_422_NV61,
+  CAMERA_YUV_422_YUYV,
 } cam_format_t;
 
 typedef enum {
@@ -208,6 +209,7 @@
   uint32_t default_preview_width;
   uint32_t default_preview_height;
   uint32_t bestshot_reconfigure;
+  uint32_t pxlcode;
 }cam_prop_t;
 
 typedef struct {
@@ -242,6 +244,7 @@
   cam_format_t    main_img_format;
   cam_format_t    rdi0_format;
   cam_format_t    rdi1_format;
+  cam_format_t    raw_img_format;
   cam_pad_format_t prev_padding_format;
   cam_pad_format_t enc_padding_format;
   cam_pad_format_t thumb_padding_format;
@@ -270,6 +273,31 @@
   uint32_t channel_interface_mask;
 } cam_ctrl_dimension_t;
 
+typedef struct {
+  uint8_t cid;
+  uint8_t dt;
+  uint32_t inst_handle;
+} cam_cid_entry_t;
+
+#define CAM_MAX_CID_NUM    8
+typedef struct {
+  /*should we hard code max CIDs? if not we need to have two CMD*/
+  uint8_t num_cids;
+  cam_cid_entry_t cid_entries[CAM_MAX_CID_NUM];
+} cam_cid_info_t;
+
+typedef struct {
+  /* we still use prev, video, main,
+   * thumb to interprete image types */
+  uint32_t image_mode;                 /* input */
+  cam_format_t format;                 /* input */
+  cam_pad_format_t padding_format;     /* input */
+  int rotation;                        /* input */
+  uint16_t width;                      /* input/output */
+  uint16_t height;                     /* input/output */
+  cam_frame_len_offset_t frame_offset; /* output */
+} cam_frame_resolution_t;
+
 /* Add enumenrations at the bottom but before MM_CAMERA_PARM_MAX */
 typedef enum {
     MM_CAMERA_PARM_PICT_SIZE,
@@ -375,8 +403,12 @@
     MM_CAMERA_PARM_CH_INTERFACE,
     //or single output enabled to differentiate 7x27a with others
     MM_CAMERA_PARM_BESTSHOT_RECONFIGURE,
-    MM_CAMERA_MAX_NUM_FACES_DECT,
+    MM_CAMERA_PARM_MAX_NUM_FACES_DECT,
     MM_CAMERA_PARM_FPS_RANGE,
+    MM_CAMERA_PARM_CID,
+    MM_CAMERA_PARM_FRAME_RESOLUTION,
+    MM_CAMERA_PARM_RAW_SNAPSHOT_FMT,
+    MM_CAMERA_PARM_FACIAL_FEATURE_INFO,
     MM_CAMERA_PARM_CAF_LOCK_CANCEL,
     MM_CAMERA_PARM_MAX
 } mm_camera_parm_type_t;
@@ -518,6 +550,9 @@
   CAMERA_GET_MAX_NUM_FACES_DECT,
   CAMERA_SET_CHANNEL_STREAM,
   CAMERA_GET_CHANNEL_STREAM,
+  CAMERA_SET_PARM_CID, /*125*/
+  CAMERA_GET_PARM_FRAME_RESOLUTION,
+  CAMERA_GET_FACIAL_FEATURE_INFO,
   CAMERA_SET_CAF_LOCK_CANCEL,
   CAMERA_CTRL_PARM_MAX
 } cam_ctrl_type;
@@ -583,6 +618,10 @@
   CAMERA_ISO_MAX
 } camera_iso_mode_type;
 
+typedef enum {
+  MM_CAMERA_FACIAL_FEATURE_FD, // facial detection
+  MM_CAMERA_FACIAL_FEATURE_MAX
+} camera_facial_features;
 
 typedef enum {
   AEC_ROI_OFF,
@@ -828,6 +867,11 @@
 } fd_roi_type_t;
 
 typedef struct {
+  int fd_mode;
+  int num_fd;
+} fd_set_parm_t;
+
+typedef struct {
   uint32_t frame_id;
   int16_t num_face_detected;
 } fd_roi_header_type;
diff --git a/camera/mm-camera-interface/mm_camera.c b/camera/mm-camera-interface/mm_camera.c
index 227e00b..727a884 100644
--- a/camera/mm-camera-interface/mm_camera.c
+++ b/camera/mm-camera-interface/mm_camera.c
@@ -312,7 +312,7 @@
                     CAMERA_SET_SCE_FACTOR, sizeof(int32_t), (void *)parm->p_value);
     case MM_CAMERA_PARM_FD:
         return mm_camera_send_native_ctrl_cmd(my_obj,
-                    CAMERA_SET_PARM_FD, sizeof(int32_t), (void *)parm->p_value);
+                    CAMERA_SET_PARM_FD, sizeof(fd_set_parm_t), (void *)parm->p_value);
     case MM_CAMERA_PARM_AEC_LOCK:
         return mm_camera_send_native_ctrl_cmd(my_obj,
                     CAMERA_SET_AEC_LOCK, sizeof(int32_t), (void *)parm->p_value);
@@ -527,6 +527,9 @@
              dim->width, dim->height);
     }
         break;
+    case MM_CAMERA_PARM_RAW_SNAPSHOT_FMT:
+        *((cam_format_t *)parm->p_value) = my_obj->properties.pxlcode;
+        break;
     case MM_CAMERA_PARM_PREVIEW_FORMAT:
         *((int *)parm->p_value) = my_obj->properties.preview_format;
         break;
@@ -630,6 +633,12 @@
     case MM_CAMERA_PARM_VFE_OUTPUT_ENABLE:
         *((int *)parm->p_value) = my_obj->properties.vfe_output_enable;
         break;
+    case MM_CAMERA_PARM_MAX_NUM_FACES_DECT:
+        return mm_camera_send_native_ctrl_cmd(my_obj, CAMERA_GET_MAX_NUM_FACES_DECT,
+                     sizeof(int), (void *)parm->p_value);
+    case MM_CAMERA_PARM_FACIAL_FEATURE_INFO:
+        return mm_camera_send_native_ctrl_cmd(my_obj, CAMERA_GET_FACIAL_FEATURE_INFO,
+                     sizeof(int), (void *)parm->p_value);
     default:
         /* needs to add more implementation */
         rc = -1;
diff --git a/camera/mm-camera-interface/mm_camera_helper.c b/camera/mm-camera-interface/mm_camera_helper.c
index 7d0377d..bee4e0b 100644
--- a/camera/mm-camera-interface/mm_camera_helper.c
+++ b/camera/mm-camera-interface/mm_camera_helper.c
@@ -217,6 +217,11 @@
         plane[0] = PAD_TO_WORD(width * height);
         size = plane[0];
         break;
+    case CAMERA_YUV_422_YUYV:
+        *num_planes = 1;
+        plane[0] = PAD_TO_WORD(width * height);
+        size = plane[0];
+        break;
     case CAMERA_YUV_422_NV16:
     case CAMERA_YUV_422_NV61:
       if( image_type == OUTPUT_TYPE_S || image_type == OUTPUT_TYPE_V) {
diff --git a/camera/mm-camera-interface/mm_camera_stream.c b/camera/mm-camera-interface/mm_camera_stream.c
index 4b12757..96c23d9 100644
--- a/camera/mm-camera-interface/mm_camera_stream.c
+++ b/camera/mm-camera-interface/mm_camera_stream.c
@@ -315,6 +315,10 @@
         val= V4L2_PIX_FMT_NV61;
         *num_planes = 2;
         break;
+    case CAMERA_YUV_422_YUYV:
+        val= V4L2_PIX_FMT_YUYV;
+        *num_planes = 1;
+        break;
     default:
         val = 0;
         *num_planes = 0;
diff --git a/camera/mm-camera-interface/mm_omx_jpeg_encoder.c b/camera/mm-camera-interface/mm_omx_jpeg_encoder.c
index bd21495..066280b 100644
--- a/camera/mm-camera-interface/mm_omx_jpeg_encoder.c
+++ b/camera/mm-camera-interface/mm_omx_jpeg_encoder.c
@@ -266,12 +266,12 @@
     return TRUE;
 }
 
-int8_t omxJpegStart()
+int8_t omxJpegStart(uint8_t hw_encode_enable)
 {
     int rc = 0;
     ALOGE("%s", __func__);
     pthread_mutex_lock(&jpege_mutex);
-    hw_encode = true;
+    hw_encode = hw_encode_enable;
     callbacks.EmptyBufferDone = etbdone;
     callbacks.FillBufferDone = ftbdone;
     callbacks.EventHandler = eventHandler;
diff --git a/camera/mm-camera-interface/mm_omx_jpeg_encoder.h b/camera/mm-camera-interface/mm_omx_jpeg_encoder.h
index c995ead..7893334 100644
--- a/camera/mm-camera-interface/mm_omx_jpeg_encoder.h
+++ b/camera/mm-camera-interface/mm_omx_jpeg_encoder.h
@@ -51,7 +51,7 @@
 }omx_jpeg_encode_params;
 
 int8_t omxJpegOpen();
-int8_t omxJpegStart();
+int8_t omxJpegStart(uint8_t hw_encode_enable);
 int8_t omxJpegEncode(omx_jpeg_encode_params *encode_params);
 int8_t omxJpegEncodeNext(omx_jpeg_encode_params *encode_params);
 void omxJpegFinish();