ipa: software_isp: AGC: Do not lower gain below 1.0

At the moment when the overall image brightness is considered too high
the AGC code will lower the gain all the way down to againMin before
considering lowering the exposure.

What should happen instead is lower the gain no lower than 1.0 and after
that lower the exposure instead of lowering the gain.

Otherwise there might be a heavily overexposed image (e.g. all white)
which then is made less white by a gain < 1.0 which is no good.

When there is no sensor-helper, assume the driver reported default-gain
value is close to a gain of 1.0 .

While at it also remove the weird limitation to only lower the gain
when exposure is set to the maximum. As long as the gain is higher
than the default gain, the gain should be lowered first.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Signed-off-by: Hans de Goede <hansg@kernel.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Hans de Goede
2025-09-30 17:04:24 +02:00
committed by Kieran Bingham
parent 7a7935e4bc
commit 950ca85e8a
3 changed files with 5 additions and 3 deletions

View File

@@ -71,8 +71,7 @@ void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, dou
} }
if (exposureMSV > kExposureOptimal + kExposureSatisfactory) { if (exposureMSV > kExposureOptimal + kExposureSatisfactory) {
if (exposure == context.configuration.agc.exposureMax && if (again > context.configuration.agc.again10) {
again > context.configuration.agc.againMin) {
next = again * kExpNumeratorDown / kExpDenominator; next = again * kExpNumeratorDown / kExpDenominator;
if (again - next < context.configuration.agc.againMinStep) if (again - next < context.configuration.agc.againMinStep)
again -= context.configuration.agc.againMinStep; again -= context.configuration.agc.againMinStep;

View File

@@ -28,7 +28,7 @@ struct IPASessionConfiguration {
float gamma; float gamma;
struct { struct {
int32_t exposureMin, exposureMax; int32_t exposureMin, exposureMax;
double againMin, againMax, againMinStep; double againMin, againMax, again10, againMinStep;
utils::Duration lineDuration; utils::Duration lineDuration;
} agc; } agc;
struct { struct {

View File

@@ -216,10 +216,12 @@ int IPASoftSimple::configure(const IPAConfigInfo &configInfo)
int32_t againMin = gainInfo.min().get<int32_t>(); int32_t againMin = gainInfo.min().get<int32_t>();
int32_t againMax = gainInfo.max().get<int32_t>(); int32_t againMax = gainInfo.max().get<int32_t>();
int32_t againDef = gainInfo.def().get<int32_t>();
if (camHelper_) { if (camHelper_) {
context_.configuration.agc.againMin = camHelper_->gain(againMin); context_.configuration.agc.againMin = camHelper_->gain(againMin);
context_.configuration.agc.againMax = camHelper_->gain(againMax); context_.configuration.agc.againMax = camHelper_->gain(againMax);
context_.configuration.agc.again10 = camHelper_->gain(1.0);
context_.configuration.agc.againMinStep = context_.configuration.agc.againMinStep =
(context_.configuration.agc.againMax - (context_.configuration.agc.againMax -
context_.configuration.agc.againMin) / context_.configuration.agc.againMin) /
@@ -246,6 +248,7 @@ int IPASoftSimple::configure(const IPAConfigInfo &configInfo)
* other) we limit the range of the gain values used. * other) we limit the range of the gain values used.
*/ */
context_.configuration.agc.againMax = againMax; context_.configuration.agc.againMax = againMax;
context_.configuration.agc.again10 = againDef;
if (againMin) { if (againMin) {
context_.configuration.agc.againMin = againMin; context_.configuration.agc.againMin = againMin;
} else { } else {