[PATCH 4/8] ipa: rkisp1: Add correction for exposure quantization
Stefan Klug
stefan.klug at ideasonboard.com
Fri Apr 11 15:04:11 CEST 2025
When WDR regulation is active, it can happen that exposure times get set
to very low values (Sometimes 2-3 lines). This intentionally introduced
underexposure is corrected by the GWDR module. As exposure time is
quantized by lines, the smalles possible change in exposure time now
results in a quite visible change in perceived brightness.
Mitigate that by applying a small global gain to account for the error
introduced by the exposure quantization.
ToDo: This needs perfect frame synchronous control of the sensor to work
properly which is not guaranteed in all cases. It still improves the
behavior with the current regulation.
Signed-off-by: Stefan Klug <stefan.klug at ideasonboard.com>
---
src/ipa/rkisp1/algorithms/agc.cpp | 2 ++
src/ipa/rkisp1/algorithms/awb.cpp | 12 ++++++++----
src/ipa/rkisp1/ipa_context.h | 2 ++
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index 8e77455e7afd..0e4fd3663167 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -583,6 +583,8 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
activeState.agc.automatic.exposure = newExposureTime / lineDuration;
activeState.agc.automatic.gain = aGain;
+ activeState.agc.automatic.gainLostInExposureQuantization =
+ newExposureTime / (activeState.agc.automatic.exposure * lineDuration);
/*
* Expand the target frame duration so that we do not run faster than
* the minimum frame duration when we have short exposures.
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp
index 84aa1d29419d..cc78136a22c8 100644
--- a/src/ipa/rkisp1/algorithms/awb.cpp
+++ b/src/ipa/rkisp1/algorithms/awb.cpp
@@ -170,6 +170,7 @@ void Awb::queueRequest(IPAContext &context,
awbAlgo_->handleControls(controls);
frameContext.awb.autoEnabled = awb.autoEnabled;
+ frameContext.awb.additionalGain = 1.0;
if (awb.autoEnabled)
return;
@@ -218,15 +219,18 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,
auto &awb = context.activeState.awb;
frameContext.awb.gains = awb.automatic.gains;
frameContext.awb.temperatureK = awb.automatic.temperatureK;
+ frameContext.awb.additionalGain =
+ context.activeState.agc.automatic.gainLostInExposureQuantization;
}
+ auto gains = frameContext.awb.gains * frameContext.awb.additionalGain;
auto gainConfig = params->block<BlockType::AwbGain>();
gainConfig.setEnabled(true);
- gainConfig->gain_green_b = std::clamp<int>(256 * frameContext.awb.gains.g(), 0, 0x3ff);
- gainConfig->gain_blue = std::clamp<int>(256 * frameContext.awb.gains.b(), 0, 0x3ff);
- gainConfig->gain_red = std::clamp<int>(256 * frameContext.awb.gains.r(), 0, 0x3ff);
- gainConfig->gain_green_r = std::clamp<int>(256 * frameContext.awb.gains.g(), 0, 0x3ff);
+ gainConfig->gain_green_b = std::clamp<int>(256 * gains.g(), 0, 0x3ff);
+ gainConfig->gain_blue = std::clamp<int>(256 * gains.b(), 0, 0x3ff);
+ gainConfig->gain_red = std::clamp<int>(256 * gains.r(), 0, 0x3ff);
+ gainConfig->gain_green_r = std::clamp<int>(256 * gains.g(), 0, 0x3ff);
/* If we have already set the AWB measurement parameters, return. */
if (frame > 0)
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index 7ccc7b501aff..182203880ac9 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -76,6 +76,7 @@ struct IPAActiveState {
} manual;
struct {
uint32_t exposure;
+ double gainLostInExposureQuantization;
double gain;
} automatic;
@@ -149,6 +150,7 @@ struct IPAFrameContext : public FrameContext {
RGB<double> gains;
bool autoEnabled;
unsigned int temperatureK;
+ double additionalGain;
} awb;
struct {
--
2.43.0
More information about the libcamera-devel
mailing list