summaryrefslogtreecommitdiff
path: root/src/ipa
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa')
-rw-r--r--src/ipa/rpi/controller/agc_algorithm.h3
-rw-r--r--src/ipa/rpi/controller/rpi/agc.cpp27
-rw-r--r--src/ipa/rpi/controller/rpi/agc.h1
-rw-r--r--src/ipa/rpi/vc4/vc4.cpp26
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 36e6c110..b6949daa 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 e6fb7b8d..e79c82e2 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 &region = 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 4e5f272f..939f9729 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 &params) 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 a32db9bc..e38024ac 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++)