@@ -453,6 +453,7 @@ int AgcMeanLuminance::parseTuningData(const YamlObject &tuningData)
* \brief Set the ExposureModeHelper limits for this class
* \param[in] minExposureTime Minimum exposure time to allow
* \param[in] maxExposureTime Maximum ewposure time to allow
+ * \param[in] maxFrameDuration Maximum frame duration
* \param[in] minGain Minimum gain to allow
* \param[in] maxGain Maximum gain to allow
* \param[in] constraints Additional constraints to apply
@@ -462,11 +463,13 @@ int AgcMeanLuminance::parseTuningData(const YamlObject &tuningData)
*/
void AgcMeanLuminance::setLimits(utils::Duration minExposureTime,
utils::Duration maxExposureTime,
+ utils::Duration maxFrameDuration,
double minGain, double maxGain,
std::vector<AgcMeanLuminance::AgcConstraint> constraints)
{
for (auto &[id, helper] : exposureModeHelpers_)
- helper->setLimits(minExposureTime, maxExposureTime, minGain, maxGain);
+ helper->setLimits(minExposureTime, maxExposureTime, maxFrameDuration,
+ minGain, maxGain);
additionalConstraints_ = std::move(constraints);
}
@@ -61,7 +61,8 @@ public:
}
void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
- double minGain, double maxGain, std::vector<AgcConstraint> constraints);
+ utils::Duration maxFrameDuration, double minGain, double maxGain,
+ std::vector<AgcConstraint> constraints);
std::map<int32_t, std::vector<AgcConstraint>> constraintModes()
{
@@ -79,6 +79,33 @@ ExposureModeHelper::ExposureModeHelper(const Span<std::pair<utils::Duration, dou
}
}
+void ExposureModeHelper::setMaxExposure(utils::Duration minExposureTime,
+ utils::Duration maxExposureTime,
+ utils::Duration maxFrameDuration)
+{
+ /*
+ * Compute the maximum exposure time.
+ *
+ * If maxExposureTime is equal to minExposureTime then we use them
+ * to fix the exposure time.
+ *
+ * Otherwise, if the exposure can range between a min and max, use the
+ * maxFrameDuration minus the margin as upper limit for exposure
+ * (capped to the provided max exposure).
+ */
+ minExposureTime_ = minExposureTime;
+ auto margin = sensorHelper_->exposureMargin();
+ if (!margin.has_value()) {
+ LOG(ExposureModeHelper, Warning)
+ << "Exposure margin not known. Default to 4";
+ margin = { 4 };
+ }
+
+ maxExposureTime_ = minExposureTime != maxExposureTime
+ ? maxFrameDuration - margin.value() * lineDuration_
+ : minExposureTime;
+}
+
/**
* \brief Configure sensor details
* \param[in] lineDuration The current line length of the sensor
@@ -111,34 +138,14 @@ void ExposureModeHelper::configure(utils::Duration lineDuration,
maxGain_ = maxGain;
sensorHelper_ = sensorHelper;
- minExposureTime_ = minExposureTime;
-
- /*
- * Compute the maximum exposure time.
- *
- * If maxExposureTime is equal to minExposureTime then we use them
- * to fix the exposure time.
- *
- * Otherwise, if the exposure can range between a min and max, use the
- * maxFrameDuration minus the margin as upper limit for exposure
- * (capped to the provided max exposure).
- */
- auto margin = sensorHelper_->exposureMargin();
- if (!margin.has_value()) {
- LOG(ExposureModeHelper, Warning)
- << "Exposure margin not known. Default to 4";
- margin = { 4 };
- }
-
- maxExposureTime_ = minExposureTime != maxExposureTime
- ? maxFrameDuration - margin.value() * lineDuration
- : minExposureTime;
+ setMaxExposure(minExposureTime, maxExposureTime, maxFrameDuration);
}
/**
* \brief Set the exposure time and gain limits
* \param[in] minExposureTime The minimum exposure time supported
* \param[in] maxExposureTime The maximum exposure time supported
+ * \param[in] maxFrameDuration The maximum frame duration
* \param[in] minGain The minimum analogue gain supported
* \param[in] maxGain The maximum analogue gain supported
*
@@ -150,15 +157,19 @@ void ExposureModeHelper::configure(utils::Duration lineDuration,
* If the algorithm using the helpers needs to indicate that either exposure time
* or analogue gain or both should be fixed it can do so by setting both the
* minima and maxima to the same value.
+ *
+ * The exposure time limits are calculated using \a maxFrameDuration as the
+ * upper bound, the \a maxExposureTime paramter effectivelly only serves
+ * to indicate that the caller wants a fixed exposure value.
*/
void ExposureModeHelper::setLimits(utils::Duration minExposureTime,
utils::Duration maxExposureTime,
+ utils::Duration maxFrameDuration,
double minGain, double maxGain)
{
- minExposureTime_ = minExposureTime;
- maxExposureTime_ = maxExposureTime;
minGain_ = minGain;
maxGain_ = maxGain;
+ setMaxExposure(minExposureTime, maxExposureTime, maxFrameDuration);
}
utils::Duration ExposureModeHelper::clampExposureTime(utils::Duration exposureTime,
@@ -31,7 +31,7 @@ public:
double minGain, double maxGain,
const CameraSensorHelper *sensorHelper);
void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
- double minGain, double maxGain);
+ utils::Duration maxFrameDuration, double minGain, double maxGain);
std::tuple<utils::Duration, double, double, double>
splitExposure(utils::Duration exposure) const;
@@ -43,6 +43,9 @@ public:
double maxGain() const { return maxGain_; }
private:
+ void setMaxExposure(utils::Duration minExposureTime,
+ utils::Duration maxExposureTime,
+ utils::Duration maxFrameDuration);
utils::Duration clampExposureTime(utils::Duration exposureTime,
double *quantizationGain = nullptr) const;
double clampGain(double gain, double *quantizationGain = nullptr) const;
@@ -579,9 +579,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
if (frameContext.agc.autoExposureEnabled) {
minExposureTime = context.configuration.sensor.minExposureTime;
- maxExposureTime = std::clamp(frameContext.agc.maxFrameDuration,
- context.configuration.sensor.minExposureTime,
- context.configuration.sensor.maxExposureTime);
+ maxExposureTime = context.configuration.sensor.maxExposureTime;
} else {
minExposureTime = context.configuration.sensor.lineDuration
* frameContext.agc.exposure;
@@ -600,8 +598,8 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
if (context.activeState.wdr.mode != controls::WdrOff)
additionalConstraints.push_back(context.activeState.wdr.constraint);
- setLimits(minExposureTime, maxExposureTime, minAnalogueGain, maxAnalogueGain,
- std::move(additionalConstraints));
+ setLimits(minExposureTime, maxExposureTime, frameContext.agc.maxFrameDuration,
+ minAnalogueGain, maxAnalogueGain, std::move(additionalConstraints));
/*
* The Agc algorithm needs to know the effective exposure value that was
Similarly to what now happens at configure() time, the AGC exposure limits updated at runtime with the setLimits() function are now computed using the maximum frame duration. Factor-out in the ExposureModeHelper class the exposure limits calculation from the configure() function so that it can be performed at setLimits() time too. Update the only IPA that handles limits update at runtime (RkISP1) to pass to the AGC the updated frame durations. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> --- src/ipa/libipa/agc_mean_luminance.cpp | 5 ++- src/ipa/libipa/agc_mean_luminance.h | 3 +- src/ipa/libipa/exposure_mode_helper.cpp | 59 +++++++++++++++++++-------------- src/ipa/libipa/exposure_mode_helper.h | 5 ++- src/ipa/rkisp1/algorithms/agc.cpp | 8 ++--- 5 files changed, 48 insertions(+), 32 deletions(-)