From patchwork Mon Aug 23 09:48:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 13428 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 CEDB0BD87C for ; Mon, 23 Aug 2021 09:48:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 43B3E68892; Mon, 23 Aug 2021 11:48:28 +0200 (CEST) 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="kuv+WlJb"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CFAC368891 for ; Mon, 23 Aug 2021 11:48:26 +0200 (CEST) Received: from pyrite.rasen.tech (unknown [IPv6:2400:4051:61:600:2c71:1b79:d06d:5032]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6D3A12A5; Mon, 23 Aug 2021 11:48:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1629712106; bh=T1aDOoZV/8oWJxhhuIl8juyH8+ijvz9Zbyw6QB7UN+4=; h=From:To:Cc:Subject:Date:From; b=kuv+WlJbalmdoX/MTxqGptszJ11C6cViYzVha+Z5GcgPC8It0nVseftZjJqtPC4aT BDbT9NFttrlaBaI9fP+Z0X2Bu36ZV/mqjyWQhwghjy5h9s5lYDZHX+D5DVhuwNgd97 K6X2Kb1O9YokcQJ1ORuSjc+hBvVhuCuuycwXd3zs= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Mon, 23 Aug 2021 18:48:05 +0900 Message-Id: <20210823094806.1434280-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 1/2] 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. Bug: https://bugs.libcamera.org/show_bug.cgi?id=46 Signed-off-by: Paul Elder --- 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; + } + /* * \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); + + 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. */ /* @@ -1330,6 +1351,9 @@ std::unique_ptr 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 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 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 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 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); + } + } + 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 max = info->second.max().get(); + 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[] = { From patchwork Mon Aug 23 09:48:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 13429 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 0B24BBD87C for ; Mon, 23 Aug 2021 09:48:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B03B0688A6; Mon, 23 Aug 2021 11:48:29 +0200 (CEST) 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="NouPLg0g"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9C5AD68893 for ; Mon, 23 Aug 2021 11:48:28 +0200 (CEST) Received: from pyrite.rasen.tech (unknown [IPv6:2400:4051:61:600:2c71:1b79:d06d:5032]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 191162A5; Mon, 23 Aug 2021 11:48:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1629712108; bh=TBdp+o6eQGxSdHS8ni1qZ3t8FCanEs9PcsOC7AbI4ng=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NouPLg0gPpgC16+61sMxJ29JtOirEAe6vk3gBmsiaPrrHaPWqN1VT4lNg2+DeynEQ KhEl7Fr+U5Td0UPk7J7aGVRfdagVnlOFVMrUJQlhj+wDTjvHu6a6GlR/yD6OOQ8sjN vRk9VsMYdItsjpjj2KRT6jLKzYpXBDtbDuV9YfWU= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Mon, 23 Aug 2021 18:48:06 +0900 Message-Id: <20210823094806.1434280-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210823094806.1434280-1-paul.elder@ideasonboard.com> References: <20210823094806.1434280-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 2/2] DNI: pipeline: ipu3: Set Sharpness control and control info 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" This is to demonstrate reporting and setting Sharpness on ipu3. Signed-off-by: Paul Elder --- src/libcamera/pipeline/ipu3/ipu3.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index a98d7eff..e90659e3 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -50,6 +50,7 @@ static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32; static constexpr Size IPU3ViewfinderSize(1280, 720); static const ControlInfoMap::Map IPU3Controls = { + { &controls::Sharpness, ControlInfo(0.0f, 1.0f, 0.0f) }, { &controls::draft::PipelineDepth, ControlInfo(2, 3) }, }; @@ -1299,6 +1300,12 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) cropRegion_ = request->controls().get(controls::ScalerCrop); request->metadata().set(controls::ScalerCrop, cropRegion_); + /* \todo Actually apply sharpness. */ + if (request->controls().contains(controls::Sharpness)) { + float val = request->controls().get(controls::Sharpness); + request->metadata().set(controls::Sharpness, val); + } + if (frameInfos_.tryComplete(info)) pipe()->completeRequest(request); }