diff --git a/camera/metadata/3.4/types.hal b/camera/metadata/3.4/types.hal
index 6765e2e88f..4eb692917e 100644
--- a/camera/metadata/3.4/types.hal
+++ b/camera/metadata/3.4/types.hal
@@ -44,6 +44,21 @@ enum CameraMetadataTag : @3.3::CameraMetadataTag {
ANDROID_REQUEST_END_3_4,
+ /** android.scaler.availableRecommendedStreamConfigurations [static, enum[], ndk_public]
+ *
+ *
Recommended stream configurations for common client use cases.
+ */
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS = android.hardware.camera.metadata@3.2::CameraMetadataTag:ANDROID_SCALER_END,
+
+ /** android.scaler.availableRecommendedInputOutputFormatsMap [static, int32, ndk_public]
+ *
+ * Recommended mappings of image formats that are supported by this
+ * camera device for input streams, to their corresponding output formats.
+ */
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP,
+
+ ANDROID_SCALER_END_3_4,
+
/** android.info.supportedBufferManagementVersion [static, enum, system]
*
* The version of buffer management API this camera device supports and opts into.
@@ -52,6 +67,14 @@ enum CameraMetadataTag : @3.3::CameraMetadataTag {
ANDROID_INFO_END_3_4,
+ /** android.depth.availableRecommendedDepthStreamConfigurations [static, int32[], ndk_public]
+ *
+ * Recommended depth stream configurations for common client use cases.
+ */
+ ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS = android.hardware.camera.metadata@3.2::CameraMetadataTag:ANDROID_DEPTH_END,
+
+ ANDROID_DEPTH_END_3_4,
+
};
/*
@@ -68,6 +91,28 @@ enum CameraMetadataEnumAndroidScalerAvailableFormats :
ANDROID_SCALER_AVAILABLE_FORMATS_Y8 = 0x20203859,
};
+/** android.scaler.availableRecommendedStreamConfigurations enumeration values
+ * @see ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS
+ */
+enum CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations : uint32_t {
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW
+ = 0x0,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD
+ = 0x1,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT
+ = 0x2,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT
+ = 0x3,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL
+ = 0x4,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW
+ = 0x5,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END
+ = 0x6,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START
+ = 0x18,
+};
+
/** android.info.supportedBufferManagementVersion enumeration values
* @see ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION
*/
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 94d06e8611..837905c89c 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -681,6 +681,7 @@ public:
const CameraMetadata& chars, int deviceVersion,
const hidl_vec& deviceNames);
void verifyCameraCharacteristics(Status status, const CameraMetadata& chars);
+ void verifyRecommendedConfigs(const CameraMetadata& metadata);
static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
std::vector &outputStreams,
@@ -698,7 +699,7 @@ public:
/*out*/);
static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
AvailableStream &hfrStream);
- static Status isZSLModeAvailable(camera_metadata_t *staticMeta);
+ static Status isZSLModeAvailable(const camera_metadata_t *staticMeta);
static Status getZSLInputOutputMap(camera_metadata_t *staticMeta,
std::vector &inputOutputMap);
static Status findLargestSize(
@@ -2079,7 +2080,7 @@ TEST_F(CameraHidlTest, getCameraCharacteristics) {
ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
verifyCameraCharacteristics(status, chars);
-
+ verifyRecommendedConfigs(chars);
verifyLogicalCameraMetadata(name, device3_x, chars, deviceVersion,
cameraDeviceNames);
});
@@ -4323,7 +4324,7 @@ Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta,
// Check whether ZSL is available using the static camera
// characteristics.
-Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) {
+Status CameraHidlTest::isZSLModeAvailable(const camera_metadata_t *staticMeta) {
Status ret = Status::METHOD_NOT_SUPPORTED;
if (nullptr == staticMeta) {
return Status::ILLEGAL_ARGUMENT;
@@ -4978,6 +4979,94 @@ void CameraHidlTest::allocateGraphicBuffer(uint32_t width, uint32_t height, uint
ASSERT_TRUE(ret.isOk());
}
+void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) {
+ size_t CONFIG_ENTRY_SIZE = 5;
+ size_t CONFIG_ENTRY_TYPE_OFFSET = 3;
+ size_t CONFIG_ENTRY_BITFIELD_OFFSET = 4;
+ uint32_t maxPublicUsecase =
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END;
+ uint32_t vendorUsecaseStart =
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START;
+ uint32_t usecaseMask = (1 << vendorUsecaseStart) - 1;
+ usecaseMask &= ~((1 << maxPublicUsecase) - 1);
+
+ const camera_metadata_t* metadata = reinterpret_cast (chars.data());
+
+ camera_metadata_ro_entry recommendedConfigsEntry, recommendedDepthConfigsEntry, ioMapEntry;
+ recommendedConfigsEntry.count = recommendedDepthConfigsEntry.count = ioMapEntry.count = 0;
+ int retCode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS, &recommendedConfigsEntry);
+ int depthRetCode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS,
+ &recommendedDepthConfigsEntry);
+ int ioRetCode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP, &ioMapEntry);
+ if ((0 != retCode) && (0 != depthRetCode)) {
+ //In case both regular and depth recommended configurations are absent,
+ //I/O should be absent as well.
+ ASSERT_NE(ioRetCode, 0);
+ return;
+ }
+
+ camera_metadata_ro_entry availableKeysEntry;
+ retCode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &availableKeysEntry);
+ ASSERT_TRUE((0 == retCode) && (availableKeysEntry.count > 0));
+ std::vector availableKeys;
+ availableKeys.reserve(availableKeysEntry.count);
+ availableKeys.insert(availableKeys.end(), availableKeysEntry.data.i32,
+ availableKeysEntry.data.i32 + availableKeysEntry.count);
+
+ if (recommendedConfigsEntry.count > 0) {
+ ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS),
+ availableKeys.end());
+ ASSERT_EQ((recommendedConfigsEntry.count % CONFIG_ENTRY_SIZE), 0);
+ for (size_t i = 0; i < recommendedConfigsEntry.count; i += CONFIG_ENTRY_SIZE) {
+ int32_t entryType =
+ recommendedConfigsEntry.data.i32[i + CONFIG_ENTRY_TYPE_OFFSET];
+ uint32_t bitfield =
+ recommendedConfigsEntry.data.i32[i + CONFIG_ENTRY_BITFIELD_OFFSET];
+ ASSERT_TRUE((entryType ==
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) ||
+ (entryType ==
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT));
+ ASSERT_TRUE((bitfield & usecaseMask) == 0);
+ }
+ }
+
+ if (recommendedDepthConfigsEntry.count > 0) {
+ ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
+ ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS),
+ availableKeys.end());
+ ASSERT_EQ((recommendedDepthConfigsEntry.count % CONFIG_ENTRY_SIZE), 0);
+ for (size_t i = 0; i < recommendedDepthConfigsEntry.count; i += CONFIG_ENTRY_SIZE) {
+ int32_t entryType =
+ recommendedDepthConfigsEntry.data.i32[i + CONFIG_ENTRY_TYPE_OFFSET];
+ uint32_t bitfield =
+ recommendedDepthConfigsEntry.data.i32[i + CONFIG_ENTRY_BITFIELD_OFFSET];
+ ASSERT_TRUE((entryType ==
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) ||
+ (entryType ==
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT));
+ ASSERT_TRUE((bitfield & usecaseMask) == 0);
+ }
+
+ if (recommendedConfigsEntry.count == 0) {
+ //In case regular recommended configurations are absent but suggested depth
+ //configurations are present, I/O should be absent.
+ ASSERT_NE(ioRetCode, 0);
+ }
+ }
+
+ if ((ioRetCode == 0) && (ioMapEntry.count > 0)) {
+ ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP),
+ availableKeys.end());
+ ASSERT_EQ(isZSLModeAvailable(metadata), Status::OK);
+ }
+}
+
int main(int argc, char **argv) {
::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);