Message ID | 20250815102945.1602071-11-stefan.klug@ideasonboard.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
Quoting Stefan Klug (2025-08-15 19:29:30) > There are several occations where quantization can lead to visible > effects. > > In WDR mode 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 smallest possible change in exposure time now results in a quite > visible change in perceived brightness. > > Sometimes the possible gain steps are also quite large leading to > visible jumps if e.g. if the exposure time is fixed. > > Mitigate that by applying a 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 and can easily be skipped, when > there is no compress algorithm. > > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> > > --- > > Changes in v3: > - Collected tags > --- > src/ipa/rkisp1/algorithms/agc.cpp | 24 +++++++++++++++++++++--- > src/ipa/rkisp1/ipa_context.h | 2 ++ > 2 files changed, 23 insertions(+), 3 deletions(-) > > diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp > index 0a29326841fb..d34c041f9fe1 100644 > --- a/src/ipa/rkisp1/algorithms/agc.cpp > +++ b/src/ipa/rkisp1/algorithms/agc.cpp > @@ -199,6 +199,9 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) > context.configuration.agc.measureWindow.h_size = configInfo.outputSize.width; > context.configuration.agc.measureWindow.v_size = configInfo.outputSize.height; > > + AgcMeanLuminance::configure(context.configuration.sensor.lineDuration, > + context.camHelper.get()); > + > setLimits(context.configuration.sensor.minExposureTime, > context.configuration.sensor.maxExposureTime, > context.configuration.sensor.minAnalogueGain, > @@ -283,6 +286,10 @@ void Agc::queueRequest(IPAContext &context, > if (!frameContext.agc.autoGainEnabled) > frameContext.agc.gain = agc.manual.gain; > > + if (!frameContext.agc.autoExposureEnabled && > + !frameContext.agc.autoGainEnabled) > + frameContext.agc.quantizationGain = 1.0; > + > const auto &meteringMode = controls.get(controls::AeMeteringMode); > if (meteringMode) { > frameContext.agc.updateMetering = agc.meteringMode != *meteringMode; > @@ -336,12 +343,17 @@ void Agc::prepare(IPAContext &context, const uint32_t frame, > { > uint32_t activeAutoExposure = context.activeState.agc.automatic.exposure; > double activeAutoGain = context.activeState.agc.automatic.gain; > + double activeAutoQGain = context.activeState.agc.automatic.quantizationGain; > > /* Populate exposure and gain in auto mode */ > - if (frameContext.agc.autoExposureEnabled) > + if (frameContext.agc.autoExposureEnabled) { > frameContext.agc.exposure = activeAutoExposure; > - if (frameContext.agc.autoGainEnabled) > + frameContext.agc.quantizationGain = activeAutoQGain; > + } > + if (frameContext.agc.autoGainEnabled) { > frameContext.agc.gain = activeAutoGain; > + frameContext.agc.quantizationGain = activeAutoQGain; > + } > > /* > * Populate manual exposure and gain from the active auto values when > @@ -354,6 +366,12 @@ void Agc::prepare(IPAContext &context, const uint32_t frame, > if (!frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) { > context.activeState.agc.manual.gain = activeAutoGain; > frameContext.agc.gain = activeAutoGain; > + frameContext.agc.quantizationGain = activeAutoQGain; > + } > + > + if (context.activeState.compress.supported) { > + frameContext.compress.enable = true; > + frameContext.compress.gain = frameContext.agc.quantizationGain; > } > > if (frame > 0 && !frameContext.agc.updateMetering) > @@ -582,7 +600,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, > /* Update the estimated exposure and gain. */ > activeState.agc.automatic.exposure = newExposureTime / lineDuration; > activeState.agc.automatic.gain = aGain; > - > + activeState.agc.automatic.quantizationGain = qGain; > /* > * 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/ipa_context.h b/src/ipa/rkisp1/ipa_context.h > index 37a74215ce19..362ab2fda5fe 100644 > --- a/src/ipa/rkisp1/ipa_context.h > +++ b/src/ipa/rkisp1/ipa_context.h > @@ -77,6 +77,7 @@ struct IPAActiveState { > struct { > uint32_t exposure; > double gain; > + double quantizationGain; > } automatic; > > bool autoExposureEnabled; > @@ -135,6 +136,7 @@ struct IPAFrameContext : public FrameContext { > uint32_t exposure; > double gain; > double exposureValue; > + double quantizationGain; > uint32_t vblank; > bool autoExposureEnabled; > bool autoGainEnabled; > -- > 2.48.1 >
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index 0a29326841fb..d34c041f9fe1 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -199,6 +199,9 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) context.configuration.agc.measureWindow.h_size = configInfo.outputSize.width; context.configuration.agc.measureWindow.v_size = configInfo.outputSize.height; + AgcMeanLuminance::configure(context.configuration.sensor.lineDuration, + context.camHelper.get()); + setLimits(context.configuration.sensor.minExposureTime, context.configuration.sensor.maxExposureTime, context.configuration.sensor.minAnalogueGain, @@ -283,6 +286,10 @@ void Agc::queueRequest(IPAContext &context, if (!frameContext.agc.autoGainEnabled) frameContext.agc.gain = agc.manual.gain; + if (!frameContext.agc.autoExposureEnabled && + !frameContext.agc.autoGainEnabled) + frameContext.agc.quantizationGain = 1.0; + const auto &meteringMode = controls.get(controls::AeMeteringMode); if (meteringMode) { frameContext.agc.updateMetering = agc.meteringMode != *meteringMode; @@ -336,12 +343,17 @@ void Agc::prepare(IPAContext &context, const uint32_t frame, { uint32_t activeAutoExposure = context.activeState.agc.automatic.exposure; double activeAutoGain = context.activeState.agc.automatic.gain; + double activeAutoQGain = context.activeState.agc.automatic.quantizationGain; /* Populate exposure and gain in auto mode */ - if (frameContext.agc.autoExposureEnabled) + if (frameContext.agc.autoExposureEnabled) { frameContext.agc.exposure = activeAutoExposure; - if (frameContext.agc.autoGainEnabled) + frameContext.agc.quantizationGain = activeAutoQGain; + } + if (frameContext.agc.autoGainEnabled) { frameContext.agc.gain = activeAutoGain; + frameContext.agc.quantizationGain = activeAutoQGain; + } /* * Populate manual exposure and gain from the active auto values when @@ -354,6 +366,12 @@ void Agc::prepare(IPAContext &context, const uint32_t frame, if (!frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) { context.activeState.agc.manual.gain = activeAutoGain; frameContext.agc.gain = activeAutoGain; + frameContext.agc.quantizationGain = activeAutoQGain; + } + + if (context.activeState.compress.supported) { + frameContext.compress.enable = true; + frameContext.compress.gain = frameContext.agc.quantizationGain; } if (frame > 0 && !frameContext.agc.updateMetering) @@ -582,7 +600,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, /* Update the estimated exposure and gain. */ activeState.agc.automatic.exposure = newExposureTime / lineDuration; activeState.agc.automatic.gain = aGain; - + activeState.agc.automatic.quantizationGain = qGain; /* * 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/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 37a74215ce19..362ab2fda5fe 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -77,6 +77,7 @@ struct IPAActiveState { struct { uint32_t exposure; double gain; + double quantizationGain; } automatic; bool autoExposureEnabled; @@ -135,6 +136,7 @@ struct IPAFrameContext : public FrameContext { uint32_t exposure; double gain; double exposureValue; + double quantizationGain; uint32_t vblank; bool autoExposureEnabled; bool autoGainEnabled;