Camera3: HAL 3.3 Reprocess: Opaque/YUV to JPEG

-Add support for enabling Opaque/YUV to JPEG reprocessing

Change-Id: I66020e946f2787d2554f496c015438b11a07a2d2
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index cea4342..a38857f 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -245,7 +245,6 @@
       mCameraOpened(false),
       mCameraInitialized(false),
       mCallbackOps(NULL),
-      mInputStream(NULL),
       mMetadataChannel(NULL),
       mPictureChannel(NULL),
       mRawChannel(NULL),
@@ -269,7 +268,7 @@
 {
     getLogLevel();
     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
-    mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_2;
+    mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_3;
     mCameraDevice.common.close = close_camera_device;
     mCameraDevice.ops = &mCameraOps;
     mCameraDevice.priv = this;
@@ -605,6 +604,19 @@
     int32_t available_jpeg_sizes[MAX_SIZES_CNT * 2];
     uint8_t jpeg_sizes_cnt = 0;
 
+    camera3_stream_t *inputStream = NULL;
+    /*
+    * Loop through all streams to find input stream if it exists*
+    */
+    for (size_t i = 0; i< streamList->num_streams; i++) {
+        if (streamList->streams[i]->stream_type == CAMERA3_STREAM_INPUT) {
+            if (inputStream != NULL) {
+                ALOGE("%s: Error, Multiple input streams requested");
+                return -EINVAL;
+            }
+            inputStream = streamList->streams[i];
+        }
+    }
     /*
     * Loop through all streams requested in configuration
     * Check if unsupported sizes have been requested on any of them
@@ -657,10 +669,22 @@
 
 
         case HAL_PIXEL_FORMAT_YCbCr_420_888:
+            if (inputStream) {
+                if (inputStream->format == newStream->format) {
+                    if ((int32_t)(newStream->width) ==
+                            gCamCapability[mCameraId]->active_array_size.width
+                            && (int32_t)(newStream->height)  ==
+                            gCamCapability[mCameraId]->active_array_size.height) {
+                        sizeFound = true;
+                    }
+                }
+            }
         case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
         default:
             /* ZSL stream will be full active array size validate that*/
-            if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
+            if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL
+                || newStream->stream_type == CAMERA3_STREAM_INPUT
+                || newStream->usage & GRALLOC_USAGE_HW_CAMERA_ZSL){
                 if ((int32_t)(newStream->width) ==
                     gCamCapability[mCameraId]->active_array_size.width
                     && (int32_t)(newStream->height)  ==
@@ -694,6 +718,9 @@
             ALOGE("%s: Error: Unsupported size of  %d x %d requested for stream"
                   "type:%d", __func__, newStream->width, newStream->height,
                   newStream->format);
+            ALOGE("%s: Active array size is  %d x %d", __func__,
+                    gCamCapability[mCameraId]->active_array_size.width,
+                    gCamCapability[mCameraId]->active_array_size.height);
             rc = -EINVAL;
             break;
         }
@@ -806,16 +833,22 @@
     bool bUseCommonFeatureMask = false;
     uint32_t commonFeatureMask = 0;
     maxViewfinderSize = gCamCapability[mCameraId]->max_viewfinder_size;
+    camera3_stream_t *inputStream = NULL;
 
     for (size_t i = 0; i < streamList->num_streams; i++) {
         camera3_stream_t *newStream = streamList->streams[i];
         CDBG_HIGH("%s: stream[%d] type = %d, format = %d, width = %d, height = %d",
                 __func__, i, newStream->stream_type, newStream->format,
                 newStream->width, newStream->height);
-        if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
-                newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED){
+
+        if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
+                newStream->stream_type == CAMERA3_STREAM_INPUT){
             isZsl = true;
         }
+        if (newStream->stream_type == CAMERA3_STREAM_INPUT){
+            inputStream = newStream;
+        }
+
         if (newStream->format == HAL_PIXEL_FORMAT_BLOB) {
             if (newStream->width > VIDEO_4K_WIDTH ||
                     newStream->height > VIDEO_4K_HEIGHT)
@@ -853,7 +886,8 @@
                 processedStreamCnt++;
                 if (newStream->width > (uint32_t)maxViewfinderSize.width ||
                         newStream->height > (uint32_t)maxViewfinderSize.height) {
-                    if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
+                    if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
+                            newStream->usage & GRALLOC_USAGE_HW_CAMERA_ZSL) {
                         commonFeatureMask |= CAM_QCOM_FEATURE_NONE;
                     } else {
                         commonFeatureMask |= CAM_QCOM_FEATURE_PP_SUPERSET;
@@ -916,9 +950,10 @@
         return rc;
     }
 
-    camera3_stream_t *inputStream = NULL;
+    camera3_stream_t *zslStream = NULL;
     camera3_stream_t *jpegStream = NULL;
     cam_stream_size_info_t stream_config_info;
+    memset(&stream_config_info, 0, sizeof(cam_stream_size_info_t));
     for (size_t i = 0; i < streamList->num_streams; i++) {
         camera3_stream_t *newStream = streamList->streams[i];
         CDBG_HIGH("%s: newStream type = %d, stream format = %d stream size : %d x %d",
@@ -932,13 +967,14 @@
                 QCamera3Channel *channel =
                     (QCamera3Channel*)(*it)->stream->priv;
                 stream_exists = true;
-                delete channel;
+                if (channel)
+                    delete channel;
                 (*it)->status = VALID;
                 (*it)->stream->priv = NULL;
                 (*it)->channel = NULL;
             }
         }
-        if (!stream_exists) {
+        if (!stream_exists && newStream->stream_type != CAMERA3_STREAM_INPUT) {
             //new stream
             stream_info_t* stream_info;
             stream_info = (stream_info_t* )malloc(sizeof(stream_info_t));
@@ -947,20 +983,35 @@
             stream_info->channel = NULL;
             mStreamInfo.push_back(stream_info);
         }
-        if (newStream->stream_type == CAMERA3_STREAM_INPUT
+        /* Covers Opaque ZSL and API1 F/W ZSL */
+        if (newStream->usage & GRALLOC_USAGE_HW_CAMERA_ZSL
                 || newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ) {
-            if (inputStream != NULL) {
-                ALOGE("%s: Multiple input streams requested!", __func__);
+            if (zslStream != NULL) {
+                ALOGE("%s: Multiple input/reprocess streams requested!", __func__);
                 pthread_mutex_unlock(&mMutex);
                 return BAD_VALUE;
             }
-            inputStream = newStream;
+            zslStream = newStream;
+        }
+        /* Covers YUV reprocess */
+        if (inputStream != NULL) {
+            if (newStream->stream_type == CAMERA3_STREAM_OUTPUT
+                    && newStream->format == HAL_PIXEL_FORMAT_YCbCr_420_888
+                    && inputStream->format == HAL_PIXEL_FORMAT_YCbCr_420_888
+                    && inputStream->width == newStream->width
+                    && inputStream->height == newStream->height) {
+                if (zslStream != NULL) {
+                    ALOGE("%s: Multiple input/reprocess streams requested!", __func__);
+                    pthread_mutex_unlock(&mMutex);
+                    return BAD_VALUE;
+                }
+                zslStream = newStream;
+            }
         }
         if (newStream->format == HAL_PIXEL_FORMAT_BLOB) {
             jpegStream = newStream;
         }
     }
-    mInputStream = inputStream;
 
     cleanAndSortStreamInfo();
     if (mMetadataChannel) {
@@ -1011,74 +1062,86 @@
     for (size_t i = 0; i < streamList->num_streams; i++) {
         camera3_stream_t *newStream = streamList->streams[i];
         uint32_t stream_usage = newStream->usage;
-        stream_config_info.stream_sizes[i].width = newStream->width;
-        stream_config_info.stream_sizes[i].height = newStream->height;
-        if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
-            newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED && jpegStream){
+        stream_config_info.stream_sizes[stream_config_info.num_streams].width = newStream->width;
+        stream_config_info.stream_sizes[stream_config_info.num_streams].height = newStream->height;
+        if ((newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL
+                || newStream->usage & GRALLOC_USAGE_HW_CAMERA_ZSL)
+                && newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
+                && jpegStream){
             //for zsl stream the size is active array size
-            stream_config_info.stream_sizes[i].width =
+            // FIXME remove this for api zsl bidirectional is alway active array size
+            // and for hal 3.3 reprocess, we will *indirectly* control using input size.
+            // there is a grey area however when the application whimsically decides to create
+            // a standalone zsl stream whose size < jpeg blob size
+            /*
+            stream_config_info.stream_sizes[stream_config_info.num_streams].width =
                     gCamCapability[mCameraId]->active_array_size.width;
-            stream_config_info.stream_sizes[i].height =
+            stream_config_info.stream_sizes[stream_config_info.num_streams].height =
                     gCamCapability[mCameraId]->active_array_size.height;
-            stream_config_info.type[i] = CAM_STREAM_TYPE_SNAPSHOT;
-            stream_config_info.postprocess_mask[i] = CAM_QCOM_FEATURE_NONE;
+            */
+            stream_config_info.type[stream_config_info.num_streams] = CAM_STREAM_TYPE_SNAPSHOT;
+            stream_config_info.postprocess_mask[stream_config_info.num_streams] = CAM_QCOM_FEATURE_NONE;
+        } else if(newStream->stream_type == CAMERA3_STREAM_INPUT) {
+                CDBG_HIGH("%s: Input stream configured, reprocess config", __func__);
         } else {
-           //for non zsl streams find out the format
-           switch (newStream->format) {
-           case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED :
+            //for non zsl streams find out the format
+            switch (newStream->format) {
+            case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED :
               {
                  if (stream_usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
-                    stream_config_info.type[i] = CAM_STREAM_TYPE_VIDEO;
+                    stream_config_info.type[stream_config_info.num_streams] = CAM_STREAM_TYPE_VIDEO;
                  } else {
-                    stream_config_info.type[i] = CAM_STREAM_TYPE_PREVIEW;
+                    stream_config_info.type[stream_config_info.num_streams] = CAM_STREAM_TYPE_PREVIEW;
                  }
-                 stream_config_info.postprocess_mask[i] = CAM_QCOM_FEATURE_PP_SUPERSET;
+                 stream_config_info.postprocess_mask[stream_config_info.num_streams] = CAM_QCOM_FEATURE_PP_SUPERSET;
               }
               break;
-           case HAL_PIXEL_FORMAT_YCbCr_420_888:
-              stream_config_info.type[i] = CAM_STREAM_TYPE_CALLBACK;
-              stream_config_info.postprocess_mask[i] = CAM_QCOM_FEATURE_PP_SUPERSET;
+            case HAL_PIXEL_FORMAT_YCbCr_420_888:
+              stream_config_info.type[stream_config_info.num_streams] = CAM_STREAM_TYPE_CALLBACK;
+              stream_config_info.postprocess_mask[stream_config_info.num_streams] = CAM_QCOM_FEATURE_PP_SUPERSET;
               break;
-           case HAL_PIXEL_FORMAT_BLOB:
-              stream_config_info.type[i] = CAM_STREAM_TYPE_SNAPSHOT;
+            case HAL_PIXEL_FORMAT_BLOB:
+              stream_config_info.type[stream_config_info.num_streams] = CAM_STREAM_TYPE_SNAPSHOT;
               if (m_bIs4KVideo && !isZsl) {
-                  stream_config_info.postprocess_mask[i] = CAM_QCOM_FEATURE_PP_SUPERSET;
+                  stream_config_info.postprocess_mask[stream_config_info.num_streams] = CAM_QCOM_FEATURE_PP_SUPERSET;
               } else {
                   if (bUseCommonFeatureMask &&
                           (newStream->width > (uint32_t)maxViewfinderSize.width ||
                                   newStream->height > (uint32_t)maxViewfinderSize.height)) {
-                      stream_config_info.postprocess_mask[i] = commonFeatureMask;
+                      stream_config_info.postprocess_mask[stream_config_info.num_streams] = commonFeatureMask;
                   } else {
-                      stream_config_info.postprocess_mask[i] = CAM_QCOM_FEATURE_NONE;
+                      stream_config_info.postprocess_mask[stream_config_info.num_streams] = CAM_QCOM_FEATURE_NONE;
                   }
               }
               if (isZsl) {
-                  stream_config_info.stream_sizes[i].width =
+                  stream_config_info.stream_sizes[stream_config_info.num_streams].width =
                           gCamCapability[mCameraId]->active_array_size.width;
-                  stream_config_info.stream_sizes[i].height =
+                  stream_config_info.stream_sizes[stream_config_info.num_streams].height =
                           gCamCapability[mCameraId]->active_array_size.height;
               } else if (m_bIs4KVideo) {
-                  stream_config_info.stream_sizes[i].width = videoWidth;
-                  stream_config_info.stream_sizes[i].height = videoHeight;
+                  stream_config_info.stream_sizes[stream_config_info.num_streams].width = videoWidth;
+                  stream_config_info.stream_sizes[stream_config_info.num_streams].height = videoHeight;
               }
               break;
-           case HAL_PIXEL_FORMAT_RAW_OPAQUE:
-           case HAL_PIXEL_FORMAT_RAW16:
-           case HAL_PIXEL_FORMAT_RAW10:
-              stream_config_info.type[i] = CAM_STREAM_TYPE_RAW;
+            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+            case HAL_PIXEL_FORMAT_RAW16:
+            case HAL_PIXEL_FORMAT_RAW10:
+              stream_config_info.type[stream_config_info.num_streams] = CAM_STREAM_TYPE_RAW;
               isRawStreamRequested = true;
               break;
-           default:
-              stream_config_info.type[i] = CAM_STREAM_TYPE_DEFAULT;
-              stream_config_info.postprocess_mask[i] = CAM_QCOM_FEATURE_NONE;
+            default:
+              stream_config_info.type[stream_config_info.num_streams] = CAM_STREAM_TYPE_DEFAULT;
+              stream_config_info.postprocess_mask[stream_config_info.num_streams] = CAM_QCOM_FEATURE_NONE;
               break;
-           }
+            }
+
         }
         if (newStream->priv == NULL) {
             //New stream, construct channel
             switch (newStream->stream_type) {
             case CAMERA3_STREAM_INPUT:
                 newStream->usage = GRALLOC_USAGE_HW_CAMERA_READ;
+                newStream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;//WR for inplace algo's
                 break;
             case CAMERA3_STREAM_BIDIRECTIONAL:
                 newStream->usage = GRALLOC_USAGE_HW_CAMERA_READ |
@@ -1112,8 +1175,8 @@
                             &gCamCapability[mCameraId]->padding_info,
                             this,
                             newStream,
-                            (cam_stream_type_t) stream_config_info.type[i],
-                            stream_config_info.postprocess_mask[i]);
+                            (cam_stream_type_t) stream_config_info.type[stream_config_info.num_streams],
+                            stream_config_info.postprocess_mask[stream_config_info.num_streams]);
                     if (channel == NULL) {
                         ALOGE("%s: allocation of channel failed", __func__);
                         pthread_mutex_unlock(&mMutex);
@@ -1145,7 +1208,7 @@
                     mPictureChannel = new QCamera3PicChannel(mCameraHandle->camera_handle,
                             mCameraHandle->ops, captureResultCb,
                             &gCamCapability[mCameraId]->padding_info, this, newStream,
-                            stream_config_info.postprocess_mask[i],
+                            stream_config_info.postprocess_mask[stream_config_info.num_streams],
                             m_bIs4KVideo, mMetadataChannel);
                     if (mPictureChannel == NULL) {
                         ALOGE("%s: allocation of channel failed", __func__);
@@ -1159,6 +1222,11 @@
                     ALOGE("%s: not a supported format 0x%x", __func__, newStream->format);
                     break;
                 }
+            } else if (newStream->stream_type == CAMERA3_STREAM_INPUT) {
+                newStream->max_buffers = MAX_INFLIGHT_REPROCESS_REQUESTS;
+            } else {
+                ALOGE("%s: Error, Unknown stream type", __func__);
+                return -EINVAL;
             }
 
             for (List<stream_info_t*>::iterator it=mStreamInfo.begin();
@@ -1172,12 +1240,26 @@
             // Channel already exists for this stream
             // Do nothing for now
         }
+
+    /* Do not add entries for input stream in metastream info
+         * since there is no real stream associated with it
+         */
+        if (newStream->stream_type != CAMERA3_STREAM_INPUT)
+            stream_config_info.num_streams++;
     }
 
     if (isZsl) {
-        mPictureChannel->overrideYuvSize(
-                gCamCapability[mCameraId]->active_array_size.width,
-                gCamCapability[mCameraId]->active_array_size.height);
+        if (zslStream == NULL) {
+            ALOGE("%s: Error Zsl stream handle missing", __func__);
+            pthread_mutex_unlock(&mMutex);
+            return -EINVAL;
+        }
+        /* This override is possible since the f/w gaurantees that the ZSL
+           stream will always be the active array size in case of Bidirectional
+           or will be limited to the max i/p stream size which we can control to
+           be equal to active array size
+           */
+        mPictureChannel->overrideYuvSize(zslStream->width, zslStream->height);
     } else if (mPictureChannel && m_bIs4KVideo) {
         mPictureChannel->overrideYuvSize(videoWidth, videoHeight);
     }
@@ -1199,12 +1281,13 @@
     }
 
 
-    stream_config_info.num_streams = streamList->num_streams;
     if (mSupportChannel) {
         stream_config_info.stream_sizes[stream_config_info.num_streams] =
                 QCamera3SupportChannel::kDim;
         stream_config_info.type[stream_config_info.num_streams] =
                 CAM_STREAM_TYPE_CALLBACK;
+        stream_config_info.postprocess_mask[stream_config_info.num_streams] =
+                CAM_QCOM_FEATURE_PP_SUPERSET;
         stream_config_info.num_streams++;
     }
 
@@ -1281,12 +1364,6 @@
     }
 
     uint32_t frameNumber = request->frame_number;
-    if (request->input_buffer != NULL &&
-            request->input_buffer->stream != mInputStream) {
-        ALOGE("%s: Request %d: Input buffer not from input stream!",
-                __FUNCTION__, frameNumber);
-        return BAD_VALUE;
-    }
     if (request->num_output_buffers < 1 || request->output_buffers == NULL) {
         ALOGE("%s: Request %d: No output buffers provided!",
                 __FUNCTION__, frameNumber);
@@ -1294,13 +1371,6 @@
     }
     if (request->input_buffer != NULL) {
         b = request->input_buffer;
-        QCamera3Channel *channel =
-            static_cast<QCamera3Channel*>(b->stream->priv);
-        if (channel == NULL) {
-            ALOGE("%s: Request %d: Buffer %ld: Unconfigured stream!",
-                    __func__, frameNumber, (long)idx);
-            return BAD_VALUE;
-        }
         if (b->status != CAMERA3_BUFFER_STATUS_OK) {
             ALOGE("%s: Request %d: Buffer %ld: Status not OK!",
                     __func__, frameNumber, (long)idx);
@@ -2270,6 +2340,18 @@
     // Notify metadata channel we receive a request
     mMetadataChannel->request(NULL, frameNumber);
 
+    metadata_buffer_t reproc_meta;
+    memset(&reproc_meta, 0, sizeof(metadata_buffer_t));
+
+    if(request->input_buffer != NULL){
+        rc = setReprocParameters(request, &reproc_meta, snapshotStreamId);
+        if (NO_ERROR != rc) {
+            ALOGE("%s: fail to set reproc parameters", __func__);
+            pthread_mutex_unlock(&mMutex);
+            return rc;
+        }
+    }
+
     // Call request on other streams
     for (size_t i = 0; i < request->num_output_buffers; i++) {
         const camera3_stream_buffer_t& output = request->output_buffers[i];
@@ -2281,39 +2363,17 @@
         }
 
         if (output.stream->format == HAL_PIXEL_FORMAT_BLOB) {
-            QCamera3RegularChannel* inputChannel = NULL;
-            if(request->input_buffer != NULL){
-
-                //Try to get the internal format
-                inputChannel = (QCamera3RegularChannel*)
-                    request->input_buffer->stream->priv;
-                if(inputChannel == NULL ){
-                    ALOGE("%s: failed to get input channel handle", __func__);
-                    pthread_mutex_unlock(&mMutex);
-                    return NO_INIT;
-                }
-                metadata_buffer_t reproc_meta;
-                rc = setReprocParameters(request, &reproc_meta, snapshotStreamId);
-                if (NO_ERROR == rc) {
-                    rc = channel->request(output.buffer, frameNumber,
-                            request->input_buffer, &reproc_meta);
-                    if (rc < 0) {
-                        ALOGE("%s: Fail to request on picture channel", __func__);
-                        pthread_mutex_unlock(&mMutex);
-                        return rc;
-                    }
-                } else {
-                    ALOGE("%s: fail to set reproc parameters", __func__);
-                    pthread_mutex_unlock(&mMutex);
-                    return rc;
-                }
-            } else
-                rc = channel->request(output.buffer, frameNumber,
-                            NULL, mParameters);
+            rc = channel->request(output.buffer, frameNumber,
+                    request->input_buffer, (request->input_buffer)? &reproc_meta : mParameters);
+            if (rc < 0) {
+                ALOGE("%s: Fail to request on picture channel", __func__);
+                pthread_mutex_unlock(&mMutex);
+                return rc;
+            }
         } else {
             CDBG("%s: %d, request with buffer %p, frame_number %d", __func__,
                 __LINE__, output.buffer, frameNumber);
-           rc = channel->request(output.buffer, frameNumber);
+            rc = channel->request(output.buffer, frameNumber);
         }
         if (rc < 0)
             ALOGE("%s: request failed", __func__);
@@ -4288,6 +4348,8 @@
             sizeof(scalar_formats)/sizeof(int32_t) * 4;
     int32_t available_stream_configs[max_stream_configs_size];
     int idx = 0;
+
+    /* Add input/output stream configurations for each scalar formats*/
     for (int j = 0; j < scalar_formats_count; j++) {
         switch (scalar_formats[j]) {
         case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
@@ -4314,6 +4376,16 @@
                 idx+=4;
             }
             break;
+
+        /*For below to format we also support i/p streams for reprocessing advertise those*/
+        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+            available_stream_configs[idx] = scalar_formats[j];
+            available_stream_configs[idx+1] = gCamCapability[cameraId]->active_array_size.width;
+            available_stream_configs[idx+2] = gCamCapability[cameraId]->active_array_size.height;
+            available_stream_configs[idx+3] = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT;
+            idx+=4;
+        /* Missing break;-) Continue to advertise o/p stream configs for these formats*/
         default:
             for (int i = 0;
                 i < gCamCapability[cameraId]->picture_sizes_tbl_cnt; i++) {
@@ -4331,6 +4403,7 @@
             break;
         }
     }
+
     staticInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
                       available_stream_configs, idx);
     static const uint8_t hotpixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
@@ -4610,6 +4683,8 @@
     available_capabilities[available_capabilities_count++] = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING;
     available_capabilities[available_capabilities_count++] = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS;
     available_capabilities[available_capabilities_count++] = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE;
+    available_capabilities[available_capabilities_count++] = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING;
+    available_capabilities[available_capabilities_count++] = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING;
     if (facingBack) {
         available_capabilities[available_capabilities_count++] = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW;
     }
@@ -5322,7 +5397,7 @@
     }
 
     info->orientation = gCamCapability[cameraId]->sensor_mount_angle;
-    info->device_version = CAMERA_DEVICE_API_VERSION_3_2;
+    info->device_version = CAMERA_DEVICE_API_VERSION_3_3;
     info->static_camera_characteristics = gStaticMetadata[cameraId];
 
     //For now assume both cameras can operate independently.
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index 44484b6..8f72d99 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -247,7 +247,6 @@
 
     const camera3_callback_ops_t *mCallbackOps;
 
-    camera3_stream_t *mInputStream;
     QCamera3MetadataChannel *mMetadataChannel;
     QCamera3PicChannel *mPictureChannel;
     QCamera3RawChannel *mRawChannel;
diff --git a/camera/QCamera2/stack/common/cam_types.h b/camera/QCamera2/stack/common/cam_types.h
index 6794eea..6f76eee 100644
--- a/camera/QCamera2/stack/common/cam_types.h
+++ b/camera/QCamera2/stack/common/cam_types.h
@@ -111,13 +111,14 @@
 
 #define MAX_AF_BRACKETING_VALUES 5
 #define MAX_TEST_PATTERN_CNT     8
-#define MAX_AVAILABLE_CAPABILITIES 6
+#define MAX_AVAILABLE_CAPABILITIES 8
 
 #define GPS_PROCESSING_METHOD_SIZE 33
 #define GPS_PROCESSING_METHOD_SIZE_IN_WORD (33+3)/4
 
 #define MAX_INFLIGHT_REQUESTS  6
 #define MIN_INFLIGHT_REQUESTS  3
+#define MAX_INFLIGHT_REPROCESS_REQUESTS 1
 
 #define QCAMERA_MAX_FILEPATH_LENGTH 64