[libcamera-devel] [PATCH 10/13] ipa: raspberrypi: agc: Move weights out of AGC
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Thu May 4 19:59:22 CEST 2023
On Wed, May 03, 2023 at 01:20:32PM +0100, Naushir Patuck via libcamera-devel wrote:
> From: David Plowman <david.plowman at raspberrypi.com>
>
> The region weights for the the AGC zones are handled by the AGC
> algorithm. Apply them directly in the IPA (vc4.cpp) to the statistics
> that we pass to the AGC.
>
> Signed-off-by: David Plowman <david.plowman at raspberrypi>
There's a .com missing. I'll add it.
> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
> Reviewed-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
> src/ipa/rpi/controller/agc_algorithm.h | 3 +++
> src/ipa/rpi/controller/rpi/agc.cpp | 27 +++++++++++++++++---------
> src/ipa/rpi/controller/rpi/agc.h | 1 +
> src/ipa/rpi/vc4/vc4.cpp | 26 ++++++++++++++++++-------
> 4 files changed, 41 insertions(+), 16 deletions(-)
>
> diff --git a/src/ipa/rpi/controller/agc_algorithm.h b/src/ipa/rpi/controller/agc_algorithm.h
> index 36e6c11058ee..b6949daa7135 100644
> --- a/src/ipa/rpi/controller/agc_algorithm.h
> +++ b/src/ipa/rpi/controller/agc_algorithm.h
> @@ -6,6 +6,8 @@
> */
> #pragma once
>
> +#include <vector>
> +
> #include <libcamera/base/utils.h>
>
> #include "algorithm.h"
> @@ -18,6 +20,7 @@ public:
> AgcAlgorithm(Controller *controller) : Algorithm(controller) {}
> /* An AGC algorithm must provide the following: */
> virtual unsigned int getConvergenceFrames() const = 0;
> + virtual std::vector<double> const &getWeights() const = 0;
> virtual void setEv(double ev) = 0;
> virtual void setFlickerPeriod(libcamera::utils::Duration flickerPeriod) = 0;
> virtual void setFixedShutter(libcamera::utils::Duration fixedShutter) = 0;
> diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp
> index e6fb7b8dbeb3..e79c82e2e65b 100644
> --- a/src/ipa/rpi/controller/rpi/agc.cpp
> +++ b/src/ipa/rpi/controller/rpi/agc.cpp
> @@ -292,6 +292,18 @@ unsigned int Agc::getConvergenceFrames() const
> return config_.convergenceFrames;
> }
>
> +std::vector<double> const &Agc::getWeights() const
> +{
> + /*
> + * In case someone calls setMeteringMode and then this before the
> + * algorithm has run and updated the meteringMode_ pointer.
> + */
> + auto it = config_.meteringModes.find(meteringModeName_);
> + if (it == config_.meteringModes.end())
> + return meteringMode_->weights;
> + return it->second.weights;
> +}
> +
> void Agc::setEv(double ev)
> {
> ev_ = ev;
> @@ -595,19 +607,16 @@ static double computeInitialY(StatisticsPtr &stats, AwbStatus const &awb,
> ASSERT(weights.size() == stats->agcRegions.numRegions());
>
> /*
> - * Note how the calculation below means that equal weights give you
> - * "average" metering (i.e. all pixels equally important).
> + * Note that the weights are applied by the IPA to the statistics directly,
> + * before they are given to us here.
> */
> double rSum = 0, gSum = 0, bSum = 0, pixelSum = 0;
> for (unsigned int i = 0; i < stats->agcRegions.numRegions(); i++) {
> auto ®ion = stats->agcRegions.get(i);
> - double rAcc = std::min<double>(region.val.rSum * gain, (maxVal - 1) * region.counted);
> - double gAcc = std::min<double>(region.val.gSum * gain, (maxVal - 1) * region.counted);
> - double bAcc = std::min<double>(region.val.bSum * gain, (maxVal - 1) * region.counted);
> - rSum += rAcc * weights[i];
> - gSum += gAcc * weights[i];
> - bSum += bAcc * weights[i];
> - pixelSum += region.counted * weights[i];
> + rSum += std::min<double>(region.val.rSum * gain, (maxVal - 1) * region.counted);
> + gSum += std::min<double>(region.val.gSum * gain, (maxVal - 1) * region.counted);
> + bSum += std::min<double>(region.val.bSum * gain, (maxVal - 1) * region.counted);
> + pixelSum += region.counted;
> }
> if (pixelSum == 0.0) {
> LOG(RPiAgc, Warning) << "computeInitialY: pixelSum is zero";
> diff --git a/src/ipa/rpi/controller/rpi/agc.h b/src/ipa/rpi/controller/rpi/agc.h
> index 4e5f272fac78..939f97295a02 100644
> --- a/src/ipa/rpi/controller/rpi/agc.h
> +++ b/src/ipa/rpi/controller/rpi/agc.h
> @@ -69,6 +69,7 @@ public:
> char const *name() const override;
> int read(const libcamera::YamlObject ¶ms) override;
> unsigned int getConvergenceFrames() const override;
> + std::vector<double> const &getWeights() const override;
> void setEv(double ev) override;
> void setFlickerPeriod(libcamera::utils::Duration flickerPeriod) override;
> void setMaxShutter(libcamera::utils::Duration maxShutter) override;
> diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp
> index a32db9bcaf9a..e38024ac5418 100644
> --- a/src/ipa/rpi/vc4/vc4.cpp
> +++ b/src/ipa/rpi/vc4/vc4.cpp
> @@ -211,13 +211,25 @@ RPiController::StatisticsPtr IpaVc4::platformProcessStats(Span<uint8_t> mem)
> stats->awb_stats[i].counted,
> stats->awb_stats[i].notcounted });
>
> - statistics->agcRegions.init(hw.agcRegions);
> - for (i = 0; i < statistics->agcRegions.numRegions(); i++)
> - statistics->agcRegions.set(i, { { stats->agc_stats[i].r_sum << scale,
> - stats->agc_stats[i].g_sum << scale,
> - stats->agc_stats[i].b_sum << scale },
> - stats->agc_stats[i].counted,
> - stats->awb_stats[i].notcounted });
> + RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
> + controller_.getAlgorithm("agc"));
> + if (!agc) {
> + LOG(IPARPI, Debug) << "No AGC algorithm - not copying statistics";
> + statistics->agcRegions.init(0);
> + } else {
> + statistics->agcRegions.init(hw.agcRegions);
> + const std::vector<double> &weights = agc->getWeights();
> + for (i = 0; i < statistics->agcRegions.numRegions(); i++) {
> + uint64_t rSum = (stats->agc_stats[i].r_sum << scale) * weights[i];
> + uint64_t gSum = (stats->agc_stats[i].g_sum << scale) * weights[i];
> + uint64_t bSum = (stats->agc_stats[i].b_sum << scale) * weights[i];
> + uint32_t counted = stats->agc_stats[i].counted * weights[i];
> + uint32_t notcounted = stats->agc_stats[i].notcounted * weights[i];
> + statistics->agcRegions.set(i, { { rSum, gSum, bSum },
> + counted,
> + notcounted });
> + }
> + }
>
> statistics->focusRegions.init(hw.focusRegions);
> for (i = 0; i < statistics->focusRegions.numRegions(); i++)
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list