diff options
-rw-r--r-- | meson.build | 4 | ||||
-rw-r--r-- | src/ipa/ipu3/ipa_context.h | 5 | ||||
-rw-r--r-- | src/ipa/ipu3/ipu3.cpp | 41 | ||||
-rw-r--r-- | src/ipa/ipu3/ipu3_agc.cpp | 24 | ||||
-rw-r--r-- | src/ipa/ipu3/ipu3_agc.h | 9 |
5 files changed, 45 insertions, 38 deletions
diff --git a/meson.build b/meson.build index 4a10e2b6..a49c484f 100644 --- a/meson.build +++ b/meson.build @@ -108,10 +108,6 @@ if cc.has_argument('-Wno-c99-designator') ] endif -# Do not warn when a function declaration hides virtual functions from -# a base class -cpp_arguments += '-Wno-overloaded-virtual' - c_arguments += common_arguments cpp_arguments += common_arguments diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 24dd8bf7..9d9444dc 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -25,6 +25,11 @@ struct IPASessionConfiguration { struct IPAFrameContext { struct { + uint32_t exposure; + double gain; + } agc; + + struct { struct { double red; double green; diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 823df34b..2468e94a 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -93,6 +93,22 @@ */ /** + * \struct IPAFrameContext::agc + * \brief Context for the Automatic Gain Control algorithm + * + * The exposure and gain determined are expected to be applied to the sensor + * at the earliest opportunity. + * + * \var IPAFrameContext::agc::exposure + * \brief Exposure time expressed as a number of lines + * + * \var IPAFrameContext::agc::gain + * \brief Analogue gain multiplier + * + * The gain should be adapted to the sensor specific gain code before applying. + */ + +/** * \struct IPAFrameContext::awb * \brief Context for the Automatic White Balance algorithm * @@ -183,7 +199,6 @@ private: /* Local parameter storage */ struct IPAContext context_; - struct ipu3_uapi_params params_; }; /** @@ -361,8 +376,7 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) defVBlank_ = itVBlank->second.def().get<int32_t>(); - /* Clean context and IPU3 parameters at configuration */ - params_ = {}; + /* Clean context at configuration */ context_ = {}; calculateBdsGrid(configInfo.bdsOutputSize); @@ -375,7 +389,7 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) awbAlgo_ = std::make_unique<IPU3Awb>(); agcAlgo_ = std::make_unique<IPU3Agc>(); - agcAlgo_->initialise(context_.configuration.grid.bdsGrid, sensorInfo_); + agcAlgo_->configure(context_, configInfo); return 0; } @@ -450,12 +464,9 @@ void IPAIPU3::processControls([[maybe_unused]] unsigned int frame, void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) { for (auto const &algo : algorithms_) - algo->prepare(context_, ¶ms_); - - if (agcAlgo_->updateControls()) - awbAlgo_->prepare(context_, ¶ms_); + algo->prepare(context_, params); - *params = params_; + awbAlgo_->prepare(context_, params); IPU3Action op; op.op = ActionParamFilled; @@ -472,14 +483,16 @@ void IPAIPU3::parseStatistics(unsigned int frame, for (auto const &algo : algorithms_) algo->process(context_, stats); - double gain = camHelper_->gain(gain_); - agcAlgo_->process(stats, exposure_, gain); - gain_ = camHelper_->gainCode(gain); + /* \todo These fields should not be written by the IPAIPU3 layer */ + context_.frameContext.agc.gain = camHelper_->gain(gain_); + context_.frameContext.agc.exposure = exposure_; + agcAlgo_->process(context_, stats); + exposure_ = context_.frameContext.agc.exposure; + gain_ = camHelper_->gainCode(context_.frameContext.agc.gain); awbAlgo_->process(context_, stats); - 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) / diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp index 20c2d3b4..1c156b89 100644 --- a/src/ipa/ipu3/ipu3_agc.cpp +++ b/src/ipa/ipu3/ipu3_agc.cpp @@ -51,20 +51,21 @@ static constexpr double kEvGainTarget = 0.5; static constexpr uint8_t kCellSize = 8; IPU3Agc::IPU3Agc() - : frameCount_(0), lastFrame_(0), converged_(false), - updateControls_(false), iqMean_(0.0), - lineDuration_(0s), maxExposureTime_(0s), - prevExposure_(0s), prevExposureNoDg_(0s), + : frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s), + maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s), currentExposure_(0s), currentExposureNoDg_(0s) { } -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo) +int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) { - aeGrid_ = bdsGrid; + aeGrid_ = context.configuration.grid.bdsGrid; - lineDuration_ = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; + lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s + / configInfo.sensorInfo.pixelRate; maxExposureTime_ = kMaxExposure * lineDuration_; + + return 0; } void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) @@ -144,8 +145,6 @@ void IPU3Agc::filterExposure() void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) { - updateControls_ = false; - /* Algorithm initialization should wait for first valid frames */ /* \todo - have a number of frames given by DelayedControls ? * - implement a function for IIR */ @@ -155,7 +154,6 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) /* Are we correctly exposed ? */ if (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) { LOG(IPU3Agc, Debug) << "!!! Good exposure with iqMean = " << iqMean_; - converged_ = true; } else { double newGain = kEvGainTarget * knumHistogramBins / iqMean_; @@ -178,20 +176,20 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) 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); - updateControls_ = true; } else if (currentShutter >= maxExposureTime_) { gain = std::clamp(static_cast<uint32_t>(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; } lastFrame_ = frameCount_; } -void IPU3Agc::process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain) +void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) { + uint32_t &exposure = context.frameContext.agc.exposure; + double &gain = context.frameContext.agc.gain; processBrightness(stats); lockExposureGain(exposure, gain); frameCount_++; diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h index 2d86127d..0e922664 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/ipu3_agc.h @@ -29,10 +29,8 @@ public: IPU3Agc(); ~IPU3Agc() = default; - 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_; } + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; + void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; private: void processBrightness(const ipu3_uapi_stats_3a *stats); @@ -44,9 +42,6 @@ private: uint64_t frameCount_; uint64_t lastFrame_; - bool converged_; - bool updateControls_; - double iqMean_; Duration lineDuration_; |