From patchwork Wed Nov 12 08:27:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 24999 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 983DDC3241 for ; Wed, 12 Nov 2025 08:27:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BD4A260AA2; Wed, 12 Nov 2025 09:27:28 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="ZN37xPLf"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B55FF606E6 for ; Wed, 12 Nov 2025 09:27:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762936044; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SSceWhmXFQmGwpHcqjV7CQ4xFm5frICgsq0OCGnPs7o=; b=ZN37xPLfMhwtXA8McmjDnCt2Wi7mdzZSNwW5sEP3/5/xCC0vziOPvx/ZONz3GPycjZ9Zu8 9xz6mtFj/FYa6TBQREedxkod93ttHvQTug+09nDvVXbAweBuleuBS95STAKjqbYFPdrG7d Iq5Y3spP7afQuoLOi1HNdVUYrzXoGzQ= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-676-AWs-6NfeMDaxp81i0H9Qjw-1; Wed, 12 Nov 2025 03:27:23 -0500 X-MC-Unique: AWs-6NfeMDaxp81i0H9Qjw-1 X-Mimecast-MFC-AGG-ID: AWs-6NfeMDaxp81i0H9Qjw_1762936042 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 47B981956095 for ; Wed, 12 Nov 2025 08:27:22 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.33.149]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 439C018004D8; Wed, 12 Nov 2025 08:27:21 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal Subject: [RFC PATCH 1/7] libcamera: ipa: simple: Remove an unused include from awb.cpp Date: Wed, 12 Nov 2025 09:27:09 +0100 Message-ID: <20251112082715.17823-2-mzamazal@redhat.com> In-Reply-To: <20251112082715.17823-1-mzamazal@redhat.com> References: <20251112082715.17823-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 1evQsTrOyzr1s-q2zAekQiAg_dNCEbKRI-aMYXVTrMI_1762936042 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" is not used any more. Signed-off-by: Milan Zamazal Reviewed-by: Kieran Bingham --- src/ipa/simple/algorithms/awb.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp index cf78e9800..9de422519 100644 --- a/src/ipa/simple/algorithms/awb.cpp +++ b/src/ipa/simple/algorithms/awb.cpp @@ -7,7 +7,6 @@ #include "awb.h" -#include #include #include From patchwork Wed Nov 12 08:27:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 25000 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 2DD8BC32DB for ; Wed, 12 Nov 2025 08:27:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C8E7860A8B; Wed, 12 Nov 2025 09:27:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="UvpxBjl0"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 56AEE609D8 for ; Wed, 12 Nov 2025 09:27:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762936046; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8ZQnlUEp8MjCfjuSJC9gqY4AhnGFBE8C4/zMTaHd5HU=; b=UvpxBjl0ZNBMwKzAdsG6YfvCBbv8GcRGQfQVTmYn/1ryi/AJm6mYGZDfLEGfXdK40KGBp1 /NCkR/B17iabgkNnxnYtOZ6eVtbsYelhDPKt3xMPSfnkPWrDqoLdHblGM1nC9ZYI3JtnxY kHmNK++XygWUC+phSvCIoQkQL/q6ZzE= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-618-Wsnkzed8PeOewHyxSy1ReQ-1; Wed, 12 Nov 2025 03:27:24 -0500 X-MC-Unique: Wsnkzed8PeOewHyxSy1ReQ-1 X-Mimecast-MFC-AGG-ID: Wsnkzed8PeOewHyxSy1ReQ_1762936044 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1FE9D1800350 for ; Wed, 12 Nov 2025 08:27:24 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.33.149]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id DFC291800451; Wed, 12 Nov 2025 08:27:22 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal Subject: [RFC PATCH 2/7] libcamera: ipa: simple: Unwrap IPAFrameContext::ccm Date: Wed, 12 Nov 2025 09:27:10 +0100 Message-ID: <20251112082715.17823-3-mzamazal@redhat.com> In-Reply-To: <20251112082715.17823-1-mzamazal@redhat.com> References: <20251112082715.17823-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: O-2Cc3bJvanoNutjspaZA2iQT0dlcbyWXH5TY78J4v0_1762936044 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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 struct has only one member and there is no immediate need to add more. Let's use the member directly, to make things a bit simpler. Signed-off-by: Milan Zamazal Reviewed-by: Kieran Bingham --- src/ipa/simple/algorithms/ccm.cpp | 6 +++--- src/ipa/simple/ipa_context.h | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp index 0a98406c1..d7d3dda76 100644 --- a/src/ipa/simple/algorithms/ccm.cpp +++ b/src/ipa/simple/algorithms/ccm.cpp @@ -94,7 +94,7 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame, if (frame > 0 && utils::abs_diff(ct, lastCt_) < kTemperatureThreshold && saturation == lastSaturation_) { - frameContext.ccm.ccm = context.activeState.ccm.ccm; + frameContext.ccm = context.activeState.ccm.ccm; context.activeState.ccm.changed = false; return; } @@ -106,9 +106,9 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame, applySaturation(ccm, saturation.value()); context.activeState.ccm.ccm = ccm; - frameContext.ccm.ccm = ccm; frameContext.saturation = saturation; context.activeState.ccm.changed = true; + frameContext.ccm = ccm; } void Ccm::process([[maybe_unused]] IPAContext &context, @@ -117,7 +117,7 @@ void Ccm::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const SwIspStats *stats, ControlList &metadata) { - metadata.set(controls::ColourCorrectionMatrix, frameContext.ccm.ccm.data()); + metadata.set(controls::ColourCorrectionMatrix, frameContext.ccm.data()); const auto &saturation = frameContext.saturation; metadata.set(controls::Saturation, saturation.value_or(1.0)); diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index c3081e306..330fe39cb 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -73,9 +73,7 @@ struct IPAActiveState { }; struct IPAFrameContext : public FrameContext { - struct { - Matrix ccm; - } ccm; + Matrix ccm; struct { int32_t exposure; From patchwork Wed Nov 12 08:27:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 25001 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 5197BC3241 for ; Wed, 12 Nov 2025 08:27:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D910A60AA1; Wed, 12 Nov 2025 09:27:32 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="d6O/vGJp"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0D94860AA3 for ; Wed, 12 Nov 2025 09:27:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762936048; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Rwk4rnUicsh9TNc31DxLqPiiN+eLGOdhYhZyVjTr5Nw=; b=d6O/vGJpqdtSq93yETYzZL/HWxOCs3epdJlE/+3wQB3Q0/zZfEYwFgMZk63Ds2t28iiTTl eucuOSTWJf+pxjM6tOlJoB4ZVQ9t0sjgtIBMmX8867j732qPzadJ4Eqw4/spG7vmjZ3i+6 H632rmS6Bk144HtyqxYQ5/NKeu+IIr8= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-257-F6fX83nsPzmP7hmzyXEoRQ-1; Wed, 12 Nov 2025 03:27:26 -0500 X-MC-Unique: F6fX83nsPzmP7hmzyXEoRQ-1 X-Mimecast-MFC-AGG-ID: F6fX83nsPzmP7hmzyXEoRQ_1762936046 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id EE45F180048E for ; Wed, 12 Nov 2025 08:27:25 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.33.149]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B9CA31800451; Wed, 12 Nov 2025 08:27:24 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal Subject: [RFC PATCH 3/7] libcamera: ipa: simple: Generalise tracking matrix changes Date: Wed, 12 Nov 2025 09:27:11 +0100 Message-ID: <20251112082715.17823-4-mzamazal@redhat.com> In-Reply-To: <20251112082715.17823-1-mzamazal@redhat.com> References: <20251112082715.17823-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 2pW0pRLCrxpKmAfLsmSXsXCbTmPOnhlDB7Q8Lpw3sTE_1762936046 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" IPAActiveState::ccm stores the colour correction matrix (CCM) and whether it has been changed. The change flag is later used when recomputing or not the lookup tables. But the CCM may include other corrections than just the sensor colour correction, for example white balance and saturation adjustments. These things should be separated and IPAActiveState::ccm should represent just the CCM itself. As the first step towards that cleanup, let's separate the change flag from the CCM. And wrap the only remaining member of IPAActiveState::ccm. Also, let's reset the separated change flag in the lookup tables; it'll be no longer tight to just CCM handling. Signed-off-by: Milan Zamazal --- src/ipa/simple/algorithms/ccm.cpp | 7 +++---- src/ipa/simple/algorithms/lut.cpp | 6 ++++-- src/ipa/simple/ipa_context.h | 6 ++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp index d7d3dda76..e05e5bc28 100644 --- a/src/ipa/simple/algorithms/ccm.cpp +++ b/src/ipa/simple/algorithms/ccm.cpp @@ -94,8 +94,7 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame, if (frame > 0 && utils::abs_diff(ct, lastCt_) < kTemperatureThreshold && saturation == lastSaturation_) { - frameContext.ccm = context.activeState.ccm.ccm; - context.activeState.ccm.changed = false; + frameContext.ccm = context.activeState.ccm; return; } @@ -105,9 +104,9 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame, if (saturation) applySaturation(ccm, saturation.value()); - context.activeState.ccm.ccm = ccm; + context.activeState.ccm = ccm; frameContext.saturation = saturation; - context.activeState.ccm.changed = true; + context.activeState.matrixChanged = true; frameContext.ccm = ccm; } diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index d1d5f7271..dead55f34 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -118,11 +118,12 @@ void Lut::prepare(IPAContext &context, params->green[i] = gammaTable[static_cast(lutGains.g())]; params->blue[i] = gammaTable[static_cast(lutGains.b())]; } - } else if (context.activeState.ccm.changed || gammaUpdateNeeded) { + + } else if (context.activeState.matrixChanged || gammaUpdateNeeded) { Matrix gainCcm = { { gains.r(), 0, 0, 0, gains.g(), 0, 0, 0, gains.b() } }; - auto ccm = context.activeState.ccm.ccm * gainCcm; + auto ccm = context.activeState.ccm * gainCcm; auto &red = params->redCcm; auto &green = params->greenCcm; auto &blue = params->blueCcm; @@ -138,6 +139,7 @@ void Lut::prepare(IPAContext &context, blue[i].b = ccmValue(i, ccm[2][2]); params->gammaLut[i] = gammaTable[i / div]; } + context.activeState.matrixChanged = false; } } diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index 330fe39cb..b6b3cbfed 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -60,10 +60,8 @@ struct IPAActiveState { double contrast; } gamma; - struct { - Matrix ccm; - bool changed; - } ccm; + Matrix ccm; + bool matrixChanged = false; struct { /* 0..2 range, 1.0 = normal */ From patchwork Wed Nov 12 08:27:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 25002 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 95273C3241 for ; Wed, 12 Nov 2025 08:27:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1037C60AAA; Wed, 12 Nov 2025 09:27:35 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="ZPsh1lCN"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0079160A9E for ; Wed, 12 Nov 2025 09:27:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762936050; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oumnQQoZKAW/ZsSaeK1XJTwDKNiPsQHH7o2c/HmpfmM=; b=ZPsh1lCNZ14xMEooybV0mYaPXJE38a2z3gI7h5Q+J+EuZs20yHYiz/QX31h7TVAUhJNSm0 oEVgrDa4mzPTfCA8MGVg2sKKyDts7VrByummEXoAgRBG/PRDfZqhlDN+OQz1dGkzD6QvIT KOGmHWBOZTeouCUe2kzzS4UvENcWkek= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-645-Laqnu6WAMjCixh9PXElZ9A-1; Wed, 12 Nov 2025 03:27:28 -0500 X-MC-Unique: Laqnu6WAMjCixh9PXElZ9A-1 X-Mimecast-MFC-AGG-ID: Laqnu6WAMjCixh9PXElZ9A_1762936047 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AFF8E1954B00 for ; Wed, 12 Nov 2025 08:27:27 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.33.149]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8B28518004D8; Wed, 12 Nov 2025 08:27:26 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal Subject: [RFC PATCH 4/7] libcamera: ipa: simple: Rename "ccm" identifiers not specific to CCM Date: Wed, 12 Nov 2025 09:27:12 +0100 Message-ID: <20251112082715.17823-5-mzamazal@redhat.com> In-Reply-To: <20251112082715.17823-1-mzamazal@redhat.com> References: <20251112082715.17823-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: jHa92R1daHnbcUZBXYgdzvP80Q5E4lEXyR3qSdfykBw_1762936047 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" Let's rename the identifiers that are related to general colour corrections applied by matrix operations, rather than directly to the sensor colour correction matrix. Signed-off-by: Milan Zamazal --- src/ipa/simple/algorithms/lut.cpp | 28 ++++++++++++++-------------- src/ipa/simple/algorithms/lut.h | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index dead55f34..b27491042 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -80,7 +80,7 @@ void Lut::updateGammaTable(IPAContext &context) context.activeState.gamma.contrast = contrast; } -int16_t Lut::ccmValue(unsigned int i, float ccm) const +int16_t Lut::matrixValue(unsigned int i, float ccm) const { return std::round(i * ccm); } @@ -120,23 +120,23 @@ void Lut::prepare(IPAContext &context, } } else if (context.activeState.matrixChanged || gammaUpdateNeeded) { - Matrix gainCcm = { { gains.r(), 0, 0, - 0, gains.g(), 0, - 0, 0, gains.b() } }; - auto ccm = context.activeState.ccm * gainCcm; + Matrix gainMatrix = { { gains.r(), 0, 0, + 0, gains.g(), 0, + 0, 0, gains.b() } }; + auto matrix = context.activeState.ccm * gainMatrix; auto &red = params->redCcm; auto &green = params->greenCcm; auto &blue = params->blueCcm; for (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) { - red[i].r = ccmValue(i, ccm[0][0]); - red[i].g = ccmValue(i, ccm[1][0]); - red[i].b = ccmValue(i, ccm[2][0]); - green[i].r = ccmValue(i, ccm[0][1]); - green[i].g = ccmValue(i, ccm[1][1]); - green[i].b = ccmValue(i, ccm[2][1]); - blue[i].r = ccmValue(i, ccm[0][2]); - blue[i].g = ccmValue(i, ccm[1][2]); - blue[i].b = ccmValue(i, ccm[2][2]); + red[i].r = matrixValue(i, matrix[0][0]); + red[i].g = matrixValue(i, matrix[1][0]); + red[i].b = matrixValue(i, matrix[2][0]); + green[i].r = matrixValue(i, matrix[0][1]); + green[i].g = matrixValue(i, matrix[1][1]); + green[i].b = matrixValue(i, matrix[2][1]); + blue[i].r = matrixValue(i, matrix[0][2]); + blue[i].g = matrixValue(i, matrix[1][2]); + blue[i].b = matrixValue(i, matrix[2][2]); params->gammaLut[i] = gammaTable[i / div]; } context.activeState.matrixChanged = false; diff --git a/src/ipa/simple/algorithms/lut.h b/src/ipa/simple/algorithms/lut.h index ba8b9021b..0eafd0695 100644 --- a/src/ipa/simple/algorithms/lut.h +++ b/src/ipa/simple/algorithms/lut.h @@ -38,7 +38,7 @@ public: private: void updateGammaTable(IPAContext &context); - int16_t ccmValue(unsigned int i, float ccm) const; + int16_t matrixValue(unsigned int i, float ccm) const; }; } /* namespace ipa::soft::algorithms */ From patchwork Wed Nov 12 08:27:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 25003 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 EEFAAC32DB for ; Wed, 12 Nov 2025 08:27:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 58C3F60AA1; Wed, 12 Nov 2025 09:27:36 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Sm7sN1CT"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B278C60A8A for ; Wed, 12 Nov 2025 09:27:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762936051; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NNsPcsRF9u7DUssA+mlF7TlhOIJYP1/loldQ9u+0kzA=; b=Sm7sN1CTQcZ0jwHtMrMjHvOGYIadZuzf/n6thZ10MKFmKYPzuCnZj4vLjyhyprlhgwEaa1 lQy3w2oFUSFV8KrdDnQBkc2L23eg6BlzmVhEU2f6ScKjzlFi2vg69jbYcN7bu5IgCUUJw3 PK/Jz6y8NjMt6QLWHaR8bPkhNVoHVGk= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-692-3uao4zJzMguN3TnRciv4SQ-1; Wed, 12 Nov 2025 03:27:30 -0500 X-MC-Unique: 3uao4zJzMguN3TnRciv4SQ-1 X-Mimecast-MFC-AGG-ID: 3uao4zJzMguN3TnRciv4SQ_1762936049 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 87E2718001FE for ; Wed, 12 Nov 2025 08:27:29 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.33.149]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 54ED11800872; Wed, 12 Nov 2025 08:27:28 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal Subject: [RFC PATCH 5/7] libcamera: ipa: simple: Introduce a general correction matrix Date: Wed, 12 Nov 2025 09:27:13 +0100 Message-ID: <20251112082715.17823-6-mzamazal@redhat.com> In-Reply-To: <20251112082715.17823-1-mzamazal@redhat.com> References: <20251112082715.17823-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: GN_czdKybibUliPEV84-MCB-B4CHiLY5QWCniM8ioos_1762936049 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" Let's introduce IPAActiveState::correctionMatrix that is separate from IPAActiveState::ccm and represents the overall correction matrix, not only the sensor colour correction matrix. IPAActiveState::ccm still includes everything; this is changed in the followup patch. Signed-off-by: Milan Zamazal Reviewed-by: Kieran Bingham --- src/ipa/simple/algorithms/ccm.cpp | 1 + src/ipa/simple/algorithms/lut.cpp | 2 +- src/ipa/simple/ipa_context.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp index e05e5bc28..3e9528a91 100644 --- a/src/ipa/simple/algorithms/ccm.cpp +++ b/src/ipa/simple/algorithms/ccm.cpp @@ -104,6 +104,7 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame, if (saturation) applySaturation(ccm, saturation.value()); + context.activeState.correctionMatrix = ccm; context.activeState.ccm = ccm; frameContext.saturation = saturation; context.activeState.matrixChanged = true; diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index b27491042..8751bb31c 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -123,7 +123,7 @@ void Lut::prepare(IPAContext &context, Matrix gainMatrix = { { gains.r(), 0, 0, 0, gains.g(), 0, 0, 0, gains.b() } }; - auto matrix = context.activeState.ccm * gainMatrix; + auto matrix = context.activeState.correctionMatrix * gainMatrix; auto &red = params->redCcm; auto &green = params->greenCcm; auto &blue = params->blueCcm; diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index b6b3cbfed..14680c726 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -61,6 +61,7 @@ struct IPAActiveState { } gamma; Matrix ccm; + Matrix correctionMatrix; bool matrixChanged = false; struct { From patchwork Wed Nov 12 08:27:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 25004 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 60FFCC3241 for ; Wed, 12 Nov 2025 08:27:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8DEFF60AAD; Wed, 12 Nov 2025 09:27:37 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Fpvt5leF"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 229D060A86 for ; Wed, 12 Nov 2025 09:27:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762936053; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BL1Y/mpIV+/ssHWmbHQ0Ivl9xvySKR0aQ6uJfhx57kU=; b=Fpvt5leFLDPa01jkWb1Ev7byaJZi0AEVPgOI71ZxlPCdn5ozWn3lXucKyXnk6ND62yCn8K ofLX33pTs4eR0x6eCBFsKQJ9GXEBCOxyRErLkamW7/1pZhKBo6JJeaGIFHZXcM7/sPuHQ4 n2HUAnmY3RTbLgmDRzcoNcXeupUhaBw= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-38-M5fDyvRsPMKkSxmPKgYN5g-1; Wed, 12 Nov 2025 03:27:31 -0500 X-MC-Unique: M5fDyvRsPMKkSxmPKgYN5g-1 X-Mimecast-MFC-AGG-ID: M5fDyvRsPMKkSxmPKgYN5g_1762936051 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 15C611956095 for ; Wed, 12 Nov 2025 08:27:31 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.33.149]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 265881800451; Wed, 12 Nov 2025 08:27:29 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal Subject: [RFC PATCH 6/7] libcamera: ipa: simple: Separate saturation from CCM Date: Wed, 12 Nov 2025 09:27:14 +0100 Message-ID: <20251112082715.17823-7-mzamazal@redhat.com> In-Reply-To: <20251112082715.17823-1-mzamazal@redhat.com> References: <20251112082715.17823-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 9fwLKz9J4571igV-Pfp2YXluKMMjD9oZjSZ9RCm1CeM_1762936051 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" Saturation adjustments are implemented using matrix operations. They are currently applied to the colour correction matrix. Let's move them to a newly introduced separate "Adjust" algorithm. This separation has the following advantages: - It allows disabling general colour adjustments algorithms without disabling the CCM algorithm. - It keeps the CCM separated from other corrections. - It's generally cleaner. Signed-off-by: Milan Zamazal Reviewed-by: Kieran Bingham --- src/ipa/simple/algorithms/adjust.cpp | 111 ++++++++++++++++++++++++++ src/ipa/simple/algorithms/adjust.h | 52 ++++++++++++ src/ipa/simple/algorithms/ccm.cpp | 58 +------------- src/ipa/simple/algorithms/ccm.h | 10 +-- src/ipa/simple/algorithms/meson.build | 1 + src/ipa/simple/data/uncalibrated.yaml | 1 + 6 files changed, 169 insertions(+), 64 deletions(-) create mode 100644 src/ipa/simple/algorithms/adjust.cpp create mode 100644 src/ipa/simple/algorithms/adjust.h diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp new file mode 100644 index 000000000..282b3ccb0 --- /dev/null +++ b/src/ipa/simple/algorithms/adjust.cpp @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Ideas On Board + * Copyright (C) 2024-2025, Red Hat Inc. + * + * Common image adjustments + */ + +#include "adjust.h" + +#include +#include + +#include + +#include "libcamera/internal/matrix.h" + +namespace libcamera { + +namespace ipa::soft::algorithms { + +LOG_DEFINE_CATEGORY(IPASoftAdjust) + +int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) +{ + if (context.ccmEnabled) + context.ctrlMap[&controls::Saturation] = ControlInfo(0.0f, 2.0f, 1.0f); + return 0; +} + +int Adjust::configure(IPAContext &context, + [[maybe_unused]] const IPAConfigInfo &configInfo) +{ + context.activeState.knobs.saturation = std::optional(); + context.activeState.correctionMatrix = + Matrix{ { 1, 0, 0, 0, 1, 0, 0, 0, 1 } }; + + return 0; +} + +void Adjust::queueRequest(typename Module::Context &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] typename Module::FrameContext &frameContext, + const ControlList &controls) +{ + const auto &saturation = controls.get(controls::Saturation); + if (saturation.has_value()) { + context.activeState.knobs.saturation = saturation; + LOG(IPASoftAdjust, Debug) << "Setting saturation to " << saturation.value(); + } +} + +void Adjust::applySaturation(Matrix &matrix, float saturation) +{ + /* https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion */ + const Matrix rgb2ycbcr{ + { 0.256788235294, 0.504129411765, 0.0979058823529, + -0.148223529412, -0.290992156863, 0.439215686275, + 0.439215686275, -0.367788235294, -0.0714274509804 } + }; + const Matrix ycbcr2rgb{ + { 1.16438356164, 0, 1.59602678571, + 1.16438356164, -0.391762290094, -0.812967647235, + 1.16438356164, 2.01723214285, 0 } + }; + const Matrix saturationMatrix{ + { 1, 0, 0, + 0, saturation, 0, + 0, 0, saturation } + }; + matrix = + ycbcr2rgb * saturationMatrix * rgb2ycbcr * matrix; +} + +void Adjust::prepare(IPAContext &context, + const uint32_t frame, + IPAFrameContext &frameContext, + [[maybe_unused]] DebayerParams *params) +{ + if (!context.ccmEnabled) + return; + + auto &saturation = context.activeState.knobs.saturation; + + if (frame > 0 && saturation == lastSaturation_) + return; + + context.activeState.correctionMatrix = context.activeState.ccm; + context.activeState.matrixChanged = true; + lastSaturation_ = saturation; + if (saturation) + applySaturation(context.activeState.correctionMatrix, saturation.value()); + + frameContext.saturation = saturation; +} + +void Adjust::process([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + [[maybe_unused]] const SwIspStats *stats, + ControlList &metadata) +{ + const auto &saturation = frameContext.saturation; + metadata.set(controls::Saturation, saturation.value_or(1.0)); +} + +REGISTER_IPA_ALGORITHM(Adjust, "Adjust") + +} /* namespace ipa::soft::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/simple/algorithms/adjust.h b/src/ipa/simple/algorithms/adjust.h new file mode 100644 index 000000000..c4baa2503 --- /dev/null +++ b/src/ipa/simple/algorithms/adjust.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024-2025, Red Hat Inc. + * + * Color correction matrix + */ + +#pragma once + +#include + +#include "libcamera/internal/matrix.h" + +#include + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::soft::algorithms { + +class Adjust : public Algorithm +{ +public: + Adjust() = default; + ~Adjust() = default; + + int init(IPAContext &context, const YamlObject &tuningData) override; + int configure(IPAContext &context, + const IPAConfigInfo &configInfo) override; + void queueRequest(typename Module::Context &context, + const uint32_t frame, + typename Module::FrameContext &frameContext, + const ControlList &controls) override; + void prepare(IPAContext &context, + const uint32_t frame, + IPAFrameContext &frameContext, + DebayerParams *params) override; + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const SwIspStats *stats, + ControlList &metadata) override; + +private: + void applySaturation(Matrix &ccm, float saturation); + + std::optional lastSaturation_; +}; + +} /* namespace ipa::soft::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp index 3e9528a91..c541ef466 100644 --- a/src/ipa/simple/algorithms/ccm.cpp +++ b/src/ipa/simple/algorithms/ccm.cpp @@ -3,7 +3,7 @@ * Copyright (C) 2024, Ideas On Board * Copyright (C) 2024-2025, Red Hat Inc. * - * Color correction matrix + saturation + * Color correction matrix */ #include "ccm.h" @@ -37,76 +37,27 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData } context.ccmEnabled = true; - context.ctrlMap[&controls::Saturation] = ControlInfo(0.0f, 2.0f, 1.0f); return 0; } -int Ccm::configure(IPAContext &context, - [[maybe_unused]] const IPAConfigInfo &configInfo) -{ - context.activeState.knobs.saturation = std::optional(); - - return 0; -} - -void Ccm::queueRequest(typename Module::Context &context, - [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] typename Module::FrameContext &frameContext, - const ControlList &controls) -{ - const auto &saturation = controls.get(controls::Saturation); - if (saturation.has_value()) { - context.activeState.knobs.saturation = saturation; - LOG(IPASoftCcm, Debug) << "Setting saturation to " << saturation.value(); - } -} - -void Ccm::applySaturation(Matrix &ccm, float saturation) -{ - /* https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion */ - const Matrix rgb2ycbcr{ - { 0.256788235294, 0.504129411765, 0.0979058823529, - -0.148223529412, -0.290992156863, 0.439215686275, - 0.439215686275, -0.367788235294, -0.0714274509804 } - }; - const Matrix ycbcr2rgb{ - { 1.16438356164, 0, 1.59602678571, - 1.16438356164, -0.391762290094, -0.812967647235, - 1.16438356164, 2.01723214285, 0 } - }; - const Matrix saturationMatrix{ - { 1, 0, 0, - 0, saturation, 0, - 0, 0, saturation } - }; - ccm = ycbcr2rgb * saturationMatrix * rgb2ycbcr * ccm; -} - void Ccm::prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, [[maybe_unused]] DebayerParams *params) { - auto &saturation = context.activeState.knobs.saturation; - const unsigned int ct = context.activeState.awb.temperatureK; - /* Change CCM only on saturation or bigger temperature changes. */ + /* Change CCM only on bigger temperature changes. */ if (frame > 0 && - utils::abs_diff(ct, lastCt_) < kTemperatureThreshold && - saturation == lastSaturation_) { + utils::abs_diff(ct, lastCt_) < kTemperatureThreshold) { frameContext.ccm = context.activeState.ccm; return; } lastCt_ = ct; - lastSaturation_ = saturation; Matrix ccm = ccm_.getInterpolated(ct); - if (saturation) - applySaturation(ccm, saturation.value()); context.activeState.correctionMatrix = ccm; context.activeState.ccm = ccm; - frameContext.saturation = saturation; context.activeState.matrixChanged = true; frameContext.ccm = ccm; } @@ -118,9 +69,6 @@ void Ccm::process([[maybe_unused]] IPAContext &context, ControlList &metadata) { metadata.set(controls::ColourCorrectionMatrix, frameContext.ccm.data()); - - const auto &saturation = frameContext.saturation; - metadata.set(controls::Saturation, saturation.value_or(1.0)); } REGISTER_IPA_ALGORITHM(Ccm, "Ccm") diff --git a/src/ipa/simple/algorithms/ccm.h b/src/ipa/simple/algorithms/ccm.h index 8279a3d59..10c9829f5 100644 --- a/src/ipa/simple/algorithms/ccm.h +++ b/src/ipa/simple/algorithms/ccm.h @@ -26,12 +26,6 @@ public: ~Ccm() = default; int init(IPAContext &context, const YamlObject &tuningData) override; - int configure(IPAContext &context, - const IPAConfigInfo &configInfo) override; - void queueRequest(typename Module::Context &context, - const uint32_t frame, - typename Module::FrameContext &frameContext, - const ControlList &controls) override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, @@ -42,11 +36,9 @@ public: ControlList &metadata) override; private: - void applySaturation(Matrix &ccm, float saturation); - unsigned int lastCt_; - std::optional lastSaturation_; Interpolator> ccm_; + Matrix lastCcm_; }; } /* namespace ipa::soft::algorithms */ diff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build index 2d0adb059..ebe9f20dd 100644 --- a/src/ipa/simple/algorithms/meson.build +++ b/src/ipa/simple/algorithms/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 soft_simple_ipa_algorithms = files([ + 'adjust.cpp', 'awb.cpp', 'agc.cpp', 'blc.cpp', diff --git a/src/ipa/simple/data/uncalibrated.yaml b/src/ipa/simple/data/uncalibrated.yaml index 5508e6686..f0410fe61 100644 --- a/src/ipa/simple/data/uncalibrated.yaml +++ b/src/ipa/simple/data/uncalibrated.yaml @@ -14,6 +14,7 @@ algorithms: # ccm: [ 1, 0, 0, # 0, 1, 0, # 0, 0, 1] + - Adjust: - Lut: - Agc: ... From patchwork Wed Nov 12 08:27:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 25005 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 78A4DC3241 for ; Wed, 12 Nov 2025 08:27:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1593860AAC; Wed, 12 Nov 2025 09:27:40 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="fZwGcxo1"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id ADE3860A86 for ; Wed, 12 Nov 2025 09:27:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762936054; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JBpLen0K8pSkW9L5KMsCrcOcmyAwMdgMgtNvB6yjQf8=; b=fZwGcxo15Oghx3GetbfLpcjQjZH0hKTwrPbH+2x5+eGCBTEgEYEGfD74fx59C2/tFuedI5 ASN6XMG+C5MjLHgt1OQ5js0YT6j5ek5xUhLFQPDOVFFw1FIwj36BKZSGT4zEiWDZlWelvv 2Pi9GdCOX5n/fcYilOTWuvRlPJ2CuLs= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-493-Qd_ITTY1MpiMW9KccB1FZA-1; Wed, 12 Nov 2025 03:27:33 -0500 X-MC-Unique: Qd_ITTY1MpiMW9KccB1FZA-1 X-Mimecast-MFC-AGG-ID: Qd_ITTY1MpiMW9KccB1FZA_1762936052 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9A3DE180034A for ; Wed, 12 Nov 2025 08:27:32 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.33.149]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 92F431800367; Wed, 12 Nov 2025 08:27:31 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal Subject: [RFC PATCH 7/7] libcamera: ipa: simple: Move contrast settings to adjust.cpp Date: Wed, 12 Nov 2025 09:27:15 +0100 Message-ID: <20251112082715.17823-8-mzamazal@redhat.com> In-Reply-To: <20251112082715.17823-1-mzamazal@redhat.com> References: <20251112082715.17823-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: P3QCJDR8oEBHFSDBtM28341YdM-BACBi3mw_YsMz3UU_1762936052 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" Let's move the contrast settings from lut.cpp to adjust.cpp, where they belong, similarly to saturation. Signed-off-by: Milan Zamazal --- src/ipa/simple/algorithms/adjust.cpp | 14 +++++++++++ src/ipa/simple/algorithms/lut.cpp | 35 +--------------------------- src/ipa/simple/algorithms/lut.h | 11 --------- 3 files changed, 15 insertions(+), 45 deletions(-) diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp index 282b3ccb0..b9a9fc710 100644 --- a/src/ipa/simple/algorithms/adjust.cpp +++ b/src/ipa/simple/algorithms/adjust.cpp @@ -23,6 +23,7 @@ LOG_DEFINE_CATEGORY(IPASoftAdjust) int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) { + context.ctrlMap[&controls::Contrast] = ControlInfo(0.0f, 2.0f, 1.0f); if (context.ccmEnabled) context.ctrlMap[&controls::Saturation] = ControlInfo(0.0f, 2.0f, 1.0f); return 0; @@ -31,6 +32,7 @@ int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningD int Adjust::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { + context.activeState.knobs.contrast = std::optional(); context.activeState.knobs.saturation = std::optional(); context.activeState.correctionMatrix = Matrix{ { 1, 0, 0, 0, 1, 0, 0, 0, 1 } }; @@ -43,6 +45,12 @@ void Adjust::queueRequest(typename Module::Context &context, [[maybe_unused]] typename Module::FrameContext &frameContext, const ControlList &controls) { + const auto &contrast = controls.get(controls::Contrast); + if (contrast.has_value()) { + context.activeState.knobs.contrast = contrast; + LOG(IPASoftAdjust, Debug) << "Setting contrast to " << contrast.value(); + } + const auto &saturation = controls.get(controls::Saturation); if (saturation.has_value()) { context.activeState.knobs.saturation = saturation; @@ -77,6 +85,8 @@ void Adjust::prepare(IPAContext &context, IPAFrameContext &frameContext, [[maybe_unused]] DebayerParams *params) { + frameContext.contrast = context.activeState.knobs.contrast; + if (!context.ccmEnabled) return; @@ -100,6 +110,10 @@ void Adjust::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const SwIspStats *stats, ControlList &metadata) { + const auto &contrast = frameContext.contrast; + if (contrast) + metadata.set(controls::Contrast, contrast.value()); + const auto &saturation = frameContext.saturation; metadata.set(controls::Saturation, saturation.value_or(1.0)); } diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index 8751bb31c..876cd5cb3 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -24,36 +24,16 @@ LOG_DEFINE_CATEGORY(IPASoftLut) namespace ipa::soft::algorithms { -int Lut::init(IPAContext &context, - [[maybe_unused]] const YamlObject &tuningData) -{ - context.ctrlMap[&controls::Contrast] = ControlInfo(0.0f, 2.0f, 1.0f); - return 0; -} - int Lut::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { /* Gamma value is fixed */ context.configuration.gamma = 0.5; - context.activeState.knobs.contrast = std::optional(); updateGammaTable(context); return 0; } -void Lut::queueRequest(typename Module::Context &context, - [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] typename Module::FrameContext &frameContext, - const ControlList &controls) -{ - const auto &contrast = controls.get(controls::Contrast); - if (contrast.has_value()) { - context.activeState.knobs.contrast = contrast; - LOG(IPASoftLut, Debug) << "Setting contrast to " << contrast.value(); - } -} - void Lut::updateGammaTable(IPAContext &context) { auto &gammaTable = context.activeState.gamma.gammaTable; @@ -87,11 +67,9 @@ int16_t Lut::matrixValue(unsigned int i, float ccm) const void Lut::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame, - IPAFrameContext &frameContext, + [[maybe_unused]] IPAFrameContext &frameContext, DebayerParams *params) { - frameContext.contrast = context.activeState.knobs.contrast; - /* * Update the gamma table if needed. This means if black level changes * and since the black level gets updated only if a lower value is @@ -143,17 +121,6 @@ void Lut::prepare(IPAContext &context, } } -void Lut::process([[maybe_unused]] IPAContext &context, - [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] IPAFrameContext &frameContext, - [[maybe_unused]] const SwIspStats *stats, - ControlList &metadata) -{ - const auto &contrast = frameContext.contrast; - if (contrast) - metadata.set(controls::Contrast, contrast.value()); -} - REGISTER_IPA_ALGORITHM(Lut, "Lut") } /* namespace ipa::soft::algorithms */ diff --git a/src/ipa/simple/algorithms/lut.h b/src/ipa/simple/algorithms/lut.h index 0eafd0695..ad16d1e8e 100644 --- a/src/ipa/simple/algorithms/lut.h +++ b/src/ipa/simple/algorithms/lut.h @@ -19,22 +19,11 @@ public: Lut() = default; ~Lut() = default; - int init(IPAContext &context, const YamlObject &tuningData) override; int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; - void queueRequest(typename Module::Context &context, - const uint32_t frame, - typename Module::FrameContext &frameContext, - const ControlList &controls) - override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, DebayerParams *params) override; - void process(IPAContext &context, - const uint32_t frame, - IPAFrameContext &frameContext, - const SwIspStats *stats, - ControlList &metadata) override; private: void updateGammaTable(IPAContext &context);