{"id":23127,"url":"https://patchwork.libcamera.org/api/patches/23127/?format=json","web_url":"https://patchwork.libcamera.org/patch/23127/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20250403154925.382973-12-stefan.klug@ideasonboard.com>","date":"2025-04-03T15:49:16","name":"[v3,11/16] ipa: rkisp1: ccm/lsc: Fix CCM/LSC based on manual color temperature","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"161b48c17959f45dc89d5e854041c0f892050087","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/?format=json","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/23127/mbox/","series":[{"id":5111,"url":"https://patchwork.libcamera.org/api/series/5111/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5111","date":"2025-04-03T15:49:05","name":"Some rkisp1 awb improvements","version":3,"mbox":"https://patchwork.libcamera.org/series/5111/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/23127/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/23127/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 2A178C327D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  3 Apr 2025 15:50:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D5A6F68AA8;\n\tThu,  3 Apr 2025 17:50:08 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 062D368A9D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  3 Apr 2025 17:50:08 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:6d9d:9854:3fc1:4bb2])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 58DF511E9;\n\tThu,  3 Apr 2025 17:48:14 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"mne3UvtY\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1743695294;\n\tbh=afdwa1VAMc7wsQSQhj/okcIeAZ3l+Zxq+xMthG3B45U=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=mne3UvtY5mNqIuPFaIJSUxuJFlx/Vxg6JHJGSwwObVQxj6WtyOry0+jN/7Rafxmo4\n\tl5G6/uVWEXQZhR6WsLeycAmgGB+CiF54z+yx2t9SeHrC7rvoZT76GhlvEB8lIYQ/Qk\n\tGweBMWzFl9n8hr2p210tG1HmuSttDpREsIEArVrc=","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>","Subject":"[PATCH v3 11/16] ipa: rkisp1: ccm/lsc: Fix CCM/LSC based on manual\n\tcolor temperature","Date":"Thu,  3 Apr 2025 17:49:16 +0200","Message-ID":"<20250403154925.382973-12-stefan.klug@ideasonboard.com>","X-Mailer":"git-send-email 2.43.0","In-Reply-To":"<20250403154925.382973-1-stefan.klug@ideasonboard.com>","References":"<20250403154925.382973-1-stefan.klug@ideasonboard.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"In RkISP1Awb::process(), the color temperature in the active state is\nupdated every time new statistics are available.  The CCM/LSC algorithms\nuse that value in prepare() to update the CCM/LSC. This is not correct\nif the color temperature was specified manually and leads to visible\nflicker even when AwbEnable is set to false.\n\nTo fix that, track the auto and manual color temperature separately in\nactive state. In Awb::prepare() the current frame context is updated\nwith the corresponding value from active state. Change the algorithms to\nfetch the color temperature from the frame context instead of the active\nstate in prepare().\n\nFixes: 02308809548d (\"ipa: rkisp1: awb: Implement ColourTemperature control\")\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n\n---\n\nChanges in v2:\n- None\n\nChanges in v3:\n- Move incorrect colour temperature metadata to separate fixup patch\n- Updated documentation\n---\n src/ipa/rkisp1/algorithms/awb.cpp | 16 +++++++++-------\n src/ipa/rkisp1/algorithms/ccm.cpp |  2 +-\n src/ipa/rkisp1/algorithms/lsc.cpp |  6 +++---\n src/ipa/rkisp1/ipa_context.cpp    |  6 +++---\n src/ipa/rkisp1/ipa_context.h      |  2 +-\n 5 files changed, 17 insertions(+), 15 deletions(-)","diff":"diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp\nindex 79c4c658406d..0795b8e5b1e1 100644\n--- a/src/ipa/rkisp1/algorithms/awb.cpp\n+++ b/src/ipa/rkisp1/algorithms/awb.cpp\n@@ -128,7 +128,8 @@ int Awb::configure(IPAContext &context,\n \tcontext.activeState.awb.automatic.gains =\n \t\tawbAlgo_->gainsFromColourTemperature(kDefaultColourTemperature);\n \tcontext.activeState.awb.autoEnabled = true;\n-\tcontext.activeState.awb.temperatureK = kDefaultColourTemperature;\n+\tcontext.activeState.awb.manual.temperatureK = kDefaultColourTemperature;\n+\tcontext.activeState.awb.automatic.temperatureK = kDefaultColourTemperature;\n \n \t/*\n \t * Define the measurement window for AWB as a centered rectangle\n@@ -185,7 +186,7 @@ void Awb::queueRequest(IPAContext &context,\n \t\tconst auto &gains = awbAlgo_->gainsFromColourTemperature(*colourTemperature);\n \t\tawb.manual.gains.r() = gains.r();\n \t\tawb.manual.gains.b() = gains.b();\n-\t\tawb.temperatureK = *colourTemperature;\n+\t\tawb.manual.temperatureK = *colourTemperature;\n \t\tupdate = true;\n \t}\n \n@@ -194,7 +195,7 @@ void Awb::queueRequest(IPAContext &context,\n \t\t\t<< \"Set colour gains to \" << awb.manual.gains;\n \n \tframeContext.awb.gains = awb.manual.gains;\n-\tframeContext.awb.temperatureK = awb.temperatureK;\n+\tframeContext.awb.temperatureK = awb.manual.temperatureK;\n }\n \n /**\n@@ -208,8 +209,9 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,\n \t * most up-to-date automatic values we can read.\n \t */\n \tif (frameContext.awb.autoEnabled) {\n-\t\tframeContext.awb.gains = context.activeState.awb.automatic.gains;\n-\t\tframeContext.awb.temperatureK = context.activeState.awb.temperatureK;\n+\t\tauto &awb = context.activeState.awb;\n+\t\tframeContext.awb.gains = awb.automatic.gains;\n+\t\tframeContext.awb.temperatureK = awb.automatic.temperatureK;\n \t}\n \n \tauto gainConfig = params->block<BlockType::AwbGain>();\n@@ -309,7 +311,7 @@ void Awb::process(IPAContext &context,\n \tRkISP1AwbStats awbStats{ rgbMeans };\n \tAwbResult awbResult = awbAlgo_->calculateAwb(awbStats, frameContext.lux.lux);\n \n-\tactiveState.awb.temperatureK = awbResult.colourTemperature;\n+\tactiveState.awb.automatic.temperatureK = awbResult.colourTemperature;\n \n \t/*\n \t * Clamp the gain values to the hardware, which expresses gains as Q2.8\n@@ -330,7 +332,7 @@ void Awb::process(IPAContext &context,\n \t\t<< std::showpoint\n \t\t<< \"Means \" << rgbMeans << \", gains \"\n \t\t<< activeState.awb.automatic.gains << \", temp \"\n-\t\t<< activeState.awb.temperatureK << \"K\";\n+\t\t<< activeState.awb.automatic.temperatureK << \"K\";\n }\n \n RGB<double> Awb::calculateRgbMeans(const IPAFrameContext &frameContext, const rkisp1_cif_isp_awb_stat *awb) const\ndiff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp\nindex eb8ca39e56a8..2e5e91006b55 100644\n--- a/src/ipa/rkisp1/algorithms/ccm.cpp\n+++ b/src/ipa/rkisp1/algorithms/ccm.cpp\n@@ -88,7 +88,7 @@ void Ccm::setParameters(struct rkisp1_cif_isp_ctk_config &config,\n void Ccm::prepare(IPAContext &context, const uint32_t frame,\n \t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n {\n-\tuint32_t ct = context.activeState.awb.temperatureK;\n+\tuint32_t ct = frameContext.awb.temperatureK;\n \n \t/*\n \t * \\todo The colour temperature will likely be noisy, add filtering to\ndiff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp\nindex e47aa2f0727e..e7301bfec863 100644\n--- a/src/ipa/rkisp1/algorithms/lsc.cpp\n+++ b/src/ipa/rkisp1/algorithms/lsc.cpp\n@@ -404,12 +404,12 @@ void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,\n /**\n  * \\copydoc libcamera::ipa::Algorithm::prepare\n  */\n-void LensShadingCorrection::prepare(IPAContext &context,\n+void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,\n \t\t\t\t    [[maybe_unused]] const uint32_t frame,\n-\t\t\t\t    [[maybe_unused]] IPAFrameContext &frameContext,\n+\t\t\t\t    IPAFrameContext &frameContext,\n \t\t\t\t    RkISP1Params *params)\n {\n-\tuint32_t ct = context.activeState.awb.temperatureK;\n+\tuint32_t ct = frameContext.awb.temperatureK;\n \tif (std::abs(static_cast<int>(ct) - static_cast<int>(lastAppliedCt_)) <\n \t    kColourTemperatureChangeThreshhold)\n \t\treturn;\ndiff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp\nindex 39b97d143e95..7bc42e6de415 100644\n--- a/src/ipa/rkisp1/ipa_context.cpp\n+++ b/src/ipa/rkisp1/ipa_context.cpp\n@@ -197,15 +197,15 @@ namespace libcamera::ipa::rkisp1 {\n  * \\struct IPAActiveState::awb::AwbState.gains\n  * \\brief White balance gains\n  *\n+ * \\var IPAActiveState::awb::AwbState.temperatureK\n+ * \\brief Estimated color temperature\n+ *\n  * \\var IPAActiveState::awb.manual\n  * \\brief Manual regulation state (set through requests)\n  *\n  * \\var IPAActiveState::awb.automatic\n  * \\brief Automatic regulation state (computed by the algorithm)\n  *\n- * \\var IPAActiveState::awb.temperatureK\n- * \\brief Estimated color temperature\n- *\n  * \\var IPAActiveState::awb.autoEnabled\n  * \\brief Whether the Auto White Balance algorithm is enabled\n  */\ndiff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\nindex 6bc922a82971..769e9f114e23 100644\n--- a/src/ipa/rkisp1/ipa_context.h\n+++ b/src/ipa/rkisp1/ipa_context.h\n@@ -91,12 +91,12 @@ struct IPAActiveState {\n \tstruct {\n \t\tstruct AwbState {\n \t\t\tRGB<double> gains;\n+\t\t\tunsigned int temperatureK;\n \t\t};\n \n \t\tAwbState manual;\n \t\tAwbState automatic;\n \n-\t\tunsigned int temperatureK;\n \t\tbool autoEnabled;\n \t} awb;\n \n","prefixes":["v3","11/16"]}