merge in lmp-release history after reset to 596b3392f3b0a954a13d65516e4632d6e6f0a9b7
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.cpp b/camera/QCamera2/HAL3/QCamera3Channel.cpp
index a4f4e61..2767540 100644
--- a/camera/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Channel.cpp
@@ -79,6 +79,7 @@
                                channel_cb_routine cb_routine,
                                cam_padding_info_t *paddingInfo,
                                uint32_t postprocess_mask,
+                               cam_is_type_t is_type,
                                void *userData)
 {
     m_camHandle = cam_handle;
@@ -99,6 +100,7 @@
     char prop[PROPERTY_VALUE_MAX];
     property_get("persist.camera.yuv.dump", prop, "0");
     mYUVDump = atoi(prop);
+    mIsType = is_type;
 }
 
 /*===========================================================================
@@ -205,7 +207,8 @@
                                   cam_format_t streamFormat,
                                   cam_dimension_t streamDim,
                                   uint8_t minStreamBufNum,
-                                  uint32_t postprocess_mask)
+                                  uint32_t postprocessMask,
+                                  cam_is_type_t isType)
 {
     int32_t rc = NO_ERROR;
 
@@ -230,7 +233,7 @@
     }
 
     rc = pStream->init(streamType, streamFormat, streamDim, NULL, minStreamBufNum,
-                       postprocess_mask, streamCbRoutine, this);
+                       postprocessMask, isType, streamCbRoutine, this);
     if (rc == 0) {
         mStreams[m_numStreams] = pStream;
         m_numStreams++;
@@ -498,9 +501,10 @@
                     void *userData,
                     camera3_stream_t *stream,
                     cam_stream_type_t stream_type,
-                    uint32_t postprocess_mask) :
+                    uint32_t postprocess_mask,
+                    cam_is_type_t is_type) :
                         QCamera3Channel(cam_handle, cam_ops, cb_routine,
-                                paddingInfo, postprocess_mask, userData),
+                                paddingInfo, postprocess_mask, is_type, userData),
                         mCamera3Stream(stream),
                         mNumBufs(0),
                         mStreamType(stream_type)
@@ -591,7 +595,8 @@
             streamFormat,
             streamDim,
             mNumBufs,
-            mPostProcMask);
+            mPostProcMask,
+            mIsType);
 
     return rc;
 }
@@ -785,16 +790,17 @@
     mMemory.unregisterBuffers();
 }
 
-int QCamera3RegularChannel::kMaxBuffers = 5;
+int QCamera3RegularChannel::kMaxBuffers = MAX_INFLIGHT_REQUESTS;
 
 QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle,
                     mm_camera_ops_t *cam_ops,
                     channel_cb_routine cb_routine,
                     cam_padding_info_t *paddingInfo,
                     uint32_t postprocess_mask,
+                    cam_is_type_t is_type,
                     void *userData) :
                         QCamera3Channel(cam_handle, cam_ops,
-                                cb_routine, paddingInfo, postprocess_mask, userData),
+                                cb_routine, paddingInfo, postprocess_mask, is_type, userData),
                         mMemory(NULL)
 {
 }
@@ -830,7 +836,7 @@
     streamDim.width = sizeof(metadata_buffer_t),
     streamDim.height = 1;
     rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX,
-        streamDim, MIN_STREAMING_BUFFER_NUM, mPostProcMask);
+        streamDim, MIN_STREAMING_BUFFER_NUM, mPostProcMask, mIsType);
     if (rc < 0) {
         ALOGE("%s: addStream failed", __func__);
     }
@@ -893,7 +899,7 @@
 }
 /*************************************************************************************/
 // RAW Channel related functions
-int QCamera3RawChannel::kMaxBuffers = 5;
+int QCamera3RawChannel::kMaxBuffers = MAX_INFLIGHT_REQUESTS;
 
 QCamera3RawChannel::QCamera3RawChannel(uint32_t cam_handle,
                     mm_camera_ops_t *cam_ops,
@@ -902,10 +908,11 @@
                     void *userData,
                     camera3_stream_t *stream,
                     uint32_t postprocess_mask,
+                    cam_is_type_t is_type,
                     bool raw_16) :
                         QCamera3RegularChannel(cam_handle, cam_ops,
                                 cb_routine, paddingInfo, userData, stream,
-                                CAM_STREAM_TYPE_RAW, postprocess_mask),
+                                CAM_STREAM_TYPE_RAW, postprocess_mask, is_type),
                         mIsRaw16(raw_16)
 {
     char prop[PROPERTY_VALUE_MAX];
@@ -1066,9 +1073,10 @@
                     cam_dimension_t rawDumpSize,
                     cam_padding_info_t *paddingInfo,
                     void *userData,
-                    uint32_t postprocess_mask) :
+                    uint32_t postprocess_mask,
+                    cam_is_type_t is_type) :
                         QCamera3Channel(cam_handle, cam_ops, NULL,
-                                paddingInfo, postprocess_mask, userData),
+                                paddingInfo, postprocess_mask, is_type, userData),
                         mDim(rawDumpSize),
                         mMemory(NULL)
 {
@@ -1260,7 +1268,7 @@
 
     rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_RAW,
         CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG, mDim, kMaxBuffers,
-        mPostProcMask);
+        mPostProcMask, mIsType);
     if (rc < 0) {
         ALOGE("%s: addStream failed", __func__);
     }
@@ -1408,9 +1416,10 @@
                     camera3_stream_t *stream,
                     uint32_t postprocess_mask,
                     bool is4KVideo,
+                    cam_is_type_t is_type,
                     QCamera3Channel *metadataChannel) :
                         QCamera3Channel(cam_handle, cam_ops, cb_routine,
-                        paddingInfo, postprocess_mask, userData),
+                        paddingInfo, postprocess_mask, is_type, userData),
                         m_postprocessor(this),
                         mCamera3Stream(stream),
                         mNumBufsRegistered(CAM_MAX_NUM_BUFS_PER_STREAM),
@@ -1490,7 +1499,7 @@
 
     mNumSnapshotBufs = mCamera3Stream->max_buffers;
     rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
-            (uint8_t)mCamera3Stream->max_buffers, mPostProcMask);
+            (uint8_t)mCamera3Stream->max_buffers, mPostProcMask, mIsType);
 
     Mutex::Autolock lock(mFreeBuffersLock);
     mFreeBufferList.clear();
@@ -2507,9 +2516,9 @@
     return exif;
 }
 
-/* There can be kMaxInFlight number of requests that could get queued up. Hence
+/* There can be MAX_INFLIGHT_REQUESTS number of requests that could get queued up. Hence
  allocating same number of picture channel buffers */
-int QCamera3PicChannel::kMaxBuffers = QCamera3HardwareInterface::kMaxInFlight;
+int QCamera3PicChannel::kMaxBuffers = MAX_INFLIGHT_REQUESTS;
 
 void QCamera3PicChannel::overrideYuvSize(uint32_t width, uint32_t height)
 {
@@ -2534,8 +2543,10 @@
                                                  channel_cb_routine cb_routine,
                                                  cam_padding_info_t *paddingInfo,
                                                  uint32_t postprocess_mask,
+                                                 cam_is_type_t is_type,
                                                  void *userData, void *ch_hdl) :
-    QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, postprocess_mask, userData),
+    QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, postprocess_mask, is_type,
+                    userData),
     picChHandle(ch_hdl),
     mOfflineBuffersIndex(-1),
     m_pSrcChannel(NULL),
@@ -2543,7 +2554,7 @@
     mMemory(NULL)
 {
     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
-    mOfflineMetaIndex = QCamera3HardwareInterface::kMaxInFlight -1;
+    mOfflineMetaIndex = MAX_INFLIGHT_REQUESTS -1;
 }
 
 
@@ -2673,9 +2684,9 @@
     }
 
     //Queue YUV buffers in the beginning mQueueAll = true
-    /* There can be kMaxInFlight number of requests that could get queued up.
+    /* There can be MAX_INFLIGHT_REQUESTS number of requests that could get queued up.
      * Hence allocating same number of reprocess channel's output buffers */
-    rc = mMemory->allocate(QCamera3HardwareInterface::kMaxInFlight, len, true);
+    rc = mMemory->allocate(MAX_INFLIGHT_REQUESTS, len, true);
     if (rc < 0) {
         ALOGE("%s: unable to allocate reproc memory", __func__);
         delete mMemory;
@@ -3015,7 +3026,7 @@
     }
 
     QCamera3Stream *pStream = mStreams[0];
-    int32_t max_idx = QCamera3HardwareInterface::kMaxInFlight -1;
+    int32_t max_idx = MAX_INFLIGHT_REQUESTS-1;
     //loop back the indices if max burst count reached
     if (mOfflineBuffersIndex == max_idx) {
        mOfflineBuffersIndex = -1;
@@ -3035,11 +3046,10 @@
         CDBG("%s: Mapped buffer with index %d", __func__, mOfflineBuffersIndex);
     }
 
-    max_idx = QCamera3HardwareInterface::kMaxInFlight +
-              QCamera3HardwareInterface::kMaxInFlight - 1;
+    max_idx = MAX_INFLIGHT_REQUESTS*2 - 1;
     //loop back the indices if max burst count reached
     if (mOfflineMetaIndex == max_idx) {
-       mOfflineMetaIndex = QCamera3HardwareInterface::kMaxInFlight -1;
+       mOfflineMetaIndex = MAX_INFLIGHT_REQUESTS-1;
     }
     uint32_t meta_buf_idx = mOfflineMetaIndex + 1;
 
@@ -3149,16 +3159,16 @@
  *              none-zero failure code
  *==========================================================================*/
 int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &pp_config,
-        const reprocess_config_t &src_config ,
+        const reprocess_config_t &src_config , cam_is_type_t is_type,
         QCamera3Channel *pMetaChannel)
 {
     int32_t rc = 0;
     cam_stream_reproc_config_t reprocess_config;
     cam_stream_type_t streamType;
 
-    /* There can be kMaxInFlight number of requests that could get queued up.
+    /* There can be MAX_INFLIGHT_REQUESTS number of requests that could get queued up.
      * Hence allocating same number of reprocess channel's output buffers */
-    int num_buffers = QCamera3HardwareInterface::kMaxInFlight;
+    int num_buffers = MAX_INFLIGHT_REQUESTS;
     cam_dimension_t streamDim = src_config.output_stream_dim;
 
     if (NULL != src_config.src_channel) {
@@ -3195,6 +3205,7 @@
             streamDim, &reprocess_config,
             num_buffers,
             reprocess_config.pp_feature_config.feature_mask,
+            is_type,
             QCamera3Channel::streamCbRoutine, this);
 
     if (rc == 0) {
@@ -3221,9 +3232,10 @@
                     mm_camera_ops_t *cam_ops,
                     cam_padding_info_t *paddingInfo,
                     uint32_t postprocess_mask,
+                    cam_is_type_t is_type,
                     void *userData) :
                         QCamera3Channel(cam_handle, cam_ops,
-                                NULL, paddingInfo, postprocess_mask, userData),
+                                NULL, paddingInfo, postprocess_mask, is_type, userData),
                         mMemory(NULL)
 {
 }
@@ -3258,7 +3270,7 @@
     // Hardcode to VGA size for now
     rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_CALLBACK,
         CAM_FORMAT_YUV_420_NV21, kDim, MIN_STREAMING_BUFFER_NUM,
-        mPostProcMask);
+        mPostProcMask, mIsType);
     if (rc < 0) {
         ALOGE("%s: addStream failed", __func__);
     }
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.h b/camera/QCamera2/HAL3/QCamera3Channel.h
index 450ab93..e18bc31 100644
--- a/camera/QCamera2/HAL3/QCamera3Channel.h
+++ b/camera/QCamera2/HAL3/QCamera3Channel.h
@@ -58,6 +58,7 @@
                    channel_cb_routine cb_routine,
                    cam_padding_info_t *paddingInfo,
                    uint32_t postprocess_mask,
+                   cam_is_type_t is_type,
                    void *userData);
     QCamera3Channel();
     virtual ~QCamera3Channel();
@@ -66,7 +67,8 @@
                       cam_format_t streamFormat,
                       cam_dimension_t streamDim,
                       uint8_t minStreamBufnum,
-                      uint32_t postproc_mask);
+                      uint32_t postprocessMask,
+                      cam_is_type_t isType);
     virtual int32_t start();
     int32_t stop();
     int32_t bufDone(mm_camera_super_buf_t *recvd_frame);
@@ -122,6 +124,7 @@
     //cam_padding_info_t *mPaddingInfo;
     uint32_t mPostProcMask;
     uint8_t mYUVDump;
+    cam_is_type_t mIsType;
 };
 
 /* QCamera3RegularChannel is used to handle all streams that are directly
@@ -137,7 +140,8 @@
                     void *userData,
                     camera3_stream_t *stream,
                     cam_stream_type_t stream_type,
-                    uint32_t postprocess_mask);
+                    uint32_t postprocess_mask,
+                    cam_is_type_t is_type);
 
     virtual ~QCamera3RegularChannel();
 
@@ -172,6 +176,7 @@
                     channel_cb_routine cb_routine,
                     cam_padding_info_t *paddingInfo,
                     uint32_t postprocess_mask,
+                    cam_is_type_t is_type,
                     void *userData);
     virtual ~QCamera3MetadataChannel();
 
@@ -202,6 +207,7 @@
                     void *userData,
                     camera3_stream_t *stream,
                     uint32_t postprocess_mask,
+                    cam_is_type_t is_type,
                     bool raw_16 = false);
     virtual ~QCamera3RawChannel();
 
@@ -234,7 +240,8 @@
                     cam_dimension_t rawDumpSize,
                     cam_padding_info_t *paddingInfo,
                     void *userData,
-                    uint32_t postprocess_mask);
+                    uint32_t postprocess_mask,
+                    cam_is_type_t is_type);
     virtual ~QCamera3RawDumpChannel();
     virtual int32_t initialize();
     virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
@@ -268,6 +275,7 @@
             camera3_stream_t *stream,
             uint32_t postprocess_mask,
             bool is4KVideo,
+            cam_is_type_t is_type,
             QCamera3Channel *metadataChannel);
     ~QCamera3PicChannel();
 
@@ -341,6 +349,7 @@
                             channel_cb_routine cb_routine,
                             cam_padding_info_t *paddingInfo,
                             uint32_t postprocess_mask,
+                            cam_is_type_t is_type,
                             void *userData, void *ch_hdl);
     QCamera3ReprocessChannel();
     virtual ~QCamera3ReprocessChannel();
@@ -364,6 +373,7 @@
                                        void* userdata);
     int32_t addReprocStreamsFromSource(cam_pp_feature_config_t &pp_config,
            const reprocess_config_t &src_config,
+           cam_is_type_t is_type,
            QCamera3Channel *pMetaChannel);
     QCamera3Stream *getStreamBySrcHandle(uint32_t srcHandle);
     QCamera3Stream *getSrcStreamBySrcHandle(uint32_t srcHandle);
@@ -397,6 +407,7 @@
                     mm_camera_ops_t *cam_ops,
                     cam_padding_info_t *paddingInfo,
                     uint32_t postprocess_mask,
+                    cam_is_type_t is_type,
                     void *userData);
     virtual ~QCamera3SupportChannel();
 
diff --git a/camera/QCamera2/HAL3/QCamera3HALHeader.h b/camera/QCamera2/HAL3/QCamera3HALHeader.h
index 63be424..3aa4bdd 100644
--- a/camera/QCamera2/HAL3/QCamera3HALHeader.h
+++ b/camera/QCamera2/HAL3/QCamera3HALHeader.h
@@ -74,6 +74,7 @@
         cam_rect_t output_crop;
         cam_rotation_t rotation;
     } reprocess_config_t;
+
 };//namespace qcamera
 
 #endif
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 1f174f3..d36c45c 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -63,6 +63,10 @@
 #define VIDEO_4K_WIDTH  3840
 #define VIDEO_4K_HEIGHT 2160
 
+#define MAX_RAW_STREAMS        1
+#define MAX_STALLING_STREAMS   1
+#define MAX_PROCESSED_STREAMS  3
+
 cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
 const camera_metadata_t *gStaticMetadata[MM_CAMERA_MAX_NUM_SENSORS];
 volatile uint32_t gCamHal3LogLevel = 1;
@@ -222,8 +226,6 @@
     reserved:                           {0},
 };
 
-int QCamera3HardwareInterface::kMaxInFlight = 4;
-
 /*===========================================================================
  * FUNCTION   : QCamera3HardwareInterface
  *
@@ -253,6 +255,7 @@
       mParameters(NULL),
       m_bIsVideo(false),
       m_bIs4KVideo(false),
+      mEisEnable(0),
       mLoopBackResult(NULL),
       mMinProcessedFrameDuration(0),
       mMinJpegFrameDuration(0),
@@ -537,41 +540,6 @@
         return BAD_VALUE;
     }
 
-    pthread_mutex_lock(&mMutex);
-
-    /* Check whether we have video stream */
-    m_bIs4KVideo = false;
-    m_bIsVideo = false;
-    bool isZsl = false;
-    size_t videoWidth = 0;
-    size_t videoHeight = 0;
-    /* Check whether we have zsl stream or 4k video case */
-    for (size_t i = 0; i < streamList->num_streams; i++) {
-        camera3_stream_t *newStream = streamList->streams[i];
-        if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
-                newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED){
-            isZsl = true;
-        }
-        if ((HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) &&
-                (newStream->usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER)) {
-            m_bIsVideo = true;
-            if ((VIDEO_4K_WIDTH <= newStream->width) &&
-                    (VIDEO_4K_HEIGHT <= newStream->height)) {
-                videoWidth = newStream->width;
-                videoHeight = newStream->height;
-                m_bIs4KVideo = true;
-            }
-        }
-    }
-
-    if (isZsl && m_bIsVideo) {
-        ALOGE("%s: Currently invalid configuration ZSL&Video!", __func__);
-        pthread_mutex_unlock(&mMutex);
-        return -EINVAL;
-    }
-
-    pthread_mutex_unlock(&mMutex);
-
     /* first invalidate all the steams in the mStreamList
      * if they appear again, they will be validated */
     for (List<stream_info_t*>::iterator it = mStreamInfo.begin();
@@ -595,6 +563,88 @@
     }
 
     pthread_mutex_lock(&mMutex);
+
+    /* Check whether we have video stream */
+    m_bIs4KVideo = false;
+    m_bIsVideo = false;
+    bool isZsl = false;
+    size_t videoWidth = 0;
+    size_t videoHeight = 0;
+    size_t rawStreamCnt = 0;
+    size_t stallStreamCnt = 0;
+    size_t processedStreamCnt = 0;
+    // Number of streams on ISP encoder path
+    size_t numStreamsOnEncoder = 0;
+    cam_dimension_t maxViewfinderSize;
+    maxViewfinderSize = gCamCapability[mCameraId]->max_viewfinder_size;
+
+    for (size_t i = 0; i < streamList->num_streams; i++) {
+        camera3_stream_t *newStream = streamList->streams[i];
+        if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
+                newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED){
+            isZsl = true;
+        }
+        if ((HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) &&
+                (newStream->usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER)) {
+            m_bIsVideo = true;
+
+            if ((VIDEO_4K_WIDTH <= newStream->width) &&
+                    (VIDEO_4K_HEIGHT <= newStream->height)) {
+                videoWidth = newStream->width;
+                videoHeight = newStream->height;
+                m_bIs4KVideo = true;
+            }
+        }
+        if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
+                newStream->stream_type == CAMERA3_STREAM_OUTPUT) {
+            switch (newStream->format) {
+            case HAL_PIXEL_FORMAT_BLOB:
+                stallStreamCnt++;
+                if (newStream->width > (uint32_t)maxViewfinderSize.width ||
+                        newStream->height > (uint32_t)maxViewfinderSize.height)
+                    numStreamsOnEncoder++;
+                break;
+            case HAL_PIXEL_FORMAT_RAW10:
+            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+            case HAL_PIXEL_FORMAT_RAW16:
+                rawStreamCnt++;
+                break;
+            case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+            case HAL_PIXEL_FORMAT_YCbCr_420_888:
+            default:
+                processedStreamCnt++;
+                if (newStream->width > (uint32_t)maxViewfinderSize.width ||
+                        newStream->height > (uint32_t)maxViewfinderSize.height)
+                    numStreamsOnEncoder++;
+                break;
+            }
+
+        }
+    }
+
+    /* Check if num_streams is sane */
+    if (stallStreamCnt > MAX_STALLING_STREAMS ||
+            rawStreamCnt > MAX_RAW_STREAMS ||
+            processedStreamCnt > MAX_PROCESSED_STREAMS) {
+        ALOGE("%s: Invalid stream configu: stall: %d, raw: %d, processed %d",
+                __func__, stallStreamCnt, rawStreamCnt, processedStreamCnt);
+        pthread_mutex_unlock(&mMutex);
+        return -EINVAL;
+    }
+    /* Check whether we have zsl stream or 4k video case */
+    if (isZsl && m_bIsVideo) {
+        ALOGE("%s: Currently invalid configuration ZSL&Video!", __func__);
+        pthread_mutex_unlock(&mMutex);
+        return -EINVAL;
+    }
+    /* Check if stream sizes are sane */
+    if (numStreamsOnEncoder > 2) {
+        ALOGE("%s: Number of streams on ISP encoder path exceeds limits of 2",
+                __func__);
+        pthread_mutex_unlock(&mMutex);
+        return -EINVAL;
+    }
+
     camera3_stream_t *inputStream = NULL;
     camera3_stream_t *jpegStream = NULL;
     cam_stream_size_info_t stream_config_info;
@@ -651,10 +701,21 @@
         mSupportChannel = NULL;
     }
 
+    /* get eis information for stream configuration */
+    cam_is_type_t is_type;
+    char is_type_value[PROPERTY_VALUE_MAX];
+    property_get("camera.is_type", is_type_value, "4");
+    is_type = static_cast<cam_is_type_t>(atoi(is_type_value));
+    //for camera use case, front camcorder and 4k video, no eis
+    if (gCamCapability[mCameraId]->position != CAM_POSITION_BACK ||
+        !m_bIsVideo || m_bIs4KVideo) {
+        is_type = IS_TYPE_NONE;
+    }
+
     //Create metadata channel and initialize it
     mMetadataChannel = new QCamera3MetadataChannel(mCameraHandle->camera_handle,
                     mCameraHandle->ops, captureResultCb,
-                    &gCamCapability[mCameraId]->padding_info, CAM_QCOM_FEATURE_NONE, this);
+                    &gCamCapability[mCameraId]->padding_info, CAM_QCOM_FEATURE_NONE, is_type, this);
     if (mMetadataChannel == NULL) {
         ALOGE("%s: failed to allocate metadata channel", __func__);
         rc = -ENOMEM;
@@ -681,6 +742,7 @@
                 mCameraHandle->ops,
                 &gCamCapability[mCameraId]->padding_info,
                 CAM_QCOM_FEATURE_NONE,
+                is_type,
                 this);
         if (!mSupportChannel) {
             ALOGE("%s: dummy channel cannot be created", __func__);
@@ -790,7 +852,8 @@
                             this,
                             newStream,
                             (cam_stream_type_t) stream_config_info.type[i],
-                            stream_config_info.postprocess_mask[i]);
+                            stream_config_info.postprocess_mask[i],
+                            is_type);
                     if (channel == NULL) {
                         ALOGE("%s: allocation of channel failed", __func__);
                         pthread_mutex_unlock(&mMutex);
@@ -808,6 +871,7 @@
                             mCameraHandle->ops, captureResultCb,
                             &gCamCapability[mCameraId]->padding_info,
                             this, newStream, CAM_QCOM_FEATURE_NONE,
+                            is_type,
                             (newStream->format == HAL_PIXEL_FORMAT_RAW16));
                     if (mRawChannel == NULL) {
                         ALOGE("%s: allocation of raw channel failed", __func__);
@@ -823,7 +887,7 @@
                             mCameraHandle->ops, captureResultCb,
                             &gCamCapability[mCameraId]->padding_info, this, newStream,
                             stream_config_info.postprocess_mask[i],
-                            m_bIs4KVideo, mMetadataChannel);
+                            m_bIs4KVideo, is_type, mMetadataChannel);
                     if (mPictureChannel == NULL) {
                         ALOGE("%s: allocation of channel failed", __func__);
                         pthread_mutex_unlock(&mMutex);
@@ -867,7 +931,7 @@
                                   mCameraHandle->ops,
                                   rawDumpSize,
                                   &gCamCapability[mCameraId]->padding_info,
-                                  this, CAM_QCOM_FEATURE_NONE);
+                                  this, CAM_QCOM_FEATURE_NONE, is_type);
         if (!mRawDumpChannel) {
             ALOGE("%s: Raw Dump channel cannot be created", __func__);
             pthread_mutex_unlock(&mMutex);
@@ -909,6 +973,18 @@
     AddSetParmEntryToBatch(mParameters,CAM_INTF_PARM_TINTLESS,
                 sizeof(tintless_value), &tintless_value);
 
+    //If EIS is enabled, turn it on for video
+    int32_t vsMode;
+    if (gCamCapability[mCameraId]->position == CAM_POSITION_BACK &&
+        mEisEnable && m_bIsVideo && !m_bIs4KVideo){
+       vsMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON;
+    } else {
+       vsMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+    }
+    rc = AddSetParmEntryToBatch(mParameters,
+            CAM_INTF_PARM_DIS_ENABLE,
+            sizeof(vsMode), &vsMode);
+
     mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
 
     /* Initialize mPendingRequestInfo and mPendnigBuffersMap */
@@ -1782,6 +1858,7 @@
     // Acquire all request buffers first
     streamID.num_streams = 0;
     int blob_request = 0;
+    uint32_t snapshotStreamId = 0;
     for (size_t i = 0; i < request->num_output_buffers; i++) {
         const camera3_stream_buffer_t& output = request->output_buffers[i];
         QCamera3Channel *channel = (QCamera3Channel *)output.stream->priv;
@@ -1790,6 +1867,7 @@
         if (output.stream->format == HAL_PIXEL_FORMAT_BLOB) {
             //Call function to store local copy of jpeg data for encode params.
             blob_request = 1;
+            snapshotStreamId = channel->getStreamID(channel->getStreamTypeMask());
         }
 
         rc = acquireFence->wait(Fence::TIMEOUT_NEVER);
@@ -1814,7 +1892,7 @@
     }
 
     if(request->input_buffer == NULL) {
-       rc = setFrameParameters(request, streamID);
+       rc = setFrameParameters(request, streamID, snapshotStreamId);
         if (rc < 0) {
             ALOGE("%s: fail to set frame parameters", __func__);
             pthread_mutex_unlock(&mMutex);
@@ -1905,7 +1983,7 @@
                     return NO_INIT;
                 }
                 metadata_buffer_t reproc_meta;
-                rc = setReprocParameters(request, &reproc_meta);
+                rc = setReprocParameters(request, &reproc_meta, snapshotStreamId);
                 if (NO_ERROR == rc) {
                     rc = channel->request(output.buffer, frameNumber,
                             request->input_buffer, &reproc_meta);
@@ -1952,7 +2030,7 @@
     //Block on conditional variable
 
     mPendingRequest++;
-    while (mPendingRequest >= kMaxInFlight) {
+    while (mPendingRequest >= MAX_INFLIGHT_REQUESTS) {
         if (!isValidTimeout) {
             CDBG("%s: Blocking on conditional wait", __func__);
             pthread_cond_wait(&mRequestCond, &mMutex);
@@ -2459,6 +2537,12 @@
             (uint8_t *)POINTER_OF_META(CAM_INTF_META_LENS_OPT_STAB_MODE, metadata);
         camMetadata.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE ,opticalStab, 1);
     }
+    if (IS_META_AVAILABLE(CAM_INTF_PARM_DIS_ENABLE, metadata)) {
+        uint8_t *vsMode =
+            (uint8_t *)POINTER_OF_META(CAM_INTF_PARM_DIS_ENABLE, metadata);
+        camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, vsMode, 1);
+    }
+
     if (IS_META_AVAILABLE(CAM_INTF_META_NOISE_REDUCTION_MODE, metadata)) {
         uint8_t  *noiseRedMode =
             (uint8_t *)POINTER_OF_META(CAM_INTF_META_NOISE_REDUCTION_MODE, metadata);
@@ -2813,9 +2897,6 @@
     }
 
     /* Constant metadata values to be update*/
-    uint8_t vs_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
-    camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vs_mode, 1);
-
     uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
     camMetadata.update(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1);
 
@@ -2825,6 +2906,9 @@
     int32_t hotPixelMap[2];
     camMetadata.update(ANDROID_STATISTICS_HOT_PIXEL_MAP, &hotPixelMap[0], 0);
 
+    uint8_t vsMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+    camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vsMode, 1);
+
     // CDS
     if (IS_META_AVAILABLE(CAM_INTF_PARM_CDS_MODE, metadata)) {
         cam_cds_mode_type_t *cds = (cam_cds_mode_type_t *)
@@ -2956,7 +3040,7 @@
         uint8_t  *afState = (uint8_t *)
             POINTER_OF_META(CAM_INTF_META_AF_STATE, metadata);
         camMetadata.update(ANDROID_CONTROL_AF_STATE, afState, 1);
-        CDBG("%s: urgent Metadata : ANDROID_CONTROL_AF_STATE", __func__);
+        CDBG("%s: urgent Metadata : ANDROID_CONTROL_AF_STATE %d", __func__, *afState);
     }
 
     if (IS_META_AVAILABLE(CAM_INTF_META_LENS_FOCUS_DISTANCE, metadata)) {
@@ -4107,7 +4191,10 @@
                       &sensor_orientation,
                       1);
 
-    int32_t max_output_streams[3] = {1, 3, 1};
+    int32_t max_output_streams[3] = {
+            MAX_STALLING_STREAMS,
+            MAX_PROCESSED_STREAMS,
+            MAX_RAW_STREAMS};
     staticInfo.update(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
                       max_output_streams,
                       3);
@@ -4142,7 +4229,7 @@
                       avail_testpattern_modes,
                       size);
 
-    uint8_t max_pipeline_depth = kMaxInFlight + EMPTY_PIPELINE_DELAY + FRAME_SKIP_DELAY;
+    uint8_t max_pipeline_depth = MAX_INFLIGHT_REQUESTS + EMPTY_PIPELINE_DELAY + FRAME_SKIP_DELAY;
     staticInfo.update(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
                       &max_pipeline_depth,
                       1);
@@ -4864,6 +4951,12 @@
     property_get("persist.camera.ois.disable", ois_prop, "0");
     uint8_t ois_disable = atoi(ois_prop);
 
+    /* OIS/EIS disable */
+    char eis_prop[PROPERTY_VALUE_MAX];
+    memset(eis_prop, 0, sizeof(eis_prop));
+    property_get("camera.eis.enable", eis_prop, "1");
+    mEisEnable = atoi(eis_prop);
+
     /* Force video to use OIS */
     char videoOisProp[PROPERTY_VALUE_MAX];
     memset(videoOisProp, 0, sizeof(videoOisProp));
@@ -4872,50 +4965,51 @@
 
     uint8_t controlIntent = 0;
     uint8_t focusMode;
-    uint8_t opt_stab_mode;
-
+    uint8_t vsMode;
+    uint8_t optStabMode;
+    vsMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
     switch (type) {
       case CAMERA3_TEMPLATE_PREVIEW:
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
         focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
         break;
       case CAMERA3_TEMPLATE_STILL_CAPTURE:
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
         focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
         break;
       case CAMERA3_TEMPLATE_VIDEO_RECORD:
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
         focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
         if (forceVideoOis)
-            opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
+            optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
         break;
       case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
         focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
         if (forceVideoOis)
-            opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
+            optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
         break;
       case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
         focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
         break;
       case CAMERA3_TEMPLATE_MANUAL:
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
         focusMode = ANDROID_CONTROL_AF_MODE_OFF;
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
         break;
       default:
         controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
         break;
     }
     settings.update(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);
-
+    settings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vsMode, 1);
     if (gCamCapability[mCameraId]->supported_focus_modes_cnt == 1) {
         focusMode = ANDROID_CONTROL_AF_MODE_OFF;
     }
@@ -4923,12 +5017,12 @@
 
     if (gCamCapability[mCameraId]->optical_stab_modes_count == 1 &&
             gCamCapability[mCameraId]->optical_stab_modes[0] == CAM_OPT_STAB_ON)
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
     else if ((gCamCapability[mCameraId]->optical_stab_modes_count == 1 &&
             gCamCapability[mCameraId]->optical_stab_modes[0] == CAM_OPT_STAB_OFF)
             || ois_disable)
-        opt_stab_mode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
-    settings.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &opt_stab_mode, 1);
+        optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+    settings.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &optStabMode, 1);
 
     settings.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
             &gCamCapability[mCameraId]->exposure_compensation_default, 1);
@@ -5043,9 +5137,6 @@
     static const uint8_t antibanding_mode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ;
     settings.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &antibanding_mode, 1);
 
-    static const uint8_t vs_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
-    settings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vs_mode, 1);
-
     /*focus distance*/
     float focus_distance = 0.0;
     settings.update(ANDROID_LENS_FOCUS_DISTANCE, &focus_distance, 1);
@@ -5171,7 +5262,8 @@
  *==========================================================================*/
 int QCamera3HardwareInterface::setFrameParameters(
                     camera3_capture_request_t *request,
-                    cam_stream_ID_t streamID)
+                    cam_stream_ID_t streamID,
+                    uint32_t snapshotStreamId)
 {
     /*translate from camera_metadata_t type to parm_type_t*/
     int rc = 0;
@@ -5203,7 +5295,7 @@
     }
 
     if(request->settings != NULL){
-        rc = translateToHalMetadata(request, mParameters);
+        rc = translateToHalMetadata(request, mParameters, snapshotStreamId);
     }
 
     return rc;
@@ -5222,7 +5314,8 @@
  *              failure:
  *==========================================================================*/
 int32_t QCamera3HardwareInterface::setReprocParameters(
-        camera3_capture_request_t *request, metadata_buffer_t *reprocParam)
+        camera3_capture_request_t *request, metadata_buffer_t *reprocParam,
+        uint32_t snapshotStreamId)
 {
     /*translate from camera_metadata_t type to parm_type_t*/
     int rc = 0;
@@ -5246,7 +5339,7 @@
         return rc;
     }
 
-    rc = translateToHalMetadata(request, reprocParam);
+    rc = translateToHalMetadata(request, reprocParam, snapshotStreamId);
     if (rc < 0) {
         ALOGE("%s: Failed to translate reproc request", __func__);
         return rc;
@@ -5317,7 +5410,8 @@
  *==========================================================================*/
 int QCamera3HardwareInterface::translateToHalMetadata
                                   (const camera3_capture_request_t *request,
-                                   metadata_buffer_t *hal_metadata)
+                                   metadata_buffer_t *hal_metadata,
+                                   uint32_t snapshotStreamId)
 {
     int rc = 0;
     CameraMetadata frame_settings;
@@ -5956,7 +6050,19 @@
     if (frame_settings.exists(ANDROID_JPEG_ORIENTATION)) {
         int32_t orientation =
             frame_settings.find(ANDROID_JPEG_ORIENTATION).data.i32[0];
+        cam_rotation_info_t rotation_info;
+        if (orientation == 0) {
+           rotation_info.rotation = ROTATE_0;
+        } else if (orientation == 90) {
+           rotation_info.rotation = ROTATE_90;
+        } else if (orientation == 180) {
+           rotation_info.rotation = ROTATE_180;
+        } else if (orientation == 270) {
+           rotation_info.rotation = ROTATE_270;
+        }
+        rotation_info.streamId = snapshotStreamId;
         rc = AddSetParmEntryToBatch(hal_metadata, CAM_INTF_META_JPEG_ORIENTATION, sizeof(orientation), &orientation);
+        rc = AddSetParmEntryToBatch(hal_metadata, CAM_INTF_PARM_ROTATION, sizeof(rotation_info), &rotation_info);
     }
 
     if (frame_settings.exists(ANDROID_JPEG_QUALITY)) {
@@ -6299,6 +6405,26 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : needJpegRotation
+ *
+ * DESCRIPTION: if rotation from jpeg is needed
+ *
+ * PARAMETERS : none
+ *
+ * RETURN     : true: needed
+ *              false: no need
+ *==========================================================================*/
+bool QCamera3HardwareInterface::needJpegRotation()
+{
+   /*If the pp does not have the ability to do rotation, enable jpeg rotation*/
+    if (!(gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION)) {
+       CDBG("%s: Need Jpeg to do the rotation", __func__);
+       return true;
+    }
+    return false;
+}
+
+/*===========================================================================
  * FUNCTION   : addOfflineReprocChannel
  *
  * DESCRIPTION: add a reprocess channel that will do reprocess on frames
@@ -6318,7 +6444,7 @@
     QCamera3ReprocessChannel *pChannel = NULL;
 
     pChannel = new QCamera3ReprocessChannel(mCameraHandle->camera_handle,
-            mCameraHandle->ops, NULL, config.padding, CAM_QCOM_FEATURE_NONE, this, picChHandle);
+            mCameraHandle->ops, NULL, config.padding, CAM_QCOM_FEATURE_NONE, IS_TYPE_NONE, this, picChHandle);
     if (NULL == pChannel) {
         ALOGE("%s: no mem for reprocess channel", __func__);
         return NULL;
@@ -6339,6 +6465,7 @@
 
     rc = pChannel->addReprocStreamsFromSource(pp_config,
             config,
+            IS_TYPE_NONE,
             mMetadataChannel);
 
     if (rc != NO_ERROR) {
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index b692bad..a3b7a78 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -143,11 +143,11 @@
     int flush();
 
     int setFrameParameters(camera3_capture_request_t *request,
-            cam_stream_ID_t streamID);
+            cam_stream_ID_t streamID, uint32_t snapshotStreamId);
     int32_t setReprocParameters(camera3_capture_request_t *request,
-            metadata_buffer_t *reprocParam);
+            metadata_buffer_t *reprocParam, uint32_t snapshotStreamId);
     int translateToHalMetadata(const camera3_capture_request_t *request,
-            metadata_buffer_t *parm);
+            metadata_buffer_t *parm, uint32_t snapshotStreamId);
     camera_metadata_t* translateCbUrgentMetadataToResultMetadata (
                              metadata_buffer_t *metadata);
 
@@ -162,6 +162,7 @@
             QCamera3PicChannel *picChHandle, metadata_buffer_t *metadata);
     bool needRotationReprocess();
     bool needReprocess(uint32_t postprocess_mask);
+    bool needJpegRotation();
     bool isWNREnabled();
     bool isCACEnabled();
     cam_denoise_process_type_t getWaveletDenoiseProcessPlate();
@@ -221,8 +222,6 @@
     bool needOnlineRotation();
     int getJpegQuality();
     QCamera3Exif *getExifData();
-public:
-    static int kMaxInFlight;
 private:
     camera3_device_t   mCameraDevice;
     uint8_t            mCameraId;
@@ -250,6 +249,7 @@
     bool m_bWNROn;
     bool m_bIsVideo;
     bool m_bIs4KVideo;
+    uint8_t mEisEnable;
 
     /* Data structure to store pending request */
     typedef struct {
diff --git a/camera/QCamera2/HAL3/QCamera3PostProc.cpp b/camera/QCamera2/HAL3/QCamera3PostProc.cpp
index d03aebe..efae00b 100644
--- a/camera/QCamera2/HAL3/QCamera3PostProc.cpp
+++ b/camera/QCamera2/HAL3/QCamera3PostProc.cpp
@@ -1136,7 +1136,7 @@
     metadata_buffer_t *metadata = NULL;
     jpeg_settings_t *jpeg_settings = NULL;
     QCamera3HardwareInterface* hal_obj = NULL;
-    bool reprocess_done = false;
+    bool needJpegRotation = false;
 
     hal_obj = (QCamera3HardwareInterface*)m_parent->mUserData;
     recvd_frame = jpeg_job_data->src_frame;
@@ -1212,7 +1212,7 @@
     memset(&dst_dim, 0, sizeof(cam_dimension_t));
     srcChannel->getStreamByIndex(0)->getFrameDimension(dst_dim);
 
-    reprocess_done = hal_obj->needReprocess(mPostProcMask);
+    needJpegRotation = hal_obj->needJpegRotation();
     CDBG_HIGH("%s: Need new session?:%d",__func__, needNewSess);
     if (needNewSess) {
         //creating a new session, so we must destroy the old one
@@ -1228,26 +1228,37 @@
         // create jpeg encoding session
         mm_jpeg_encode_params_t encodeParam;
         memset(&encodeParam, 0, sizeof(mm_jpeg_encode_params_t));
-        if (reprocess_done &&
+        getJpegEncodeConfig(encodeParam, main_stream, jpeg_settings);
+        CDBG_HIGH("%s: #src bufs:%d # tmb bufs:%d #dst_bufs:%d", __func__,
+                     encodeParam.num_src_bufs,encodeParam.num_tmb_bufs,encodeParam.num_dst_bufs);
+        if (!needJpegRotation &&
             (jpeg_settings->jpeg_orientation == 90 ||
             jpeg_settings->jpeg_orientation == 270)) {
-           //swap src width and height due to rotation
+           //swap src width and height, stride and scanline due to rotation
            encodeParam.main_dim.src_dim.width = src_dim.height;
            encodeParam.main_dim.src_dim.height = src_dim.width;
            encodeParam.thumb_dim.src_dim.width = src_dim.height;
            encodeParam.thumb_dim.src_dim.height = src_dim.width;
+
+           int32_t temp = encodeParam.src_main_buf[0].offset.mp[0].stride;
+           encodeParam.src_main_buf[0].offset.mp[0].stride =
+              encodeParam.src_main_buf[0].offset.mp[0].scanline;
+           encodeParam.src_main_buf[0].offset.mp[0].scanline = temp;
+
+           temp = encodeParam.src_thumb_buf[0].offset.mp[0].stride;
+           encodeParam.src_thumb_buf[0].offset.mp[0].stride =
+              encodeParam.src_thumb_buf[0].offset.mp[0].scanline;
+           encodeParam.src_thumb_buf[0].offset.mp[0].scanline = temp;
         } else {
            encodeParam.main_dim.src_dim  = src_dim;
            encodeParam.thumb_dim.src_dim = src_dim;
         }
         encodeParam.main_dim.dst_dim = dst_dim;
         encodeParam.thumb_dim.dst_dim = jpeg_settings->thumbnail_size;
-        if (!reprocess_done) {
+        if (needJpegRotation) {
            encodeParam.rotation = jpeg_settings->jpeg_orientation;
         }
-        getJpegEncodeConfig(encodeParam, main_stream, jpeg_settings);
-        CDBG_HIGH("%s: #src bufs:%d # tmb bufs:%d #dst_bufs:%d", __func__,
-                     encodeParam.num_src_bufs,encodeParam.num_tmb_bufs,encodeParam.num_dst_bufs);
+
 
         ret = mJpegHandle.create_session(mJpegClientHandle, &encodeParam, &mJpegSessionId);
         if (ret != NO_ERROR) {
@@ -1264,7 +1275,7 @@
     jpg_job.encode_job.src_index = main_frame->buf_idx;
     jpg_job.encode_job.dst_index = 0;
 
-    if (!reprocess_done) {
+    if (needJpegRotation) {
         jpg_job.encode_job.rotation =
                 jpeg_settings->jpeg_orientation;
         CDBG("%s: %d: jpeg rotation is set to %d", __func__, __LINE__,
@@ -1297,7 +1308,7 @@
         jpg_job.encode_job.thumb_dim.dst_dim =
                 jpeg_settings->thumbnail_size;
 
-      if (reprocess_done &&
+      if (!needJpegRotation &&
           (jpeg_settings->jpeg_orientation  == 90 ||
            jpeg_settings->jpeg_orientation == 270)) {
             //swap the thumbnail destination width and height if it has
diff --git a/camera/QCamera2/HAL3/QCamera3Stream.cpp b/camera/QCamera2/HAL3/QCamera3Stream.cpp
index 6051793..2d0649d 100644
--- a/camera/QCamera2/HAL3/QCamera3Stream.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Stream.cpp
@@ -238,6 +238,7 @@
                             cam_stream_reproc_config_t* reprocess_config,
                             uint8_t minNumBuffers,
                             uint32_t postprocess_mask,
+                            cam_is_type_t is_type,
                             hal3_stream_cb_routine stream_cb,
                             void *userdata)
 {
@@ -275,6 +276,7 @@
     mStreamInfo->pp_config.feature_mask = postprocess_mask;
     ALOGV("%s: stream_type is %d, feature_mask is %d",
           __func__, mStreamInfo->stream_type, mStreamInfo->pp_config.feature_mask);
+    mStreamInfo->is_type = is_type;
     rc = mCamOps->map_stream_buf(mCamHandle,
             mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
             0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
diff --git a/camera/QCamera2/HAL3/QCamera3Stream.h b/camera/QCamera2/HAL3/QCamera3Stream.h
index f44aee1..f8e0cdb 100644
--- a/camera/QCamera2/HAL3/QCamera3Stream.h
+++ b/camera/QCamera2/HAL3/QCamera3Stream.h
@@ -62,6 +62,7 @@
                          cam_stream_reproc_config_t* reprocess_config,
                          uint8_t minStreamBufNum,
                          uint32_t postprocess_mask,
+                         cam_is_type_t is_type,
                          hal3_stream_cb_routine stream_cb,
                          void *userdata);
     virtual int32_t bufDone(int index);
diff --git a/camera/QCamera2/stack/common/cam_intf.h b/camera/QCamera2/stack/common/cam_intf.h
index 6326618..688a6db 100644
--- a/camera/QCamera2/stack/common/cam_intf.h
+++ b/camera/QCamera2/stack/common/cam_intf.h
@@ -336,6 +336,9 @@
     /* Can the sensor timestamp be compared to
      * timestamps from other sub-systems (gyro, accelerometer etc.) */
     uint8_t isTimestampCalibrated;
+
+    /* Max size supported by ISP viewfinder path */
+    cam_dimension_t max_viewfinder_size;
 } cam_capability_t;
 
 typedef enum {
@@ -629,6 +632,7 @@
     INCLUDE(CAM_INTF_META_OTP_WB_GRGB,                  float,                       1);
     INCLUDE(CAM_INTF_PARM_CAC,                          cam_aberration_mode_t,       1);
     INCLUDE(CAM_INTF_META_NEUTRAL_COL_POINT,            cam_neutral_col_point_t,     1);
+    INCLUDE(CAM_INTF_PARM_ROTATION,                     cam_rotation_info_t,         1);
 } parm_data_t;
 
 typedef parm_data_t metadata_data_t;
diff --git a/camera/QCamera2/stack/common/cam_types.h b/camera/QCamera2/stack/common/cam_types.h
index 4bda244..aeda46e 100644
--- a/camera/QCamera2/stack/common/cam_types.h
+++ b/camera/QCamera2/stack/common/cam_types.h
@@ -116,6 +116,8 @@
 #define GPS_PROCESSING_METHOD_SIZE 33
 #define GPS_PROCESSING_METHOD_SIZE_IN_WORD (33+3)/4
 
+#define MAX_INFLIGHT_REQUESTS  4
+
 typedef enum {
     CAM_HAL_V1 = 1,
     CAM_HAL_V3 = 3
@@ -1543,6 +1545,11 @@
     ROTATE_270 = 1<<3,
 } cam_rotation_t;
 
+typedef struct {
+   cam_rotation_t rotation;
+   uint32_t streamId;
+} cam_rotation_info_t;
+
 typedef enum {
     FLIP_H = 1<<0,
     FLIP_V = 1<<1,
diff --git a/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c b/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
index 4f8d6e3..1d0e21b 100644
--- a/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
+++ b/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
@@ -337,6 +337,8 @@
             return POINTER_OF_META(CAM_INTF_META_NEUTRAL_COL_POINT, metadata);
         case CAM_INTF_PARM_CDS_MODE:
             return POINTER_OF_META(CAM_INTF_PARM_CDS_MODE, metadata);
+        case CAM_INTF_PARM_ROTATION:
+          return POINTER_OF_META(CAM_INTF_PARM_ROTATION, metadata);
         default:
             return NULL;
     }
@@ -650,6 +652,8 @@
             return SIZE_OF_PARAM(CAM_INTF_META_NEUTRAL_COL_POINT, metadata);
         case CAM_INTF_PARM_CDS_MODE:
             return SIZE_OF_PARAM(CAM_INTF_PARM_CDS_MODE, metadata);
+        case CAM_INTF_PARM_ROTATION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ROTATION, metadata);
         default:
             return 0;
     }
diff --git a/camera/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c b/camera/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
index 8dca98b..5ba0748 100644
--- a/camera/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
+++ b/camera/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
@@ -748,18 +748,10 @@
     p_params->main_dim.src_dim.width;
   p_session->inputPort.format.image.nFrameHeight =
     p_params->main_dim.src_dim.height;
-  if (!p_params->rotation &&
-      (p_params->jpeg_orientation == 90 || p_params->jpeg_orientation == 270)) {
-     p_session->inputPort.format.image.nStride =
-       p_src_buf->offset.mp[0].scanline;
-     p_session->inputPort.format.image.nSliceHeight =
+  p_session->inputPort.format.image.nStride =
        p_src_buf->offset.mp[0].stride;
-  } else {
-     p_session->inputPort.format.image.nStride =
-       p_src_buf->offset.mp[0].stride;
-     p_session->inputPort.format.image.nSliceHeight =
+  p_session->inputPort.format.image.nSliceHeight =
        p_src_buf->offset.mp[0].scanline;
-  }
   p_session->inputPort.format.image.eColorFormat =
     map_jpeg_format(p_params->color_format);
   p_session->inputPort.nBufferSize =
@@ -779,19 +771,10 @@
       p_params->thumb_dim.src_dim.width;
     p_session->inputTmbPort.format.image.nFrameHeight =
       p_params->thumb_dim.src_dim.height;
-    if (!p_params->rotation &&
-      (p_params->jpeg_orientation == 90 || p_params->jpeg_orientation == 270)) {
-       p_session->inputTmbPort.format.image.nStride =
-         p_tmb_buf->offset.mp[0].scanline;
-       p_session->inputTmbPort.format.image.nSliceHeight =
+    p_session->inputTmbPort.format.image.nStride =
          p_tmb_buf->offset.mp[0].stride;
-    } else {
-       p_session->inputTmbPort.format.image.nStride =
-         p_tmb_buf->offset.mp[0].stride;
-       p_session->inputTmbPort.format.image.nSliceHeight =
+    p_session->inputTmbPort.format.image.nSliceHeight =
          p_tmb_buf->offset.mp[0].scanline;
-
-    }
     p_session->inputTmbPort.format.image.eColorFormat =
       map_jpeg_format(p_params->thumb_color_format);
     p_session->inputTmbPort.nBufferSize =
diff --git a/gps.conf b/gps.conf
index 394a558..e461385 100644
--- a/gps.conf
+++ b/gps.conf
@@ -5,23 +5,23 @@
 XTRA_SERVER_QUERY=0
 # XTRA_SERVERs below are used only if XTRA_SERVER_QUERY
 # is off.
-XTRA_SERVER_1=http://xtra1.gpsonextra.net/xtra2.bin
-XTRA_SERVER_2=http://xtra2.gpsonextra.net/xtra2.bin
-XTRA_SERVER_3=http://xtra3.gpsonextra.net/xtra2.bin
+XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra2.bin
+XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra2.bin
+XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra2.bin
 
 # Error Estimate
 # _SET = 1
 # _CLEAR = 0
 ERR_ESTIMATE=0
 
-#Test
-NTP_SERVER=time.gpsonextra.net
-#Asia
-# NTP_SERVER=asia.pool.ntp.org
-#Europe
-# NTP_SERVER=europe.pool.ntp.org
-#North America
-# NTP_SERVER=north-america.pool.ntp.org
+# Test
+#NTP_SERVER=time.gpsonextra.net
+# Asia
+#NTP_SERVER=asia.pool.ntp.org
+# Europe
+#NTP_SERVER=europe.pool.ntp.org
+# North America
+#NTP_SERVER=north-america.pool.ntp.org
 
 # DEBUG LEVELS: 0 - none, 1 - Error, 2 - Warning, 3 - Info
 #               4 - Debug, 5 - Verbose
@@ -31,8 +31,8 @@
 # Intermediate position report, 1=enable, 0=disable
 INTERMEDIATE_POS=0
 
-# supl version 2.0
-SUPL_VER=0x20000
+# SUPL version 2.0
+#SUPL_VER=0x20000
 
 # GPS Capabilities bit mask
 # SCHEDULING = 0x01
@@ -41,11 +41,11 @@
 # ON_DEMAND_TIME = 0x10
 # GEOFENCE = 0x20
 # default = ON_DEMAND_TIME | MSA | MSB | SCHEDULING | GEOFENCE
-CAPABILITIES=0x33
+#CAPABILITIES=0x33
 
 # Accuracy threshold for intermediate positions
 # less accurate positions are ignored, 0 for passing all positions
-# ACCURACY_THRES=5000
+#ACCURACY_THRES=5000
 
 ################################
 ##### AGPS server settings #####
@@ -54,12 +54,8 @@
 # FOR SUPL SUPPORT, set the following
 # SUPL_HOST=supl.host.com or IP
 # SUPL_PORT=1234
-SUPL_HOST=supl.google.com
-SUPL_PORT=7275
-
-# FOR C2K PDE SUPPORT, set the following
-# C2K_HOST=c2k.pde.com or IP
-# C2K_PORT=1234
+#SUPL_HOST=supl.google.com
+#SUPL_PORT=7275
 
 # Bitmask of slots that are available
 # for write/install to, where 1s indicate writable,
@@ -77,13 +73,13 @@
 # 1: Enable LPP_User_Plane on LTE
 # 2: Enable LPP_Control_Plane
 # 3: Enable both LPP_User_Plane and LPP_Control_Plane
-LPP_PROFILE = 2
+#LPP_PROFILE = 2
 
 ################################
 # EXTRA SETTINGS
 ################################
 # NMEA provider (1=Modem Processor, 0=Application Processor)
-NMEA_PROVIDER=0
+#NMEA_PROVIDER=0
 
 ##################################################
 # Select Positioning Protocol on A-GLONASS system
@@ -91,4 +87,4 @@
 # 0x1: RRC CPlane
 # 0x2: RRLP UPlane
 # 0x4: LLP Uplane
-A_GLONASS_POS_PROTOCOL_SELECT = 0
+#A_GLONASS_POS_PROTOCOL_SELECT = 0
diff --git a/init.shamu.rc b/init.shamu.rc
index 1bd0f74..d0e1db7 100644
--- a/init.shamu.rc
+++ b/init.shamu.rc
@@ -31,7 +31,6 @@
 
     # Set permissions for persist partition
     mkdir /persist 0771 system system
-    mkdir /firmware 0771 system system
 
     export EXTERNAL_STORAGE /storage/emulated/legacy
     export EMULATED_STORAGE_SOURCE /mnt/shell/emulated
@@ -102,7 +101,8 @@
     write /sys/bus/msm_subsys/devices/subsys0/restart_level "related"
     write /sys/bus/msm_subsys/devices/subsys0/recovery_policy "skip_restart"
     #adsp
-    write /sys/bus/msm_subsys/devices/subsys1/restart_level "system"
+    write /sys/bus/msm_subsys/devices/subsys1/restart_level "related"
+    write /sys/bus/msm_subsys/devices/subsys1/recovery_policy "skip_restart"
     #vpu
     write /sys/bus/msm_subsys/devices/subsys2/restart_level "related"
     write /sys/bus/msm_subsys/devices/subsys2/recovery_policy "skip_restart"
diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml
index 6325394..bbc1382 100644
--- a/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/overlay/frameworks/base/core/res/res/values/config.xml
@@ -124,7 +124,6 @@
          USB interfaces.  If the device doesn't want to support tething over USB this should
          be empty.  An example would be "usb.*" -->
     <string-array translatable="false" name="config_tether_usb_regexs">
-        <item>"usb\\d"</item>
         <item>"rndis\\d"</item>
     </string-array>
 
diff --git a/sepolicy/bluetooth_loader.te b/sepolicy/bluetooth_loader.te
index 15bfdbd..8ac52ba 100644
--- a/sepolicy/bluetooth_loader.te
+++ b/sepolicy/bluetooth_loader.te
@@ -1,9 +1,6 @@
 type bluetooth_loader, domain;
 type bluetooth_loader_exec, exec_type, file_type;
 
-# STOPSHIP - CTS violation
-permissive bluetooth_loader;
-
 # Started by init
 init_daemon_domain(bluetooth_loader)
 
diff --git a/sepolicy/file.te b/sepolicy/file.te
index 7cd1edd..4b40450 100644
--- a/sepolicy/file.te
+++ b/sepolicy/file.te
@@ -11,9 +11,13 @@
 
 type diag_logs, file_type, data_file_type;
 type time_data_file, file_type, data_file_type;
+type gsiffd_data_file, data_file_type, file_type;
+type quipc_data_file, data_file_type, file_type;
 
 type sysfs_rmnet, fs_type, sysfs_type;
 type sysfs_smdcntl_open_timeout, fs_type, sysfs_type;
+type sysfs_xhci_msm_hsic, fs_type, sysfs_type;
+type sysfs_msm_hsic_host, fs_type, sysfs_type;
 
 type persist_file, file_type;
 type persist_data_file, file_type;
diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts
index bd5cd6a..cb79214 100644
--- a/sepolicy/file_contexts
+++ b/sepolicy/file_contexts
@@ -3,6 +3,8 @@
 /data/misc/radio(/.*)?         u:object_r:radio_data_file:s0
 /data/nfc(/.*)?                u:object_r:nfc_data_file:s0
 /data/time(/.*)?               u:object_r:time_data_file:s0
+/data/misc/location/gsiff(/.*)? u:object_r:gsiffd_data_file:s0
+/data/misc/location/quipc(/.*)? u:object_r:quipc_data_file:s0
 
 # Bluetooth
 /dev/ttyHS0                    u:object_r:hci_attach_dev:s0
@@ -125,3 +127,6 @@
 /sys/module/msm_thermal/core_control/cpus_offlined              u:object_r:sysfs_mpdecision:s0
 /sys/devices/system/cpu/cpu0/rq-stats(/.*)?                     u:object_r:sysfs_rqstats:s0
 /sys/module/cpu_boost/parameters(/.*)?                          u:object_r:sysfs_cpuboost:s0
+
+/sys/bus/platform/drivers/xhci_msm_hsic(/.*)?            u:object_r:sysfs_xhci_msm_hsic:s0
+/sys/devices/msm_hsic_host/host_ready                    u:object_r:sysfs_msm_hsic_host:s0
diff --git a/sepolicy/gsiffd.te b/sepolicy/gsiffd.te
index 8d0f9da..da3fd7d 100644
--- a/sepolicy/gsiffd.te
+++ b/sepolicy/gsiffd.te
@@ -1,8 +1,25 @@
 type gsiffd, domain;
 type gsiffd_exec, exec_type, file_type;
 
-# STOPSHIP - CTS violation
-permissive gsiffd;
-
 # Started by init
-init_daemon_domain(gsiffd)
\ No newline at end of file
+init_daemon_domain(gsiffd)
+
+# Write to /data/misc/location/gsiff/
+allow gsiffd gsiffd_data_file:dir rw_dir_perms;
+allow gsiffd gsiffd_data_file:fifo_file create_file_perms;
+
+# Write to /data/misc/location/quipc/
+allow gsiffd quipc_data_file:dir rw_dir_perms;
+allow gsiffd quipc_data_file:sock_file create_file_perms;
+
+# Create sockets
+allow gsiffd self:socket create_socket_perms;
+
+# Talk to qmux
+qmux_socket(gsiffd)
+
+# Run stat on /dev/sensors
+allow gsiffd sensors_device:chr_file getattr;
+
+# Talk to the sensors daemon
+unix_socket_connect(gsiffd, sensors, sensors)
diff --git a/sepolicy/irsc_util.te b/sepolicy/irsc_util.te
index 9c99cca..132c6b5 100644
--- a/sepolicy/irsc_util.te
+++ b/sepolicy/irsc_util.te
@@ -2,9 +2,6 @@
 type irsc_util, domain;
 type irsc_util_exec, exec_type, file_type;
 
-# STOPSHIP - CTS violation
-permissive irsc_util;
-
 # Started by init
 init_daemon_domain(irsc_util)
 
diff --git a/sepolicy/mdm_helper.te b/sepolicy/mdm_helper.te
index 6bc1232..8d6a11b 100644
--- a/sepolicy/mdm_helper.te
+++ b/sepolicy/mdm_helper.te
@@ -7,6 +7,9 @@
 
 init_daemon_domain(mdm_helper)
 
+# access /sys/power/wakelock
+allow mdm_helper self:capability dac_override;
+
 # Spawn /system/bin/efsks and /system/bin/ks
 allow mdm_helper mdm_helper_exec:file { open execute_no_trans getattr };
 
@@ -19,9 +22,24 @@
 
 # Let qcks access /dev/mdm node (modem driver)??
 allow mdm_helper radio_device:chr_file r_file_perms;
-allow mdm_helper modem_block_device:blk_file r_file_perms;
+allow mdm_helper modem_block_device:blk_file rw_file_perms;
+
+allow mdm_helper firmware_file:dir r_dir_perms;
+allow mdm_helper firmware_file:file r_file_perms;
+
+allow mdm_helper fsg_file:file r_file_perms;
 
 allow mdm_helper persist_file:dir rw_dir_perms;
 allow mdm_helper persist_file:file create_file_perms;
 
+# Runs commands via sh.
+allow mdm_helper shell_exec:file rx_file_perms;
+
+allow mdm_helper sysfs_xhci_msm_hsic:dir r_dir_perms;
+allow mdm_helper sysfs_xhci_msm_hsic:file rw_file_perms;
+allow mdm_helper sysfs_msm_hsic_host:file write;
+
+# host_ready not labeled correctly
+allow mdm_helper sysfs:file write;
+
 wakelock_use(mdm_helper)
diff --git a/sepolicy/mpdecision.te b/sepolicy/mpdecision.te
index ec35cbd..cae326d 100644
--- a/sepolicy/mpdecision.te
+++ b/sepolicy/mpdecision.te
@@ -2,9 +2,6 @@
 type mpdecision, domain;
 type mpdecision_exec, exec_type, file_type;
 
-# STOPSHIP - CTS violation
-permissive mpdecision;
-
 # Started by init
 init_daemon_domain(mpdecision)
 
diff --git a/sepolicy/netmgrd.te b/sepolicy/netmgrd.te
index e2f9e62..2bacdda 100644
--- a/sepolicy/netmgrd.te
+++ b/sepolicy/netmgrd.te
@@ -26,10 +26,15 @@
 allow netmgrd system_file:file rx_file_perms;
 
 allow netmgrd self:netlink_socket create_socket_perms;
+allow netmgrd self:netlink_route_socket nlmsg_write;
 allow netmgrd self:netlink_xfrm_socket create_socket_perms;
 
 # b/17065650
 allow netmgrd self:socket {create ioctl read};
 
 # CONFIG_MODULES not set in shamu_defconfig
-dontaudit netmgrd self:capability sys_module;
\ No newline at end of file
+dontaudit netmgrd self:capability sys_module;
+
+# Set net_radio properties
+unix_socket_connect(netmgrd, property, init)
+allow netmgrd net_radio_prop:property_service set;
diff --git a/sepolicy/ss_ramdump.te b/sepolicy/ss_ramdump.te
index 3e134c1..a73e5d8 100644
--- a/sepolicy/ss_ramdump.te
+++ b/sepolicy/ss_ramdump.te
@@ -5,4 +5,7 @@
 permissive ss_ramdump;
 
 # Started by init
-init_daemon_domain(ss_ramdump)
\ No newline at end of file
+init_daemon_domain(ss_ramdump)
+
+# read the contents of the /dev directory
+allow ss_ramdump device:dir r_dir_perms;
diff --git a/sepolicy/thermald.te b/sepolicy/thermald.te
index ce5583d..3588f7f 100644
--- a/sepolicy/thermald.te
+++ b/sepolicy/thermald.te
@@ -24,5 +24,8 @@
 
 allow thermald self:socket create_socket_perms;
 
+# Writes to /sys/module/msm_thermal/core_control/cpus_offlined
+allow thermald sysfs_mpdecision:file rw_file_perms;
+
 # TODO specify specific labels for /sys/ files
-allow thermald sysfs:file write;
\ No newline at end of file
+allow thermald sysfs:file write;