update AU_LINUX_ANDROID_LA.BF64.1.2.9.05.01.00.089.245

a5d1ddb Camera3: Fixes related to flush and abort
9ae95c6 Camera3: Correct the assumption on when to create reprocess channel
8f4ec04 Camera3: Add YUV_888 as a supported output format for reprocess
07a2608 Revert "Camera3: Override CDS mode in Pproc bypass case"
5f72dad QCamera2: HAL3: Add stream based cds into metadata
ce5c2a5 QCamera2: add CDS feature mask
b077914 Camera3: Improve PPROC bypass

Change-Id: I56b361afb98f1598e31089a1dc3cb1774bc7e75e
diff --git a/QCamera2/HAL3/QCamera3Channel.cpp b/QCamera2/HAL3/QCamera3Channel.cpp
index d3c7d82..d395fca 100644
--- a/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/QCamera2/HAL3/QCamera3Channel.cpp
@@ -2912,12 +2912,14 @@
                     camera3_stream_t *stream,
                     uint32_t postprocess_mask,
                     bool is4KVideo,
+                    bool isInputStreamConfigured,
                     QCamera3Channel *metadataChannel,
                     uint32_t numBuffers) :
                         QCamera3ProcessingChannel(cam_handle, cam_ops, cb_routine,
                                 paddingInfo, userData, stream, CAM_STREAM_TYPE_SNAPSHOT,
                                 postprocess_mask, metadataChannel, numBuffers),
                         mNumSnapshotBufs(0),
+                        mInputBufferHint(isInputStreamConfigured),
                         mYuvMemory(NULL)
 {
     QCamera3HardwareInterface* hal_obj = (QCamera3HardwareInterface*)mUserData;
@@ -3342,7 +3344,16 @@
  *==========================================================================*/
 reprocess_type_t QCamera3PicChannel::getReprocessType()
 {
-    return REPROCESS_TYPE_JPEG;
+    /* a picture channel could either use the postprocessor for reprocess+jpeg
+       or only for reprocess */
+    reprocess_type_t expectedReprocess;
+    if (mPostProcMask == CAM_QCOM_FEATURE_NONE || mInputBufferHint) {
+        expectedReprocess = REPROCESS_TYPE_JPEG;
+    } else {
+        expectedReprocess = REPROCESS_TYPE_NONE;
+    }
+    CDBG_HIGH("%s: expectedReprocess from Pic Channel is %d", __func__, expectedReprocess);
+    return expectedReprocess;
 }
 
 /* Reprocess Channel methods */
@@ -3767,9 +3778,9 @@
 }
 
 /*===========================================================================
- * FUNCTION   : extractFrameAndRotation
+ * FUNCTION   : overrideMetadata
  *
- * DESCRIPTION: Extract output rotation and frame data if present
+ * DESCRIPTION: Override metadata entry such as rotation, crop, and CDS info.
  *
  * PARAMETERS :
  *   @frame     : input frame from source stream
@@ -3781,7 +3792,7 @@
  *              NO_ERROR  -- success
  *              none-zero failure code
  *==========================================================================*/
-int32_t QCamera3ReprocessChannel::extractFrameCropAndRotation(qcamera_hal3_pp_buffer_t *pp_buffer,
+int32_t QCamera3ReprocessChannel::overrideMetadata(qcamera_hal3_pp_buffer_t *pp_buffer,
         mm_camera_buf_def_t *meta_buffer, jpeg_settings_t *jpeg_settings,
         qcamera_fwk_input_pp_data_t &fwk_frame)
 {
@@ -3861,6 +3872,28 @@
                 }
             }
 
+            IF_META_AVAILABLE(cam_cds_data_t, cdsInfo, CAM_INTF_META_CDS_DATA, meta) {
+                uint8_t cnt = cdsInfo->num_of_streams;
+                if (cnt <= MAX_NUM_STREAMS) {
+                    cam_stream_cds_info_t repro_cds_info;
+                    memset(&repro_cds_info, 0, sizeof(repro_cds_info));
+                    repro_cds_info.stream_id = mStreams[0]->getMyServerID();
+                    for (size_t i = 0; i < cnt; i++) {
+                        if (cdsInfo->cds_info[i].stream_id ==
+                                pSrcStream->getMyServerID()) {
+                            repro_cds_info.cds_enable =
+                                    cdsInfo->cds_info[i].cds_enable;
+                            break;
+                        }
+                    }
+                    cdsInfo->num_of_streams = 1;
+                    cdsInfo->cds_info[0] = repro_cds_info;
+                } else {
+                    ALOGE("%s: No space to add reprocess stream cds information",
+                            __func__);
+                }
+            }
+
             fwk_frame.input_buffer = *frame->bufs[i];
             fwk_frame.metadata_buffer = *meta_buffer;
             fwk_frame.output_buffer = pp_buffer->output;
@@ -3875,9 +3908,9 @@
 }
 
 /*===========================================================================
-* FUNCTION : extractCrop
+* FUNCTION : overrideFwkMetadata
 *
-* DESCRIPTION: Extract framework output crop if present
+* DESCRIPTION: Override frameworks metadata such as crop, and CDS data.
 *
 * PARAMETERS :
 * @frame : input frame for reprocessing
@@ -3886,7 +3919,8 @@
 * NO_ERROR -- success
 * none-zero failure code
 *==========================================================================*/
-int32_t QCamera3ReprocessChannel::extractCrop(qcamera_fwk_input_pp_data_t *frame)
+int32_t QCamera3ReprocessChannel::overrideFwkMetadata(
+        qcamera_fwk_input_pp_data_t *frame)
 {
     if (NULL == frame) {
         ALOGE("%s: Incorrect input frame", __func__);
@@ -3935,6 +3969,16 @@
         CDBG_HIGH("%s: Crop data not present", __func__);
     }
 
+    IF_META_AVAILABLE(cam_cds_data_t, cdsInfo, CAM_INTF_META_CDS_DATA, meta) {
+        if (1 == cdsInfo->num_of_streams) {
+            cdsInfo->cds_info[0].stream_id = mStreams[0]->getMyServerID();
+        } else {
+            ALOGE("%s: Incorrect number of offline cds info entries %d",
+                    __func__, cdsInfo->num_of_streams);
+            return BAD_VALUE;
+        }
+    }
+
     return NO_ERROR;
 }
 
diff --git a/QCamera2/HAL3/QCamera3Channel.h b/QCamera2/HAL3/QCamera3Channel.h
index 0e1408f..ec16402 100644
--- a/QCamera2/HAL3/QCamera3Channel.h
+++ b/QCamera2/HAL3/QCamera3Channel.h
@@ -428,6 +428,7 @@
             camera3_stream_t *stream,
             uint32_t postprocess_mask,
             bool is4KVideo,
+            bool isInputStreamConfigured,
             QCamera3Channel *metadataChannel,
             uint32_t numBuffers = MAX_INFLIGHT_REQUESTS);
     ~QCamera3PicChannel();
@@ -465,6 +466,7 @@
     uint32_t mNumSnapshotBufs;
     uint32_t mYuvWidth, mYuvHeight;
     int32_t mCurrentBufIndex;
+    bool mInputBufferHint;
     QCamera3StreamMem *mYuvMemory;
     // Keep a list of free buffers
     Mutex mFreeBuffersLock;
@@ -487,11 +489,11 @@
     int32_t doReprocessOffline(qcamera_fwk_input_pp_data_t *frame);
     int32_t doReprocess(int buf_fd, size_t buf_length, int32_t &ret_val,
                         mm_camera_super_buf_t *meta_buf);
-    int32_t extractFrameCropAndRotation(qcamera_hal3_pp_buffer_t *pp_buffer,
+    int32_t overrideMetadata(qcamera_hal3_pp_buffer_t *pp_buffer,
             mm_camera_buf_def_t *meta_buffer,
             jpeg_settings_t *jpeg_settings,
             qcamera_fwk_input_pp_data_t &fwk_frame);
-    int32_t extractCrop(qcamera_fwk_input_pp_data_t *frame);
+    int32_t overrideFwkMetadata(qcamera_fwk_input_pp_data_t *frame);
     virtual QCamera3StreamMem *getStreamBufs(uint32_t len);
     virtual void putStreamBufs();
     virtual int32_t initialize(cam_is_type_t isType);
diff --git a/QCamera2/HAL3/QCamera3HWI.cpp b/QCamera2/HAL3/QCamera3HWI.cpp
index ce4c879..ce3b8b2 100644
--- a/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/QCamera2/HAL3/QCamera3HWI.cpp
@@ -89,7 +89,9 @@
                                               CAM_QCOM_FEATURE_ROTATION |\
                                               CAM_QCOM_FEATURE_SHARPNESS |\
                                               CAM_QCOM_FEATURE_SCALE |\
-                                              CAM_QCOM_FEATURE_CAC )
+                                              CAM_QCOM_FEATURE_CAC |\
+                                              CAM_QCOM_FEATURE_CDS )
+
 #define TIMEOUT_NEVER -1
 
 cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
@@ -345,7 +347,6 @@
       mPrevUrgentFrameNumber(0),
       mPrevFrameNumber(0),
       mNeedSensorRestart(false),
-      mPprocBypass(false),
       mLdafCalibExist(false)
 {
     getLogLevel();
@@ -390,7 +391,7 @@
         CDBG("%s: Override face detection: %d", __func__, m_overrideAppFaceDetection);
     }
 
-    memset(&mInputStreamSize, 0, sizeof(mInputStreamSize));
+    memset(&mInputStreamInfo, 0, sizeof(mInputStreamInfo));
     memset(mLdafCalib, 0, sizeof(mLdafCalib));
 
     memset(prop, 0, sizeof(prop));
@@ -1066,7 +1067,6 @@
 
     pthread_mutex_lock(&mMutex);
 
-    mPprocBypass = false;
     /* Check whether we have video stream */
     m_bIs4KVideo = false;
     m_bIsVideo = false;
@@ -1107,7 +1107,7 @@
     uint32_t maxEisHeight = 0;
     int32_t hal_version = CAM_HAL_V3;
 
-    memset(&mInputStreamSize, 0, sizeof(mInputStreamSize));
+    memset(&mInputStreamInfo, 0, sizeof(mInputStreamInfo));
 
     size_t count = IS_TYPE_MAX;
     count = MIN(gCamCapability[mCameraId]->supported_is_types_cnt, count);
@@ -1368,10 +1368,14 @@
     /* If a zsl stream is set, we know that we have configured at least one input or
        bidirectional stream */
     if (NULL != zslStream) {
-        mInputStreamSize.width = (int32_t)zslStream->width;
-        mInputStreamSize.height = (int32_t)zslStream->height;
-        CDBG("%s: Input stream configured! %d x %d", __func__, mInputStreamSize.width,
-                mInputStreamSize.height);
+        mInputStreamInfo.dim.width = (int32_t)zslStream->width;
+        mInputStreamInfo.dim.height = (int32_t)zslStream->height;
+        mInputStreamInfo.format = zslStream->format;
+        mInputStreamInfo.usage = zslStream->usage;
+        CDBG("%s: Input stream configured! %d x %d, format %d, usage %d",
+                __func__, mInputStreamInfo.dim.width,
+                mInputStreamInfo.dim.height,
+                mInputStreamInfo.format, mInputStreamInfo.usage);
     }
 
     cleanAndSortStreamInfo();
@@ -1483,10 +1487,6 @@
                   mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
                           fullFeatureMask;
               }
-              if (CAM_QCOM_FEATURE_NONE ==
-                      mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams]) {
-                  mPprocBypass = true;
-              }
               break;
            case HAL_PIXEL_FORMAT_BLOB:
               mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_SNAPSHOT;
@@ -1657,7 +1657,7 @@
                             mCameraHandle->ops, captureResultCb,
                             &gCamCapability[mCameraId]->padding_info, this, newStream,
                             mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
-                            m_bIs4KVideo, mMetadataChannel,
+                            m_bIs4KVideo, isZsl, mMetadataChannel,
                             (m_bIsVideo ? 1 : MAX_INFLIGHT_REQUESTS));
                     if (mPictureChannel == NULL) {
                         ALOGE("%s: allocation of channel failed", __func__);
@@ -2873,8 +2873,7 @@
         //Disable CDS for HFR mode and if mPprocBypass = true.
         //CDS is a session parameter in the backend/ISP, so need to be set/reset
         //after every configure_stream
-        if((CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE == mOpMode) ||
-                mPprocBypass) {
+        if(CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE == mOpMode) {
             int32_t cds = CAM_CDS_MODE_OFF;
             if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
                     CAM_INTF_PARM_CDS_MODE, cds))
@@ -3578,36 +3577,51 @@
 }
 
 /*===========================================================================
- * FUNCTION   : getReprocessibleOutputStream
+ * FUNCTION   : getReprocessibleOutputStreamId
  *
- * DESCRIPTION: return the output stream corresponding to the supported input
- *              reprocess stream size, which would be the largest output stream
- *              if an input stream exists
+ * DESCRIPTION: Get source output stream id for the input reprocess stream
+ *              based on size and format, which would be the largest
+ *              output stream if an input stream exists.
  *
- * PARAMETERS : NONE
+ * PARAMETERS :
+ *   @id      : return the stream id if found
  *
- * RETURN     :
- *    stream_info_t* : pointer to largest output stream
- *    NULL if not found
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
  *==========================================================================*/
-stream_info_t* QCamera3HardwareInterface::getReprocessibleOutputStream()
+int32_t QCamera3HardwareInterface::getReprocessibleOutputStreamId(uint32_t &id)
 {
-   /* check if any output or bidirectional stream has the input stream dimensions
-      and return that stream */
-   if ((mInputStreamSize.width > 0) && (mInputStreamSize.height > 0)) {
-       for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
-           it != mStreamInfo.end(); it++) {
-           if (((*it)->stream->width == (uint32_t)mInputStreamSize.width) &&
-                   ((*it)->stream->height == (uint32_t)mInputStreamSize.height)) {
-               CDBG("%s: Found reprocessible output stream! %p", __func__, *it);
-               return *it;
-           }
-       }
-   } else {
-       CDBG("%s: No input stream, so no reprocessible output stream", __func__);
-   }
-   CDBG("%s: Could not find reprocessible output stream", __func__);
-   return NULL;
+    stream_info_t* stream = NULL;
+
+    /* check if any output or bidirectional stream with the same size and format
+       and return that stream */
+    if ((mInputStreamInfo.dim.width > 0) &&
+            (mInputStreamInfo.dim.height > 0)) {
+        for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
+                it != mStreamInfo.end(); it++) {
+
+            camera3_stream_t *stream = (*it)->stream;
+            if ((stream->width == (uint32_t)mInputStreamInfo.dim.width) &&
+                    (stream->height == (uint32_t)mInputStreamInfo.dim.height) &&
+                    (stream->format == mInputStreamInfo.format)) {
+                // Usage flag for an input stream and the source output stream
+                // may be different.
+                CDBG("%s: Found reprocessible output stream! %p", __func__, *it);
+                CDBG("%s: input stream usage 0x%x, current stream usage 0x%x",
+                        __func__, stream->usage, mInputStreamInfo.usage);
+
+                QCamera3Channel *channel = (QCamera3Channel *)stream->priv;
+                if (channel != NULL && channel->mStreams[0]) {
+                    id = channel->mStreams[0]->getMyServerID();
+                    return NO_ERROR;
+                }
+            }
+        }
+    } else {
+        CDBG("%s: No input stream, so no reprocessible output stream", __func__);
+    }
+    return NAME_NOT_FOUND;
 }
 
 /*===========================================================================
@@ -4339,22 +4353,20 @@
     IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, metadata) {
         uint8_t cnt = crop_data->num_of_streams;
         if ((0 < cnt) && (cnt < MAX_NUM_STREAMS)) {
-            stream_info_t* reprocessible_stream = getReprocessibleOutputStream();
-            if (NULL == reprocessible_stream) {
+            uint32_t reproc_stream_id;
+            if ( NO_ERROR != getReprocessibleOutputStreamId(reproc_stream_id)) {
                 CDBG("%s: No reprocessible stream found, ignore crop data", __func__);
             } else {
-                QCamera3Channel *channel = (QCamera3Channel *)reprocessible_stream->stream->priv;
                 int rc = NO_ERROR;
                 Vector<int32_t> roi_map;
                 int32_t *crop = new int32_t[cnt*4];
                 if (NULL == crop) {
                    rc = NO_MEMORY;
                 }
-                if (NO_ERROR == rc && NULL != channel) {
+                if (NO_ERROR == rc) {
                     int32_t streams_found = 0;
-                    uint32_t reprocessible_stream_id = channel->mStreams[0]->getMyServerID();
                     for (size_t i = 0; i < cnt; i++) {
-                        if (crop_data->crop_info[i].stream_id == reprocessible_stream_id) {
+                        if (crop_data->crop_info[i].stream_id == reproc_stream_id) {
                             crop[0] = crop_data->crop_info[i].crop.left;
                             crop[1] = crop_data->crop_info[i].crop.top;
                             crop[2] = crop_data->crop_info[i].crop.width;
@@ -4364,16 +4376,14 @@
                             roi_map.add(crop_data->crop_info[i].roi_map.width);
                             roi_map.add(crop_data->crop_info[i].roi_map.height);
                             streams_found++;
-                            CDBG("%s: Adding reprocess crop data for stream %p %dx%d, %dx%d",
+                            CDBG("%s: Adding reprocess crop data for stream %dx%d, %dx%d",
                                     __func__,
-                                    reprocessible_stream->stream,
                                     crop_data->crop_info[i].crop.left,
                                     crop_data->crop_info[i].crop.top,
                                     crop_data->crop_info[i].crop.width,
                                     crop_data->crop_info[i].crop.height);
-                            CDBG("%s: Adding reprocess crop roi map for stream %p %dx%d, %dx%d",
+                            CDBG("%s: Adding reprocess crop roi map for stream %dx%d, %dx%d",
                                     __func__,
-                                    reprocessible_stream->stream,
                                     crop_data->crop_info[i].roi_map.left,
                                     crop_data->crop_info[i].roi_map.top,
                                     crop_data->crop_info[i].roi_map.width,
@@ -4414,6 +4424,35 @@
         }
     }
 
+    // Post blob of cam_cds_data through vendor tag.
+    IF_META_AVAILABLE(cam_cds_data_t, cdsInfo, CAM_INTF_META_CDS_DATA, metadata) {
+        uint8_t cnt = cdsInfo->num_of_streams;
+        cam_cds_data_t cdsDataOverride;
+        memset(&cdsDataOverride, 0, sizeof(cdsDataOverride));
+        cdsDataOverride.session_cds_enable = cdsInfo->session_cds_enable;
+        cdsDataOverride.num_of_streams = 1;
+        if ((0 < cnt) && (cnt <= MAX_NUM_STREAMS)) {
+            uint32_t reproc_stream_id;
+            if ( NO_ERROR != getReprocessibleOutputStreamId(reproc_stream_id)) {
+                CDBG("%s: No reprocessible stream found, ignore cds data", __func__);
+            } else {
+                for (size_t i = 0; i < cnt; i++) {
+                    if (cdsInfo->cds_info[i].stream_id ==
+                            reproc_stream_id) {
+                        cdsDataOverride.cds_info[0].cds_enable =
+                                cdsInfo->cds_info[i].cds_enable;
+                        break;
+                    }
+                }
+            }
+        } else {
+            ALOGE("%s: Invalid stream count %d in CDS_DATA", __func__, cnt);
+        }
+        camMetadata.update(QCAMERA3_CDS_INFO,
+                (uint8_t *)&cdsDataOverride,
+                sizeof(cam_cds_data_t));
+    }
+
     // Ldaf calibration data
     if (!mLdafCalibExist) {
         IF_META_AVAILABLE(uint32_t, ldafCalib,
@@ -5902,8 +5941,11 @@
                       &max_input_streams,
                       1);
 
-    int32_t io_format_map[] = {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 1, HAL_PIXEL_FORMAT_BLOB,
-            HAL_PIXEL_FORMAT_YCbCr_420_888, 1,HAL_PIXEL_FORMAT_BLOB};
+    /* format of the map is : input format, num_output_formats, outputFormat1,..,outputFormatN */
+    int32_t io_format_map[] = {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 2,
+            HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_YCbCr_420_888,
+            HAL_PIXEL_FORMAT_YCbCr_420_888, 2, HAL_PIXEL_FORMAT_BLOB,
+            HAL_PIXEL_FORMAT_YCbCr_420_888};
     staticInfo.update(ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
                       io_format_map, sizeof(io_format_map)/sizeof(io_format_map[0]));
 
@@ -7777,7 +7819,6 @@
 
     // CDS for non-HFR mode
     if ((mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
-            (false == mPprocBypass) &&
             frame_settings.exists(QCAMERA3_CDS_MODE)) {
         int32_t *fwk_cds = frame_settings.find(QCAMERA3_CDS_MODE).data.i32;
         if ((CAM_CDS_MODE_MAX <= *fwk_cds) || (0 > *fwk_cds)) {
@@ -7948,6 +7989,17 @@
         rc = BAD_VALUE;
     }
 
+    // CDS info
+    if (frame_settings.exists(QCAMERA3_CDS_INFO)) {
+        cam_cds_data_t *cdsData = (cam_cds_data_t *)
+                frame_settings.find(QCAMERA3_CDS_INFO).data.u8;
+
+        if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
+                CAM_INTF_META_CDS_DATA, *cdsData)) {
+            rc = BAD_VALUE;
+        }
+    }
+
     return rc;
 }
 
@@ -8774,8 +8826,16 @@
 
     memset(&result, 0, sizeof(camera3_capture_result_t));
 
-    pendingRequestIterator i = mPendingRequestsList.begin();
-    frameNum = i->frame_number;
+    if (mPendingRequestsList.size() > 0) {
+        pendingRequestIterator i = mPendingRequestsList.begin();
+        frameNum = i->frame_number;
+    } else {
+        /* There might still be pending buffers even though there are
+         no pending requests. Setting the frameNum to MAX so that
+         all the buffers with smaller frame numbers are returned */
+        frameNum = UINT_MAX;
+    }
+
     CDBG_HIGH("%s: Oldest frame num on  mPendingRequestsList = %d",
       __func__, frameNum);
 
@@ -8868,6 +8928,8 @@
         k = mPendingBuffersMap.mPendingBufferList.erase(k);
     }
 
+    pendingRequestIterator i = mPendingRequestsList.begin(); //make sure i is at the beginning
+
     // Go through the pending requests info and send error request to framework
     for (size_t iFlush = 0; iFlush < flushMap.size(); iFlush++) {
         uint32_t frame_number = flushMap.keyAt(iFlush);
@@ -8900,19 +8962,16 @@
             pStream_Buf[j].stream = info.stream;
         }
 
+        result.input_buffer = i->input_buffer;
         result.num_output_buffers = (uint32_t)pending.size();
         result.output_buffers = pStream_Buf;
         result.result = NULL;
         result.frame_number = frame_number;
         mCallbackOps->process_capture_result(mCallbackOps, &result);
         delete [] pStream_Buf;
-    }
-
-    /* Reset pending buffer list and requests list */
-    for (pendingRequestIterator i = mPendingRequestsList.begin();
-            i != mPendingRequestsList.end();) {
         i = erasePendingRequest(i);
     }
+
     /* Reset pending frame Drop list and requests list */
     mPendingFrameDropList.clear();
 
diff --git a/QCamera2/HAL3/QCamera3HWI.h b/QCamera2/HAL3/QCamera3HWI.h
index 13161ab..9a0678d 100644
--- a/QCamera2/HAL3/QCamera3HWI.h
+++ b/QCamera2/HAL3/QCamera3HWI.h
@@ -259,7 +259,7 @@
     int32_t startAllChannels();
     int32_t stopAllChannels();
     int32_t notifyErrorForPendingRequests();
-    stream_info_t* getReprocessibleOutputStream();
+    int32_t getReprocessibleOutputStreamId(uint32_t &id);
 
     bool isOnEncoder(const cam_dimension_t max_viewfinder_size,
             uint32_t width, uint32_t height);
@@ -295,7 +295,13 @@
     bool m_bIs4KVideo;
     bool m_bEisSupportedSize;
     bool m_bEisEnable;
-    cam_dimension_t mInputStreamSize;
+    typedef struct {
+        cam_dimension_t dim;
+        int format;
+        uint32_t usage;
+    } InputStreamInfo;
+
+    InputStreamInfo mInputStreamInfo;
     uint8_t m_MobicatMask;
     int8_t  m_overrideAppFaceDetection;
     uint8_t m_bTnrEnabled;
@@ -398,9 +404,6 @@
     /* sensor output size with current stream configuration */
     QCamera3CropRegionMapper mCropRegionMapper;
 
-    /* Whether PPROC bypass is enabled for YUV888 */
-    bool mPprocBypass;
-
     /* Ldaf calibration data */
     bool mLdafCalibExist;
     uint32_t mLdafCalib[2];
diff --git a/QCamera2/HAL3/QCamera3PostProc.cpp b/QCamera2/HAL3/QCamera3PostProc.cpp
index f91bc98..e88e181 100644
--- a/QCamera2/HAL3/QCamera3PostProc.cpp
+++ b/QCamera2/HAL3/QCamera3PostProc.cpp
@@ -216,7 +216,7 @@
     int32_t rc = NO_ERROR;
     QCamera3HardwareInterface* hal_obj = (QCamera3HardwareInterface*)m_parent->mUserData;
 
-    if (hal_obj->needReprocess(mPostProcMask) || config.src_channel != m_parent) {
+    if (config.reprocess_type != REPROCESS_TYPE_NONE) {
         if (m_pReprocChannel != NULL) {
             m_pReprocChannel->stop();
             delete m_pReprocChannel;
@@ -569,8 +569,7 @@
 int32_t QCamera3PostProcessor::processData(qcamera_fwk_input_pp_data_t *frame)
 {
     QCamera3HardwareInterface* hal_obj = (QCamera3HardwareInterface*)m_parent->mUserData;
-    if (hal_obj->needReprocess(mPostProcMask) ||
-            frame->reproc_config.src_channel != m_parent) {
+    if (frame->reproc_config.reprocess_type != REPROCESS_TYPE_NONE) {
         pthread_mutex_lock(&mReprocJobLock);
         // enqueu to post proc input queue
         m_inputFWKPPQ.enqueue((void *)frame);
@@ -1693,7 +1692,7 @@
                                 memset(pp_job, 0, sizeof(qcamera_hal3_pp_data_t));
                                 pp_job->jpeg_settings = jpeg_settings;
                                 if (pme->m_pReprocChannel != NULL) {
-                                    if (NO_ERROR != pme->m_pReprocChannel->extractCrop(fwk_frame)) {
+                                    if (NO_ERROR != pme->m_pReprocChannel->overrideFwkMetadata(fwk_frame)) {
                                         ALOGE("%s: Failed to extract output crop", __func__);
                                     }
                                     // add into ongoing PP job Q
@@ -1762,7 +1761,7 @@
                                 qcamera_fwk_input_pp_data_t fwk_frame;
                                 memset(&fwk_frame, 0, sizeof(qcamera_fwk_input_pp_data_t));
                                 fwk_frame.frameNumber = pp_buffer->frameNumber;
-                                ret = pme->m_pReprocChannel->extractFrameCropAndRotation(
+                                ret = pme->m_pReprocChannel->overrideMetadata(
                                         pp_buffer, meta_buffer_arg,
                                         pp_job->jpeg_settings,
                                         fwk_frame);
diff --git a/QCamera2/HAL3/QCamera3VendorTags.cpp b/QCamera2/HAL3/QCamera3VendorTags.cpp
index 7f75364..fbc84c4 100644
--- a/QCamera2/HAL3/QCamera3VendorTags.cpp
+++ b/QCamera2/HAL3/QCamera3VendorTags.cpp
@@ -76,7 +76,8 @@
 };
 
 vendor_tag_info_t qcamera3_cds[QCAMERA3_CDS_END - QCAMERA3_CDS_START] = {
-    { "cds_mode", TYPE_INT32 }
+    { "cds_mode", TYPE_INT32 },
+    { "cds_info", TYPE_BYTE }
 };
 
 vendor_tag_info_t qcamera3_opaque_raw[QCAMERA3_OPAQUE_RAW_END -
@@ -130,6 +131,7 @@
 
     // QCAMERA3_CDS
     (uint32_t)QCAMERA3_CDS_MODE,
+    (uint32_t)QCAMERA3_CDS_INFO,
 
     // QCAMERA3_OPAQUE_RAW
     (uint32_t)QCAMERA3_OPAQUE_RAW_STRIDES,
diff --git a/QCamera2/HAL3/QCamera3VendorTags.h b/QCamera2/HAL3/QCamera3VendorTags.h
index 3c2ea72..259953a 100644
--- a/QCamera2/HAL3/QCamera3VendorTags.h
+++ b/QCamera2/HAL3/QCamera3VendorTags.h
@@ -59,6 +59,7 @@
     QCAMERA3_PRIVATEDATA_REPROCESS = QCAMERA3_PRIVATEDATA_START,
     QCAMERA3_PRIVATEDATA_END,
     QCAMERA3_CDS_MODE = QCAMERA3_CDS_START,
+    QCAMERA3_CDS_INFO,
     QCAMERA3_CDS_END,
 
     //Property Name:  org.codeaurora.qcamera3.opaque_raw.opaque_raw_strides
diff --git a/QCamera2/stack/common/cam_intf.h b/QCamera2/stack/common/cam_intf.h
index 25ac251..fe0cdc0 100644
--- a/QCamera2/stack/common/cam_intf.h
+++ b/QCamera2/stack/common/cam_intf.h
@@ -580,6 +580,7 @@
     INCLUDE(CAM_INTF_META_HISTOGRAM,                    cam_hist_stats_t,               1);
     INCLUDE(CAM_INTF_META_FACE_DETECTION,               cam_face_detection_data_t,      1);
     INCLUDE(CAM_INTF_META_AUTOFOCUS_DATA,               cam_auto_focus_data_t,          1);
+    INCLUDE(CAM_INTF_META_CDS_DATA,                     cam_cds_data_t,                 1);
     INCLUDE(CAM_INTF_PARM_UPDATE_DEBUG_LEVEL,           uint32_t,                       1);
 
     /* Specific to HAl1 */
diff --git a/QCamera2/stack/common/cam_types.h b/QCamera2/stack/common/cam_types.h
index 906afad..862cf78 100644
--- a/QCamera2/stack/common/cam_types.h
+++ b/QCamera2/stack/common/cam_types.h
@@ -1158,6 +1158,17 @@
     cam_stream_crop_info_t crop_info[MAX_NUM_STREAMS];
 } cam_crop_data_t;
 
+typedef struct {
+    uint32_t stream_id;
+    uint32_t cds_enable;
+} cam_stream_cds_info_t;
+
+typedef struct {
+    uint8_t session_cds_enable;
+    uint8_t num_of_streams;
+    cam_stream_cds_info_t cds_info[MAX_NUM_STREAMS];
+} cam_cds_data_t;
+
 typedef enum {
     DO_NOT_NEED_FUTURE_FRAME,
     NEED_FUTURE_FRAME,
@@ -1745,6 +1756,7 @@
     CAM_INTF_META_LDAF_EXIF,
     CAM_INTF_META_BLACK_LEVEL_SOURCE_PATTERN,
     CAM_INTF_META_BLACK_LEVEL_APPLIED_PATTERN,
+    CAM_INTF_META_CDS_DATA,
     CAM_INTF_PARM_MAX
 } cam_intf_parm_type_t;
 
@@ -1961,7 +1973,8 @@
 #define CAM_QCOM_FEATURE_LLVD           (1U<<20)
 #define CAM_QCOM_FEATURE_DIS20          (1U<<21)
 #define CAM_QCOM_FEATURE_STILLMORE      (1U<<22)
-#define CAM_QCOM_FEATURE_MAX            (1U<<23)
+#define CAM_QCOM_FEATURE_CDS            (1U<<23)
+#define CAM_QCOM_FEATURE_MAX            (1U<<24)
 #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)