@@ -262,6 +262,15 @@ namespace agc {
* control only, without automatic adjustments. In this mode statistics
* must not be provided to AgcAlgorithm::process(), and ExposureTimeMode
* and AnalogueGainMode will only advertise manual control.
+ *
+ * \var AgcAlgorithm::ConfigurationParams::numStartupFrames
+ * \brief Number of startup frames
+ *
+ * During these frame the regulation speed is set to 1.0 to reach faster
+ * convergence.
+ *
+ * \var AgcAlgorithm::ConfigurationParams::regulationSpeed
+ * \brief The regulation speed
*/
/**
@@ -513,6 +522,11 @@ int AgcAlgorithm::configure(agc::Session &session, agc::ActiveState &state,
state.automatic.yTarget = impl.effectiveYTarget(0, 1);
impl.configure(session.lineDuration, sensor_);
+ if (config.numStartupFrames)
+ impl.numStartupFrames_ = config.numStartupFrames.value();
+
+ if (config.regulationSpeed)
+ impl.regulationSpeed_ = config.regulationSpeed.value();
if (!session.autoAllowed)
return;
@@ -126,6 +126,8 @@ public:
const ControlInfoMap &sensorControls;
ControlInfoMap::Map &ctrlMap;
bool autoAllowed = true;
+ std::optional<uint32_t> numStartupFrames = std::nullopt;
+ std::optional<double> regulationSpeed = std::nullopt;
};
struct ProcessParams {
@@ -37,7 +37,7 @@ namespace ipa {
* Number of frames for which to run the algorithm at full speed, before slowing
* down to prevent large and jarring changes in exposure from frame to frame.
*/
-static constexpr uint32_t kNumStartupFrames = 10;
+static constexpr uint32_t kDefaultNumStartupFrames = 10;
/*
* Default relative luminance target
@@ -178,7 +178,8 @@ static constexpr unsigned int kDefaultLuxLevel = 500;
*/
AgcMeanLuminance::AgcMeanLuminance()
- : filteredExposure_(0s), luxWarningEnabled_(true), frameCount_(0)
+ : numStartupFrames_(kDefaultNumStartupFrames), regulationSpeed_(0.2),
+ filteredExposure_(0s), luxWarningEnabled_(true), frameCount_(0)
{
}
@@ -587,10 +588,10 @@ double AgcMeanLuminance::effectiveYTarget(double lux, double exposureCompensatio
*/
utils::Duration AgcMeanLuminance::filterExposure(utils::Duration exposureValue)
{
- double speed = 0.2;
+ double speed = regulationSpeed_;
/* Adapt instantly if we are in startup phase. */
- if (frameCount_ < kNumStartupFrames)
+ if (frameCount_ < numStartupFrames_)
speed = 1.0;
/*
@@ -701,6 +702,22 @@ AgcMeanLuminance::calculateNewEv(const Params ¶ms)
return { exposureModeHelper.splitExposure(newExposureValue), yTarget };
}
+/**
+ * \var AgcMeanLuminance::numStartupFrames_
+ * \brief The number of startup frames
+ *
+ * During this number of frames after startup, the regulation is very aggressive
+ * to reach the target value within one or two cycles.
+ *
+ * \var AgcMeanLuminance::regulationSpeed_
+ * The regulation speed. This controls the speed at which new target values are
+ * applied. The new target value is calculated as:
+ *
+ * \code{.unparsed}
+ * value = target * speed + oldValue * (1.0 - speed)
+ * \endcode
+ */
+
} /* namespace ipa */
} /* namespace libcamera */
@@ -79,6 +79,9 @@ public:
double effectiveYTarget(double lux, double exposureCompensation) const;
+ uint32_t numStartupFrames_;
+ double regulationSpeed_;
+
private:
int parseRelativeLuminanceTarget(const ValueNode &tuningData);
int parseConstraint(const ValueNode &modeDict, int32_t id);
The rkisp1 has now a good synchronization between sensor settings/isp params and stats. It can therefore benefit from a faster regulation. To do that without breaking other IPAs that use AgcMeanLuminance, move regulation speed and startup frames into configuration parameters that can be set at runtime. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> --- src/ipa/libipa/agc.cpp | 14 ++++++++++++++ src/ipa/libipa/agc.h | 2 ++ src/ipa/libipa/agc_mean_luminance.cpp | 25 +++++++++++++++++++++---- src/ipa/libipa/agc_mean_luminance.h | 3 +++ 4 files changed, 40 insertions(+), 4 deletions(-)