summaryrefslogtreecommitdiff
path: root/src/ipa/raspberrypi/controller/rpi/agc.cpp
diff options
context:
space:
mode:
authorNaushir Patuck <naush@raspberrypi.com>2023-02-09 12:47:35 +0000
committerKieran Bingham <kieran.bingham@ideasonboard.com>2023-02-09 13:11:30 +0000
commit6d60f264d1e05bd19640b66bc72bda9f303bf72d (patch)
tree18d98783e0346b315dbeb61ba04af6f12377cb61 /src/ipa/raspberrypi/controller/rpi/agc.cpp
parente8dd0fdc8321dce4c15b55b895e9efb5181ddb4c (diff)
ipa: raspberrypi: Use the generic statistics structure in the algorithms
Repurpose the StatisticsPtr type from being a shared_ptr<bcm2835_isp_stats> to shared_ptr<RPiController::Statistics>. This removes any hardware specific header files and structures from the algorithms source code. Add a new function in the Raspberry Pi IPA to populate the generic statistics structure from the values provided by the hardware in the bcm2835_isp_stats structure. Update the Lux, AWB, AGC, ALSC, Contrast, and Focus algorithms to use the generic statistics structure appropriately in their calculations. Additionally, remove references to any hardware specific headers and defines in these source files. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Tested-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'src/ipa/raspberrypi/controller/rpi/agc.cpp')
-rw-r--r--src/ipa/raspberrypi/controller/rpi/agc.cpp27
1 files changed, 12 insertions, 15 deletions
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp
index 46dcc81a..868c30f0 100644
--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp
+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp
@@ -9,8 +9,6 @@
#include <map>
#include <tuple>
-#include <linux/bcm2835-isp.h>
-
#include <libcamera/base/log.h>
#include "../awb_status.h"
@@ -451,7 +449,7 @@ void Agc::process(StatisticsPtr &stats, Metadata *imageMetadata)
fetchCurrentExposure(imageMetadata);
/* Compute the total gain we require relative to the current exposure. */
double gain, targetY;
- computeGain(stats.get(), imageMetadata, gain, targetY);
+ computeGain(stats, imageMetadata, gain, targetY);
/* Now compute the target (final) exposure which we think we want. */
computeTargetExposure(gain);
/*
@@ -585,24 +583,23 @@ void Agc::fetchAwbStatus(Metadata *imageMetadata)
LOG(RPiAgc, Debug) << "No AWB status found";
}
-static double computeInitialY(bcm2835_isp_stats *stats, AwbStatus const &awb,
+static double computeInitialY(StatisticsPtr &stats, AwbStatus const &awb,
double weights[], double gain)
{
- bcm2835_isp_stats_region *regions = stats->agc_stats;
/*
* Note how the calculation below means that equal weights give you
* "average" metering (i.e. all pixels equally important).
*/
double rSum = 0, gSum = 0, bSum = 0, pixelSum = 0;
- for (unsigned int i = 0; i < AgcStatsSize; i++) {
- double counted = regions[i].counted;
- double rAcc = std::min(regions[i].r_sum * gain, ((1 << PipelineBits) - 1) * counted);
- double gAcc = std::min(regions[i].g_sum * gain, ((1 << PipelineBits) - 1) * counted);
- double bAcc = std::min(regions[i].b_sum * gain, ((1 << PipelineBits) - 1) * counted);
+ 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, ((1 << PipelineBits) - 1) * region.counted);
+ double gAcc = std::min<double>(region.val.gSum * gain, ((1 << PipelineBits) - 1) * region.counted);
+ double bAcc = std::min<double>(region.val.bSum * gain, ((1 << PipelineBits) - 1) * region.counted);
rSum += rAcc * weights[i];
gSum += gAcc * weights[i];
bSum += bAcc * weights[i];
- pixelSum += counted * weights[i];
+ pixelSum += region.counted * weights[i];
}
if (pixelSum == 0.0) {
LOG(RPiAgc, Warning) << "computeInitialY: pixelSum is zero";
@@ -624,23 +621,23 @@ static double computeInitialY(bcm2835_isp_stats *stats, AwbStatus const &awb,
static constexpr double EvGainYTargetLimit = 0.9;
-static double constraintComputeGain(AgcConstraint &c, Histogram &h, double lux,
+static double constraintComputeGain(AgcConstraint &c, const Histogram &h, double lux,
double evGain, double &targetY)
{
targetY = c.yTarget.eval(c.yTarget.domain().clip(lux));
targetY = std::min(EvGainYTargetLimit, targetY * evGain);
double iqm = h.interQuantileMean(c.qLo, c.qHi);
- return (targetY * NUM_HISTOGRAM_BINS) / iqm;
+ return (targetY * h.bins()) / iqm;
}
-void Agc::computeGain(bcm2835_isp_stats *statistics, Metadata *imageMetadata,
+void Agc::computeGain(StatisticsPtr &statistics, Metadata *imageMetadata,
double &gain, double &targetY)
{
struct LuxStatus lux = {};
lux.lux = 400; /* default lux level to 400 in case no metadata found */
if (imageMetadata->get("lux.status", lux) != 0)
LOG(RPiAgc, Warning) << "No lux level found";
- Histogram h(statistics->hist[0].g_hist, NUM_HISTOGRAM_BINS);
+ const Histogram &h = statistics->yHist;
double evGain = status_.ev * config_.baseEv;
/*
* The initial gain and target_Y come from some of the regions. After