QCamera3: Add support for PD stat streams

Streams carrying phase detection data from camera
can be supported granted the camera has meta raw
support.

Bug: 36015382
Test: testPDStats
Change-Id: I58803ac578908616b8710fcde593ccb3651ef887
diff --git a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
index 26de733..0bed08f 100644
--- a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
@@ -456,6 +456,8 @@
       mPreviewStarted(false),
       mMinInFlightRequests(MIN_INFLIGHT_REQUESTS),
       mMaxInFlightRequests(MAX_INFLIGHT_REQUESTS),
+      mPDSupported(false),
+      mPDIndex(0),
       mInstantAEC(false),
       mResetInstantAEC(false),
       mInstantAECSettledFrameNumber(0),
@@ -550,6 +552,9 @@
          dlclose(lib_surface_utils);
     }
 
+    mPDIndex = getPDStatIndex(gCamCapability[cameraId]);
+    mPDSupported = (0 <= mPDIndex) ? true : false;
+
     m60HzZone = is60HzZone();
 }
 
@@ -1120,10 +1125,12 @@
 {
     int rc = NO_ERROR;
     size_t count = 0;
-    uint32_t depthWidth =
-            gCamCapability[mCameraId]->active_array_size.width;
-    uint32_t depthHeight =
-            gCamCapability[mCameraId]->active_array_size.height;
+    uint32_t depthWidth = 0;
+    uint32_t depthHeight = 0;
+    if (mPDSupported) {
+        depthWidth = gCamCapability[mCameraId]->raw_meta_dim[mPDIndex].width;
+        depthHeight = gCamCapability[mCameraId]->raw_meta_dim[mPDIndex].height;
+    }
 
     camera3_stream_t *inputStream = NULL;
     /*
@@ -1162,6 +1169,15 @@
         case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
         case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
         case HAL_PIXEL_FORMAT_RAW10:
+            if ((HAL_DATASPACE_DEPTH == newStream->data_space) &&
+                    (ANDROID_SCALER_AVAILABLE_FORMATS_RAW16 == newStream->format) &&
+                    mPDSupported) {
+                if ((depthWidth == newStream->width) &&
+                        (depthHeight == newStream->height)) {
+                    sizeFound = true;
+                }
+                break;
+            }
             count = MIN(gCamCapability[mCameraId]->supported_raw_dim_cnt, MAX_SIZES_CNT);
             for (size_t i = 0; i < count; i++) {
                 if ((gCamCapability[mCameraId]->raw_dim[i].width == (int32_t)rotatedWidth) &&
@@ -1172,9 +1188,10 @@
             }
             break;
         case HAL_PIXEL_FORMAT_BLOB:
-            if (newStream->data_space == HAL_DATASPACE_DEPTH) {
+            if ((newStream->data_space == HAL_DATASPACE_DEPTH) &&
+                    mPDSupported) {
                 //As per spec. depth cloud should be sample count / 16
-                uint32_t depthSamplesCount = depthWidth * depthHeight / 16;
+                uint32_t depthSamplesCount = (depthWidth * depthHeight * 2) / 16;
                 if ((depthSamplesCount == newStream->width) &&
                         (1 == newStream->height)) {
                     sizeFound = true;
@@ -1740,6 +1757,7 @@
     bool isJpeg = false;
     cam_dimension_t jpegSize = {0, 0};
     cam_dimension_t previewSize = {0, 0};
+    size_t pdStatCount = 0;
 
     cam_padding_info_t padding_info = gCamCapability[mCameraId]->padding_info;
 
@@ -1866,6 +1884,10 @@
             case HAL_PIXEL_FORMAT_RAW_OPAQUE:
             case HAL_PIXEL_FORMAT_RAW16:
                 rawStreamCnt++;
+                if ((HAL_DATASPACE_DEPTH == newStream->data_space) &&
+                        (HAL_PIXEL_FORMAT_RAW16 == newStream->format)) {
+                    pdStatCount++;
+                }
                 break;
             case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
                 processedStreamCnt++;
@@ -2028,6 +2050,19 @@
         return rc;
     }
 
+    if (1 < pdStatCount) {
+        LOGE("HAL doesn't support multiple PD streams");
+        pthread_mutex_unlock(&mMutex);
+        return -EINVAL;
+    }
+
+    if ((mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
+            (1 == pdStatCount)) {
+        LOGE("HAL doesn't support PD streams in HFR mode!");
+        pthread_mutex_unlock(&mMutex);
+        return -EINVAL;
+    }
+
     camera3_stream_t *zslStream = NULL; //Only use this for size and not actual handle!
     for (size_t i = 0; i < streamList->num_streams; i++) {
         camera3_stream_t *newStream = streamList->streams[i];
@@ -2315,6 +2350,17 @@
                 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_RAW;
                 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = CAM_QCOM_FEATURE_NONE;
                 isRawStreamRequested = true;
+                if ((HAL_DATASPACE_DEPTH == newStream->data_space) &&
+                        (HAL_PIXEL_FORMAT_RAW16 == newStream->format)) {
+                    mStreamConfigInfo.sub_format_type[mStreamConfigInfo.num_streams] =
+                            gCamCapability[mCameraId]->sub_fmt[mPDIndex];
+                    mStreamConfigInfo.format[mStreamConfigInfo.num_streams] =
+                            gCamCapability[mCameraId]->supported_meta_raw_fmts[mPDIndex];
+                    mStreamConfigInfo.dt[mStreamConfigInfo.num_streams] =
+                            gCamCapability[mCameraId]->dt[mPDIndex];
+                    mStreamConfigInfo.vc[mStreamConfigInfo.num_streams] =
+                            gCamCapability[mCameraId]->vc[mPDIndex];
+                }
                 break;
             default:
                 onlyRaw = false; // There is non-raw stream - bypass flag if set
@@ -2457,15 +2503,17 @@
                 }
                 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
                 case HAL_PIXEL_FORMAT_RAW16:
-                case HAL_PIXEL_FORMAT_RAW10:
+                case HAL_PIXEL_FORMAT_RAW10: {
+                    bool isRAW16 = ((newStream->format == HAL_PIXEL_FORMAT_RAW16) &&
+                            (HAL_DATASPACE_DEPTH != newStream->data_space))
+                            ? true : false;
                     mRawChannel = new QCamera3RawChannel(
                             mCameraHandle->camera_handle, mChannelHandle,
                             mCameraHandle->ops, captureResultCb,
                             setBufferErrorStatus, &padding_info,
                             this, newStream,
                             mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
-                            mMetadataChannel,
-                            (newStream->format == HAL_PIXEL_FORMAT_RAW16));
+                            mMetadataChannel, isRAW16);
                     if (mRawChannel == NULL) {
                         LOGE("allocation of raw channel failed");
                         pthread_mutex_unlock(&mMutex);
@@ -2474,6 +2522,7 @@
                     newStream->max_buffers = mRawChannel->getNumBuffers();
                     newStream->priv = (QCamera3ProcessingChannel*)mRawChannel;
                     break;
+                }
                 case HAL_PIXEL_FORMAT_BLOB:
                     if (newStream->data_space == HAL_DATASPACE_DEPTH) {
                         mDepthChannel = new QCamera3DepthChannel(
@@ -2551,7 +2600,8 @@
          * since there is no real stream associated with it
          */
         if ((newStream->stream_type != CAMERA3_STREAM_INPUT) &&
-                (newStream->data_space != HAL_DATASPACE_DEPTH)) {
+                !((newStream->data_space == HAL_DATASPACE_DEPTH) &&
+                        (newStream->format == HAL_PIXEL_FORMAT_BLOB))) {
             mStreamConfigInfo.num_streams++;
         }
     }
@@ -5195,7 +5245,8 @@
            }
         }
 
-        if (output.stream->data_space == HAL_DATASPACE_DEPTH) {
+        if ((output.stream->format == HAL_PIXEL_FORMAT_BLOB) &&
+                (output.stream->data_space == HAL_DATASPACE_DEPTH)) {
             depthRequestPresent = true;
             continue;
         }
@@ -5410,8 +5461,10 @@
     }
 
     for (size_t i = 0; i < request->num_output_buffers; i++) {
-        if (request->output_buffers[i].stream->data_space ==
-                HAL_DATASPACE_DEPTH) {
+        if ((request->output_buffers[i].stream->data_space ==
+                HAL_DATASPACE_DEPTH) &&
+                (HAL_PIXEL_FORMAT_BLOB ==
+                        request->output_buffers[i].stream->format)) {
             continue;
         }
         RequestedBufferInfo requestedBuf;
@@ -8754,6 +8807,35 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : getPDStatIndex
+ *
+ * DESCRIPTION: Return the meta raw phase detection statistics index if present
+ *
+ * PARAMETERS :
+ *   @caps    : camera capabilities
+ *
+ * RETURN     : int32_t type
+ *              non-negative - on success
+ *              -1 - on failure
+ *==========================================================================*/
+int32_t QCamera3HardwareInterface::getPDStatIndex(cam_capability_t *caps) {
+    if (nullptr == caps) {
+        return -1;
+    }
+
+    uint32_t metaRawCount = caps->meta_raw_channel_count;
+    int32_t ret = -1;
+    for (size_t i = 0; i < metaRawCount; i++) {
+        if (CAM_FORMAT_SUBTYPE_PDAF_STATS == caps->sub_fmt[i]) {
+            ret = i;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+/*===========================================================================
  * FUNCTION   : initStaticMetadata
  *
  * DESCRIPTION: initialize the static metadata
@@ -8936,6 +9018,44 @@
     staticInfo.update(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
             &gCamCapability[cameraId]->max_sharpness_map_value, 1);
 
+    int32_t indexPD = getPDStatIndex(gCamCapability[cameraId]);
+    if (0 <= indexPD) {
+        // Advertise PD stats data as part of the Depth capabilities
+        int32_t depthWidth =
+                gCamCapability[cameraId]->raw_meta_dim[indexPD].width;
+        int32_t depthHeight =
+                gCamCapability[cameraId]->raw_meta_dim[indexPD].height;
+        int32_t depthSamplesCount = (depthWidth * depthHeight * 2) / 16;
+        assert(0 < depthSamplesCount);
+        staticInfo.update(ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
+                &depthSamplesCount, 1);
+
+        int32_t depthConfigs[] = {HAL_PIXEL_FORMAT_RAW16, depthWidth,
+                depthHeight,
+                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+                HAL_PIXEL_FORMAT_BLOB, depthSamplesCount, 1,
+                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT};
+        staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+                depthConfigs, sizeof(depthConfigs)/sizeof(depthConfigs[0]));
+
+        int64_t depthMinDuration[] = {HAL_PIXEL_FORMAT_RAW16, depthWidth,
+                depthHeight, 33333333,
+                HAL_PIXEL_FORMAT_BLOB, depthSamplesCount, 1, 33333333};
+        staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+                depthMinDuration,
+                sizeof(depthMinDuration) / sizeof(depthMinDuration[0]));
+
+        int64_t depthStallDuration[] = {HAL_PIXEL_FORMAT_RAW16, depthWidth,
+                depthHeight, 0,
+                HAL_PIXEL_FORMAT_BLOB, depthSamplesCount, 1, 0};
+        staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
+                depthStallDuration,
+                sizeof(depthStallDuration) / sizeof(depthStallDuration[0]));
+
+        uint8_t depthExclusive = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE;
+        staticInfo.update(ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE, &depthExclusive, 1);
+    }
+
     int32_t scalar_formats[] = {
             ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE,
             ANDROID_SCALER_AVAILABLE_FORMATS_RAW16,
@@ -8943,10 +9063,9 @@
             ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
             HAL_PIXEL_FORMAT_RAW10,
             HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED};
-    size_t scalar_formats_count = sizeof(scalar_formats) / sizeof(int32_t);
-    staticInfo.update(ANDROID_SCALER_AVAILABLE_FORMATS,
-                      scalar_formats,
-                      scalar_formats_count);
+    size_t scalar_formats_count = sizeof(scalar_formats) / sizeof(scalar_formats[0]);
+    staticInfo.update(ANDROID_SCALER_AVAILABLE_FORMATS, scalar_formats,
+            scalar_formats_count);
 
     int32_t available_processed_sizes[MAX_SIZES_CNT * 2];
     count = MIN(gCamCapability[cameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
@@ -9047,41 +9166,6 @@
     staticInfo.update(QCAMERA3_STATS_BSGC_AVAILABLE,
             &face_bsgc, 1);
 
-#ifdef SUPPORT_DEPTH_DATA
-    if (gCamCapability[cameraId]->supported_focus_modes_cnt > 1) {
-        //TODO: Update depth size accordingly, currently we use active array
-        //      as reference.
-        int32_t depthWidth = gCamCapability[cameraId]->active_array_size.width;
-        int32_t depthHeight =
-                gCamCapability[cameraId]->active_array_size.height;
-        //As per spec. depth cloud should be sample count / 16
-        int32_t depthSamplesCount = depthWidth * depthHeight / 16;
-        assert(0 < depthSamplesCount);
-        staticInfo.update(ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
-                &depthSamplesCount, 1);
-
-        int32_t depthConfigs[] = {HAL_PIXEL_FORMAT_BLOB, depthSamplesCount, 1,
-                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT };
-        staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
-                depthConfigs, sizeof(depthConfigs)/sizeof(depthConfigs[0]));
-
-        int64_t depthMinDuration[] = {HAL_PIXEL_FORMAT_BLOB, depthSamplesCount,
-                1, 1 };
-        staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
-                depthMinDuration,
-                sizeof(depthMinDuration) / sizeof(depthMinDuration[0]));
-
-        int64_t depthStallDuration[] = {HAL_PIXEL_FORMAT_BLOB,
-                depthSamplesCount, 1, 0 };
-        staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
-                depthStallDuration,
-                sizeof(depthStallDuration) / sizeof(depthStallDuration[0]));
-
-        uint8_t depthExclusive = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE;
-        staticInfo.update(ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE, &depthExclusive, 1);
-    }
-#endif
-
     int32_t exposureCompensationRange[] = {
             gCamCapability[cameraId]->exposure_compensation_min,
             gCamCapability[cameraId]->exposure_compensation_max};
@@ -9899,13 +9983,6 @@
        ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
        ANDROID_SHADING_AVAILABLE_MODES,
        ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
-#ifdef SUPPORT_DEPTH_DATA
-       ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
-       ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
-       ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
-       ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
-       ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE,
-#endif
 #ifndef USE_HAL_3_3
        ANDROID_SENSOR_OPAQUE_RAW_SIZE,
        ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
@@ -9920,6 +9997,19 @@
         available_characteristics_keys.add(ANDROID_SENSOR_OPTICAL_BLACK_REGIONS);
     }
 #endif
+
+    if (0 <= indexPD) {
+        int32_t depthKeys[] = {
+                ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
+                ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE
+        };
+        available_characteristics_keys.appendArray(depthKeys,
+                sizeof(depthKeys) / sizeof(depthKeys[0]));
+    }
+
     staticInfo.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
                       available_characteristics_keys.array(),
                       available_characteristics_keys.size());