[{"id":37958,"web_url":"https://patchwork.libcamera.org/comment/37958/","msgid":"<e40b4fb4-4ea8-4d48-87f9-7788b113153a@collabora.com>","date":"2026-01-26T16:00:25","subject":"Re: [PATCH v4 06/15] libcamera: ipa: simple: Initialise the general\n\tcorrection matrix","submitter":{"id":140,"url":"https://patchwork.libcamera.org/api/people/140/","name":"Robert Mader","email":"robert.mader@collabora.com"},"content":"Reviewed-by: Robert Mader <robert.mader@collabora.com>\n\nOn 22.01.26 17:19, Milan Zamazal wrote:\n> The combined matrix must be reset to the initial value before each frame\n> is prepared.  This must be done outside algorithms because any of the\n> algorithms may be disabled while the matrix must be always initialised.\n>\n> Let's initialise the combined matrix to the identity matrix (which keeps\n> the pixel values unchanged) in software ISP just before calling\n> `prepare' on the algorithms.\n>\n> Matrix updates can no longer be skipped in ccm.cpp, otherwise the CCM\n> won't be applied if there is no temperature or saturation change.  We\n> explicitly track whether the CCM has been set up completely rather than\n> relying on the frame number, to avoid missing the initialisation in case\n> the first frame is skipped due to some error.\n>\n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>   src/ipa/simple/algorithms/ccm.cpp | 29 +++++++++++++----------------\n>   src/ipa/simple/algorithms/ccm.h   |  3 ++-\n>   src/ipa/simple/ipa_context.h      |  1 -\n>   src/ipa/simple/soft_simple.cpp    |  2 ++\n>   4 files changed, 17 insertions(+), 18 deletions(-)\n>\n> diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp\n> index a3e8cd6c4..85643645b 100644\n> --- a/src/ipa/simple/algorithms/ccm.cpp\n> +++ b/src/ipa/simple/algorithms/ccm.cpp\n> @@ -83,7 +83,7 @@ void Ccm::applySaturation(Matrix<float, 3, 3> &ccm, float saturation)\n>   \tccm = ycbcr2rgb * saturationMatrix * rgb2ycbcr * ccm;\n>   }\n>   \n> -void Ccm::prepare(IPAContext &context, const uint32_t frame,\n> +void Ccm::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n>   \t\t  IPAFrameContext &frameContext, [[maybe_unused]] DebayerParams *params)\n>   {\n>   \tauto &saturation = context.activeState.knobs.saturation;\n> @@ -91,24 +91,21 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame,\n>   \tconst unsigned int ct = context.activeState.awb.temperatureK;\n>   \n>   \t/* Change CCM only on saturation or bigger temperature changes. */\n> -\tif (frame > 0 &&\n> -\t    utils::abs_diff(ct, lastCt_) < kTemperatureThreshold &&\n> -\t    saturation == lastSaturation_) {\n> -\t\tframeContext.ccm = context.activeState.ccm;\n> -\t\treturn;\n> +\tif (!currentCcm_ ||\n> +\t    utils::abs_diff(ct, lastCt_) >= kTemperatureThreshold ||\n> +\t    saturation != lastSaturation_) {\n> +\t\tcurrentCcm_ = ccm_.getInterpolated(ct);\n> +\t\tif (saturation)\n> +\t\t\tapplySaturation(currentCcm_.value(), saturation.value());\n> +\t\tlastCt_ = ct;\n> +\t\tlastSaturation_ = saturation;\n> +\t\tcontext.activeState.matrixChanged = true;\n>   \t}\n>   \n> -\tlastCt_ = ct;\n> -\tlastSaturation_ = saturation;\n> -\tMatrix<float, 3, 3> ccm = ccm_.getInterpolated(ct);\n> -\tif (saturation)\n> -\t\tapplySaturation(ccm, saturation.value());\n> -\n> -\tcontext.activeState.combinedMatrix = ccm;\n> -\tcontext.activeState.ccm = ccm;\n> +\tcontext.activeState.combinedMatrix =\n> +\t\tcurrentCcm_.value() * context.activeState.combinedMatrix;\n>   \tframeContext.saturation = saturation;\n> -\tcontext.activeState.matrixChanged = true;\n> -\tframeContext.ccm = ccm;\n> +\tframeContext.ccm = currentCcm_.value();\n>   }\n>   \n>   void Ccm::process([[maybe_unused]] IPAContext &context,\n> diff --git a/src/ipa/simple/algorithms/ccm.h b/src/ipa/simple/algorithms/ccm.h\n> index 8279a3d59..867a680c3 100644\n> --- a/src/ipa/simple/algorithms/ccm.h\n> +++ b/src/ipa/simple/algorithms/ccm.h\n> @@ -1,6 +1,6 @@\n>   /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>   /*\n> - * Copyright (C) 2024-2025, Red Hat Inc.\n> + * Copyright (C) 2024-2026, Red Hat Inc.\n>    *\n>    * Color correction matrix\n>    */\n> @@ -47,6 +47,7 @@ private:\n>   \tunsigned int lastCt_;\n>   \tstd::optional<float> lastSaturation_;\n>   \tInterpolator<Matrix<float, 3, 3>> ccm_;\n> +\tstd::optional<Matrix<float, 3, 3>> currentCcm_;\n>   };\n>   \n>   } /* namespace ipa::soft::algorithms */\n> diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n> index 58dcad290..a3ff3d038 100644\n> --- a/src/ipa/simple/ipa_context.h\n> +++ b/src/ipa/simple/ipa_context.h\n> @@ -62,7 +62,6 @@ struct IPAActiveState {\n>   \t\tdouble contrastExp;\n>   \t} gamma;\n>   \n> -\tMatrix<float, 3, 3> ccm;\n>   \tMatrix<float, 3, 3> combinedMatrix;\n>   \tbool matrixChanged = false;\n>   \n> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n> index 57836c73c..732e82510 100644\n> --- a/src/ipa/simple/soft_simple.cpp\n> +++ b/src/ipa/simple/soft_simple.cpp\n> @@ -282,6 +282,8 @@ void IPASoftSimple::queueRequest(const uint32_t frame, const ControlList &contro\n>   \n>   void IPASoftSimple::computeParams(const uint32_t frame)\n>   {\n> +\tcontext_.activeState.combinedMatrix = Matrix<float, 3, 3>::identity();\n> +\n>   \tIPAFrameContext &frameContext = context_.frameContexts.get(frame);\n>   \tfor (auto const &algo : algorithms())\n>   \t\talgo->prepare(context_, frame, frameContext, params_);","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 273ECC3200\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 26 Jan 2026 16:00:34 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id ABD9F61FD0;\n\tMon, 26 Jan 2026 17:00:33 +0100 (CET)","from sender4-op-o12.zoho.com (sender4-op-o12.zoho.com\n\t[136.143.188.12])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8615561FC5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 26 Jan 2026 17:00:31 +0100 (CET)","by mx.zohomail.com with SMTPS id 1769443227594788.4723417534884;\n\tMon, 26 Jan 2026 08:00:27 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=collabora.com\n\theader.i=robert.mader@collabora.com header.b=\"bSj+LngS\"; \n\tdkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1769443228; cv=none; \n\td=zohomail.com; s=zohoarc; \n\tb=S+ddF8B+ghauXXBbdCuxeynAlVhMZEneWGDRsy1oQGDzXF6J8UBwyeI60038kIC7OGV6UN72VXXwn0bX5JFkzp3JyW1TPlhr1dYORU0VAcCC6PGyZkJciYRD64No5YwA8xWmim9F+DXg472bZLYBjsXxblBHCVOjhFogcpLEgFo=","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; \n\ts=zohoarc; t=1769443228;\n\th=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To:Cc;\n\tbh=m/yMIha7gmFZnmk7eNq7wD6OFdorXeIxoW1xAtgViHY=; \n\tb=jMvUCy98Qk9G0u6WoVQMcYHTP4jrqnMT0rOgXa6AeWXf6XQmw8ZjnNUxkPLVbFP9lYg+PisbKYiMVRrl7wdlb++iJLNbFdzqVQ5rGmgT+xk87qoJaS64YwOBXwmytEkSVAFKha/ZJ+SJAaWJ9orCLasdmkJArgvNDAto+jt18Es=","ARC-Authentication-Results":"i=1; mx.zohomail.com;\n\tdkim=pass  header.i=collabora.com;\n\tspf=pass  smtp.mailfrom=robert.mader@collabora.com;\n\tdmarc=pass header.from=<robert.mader@collabora.com>","DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1769443228;\n\ts=zohomail; d=collabora.com; i=robert.mader@collabora.com;\n\th=Message-ID:Date:Date:MIME-Version:Subject:Subject:To:To:References:From:From:In-Reply-To:Content-Type:Content-Transfer-Encoding:Message-Id:Reply-To:Cc;\n\tbh=m/yMIha7gmFZnmk7eNq7wD6OFdorXeIxoW1xAtgViHY=;\n\tb=bSj+LngS8x5igkKtsQwTBYk0ljn6iZ80HLogzDvmwTb/V1ElhqOJjkKcUdA/mYAU\n\tH2GilLm/h0MSJKhj8k7mNSz9k7EvcQS2DOibCyYRYhyya4+25M6RWUIIxvYohoirp2u\n\t3+CTHx2Sp8Q+7UrNM8E4tkMj8nHFC5WH2gL1iV/Y=","Message-ID":"<e40b4fb4-4ea8-4d48-87f9-7788b113153a@collabora.com>","Date":"Mon, 26 Jan 2026 17:00:25 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v4 06/15] libcamera: ipa: simple: Initialise the general\n\tcorrection matrix","To":"libcamera-devel@lists.libcamera.org","References":"<20260122161935.208562-1-mzamazal@redhat.com>\n\t<20260122161935.208562-7-mzamazal@redhat.com>","Content-Language":"en-US, de-DE","From":"Robert Mader <robert.mader@collabora.com>","In-Reply-To":"<20260122161935.208562-7-mzamazal@redhat.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","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>"}}]