[libcamera-devel] [RFC PATCH 1/2] android: Plumb Sharpness control into EDGE_MODE
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Aug 31 05:07:42 CEST 2021
Hi Paul,
Thank you for the patch.
On Mon, Aug 23, 2021 at 06:48:05PM +0900, Paul Elder wrote:
> Plumb the Sharpness control into the HAL for EDGE_MODE and other related
> android controls.
>
> Bug: https://bugs.libcamera.org/show_bug.cgi?id=46
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> ---
> src/android/camera_capabilities.cpp | 33 ++++++++++++++++++++++
> src/android/camera_device.cpp | 44 +++++++++++++++++++++++++++++
> 2 files changed, 77 insertions(+)
>
> diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp
> index bd661675..d12dc048 100644
> --- a/src/android/camera_capabilities.cpp
> +++ b/src/android/camera_capabilities.cpp
> @@ -231,6 +231,11 @@ bool CameraCapabilities::validateManualSensorCapability()
> return false;
> }
>
> + if (!staticMetadata_->hasEntry(ANDROID_EDGE_AVAILABLE_EDGE_MODES)) {
> + LOG(HAL, Info) << noMode << "missing edge modes";
> + return false;
> + }
Where did you see that the manual sensor capability requires edge mode ?
I'm looking at
https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
and I don't see edge mode control there. It's however required for FULL
level, but I'm not entirely sure if FULL level request supporting other
modes than OFF.
> +
> /*
> * \todo Return true here after we satisfy all the requirements:
> * https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
> @@ -938,6 +943,22 @@ int CameraCapabilities::initializeStaticMetadata()
> staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
> availableControlModes);
>
> +
Extra blank line.
> + const auto &edgeInfo = controlsInfo.find(&controls::Sharpness);
> + if (edgeInfo != controlsInfo.end()) {
> + 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);
> + availableCharacteristicsKeys_.insert(ANDROID_EDGE_AVAILABLE_EDGE_MODES);
> + availableRequestKeys_.insert(ANDROID_EDGE_MODE);
> + availableResultKeys_.insert(ANDROID_EDGE_MODE);
> + }
> +
> /* JPEG static metadata. */
>
> /*
> @@ -1330,6 +1351,9 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateManual() cons
> if (!manualTemplate)
> return nullptr;
>
> + if (availableRequestKeys_.count(ANDROID_EDGE_MODE))
> + manualTemplate->addEntry(ANDROID_EDGE_MODE, ANDROID_EDGE_MODE_OFF);
> +
> return manualTemplate;
> }
>
> @@ -1390,6 +1414,9 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplatePreview() con
> uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
> requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK, awbLock);
>
> + if (availableRequestKeys_.count(ANDROID_EDGE_MODE))
> + requestTemplate->addEntry(ANDROID_EDGE_MODE, ANDROID_EDGE_MODE_FAST);
> +
> uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
> requestTemplate->addEntry(ANDROID_FLASH_MODE, flashMode);
>
> @@ -1428,6 +1455,9 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateStill() const
> if (!stillTemplate)
> return nullptr;
>
> + if (availableRequestKeys_.count(ANDROID_EDGE_MODE))
> + stillTemplate->addEntry(ANDROID_EDGE_MODE, ANDROID_EDGE_MODE_HIGH_QUALITY);
> +
> return stillTemplate;
> }
>
> @@ -1445,6 +1475,9 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateVideo() const
> staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
> &entry);
>
> + if (availableRequestKeys_.count(ANDROID_EDGE_MODE))
> + previewTemplate->addEntry(ANDROID_EDGE_MODE, ANDROID_EDGE_MODE_FAST);
> +
> /*
> * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
> * has been assembled as {{min, max} {max, max}}.
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index a69b687a..96afec81 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -829,6 +829,24 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
> controls.set(controls::draft::TestPatternMode, testPatternMode);
> }
>
> + if (settings.getEntry(ANDROID_EDGE_MODE, &entry)) {
> + const auto &info = camera_->controls().find(&controls::Sharpness);
> + if (info != camera_->controls().end()) {
> + float min = info->second.min().get<float>();
> + float def = info->second.def().get<float>();
> + float max = info->second.max().get<float>();
> + /*
> + * The default value might be unusable since control
> + * serialization ignores it. Alternatively the default
Isn't this something that needs to be fixed in controls serialization ?
We can keep the workaround to avoiding depending on that work, but a
todo comment is needed then.
> + * could be simply set to zero or the minimum value.
> + * Use the maximum sharpness value in these cases.
> + */
> + float val = (def == 0.0f || def == min) ? max : def;
> + controls.set(controls::Sharpness,
> + *entry.data.u8 == ANDROID_EDGE_MODE_OFF ? min : val);
> + }
> + }
> +
> return 0;
> }
>
> @@ -1371,6 +1389,32 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons
> duration);
> }
>
> + if (metadata.contains(controls::Sharpness) &&
> + settings.getEntry(ANDROID_EDGE_MODE, &entry)) {
> + const auto &info = camera_->controls().find(&controls::Sharpness);
> + if (info != camera_->controls().end()) {
> + float min = info->second.min().get<float>();
> + float max = info->second.max().get<float>();
> + float sharpness = metadata.get(controls::Sharpness);
> + /*
> + * 1% of the sharpening value range is considered "no
> + * sharpening".
> + */
> + bool closeToMin = (sharpness - min) < (min + (0.01 * (max - min))) ||
> + min == max;
> +
> + /*
> + * libcamera doesn't distinguish between fast vs HQ
> + * sharpening modes. Report the mode that was
> + * requested.
> + */
> + resultMetadata->addEntry(ANDROID_EDGE_MODE,
> + closeToMin ?
> + (uint8_t)ANDROID_EDGE_MODE_OFF :
> + *entry.data.u8);
> + }
> + }
> +
> if (metadata.contains(controls::ScalerCrop)) {
> Rectangle crop = metadata.get(controls::ScalerCrop);
> int32_t cropRect[] = {
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list