From patchwork Wed Oct 29 17:24:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24900 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 5B6FCC3259 for ; Wed, 29 Oct 2025 17:25:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 025DB608F3; Wed, 29 Oct 2025 18:25:08 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="LPUlsNDC"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5B2B8608BF for ; Wed, 29 Oct 2025 18:24:49 +0100 (CET) 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 01AF64FB7; Wed, 29 Oct 2025 18:22:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761758580; bh=l966tlqAt5TcMyFfQ13zq22CqD1lNDZDBsQfPsUjJa4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LPUlsNDCX30I99OUQPVzEt/CslsIwmPIdkE+ikbc7loNo9Z5rXwyY3KvBdPSbaO0e yZSvU5L5BOH84JeBWmuO98uuEyRLmOooBW5aKcrFP7gsYwXFNyq+9B4h6w7snPeugP CTaZ+N/zjFZXVHAhQ+nx1riEZFxK01eVBK/l6YP0= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH v2 12/13] ipa: rkisp1: cproc: Provide a Hue control Date: Wed, 29 Oct 2025 17:24:37 +0000 Message-ID: <20251029172439.1513907-13-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251029172439.1513907-1-kieran.bingham@ideasonboard.com> References: <20251029172439.1513907-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 according to the datasheet however the type itself would imply that this is a range between -90 and 89.2969. 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 | 18 ++++++++++++++++++ src/ipa/rkisp1/ipa_context.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp index 7475e6c1b609..5389882c1685 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; } /* namespace */ @@ -53,6 +54,8 @@ 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(HueQ::TraitsType::min, + HueQ::TraitsType::max, kDefaultHue); cmap[&controls::Saturation] = ControlInfo(0.0f, 1.993f, kDefaultSaturation); return 0; @@ -68,6 +71,7 @@ int ColorProcessing::configure(IPAContext &context, cproc.brightness = BrightnessQ(kDefaultBrightness); cproc.contrast = ContrastQ(kDefaultContrast); + cproc.hue = HueQ(kDefaultHue); cproc.saturation = SaturationQ(kDefaultSaturation); return 0; @@ -109,6 +113,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; @@ -122,6 +137,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; } @@ -142,6 +158,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(); } @@ -154,6 +171,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 0a5fb2769d31..a4badbfc0c36 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -37,6 +37,7 @@ namespace ipa::rkisp1 { /* Fixed point types used by CPROC */ using BrightnessQ = Q1_7; using ContrastQ = UQ1_7; +using HueQ = Quantized>; using SaturationQ = UQ1_7; struct IPAHwSettings { @@ -124,6 +125,7 @@ struct IPAActiveState { struct { BrightnessQ brightness; ContrastQ contrast; + HueQ hue; SaturationQ saturation; } cproc; @@ -178,6 +180,7 @@ struct IPAFrameContext : public FrameContext { struct { BrightnessQ brightness; ContrastQ contrast; + HueQ hue; SaturationQ saturation; bool update;