diff options
author | Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> | 2021-10-12 16:52:44 +0200 |
---|---|---|
committer | Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> | 2021-10-22 07:31:28 +0200 |
commit | 17dbae2325d81f555cdaae0a631dd6435e71159b (patch) | |
tree | ac59a5861717f8b974c8fd190f1c10aa8269e3f3 /src/ipa/ipu3 | |
parent | f1cf01d13b729f0f6efeef07012605577f31ee69 (diff) |
ipa: ipu3: agc: Simplify division of exposure/gain
Until now, the algorithm makes complex assumptions when dividing the
exposure and analogue gain values. Instead, use a simpler clamping of
the shutter speed first, and then of the analogue gain, based on the
limits configured.
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'src/ipa/ipu3')
-rw-r--r-- | src/ipa/ipu3/algorithms/agc.cpp | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index f5bb3328..6f5b6a45 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -147,7 +147,9 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) << " Gain " << gain; currentExposure_ = currentExposureNoDg_ * newGain; + utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; + utils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain; currentExposure_ = std::min(currentExposure_, maxTotalExposure); LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ @@ -156,23 +158,23 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) /* \todo: estimate if we need to desaturate */ filterExposure(); - utils::Duration newExposure = 0.0s; - if (currentShutter < maxShutterSpeed) { - exposure = std::clamp<uint32_t>(exposure * filteredExposure_ / currentExposureNoDg_, - minExposureLines_, - maxExposureLines_); - newExposure = filteredExposure_ / exposure; - gain = std::clamp(gain * filteredExposure_ / newExposure, - kMinGain, kMaxGain); - } else { - gain = std::clamp(gain * filteredExposure_ / currentExposureNoDg_, - kMinGain, kMaxGain); - newExposure = filteredExposure_ / gain; - exposure = std::clamp<uint32_t>(exposure * filteredExposure_ / newExposure, - minExposureLines_, - maxExposureLines_); - } - LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain; + utils::Duration exposureValue = filteredExposure_; + utils::Duration shutterTime = minShutterSpeed; + + /* + * Push the shutter time up to the maximum first, and only then + * increase the gain. + */ + shutterTime = std::clamp<utils::Duration>(exposureValue / kMinGain, + minShutterSpeed, maxShutterSpeed); + double stepGain = std::clamp(exposureValue / shutterTime, + kMinGain, kMaxGain); + LOG(IPU3Agc, Debug) << "Divided up shutter and gain are " + << shutterTime << " and " + << stepGain; + + exposure = shutterTime / lineDuration_; + gain = stepGain; } lastFrame_ = frameCount_; } |