Camera: Add new function to query for SessionConfiguration

- The new isStreamCombinationSupported takes into consideration
  the session parameters.
- In order to create CaptureRequest in ICameraDevice, a
  createDefaultRequestSettings function is needed.

Test: Run camera VTS with session_configuration_with_parameters_query flag enabled
Bug: 309627704
Change-Id: Ib344e6991484b834aa8483ed8637ce5cd02ede87
This commit is contained in:
Shuzhen Wang
2023-11-09 18:24:42 -08:00
parent 3478b3d87e
commit df89cb9c21
8 changed files with 162 additions and 30 deletions

View File

@@ -43,4 +43,6 @@ interface ICameraDevice {
void setTorchMode(boolean on);
void turnOnTorchWithStrengthLevel(int torchStrength);
int getTorchStrengthLevel();
android.hardware.camera.device.CameraMetadata constructDefaultRequestSettings(in android.hardware.camera.device.RequestTemplate type);
boolean isStreamCombinationWithSettingsSupported(in android.hardware.camera.device.StreamConfiguration streams);
}

View File

@@ -21,6 +21,7 @@ import android.hardware.camera.device.CameraMetadata;
import android.hardware.camera.device.ICameraDeviceCallback;
import android.hardware.camera.device.ICameraDeviceSession;
import android.hardware.camera.device.ICameraInjectionSession;
import android.hardware.camera.device.RequestTemplate;
import android.hardware.camera.device.StreamConfiguration;
import android.os.ParcelFileDescriptor;
@@ -346,4 +347,92 @@ interface ICameraDevice {
*
*/
int getTorchStrengthLevel();
/**
* constructDefaultRequestSettings:
*
* This is the same as ICameraDeviceSession.constructDefaultRequestSettings, with
* the exception that it can be called before the ICameraDevice.open call.
*
* @param type The requested template CaptureRequest type to create the default settings for.
*
* @return capture settings for the requested use case.
*
*/
CameraMetadata constructDefaultRequestSettings(in RequestTemplate type);
/**
* isStreamCombinationWithSettingsSupported:
*
* This is the same as isStreamCombinationSupported with below exceptions:
*
* 1. The input StreamConfiguration parameter may contain session parameters
* supported by this camera device. When checking if the particular StreamConfiguration
* is supported, the camera HAL must take the session parameters into consideration.
*
* 2. For version 3 of this interface, the camera compliance test will verify that
* isStreamCombinationWithSettingsSupported behaves properly for all combinations of
* below features. This function must return true for all supported combinations,
* and return false for non-supported feature combinations. The list of features
* required may grow in future versions.
*
* - Stream Combinations (a subset of LEGACY device mandatory stream combinations):
* {
* // 4:3 16:9
* // S1440P: 1920 x 1440 2560 x 1440
* // S1080P: 1440 x 1080 1920 x 1080
* // S720P: 960 x 720 1280 x 720
*
* // Simple preview, GPU video processing, or no-preview video recording
* {PRIV, MAXIMUM},
* {PRIV, PREVIEW},
* {PRIV, S1440P},
* {PRIV, S1080P},
* {PRIV, S720P},
* // In-application video/image processing
* {YUV, MAXIMUM},
* {YUV, PREVIEW},
* {YUV, S1440P},
* {YUV, S1080P},
* {YUV, S720P},
* // Standard still imaging.
* {PRIV, PREVIEW, JPEG, MAXIMUM},
* {PRIV, S1440P, JPEG, MAXIMUM},
* {PRIV, S1080P, JPEG, MAXIMUM},
* {PRIV, S720P, JPEG, MAXIMUM},
* {PRIV, S1440P, JPEG, S1440P},
* {PRIV, S1080P, JPEG, S1080P},
* {PRIV, S720P, JPEG, S1080P},
* // In-app processing plus still capture.
* {YUV, PREVIEW, JPEG, MAXIMUM},
* {YUV, S1440P, JPEG, MAXIMUM},
* {YUV, S1080P, JPEG, MAXIMUM},
* {YUV, S720P, JPEG, MAXIMUM},
* // Standard recording.
* {PRIV, PREVIEW, PRIV, PREVIEW},
* {PRIV, S1440P, PRIV, S1440P},
* {PRIV, S1080P, PRIV, S1080P},
* {PRIV, S720P, PRIV, S720P},
* // Preview plus in-app processing.
* {PRIV, PREVIEW, YUV, PREVIEW},
* {PRIV, S1440P, YUV, S1440P},
* {PRIV, S1080P, YUV, S1080P},
* {PRIV, S720P, YUV, S720P},
* }
* - VIDEO_STABILIZATION_MODES: {OFF, PREVIEW}
* - AE_TARGET_FPS_RANGE: {{*, 30}, {*, 60}}
* - DYNAMIC_RANGE_PROFILE: {STANDARD, HLG10}
*
* Note: If a combination contains a S1440P, S1080P, or S720P stream,
* both 4:3 and 16:9 aspect ratio will be considered. For example, for the
* stream combination of {PRIV, S1440P, JPEG, MAXIMUM}, and if MAXIMUM ==
* 4032 x 3024, the camera compliance test will verify both
* {PRIV, 1920 x 1440, JPEG, 4032 x 3024} and {PRIV, 2560 x 1440, JPEG, 4032 x 2268}.
*
* @param streams The StreamConfiguration to be tested, with optional session parameters.
*
* @return true in case the stream combination is supported, false otherwise.
*
*/
boolean isStreamCombinationWithSettingsSupported(in StreamConfiguration streams);
}

View File

@@ -17,7 +17,7 @@ aidl_interface {
"android.hardware.camera.device-V3",
"android.hardware.camera.common-V1",
],
frozen: true,
frozen: false,
stability: "vintf",
backend: {
java: {
@@ -38,7 +38,7 @@ aidl_interface {
{
version: "2",
imports: [
"android.hardware.camera.device-V3",
"android.hardware.camera.device-V2",
"android.hardware.camera.common-V1",
],
},

View File

@@ -62,7 +62,7 @@ cc_test {
"android.hardware.camera.common-V1-ndk",
"android.hardware.camera.device-V3-ndk",
"android.hardware.camera.metadata-V2-ndk",
"android.hardware.camera.provider-V2-ndk",
"android.hardware.camera.provider-V3-ndk",
"android.hidl.allocator@1.0",
"libgrallocusage",
"libhidlmemory",

View File

@@ -500,6 +500,12 @@ TEST_P(CameraAidlTest, constructDefaultRequestSettings) {
ASSERT_TRUE(ret.isOk());
ASSERT_NE(device, nullptr);
int32_t interfaceVersion;
ret = device->getInterfaceVersion(&interfaceVersion);
ASSERT_TRUE(ret.isOk());
bool supportFeatureCombinationQuery =
(interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
std::shared_ptr<EmptyDeviceCb> cb = ndk::SharedRefBase::make<EmptyDeviceCb>();
ret = device->open(cb, &mSession);
ALOGI("device::open returns status:%d:%d", ret.getExceptionCode(),
@@ -533,6 +539,34 @@ TEST_P(CameraAidlTest, constructDefaultRequestSettings) {
} else {
ASSERT_EQ(0u, rawMetadata.metadata.size());
}
if (flags::feature_combination_query()) {
if (supportFeatureCombinationQuery) {
CameraMetadata rawMetadata2;
ndk::ScopedAStatus ret2 =
device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
// TODO: Do not allow OPERATION_NOT_SUPPORTED once HAL
// implementation is in place.
if (static_cast<Status>(ret2.getServiceSpecificError()) !=
Status::OPERATION_NOT_SUPPORTED) {
ASSERT_EQ(ret.isOk(), ret2.isOk());
ASSERT_EQ(ret.getStatus(), ret2.getStatus());
ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
if (ret2.isOk()) {
const camera_metadata_t* metadata =
(camera_metadata_t*)rawMetadata2.metadata.data();
size_t expectedSize = rawMetadata2.metadata.size();
int result =
validate_camera_metadata_structure(metadata, &expectedSize);
ASSERT_TRUE((result == 0) ||
(result == CAMERA_METADATA_VALIDATION_SHIFTED));
verifyRequestTemplate(metadata, reqTemplate);
}
}
}
}
}
ret = mSession->close();
mSession = nullptr;
@@ -588,8 +622,7 @@ TEST_P(CameraAidlTest, configureStreamsAvailableOutputs) {
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
verifyStreamCombination(device, config, /*expectedStatus*/ true, expectStreamCombQuery);
verifyStreamCombination(device, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -687,11 +720,7 @@ TEST_P(CameraAidlTest, configureConcurrentStreamsAvailableOutputs) {
// Test the stream can actually be configured
for (auto& cti : cameraTestInfos) {
if (cti.session != nullptr) {
camera_metadata_t* staticMeta =
reinterpret_cast<camera_metadata_t*>(cti.staticMeta.metadata.data());
bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
verifyStreamCombination(cti.cameraDevice, cti.config, /*expectedStatus*/ true,
expectStreamCombQuery);
verifyStreamCombination(cti.cameraDevice, cti.config, /*expectedStatus*/ true);
}
if (cti.session != nullptr) {
@@ -752,8 +781,7 @@ TEST_P(CameraAidlTest, configureStreamsInvalidOutputs) {
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ false,
/*expectStreamCombQuery*/ false);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ false);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -972,8 +1000,7 @@ TEST_P(CameraAidlTest, configureStreamsZSLInputOutputs) {
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
/*expectStreamCombQuery*/ false);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -1191,8 +1218,7 @@ TEST_P(CameraAidlTest, configureStreamsPreviewStillOutputs) {
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
config.streamConfigCounter = streamConfigCounter++;
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
/*expectStreamCombQuery*/ false);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
std::vector<HalStream> halConfigs;
ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
@@ -1256,8 +1282,7 @@ TEST_P(CameraAidlTest, configureStreamsConstrainedOutputs) {
createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
&config);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
/*expectStreamCombQuery*/ false);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -1429,8 +1454,7 @@ TEST_P(CameraAidlTest, configureStreamsVideoStillOutputs) {
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
/*expectStreamCombQuery*/ false);
verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;

View File

@@ -58,6 +58,8 @@ using ::ndk::ScopedAStatus;
using ::ndk::SpAIBinder;
namespace {
namespace flags = com::android::internal::camera::flags;
bool parseProviderName(const std::string& serviceDescriptor, std::string* type /*out*/,
uint32_t* id /*out*/) {
if (!type || !id) {
@@ -1899,17 +1901,32 @@ void CameraAidlTest::createStreamConfiguration(std::vector<Stream>& streams,
}
void CameraAidlTest::verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
const StreamConfiguration& config, bool expectedStatus,
bool expectStreamCombQuery) {
const StreamConfiguration& config,
bool expectedStatus) {
if (device != nullptr) {
bool streamCombinationSupported;
ScopedAStatus ret =
device->isStreamCombinationSupported(config, &streamCombinationSupported);
// TODO: Check is unsupported operation is correct.
ASSERT_TRUE(ret.isOk() ||
(expectStreamCombQuery && ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION));
if (ret.isOk()) {
ASSERT_EQ(expectedStatus, streamCombinationSupported);
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(expectedStatus, streamCombinationSupported);
if (flags::feature_combination_query()) {
int32_t interfaceVersion;
ret = device->getInterfaceVersion(&interfaceVersion);
ASSERT_TRUE(ret.isOk());
bool supportFeatureCombinationQuery =
(interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
if (supportFeatureCombinationQuery) {
ret = device->isStreamCombinationWithSettingsSupported(config,
&streamCombinationSupported);
// TODO: Do not allow OPERATION_NOT_SUPPORTED once HAL
// implementation is in place.
ASSERT_TRUE(ret.isOk() || static_cast<Status>(ret.getServiceSpecificError()) ==
Status::OPERATION_NOT_SUPPORTED);
if (ret.isOk()) {
ASSERT_EQ(expectedStatus, streamCombinationSupported);
}
}
}
}
}

View File

@@ -279,8 +279,7 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
static void verifySettingsOverrideCharacteristics(const camera_metadata_t* metadata);
static void verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
const StreamConfiguration& config, bool expectedStatus,
bool expectStreamCombQuery);
const StreamConfiguration& config, bool expectedStatus);
static void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
const std::vector<uint8_t>& resultMetadata);
@@ -625,6 +624,7 @@ namespace {
// device@<major>.<minor>/<type>/id
const char* kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/\\s+/(.+)";
const std::string CAMERA_DEVICE_API_VERSION_1 = "1.1";
const int32_t CAMERA_DEVICE_API_MINOR_VERSION_3 = 3;
const int32_t kMaxVideoWidth = 4096;
const int32_t kMaxVideoHeight = 2160;

View File

@@ -181,7 +181,7 @@
</hal>
<hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.camera.provider</name>
<version>1-2</version>
<version>1-3</version>
<interface>
<name>ICameraProvider</name>
<regex-instance>[^/]+/[0-9]+</regex-instance>