From patchwork Wed Jan 14 11:58:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 25789 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 10626C3226 for ; Wed, 14 Jan 2026 11:58:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B9B9F61FCF; Wed, 14 Jan 2026 12:58:27 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Rw1I3Vct"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B1B4C61FB9 for ; Wed, 14 Jan 2026 12:58:25 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:b781:dff2:957:7831]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 0790F316; Wed, 14 Jan 2026 12:57:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1768391879; bh=Roq0HS8t5ZHiOGNOCWixxddzZZncwjZ5zGsFl752i7A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Rw1I3Vct58g+DNbc79XYV/1P99Hh8IeluygvUbYmkWL2Bxm1R3zz6zAleuu/ey6+u xx6SKEO3ITc0C0QveZ5ItAdZ/0y5zpyGp3sZBDWCEC5W4ED1ii9+8J0q/nDyrw5s+l TU/a2eJrnTvzJdjdZY3wExDQhdsVsfsKcism98BY= From: Stefan Klug Date: Wed, 14 Jan 2026 12:58:02 +0100 Subject: [PATCH v3 09/15] ipa: rkisp1: lsc: Handle quantization locally MIME-Version: 1.0 Message-Id: <20260114-sklug-lsc-resampling-v2-dev-v3-9-80cd24f4dd61@ideasonboard.com> References: <20260114-sklug-lsc-resampling-v2-dev-v3-0-80cd24f4dd61@ideasonboard.com> In-Reply-To: <20260114-sklug-lsc-resampling-v2-dev-v3-0-80cd24f4dd61@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham X-Mailer: b4 0.14.2 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 quantization functionality in the Interpolator hinders in writing nice code. Don't use it and implement the functionality directly in the algorithm. While at it, reduce the threshold to half of the quantization step size, otherwise it might happen that we skip a full quantization step. Rename the kColourTemperatureChangeThreshhold to kColourTemperatureQuantization to better express the usecase. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Barnabás Pőcze --- Changes in v3: - Reduce threshold to quantization step/2 - Drop unnecessary static modifier - Collected tag Changes in v2: - Added this patch --- src/ipa/rkisp1/algorithms/lsc.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp index c42f74557c7364935254d75ee1fb923d176e0dbd..77ed0a95209ac13e82f4ee43f7a22095bb5fd65f 100644 --- a/src/ipa/rkisp1/algorithms/lsc.cpp +++ b/src/ipa/rkisp1/algorithms/lsc.cpp @@ -70,7 +70,7 @@ LOG_DEFINE_CATEGORY(RkISP1Lsc) namespace { -constexpr int kColourTemperatureChangeThreshhold = 10; +constexpr int kColourTemperatureQuantization = 10; class LscPolynomialLoader { @@ -308,12 +308,16 @@ std::vector parseSizes(const YamlObject &tuningData, return sizes; } +unsigned int quantize(unsigned int value, unsigned int step) +{ + return std::lround(value / static_cast(step)) * step; +} + } /* namespace */ LensShadingCorrection::LensShadingCorrection() : lastAppliedCt_(0), lastAppliedQuantizedCt_(0) { - sets_.setQuantization(kColourTemperatureChangeThreshhold); } /** @@ -426,17 +430,24 @@ void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context, RkISP1Params *params) { uint32_t ct = frameContext.awb.temperatureK; - if (std::abs(static_cast(ct) - static_cast(lastAppliedCt_)) < - kColourTemperatureChangeThreshhold) + unsigned int quantizedCt = quantize(ct, kColourTemperatureQuantization); + int ctDiff = static_cast(ct) - static_cast(lastAppliedCt_); + + /* + * Add a threshold so that oscillations around a quantization step don't + * lead to constant changes. + */ + if (std::abs(ctDiff) < kColourTemperatureQuantization / 2) return; - unsigned int quantizedCt; - const Components &set = sets_.getInterpolated(ct, &quantizedCt); - if (lastAppliedQuantizedCt_ == quantizedCt) + + if (quantizedCt == lastAppliedQuantizedCt_) return; auto config = params->block(); config.setEnabled(true); setParameters(*config); + + const Components &set = sets_.getInterpolated(quantizedCt); copyTable(*config, set); lastAppliedCt_ = ct;