libipa: agc_mean_luminance: Add support for additional constraints

Add support for additional constraints added at runtime. This is for
example useful for WDR use cases where you want to add an upper
constraint to limit the amount of saturated pixels.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Stefan Klug
2025-09-19 11:40:31 +02:00
committed by Kieran Bingham
parent 6eb02d6759
commit 06fe931d79
5 changed files with 20 additions and 9 deletions
+1 -1
View File
@@ -117,7 +117,7 @@ int Agc::configure(IPAContext &context,
/* \todo Run this again when FrameDurationLimits is passed in */
setLimits(minExposureTime_, maxExposureTime_, minAnalogueGain_,
maxAnalogueGain_);
maxAnalogueGain_, {});
resetFrameCount();
return 0;
+13 -4
View File
@@ -7,6 +7,7 @@
#include "agc_mean_luminance.h"
#include <algorithm>
#include <cmath>
#include <libcamera/base/log.h>
@@ -408,16 +409,20 @@ int AgcMeanLuminance::parseTuningData(const YamlObject &tuningData)
* \param[in] maxExposureTime Maximum ewposure time to allow
* \param[in] minGain Minimum gain to allow
* \param[in] maxGain Maximum gain to allow
* \param[in] constraints Additional constraints to apply
*
* This function calls \ref ExposureModeHelper::setLimits() for each
* ExposureModeHelper that has been created for this class.
*/
void AgcMeanLuminance::setLimits(utils::Duration minExposureTime,
utils::Duration maxExposureTime,
double minGain, double maxGain)
double minGain, double maxGain,
std::vector<AgcMeanLuminance::AgcConstraint> constraints)
{
for (auto &[id, helper] : exposureModeHelpers_)
helper->setLimits(minExposureTime, maxExposureTime, minGain, maxGain);
additionalConstraints_ = std::move(constraints);
}
/**
@@ -495,8 +500,7 @@ double AgcMeanLuminance::constraintClampGain(uint32_t constraintModeIndex,
const Histogram &hist,
double gain)
{
std::vector<AgcConstraint> &constraints = constraintModes_[constraintModeIndex];
for (const AgcConstraint &constraint : constraints) {
auto applyConstraint = [&gain, &hist](const AgcConstraint &constraint) {
double newGain = constraint.yTarget * hist.bins() /
hist.interQuantileMean(constraint.qLo, constraint.qHi);
@@ -515,7 +519,12 @@ double AgcMeanLuminance::constraintClampGain(uint32_t constraintModeIndex,
<< newGain;
gain = newGain;
}
}
};
std::vector<AgcConstraint> &constraints = constraintModes_[constraintModeIndex];
std::for_each(constraints.begin(), constraints.end(), applyConstraint);
std::for_each(additionalConstraints_.begin(), additionalConstraints_.end(), applyConstraint);
return gain;
}
+2 -1
View File
@@ -51,7 +51,7 @@ public:
}
void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
double minGain, double maxGain);
double minGain, double maxGain, std::vector<AgcConstraint> constraints);
std::map<int32_t, std::vector<AgcConstraint>> constraintModes()
{
@@ -97,6 +97,7 @@ private:
utils::Duration filteredExposure_;
double relativeLuminanceTarget_;
std::vector<AgcConstraint> additionalConstraints_;
std::map<int32_t, std::vector<AgcConstraint>> constraintModes_;
std::map<int32_t, std::shared_ptr<ExposureModeHelper>> exposureModeHelpers_;
ControlInfoMap::Map controls_;
+2 -1
View File
@@ -173,7 +173,8 @@ int Agc::configure(IPAContext &context,
setLimits(context.configuration.agc.minShutterSpeed,
context.configuration.agc.maxShutterSpeed,
context.configuration.agc.minAnalogueGain,
context.configuration.agc.maxAnalogueGain);
context.configuration.agc.maxAnalogueGain,
{});
resetFrameCount();
+2 -2
View File
@@ -206,7 +206,7 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
setLimits(context.configuration.sensor.minExposureTime,
context.configuration.sensor.maxExposureTime,
context.configuration.sensor.minAnalogueGain,
context.configuration.sensor.maxAnalogueGain);
context.configuration.sensor.maxAnalogueGain, {});
resetFrameCount();
@@ -590,7 +590,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
maxAnalogueGain = frameContext.agc.gain;
}
setLimits(minExposureTime, maxExposureTime, minAnalogueGain, maxAnalogueGain);
setLimits(minExposureTime, maxExposureTime, minAnalogueGain, maxAnalogueGain, {});
/*
* The Agc algorithm needs to know the effective exposure value that was