From patchwork Tue Jun 24 17:12:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 23645 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 2ED58C3237 for ; Tue, 24 Jun 2025 17:12:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AF75668DEF; Tue, 24 Jun 2025 19:12:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tADlDAr+"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6B91468DDD for ; Tue, 24 Jun 2025 19:12:27 +0200 (CEST) Received: from Monstersaurus.hippo-penny.ts.net (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A79383D5; Tue, 24 Jun 2025 19:12:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1750785129; bh=4h/zOOYNTmEk+ptkmff2Xq2AtxC5eI7iSZg4FPiZPfU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tADlDAr+9Q9DJI42LYAP9Af+dT0W6PaUyzjOIyN5LYg2hkw3Odp23ss1un8gntZum fjSNvJzeLhMJ3eoe+ex5vc7FBv/2EtOWO6QuWTTLyQM7YUfhUVMcuKc8QU5YWloEpp P+9VD2nqM1X+mq+3mcYSzUiNZZ7c8eXZBmC66+00= From: Kieran Bingham To: libcamera devel Cc: "van Veen, Stephan" , "Zenker, Sebastian" , Kieran Bingham Subject: [PATCH 1/3] ipa: rkisp1: cproc: Report metadata Date: Tue, 24 Jun 2025 18:12:21 +0100 Message-ID: <20250624171223.2181226-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250624171223.2181226-1-kieran.bingham@ideasonboard.com> References: <20250624171223.2181226-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 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" From: "van Veen, Stephan" Presently the colour processing component exposes controls for brightness, saturation, and contrast to the applications which are handled and processed accordingly on the ISP. The implementation lacks reporting the values that are set back to the application. Provide the inverse conversion functions to convert the values applied and report them in the completed request metadata. Signed-off-by: van Veen, Stephan Signed-off-by: Zenker, Sebastian [Kieran: Refactor commit message, fix checkstyle warnings] Signed-off-by: Kieran Bingham --- src/ipa/rkisp1/algorithms/cproc.cpp | 22 ++++++++++++++++++++++ src/ipa/rkisp1/algorithms/cproc.h | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp index d1fff6990d37..9213ee49b374 100644 --- a/src/ipa/rkisp1/algorithms/cproc.cpp +++ b/src/ipa/rkisp1/algorithms/cproc.cpp @@ -44,11 +44,21 @@ int convertBrightness(const float v) return std::clamp(std::lround(v * 128), -128, 127); } +float convertBrightness(const int v) +{ + return static_cast(v) / 128.0f; +} + int convertContrastOrSaturation(const float v) { return std::clamp(std::lround(v * 128), 0, 255); } +float convertContrastOrSaturation(const int v) +{ + return static_cast(v) / 128.0f; +} + } /* namespace */ /** @@ -153,6 +163,18 @@ void ColorProcessing::prepare([[maybe_unused]] IPAContext &context, config->sat = frameContext.cproc.saturation; } +/** + * \copydoc libcamera::ipa::Algorithm::process + */ +void ColorProcessing::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, [[maybe_unused]] const rkisp1_stat_buffer *stats, + ControlList &metadata) +{ + metadata.set(controls::Brightness, convertBrightness(frameContext.cproc.brightness)); + metadata.set(controls::Contrast, convertContrastOrSaturation(frameContext.cproc.contrast)); + metadata.set(controls::Saturation, convertContrastOrSaturation(frameContext.cproc.saturation)); +} + REGISTER_IPA_ALGORITHM(ColorProcessing, "ColorProcessing") } /* namespace ipa::rkisp1::algorithms */ diff --git a/src/ipa/rkisp1/algorithms/cproc.h b/src/ipa/rkisp1/algorithms/cproc.h index fd38fd17e8bb..9b589ebd4ad7 100644 --- a/src/ipa/rkisp1/algorithms/cproc.h +++ b/src/ipa/rkisp1/algorithms/cproc.h @@ -30,6 +30,10 @@ public: void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, RkISP1Params *params) override; + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const rkisp1_stat_buffer *stats, + ControlList &metadata) override; }; } /* namespace ipa::rkisp1::algorithms */ From patchwork Tue Jun 24 17:12:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 23646 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 B535AC3237 for ; Tue, 24 Jun 2025 17:12:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8CCE268DF7; Tue, 24 Jun 2025 19:12:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="qz5e6Rcq"; 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 9E83C61536 for ; Tue, 24 Jun 2025 19:12:27 +0200 (CEST) Received: from Monstersaurus.hippo-penny.ts.net (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EA7B26A6; Tue, 24 Jun 2025 19:12:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1750785130; bh=ruvTkwLj/SkKTC/SNrMWgEW7H/eoXPodGYY3DLlb97k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qz5e6RcqqrLclJ7NshBOlhxx1BIIJXG1UEXsRmAGabwShjtYozln7ib0RcPCe1sV9 RRtmuLzwVz9K2LR61A4iEK4E0mFQa8g/QFP/+alnTvPjbO/OFjEXn6Rp7E4r//iu1U 3aont+qMO4RZ5tjOWRAfjw+rSNxo2N1yy8aCl0iE= From: Kieran Bingham To: libcamera devel Cc: "van Veen, Stephan" , Kieran Bingham Subject: [PATCH 2/3] libcamera: controls: Define a new core Hue control Date: Tue, 24 Jun 2025 18:12:22 +0100 Message-ID: <20250624171223.2181226-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250624171223.2181226-1-kieran.bingham@ideasonboard.com> References: <20250624171223.2181226-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 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" From: "van Veen, Stephan" Define a new control to support configuration of Hue adjustments when supported by the available platform. Signed-off-by: van Veen, Stephan [Kieran: Split control addition and implementation and refactor commit messages] Signed-off-by: Kieran Bingham --- Open questions How should we standardise the units on this control? Should this be a scale of -1, 0, +1 and scaled to the capability of the hardware by the IPA? Or should we standardise on similar units from a colour wheel and use values in degrees (for RKISP1 use case this would be -90,0,+87.188). As the RKISP1 makes a phase shift adjustment, is this expected to be similar on other pipelines? Or should we also expect anything that would expose a full 360 degree explicit hue? (I assume not now I write that :D) Signed-off-by: Kieran Bingham --- src/libcamera/control_ids_core.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml index 028919ef3d3e..58abf8434eae 100644 --- a/src/libcamera/control_ids_core.yaml +++ b/src/libcamera/control_ids_core.yaml @@ -1281,4 +1281,14 @@ controls: The FrameWallClock control can only be returned in metadata. + - Hue: + type: float + direction: inout + description: | + Specify a fixed hue parameter. + + Positive values (up to 1.0) produce an increase of the hue angle up to + 90 degrees; negative values (up to -1.0) produce a decrease of the hue + angle down to -90 degrees. + ... From patchwork Tue Jun 24 17:12:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 23647 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 E8CE8C3237 for ; Tue, 24 Jun 2025 17:12:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5DC2B68DEC; Tue, 24 Jun 2025 19:12:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="keClc7JD"; 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 B6E8768DE6 for ; Tue, 24 Jun 2025 19:12:27 +0200 (CEST) Received: from Monstersaurus.hippo-penny.ts.net (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 347D9134A; Tue, 24 Jun 2025 19:12:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1750785130; bh=6g3S9fjkjcq7fIKKMWKaZbPmvsHirjBCKluUsFM+Abw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=keClc7JDLIowTwqzCbvkCVEiG5Geo0zNRBdU/KJasWztWKE2hj9CtwRPKZjqlvWzk BP+1J1CPL7cTLCvc5R9KbNw1GW3lkd61lCf+Cm9OQgg5ZSZ/vGdbrDF6rsujytUaXC PnR1qmUILzdtN3kRkIImzZBBOJC88BId8sr4TiGY= From: Kieran Bingham To: libcamera devel Cc: "van Veen, Stephan" , Kieran Bingham Subject: [PATCH 3/3] ipa: rkisp1: cproc: Provide a Hue control Date: Tue, 24 Jun 2025 18:12:23 +0100 Message-ID: <20250624171223.2181226-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250624171223.2181226-1-kieran.bingham@ideasonboard.com> References: <20250624171223.2181226-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 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" From: "van Veen, Stephan" The RKISP1 supports a configurable Hue as part of the colour processing unit (cproc). This is implemented as a phase shift of the chrominance values between -90 and +87.188 degrees. Implement the new control converting to the hardware scale accordingly and report the applied control in the completed request metadata. Signed-off-by: van Veen, Stephan Signed-off-by: Kieran Bingham --- src/ipa/rkisp1/algorithms/cproc.cpp | 31 ++++++++++++++++++++++------- src/ipa/rkisp1/ipa_context.h | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp index 9213ee49b374..217c1ee2b039 100644 --- a/src/ipa/rkisp1/algorithms/cproc.cpp +++ b/src/ipa/rkisp1/algorithms/cproc.cpp @@ -27,8 +27,8 @@ namespace ipa::rkisp1::algorithms { * \brief RkISP1 Color Processing control * * The ColorProcessing algorithm is responsible for applying brightness, - * contrast and saturation corrections. The values are directly provided - * through requests by the corresponding controls. + * contrast, hue and saturation corrections. The values are directly + * provided through requests by the corresponding controls. */ LOG_DEFINE_CATEGORY(RkISP1CProc) @@ -37,14 +37,15 @@ namespace { constexpr float kDefaultBrightness = 0.0f; constexpr float kDefaultContrast = 1.0f; +constexpr float kDefaultHue = 0.0f; constexpr float kDefaultSaturation = 1.0f; -int convertBrightness(const float v) +int convertBrightnessOrHue(const float v) { return std::clamp(std::lround(v * 128), -128, 127); } -float convertBrightness(const int v) +float convertBrightnessOrHue(const int v) { return static_cast(v) / 128.0f; } @@ -71,6 +72,7 @@ int ColorProcessing::init(IPAContext &context, cmap[&controls::Brightness] = ControlInfo(-1.0f, 0.993f, kDefaultBrightness); cmap[&controls::Contrast] = ControlInfo(0.0f, 1.993f, kDefaultContrast); + cmap[&controls::Hue] = ControlInfo(-1.0f, 0.993f, kDefaultHue); cmap[&controls::Saturation] = ControlInfo(0.0f, 1.993f, kDefaultSaturation); return 0; @@ -84,8 +86,9 @@ int ColorProcessing::configure(IPAContext &context, { auto &cproc = context.activeState.cproc; - cproc.brightness = convertBrightness(kDefaultBrightness); + cproc.brightness = convertBrightnessOrHue(kDefaultBrightness); cproc.contrast = convertContrastOrSaturation(kDefaultContrast); + cproc.hue = convertBrightnessOrHue(kDefaultHue); cproc.saturation = convertContrastOrSaturation(kDefaultSaturation); return 0; @@ -107,7 +110,7 @@ void ColorProcessing::queueRequest(IPAContext &context, const auto &brightness = controls.get(controls::Brightness); if (brightness) { - int value = convertBrightness(*brightness); + int value = convertBrightnessOrHue(*brightness); if (cproc.brightness != value) { cproc.brightness = value; update = true; @@ -127,6 +130,17 @@ void ColorProcessing::queueRequest(IPAContext &context, LOG(RkISP1CProc, Debug) << "Set contrast to " << value; } + const auto &hue = controls.get(controls::Hue); + if (hue) { + int value = convertBrightnessOrHue(*hue); + if (cproc.hue != value) { + cproc.hue = value; + update = true; + } + + LOG(RkISP1CProc, Debug) << "Set hue to " << value; + } + const auto saturation = controls.get(controls::Saturation); if (saturation) { int value = convertContrastOrSaturation(*saturation); @@ -140,6 +154,7 @@ void ColorProcessing::queueRequest(IPAContext &context, frameContext.cproc.brightness = cproc.brightness; frameContext.cproc.contrast = cproc.contrast; + frameContext.cproc.hue = cproc.hue; frameContext.cproc.saturation = cproc.saturation; frameContext.cproc.update = update; } @@ -160,6 +175,7 @@ void ColorProcessing::prepare([[maybe_unused]] IPAContext &context, config.setEnabled(true); config->brightness = frameContext.cproc.brightness; config->contrast = frameContext.cproc.contrast; + config->hue = frameContext.cproc.hue; config->sat = frameContext.cproc.saturation; } @@ -170,8 +186,9 @@ void ColorProcessing::process([[maybe_unused]] IPAContext &context, [[maybe_unus IPAFrameContext &frameContext, [[maybe_unused]] const rkisp1_stat_buffer *stats, ControlList &metadata) { - metadata.set(controls::Brightness, convertBrightness(frameContext.cproc.brightness)); + metadata.set(controls::Brightness, convertBrightnessOrHue(frameContext.cproc.brightness)); metadata.set(controls::Contrast, convertContrastOrSaturation(frameContext.cproc.contrast)); + metadata.set(controls::Hue, convertBrightnessOrHue(frameContext.cproc.hue)); metadata.set(controls::Saturation, convertContrastOrSaturation(frameContext.cproc.saturation)); } diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index f0d504215d34..54234ea3acc4 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -108,6 +108,7 @@ struct IPAActiveState { struct { int8_t brightness; uint8_t contrast; + int8_t hue; uint8_t saturation; } cproc; @@ -152,6 +153,7 @@ struct IPAFrameContext : public FrameContext { struct { int8_t brightness; uint8_t contrast; + int8_t hue; uint8_t saturation; bool update; } cproc;