[libcamera-devel] [PATCH v1 4/5] ipa: raspberrypi: Use the generic statistics structure in the algorithms
David Plowman
david.plowman at raspberrypi.com
Wed Nov 23 15:34:20 CET 2022
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...?
> + 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)...?
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
>
More information about the libcamera-devel
mailing list