diff options
author | Shuzhen Wang <shuzhenwang@google.com> | 2021-12-14 20:12:08 -0800 |
---|---|---|
committer | Shuzhen Wang <shuzhenwang@google.com> | 2022-02-03 17:46:44 -0800 |
commit | 7267abff252f63c76a5390dba4a3ab8d14c3bafc (patch) | |
tree | 2de338c65652e159ad9b69e1f4a7f2e9efa597eb /camera | |
parent | 1bbd78efcd6d2f42d736b6b6b0b52bb4bd0dbdd4 (diff) |
Camera: Add stream use case API
- Add availableStreamUseCase static metadata tag
- Add STREAM_USE_CASE camera capability
- Add useCase flag in camera stream interface
Test: atest VtsHalCameraProviderV2_4TargetTest
Bug: 200307880
Change-Id: I4e473edcb52a97fa0e1b27cf94603cf9f9984f82
Diffstat (limited to 'camera')
-rw-r--r-- | camera/device/3.8/ICameraDevice.hal | 3 | ||||
-rw-r--r-- | camera/device/3.8/ICameraDeviceSession.hal | 3 | ||||
-rw-r--r-- | camera/device/3.8/types.hal | 37 | ||||
-rw-r--r-- | camera/metadata/3.8/types.hal | 23 | ||||
-rw-r--r-- | camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp | 182 |
5 files changed, 234 insertions, 14 deletions
diff --git a/camera/device/3.8/ICameraDevice.hal b/camera/device/3.8/ICameraDevice.hal index 8832c68098..09edb8ba20 100644 --- a/camera/device/3.8/ICameraDevice.hal +++ b/camera/device/3.8/ICameraDevice.hal @@ -113,7 +113,8 @@ interface ICameraDevice extends @3.7::ICameraDevice { * * Identical to @3.7::ICameraDevice.isStreamCombinationSupported, except * that it takes a @3.8::StreamConfiguration parameter, which could contain - * additional information about a specific 10-bit dynamic range profile. + * additional information about a specific 10-bit dynamic range profile or + * stream use case. * */ isStreamCombinationSupported_3_8(StreamConfiguration streams) diff --git a/camera/device/3.8/ICameraDeviceSession.hal b/camera/device/3.8/ICameraDeviceSession.hal index 88e4338209..c3aa836ec1 100644 --- a/camera/device/3.8/ICameraDeviceSession.hal +++ b/camera/device/3.8/ICameraDeviceSession.hal @@ -35,6 +35,8 @@ interface ICameraDeviceSession extends @3.7::ICameraDeviceSession { * * - The requestedConfiguration allows the camera framework to configure * 10-bit dynamic range profile. + * - The requestedConfiguration allows the camera framework to configure + * stream use cases. * * @return status Status code for the operation, one of: * OK: @@ -61,6 +63,7 @@ interface ICameraDeviceSession extends @3.7::ICameraDeviceSession { * input stream. * - Invalid combination between a 10-bit dynamic range profile * and none impl. defined 8-bit format for a particular stream. + * - Unsupported stream use case * The camera service cannot filter out all possible illegal stream * configurations, since some devices may support more simultaneous * streams or larger stream resolutions than the minimum required diff --git a/camera/device/3.8/types.hal b/camera/device/3.8/types.hal index 9d1ac22f5a..04a245085b 100644 --- a/camera/device/3.8/types.hal +++ b/camera/device/3.8/types.hal @@ -17,6 +17,7 @@ package android.hardware.camera.device@3.8; import @3.2::ErrorMsg; +import @3.2::CameraMetadata; import @3.2::MsgType; import @3.2::ShutterMsg; import @3.2::CameraMetadata; @@ -24,6 +25,7 @@ import @3.2::StreamConfigurationMode; import @3.7::Stream; import android.hardware.camera.metadata@3.8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap; +import android.hardware.camera.metadata@3.8::CameraMetadataEnumAndroidScalerAvailableStreamUseCases; /** * ShutterMsg: @@ -80,7 +82,8 @@ struct NotifyMsg { * by the framework by its buffer resolution and format, and additionally by the * HAL with the gralloc usage flags and the maximum in-flight buffer count. * - * This version extends the @3.7 Stream with the dynamic range profile field. + * This version extends the @3.7 Stream with the dynamic range profile and the + * stream use case field. */ struct Stream { /** @@ -98,6 +101,25 @@ struct Stream { * */ CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap dynamicRangeProfile; + + /** + * The stream use case describing the stream's purpose + * + * This flag provides the camera device a hint on what user scenario this + * stream is intended for. With this flag, the camera device can optimize + * camera pipeline parameters, such as tuning, sensor mode, and ISP settings, + * for the intended use case. + * + * When this field is set to DEFAULT, the camera device should behave in + * the same way as in previous HAL versions, and optimize the camera pipeline + * based on stream format, data space, usage flag, and other stream properties. + * + * The HAL reports supported stream use cases in + * ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES. If the HAL doesn't support + * setting stream use cases, the camera framework leaves this field as + * DEFAULT. + */ + CameraMetadataEnumAndroidScalerAvailableStreamUseCases useCase; }; /** @@ -115,7 +137,6 @@ struct StreamConfiguration { /** * The definition of operation mode from prior version. - * */ @3.2::StreamConfigurationMode operationMode; @@ -130,17 +151,7 @@ struct StreamConfiguration { uint32_t streamConfigCounter; /** - * If an input stream is configured, whether the input stream is expected to - * receive variable resolution images. - * - * This flag can only be set to true if the camera device supports - * multi-resolution input streams by advertising input stream configurations in - * physicalCameraMultiResolutionStreamConfigurations in its physical cameras' - * characteristics. - * - * When this flag is set to true, the input stream's width and height can be - * any one of the supported multi-resolution input stream sizes. + * The definition of multi-resolution input image flag from prior version. */ bool multiResolutionInputImage; }; - diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal index 4c70eb9528..488bf9d3cc 100644 --- a/camera/metadata/3.8/types.hal +++ b/camera/metadata/3.8/types.hal @@ -68,6 +68,14 @@ enum CameraMetadataTag : @3.7::CameraMetadataTag { ANDROID_REQUEST_END_3_8, + /** android.scaler.availableStreamUseCases [static, enum[], public] + * + * <p>The stream use cases supported by this camera device.</p> + */ + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = android.hardware.camera.metadata@3.6::CameraMetadataTag:ANDROID_SCALER_END_3_6, + + ANDROID_SCALER_END_3_8, + }; /* @@ -88,6 +96,7 @@ enum CameraMetadataEnumAndroidControlVideoStabilizationMode : enum CameraMetadataEnumAndroidRequestAvailableCapabilities : @3.6::CameraMetadataEnumAndroidRequestAvailableCapabilities { ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE, }; /** android.request.availableDynamicRangeProfilesMap enumeration values @@ -129,3 +138,17 @@ enum CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations : ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8 = 0x9, }; + +/** android.scaler.availableStreamUseCases enumeration values + * @see ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES + */ +enum CameraMetadataEnumAndroidScalerAvailableStreamUseCases : uint32_t { + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT = 0x0, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 0x1, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE = 0x2, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL + = 0x4, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000, +}; diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index 8c44010441..3254cf2a21 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -44,6 +44,7 @@ #include <android/hardware/camera/device/3.7/ICameraDevice.h> #include <android/hardware/camera/device/3.8/ICameraDevice.h> #include <android/hardware/camera/device/3.7/ICameraDeviceSession.h> +#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.7/ICameraInjectionSession.h> #include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h> #include <android/hardware/camera/device/3.8/ICameraDeviceSession.h> @@ -135,6 +136,8 @@ using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag; using ::android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode; using ::android::hardware::camera::metadata::V3_8:: CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap; +using ::android::hardware::camera::metadata::V3_8:: + CameraMetadataEnumAndroidScalerAvailableStreamUseCases; using ::android::hardware::camera::provider::V2_4::ICameraProvider; using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; using ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination; @@ -198,6 +201,15 @@ enum SystemCameraKind { HIDDEN_SECURE_CAMERA }; +const static std::vector<int32_t> kMandatoryUseCases = { + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL +}; + namespace { // "device@<version>/legacy/<id>" const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)"; @@ -879,6 +891,7 @@ public: void verifyCameraCharacteristics(Status status, const CameraMetadata& chars); void verifyExtendedSceneModeCharacteristics(const camera_metadata_t* metadata); void verifyZoomCharacteristics(const camera_metadata_t* metadata); + void verifyStreamUseCaseCharacteristics(const camera_metadata_t* metadata); void verifyRecommendedConfigs(const CameraMetadata& metadata); void verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion); void verifyMonochromeCameraResult( @@ -6879,6 +6892,134 @@ TEST_P(CameraHidlTest, configureInjectionStreamsWithSessionParameters) { } } +// Verify that valid stream use cases can be configured successfully, and invalid use cases +// fail stream configuration. +TEST_P(CameraHidlTest, configureStreamsUseCases) { + hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_8) { + continue; + } + + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + sp<device::V3_5::ICameraDeviceSession> session3_5; + sp<device::V3_6::ICameraDeviceSession> session3_6; + sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; + sp<device::V3_2::ICameraDevice> cameraDevice; + sp<device::V3_5::ICameraDevice> cameraDevice3_5; + sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, + &cameraDevice /*out*/); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7, &session3_8); + ASSERT_NE(nullptr, session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); + ASSERT_NE(nullptr, cameraDevice3_8); + + // Check if camera support depth only + if (isDepthOnly(staticMeta)) { + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + + std::vector<AvailableStream> outputPreviewStreams; + AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, + static_cast<int32_t>(PixelFormat::YCBCR_420_888)}; + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams, + &previewThreshold)); + ASSERT_NE(0u, outputPreviewStreams.size()); + + // Combine valid and invalid stream use cases + std::vector<int32_t> useCases(kMandatoryUseCases); + useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL + 1); + + std::vector<int32_t> supportedUseCases; + camera_metadata_ro_entry entry; + auto retcode = find_camera_metadata_ro_entry(staticMeta, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry); + if ((0 == retcode) && (entry.count > 0)) { + supportedUseCases.insert(supportedUseCases.end(), entry.data.i32, + entry.data.i32 + entry.count); + } else { + supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT); + } + free_camera_metadata(staticMeta); + + ::android::hardware::hidl_vec<V3_8::Stream> streams3_8(1); + streams3_8[0].v3_7.groupId = -1; + streams3_8[0].v3_7.sensorPixelModesUsed = { + CameraMetadataEnumAndroidSensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT}; + streams3_8[0].v3_7.v3_4.bufferSize = 0; + streams3_8[0].v3_7.v3_4.v3_2.id = 0; + streams3_8[0].v3_7.v3_4.v3_2.streamType = StreamType::OUTPUT; + streams3_8[0].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(outputPreviewStreams[0].width); + streams3_8[0].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(outputPreviewStreams[0].height); + streams3_8[0].v3_7.v3_4.v3_2.format = + static_cast<PixelFormat>(outputPreviewStreams[0].format); + streams3_8[0].v3_7.v3_4.v3_2.usage = GRALLOC1_CONSUMER_USAGE_CPU_READ; + streams3_8[0].v3_7.v3_4.v3_2.dataSpace = 0; + streams3_8[0].v3_7.v3_4.v3_2.rotation = StreamRotation::ROTATION_0; + streams3_8[0].dynamicRangeProfile = + static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>( + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD); + + uint32_t streamConfigCounter = 0; + ::android::hardware::camera::device::V3_8::StreamConfiguration config3_8; + RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; + ret = session3_8->constructDefaultRequestSettings(reqTemplate, + [&config3_8](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + config3_8.sessionParams = req; + }); + ASSERT_TRUE(ret.isOk()); + + for (int32_t useCase : useCases) { + bool useCaseSupported = std::find(supportedUseCases.begin(), + supportedUseCases.end(), useCase) != supportedUseCases.end(); + + streams3_8[0].useCase = + static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(useCase); + config3_8.streams = streams3_8; + config3_8.operationMode = StreamConfigurationMode::NORMAL_MODE; + config3_8.streamConfigCounter = streamConfigCounter; + config3_8.multiResolutionInputImage = false; + ret = cameraDevice3_8->isStreamCombinationSupported_3_8( + config3_8, [&useCaseSupported](Status s, bool combStatus) { + ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s)); + if (Status::OK == s) { + ASSERT_EQ(combStatus, useCaseSupported); + } + }); + ASSERT_TRUE(ret.isOk()); + + ret = session3_8->configureStreams_3_8( + config3_8, + [&](Status s, device::V3_6::HalStreamConfiguration halConfig) { + if (useCaseSupported) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + } else { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + } + }); + ASSERT_TRUE(ret.isOk()); + } + ret = session3_8->close(); + ASSERT_TRUE(ret.isOk()); + } +} + // Retrieve all valid output stream resolutions from the camera // static characteristics. Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t* staticMeta, @@ -9042,6 +9183,7 @@ void CameraHidlTest::verifyCameraCharacteristics(Status status, const CameraMeta verifyExtendedSceneModeCharacteristics(metadata); verifyZoomCharacteristics(metadata); + verifyStreamUseCaseCharacteristics(metadata); } void CameraHidlTest::verifyExtendedSceneModeCharacteristics(const camera_metadata_t* metadata) { @@ -9272,6 +9414,46 @@ void CameraHidlTest::verifyZoomCharacteristics(const camera_metadata_t* metadata } } +void CameraHidlTest::verifyStreamUseCaseCharacteristics(const camera_metadata_t* metadata) { + camera_metadata_ro_entry entry; + // Check capabilities + int retcode = find_camera_metadata_ro_entry(metadata, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); + bool hasStreamUseCaseCap = false; + if ((0 == retcode) && (entry.count > 0)) { + if (std::find(entry.data.u8, entry.data.u8 + entry.count, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE) != + entry.data.u8 + entry.count) { + hasStreamUseCaseCap = true; + } + } + + bool supportMandatoryUseCases = false; + retcode = find_camera_metadata_ro_entry(metadata, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry); + if ((0 == retcode) && (entry.count > 0)) { + supportMandatoryUseCases = true; + for (size_t i = 0; i < kMandatoryUseCases.size(); i++) { + if (std::find(entry.data.i32, entry.data.i32 + entry.count, kMandatoryUseCases[i]) + == entry.data.i32 + entry.count) { + supportMandatoryUseCases = false; + break; + } + } + bool supportDefaultUseCase = false; + for (size_t i = 0; i < entry.count; i++) { + if (entry.data.i32[i] == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) { + supportDefaultUseCase = true; + } + ASSERT_TRUE(entry.data.i32[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL || + entry.data.i32[i] >= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START); + } + ASSERT_TRUE(supportDefaultUseCase); + } + + ASSERT_EQ(hasStreamUseCaseCap, supportMandatoryUseCases); +} + void CameraHidlTest::verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion) { const camera_metadata_t* metadata = (camera_metadata_t*)chars.data(); |