[libcamera-devel] [RFC PATCH v2 05/12] android: camera_device: Set static metadata for FULL requirements

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Apr 27 06:44:18 CEST 2021


Hi Paul,

Thank you for the patch.

On Thu, Apr 22, 2021 at 06:40:55PM +0900, Paul Elder wrote:
> Set the static metadata as required by CTS for FULL hardware level.
> 
> The tests that this fixes are:
> android.hardware.camera2.cts.StaticMetadataTest#testHwSupportedLevel
> 
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> 
> ---
> This patch actually introduces more failures in CTS, but that's because
> we report that we support many more things in the static metadata.
> 
> The main thing I'm not sure of in this patch is if the entries in any
> AVAILABLE_* tags require allocated space in the static metadata. Also
> the android docs say that they need to be int32_t while CTS (and other
> HAL implementations) say that they need to be uint8_t.

Hiro, do you think you could get more information on this ?

> ---
>  src/android/camera_device.cpp | 148 +++++++++++++++++++++++++++++++---
>  1 file changed, 139 insertions(+), 9 deletions(-)
> 
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index a11ad848..7f0f8f1a 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -776,10 +776,19 @@ std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
>  {
>  	/*
>  	 * \todo Keep this in sync with the actual number of entries.
> -	 * Currently: 54 entries, 874 bytes of static metadata
> +	 * Currently: 63 entries, 990 bytes of static metadata
>  	 */
> -	uint32_t numEntries = 54;
> -	uint32_t byteSize = 874;
> +	uint32_t numEntries = 63;
> +	uint32_t byteSize = 990;
> +
> +	// do i need to add for entries in the available keys?
> +	// +1, +4 for EDGE_AVAILABLE_EDGE_MODES
> +	// +1, +4 for LENS_INFO_AVAILABLE_FILTER_DENSITIES
> +	// +1, +4 for BLACK_LEVEL_PATTERN
> +	// +1, +4 for TONEMAP_AVAILABLE_TONE_MAP_MODES
> +	// +1, +4 for TONEMAP_MAX_CURVE_POINTS
> +
> +	// +36 for new request keys

C-style comments.

A question for Jacopo maybe ?

I think it's time to bite the bullet and stop computing sizes manually.

>  
>  	/*
>  	 * Calculate space occupation in bytes for dynamically built metadata
> @@ -861,7 +870,9 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  				  aeAvailableAntiBandingModes.data(),
>  				  aeAvailableAntiBandingModes.size());
>  
> +	/* \todo FULL requires OFF */
>  	std::vector<uint8_t> aeAvailableModes = {
> +		ANDROID_CONTROL_AE_MODE_OFF,
>  		ANDROID_CONTROL_AE_MODE_ON,
>  	};

This needs to be plumbed to the pipeline handler, and made conditional
on a property. Same in several locations below I suppose. We can't
hardcode metadata for FULL mode only, we need to make sure we can
support LIMITED mode devices.

>  	staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
> @@ -958,9 +969,11 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  
>  	/*
>  	 * \todo Inspect the Camera capabilities to report the available
> -	 * AWB modes. Default to AUTO as CTS tests require it.
> +	 * AWB modes. Default to AUTO as CTS tests require it. FULL requires
> +	 * OFF.
>  	 */
>  	std::vector<uint8_t> availableAwbModes = {
> +		ANDROID_CONTROL_AWB_MODE_OFF,
>  		ANDROID_CONTROL_AWB_MODE_AUTO,
>  	};
>  	staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
> @@ -983,17 +996,32 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  				  sceneModesOverride.data(),
>  				  sceneModesOverride.size());
>  
> -	uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
> +	/* true for MANUAL_SENSOR or BURST_CAPTURE capable devices */
> +	uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
>  	staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
>  				  &aeLockAvailable, 1);
>  
> -	uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
> +	/* true for MANUAL_SENSOR or BURST_CAPTURE capable devices */
> +	uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE;
>  	staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
>  				  &awbLockAvailable, 1);
>  
>  	char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
>  	staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
>  				  &availableControlModes, 1);
> +	/*
> +	 * FULL - always support OFF
> +	 * camera devices that support YUV_REPROCESSING or PRIVATE_REPROCESSING - ZERO_SHUTTER_LAG
> +	 * all devices will list FAST
> +	 */
> +	std::vector<uint8_t> availableEdgeModes = {
> +		ANDROID_EDGE_MODE_OFF,
> +		ANDROID_EDGE_MODE_FAST,
> +		ANDROID_EDGE_MODE_HIGH_QUALITY,
> +	};
> +	staticMetadata_->addEntry(ANDROID_EDGE_AVAILABLE_EDGE_MODES,
> +				  availableEdgeModes.data(),
> +				  availableEdgeModes.size());
>  
>  	/* JPEG static metadata. */
>  
> @@ -1079,10 +1107,20 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  			exposureInfo->second.min().get<int32_t>() * 1000LL,
>  			exposureInfo->second.max().get<int32_t>() * 1000LL,
>  		};
> +		/* min must be at most 100us, max at least 100ms */
> +		if (exposureTimeRange[0] > 100000)
> +			exposureTimeRange[0] = 100000;
> +		if (exposureTimeRange[1] < 100000000)
> +			exposureTimeRange[1] = 100000000;
>  		staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
>  					  &exposureTimeRange, 2);
>  	}
>  
> +	/* min at most 100, max at least 800 */
> +	int32_t maxAnalogSensitivity = 800;
> +	staticMetadata_->addEntry(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
> +				  &maxAnalogSensitivity, 1);
> +
>  	staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
>  
>  	std::vector<int32_t> testPatterModes = {
> @@ -1092,6 +1130,21 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  				  testPatterModes.data(),
>  				  testPatterModes.size());
>  
> +	/*
> +	 * required for FULL (docs don't say it is, but cts says it is)
> +	 * \todo figure out how this works
> +	 */
> +	std::vector<int32_t> blackLevelPattern = { 0, 0, 0, 0 };
> +	staticMetadata_->addEntry(ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
> +				  blackLevelPattern.data(),
> +				  blackLevelPattern.size());
> +
> +	/* range of valid values: > 255 (8-bit output) */
> +	/* this xnor BLACK_LEVEL_PATTERN must be available */
> +	int32_t whiteLevel = 256;
> +	staticMetadata_->addEntry(ANDROID_SENSOR_INFO_WHITE_LEVEL,
> +				  &whiteLevel, 1);
> +
>  	std::vector<float> physicalSize = {
>  		2592, 1944,
>  	};
> @@ -1131,7 +1184,7 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  	}
>  
>  	/* Sync static metadata. */
> -	int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
> +	int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL;
>  	staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
>  
>  	/* Flash static metadata. */
> @@ -1147,6 +1200,15 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  				  lensApertures.data(),
>  				  lensApertures.size());
>  
> +	/*
> +	 * Required for FULL
> +	 * \todo get this information from the camera, in ascending order
> +	 */
> +	std::vector<float> availableFilterDensities = { 0 };
> +	staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
> +				  availableFilterDensities.data(),
> +				  availableFilterDensities.size());
> +
>  	uint8_t lensFacing;
>  	switch (facing_) {
>  	default:
> @@ -1176,6 +1238,11 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  				  opticalStabilizations.data(),
>  				  opticalStabilizations.size());
>  
> +	/* \todo set this based on camera capability */
> +	int distanceCalibration = ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE;
> +	staticMetadata_->addEntry(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
> +				  &distanceCalibration, 1);
> +
>  	float hypeFocalDistance = 0;
>  	staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
>  				  &hypeFocalDistance, 1);
> @@ -1188,12 +1255,18 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  	{
>  		std::vector<uint8_t> data;
>  		data.reserve(5);
> +		/*
> +		 * \todo if this doesn't have OFF and FAST and HIGH_QUALITY
> +		 * then this camera does not support FULL
> +		 */
>  		const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
>  		if (infoMap != controlsInfo.end()) {
>  			for (const auto &value : infoMap->second.values())
>  				data.push_back(value.get<int32_t>());
>  		} else {
>  			data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
> +			data.push_back(ANDROID_NOISE_REDUCTION_MODE_FAST);
> +			data.push_back(ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY);
>  		}
>  		staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
>  					  data.data(), data.size());
> @@ -1261,6 +1334,16 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  	uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
>  	staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
>  
> +	/* \todo figure out if this should be int32 as documented */
> +	std::vector<uint8_t> shadingAvailableModes = {
> +		ANDROID_SHADING_MODE_OFF,
> +		ANDROID_SHADING_MODE_FAST,
> +		ANDROID_SHADING_MODE_HIGH_QUALITY,
> +	};
> +	staticMetadata_->addEntry(ANDROID_SHADING_AVAILABLE_MODES,
> +				  shadingAvailableModes.data(),
> +				  shadingAvailableModes.size());
> +
>  	/* Info static metadata. */
>  	uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
>  	staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
> @@ -1288,6 +1371,10 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  
>  	std::vector<uint8_t> availableCapabilities = {
>  		ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
> +		ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR,
> +		ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING,
> +		ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS,
> +		ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE,
>  	};
>  
>  	/* Report if camera supports RAW. */
> @@ -1306,7 +1393,7 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  	}
>  
>  	/* Number of { RAW, YUV, JPEG } supported output streams */
> -	int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
> +	int32_t numOutStreams[] = { rawStreamAvailable, 3, 1 };
>  	staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
>  				  &numOutStreams, 3);
>  
> @@ -1314,6 +1401,29 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  				  availableCapabilities.data(),
>  				  availableCapabilities.size());
>  
> +	/*
> +	 * required for FULL
> +	 * at least one of the below mode combinations:
> +	 * - CONTRAST_CURVE, FAST, HIGH_QUALITY
> +	 * - GAMMA_VALUE, PRESET_CURVE, FAST, HIGH_QUALITY
> +	 */
> +	std::vector<uint8_t> availableTonemapModes = {
> +		ANDROID_TONEMAP_MODE_CONTRAST_CURVE,
> +		ANDROID_TONEMAP_MODE_FAST,
> +		ANDROID_TONEMAP_MODE_HIGH_QUALITY,
> +	};
> +	staticMetadata_->addEntry(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
> +				  availableTonemapModes.data(),
> +				  availableTonemapModes.size());
> +
> +	/*
> +	 * required for FULL
> +	 * \todo get from camera (camCapabilities[camId]->tonemapCurvePoints?)
> +	 */
> +	int32_t tonemapCurvePoints = 0;
> +	staticMetadata_->addEntry(ANDROID_TONEMAP_MAX_CURVE_POINTS,
> +				  &tonemapCurvePoints, 1);
> +
>  	std::vector<int32_t> availableCharacteristicsKeys = {
>  		ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
>  		ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
> @@ -1331,14 +1441,17 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  		ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
>  		ANDROID_CONTROL_MAX_REGIONS,
>  		ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
> +		ANDROID_EDGE_AVAILABLE_EDGE_MODES,
>  		ANDROID_FLASH_INFO_AVAILABLE,
>  		ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
>  		ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
>  		ANDROID_JPEG_MAX_SIZE,
>  		ANDROID_LENS_FACING,
>  		ANDROID_LENS_INFO_AVAILABLE_APERTURES,
> +		ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
>  		ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
>  		ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
> +		ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
>  		ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
>  		ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
>  		ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
> @@ -1353,6 +1466,7 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  		ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
>  		ANDROID_SCALER_CROPPING_TYPE,
>  		ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
> +		ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
>  		ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
>  		ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
>  		ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
> @@ -1361,17 +1475,25 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  		ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
>  		ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
>  		ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
> +		ANDROID_SENSOR_INFO_WHITE_LEVEL,
> +		ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
>  		ANDROID_SENSOR_ORIENTATION,
> +		ANDROID_SHADING_AVAILABLE_MODES,
>  		ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
>  		ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
>  		ANDROID_SYNC_MAX_LATENCY,
> +		ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
> +		ANDROID_TONEMAP_MAX_CURVE_POINTS,
>  	};
>  	staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
>  				  availableCharacteristicsKeys.data(),
>  				  availableCharacteristicsKeys.size());
>  
>  	std::vector<int32_t> availableRequestKeys = {
> +		ANDROID_BLACK_LEVEL_LOCK,
>  		ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
> +		ANDROID_COLOR_CORRECTION_GAINS,
> +		ANDROID_COLOR_CORRECTION_TRANSFORM,
>  		ANDROID_CONTROL_AE_ANTIBANDING_MODE,
>  		ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
>  		ANDROID_CONTROL_AE_LOCK,
> @@ -1387,16 +1509,24 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  		ANDROID_CONTROL_MODE,
>  		ANDROID_CONTROL_SCENE_MODE,
>  		ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
> +		ANDROID_EDGE_MODE,
>  		ANDROID_FLASH_MODE,
>  		ANDROID_JPEG_ORIENTATION,
>  		ANDROID_JPEG_QUALITY,
>  		ANDROID_JPEG_THUMBNAIL_QUALITY,
>  		ANDROID_JPEG_THUMBNAIL_SIZE,
>  		ANDROID_LENS_APERTURE,
> +		ANDROID_LENS_FILTER_DENSITY,
>  		ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
>  		ANDROID_NOISE_REDUCTION_MODE,
>  		ANDROID_SCALER_CROP_REGION,
> -		ANDROID_STATISTICS_FACE_DETECT_MODE
> +		ANDROID_SENSOR_EXPOSURE_TIME,
> +		ANDROID_SENSOR_FRAME_DURATION,
> +		ANDROID_SENSOR_SENSITIVITY,
> +		ANDROID_SHADING_MODE,
> +		ANDROID_STATISTICS_FACE_DETECT_MODE,
> +		ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
> +		ANDROID_TONEMAP_MODE,
>  	};
>  	staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
>  				  availableRequestKeys.data(),

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list