[libcamera-devel,RFC,v2,06/12] android: camera_device: Set templates for FULL requirements
diff mbox series

Message ID 20210422094102.371772-7-paul.elder@ideasonboard.com
State Superseded
Delegated to: Paul Elder
Headers show
Series
  • FULL hardware level fixes
Related show

Commit Message

Paul Elder April 22, 2021, 9:40 a.m. UTC
Add separate functions for manual template and still capture template.
Set all template values to match FULL requirements.

This patch fixes the following tests:
- android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceCreateCaptureBuilder
- android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceManualTemplate
- android.hardware.camera2.cts.CameraDeviceTest#testCameraDevicePreviewTemplate
- android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceRecordingTemplate
- android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceStillTemplate
- android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceVideoSnapShotTemplate

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>

---
All of the templates build off of the preview template, but there is one
tag that the preview template doesn't initialize but the manual template
adds, so we still have to allocate space for that one in the preview
template. Certainly there's a better way...
---
 src/android/camera_device.cpp | 105 +++++++++++++++++++++++++++++++---
 src/android/camera_device.h   |   2 +
 2 files changed, 99 insertions(+), 8 deletions(-)

Comments

Laurent Pinchart April 27, 2021, 4:49 a.m. UTC | #1
Hi Paul,

Thank you for the patch.

On Thu, Apr 22, 2021 at 06:40:56PM +0900, Paul Elder wrote:
> Add separate functions for manual template and still capture template.
> Set all template values to match FULL requirements.
> 
> This patch fixes the following tests:
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceCreateCaptureBuilder
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceManualTemplate
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDevicePreviewTemplate
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceRecordingTemplate
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceStillTemplate
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceVideoSnapShotTemplate
> 
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> 
> ---
> All of the templates build off of the preview template, but there is one
> tag that the preview template doesn't initialize but the manual template
> adds, so we still have to allocate space for that one in the preview
> template. Certainly there's a better way...

As commented in the previous patch, I think it's time to bite the bullet
and address this. We need containers that will not require manually
tracking the amount of data. Bonus points if we can be smart to stay
efficient. If efficiency and correctness are too hard to achieve in one
go, let's start with correctness.

> ---
>  src/android/camera_device.cpp | 105 +++++++++++++++++++++++++++++++---
>  src/android/camera_device.h   |   2 +
>  2 files changed, 99 insertions(+), 8 deletions(-)
> 
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index 7f0f8f1a..c9d4afc3 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -1596,8 +1596,9 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
>  	/*
>  	 * \todo Keep this in sync with the actual number of entries.
>  	 * Currently: 20 entries, 35 bytes
> +	 * \todo how to split this with the functions that build off of this?
>  	 */
> -	auto requestTemplate = std::make_unique<CameraMetadata>(21, 36);
> +	auto requestTemplate = std::make_unique<CameraMetadata>(30, 65);
>  	if (!requestTemplate->isValid()) {
>  		return nullptr;
>  	}
> @@ -1653,6 +1654,9 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
>  	requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
>  				  &awbLock, 1);
>  
> +	uint8_t edgeMode = ANDROID_EDGE_MODE_FAST;
> +	requestTemplate->addEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
> +
>  	uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
>  	requestTemplate->addEntry(ANDROID_FLASH_MODE,
>  				  &flashMode, 1);
> @@ -1661,7 +1665,8 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
>  	requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
>  				  &faceDetectMode, 1);
>  
> -	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
> +	/* \todo FULL expects this to be FAST, not OFF*/
> +	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_FAST;
>  	requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
>  				  &noiseReduction, 1);
>  
> @@ -1683,6 +1688,35 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
>  	requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
>  				  &captureIntent, 1);
>  
> +	int64_t exposureTime = 100000;
> +	requestTemplate->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
> +				  &exposureTime, 1);
> +
> +	int32_t sensorSensitivity = 32;
> +	requestTemplate->addEntry(ANDROID_SENSOR_SENSITIVITY,
> +				  &sensorSensitivity, 1);
> +
> +	bool blackLevelLock = false;
> +	requestTemplate->addEntry(ANDROID_BLACK_LEVEL_LOCK,
> +				  &blackLevelLock, 1);
> +
> +	/* Hardcode this. We ignore it if it comes in as a request key. */
> +	int64_t frameDuration = 33333333;
> +	requestTemplate->addEntry(ANDROID_SENSOR_FRAME_DURATION,
> +				  &frameDuration, 1);
> +
> +	uint8_t shadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
> +	requestTemplate->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
> +				  &shadingMapMode, 1);
> +
> +	/* \todo handle this */
> +	uint8_t tonemapMode = ANDROID_TONEMAP_MODE_FAST;
> +	requestTemplate->addEntry(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
> +
> +	/* \todo get this from request? and set it. handle map mode too */
> +	uint8_t shadingMode = ANDROID_SHADING_MODE_FAST;
> +	requestTemplate->addEntry(ANDROID_SHADING_MODE, &shadingMode, 1);
> +
>  	return requestTemplate;
>  }
>  
> @@ -1700,6 +1734,9 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
>  	staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
>  				  &entry);
>  
> +	uint8_t edgeMode = ANDROID_EDGE_MODE_FAST;
> +	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
> +
>  	/*
>  	 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
>  	 * has been assembled as {{min, max} {max, max}}.
> @@ -1710,6 +1747,58 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
>  	return previewTemplate;
>  }
>  
> +std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateStill()
> +{
> +	std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
> +	if (!previewTemplate)
> +		return nullptr;
> +
> +	/*
> +	 * The still template with FULL requires the noise reduction mode to be
> +	 * HIGH_QUALITY.
> +	 */
> +	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
> +	previewTemplate->updateEntry(ANDROID_NOISE_REDUCTION_MODE,
> +				     &noiseReduction, 1);
> +
> +	uint8_t edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;
> +	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
> +
> +	uint8_t shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
> +	previewTemplate->updateEntry(ANDROID_SHADING_MODE, &shadingMode, 1);
> +
> +	uint8_t tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
> +	previewTemplate->updateEntry(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
> +
> +	return previewTemplate;
> +}
> +
> +std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateManual()
> +{
> +	std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
> +	if (!previewTemplate)
> +		return nullptr;
> +
> +	uint8_t controlMode = ANDROID_CONTROL_MODE_OFF;
> +	previewTemplate->updateEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
> +
> +	uint8_t aeMode = ANDROID_CONTROL_AE_MODE_OFF;
> +	previewTemplate->updateEntry(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
> +
> +	uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_OFF;
> +	previewTemplate->updateEntry(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
> +
> +	uint8_t edgeMode = ANDROID_EDGE_MODE_OFF;
> +	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
> +
> +	/* \todo get this from available filter densities */
> +	float filterDensity = 0.0f;
> +	previewTemplate->addEntry(ANDROID_LENS_FILTER_DENSITY,
> +				  &filterDensity, 1);
> +
> +	return previewTemplate;
> +}
> +
>  /*
>   * Produce a metadata pack to be used as template for a capture request.
>   */
> @@ -1728,12 +1817,8 @@ const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
>  		requestTemplate = requestTemplatePreview();
>  		break;
>  	case CAMERA3_TEMPLATE_STILL_CAPTURE:
> -		/*
> -		 * Use the preview template for still capture, they only differ
> -		 * for the torch mode we currently do not support.
> -		 */
>  		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
> -		requestTemplate = requestTemplatePreview();
> +		requestTemplate = requestTemplateStill();
>  		break;
>  	case CAMERA3_TEMPLATE_VIDEO_RECORD:
>  		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
> @@ -1743,9 +1828,13 @@ const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
>  		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
>  		requestTemplate = requestTemplateVideo();
>  		break;
> +	case CAMERA3_TEMPLATE_MANUAL:
> +		/* required for FULL */
> +		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
> +		requestTemplate = requestTemplateManual();
> +		break;
>  	/* \todo Implement templates generation for the remaining use cases. */
>  	case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
> -	case CAMERA3_TEMPLATE_MANUAL:
>  	default:
>  		LOG(HAL, Error) << "Unsupported template request type: " << type;
>  		return nullptr;
> diff --git a/src/android/camera_device.h b/src/android/camera_device.h
> index 23457e47..8edbcdfd 100644
> --- a/src/android/camera_device.h
> +++ b/src/android/camera_device.h
> @@ -104,6 +104,8 @@ private:
>  	void notifyError(uint32_t frameNumber, camera3_stream_t *stream);
>  	std::unique_ptr<CameraMetadata> requestTemplatePreview();
>  	std::unique_ptr<CameraMetadata> requestTemplateVideo();
> +	std::unique_ptr<CameraMetadata> requestTemplateStill();
> +	std::unique_ptr<CameraMetadata> requestTemplateManual();
>  	libcamera::PixelFormat toPixelFormat(int format) const;
>  	int processControls(Camera3RequestDescriptor *descriptor);
>  	std::unique_ptr<CameraMetadata> getResultMetadata(
Jacopo Mondi April 27, 2021, 9 a.m. UTC | #2
Hi Paul,

On Thu, Apr 22, 2021 at 06:40:56PM +0900, Paul Elder wrote:
> Add separate functions for manual template and still capture template.
> Set all template values to match FULL requirements.
>
> This patch fixes the following tests:
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceCreateCaptureBuilder
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceManualTemplate
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDevicePreviewTemplate
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceRecordingTemplate
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceStillTemplate
> - android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceVideoSnapShotTemplate
>
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
>
> ---
> All of the templates build off of the preview template, but there is one
> tag that the preview template doesn't initialize but the manual template
> adds, so we still have to allocate space for that one in the preview
> template. Certainly there's a better way...

There is, certainly... At the moment the code looks like this as there
is a single tag that deviates between the supported templates.

If the generation of templates starts deviating (and it's certainly
expected) I would not refrain from breaking each template apart in its
own function. Then we can group setting the 'common' tags into a single
function, but on top.

I would also consider if we maybe want to breakout the template
generation to its own file, camera_device.cpp is really growing too
fast...

> ---
>  src/android/camera_device.cpp | 105 +++++++++++++++++++++++++++++++---
>  src/android/camera_device.h   |   2 +
>  2 files changed, 99 insertions(+), 8 deletions(-)
>
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index 7f0f8f1a..c9d4afc3 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -1596,8 +1596,9 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
>  	/*
>  	 * \todo Keep this in sync with the actual number of entries.
>  	 * Currently: 20 entries, 35 bytes
> +	 * \todo how to split this with the functions that build off of this?
>  	 */
> -	auto requestTemplate = std::make_unique<CameraMetadata>(21, 36);
> +	auto requestTemplate = std::make_unique<CameraMetadata>(30, 65);
>  	if (!requestTemplate->isValid()) {
>  		return nullptr;
>  	}
> @@ -1653,6 +1654,9 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
>  	requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
>  				  &awbLock, 1);
>
> +	uint8_t edgeMode = ANDROID_EDGE_MODE_FAST;
> +	requestTemplate->addEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
> +
>  	uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
>  	requestTemplate->addEntry(ANDROID_FLASH_MODE,
>  				  &flashMode, 1);
> @@ -1661,7 +1665,8 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
>  	requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
>  				  &faceDetectMode, 1);
>
> -	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
> +	/* \todo FULL expects this to be FAST, not OFF*/
> +	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_FAST;
>  	requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
>  				  &noiseReduction, 1);
>
> @@ -1683,6 +1688,35 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
>  	requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
>  				  &captureIntent, 1);
>
> +	int64_t exposureTime = 100000;
> +	requestTemplate->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
> +				  &exposureTime, 1);

Should this be clamped to the min/max values of
controls::ExposureTime, which the HAL uses to populate
ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE

> +
> +	int32_t sensorSensitivity = 32;
> +	requestTemplate->addEntry(ANDROID_SENSOR_SENSITIVITY,
> +				  &sensorSensitivity, 1);
> +
> +	bool blackLevelLock = false;
> +	requestTemplate->addEntry(ANDROID_BLACK_LEVEL_LOCK,
> +				  &blackLevelLock, 1);
> +
> +	/* Hardcode this. We ignore it if it comes in as a request key. */
> +	int64_t frameDuration = 33333333;
> +	requestTemplate->addEntry(ANDROID_SENSOR_FRAME_DURATION,
> +				  &frameDuration, 1);

Should be at least clamped to the supported FrameDurations ?

> +
> +	uint8_t shadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
> +	requestTemplate->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
> +				  &shadingMapMode, 1);
> +
> +	/* \todo handle this */
> +	uint8_t tonemapMode = ANDROID_TONEMAP_MODE_FAST;
> +	requestTemplate->addEntry(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
> +
> +	/* \todo get this from request? and set it. handle map mode too */

Not sure "get this from request" fits here. The templates are used by
the framework to construct, well, templates for the capture requests
it will issue to the camera. So, we don't have a "request" here, but
rather we can expect the forthcoming requests to have the values we
set here.

> +	uint8_t shadingMode = ANDROID_SHADING_MODE_FAST;
> +	requestTemplate->addEntry(ANDROID_SHADING_MODE, &shadingMode, 1);
> +
>  	return requestTemplate;
>  }
>
> @@ -1700,6 +1734,9 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
>  	staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
>  				  &entry);
>
> +	uint8_t edgeMode = ANDROID_EDGE_MODE_FAST;
> +	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
> +
>  	/*
>  	 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
>  	 * has been assembled as {{min, max} {max, max}}.
> @@ -1710,6 +1747,58 @@ std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
>  	return previewTemplate;
>  }
>
> +std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateStill()
> +{
> +	std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
> +	if (!previewTemplate)
> +		return nullptr;
> +
> +	/*
> +	 * The still template with FULL requires the noise reduction mode to be
> +	 * HIGH_QUALITY.
> +	 */
> +	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
> +	previewTemplate->updateEntry(ANDROID_NOISE_REDUCTION_MODE,
> +				     &noiseReduction, 1);
> +
> +	uint8_t edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;
> +	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
> +
> +	uint8_t shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
> +	previewTemplate->updateEntry(ANDROID_SHADING_MODE, &shadingMode, 1);
> +
> +	uint8_t tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
> +	previewTemplate->updateEntry(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
> +
> +	return previewTemplate;
> +}
> +
> +std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateManual()
> +{
> +	std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
> +	if (!previewTemplate)
> +		return nullptr;
> +
> +	uint8_t controlMode = ANDROID_CONTROL_MODE_OFF;
> +	previewTemplate->updateEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
> +
> +	uint8_t aeMode = ANDROID_CONTROL_AE_MODE_OFF;
> +	previewTemplate->updateEntry(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
> +
> +	uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_OFF;
> +	previewTemplate->updateEntry(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
> +
> +	uint8_t edgeMode = ANDROID_EDGE_MODE_OFF;
> +	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
> +
> +	/* \todo get this from available filter densities */
> +	float filterDensity = 0.0f;
> +	previewTemplate->addEntry(ANDROID_LENS_FILTER_DENSITY,
> +				  &filterDensity, 1);
> +
> +	return previewTemplate;
> +}
> +
>  /*
>   * Produce a metadata pack to be used as template for a capture request.
>   */
> @@ -1728,12 +1817,8 @@ const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
>  		requestTemplate = requestTemplatePreview();
>  		break;
>  	case CAMERA3_TEMPLATE_STILL_CAPTURE:
> -		/*
> -		 * Use the preview template for still capture, they only differ
> -		 * for the torch mode we currently do not support.
> -		 */
>  		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
> -		requestTemplate = requestTemplatePreview();
> +		requestTemplate = requestTemplateStill();
>  		break;
>  	case CAMERA3_TEMPLATE_VIDEO_RECORD:
>  		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
> @@ -1743,9 +1828,13 @@ const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
>  		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
>  		requestTemplate = requestTemplateVideo();
>  		break;
> +	case CAMERA3_TEMPLATE_MANUAL:
> +		/* required for FULL */
> +		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
> +		requestTemplate = requestTemplateManual();
> +		break;
>  	/* \todo Implement templates generation for the remaining use cases. */
>  	case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
> -	case CAMERA3_TEMPLATE_MANUAL:
>  	default:
>  		LOG(HAL, Error) << "Unsupported template request type: " << type;
>  		return nullptr;
> diff --git a/src/android/camera_device.h b/src/android/camera_device.h
> index 23457e47..8edbcdfd 100644
> --- a/src/android/camera_device.h
> +++ b/src/android/camera_device.h
> @@ -104,6 +104,8 @@ private:
>  	void notifyError(uint32_t frameNumber, camera3_stream_t *stream);
>  	std::unique_ptr<CameraMetadata> requestTemplatePreview();
>  	std::unique_ptr<CameraMetadata> requestTemplateVideo();
> +	std::unique_ptr<CameraMetadata> requestTemplateStill();
> +	std::unique_ptr<CameraMetadata> requestTemplateManual();
>  	libcamera::PixelFormat toPixelFormat(int format) const;
>  	int processControls(Camera3RequestDescriptor *descriptor);
>  	std::unique_ptr<CameraMetadata> getResultMetadata(
> --
> 2.27.0
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch
diff mbox series

diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 7f0f8f1a..c9d4afc3 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -1596,8 +1596,9 @@  std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
 	/*
 	 * \todo Keep this in sync with the actual number of entries.
 	 * Currently: 20 entries, 35 bytes
+	 * \todo how to split this with the functions that build off of this?
 	 */
-	auto requestTemplate = std::make_unique<CameraMetadata>(21, 36);
+	auto requestTemplate = std::make_unique<CameraMetadata>(30, 65);
 	if (!requestTemplate->isValid()) {
 		return nullptr;
 	}
@@ -1653,6 +1654,9 @@  std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
 	requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
 				  &awbLock, 1);
 
+	uint8_t edgeMode = ANDROID_EDGE_MODE_FAST;
+	requestTemplate->addEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
+
 	uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
 	requestTemplate->addEntry(ANDROID_FLASH_MODE,
 				  &flashMode, 1);
@@ -1661,7 +1665,8 @@  std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
 	requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
 				  &faceDetectMode, 1);
 
-	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
+	/* \todo FULL expects this to be FAST, not OFF*/
+	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_FAST;
 	requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
 				  &noiseReduction, 1);
 
@@ -1683,6 +1688,35 @@  std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
 	requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
 				  &captureIntent, 1);
 
+	int64_t exposureTime = 100000;
+	requestTemplate->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
+				  &exposureTime, 1);
+
+	int32_t sensorSensitivity = 32;
+	requestTemplate->addEntry(ANDROID_SENSOR_SENSITIVITY,
+				  &sensorSensitivity, 1);
+
+	bool blackLevelLock = false;
+	requestTemplate->addEntry(ANDROID_BLACK_LEVEL_LOCK,
+				  &blackLevelLock, 1);
+
+	/* Hardcode this. We ignore it if it comes in as a request key. */
+	int64_t frameDuration = 33333333;
+	requestTemplate->addEntry(ANDROID_SENSOR_FRAME_DURATION,
+				  &frameDuration, 1);
+
+	uint8_t shadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+	requestTemplate->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+				  &shadingMapMode, 1);
+
+	/* \todo handle this */
+	uint8_t tonemapMode = ANDROID_TONEMAP_MODE_FAST;
+	requestTemplate->addEntry(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
+
+	/* \todo get this from request? and set it. handle map mode too */
+	uint8_t shadingMode = ANDROID_SHADING_MODE_FAST;
+	requestTemplate->addEntry(ANDROID_SHADING_MODE, &shadingMode, 1);
+
 	return requestTemplate;
 }
 
@@ -1700,6 +1734,9 @@  std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
 	staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
 				  &entry);
 
+	uint8_t edgeMode = ANDROID_EDGE_MODE_FAST;
+	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
+
 	/*
 	 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
 	 * has been assembled as {{min, max} {max, max}}.
@@ -1710,6 +1747,58 @@  std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
 	return previewTemplate;
 }
 
+std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateStill()
+{
+	std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
+	if (!previewTemplate)
+		return nullptr;
+
+	/*
+	 * The still template with FULL requires the noise reduction mode to be
+	 * HIGH_QUALITY.
+	 */
+	uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
+	previewTemplate->updateEntry(ANDROID_NOISE_REDUCTION_MODE,
+				     &noiseReduction, 1);
+
+	uint8_t edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;
+	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
+
+	uint8_t shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
+	previewTemplate->updateEntry(ANDROID_SHADING_MODE, &shadingMode, 1);
+
+	uint8_t tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
+	previewTemplate->updateEntry(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
+
+	return previewTemplate;
+}
+
+std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateManual()
+{
+	std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
+	if (!previewTemplate)
+		return nullptr;
+
+	uint8_t controlMode = ANDROID_CONTROL_MODE_OFF;
+	previewTemplate->updateEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
+
+	uint8_t aeMode = ANDROID_CONTROL_AE_MODE_OFF;
+	previewTemplate->updateEntry(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
+
+	uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_OFF;
+	previewTemplate->updateEntry(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
+
+	uint8_t edgeMode = ANDROID_EDGE_MODE_OFF;
+	previewTemplate->updateEntry(ANDROID_EDGE_MODE, &edgeMode, 1);
+
+	/* \todo get this from available filter densities */
+	float filterDensity = 0.0f;
+	previewTemplate->addEntry(ANDROID_LENS_FILTER_DENSITY,
+				  &filterDensity, 1);
+
+	return previewTemplate;
+}
+
 /*
  * Produce a metadata pack to be used as template for a capture request.
  */
@@ -1728,12 +1817,8 @@  const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
 		requestTemplate = requestTemplatePreview();
 		break;
 	case CAMERA3_TEMPLATE_STILL_CAPTURE:
-		/*
-		 * Use the preview template for still capture, they only differ
-		 * for the torch mode we currently do not support.
-		 */
 		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
-		requestTemplate = requestTemplatePreview();
+		requestTemplate = requestTemplateStill();
 		break;
 	case CAMERA3_TEMPLATE_VIDEO_RECORD:
 		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
@@ -1743,9 +1828,13 @@  const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
 		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
 		requestTemplate = requestTemplateVideo();
 		break;
+	case CAMERA3_TEMPLATE_MANUAL:
+		/* required for FULL */
+		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
+		requestTemplate = requestTemplateManual();
+		break;
 	/* \todo Implement templates generation for the remaining use cases. */
 	case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
-	case CAMERA3_TEMPLATE_MANUAL:
 	default:
 		LOG(HAL, Error) << "Unsupported template request type: " << type;
 		return nullptr;
diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index 23457e47..8edbcdfd 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -104,6 +104,8 @@  private:
 	void notifyError(uint32_t frameNumber, camera3_stream_t *stream);
 	std::unique_ptr<CameraMetadata> requestTemplatePreview();
 	std::unique_ptr<CameraMetadata> requestTemplateVideo();
+	std::unique_ptr<CameraMetadata> requestTemplateStill();
+	std::unique_ptr<CameraMetadata> requestTemplateManual();
 	libcamera::PixelFormat toPixelFormat(int format) const;
 	int processControls(Camera3RequestDescriptor *descriptor);
 	std::unique_ptr<CameraMetadata> getResultMetadata(