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

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

Commit Message

Paul Elder June 17, 2021, 7:38 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>

---
Changes in v2:
- add a flag for FULL, since there are a few requirements that are not
  obtained from capabilities alone
- add burst capture capability, since that is required for FULL as well

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 | 45 +++++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 10 deletions(-)

Comments

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

On Thu, Jun 17, 2021 at 04:38:56PM +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>
> 
> ---
> Changes in v2:
> - add a flag for FULL, since there are a few requirements that are not
>   obtained from capabilities alone
> - add burst capture capability, since that is required for FULL as well
> 
> 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 | 45 +++++++++++++++++++++++++++--------
>  1 file changed, 35 insertions(+), 10 deletions(-)
> 
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index 8c71fd06..0dcdda23 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,19 @@ 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 three to true when we have checks for them */
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW, false },
> +	};
> +
> +	/* \todo Change this to true when we have checks for it */
> +	bool fullSupport = false;
> +
>  	/* Color correction static metadata. */
>  	{
>  		std::vector<uint8_t> data;
> @@ -1298,11 +1312,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 +1332,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 +1343,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 +1352,29 @@ 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));

CapabilityTable doesn't exist as of v1.

> +	}
>  	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] &&
> +	    capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE] &&
> +	    fullSupport)
> +		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

<< has higher precedence than ==.


Paul

> +		   ? "FULL" : "LIMITED";
> +
>  	std::vector<int32_t> availableCharacteristicsKeys = {
>  		ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
>  		ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
> -- 
> 2.27.0
>
Laurent Pinchart June 17, 2021, 2:48 p.m. UTC | #2
Hi Paul,

Thank you for the patch.

On Thu, Jun 17, 2021 at 04:38:56PM +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>
> 
> ---
> Changes in v2:
> - add a flag for FULL, since there are a few requirements that are not
>   obtained from capabilities alone
> - add burst capture capability, since that is required for FULL as well
> 
> 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?

They're long, but all lines are long in that function, so I don't mind.
If we start shortening one enum then we'll do a second one, and I fear
we'll rewrite all constants :-)

> 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 | 45 +++++++++++++++++++++++++++--------
>  1 file changed, 35 insertions(+), 10 deletions(-)
> 
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index 8c71fd06..0dcdda23 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,19 @@ 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>

I think std::set<camera_metadata_enum_android_request_available_capabilities>
would be a better data type. You can easily add, remove and check for
presence of entries. The drawback is that lookups would be slightly
longer to write. Instead of

	if (capabilities[FOO])

you would need

	if (capabilities.count(FOO))

There's also

	if (capabilities.contains(FOO))

but only in C++20 :-S

I'd rule out

	if (capabilities.find(FOO) != capabilities.end())

as that's too verbose here.

Another option would be a bitmask :-) (std::bitset can be useful).

> +	capabilities = {
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE, true },
> +		/* \todo Change these three to true when we have checks for them */
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW, false },
> +	};
> +
> +	/* \todo Change this to true when we have checks for it */
> +	bool fullSupport = false;
> +
>  	/* Color correction static metadata. */
>  	{
>  		std::vector<uint8_t> data;
> @@ -1298,11 +1312,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 +1332,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 +1343,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 +1352,29 @@ 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] &&
> +	    capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE] &&
> +	    fullSupport)
> +		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";

I'd add a static table of strings indexed by
camera_metadata_enum_android_info_supported_hardware_level value, that
way we'll be ready for other hardware levels (including external).

This otherwise looks fine to me.

> +
>  	std::vector<int32_t> availableCharacteristicsKeys = {
>  		ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
>  		ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
Jacopo Mondi June 18, 2021, 8:45 a.m. UTC | #3
Hi Paul,
   thanks for addressing this.

On Thu, Jun 17, 2021 at 04:38:56PM +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>
>
> ---
> Changes in v2:
> - add a flag for FULL, since there are a few requirements that are not
>   obtained from capabilities alone
> - add burst capture capability, since that is required for FULL as well
>
> 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.
> ---

More than a comment on the patch itself, let me try to formalize the
problem a bit

We have 4 different 'items':
- supported streams
- static metadata
- capabilities
- hw level

- supported streams: self descriptive, we already collect them in
  initializeStreamConfigurations()

- static metadata: List of static properties as collected in
  getStaticMetadata with an associated set of values

  This is what we collect in getStaticMetadata by inspecting the
  libcamera::Camera capabilities plus some other information from the
  configuration file.

  A static metadata might be present/not present, and if it is present
  it might have associated values

- capabilities: A list of static metadata which has to be present in the static
  metadata pack with associated values and a list of required streams

  In example, from the android.request.availableCapabilities
  documentation the RAW capability requires:
  - An output stream in RAW_FORMAT format with an output size equal to
    the sensor pixel array
  - DNG related metadata (the list to be formalized)

  For MANUAL_SENSOR capability:
  - android.control.aeMode contains OFF
  - android.control.awbMode contains OFF
  - android.control.afMode contains OFF
  - ANDROID_REQUEST_AVAILABLE_RESULT_KEYS contains android.sensor.frameDuration
  - ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS contains
    android.sensor.info.maxFrameDuration
  - ...

- hw level: a list of requested 'capabilities',  a list of static
  metadata that has to be present in the static metadata pack and a
  list of request streams

  In example, FULL requires
  - The stream list required for FULL, LIMITED and LEGACY levels
    (see the table here
    https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#regular-capture)
  - The following capabilities:
    - BURST_CAPTURE, MANUAL_SENSOR, MANUAL_POST_PROCESSING
  - A list of static metadata and associated requirements for values
    - android.sync.maxLatency == PER_FRAME_CONTROL
    - max(android.sensor.info.exposureTimeRange) >= 100ms
    - max(android.sensor.info.maxFrameDuration) >= 100ms
    - android.scaler.croppingType contains CENTERED

It's not easy to formalize this in a table and I'm afraid all
these checks should be open coded and built iteratively

* Build the list of supported streams like we're doing
* Build the list of static metadata like we're doing
* Build the list of capabilities inspecting the supported streams and
  static metadata
* Infer the HW level by inspecting capabilities, static metadata and
  the list of supported streams

I think we're good for the first two steps, the last two have to be
done and as I've said I suspect it's not easy to formalize all the
requirements in a table (not impossible though, we can associate to
each capability a list of streams and metadata, to each HW level a
list of capabilities, streams and metadata... Although how to express
constrains like "maxFrameDuration should be 1s and MUST be > 100ms"
might end up requiring more complexity than open coding)

Now, that's potentially quite some code, and I would really take the
occasion to break out from camera_device.cpp which is already ~2400
loc the parts that deal with:
- stream list contruction (initializeStreamConfigurations() function)
- static metadata pack contructions (getStaticMetadata() function)
- capabilities building
- HW level inferring

If we move all of this to a CameraCapabilities (?) class we can logically
separate it from the CameraDevice. I don't see huge blockers if not
that the CameraCapabilities class should receive quite some parameters
from CameraDevice, but we can work it out.

Should we start moving the existing code to a new class and the build
the last two steps (capabilities and hw level) there ?

What do you think ?

Thanks
  j

>  src/android/camera_device.cpp | 45 +++++++++++++++++++++++++++--------
>  1 file changed, 35 insertions(+), 10 deletions(-)
>
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index 8c71fd06..0dcdda23 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,19 @@ 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 three to true when we have checks for them */
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING, false },
> +		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW, false },
> +	};
> +
> +	/* \todo Change this to true when we have checks for it */
> +	bool fullSupport = false;
> +
>  	/* Color correction static metadata. */
>  	{
>  		std::vector<uint8_t> data;
> @@ -1298,11 +1312,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 +1332,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 +1343,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 +1352,29 @@ 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] &&
> +	    capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE] &&
> +	    fullSupport)
> +		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,
> --
> 2.27.0
>

Patch
diff mbox series

diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 8c71fd06..0dcdda23 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,19 @@  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 three to true when we have checks for them */
+		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE, false },
+		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR, false },
+		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING, false },
+		{ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW, false },
+	};
+
+	/* \todo Change this to true when we have checks for it */
+	bool fullSupport = false;
+
 	/* Color correction static metadata. */
 	{
 		std::vector<uint8_t> data;
@@ -1298,11 +1312,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 +1332,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 +1343,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 +1352,29 @@  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] &&
+	    capabilities[ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE] &&
+	    fullSupport)
+		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,