From patchwork Wed Mar 19 16:11:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22988 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 39C7FC32FE for ; Wed, 19 Mar 2025 16:12:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E643168966; Wed, 19 Mar 2025 17:12:28 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BiCOAwWQ"; 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 12EE668962 for ; Wed, 19 Mar 2025 17:12:27 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:760:e5ca:4814:99c7]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2726E55A; Wed, 19 Mar 2025 17:10:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1742400644; bh=7yqQmpCCDzAK3bhr7VJjJZpMNjdv/M+Z6prXZurl3NY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BiCOAwWQj1mXbkFfHuWH07j+oJ6Hzkpc0Ktq1pmZZQ6wP/+gN0LLV3T2YuMpe0KP5 u1BGP9lkKLjUooTg9rMYp8WTcHgMJenzf+Ybp0QSO40n6/p5G7mQw54AZlcvlZuQnl +D0yJMLjePkGUedojvqWomZ88l4h2lqLvuR0s894= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v2 10/17] ipa: rkisp1: ccm/lsc: Fix CCM/LSC based on manual color temperature Date: Wed, 19 Mar 2025 17:11:15 +0100 Message-ID: <20250319161152.63625-11-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250319161152.63625-1-stefan.klug@ideasonboard.com> References: <20250319161152.63625-1-stefan.klug@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" In RkISP1Awb::process(), the color temperature in the active state is updated every time new statistics are available. The CCM/LSC algorithms use that value in prepare() to update the CCM/LSC. This is not correct if the color temperature was specified manually and leads to visible flicker even when AwbEnable is set to false. To fix that, track the auto and manual color temperature separately in active state. In Awb::prepare() the current frame context is updated with the corresponding value from active state. Change the algorithms to fetch the color temperature from the frame context instead of the active state in prepare(). Fixes: 02308809548d ("ipa: rkisp1: awb: Implement ColourTemperature control") Signed-off-by: Stefan Klug --- Changes in v2: - None --- src/ipa/rkisp1/algorithms/awb.cpp | 18 ++++++++++-------- src/ipa/rkisp1/algorithms/ccm.cpp | 2 +- src/ipa/rkisp1/algorithms/lsc.cpp | 6 +++--- src/ipa/rkisp1/ipa_context.h | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index a9759e53f593..5e067e50cd52 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -128,7 +128,8 @@ int Awb::configure(IPAContext &context, context.activeState.awb.automatic.gains = awbAlgo_->gainsFromColourTemperature(kDefaultColourTemperature); context.activeState.awb.autoEnabled = true; - context.activeState.awb.temperatureK = kDefaultColourTemperature; + context.activeState.awb.manual.temperatureK = kDefaultColourTemperature; + context.activeState.awb.automatic.temperatureK = kDefaultColourTemperature; /* * Define the measurement window for AWB as a centered rectangle @@ -185,7 +186,7 @@ void Awb::queueRequest(IPAContext &context, const auto &gains = awbAlgo_->gainsFromColourTemperature(*colourTemperature); awb.manual.gains.r() = gains.r(); awb.manual.gains.b() = gains.b(); - awb.temperatureK = *colourTemperature; + awb.manual.temperatureK = *colourTemperature; update = true; } @@ -194,7 +195,7 @@ void Awb::queueRequest(IPAContext &context, << "Set colour gains to " << awb.manual.gains; frameContext.awb.gains = awb.manual.gains; - frameContext.awb.temperatureK = awb.temperatureK; + frameContext.awb.temperatureK = awb.manual.temperatureK; } /** @@ -208,8 +209,9 @@ void Awb::prepare(IPAContext &context, const uint32_t frame, * most up-to-date automatic values we can read. */ if (frameContext.awb.autoEnabled) { - frameContext.awb.gains = context.activeState.awb.automatic.gains; - frameContext.awb.temperatureK = context.activeState.awb.temperatureK; + auto &awb = context.activeState.awb; + frameContext.awb.gains = awb.automatic.gains; + frameContext.awb.temperatureK = awb.automatic.temperatureK; } auto gainConfig = params->block(); @@ -309,10 +311,10 @@ void Awb::process(IPAContext &context, RkISP1AwbStats awbStats{ rgbMeans }; AwbResult awbResult = awbAlgo_->calculateAwb(awbStats, frameContext.lux.lux); - activeState.awb.temperatureK = awbResult.colourTemperature; + activeState.awb.automatic.temperatureK = awbResult.colourTemperature; /* Metadata shall contain the up to date measurement */ - metadata.set(controls::ColourTemperature, activeState.awb.temperatureK); + metadata.set(controls::ColourTemperature, activeState.awb.automatic.temperatureK); /* * Clamp the gain values to the hardware, which expresses gains as Q2.8 @@ -333,7 +335,7 @@ void Awb::process(IPAContext &context, << std::showpoint << "Means " << rgbMeans << ", gains " << activeState.awb.automatic.gains << ", temp " - << activeState.awb.temperatureK << "K"; + << activeState.awb.automatic.temperatureK << "K"; } RGB Awb::calculateRgbMeans(const IPAFrameContext &frameContext, const rkisp1_cif_isp_awb_stat *awb) const diff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp index eb8ca39e56a8..2e5e91006b55 100644 --- a/src/ipa/rkisp1/algorithms/ccm.cpp +++ b/src/ipa/rkisp1/algorithms/ccm.cpp @@ -88,7 +88,7 @@ void Ccm::setParameters(struct rkisp1_cif_isp_ctk_config &config, void Ccm::prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, RkISP1Params *params) { - uint32_t ct = context.activeState.awb.temperatureK; + uint32_t ct = frameContext.awb.temperatureK; /* * \todo The colour temperature will likely be noisy, add filtering to diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp index e47aa2f0727e..e7301bfec863 100644 --- a/src/ipa/rkisp1/algorithms/lsc.cpp +++ b/src/ipa/rkisp1/algorithms/lsc.cpp @@ -404,12 +404,12 @@ void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config, /** * \copydoc libcamera::ipa::Algorithm::prepare */ -void LensShadingCorrection::prepare(IPAContext &context, +void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context, [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] IPAFrameContext &frameContext, + IPAFrameContext &frameContext, RkISP1Params *params) { - uint32_t ct = context.activeState.awb.temperatureK; + uint32_t ct = frameContext.awb.temperatureK; if (std::abs(static_cast(ct) - static_cast(lastAppliedCt_)) < kColourTemperatureChangeThreshhold) return; diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 6bc922a82971..769e9f114e23 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -91,12 +91,12 @@ struct IPAActiveState { struct { struct AwbState { RGB gains; + unsigned int temperatureK; }; AwbState manual; AwbState automatic; - unsigned int temperatureK; bool autoEnabled; } awb;