[libcamera-devel] android: Add infrastructure for determining capabilities and hardware level
diff mbox series

Message ID 20210617072246.1455382-1-paul.elder@ideasonboard.com
State Superseded
Delegated to: Paul Elder
Headers show
Series
  • [libcamera-devel] android: Add infrastructure for determining capabilities and hardware level
Related show

Commit Message

Paul Elder June 17, 2021, 7:22 a.m. UTC
Add the infrastructure for checking and reporting capabilities. Use
these capabilities to determine the hardware level as well.

Since the raw capability is set to true when support is determined to be
available, leave that as default false and set to true, since copying
the pattern of the other capabilities would cause redundant code.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=55
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>

---
This is my vision of how we would support the various capabilities.
Although we don't have anything for FULL yet; I imagine that we would
start the flags for manual sensor and manual post processing with true,
and then if a required control is unavailable, then we would set the
flag to false.

I considered declaring an enum in CameraDevice to mirror the android
ones, just for shorthand, but it seemed like a lot of code for not much
gain. Unless the shorthand would be valuable because these constant
names are so long?

I think the available keys lists will have to be moved to the head of
the function, and then as available controls are discovered add them to
that list.
---
 src/android/camera_device.cpp | 39 ++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 10 deletions(-)

Comments

Paul Elder June 17, 2021, 7:33 a.m. UTC | #1
Hi me,

On Thu, Jun 17, 2021 at 04:22:46PM +0900, Paul Elder wrote:
> Add the infrastructure for checking and reporting capabilities. Use
> these capabilities to determine the hardware level as well.
> 
> Since the raw capability is set to true when support is determined to be
> available, leave that as default false and set to true, since copying
> the pattern of the other capabilities would cause redundant code.
> 
> Bug: https://bugs.libcamera.org/show_bug.cgi?id=55
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> 
> ---
> This is my vision of how we would support the various capabilities.
> Although we don't have anything for FULL yet; I imagine that we would
> start the flags for manual sensor and manual post processing with true,
> and then if a required control is unavailable, then we would set the
> flag to false.
> 
> I considered declaring an enum in CameraDevice to mirror the android
> ones, just for shorthand, but it seemed like a lot of code for not much
> gain. Unless the shorthand would be valuable because these constant
> names are so long?
> 
> I think the available keys lists will have to be moved to the head of
> the function, and then as available controls are discovered add them to
> that list.
> ---
>  src/android/camera_device.cpp | 39 ++++++++++++++++++++++++++---------
>  1 file changed, 29 insertions(+), 10 deletions(-)
> 
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index 8c71fd06..1e437907 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -13,6 +13,7 @@
>  #include <array>
>  #include <cmath>
>  #include <fstream>
> +#include <map>
>  #include <sys/mman.h>
>  #include <tuple>
>  #include <unistd.h>
> @@ -840,6 +841,15 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  	const ControlInfoMap &controlsInfo = camera_->controls();
>  	const ControlList &properties = camera_->properties();
>  
> +	std::map<camera_metadata_enum_android_request_available_capabilities, bool>
> +	capabilities = {
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE, true },
> +		/* \todo Change these two to true when we have checks for them */
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW, false },
> +	};
> +
>  	/* Color correction static metadata. */
>  	{
>  		std::vector<uint8_t> data;
> @@ -1298,11 +1308,6 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  	uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
>  	staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, croppingType);
>  
> -	/* Info static metadata. */
> -	uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
> -	staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
> -				  supportedHWLevel);
> -
>  	/* Request static metadata. */
>  	int32_t partialResultCount = 1;
>  	staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
> @@ -1323,10 +1328,6 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  	staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
>  				  maxNumInputStreams);
>  
> -	std::vector<uint8_t> availableCapabilities = {
> -		ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
> -	};
> -
>  	/* Report if camera supports RAW. */
>  	bool rawStreamAvailable = false;
>  	std::unique_ptr<CameraConfiguration> cameraConfig =
> @@ -1338,7 +1339,7 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  		if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
>  		    info.bitsPerPixel == 16) {
>  			rawStreamAvailable = true;
> -			availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
> +			capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW] = true;
>  		}
>  	}
>  
> @@ -1347,9 +1348,27 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
>  	staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
>  				  numOutStreams);
>  
> +	/* Check capabilities */
> +	std::vector<uint8_t> availableCapabilities;
> +	for (auto cap : capabilities) {
> +		if (cap.second)
> +			availableCapabilities.push_back(CapabilityTable.at(cap.first));
> +	}
>  	staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
>  				  availableCapabilities);
>  
> +	uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
> +	if (capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR] &&
> +	    capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING])
> +		supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL;

Apparently this is insufficient to conclude FULL support [1]:

A FULL device will support below capabilities:

    BURST_CAPTURE capability (android.request.availableCapabilities contains BURST_CAPTURE)
    Per frame control (android.sync.maxLatency == PER_FRAME_CONTROL)
    Manual sensor control (android.request.availableCapabilities contains MANUAL_SENSOR)
    Manual post-processing control (android.request.availableCapabilities contains MANUAL_POST_PROCESSING)
    The required exposure time range defined in android.sensor.info.exposureTimeRange
    The required maxFrameDuration defined in android.sensor.info.maxFrameDuration


[1] https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL

So I guess we need a flag just to check FULL support :/


Paul

> +	staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
> +				  supportedHWLevel);
> +
> +	LOG(HAL, Info)
> +		<< "Hardware level: "
> +		<< supportedHWLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL
> +		   ? "FULL" : "LIMITED";
> +
>  	std::vector<int32_t> availableCharacteristicsKeys = {
>  		ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
>  		ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
> -- 
> 2.27.0
>

Patch
diff mbox series

diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 8c71fd06..1e437907 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -13,6 +13,7 @@ 
 #include <array>
 #include <cmath>
 #include <fstream>
+#include <map>
 #include <sys/mman.h>
 #include <tuple>
 #include <unistd.h>
@@ -840,6 +841,15 @@  const camera_metadata_t *CameraDevice::getStaticMetadata()
 	const ControlInfoMap &controlsInfo = camera_->controls();
 	const ControlList &properties = camera_->properties();
 
+	std::map<camera_metadata_enum_android_request_available_capabilities, bool>
+	capabilities = {
+		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE, true },
+		/* \todo Change these two to true when we have checks for them */
+		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR, false },
+		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING, false },
+		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW, false },
+	};
+
 	/* Color correction static metadata. */
 	{
 		std::vector<uint8_t> data;
@@ -1298,11 +1308,6 @@  const camera_metadata_t *CameraDevice::getStaticMetadata()
 	uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
 	staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, croppingType);
 
-	/* Info static metadata. */
-	uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
-	staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
-				  supportedHWLevel);
-
 	/* Request static metadata. */
 	int32_t partialResultCount = 1;
 	staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
@@ -1323,10 +1328,6 @@  const camera_metadata_t *CameraDevice::getStaticMetadata()
 	staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
 				  maxNumInputStreams);
 
-	std::vector<uint8_t> availableCapabilities = {
-		ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
-	};
-
 	/* Report if camera supports RAW. */
 	bool rawStreamAvailable = false;
 	std::unique_ptr<CameraConfiguration> cameraConfig =
@@ -1338,7 +1339,7 @@  const camera_metadata_t *CameraDevice::getStaticMetadata()
 		if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
 		    info.bitsPerPixel == 16) {
 			rawStreamAvailable = true;
-			availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
+			capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW] = true;
 		}
 	}
 
@@ -1347,9 +1348,27 @@  const camera_metadata_t *CameraDevice::getStaticMetadata()
 	staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
 				  numOutStreams);
 
+	/* Check capabilities */
+	std::vector<uint8_t> availableCapabilities;
+	for (auto cap : capabilities) {
+		if (cap.second)
+			availableCapabilities.push_back(CapabilityTable.at(cap.first));
+	}
 	staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
 				  availableCapabilities);
 
+	uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
+	if (capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR] &&
+	    capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING])
+		supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
+	staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
+				  supportedHWLevel);
+
+	LOG(HAL, Info)
+		<< "Hardware level: "
+		<< supportedHWLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL
+		   ? "FULL" : "LIMITED";
+
 	std::vector<int32_t> availableCharacteristicsKeys = {
 		ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
 		ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,