From 0810b8a70a1f4f05327c8e938b0669dcefdc26cc Mon Sep 17 00:00:00 2001 From: David Plowman Date: Thu, 23 Oct 2025 12:49:16 +0100 Subject: [PATCH] ipa: rpi: vc4: Use a floating statistics region for a full image Y sum 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 Signed-off-by: Kieran Bingham --- 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 b2fec934..2b205b28 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() @@ -83,6 +86,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) @@ -147,8 +153,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) @@ -234,7 +242,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]; @@ -245,7 +259,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);