Message ID | 20210809092007.79067-6-jeanmichel.hautbois@ideasonboard.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi JM, Thanks for the patch. On 8/9/21 2:50 PM, Jean-Michel Hautbois wrote: > Use the Context class and algorithm interface to properly call the AGC > algorithm from IPAIPU3. > We need to pass shutter speed and analogue gain through Context. Add a > dedicated AGC structure for that. > > Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> > --- > .../ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} | 56 ++++++++++--------- > src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} | 31 +++++----- > src/ipa/ipu3/algorithms/meson.build | 1 + > src/ipa/ipu3/ipa_context.h | 11 ++++ > src/ipa/ipu3/ipu3.cpp | 25 +++++---- > src/ipa/ipu3/meson.build | 1 - > 6 files changed, 70 insertions(+), 55 deletions(-) > rename src/ipa/ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} (81%) > rename src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} (61%) > > diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp > similarity index 81% > rename from src/ipa/ipu3/ipu3_agc.cpp > rename to src/ipa/ipu3/algorithms/agc.cpp > index 733814dd..1146a34a 100644 > --- a/src/ipa/ipu3/ipu3_agc.cpp > +++ b/src/ipa/ipu3/algorithms/agc.cpp > @@ -2,26 +2,25 @@ > /* > * Copyright (C) 2021, Ideas On Board SPDX license missing, I think it's missing in 4/5 too > * > - * ipu3_agc.cpp - AGC/AEC control algorithm > + * agc.cpp - AGC/AEC control algorithm > */ > > -#include "ipu3_agc.h" > +#include "agc.h" > > -#include <algorithm> > #include <cmath> > + > +#include <algorithm> I guess this a transient change that creeped in? :) > #include <numeric> > > #include <libcamera/base/log.h> > > -#include <libcamera/ipa/core_ipa_interface.h> > - > #include "libipa/histogram.h" > > namespace libcamera { > > using namespace std::literals::chrono_literals; > > -namespace ipa::ipu3 { > +namespace ipa::ipu3::algorithms { > > LOG_DEFINE_CATEGORY(IPU3Agc) > > @@ -36,8 +35,8 @@ static constexpr uint32_t kMaxISO = 1500; > > /* Maximum analogue gain value > * \todo grab it from a camera helper */ > -static constexpr uint32_t kMinGain = kMinISO / 100; > -static constexpr uint32_t kMaxGain = kMaxISO / 100; > +static constexpr double kMinGain = kMinISO / 100; > +static constexpr double kMaxGain = kMaxISO / 100; Probably "/ 100.0" , if you want converted to double? > > /* \todo use calculated value based on sensor */ > static constexpr uint32_t kMinExposure = 1; > @@ -50,24 +49,24 @@ static constexpr double kEvGainTarget = 0.5; > /* A cell is 8 bytes and contains averages for RGB values and saturation ratio */ > static constexpr uint8_t kCellSize = 8; > > -IPU3Agc::IPU3Agc() > +Agc::Agc() > : frameCount_(0), lastFrame_(0), converged_(false), > - updateControls_(false), iqMean_(0.0), > - lineDuration_(0s), maxExposureTime_(0s), > + updateControls_(false), iqMean_(0.0), maxExposureTime_(0s), > prevExposure_(0s), prevExposureNoDg_(0s), > currentExposure_(0s), currentExposureNoDg_(0s) > { > } > > -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo) > +int Agc::configure(IPAContext &context) > { > - aeGrid_ = bdsGrid; > + /* The AGC algorithm uses the AWB statistics */ > + aeGrid_ = context.awb.grid.bdsGrid; > + maxExposureTime_ = kMaxExposure * context.agc.lineDuration; > > - lineDuration_ = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; > - maxExposureTime_ = kMaxExposure * lineDuration_; > + return 0; > } > > -void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) > +void Agc::processBrightness(const ipu3_uapi_stats_3a *stats) > { > const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid; > Rectangle aeRegion = { statsAeGrid.x_start, > @@ -108,7 +107,7 @@ void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) > iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0); > } > > -void IPU3Agc::filterExposure() > +void Agc::filterExposure() > { > double speed = 0.2; > if (prevExposure_ == 0s) { > @@ -128,7 +127,7 @@ void IPU3Agc::filterExposure() > prevExposure_ = speed * currentExposure_ + > prevExposure_ * (1.0 - speed); > prevExposureNoDg_ = speed * currentExposureNoDg_ + > - prevExposureNoDg_ * (1.0 - speed); > + prevExposureNoDg_ * (1.0 - speed); > } > /* > * We can't let the no_dg exposure deviate too far below the > @@ -142,7 +141,7 @@ void IPU3Agc::filterExposure() > LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_; > } > > -void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) > +void Agc::lockExposureGain(IPAContext &context) > { > updateControls_ = false; > > @@ -160,7 +159,9 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) > double newGain = kEvGainTarget * knumHistogramBins / iqMean_; > > /* extracted from Rpi::Agc::computeTargetExposure */ > - libcamera::utils::Duration currentShutter = exposure * lineDuration_; > + libcamera::utils::Duration currentShutter = context.agc.shutterTime; > + uint32_t exposure = currentShutter / context.agc.lineDuration; > + double &gain = context.agc.analogueGain; > currentExposureNoDg_ = currentShutter * gain; > LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ > << " Shutter speed " << currentShutter > @@ -177,26 +178,27 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) > if (currentShutter < maxExposureTime_) { > exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure); > newExposure = currentExposure_ / exposure; > - gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); > + gain = std::clamp(static_cast<double>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); > updateControls_ = true; > } else if (currentShutter >= maxExposureTime_) { > - gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); > + gain = std::clamp(static_cast<double>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); > newExposure = currentExposure_ / gain; > exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure); > updateControls_ = true; > } > - LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain; > + context.agc.shutterTime = exposure * context.agc.lineDuration; > + LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * context.agc.lineDuration << " and gain " << gain; > } > lastFrame_ = frameCount_; > } > > -void IPU3Agc::process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain) > +void Agc::process(IPAContext &context) > { > - processBrightness(stats); > - lockExposureGain(exposure, gain); > + processBrightness(context.stats); > + lockExposureGain(context); > frameCount_++; > } > > -} /* namespace ipa::ipu3 */ > +} /* namespace ipa::ipu3::algorithms */ > > } /* namespace libcamera */ > diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/algorithms/agc.h > similarity index 61% > rename from src/ipa/ipu3/ipu3_agc.h > rename to src/ipa/ipu3/algorithms/agc.h > index 3b7f781e..e87a06f3 100644 > --- a/src/ipa/ipu3/ipu3_agc.h > +++ b/src/ipa/ipu3/algorithms/agc.h > @@ -4,44 +4,44 @@ > * > * ipu3_agc.h - IPU3 AGC/AEC control algorithm > */ > -#ifndef __LIBCAMERA_IPU3_AGC_H__ > -#define __LIBCAMERA_IPU3_AGC_H__ > +#ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ > +#define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ > + > +#include <linux/intel-ipu3.h> > > #include <array> > #include <unordered_map> > > -#include <linux/intel-ipu3.h> > - > #include <libcamera/base/utils.h> > > #include <libcamera/geometry.h> > > -#include "algorithms/algorithm.h" > -#include "libipa/algorithm.h" > +#include "algorithm.h" > > namespace libcamera { > > struct IPACameraSensorInfo; > > -namespace ipa::ipu3 { > +namespace ipa::ipu3::algorithms { > > using utils::Duration; > > -class IPU3Agc : public ipa::Algorithm > +class Agc : public Algorithm > { > public: > - IPU3Agc(); > - ~IPU3Agc() = default; > + Agc(); > + ~Agc() = default; > + > + int configure(IPAContext &context) override; > + void process(IPAContext &context) override; > > - void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo); > - void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain); > bool converged() { return converged_; } > bool updateControls() { return updateControls_; } > > private: > void processBrightness(const ipu3_uapi_stats_3a *stats); > void filterExposure(); > - void lockExposureGain(uint32_t &exposure, double &gain); > + void lockExposureGain(IPAContext &context); > > struct ipu3_uapi_grid_config aeGrid_; > > @@ -53,7 +53,6 @@ private: > > double iqMean_; > > - Duration lineDuration_; > Duration maxExposureTime_; > > Duration prevExposure_; > @@ -62,8 +61,8 @@ private: > Duration currentExposureNoDg_; > }; > > -} /* namespace ipa::ipu3 */ > +} /* namespace ipa::ipu3::algorithms */ > > } /* namespace libcamera */ > > -#endif /* __LIBCAMERA_IPU3_AGC_H__ */ > +#endif /* __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ */ > diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build > index df36d719..3faf913e 100644 > --- a/src/ipa/ipu3/algorithms/meson.build > +++ b/src/ipa/ipu3/algorithms/meson.build > @@ -1,6 +1,7 @@ > # SPDX-License-Identifier: CC0-1.0 > > ipu3_ipa_algorithms = files([ > + 'agc.cpp', > 'awb.cpp', > 'contrast.cpp', > ]) > diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h > index c43b275b..1d7a1984 100644 > --- a/src/ipa/ipu3/ipa_context.h > +++ b/src/ipa/ipu3/ipa_context.h > @@ -11,10 +11,14 @@ > > #include <linux/intel-ipu3.h> > > +#include <libcamera/base/utils.h> > + > #include <libcamera/geometry.h> > > namespace libcamera { > > +using libcamera::utils::Duration; > + I think you can drop "libcamera::" here, just utils::Duration > namespace ipa::ipu3 { > > struct IPAContext { > @@ -33,6 +37,13 @@ struct IPAContext { > Size bdsOutputSize; > } grid; > } awb; > + > + /* AGC specific parameters to share */ > + struct Agc { > + Duration lineDuration; > + Duration shutterTime; > + double analogueGain; > + } agc; > }; > > } /* namespace ipa::ipu3 */ > diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp > index 82506461..07b1d11c 100644 > --- a/src/ipa/ipu3/ipu3.cpp > +++ b/src/ipa/ipu3/ipu3.cpp > @@ -22,12 +22,12 @@ > > #include "libcamera/internal/framebuffer.h" > > +#include "algorithms/agc.h" > #include "algorithms/algorithm.h" > #include "algorithms/awb.h" > #include "algorithms/contrast.h" > #include "ipa_context.h" > > -#include "ipu3_agc.h" > #include "libipa/camera_sensor_helper.h" > > static constexpr uint32_t kMaxCellWidthPerSet = 160; > @@ -37,6 +37,8 @@ namespace libcamera { > > LOG_DEFINE_CATEGORY(IPAIPU3) > > +using namespace std::literals::chrono_literals; > + > namespace ipa::ipu3 { > > class IPAIPU3 : public IPAIPU3Interface > @@ -81,8 +83,6 @@ private: > uint32_t minGain_; > uint32_t maxGain_; > > - /* Interface to the AEC/AGC algorithm */ > - std::unique_ptr<IPU3Agc> agcAlgo_; > /* Interface to the Camera Helper */ > std::unique_ptr<CameraSensorHelper> camHelper_; > > @@ -103,6 +103,7 @@ int IPAIPU3::init(const IPASettings &settings) > } > > /* Construct our Algorithms */ > + algorithms_.emplace_back(new algorithms::Agc()); > algorithms_.emplace_back(new algorithms::Awb()); > algorithms_.emplace_back(new algorithms::Contrast()); > > @@ -214,11 +215,14 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) > calculateBdsGrid(configInfo.bdsOutputSize); > context_.awb.grid.bdsOutputSize = configInfo.bdsOutputSize; > > + /* Prepare AGC parameters */ > + context_.agc.lineDuration = sensorInfo_.lineLength * 1.0s / sensorInfo_.pixelRate; > + context_.agc.shutterTime = exposure_ * context_.agc.lineDuration; > + context_.agc.analogueGain = camHelper_->gain(gain_); > + > configureAlgorithms(); > > bdsGrid_ = context_.awb.grid.bdsGrid; > - agcAlgo_ = std::make_unique<IPU3Agc>(); > - agcAlgo_->initialise(bdsGrid_, sensorInfo_); > > return 0; > } > @@ -341,12 +345,7 @@ void IPAIPU3::parseStatistics(unsigned int frame, > /* Run the process for each algorithm on the stats */ > processAlgorithms(stats); > > - double gain = camHelper_->gain(gain_); > - agcAlgo_->process(stats, exposure_, gain); > - gain_ = camHelper_->gainCode(gain); > - > - if (agcAlgo_->updateControls()) > - setControls(frame); > + setControls(frame); > > /* \todo Use VBlank value calculated from each frame exposure. */ > int64_t frameDuration = sensorInfo_.lineLength * (defVBlank_ + sensorInfo_.outputSize.height) / > @@ -365,6 +364,10 @@ void IPAIPU3::setControls(unsigned int frame) > IPU3Action op; > op.op = ActionSetSensorControls; > > + /* Convert gain and exposure */ > + gain_ = camHelper_->gainCode(context_.agc.analogueGain); > + exposure_ = context_.agc.shutterTime / context_.agc.lineDuration; > + > ControlList ctrls(ctrls_); > ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_)); > ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_)); > diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build > index d1126947..39320980 100644 > --- a/src/ipa/ipu3/meson.build > +++ b/src/ipa/ipu3/meson.build > @@ -6,7 +6,6 @@ ipa_name = 'ipa_ipu3' > > ipu3_ipa_sources = files([ > 'ipu3.cpp', > - 'ipu3_agc.cpp', > ]) > > ipu3_ipa_sources += ipu3_ipa_algorithms
On 09/08/2021 10:20, Jean-Michel Hautbois wrote: > Use the Context class and algorithm interface to properly call the AGC > algorithm from IPAIPU3. > We need to pass shutter speed and analogue gain through Context. Add a > dedicated AGC structure for that. Same comments from the previous patch I think ;-) > Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> > --- > .../ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} | 56 ++++++++++--------- > src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} | 31 +++++----- > src/ipa/ipu3/algorithms/meson.build | 1 + > src/ipa/ipu3/ipa_context.h | 11 ++++ > src/ipa/ipu3/ipu3.cpp | 25 +++++---- > src/ipa/ipu3/meson.build | 1 - > 6 files changed, 70 insertions(+), 55 deletions(-) > rename src/ipa/ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} (81%) > rename src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} (61%) > > diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp > similarity index 81% > rename from src/ipa/ipu3/ipu3_agc.cpp > rename to src/ipa/ipu3/algorithms/agc.cpp > index 733814dd..1146a34a 100644 > --- a/src/ipa/ipu3/ipu3_agc.cpp > +++ b/src/ipa/ipu3/algorithms/agc.cpp > @@ -2,26 +2,25 @@ > /* > * Copyright (C) 2021, Ideas On Board > * > - * ipu3_agc.cpp - AGC/AEC control algorithm > + * agc.cpp - AGC/AEC control algorithm > */ > > -#include "ipu3_agc.h" > +#include "agc.h" > > -#include <algorithm> > #include <cmath> > +> +#include <algorithm> > #include <numeric> What's going on there? Shouldn't cmath algorithm, and numeric all be one alphabetically sorted block? > > #include <libcamera/base/log.h> > > -#include <libcamera/ipa/core_ipa_interface.h> > - Was this no longer required as part of the conversion, or something that could have been done on it's own? > #include "libipa/histogram.h" > > namespace libcamera { > > using namespace std::literals::chrono_literals; > > -namespace ipa::ipu3 { > +namespace ipa::ipu3::algorithms { > > LOG_DEFINE_CATEGORY(IPU3Agc) > > @@ -36,8 +35,8 @@ static constexpr uint32_t kMaxISO = 1500; > > /* Maximum analogue gain value > * \todo grab it from a camera helper */ > -static constexpr uint32_t kMinGain = kMinISO / 100; > -static constexpr uint32_t kMaxGain = kMaxISO / 100; > +static constexpr double kMinGain = kMinISO / 100; > +static constexpr double kMaxGain = kMaxISO / 100; Why do these types change as part of moving the algorithm and restructuring? It doesn't sound like something related to moving code - so it should be in it's own patch, either before if it's a bug fix, or after if it doesn't matter when the types change. > /* \todo use calculated value based on sensor */ > static constexpr uint32_t kMinExposure = 1; > @@ -50,24 +49,24 @@ static constexpr double kEvGainTarget = 0.5; > /* A cell is 8 bytes and contains averages for RGB values and saturation ratio */ > static constexpr uint8_t kCellSize = 8; > > -IPU3Agc::IPU3Agc() > +Agc::Agc() > : frameCount_(0), lastFrame_(0), converged_(false), > - updateControls_(false), iqMean_(0.0), > - lineDuration_(0s), maxExposureTime_(0s), > + updateControls_(false), iqMean_(0.0), maxExposureTime_(0s), > prevExposure_(0s), prevExposureNoDg_(0s), > currentExposure_(0s), currentExposureNoDg_(0s) > { > } > > -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo) > +int Agc::configure(IPAContext &context) > { > - aeGrid_ = bdsGrid; > + /* The AGC algorithm uses the AWB statistics */ > + aeGrid_ = context.awb.grid.bdsGrid; > + maxExposureTime_ = kMaxExposure * context.agc.lineDuration; > > - lineDuration_ = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; > - maxExposureTime_ = kMaxExposure * lineDuration_; > + return 0; > } > > -void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) > +void Agc::processBrightness(const ipu3_uapi_stats_3a *stats) > { > const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid; > Rectangle aeRegion = { statsAeGrid.x_start, > @@ -108,7 +107,7 @@ void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) > iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0); > } > > -void IPU3Agc::filterExposure() > +void Agc::filterExposure() > { > double speed = 0.2; > if (prevExposure_ == 0s) { > @@ -128,7 +127,7 @@ void IPU3Agc::filterExposure() > prevExposure_ = speed * currentExposure_ + > prevExposure_ * (1.0 - speed); > prevExposureNoDg_ = speed * currentExposureNoDg_ + > - prevExposureNoDg_ * (1.0 - speed); > + prevExposureNoDg_ * (1.0 - speed); This is a minor whitespace fix, so I guess it showed up in checkstyle as part of the code move. Could either be it's own patch - or needs to be metnioned in the commit message as something like: "Fixed up white-space issues only were fixed as part of the move." > } > /* > * We can't let the no_dg exposure deviate too far below the > @@ -142,7 +141,7 @@ void IPU3Agc::filterExposure() > LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_; > } > > -void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) > +void Agc::lockExposureGain(IPAContext &context) Private algorithm functions don't have to take the IPAContext, these could have been passed in from ::process() still... > { > updateControls_ = false; > > @@ -160,7 +159,9 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) > double newGain = kEvGainTarget * knumHistogramBins / iqMean_; > > /* extracted from Rpi::Agc::computeTargetExposure */ > - libcamera::utils::Duration currentShutter = exposure * lineDuration_; > + libcamera::utils::Duration currentShutter = context.agc.shutterTime; > + uint32_t exposure = currentShutter / context.agc.lineDuration; > + double &gain = context.agc.analogueGain; I'm not sure I like this. If gain is something that is calculated by this function, it should be setting the end result after it is calculated. I guess this is a shortcut that the answer is calculated in place... but it feels like a hack - as reading the code it's not clear where the results go. I.e. usually, you'd expect calculations and then results to be set at the end or return by the function? To keep the churn minimal in this patch which just moves to the new interface, I'd stick with the existing function prototype and pass in the references from the IPAContext to the private function. > currentExposureNoDg_ = currentShutter * gain; > LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ > << " Shutter speed " << currentShutter > @@ -177,26 +178,27 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) > if (currentShutter < maxExposureTime_) { > exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure); > newExposure = currentExposure_ / exposure; > - gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); > + gain = std::clamp(static_cast<double>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); > updateControls_ = true; > } else if (currentShutter >= maxExposureTime_) { > - gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); > + gain = std::clamp(static_cast<double>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); > newExposure = currentExposure_ / gain; > exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure); > updateControls_ = true; > } > - LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain; > + context.agc.shutterTime = exposure * context.agc.lineDuration; Perhaps that shutterTime line is something that should happen in Agc::process() if the context isn't available in the function. > + LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * context.agc.lineDuration << " and gain " << gain; > } > lastFrame_ = frameCount_; > } > > -void IPU3Agc::process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain) > +void Agc::process(IPAContext &context) > { > - processBrightness(stats); > - lockExposureGain(exposure, gain); > + processBrightness(context.stats); > + lockExposureGain(context); > frameCount_++; > } > > -} /* namespace ipa::ipu3 */ > +} /* namespace ipa::ipu3::algorithms */ > > } /* namespace libcamera */ > diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/algorithms/agc.h > similarity index 61% > rename from src/ipa/ipu3/ipu3_agc.h > rename to src/ipa/ipu3/algorithms/agc.h > index 3b7f781e..e87a06f3 100644 > --- a/src/ipa/ipu3/ipu3_agc.h > +++ b/src/ipa/ipu3/algorithms/agc.h > @@ -4,44 +4,44 @@ > * > * ipu3_agc.h - IPU3 AGC/AEC control algorithm > */ > -#ifndef __LIBCAMERA_IPU3_AGC_H__ > -#define __LIBCAMERA_IPU3_AGC_H__ > +#ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ > +#define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ > + > +#include <linux/intel-ipu3.h> > > #include <array> > #include <unordered_map> > > -#include <linux/intel-ipu3.h> > - Why did the linux header move? I think it was in the right place here. https://git.libcamera.org/libcamera/libcamera.git/tree/Documentation/coding-style.rst#n64 states: 1. The header declaring the API being implemented (if any) 2. The C and C++ system and standard library headers 3. Other libraries' headers, with one group per library 4. Other project's headers > #include <libcamera/base/utils.h> > > #include <libcamera/geometry.h> > > -#include "algorithms/algorithm.h" > -#include "libipa/algorithm.h" > +#include "algorithm.h" > > namespace libcamera { > > struct IPACameraSensorInfo; > > -namespace ipa::ipu3 { > +namespace ipa::ipu3::algorithms { > > using utils::Duration; > > -class IPU3Agc : public ipa::Algorithm > +class Agc : public Algorithm > { > public: > - IPU3Agc(); > - ~IPU3Agc() = default; > + Agc(); > + ~Agc() = default; > + > + int configure(IPAContext &context) override; > + void process(IPAContext &context) override; > > - void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo); > - void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain); > bool converged() { return converged_; } > bool updateControls() { return updateControls_; } > > private: > void processBrightness(const ipu3_uapi_stats_3a *stats); > void filterExposure(); > - void lockExposureGain(uint32_t &exposure, double &gain); > + void lockExposureGain(IPAContext &context); > > struct ipu3_uapi_grid_config aeGrid_; > > @@ -53,7 +53,6 @@ private: > > double iqMean_; > > - Duration lineDuration_; > Duration maxExposureTime_; > > Duration prevExposure_; > @@ -62,8 +61,8 @@ private: > Duration currentExposureNoDg_; > }; > > -} /* namespace ipa::ipu3 */ > +} /* namespace ipa::ipu3::algorithms */ > > } /* namespace libcamera */ > > -#endif /* __LIBCAMERA_IPU3_AGC_H__ */ > +#endif /* __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ */ > diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build > index df36d719..3faf913e 100644 > --- a/src/ipa/ipu3/algorithms/meson.build > +++ b/src/ipa/ipu3/algorithms/meson.build > @@ -1,6 +1,7 @@ > # SPDX-License-Identifier: CC0-1.0 > > ipu3_ipa_algorithms = files([ > + 'agc.cpp', > 'awb.cpp', > 'contrast.cpp', > ]) > diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h > index c43b275b..1d7a1984 100644 > --- a/src/ipa/ipu3/ipa_context.h > +++ b/src/ipa/ipu3/ipa_context.h > @@ -11,10 +11,14 @@ > > #include <linux/intel-ipu3.h> > > +#include <libcamera/base/utils.h> > + > #include <libcamera/geometry.h> > > namespace libcamera { > > +using libcamera::utils::Duration; > + > namespace ipa::ipu3 { > > struct IPAContext { > @@ -33,6 +37,13 @@ struct IPAContext { > Size bdsOutputSize; > } grid; > } awb; > + > + /* AGC specific parameters to share */ > + struct Agc { > + Duration lineDuration; > + Duration shutterTime; > + double analogueGain; > + } agc; > }; > > } /* namespace ipa::ipu3 */ > diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp > index 82506461..07b1d11c 100644 > --- a/src/ipa/ipu3/ipu3.cpp > +++ b/src/ipa/ipu3/ipu3.cpp > @@ -22,12 +22,12 @@ > > #include "libcamera/internal/framebuffer.h" > > +#include "algorithms/agc.h" > #include "algorithms/algorithm.h" I don't like including an algorithm, then including the algorithm header. Either we include the algorithm header first, and ignore alphabetical ordering, or we don't need to include algorithm ? I think this is an instance where we should ignore alphabetical - But maybe Laurent has different ideas. > #include "algorithms/awb.h" > #include "algorithms/contrast.h" > #include "ipa_context.h" > > -#include "ipu3_agc.h" > #include "libipa/camera_sensor_helper.h" > > static constexpr uint32_t kMaxCellWidthPerSet = 160; > @@ -37,6 +37,8 @@ namespace libcamera { > > LOG_DEFINE_CATEGORY(IPAIPU3) > > +using namespace std::literals::chrono_literals; > + Why has this sprung up in here? Presumably regarding Duration or something? Should this be specified in the header that brings that in ? > namespace ipa::ipu3 { > > class IPAIPU3 : public IPAIPU3Interface > @@ -81,8 +83,6 @@ private: > uint32_t minGain_; > uint32_t maxGain_; > > - /* Interface to the AEC/AGC algorithm */ > - std::unique_ptr<IPU3Agc> agcAlgo_; > /* Interface to the Camera Helper */ > std::unique_ptr<CameraSensorHelper> camHelper_; > > @@ -103,6 +103,7 @@ int IPAIPU3::init(const IPASettings &settings) > } > > /* Construct our Algorithms */ > + algorithms_.emplace_back(new algorithms::Agc()); > algorithms_.emplace_back(new algorithms::Awb()); > algorithms_.emplace_back(new algorithms::Contrast()); > > @@ -214,11 +215,14 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) > calculateBdsGrid(configInfo.bdsOutputSize); > context_.awb.grid.bdsOutputSize = configInfo.bdsOutputSize; > > + /* Prepare AGC parameters */ > + context_.agc.lineDuration = sensorInfo_.lineLength * 1.0s / sensorInfo_.pixelRate; > + context_.agc.shutterTime = exposure_ * context_.agc.lineDuration; > + context_.agc.analogueGain = camHelper_->gain(gain_); How do we avoid algorithm specific code living in this function. Can this be handled during Agc::configure()? What information do we need to pass into configure to make that happen? > + > configureAlgorithms(); it might even be that the implementation of configureAlgorithms() may as well be directly coded in here.... Same for the others potentially too. Might be something to revisit later. > > bdsGrid_ = context_.awb.grid.bdsGrid; > - agcAlgo_ = std::make_unique<IPU3Agc>(); > - agcAlgo_->initialise(bdsGrid_, sensorInfo_); > > return 0; > } > @@ -341,12 +345,7 @@ void IPAIPU3::parseStatistics(unsigned int frame, > /* Run the process for each algorithm on the stats */ > processAlgorithms(stats); > > - double gain = camHelper_->gain(gain_); > - agcAlgo_->process(stats, exposure_, gain); > - gain_ = camHelper_->gainCode(gain); > - > - if (agcAlgo_->updateControls()) > - setControls(frame); > + setControls(frame); Will we always have controls to set? Should we have a control list in the IPAContext that can be updated, or a flag? Not necessarily for this patch - but in trying to think about the overall design goals. > > /* \todo Use VBlank value calculated from each frame exposure. */ > int64_t frameDuration = sensorInfo_.lineLength * (defVBlank_ + sensorInfo_.outputSize.height) / > @@ -365,6 +364,10 @@ void IPAIPU3::setControls(unsigned int frame) > IPU3Action op; > op.op = ActionSetSensorControls; > > + /* Convert gain and exposure */ > + gain_ = camHelper_->gainCode(context_.agc.analogueGain); > + exposure_ = context_.agc.shutterTime / context_.agc.lineDuration; > + > ControlList ctrls(ctrls_); > ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_)); > ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_)); > diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build > index d1126947..39320980 100644 > --- a/src/ipa/ipu3/meson.build > +++ b/src/ipa/ipu3/meson.build > @@ -6,7 +6,6 @@ ipa_name = 'ipa_ipu3' > > ipu3_ipa_sources = files([ > 'ipu3.cpp', > - 'ipu3_agc.cpp', > ]) > > ipu3_ipa_sources += ipu3_ipa_algorithms >
diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp similarity index 81% rename from src/ipa/ipu3/ipu3_agc.cpp rename to src/ipa/ipu3/algorithms/agc.cpp index 733814dd..1146a34a 100644 --- a/src/ipa/ipu3/ipu3_agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -2,26 +2,25 @@ /* * Copyright (C) 2021, Ideas On Board * - * ipu3_agc.cpp - AGC/AEC control algorithm + * agc.cpp - AGC/AEC control algorithm */ -#include "ipu3_agc.h" +#include "agc.h" -#include <algorithm> #include <cmath> + +#include <algorithm> #include <numeric> #include <libcamera/base/log.h> -#include <libcamera/ipa/core_ipa_interface.h> - #include "libipa/histogram.h" namespace libcamera { using namespace std::literals::chrono_literals; -namespace ipa::ipu3 { +namespace ipa::ipu3::algorithms { LOG_DEFINE_CATEGORY(IPU3Agc) @@ -36,8 +35,8 @@ static constexpr uint32_t kMaxISO = 1500; /* Maximum analogue gain value * \todo grab it from a camera helper */ -static constexpr uint32_t kMinGain = kMinISO / 100; -static constexpr uint32_t kMaxGain = kMaxISO / 100; +static constexpr double kMinGain = kMinISO / 100; +static constexpr double kMaxGain = kMaxISO / 100; /* \todo use calculated value based on sensor */ static constexpr uint32_t kMinExposure = 1; @@ -50,24 +49,24 @@ static constexpr double kEvGainTarget = 0.5; /* A cell is 8 bytes and contains averages for RGB values and saturation ratio */ static constexpr uint8_t kCellSize = 8; -IPU3Agc::IPU3Agc() +Agc::Agc() : frameCount_(0), lastFrame_(0), converged_(false), - updateControls_(false), iqMean_(0.0), - lineDuration_(0s), maxExposureTime_(0s), + updateControls_(false), iqMean_(0.0), maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s), currentExposure_(0s), currentExposureNoDg_(0s) { } -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo) +int Agc::configure(IPAContext &context) { - aeGrid_ = bdsGrid; + /* The AGC algorithm uses the AWB statistics */ + aeGrid_ = context.awb.grid.bdsGrid; + maxExposureTime_ = kMaxExposure * context.agc.lineDuration; - lineDuration_ = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; - maxExposureTime_ = kMaxExposure * lineDuration_; + return 0; } -void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) +void Agc::processBrightness(const ipu3_uapi_stats_3a *stats) { const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid; Rectangle aeRegion = { statsAeGrid.x_start, @@ -108,7 +107,7 @@ void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0); } -void IPU3Agc::filterExposure() +void Agc::filterExposure() { double speed = 0.2; if (prevExposure_ == 0s) { @@ -128,7 +127,7 @@ void IPU3Agc::filterExposure() prevExposure_ = speed * currentExposure_ + prevExposure_ * (1.0 - speed); prevExposureNoDg_ = speed * currentExposureNoDg_ + - prevExposureNoDg_ * (1.0 - speed); + prevExposureNoDg_ * (1.0 - speed); } /* * We can't let the no_dg exposure deviate too far below the @@ -142,7 +141,7 @@ void IPU3Agc::filterExposure() LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_; } -void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) +void Agc::lockExposureGain(IPAContext &context) { updateControls_ = false; @@ -160,7 +159,9 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) double newGain = kEvGainTarget * knumHistogramBins / iqMean_; /* extracted from Rpi::Agc::computeTargetExposure */ - libcamera::utils::Duration currentShutter = exposure * lineDuration_; + libcamera::utils::Duration currentShutter = context.agc.shutterTime; + uint32_t exposure = currentShutter / context.agc.lineDuration; + double &gain = context.agc.analogueGain; currentExposureNoDg_ = currentShutter * gain; LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ << " Shutter speed " << currentShutter @@ -177,26 +178,27 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) if (currentShutter < maxExposureTime_) { exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure); newExposure = currentExposure_ / exposure; - gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); + gain = std::clamp(static_cast<double>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); updateControls_ = true; } else if (currentShutter >= maxExposureTime_) { - gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); + gain = std::clamp(static_cast<double>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); newExposure = currentExposure_ / gain; exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure); updateControls_ = true; } - LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain; + context.agc.shutterTime = exposure * context.agc.lineDuration; + LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * context.agc.lineDuration << " and gain " << gain; } lastFrame_ = frameCount_; } -void IPU3Agc::process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain) +void Agc::process(IPAContext &context) { - processBrightness(stats); - lockExposureGain(exposure, gain); + processBrightness(context.stats); + lockExposureGain(context); frameCount_++; } -} /* namespace ipa::ipu3 */ +} /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera */ diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/algorithms/agc.h similarity index 61% rename from src/ipa/ipu3/ipu3_agc.h rename to src/ipa/ipu3/algorithms/agc.h index 3b7f781e..e87a06f3 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -4,44 +4,44 @@ * * ipu3_agc.h - IPU3 AGC/AEC control algorithm */ -#ifndef __LIBCAMERA_IPU3_AGC_H__ -#define __LIBCAMERA_IPU3_AGC_H__ +#ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ +#define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ + +#include <linux/intel-ipu3.h> #include <array> #include <unordered_map> -#include <linux/intel-ipu3.h> - #include <libcamera/base/utils.h> #include <libcamera/geometry.h> -#include "algorithms/algorithm.h" -#include "libipa/algorithm.h" +#include "algorithm.h" namespace libcamera { struct IPACameraSensorInfo; -namespace ipa::ipu3 { +namespace ipa::ipu3::algorithms { using utils::Duration; -class IPU3Agc : public ipa::Algorithm +class Agc : public Algorithm { public: - IPU3Agc(); - ~IPU3Agc() = default; + Agc(); + ~Agc() = default; + + int configure(IPAContext &context) override; + void process(IPAContext &context) override; - void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo); - void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain); bool converged() { return converged_; } bool updateControls() { return updateControls_; } private: void processBrightness(const ipu3_uapi_stats_3a *stats); void filterExposure(); - void lockExposureGain(uint32_t &exposure, double &gain); + void lockExposureGain(IPAContext &context); struct ipu3_uapi_grid_config aeGrid_; @@ -53,7 +53,6 @@ private: double iqMean_; - Duration lineDuration_; Duration maxExposureTime_; Duration prevExposure_; @@ -62,8 +61,8 @@ private: Duration currentExposureNoDg_; }; -} /* namespace ipa::ipu3 */ +} /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera */ -#endif /* __LIBCAMERA_IPU3_AGC_H__ */ +#endif /* __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ */ diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build index df36d719..3faf913e 100644 --- a/src/ipa/ipu3/algorithms/meson.build +++ b/src/ipa/ipu3/algorithms/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 ipu3_ipa_algorithms = files([ + 'agc.cpp', 'awb.cpp', 'contrast.cpp', ]) diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index c43b275b..1d7a1984 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -11,10 +11,14 @@ #include <linux/intel-ipu3.h> +#include <libcamera/base/utils.h> + #include <libcamera/geometry.h> namespace libcamera { +using libcamera::utils::Duration; + namespace ipa::ipu3 { struct IPAContext { @@ -33,6 +37,13 @@ struct IPAContext { Size bdsOutputSize; } grid; } awb; + + /* AGC specific parameters to share */ + struct Agc { + Duration lineDuration; + Duration shutterTime; + double analogueGain; + } agc; }; } /* namespace ipa::ipu3 */ diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 82506461..07b1d11c 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -22,12 +22,12 @@ #include "libcamera/internal/framebuffer.h" +#include "algorithms/agc.h" #include "algorithms/algorithm.h" #include "algorithms/awb.h" #include "algorithms/contrast.h" #include "ipa_context.h" -#include "ipu3_agc.h" #include "libipa/camera_sensor_helper.h" static constexpr uint32_t kMaxCellWidthPerSet = 160; @@ -37,6 +37,8 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPAIPU3) +using namespace std::literals::chrono_literals; + namespace ipa::ipu3 { class IPAIPU3 : public IPAIPU3Interface @@ -81,8 +83,6 @@ private: uint32_t minGain_; uint32_t maxGain_; - /* Interface to the AEC/AGC algorithm */ - std::unique_ptr<IPU3Agc> agcAlgo_; /* Interface to the Camera Helper */ std::unique_ptr<CameraSensorHelper> camHelper_; @@ -103,6 +103,7 @@ int IPAIPU3::init(const IPASettings &settings) } /* Construct our Algorithms */ + algorithms_.emplace_back(new algorithms::Agc()); algorithms_.emplace_back(new algorithms::Awb()); algorithms_.emplace_back(new algorithms::Contrast()); @@ -214,11 +215,14 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) calculateBdsGrid(configInfo.bdsOutputSize); context_.awb.grid.bdsOutputSize = configInfo.bdsOutputSize; + /* Prepare AGC parameters */ + context_.agc.lineDuration = sensorInfo_.lineLength * 1.0s / sensorInfo_.pixelRate; + context_.agc.shutterTime = exposure_ * context_.agc.lineDuration; + context_.agc.analogueGain = camHelper_->gain(gain_); + configureAlgorithms(); bdsGrid_ = context_.awb.grid.bdsGrid; - agcAlgo_ = std::make_unique<IPU3Agc>(); - agcAlgo_->initialise(bdsGrid_, sensorInfo_); return 0; } @@ -341,12 +345,7 @@ void IPAIPU3::parseStatistics(unsigned int frame, /* Run the process for each algorithm on the stats */ processAlgorithms(stats); - double gain = camHelper_->gain(gain_); - agcAlgo_->process(stats, exposure_, gain); - gain_ = camHelper_->gainCode(gain); - - if (agcAlgo_->updateControls()) - setControls(frame); + setControls(frame); /* \todo Use VBlank value calculated from each frame exposure. */ int64_t frameDuration = sensorInfo_.lineLength * (defVBlank_ + sensorInfo_.outputSize.height) / @@ -365,6 +364,10 @@ void IPAIPU3::setControls(unsigned int frame) IPU3Action op; op.op = ActionSetSensorControls; + /* Convert gain and exposure */ + gain_ = camHelper_->gainCode(context_.agc.analogueGain); + exposure_ = context_.agc.shutterTime / context_.agc.lineDuration; + ControlList ctrls(ctrls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_)); diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build index d1126947..39320980 100644 --- a/src/ipa/ipu3/meson.build +++ b/src/ipa/ipu3/meson.build @@ -6,7 +6,6 @@ ipa_name = 'ipa_ipu3' ipu3_ipa_sources = files([ 'ipu3.cpp', - 'ipu3_agc.cpp', ]) ipu3_ipa_sources += ipu3_ipa_algorithms
Use the Context class and algorithm interface to properly call the AGC algorithm from IPAIPU3. We need to pass shutter speed and analogue gain through Context. Add a dedicated AGC structure for that. Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> --- .../ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} | 56 ++++++++++--------- src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} | 31 +++++----- src/ipa/ipu3/algorithms/meson.build | 1 + src/ipa/ipu3/ipa_context.h | 11 ++++ src/ipa/ipu3/ipu3.cpp | 25 +++++---- src/ipa/ipu3/meson.build | 1 - 6 files changed, 70 insertions(+), 55 deletions(-) rename src/ipa/ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} (81%) rename src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} (61%)