[libcamera-devel] [PATCH v1 4/5] ipa: raspberrypi: Use the generic statistics structure in the algorithms
Naushir Patuck
naush at raspberrypi.com
Wed Nov 23 15:53:03 CET 2022
Hi David,
Thank you for your feedback.
On Wed, 23 Nov 2022 at 14:34, David Plowman <david.plowman at raspberrypi.com>
wrote:
> Hi Naush
>
> Thanks for all these updates!
>
> On Tue, 22 Nov 2022 at 11:22, Naushir Patuck via libcamera-devel
> <libcamera-devel at lists.libcamera.org> wrote:
> >
> > 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, ALCS, Contrast, and Focus algorithms to use the
>
> s/ALCS/ALSC/ I think, I get muddled too!
>
> > 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 at raspberrypi.com>
> > ---
> > src/ipa/raspberrypi/controller/controller.h | 4 +-
> > src/ipa/raspberrypi/controller/rpi/agc.cpp | 26 ++++++-------
> > src/ipa/raspberrypi/controller/rpi/agc.h | 2 +-
> > src/ipa/raspberrypi/controller/rpi/alsc.cpp | 33 +++++++++-------
> > src/ipa/raspberrypi/controller/rpi/alsc.h | 3 +-
> > src/ipa/raspberrypi/controller/rpi/awb.cpp | 20 +++++-----
> > src/ipa/raspberrypi/controller/rpi/awb.h | 1 +
> > .../raspberrypi/controller/rpi/contrast.cpp | 8 ++--
> > src/ipa/raspberrypi/controller/rpi/focus.cpp | 7 ++--
> > src/ipa/raspberrypi/controller/rpi/lux.cpp | 13 +------
> > src/ipa/raspberrypi/raspberrypi.cpp | 39 ++++++++++++++++++-
> > src/ipa/raspberrypi/statistics.h | 2 +
> > 12 files changed, 95 insertions(+), 63 deletions(-)
> >
> > diff --git a/src/ipa/raspberrypi/controller/controller.h
> b/src/ipa/raspberrypi/controller/controller.h
> > index 3e1e051703b3..e6c950c3a509 100644
> > --- a/src/ipa/raspberrypi/controller/controller.h
> > +++ b/src/ipa/raspberrypi/controller/controller.h
> > @@ -15,19 +15,17 @@
> > #include <vector>
> > #include <string>
> >
> > -#include <linux/bcm2835-isp.h>
> > -
> > #include "libcamera/internal/yaml_parser.h"
> >
> > #include "camera_mode.h"
> > #include "device_status.h"
> > #include "metadata.h"
> > +#include "statistics.h"
> >
> > namespace RPiController {
> >
> > class Algorithm;
> > typedef std::unique_ptr<Algorithm> AlgorithmPtr;
> > -typedef std::shared_ptr<bcm2835_isp_stats> StatisticsPtr;
> >
> > /*
> > * The Controller holds a pointer to some global_metadata, which is how
> > diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp
> b/src/ipa/raspberrypi/controller/rpi/agc.cpp
> > index bd54a639d637..79c83e0a9eae 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"
> > @@ -450,7 +448,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);
>
> I suppose "stats.get()" was a bit of a promise that the function
> couldn't possibly acquire another reference or anything like that, but
> I don't think it matters!
>
> > /* Now compute the target (final) exposure which we think we
> want. */
> > computeTargetExposure(gain);
> > /*
> > @@ -584,20 +582,20 @@ 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++) {
> > + uint32_t counted, uncounted;
> > + auto s = stats->agcRegions.get(i, counted, uncounted);
> > + double rAcc = std::min<double>(s.rSum * gain, ((1 <<
> PipelineBits) - 1) * counted);
> > + double gAcc = std::min<double>(s.gSum * gain, ((1 <<
> PipelineBits) - 1) * counted);
> > + double bAcc = std::min<double>(s.bSum * gain, ((1 <<
> PipelineBits) - 1) * counted);
> > rSum += rAcc * weights[i];
> > gSum += gAcc * weights[i];
> > bSum += bAcc * weights[i];
> > @@ -623,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
> > diff --git a/src/ipa/raspberrypi/controller/rpi/agc.h
> b/src/ipa/raspberrypi/controller/rpi/agc.h
> > index 6d6b0e5ad857..0ea71e6d1aa0 100644
> > --- a/src/ipa/raspberrypi/controller/rpi/agc.h
> > +++ b/src/ipa/raspberrypi/controller/rpi/agc.h
> > @@ -98,7 +98,7 @@ private:
> > void housekeepConfig();
> > void fetchCurrentExposure(Metadata *imageMetadata);
> > void fetchAwbStatus(Metadata *imageMetadata);
> > - void computeGain(bcm2835_isp_stats *statistics, Metadata
> *imageMetadata,
> > + void computeGain(StatisticsPtr &statistics, Metadata
> *imageMetadata,
> > double &gain, double &targetY);
> > void computeTargetExposure(double gain);
> > bool applyDigitalGain(double gain, double targetY);
> > diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp
> b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
> > index a4afaf841c41..d8c650e6faa6 100644
> > --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp
> > +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
> > @@ -310,18 +310,22 @@ double getCt(Metadata *metadata, double defaultCt)
> > return awbStatus.temperatureK;
> > }
> >
> > -static void copyStats(bcm2835_isp_stats_region regions[XY],
> StatisticsPtr &stats,
> > +static void copyStats(RgbyRegions ®ions, StatisticsPtr &stats,
> > AlscStatus const &status)
> > {
> > - bcm2835_isp_stats_region *inputRegions = stats->awb_stats;
> > + if (!regions.numRegions())
> > + regions.init(stats->awbRegions.numRegions());
> > +
> > double *rTable = (double *)status.r;
> > double *gTable = (double *)status.g;
> > double *bTable = (double *)status.b;
> > - for (int i = 0; i < XY; i++) {
> > - regions[i].r_sum = inputRegions[i].r_sum / rTable[i];
> > - regions[i].g_sum = inputRegions[i].g_sum / gTable[i];
> > - regions[i].b_sum = inputRegions[i].b_sum / bTable[i];
> > - regions[i].counted = inputRegions[i].counted;
> > + for (unsigned int i = 0; i < stats->awbRegions.numRegions();
> i++) {
> > + uint32_t counted, uncounted;
> > + auto s = stats->awbRegions.get(i, counted, uncounted);
> > + regions.set(i, { s.rSum /
> static_cast<uint64_t>(rTable[i]),
>
> Just wondering a bit about the casts here, it doesn't look obviously
> the same as what we have above...?
>
I'll cast the result of the div to minimise rounding errors.
>
> > + s.gSum /
> static_cast<uint64_t>(gTable[i]),
> > + s.bSum /
> static_cast<uint64_t>(bTable[i]) },
> > + counted, uncounted);
> > /* (don't care about the uncounted value) */
> > }
> > }
> > @@ -512,19 +516,20 @@ void resampleCalTable(double const calTableIn[XY],
> > }
> >
> > /* Calculate chrominance statistics (R/G and B/G) for each region. */
> > -static_assert(XY == AWB_REGIONS, "ALSC/AWB statistics region mismatch");
> > -static void calculateCrCb(bcm2835_isp_stats_region *awbRegion, double
> cr[XY],
> > +static void calculateCrCb(const RgbyRegions &awbRegion, double cr[XY],
> > double cb[XY], uint32_t minCount, uint16_t
> minG)
> > {
> > for (int i = 0; i < XY; i++) {
> > - bcm2835_isp_stats_region &zone = awbRegion[i];
> > - if (zone.counted <= minCount ||
> > - zone.g_sum / zone.counted <= minG) {
> > + uint32_t counted, uncounted;
> > + auto s = awbRegion.get(i, counted, uncounted);
> > +
> > + if (counted <= minCount || s.gSum / counted <= minG) {
> > cr[i] = cb[i] = InsufficientData;
> > continue;
> > }
> > - cr[i] = zone.r_sum / (double)zone.g_sum;
> > - cb[i] = zone.b_sum / (double)zone.g_sum;
> > +
> > + cr[i] = s.rSum / (double)s.gSum;
> > + cb[i] = s.bSum / (double)s.gSum;
> > }
> > }
> >
> > diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.h
> b/src/ipa/raspberrypi/controller/rpi/alsc.h
> > index a858ef5a6551..9167c9ffa2e3 100644
> > --- a/src/ipa/raspberrypi/controller/rpi/alsc.h
> > +++ b/src/ipa/raspberrypi/controller/rpi/alsc.h
> > @@ -12,6 +12,7 @@
> >
> > #include "../algorithm.h"
> > #include "../alsc_status.h"
> > +#include "../statistics.h"
> >
> > namespace RPiController {
> >
> > @@ -98,7 +99,7 @@ private:
> > /* copy out the results from the async thread so that it can be
> restarted */
> > void fetchAsyncResults();
> > double ct_;
> > - bcm2835_isp_stats_region statistics_[AlscCellsY * AlscCellsX];
> > + RgbyRegions statistics_;
> > double asyncResults_[3][AlscCellsY][AlscCellsX];
> > double asyncLambdaR_[AlscCellsX * AlscCellsY];
> > double asyncLambdaB_[AlscCellsX * AlscCellsY];
> > diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp
> b/src/ipa/raspberrypi/controller/rpi/awb.cpp
> > index 861022014896..901498382c6b 100644
> > --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp
> > +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp
> > @@ -21,9 +21,6 @@ LOG_DEFINE_CATEGORY(RPiAwb)
> >
> > #define NAME "rpi.awb"
> >
> > -static constexpr unsigned int AwbStatsSizeX = DEFAULT_AWB_REGIONS_X;
> > -static constexpr unsigned int AwbStatsSizeY = DEFAULT_AWB_REGIONS_Y;
> > -
> > /*
> > * todo - the locking in this algorithm needs some tidying up as has
> been done
> > * elsewhere (ALSC and AGC).
> > @@ -406,17 +403,18 @@ void Awb::asyncFunc()
> > }
> >
> > static void generateStats(std::vector<Awb::RGB> &zones,
> > - bcm2835_isp_stats_region *stats, double
> minPixels,
> > + RgbyRegions &stats, double minPixels,
> > double minG)
> > {
> > - for (unsigned int i = 0; i < AwbStatsSizeX * AwbStatsSizeY; i++)
> {
> > + for (unsigned int i = 0; i < stats.numRegions(); i++) {
> > Awb::RGB zone;
> > - double counted = stats[i].counted;
> > + uint32_t counted, uncounted;
> > + auto s = stats.get(i, counted, uncounted);
> > if (counted >= minPixels) {
> > - zone.G = stats[i].g_sum / counted;
> > + zone.G = s.gSum / counted;
> > if (zone.G >= minG) {
> > - zone.R = stats[i].r_sum / counted;
> > - zone.B = stats[i].b_sum / counted;
> > + zone.R = s.rSum / counted;
> > + zone.B = s.bSum / counted;
> > zones.push_back(zone);
> > }
> > }
> > @@ -430,7 +428,7 @@ void Awb::prepareStats()
> > * LSC has already been applied to the stats in this pipeline,
> so stop
> > * any LSC compensation. We also ignore config_.fast in this
> version.
> > */
> > - generateStats(zones_, statistics_->awb_stats, config_.minPixels,
> > + generateStats(zones_, statistics_->awbRegions, config_.minPixels,
> > config_.minG);
> > /*
> > * apply sensitivities, so values appear to come from our
> "canonical"
> > @@ -646,7 +644,7 @@ void Awb::awbBayes()
> > * valid... not entirely sure about this.
> > */
> > Pwl prior = interpolatePrior();
> > - prior *= zones_.size() / (double)(AwbStatsSizeX * AwbStatsSizeY);
> > + prior *= zones_.size() /
> (double)(statistics_->awbRegions.numRegions());
> > prior.map([](double x, double y) {
> > LOG(RPiAwb, Debug) << "(" << x << "," << y << ")";
> > });
> > diff --git a/src/ipa/raspberrypi/controller/rpi/awb.h
> b/src/ipa/raspberrypi/controller/rpi/awb.h
> > index 30acd89d0969..d81779dd51ff 100644
> > --- a/src/ipa/raspberrypi/controller/rpi/awb.h
> > +++ b/src/ipa/raspberrypi/controller/rpi/awb.h
> > @@ -13,6 +13,7 @@
> > #include "../awb_algorithm.h"
> > #include "../pwl.h"
> > #include "../awb_status.h"
> > +#include "../statistics.h"
> >
> > namespace RPiController {
> >
> > diff --git a/src/ipa/raspberrypi/controller/rpi/contrast.cpp
> b/src/ipa/raspberrypi/controller/rpi/contrast.cpp
> > index 5b37edcbd46a..a4f8c4f04fc4 100644
> > --- a/src/ipa/raspberrypi/controller/rpi/contrast.cpp
> > +++ b/src/ipa/raspberrypi/controller/rpi/contrast.cpp
> > @@ -106,7 +106,7 @@ Pwl computeStretchCurve(Histogram const &histogram,
> > * bit.
> > */
> > double histLo = histogram.quantile(config.loHistogram) *
> > - (65536 / NUM_HISTOGRAM_BINS);
> > + (65536 / histogram.bins());
> > double levelLo = config.loLevel * 65536;
> > LOG(RPiContrast, Debug)
> > << "Move histogram point " << histLo << " to " <<
> levelLo;
> > @@ -119,7 +119,7 @@ Pwl computeStretchCurve(Histogram const &histogram,
> > * Keep the mid-point (median) in the same place, though, to
> limit the
> > * apparent amount of global brightness shift.
> > */
> > - double mid = histogram.quantile(0.5) * (65536 /
> NUM_HISTOGRAM_BINS);
> > + double mid = histogram.quantile(0.5) * (65536 /
> histogram.bins());
> > enhance.append(mid, mid);
> >
> > /*
> > @@ -127,7 +127,7 @@ Pwl computeStretchCurve(Histogram const &histogram,
> > * there up.
> > */
> > double histHi = histogram.quantile(config.hiHistogram) *
> > - (65536 / NUM_HISTOGRAM_BINS);
> > + (65536 / histogram.bins());
> > double levelHi = config.hiLevel * 65536;
> > LOG(RPiContrast, Debug)
> > << "Move histogram point " << histHi << " to " <<
> levelHi;
> > @@ -158,7 +158,7 @@ Pwl applyManualContrast(Pwl const &gammaCurve,
> double brightness,
> > void Contrast::process(StatisticsPtr &stats,
> > [[maybe_unused]] Metadata *imageMetadata)
> > {
> > - Histogram histogram(stats->hist[0].g_hist, NUM_HISTOGRAM_BINS);
> > + Histogram &histogram = stats->yHist;
> > /*
> > * We look at the histogram and adjust the gamma curve in the
> following
> > * ways: 1. Adjust the gamma curve so as to pull the start of the
> > diff --git a/src/ipa/raspberrypi/controller/rpi/focus.cpp
> b/src/ipa/raspberrypi/controller/rpi/focus.cpp
> > index 8c5029bd0e95..41afbf43f2b7 100644
> > --- a/src/ipa/raspberrypi/controller/rpi/focus.cpp
> > +++ b/src/ipa/raspberrypi/controller/rpi/focus.cpp
> > @@ -32,9 +32,10 @@ void Focus::process(StatisticsPtr &stats, Metadata
> *imageMetadata)
> > {
> > FocusStatus status;
> > unsigned int i;
> > - for (i = 0; i < FOCUS_REGIONS; i++)
> > - status.focusMeasures[i] =
> stats->focus_stats[i].contrast_val[1][1] / 1000;
> > - status.num = i;
> > + uint32_t counted, uncounted;
> > + for (i = 0; i < stats->focusRegions.numRegions(); i++)
> > + status.focusMeasures[i] = stats->focusRegions.get(i,
> counted, uncounted);
> > + status.num = stats->focusRegions.numRegions();
> > imageMetadata->set("focus.status", status);
> >
> > LOG(RPiFocus, Debug)
> > diff --git a/src/ipa/raspberrypi/controller/rpi/lux.cpp
> b/src/ipa/raspberrypi/controller/rpi/lux.cpp
> > index 9759186afacf..a49d402707c7 100644
> > --- a/src/ipa/raspberrypi/controller/rpi/lux.cpp
> > +++ b/src/ipa/raspberrypi/controller/rpi/lux.cpp
> > @@ -6,8 +6,6 @@
> > */
> > #include <math.h>
> >
> > -#include <linux/bcm2835-isp.h>
> > -
> > #include <libcamera/base/log.h>
> >
> > #include "../device_status.h"
> > @@ -83,20 +81,13 @@ void Lux::process(StatisticsPtr &stats, Metadata
> *imageMetadata)
> > if (imageMetadata->get("device.status", deviceStatus) == 0) {
> > double currentGain = deviceStatus.analogueGain;
> > double currentAperture =
> deviceStatus.aperture.value_or(currentAperture_);
> > - uint64_t sum = 0;
> > - uint32_t num = 0;
> > - uint32_t *bin = stats->hist[0].g_hist;
> > - const int numBins = sizeof(stats->hist[0].g_hist) /
> > - sizeof(stats->hist[0].g_hist[0]);
> > - for (int i = 0; i < numBins; i++)
> > - sum += bin[i] * (uint64_t)i, num += bin[i];
> > /* add .5 to reflect the mid-points of bins */
> > - double currentY = sum / (double)num + .5;
> > + double currentY = stats->yHist.total() /
> stats->yHist.bins() + .5;
>
> Is this the same thing? I have a bad feeling this might be the average
> number of pixels per bin, or something. Maybe we need something
> involving yHist.interQuantileMean(0, 1)...?
>
Argh, luckily we never use Lux values :-)
yHist.interQuantileMean(0, 1) will be the right substitute here.
Naush
>
> Thanks!
> David
>
> > double gainRatio = referenceGain_ / currentGain;
> > double shutterSpeedRatio =
> > referenceShutterSpeed_ /
> deviceStatus.shutterSpeed;
> > double apertureRatio = referenceAperture_ /
> currentAperture;
> > - double yRatio = currentY * (65536 / numBins) /
> referenceY_;
> > + double yRatio = currentY * (65536 / stats->yHist.bins())
> / referenceY_;
> > double estimatedLux = shutterSpeedRatio * gainRatio *
> > apertureRatio * apertureRatio *
> > yRatio * referenceLux_;
> > diff --git a/src/ipa/raspberrypi/raspberrypi.cpp
> b/src/ipa/raspberrypi/raspberrypi.cpp
> > index b74f1ecf738f..8fcfa0b3ea50 100644
> > --- a/src/ipa/raspberrypi/raspberrypi.cpp
> > +++ b/src/ipa/raspberrypi/raspberrypi.cpp
> > @@ -51,6 +51,7 @@
> > #include "metadata.h"
> > #include "sharpen_algorithm.h"
> > #include "sharpen_status.h"
> > +#include "statistics.h"
> >
> > namespace libcamera {
> >
> > @@ -136,6 +137,7 @@ private:
> > void prepareISP(const ISPConfig &data);
> > void reportMetadata();
> > void fillDeviceStatus(const ControlList &sensorControls);
> > + RPiController::StatisticsPtr fillStatistics(bcm2835_isp_stats
> *stats) const;
> > void processStats(unsigned int bufferId);
> > void applyFrameDurations(Duration minFrameDuration, Duration
> maxFrameDuration);
> > void applyAGC(const struct AgcStatus *agcStatus, ControlList
> &ctrls);
> > @@ -1119,6 +1121,41 @@ void IPARPi::fillDeviceStatus(const ControlList
> &sensorControls)
> > rpiMetadata_.set("device.status", deviceStatus);
> > }
> >
> > +RPiController::StatisticsPtr IPARPi::fillStatistics(bcm2835_isp_stats
> *stats) const
> > +{
> > + using namespace RPiController;
> > +
> > + unsigned int i;
> > + StatisticsPtr statistics =
> > +
> std::make_unique<Statistics>(Statistics::AgcStatsPos::PreWb,
> Statistics::ColourStatsPos::PostLsc);
> > +
> > + /* RGB histograms are not used, so do not populate them. */
> > + statistics->yHist =
> std::move(RPiController::Histogram(stats->hist[0].g_hist,
> NUM_HISTOGRAM_BINS));
> > +
> > + statistics->awbRegions.init(DEFAULT_AWB_REGIONS_X,
> DEFAULT_AWB_REGIONS_Y);
> > + for (i = 0; i < statistics->awbRegions.numRegions(); i++)
> > + statistics->awbRegions.set(i, {
> stats->awb_stats[i].r_sum,
> > +
> stats->awb_stats[i].g_sum,
> > +
> stats->awb_stats[i].b_sum },
> > + stats->awb_stats[i].counted,
> stats->awb_stats[i].notcounted);
> > +
> > + /* There are only ever 15 regions computed by the firmware, but
> the HW defines AGC_REGIONS == 16! */
> > + statistics->agcRegions.init(15);
> > + for (i = 0; i < statistics->agcRegions.numRegions(); i++)
> > + statistics->agcRegions.set(i, {
> stats->agc_stats[i].r_sum,
> > +
> stats->agc_stats[i].g_sum,
> > +
> stats->agc_stats[i].b_sum },
> > + stats->agc_stats[i].counted,
> 0);
> > +
> > + statistics->focusRegions.init(4, 3);
> > + for (i = 0; i < FOCUS_REGIONS; i++)
> > + statistics->focusRegions.set(i,
> stats->focus_stats[i].contrast_val[1][1] / 1000,
> > +
> stats->focus_stats[i].contrast_val_num[1][1],
> > +
> stats->focus_stats[i].contrast_val_num[1][0]);
> > +
> > + return statistics;
> > +}
> > +
> > void IPARPi::processStats(unsigned int bufferId)
> > {
> > auto it = buffers_.find(bufferId);
> > @@ -1129,7 +1166,7 @@ void IPARPi::processStats(unsigned int bufferId)
> >
> > Span<uint8_t> mem = it->second.planes()[0];
> > bcm2835_isp_stats *stats = reinterpret_cast<bcm2835_isp_stats
> *>(mem.data());
> > - RPiController::StatisticsPtr statistics =
> std::make_shared<bcm2835_isp_stats>(*stats);
> > + RPiController::StatisticsPtr statistics = fillStatistics(stats);
> > helper_->process(statistics, rpiMetadata_);
> > controller_.process(statistics, &rpiMetadata_);
> >
> > diff --git a/src/ipa/raspberrypi/statistics.h
> b/src/ipa/raspberrypi/statistics.h
> > index a762bf3d41aa..affb7272c963 100644
> > --- a/src/ipa/raspberrypi/statistics.h
> > +++ b/src/ipa/raspberrypi/statistics.h
> > @@ -67,4 +67,6 @@ struct Statistics {
> > FocusRegions focusRegions;
> > };
> >
> > +using StatisticsPtr = std::shared_ptr<Statistics>;
> > +
> > } /* namespace RPiController */
> > --
> > 2.25.1
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20221123/444ba630/attachment.htm>
More information about the libcamera-devel
mailing list