From ee37bd5cedb34df8db03a54e1129aaac0f49d8ce Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 15 Oct 2018 12:55:27 +0100 Subject: [PATCH] Camera: Add support for recommended stream configurations Hal must be able to recommend efficient stream configurations for common client use cases. Add the necessary static metadata keys. Bug: 64029608 Test: vts-tradefed run commandAndExit vts --skip-all-system-status-check --skip-preconditions --module VtsHalCameraProviderV2_4Target -l INFO Change-Id: I0c2306501094383af78cb7ced1fa700b259d2b08 --- camera/metadata/3.4/types.hal | 45 +++++++++ .../VtsHalCameraProviderV2_4TargetTest.cpp | 95 ++++++++++++++++++- 2 files changed, 137 insertions(+), 3 deletions(-) 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);