From patchwork Thu Oct 23 11:49:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 24831 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by patchwork.libcamera.org (Postfix) with ESMTPS id D37E2BE080 for ; Sun, 26 Oct 2025 23:32:10 +0000 (UTC) Received: from pendragon.ideasonboard.com (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 77B98AB4 for ; Mon, 27 Oct 2025 00:30:23 +0100 (CET) Authentication-Results: perceval.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.a=rsa-sha256 header.s=google header.b=ttBM8ABS; dkim-atps=neutral Delivered-To: kbingham@ideasonboard.com Received: from perceval.ideasonboard.com by perceval.ideasonboard.com with LMTP id WNtiFDcW+mhDUhcA4E0KoQ (envelope-from ) for ; Thu, 23 Oct 2025 13:49:11 +0200 Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by perceval.ideasonboard.com (Postfix) with ESMTPS id 7B7761D2B; Thu, 23 Oct 2025 13:49:04 +0200 (CEST) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 11D81607BE; Thu, 23 Oct 2025 13:50:48 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="ttBM8ABS"; dkim-atps=neutral Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0B66E607BE for ; Thu, 23 Oct 2025 13:50:44 +0200 (CEST) Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-428564f8d16so368484f8f.1 for ; Thu, 23 Oct 2025 04:50:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1761220243; x=1761825043; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MT+p1j+p/DveVI+kn0QiagoZ5EXuJnmCwmRZyRj4aXA=; b=ttBM8ABS2gj2I4AmuLSIPCZ6sJgLWGG7sNDlySGR6chfJyE/gzOp0/x2rQQtc9qzRk GmPeaXqc56TAgB/nVeTbI84jlq3W7TpFdggODx8w7iOxe7YBqKcArTwbkeyoR7o4bc2V AdurNiHmoShRwnrxhN5zE3rOsNERWgIKVv/Tt1HL7mpgBa3nbv9Sdza5KI4Hpv/RZ01F O8nCmRQTzmHLQCUcVAwROm+bf83xRAORCpJAsmPsk+5bBuIGgkkAo/Ma9w4YJCAt2hhU 7NQrT6Jiac1tJTo1nG6OMbON83y/l7v8yvB5Ex/3gbd13uIdyT9Cd+4r+x2oi7mu20t2 AxhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761220243; x=1761825043; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MT+p1j+p/DveVI+kn0QiagoZ5EXuJnmCwmRZyRj4aXA=; b=ck2WDHdkKm6Kn6arkXqJi9KBFLyjGgbblcEEL5CTbajFQ+WfqMrjEGVMcZ+qj0atwe oDNButMXvZsUEkGjYlkK1jlDDXaas4qORVdysjYShJP5I5uRSzAGo7rWUD4VzzmdZFO0 8tWrlSxt792pcjciPWZefNcTOvKjB2BCe+rbZV7CCtsiIQeugXWoHWV7wEXgezZ2gT8M ue10ZWYO5KmcxCfj5V7JICwrP76H3zsNTduqLxUWkQEmE+bGGeO5ZPcolH519BxuRX9q raoG9QL3MIQH6UilzcARVJL2hRnjruSv1Cx5mWNRay21qTt/25Ttrydgb6MHBaeIn1bJ cZyw== X-Gm-Message-State: AOJu0Yy/MDizx/oB80vU7nzRac3JDy+mmWS4zN8xmO+7JE0dMz+JHTHH FdzC6SznQPwfCm014qzDQHlE4LQfqxR1QBc3be1KfoXCLe7Msk4LFo0V6amy7aQ5LbNyjFrRJag MpzOTR6w= X-Gm-Gg: ASbGncsOKkJ4DfoQ/KH33QQsMIft0i0+x1QZu5Dj4mfSBkb4iPM4kVu7Czat8Ngb+B5 Ocaal6+ZIseHiCetU/se5NxiVld1o4iWssOhjV4oy3zKeK0mEluR8XAT8Huz8we9n7lVt1nnZhx s4HzTp3VJ15MChRmYk4ZSc+mHiLxBg+cOovnG8R1U6b98rBu9uKc/cc9CeGjQm7cHGEwphec51C cH7XHDZkVv4ot9nIbXyan3opKF3G87FIrJYLq/tq4JC9Qg9UzVdFPxZKhSygEliS0JbzF/FWPzx r289Gv+gMPmyhKR/ACLIk4CZa3wL/CTBhpr9QWnMFYY/7NnjcdFFhDd0ugOGE8HGU8tzTr2muab +8X4LNAqarPjJ9QmqK77eyGdEa9txhwicfYWAUyB8KPrbT4cL2XQKdrKQuRi/jLlwwMCmlEX5C1 FKcDyQBmtnTedo98UaPLLbf+OZpFyP1HuBL1M2mPomswV7GoxWZ+vH96trM9WJGqDjI0hgXl+Be XFTdTNOnx0FuEupgw== X-Google-Smtp-Source: =?utf-8?q?AGHT+IFFHOrG209SMiJEKUxtd+91iRl5RdS9mZ5yD?= =?utf-8?q?2WE/IG+0rrfKmIiFl9zQnQUQOmteaueaQjufA=3D=3D?= X-Received: by 2002:a05:6000:40dd:b0:427:548:6e3b with SMTP id ffacd0b85a97d-42853264540mr5156729f8f.13.1761220243149; Thu, 23 Oct 2025 04:50:43 -0700 (PDT) Received: from davidp-pi.pitowers.org ([2a00:1098:3142:1f:f75f:a9a5:3eb7:34d4]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4298b996aaasm1900760f8f.3.2025.10.23.04.50.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Oct 2025 04:50:42 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Stefan Klug , Naushir Patuck Subject: [PATCH v2 4/5] ipa: rpi: vc4: Use a floating statistics region for a full image Y sum Date: Thu, 23 Oct 2025 12:49:16 +0100 Message-ID: <20251023115034.2207-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251023115034.2207-1-david.plowman@raspberrypi.com> References: <20251023115034.2207-1-david.plowman@raspberrypi.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" X-TUID: 56uNb2kcEtX5 Resent-From: Kieran Bingham Resent-To: parsemail@patchwork.libcamera.org We're going to use a "floating statistics region" to store a full image Y sum. The VC4 platform actually has no floating region for this, but we can synthesize such a region as follows in software. We know that the 15 AGC regions that we do have are arranged to cover the whole image, and they cannot be changed. Adding up the R, G and B values here will get us most of the way to Y. But we do also need to know the most recent colour gains, so code must also be added to remember the last AWB status. With this change, algorithms can now look at the first floating region on both VC4 and PiSP platforms to get a full image Y average value. Signed-off-by: David Plowman Reviewed-by: Stefan Klug Reviewed-by: Naushir Patuck --- src/ipa/rpi/vc4/vc4.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp index ba43e474..19d7b9d8 100644 --- a/src/ipa/rpi/vc4/vc4.cpp +++ b/src/ipa/rpi/vc4/vc4.cpp @@ -43,6 +43,9 @@ public: IpaVc4() : IpaBase(), lsTable_(nullptr) { + lastAwbStatus_.gainR = 1.0; + lastAwbStatus_.gainG = 1.0; + lastAwbStatus_.gainB = 1.0; } ~IpaVc4() @@ -81,6 +84,9 @@ private: /* LS table allocation passed in from the pipeline handler. */ SharedFD lsTableHandle_; void *lsTable_; + + /* Remember the most recent AWB values. */ + AwbStatus lastAwbStatus_; }; int32_t IpaVc4::platformInit([[maybe_unused]] const InitParams ¶ms, [[maybe_unused]] InitResult *result) @@ -144,8 +150,10 @@ void IpaVc4::platformPrepareIsp([[maybe_unused]] const PrepareParams ¶ms, std::unique_lock lock(rpiMetadata); AwbStatus *awbStatus = rpiMetadata.getLocked("awb.status"); - if (awbStatus) + if (awbStatus) { applyAWB(awbStatus, ctrls); + lastAwbStatus_ = *awbStatus; + } CcmStatus *ccmStatus = rpiMetadata.getLocked("ccm.status"); if (ccmStatus) @@ -226,7 +234,13 @@ RPiController::StatisticsPtr IpaVc4::platformProcessStats(Span mem) LOG(IPARPI, Debug) << "No AGC algorithm - not copying statistics"; statistics->agcRegions.init(0); } else { - statistics->agcRegions.init(hw.agcRegions); + RgbySums fullImage; + uint32_t countedSum = 0; + uint32_t notCountedSum = 0; + /* We're going to pretend there's a floating region where we will put a full image Y sum. */ + const unsigned int numFloating = 1; + + statistics->agcRegions.init(hw.agcRegions, numFloating); const std::vector &weights = agc->getWeights(); for (i = 0; i < statistics->agcRegions.numRegions(); i++) { uint64_t rSum = (stats->agc_stats[i].r_sum << scale) * weights[i]; @@ -237,7 +251,20 @@ RPiController::StatisticsPtr IpaVc4::platformProcessStats(Span mem) statistics->agcRegions.set(i, { { rSum, gSum, bSum }, counted, notcounted }); + + /* Accumulate values for the full image Y sum. */ + fullImage.rSum += stats->agc_stats[i].r_sum << scale; + fullImage.gSum += stats->agc_stats[i].g_sum << scale; + fullImage.bSum += stats->agc_stats[i].b_sum << scale; + countedSum += stats->agc_stats[i].counted; + notCountedSum += stats->agc_stats[i].notcounted; } + + /* The "floating" region has the Y sum for the entire image. */ + fullImage.ySum = fullImage.rSum * lastAwbStatus_.gainR * 0.299 + + fullImage.gSum * lastAwbStatus_.gainG * 0.587 + + fullImage.bSum * lastAwbStatus_.gainB * 0.114; + statistics->agcRegions.setFloating(0, { fullImage, countedSum, notCountedSum }); } statistics->focusRegions.init(hw.focusRegions);