From patchwork Tue Dec 21 04:41:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 15187 X-Patchwork-Delegate: paul.elder@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id C08C3BF415 for ; Tue, 21 Dec 2021 04:41:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0D9BC608E8; Tue, 21 Dec 2021 05:41:50 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="hNoiv0hb"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 25BEF60868 for ; Tue, 21 Dec 2021 05:41:48 +0100 (CET) Received: from pyrite.mediacom.info (unknown [IPv6:2604:2d80:ad90:fb00:96fd:8874:873:6c16]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1215C881; Tue, 21 Dec 2021 05:41:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1640061707; bh=dF5Ts4fNytawe+OCmosRrIEnz6dEkyhneK4SITwvzg8=; h=From:To:Cc:Subject:Date:From; b=hNoiv0hbZJwbgdwaQX8RC+JxMGcHLeddJgCp6/cZtf/BD1qK6HJt9xh9ChjmzJWfG O39pYFAT14dsfQOCWB+0OxkZcQAdkEtvVg7aTIiKMHOB5YchqaaB5Wz6sVJkkaBsgn MRyM6jeWQ+Y01bv7ZYwDph+OdI0GbYrP3rTFIaso= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Dec 2021 22:41:33 -0600 Message-Id: <20211221044133.2531278-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2] android: Plumb Sharpness control into EDGE_MODE X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Plumb the Sharpness control into the HAL for EDGE_MODE and other related android controls. libcamera doesn't distinguish between fast and HQ, but rather with a floating value for how much sharpening to apply. This is thus unsufficient information for retaining whether the request was for fast or HQ, so save it in the request, and report what was requested. Bug: https://bugs.libcamera.org/show_bug.cgi?id=46 Signed-off-by: Paul Elder Reviewed-by: Kieran Bingham --- This patch depends on "android: camera_metadata: Add appendEntry helper" Changes in v2: - fix the assertions in template creation - report the edge mode that was requested, instead of doing conversion to and from the floating value and its ControlInfo - move edge mode capability check out of manual control (as docs say it's not required) and into the top-level FULL hardware level validator --- src/android/camera_capabilities.cpp | 44 +++++++++++++++++++++++++++++ src/android/camera_device.cpp | 28 ++++++++++++++++++ src/android/camera_request.h | 4 +++ 3 files changed, 76 insertions(+) diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp index b9a1f6e5..727204b9 100644 --- a/src/android/camera_capabilities.cpp +++ b/src/android/camera_capabilities.cpp @@ -401,6 +401,11 @@ void CameraCapabilities::computeHwLevel( if (!caps.count(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE)) hwLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED; + if (!staticMetadata_->hasEntry(ANDROID_EDGE_AVAILABLE_EDGE_MODES)) { + LOG(HAL, Info) << noFull << "missing edge modes"; + hwLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED; + } + found = staticMetadata_->getEntry(ANDROID_SYNC_MAX_LATENCY, &entry); if (!found || *entry.data.i32 != 0) { LOG(HAL, Info) << noFull << "missing or invalid max sync latency"; @@ -1078,6 +1083,21 @@ int CameraCapabilities::initializeStaticMetadata() staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES, availableControlModes); + const auto &edgeInfo = controlsInfo.find(&controls::Sharpness); + if (edgeInfo != controlsInfo.end()) { + std::vector 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. */ /* @@ -1593,6 +1613,12 @@ std::unique_ptr CameraCapabilities::requestTemplateManual() cons manualTemplate->appendEntry(ANDROID_CONTROL_AE_MODE, aeMode); } + if (staticMetadata_->entryContains(ANDROID_EDGE_AVAILABLE_EDGE_MODES, + ANDROID_EDGE_MODE_OFF)) { + uint8_t edgeMode = ANDROID_EDGE_MODE_OFF; + manualTemplate->appendEntry(ANDROID_EDGE_MODE, edgeMode); + } + return manualTemplate; } @@ -1675,6 +1701,12 @@ std::unique_ptr CameraCapabilities::requestTemplatePreview() con if (availableRequestKeys_.count(ANDROID_SENSOR_SENSITIVITY)) requestTemplate->addEntry(ANDROID_SENSOR_SENSITIVITY, minISO_); + if (staticMetadata_->entryContains(ANDROID_EDGE_AVAILABLE_EDGE_MODES, + ANDROID_EDGE_MODE_FAST)) { + uint8_t edgeMode = ANDROID_EDGE_MODE_FAST; + requestTemplate->addEntry(ANDROID_EDGE_MODE, edgeMode); + } + uint8_t flashMode = ANDROID_FLASH_MODE_OFF; requestTemplate->addEntry(ANDROID_FLASH_MODE, flashMode); @@ -1713,6 +1745,12 @@ std::unique_ptr CameraCapabilities::requestTemplateStill() const if (!stillTemplate) return nullptr; + if (staticMetadata_->entryContains(ANDROID_EDGE_AVAILABLE_EDGE_MODES, + ANDROID_EDGE_MODE_HIGH_QUALITY)) { + uint8_t edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY; + stillTemplate->appendEntry(ANDROID_EDGE_MODE, edgeMode); + } + return stillTemplate; } @@ -1730,6 +1768,12 @@ std::unique_ptr CameraCapabilities::requestTemplateVideo() const staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, &entry); + if (staticMetadata_->entryContains(ANDROID_EDGE_AVAILABLE_EDGE_MODES, + ANDROID_EDGE_MODE_FAST)) { + uint8_t edgeMode = ANDROID_EDGE_MODE_FAST; + previewTemplate->appendEntry(ANDROID_EDGE_MODE, edgeMode); + } + /* * 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 1a508923..0d668ea6 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -920,6 +920,26 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor) controls.set(controls::DigitalGain, lastDigitalGain_); } + 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 def = info->second.def().get(); + float max = info->second.max().get(); + /* + * The default value might be unusable since control + * serialization ignores it. Alternatively the default + * 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); + + descriptor->edgeMode_ = *entry.data.u8; + } + } + return 0; } @@ -1602,6 +1622,14 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons duration); } + if (metadata.contains(controls::Sharpness)) { + /* + * libcamera doesn't distinguish between fast vs HQ sharpening + * modes. Report the mode that was requested. + */ + resultMetadata->addEntry(ANDROID_EDGE_MODE, descriptor.edgeMode_); + } + if (metadata.contains(controls::ScalerCrop)) { Rectangle crop = metadata.get(controls::ScalerCrop); int32_t cropRect[] = { diff --git a/src/android/camera_request.h b/src/android/camera_request.h index b2809179..69b6c8fc 100644 --- a/src/android/camera_request.h +++ b/src/android/camera_request.h @@ -87,6 +87,10 @@ public: /* The libcamera internal AE state for this request */ AutoMode aeMode_ = AutoMode::Auto; + /* The android edge mode associated with this request */ + /* \todo Wrap all such controls? */ + int32_t edgeMode_; + private: LIBCAMERA_DISABLE_COPY(Camera3RequestDescriptor) };