Merge "Update to 07.00.00.253.024" into nyc-mr1-dev
diff --git a/msmcobalt/QCamera2/Android.mk b/msmcobalt/QCamera2/Android.mk
index d65133e..6278c36 100644
--- a/msmcobalt/QCamera2/Android.mk
+++ b/msmcobalt/QCamera2/Android.mk
@@ -61,7 +61,7 @@
 endif
 
 ifeq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) <= 23 ))" )))
-LOCAL_CFLAGS += -DUSE_M_AOSP
+LOCAL_CFLAGS += -DUSE_HAL_3_3
 endif
 
 #use media extension
diff --git a/msmcobalt/QCamera2/HAL/QCamera2HWI.cpp b/msmcobalt/QCamera2/HAL/QCamera2HWI.cpp
index 46181b1..047f55c 100644
--- a/msmcobalt/QCamera2/HAL/QCamera2HWI.cpp
+++ b/msmcobalt/QCamera2/HAL/QCamera2HWI.cpp
@@ -770,17 +770,6 @@
     }
     LOGD("E camera id %d", hw->getCameraId());
 
-    //Close and delete duplicated native handle and FD's.
-    if ((hw->mVideoMem != NULL) && (hw->mStoreMetaDataInFrame)) {
-         ret = hw->mVideoMem->closeNativeHandle(opaque, TRUE);
-        if (ret != NO_ERROR) {
-            LOGE("Invalid video metadata");
-            return;
-        }
-    } else {
-        LOGW("Possible FD leak. Release recording called after stop");
-    }
-
     hw->lockAPI();
     qcamera_api_result_t apiResult;
     ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
@@ -1641,6 +1630,7 @@
       mLiveSnapshotThread(0),
       mIntPicThread(0),
       mFlashNeeded(false),
+      mFlashConfigured(false),
       mDeviceRotation(0U),
       mCaptureRotation(0U),
       mJpegExifRotation(0U),
@@ -1674,7 +1664,6 @@
       mJpegClientHandle(0),
       mJpegHandleOwner(false),
       mMetadataMem(NULL),
-      mVideoMem(NULL),
       mCACDoneReceived(false),
       m_bNeedRestart(false),
       mBootToMonoTimestampOffset(0)
@@ -2878,10 +2867,6 @@
             }
             videoMemory->setVideoInfo(usage, fmt);
             mem = videoMemory;
-            if (!mParameters.getBufBatchCount()) {
-                //For batch mode this will be part of user buffer.
-                mVideoMem = videoMemory;
-            }
         }
         break;
     case CAM_STREAM_TYPE_CALLBACK:
@@ -3017,6 +3002,9 @@
     int rc = NO_ERROR;
     char value[PROPERTY_VALUE_MAX];
     bool raw_yuv = false;
+    int32_t dt = 0;
+    int32_t vc = 0;
+
 
     QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
     if (!streamInfoBuf) {
@@ -3069,6 +3057,13 @@
         } else {
             streamInfo->is_secure = NON_SECURE;
         }
+        if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
+            mParameters.updateDtVc(&dt, &vc);
+            if (dt)
+                streamInfo->dt = dt;
+            streamInfo->vc = vc;
+        }
+
         break;
     case CAM_STREAM_TYPE_POSTVIEW:
         if (mLongshotEnabled) {
@@ -3099,7 +3094,7 @@
         }
         if (mParameters.getRecordingHintValue()) {
             if(mParameters.isDISEnabled()) {
-                streamInfo->is_type = mParameters.getISType();
+                streamInfo->is_type = mParameters.getVideoISType();
             } else {
                 streamInfo->is_type = IS_TYPE_NONE;
             }
@@ -3163,10 +3158,11 @@
             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
     }
 
-    LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x\n",
+    LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
            stream_type, streamInfo->fmt, streamInfo->dim.width,
            streamInfo->dim.height, streamInfo->num_bufs,
-           streamInfo->pp_config.feature_mask);
+           streamInfo->pp_config.feature_mask,
+           streamInfo->is_type);
 
     return streamInfoBuf;
 }
@@ -3223,7 +3219,6 @@
         }
         video_mem->setVideoInfo(usage, fmt);
         mem = static_cast<QCameraMemory *>(video_mem);
-        mVideoMem = video_mem;
     }
     break;
 
@@ -3673,7 +3668,6 @@
     int32_t rc = NO_ERROR;
 
     LOGI("E");
-    mVideoMem = NULL;
     //link meta stream with video channel if low power mode.
     if (isLowPowerMode()) {
         // Find and try to link a metadata stream from preview channel
@@ -3773,7 +3767,6 @@
     m_cbNotifier.flushVideoNotifications();
     // Disable power hint for video encoding
     m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
-    mVideoMem = NULL;
     LOGI("X rc = %d", rc);
     return rc;
 }
@@ -3978,7 +3971,7 @@
             mHDRBracketingEnabled = false;
             rc = mParameters.stopAEBracket();
         } else if ((mParameters.isChromaFlashEnabled())
-                || (mFlashNeeded && !mLongshotEnabled)
+                || (mFlashConfigured && !mLongshotEnabled)
                 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
                 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
             rc = mParameters.resetFrameCapture(TRUE);
@@ -4077,6 +4070,7 @@
         rc = mParameters.configFrameCapture(TRUE);
     } else if (mFlashNeeded && !mLongshotEnabled) {
         rc = mParameters.configFrameCapture(TRUE);
+        mFlashConfigured = true;
         bSkipDisplay = false;
     } else {
         LOGH("Advanced Capture feature not enabled!! ");
@@ -4351,10 +4345,11 @@
     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
     } else if (mParameters.isChromaFlashEnabled()
-            || (mFlashNeeded && !mLongshotEnabled)
+            || (mFlashConfigured && !mLongshotEnabled)
             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
         rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
+        mFlashConfigured = false;
     } else if(mParameters.isHDREnabled()
             || mParameters.isAEBracketEnabled()) {
         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
@@ -6896,6 +6891,10 @@
         } else {
             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                                     preview_stream_cb_routine, this);
+#ifdef TARGET_TS_MAKEUP
+            int whiteLevel, cleanLevel;
+            if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
+#endif
             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
                     synchronous_stream_cb_routine);
         }
@@ -7213,6 +7212,10 @@
     } else {
         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                                 preview_stream_cb_routine, this);
+#ifdef TARGET_TS_MAKEUP
+        int whiteLevel, cleanLevel;
+        if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
+#endif
         pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
                 synchronous_stream_cb_routine);
     }
@@ -7245,7 +7248,7 @@
     if (raw_yuv) {
         rc = addStreamToChannel(pChannel,
                                 CAM_STREAM_TYPE_RAW,
-                                NULL,
+                                preview_raw_stream_cb_routine,
                                 this);
         if (rc != NO_ERROR) {
             LOGE("add raw stream failed, ret = %d", rc);
@@ -7319,15 +7322,7 @@
         return rc;
     }
 
-    if (!mLongshotEnabled) {
-        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
-                                NULL, this);
-
-        if (rc != NO_ERROR) {
-            LOGE("add postview stream failed, ret = %d", rc);
-            return rc;
-        }
-    } else {
+    if (mLongshotEnabled) {
         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                                 preview_stream_cb_routine, this);
 
@@ -7335,8 +7330,21 @@
             LOGE("add preview stream failed, ret = %d", rc);
             return rc;
         }
+#ifdef TARGET_TS_MAKEUP
+        int whiteLevel, cleanLevel;
+        if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
+#endif
         pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
                 synchronous_stream_cb_routine);
+    //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
+    } else if (!mParameters.getQuadraCfa()) {
+        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
+                                NULL, this);
+
+        if (rc != NO_ERROR) {
+            LOGE("add postview stream failed, ret = %d", rc);
+            return rc;
+        }
     }
 
     if (!mParameters.getofflineRAW()) {
@@ -7533,6 +7541,7 @@
         int8_t curIndex, bool multipass)
 {
     int32_t rc = NO_ERROR;
+    int32_t feature_set = 0;
 
     if (multipass) {
         LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
@@ -7549,7 +7558,22 @@
     pp_config.cur_reproc_count = curIndex + 1;
     pp_config.total_reproc_count = mParameters.getReprocCount();
 
-    switch(curIndex) {
+    //Checking what feature mask to enable
+    if (curIndex == 0) {
+        if (mParameters.getQuadraCfa()) {
+            feature_set = 2;
+        } else {
+            feature_set = 0;
+        }
+    } else if (curIndex == 1) {
+        if (mParameters.getQuadraCfa()) {
+            feature_set = 0;
+        } else {
+            feature_set = 1;
+        }
+    }
+
+    switch(feature_set) {
         case 0:
             //Configure feature mask for first pass of reprocessing
             //check if any effects are enabled
@@ -7675,7 +7699,8 @@
             }
 
             if ((multipass) &&
-                    (m_postprocessor.getPPChannelCount() > 1)) {
+                    (m_postprocessor.getPPChannelCount() > 1)
+                    && (!mParameters.getQuadraCfa())) {
                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
@@ -7724,9 +7749,15 @@
             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
             break;
 
+        case 2:
+            //Setting feature for Quadra CFA
+            pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
+            break;
+
     }
+
     LOGH("pproc feature mask set = %llx pass count = %d",
-             pp_config.feature_mask, curIndex);
+        pp_config.feature_mask, curIndex);
     return rc;
 }
 
@@ -8584,7 +8615,25 @@
 
     switch (stats_data.type) {
     case CAM_HISTOGRAM_TYPE_BAYER:
-        *pHistData = stats_data.bayer_stats.gb_stats;
+        switch (stats_data.bayer_stats.data_type) {
+            case CAM_STATS_CHANNEL_Y:
+            case CAM_STATS_CHANNEL_R:
+                *pHistData = stats_data.bayer_stats.r_stats;
+                break;
+            case CAM_STATS_CHANNEL_GR:
+                *pHistData = stats_data.bayer_stats.gr_stats;
+                break;
+            case CAM_STATS_CHANNEL_GB:
+            case CAM_STATS_CHANNEL_ALL:
+                *pHistData = stats_data.bayer_stats.gb_stats;
+                break;
+            case CAM_STATS_CHANNEL_B:
+                *pHistData = stats_data.bayer_stats.b_stats;
+                break;
+            default:
+                *pHistData = stats_data.bayer_stats.r_stats;
+                break;
+        }
         break;
     case CAM_HISTOGRAM_TYPE_YUV:
         *pHistData = stats_data.yuv_stats;
@@ -9345,9 +9394,10 @@
  *==========================================================================*/
 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
 {
-    return ((m_stateMachine.isPreviewRunning()) &&
+    return (((m_stateMachine.isPreviewRunning()) &&
             (!isDisplayFrameToSkip(frameID)) &&
-            (!mParameters.isInstantAECEnabled()));
+            (!mParameters.isInstantAECEnabled())) ||
+            (isPreviewRestartEnabled()));
 }
 
 /*===========================================================================
@@ -10235,7 +10285,7 @@
         !isLongshotEnabled() &&
         !mParameters.isHDREnabled() &&
         !mParameters.getRecordingHintValue() &&
-        !isZSLMode() && !mParameters.getofflineRAW()) {
+        !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
             ret = true;
     }
     return ret;
diff --git a/msmcobalt/QCamera2/HAL/QCamera2HWI.h b/msmcobalt/QCamera2/HAL/QCamera2HWI.h
index 2d365bb..4d9929b 100644
--- a/msmcobalt/QCamera2/HAL/QCamera2HWI.h
+++ b/msmcobalt/QCamera2/HAL/QCamera2HWI.h
@@ -631,6 +631,7 @@
     pthread_t mLiveSnapshotThread;
     pthread_t mIntPicThread;
     bool mFlashNeeded;
+    bool mFlashConfigured;
     uint32_t mDeviceRotation;
     uint32_t mCaptureRotation;
     uint32_t mJpegExifRotation;
@@ -761,7 +762,6 @@
     bool TsMakeupProcess(mm_camera_buf_def_t *frame,QCameraStream * stream,TSRect& faceRect);
 #endif
     QCameraMemory *mMetadataMem;
-    QCameraVideoMemory *mVideoMem;
 
     static uint32_t sNextJobId;
 
diff --git a/msmcobalt/QCamera2/HAL/QCamera2HWICallbacks.cpp b/msmcobalt/QCamera2/HAL/QCamera2HWICallbacks.cpp
index 93a5271..dca74fd 100644
--- a/msmcobalt/QCamera2/HAL/QCamera2HWICallbacks.cpp
+++ b/msmcobalt/QCamera2/HAL/QCamera2HWICallbacks.cpp
@@ -1400,7 +1400,7 @@
     nsecs_t timeStamp = 0;
     bool triggerTCB = FALSE;
 
-    LOGH("[KPI Perf] : BEGIN");
+    LOGD("[KPI Perf] : BEGIN");
     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
     if (pme == NULL ||
         pme->mCameraHandle == NULL ||
@@ -1429,16 +1429,15 @@
         if (pme->mParameters.getVideoBatchSize() == 0) {
             timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL
                     + frame->ts.tv_nsec;
-            LOGD("Video frame to encoder TimeStamp : %lld batch = 0",
-                    timeStamp);
             pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO);
             videoMemObj = (QCameraVideoMemory *)frame->mem_info;
             video_mem = NULL;
             if (NULL != videoMemObj) {
                 video_mem = videoMemObj->getMemory(frame->buf_idx,
                         (pme->mStoreMetaDataInFrame > 0)? true : false);
-                videoMemObj->updateNativeHandle(frame->buf_idx);
                 triggerTCB = TRUE;
+                LOGH("Video frame TimeStamp : %lld batch = 0 index = %d",
+                        timeStamp, frame->buf_idx);
             }
         } else {
             //Handle video batch callback
@@ -1459,7 +1458,7 @@
                 }
             }
             video_mem = stream->mCurMetaMemory;
-            nh = videoMemObj->updateNativeHandle(stream->mCurMetaIndex);
+            nh = videoMemObj->getNativeHandle(stream->mCurMetaIndex);
             if (video_mem == NULL || nh == NULL) {
                 LOGE("No Free metadata. Drop this frame");
                 stream->mCurBufIndex = -1;
@@ -1498,8 +1497,9 @@
             stream->mCurBufIndex++;
             if (stream->mCurBufIndex == fd_cnt) {
                 timeStamp = stream->mFirstTimeStamp;
-                LOGD("Video frame to encoder TimeStamp : %lld batch = %d",
-                    timeStamp, fd_cnt);
+                LOGH("Video frame to encoder TimeStamp : %lld batch = %d Buffer idx = %d",
+                        timeStamp, fd_cnt,
+                        nh->data[nh->numFds + nh->numInts - VIDEO_METADATA_NUM_COMMON_INTS]);
                 stream->mCurBufIndex = -1;
                 stream->mCurMetaIndex = -1;
                 stream->mCurMetaMemory = NULL;
@@ -1513,7 +1513,7 @@
         int fd_cnt = frame->user_buf.bufs_used;
         if (NULL != videoMemObj) {
             video_mem = videoMemObj->getMemory(frame->buf_idx, true);
-            nh = videoMemObj->updateNativeHandle(frame->buf_idx);
+            nh = videoMemObj->getNativeHandle(frame->buf_idx);
         } else {
             LOGE("videoMemObj NULL");
         }
@@ -1521,8 +1521,6 @@
         if (nh != NULL) {
             timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL
                     + frame->ts.tv_nsec;
-            LOGD("Batch buffer TimeStamp : %lld FD = %d index = %d fd_cnt = %d",
-                    timeStamp, frame->fd, frame->buf_idx, fd_cnt);
 
             for (int i = 0; i < fd_cnt; i++) {
                 if (frame->user_buf.buf_idx[i] >= 0) {
@@ -1553,6 +1551,8 @@
                 }
             }
             triggerTCB = TRUE;
+            LOGH("Batch buffer TimeStamp : %lld FD = %d index = %d fd_cnt = %d",
+                    timeStamp, frame->fd, frame->buf_idx, fd_cnt);
         } else {
             LOGE("No Video Meta Available. Return Buffer");
             stream->bufDone(super_frame->bufs[0]->buf_idx);
@@ -1582,7 +1582,7 @@
     }
 
     free(super_frame);
-    LOGH("[KPI Perf] : END");
+    LOGD("[KPI Perf] : END");
 }
 
 /*===========================================================================
diff --git a/msmcobalt/QCamera2/HAL/QCameraChannel.cpp b/msmcobalt/QCamera2/HAL/QCameraChannel.cpp
index b5a59ef..233474c 100644
--- a/msmcobalt/QCamera2/HAL/QCameraChannel.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraChannel.cpp
@@ -1053,8 +1053,13 @@
             // Enable CPP high performance mode to put it in turbo frequency mode for
             // burst/longshot/HDR snapshot cases
             streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE;
-            if (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) {
-                streamInfo->fmt = CAM_FORMAT_YUV_420_NV21;
+            if (param.getofflineRAW() && (pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
+                    || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) {
+                if (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_QUADRA_CFA) {
+                    param.getStreamFormat(CAM_STREAM_TYPE_OFFLINE_PROC, streamInfo->fmt);
+                } else {
+                    streamInfo->fmt = CAM_FORMAT_YUV_420_NV21;
+                }
             } else {
                 rc = pStream->getFormat(streamInfo->fmt);
             }
@@ -1075,8 +1080,14 @@
                     rc = param.getStreamDimension(CAM_STREAM_TYPE_OFFLINE_PROC,
                             streamInfo->dim);
                 } else if ((param.getofflineRAW()) &&
-                        (pStream->isTypeOf(CAM_STREAM_TYPE_RAW))) {
-                    param.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,streamInfo->dim);
+                        ((pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) ||
+                        (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)))) {
+                         if ((param.getQuadraCfa()) &&
+                             (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_QUADRA_CFA)) {
+                             rc = pStream->getFrameDimension(streamInfo->dim);
+                         } else {
+                             param.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,streamInfo->dim);
+                         }
                 } else {
                     rc = pStream->getFrameDimension(streamInfo->dim);
                 }
diff --git a/msmcobalt/QCamera2/HAL/QCameraMem.cpp b/msmcobalt/QCamera2/HAL/QCameraMem.cpp
old mode 100755
new mode 100644
index 0c599cf..214f219
--- a/msmcobalt/QCamera2/HAL/QCameraMem.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraMem.cpp
@@ -44,7 +44,6 @@
 #include "QCameraTrace.h"
 
 // Media dependencies
-#include "OMX_QCOMExtns.h"
 #ifdef USE_MEDIA_EXTENSIONS
 #include <media/hardware/HardwareAPI.h>
 typedef struct VideoNativeHandleMetadata media_metadata_buffer;
@@ -1333,7 +1332,7 @@
     if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) {
         /*
         *    FDs = 1
-        *    numInts  = 5 //offset, size, usage, timestamp, format
+        *    numInts  = 5 //offset, size, usage, timestamp, format + 1 for buffer index
         */
         rc = allocateMeta(count, 1, VIDEO_METADATA_NUM_INTS);
         if (rc != NO_ERROR) {
@@ -1401,10 +1400,11 @@
                     (media_metadata_buffer *)mMetadata[i]->data;
             //FDs = 1
             //numInts  = 5 (offset, size, usage, timestamp, format)
-            mNativeHandle[i] = native_handle_create(1, VIDEO_METADATA_NUM_INTS);
+            mNativeHandle[i] = native_handle_create(1,
+                    (VIDEO_METADATA_NUM_INTS + VIDEO_METADATA_NUM_COMMON_INTS));
 #ifdef USE_MEDIA_EXTENSIONS
             packet->eType = kMetadataBufferTypeNativeHandleSource;
-            packet->pHandle = mNativeHandle[i];
+            packet->pHandle = NULL;
 #else
             packet->buffer_type = kMetadataBufferTypeCameraSource;
             packet->meta_handle = mNativeHandle[i];
@@ -1421,6 +1421,7 @@
             nh->data[3] = mUsage;
             nh->data[4] = 0; //dummy value for timestamp in non-batch mode
             nh->data[5] = mFormat;
+            nh->data[6] = i;
         }
     }
     mBufferCount = (uint8_t)(mBufferCount + count);
@@ -1444,6 +1445,7 @@
 int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts)
 {
     int rc = NO_ERROR;
+    int mTotalInts = 0;
 
     for (int i = 0; i < buf_cnt; i++) {
         mMetadata[i] = mGetMemory(-1,
@@ -1460,7 +1462,9 @@
         }
         media_metadata_buffer *packet =
                 (media_metadata_buffer *)mMetadata[i]->data;
-        mNativeHandle[i] = native_handle_create(numFDs, (numInts * numFDs));
+        mTotalInts = (numInts * numFDs);
+        mNativeHandle[i] = native_handle_create(numFDs,
+                (mTotalInts + VIDEO_METADATA_NUM_COMMON_INTS));
         if (mNativeHandle[i] == NULL) {
             LOGE("Error in getting video native handle");
             for (int j = (i - 1); j >= 0; j--) {
@@ -1471,10 +1475,14 @@
                 mMetadata[j]->release(mMetadata[j]);
             }
             return NO_MEMORY;
+        } else {
+            //assign buffer index to native handle.
+            native_handle_t *nh =  mNativeHandle[i];
+            nh->data[numFDs + mTotalInts] = i;
         }
 #ifdef USE_MEDIA_EXTENSIONS
         packet->eType = kMetadataBufferTypeNativeHandleSource;
-        packet->pHandle = mNativeHandle[i];
+        packet->pHandle = NULL;
 #else
         packet->buffer_type = kMetadataBufferTypeCameraSource;
         packet->meta_handle = mNativeHandle[i];
@@ -1548,51 +1556,56 @@
     if (index >= mMetaBufCount || (!metadata && index >= mBufferCount))
         return NULL;
 
-    if (metadata)
+    if (metadata) {
+#ifdef USE_MEDIA_EXTENSIONS
+        int i;
+        media_metadata_buffer *packet = NULL;
+
+        for (i = 0; i < mMetaBufCount; i++) {
+            packet = (media_metadata_buffer *)mMetadata[i]->data;
+            if (packet != NULL && packet->pHandle == NULL) {
+                packet->pHandle = mNativeHandle[index];
+                break;
+            }
+        }
+        if (i < mMetaBufCount) {
+            return mMetadata[i];
+        } else {
+            LOGE("No free video meta memory");
+            return NULL;
+        }
+#else
         return mMetadata[index];
-    else
+#endif
+    } else {
         return mCameraMemory[index];
+    }
 }
 
 /*===========================================================================
- * FUNCTION   : updateNativeHandle
+ * FUNCTION   : getNativeHandle
  *
- * DESCRIPTION: Updating native handle pointer
+ * DESCRIPTION: getNativeHandle from video buffer
  *
  * PARAMETERS :
  *   @index   : buffer index
- *   @metadata: flag if it's metadata
  *
- * RETURN     : camera native handle ptr
- *              NULL if not supported or failed
+ * RETURN     : native_handle_t  * type of handle
  *==========================================================================*/
-native_handle_t *QCameraVideoMemory::updateNativeHandle(uint32_t index, bool metadata)
+native_handle_t *QCameraVideoMemory::getNativeHandle(uint32_t index, bool metadata)
 {
-    if (index >= mMetaBufCount || (!metadata && index >= mBufferCount)) {
+    if (index >= mMetaBufCount || !metadata)
         return NULL;
-    }
-
-    native_handle_t *nh = NULL;
-    if (metadata && mMetadata[index] != NULL) {
-        media_metadata_buffer *packet =
-                (media_metadata_buffer *)mMetadata[index]->data;
-        nh = mNativeHandle[index];
-#ifdef USE_MEDIA_EXTENSIONS
-        packet->pHandle = nh;
-#else
-        packet->meta_handle = nh;
-#endif
-    }
-    return nh;
+    return mNativeHandle[index];
 }
 
 /*===========================================================================
  * FUNCTION   : closeNativeHandle
  *
- * DESCRIPTION: close video native handle
+ * DESCRIPTION: close video native handle and update cached ptrs
  *
  * PARAMETERS :
- *   @opaque  : ptr to video frame to be returned
+ *   @data  : ptr to video frame to be returned
  *
  * RETURN     : int32_t type of status
  *              NO_ERROR  -- success
@@ -1602,28 +1615,21 @@
 {
     int32_t rc = NO_ERROR;
 #ifdef USE_MEDIA_EXTENSIONS
-    int32_t index = -1;
-
-    camera_memory_t *video_mem = NULL;
-
     if (metadata) {
-        index = getMatchBufIndex(data, metadata);
-        if (index < 0) {
-            LOGE("Invalid buffer");
-            return BAD_VALUE;
-        }
-        video_mem = getMemory(index, metadata);
-        media_metadata_buffer * packet = NULL;
-        if (video_mem) {
-             packet = (media_metadata_buffer *)video_mem->data;
-        }
-
-        if (packet != NULL && packet->eType ==
-                kMetadataBufferTypeNativeHandleSource) {
-            native_handle_close(packet->pHandle);
-            native_handle_delete(packet->pHandle);
-            packet->pHandle = NULL;
-        } else {
+        const media_metadata_buffer *packet =
+                    (const media_metadata_buffer *)data;
+        if ((packet != NULL) && (packet->eType ==
+                kMetadataBufferTypeNativeHandleSource)
+                && (packet->pHandle)) {
+            for (int i = 0; i < mMetaBufCount; i++) {
+                if(mMetadata[i]->data == data) {
+                    media_metadata_buffer *mem =
+                            (media_metadata_buffer *)mMetadata[i]->data;
+                    mem->pHandle = NULL;
+                    break;
+                }
+            }
+         } else {
             LOGE("Invalid Data. Could not release");
             return BAD_VALUE;
         }
@@ -1655,12 +1661,31 @@
     int index = -1;
 
     if (metadata) {
+#ifdef USE_MEDIA_EXTENSIONS
+        const media_metadata_buffer *packet =
+                (const media_metadata_buffer *)opaque;
+        native_handle_t *nh = NULL;
+        if ((packet != NULL) && (packet->eType ==
+                kMetadataBufferTypeNativeHandleSource)
+                && (packet->pHandle)) {
+            nh = (native_handle_t *)packet->pHandle;
+            int mCommonIdx = (nh->numInts + nh->numFds -
+                    VIDEO_METADATA_NUM_COMMON_INTS);
+            for (int i = 0; i < mMetaBufCount; i++) {
+                if(nh->data[mCommonIdx] == mNativeHandle[i]->data[mCommonIdx]) {
+                    index = i;
+                    break;
+                }
+            }
+        }
+#else
         for (int i = 0; i < mMetaBufCount; i++) {
-            if (mMetadata[i]->data == opaque) {
+            if(mMetadata[i]->data == opaque) {
                 index = i;
                 break;
             }
         }
+#endif
     } else {
         for (int i = 0; i < mBufferCount; i++) {
             if (mCameraMemory[i]->data == opaque) {
diff --git a/msmcobalt/QCamera2/HAL/QCameraMem.h b/msmcobalt/QCamera2/HAL/QCameraMem.h
index 2979696..c450ba0 100644
--- a/msmcobalt/QCamera2/HAL/QCameraMem.h
+++ b/msmcobalt/QCamera2/HAL/QCameraMem.h
@@ -35,6 +35,9 @@
 #include <utils/Mutex.h>
 #include <utils/List.h>
 
+//Media depedancies
+#include "OMX_QCOMExtns.h"
+
 // Display dependencies
 #include "qdMetaData.h"
 
@@ -52,6 +55,14 @@
 //OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
 #define VIDEO_METADATA_NUM_INTS          5
 
+//Buffer identity
+//Note that this macro might have already been
+//defined in OMX_QCOMExtns.h, in which case
+//the local value below will not be used.
+#ifndef VIDEO_METADATA_NUM_COMMON_INTS
+#define VIDEO_METADATA_NUM_COMMON_INTS   1
+#endif
+
 enum QCameraMemType {
     QCAMERA_MEM_TYPE_DEFAULT      = 0,
     QCAMERA_MEM_TYPE_SECURE       = 1,
@@ -236,8 +247,8 @@
     int getUsage(){return mUsage;};
     int getFormat(){return mFormat;};
     int convCamtoOMXFormat(cam_format_t format);
-    native_handle_t *updateNativeHandle(uint32_t index, bool metadata = true);
     int closeNativeHandle(const void *data, bool metadata = true);
+    native_handle_t *getNativeHandle(uint32_t index, bool metadata = true);
 private:
     camera_memory_t *mMetadata[MM_CAMERA_MAX_NUM_FRAMES];
     uint8_t mMetaBufCount;
diff --git a/msmcobalt/QCamera2/HAL/QCameraParameters.cpp b/msmcobalt/QCamera2/HAL/QCameraParameters.cpp
index c403574..f0a65ba 100644
--- a/msmcobalt/QCamera2/HAL/QCameraParameters.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraParameters.cpp
@@ -900,7 +900,7 @@
       m_pRelCamSyncHeap(NULL),
       m_pRelCamSyncBuf(NULL),
       m_bFrameSyncEnabled(false),
-      mIsType(IS_TYPE_NONE),
+      mIsTypeVideo(IS_TYPE_NONE),
       mIsTypePreview(IS_TYPE_NONE),
       m_bZslMode(false),
       m_bZslMode_new(false),
@@ -935,6 +935,7 @@
       m_bLocalHDREnabled(false),
       m_bAVTimerEnabled(false),
       m_bDISEnabled(false),
+      m_bMetaRawEnabled(false),
       m_MobiMask(0),
       m_AdjustFPS(NULL),
       m_bHDR1xFrameEnabled(false),
@@ -975,7 +976,8 @@
       m_bInstantAEC(false),
       m_bInstantCapture(false),
       mAecFrameBound(0),
-      mAecSkipDisplayFrameBound(0)
+      mAecSkipDisplayFrameBound(0),
+      m_bQuadraCfa(false)
 {
     char value[PROPERTY_VALUE_MAX];
     // TODO: may move to parameter instead of sysprop
@@ -1106,7 +1108,8 @@
     m_bInstantAEC(false),
     m_bInstantCapture(false),
     mAecFrameBound(0),
-    mAecSkipDisplayFrameBound(0)
+    mAecSkipDisplayFrameBound(0),
+    m_bQuadraCfa(false)
 {
     memset(&m_LiveSnapshotSize, 0, sizeof(m_LiveSnapshotSize));
     memset(&m_default_fps_range, 0, sizeof(m_default_fps_range));
@@ -3583,6 +3586,7 @@
                 // If HDR is set from client  and the feature is not enabled in the backend, ignore it.
                 if (m_bHDRModeSensor && isSupportedSensorHdrSize(params)) {
                     m_bSensorHDREnabled = true;
+                    m_bHDREnabled = false;
                     LOGH("Sensor HDR mode Enabled");
                 } else {
                     m_bHDREnabled = true;
@@ -3913,6 +3917,75 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : setQuadraCFA
+ *
+ * DESCRIPTION: set Quadra CFA mode
+ *
+ * PARAMETERS :
+ *   @params  : user setting parameters
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::setQuadraCfa(const QCameraParameters& params)
+{
+
+    int32_t width = 0,height = 0;
+    bool prev_quadracfa = getQuadraCfa();
+    int32_t rc = NO_ERROR;
+    int32_t value;
+
+    if (!m_pCapability->is_remosaic_lib_present) {
+        LOGD("Quadra CFA mode not supported");
+        return rc;
+    }
+
+    /*Checking if the user selected dim is more than maximum dim supported by
+    Quadra sensor in normal mode. If more then switch to Quadra CFA mode else
+    remain in normal zsl mode */
+    params.getPictureSize(&width, &height);
+    if (width > m_pCapability->raw_dim[0].width &&
+        height > m_pCapability->raw_dim[0].height) {
+        LOGI("Quadra CFA mode selected");
+        m_bQuadraCfa = TRUE;
+    } else {
+        LOGI("Quadra CFA mode not selected");
+        m_bQuadraCfa = FALSE;
+    }
+    value = m_bQuadraCfa;
+    if (prev_quadracfa == m_bQuadraCfa) {
+        LOGD("No change in Quadra CFA mode");
+    } else {
+        if (ADD_SET_PARAM_ENTRY_TO_BATCH(m_pParamBuf, CAM_INTF_PARM_QUADRA_CFA, value)) {
+            rc = BAD_VALUE;
+            LOGE("Error sending Quadra CFA set param to modules");
+            return rc;
+        }
+
+        if (m_bZslMode && m_bQuadraCfa) {
+            m_bNeedRestart = TRUE;
+            setZslMode(FALSE);
+        }
+
+        if (m_bQuadraCfa) {
+            setOfflineRAW(TRUE);
+        } else  {
+            setOfflineRAW(FALSE);
+            const char *str_val  = params.get(KEY_QC_ZSL);
+            int32_t value = lookupAttr(ON_OFF_MODES_MAP, PARAM_MAP_SIZE(ON_OFF_MODES_MAP),
+                    str_val);
+            if (value != NAME_NOT_FOUND && value) {
+                rc = setZslMode(value);
+                // ZSL mode changed, need restart preview
+                m_bNeedRestart = true;
+            }
+        }
+    }
+    LOGH("Quadra CFA mode = %d", m_bQuadraCfa);
+    return rc;
+}
+/*===========================================================================
  * FUNCTION   : setSeeMore
  *
  * DESCRIPTION: set see more (llvd) from user setting
@@ -4004,6 +4077,45 @@
     return NO_ERROR;
 }
 
+#ifdef TARGET_TS_MAKEUP
+
+/*===========================================================================
+ * FUNCTION   : setTsMakeup
+ *
+ * DESCRIPTION: set setTsMakeup from user setting
+ *
+ * PARAMETERS :
+ *   @params  : user setting parameters
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::setTsMakeup(const QCameraParameters& params)
+{
+    const char *str = params.get(KEY_TS_MAKEUP);
+    const char *prev_str = get(KEY_TS_MAKEUP);
+    LOGH("str =%s & prev_str =%s", str, prev_str);
+    if (str != NULL) {
+        if (prev_str == NULL || strcmp(str, prev_str) != 0) {
+            m_bNeedRestart = true;
+            set(KEY_TS_MAKEUP, str);
+            const char *str1 = params.get(KEY_TS_MAKEUP_WHITEN);
+            if (str1 != NULL) {
+                set(KEY_TS_MAKEUP_WHITEN, str1);
+            }
+            const char *str2 = params.get(KEY_TS_MAKEUP_CLEAN);
+            if (str2 != NULL) {
+                set(KEY_TS_MAKEUP_CLEAN, str2);
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+#endif
+
 /*===========================================================================
  * FUNCTION   : setRedeyeReduction
  *
@@ -5114,26 +5226,14 @@
     if ((rc = setLongshotParam(params)))                final_rc = rc;
     if ((rc = setDualLedCalibration(params)))           final_rc = rc;
 
+    setQuadraCfa(params);
     setVideoBatchSize();
     setLowLightCapture();
 
     if ((rc = updateFlash(false)))                      final_rc = rc;
-
 #ifdef TARGET_TS_MAKEUP
-    if (params.get(KEY_TS_MAKEUP) != NULL) {
-        set(KEY_TS_MAKEUP,params.get(KEY_TS_MAKEUP));
-        final_rc = rc;
-    }
-    if (params.get(KEY_TS_MAKEUP_WHITEN) != NULL) {
-        set(KEY_TS_MAKEUP_WHITEN,params.get(KEY_TS_MAKEUP_WHITEN));
-        final_rc = rc;
-    }
-    if (params.get(KEY_TS_MAKEUP_CLEAN) != NULL) {
-        set(KEY_TS_MAKEUP_CLEAN,params.get(KEY_TS_MAKEUP_CLEAN));
-        final_rc = rc;
-    }
+    if ((rc = setTsMakeup(params)))                     final_rc = rc;
 #endif
-
     if ((rc = setAdvancedCaptureMode()))                final_rc = rc;
 UPDATE_PARAM_DONE:
     needRestart = m_bNeedRestart;
@@ -9640,7 +9740,7 @@
     }
 
     if (isHDREnabled() || m_bAeBracketingEnabled || m_bAFBracketingOn ||
-          m_bOptiZoomOn || m_bReFocusOn || m_LowLightLevel) {
+          m_bOptiZoomOn || m_bReFocusOn || m_LowLightLevel || m_bStillMoreOn) {
         value = CAM_FLASH_MODE_OFF;
     } else if (m_bChromaFlashOn) {
         value = CAM_FLASH_MODE_ON;
@@ -9919,6 +10019,29 @@
     return ret;
 }
 
+int32_t QCameraParameters::getStreamSubFormat(cam_stream_type_t streamType,
+                            cam_sub_format_type_t &sub_format)
+{
+    int32_t ret = NO_ERROR;
+    sub_format = CAM_FORMAT_SUBTYPE_MAX;
+
+    switch (streamType) {
+        case CAM_STREAM_TYPE_RAW: {
+          char raw_sub_format[PROPERTY_VALUE_MAX];
+          int rawSubFormat;
+          memset(raw_sub_format, 0, sizeof(raw_sub_format));
+          /*Default value is CAM_FORMAT_SUBTYPE_PDAF_STATS*/
+          property_get("persist.camera.raw.subformat", raw_sub_format, "1");
+          rawSubFormat = atoi(raw_sub_format);
+          sub_format = (cam_sub_format_type_t)rawSubFormat;
+          LOGH("Subformat for raw stream = %d", sub_format);
+        }
+            break;
+        default:
+            break;
+    }
+    return ret;
+}
 /*===========================================================================
  * FUNCTION   : getStreamFormat
  *
@@ -10025,7 +10148,7 @@
         }
         break;
     case CAM_STREAM_TYPE_RAW:
-        if ((isRdiMode()) || (getofflineRAW())) {
+        if ((isRdiMode()) || (getofflineRAW())|| (getQuadraCfa())) {
             format = m_pCapability->rdi_mode_stream_fmt;
         } else if (mPictureFormat >= CAM_FORMAT_YUV_RAW_8BIT_YUYV) {
             format = (cam_format_t)mPictureFormat;
@@ -10041,8 +10164,12 @@
                     format);
         }
         break;
-    case CAM_STREAM_TYPE_METADATA:
     case CAM_STREAM_TYPE_OFFLINE_PROC:
+        if (getQuadraCfa()) {
+            format = m_pCapability->quadra_cfa_format;
+        }
+        break;
+    case CAM_STREAM_TYPE_METADATA:
     case CAM_STREAM_TYPE_DEFAULT:
     default:
         break;
@@ -10358,6 +10485,19 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : getQuadraCFA
+ *
+ * DESCRIPTION: get QuadraCFA mode
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : none
+ *==========================================================================*/
+bool QCameraParameters::getQuadraCfa()
+{
+    return m_bQuadraCfa;
+}
+/*===========================================================================
  * FUNCTION   : getthumbnailSize
  *
  * DESCRIPTION: get thumbnail size
@@ -11458,15 +11598,24 @@
     int32_t rc = NO_ERROR;
     cam_dimension_t raw_dim, pic_dim;
 
+    //No need to update RAW dimensions if meta raw is enabled.
+    if (m_bMetaRawEnabled) {
+        return rc;
+    }
     // If offline raw is enabled, check the dimensions from Picture size since snapshot
     // stream is not added but final JPEG is required of snapshot size
     if (getofflineRAW()) {
-        getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, pic_dim);
-        if (pic_dim.width > max_dim.width) {
-            max_dim.width = pic_dim.width;
-        }
-        if (pic_dim.height > max_dim.height) {
-            max_dim.height = pic_dim.height;
+        if (getQuadraCfa()) {
+            max_dim.width = m_pCapability->quadra_cfa_dim[0].width;
+            max_dim.height = m_pCapability->quadra_cfa_dim[0].height;
+        } else {
+            getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, pic_dim);
+            if (pic_dim.width > max_dim.width) {
+                max_dim.width = pic_dim.width;
+            }
+            if (pic_dim.height > max_dim.height) {
+                max_dim.height = pic_dim.height;
+            }
         }
     }
 
@@ -11508,7 +11657,11 @@
     LOGH("RAW Dimension = %d X %d",raw_dim.width,raw_dim.height);
     if (raw_dim.width == 0 || raw_dim.height == 0) {
         LOGW("Error getting RAW size. Setting to Capability value");
-        raw_dim = m_pCapability->raw_dim[0];
+        if (getQuadraCfa()) {
+            raw_dim = m_pCapability->quadra_cfa_dim[0];
+        } else {
+            raw_dim = m_pCapability->raw_dim[0];
+        }
     }
     setRawSize(raw_dim);
     return rc;
@@ -12629,6 +12782,47 @@
 }
 
 /*===========================================================================
+* FUNCTION   : setISType
+*
+* DESCRIPTION: Set both Preview & Video IS type by reading the correspoding setprop's
+*
+* PARAMETERS : none
+*
+* RETURN     : IS type
+*
+*==========================================================================*/
+int32_t QCameraParameters::setISType()
+{
+    bool eisSupported = false, eis3Supported = false;
+    for (size_t i = 0; i < m_pCapability->supported_is_types_cnt; i++) {
+        if ((m_pCapability->supported_is_types[i] == IS_TYPE_EIS_2_0) ||
+                (m_pCapability->supported_is_types[i] == IS_TYPE_EIS_3_0)) {
+            eisSupported = true;
+        }
+        if (m_pCapability->supported_is_types[i] == IS_TYPE_EIS_3_0) {
+            eis3Supported = TRUE;
+        }
+    }
+    if (m_bDISEnabled && eisSupported) {
+        char value[PROPERTY_VALUE_MAX];
+        // Make default value for Video IS_TYPE as IS_TYPE_EIS_2_0
+        property_get("persist.camera.is_type", value, "4");
+        mIsTypeVideo = static_cast<cam_is_type_t>(atoi(value));
+        if ( (mIsTypeVideo == IS_TYPE_EIS_3_0) && (eis3Supported == FALSE) ) {
+            LOGW("EIS_3.0 is not supported and so setting EIS_2.0");
+            mIsTypeVideo = IS_TYPE_EIS_2_0;
+        }
+        // Make default value for preview IS_TYPE as IS_TYPE_EIS_2_0
+        property_get("persist.camera.is_type_preview", value, "4");
+        mIsTypePreview = static_cast<cam_is_type_t>(atoi(value));
+    } else {
+        mIsTypeVideo = IS_TYPE_NONE;
+        mIsTypePreview = IS_TYPE_NONE;
+    }
+    return NO_ERROR;
+}
+
+/*===========================================================================
 * FUNCTION   : getISType
 *
 * DESCRIPTION: returns IS type
@@ -12638,9 +12832,9 @@
 * RETURN     : IS type
 *
 *==========================================================================*/
-cam_is_type_t QCameraParameters::getISType()
+cam_is_type_t QCameraParameters::getVideoISType()
 {
-    return mIsType;
+    return mIsTypeVideo;
 }
 
 /*===========================================================================
@@ -12749,6 +12943,12 @@
     stream_config_info.min_scanline   = m_pCapability->min_scanline;
     stream_config_info.batch_size = getBufBatchCount();
 
+    LOGH("buf_alignment=%d stride X scan=%dx%d batch size = %d\n",
+            m_pCapability->buf_alignment,
+            m_pCapability->min_stride,
+            m_pCapability->min_scanline,
+            stream_config_info.batch_size);
+
     property_get("persist.camera.raw_yuv", value, "0");
     raw_yuv = atoi(value) > 0 ? true : false;
 
@@ -12805,19 +13005,10 @@
 
     } else if (!isCapture) {
         if (m_bRecordingHint) {
-            if (m_bDISEnabled) {
-                char value[PROPERTY_VALUE_MAX];
-                // Make default value for IS_TYPE as IS_TYPE_EIS_2_0
-                property_get("persist.camera.is_type", value, "4");
-                mIsType = static_cast<cam_is_type_t>(atoi(value));
-                // Make default value for preview IS_TYPE as IS_TYPE_EIS_2_0
-                property_get("persist.camera.is_type_preview", value, "4");
-                mIsTypePreview = static_cast<cam_is_type_t>(atoi(value));
-            } else {
-                mIsType = IS_TYPE_NONE;
-                mIsTypePreview = IS_TYPE_NONE;
-            }
-            stream_config_info.is_type[stream_config_info.num_streams] = mIsType;
+            setISType();
+            mIsTypeVideo = getVideoISType();
+            mIsTypePreview = getPreviewISType();
+            stream_config_info.is_type[stream_config_info.num_streams] = IS_TYPE_NONE;
             stream_config_info.type[stream_config_info.num_streams] =
                     CAM_STREAM_TYPE_SNAPSHOT;
             getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,
@@ -12828,7 +13019,7 @@
             getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT,
                         stream_config_info.format[stream_config_info.num_streams]);
             stream_config_info.num_streams++;
-            stream_config_info.is_type[stream_config_info.num_streams] = mIsType;
+            stream_config_info.is_type[stream_config_info.num_streams] = mIsTypeVideo;
             stream_config_info.type[stream_config_info.num_streams] =
                     CAM_STREAM_TYPE_VIDEO;
             getStreamDimension(CAM_STREAM_TYPE_VIDEO,
@@ -12882,7 +13073,7 @@
                         mStreamPpMask[CAM_STREAM_TYPE_CALLBACK];
                 getStreamFormat(CAM_STREAM_TYPE_CALLBACK,
                         stream_config_info.format[stream_config_info.num_streams]);
-                stream_config_info.is_type[stream_config_info.num_streams] = mIsType;
+                stream_config_info.is_type[stream_config_info.num_streams] = IS_TYPE_NONE;
                 stream_config_info.num_streams++;
             }
         }
@@ -12899,7 +13090,7 @@
                         mStreamPpMask[CAM_STREAM_TYPE_SNAPSHOT];
                 getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT,
                         stream_config_info.format[stream_config_info.num_streams]);
-                stream_config_info.is_type[stream_config_info.num_streams] = mIsType;
+                stream_config_info.is_type[stream_config_info.num_streams] = IS_TYPE_NONE;
                 stream_config_info.num_streams++;
             }
 
@@ -12913,9 +13104,9 @@
                         mStreamPpMask[CAM_STREAM_TYPE_PREVIEW];
                 getStreamFormat(CAM_STREAM_TYPE_PREVIEW,
                         stream_config_info.format[stream_config_info.num_streams]);
-                stream_config_info.is_type[stream_config_info.num_streams] = mIsType;
+                stream_config_info.is_type[stream_config_info.num_streams] = IS_TYPE_NONE;
                 stream_config_info.num_streams++;
-            } else {
+            } else if(!getQuadraCfa()) {
                 stream_config_info.type[stream_config_info.num_streams] =
                         CAM_STREAM_TYPE_POSTVIEW;
                 getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,
@@ -12925,7 +13116,7 @@
                         mStreamPpMask[CAM_STREAM_TYPE_POSTVIEW];
                 getStreamFormat(CAM_STREAM_TYPE_POSTVIEW,
                         stream_config_info.format[stream_config_info.num_streams]);
-                stream_config_info.is_type[stream_config_info.num_streams] = mIsType;
+                stream_config_info.is_type[stream_config_info.num_streams] = IS_TYPE_NONE;
                 stream_config_info.num_streams++;
             }
         } else {
@@ -12939,7 +13130,7 @@
                     mStreamPpMask[CAM_STREAM_TYPE_RAW];
             getStreamFormat(CAM_STREAM_TYPE_RAW,
                     stream_config_info.format[stream_config_info.num_streams]);
-            stream_config_info.is_type[stream_config_info.num_streams] = mIsType;
+            stream_config_info.is_type[stream_config_info.num_streams] = IS_TYPE_NONE;
             stream_config_info.num_streams++;
         }
     }
@@ -12947,35 +13138,69 @@
     if ((!raw_capture) && ((getofflineRAW() && !getRecordingHintValue())
             || (raw_yuv))) {
         cam_dimension_t max_dim = {0,0};
-        // Find the Maximum dimension admong all the streams
-        for (uint32_t j = 0; j < stream_config_info.num_streams; j++) {
-            if (stream_config_info.stream_sizes[j].width > max_dim.width) {
-                max_dim.width = stream_config_info.stream_sizes[j].width;
+
+        if (!getQuadraCfa()) {
+            // Find the Maximum dimension admong all the streams
+            for (uint32_t j = 0; j < stream_config_info.num_streams; j++) {
+                if (stream_config_info.stream_sizes[j].width > max_dim.width) {
+                    max_dim.width = stream_config_info.stream_sizes[j].width;
+                }
+                if (stream_config_info.stream_sizes[j].height > max_dim.height) {
+                    max_dim.height = stream_config_info.stream_sizes[j].height;
+                }
             }
-            if (stream_config_info.stream_sizes[j].height > max_dim.height) {
-                max_dim.height = stream_config_info.stream_sizes[j].height;
-            }
+        } else {
+            max_dim.width = m_pCapability->quadra_cfa_dim[0].width;
+            max_dim.height = m_pCapability->quadra_cfa_dim[0].height;
         }
         LOGH("Max Dimension = %d X %d", max_dim.width, max_dim.height);
-        updateRAW(max_dim);
         stream_config_info.type[stream_config_info.num_streams] =
-                CAM_STREAM_TYPE_RAW;
-        getStreamDimension(CAM_STREAM_TYPE_RAW,
-                stream_config_info.stream_sizes[stream_config_info.num_streams]);
+            CAM_STREAM_TYPE_RAW;
+        getStreamFormat(CAM_STREAM_TYPE_RAW,
+                stream_config_info.format[stream_config_info.num_streams]);
+        if (CAM_FORMAT_META_RAW_10BIT ==
+            stream_config_info.format[stream_config_info.num_streams]) {
+            int32_t dt = 0;
+            int32_t vc = 0;
+            cam_stream_size_info_t temp_stream_config_info;
+            getStreamSubFormat(CAM_STREAM_TYPE_RAW,
+                stream_config_info.sub_format_type[
+                stream_config_info.num_streams]);
+            /* Sending separate meta_stream_info so that other modules do
+             * not confuse with original sendStreamConfigInfo(). This is only
+             * for sensor where sensor can run pick resolusion for meta raw.
+             */
+            updateDtVc(&dt, &vc);
+            stream_config_info.dt[stream_config_info.num_streams] = dt;
+            stream_config_info.vc[stream_config_info.num_streams] = vc;
+            memcpy(&temp_stream_config_info, &stream_config_info,
+                sizeof(temp_stream_config_info));
+            temp_stream_config_info.num_streams++;
+            sendStreamConfigForPickRes(temp_stream_config_info);
+            getMetaRawInfo();
+        } else {
+            updateRAW(max_dim);
+        }
+        getStreamDimension(CAM_STREAM_TYPE_RAW, stream_config_info.stream_sizes[
+                stream_config_info.num_streams]);
         updatePpFeatureMask(CAM_STREAM_TYPE_RAW);
         stream_config_info.postprocess_mask[stream_config_info.num_streams] =
                 mStreamPpMask[CAM_STREAM_TYPE_RAW];
-        getStreamFormat(CAM_STREAM_TYPE_RAW,
-                stream_config_info.format[stream_config_info.num_streams]);
         stream_config_info.num_streams++;
     }
+
     for (uint32_t k = 0; k < stream_config_info.num_streams; k++) {
-        LOGI("STREAM INFO : type %d, wxh: %d x %d, pp_mask: 0x%llx Format = %d",
+        LOGI("STREAM INFO : type %d, wxh: %d x %d, pp_mask: 0x%llx \
+                Format = %d, dt =%d cid =%d subformat =%d, is_type %d",
                 stream_config_info.type[k],
                 stream_config_info.stream_sizes[k].width,
                 stream_config_info.stream_sizes[k].height,
                 stream_config_info.postprocess_mask[k],
-                stream_config_info.format[k]);
+                stream_config_info.format[k],
+                stream_config_info.dt[k],
+                stream_config_info.vc[k],
+                stream_config_info.sub_format_type[k],
+                stream_config_info.is_type[k]);
     }
 
     rc = sendStreamConfigInfo(stream_config_info);
@@ -13065,7 +13290,7 @@
             isOptiZoomEnabled() || isUbiRefocus() ||
             isStillMoreEnabled() ||
             (isHDREnabled() && !isHDRThumbnailProcessNeeded())
-            || isUBWCEnabled()) {
+            || isUBWCEnabled()|| getQuadraCfa()) {
         *pFeatureMask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
         *pFeatureMask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
         *pFeatureMask &= ~CAM_QCOM_FEATURE_REFOCUS;
@@ -13122,6 +13347,10 @@
         numOfBufs += 1;
     }
 
+    if (getQuadraCfa()) {
+        numOfBufs += 1;
+    }
+
     return (uint8_t)(numOfBufs);
 }
 
@@ -13486,7 +13715,7 @@
             (stream_type == CAM_STREAM_TYPE_PREVIEW)) {
             feature_mask |= CAM_QCOM_FEATURE_PAAF;
         } else if (stream_type == CAM_STREAM_TYPE_VIDEO) {
-            if (getISType() != IS_TYPE_EIS_3_0)
+            if (getVideoISType() != IS_TYPE_EIS_3_0)
                 feature_mask |= CAM_QCOM_FEATURE_PAAF;
         }
         break;
@@ -13500,6 +13729,12 @@
         break;
     }
 
+    // Enable PPEISCORE for EIS 3.0
+    if ((stream_type == CAM_STREAM_TYPE_VIDEO) &&
+            (getVideoISType() == IS_TYPE_EIS_3_0)) {
+        feature_mask |= CAM_QTI_FEATURE_PPEISCORE;
+    }
+
     // Store stream feature mask
     setStreamPpMask(stream_type, feature_mask);
     LOGH("stream type: %d, pp_mask: 0x%llx", stream_type, feature_mask);
@@ -13568,6 +13803,11 @@
     char value[PROPERTY_VALUE_MAX];
     int multpass = 0;
 
+    if (getQuadraCfa()) {
+        multpass = TRUE;
+        return TRUE;
+    }
+
     property_get("persist.camera.multi_pass", value, "0");
     multpass = atoi(value);
 
@@ -13603,6 +13843,10 @@
         LOGD("2 Pass postprocessing enabled");
         mTotalPPCount++;
     }
+
+    if (getQuadraCfa()) {
+        mTotalPPCount++;
+    }
 }
 
 /*===========================================================================
@@ -14246,8 +14490,6 @@
     return m_reprocScaleParam.getPicSizeFromAPK(width, height);
 }
 
-
-
 /*===========================================================================
  * FUNCTION   : setDualLedCalibration
  *
@@ -14375,4 +14617,121 @@
     return mCommon.getAnalysisInfo(fdVideoEnabled, hal3, featureMask, pAnalysisInfo);
 }
 
+/*===========================================================================
+ * FUNCTION   : getMetaRawInfo
+ *
+ * DESCRIPTION: fetch meta raw dimension
+ *
+ * PARAMETERS :
+ *   @dim  : get dimension for meta raw stream
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::getMetaRawInfo()
+{
+    int32_t rc = NO_ERROR;
+    cam_dimension_t meta_stream_size;
+
+    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+        LOGE("Failed to initialize group update table");
+        return BAD_TYPE;
+    }
+
+    ADD_GET_PARAM_ENTRY_TO_BATCH(m_pParamBuf,
+            CAM_INTF_META_RAW);
+
+    rc = commitGetBatch();
+    if (rc != NO_ERROR) {
+        LOGE("Failed to get extened RAW info");
+        return rc;
+    }
+
+    READ_PARAM_ENTRY(m_pParamBuf,
+            CAM_INTF_META_RAW, meta_stream_size);
+
+    if (meta_stream_size.width == 0 || meta_stream_size.height == 0) {
+        LOGE("Error getting RAW size. Setting to Capability value");
+        meta_stream_size = m_pCapability->raw_meta_dim[0];
+    }
+    LOGH("RAW meta size. width =%d height =%d",
+      meta_stream_size.width, meta_stream_size.height);
+
+    setRawSize(meta_stream_size);
+    m_bMetaRawEnabled = true;
+    return rc;
+}
+/*===========================================================================
+ * FUNCTION   : sendStreamConfigForPickRes
+ *
+ * DESCRIPTION: send Stream config info.
+ *
+ * PARAMETERS :
+ *   @stream_config_info: Stream config information
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+bool QCameraParameters::sendStreamConfigForPickRes
+    (cam_stream_size_info_t &stream_config_info) {
+    int32_t rc = NO_ERROR;
+    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+        LOGE("Failed to initialize group update table");
+        return BAD_TYPE;
+    }
+
+    if (ADD_SET_PARAM_ENTRY_TO_BATCH(m_pParamBuf,
+            CAM_INTF_META_STREAM_INFO_FOR_PIC_RES, stream_config_info)) {
+        LOGE("%s:Failed to update table");
+        return BAD_VALUE;
+    }
+
+    rc = commitSetBatch();
+    if (rc != NO_ERROR) {
+        LOGE("Failed to set stream info parm");
+        return rc;
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : updateDtVc
+ *
+ * DESCRIPTION: Update DT and Vc from capabilities
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::updateDtVc(int32_t *dt, int32_t *vc)
+{
+    int32_t rc = NO_ERROR;
+    char prop[PROPERTY_VALUE_MAX];
+
+    int dt_val = 0;
+    int vc_val = 0;
+
+    /* Setting Dt from setprop or capability */
+    property_get("persist.camera.dt", prop, "0");
+    dt_val = atoi(prop);
+    if (dt_val == 0) {
+        dt_val = m_pCapability->dt[0];
+    }
+    *dt = dt_val;
+
+    /*Setting vc from setprop or capability */
+    property_get("persist.camera.vc", prop, "-1");
+    vc_val = atoi(prop);
+    if (vc_val== -1) {
+        vc_val = m_pCapability->vc[0];
+    }
+    *vc = vc_val;
+
+    LOGH("dt=%d vc=%d",*dt, *vc);
+    return rc;
+}
+
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCameraParameters.h b/msmcobalt/QCamera2/HAL/QCameraParameters.h
index e0877d8..4a4fd6e 100644
--- a/msmcobalt/QCamera2/HAL/QCameraParameters.h
+++ b/msmcobalt/QCamera2/HAL/QCameraParameters.h
@@ -644,6 +644,9 @@
                                cam_dimension_t &dim);
     int32_t getStreamFormat(cam_stream_type_t streamType,
                              cam_format_t &format);
+  int32_t getStreamSubFormat(cam_stream_type_t streamType,
+             cam_sub_format_type_t &sub_format);
+
     int32_t getStreamDimension(cam_stream_type_t streamType,
             cam_dimension_t &dim);
     void getThumbnailSize(int *width, int *height) const;
@@ -712,7 +715,8 @@
     int32_t stopAEBracket();
     int32_t updateRAW(cam_dimension_t max_dim);
     bool isDISEnabled();
-    cam_is_type_t getISType();
+    int32_t setISType();
+    cam_is_type_t getVideoISType();
     cam_is_type_t getPreviewISType();
     uint8_t getMobicatMask();
 
@@ -791,6 +795,7 @@
     int32_t updateOisValue(bool oisValue);
     int32_t setIntEvent(cam_int_evt_params_t params);
     bool getofflineRAW() {return mOfflineRAW;}
+    bool getQuadraCfa();
     int32_t updatePpFeatureMask(cam_stream_type_t stream_type);
     int32_t getStreamPpMask(cam_stream_type_t stream_type, cam_feature_mask_t &pp_mask);
     int32_t getSharpness() {return m_nSharpness;};
@@ -867,6 +872,11 @@
         bool hal3,
         cam_feature_mask_t featureMask,
         cam_analysis_info_t *pAnalysisInfo);
+
+    int32_t getMetaRawInfo();
+    bool sendStreamConfigForPickRes(cam_stream_size_info_t &stream_config_info);
+    int32_t updateDtVc(int32_t *dt, int32_t *vc);
+
 private:
     int32_t setPreviewSize(const QCameraParameters& );
     int32_t setVideoSize(const QCameraParameters& );
@@ -921,6 +931,9 @@
     int32_t setTruePortrait(const QCameraParameters& );
     int32_t setSeeMore(const QCameraParameters& );
     int32_t setStillMore(const QCameraParameters& );
+#ifdef TARGET_TS_MAKEUP
+    int32_t setTsMakeup(const QCameraParameters& );
+#endif
     int32_t setNoiseReductionMode(const QCameraParameters& );
     int32_t setRedeyeReduction(const QCameraParameters& );
     int32_t setGpsLocation(const QCameraParameters& );
@@ -1019,6 +1032,7 @@
     void setDcrf();
     int32_t setStreamPpMask(cam_stream_type_t stream_type, cam_feature_mask_t pp_mask);
     void setOfflineRAW(bool value = 0);
+    int32_t setQuadraCfa(const QCameraParameters& params);
     int32_t configureFlash(cam_capture_frame_config_t &frame_config);
     int32_t configureLowLight(cam_capture_frame_config_t &frame_config);
     int32_t configureManualCapture(cam_capture_frame_config_t &frame_config);
@@ -1113,7 +1127,7 @@
     cam_sync_related_sensors_event_info_t *m_pRelCamSyncBuf;
     cam_sync_related_sensors_event_info_t m_relCamSyncInfo;
     bool m_bFrameSyncEnabled;
-    cam_is_type_t mIsType;
+    cam_is_type_t mIsTypeVideo;
     cam_is_type_t mIsTypePreview;
 
     bool m_bZslMode;                // if ZSL is enabled
@@ -1148,7 +1162,7 @@
     bool m_bFixedFrameRateSet;      // Indicates that a fixed frame rate is set
     qcamera_thermal_mode m_ThermalMode; // adjust fps vs adjust frameskip
     cam_dimension_t m_LiveSnapshotSize; // live snapshot size
-    cam_dimension_t m_rawSize; // live snapshot size
+    cam_dimension_t m_rawSize; // Raw size
     cam_dimension_t m_maxPicSize;
     bool m_bHDREnabled;             // if HDR is enabled
     bool m_bLocalHDREnabled;   // This flag tells whether HDR enabled or not regarless of APP mode
@@ -1156,6 +1170,7 @@
     bool m_bDISEnabled;
     bool m_bOISEnabled;
     cam_still_more_t m_stillmore_config;
+    bool m_bMetaRawEnabled;
 
     uint8_t m_MobiMask;
     QCameraAdjustFPS *m_AdjustFPS;
@@ -1222,6 +1237,7 @@
     uint8_t mAecFrameBound;
     // Number of preview frames, that HAL will hold without displaying, for instant AEC mode.
     uint8_t mAecSkipDisplayFrameBound;
+    bool m_bQuadraCfa;
 };
 
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCameraParametersIntf.cpp b/msmcobalt/QCamera2/HAL/QCameraParametersIntf.cpp
index 926d5c4..4534b3a 100644
--- a/msmcobalt/QCamera2/HAL/QCameraParametersIntf.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraParametersIntf.cpp
@@ -144,6 +144,15 @@
 
 }
 
+int32_t QCameraParametersIntf::getStreamSubFormat(cam_stream_type_t streamType,
+                                            cam_sub_format_type_t &sub_format)
+{
+    Mutex::Autolock lock(mLock);
+    CHECK_PARAM_INTF(mImpl);
+    return mImpl->getStreamSubFormat(streamType, sub_format);
+}
+
+
 int32_t QCameraParametersIntf::getStreamFormat(cam_stream_type_t streamType,
                                             cam_format_t &format)
 {
@@ -581,11 +590,19 @@
     return mImpl->isDISEnabled();
 }
 
-cam_is_type_t QCameraParametersIntf::getISType()
+int32_t QCameraParametersIntf::setISType()
 {
     Mutex::Autolock lock(mLock);
     CHECK_PARAM_INTF(mImpl);
-    return mImpl->getISType();
+    return mImpl->setISType();
+}
+
+
+cam_is_type_t QCameraParametersIntf::getVideoISType()
+{
+    Mutex::Autolock lock(mLock);
+    CHECK_PARAM_INTF(mImpl);
+    return mImpl->getVideoISType();
 }
 
 cam_is_type_t QCameraParametersIntf::getPreviewISType()
@@ -1025,6 +1042,13 @@
     return mImpl->getofflineRAW();
 }
 
+bool QCameraParametersIntf::getQuadraCfa()
+{
+    Mutex::Autolock lock(mLock);
+    CHECK_PARAM_INTF(mImpl);
+    return mImpl->getQuadraCfa();
+}
+
 int32_t QCameraParametersIntf::updatePpFeatureMask(cam_stream_type_t stream_type)
 {
     Mutex::Autolock lock(mLock);
@@ -1403,5 +1427,11 @@
     CHECK_PARAM_INTF(mImpl);
     return mImpl->getAnalysisInfo(fdVideoEnabled, hal3, featureMask, pAnalysisInfo);
 }
+int32_t QCameraParametersIntf::updateDtVc(int32_t *dt, int32_t *vc)
+{
+    Mutex::Autolock lock(mLock);
+    CHECK_PARAM_INTF(mImpl);
+    return mImpl->updateDtVc(dt, vc);
+}
 
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCameraParametersIntf.h b/msmcobalt/QCamera2/HAL/QCameraParametersIntf.h
index fb09ce8..d8b8fa3 100644
--- a/msmcobalt/QCamera2/HAL/QCameraParametersIntf.h
+++ b/msmcobalt/QCamera2/HAL/QCameraParametersIntf.h
@@ -87,6 +87,11 @@
             cam_dimension_t &dim);
     int32_t getStreamFormat(cam_stream_type_t streamType,
             cam_format_t &format);
+
+    int32_t getStreamSubFormat(
+      cam_stream_type_t streamType, cam_sub_format_type_t &sub_format);
+
+
     int32_t getStreamDimension(cam_stream_type_t streamType,
             cam_dimension_t &dim);
 
@@ -155,7 +160,8 @@
     int32_t stopAEBracket();
     int32_t updateRAW(cam_dimension_t max_dim);
     bool isDISEnabled();
-    cam_is_type_t getISType();
+    int32_t setISType();
+    cam_is_type_t getVideoISType();
     cam_is_type_t getPreviewISType();
     uint8_t getMobicatMask();
 
@@ -228,6 +234,7 @@
     int32_t updateOisValue(bool oisValue);
     int32_t setIntEvent(cam_int_evt_params_t params);
     bool getofflineRAW();
+    bool getQuadraCfa();
     int32_t updatePpFeatureMask(cam_stream_type_t stream_type);
     int32_t getStreamPpMask(cam_stream_type_t stream_type, cam_feature_mask_t &pp_mask);
     int32_t getSharpness();
@@ -298,6 +305,8 @@
         bool hal3,
         cam_feature_mask_t featureMask,
         cam_analysis_info_t *pAnalysisInfo);
+    int32_t updateDtVc(int32_t *dt, int32_t *vc);
+
 private:
     QCameraParameters *mImpl;
     mutable Mutex mLock;
diff --git a/msmcobalt/QCamera2/HAL/QCameraPostProc.cpp b/msmcobalt/QCamera2/HAL/QCameraPostProc.cpp
index 6ba96e9..48ad35a 100644
--- a/msmcobalt/QCamera2/HAL/QCameraPostProc.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraPostProc.cpp
@@ -633,6 +633,13 @@
             (img_fmt_thumb != CAM_FORMAT_YUV_420_NV12_UBWC) &&
             (m_parent->mParameters.useJpegExifRotation() ||
             m_parent->mParameters.getJpegRotation() == 0);
+
+        if (encode_parm.thumb_from_postview &&
+          m_parent->mParameters.useJpegExifRotation()){
+          encode_parm.thumb_rotation =
+            m_parent->mParameters.getJpegExifRotation();
+        }
+
         LOGI("Src THUMB buf_cnt = %d, res = %dX%d len = %d rot = %d "
             "src_dim = %dX%d, dst_dim = %dX%d",
             encode_parm.num_tmb_bufs,
@@ -644,10 +651,6 @@
             encode_parm.thumb_dim.dst_dim.height);
     }
 
-    if (m_parent->mParameters.useJpegExifRotation()){
-        encode_parm.thumb_rotation = m_parent->mParameters.getJpegExifRotation();
-    }
-
     encode_parm.num_dst_bufs = 1;
     if (mUseJpegBurst) {
         encode_parm.num_dst_bufs = MAX_JPEG_BURST;
diff --git a/msmcobalt/QCamera2/HAL/QCameraStream.cpp b/msmcobalt/QCamera2/HAL/QCameraStream.cpp
index 9bb02b8..2dd5f5b 100644
--- a/msmcobalt/QCamera2/HAL/QCameraStream.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraStream.cpp
@@ -1178,13 +1178,27 @@
 {
     int32_t rc = NO_ERROR;
     int index = -1;
+    QCameraVideoMemory *mVideoMem = NULL;
 
     if ((mStreamInfo != NULL)
             && (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH)
             && (mStreamBatchBufs != NULL)) {
         index = mStreamBatchBufs->getMatchBufIndex(opaque, isMetaData);
+        mVideoMem = (QCameraVideoMemory *)mStreamBatchBufs;
     } else if (mStreamBufs != NULL){
         index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
+        mVideoMem = (QCameraVideoMemory *)mStreamBufs;
+    }
+
+    //Close and delete duplicated native handle and FD's.
+    if (mVideoMem != NULL) {
+        rc = mVideoMem->closeNativeHandle(opaque, isMetaData);
+        if (rc != NO_ERROR) {
+            LOGE("Invalid video metadata");
+            return rc;
+        }
+    } else {
+        LOGE("Possible FD leak. Release recording called after stop");
     }
 
     if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3Channel.cpp b/msmcobalt/QCamera2/HAL3/QCamera3Channel.cpp
index f55b65a..3fa72a3 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/msmcobalt/QCamera2/HAL3/QCamera3Channel.cpp
@@ -2916,6 +2916,8 @@
             return BAD_VALUE;
         }
         mFreeHeapBufferList.push_back(bufferIndex);
+        mMemory.markFrameNumber(bufferIndex, -1);
+        //Move heap buffer into free pool and invalidate the frame number
         ppInfo = mOfflinePpInfoList.erase(ppInfo);
 
         // Return pending buffer callbacks
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3HWI.cpp b/msmcobalt/QCamera2/HAL3/QCamera3HWI.cpp
index 9ce8d53..1806e77 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/msmcobalt/QCamera2/HAL3/QCamera3HWI.cpp
@@ -89,7 +89,6 @@
 #define MAX_HFR_BATCH_SIZE     (8)
 #define REGIONS_TUPLE_COUNT    5
 #define HDR_PLUS_PERF_TIME_OUT  (7000) // milliseconds
-#define BURST_REPROCESS_PERF_TIME_OUT  (1000) // milliseconds
 // Set a threshold for detection of missing buffers //seconds
 #define MISSING_REQUEST_BUF_TIMEOUT 3
 #define FLUSH_TIMEOUT 3
@@ -102,6 +101,8 @@
                                               CAM_QCOM_FEATURE_SCALE |\
                                               CAM_QCOM_FEATURE_CAC |\
                                               CAM_QCOM_FEATURE_CDS )
+/* Per configuration size for static metadata length*/
+#define PER_CONFIGURATION_SIZE_3 (3)
 
 #define TIMEOUT_NEVER -1
 
@@ -366,6 +367,8 @@
       mOpMode(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE),
       mFirstFrameNumberInBatch(0),
       mNeedSensorRestart(false),
+      mMinInFlightRequests(MIN_INFLIGHT_REQUESTS),
+      mMaxInFlightRequests(MAX_INFLIGHT_REQUESTS),
       mLdafCalibExist(false),
       mPowerHintEnabled(false),
       mLastCustIntentFrmNum(-1),
@@ -380,7 +383,11 @@
     m_perfLock.lock_init();
     mCommon.init(gCamCapability[cameraId]);
     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
+#ifndef USE_HAL_3_3
+    mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
+#else
     mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_3;
+#endif
     mCameraDevice.common.close = close_camera_device;
     mCameraDevice.ops = &mCameraOps;
     mCameraDevice.priv = this;
@@ -526,6 +533,7 @@
             stream_config_info.buffer_info.min_buffers = MIN_INFLIGHT_REQUESTS;
             stream_config_info.buffer_info.max_buffers =
                     m_bIs4KVideo ? 0 : MAX_INFLIGHT_REQUESTS;
+            clear_metadata_buffer(mParameters);
             ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_STREAM_INFO,
                     stream_config_info);
             int rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
@@ -1416,9 +1424,7 @@
     cam_padding_info_t padding_info = gCamCapability[mCameraId]->padding_info;
 
     /*EIS configuration*/
-    bool eisSupported = false;
     bool oisSupported = false;
-    int32_t margin_index = -1;
     uint8_t eis_prop_set;
     uint32_t maxEisWidth = 0;
     uint32_t maxEisHeight = 0;
@@ -1429,14 +1435,11 @@
     count = MIN(gCamCapability[mCameraId]->supported_is_types_cnt, count);
     for (size_t i = 0; i < count; i++) {
         if ((gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_2_0) ||
-            (gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0))
-        {
-            eisSupported = true;
-            margin_index = (int32_t)i;
+            (gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0)) {
+            m_bEisSupported = true;
             break;
         }
     }
-
     count = CAM_OPT_STAB_MAX;
     count = MIN(gCamCapability[mCameraId]->optical_stab_modes_count, count);
     for (size_t i = 0; i < count; i++) {
@@ -1446,7 +1449,7 @@
         }
     }
 
-    if (eisSupported) {
+    if (m_bEisSupported) {
         maxEisWidth = MAX_EIS_WIDTH;
         maxEisHeight = MAX_EIS_HEIGHT;
     }
@@ -1454,12 +1457,15 @@
     /* EIS setprop control */
     char eis_prop[PROPERTY_VALUE_MAX];
     memset(eis_prop, 0, sizeof(eis_prop));
-    property_get("persist.camera.eis.enable", eis_prop, "0");
+    property_get("persist.camera.eis.enable", eis_prop, "1");
     eis_prop_set = (uint8_t)atoi(eis_prop);
 
-    m_bEisEnable = eis_prop_set && (!oisSupported && eisSupported) &&
+    m_bEisEnable = eis_prop_set && (!oisSupported && m_bEisSupported) &&
             (mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE);
 
+    LOGD("m_bEisEnable: %d, eis_prop_set: %d, m_bEisSupported: %d, oisSupported:%d ",
+            m_bEisEnable, eis_prop_set, m_bEisSupported, oisSupported);
+
     /* stream configurations */
     for (size_t i = 0; i < streamList->num_streams; i++) {
         camera3_stream_t *newStream = streamList->streams[i];
@@ -1783,35 +1789,33 @@
         setPAAFSupport(analysisFeatureMask, CAM_STREAM_TYPE_ANALYSIS,
                 gCamCapability[mCameraId]->color_arrangement);
         cam_analysis_info_t analysisInfo;
-        rc = mCommon.getAnalysisInfo(
+        int32_t ret = NO_ERROR;
+        ret = mCommon.getAnalysisInfo(
                 FALSE,
                 TRUE,
                 analysisFeatureMask,
                 &analysisInfo);
-        if (rc != NO_ERROR) {
-            LOGE("getAnalysisInfo failed, ret = %d", rc);
-        }
-        if (rc == NO_ERROR) {
+        if (ret == NO_ERROR) {
             mAnalysisChannel = new QCamera3SupportChannel(
-                mCameraHandle->camera_handle,
-                mChannelHandle,
-                mCameraHandle->ops,
-                &analysisInfo.analysis_padding_info,
-                analysisFeatureMask,
-                CAM_STREAM_TYPE_ANALYSIS,
-                &analysisInfo.analysis_max_res,
-                (analysisInfo.analysis_format
-                == CAM_FORMAT_Y_ONLY ? CAM_FORMAT_Y_ONLY
-                : CAM_FORMAT_YUV_420_NV21),
-                analysisInfo.hw_analysis_supported,
-                gCamCapability[mCameraId]->color_arrangement,
-                this,
-                0); // force buffer count to 0
-            if (!mAnalysisChannel) {
-                LOGE("H/W Analysis channel cannot be created");
-                pthread_mutex_unlock(&mMutex);
-                return -ENOMEM;
-            }
+                    mCameraHandle->camera_handle,
+                    mChannelHandle,
+                    mCameraHandle->ops,
+                    &analysisInfo.analysis_padding_info,
+                    analysisFeatureMask,
+                    CAM_STREAM_TYPE_ANALYSIS,
+                    &analysisInfo.analysis_max_res,
+                    (analysisInfo.analysis_format
+                    == CAM_FORMAT_Y_ONLY ? CAM_FORMAT_Y_ONLY
+                    : CAM_FORMAT_YUV_420_NV21),
+                    analysisInfo.hw_analysis_supported,
+                    gCamCapability[mCameraId]->color_arrangement,
+                    this,
+                    0); // force buffer count to 0
+        } else {
+            LOGW("getAnalysisInfo failed, ret = %d", ret);
+        }
+        if (!mAnalysisChannel) {
+            LOGW("Analysis channel cannot be created");
         }
     }
 
@@ -2199,11 +2203,16 @@
         setPAAFSupport(callbackFeatureMask,
                 CAM_STREAM_TYPE_CALLBACK,
                 gCamCapability[mCameraId]->color_arrangement);
-        rc = mCommon.getAnalysisInfo(FALSE, TRUE, callbackFeatureMask, &supportInfo);
-        if (rc != NO_ERROR) {
-            LOGE("getAnalysisInfo failed, ret = %d", rc);
-            pthread_mutex_unlock(&mMutex);
-            return rc;
+        int32_t ret = NO_ERROR;
+        ret = mCommon.getAnalysisInfo(FALSE, TRUE, callbackFeatureMask, &supportInfo);
+        if (ret != NO_ERROR) {
+            /* Ignore the error for Mono camera
+             * because the PAAF bit mask is only set
+             * for CAM_STREAM_TYPE_ANALYSIS stream type
+             */
+            if (gCamCapability[mCameraId]->color_arrangement != CAM_FILTER_ARRANGEMENT_Y) {
+                LOGW("getAnalysisInfo failed, ret = %d", ret);
+            }
         }
         mSupportChannel = new QCamera3SupportChannel(
                 mCameraHandle->camera_handle,
@@ -2757,9 +2766,9 @@
             if (last_frame_capture_time) {
                 //Infer timestamp
                 first_frame_capture_time = last_frame_capture_time -
-                        (((loopCount - 1) * NSEC_PER_SEC) / mHFRVideoFps);
+                        (((loopCount - 1) * NSEC_PER_SEC) / (double) mHFRVideoFps);
                 capture_time =
-                        first_frame_capture_time + (i * NSEC_PER_SEC / mHFRVideoFps);
+                        first_frame_capture_time + (i * NSEC_PER_SEC / (double) mHFRVideoFps);
                 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
                         CAM_INTF_META_SENSOR_TIMESTAMP, capture_time);
                 LOGD("batch capture_time: %lld, capture_time: %lld",
@@ -2768,7 +2777,8 @@
         }
         pthread_mutex_lock(&mMutex);
         handleMetadataWithLock(metadata_buf,
-                false /* free_and_bufdone_meta_buf */);
+                false /* free_and_bufdone_meta_buf */,
+                (i == 0) /* first metadata in the batch metadata */);
         pthread_mutex_unlock(&mMutex);
     }
 
@@ -2779,6 +2789,19 @@
     }
 }
 
+void QCamera3HardwareInterface::notifyError(uint32_t frameNumber,
+        camera3_error_msg_code_t errorCode)
+{
+    camera3_notify_msg_t notify_msg;
+    memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
+    notify_msg.type = CAMERA3_MSG_ERROR;
+    notify_msg.message.error.error_code = errorCode;
+    notify_msg.message.error.error_stream = NULL;
+    notify_msg.message.error.frame_number = frameNumber;
+    mCallbackOps->notify(mCallbackOps, &notify_msg);
+
+    return;
+}
 /*===========================================================================
  * FUNCTION   : handleMetadataWithLock
  *
@@ -2787,12 +2810,15 @@
  * PARAMETERS : @metadata_buf: metadata buffer
  *              @free_and_bufdone_meta_buf: Buf done on the meta buf and free
  *                 the meta buf in this method
+ *              @firstMetadataInBatch: Boolean to indicate whether this is the
+ *                  first metadata in a batch. Valid only for batch mode
  *
  * RETURN     :
  *
  *==========================================================================*/
 void QCamera3HardwareInterface::handleMetadataWithLock(
-    mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf)
+    mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf,
+    bool firstMetadataInBatch)
 {
     ATRACE_CALL();
     if ((mFlushPerf) || (ERROR == mState) || (DEINIT == mState)) {
@@ -2922,39 +2948,33 @@
 
         // Check whether any stream buffer corresponding to this is dropped or not
         // If dropped, then send the ERROR_BUFFER for the corresponding stream
-        // The API does not expect a blob buffer to be dropped
         if (p_cam_frame_drop) {
             /* Clear notify_msg structure */
             camera3_notify_msg_t notify_msg;
             memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
             for (List<RequestedBufferInfo>::iterator j = i->buffers.begin();
                     j != i->buffers.end(); j++) {
-               if (j->stream->format != HAL_PIXEL_FORMAT_BLOB) {
-                   QCamera3ProcessingChannel *channel = (QCamera3ProcessingChannel *)j->stream->priv;
-                   uint32_t streamID = channel->getStreamID(channel->getStreamTypeMask());
-                   for (uint32_t k = 0; k < p_cam_frame_drop->num_streams; k++) {
-                       if (streamID == p_cam_frame_drop->streamID[k]) {
-                           // Send Error notify to frameworks with CAMERA3_MSG_ERROR_BUFFER
-                           LOGE("Start of reporting error frame#=%u, streamID=%u",
-                                    i->frame_number, streamID);
-                           notify_msg.type = CAMERA3_MSG_ERROR;
-                           notify_msg.message.error.frame_number = i->frame_number;
-                           notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER ;
-                           notify_msg.message.error.error_stream = j->stream;
-                           mCallbackOps->notify(mCallbackOps, &notify_msg);
-                           LOGE("End of reporting error frame#=%u, streamID=%u",
-                                   i->frame_number, streamID);
-                           PendingFrameDropInfo PendingFrameDrop;
-                           PendingFrameDrop.frame_number=i->frame_number;
-                           PendingFrameDrop.stream_ID = streamID;
-                           // Add the Frame drop info to mPendingFrameDropList
-                           mPendingFrameDropList.push_back(PendingFrameDrop);
-                      }
+                QCamera3ProcessingChannel *channel = (QCamera3ProcessingChannel *)j->stream->priv;
+                uint32_t streamID = channel->getStreamID(channel->getStreamTypeMask());
+                for (uint32_t k = 0; k < p_cam_frame_drop->num_streams; k++) {
+                    if (streamID == p_cam_frame_drop->streamID[k]) {
+                        // Send Error notify to frameworks with CAMERA3_MSG_ERROR_BUFFER
+                        LOGE("Start of reporting error frame#=%u, streamID=%u",
+                                 i->frame_number, streamID);
+                        notify_msg.type = CAMERA3_MSG_ERROR;
+                        notify_msg.message.error.frame_number = i->frame_number;
+                        notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER ;
+                        notify_msg.message.error.error_stream = j->stream;
+                        mCallbackOps->notify(mCallbackOps, &notify_msg);
+                        LOGE("End of reporting error frame#=%u, streamID=%u",
+                                i->frame_number, streamID);
+                        PendingFrameDropInfo PendingFrameDrop;
+                        PendingFrameDrop.frame_number=i->frame_number;
+                        PendingFrameDrop.stream_ID = streamID;
+                        // Add the Frame drop info to mPendingFrameDropList
+                        mPendingFrameDropList.push_back(PendingFrameDrop);
                    }
-               } else {
-                   LOGE("JPEG buffer dropped for frame number %d",
-                            i->frame_number);
-               }
+                }
             }
         }
 
@@ -2968,6 +2988,15 @@
                 /* this will be handled in handleInputBufferWithLock */
                 i++;
                 continue;
+            } else if (mBatchSize) {
+
+                mPendingLiveRequest--;
+
+                CameraMetadata dummyMetadata;
+                dummyMetadata.update(ANDROID_REQUEST_ID, &(i->request_id), 1);
+                result.result = dummyMetadata.release();
+
+                notifyError(i->frame_number, CAMERA3_MSG_ERROR_RESULT);
             } else {
                 LOGE("Fatal: Missing metadata buffer for frame number %d", i->frame_number);
                 if (free_and_bufdone_meta_buf) {
@@ -3009,7 +3038,8 @@
 
             result.result = translateFromHalMetadata(metadata,
                     i->timestamp, i->request_id, i->jpegMetadata, i->pipeline_depth,
-                    i->capture_intent, internalPproc, i->fwkCacMode);
+                    i->capture_intent, internalPproc, i->fwkCacMode,
+                    firstMetadataInBatch);
 
             saveExifParams(metadata);
 
@@ -3409,8 +3439,6 @@
     int rc = NO_ERROR;
     int32_t request_id;
     CameraMetadata meta;
-    uint32_t minInFlightRequests = MIN_INFLIGHT_REQUESTS;
-    uint32_t maxInFlightRequests = MAX_INFLIGHT_REQUESTS;
     bool isVidBufRequested = false;
     camera3_stream_buffer_t *pInputBuffer = NULL;
 
@@ -3471,10 +3499,14 @@
         }
         m_perfLock.lock_acq();
         /* get eis information for stream configuration */
-        cam_is_type_t is_type;
+        cam_is_type_t isTypeVideo, isTypePreview, is_type=IS_TYPE_NONE;
         char is_type_value[PROPERTY_VALUE_MAX];
-        property_get("persist.camera.is_type", is_type_value, "0");
-        is_type = static_cast<cam_is_type_t>(atoi(is_type_value));
+        property_get("persist.camera.is_type", is_type_value, "4");
+        isTypeVideo = static_cast<cam_is_type_t>(atoi(is_type_value));
+        // Make default value for preview IS_TYPE as IS_TYPE_EIS_2_0
+        property_get("persist.camera.is_type_preview", is_type_value, "4");
+        isTypePreview = static_cast<cam_is_type_t>(atoi(is_type_value));
+        LOGD("isTypeVideo: %d isTypePreview: %d", isTypeVideo, isTypePreview);
 
         if (meta.exists(ANDROID_CONTROL_CAPTURE_INTENT)) {
             int32_t hal_version = CAM_HAL_V3;
@@ -3486,32 +3518,49 @@
             ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_CAPTURE_INTENT, captureIntent);
         }
 
-        //If EIS is enabled, turn it on for video
-        bool setEis = m_bEisEnable && m_bEisSupportedSize;
+        uint8_t fwkVideoStabMode=0;
+        if (meta.exists(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE)) {
+            fwkVideoStabMode = meta.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE).data.u8[0];
+        }
+
+        // If EIS setprop is enabled & if first capture setting has EIS enabled then only
+        // turn it on for video/preview
+        bool setEis = m_bEisEnable && fwkVideoStabMode && m_bEisSupportedSize &&
+                (isTypeVideo >= IS_TYPE_EIS_2_0);
         int32_t vsMode;
         vsMode = (setEis)? DIS_ENABLE: DIS_DISABLE;
         if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_DIS_ENABLE, vsMode)) {
             rc = BAD_VALUE;
         }
+        LOGD("setEis %d", setEis);
+        bool eis3Supported = false;
+        size_t count = IS_TYPE_MAX;
+        count = MIN(gCamCapability[mCameraId]->supported_is_types_cnt, count);
+        for (size_t i = 0; i < count; i++) {
+            if (gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0) {
+                eis3Supported = true;
+                break;
+            }
+        }
 
         //IS type will be 0 unless EIS is supported. If EIS is supported
-        //it could either be 1 or 4 depending on the stream and video size
+        //it could either be 4 or 5 depending on the stream and video size
         for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
             if (setEis) {
-                if (!m_bEisSupportedSize) {
-                    is_type = IS_TYPE_DIS;
-                    } else {
-                    if (mStreamConfigInfo.type[i] == CAM_STREAM_TYPE_PREVIEW) {
+                if (mStreamConfigInfo.type[i] == CAM_STREAM_TYPE_PREVIEW) {
+                    is_type = isTypePreview;
+                } else if (mStreamConfigInfo.type[i] == CAM_STREAM_TYPE_VIDEO ) {
+                    if ( (isTypeVideo == IS_TYPE_EIS_3_0) && (eis3Supported == FALSE) ) {
+                        LOGW(" EIS_3.0 is not supported and so setting EIS_2.0");
                         is_type = IS_TYPE_EIS_2_0;
-                    }else if (mStreamConfigInfo.type[i] == CAM_STREAM_TYPE_VIDEO) {
-                        is_type = IS_TYPE_EIS_3_0;
-                    }else {
-                        is_type = IS_TYPE_NONE;
+                    } else {
+                        is_type = isTypeVideo;
                     }
-                 }
+                } else {
+                    is_type = IS_TYPE_NONE;
+                }
                  mStreamConfigInfo.is_type[i] = is_type;
-            }
-            else {
+            } else {
                  mStreamConfigInfo.is_type[i] = IS_TYPE_NONE;
             }
         }
@@ -3533,14 +3582,45 @@
                 LOGE("Failed to disable CDS for HFR mode");
 
         }
+
+        if (m_debug_avtimer || meta.exists(QCAMERA3_USE_AV_TIMER)) {
+            uint8_t* use_av_timer = NULL;
+
+            if (m_debug_avtimer){
+                use_av_timer = &m_debug_avtimer;
+            }
+            else{
+                use_av_timer =
+                    meta.find(QCAMERA3_USE_AV_TIMER).data.u8;
+            }
+
+            if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_USE_AV_TIMER, *use_av_timer)) {
+                rc = BAD_VALUE;
+            }
+        }
+
         setMobicat();
 
         /* Set fps and hfr mode while sending meta stream info so that sensor
          * can configure appropriate streaming mode */
         mHFRVideoFps = DEFAULT_VIDEO_FPS;
+        mMinInFlightRequests = MIN_INFLIGHT_REQUESTS;
+        mMaxInFlightRequests = MAX_INFLIGHT_REQUESTS;
         if (meta.exists(ANDROID_CONTROL_AE_TARGET_FPS_RANGE)) {
             rc = setHalFpsRange(meta, mParameters);
-            if (rc != NO_ERROR) {
+            if (rc == NO_ERROR) {
+                int32_t max_fps =
+                    (int32_t) meta.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE).data.i32[1];
+                if (max_fps == 60) {
+                    mMinInFlightRequests = MIN_INFLIGHT_60FPS_REQUESTS;
+                }
+                /* For HFR, more buffers are dequeued upfront to improve the performance */
+                if (mBatchSize) {
+                    mMinInFlightRequests = MIN_INFLIGHT_HFR_REQUESTS;
+                    mMaxInFlightRequests = MAX_INFLIGHT_HFR_REQUESTS;
+                }
+            }
+            else {
                 LOGE("setHalFpsRange failed");
             }
         }
@@ -3552,6 +3632,7 @@
             }
         }
 
+
         //TODO: validate the arguments, HSV scenemode should have only the
         //advertised fps ranges
 
@@ -3560,13 +3641,15 @@
         LOGD("set_parms META_STREAM_INFO " );
         for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
             LOGI("STREAM INFO : type %d, wxh: %d x %d, pp_mask: 0x%x "
-                    "Format:%d",
+                    "Format:%d is_type: %d",
                     mStreamConfigInfo.type[i],
                     mStreamConfigInfo.stream_sizes[i].width,
                     mStreamConfigInfo.stream_sizes[i].height,
                     mStreamConfigInfo.postprocess_mask[i],
-                    mStreamConfigInfo.format[i]);
+                    mStreamConfigInfo.format[i],
+                    mStreamConfigInfo.is_type[i]);
         }
+
         rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
                     mParameters);
         if (rc < 0) {
@@ -3611,9 +3694,15 @@
             QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
             if ((((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask()) ||
                ((1U << CAM_STREAM_TYPE_PREVIEW) == channel->getStreamTypeMask())) &&
-               setEis)
+               setEis) {
+                for (size_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
+                    if ( (1U << mStreamConfigInfo.type[i]) == channel->getStreamTypeMask() ) {
+                        is_type = mStreamConfigInfo.is_type[i];
+                        break;
+                    }
+                }
                 rc = channel->initialize(is_type);
-            else {
+            } else {
                 rc = channel->initialize(IS_TYPE_NONE);
             }
             if (NO_ERROR != rc) {
@@ -3654,7 +3743,7 @@
                 pthread_mutex_unlock(&mMutex);
                 goto error_exit;
             }
-            rc = mDummyBatchChannel->initialize(is_type);
+            rc = mDummyBatchChannel->initialize(IS_TYPE_NONE);
             if (rc < 0) {
                 LOGE("mDummyBatchChannel initialization failed");
                 pthread_mutex_unlock(&mMutex);
@@ -3687,6 +3776,7 @@
                 (mLinkedCameraId != mCameraId) ) {
                 LOGE("Dualcam: mLinkedCameraId %d is invalid, current cam id = %d",
                     mLinkedCameraId, mCameraId);
+                pthread_mutex_unlock(&mMutex);
                 goto error_exit;
             }
         }
@@ -3704,6 +3794,7 @@
             if (sessionId[mLinkedCameraId] == 0xDEADBEEF) {
                 LOGE("Dualcam: Invalid Session Id ");
                 pthread_mutex_unlock(&gCamLock);
+                pthread_mutex_unlock(&mMutex);
                 goto error_exit;
             }
 
@@ -3723,6 +3814,7 @@
                     mCameraHandle->camera_handle, m_pRelCamSyncBuf);
             if (rc < 0) {
                 LOGE("Dualcam: link failed");
+                pthread_mutex_unlock(&mMutex);
                 goto error_exit;
             }
         }
@@ -3923,6 +4015,7 @@
             if(ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
                 CAM_INTF_META_FRAME_NUMBER, request->frame_number)) {
                 LOGE("Failed to set the frame number in the parameters");
+                pthread_mutex_unlock(&mMutex);
                 return BAD_VALUE;
             }
         }
@@ -4086,17 +4179,6 @@
             }
         } else if (output.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
             bool needMetadata = false;
-
-            if (m_perfLock.isPerfLockTimedAcquired()) {
-                if (m_perfLock.isTimerReset())
-                {
-                    m_perfLock.lock_rel_timed();
-                    m_perfLock.lock_acq_timed(BURST_REPROCESS_PERF_TIME_OUT);
-                }
-            } else {
-                m_perfLock.lock_acq_timed(BURST_REPROCESS_PERF_TIME_OUT);
-            }
-
             QCamera3YUVChannel *yuvChannel = (QCamera3YUVChannel *)channel;
             rc = yuvChannel->request(output.buffer, frameNumber,
                     pInputBuffer,
@@ -4114,19 +4196,6 @@
         } else {
             LOGD("request with buffer %p, frame_number %d",
                   output.buffer, frameNumber);
-            /* Set perf lock for API-2 zsl */
-            if (IS_USAGE_ZSL(output.stream->usage)) {
-                if (m_perfLock.isPerfLockTimedAcquired()) {
-                    if (m_perfLock.isTimerReset())
-                    {
-                        m_perfLock.lock_rel_timed();
-                        m_perfLock.lock_acq_timed(BURST_REPROCESS_PERF_TIME_OUT);
-                    }
-                } else {
-                    m_perfLock.lock_acq_timed(BURST_REPROCESS_PERF_TIME_OUT);
-                }
-            }
-
             rc = channel->request(output.buffer, frameNumber);
             if (((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask())
                     && mBatchSize) {
@@ -4193,15 +4262,7 @@
       ts.tv_sec += 5;
     }
     //Block on conditional variable
-    if (mBatchSize) {
-        /* For HFR, more buffers are dequeued upfront to improve the performance */
-        minInFlightRequests = MIN_INFLIGHT_HFR_REQUESTS;
-        maxInFlightRequests = MAX_INFLIGHT_HFR_REQUESTS;
-    }
-    if (m_perfLock.isPerfLockTimedAcquired() && m_perfLock.isTimerReset())
-        m_perfLock.lock_rel_timed();
-
-    while ((mPendingLiveRequest >= minInFlightRequests) && !pInputBuffer &&
+    while ((mPendingLiveRequest >= mMinInFlightRequests) && !pInputBuffer &&
             (mState != ERROR) && (mState != DEINIT)) {
         if (!isValidTimeout) {
             LOGD("Blocking on conditional wait");
@@ -4219,7 +4280,7 @@
         LOGD("Unblocked");
         if (mWokenUpByDaemon) {
             mWokenUpByDaemon = false;
-            if (mPendingLiveRequest < maxInFlightRequests)
+            if (mPendingLiveRequest < mMaxInFlightRequests)
                 break;
         }
     }
@@ -4575,7 +4636,8 @@
             hdrPlusPerfLock(metadata_buf);
             pthread_mutex_lock(&mMutex);
             handleMetadataWithLock(metadata_buf,
-                    true /* free_and_bufdone_meta_buf */);
+                    true /* free_and_bufdone_meta_buf */,
+                    false /* first frame of batch metadata */ );
             pthread_mutex_unlock(&mMutex);
         }
     } else if (isInputBuffer) {
@@ -4745,11 +4807,19 @@
                                  uint8_t pipeline_depth,
                                  uint8_t capture_intent,
                                  bool pprocDone,
-                                 uint8_t fwk_cacMode)
+                                 uint8_t fwk_cacMode,
+                                 bool firstMetadataInBatch)
 {
     CameraMetadata camMetadata;
     camera_metadata_t *resultMetadata;
 
+    if (mBatchSize && !firstMetadataInBatch) {
+        /* In batch mode, use cached metadata from the first metadata
+            in the batch */
+        camMetadata.clear();
+        camMetadata = mCachedMetadata;
+    }
+
     if (jpegMetadata.entryCount())
         camMetadata.append(jpegMetadata);
 
@@ -4758,6 +4828,12 @@
     camMetadata.update(ANDROID_REQUEST_PIPELINE_DEPTH, &pipeline_depth, 1);
     camMetadata.update(ANDROID_CONTROL_CAPTURE_INTENT, &capture_intent, 1);
 
+    if (mBatchSize && !firstMetadataInBatch) {
+        /* In batch mode, use cached metadata instead of parsing metadata buffer again */
+        resultMetadata = camMetadata.release();
+        return resultMetadata;
+    }
+
     IF_META_AVAILABLE(uint32_t, frame_number, CAM_INTF_META_FRAME_NUMBER, metadata) {
         int64_t fwk_frame_number = *frame_number;
         camMetadata.update(ANDROID_SYNC_FRAME_NUMBER, &fwk_frame_number, 1);
@@ -4867,7 +4943,7 @@
         // and so hardcoding the Video Stab result to OFF mode.
         uint8_t fwkVideoStabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
         camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &fwkVideoStabMode, 1);
-        LOGD("%s: EIS result default to OFF mode", __func__);
+        LOGD("EIS result default to OFF mode");
     }
 
     IF_META_AVAILABLE(uint32_t, noiseRedMode, CAM_INTF_META_NOISE_REDUCTION_MODE, metadata) {
@@ -4904,19 +4980,24 @@
           blackLevelAppliedPattern->cam_black_level[2],
           blackLevelAppliedPattern->cam_black_level[3]);
         camMetadata.update(QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN, fwk_blackLevelInd, 4);
-        camMetadata.update(NEXUS_EXPERIMENTAL_2015_SENSOR_DYNAMIC_BLACK_LEVEL, fwk_blackLevelInd, 4);
+
+#ifndef USE_HAL_3_3
+        // Update the ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL
+        // Need convert the internal 16 bit depth to sensor 10 bit sensor raw
+        // depth space.
+        fwk_blackLevelInd[0] /= 64.0;
+        fwk_blackLevelInd[1] /= 64.0;
+        fwk_blackLevelInd[2] /= 64.0;
+        fwk_blackLevelInd[3] /= 64.0;
+        camMetadata.update(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL, fwk_blackLevelInd, 4);
+#endif
     }
 
-
-    if (gCamCapability[mCameraId]->optical_black_region_count != 0 &&
-        gCamCapability[mCameraId]->optical_black_region_count <= MAX_OPTICAL_BLACK_REGIONS) {
-        int32_t opticalBlackRegions[MAX_OPTICAL_BLACK_REGIONS * 4];
-        for (size_t i = 0; i < gCamCapability[mCameraId]->optical_black_region_count * 4; i++) {
-            opticalBlackRegions[i] = gCamCapability[mCameraId]->optical_black_regions[i];
-        }
-        camMetadata.update(NEXUS_EXPERIMENTAL_2015_SENSOR_INFO_OPTICALLY_SHIELDED_REGIONS,
-                opticalBlackRegions, gCamCapability[mCameraId]->optical_black_region_count * 4);
-    }
+#ifndef USE_HAL_3_3
+    // Fixed whitelevel is used by ISP/Sensor
+    camMetadata.update(ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL,
+            &gCamCapability[mCameraId]->white_level, 1);
+#endif
 
     IF_META_AVAILABLE(cam_crop_region_t, hScalerCropRegion,
             CAM_INTF_META_SCALER_CROP_REGION, metadata) {
@@ -4970,6 +5051,13 @@
                 (size_t) (2 * gCamCapability[mCameraId]->num_color_channels));
     }
 
+#ifndef USE_HAL_3_3
+    IF_META_AVAILABLE(int32_t, ispSensitivity, CAM_INTF_META_ISP_SENSITIVITY, metadata) {
+        int32_t fwk_ispSensitivity = (int32_t) *ispSensitivity;
+        camMetadata.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &fwk_ispSensitivity, 1);
+    }
+#endif
+
     IF_META_AVAILABLE(uint32_t, shadingMode, CAM_INTF_META_SHADING_MODE, metadata) {
         uint8_t fwk_shadingMode = (uint8_t) *shadingMode;
         camMetadata.update(ANDROID_SHADING_MODE, &fwk_shadingMode, 1);
@@ -5052,6 +5140,55 @@
     IF_META_AVAILABLE(uint32_t, histogramMode, CAM_INTF_META_STATS_HISTOGRAM_MODE, metadata) {
         uint8_t fwk_histogramMode = (uint8_t) *histogramMode;
         camMetadata.update(ANDROID_STATISTICS_HISTOGRAM_MODE, &fwk_histogramMode, 1);
+
+        if (fwk_histogramMode == ANDROID_STATISTICS_HISTOGRAM_MODE_ON) {
+            IF_META_AVAILABLE(cam_hist_stats_t, stats_data, CAM_INTF_META_HISTOGRAM, metadata) {
+                // process histogram statistics info
+                uint32_t hist_buf[3][CAM_HISTOGRAM_STATS_SIZE];
+                uint32_t hist_size = sizeof(cam_histogram_data_t::hist_buf);
+                cam_histogram_data_t rHistData, gHistData, bHistData;
+                memset(&rHistData, 0, sizeof(rHistData));
+                memset(&gHistData, 0, sizeof(gHistData));
+                memset(&bHistData, 0, sizeof(bHistData));
+
+                switch (stats_data->type) {
+                case CAM_HISTOGRAM_TYPE_BAYER:
+                    switch (stats_data->bayer_stats.data_type) {
+                        case CAM_STATS_CHANNEL_GR:
+                            rHistData = gHistData = bHistData = stats_data->bayer_stats.gr_stats;
+                            break;
+                        case CAM_STATS_CHANNEL_GB:
+                            rHistData = gHistData = bHistData = stats_data->bayer_stats.gb_stats;
+                            break;
+                        case CAM_STATS_CHANNEL_B:
+                            rHistData = gHistData = bHistData = stats_data->bayer_stats.b_stats;
+                            break;
+                        case CAM_STATS_CHANNEL_ALL:
+                            rHistData = stats_data->bayer_stats.r_stats;
+                            //Framework expects only 3 channels. So, for now,
+                            //use gb stats for G channel.
+                            gHistData = stats_data->bayer_stats.gb_stats;
+                            bHistData = stats_data->bayer_stats.b_stats;
+                            break;
+                        case CAM_STATS_CHANNEL_Y:
+                        case CAM_STATS_CHANNEL_R:
+                        default:
+                            rHistData = gHistData = bHistData = stats_data->bayer_stats.r_stats;
+                            break;
+                    }
+                    break;
+                case CAM_HISTOGRAM_TYPE_YUV:
+                    rHistData = gHistData = bHistData = stats_data->yuv_stats;
+                    break;
+                }
+
+                memcpy(hist_buf, rHistData.hist_buf, hist_size);
+                memcpy(hist_buf[1], gHistData.hist_buf, hist_size);
+                memcpy(hist_buf[2], bHistData.hist_buf, hist_size);
+
+                camMetadata.update(ANDROID_STATISTICS_HISTOGRAM, (int32_t*)hist_buf, hist_size*3);
+            }
+        }
     }
 
     IF_META_AVAILABLE(uint32_t, sharpnessMapMode,
@@ -5581,6 +5718,12 @@
     camMetadata.update(QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB,
             (uint8_t *)&ddm_info, sizeof(cam_ddm_info_t));
 
+    /* In batch mode, cache the first metadata in the batch */
+    if (mBatchSize && firstMetadataInBatch) {
+        mCachedMetadata.clear();
+        mCachedMetadata = camMetadata;
+    }
+
     resultMetadata = camMetadata.release();
     return resultMetadata;
 }
@@ -6002,7 +6145,7 @@
         if (frame_settings.exists(ANDROID_JPEG_ORIENTATION)) {
             int32_t orientation =
                   frame_settings.find(ANDROID_JPEG_ORIENTATION).data.i32[0];
-            if ((orientation == 90) || (orientation == 270)) {
+            if ((!needJpegExifRotation()) && ((orientation == 90) || (orientation == 270))) {
                //swap thumbnail dimensions for rotations 90 and 270 in jpeg metadata.
                int32_t temp;
                temp = thumbnail_size[0];
@@ -6512,7 +6655,12 @@
 
     uint8_t supportedHwLvl = limitedDevice ?
             ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED :
+#ifndef USE_HAL_3_3
+            // LEVEL_3 - This device will support level 3.
+            ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3;
+#else
             ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
+#endif
 
     staticInfo.update(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
             &supportedHwLvl, 1);
@@ -6590,6 +6738,23 @@
     staticInfo.update(ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
             gCamCapability[cameraId]->black_level_pattern, BLACK_LEVEL_PATTERN_CNT);
 
+#ifndef USE_HAL_3_3
+    bool hasBlackRegions = false;
+    if (gCamCapability[cameraId]->optical_black_region_count > MAX_OPTICAL_BLACK_REGIONS) {
+        LOGW("black_region_count: %d is bounded to %d",
+            gCamCapability[cameraId]->optical_black_region_count, MAX_OPTICAL_BLACK_REGIONS);
+        gCamCapability[cameraId]->optical_black_region_count = MAX_OPTICAL_BLACK_REGIONS;
+    }
+    if (gCamCapability[cameraId]->optical_black_region_count != 0) {
+        int32_t opticalBlackRegions[MAX_OPTICAL_BLACK_REGIONS * 4];
+        for (size_t i = 0; i < gCamCapability[cameraId]->optical_black_region_count * 4; i++) {
+            opticalBlackRegions[i] = gCamCapability[cameraId]->optical_black_regions[i];
+        }
+        staticInfo.update(ANDROID_SENSOR_OPTICAL_BLACK_REGIONS,
+                opticalBlackRegions, gCamCapability[cameraId]->optical_black_region_count * 4);
+        hasBlackRegions = true;
+    }
+#endif
     staticInfo.update(ANDROID_FLASH_INFO_CHARGE_DURATION,
             &gCamCapability[cameraId]->flash_charge_duration, 1);
 
@@ -6658,10 +6823,20 @@
     Vector<uint8_t> availableVstabModes;
     availableVstabModes.add(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF);
     char eis_prop[PROPERTY_VALUE_MAX];
+    bool eisSupported = false;
     memset(eis_prop, 0, sizeof(eis_prop));
-    property_get("persist.camera.eis.enable", eis_prop, "0");
+    property_get("persist.camera.eis.enable", eis_prop, "1");
     uint8_t eis_prop_set = (uint8_t)atoi(eis_prop);
-    if (facingBack && eis_prop_set) {
+    count = IS_TYPE_MAX;
+    count = MIN(gCamCapability[cameraId]->supported_is_types_cnt, count);
+    for (size_t i = 0; i < count; i++) {
+        if ((gCamCapability[cameraId]->supported_is_types[i] == IS_TYPE_EIS_2_0) ||
+            (gCamCapability[cameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0)) {
+            eisSupported = true;
+            break;
+        }
+    }
+    if (facingBack && eis_prop_set && eisSupported) {
         availableVstabModes.add(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON);
     }
     staticInfo.update(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
@@ -7183,6 +7358,17 @@
                       &max_latency,
                       1);
 
+#ifndef USE_HAL_3_3
+    int32_t isp_sensitivity_range[2];
+    isp_sensitivity_range[0] =
+        gCamCapability[cameraId]->isp_sensitivity_range.min_sensitivity;
+    isp_sensitivity_range[1] =
+        gCamCapability[cameraId]->isp_sensitivity_range.max_sensitivity;
+    staticInfo.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
+                      isp_sensitivity_range,
+                      sizeof(isp_sensitivity_range) / sizeof(isp_sensitivity_range[0]));
+#endif
+
     uint8_t available_hot_pixel_modes[] = {ANDROID_HOT_PIXEL_MODE_FAST,
                                            ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY};
     staticInfo.update(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
@@ -7293,6 +7479,9 @@
        ANDROID_SENSOR_FRAME_DURATION, ANDROID_HOT_PIXEL_MODE,
        ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
        ANDROID_SENSOR_SENSITIVITY, ANDROID_SHADING_MODE,
+#ifndef USE_HAL_3_3
+       ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
+#endif
        ANDROID_STATISTICS_FACE_DETECT_MODE,
        ANDROID_STATISTICS_HISTOGRAM_MODE, ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
        ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, ANDROID_TONEMAP_CURVE_BLUE,
@@ -7331,7 +7520,12 @@
        ANDROID_STATISTICS_SHARPNESS_MAP, ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
        ANDROID_STATISTICS_PREDICTED_COLOR_GAINS, ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM,
        ANDROID_STATISTICS_SCENE_FLICKER, ANDROID_STATISTICS_FACE_RECTANGLES,
-       ANDROID_STATISTICS_FACE_SCORES};
+       ANDROID_STATISTICS_FACE_SCORES,
+#ifndef USE_HAL_3_3
+       ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
+#endif
+       };
+
     size_t result_keys_cnt =
             sizeof(result_keys_basic)/sizeof(result_keys_basic[0]);
 
@@ -7352,10 +7546,16 @@
         available_result_keys.add(ANDROID_STATISTICS_FACE_IDS);
         available_result_keys.add(ANDROID_STATISTICS_FACE_LANDMARKS);
     }
+#ifndef USE_HAL_3_3
+    if (hasBlackRegions) {
+        available_result_keys.add(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
+        available_result_keys.add(ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL);
+    }
+#endif
     staticInfo.update(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
             available_result_keys.array(), available_result_keys.size());
 
-    int32_t available_characteristics_keys[] = {ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+    int32_t characteristics_keys_basic[] = {ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
        ANDROID_CONTROL_AE_AVAILABLE_MODES, ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
        ANDROID_CONTROL_AE_COMPENSATION_RANGE, ANDROID_CONTROL_AE_COMPENSATION_STEP,
        ANDROID_CONTROL_AF_AVAILABLE_MODES, ANDROID_CONTROL_AVAILABLE_EFFECTS,
@@ -7409,10 +7609,24 @@
        ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
        ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
        ANDROID_SHADING_AVAILABLE_MODES,
-       ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL };
+       ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
+#ifndef USE_HAL_3_3
+       ANDROID_SENSOR_OPAQUE_RAW_SIZE,
+       ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
+#endif
+       };
+
+    Vector<int32_t> available_characteristics_keys;
+    available_characteristics_keys.appendArray(characteristics_keys_basic,
+            sizeof(characteristics_keys_basic)/sizeof(int32_t));
+#ifndef USE_HAL_3_3
+    if (hasBlackRegions) {
+        available_characteristics_keys.add(ANDROID_SENSOR_OPTICAL_BLACK_REGIONS);
+    }
+#endif
     staticInfo.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
-                      available_characteristics_keys,
-                      sizeof(available_characteristics_keys)/sizeof(int32_t));
+                      available_characteristics_keys.array(),
+                      available_characteristics_keys.size());
 
     /*available stall durations depend on the hw + sw and will be different for different devices */
     /*have to add for raw after implementation*/
@@ -7494,6 +7708,35 @@
     staticInfo.update(QCAMERA3_SENSOR_IS_MONO_ONLY,
             &isMonoOnly, 1);
 
+#ifndef USE_HAL_3_3
+    Vector<int32_t> opaque_size;
+    for (size_t j = 0; j < scalar_formats_count; j++) {
+        if (scalar_formats[j] == ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE) {
+            for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
+                    gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
+                cam_stream_buf_plane_info_t buf_planes;
+
+                rc = mm_stream_calc_offset_raw(fmt, &gCamCapability[cameraId]->raw_dim[i],
+                         &gCamCapability[cameraId]->padding_info, &buf_planes);
+
+                if (rc == 0) {
+                    opaque_size.add(gCamCapability[cameraId]->raw_dim[i].width);
+                    opaque_size.add(gCamCapability[cameraId]->raw_dim[i].height);
+                    opaque_size.add(buf_planes.plane_info.frame_len);
+                }else {
+                    LOGE("raw frame calculation failed!");
+                }
+            }
+        }
+    }
+
+    if ((opaque_size.size() > 0) &&
+            (opaque_size.size() % PER_CONFIGURATION_SIZE_3 == 0))
+        staticInfo.update(ANDROID_SENSOR_OPAQUE_RAW_SIZE, opaque_size.array(), opaque_size.size());
+    else
+        LOGW("Warning: ANDROID_SENSOR_OPAQUE_RAW_SIZE is using rough estimation(2 bytes/pixel)");
+#endif
+
     gStaticMetadata[cameraId] = staticInfo.release();
     return rc;
 }
@@ -7762,7 +8005,11 @@
 
 
     info->orientation = (int)gCamCapability[cameraId]->sensor_mount_angle;
+#ifndef USE_HAL_3_3
+    info->device_version = CAMERA_DEVICE_API_VERSION_3_4;
+#else
     info->device_version = CAMERA_DEVICE_API_VERSION_3_3;
+#endif
     info->static_camera_characteristics = gStaticMetadata[cameraId];
 
     //For now assume both cameras can operate independently.
@@ -7827,23 +8074,6 @@
     memset(videoOisProp, 0, sizeof(videoOisProp));
     property_get("persist.camera.ois.video", videoOisProp, "1");
     uint8_t forceVideoOis = (uint8_t)atoi(videoOisProp);
-
-    // EIS enable/disable
-    char eis_prop[PROPERTY_VALUE_MAX];
-    memset(eis_prop, 0, sizeof(eis_prop));
-    property_get("persist.camera.eis.enable", eis_prop, "0");
-    const uint8_t eis_prop_set = (uint8_t)atoi(eis_prop);
-
-    const bool facingBack = ((gCamCapability[mCameraId]->position == CAM_POSITION_BACK) ||
-            (gCamCapability[mCameraId]->position == CAM_POSITION_BACK_AUX));
-    // This is a bit hacky. EIS is enabled only when the above setprop
-    // is set to non-zero value and on back camera (for 2015 Nexus).
-    // Ideally, we should rely on m_bEisEnable, but we cannot guarantee
-    // configureStream is called before this function. In other words,
-    // we cannot guarantee the app will call configureStream before
-    // calling createDefaultRequest.
-    const bool eisEnabled = facingBack && eis_prop_set;
-
     uint8_t controlIntent = 0;
     uint8_t focusMode;
     uint8_t vsMode;
@@ -7894,9 +8124,6 @@
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
         focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
         optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
-        if (eisEnabled) {
-            vsMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON;
-        }
         cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
         edge_mode = ANDROID_EDGE_MODE_FAST;
         noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
@@ -7908,9 +8135,6 @@
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
         focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
         optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
-        if (eisEnabled) {
-            vsMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON;
-        }
         cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
         edge_mode = ANDROID_EDGE_MODE_FAST;
         noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
@@ -8052,6 +8276,11 @@
     /* sensitivity */
     static const int32_t default_sensitivity = 100;
     settings.update(ANDROID_SENSOR_SENSITIVITY, &default_sensitivity, 1);
+#ifndef USE_HAL_3_3
+    static const int32_t default_isp_sensitivity =
+            gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity;
+    settings.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &default_isp_sensitivity, 1);
+#endif
 
     /*edge mode*/
     settings.update(ANDROID_EDGE_MODE, &edge_mode, 1);
@@ -8446,7 +8675,6 @@
             ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_ROTATION,
                     ddm_info->rotation_info);
         }
-
     }
 
     /* Add additional JPEG cropping information. App add QCAMERA3_JPEG_ENCODE_CROP_RECT
@@ -8467,26 +8695,36 @@
             crop_meta.crop.top    = crop_data[1];
             crop_meta.crop.width  = crop_data[2];
             crop_meta.crop.height = crop_data[3];
-            if (frame_settings.exists(QCAMERA3_JPEG_ENCODE_CROP_ROI)) {
-                int32_t *roi =
-                    frame_settings.find(QCAMERA3_JPEG_ENCODE_CROP_ROI).data.i32;
-                crop_meta.roi_map.left =
-                        roi[0];
-                crop_meta.roi_map.top =
-                        roi[1];
-                crop_meta.roi_map.width =
-                        roi[2];
-                crop_meta.roi_map.height =
-                        roi[3];
+            // The JPEG crop roi should match cpp output size
+            IF_META_AVAILABLE(cam_stream_crop_info_t, cpp_crop,
+                    CAM_INTF_META_SNAP_CROP_INFO_CPP, reprocParam) {
+                crop_meta.roi_map.left = 0;
+                crop_meta.roi_map.top = 0;
+                crop_meta.roi_map.width = cpp_crop->crop.width;
+                crop_meta.roi_map.height = cpp_crop->crop.height;
             }
             ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_JPEG_ENCODE_CROP,
                     crop_meta);
-            LOGH("Add JPEG encode crop left %d, top %d, width %d, height %d",
+            LOGH("Add JPEG encode crop left %d, top %d, width %d, height %d, mCameraId %d",
                     crop_meta.crop.left, crop_meta.crop.top,
-                    crop_meta.crop.width, crop_meta.crop.height);
-            LOGH("Add JPEG encode crop ROI left %d, top %d, width %d, height %d",
+                    crop_meta.crop.width, crop_meta.crop.height, mCameraId);
+            LOGH("Add JPEG encode crop ROI left %d, top %d, width %d, height %d, mCameraId %d",
                     crop_meta.roi_map.left, crop_meta.roi_map.top,
-                    crop_meta.roi_map.width, crop_meta.roi_map.height);
+                    crop_meta.roi_map.width, crop_meta.roi_map.height, mCameraId);
+
+            // Add JPEG scale information
+            cam_dimension_t scale_dim;
+            memset(&scale_dim, 0, sizeof(cam_dimension_t));
+            if (frame_settings.exists(QCAMERA3_JPEG_ENCODE_CROP_ROI)) {
+                int32_t *roi =
+                    frame_settings.find(QCAMERA3_JPEG_ENCODE_CROP_ROI).data.i32;
+                scale_dim.width = roi[2];
+                scale_dim.height = roi[3];
+                ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_JPEG_SCALE_DIMENSION,
+                    scale_dim);
+                LOGH("Add JPEG encode scale width %d, height %d, mCameraId %d",
+                    scale_dim.width, scale_dim.height, mCameraId);
+            }
         }
     }
 
@@ -9106,6 +9344,29 @@
         }
     }
 
+#ifndef USE_HAL_3_3
+    if (frame_settings.exists(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
+        int32_t ispSensitivity =
+            frame_settings.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST).data.i32[0];
+        if (ispSensitivity <
+            gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity) {
+                ispSensitivity =
+                    gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity;
+                LOGD("clamp ispSensitivity to %d", ispSensitivity);
+        }
+        if (ispSensitivity >
+            gCamCapability[mCameraId]->isp_sensitivity_range.max_sensitivity) {
+                ispSensitivity =
+                    gCamCapability[mCameraId]->isp_sensitivity_range.max_sensitivity;
+                LOGD("clamp ispSensitivity to %d", ispSensitivity);
+        }
+        if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_ISP_SENSITIVITY,
+                ispSensitivity)) {
+            rc = BAD_VALUE;
+        }
+    }
+#endif
+
     if (frame_settings.exists(ANDROID_SHADING_MODE)) {
         uint8_t shadingMode = frame_settings.find(ANDROID_SHADING_MODE).data.u8[0];
         if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SHADING_MODE, shadingMode)) {
@@ -9428,22 +9689,6 @@
         }
     }
 
-    if (m_debug_avtimer || frame_settings.exists(QCAMERA3_USE_AV_TIMER)) {
-        uint8_t* use_av_timer = NULL;
-
-        if (m_debug_avtimer){
-            use_av_timer = &m_debug_avtimer;
-        }
-        else{
-            use_av_timer =
-                frame_settings.find(QCAMERA3_USE_AV_TIMER).data.u8;
-        }
-
-        if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_USE_AV_TIMER, *use_av_timer)) {
-            rc = BAD_VALUE;
-        }
-    }
-
     // EV step
     if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_EV_STEP,
             gCamCapability[mCameraId]->exp_compensation_step)) {
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3HWI.h b/msmcobalt/QCamera2/HAL3/QCamera3HWI.h
index f200f30..c398dac 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3HWI.h
+++ b/msmcobalt/QCamera2/HAL3/QCamera3HWI.h
@@ -191,7 +191,8 @@
     camera_metadata_t* translateFromHalMetadata(metadata_buffer_t *metadata,
                             nsecs_t timestamp, int32_t request_id,
                             const CameraMetadata& jpegMetadata, uint8_t pipeline_depth,
-                            uint8_t capture_intent, bool pprocDone, uint8_t fwk_cacMode);
+                            uint8_t capture_intent, bool pprocDone, uint8_t fwk_cacMode,
+                            bool firstMetadataInBatch);
     camera_metadata_t* saveRequestSettings(const CameraMetadata& jpegMetadata,
                             camera3_capture_request_t *request);
     int initParameters();
@@ -288,7 +289,8 @@
     int32_t handlePendingReprocResults(uint32_t frame_number);
     int64_t getMinFrameDuration(const camera3_capture_request_t *request);
     void handleMetadataWithLock(mm_camera_super_buf_t *metadata_buf,
-            bool free_and_bufdone_meta_buf);
+            bool free_and_bufdone_meta_buf,
+            bool firstMetadataInBatch);
     void handleBatchMetadata(mm_camera_super_buf_t *metadata_buf,
             bool free_and_bufdone_meta_buf);
     void handleBufferWithLock(camera3_stream_buffer_t *buffer,
@@ -324,6 +326,8 @@
     int32_t startAllChannels();
     int32_t stopAllChannels();
     int32_t notifyErrorForPendingRequests();
+    void notifyError(uint32_t frameNumber,
+            camera3_error_msg_code_t errorCode);
     int32_t getReprocessibleOutputStreamId(uint32_t &id);
     int32_t handleCameraDeviceError();
 
@@ -373,6 +377,7 @@
     bool m_bIs4KVideo;
     bool m_bEisSupportedSize;
     bool m_bEisEnable;
+    bool m_bEisSupported;
     typedef struct {
         cam_dimension_t dim;
         int format;
@@ -472,6 +477,8 @@
     uint32_t mFirstFrameNumberInBatch;
     camera3_stream_t mDummyBatchStream;
     bool mNeedSensorRestart;
+    uint32_t mMinInFlightRequests;
+    uint32_t mMaxInFlightRequests;
 
     /* sensor output size with current stream configuration */
     QCamera3CropRegionMapper mCropRegionMapper;
@@ -481,6 +488,7 @@
     uint32_t mLdafCalib[2];
     bool mPowerHintEnabled;
     int32_t mLastCustIntentFrmNum;
+    CameraMetadata  mCachedMetadata;
 
     static const QCameraMap<camera_metadata_enum_android_control_effect_mode_t,
             cam_effect_mode_type> EFFECT_MODES_MAP[];
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3PostProc.cpp b/msmcobalt/QCamera2/HAL3/QCamera3PostProc.cpp
index 447bd40..84538c7 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3PostProc.cpp
+++ b/msmcobalt/QCamera2/HAL3/QCamera3PostProc.cpp
@@ -1207,6 +1207,10 @@
     }
 
     hal_obj = (QCamera3HardwareInterface*)m_parent->mUserData;
+    if (hal_obj == NULL) {
+        LOGE("hal_obj is NULL, Error");
+        return BAD_VALUE;
+    }
 
     if (mJpegClientHandle <= 0) {
         LOGE("Error: bug here, mJpegClientHandle is 0");
@@ -1229,21 +1233,37 @@
     //main_stream->getCropInfo(crop);
 
     // Set JPEG encode crop in reprocess frame metadata
-    // If this JPEG crop info exist, encoder should
-    // crop and scale (if roi width and height is not 0)
+    // If this JPEG crop info exist, encoder should do cropping
     IF_META_AVAILABLE(cam_stream_crop_info_t, jpeg_crop,
             CAM_INTF_PARM_JPEG_ENCODE_CROP, metadata) {
         memcpy(&crop, &(jpeg_crop->crop), sizeof(cam_rect_t));
-        // change the JPEG dst_dim if roi_map width and height is not 0
-        if (jpeg_crop->roi_map.width != 0 &&
-                jpeg_crop->roi_map.height != 0) {
-            dst_dim.width = jpeg_crop->roi_map.width;
-            dst_dim.height = jpeg_crop->roi_map.height;
+    }
+
+    // Set JPEG encode crop in reprocess frame metadata
+    // If this JPEG scale info exist, encoder should do scaling
+    IF_META_AVAILABLE(cam_dimension_t, scale_dim,
+            CAM_INTF_PARM_JPEG_SCALE_DIMENSION, metadata) {
+        if (scale_dim->width != 0 && scale_dim->height != 0) {
+            dst_dim.width = scale_dim->width;
+            dst_dim.height = scale_dim->height;
         }
     }
 
     needJpegExifRotation = (hal_obj->needJpegExifRotation() || !needsReprocess(recvd_frame));
 
+    // If EXIF rotation metadata is added and used to match the JPEG orientation,
+    // it means CPP rotation is not involved, whether it is because CPP does not
+    // support rotation, or the reprocessed frame is not sent to CPP.
+    // Override CAM_INTF_PARM_ROTATION to 0 to avoid wrong CPP rotation info
+    // to be filled in to JPEG metadata.
+    if (needJpegExifRotation) {
+        cam_rotation_info_t rotation_info;
+        memset(&rotation_info, 0, sizeof(rotation_info));
+        rotation_info.rotation = ROTATE_0;
+        rotation_info.streamId = 0;
+        ADD_SET_PARAM_ENTRY_TO_BATCH(metadata, CAM_INTF_PARM_ROTATION, rotation_info);
+    }
+
     LOGH("Need new session?:%d", needNewSess);
     if (needNewSess) {
         //creating a new session, so we must destroy the old one
@@ -1287,10 +1307,6 @@
         encodeParam.main_dim.dst_dim = dst_dim;
         encodeParam.thumb_dim.dst_dim = jpeg_settings->thumbnail_size;
 
-        if (needJpegExifRotation) {
-            encodeParam.thumb_rotation = (uint32_t)jpeg_settings->jpeg_orientation;
-        }
-
         LOGI("Src Buffer cnt = %d, res = %dX%d len = %d rot = %d "
             "src_dim = %dX%d dst_dim = %dX%d",
             encodeParam.num_src_bufs,
@@ -1546,10 +1562,14 @@
     QCamera3HardwareInterface* hal_obj = NULL;
     mm_jpeg_debug_exif_params_t *exif_debug_params = NULL;
     if (m_parent != NULL) {
-       hal_obj = (QCamera3HardwareInterface*)m_parent->mUserData;
+        hal_obj = (QCamera3HardwareInterface*)m_parent->mUserData;
+        if (hal_obj == NULL) {
+            LOGE("hal_obj is NULL, Error");
+            return BAD_VALUE;
+        }
     } else {
-       LOGE("m_parent is NULL, Error");
-       return BAD_VALUE;
+        LOGE("m_parent is NULL, Error");
+        return BAD_VALUE;
     }
     bool needJpegExifRotation = false;
 
@@ -1635,6 +1655,13 @@
             LOGH("Need EXIF JPEG ROTATION");
         }
     }
+
+    // Although in HAL3, legacy flip mode is not advertised
+    // default value of CAM_INTF_PARM_FLIP is still added here
+    // for jpge metadata
+    int32_t flipMode = 0; // no flip
+    ADD_SET_PARAM_ENTRY_TO_BATCH(metadata, CAM_INTF_PARM_FLIP, flipMode);
+
     LOGH("Need new session?:%d", needNewSess);
     if (needNewSess) {
         //creating a new session, so we must destroy the old one
@@ -1678,10 +1705,6 @@
         encodeParam.main_dim.dst_dim = dst_dim;
         encodeParam.thumb_dim.dst_dim = jpeg_settings->thumbnail_size;
 
-        if (needJpegExifRotation) {
-            encodeParam.thumb_rotation = (uint32_t)jpeg_settings->jpeg_orientation;
-        }
-
         LOGI("Src Buffer cnt = %d, res = %dX%d len = %d rot = %d "
             "src_dim = %dX%d dst_dim = %dX%d",
             encodeParam.num_src_bufs,
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.cpp b/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.cpp
index 1621d24..95eff54 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.cpp
+++ b/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.cpp
@@ -51,7 +51,6 @@
         QCAMERA3_TEMPORAL_DENOISE_END,
         QCAMERA3_AV_TIMER_END,
         QCAMERA3_SENSOR_META_DATA_END,
-        NEXUS_EXPERIMENTAL_2015_END,
         QCAMERA3_DUALCAM_LINK_META_DATA_END,
         QCAMERA3_DUALCAM_CALIB_META_DATA_END,
         QCAMERA3_HAL_PRIVATEDATA_END,
@@ -73,7 +72,6 @@
     "org.codeaurora.qcamera3.temporal_denoise",
     "org.codeaurora.qcamera3.av_timer",
     "org.codeaurora.qcamera3.sensor_meta_data",
-    "com.google.nexus.experimental2015",
     "org.codeaurora.qcamera3.dualcam_link_meta_data",
     "org.codeaurora.qcamera3.dualcam_calib_meta_data",
     "org.codeaurora.qcamera3.hal_private_data",
@@ -123,12 +121,6 @@
    {"is_mono_only",                TYPE_BYTE }
 };
 
-vendor_tag_info_t nexus_experimental_2015[NEXUS_EXPERIMENTAL_2015_END -
-        NEXUS_EXPERIMENTAL_2015_START] = {
-    {"sensor.dynamicBlackLevel", TYPE_FLOAT },
-    {"sensor.info.opticallyShieldedRegions", TYPE_INT32 }
-};
-
 vendor_tag_info_t
         qcamera3_dualcam_link_meta_data[QCAMERA3_DUALCAM_LINK_META_DATA_END -
         QCAMERA3_DUALCAM_LINK_META_DATA_START] = {
@@ -168,7 +160,6 @@
     qcamera3_temporal_denoise,
     qcamera3_av_timer,
     qcamera3_sensor_meta_data,
-    nexus_experimental_2015,
     qcamera3_dualcam_link_meta_data,
     qcamera3_dualcam_calib_meta_data,
     qcamera3_hal_privatedata,
@@ -205,10 +196,6 @@
     (uint32_t)QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN,
     (uint32_t)QCAMERA3_SENSOR_IS_MONO_ONLY,
 
-    //NEXUS_EXPERIMENTAL_2015
-    (uint32_t)NEXUS_EXPERIMENTAL_2015_SENSOR_DYNAMIC_BLACK_LEVEL,
-    (uint32_t)NEXUS_EXPERIMENTAL_2015_SENSOR_INFO_OPTICALLY_SHIELDED_REGIONS,
-
     // QCAMERA3_DUALCAM_LINK_META_DATA
     (uint32_t)QCAMERA3_DUALCAM_LINK_ENABLE,
     (uint32_t)QCAMERA3_DUALCAM_LINK_IS_MAIN,
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.h b/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.h
index 9fc180e..7f02afa 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.h
+++ b/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.h
@@ -44,7 +44,6 @@
     QCAMERA3_TEMPORAL_DENOISE,
     QCAMERA3_AV_TIMER,
     QCAMERA3_SENSOR_META_DATA,
-    NEXUS_EXPERIMENTAL_2015,
     QCAMERA3_DUALCAM_LINK_META_DATA,
     QCAMERA3_DUALCAM_CALIB_META_DATA,
     QCAMERA3_HAL_PRIVATEDATA,
@@ -61,7 +60,6 @@
     QCAMERA3_TEMPORAL_DENOISE_START = QCAMERA3_TEMPORAL_DENOISE << 16,
     QCAMERA3_AV_TIMER_START = QCAMERA3_AV_TIMER << 16,
     QCAMERA3_SENSOR_META_DATA_START = QCAMERA3_SENSOR_META_DATA << 16,
-    NEXUS_EXPERIMENTAL_2015_START = NEXUS_EXPERIMENTAL_2015 << 16,
     QCAMERA3_DUALCAM_LINK_META_DATA_START = QCAMERA3_DUALCAM_LINK_META_DATA << 16,
     QCAMERA3_DUALCAM_CALIB_META_DATA_START = QCAMERA3_DUALCAM_CALIB_META_DATA << 16,
     QCAMERA3_HAL_PRIVATEDATA_START = QCAMERA3_HAL_PRIVATEDATA << 16,
@@ -146,10 +144,6 @@
     QCAMERA3_SENSOR_IS_MONO_ONLY,
     QCAMERA3_SENSOR_META_DATA_END,
 
-    NEXUS_EXPERIMENTAL_2015_SENSOR_DYNAMIC_BLACK_LEVEL = NEXUS_EXPERIMENTAL_2015_START,
-    NEXUS_EXPERIMENTAL_2015_SENSOR_INFO_OPTICALLY_SHIELDED_REGIONS,
-    NEXUS_EXPERIMENTAL_2015_END,
-
     QCAMERA3_DUALCAM_LINK_ENABLE = QCAMERA3_DUALCAM_LINK_META_DATA_START,
     QCAMERA3_DUALCAM_LINK_IS_MAIN,
     QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID,
diff --git a/msmcobalt/QCamera2/HAL3/test/Android.mk b/msmcobalt/QCamera2/HAL3/test/Android.mk
new file mode 100644
index 0000000..709ee2a
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/Android.mk
@@ -0,0 +1,47 @@
+LOCAL_PATH:=$(call my-dir)
+
+# Build command line test app: mm-hal3-app
+include $(CLEAR_VARS)
+
+ifeq ($(TARGET_SUPPORT_HAL1),false)
+LOCAL_CFLAGS += -DQCAMERA_HAL3_SUPPORT
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM),msm8953)
+    LOCAL_CFLAGS += -DCAMERA_CHIPSET_8953
+else
+    LOCAL_CFLAGS += -DCAMERA_CHIPSET_8937
+endif
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_C_INCLUDES+= $(kernel_includes)
+
+LOCAL_C_INCLUDES += \
+    hardware/libhardware/include/hardware \
+    system/media/camera/include \
+    system/media/private/camera/include \
+    $(LOCAL_PATH)/../ \
+    $(LOCAL_PATH)/../../stack/mm-camera-interface/inc \
+
+
+LOCAL_SRC_FILES := \
+    QCameraHAL3Base.cpp \
+    QCameraHAL3MainTestContext.cpp \
+    QCameraHAL3VideoTest.cpp \
+    QCameraHAL3PreviewTest.cpp \
+    QCameraHAL3SnapshotTest.cpp \
+    QCameraHAL3RawSnapshotTest.cpp \
+    QCameraHAL3Test.cpp
+
+
+LOCAL_SHARED_LIBRARIES:= libutils libcamera_client liblog libcamera_metadata libcutils
+
+LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
+
+LOCAL_MODULE:= hal3-test-app
+
+LOCAL_CFLAGS += -Wall -Wextra
+
+LOCAL_CFLAGS += -std=c++11 -std=gnu++0x
+
+include $(BUILD_EXECUTABLE)
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Base.cpp b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Base.cpp
new file mode 100644
index 0000000..b9fa5e1
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Base.cpp
@@ -0,0 +1,447 @@
+/*Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "QCameraHAL3MainTestContext.h"
+#include "QCameraHAL3SnapshotTest.h"
+#include "QCameraHAL3RawSnapshotTest.h"
+#include "QCameraHAL3PreviewTest.h"
+
+#ifdef QCAMERA_HAL3_SUPPORT
+#define LIB_PATH /usr/lib/hw/camera.msm8953.so
+#else
+#define LIB_PATH /system/lib/hw/camera.msm8953.so
+#endif
+
+extern "C" {
+extern int set_camera_metadata_vendor_ops(const vendor_tag_ops_t *query_ops);
+}
+
+/*#ifdef CAMERA_CHIPSET_8953
+#define CHIPSET_LIB lib/hw/camera.msm8953.so
+#else
+#define CHIPSET_LIB lib/hw/camera.msm8937.so
+#endif*/
+
+#define CAM_LIB(s) STR_LIB_PATH(s)
+#define STR_LIB_PATH(s) #s
+
+namespace qcamera {
+
+QCameraHAL3PreviewTest *mPreviewtestCase = NULL;
+QCameraHAL3VideoTest *mVideotestCase = NULL;
+QCameraHAL3SnapshotTest *mSnapshottestCase = NULL;
+QCameraHAL3RawSnapshotTest *mRawSnapshottestCase = NULL;
+
+struct timeval start_time;
+int capture_received;
+int pfd[2];
+extern int test_case_end;
+extern int snapshot_buffer;
+
+pthread_cond_t mRequestAppCond;
+std::list<uint32_t> PreviewQueue;
+std::list<uint32_t> VideoQueue;
+
+pthread_mutex_t TestAppLock = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t mCaptureRequestLock = PTHREAD_MUTEX_INITIALIZER;
+
+
+
+static void camera_device_status_change(
+        const struct camera_module_callbacks* callbacks,
+        int camera_id, int new_status)
+{
+    /* Stub function */
+}
+
+static void torch_mode_status_change(
+        const struct camera_module_callbacks* callbacks,
+        const char* camera_id, int new_status)
+{
+    /* Stub function */
+}
+
+static void Notify(
+        const camera3_callback_ops *cb,
+        const camera3_notify_msg *msg)
+{
+    /* Stub function */
+}
+
+static void ProcessCaptureResult(
+        const camera3_callback_ops *cb,
+        const camera3_capture_result *result)
+{
+    buffer_thread_msg_t msg;
+    extern CameraHAL3Base *mCamHal3Base;
+    int frame_num;
+    extern int req_sent;
+    extern int preview_buffer_allocated;
+    extern int video_buffer_allocated;
+    double elapsedTime;
+    int num;
+    struct timeval end_time;
+    LOGD("Cam Capture Result Callback %d and %d",
+            result->num_output_buffers, mCamHal3Base->mFrameCount);
+    if (mCamHal3Base->mTestCaseSelected == MENU_START_PREVIEW ||
+            mCamHal3Base->mTestCaseSelected == MENU_START_VIDEO) {
+        if (result->num_output_buffers == 1) {
+            frame_num = result->frame_number;
+            LOGD("Frame width:%d and height:%d and format:%d",
+                    result->output_buffers->stream->width,
+                    result->output_buffers->stream->height,
+                    result->output_buffers->stream->format);
+            (mCamHal3Base->mFrameCount)++;
+            LOGD("Preview/Video Capture Result %d and fcount: %d and req_Sent:%d and %d ",
+            result->num_output_buffers, mCamHal3Base->mFrameCount, req_sent, result->frame_number);
+            if (test_case_end == 0) {
+                if (mCamHal3Base->mTestCaseSelected == MENU_START_PREVIEW) {
+                    num = (result->frame_number)%preview_buffer_allocated;
+                    PreviewQueue.push_back(num);
+                }
+                else {
+                    num = (result->frame_number)%video_buffer_allocated;
+                           VideoQueue.push_back(num);
+                }
+                pthread_cond_signal(&mRequestAppCond);
+                memset(&msg, 0, sizeof(buffer_thread_msg_t));
+            }
+        }
+    }
+    else {
+        extern int fcount_captured;
+        if (result->num_output_buffers == 1) {
+            LOGD("snapshot/Raw Capture1 Result Callback %d and %d",
+                    result->num_output_buffers, fcount_captured);
+            (mCamHal3Base->mFrameCount)++;
+            fcount_captured++;
+            LOGD("\n Capture %d done preparing for capture ", fcount_captured);
+            memset(&msg, 0, sizeof(buffer_thread_msg_t));
+            write(pfd[1], &msg, sizeof(buffer_thread_msg_t));
+        }
+    }
+}
+
+CameraHAL3Base::CameraHAL3Base(int cameraIndex) :
+    mCameraIndex(cameraIndex),
+    mLibHandle(NULL),
+    mFrameCount(0),
+    mSecElapsed(1),
+    mTestCaseSelected(0),
+    mPreviewRunning(0),
+    mVideoRunning(0),
+    mSnapShotRunning(0)
+{
+
+}
+
+
+int CameraHAL3Base::hal3appCameraTestLoad()
+{
+    int rc = HAL3_CAM_OK;
+    int numCam;
+    int32_t res = 0;
+    hal3_camera_test_obj_t *my_test_obj;
+    mLibHandle = new hal3_camera_lib_test;
+    memset(mLibHandle, 0, sizeof(hal3_camera_lib_handle));
+    rc = hal3appTestLoad(&mLibHandle->app_obj);
+    camera_module_t *my_if_handle = mLibHandle->app_obj.hal3_lib.halModule_t;
+    if (HAL3_CAM_OK != rc) {
+        LOGE("hal3 err\n");
+        goto EXIT;
+    }
+
+    numCam = my_if_handle->get_number_of_cameras();
+    printf("\n Number of Cameras are : %d ", numCam);
+    if (my_if_handle->get_vendor_tag_ops) {
+        mLibHandle->app_obj.mVendorTagOps = vendor_tag_ops_t();
+        my_if_handle->get_vendor_tag_ops(&(mLibHandle->app_obj.mVendorTagOps));
+
+        res = set_camera_metadata_vendor_ops(&(mLibHandle->app_obj.mVendorTagOps));
+        if (0 != res) {
+            printf("%s: Could not set vendor tag descriptor, "
+                    "received error %s (%d). \n", __func__,
+                    strerror(-res), res);
+            goto EXIT;
+        }
+    }
+    my_test_obj = &(mLibHandle->test_obj);
+    my_test_obj->module_cb.torch_mode_status_change = &torch_mode_status_change;
+    my_test_obj->module_cb.camera_device_status_change = &camera_device_status_change;
+    my_if_handle->set_callbacks(&(my_test_obj->module_cb));
+    my_if_handle->get_camera_info(0, &(mLibHandle->test_obj.cam_info));
+    return numCam;
+    EXIT:
+    return rc;
+
+}
+
+int CameraHAL3Base::hal3appCameraLibOpen(int camid)
+{
+    int rc;
+    rc = hal3appCamOpen(&mLibHandle->app_obj, (int)camid, &(mLibHandle->test_obj));
+    if (rc != HAL3_CAM_OK) {
+        LOGE("hal3appCamOpen() camidx=%d, err=%d\n",
+                camid, rc);
+        goto EXIT;
+    }
+    rc = hal3appCamInitialize((int)camid, &mLibHandle->test_obj);
+    EXIT:
+    return rc;
+}
+
+int CameraHAL3Base::hal3appTestLoad(hal3_camera_app_t *my_hal3_app)
+{
+    memset(&my_hal3_app->hal3_lib, 0, sizeof(hal3_interface_lib_t));
+    printf("\nLibrary path is :%s", CAM_LIB(LIB_PATH));
+    my_hal3_app->hal3_lib.ptr = dlopen(CAM_LIB(LIB_PATH), RTLD_NOW);
+
+    if (!my_hal3_app->hal3_lib.ptr) {
+        LOGE("Error opening HAL libraries %s\n",
+                dlerror());
+        return -HAL3_CAM_E_GENERAL;
+    }
+    my_hal3_app->hal3_lib.halModule_t =
+        (camera_module_t*)dlsym(my_hal3_app->hal3_lib.ptr, HAL_MODULE_INFO_SYM_AS_STR);
+    if (my_hal3_app->hal3_lib.halModule_t == NULL) {
+        LOGE("Error opening HAL library %s\n",
+                dlerror());
+        return -HAL3_CAM_E_GENERAL;
+    }
+    return HAL3_CAM_OK;
+}
+
+int CameraHAL3Base::hal3appCamOpen(
+        hal3_camera_app_t *my_hal3_app,
+        int camid,
+        hal3_camera_test_obj_t *my_test_obj)
+{
+    int rc = 0;
+    int numCam;
+    camera_module_t *my_if_handle = my_hal3_app->hal3_lib.halModule_t;
+    my_if_handle->common.methods->open(&(my_if_handle->common), "0",
+            reinterpret_cast<hw_device_t**>(&(my_test_obj->device)));
+    printf("\n Camera ID %d Opened \n", camid);
+    return HAL3_CAM_OK;
+}
+
+int CameraHAL3Base::hal3appCamInitialize(int camid, hal3_camera_test_obj_t *my_test_obj)
+{
+    int rc = 0;
+    camera3_device_t *device_handle = my_test_obj->device;
+    my_test_obj->callback_ops.notify = &Notify;
+    my_test_obj->callback_ops.process_capture_result = &ProcessCaptureResult;
+    rc = device_handle->ops->initialize(my_test_obj->device, &(my_test_obj->callback_ops));
+    if (rc != HAL3_CAM_OK) {
+        LOGE("hal3appCamInitialize() camidx=%d, err=%d\n",
+                camid, rc);
+        goto EXIT;
+    }
+    EXIT:
+    return rc;
+}
+
+
+void CameraHAL3Base::hal3appCheckStream(int testcase, int camid)
+{
+    if (testcase != MENU_START_PREVIEW) {
+        if (mPreviewtestCase != NULL) {
+            mPreviewtestCase->previewTestEnd(mLibHandle, camid);
+            delete mPreviewtestCase;
+            mPreviewtestCase = NULL;
+        }
+    }
+    if (testcase != MENU_START_VIDEO){
+        if (mVideotestCase != NULL) {
+            mVideotestCase->videoTestEnd(mLibHandle, camid);
+            delete mVideotestCase;
+            mVideotestCase = NULL;
+        }
+    }
+
+    if (testcase != MENU_START_CAPTURE){
+        if (mSnapshottestCase != NULL) {
+            delete mSnapshottestCase;
+            mSnapshottestCase = NULL;
+        }
+    }
+
+    if (testcase != MENU_START_RAW_CAPTURE) {
+        if (mRawSnapshottestCase != NULL) {
+            delete mRawSnapshottestCase;
+            mRawSnapshottestCase = NULL;
+        }
+    }
+}
+
+
+int CameraHAL3Base::hal3appCameraPreviewInit(int testcase, int camid, int w, int h)
+{
+    extern int req_sent;
+    int testCaseEndComplete = 0;
+    int CaptureRequestSent = 0;
+    if (w == 0 || h == 0) {
+        printf("\n Frame dimension is wrong");
+        return -1;
+    }
+    if ( mPreviewtestCase != NULL) {
+        return 0;
+    }
+    else {
+        testCaseEndComplete = 0;
+        do {
+            if (mVideoRunning == 1) {
+                hal3appCheckStream(MENU_START_PREVIEW, camid);
+            }
+            pthread_mutex_lock(&TestAppLock);
+            mTestCaseSelected = MENU_START_PREVIEW;
+            if (mVideoRunning != 1) {
+                hal3appCheckStream(MENU_START_PREVIEW, camid);
+            }
+            mPreviewtestCase = new QCameraHAL3PreviewTest(0);
+            printf("\n\n Testing the Resolution : %d X %d", w, h);
+            req_sent = 0;
+            PreviewQueue.clear();
+            capture_received = 0; mSecElapsed = 1;
+            snapshot_buffer = -1; mFrameCount = 0;
+            mPreviewtestCase->width = w; mPreviewtestCase->height = h;
+            mPreviewtestCase->initTest(mLibHandle,
+                    (int) MENU_START_PREVIEW, camid, w, h);
+            testCaseEndComplete = 1;
+        }while(testCaseEndComplete != 1);
+    }
+    return 0;
+}
+
+int CameraHAL3Base::hal3appCameraVideoInit(int testcase, int camid, int w, int h)
+{
+    extern int req_sent;
+    int testCaseEndComplete = 0;
+    int CaptureRequestSent = 0;
+    if (w == 0 || h == 0) {
+        printf("\n Frame dimension is wrong");
+        return -1;
+    }
+
+    if (mVideotestCase != NULL) {
+            return 0;
+    }
+    else {
+        testCaseEndComplete = 0;
+        do {
+            if (mPreviewRunning == 1) {
+                hal3appCheckStream(MENU_START_VIDEO, camid);
+            }
+            pthread_mutex_lock(&TestAppLock);
+            mTestCaseSelected = MENU_START_VIDEO;
+            if (mPreviewRunning != 1) {
+                hal3appCheckStream(MENU_START_VIDEO, camid);
+            }
+            mVideotestCase = new QCameraHAL3VideoTest(0);
+            VideoQueue.clear();
+            printf("\n\nTesting the Resolution : %d X %d", w, h);
+            req_sent = 0;
+            capture_received =0; mSecElapsed = 1; test_case_end = 0;
+            mVideotestCase->width = w; mVideotestCase->height = h;
+            snapshot_buffer = -1; mFrameCount = 0;
+            mVideotestCase->initTest(mLibHandle,
+                    (int) MENU_START_VIDEO, camid, w, h);
+            testCaseEndComplete = 1;
+        }while(testCaseEndComplete !=1);
+    }
+    return 0;
+}
+
+
+int CameraHAL3Base::hal3appRawCaptureInit(hal3_camera_lib_test *handle, int camid, int req_cap)
+{
+    int testCaseEndComplete = 0;
+    if (mSnapShotRunning != 1) {
+        hal3appCheckStream(MENU_START_RAW_CAPTURE, camid);
+    }
+    testCaseEndComplete = 0;
+    do {
+        pthread_mutex_lock(&TestAppLock);
+        if (mSnapShotRunning == 1) {
+            hal3appCheckStream(MENU_START_RAW_CAPTURE, camid);
+        }
+        printf("\n capture:%d", req_cap);
+        mTestCaseSelected = MENU_START_RAW_CAPTURE;
+        mRawSnapshottestCase = new QCameraHAL3RawSnapshotTest(req_cap);
+        mRawSnapshottestCase->mRequestedCapture = req_cap;
+        mRawSnapshottestCase->initTest(mLibHandle,
+        (int) MENU_START_RAW_CAPTURE, camid, RAWSNAPSHOT_CAPTURE_WIDTH,
+                RAWSNAPSHOT_CAPTURE_HEIGHT);
+        testCaseEndComplete = 1;
+    }while(testCaseEndComplete !=1);
+    return 0;
+}
+
+int CameraHAL3Base::hal3appCameraCaptureInit(hal3_camera_lib_test *handle,
+        int camid, int req_cap)
+{
+    int testCaseEndComplete = 0;
+    if (mSnapShotRunning != 1) {
+        hal3appCheckStream(MENU_START_CAPTURE, camid);
+    }
+    testCaseEndComplete = 0;
+    do {
+        pthread_mutex_lock(&TestAppLock);
+        if (mSnapShotRunning == 1) {
+            hal3appCheckStream(MENU_START_CAPTURE, camid);
+        }
+        printf("\n capture:%d", req_cap);
+        mTestCaseSelected = MENU_START_CAPTURE;
+        mSnapshottestCase = new QCameraHAL3SnapshotTest(req_cap);
+        mSnapshottestCase->mRequestedCapture = req_cap;
+        mSnapshottestCase->initTest(mLibHandle,
+            (int) MENU_START_CAPTURE, camid, SNAPSHOT_CAPTURE_WIDTH, SNAPSHOT_CAPTURE_HEIGHT);
+        testCaseEndComplete = 1;
+    }while(testCaseEndComplete != 1);
+    return 0;
+}
+
+void CameraHAL3Base::hal3appCamCapabilityGet(hal3_camera_lib_test *handle, int camid)
+{
+    camera_module_t *my_if_handle = ((handle->app_obj).hal3_lib).halModule_t;
+    hal3_camera_test_obj_t *test_obj_handle = &(handle->test_obj);
+    camera_metadata_entry entry_hal3app;
+    camera_info info;
+    int i = 0, count = 0, j = 0;
+    long int num = 0;
+    int32_t *available_hdr = NULL, *available_svhdr = NULL, *available_ir = NULL;
+    android::CameraMetadata hal3_cam_settings;
+    printf("\n Number of Cameras are : %d and %p", camid, &(test_obj_handle->cam_info));
+    my_if_handle->get_camera_info(camid, &(test_obj_handle->cam_info));
+    info = test_obj_handle->cam_info;
+    hal3_cam_settings = (info.static_camera_characteristics);
+}
+
+}
+
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Base.h b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Base.h
new file mode 100644
index 0000000..2b24816
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Base.h
@@ -0,0 +1,170 @@
+/*Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 __HAL3APP_H__
+#define __HAL3APP_H__
+
+#include <hardware/hardware.h>
+#include <dlfcn.h>
+#include <hardware/camera3.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <list>
+#include <camera/CameraMetadata.h>
+#include <linux/msm_ion.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <system/window.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <poll.h>
+
+extern "C" {
+#include "mm_camera_dbg.h"
+}
+
+#define HAL3_DATASPACE_UNKNOWN 0x0
+#define HAL3_DATASPACE_ARBITRARY 0x1
+#define HAL3_DATASPACE_JFIF 0x101
+#define FLAGS_VIDEO_ENCODER 0x00010000
+
+#define PREVIEW_WIDTH 1440
+#define PREVIEW_HEIGHT 1080
+
+#define VIDEO_WIDTH 1920
+#define VIDEO_HEIGHT 1080
+
+#define SNAPSHOT_CAPTURE_WIDTH 5344
+#define SNAPSHOT_CAPTURE_HEIGHT 4008
+
+#define RAWSNAPSHOT_CAPTURE_WIDTH 5344
+#define RAWSNAPSHOT_CAPTURE_HEIGHT 4016
+
+namespace qcamera {
+
+typedef enum {
+    HAL3_CAM_OK,
+    HAL3_CAM_E_GENERAL,
+    HAL3_CAM_E_NO_MEMORY,
+    HAL3_CAM_E_NOT_SUPPORTED,
+    HAL3_CAM_E_INVALID_INPUT,
+    HAL3_CAM_E_INVALID_OPERATION,
+    HAL3_CAM_E_ENCODE,
+    HAL3_CAM_E_BUFFER_REG,
+    HAL3_CAM_E_PMEM_ALLOC,
+    HAL3_CAM_E_CAPTURE_FAILED,
+    HAL3_CAM_E_CAPTURE_TIMEOUT,
+} hal3_camera_status_type_t;
+
+typedef enum {
+    PROCESS_BUFFER,
+} buffer_thread_msg_type_t;
+
+typedef struct {
+    camera3_device_t *device;
+    camera3_callback_ops callback_ops;
+    struct camera_info cam_info;
+    camera_module_callbacks_t module_cb;
+} hal3_camera_test_obj_t;
+
+typedef struct {
+    int fd;
+    int ion_fd;
+    ion_user_handle_t ion_handle;
+    size_t size;
+} hal3_camtest_meminfo_t;
+
+typedef struct {
+    buffer_thread_msg_type_t msg;
+    bool stop_thread;
+} buffer_thread_msg_t;
+
+typedef struct {
+    void *ptr;
+    camera_module_t* halModule_t;
+} hal3_interface_lib_t;
+
+typedef struct {
+    uint8_t num_cameras;
+    vendor_tag_ops_t mVendorTagOps;
+    hal3_interface_lib_t hal3_lib;
+} hal3_camera_app_t;
+
+typedef struct {
+    hal3_camera_app_t app_obj;
+    hal3_camera_test_obj_t test_obj;
+} hal3_camera_lib_test;
+
+typedef struct {
+    pthread_t td;
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+    int32_t readfd;
+    int32_t writefd;
+    void *data_obj;
+    bool is_thread_started;
+    int testcase;
+} buffer_thread_t;
+
+extern int32_t pfd[2];
+typedef hal3_camera_lib_test hal3_camera_lib_handle;
+
+class CameraHAL3Base
+{
+    friend class MainTestContext;
+protected:
+    int mCameraIndex;
+public:
+    CameraHAL3Base();
+    CameraHAL3Base(int cameraIndex);
+    hal3_camera_lib_test *mLibHandle;
+    int mFrameCount;
+    int fps;
+    int mSecElapsed;
+    int mTestCaseSelected;
+    int mPreviewRunning;
+    int mVideoRunning;
+    int mSnapShotRunning;
+
+    int hal3appCamInitialize(int camid, hal3_camera_test_obj_t *my_test_obj);
+    void hal3appCamCapabilityGet(hal3_camera_lib_test *handle,int camid);
+    int hal3appCameraLibOpen(int );
+    int hal3appTestLoad(hal3_camera_app_t *);
+    int hal3appCamOpen(hal3_camera_app_t *,
+             int,
+             hal3_camera_test_obj_t *);
+    int hal3appCameraPreviewInit(int, int, int, int);
+    int hal3appCameraVideoInit(int, int camid, int w, int h);
+    int hal3appCameraCaptureInit(hal3_camera_lib_test *, int, int);
+    int hal3appRawCaptureInit(hal3_camera_lib_test *handle, int camid, int );
+    int hal3appCameraTestLoad();
+    void hal3appCheckStream(int testcase, int camid);
+};
+
+}
+#endif
\ No newline at end of file
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3MainTestContext.cpp b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3MainTestContext.cpp
new file mode 100644
index 0000000..13e46f9
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3MainTestContext.cpp
@@ -0,0 +1,276 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "QCameraHAL3MainTestContext.h"
+#include "QCameraHAL3Base.h"
+
+namespace qcamera {
+
+#define MAX_CAMERA_SUPPORTED 20
+
+const CAMERA_BASE_MENU_TBL_T camera_main_menu_tbl[] = {
+    {MENU_START_PREVIEW,             "To Start Preview"},
+    {MENU_START_VIDEO,               "To Start Video"},
+    {MENU_START_CAPTURE,             "To Capture"},
+    {MENU_START_RAW_CAPTURE,         "To Raw Capture"},
+    {MENU_EXIT,                      "EXIT"},
+};
+
+const HAL3TEST_SENSOR_MENU_TBL_T sensor_tbl[] = {
+    {"Rear Camera"},
+    {"Front Camera"},
+};
+
+CameraHAL3Base *mCamHal3Base = NULL;
+pthread_mutex_t gCamLock = PTHREAD_MUTEX_INITIALIZER;
+
+MainTestContext::MainTestContext()
+{
+    int i = 0;
+    mTestRunning = false;
+    mCamHal3Base = NULL;
+}
+
+int MainTestContext::hal3appGetUserEvent()
+{
+    char tc_buf[3];
+    int choice;
+    int rc = 0, req_capture = 0;
+    int num_testcase = MENU_EXIT+1;
+    int submenu_choice, num;
+    int preview_restart;
+    static int prev_menu_choice;
+    uint8_t camid, num_of_cameras;
+    if (mCamHal3Base != NULL) {
+        delete mCamHal3Base;
+    }
+    mCamHal3Base = new CameraHAL3Base(0);
+    num_of_cameras = mCamHal3Base->hal3appCameraTestLoad();
+    if ((num_of_cameras <= 0) && (num_of_cameras >= MAX_CAMERA_SUPPORTED)) {
+        LOGE("\n Supported Camera Value is wrong : %d", num_of_cameras);
+        printf("\n Invalid Number Of Cameras");
+        goto exit;
+    }
+    else {
+        choice = hal3appDisplaySensorMenu(num_of_cameras);
+        if (choice >= num_of_cameras || choice < 0) {
+            printf("\n Unsupported Parameter");
+            goto exit;
+        }
+        else {
+            mCamHal3Base->mCameraIndex = choice;
+            rc = mCamHal3Base->hal3appCameraLibOpen(choice);
+        }
+    }
+    do {
+        choice = hal3appPrintMenu();
+        switch(choice) {
+            case MENU_START_PREVIEW:
+                mCamHal3Base->hal3appCameraPreviewInit(MENU_START_PREVIEW,
+                        mCamHal3Base->mCameraIndex, PREVIEW_WIDTH, PREVIEW_HEIGHT);
+                mCamHal3Base->mPreviewRunning = 1; mCamHal3Base->mVideoRunning = 0;
+                mCamHal3Base->mSnapShotRunning = 0;
+            break;
+
+            case MENU_START_VIDEO:
+                mCamHal3Base->hal3appCameraVideoInit(MENU_START_VIDEO,
+                        mCamHal3Base->mCameraIndex, VIDEO_WIDTH, VIDEO_HEIGHT);
+                mCamHal3Base->mPreviewRunning = 0; mCamHal3Base->mVideoRunning = 1;
+                mCamHal3Base->mSnapShotRunning = 0;
+            break;
+
+            case MENU_START_CAPTURE:
+                hal3appDisplaySnapshotMenu();
+                req_capture = 3; preview_restart = 0;
+                if (mCamHal3Base->mPreviewRunning == 1) {
+                    preview_restart = 1;
+                }
+                mCamHal3Base->hal3appCameraCaptureInit(0, 0, req_capture);
+                mCamHal3Base->mPreviewRunning = 0; mCamHal3Base->mVideoRunning = 0;
+                mCamHal3Base->mSnapShotRunning = 1;
+                if (preview_restart == 1) {
+                    mCamHal3Base->hal3appCameraPreviewInit(MENU_START_PREVIEW,
+                            mCamHal3Base->mCameraIndex, PREVIEW_WIDTH, PREVIEW_HEIGHT);
+                    mCamHal3Base->mPreviewRunning = 1; mCamHal3Base->mVideoRunning = 0;
+                    mCamHal3Base->mSnapShotRunning = 0;
+                }
+            break;
+
+            case MENU_START_RAW_CAPTURE:
+                hal3appDisplayRawCaptureMenu();
+                req_capture = 3;
+                mCamHal3Base->hal3appRawCaptureInit(0, 0, req_capture);
+                mCamHal3Base->mPreviewRunning = 0; mCamHal3Base->mVideoRunning = 0;
+                mCamHal3Base->mSnapShotRunning = 1;
+            break;
+
+            case MENU_EXIT:
+                hal3appDisplayExitMenu();
+            break;
+
+            default:
+                printf("\n Option not in Menu\n");
+        }
+    }while(choice != MENU_EXIT);
+    exit:
+    return 0;
+}
+
+int MainTestContext::hal3appDisplaySensorMenu(uint8_t num_of_cameras)
+{
+    int i, choice;
+    printf("\n");
+    printf("===========================================\n");
+    printf("    Camera Sensor to be used:            \n");
+    printf("===========================================\n\n");
+
+    for ( i=0;i < num_of_cameras; i++) {
+        if (i <= 1) {
+            printf("\n Press %d to select %s", (i), sensor_tbl[i].menu_name);
+        }
+        else {
+            printf("\n Press %d to select Camera%d", (i), i);
+        }
+    }
+    printf("\n Enter your Choice:");
+    fscanf(stdin, "%d", &choice);
+    return choice;
+}
+
+void MainTestContext::hal3appDisplayCapabilityMenu()
+{
+    printf("\n");
+    printf("===========================================\n");
+    printf("      Sensor Capabilty are dumped at location:\n");
+    printf("===========================================\n\n");
+}
+
+int MainTestContext::hal3appDisplayPreviewMenu()
+{
+    int choice;
+    printf("\n");
+    printf("===========================================\n");
+    printf("Select Camera Preview Resolution:\n");
+    printf("===========================================\n\n");
+    printf("========Select Preview Resolutions================\n");
+    printf("\nPress 1 .Aspect Ratio(4:3) Resolution 1440 X 1080");
+    printf("\nPress 2 .Aspect Ratio(16:9) Resolution 1920 X 1080");
+    printf("\n Enter your Choice:");
+    fscanf(stdin, "%d", &choice);
+    return choice;
+}
+
+int MainTestContext::hal3appDisplayVideoMenu()
+{
+    int choice1;
+    printf("\n");
+    printf("===========================================\n");
+    printf("Testing Camera Recording on Different Resolution:\n");
+    printf("===========================================\n\n");
+
+    printf("========Select Video Resolutions================\n");
+    printf("\nPress 1 .Aspect Ratio(4:3) Resolution 640 X 480");
+    printf("\nPress 2 .Aspect Ratio(16:9) Resolution 1920 X 1080");
+    printf("\nPress 3 .To select both");
+
+    printf("\n Enter your Choice:");
+    fscanf(stdin, "%d", &choice1);
+    return choice1;
+}
+
+void MainTestContext::hal3appDisplayRawCaptureMenu()
+{
+    int req_cap;
+    printf("\n");
+    printf("===========================================\n");
+    printf("Testing RAW Camera Capture on Different Resolution::\n");
+    printf("===========================================\n\n");
+}
+
+void MainTestContext::hal3appDisplaySnapshotMenu()
+{
+    int req_cap;
+    printf("\n");
+    printf("===========================================\n");
+    printf("Testing Normal Camera Capture on Resolution 5344 X 4008\n");
+    printf("===========================================\n\n");
+}
+
+
+void MainTestContext::hal3appDisplayExitMenu()
+{
+    printf("\n");
+    printf("===========================================\n");
+    printf("      Exiting HAL3 APP test \n");
+    printf("===========================================\n\n");
+}
+
+int MainTestContext::hal3appPrintMenu()
+{
+    int i, choice = 0;
+    char ch = '0';
+    printf("\n");
+    printf("===========================================\n");
+    printf("       HAL3 MENU \n");
+    printf("===========================================\n\n");
+    for ( i = 0; i < (int)(sizeof(camera_main_menu_tbl)/sizeof(camera_main_menu_tbl[0])); i++) {
+        printf("\n Press %d to select %s", (i+1), camera_main_menu_tbl[i].menu_name);
+    }
+    printf("\n Enter your Choice:");
+    do {
+        std::cin >> ch;
+    } while(!(ch >= '1' && ch <= '9'));
+    choice = ch -'0';
+    return choice;
+}
+}
+
+int main()
+{
+    char tc_buf[3];
+    int mode = 0;
+    int rc = 0;
+    qcamera::MainTestContext main_ctx;
+    printf("Please Select Execution Mode:\n");
+    printf("0: Menu Based 1: Regression\n");
+    printf("\n Enter your choice:");
+    fgets(tc_buf, 3, stdin);
+    mode = tc_buf[0] - '0';
+    if (mode == 0) {
+        printf("\nStarting Menu based!!\n");
+    } else {
+        printf("\nPlease Enter 0 or 1\n");
+        printf("\nExisting the App!!\n");
+        exit(1);
+    }
+    rc = main_ctx.hal3appGetUserEvent();
+    printf("Exiting application\n");
+    return rc;
+}
+
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3MainTestContext.h b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3MainTestContext.h
new file mode 100644
index 0000000..1201cfd
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3MainTestContext.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 __HAL3TEST_H__
+#define __HAL3TEST_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+namespace qcamera {
+
+
+typedef enum
+{
+    MENU_BASE = 0,
+    MENU_START_PREVIEW,
+    MENU_START_VIDEO,
+    MENU_START_CAPTURE,
+    MENU_START_RAW_CAPTURE,
+    MENU_EXIT
+} menu_id;
+
+typedef struct {
+    menu_id base_menu;
+    char *  basemenu_name;
+} HAL3TEST_BASE_MENU_TBL_T;
+
+typedef struct {
+    char * menu_name;
+} HAL3TEST_SENSOR_MENU_TBL_T;
+
+typedef struct {
+    menu_id main_menu;
+    char * menu_name;
+} CAMERA_BASE_MENU_TBL_T;
+
+class CameraHAL3Base;
+class MainTestContext
+{
+    int choice;
+    bool mTestRunning;
+public:
+    MainTestContext();
+    int hal3appGetUserEvent();
+    int hal3appDisplaySensorMenu(uint8_t );
+    void hal3appDisplayCapabilityMenu();
+    int hal3appDisplayPreviewMenu();
+    int hal3appDisplayVideoMenu();
+    void hal3appDisplayRawCaptureMenu();
+    void hal3appDisplaySnapshotMenu();
+    void hal3appDisplayExitMenu();
+    int hal3appPrintMenu();
+};
+
+}
+
+#endif
\ No newline at end of file
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3PreviewTest.cpp b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3PreviewTest.cpp
new file mode 100644
index 0000000..34693ad
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3PreviewTest.cpp
@@ -0,0 +1,206 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "QCameraHAL3PreviewTest.h"
+#include "QCameraHAL3MainTestContext.h"
+
+namespace qcamera {
+extern hal3_camera_lib_test *CamObj_handle;
+int req_sent;
+extern pthread_cond_t mRequestAppCond;
+int test_case_end;
+bool thread_exit;
+extern std::list<uint32_t> PreviewQueue;
+int preview_buffer_allocated;
+extern pthread_mutex_t TestAppLock, mCaptureRequestLock;
+int snapshot_buffer = -1;
+
+
+QCameraHAL3PreviewTest::QCameraHAL3PreviewTest(int camid) :
+    QCameraHAL3Test(0),
+    mPreviewHandle(NULL),
+    mCaptureHandle(NULL),
+    mPreviewStream(NULL),
+    nobuffer(0)
+{
+
+}
+
+void QCameraHAL3PreviewTest::initTest(hal3_camera_lib_test *handle,
+                                int testcase, int camid, int w, int h)
+{
+    int i;
+    CamObj_handle = handle; thread_exit = 0; test_case_end = 0;
+    LOGD("\n buffer thread created %d and %d ", w, h);
+    configurePreviewStream(&(handle->test_obj) , camid, w, h);
+    LOGD("\n preview stream configured");
+    constructDefaultRequest(&(handle->test_obj), camid);
+    LOGD("Default stream setting read ");
+    printf("\npipeline_depth is %d", mPipelineDepthPreview);
+    mPreviewHandle = new native_handle_t *[mPipelineDepthPreview];
+    for (i = 0; i < mPipelineDepthPreview; i++)
+        mPreviewHandle[i] = new native_handle_t;
+    for (i = 0, req_sent = 1; i < mPipelineDepthPreview; i++, req_sent++) {
+        previewAllocateBuffers(width, height, i);
+        PreviewQueue.push_back(i);
+    }
+    LOGD(" Request Number is preview : %d ",mRequest.frame_number);
+    mRequest.frame_number = 0;
+    previewProcessThreadCreate(handle);
+}
+
+void QCameraHAL3PreviewTest::snapshotCaptureRequest(hal3_camera_lib_test *handle,
+        int testcase, int camid, int w, int h)
+{
+    captureRequestRepeat(handle, camid, MENU_START_CAPTURE);
+    pthread_mutex_unlock(&mCaptureRequestLock);
+}
+
+void QCameraHAL3PreviewTest::configurePreviewStream(hal3_camera_test_obj_t *my_test_obj,
+                                int camid, int w, int h)
+{
+    camera3_device_t *device_handle = my_test_obj->device;
+    mPreviewStream =  new camera3_stream_t;
+    memset(mPreviewStream, 0, sizeof(camera3_stream_t));
+    mPreviewStream = initStream(CAMERA3_STREAM_OUTPUT, camid, w, h, 0,
+            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, HAL3_DATASPACE_UNKNOWN);
+
+    mPreviewConfig = configureStream(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE, 1);
+    mPreviewConfig.streams[0] = mPreviewStream;
+    device_handle->ops->configure_streams(my_test_obj->device, &(mPreviewConfig));
+    mPipelineDepthPreview = mPreviewConfig.streams[0]->max_buffers;
+    preview_buffer_allocated = mPipelineDepthPreview;
+}
+
+void QCameraHAL3PreviewTest::constructDefaultRequest(
+        hal3_camera_test_obj_t *my_test_obj, int camid)
+{
+    camera3_device_t *device_handle = my_test_obj->device;
+    mMetaDataPtr[0]= device_handle->ops->construct_default_request_settings(my_test_obj->device,
+            CAMERA3_TEMPLATE_PREVIEW);
+    mMetaDataPtr[1] = device_handle->ops->construct_default_request_settings(my_test_obj->device,
+            CAMERA3_TEMPLATE_STILL_CAPTURE);
+}
+
+void QCameraHAL3PreviewTest::captureRequestRepeat(
+        hal3_camera_lib_test *my_hal3test_obj, int camid, int testcase)
+{
+    struct timeval current_time;
+    int num1, num2;
+    double total_elapsedTime;
+    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
+    camera3_device_t *device_handle = my_test_obj->device;
+    int buffer_id;
+
+    if (testcase == MENU_START_PREVIEW) {
+        if (PreviewQueue.empty()) {
+            LOGE("no preview buffer");
+        }
+        else {
+            if (test_case_end == 0) {
+                LOGD(" Request Number is preview : %d ",mRequest.frame_number);
+                pthread_mutex_lock(&mCaptureRequestLock);
+                num2 = PreviewQueue.front();
+                PreviewQueue.pop_front();
+                num1 = mRequest.frame_number;
+                if (num1 < 2) {
+                    (mRequest).settings = mMetaDataPtr[0];
+                }
+                else {
+                    (mRequest).settings = NULL;
+                }
+                (mRequest).input_buffer = NULL;
+                (mRequest).num_output_buffers = 1;
+                mPreviewStreamBuffs.stream = mPreviewStream;
+                mPreviewStreamBuffs.status = 0;
+                mPreviewStreamBuffs.buffer =
+                        (const native_handle_t**)&mPreviewHandle[num2];
+                mPreviewStreamBuffs.release_fence = -1;
+                mPreviewStreamBuffs.acquire_fence = -1;
+                (mRequest).output_buffers = &(mPreviewStreamBuffs);
+                LOGD("Calling HAL3APP repeat capture request %d and %d and free buffer :%d "
+                        , num1, num2, PreviewQueue.size());
+
+                device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
+                (mRequest.frame_number)++;
+                pthread_mutex_unlock(&mCaptureRequestLock);
+            }
+        }
+    }
+    else {
+        snapshot_buffer = mRequest.frame_number;
+        (mRequest).settings = mMetaDataPtr[1];
+        mSnapshotStreamBuffs = hal3appGetStreamBuffs(mSnapshotStream);
+        mSnapshotStreamBuffs.buffer = (const native_handle_t**)&mCaptureHandle;
+        mRequest = hal3appGetRequestSettings(&mSnapshotStreamBuffs, 1);
+        LOGD("Calling snap HAL3APP repeat capture request repeat %d  ", snapshot_buffer);
+        device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
+        (mRequest.frame_number)++;
+    }
+}
+
+void QCameraHAL3PreviewTest::previewTestEnd(
+        hal3_camera_lib_test *my_hal3test_obj, int camid)
+{
+    buffer_thread_msg_t msg;
+    test_case_end = 1;
+    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
+    camera3_device_t *device_handle = my_test_obj->device;
+    device_handle->ops->flush(my_test_obj->device);
+    LOGD("%s Closing Camera", __func__);
+    ioctl(mPreviewMeminfo.ion_fd, ION_IOC_FREE, &mPreviewMeminfo.ion_handle);
+    close(mPreviewMeminfo.ion_fd);
+    mPreviewMeminfo.ion_fd = -1;
+    LOGD("%s Closing thread", __func__);
+    thread_exit = 1;
+}
+
+void QCameraHAL3PreviewTest::previewAllocateBuffers(int width, int height, int num)
+{
+    mPreviewHandle[num] = allocateBuffers(width, height, &mPreviewMeminfo);
+}
+
+void QCameraHAL3PreviewTest::snapshotAllocateBuffers(int width, int height)
+{
+    mCaptureHandle = allocateBuffers(width, height, &mCaptureMemInfo);
+}
+
+bool QCameraHAL3PreviewTest::previewProcessThreadCreate(
+        hal3_camera_lib_test *handle)
+{
+    processThreadCreate(this, MENU_START_PREVIEW);
+    return 1;
+}
+
+QCameraHAL3PreviewTest::~QCameraHAL3PreviewTest()
+{
+
+}
+
+}
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3PreviewTest.h b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3PreviewTest.h
new file mode 100644
index 0000000..ae687cd
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3PreviewTest.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 __HAL3APPPREVIEWTEST_H__
+#define __HAL3APPPREVIEWTEST_H__
+
+#include "QCameraHAL3Base.h"
+#include "QCameraHAL3Test.h"
+
+namespace qcamera {
+
+class QCameraHAL3PreviewTest : public QCameraHAL3Test
+{
+private:
+    hal3_camtest_meminfo_t mPreviewMeminfo;
+    native_handle_t **mPreviewHandle;
+    hal3_camtest_meminfo_t mCaptureMemInfo;
+    native_handle_t *mCaptureHandle;
+    const camera_metadata_t *mMetaDataPtr[3];
+    camera3_stream_t *mPreviewStream;
+    camera3_stream_t *mSnapshotStream;
+    camera3_capture_request mRequest;
+    camera3_stream_buffer_t mPreviewStreamBuffs;
+    camera3_stream_buffer_t mSnapshotStreamBuffs;
+    camera3_stream_configuration mPreviewConfig;
+public:
+    int width;
+    int height;
+    int nobuffer;
+    int mPipelineDepthPreview;
+
+    QCameraHAL3PreviewTest(int cameraIndex);
+    void configurePreviewStream(hal3_camera_test_obj_t *my_test_obj, int camid,
+            int w, int h);
+
+    void snapshotCaptureRequest(hal3_camera_lib_test *handle,
+            int testcase, int camid, int w, int h);
+    void constructDefaultRequest(hal3_camera_test_obj_t *, int);
+    void initTest(hal3_camera_lib_test *handle,
+            int testcase, int camid, int w, int h);
+
+    void captureRequestRepeat(hal3_camera_lib_test *, int, int);
+    void previewAllocateBuffers(int,
+            int, int);
+    bool previewProcessThreadCreate(hal3_camera_lib_test *);
+    void previewTestEnd(hal3_camera_lib_test *my_hal3test_obj, int camid);
+    void snapshotAllocateBuffers(int, int );
+    virtual ~QCameraHAL3PreviewTest();
+};
+
+    void * hal3appPreviewProcessBuffers(void *);
+}
+#endif
\ No newline at end of file
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3RawSnapshotTest.cpp b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3RawSnapshotTest.cpp
new file mode 100644
index 0000000..f7e05a4
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3RawSnapshotTest.cpp
@@ -0,0 +1,263 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "QCameraHAL3RawSnapshotTest.h"
+#include "QCameraHAL3MainTestContext.h"
+
+namespace qcamera {
+hal3_camera_lib_test *RawSnapshot_CamObj_handle;
+extern int fcount_captured;
+extern pthread_mutex_t TestAppLock;
+
+QCameraHAL3RawSnapshotTest::QCameraHAL3RawSnapshotTest(int req_cap) :
+    QCameraHAL3Test(0),
+    mRawCaptureHandle(NULL),
+    mRawSnapshotStream(NULL),
+    mRequestedCapture(req_cap)
+{
+
+}
+
+void QCameraHAL3RawSnapshotTest::initTest(hal3_camera_lib_test *handle,
+        int testcase, int camid, int w, int h)
+{
+    int i; fcount_captured = 0;
+    RawSnapshot_CamObj_handle = handle;
+    LOGD("\n Raw buffer thread created");
+    configureRawSnapshotStream(&(handle->test_obj), camid, w, h);
+    constructDefaultRequest(&(handle->test_obj), 0);
+    LOGD("\n Raw Snapshot Default stream setting read");
+    rawProcessThreadCreate(MENU_START_RAW_CAPTURE,
+            rawProcessBuffers);
+    mRequest.frame_number = 0;
+    LOGD("\nRaw  Snapshot stream configured");
+    rawProcessCaptureRequest(&(handle->test_obj), 0);
+    LOGD("\nRaw  Snapshot Process Capture Request Sent");
+}
+
+void QCameraHAL3RawSnapshotTest::constructDefaultRequest(
+        hal3_camera_test_obj_t *my_test_obj, int camid)
+{
+    camera3_device_t *device_handle = my_test_obj->device;
+    mMetaDataPtr[0] = device_handle->ops->construct_default_request_settings(
+            my_test_obj->device, CAMERA3_TEMPLATE_PREVIEW);
+    mMetaDataPtr[1] = device_handle->ops->construct_default_request_settings(
+            my_test_obj->device, CAMERA3_TEMPLATE_STILL_CAPTURE);
+}
+
+void QCameraHAL3RawSnapshotTest::configureRawSnapshotStream(hal3_camera_test_obj_t *my_test_obj,
+                                    int camid, int w, int h)
+{
+    camera3_stream_t *r_stream, *p_stream;
+    camera3_device_t *device_handle = my_test_obj->device;
+    mPreviewStream = new camera3_stream_t;
+    mRawSnapshotStream = new camera3_stream_t;
+
+    memset(mPreviewStream, 0, sizeof(camera3_stream_t));
+    memset(mRawSnapshotStream, 0, sizeof(camera3_stream_t));
+
+    mPreviewStream = initStream(CAMERA3_STREAM_OUTPUT, camid, PREVIEW_WIDTH, PREVIEW_HEIGHT, 0,
+            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, HAL3_DATASPACE_UNKNOWN);
+    mRawSnapshotStream = initStream(CAMERA3_STREAM_OUTPUT, camid, RAWSNAPSHOT_CAPTURE_WIDTH,
+            RAWSNAPSHOT_CAPTURE_HEIGHT, 0, HAL_PIXEL_FORMAT_RAW16, HAL3_DATASPACE_ARBITRARY);
+    mRawSnapshotConfig = configureStream(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE, 2);
+
+    mRawSnapshotConfig.streams[0] = mPreviewStream;
+    mRawSnapshotConfig.streams[1] = mRawSnapshotStream;
+    device_handle->ops->configure_streams(my_test_obj->device, &(mRawSnapshotConfig));
+}
+
+
+void QCameraHAL3RawSnapshotTest::rawProcessCaptureRequest(
+        hal3_camera_test_obj_t *my_test_obj, int camid)
+{
+    int width, height;
+    static int num = 1;
+
+    camera3_device_t *device_handle = my_test_obj->device;
+    width = mRawSnapshotStream->width;
+    height = mRawSnapshotStream->height;
+    rawAllocateBuffers(width, height);
+    mRequest.frame_number = 0;
+    mRequest.settings = mMetaDataPtr[1];
+    mRequest.input_buffer = NULL;
+    mRequest.num_output_buffers = 1;
+    mRawSnapshotStreamBuffs.stream = mRawSnapshotStream;
+    mRawSnapshotStreamBuffs.status = 0;
+    mRawSnapshotStreamBuffs.buffer = (const native_handle_t**)&mRawCaptureHandle;
+    mRawSnapshotStreamBuffs.release_fence = -1;
+    mRawSnapshotStreamBuffs.acquire_fence = -1;
+    mRequest.output_buffers = &(mRawSnapshotStreamBuffs);
+    LOGD("Calling HAL3APP capture request ");
+    device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
+}
+
+void QCameraHAL3RawSnapshotTest::rawProcessCaptureRequestRepeat(
+        hal3_camera_lib_test *my_hal3test_obj, int camid)
+{
+    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
+    LOGD("\nRaw Requested Capture : %d and Received Capture : %d",
+            mRequestedCapture, fcount_captured);
+    if (mRequestedCapture == fcount_captured) {
+        LOGD("\n Raw Snapshot is running successfully Ending test");
+        fflush(stdout);
+        LOGD("\n Capture Done , Recieved Frame : %d", fcount_captured);
+        rawTestEnd(my_hal3test_obj, camid);
+    }
+    else {
+        camera3_device_t *device_handle = my_test_obj->device;
+        (mRequest.frame_number)++;
+        mRequest.settings = mMetaDataPtr[1];
+        mRequest.input_buffer = NULL;
+        mRequest.num_output_buffers = 1;
+        mRawSnapshotStreamBuffs.stream = mRawSnapshotStream;
+        mRawSnapshotStreamBuffs.buffer = (const native_handle_t**)&mRawCaptureHandle;
+        mRawSnapshotStreamBuffs.release_fence = -1;
+        mRawSnapshotStreamBuffs.acquire_fence = -1;
+        mRequest.output_buffers = &(mRawSnapshotStreamBuffs);
+        LOGD("Calling HAL3APP repeat capture request repeat ");
+        device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
+    }
+}
+
+void QCameraHAL3RawSnapshotTest::rawTestEnd(
+        hal3_camera_lib_test *my_hal3test_obj, int camid)
+{
+    buffer_thread_msg_t msg;
+    extern pthread_mutex_t gCamLock;
+    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
+    camera3_device_t *device_handle = my_test_obj->device;
+    device_handle->ops->flush(my_test_obj->device);
+    LOGD("%s Closing Camera", __func__);
+    /* Free the Allocated ION Memory */
+    ioctl(mRawCaptureMemInfo.ion_fd, ION_IOC_FREE, &mRawCaptureMemInfo.ion_handle);
+    close(mRawCaptureMemInfo.ion_fd);
+    mRawCaptureMemInfo.ion_fd = -1;
+    /* Close the Thread */
+    memset(&msg, 0, sizeof(buffer_thread_msg_t));
+    msg.stop_thread = 1;
+    write(pfd[1], &msg, sizeof(buffer_thread_msg_t));
+}
+
+
+void QCameraHAL3RawSnapshotTest::rawAllocateBuffers(int width, int height)
+{
+    mRawCaptureHandle = allocateBuffers(width, height, &mRawCaptureMemInfo);
+}
+
+bool QCameraHAL3RawSnapshotTest::rawProcessThreadCreate(int testcase_id,
+        void *(*hal3_thread_ops)(void *))
+{
+    int32_t ret = 0;
+    buffer_thread_t thread;
+    pthread_attr_t attr;
+    if (pipe(pfd) < 0) {
+        LOGE("%s: Error in creating the pipe", __func__);
+    }
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_mutex_init(&thread.mutex, NULL);
+    pthread_cond_init(&thread.cond, NULL);
+    thread.is_thread_started = 0;
+    thread.readfd = pfd[0];
+    thread.writefd = pfd[1];
+    thread.data_obj = this;
+    ret = pthread_create(&thread.td, &attr, hal3_thread_ops, &thread );
+    pthread_setname_np(thread.td, "TestApp_Thread");
+    if (ret < 0) {
+        LOGE("Failed to create status thread");
+        return 0;
+    }
+    pthread_mutex_lock(&thread.mutex);
+    while(thread.is_thread_started == 0) {
+        pthread_cond_wait(&thread.cond, &thread.mutex);
+    }
+    pthread_mutex_unlock(&thread.mutex);
+    return 1;
+}
+
+void QCameraHAL3RawSnapshotTest::captureRequestRepeat(
+        hal3_camera_lib_test *my_hal3test_obj, int camid, int testcase)
+{
+}
+
+void * rawProcessBuffers(void *data) {
+    buffer_thread_t *thread = (buffer_thread_t*)data;
+    int32_t readfd, writefd;
+    hal3_camera_lib_test *hal3_test_handle;
+    pthread_mutex_lock(&thread->mutex);
+    thread->is_thread_started = 1;
+    readfd = thread->readfd;
+    writefd = thread->writefd;
+    QCameraHAL3RawSnapshotTest *obj;
+    obj = (QCameraHAL3RawSnapshotTest *)thread->data_obj;
+    pthread_cond_signal(&thread->cond);
+    pthread_mutex_unlock(&thread->mutex);
+    struct pollfd pollfds;
+    int32_t num_of_fds = 1;
+    bool rthread_exit = 0;
+    int32_t ready = 0;
+    pollfds.fd = readfd;
+    pollfds.events = POLLIN | POLLPRI;
+    while(!rthread_exit) {
+        ready = poll(&pollfds, (nfds_t)num_of_fds, -1);
+        if (ready > 0) {
+            if (pollfds.revents & (POLLIN | POLLPRI)) {
+                ssize_t nread = 0;
+                buffer_thread_msg_t msg;
+                nread = read(pollfds.fd, &msg, sizeof(buffer_thread_msg_t));
+                if (nread < 0) {
+                    LOGE("Unable to read the message");
+                }
+                if (msg.stop_thread) {
+                    break;
+                }
+                hal3_test_handle = RawSnapshot_CamObj_handle;
+                obj->rawProcessCaptureRequestRepeat(hal3_test_handle, 0);
+            }
+        }
+        else {
+            LOGE("Unable to poll exiting the thread");
+            break;
+        }
+    }
+    LOGD("Sensor thread is exiting");
+    close(readfd);
+    close(writefd);
+    pthread_mutex_unlock(&TestAppLock);
+    pthread_exit(0);
+    return NULL;
+}
+
+QCameraHAL3RawSnapshotTest::~QCameraHAL3RawSnapshotTest()
+{
+
+}
+
+}
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3RawSnapshotTest.h b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3RawSnapshotTest.h
new file mode 100644
index 0000000..c92d04a
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3RawSnapshotTest.h
@@ -0,0 +1,69 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 __HAL3APPRAWSNAPSHOT_H__
+#define __HAL3APPRAWSNAPSHOT_H__
+
+#include "QCameraHAL3SnapshotTest.h"
+
+namespace qcamera
+{
+class QCameraHAL3RawSnapshotTest : public QCameraHAL3Test
+{
+private:
+    hal3_camtest_meminfo_t mRawCaptureMemInfo;
+    native_handle_t *mRawCaptureHandle;
+    const camera_metadata_t *mMetaDataPtr[3];
+    camera3_stream_t *mPreviewStream;
+    camera3_stream_t *mRawSnapshotStream;
+    camera3_capture_request mRequest;
+    camera3_stream_buffer_t mRawSnapshotStreamBuffs;
+    camera3_stream_configuration mRawSnapshotConfig;
+public:
+    int mRequestedCapture;
+    QCameraHAL3RawSnapshotTest(int req_cap);
+    void constructDefaultRequest(hal3_camera_test_obj_t *my_test_obj,
+            int camid);
+    void configureRawSnapshotStream(hal3_camera_test_obj_t *my_test_obj,
+            int camid, int, int );
+    void rawProcessCaptureRequest(hal3_camera_test_obj_t *my_test_obj,
+            int camid);
+    void rawProcessCaptureRequestRepeat(hal3_camera_lib_test *my_hal3test_obj,
+            int camid);
+    void initTest(hal3_camera_lib_test *handle, int testcase, int, int, int);
+    bool rawProcessThreadCreate(int testcase_id,
+            void *(*hal3_thread_ops)(void *));
+    void rawAllocateBuffers(int height, int width);
+    void rawTestEnd(hal3_camera_lib_test *my_hal3test_obj, int camid);
+    void captureRequestRepeat(hal3_camera_lib_test *my_hal3test_obj, int camid, int testcase);
+    virtual ~QCameraHAL3RawSnapshotTest();
+};
+    void * rawProcessBuffers(void *data);
+}
+#endif
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3SnapshotTest.cpp b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3SnapshotTest.cpp
new file mode 100644
index 0000000..1ef3c54
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3SnapshotTest.cpp
@@ -0,0 +1,260 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "QCameraHAL3SnapshotTest.h"
+#include "QCameraHAL3MainTestContext.h"
+
+
+namespace qcamera {
+
+hal3_camera_lib_test *Snapshot_CamObj_handle;
+int fcount_captured;
+extern pthread_mutex_t TestAppLock;
+QCameraHAL3SnapshotTest::QCameraHAL3SnapshotTest(int req_cap) :
+    QCameraHAL3Test(0),
+    mCaptureHandle(NULL),
+    mSnapshotStream(NULL),
+    mRequestedCapture(req_cap)
+{
+
+}
+
+void QCameraHAL3SnapshotTest::initTest(hal3_camera_lib_test *handle,
+        int testcase, int camid, int w, int h)
+{
+    int i;
+    fcount_captured = 0;
+    Snapshot_CamObj_handle = handle;
+    configureSnapshotStream(&(handle->test_obj), camid, w, h);
+
+    constructDefaultRequest(&(handle->test_obj), 0);
+    LOGD("\n Snapshot Default stream setting read");
+
+    LOGD("\n Snapshot stream configured");
+    snapshotThreadCreate(MENU_START_CAPTURE, hal3appSnapshotProcessBuffers);
+    (mRequest.frame_number) = 0;
+    snapshotProcessCaptureRequest(&(handle->test_obj), 0);
+    LOGD("\n Snapshot Process Capture Request Sent");
+}
+
+void QCameraHAL3SnapshotTest::constructDefaultRequest(
+        hal3_camera_test_obj_t *my_test_obj, int camid)
+{
+    camera3_device_t *device_handle = my_test_obj->device;
+    mMetaDataPtr[0]= device_handle->ops->construct_default_request_settings(my_test_obj->device,
+            CAMERA3_TEMPLATE_PREVIEW);
+    mMetaDataPtr[1] = device_handle->ops->construct_default_request_settings(my_test_obj->device,
+            CAMERA3_TEMPLATE_STILL_CAPTURE);
+}
+
+void QCameraHAL3SnapshotTest::configureSnapshotStream(hal3_camera_test_obj_t *my_test_obj,
+        int camid, int w, int h)
+{
+    camera3_stream_t *s_stream, *p_stream;
+    camera3_device_t *device_handle = my_test_obj->device;
+    mPreviewStream = new camera3_stream_t;
+    mSnapshotStream = new camera3_stream_t;
+
+    memset(mPreviewStream, 0, sizeof(camera3_stream_t));
+    memset(mSnapshotStream, 0, sizeof(camera3_stream_t));
+    mPreviewStream = initStream(CAMERA3_STREAM_OUTPUT, camid, PREVIEW_WIDTH, PREVIEW_HEIGHT, 0,
+            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, HAL3_DATASPACE_UNKNOWN);
+    mSnapshotStream = initStream(CAMERA3_STREAM_OUTPUT, camid, SNAPSHOT_CAPTURE_WIDTH,
+            SNAPSHOT_CAPTURE_HEIGHT, 0, HAL_PIXEL_FORMAT_BLOB, HAL3_DATASPACE_JFIF);
+
+    mSnapshotConfig = configureStream(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE, 2);
+    mSnapshotConfig.streams[0] = mPreviewStream;
+    mSnapshotConfig.streams[1] = mSnapshotStream;
+    device_handle->ops->configure_streams(my_test_obj->device, &(mSnapshotConfig));
+}
+
+void QCameraHAL3SnapshotTest::snapshotProcessCaptureRequest(
+                hal3_camera_test_obj_t *my_test_obj, int camid)
+{
+    int width, height;
+    camera3_device_t *device_handle = my_test_obj->device;
+    width = mSnapshotStream->width;
+    height = mSnapshotStream->height;
+    snapshotAllocateBuffers(width, height);
+    mRequest.settings = mMetaDataPtr[1];
+    mRequest.input_buffer = NULL;
+    mRequest.num_output_buffers = 1;
+    mSnapshotStreamBuffs.stream = mSnapshotStream;
+    mSnapshotStreamBuffs.status = 0;
+    mSnapshotStreamBuffs.buffer = (const native_handle_t**)&mCaptureHandle;
+    mSnapshotStreamBuffs.release_fence = -1;
+    mSnapshotStreamBuffs.acquire_fence = -1;
+    mRequest.output_buffers = &(mSnapshotStreamBuffs);
+    LOGD("Calling HAL3APP capture request ");
+    device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
+    (mRequest.frame_number)++;
+}
+
+void QCameraHAL3SnapshotTest::snapshotProcessCaptureRequestRepeat(
+                    hal3_camera_lib_test *my_hal3test_obj, int camid)
+{
+    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
+    LOGD("\nSnapshot Requested Capture : %d and Received Capture : %d",
+            mRequestedCapture, fcount_captured);
+    if (mRequestedCapture == fcount_captured) {
+        LOGD("\n Snapshot is running successfully Ending test");
+        fflush(stdout);
+        LOGD("\n Capture Done , Recieved Frame : %d", fcount_captured);
+        snapshotTestEnd(my_hal3test_obj, camid);
+    }
+    else {
+        camera3_device_t *device_handle = my_test_obj->device;
+        mRequest.settings = mMetaDataPtr[1];
+        mRequest.input_buffer = NULL;
+        mRequest.num_output_buffers = 1;
+        mSnapshotStreamBuffs.stream = mSnapshotStream;
+        mSnapshotStreamBuffs.buffer = (const native_handle_t**)&mCaptureHandle;
+        mSnapshotStreamBuffs.release_fence = -1;
+        mSnapshotStreamBuffs.acquire_fence = -1;
+        mRequest.output_buffers = &(mSnapshotStreamBuffs);
+        LOGD("Calling HAL3APP repeat capture request repeat %d and %d",
+                mRequestedCapture, fcount_captured);
+        device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
+        (mRequest.frame_number)++;
+    }
+}
+
+void QCameraHAL3SnapshotTest::snapshotTestEnd(
+        hal3_camera_lib_test *my_hal3test_obj, int camid)
+{
+    buffer_thread_msg_t msg;
+    extern pthread_mutex_t gCamLock;
+    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
+    camera3_device_t *device_handle = my_test_obj->device;
+    device_handle->ops->flush(my_test_obj->device);
+    LOGD("%s Closing Camera", __func__);
+    ioctl(mCaptureMemInfo.ion_fd, ION_IOC_FREE, &mCaptureMemInfo.ion_handle);
+    close(mCaptureMemInfo.ion_fd);
+    mCaptureMemInfo.ion_fd = -1;
+    memset(&msg, 0, sizeof(buffer_thread_msg_t));
+    msg.stop_thread = 1;
+    write(pfd[1], &msg, sizeof(buffer_thread_msg_t));
+}
+
+void QCameraHAL3SnapshotTest::snapshotAllocateBuffers(int width, int height)
+{
+    mCaptureHandle= allocateBuffers(width, height, &mCaptureMemInfo);
+}
+
+bool QCameraHAL3SnapshotTest::snapshotThreadCreate(int testcase_id,
+                void *(*hal3_thread_ops)(void *))
+{
+    int32_t ret = 0;
+    buffer_thread_t thread;
+    pthread_attr_t attr;
+    if (pipe(pfd) < 0) {
+        LOGE("%s: Error in creating the pipe", __func__);
+    }
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_mutex_init(&thread.mutex, NULL);
+    pthread_cond_init(&thread.cond, NULL);
+    thread.is_thread_started = 0;
+    thread.readfd = pfd[0];
+    thread.writefd = pfd[1];
+    thread.data_obj = this;
+    ret = pthread_create(&thread.td, &attr, hal3_thread_ops, &thread );
+    pthread_setname_np(thread.td, "TestApp_Thread");
+    if (ret < 0) {
+        LOGE("Failed to create status thread");
+        return 0;
+    }
+    pthread_mutex_lock(&thread.mutex);
+    while(thread.is_thread_started == 0) {
+        pthread_cond_wait(&thread.cond, &thread.mutex);
+    }
+    pthread_mutex_unlock(&thread.mutex);
+    return 1;
+}
+
+void * hal3appSnapshotProcessBuffers(void *data)
+{
+    buffer_thread_t *thread = (buffer_thread_t*)data;
+    int32_t readfd, writefd;
+    hal3_camera_lib_test *hal3_test_handle;
+    pthread_mutex_lock(&thread->mutex);
+    thread->is_thread_started = 1;
+    readfd = thread->readfd;
+    writefd = thread->writefd;
+    QCameraHAL3SnapshotTest *obj;
+    obj = (QCameraHAL3SnapshotTest *)thread->data_obj;
+    pthread_cond_signal(&thread->cond);
+    pthread_mutex_unlock(&thread->mutex);
+    struct pollfd pollfds;
+    int32_t num_of_fds = 1;
+    bool sthread_exit = 0;
+    int32_t ready = 0;
+    pollfds.fd = readfd;
+    pollfds.events = POLLIN | POLLPRI;
+    while(!sthread_exit) {
+        ready = poll(&pollfds, (nfds_t)num_of_fds, -1);
+        if (ready > 0) {
+            LOGD("Got some events");
+            if (pollfds.revents & (POLLIN | POLLPRI)) {
+                ssize_t nread = 0;
+                buffer_thread_msg_t msg;
+                nread = read(pollfds.fd, &msg, sizeof(buffer_thread_msg_t));
+                if (nread < 0) {
+                    LOGE("Unable to read the message");
+                }
+                if (msg.stop_thread) {
+                    break;
+                }
+                hal3_test_handle = Snapshot_CamObj_handle;
+                obj->snapshotProcessCaptureRequestRepeat(hal3_test_handle, 0);
+            }
+        }
+        else {
+            LOGE("Unable to poll exiting the thread");
+            break;
+        }
+    }
+    LOGD("Sensor thread is exiting");
+    close(readfd);
+    close(writefd);
+    pthread_mutex_unlock(&TestAppLock);
+    pthread_exit(0);
+    return NULL;
+}
+
+void QCameraHAL3SnapshotTest::captureRequestRepeat(
+        hal3_camera_lib_test *my_hal3test_obj, int camid, int testcase)
+{
+}
+
+QCameraHAL3SnapshotTest::~QCameraHAL3SnapshotTest()
+{
+
+}
+
+}
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3SnapshotTest.h b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3SnapshotTest.h
new file mode 100644
index 0000000..e52a21e
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3SnapshotTest.h
@@ -0,0 +1,69 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 __HAL3APPSNAPSHOT_H__
+#define __HAL3APPSNAPSHOT_H__
+
+#include "QCameraHAL3VideoTest.h"
+
+namespace qcamera
+{
+class QCameraHAL3SnapshotTest : public QCameraHAL3Test
+{
+private:
+    hal3_camtest_meminfo_t mCaptureMemInfo;
+    native_handle_t *mCaptureHandle;
+    const camera_metadata_t *mMetaDataPtr[3];
+    camera3_stream_t *mPreviewStream;
+    camera3_stream_t *mSnapshotStream;
+    camera3_capture_request mRequest;
+    camera3_stream_buffer_t mSnapshotStreamBuffs;
+    camera3_stream_configuration mSnapshotConfig;
+public:
+    int mRequestedCapture;
+    QCameraHAL3SnapshotTest(int req_cap);
+    void constructDefaultRequest(hal3_camera_test_obj_t *, int );
+    void configureSnapshotStream(hal3_camera_test_obj_t *, int,
+            int w, int h);
+    void snapshotProcessCaptureRequest(hal3_camera_test_obj_t *my_test_obj,
+            int camid);
+    void snapshotAllocateBuffers(int, int );
+    void initTest(hal3_camera_lib_test *my_test_obj,
+            int testcase, int camid, int w, int h);
+    bool snapshotThreadCreate(int testcase_id, void * (*hal3_thread_ops)(void *));
+    void snapshotProcessCaptureRequestRepeat(hal3_camera_lib_test *my_hal3test_obj,
+            int camid);
+    void captureRequestRepeat(hal3_camera_lib_test *my_hal3test_obj, int camid, int testcase);
+    void snapshotTestEnd(hal3_camera_lib_test *my_hal3test_obj, int camid);
+    virtual ~QCameraHAL3SnapshotTest();
+};
+
+    void * hal3appSnapshotProcessBuffers(void *data);
+}
+
+#endif
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Test.cpp b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Test.cpp
new file mode 100644
index 0000000..fc27a34
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Test.cpp
@@ -0,0 +1,216 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "QCameraHAL3Test.h"
+#include "QCameraHAL3Base.h"
+
+namespace qcamera {
+hal3_camera_lib_test *CamObj_handle;
+extern bool thread_exit;
+extern int test_case_end;
+buffer_thread_t thread;
+extern pthread_cond_t mRequestAppCond;
+extern pthread_mutex_t TestAppLock, mCaptureRequestLock;
+
+camera3_stream_t *QCameraHAL3Test::initStream(int streamtype,
+        int camid, int w, int h, int usage, int format, int dataspace)
+{
+    requested_stream =  new camera3_stream_t;
+    memset(requested_stream, 0, sizeof(camera3_stream_t));
+
+    requested_stream->stream_type = streamtype;
+    requested_stream->width = w;
+    requested_stream->height = h;
+    requested_stream->format = format;
+    requested_stream->usage = usage;
+    requested_stream->data_space = (android_dataspace_t)dataspace;
+    requested_stream->rotation = CAMERA3_STREAM_ROTATION_0;
+    return requested_stream;
+}
+
+QCameraHAL3Test::QCameraHAL3Test(int id)
+{
+    mCamId = id;
+}
+
+camera3_stream_configuration QCameraHAL3Test::configureStream(
+        int opmode, int num_streams)
+{
+    int i;
+    camera3_stream_configuration requested_config;
+    requested_config.operation_mode  = opmode;
+    requested_config.num_streams = num_streams;
+    requested_config.streams = new camera3_stream_t *[num_streams];
+    return requested_config;
+}
+
+
+camera3_stream_buffer_t QCameraHAL3Test::hal3appGetStreamBuffs(camera3_stream_t *req_stream)
+{
+    camera3_stream_buffer_t stream_buffs;
+    stream_buffs.stream = req_stream;
+    stream_buffs.release_fence = -1;
+    stream_buffs.acquire_fence = -1;
+    return stream_buffs;
+}
+
+camera3_capture_request QCameraHAL3Test::hal3appGetRequestSettings(
+        camera3_stream_buffer_t *stream_buffs, int num_buffer)
+{
+    camera3_capture_request request_settings;
+    request_settings.input_buffer = NULL;
+    request_settings.num_output_buffers = 1;
+    request_settings.output_buffers = stream_buffs;
+    return request_settings;
+}
+
+native_handle_t *QCameraHAL3Test::allocateBuffers(int width, int height,
+        hal3_camtest_meminfo_t *req_meminfo)
+{
+    struct ion_handle_data handle_data;
+    struct ion_allocation_data alloc;
+    struct ion_fd_data ion_info_fd;
+    int main_ion_fd = -1, rc;
+    size_t buf_size;
+    void *data = NULL;
+    native_handle_t *nh_test;
+    main_ion_fd = open("/dev/ion", O_RDONLY);
+    if (main_ion_fd <= 0) {
+        LOGE("Ion dev open failed %s\n", strerror(errno));
+        return NULL;
+    }
+    memset(&alloc, 0, sizeof(alloc));
+    buf_size = (size_t)(width * height *2);
+    alloc.len = (size_t)(buf_size);
+    alloc.len = (alloc.len + 4095U) & (~4095U);
+    alloc.align = 4096;
+    alloc.flags = ION_FLAG_CACHED;
+    alloc.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
+    rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
+    if (rc < 0) {
+        LOGE("ION allocation failed %s with rc = %d \n", strerror(errno), rc);
+        return NULL;
+    }
+    memset(&ion_info_fd, 0, sizeof(ion_info_fd));
+    ion_info_fd.handle = alloc.handle;
+    rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
+    if (rc < 0) {
+        LOGE("ION map failed %s\n", strerror(errno));
+        return NULL;
+    }
+    req_meminfo->ion_fd = main_ion_fd;
+    req_meminfo->ion_handle = ion_info_fd.handle;
+    LOGD("%s ION FD %d len %d\n", __func__, ion_info_fd.fd, alloc.len);
+    nh_test = native_handle_create(2, 4);
+    nh_test->data[0] = ion_info_fd.fd;
+    nh_test->data[1] = 0;
+    nh_test->data[2] = 0;
+    nh_test->data[3] = 0;
+    nh_test->data[4] = alloc.len;
+    nh_test->data[5] = 0;
+    return nh_test;
+}
+
+void QCameraHAL3Test::captureRequestRepeat(
+        hal3_camera_lib_test *my_hal3test_obj, int camid, int testcase)
+{
+
+}
+
+bool QCameraHAL3Test::processThreadCreate(
+        void *obj, int testcase)
+{
+    int32_t ret = 0;
+    pthread_attr_t attr;
+    if (pipe(pfd) < 0) {
+        LOGE("%s: Error in creating the pipe", __func__);
+    }
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_mutex_init(&thread.mutex, NULL);
+    pthread_cond_init(&thread.cond, NULL);
+    pthread_cond_init(&mRequestAppCond, NULL);
+    thread.is_thread_started = 0;
+    thread.readfd = pfd[0];
+    thread.writefd = pfd[1];
+    thread.data_obj = obj;
+    thread.testcase = testcase;
+    pthread_mutex_lock(&thread.mutex);
+    ret = pthread_create(&thread.td, &attr, processBuffers, &thread );
+    pthread_setname_np(thread.td, "TestApp_Thread");
+    if (ret < 0) {
+        LOGE("Failed to create status thread");
+        return 0;
+    }
+    pthread_mutex_unlock(&thread.mutex);
+    return 1;
+}
+
+void * processBuffers(void *data) {
+    buffer_thread_t *thread = (buffer_thread_t*)data;
+    int32_t readfd, writefd;
+    int testcase;
+    hal3_camera_lib_test *hal3_test_handle;
+    struct timespec ts1;
+    thread->is_thread_started = 1;
+    readfd = thread->readfd;
+    writefd = thread->writefd;
+    testcase = thread->testcase;
+    QCameraHAL3Test *obj;
+    obj = (QCameraHAL3Test *)thread->data_obj;
+    struct pollfd pollfds;
+    int32_t num_of_fds = 1;
+    int32_t ready = 0;
+    while(!thread_exit) {
+        pthread_mutex_lock(&thread->mutex);
+        clock_gettime(CLOCK_REALTIME, &ts1);
+        ts1.tv_nsec += 10000000L;
+        pthread_cond_timedwait(&mRequestAppCond, &thread->mutex, &ts1);
+        pthread_mutex_unlock(&thread->mutex);
+        hal3_test_handle = CamObj_handle;
+        if (test_case_end == 0) {
+            obj->captureRequestRepeat(hal3_test_handle, 0, testcase);
+        }
+    }
+    LOGD("Sensor thread is exiting");
+    close(readfd);
+    close(writefd);
+    pthread_cond_destroy(&mRequestAppCond);
+    pthread_mutex_unlock(&TestAppLock);
+    pthread_exit(0);
+    return NULL;
+}
+
+QCameraHAL3Test::~QCameraHAL3Test()
+{
+
+}
+
+}
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Test.h b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Test.h
new file mode 100644
index 0000000..8582681
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3Test.h
@@ -0,0 +1,63 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 __HAL3APPTESTINIT_H__
+#define __HAL3APPTESTINIT_H__
+
+#include "QCameraHAL3MainTestContext.h"
+#include "QCameraHAL3Base.h"
+
+namespace qcamera {
+
+class QCameraHAL3Test
+{
+    int mCamId;
+public:
+    QCameraHAL3Test(int cameraIndex);
+    camera3_stream_t *requested_stream;
+    camera3_stream_t *initStream(int streamtype,
+            int camid, int w, int h, int format,int usage,int dataspace);
+
+    camera3_stream_configuration configureStream(
+            int opmode, int num_streams);
+    virtual void captureRequestRepeat(hal3_camera_lib_test *, int, int);
+    camera_metadata_t* hal3appGetDefaultRequest(int type);
+
+    camera3_capture_request hal3appGetRequestSettings(
+            camera3_stream_buffer_t *stream_buffs, int num_buffer);
+    camera3_stream_buffer_t hal3appGetStreamBuffs(camera3_stream_t *req_stream);
+
+    native_handle_t *allocateBuffers(int width, int height,
+            hal3_camtest_meminfo_t *req_meminfo);
+    bool processThreadCreate(void *obj, int testcase);
+    virtual ~QCameraHAL3Test();
+};
+
+    void * processBuffers(void *data);
+}
+#endif
\ No newline at end of file
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3VideoTest.cpp b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3VideoTest.cpp
new file mode 100644
index 0000000..bca887c
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3VideoTest.cpp
@@ -0,0 +1,211 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "QCameraHAL3VideoTest.h"
+#include "QCameraHAL3MainTestContext.h"
+
+namespace qcamera {
+
+extern hal3_camera_lib_test *CamObj_handle;
+buffer_thread_t Video_thread;
+int video_req_sent;
+extern pthread_cond_t mRequestAppCond;
+
+extern int test_case_end;
+extern bool thread_exit;
+extern std::list<uint32_t> VideoQueue;
+int video_buffer_allocated;
+extern pthread_mutex_t TestAppLock, mCaptureRequestLock;
+extern int snapshot_buffer;
+
+
+QCameraHAL3VideoTest::QCameraHAL3VideoTest(int camid) :
+    QCameraHAL3Test(0),
+    mVideoHandle(NULL),
+    mCaptureHandle(NULL),
+    mVideoStream(NULL)
+{
+
+}
+
+void QCameraHAL3VideoTest::initTest(hal3_camera_lib_test *handle,
+        int testcase, int camid, int w, int h)
+{
+    int i;
+    CamObj_handle = handle; thread_exit = 0;
+    test_case_end = 0;
+    LOGD("\n buffer thread created");
+    configureVideoStream(&(handle->test_obj), camid, w, h);
+    LOGD("\n video stream configured");
+    constructDefaultRequest(&(handle->test_obj), camid);
+    LOGD("pipeline_depth is %d", mPipelineDepthVideo);
+    mVideoHandle = new native_handle_t *[mPipelineDepthVideo];
+    for (i = 0; i < mPipelineDepthVideo; i++) {
+        mVideoHandle[i] = new native_handle_t;
+    }
+
+    for (i = 0, video_req_sent = 1; i < mPipelineDepthVideo; i++, video_req_sent++) {
+        vidoeAllocateBuffers(width, height, i);
+        VideoQueue.push_back(i);
+    }
+    LOGD(" Request Number is : %d ",mRequest.frame_number);
+    mRequest.frame_number = 0;
+    videoProcessThreadCreate(handle);
+}
+
+
+void QCameraHAL3VideoTest::snapshotCaptureRequest(hal3_camera_lib_test *handle,
+        int testcase, int camid, int w, int h)
+{
+
+    captureRequestRepeat(handle, camid, MENU_START_CAPTURE);
+    pthread_mutex_unlock(&mCaptureRequestLock);
+}
+
+
+void QCameraHAL3VideoTest::configureVideoStream(hal3_camera_test_obj_t *my_test_obj,
+        int camid, int w, int h)
+{
+    camera3_device_t *device_handle = my_test_obj->device;
+    mVideoStream = new camera3_stream_t;
+    memset(mVideoStream, 0, sizeof(camera3_stream_t));
+    mVideoStream = initStream(CAMERA3_STREAM_OUTPUT, camid, w, h, FLAGS_VIDEO_ENCODER,
+            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, HAL3_DATASPACE_UNKNOWN);
+    mVideoConfig = configureStream(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE, 1);
+    mVideoConfig.streams[0] = mVideoStream;
+
+    device_handle->ops->configure_streams(my_test_obj->device, &(mVideoConfig));
+    mPipelineDepthVideo = mVideoConfig.streams[0]->max_buffers;
+    video_buffer_allocated = mPipelineDepthVideo;
+}
+
+void QCameraHAL3VideoTest::constructDefaultRequest(
+        hal3_camera_test_obj_t *my_test_obj, int camid)
+{
+    camera3_device_t *device_handle = my_test_obj->device;
+    mMetaDataPtr[0] = device_handle->ops->construct_default_request_settings(
+            my_test_obj->device, CAMERA3_TEMPLATE_VIDEO_RECORD);
+    mMetaDataPtr[1] = device_handle->ops->construct_default_request_settings(my_test_obj->device,
+            CAMERA3_TEMPLATE_STILL_CAPTURE);
+}
+
+
+
+void QCameraHAL3VideoTest::captureRequestRepeat(
+        hal3_camera_lib_test *my_hal3test_obj, int camid, int testcase)
+{
+    struct timeval current_time;
+    int num1, num2;
+    double total_elapsedTime;
+    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
+    camera3_device_t *device_handle = my_test_obj->device;
+    if (testcase == MENU_START_VIDEO) {
+        if (VideoQueue.empty()) {
+            LOGE("no Video buffer");
+        }
+        else {
+            if (test_case_end == 0) {
+                LOGD(" Request Number is : %d ", mRequest.frame_number);
+                pthread_mutex_lock(&mCaptureRequestLock);
+                num2 = VideoQueue.front();
+                VideoQueue.pop_front();
+                num1 = mRequest.frame_number;
+                if (num1 < 2) {
+                    (mRequest).settings = mMetaDataPtr[0];
+                }
+                else {
+                    (mRequest).settings = NULL;
+                }
+                (mRequest).input_buffer = NULL;
+                (mRequest).num_output_buffers = 1;
+                mVideoStreamBuffs.stream = mVideoStream;
+                mVideoStreamBuffs.status = 0;
+                mVideoStreamBuffs.buffer =
+                        (const native_handle_t**)&mVideoHandle[num2];
+                mVideoStreamBuffs.release_fence = -1;
+                mVideoStreamBuffs.acquire_fence = -1;
+                (mRequest).output_buffers = &(mVideoStreamBuffs);
+                LOGD("Calling HAL3APP repeat capture request %d and %d and free buffer :%d "
+                        , num1, num2, VideoQueue.size());
+                device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
+                        (mRequest.frame_number)++;
+                pthread_mutex_unlock(&mCaptureRequestLock);
+            }
+        }
+    }
+    else {
+        snapshot_buffer = mRequest.frame_number;
+        (mRequest).settings = mMetaDataPtr[1];
+        mSnapshotStreamBuffs = hal3appGetStreamBuffs(mSnapshotStream);
+        mSnapshotStreamBuffs.buffer = (const native_handle_t**)&mCaptureHandle;
+        mRequest = hal3appGetRequestSettings(&mSnapshotStreamBuffs, 1);
+        LOGD("Calling snap HAL3APP repeat capture request repeat %d  ", snapshot_buffer);
+        device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
+        (mRequest.frame_number)++;
+    }
+}
+
+void QCameraHAL3VideoTest::videoTestEnd(
+                    hal3_camera_lib_test *my_hal3test_obj, int camid)
+{
+    buffer_thread_msg_t msg;
+    test_case_end = 1;
+    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
+    camera3_device_t *device_handle = my_test_obj->device;
+    device_handle->ops->flush(my_test_obj->device);
+    LOGD("%s Closing Camera", __func__);
+    ioctl(mVideoMeminfo.ion_fd, ION_IOC_FREE, &mVideoMeminfo.ion_handle);
+    close(mVideoMeminfo.ion_fd);
+    mVideoMeminfo.ion_fd = -1;
+    LOGD("%s Closing thread", __func__);
+    thread_exit = 1;
+}
+
+void QCameraHAL3VideoTest::vidoeAllocateBuffers(int height, int width, int num)
+{
+    mVideoHandle[num] = allocateBuffers(width, height, &mVideoMeminfo);
+}
+
+void QCameraHAL3VideoTest::snapshotAllocateBuffers(int width, int height)
+{
+    mCaptureHandle = allocateBuffers(width, height, &mCaptureMemInfo);
+}
+
+bool QCameraHAL3VideoTest::videoProcessThreadCreate(
+                    hal3_camera_lib_test *handle) {
+    processThreadCreate(this, MENU_START_VIDEO);
+    return 1;
+}
+
+QCameraHAL3VideoTest::~QCameraHAL3VideoTest()
+{
+
+}
+
+}
diff --git a/msmcobalt/QCamera2/HAL3/test/QCameraHAL3VideoTest.h b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3VideoTest.h
new file mode 100644
index 0000000..b4d609a
--- /dev/null
+++ b/msmcobalt/QCamera2/HAL3/test/QCameraHAL3VideoTest.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 __HAL3APPVIDEOTEST_H__
+#define __HAL3APPVIDEOTEST_H__
+
+#include "QCameraHAL3Base.h"
+#include "QCameraHAL3Test.h"
+
+
+namespace qcamera {
+
+
+class QCameraHAL3VideoTest : public QCameraHAL3Test
+{
+
+private:
+    hal3_camtest_meminfo_t mVideoMeminfo;
+    native_handle_t **mVideoHandle;
+    hal3_camtest_meminfo_t mCaptureMemInfo;
+    native_handle_t *mCaptureHandle;
+    const camera_metadata_t *mMetaDataPtr[3];
+    camera3_stream_t *mVideoStream;
+    camera3_stream_t *mSnapshotStream;
+    camera3_capture_request mRequest;
+    camera3_stream_buffer_t mVideoStreamBuffs;
+    camera3_stream_buffer_t mSnapshotStreamBuffs;
+    camera3_stream_configuration mVideoConfig;
+public:
+    int width;
+    int height;
+    int nobuffer;
+    int mPipelineDepthVideo;
+
+    QCameraHAL3VideoTest(int cameraIndex);
+
+    void configureVideoStream(hal3_camera_test_obj_t *,
+            int, int, int);
+    void snapshotCaptureRequest(hal3_camera_lib_test *handle,int testcase,
+            int camid, int w, int h);
+
+    void constructDefaultRequest(hal3_camera_test_obj_t *,
+            int);
+
+    void captureRequestRepeat(hal3_camera_lib_test *, int, int);
+    void initTest(hal3_camera_lib_test *handle, int testcase, int camid,
+            int w, int h);
+    void vidoeAllocateBuffers(int, int, int);
+
+    bool videoProcessThreadCreate(hal3_camera_lib_test *);
+    void videoTestEnd(hal3_camera_lib_test *my_hal3test_obj, int camid);
+    void snapshotAllocateBuffers(int, int );
+    virtual ~QCameraHAL3VideoTest();
+};
+
+    void * hal3appVideoProcessBuffers(void *);
+}
+
+#endif
diff --git a/msmcobalt/QCamera2/stack/common/cam_intf.h b/msmcobalt/QCamera2/stack/common/cam_intf.h
index 54fcb6f..da442c5 100644
--- a/msmcobalt/QCamera2/stack/common/cam_intf.h
+++ b/msmcobalt/QCamera2/stack/common/cam_intf.h
@@ -283,6 +283,11 @@
     size_t zzhdr_sizes_tbl_cnt;                             /* Number of resolutions in zzHDR mode*/
     cam_dimension_t zzhdr_sizes_tbl[MAX_SIZES_CNT];         /* Table for ZZHDR supported sizes */
 
+    size_t supported_quadra_cfa_dim_cnt;              /* Number of resolutions in Quadra CFA mode */
+    cam_dimension_t quadra_cfa_dim[MAX_SIZES_CNT];    /* Table for Quadra CFA supported sizes */
+    cam_format_t quadra_cfa_format;                   /* Quadra CFA output format */
+    uint32_t is_remosaic_lib_present;                 /* Flag indicating if remosaic lib present */
+
     /* supported preview formats */
     size_t supported_preview_fmt_cnt;
     cam_format_t supported_preview_fmts[CAM_FORMAT_MAX];
@@ -544,6 +549,14 @@
 
     /* Dual cam calibration data */
     cam_related_system_calibration_data_t related_cam_calibration;
+
+    /* Meta_RAW capability */
+    uint8_t meta_raw_channel_count;
+    uint8_t vc[MAX_SIZES_CNT];
+    uint8_t dt[MAX_SIZES_CNT];
+    cam_format_t supported_meta_raw_fmts[CAM_FORMAT_MAX];
+    cam_dimension_t raw_meta_dim[MAX_SIZES_CNT];
+    cam_sub_format_type_t sub_fmt[CAM_FORMAT_SUBTYPE_MAX];
 } cam_capability_t;
 
 typedef enum {
@@ -656,6 +669,16 @@
 
     /* if frames will not be received */
     uint8_t noFrameExpected;
+
+    /* DT for this stream */
+    int32_t dt;
+
+    /* VC for this stream */
+    int32_t vc;
+
+   /* Subformat for this stream */
+    cam_sub_format_type_t sub_format_type;
+
 } cam_stream_info_t;
 
 /*****************************************************************************
@@ -928,6 +951,10 @@
     INCLUDE(CAM_INTF_META_TOUCH_AE_RESULT,              int32_t,                     1);
     INCLUDE(CAM_INTF_PARM_DUAL_LED_CALIBRATION,         int32_t,                     1);
     INCLUDE(CAM_INTF_PARM_ADV_CAPTURE_MODE,             uint8_t,                     1);
+    INCLUDE(CAM_INTF_PARM_QUADRA_CFA,                   int32_t,                     1);
+    INCLUDE(CAM_INTF_META_RAW,                          cam_dimension_t,             1);
+    INCLUDE(CAM_INTF_META_STREAM_INFO_FOR_PIC_RES,      cam_stream_size_info_t,      1);
+
 
     /* HAL3 specific */
     INCLUDE(CAM_INTF_META_STREAM_INFO,                  cam_stream_size_info_t,      1);
@@ -980,6 +1007,7 @@
     INCLUDE(CAM_INTF_PARM_INSTANT_AEC,                  uint8_t,                     1);
     INCLUDE(CAM_INTF_META_REPROCESS_FLAGS,              uint8_t,                     1);
     INCLUDE(CAM_INTF_PARM_JPEG_ENCODE_CROP,             cam_stream_crop_info_t,      1);
+    INCLUDE(CAM_INTF_PARM_JPEG_SCALE_DIMENSION,         cam_dimension_t,             1);
 } metadata_data_t;
 
 /* Update clear_metadata_buffer() function when a new is_xxx_valid is added to
diff --git a/msmcobalt/QCamera2/stack/common/cam_types.h b/msmcobalt/QCamera2/stack/common/cam_types.h
index 0bd0fa5..38c1435 100644
--- a/msmcobalt/QCamera2/stack/common/cam_types.h
+++ b/msmcobalt/QCamera2/stack/common/cam_types.h
@@ -109,6 +109,7 @@
 #define MAX_INFLIGHT_REQUESTS  6
 #define MAX_INFLIGHT_BLOB      3
 #define MIN_INFLIGHT_REQUESTS  3
+#define MIN_INFLIGHT_60FPS_REQUESTS (6)
 #define MAX_INFLIGHT_REPROCESS_REQUESTS 1
 #define MAX_INFLIGHT_HFR_REQUESTS (48)
 #define MIN_INFLIGHT_HFR_REQUESTS (40)
@@ -285,6 +286,9 @@
     CAM_FORMAT_JPEG_RAW_8BIT,
     CAM_FORMAT_META_RAW_8BIT,
 
+    /* generic 10-bit raw */
+    CAM_FORMAT_META_RAW_10BIT,
+
     /* QCOM RAW formats where data is packed into 64bit word.
      * 14BPP: 1 64-bit word contains 4 pixels p0 - p3, where most
      *       significant 4 bits are set to 0. P0 is stored at LSB.
@@ -364,6 +368,12 @@
 } cam_format_t;
 
 typedef enum {
+    CAM_FORMAT_SUBTYPE_HDR_STATS,
+    CAM_FORMAT_SUBTYPE_PDAF_STATS,
+    CAM_FORMAT_SUBTYPE_MAX
+} cam_sub_format_type_t;
+
+typedef enum {
     CAM_STREAM_TYPE_DEFAULT,       /* default stream type */
     CAM_STREAM_TYPE_PREVIEW,       /* preview */
     CAM_STREAM_TYPE_POSTVIEW,      /* postview */
@@ -884,9 +894,9 @@
 
 typedef enum {
     IS_TYPE_NONE,
+    IS_TYPE_CROP,
     IS_TYPE_DIS,
     IS_TYPE_GA_DIS,
-    IS_TYPE_EIS_1_0,
     IS_TYPE_EIS_2_0,
     IS_TYPE_EIS_3_0,
     IS_TYPE_MAX
@@ -1248,12 +1258,24 @@
 } cam_faces_data_t;
 
 #define CAM_HISTOGRAM_STATS_SIZE 256
+
+typedef enum {
+  CAM_STATS_CHANNEL_Y,
+  CAM_STATS_CHANNEL_GR,
+  CAM_STATS_CHANNEL_GB,
+  CAM_STATS_CHANNEL_R,
+  CAM_STATS_CHANNEL_B,
+  CAM_STATS_CHANNEL_ALL,
+  CAM_STATS_CHANNEL_MAX
+} cam_histogram_data_type;
+
 typedef struct {
     uint32_t max_hist_value;
     uint32_t hist_buf[CAM_HISTOGRAM_STATS_SIZE]; /* buf holding histogram stats data */
 } cam_histogram_data_t;
 
 typedef struct {
+    cam_histogram_data_type data_type;
     cam_histogram_data_t r_stats;
     cam_histogram_data_t b_stats;
     cam_histogram_data_t gr_stats;
@@ -1626,9 +1648,11 @@
     uint32_t min_scanline;
     uint8_t batch_size;
     cam_sync_type_t sync_type;
+    uint32_t dt[MAX_NUM_STREAMS];
+    uint32_t vc[MAX_NUM_STREAMS];
+    cam_sub_format_type_t sub_format_type[MAX_NUM_STREAMS];
 } cam_stream_size_info_t;
 
-
 typedef enum {
     CAM_INTF_OVERWRITE_MINI_CHROMATIX_OFFLINE,
     CAM_INTF_OVERWRITE_ISP_HW_DATA_OFFLINE,
@@ -2170,6 +2194,15 @@
     CAM_INTF_META_REPROCESS_FLAGS,
     /* Param of cropping information for JPEG encoder */
     CAM_INTF_PARM_JPEG_ENCODE_CROP,
+    /* Param of scaling information for JPEG encoder */
+    CAM_INTF_PARM_JPEG_SCALE_DIMENSION,
+    /*Param for updating Quadra CFA mode */
+    CAM_INTF_PARM_QUADRA_CFA,
+    /* Meta Raw Dim */
+    CAM_INTF_META_RAW,
+    /* Number of streams and size of streams in
+       current configuration for pic res*/
+    CAM_INTF_META_STREAM_INFO_FOR_PIC_RES,
     CAM_INTF_PARM_MAX
 } cam_intf_parm_type_t;
 
@@ -2391,11 +2424,13 @@
 #define CAM_QTI_FEATURE_SW_TNR          ((cam_feature_mask_t)1UL<<30)
 #define CAM_QCOM_FEATURE_METADATA_PROCESSING ((cam_feature_mask_t)1UL<<31)
 #define CAM_QCOM_FEATURE_PAAF           (((cam_feature_mask_t)1UL)<<32)
+#define CAM_QCOM_FEATURE_QUADRA_CFA     (((cam_feature_mask_t)1UL)<<33)
+#define CAM_QTI_FEATURE_PPEISCORE       (((cam_feature_mask_t)1UL)<<34)
 #define CAM_QCOM_FEATURE_PP_SUPERSET    (CAM_QCOM_FEATURE_DENOISE2D|CAM_QCOM_FEATURE_CROP|\
                                          CAM_QCOM_FEATURE_ROTATION|CAM_QCOM_FEATURE_SHARPNESS|\
                                          CAM_QCOM_FEATURE_SCALE|CAM_QCOM_FEATURE_CAC|\
                                          CAM_QCOM_FEATURE_EZTUNE|CAM_QCOM_FEATURE_CPP_TNR|\
-                                         CAM_QCOM_FEATURE_LLVD)
+                                         CAM_QCOM_FEATURE_LLVD|CAM_QCOM_FEATURE_QUADRA_CFA)
 
 #define CAM_QCOM_FEATURE_PP_PASS_1      CAM_QCOM_FEATURE_PP_SUPERSET
 #define CAM_QCOM_FEATURE_PP_PASS_2      CAM_QCOM_FEATURE_SCALE | CAM_QCOM_FEATURE_CROP;
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
index fd90e83..70b91a8 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
@@ -3585,6 +3585,7 @@
     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GRBG:
     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_RGGB:
     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_BGGR:
+    case CAM_FORMAT_META_RAW_10BIT:
     case CAM_FORMAT_BAYER_IDEAL_RAW_MIPI_10BPP_GREY:
         /* Every 64 pixels occupy 80 bytes */
         stride = PAD_TO_SIZE(dim->width, CAM_PAD_TO_4);
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/inc/mm_qcamera_app.h b/msmcobalt/QCamera2/stack/mm-camera-test/inc/mm_qcamera_app.h
index 1b94ea8..a78a332 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/inc/mm_qcamera_app.h
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/inc/mm_qcamera_app.h
@@ -240,6 +240,7 @@
     int32_t reproc_sharpness;
     cam_denoise_param_t reproc_wnr;
     int8_t enable_CAC;
+    int8_t enable_EZTune;
     mm_camera_queue_t pp_frames;
     mm_camera_stream_t *reproc_stream;
     metadata_buffer_t *metadata;
@@ -315,6 +316,7 @@
     MM_CAMERA_LIB_FPS_RANGE,
     MM_CAMERA_LIB_WNR_ENABLE,
     MM_CAMERA_LIB_SET_TINTLESS,
+    MM_CAMERA_LIB_EZTUNE_ENABLE,
 } mm_camera_lib_commands;
 
 typedef struct {
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/inc/mm_qcamera_main_menu.h b/msmcobalt/QCamera2/stack/mm-camera-test/inc/mm_qcamera_main_menu.h
index 1b9eb4e..faf9453 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/inc/mm_qcamera_main_menu.h
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/inc/mm_qcamera_main_menu.h
@@ -56,7 +56,7 @@
   SET_TINTLESS_DISABLE,
   SET_EXP_METERING,
   GET_CTRL_VALUE,
-  TOGGLE_AFR,
+  TOGGLE_EZTUNE,
   SET_ISO,
   BRIGHTNESS_GOTO_SUBMENU,
   CONTRAST_GOTO_SUBMENU,
@@ -88,6 +88,7 @@
   ACTION_SET_EXP_METERING,
   ACTION_GET_CTRL_VALUE,
   ACTION_TOGGLE_AFR,
+  ACTION_TOGGLE_EZTUNE,
   ACTION_SET_ISO,
   ACTION_BRIGHTNESS_INCREASE,
   ACTION_BRIGHTNESS_DECREASE,
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
index e7a2afb..5d845b4 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
@@ -1555,7 +1555,11 @@
     return rc;
 }
 
-
+int setEZTune(mm_camera_test_obj_t *test_obj, uint8_t enable)
+{
+    test_obj->enable_EZTune = enable;
+    return 0;
+}
 /** tuneserver_capture
  *    @lib_handle: the camera handle object
  *    @dim: snapshot dimensions
@@ -1878,14 +1882,26 @@
     camera_cap = (cam_capability_t *) handle->test_obj.cap_buf.mem_info.data;
 
     switch(cmd) {
-        case MM_CAMERA_LIB_FPS_RANGE:
-            if ( NULL != in_data ) {
-                cam_fps_range_t range = *(( cam_fps_range_t * )in_data);
-                rc = setFPSRange(&handle->test_obj, range);
-                if (rc != MM_CAMERA_OK) {
-                        LOGE("setFPSRange() err=%d\n",
+        case MM_CAMERA_LIB_EZTUNE_ENABLE:
+            if ( NULL != in_data) {
+                int enable_eztune = *(( int * )in_data);
+                if ( ( enable_eztune != handle->test_obj.enable_EZTune) &&
+                        handle->stream_running ) {
+                    rc = mm_camera_lib_stop_stream(handle);
+                    if (rc != MM_CAMERA_OK) {
+                        LOGE("mm_camera_lib_stop_stream() err=%d\n",
                                     rc);
                         goto EXIT;
+                    }
+                    handle->test_obj.enable_EZTune= enable_eztune;
+                    rc = mm_camera_lib_start_stream(handle);
+                    if (rc != MM_CAMERA_OK) {
+                        LOGE("mm_camera_lib_start_stream() err=%d\n",
+                                    rc);
+                        goto EXIT;
+                    }
+                } else {
+                    handle->test_obj.enable_EZTune= enable_eztune;
                 }
             }
             break;
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_main_menu.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_main_menu.c
index 0865c6f..29c2cd0 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_main_menu.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_main_menu.c
@@ -83,14 +83,14 @@
 #define CAMERA_SHARPNESS_STEP 1
 
 const CAMERA_MAIN_MENU_TBL_T camera_main_menu_tbl[] = {
-  {START_PREVIEW,               "Start preview"},
+  {START_PREVIEW,              "Start preview"},
   {STOP_PREVIEW,               "Stop preview/video"},
   {SET_WHITE_BALANCE,          "Set white balance mode"},
   {SET_TINTLESS_ENABLE,        "Set Tintless Enable"},
   {SET_TINTLESS_DISABLE,       "Set Tintless Disable"},
   {SET_EXP_METERING,           "Set exposure metering mode"},
   {GET_CTRL_VALUE,             "Get control value menu"},
-  {TOGGLE_AFR,                 "Toggle auto frame rate. Default fixed frame rate"},
+  {TOGGLE_EZTUNE,              "Toggle EZtune. Default EZTune Off"},
   {SET_ISO,                    "ISO changes."},
   {BRIGHTNESS_GOTO_SUBMENU,    "Brightness changes."},
   {CONTRAST_GOTO_SUBMENU,      "Contrast changes."},
@@ -243,6 +243,8 @@
 int contrast = CAMERA_DEF_CONTRAST;
 int saturation = CAMERA_DEF_SATURATION;
 int sharpness = CAMERA_DEF_SHARPNESS;
+int ev_numerator = 0;
+
 #else
 int brightness = 0;
 int contrast = 0;
@@ -345,9 +347,9 @@
           next_menu_id = MENU_ID_SATURATIONCHANGE;
           break;
 
-        case TOGGLE_AFR:
-          * action_id_ptr = ACTION_TOGGLE_AFR;
-          LOGD("next_menu_id = MENU_ID_TOGGLEAFR = %d\n", next_menu_id);
+        case TOGGLE_EZTUNE:
+          * action_id_ptr = ACTION_TOGGLE_EZTUNE;
+          LOGD("next_menu_id = MENU_ID_TOGGLE EZTUNE = %d\n", next_menu_id);
           break;
 
         case SET_ISO:
@@ -996,27 +998,20 @@
  * DESCRIPTION:
  * ===========================================================================*/
 
-int increase_EV (void) {
-#if 0
-   int rc = 0;
-   int32_t value = 0;
-   rc = cam_config_is_parm_supported(cam_id, MM_CAMERA_PARM_EXPOSURE_COMPENSATION);
-    if(!rc) {
-       printf("MM_CAMERA_PARM_EXPOSURE_COMPENSATION mode is not supported for this sensor");
-       return -1;
-    }
-    ev_numerator += 1;
+int increase_EV (mm_camera_lib_handle *lib_handle) {
+
+    ev_numerator += 4;
     if(ev_numerator >= EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR &&
             ev_numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){
-        int16_t  numerator16 = (int16_t)(ev_numerator & 0x0000ffff);
-        uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR;
-        value = numerator16 << 16 | denominator16;
+
     } else {
        printf("Reached max EV.\n");
     }
-    return mm_app_set_config_parm(cam_id, MM_CAMERA_PARM_EXPOSURE_COMPENSATION, value);
-#endif
-  return 0;
+    printf("Increase EV to %d\n", ev_numerator);
+    return mm_camera_lib_send_command(lib_handle,
+                                       MM_CAMERA_LIB_EV,
+                                       &ev_numerator,
+                                       NULL);
 }
 
 /*===========================================================================
@@ -1024,27 +1019,21 @@
  *
  * DESCRIPTION:
  * ===========================================================================*/
-int decrease_EV (void) {
-#if 0
-   int rc = 0;
-   int32_t  value = 0;
-   rc = cam_config_is_parm_supported(cam_id, MM_CAMERA_PARM_EXPOSURE_COMPENSATION);
-    if(!rc) {
-       printf("MM_CAMERA_PARM_EXPOSURE_COMPENSATION mode is not supported for this sensor");
-       return -1;
-    }
-    ev_numerator -= 1;
+int decrease_EV (mm_camera_lib_handle *lib_handle) {
+
+    ev_numerator -= 4;
     if(ev_numerator >= EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR &&
             ev_numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){
-        int16_t  numerator16 = (int16_t)(ev_numerator & 0x0000ffff);
-        uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR;
-        value = numerator16 << 16 | denominator16;
+
     } else {
        printf("Reached min EV.\n");
     }
-    return mm_app_set_config_parm(cam_id, MM_CAMERA_PARM_EXPOSURE_COMPENSATION, value);
-#endif
-  return 0;
+    printf("Decrease EV to %d\n", ev_numerator);
+    return mm_camera_lib_send_command(lib_handle,
+                                       MM_CAMERA_LIB_EV,
+                                       &ev_numerator,
+                                       NULL);
+
 }
 
 /*===========================================================================
@@ -1304,7 +1293,6 @@
 #endif
   return 0;
 }
-
 int set_zoom (mm_camera_lib_handle *lib_handle, int zoom_action_param) {
 
     if (zoom_action_param == ZOOM_IN) {
@@ -1662,6 +1650,7 @@
     int action_param;
     uint8_t previewing = 0;
     int isZSL = 0;
+    int isezTune = 0;
     uint8_t wnr_enabled = 0;
     mm_camera_lib_handle lib_handle;
     int num_cameras;
@@ -1722,9 +1711,6 @@
             goto ERROR;
         }
     }
-    /*start the eztune server*/
-    LOGH("Starting eztune Server \n");
-    eztune_server_start(&lib_handle);
 
     do {
         print_current_menu (current_menu_id);
@@ -1823,12 +1809,12 @@
 
             case ACTION_EV_INCREASE:
                 LOGD("Selection for the EV increase\n");
-                increase_EV ();
+                increase_EV (&lib_handle);
                 break;
 
             case ACTION_EV_DECREASE:
                 LOGD("Selection for the EV decrease\n");
-                decrease_EV ();
+                decrease_EV (&lib_handle);
                 break;
 
             case ACTION_SATURATION_INCREASE:
@@ -1846,6 +1832,26 @@
                 toggle_afr();
                 break;
 
+            case ACTION_TOGGLE_EZTUNE:
+                LOGE("Select for EzTune");
+                printf("EZTUNE Toggle\n");
+                isezTune = !isezTune;
+                if (isezTune) {
+                    printf("EZ TUNE On !!!");
+                } else {
+                    printf("EZ TUNE Off !!!");
+                }
+
+                rc = mm_camera_lib_send_command(&lib_handle,
+                                      MM_CAMERA_LIB_EZTUNE_ENABLE,
+                                      &isezTune,
+                                      NULL);
+                if (rc != MM_CAMERA_OK) {
+                    LOGE("mm_camera_lib_send_command() err=%d\n",  rc);
+                    goto ERROR;
+                }
+                break;
+
             case ACTION_SET_ISO:
                 LOGD("Select for ISO changes\n");
                 set_iso(&lib_handle, action_param);
@@ -1976,24 +1982,20 @@
                 snap_dim.height = dimension_tbl[action_param].height;
                 break;
 
-      case ACTION_START_RECORDING:
-        LOGD("Start recording action\n");
-#if 0
-        if (mm_app_start_video(cam_id) < 0)
-          goto ERROR;
-        is_rec = 1;
-#endif
-        break;
-      case ACTION_STOP_RECORDING:
-        LOGD("Stop recording action\n");
-#if 0
-        if(is_rec) {
-          if (mm_app_stop_video(cam_id) < 0)
-            goto ERROR;
-          is_rec = 0;
-        }
-#endif
-        break;
+           case ACTION_START_RECORDING:
+             LOGD("Start recording action\n");
+             mm_app_start_record_preview(&lib_handle.test_obj);
+             is_rec = 1;
+             break;
+
+           case ACTION_STOP_RECORDING:
+             LOGD("Stop recording action\n");
+             if(is_rec) {
+                 mm_app_stop_record_preview(&lib_handle.test_obj);
+                 is_rec = 0;
+             }
+
+             break;
       case ACTION_TAKE_LIVE_SNAPSHOT:
         printf("Selection for live shot\n");
 #if 0
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
index ce9d632..46596bc 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
@@ -602,13 +602,6 @@
     cam_dimension_t preview_dim = {0, 0};
     cam_dimension_t analysis_dim = {0, 0};
 
-
-    stream = mm_app_add_stream(test_obj, channel);
-    if (NULL == stream) {
-        LOGE("add stream failed\n");
-        return NULL;
-    }
-
     if ((test_obj->preview_resolution.user_input_display_width == 0) ||
            ( test_obj->preview_resolution.user_input_display_height == 0)) {
         preview_dim.width = DEFAULT_PREVIEW_WIDTH;
@@ -626,6 +619,12 @@
         return NULL;
     }
 
+    stream = mm_app_add_stream(test_obj, channel);
+    if (NULL == stream) {
+        LOGE("add stream failed\n");
+        return NULL;
+    }
+
     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
     stream->s_config.mem_vtbl.clean_invalidate_buf =
@@ -653,6 +652,74 @@
 
     return stream;
 }
+mm_camera_stream_t * mm_app_add_ZSL_preview_stream(mm_camera_test_obj_t *test_obj,
+                                               mm_camera_channel_t *channel,
+                                               mm_camera_buf_notify_t stream_cb,
+                                               void *userdata,
+                                               uint8_t num_bufs)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_stream_t *stream = NULL;
+    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
+    cam_dimension_t preview_dim = {0, 0};
+    cam_dimension_t analysis_dim = {0, 0};
+
+    if ((test_obj->preview_resolution.user_input_display_width == 0) ||
+           ( test_obj->preview_resolution.user_input_display_height == 0)) {
+        preview_dim.width = DEFAULT_PREVIEW_WIDTH;
+        preview_dim.height = DEFAULT_PREVIEW_HEIGHT;
+    } else {
+        preview_dim.width = test_obj->preview_resolution.user_input_display_width;
+        preview_dim.height = test_obj->preview_resolution.user_input_display_height;
+    }
+    LOGI("preview dimesion: %d x %d\n",  preview_dim.width, preview_dim.height);
+
+    analysis_dim = mm_app_get_analysis_stream_dim(test_obj, &preview_dim);
+    LOGI("analysis stream dimesion: %d x %d\n",
+            analysis_dim.width, analysis_dim.height);
+
+    uint32_t analysis_pp_mask = cam_cap->qcom_supported_feature_mask &
+                                        (CAM_QCOM_FEATURE_SHARPNESS |
+                                         CAM_QCOM_FEATURE_EFFECT |
+                                         CAM_QCOM_FEATURE_DENOISE2D);
+    LOGI("analysis stream pp mask:%x\n",  analysis_pp_mask);
+
+    stream = mm_app_add_stream(test_obj, channel);
+    if (NULL == stream) {
+        LOGE("add stream failed\n");
+        return NULL;
+    }
+    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
+    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+      mm_app_stream_clean_invalidate_buf;
+    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
+    stream->s_config.mem_vtbl.user_data = (void *)stream;
+    stream->s_config.stream_cb = stream_cb;
+    stream->s_config.stream_cb_sync = NULL;
+    stream->s_config.userdata = userdata;
+    stream->num_of_bufs = num_bufs;
+
+    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
+    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
+    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
+    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
+    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
+
+    stream->s_config.stream_info->dim.width = preview_dim.width;
+    stream->s_config.stream_info->dim.height = preview_dim.height;
+
+    stream->s_config.padding_info = cam_cap->padding_info;
+
+    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
+    if (MM_CAMERA_OK != rc) {
+        LOGE("config preview stream err=%d\n",  rc);
+        return NULL;
+    }
+
+    return stream;
+}
+
 
 mm_camera_stream_t * mm_app_add_preview_stream(mm_camera_test_obj_t *test_obj,
                                                mm_camera_channel_t *channel,
@@ -689,16 +756,22 @@
     cam_stream_size_info_t abc ;
     memset (&abc , 0, sizeof (cam_stream_size_info_t));
 
-    abc.num_streams = 2;
+    if (analysis_dim.width != 0 && analysis_dim.height != 0) {
+      abc.num_streams = 2;
+    } else {
+      abc.num_streams = 1;
+    }
     abc.postprocess_mask[0] = 2178;
     abc.stream_sizes[0].width = preview_dim.width;
     abc.stream_sizes[0].height = preview_dim.height;
     abc.type[0] = CAM_STREAM_TYPE_PREVIEW;
 
-    abc.postprocess_mask[1] = analysis_pp_mask;
-    abc.stream_sizes[1].width = analysis_dim.width;
-    abc.stream_sizes[1].height = analysis_dim.height;
-    abc.type[1] = CAM_STREAM_TYPE_ANALYSIS;
+    if (analysis_dim.width != 0 && analysis_dim.height != 0) {
+      abc.postprocess_mask[1] = analysis_pp_mask;
+      abc.stream_sizes[1].width = analysis_dim.width;
+      abc.stream_sizes[1].height = analysis_dim.height;
+      abc.type[1] = CAM_STREAM_TYPE_ANALYSIS;
+    }
 
     abc.buffer_info.min_buffers = 10;
     abc.buffer_info.max_buffers = 10;
@@ -731,6 +804,10 @@
     stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
 
+    if (test_obj->enable_EZTune) {
+        stream->s_config.stream_info->pp_config.feature_mask = CAM_QCOM_FEATURE_EZTUNE;
+    }
+
     stream->s_config.stream_info->dim.width = preview_dim.width;
     stream->s_config.stream_info->dim.height = preview_dim.height;
 
@@ -823,6 +900,88 @@
     return stream;
 }
 
+mm_camera_stream_t * mm_app_add_ZSL_snapshot_stream(mm_camera_test_obj_t *test_obj,
+                                                mm_camera_channel_t *channel,
+                                                mm_camera_buf_notify_t stream_cb,
+                                                void *userdata,
+                                                uint8_t num_bufs,
+                                                uint8_t num_burst)
+{
+  int rc = MM_CAMERA_OK;
+    mm_camera_stream_t *stream = NULL;
+    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
+    cam_stream_size_info_t abc_snap ;
+    memset (&abc_snap , 0, sizeof (cam_stream_size_info_t));
+
+    abc_snap.num_streams = 2;
+    abc_snap.postprocess_mask[1] = 2178;
+    abc_snap.stream_sizes[1].width = DEFAULT_PREVIEW_WIDTH;
+    abc_snap.stream_sizes[1].height = DEFAULT_PREVIEW_HEIGHT;
+    abc_snap.type[1] = CAM_STREAM_TYPE_PREVIEW;
+
+    abc_snap.postprocess_mask[0] = 0;
+    abc_snap.stream_sizes[0].width = DEFAULT_SNAPSHOT_WIDTH;
+    abc_snap.stream_sizes[0].height = DEFAULT_SNAPSHOT_HEIGHT;
+    abc_snap.type[0] = CAM_STREAM_TYPE_SNAPSHOT;
+
+    abc_snap.buffer_info.min_buffers = 7;
+    abc_snap.buffer_info.max_buffers = 7;
+    abc_snap.is_type[0] = IS_TYPE_NONE;
+
+    rc = setmetainfoCommand(test_obj, &abc_snap);
+    if (rc != MM_CAMERA_OK) {
+       LOGE("meta info command snapshot failed\n");
+    }
+
+    stream = mm_app_add_stream(test_obj, channel);
+    if (NULL == stream) {
+        LOGE("add stream failed\n");
+        return NULL;
+    }
+
+    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
+    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+      mm_app_stream_clean_invalidate_buf;
+    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
+    stream->s_config.mem_vtbl.user_data = (void *)stream;
+    stream->s_config.stream_cb = stream_cb;
+    stream->s_config.stream_cb_sync = NULL;
+    stream->s_config.userdata = userdata;
+    stream->num_of_bufs = num_bufs;
+
+    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
+    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
+    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
+    if (num_burst == 0) {
+        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
+    } else {
+        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
+        stream->s_config.stream_info->num_of_burst = num_burst;
+    }
+    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
+    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
+        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
+        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
+    } else {
+        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
+        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
+    }
+    stream->s_config.padding_info = cam_cap->padding_info;
+    /* Make offset as zero as CPP will not be used  */
+    stream->s_config.padding_info.offset_info.offset_x = 0;
+    stream->s_config.padding_info.offset_info.offset_y = 0;
+
+    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
+    if (MM_CAMERA_OK != rc) {
+        LOGE("config preview stream err=%d\n",  rc);
+        return NULL;
+    }
+
+    return stream;
+}
+
+
 mm_camera_stream_t * mm_app_add_snapshot_stream(mm_camera_test_obj_t *test_obj,
                                                 mm_camera_channel_t *channel,
                                                 mm_camera_buf_notify_t stream_cb,
@@ -891,6 +1050,9 @@
         stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
     }
     stream->s_config.padding_info = cam_cap->padding_info;
+    /* Make offset as zero as CPP will not be used  */
+    stream->s_config.padding_info.offset_info.offset_x = 0;
+    stream->s_config.padding_info.offset_info.offset_y = 0;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
     if (MM_CAMERA_OK != rc) {
@@ -1059,7 +1221,19 @@
         return -MM_CAMERA_E_GENERAL;
     }
 
-    s_preview = mm_app_add_preview_stream(test_obj,
+
+    s_main = mm_app_add_ZSL_snapshot_stream(test_obj,
+                                        channel,
+                                        mm_app_snapshot_notify_cb,
+                                        (void *)test_obj,
+                                        PREVIEW_BUF_NUM,
+                                        0);
+    if (NULL == s_main) {
+        LOGE("add main snapshot stream failed\n");
+        mm_app_del_channel(test_obj, channel);
+        return rc;
+    }
+    s_preview = mm_app_add_ZSL_preview_stream(test_obj,
                                           channel,
                                           mm_app_preview_notify_cb,
                                           (void *)test_obj,
@@ -1070,18 +1244,6 @@
         return rc;
     }
 
-    s_main = mm_app_add_snapshot_stream(test_obj,
-                                        channel,
-                                        mm_app_snapshot_notify_cb,
-                                        (void *)test_obj,
-                                        PREVIEW_BUF_NUM,
-                                        0);
-    if (NULL == s_main) {
-        LOGE("add main snapshot stream failed\n");
-        mm_app_del_stream(test_obj, channel, s_preview);
-        mm_app_del_channel(test_obj, channel);
-        return rc;
-    }
 
     s_metadata = mm_app_add_metadata_stream(test_obj,
                                             channel,
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
index b56e6b4..69c09d0 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
@@ -80,7 +80,6 @@
 int encodeData(mm_camera_test_obj_t *test_obj, mm_camera_super_buf_t* recvd_frame,
                mm_camera_stream_t *m_stream)
 {
-    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
 
     int rc = -MM_CAMERA_E_GENERAL;
     mm_jpeg_job_t job;
@@ -101,9 +100,6 @@
     // TODO: Rotation should be set according to
     //       sensor&device orientation
     job.encode_job.rotation = 0;
-    if (cam_cap->position == CAM_POSITION_BACK) {
-        job.encode_job.rotation = 270;
-    }
 
     /* fill in main src img encode param */
     job.encode_job.main_dim.src_dim = m_stream->s_config.stream_info->dim;
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
index ba0a57f..bf07877 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
@@ -31,6 +31,284 @@
 #include "mm_qcamera_app.h"
 #include "mm_qcamera_dbg.h"
 
+static void mm_app_metadata_notify_cb(mm_camera_super_buf_t *bufs,
+                                     void *user_data)
+{
+  uint32_t i = 0;
+  mm_camera_channel_t *channel = NULL;
+  mm_camera_stream_t *p_stream = NULL;
+  mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
+  mm_camera_buf_def_t *frame;
+  metadata_buffer_t *pMetadata;
+
+  if (NULL == bufs || NULL == user_data) {
+      LOGE("bufs or user_data are not valid ");
+      return;
+  }
+  frame = bufs->bufs[0];
+
+  /* find channel */
+  for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
+      if (pme->channels[i].ch_id == bufs->ch_id) {
+          channel = &pme->channels[i];
+          break;
+      }
+  }
+
+  if (NULL == channel) {
+      LOGE("Channel object is NULL ");
+      return;
+  }
+
+  /* find preview stream */
+  for (i = 0; i < channel->num_streams; i++) {
+      if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
+          p_stream = &channel->streams[i];
+          break;
+      }
+  }
+
+  if (NULL == p_stream) {
+      LOGE("cannot find metadata stream");
+      return;
+  }
+
+  /* find preview frame */
+  for (i = 0; i < bufs->num_bufs; i++) {
+      if (bufs->bufs[i]->stream_id == p_stream->s_id) {
+          frame = bufs->bufs[i];
+          break;
+      }
+  }
+
+  if (pme->metadata == NULL) {
+    /* The app will free the meta data, we don't need to bother here */
+    pme->metadata = malloc(sizeof(metadata_buffer_t));
+    if (NULL == pme->metadata) {
+        LOGE("Canot allocate metadata memory\n");
+        return;
+    }
+  }
+  memcpy(pme->metadata, frame->buffer, sizeof(metadata_buffer_t));
+
+  pMetadata = (metadata_buffer_t *)frame->buffer;
+  IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, pMetadata) {
+    if ((cam_af_state_t)(*afState) == CAM_AF_STATE_FOCUSED_LOCKED ||
+            (cam_af_state_t)(*afState) == CAM_AF_STATE_NOT_FOCUSED_LOCKED) {
+        LOGE("AutoFocus Done Call Back Received\n");
+        mm_camera_app_done();
+    } else if ((cam_af_state_t)(*afState) == CAM_AF_STATE_NOT_FOCUSED_LOCKED) {
+        LOGE("AutoFocus failed\n");
+        mm_camera_app_done();
+    }
+  }
+
+  if (pme->user_metadata_cb) {
+      LOGD("[DBG] %s, user defined own metadata cb. calling it...");
+      pme->user_metadata_cb(frame);
+  }
+
+  if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
+                                          bufs->ch_id,
+                                          frame)) {
+      LOGE("Failed in Preview Qbuf\n");
+  }
+  mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
+                   ION_IOC_INV_CACHES);
+}
+
+
+static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
+                                      void *user_data)
+{
+
+    int rc = 0;
+    uint32_t i = 0;
+    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
+    mm_camera_channel_t *channel = NULL;
+    mm_camera_stream_t *p_stream = NULL;
+    mm_camera_stream_t *m_stream = NULL;
+    mm_camera_buf_def_t *p_frame = NULL;
+    mm_camera_buf_def_t *m_frame = NULL;
+
+    /* find channel */
+    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
+        if (pme->channels[i].ch_id == bufs->ch_id) {
+            channel = &pme->channels[i];
+            break;
+        }
+    }
+    if (NULL == channel) {
+        LOGE("Wrong channel id (%d)",  bufs->ch_id);
+        rc = -1;
+        goto error;
+    }
+
+    /* find snapshot stream */
+    for (i = 0; i < channel->num_streams; i++) {
+        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
+            m_stream = &channel->streams[i];
+            break;
+        }
+    }
+    if (NULL == m_stream) {
+        LOGE("cannot find snapshot stream");
+        rc = -1;
+        goto error;
+    }
+
+    /* find snapshot frame */
+    for (i = 0; i < bufs->num_bufs; i++) {
+        if (bufs->bufs[i]->stream_id == m_stream->s_id) {
+            m_frame = bufs->bufs[i];
+            break;
+        }
+    }
+    if (NULL == m_frame) {
+        LOGE("main frame is NULL");
+        rc = -1;
+        goto error;
+    }
+
+    mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx);
+
+    /* find postview stream */
+    for (i = 0; i < channel->num_streams; i++) {
+        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) {
+            p_stream = &channel->streams[i];
+            break;
+        }
+    }
+    if (NULL != p_stream) {
+        /* find preview frame */
+        for (i = 0; i < bufs->num_bufs; i++) {
+            if (bufs->bufs[i]->stream_id == p_stream->s_id) {
+                p_frame = bufs->bufs[i];
+                break;
+            }
+        }
+        if (NULL != p_frame) {
+            mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx);
+        }
+    }
+
+    mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
+                     ION_IOC_CLEAN_INV_CACHES);
+
+    pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
+    if ( NULL == pme->jpeg_buf.buf.buffer ) {
+        LOGE("error allocating jpeg output buffer");
+        goto error;
+    }
+
+    pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
+    /* create a new jpeg encoding session */
+    rc = createEncodingSession(pme, m_stream, m_frame);
+    if (0 != rc) {
+        LOGE("error creating jpeg session");
+        free(pme->jpeg_buf.buf.buffer);
+        goto error;
+    }
+
+    /* start jpeg encoding job */
+    rc = encodeData(pme, bufs, m_stream);
+    if (0 != rc) {
+        LOGE("error creating jpeg session");
+        free(pme->jpeg_buf.buf.buffer);
+        goto error;
+    }
+
+error:
+    /* buf done rcvd frames in error case */
+    if ( 0 != rc ) {
+        for (i=0; i<bufs->num_bufs; i++) {
+            if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
+                                                    bufs->ch_id,
+                                                    bufs->bufs[i])) {
+                LOGE("Failed in Qbuf\n");
+            }
+            mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info,
+                             ION_IOC_INV_CACHES);
+        }
+    }
+
+    LOGD(" END\n");
+}
+
+static void mm_app_preview_notify_cb(mm_camera_super_buf_t *bufs,
+                                     void *user_data)
+{
+    uint32_t i = 0;
+    mm_camera_channel_t *channel = NULL;
+    mm_camera_stream_t *p_stream = NULL;
+    mm_camera_buf_def_t *frame = NULL;
+    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
+
+    if (NULL == bufs || NULL == user_data) {
+        LOGE("bufs or user_data are not valid ");
+        return;
+    }
+
+    frame = bufs->bufs[0];
+
+    /* find channel */
+    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
+        if (pme->channels[i].ch_id == bufs->ch_id) {
+            channel = &pme->channels[i];
+            break;
+        }
+    }
+    if (NULL == channel) {
+        LOGE("Channel object is NULL ");
+        return;
+    }
+    /* find preview stream */
+    for (i = 0; i < channel->num_streams; i++) {
+        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
+            p_stream = &channel->streams[i];
+            break;
+        }
+    }
+
+    if (NULL == p_stream) {
+        LOGE("cannot find preview stream");
+        return;
+    }
+
+    /* find preview frame */
+    for (i = 0; i < bufs->num_bufs; i++) {
+        if (bufs->bufs[i]->stream_id == p_stream->s_id) {
+            frame = bufs->bufs[i];
+            break;
+        }
+    }
+
+    if ( 0 < pme->fb_fd ) {
+        mm_app_overlay_display(pme, frame->fd);
+    }
+#ifdef DUMP_PRV_IN_FILE
+    {
+        char file_name[64];
+        snprintf(file_name, sizeof(file_name), "P_C%d", pme->cam->camera_handle);
+        mm_app_dump_frame(frame, file_name, "yuv", frame->frame_idx);
+    }
+#endif
+    if (pme->user_preview_cb) {
+        LOGE("[DBG] %s, user defined own preview cb. calling it...");
+        pme->user_preview_cb(frame);
+    }
+    if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
+                bufs->ch_id,
+                frame)) {
+        LOGE("Failed in Preview Qbuf\n");
+    }
+    mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
+            ION_IOC_INV_CACHES);
+
+    LOGD(" END\n");
+}
+
+
 static void mm_app_video_notify_cb(mm_camera_super_buf_t *bufs,
                                    void *user_data)
 {
@@ -54,11 +332,70 @@
     LOGD("END\n");
 }
 
-mm_camera_stream_t * mm_app_add_video_stream(mm_camera_test_obj_t *test_obj,
-                                             mm_camera_channel_t *channel,
-                                             mm_camera_buf_notify_t stream_cb,
-                                             void *userdata,
-                                             uint8_t num_bufs)
+mm_camera_stream_t * mm_app_add_video_preview_stream(mm_camera_test_obj_t *test_obj,
+                                               mm_camera_channel_t *channel,
+                                               mm_camera_buf_notify_t stream_cb,
+                                               void *userdata,
+                                               uint8_t num_bufs)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_stream_t *stream = NULL;
+    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
+    cam_dimension_t preview_dim = {0, 0};
+
+    if ((test_obj->preview_resolution.user_input_display_width == 0) ||
+           ( test_obj->preview_resolution.user_input_display_height == 0)) {
+        preview_dim.width = DEFAULT_PREVIEW_WIDTH;
+        preview_dim.height = DEFAULT_PREVIEW_HEIGHT;
+    } else {
+        preview_dim.width = test_obj->preview_resolution.user_input_display_width;
+        preview_dim.height = test_obj->preview_resolution.user_input_display_height;
+    }
+    LOGI("preview dimesion: %d x %d\n",  preview_dim.width, preview_dim.height);
+
+    stream = mm_app_add_stream(test_obj, channel);
+    if (NULL == stream) {
+        LOGE("add stream failed\n");
+        return NULL;
+    }
+    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
+    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+            mm_app_stream_clean_invalidate_buf;
+    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
+    stream->s_config.mem_vtbl.user_data = (void *)stream;
+    stream->s_config.stream_cb = stream_cb;
+    stream->s_config.stream_cb_sync = NULL;
+    stream->s_config.userdata = userdata;
+    stream->num_of_bufs = num_bufs;
+
+    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
+    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
+    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
+    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
+    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
+
+    stream->s_config.stream_info->dim.width = preview_dim.width;
+    stream->s_config.stream_info->dim.height = preview_dim.height;
+
+    stream->s_config.padding_info = cam_cap->padding_info;
+
+    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
+    if (MM_CAMERA_OK != rc) {
+        LOGE("config preview stream err=%d\n",  rc);
+        return NULL;
+    }
+
+    return stream;
+}
+
+
+mm_camera_stream_t * mm_app_add_video_snapshot_stream(mm_camera_test_obj_t *test_obj,
+                                                mm_camera_channel_t *channel,
+                                                mm_camera_buf_notify_t stream_cb,
+                                                void *userdata,
+                                                uint8_t num_bufs,
+                                                uint8_t num_burst)
 {
     int rc = MM_CAMERA_OK;
     mm_camera_stream_t *stream = NULL;
@@ -83,11 +420,99 @@
 
     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
+    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
+    if (num_burst == 0) {
+        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
+    } else {
+        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
+        stream->s_config.stream_info->num_of_burst = num_burst;
+    }
+    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
+    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
+        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
+        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
+    } else {
+        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
+        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
+    }
+    stream->s_config.padding_info = cam_cap->padding_info;
+    /* Make offset as zero as CPP will not be used  */
+    stream->s_config.padding_info.offset_info.offset_x = 0;
+    stream->s_config.padding_info.offset_info.offset_y = 0;
+
+    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
+    if (MM_CAMERA_OK != rc) {
+        LOGE("config preview stream err=%d\n",  rc);
+        return NULL;
+    }
+
+    return stream;
+
+}
+
+
+mm_camera_stream_t * mm_app_add_video_stream(mm_camera_test_obj_t *test_obj,
+                                             mm_camera_channel_t *channel,
+                                             mm_camera_buf_notify_t stream_cb,
+                                             void *userdata,
+                                             uint8_t num_bufs)
+{
+    int rc = MM_CAMERA_OK;
+    mm_camera_stream_t *stream = NULL;
+    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
+
+    cam_stream_size_info_t abc_snap ;
+    memset (&abc_snap , 0, sizeof (cam_stream_size_info_t));
+
+    abc_snap.num_streams = 3;
+    abc_snap.postprocess_mask[2] = 2178;
+    abc_snap.stream_sizes[2].width = DEFAULT_PREVIEW_WIDTH;
+    abc_snap.stream_sizes[2].height = DEFAULT_PREVIEW_HEIGHT;
+    abc_snap.type[2] = CAM_STREAM_TYPE_PREVIEW;
+
+    abc_snap.postprocess_mask[1] = 2178;
+    abc_snap.stream_sizes[1].width = DEFAULT_PREVIEW_WIDTH;
+    abc_snap.stream_sizes[1].height = DEFAULT_PREVIEW_HEIGHT;
+    abc_snap.type[1] = CAM_STREAM_TYPE_VIDEO;
+
+    abc_snap.postprocess_mask[0] = 0;
+    abc_snap.stream_sizes[0].width = DEFAULT_SNAPSHOT_WIDTH;
+    abc_snap.stream_sizes[0].height = DEFAULT_SNAPSHOT_HEIGHT;
+    abc_snap.type[0] = CAM_STREAM_TYPE_SNAPSHOT;
+
+    abc_snap.buffer_info.min_buffers = 7;
+    abc_snap.buffer_info.max_buffers = 7;
+    abc_snap.is_type[0] = IS_TYPE_NONE;
+
+    rc = setmetainfoCommand(test_obj, &abc_snap);
+    if (rc != MM_CAMERA_OK) {
+       LOGE("meta info command snapshot failed\n");
+    }
+
+    stream = mm_app_add_stream(test_obj, channel);
+    if (NULL == stream) {
+        LOGE("add stream failed\n");
+        return NULL;
+    }
+
+    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
+    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+            mm_app_stream_clean_invalidate_buf;
+    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
+    stream->s_config.mem_vtbl.user_data = (void *)stream;
+    stream->s_config.stream_cb = stream_cb;
+    stream->s_config.stream_cb_sync = NULL;
+    stream->s_config.userdata = userdata;
+    stream->num_of_bufs = num_bufs;
+
+    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
+    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_VIDEO;
     stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
     stream->s_config.stream_info->fmt = DEFAULT_VIDEO_FORMAT;
-    stream->s_config.stream_info->dim.width = DEFAULT_VIDEO_WIDTH;
-    stream->s_config.stream_info->dim.height = DEFAULT_VIDEO_HEIGHT;
+    stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
+    stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
     stream->s_config.padding_info = cam_cap->padding_info;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
@@ -134,29 +559,109 @@
     mm_camera_channel_t *p_ch = NULL;
     mm_camera_channel_t *v_ch = NULL;
     mm_camera_channel_t *s_ch = NULL;
+    mm_camera_stream_t *s_preview = NULL;
+    mm_camera_stream_t *s_metadata = NULL;
+    mm_camera_stream_t *s_main = NULL;
+    mm_camera_stream_t *s_video = NULL;
 
-    p_ch = mm_app_add_preview_channel(test_obj);
-    if (NULL == p_ch) {
-        LOGE("add preview channel failed");
-        return -MM_CAMERA_E_GENERAL;
-    }
 
-    v_ch = mm_app_add_video_channel(test_obj);
+    /* Create Video Channel */
+    v_ch = mm_app_add_channel(test_obj,
+                              MM_CHANNEL_TYPE_VIDEO,
+                              NULL,
+                              NULL,
+                              NULL);
     if (NULL == v_ch) {
-        LOGE("add video channel failed");
-        mm_app_del_channel(test_obj, p_ch);
+        LOGE("add channel failed");
         return -MM_CAMERA_E_GENERAL;
     }
 
-    s_ch = mm_app_add_snapshot_channel(test_obj);
+   /* Add Video Stream */
+    s_video = mm_app_add_video_stream(test_obj,
+                                      v_ch,
+                                      mm_app_video_notify_cb,
+                                      (void*)test_obj,
+                                      VIDEO_BUF_NUM);
+
+    if (NULL == s_video) {
+        LOGE("add video stream failed\n");
+        mm_app_del_channel(test_obj, v_ch);
+        return rc;
+    }
+
+    /* Create Preview Channel */
+    p_ch = mm_app_add_channel(test_obj,
+                              MM_CHANNEL_TYPE_PREVIEW,
+                              NULL,
+                              NULL,
+                              NULL);
+    /* Add Preview stream to Channel */
+    if (NULL == p_ch) {
+        LOGE("add channel failed");
+        return -MM_CAMERA_E_GENERAL;
+    }
+
+
+    s_preview = mm_app_add_video_preview_stream(test_obj,
+                                             p_ch,
+                                             mm_app_preview_notify_cb,
+                                             (void *)test_obj,
+                                             PREVIEW_BUF_NUM);
+    if (NULL == s_preview) {
+        LOGE("add preview stream failed\n");
+        mm_app_del_channel(test_obj, p_ch);
+        return rc;
+    }
+    /* Create Snapshot Channel */
+    s_ch = mm_app_add_channel(test_obj,
+                              MM_CHANNEL_TYPE_SNAPSHOT,
+                              NULL,
+                              NULL,
+                              NULL);
     if (NULL == s_ch) {
-        LOGE("add snapshot channel failed");
+        LOGE("add channel failed");
+        return -MM_CAMERA_E_GENERAL;
+    }
+
+    /* Add Snapshot Stream */
+    s_main = mm_app_add_video_snapshot_stream(test_obj,
+                                           s_ch,
+                                           mm_app_snapshot_notify_cb,
+                                           (void *)test_obj,
+                                           1,
+                                           1);
+    if (NULL == s_main) {
+        LOGE("add main snapshot stream failed\n");
+        mm_app_del_channel(test_obj, s_ch);
+        return rc;
+    }
+
+
+    /* Add Metadata Stream to preview channel */
+    s_metadata = mm_app_add_metadata_stream(test_obj,
+                                            p_ch,
+                                            mm_app_metadata_notify_cb,
+                                            (void *)test_obj,
+                                            PREVIEW_BUF_NUM);
+
+    if (NULL == s_metadata) {
+        LOGE("add metadata stream failed\n");
+        mm_app_del_channel(test_obj, p_ch);
+        return rc;
+    }
+
+    /* Start Preview Channel */
+    rc = mm_app_start_channel(test_obj, p_ch);
+    if (MM_CAMERA_OK != rc) {
+        LOGE("start preview failed rc=%d\n", rc);
         mm_app_del_channel(test_obj, p_ch);
         mm_app_del_channel(test_obj, v_ch);
-        return -MM_CAMERA_E_GENERAL;
+        mm_app_del_channel(test_obj, s_ch);
+        return rc;
     }
 
-    rc = mm_app_start_channel(test_obj, p_ch);
+    /* Start Video Channel */
+    rc = mm_app_start_channel(test_obj, v_ch);
     if (MM_CAMERA_OK != rc) {
         LOGE("start preview failed rc=%d\n", rc);
         mm_app_del_channel(test_obj, p_ch);
diff --git a/msmcobalt/QCamera2/util/QCameraDisplay.h b/msmcobalt/QCamera2/util/QCameraDisplay.h
index bb6d157..97a4003 100644
--- a/msmcobalt/QCamera2/util/QCameraDisplay.h
+++ b/msmcobalt/QCamera2/util/QCameraDisplay.h
@@ -36,7 +36,7 @@
 
 namespace qcamera {
 
-#define CAMERA_NUM_VSYNC_INTERVAL_HISTORY  6
+#define CAMERA_NUM_VSYNC_INTERVAL_HISTORY  8
 #define NSEC_PER_MSEC 1000000LLU
 
 class QCameraDisplay {
diff --git a/msmcobalt/QCamera2/util/QCameraPerf.h b/msmcobalt/QCamera2/util/QCameraPerf.h
index aa3e6be..3f1034e 100644
--- a/msmcobalt/QCamera2/util/QCameraPerf.h
+++ b/msmcobalt/QCamera2/util/QCameraPerf.h
@@ -67,7 +67,6 @@
     bool    isTimerReset();
     void    powerHintInternal(power_hint_t hint, bool enable);
     void    powerHint(power_hint_t hint, bool enable);
-    bool    isPerfLockTimedAcquired() { return (0 <= mPerfLockHandleTimed); }
 
 private:
     int32_t        (*perf_lock_acq)(int, int, int[], int);
diff --git a/msmcobalt/QCamera_Intf.h b/msmcobalt/QCamera_Intf.h
index f2360cc..fd43494 100644
--- a/msmcobalt/QCamera_Intf.h
+++ b/msmcobalt/QCamera_Intf.h
@@ -26,7 +26,7 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
-
+/*for test */
 #ifndef __QCAMERA_INTF_H__
 #define __QCAMERA_INTF_H__