From de1909e86558ed87b02c5c20b4c2d832e09c1d42 Mon Sep 17 00:00:00 2001 From: Jayant Chowdhary Date: Wed, 23 Nov 2022 17:18:38 +0000 Subject: [PATCH] Camera: Add metadata support for cropped RAW streams. Bug: 247524520 Test: Camera CTS Test: Camera VTS Change-Id: Ie50359aca3fbbd6088e2e1525cca85c7d5eb0ad0 Signed-off-by: Jayant Chowdhary --- .../camera/metadata/CameraMetadataTag.aidl | 1 + .../ScalerAvailableStreamUseCases.aidl | 1 + .../camera/metadata/CameraMetadataTag.aidl | 7 + .../ScalerAvailableStreamUseCases.aidl | 1 + .../VtsAidlHalCameraProvider_TargetTest.cpp | 113 ++------------- camera/provider/aidl/vts/camera_aidl_test.cpp | 134 +++++++++++++++++- camera/provider/aidl/vts/camera_aidl_test.h | 3 + 7 files changed, 155 insertions(+), 105 deletions(-) diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl index ecbfc9371f..8c98e38fc5 100644 --- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl +++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl @@ -204,6 +204,7 @@ enum CameraMetadataTag { ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION = 851991, ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED = 851992, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994, + ANDROID_SCALER_RAW_CROP_REGION = 851995, ANDROID_SENSOR_EXPOSURE_TIME = 917504, ANDROID_SENSOR_FRAME_DURATION = 917505, ANDROID_SENSOR_SENSITIVITY = 917506, diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl index bfa4f1ae8b..958fa122b0 100644 --- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl +++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl @@ -44,5 +44,6 @@ enum ScalerAvailableStreamUseCases { ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 3, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 4, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 5, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 6, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 65536, } diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl index 2e9bde95a3..172dc1fae8 100644 --- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl +++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl @@ -1283,6 +1283,13 @@ enum CameraMetadataTag { *

The stream use cases supported by this camera device.

*/ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994, + /** + * android.scaler.rawCropRegion [dynamic, int32[], public] + * + *

The region of the sensor that corresponds to the RAW read out for this + * capture when the stream use case of a RAW stream is set to CROPPED_RAW.

+ */ + ANDROID_SCALER_RAW_CROP_REGION, /** * android.sensor.exposureTime [dynamic, int64, public] * diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl index daa0fd3028..da27a48e32 100644 --- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl +++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl @@ -35,5 +35,6 @@ enum ScalerAvailableStreamUseCases { ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3L, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4L, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5L, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 0x6L, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000L, } diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp index 747ea336e2..4d4bb26800 100644 --- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp +++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp @@ -3035,115 +3035,22 @@ TEST_P(CameraAidlTest, configureInjectionStreamsWithSessionParameters) { } } +TEST_P(CameraAidlTest, configureStreamsUseCasesCroppedRaw) { + AvailableStream rawStreamThreshold = + {INT_MAX, INT_MAX, static_cast(PixelFormat::RAW16)}; + configureStreamUseCaseInternal(rawStreamThreshold); +} + // Verify that valid stream use cases can be configured successfully, and invalid use cases // fail stream configuration. TEST_P(CameraAidlTest, configureStreamsUseCases) { - std::vector cameraDeviceNames = getCameraDeviceNames(mProvider); - - for (const auto& name : cameraDeviceNames) { - CameraMetadata meta; - std::shared_ptr cameraDevice; - - openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/, - &cameraDevice /*out*/); - - camera_metadata_t* staticMeta = reinterpret_cast(meta.metadata.data()); - // Check if camera support depth only - if (isDepthOnly(staticMeta)) { - ndk::ScopedAStatus ret = mSession->close(); - mSession = nullptr; - ASSERT_TRUE(ret.isOk()); - continue; - } - - std::vector outputPreviewStreams; - AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, - static_cast(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 useCases(kMandatoryUseCases); - useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL + 1); - - std::vector 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.i64, - entry.data.i64 + entry.count); - } else { - supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT); - } - - std::vector streams(1); - streams[0] = {0, - StreamType::OUTPUT, - outputPreviewStreams[0].width, - outputPreviewStreams[0].height, - static_cast(outputPreviewStreams[0].format), - static_cast<::aidl::android::hardware::graphics::common::BufferUsage>( - GRALLOC1_CONSUMER_USAGE_CPU_READ), - Dataspace::UNKNOWN, - StreamRotation::ROTATION_0, - std::string(), - 0, - -1, - {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT}, - RequestAvailableDynamicRangeProfilesMap:: - ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD}; - - int32_t streamConfigCounter = 0; - CameraMetadata req; - StreamConfiguration config; - RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; - ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &req); - ASSERT_TRUE(ret.isOk()); - config.sessionParams = req; - - for (int64_t useCase : useCases) { - bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(), - useCase) != supportedUseCases.end(); - - streams[0].useCase = static_cast< - aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases>( - useCase); - config.streams = streams; - config.operationMode = StreamConfigurationMode::NORMAL_MODE; - config.streamConfigCounter = streamConfigCounter; - config.multiResolutionInputImage = false; - - bool combSupported; - ret = cameraDevice->isStreamCombinationSupported(config, &combSupported); - if (static_cast(Status::OPERATION_NOT_SUPPORTED) == - ret.getServiceSpecificError()) { - continue; - } - - ASSERT_TRUE(ret.isOk()); - ASSERT_EQ(combSupported, useCaseSupported); - - std::vector halStreams; - ret = mSession->configureStreams(config, &halStreams); - ALOGI("configureStreams returns status: %d", ret.getServiceSpecificError()); - if (useCaseSupported) { - ASSERT_TRUE(ret.isOk()); - ASSERT_EQ(1u, halStreams.size()); - } else { - ASSERT_EQ(static_cast(Status::ILLEGAL_ARGUMENT), - ret.getServiceSpecificError()); - } - } - ret = mSession->close(); - mSession = nullptr; - ASSERT_TRUE(ret.isOk()); - } + AvailableStream previewStreamThreshold = + {kMaxPreviewWidth, kMaxPreviewHeight, static_cast(PixelFormat::YCBCR_420_888)}; + configureStreamUseCaseInternal(previewStreamThreshold); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CameraAidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, CameraAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ICameraProvider::descriptor)), - android::hardware::PrintInstanceNameToString); \ No newline at end of file + android::hardware::PrintInstanceNameToString); diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp index b9e30ab891..974223d029 100644 --- a/camera/provider/aidl/vts/camera_aidl_test.cpp +++ b/camera/provider/aidl/vts/camera_aidl_test.cpp @@ -321,8 +321,8 @@ void CameraAidlTest::verifyStreamUseCaseCharacteristics(const camera_metadata_t* if (entry.data.i64[i] == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) { supportDefaultUseCase = true; } - ASSERT_TRUE(entry.data.i64[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL || - entry.data.i64[i] >= + ASSERT_TRUE(entry.data.i64[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW + || entry.data.i64[i] >= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START); } ASSERT_TRUE(supportDefaultUseCase); @@ -2164,6 +2164,121 @@ void CameraAidlTest::processCaptureRequestInternal(uint64_t bufferUsage, } } +void CameraAidlTest::configureStreamUseCaseInternal(const AvailableStream &threshold) { + std::vector cameraDeviceNames = getCameraDeviceNames(mProvider); + + for (const auto& name : cameraDeviceNames) { + CameraMetadata meta; + std::shared_ptr cameraDevice; + + openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/, + &cameraDevice /*out*/); + + camera_metadata_t* staticMeta = reinterpret_cast(meta.metadata.data()); + // Check if camera support depth only + if (isDepthOnly(staticMeta) || + (threshold.format == static_cast(PixelFormat::RAW16) && + !supportsCroppedRawUseCase(staticMeta))) { + ndk::ScopedAStatus ret = mSession->close(); + mSession = nullptr; + ASSERT_TRUE(ret.isOk()); + continue; + } + + std::vector outputPreviewStreams; + + ASSERT_EQ(Status::OK, + getAvailableOutputStreams(staticMeta, outputPreviewStreams, &threshold)); + ASSERT_NE(0u, outputPreviewStreams.size()); + + // Combine valid and invalid stream use cases + std::vector useCases(kMandatoryUseCases); + useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW + 1); + + std::vector supportedUseCases; + if (threshold.format == static_cast(PixelFormat::RAW16)) { + // If the format is RAW16, supported use case is only CROPPED_RAW. + // All others are unsupported for this format. + useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW); + supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW); + supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT); + } else { + 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.i64, + entry.data.i64 + entry.count); + } else { + supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT); + } + } + + std::vector streams(1); + streams[0] = {0, + StreamType::OUTPUT, + outputPreviewStreams[0].width, + outputPreviewStreams[0].height, + static_cast(outputPreviewStreams[0].format), + static_cast<::aidl::android::hardware::graphics::common::BufferUsage>( + GRALLOC1_CONSUMER_USAGE_CPU_READ), + Dataspace::UNKNOWN, + StreamRotation::ROTATION_0, + std::string(), + 0, + -1, + {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT}, + RequestAvailableDynamicRangeProfilesMap:: + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD}; + + int32_t streamConfigCounter = 0; + CameraMetadata req; + StreamConfiguration config; + RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; + ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &req); + ASSERT_TRUE(ret.isOk()); + config.sessionParams = req; + + for (int64_t useCase : useCases) { + bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(), + useCase) != supportedUseCases.end(); + + streams[0].useCase = static_cast< + aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases>( + useCase); + config.streams = streams; + config.operationMode = StreamConfigurationMode::NORMAL_MODE; + config.streamConfigCounter = streamConfigCounter; + config.multiResolutionInputImage = false; + + bool combSupported; + ret = cameraDevice->isStreamCombinationSupported(config, &combSupported); + if (static_cast(Status::OPERATION_NOT_SUPPORTED) == + ret.getServiceSpecificError()) { + continue; + } + + ASSERT_TRUE(ret.isOk()); + ASSERT_EQ(combSupported, useCaseSupported); + + std::vector halStreams; + ret = mSession->configureStreams(config, &halStreams); + ALOGI("configureStreams returns status: %d", ret.getServiceSpecificError()); + if (useCaseSupported) { + ASSERT_TRUE(ret.isOk()); + ASSERT_EQ(1u, halStreams.size()); + } else { + ASSERT_EQ(static_cast(Status::ILLEGAL_ARGUMENT), + ret.getServiceSpecificError()); + } + } + ret = mSession->close(); + mSession = nullptr; + ASSERT_TRUE(ret.isOk()); + } + +} + void CameraAidlTest::configureSingleStream( const std::string& name, const std::shared_ptr& provider, const AvailableStream* previewThreshold, uint64_t bufferUsage, RequestTemplate reqTemplate, @@ -3039,6 +3154,21 @@ bool CameraAidlTest::supportZoomSettingsOverride(const camera_metadata_t* static return false; } +bool CameraAidlTest::supportsCroppedRawUseCase(const camera_metadata_t *staticMeta) { + camera_metadata_ro_entry availableStreamUseCasesEntry; + int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, + &availableStreamUseCasesEntry); + if (rc == 0) { + for (size_t i = 0; i < availableStreamUseCasesEntry.count; i++) { + if (availableStreamUseCasesEntry.data.i64[i] == + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW) { + return true; + } + } + } + return false; +} + bool CameraAidlTest::isPerFrameControl(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry syncLatencyEntry; int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SYNC_MAX_LATENCY, diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h index b6e398b435..8b8a4bca46 100644 --- a/camera/provider/aidl/vts/camera_aidl_test.h +++ b/camera/provider/aidl/vts/camera_aidl_test.h @@ -223,6 +223,8 @@ class CameraAidlTest : public ::testing::TestWithParam { int32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, std::shared_ptr* cb /*out*/, uint32_t streamConfigCounter = 0); + void configureStreamUseCaseInternal(const AvailableStream &threshold); + void configureSingleStream( const std::string& name, const std::shared_ptr& provider, const AvailableStream* previewThreshold, uint64_t bufferUsage, @@ -410,6 +412,7 @@ class CameraAidlTest : public ::testing::TestWithParam { int32_t frameCount, const bool *overrideSequence, const bool *expectedResults); bool supportZoomSettingsOverride(const camera_metadata_t* staticMeta); + bool supportsCroppedRawUseCase(const camera_metadata_t *staticMeta); bool isPerFrameControl(const camera_metadata_t* staticMeta); protected: