From patchwork Sun Oct 26 23:30:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24829 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 720A2BE080 for ; Sun, 26 Oct 2025 23:31:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CD9C160751; Mon, 27 Oct 2025 00:31:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HbQxr1i3"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2BCE1606F8 for ; Mon, 27 Oct 2025 00:30:55 +0100 (CET) Received: from charm.hippo-penny.ts.net (unknown [209.38.108.23]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B8A69177B; Mon, 27 Oct 2025 00:29:07 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761521347; bh=KP+YWnztm0c8cLSMzDHVFJJYgv58QJA33dIgfbcoYJI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HbQxr1i34M5giUy2XfueB8dZJvHQHpkeoHEwLQyH0Z222fUKQGxrS5pKSgoTOG1YV 7h+QPWLWUbVXJNvj3uc81F/3XOO3UU6RXnqnOTSOeyNokU53zceJzMmzDKATwct1qD VpSYiFnqVI6KQCxsvJH4436i2ISAKO1atdKQBuMw= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH 6/6] ipa: rkisp1: cproc: Provide a Hue control Date: Sun, 26 Oct 2025 23:30:43 +0000 Message-ID: <20251026233048.175689-7-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251026233048.175689-1-kieran.bingham@ideasonboard.com> References: <20251026233048.175689-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" 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: Kieran Bingham --- src/ipa/rkisp1/algorithms/cproc.cpp | 38 +++++++++++++++++++++++++++++ src/ipa/rkisp1/ipa_context.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp index d19d808cce4d..a92bf05131ba 100644 --- a/src/ipa/rkisp1/algorithms/cproc.cpp +++ b/src/ipa/rkisp1/algorithms/cproc.cpp @@ -39,6 +39,7 @@ namespace { constexpr float kDefaultBrightness = 0.0f; constexpr float kDefaultContrast = 1.0f; +constexpr float kDefaultHue = 0.0f; constexpr float kDefaultSaturation = 1.0f; class BrightnessQ : public Quantizer @@ -59,6 +60,27 @@ public: } }; +class HueQ : public Quantizer +{ +public: + HueQ(float val) { set(val); } + HueQ(int8_t val) { set(val); } + + static constexpr float MaxDegrees = 90; + static constexpr float q = 128.0f / MaxDegrees; + + int8_t fromFloat(float v) const override + { + int quantized = std::lround(v * q); + return static_cast(std::clamp(quantized, -128, 127)); + } + + float toFloat(int8_t v) const override + { + return static_cast(v) / q; + } +}; + class ContrastSaturationQuantizer : public Quantizer { public: @@ -92,6 +114,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(-90.0f, 90.0f, kDefaultHue); cmap[&controls::Saturation] = ControlInfo(0.0f, 1.993f, kDefaultSaturation); return 0; @@ -107,6 +130,7 @@ int ColorProcessing::configure(IPAContext &context, cproc.brightness = BrightnessQ(kDefaultBrightness); cproc.contrast = ContrastQ(kDefaultContrast); + cproc.hue = HueQ(kDefaultHue); cproc.saturation = SaturationQ(kDefaultSaturation); return 0; @@ -148,6 +172,17 @@ void ColorProcessing::queueRequest(IPAContext &context, LOG(RkISP1CProc, Debug) << "Set contrast to " << value.value(); } + const auto &hue = controls.get(controls::Hue); + if (hue) { + HueQ value = *hue; + if (cproc.hue != value) { + cproc.hue = value; + update = true; + } + + LOG(RkISP1CProc, Debug) << "Set hue to " << value.value(); + } + const auto saturation = controls.get(controls::Saturation); if (saturation) { SaturationQ value = *saturation; @@ -161,6 +196,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; } @@ -181,6 +217,7 @@ void ColorProcessing::prepare([[maybe_unused]] IPAContext &context, config.setEnabled(true); config->brightness = frameContext.cproc.brightness.quantized(); config->contrast = frameContext.cproc.contrast.quantized(); + config->hue = frameContext.cproc.hue.quantized(); config->sat = frameContext.cproc.saturation.quantized(); } @@ -193,6 +230,7 @@ void ColorProcessing::process([[maybe_unused]] IPAContext &context, [[maybe_unus { metadata.set(controls::Brightness, frameContext.cproc.brightness.value()); metadata.set(controls::Contrast, frameContext.cproc.contrast.value()); + metadata.set(controls::Hue, frameContext.cproc.hue.value()); metadata.set(controls::Saturation, frameContext.cproc.saturation.value()); } diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index b7cdfc36b275..51281e7f7b82 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -118,6 +118,7 @@ struct IPAActiveState { struct { Quantized brightness; Quantized contrast; + Quantized hue; Quantized saturation; } cproc; @@ -172,6 +173,7 @@ struct IPAFrameContext : public FrameContext { struct { Quantized brightness; Quantized contrast; + Quantized hue; Quantized saturation; bool update; } cproc;