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
This commit is contained in:
parent
1bbd78efcd
commit
7267abff25
5 changed files with 234 additions and 14 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue