@@ -120,13 +120,15 @@ int Agc::configure(IPAContext &context,
AgcMeanLuminance::AgcSensorConfiguration sensorConfig;
sensorConfig.lineDuration = context.configuration.sensor.lineDuration;
sensorConfig.minExposureTime = minExposureTime_;
+ sensorConfig.minFrameDuration =
+ std::chrono::microseconds(frameDurationLimits.min().get<int64_t>());
sensorConfig.maxFrameDuration =
std::chrono::microseconds(frameDurationLimits.max().get<int64_t>());
sensorConfig.maxExposureTime = maxExposureTime_;
sensorConfig.minAnalogueGain = minAnalogueGain_;
sensorConfig.maxAnalogueGain = maxAnalogueGain_;
- AgcMeanLuminance::configure(sensorConfig, context.camHelper.get());
+ AgcMeanLuminance::configure(&sensorConfig, context.camHelper.get());
/* \todo Update AGC limits when FrameDurationLimits is passed in */
@@ -121,6 +121,11 @@ static constexpr double kMaxRelativeLuminanceTarget = 0.95;
* \brief The sensor maximum exposure time in microseconds
*/
+/**
+ * \var AgcMeanLuminance::AgcSensorConfiguration::minFrameDuration
+ * \brief The sensor minimum exposure time in microseconds
+ */
+
/**
* \var AgcMeanLuminance::AgcSensorConfiguration::maxFrameDuration
* \brief The sensor maximum frame duration in microseconds
@@ -355,21 +360,24 @@ int AgcMeanLuminance::parseExposureModes(const YamlObject &tuningData)
/**
* \brief Configure the exposure mode helpers
- * \param[in] config The sensor configuration
+ * \param[inout] config The sensor configuration
* \param[in] sensorHelper The sensor helper
*
* This function configures the exposure mode helpers by providing them the
* sensor configuration parameters and the sensor helper, so they can correctly
* take quantization effects into account.
+ *
+ * The maximum frame duration passed in as a member of \a config is updated to
+ * the AGC algorithm startup value.
*/
-void AgcMeanLuminance::configure(const AgcSensorConfiguration &config,
+void AgcMeanLuminance::configure(AgcSensorConfiguration *config,
const CameraSensorHelper *sensorHelper)
{
for (auto &[id, helper] : exposureModeHelpers_)
- helper->configure(config.lineDuration,
- config.minExposureTime, config.maxExposureTime,
- config.maxFrameDuration,
- config.minAnalogueGain, config.maxAnalogueGain,
+ helper->configure(config->lineDuration,
+ config->minExposureTime, config->maxExposureTime,
+ config->minFrameDuration, &config->maxFrameDuration,
+ config->minAnalogueGain, config->maxAnalogueGain,
sensorHelper);
}
@@ -46,12 +46,13 @@ public:
utils::Duration lineDuration;
utils::Duration minExposureTime;
utils::Duration maxExposureTime;
+ utils::Duration minFrameDuration;
utils::Duration maxFrameDuration;
double minAnalogueGain;
double maxAnalogueGain;
};
- void configure(const AgcSensorConfiguration &config,
+ void configure(AgcSensorConfiguration *config,
const CameraSensorHelper *sensorHelper);
int parseTuningData(const YamlObject &tuningData);
@@ -111,7 +111,8 @@ void ExposureModeHelper::setMaxExposure(utils::Duration minExposureTime,
* \param[in] lineDuration The current line length of the sensor
* \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] minFrameDuration The minimum frame duration
+ * \param[inout] maxFrameDuration The maximum frame duration
* \param[in] minGain The minimum analogue gain supported
* \param[in] maxGain The maximum analogue gain supported
* \param[in] sensorHelper The sensor helper
@@ -128,17 +129,29 @@ void ExposureModeHelper::setMaxExposure(utils::Duration minExposureTime,
void ExposureModeHelper::configure(utils::Duration lineDuration,
utils::Duration minExposureTime,
utils::Duration maxExposureTime,
- utils::Duration maxFrameDuration,
+ utils::Duration minFrameDuration,
+ utils::Duration *maxFrameDuration,
double minGain, double maxGain,
const CameraSensorHelper *sensorHelper)
{
lineDuration_ = lineDuration;
- maxFrameDuration_ = maxFrameDuration;
minGain_ = minGain;
maxGain_ = maxGain;
sensorHelper_ = sensorHelper;
- setMaxExposure(minExposureTime, maxExposureTime, maxFrameDuration);
+ static constexpr utils::Duration duration30fps = 33.333 * 1ms;
+ static constexpr utils::Duration duration15fps = 66.666 * 1ms;
+ static constexpr utils::Duration duration10fps = 100.00 * 1ms;
+ utils::Duration frameDuration = minFrameDuration < duration30fps
+ ? duration30fps
+ : minFrameDuration < duration15fps
+ ? duration15fps
+ : minFrameDuration < duration10fps
+ ? duration10fps : minFrameDuration;
+ frameDuration = std::min(frameDuration, *maxFrameDuration);
+ setMaxExposure(minExposureTime, maxExposureTime, frameDuration);
+
+ maxFrameDuration_ = *maxFrameDuration = frameDuration;
}
/**
@@ -27,11 +27,12 @@ public:
~ExposureModeHelper() = default;
void configure(utils::Duration lineLength, utils::Duration minExposureTime,
- utils::Duration maxExposureTime, utils::Duration maxFrameDuration,
- double minGain, double maxGain,
+ utils::Duration maxExposureTime, utils::Duration minFrameDuration,
+ utils::Duration *maxFrameDuration, double minGain, double maxGain,
const CameraSensorHelper *sensorHelper);
void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
- utils::Duration maxFrameDuration, double minGain, double maxGain);
+ utils::Duration maxFrameDuration,
+ double minGain, double maxGain);
std::tuple<utils::Duration, double, double, double>
splitExposure(utils::Duration exposure) const;
@@ -175,12 +175,14 @@ int Agc::configure(IPAContext &context,
sensorConfig.lineDuration = context.configuration.sensor.lineDuration;
sensorConfig.minExposureTime = context.configuration.agc.minShutterSpeed;
sensorConfig.maxExposureTime = context.configuration.agc.maxShutterSpeed;
+ sensorConfig.minFrameDuration =
+ std::chrono::microseconds(frameDurationLimits.min().get<int64_t>());
sensorConfig.maxFrameDuration =
std::chrono::microseconds(frameDurationLimits.max().get<int64_t>());
sensorConfig.minAnalogueGain = context.configuration.agc.minAnalogueGain;
sensorConfig.maxAnalogueGain = context.configuration.agc.maxAnalogueGain;
- AgcMeanLuminance::configure(sensorConfig, context.camHelper.get());
+ AgcMeanLuminance::configure(&sensorConfig, context.camHelper.get());
/* \todo Update AGC limits when FrameDurationLimits is passed in */
@@ -190,10 +190,13 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
context.activeState.agc.meteringMode =
static_cast<controls::AeMeteringModeEnum>(meteringModes_.begin()->first);
- /* Limit the frame duration to match current initialisation */
+ /*
+ * Initialize frame duration with the camera limits and update it to
+ * the value computed by AgcMeanLuminance::configure().
+ */
ControlInfo &frameDurationLimits = context.ctrlMap[&controls::FrameDurationLimits];
context.activeState.agc.minFrameDuration = std::chrono::microseconds(frameDurationLimits.min().get<int64_t>());
- context.activeState.agc.maxFrameDuration = std::chrono::microseconds(frameDurationLimits.max().get<int64_t>());
+ utils::Duration maxFrameDuration = std::chrono::microseconds(frameDurationLimits.max().get<int64_t>());
context.configuration.agc.measureWindow.h_offs = 0;
context.configuration.agc.measureWindow.v_offs = 0;
@@ -204,12 +207,14 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
sensorConfig.lineDuration = context.configuration.sensor.lineDuration;
sensorConfig.minExposureTime = context.configuration.sensor.minExposureTime;
sensorConfig.maxExposureTime = context.configuration.sensor.maxExposureTime;
- sensorConfig.maxFrameDuration = context.activeState.agc.maxFrameDuration;
+ sensorConfig.minFrameDuration = context.activeState.agc.minFrameDuration;
+ sensorConfig.maxFrameDuration = maxFrameDuration;
sensorConfig.minAnalogueGain = context.configuration.sensor.minAnalogueGain;
sensorConfig.maxAnalogueGain = context.configuration.sensor.maxAnalogueGain;
- AgcMeanLuminance::configure(sensorConfig, context.camHelper.get());
+ AgcMeanLuminance::configure(&sensorConfig, context.camHelper.get());
+ context.activeState.agc.maxFrameDuration = sensorConfig.maxFrameDuration;
context.activeState.agc.automatic.yTarget = effectiveYTarget();
resetFrameCount();
The AGC algorithm implemented by AgcMeanLuminance splits the desired exposure between shutter time, analogue and digital gains. It tries to maximize the shutter time up to the specified limits and then increases the gains. When initializing the algorithm at configure() time the IPA modules have access to the Camera's absolute limits, which might include a very long maximum frame duration. If such duration is used to clamp the maximum exposure, the algorithm will maximize the shutter time, resulting in a very low frame rate. Try to pick a slighlty saner default of 30, 15 or 10 fps to limit the maximum shutter time with to provide a reasonable out-of-the-box behaviour for users. The new frame duration limit calculated by the AGC algorithm is passed back to the IPA module that shall use it to compute the right blankings to configure the camera with. At the moment, only the RkISP1 IPA actually controls the frame duration, and so it is the only IPA that needs to use the frame duration limit computed by the AGC algorithm. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> --- src/ipa/ipu3/algorithms/agc.cpp | 4 +++- src/ipa/libipa/agc_mean_luminance.cpp | 20 ++++++++++++++------ src/ipa/libipa/agc_mean_luminance.h | 3 ++- src/ipa/libipa/exposure_mode_helper.cpp | 21 +++++++++++++++++---- src/ipa/libipa/exposure_mode_helper.h | 7 ++++--- src/ipa/mali-c55/algorithms/agc.cpp | 4 +++- src/ipa/rkisp1/algorithms/agc.cpp | 13 +++++++++---- 7 files changed, 52 insertions(+), 20 deletions(-)