Message ID | 20241205112241.641964-7-paul.elder@ideasonboard.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi Paul, Thank you for the patch. On Thu, Dec 05, 2024 at 08:22:39PM +0900, Paul Elder wrote: > The newly introduced controls to drive the AEGC algorithm allow > controlling the computation of the exposure time and analogue gain > separately. > > Augument the RkISP1 AEGC implementation to handle the exposure and gain > controls separately using the new controls. > > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> > > --- > Changes in v4: > - make auto the default value in the control infos > - implement the expected behavior when transitioning between manual and > auto modes > > New in v3 > > Back 2 years ago in v2 RkISP1 didn't yet support AeEnable properly yet > so the AeEnable control was simply removed. > --- > src/ipa/rkisp1/algorithms/agc.cpp | 102 +++++++++++++++++++++++++----- > src/ipa/rkisp1/ipa_context.cpp | 22 +++++-- > src/ipa/rkisp1/ipa_context.h | 8 ++- > 3 files changed, 110 insertions(+), 22 deletions(-) > > diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp > index 40e5a8f481b2..c92115e8cc0d 100644 > --- a/src/ipa/rkisp1/algorithms/agc.cpp > +++ b/src/ipa/rkisp1/algorithms/agc.cpp > @@ -148,7 +148,14 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData) > if (ret) > return ret; > > - context.ctrlMap[&controls::AeEnable] = ControlInfo(false, true); > + context.ctrlMap[&controls::ExposureTimeMode] = > + ControlInfo(static_cast<int32_t>(controls::ExposureTimeModeAuto), > + static_cast<int32_t>(controls::ExposureTimeModeManual), > + static_cast<int32_t>(controls::ExposureTimeModeAuto)); > + context.ctrlMap[&controls::AnalogueGainMode] = > + ControlInfo(static_cast<int32_t>(controls::AnalogueGainModeAuto), > + static_cast<int32_t>(controls::AnalogueGainModeManual), > + static_cast<int32_t>(controls::AnalogueGainModeAuto)); > context.ctrlMap.merge(controls()); > > return 0; > @@ -169,7 +176,8 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) > 10ms / context.configuration.sensor.lineDuration; > context.activeState.agc.manual.gain = context.activeState.agc.automatic.gain; > context.activeState.agc.manual.exposure = context.activeState.agc.automatic.exposure; > - context.activeState.agc.autoEnabled = !context.configuration.raw; > + context.activeState.agc.autoExposureEnabled = !context.configuration.raw; > + context.activeState.agc.autoGainEnabled = !context.configuration.raw; > > context.activeState.agc.constraintMode = > static_cast<controls::AeConstraintModeEnum>(constraintModes().begin()->first); > @@ -215,18 +223,44 @@ void Agc::queueRequest(IPAContext &context, > auto &agc = context.activeState.agc; > > if (!context.configuration.raw) { > - const auto &agcEnable = controls.get(controls::AeEnable); > - if (agcEnable && *agcEnable != agc.autoEnabled) { > - agc.autoEnabled = *agcEnable; > + const auto &aeEnable = controls.get(controls::ExposureTimeMode); > + if (aeEnable && > + (*aeEnable == controls::ExposureTimeModeAuto) != agc.autoExposureEnabled) { > + agc.autoExposureEnabled = (*aeEnable == controls::ExposureTimeModeAuto); > > LOG(RkISP1Agc, Debug) > - << (agc.autoEnabled ? "Enabling" : "Disabling") > - << " AGC"; > + << (agc.autoExposureEnabled ? "Enabling" : "Disabling") > + << " AGC (exposure)"; > + > + /* > + * If we go from auto -> manual with no manual control > + * set, use the last computed value, which we don't > + * know until prepare() so save this information s/$/./ Same below where applicable. > + */ > + if (!agc.autoExposureEnabled && !controls.get(controls::ExposureTime)) > + frameContext.agc.autoExposureModeChange = true; frameContext.agc.autoExposureModeChange is documented as "Indicate if autoExposureEnabled has changed between the previous and current frame", but it records something more specific. The documentation should be updated. Same for autoGainModeChange. A long time ago I envisioned that this could be checked in prepare() by looking at the context for the previous frame. We don't have a good infrastructure to do so yet, so this is fine. I wonder if we should try get there though. Maybe a \todo comment would be useful ? > + } > + > + const auto &agEnable = controls.get(controls::AnalogueGainMode); > + if (agEnable && > + (*agEnable == controls::AnalogueGainModeAuto) != agc.autoGainEnabled) { > + agc.autoGainEnabled = (*agEnable == controls::AnalogueGainModeAuto); > + > + LOG(RkISP1Agc, Debug) > + << (agc.autoGainEnabled ? "Enabling" : "Disabling") > + << " AGC (gain)"; > + /* > + * If we go from auto -> manual with no manual control > + * set, use the last computed value, which we don't > + * know until prepare() so save this information > + */ > + if (!agc.autoGainEnabled && !controls.get(controls::AnalogueGain)) > + frameContext.agc.autoGainModeChange = true; > } > } > > const auto &exposure = controls.get(controls::ExposureTime); > - if (exposure && !agc.autoEnabled) { > + if (exposure && !agc.autoExposureEnabled) { > agc.manual.exposure = *exposure * 1.0us > / context.configuration.sensor.lineDuration; > > @@ -235,18 +269,19 @@ void Agc::queueRequest(IPAContext &context, > } > > const auto &gain = controls.get(controls::AnalogueGain); > - if (gain && !agc.autoEnabled) { > + if (gain && !agc.autoGainEnabled) { > agc.manual.gain = *gain; > > LOG(RkISP1Agc, Debug) << "Set gain to " << agc.manual.gain; > } > > - frameContext.agc.autoEnabled = agc.autoEnabled; > + frameContext.agc.autoExposureEnabled = agc.autoExposureEnabled; > + frameContext.agc.autoGainEnabled = agc.autoGainEnabled; > > - if (!frameContext.agc.autoEnabled) { > + if (!frameContext.agc.autoExposureEnabled) > frameContext.agc.exposure = agc.manual.exposure; > + if (!frameContext.agc.autoGainEnabled) > frameContext.agc.gain = agc.manual.gain; > - } > > const auto &meteringMode = controls.get(controls::AeMeteringMode); > if (meteringMode) { > @@ -283,9 +318,26 @@ void Agc::queueRequest(IPAContext &context, > void Agc::prepare(IPAContext &context, const uint32_t frame, > IPAFrameContext &frameContext, RkISP1Params *params) > { > - if (frameContext.agc.autoEnabled) { > - frameContext.agc.exposure = context.activeState.agc.automatic.exposure; > - frameContext.agc.gain = context.activeState.agc.automatic.gain; > + uint32_t activeAutoExposure = context.activeState.agc.automatic.exposure; > + double activeAutoGain = context.activeState.agc.automatic.gain; > + > + /* Populate exposure and gain in auto mode */ > + if (frameContext.agc.autoExposureEnabled) > + frameContext.agc.exposure = activeAutoExposure; > + if (frameContext.agc.autoGainEnabled) > + frameContext.agc.gain = activeAutoGain; > + > + /* > + * Populate manual exposure and gain from the active auto values when > + * transitioning from auto to manual > + */ > + if (!frameContext.agc.autoExposureEnabled && frameContext.agc.autoExposureModeChange) { > + context.activeState.agc.manual.exposure = activeAutoExposure; > + frameContext.agc.exposure = activeAutoExposure; > + } > + if (!frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) { > + context.activeState.agc.manual.gain = activeAutoGain; > + frameContext.agc.gain = activeAutoGain; > } > > if (frame > 0 && !frameContext.agc.updateMetering) > @@ -333,7 +385,14 @@ void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext, > * frameContext.sensor.exposure; > metadata.set(controls::AnalogueGain, frameContext.sensor.gain); > metadata.set(controls::ExposureTime, exposureTime.get<std::micro>()); > - metadata.set(controls::AeEnable, frameContext.agc.autoEnabled); > + metadata.set(controls::ExposureTimeMode, > + frameContext.agc.autoExposureEnabled > + ? controls::ExposureTimeModeAuto > + : controls::ExposureTimeModeManual); > + metadata.set(controls::AnalogueGainMode, > + frameContext.agc.autoGainEnabled > + ? controls::AnalogueGainModeAuto > + : controls::AnalogueGainModeManual); > > /* \todo Use VBlank value calculated from each frame exposure. */ > uint32_t vTotal = context.configuration.sensor.size.height > @@ -459,6 +518,17 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, > / context.configuration.sensor.lineDuration; > activeState.agc.automatic.gain = aGain; > > + /* > + * Populate auto exposure and gain from the active manual values when > + * transitioning from manual to auto > + * > + * The frame context doesn't need to be populated here as it will be populated in prepare() Line wrap. > + */ > + if (frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) > + context.activeState.agc.automatic.exposure = context.activeState.agc.manual.exposure; > + if (frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) > + context.activeState.agc.automatic.gain = context.activeState.agc.manual.gain; > + Is that all that is needed ? When running in e.g. auto-exposure and manual gain, shouldn't the AGC algorithm take that the manual gain into account when dividing the total exposure between exposure time and gain ? With this code the algorithm will compute an exposure time and a gain, and the gain will the be overridden, messing up the total exposure value. > fillMetadata(context, frameContext, metadata); > expMeans_ = {}; > } > diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp > index 80b99df8eaf8..c7ccc3093078 100644 > --- a/src/ipa/rkisp1/ipa_context.cpp > +++ b/src/ipa/rkisp1/ipa_context.cpp > @@ -165,8 +165,11 @@ namespace libcamera::ipa::rkisp1 { > * \var IPAActiveState::agc.automatic.gain > * \brief Automatic analogue gain multiplier > * > - * \var IPAActiveState::agc.autoEnabled > - * \brief Manual/automatic AGC state as set by the AeEnable control > + * \var IPAActiveState::agc.autoExposureEnabled > + * \brief Manual/automatic AGC state (exposure) as set by the ExposureTimeMode control > + * > + * \var IPAActiveState::agc.autoGainEnabled > + * \brief Manual/automatic AGC state (gain) as set by the AnalogueGainMode control > * > * \var IPAActiveState::agc.constraintMode > * \brief Constraint mode as set by the AeConstraintMode control > @@ -289,8 +292,11 @@ namespace libcamera::ipa::rkisp1 { > * > * The gain should be adapted to the sensor specific gain code before applying. > * > - * \var IPAFrameContext::agc.autoEnabled > - * \brief Manual/automatic AGC state as set by the AeEnable control > + * \var IPAFrameContext::agc.autoExposureEnabled > + * \brief Manual/automatic AGC state (exposure) as set by the ExposureTimeMode control > + * > + * \var IPAFrameContext::agc.autoGainEnabled > + * \brief Manual/automatic AGC state (gain) as set by the AnalogueGainMode control > * > * \var IPAFrameContext::agc.constraintMode > * \brief Constraint mode as set by the AeConstraintMode control > @@ -306,6 +312,14 @@ namespace libcamera::ipa::rkisp1 { > * > * \var IPAFrameContext::agc.updateMetering > * \brief Indicate if new ISP AGC metering parameters need to be applied > + * > + * \var IPAFrameContext::agc.autoExposureModeChange > + * \brief Indicate if autoExposureEnabled has changed between the previous and > + * current frame > + * > + * \var IPAFrameContext::agc.autoGainModeChange > + * \brief Indicate if autoGainEnabled has changed between the previous and > + * current frame > */ > > /** > diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h > index deb8c196f1b8..bc3d5a24be3a 100644 > --- a/src/ipa/rkisp1/ipa_context.h > +++ b/src/ipa/rkisp1/ipa_context.h > @@ -79,7 +79,8 @@ struct IPAActiveState { > double gain; > } automatic; > > - bool autoEnabled; > + bool autoExposureEnabled; > + bool autoGainEnabled; > controls::AeConstraintModeEnum constraintMode; > controls::AeExposureModeEnum exposureMode; > controls::AeMeteringModeEnum meteringMode; > @@ -124,12 +125,15 @@ struct IPAFrameContext : public FrameContext { > struct { > uint32_t exposure; > double gain; > - bool autoEnabled; > + bool autoExposureEnabled; > + bool autoGainEnabled; > controls::AeConstraintModeEnum constraintMode; > controls::AeExposureModeEnum exposureMode; > controls::AeMeteringModeEnum meteringMode; > utils::Duration maxFrameDuration; > bool updateMetering; > + bool autoExposureModeChange; > + bool autoGainModeChange; > } agc; > > struct {
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index 40e5a8f481b2..c92115e8cc0d 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -148,7 +148,14 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData) if (ret) return ret; - context.ctrlMap[&controls::AeEnable] = ControlInfo(false, true); + context.ctrlMap[&controls::ExposureTimeMode] = + ControlInfo(static_cast<int32_t>(controls::ExposureTimeModeAuto), + static_cast<int32_t>(controls::ExposureTimeModeManual), + static_cast<int32_t>(controls::ExposureTimeModeAuto)); + context.ctrlMap[&controls::AnalogueGainMode] = + ControlInfo(static_cast<int32_t>(controls::AnalogueGainModeAuto), + static_cast<int32_t>(controls::AnalogueGainModeManual), + static_cast<int32_t>(controls::AnalogueGainModeAuto)); context.ctrlMap.merge(controls()); return 0; @@ -169,7 +176,8 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) 10ms / context.configuration.sensor.lineDuration; context.activeState.agc.manual.gain = context.activeState.agc.automatic.gain; context.activeState.agc.manual.exposure = context.activeState.agc.automatic.exposure; - context.activeState.agc.autoEnabled = !context.configuration.raw; + context.activeState.agc.autoExposureEnabled = !context.configuration.raw; + context.activeState.agc.autoGainEnabled = !context.configuration.raw; context.activeState.agc.constraintMode = static_cast<controls::AeConstraintModeEnum>(constraintModes().begin()->first); @@ -215,18 +223,44 @@ void Agc::queueRequest(IPAContext &context, auto &agc = context.activeState.agc; if (!context.configuration.raw) { - const auto &agcEnable = controls.get(controls::AeEnable); - if (agcEnable && *agcEnable != agc.autoEnabled) { - agc.autoEnabled = *agcEnable; + const auto &aeEnable = controls.get(controls::ExposureTimeMode); + if (aeEnable && + (*aeEnable == controls::ExposureTimeModeAuto) != agc.autoExposureEnabled) { + agc.autoExposureEnabled = (*aeEnable == controls::ExposureTimeModeAuto); LOG(RkISP1Agc, Debug) - << (agc.autoEnabled ? "Enabling" : "Disabling") - << " AGC"; + << (agc.autoExposureEnabled ? "Enabling" : "Disabling") + << " AGC (exposure)"; + + /* + * If we go from auto -> manual with no manual control + * set, use the last computed value, which we don't + * know until prepare() so save this information + */ + if (!agc.autoExposureEnabled && !controls.get(controls::ExposureTime)) + frameContext.agc.autoExposureModeChange = true; + } + + const auto &agEnable = controls.get(controls::AnalogueGainMode); + if (agEnable && + (*agEnable == controls::AnalogueGainModeAuto) != agc.autoGainEnabled) { + agc.autoGainEnabled = (*agEnable == controls::AnalogueGainModeAuto); + + LOG(RkISP1Agc, Debug) + << (agc.autoGainEnabled ? "Enabling" : "Disabling") + << " AGC (gain)"; + /* + * If we go from auto -> manual with no manual control + * set, use the last computed value, which we don't + * know until prepare() so save this information + */ + if (!agc.autoGainEnabled && !controls.get(controls::AnalogueGain)) + frameContext.agc.autoGainModeChange = true; } } const auto &exposure = controls.get(controls::ExposureTime); - if (exposure && !agc.autoEnabled) { + if (exposure && !agc.autoExposureEnabled) { agc.manual.exposure = *exposure * 1.0us / context.configuration.sensor.lineDuration; @@ -235,18 +269,19 @@ void Agc::queueRequest(IPAContext &context, } const auto &gain = controls.get(controls::AnalogueGain); - if (gain && !agc.autoEnabled) { + if (gain && !agc.autoGainEnabled) { agc.manual.gain = *gain; LOG(RkISP1Agc, Debug) << "Set gain to " << agc.manual.gain; } - frameContext.agc.autoEnabled = agc.autoEnabled; + frameContext.agc.autoExposureEnabled = agc.autoExposureEnabled; + frameContext.agc.autoGainEnabled = agc.autoGainEnabled; - if (!frameContext.agc.autoEnabled) { + if (!frameContext.agc.autoExposureEnabled) frameContext.agc.exposure = agc.manual.exposure; + if (!frameContext.agc.autoGainEnabled) frameContext.agc.gain = agc.manual.gain; - } const auto &meteringMode = controls.get(controls::AeMeteringMode); if (meteringMode) { @@ -283,9 +318,26 @@ void Agc::queueRequest(IPAContext &context, void Agc::prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, RkISP1Params *params) { - if (frameContext.agc.autoEnabled) { - frameContext.agc.exposure = context.activeState.agc.automatic.exposure; - frameContext.agc.gain = context.activeState.agc.automatic.gain; + uint32_t activeAutoExposure = context.activeState.agc.automatic.exposure; + double activeAutoGain = context.activeState.agc.automatic.gain; + + /* Populate exposure and gain in auto mode */ + if (frameContext.agc.autoExposureEnabled) + frameContext.agc.exposure = activeAutoExposure; + if (frameContext.agc.autoGainEnabled) + frameContext.agc.gain = activeAutoGain; + + /* + * Populate manual exposure and gain from the active auto values when + * transitioning from auto to manual + */ + if (!frameContext.agc.autoExposureEnabled && frameContext.agc.autoExposureModeChange) { + context.activeState.agc.manual.exposure = activeAutoExposure; + frameContext.agc.exposure = activeAutoExposure; + } + if (!frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) { + context.activeState.agc.manual.gain = activeAutoGain; + frameContext.agc.gain = activeAutoGain; } if (frame > 0 && !frameContext.agc.updateMetering) @@ -333,7 +385,14 @@ void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext, * frameContext.sensor.exposure; metadata.set(controls::AnalogueGain, frameContext.sensor.gain); metadata.set(controls::ExposureTime, exposureTime.get<std::micro>()); - metadata.set(controls::AeEnable, frameContext.agc.autoEnabled); + metadata.set(controls::ExposureTimeMode, + frameContext.agc.autoExposureEnabled + ? controls::ExposureTimeModeAuto + : controls::ExposureTimeModeManual); + metadata.set(controls::AnalogueGainMode, + frameContext.agc.autoGainEnabled + ? controls::AnalogueGainModeAuto + : controls::AnalogueGainModeManual); /* \todo Use VBlank value calculated from each frame exposure. */ uint32_t vTotal = context.configuration.sensor.size.height @@ -459,6 +518,17 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, / context.configuration.sensor.lineDuration; activeState.agc.automatic.gain = aGain; + /* + * Populate auto exposure and gain from the active manual values when + * transitioning from manual to auto + * + * The frame context doesn't need to be populated here as it will be populated in prepare() + */ + if (frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) + context.activeState.agc.automatic.exposure = context.activeState.agc.manual.exposure; + if (frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) + context.activeState.agc.automatic.gain = context.activeState.agc.manual.gain; + fillMetadata(context, frameContext, metadata); expMeans_ = {}; } diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 80b99df8eaf8..c7ccc3093078 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -165,8 +165,11 @@ namespace libcamera::ipa::rkisp1 { * \var IPAActiveState::agc.automatic.gain * \brief Automatic analogue gain multiplier * - * \var IPAActiveState::agc.autoEnabled - * \brief Manual/automatic AGC state as set by the AeEnable control + * \var IPAActiveState::agc.autoExposureEnabled + * \brief Manual/automatic AGC state (exposure) as set by the ExposureTimeMode control + * + * \var IPAActiveState::agc.autoGainEnabled + * \brief Manual/automatic AGC state (gain) as set by the AnalogueGainMode control * * \var IPAActiveState::agc.constraintMode * \brief Constraint mode as set by the AeConstraintMode control @@ -289,8 +292,11 @@ namespace libcamera::ipa::rkisp1 { * * The gain should be adapted to the sensor specific gain code before applying. * - * \var IPAFrameContext::agc.autoEnabled - * \brief Manual/automatic AGC state as set by the AeEnable control + * \var IPAFrameContext::agc.autoExposureEnabled + * \brief Manual/automatic AGC state (exposure) as set by the ExposureTimeMode control + * + * \var IPAFrameContext::agc.autoGainEnabled + * \brief Manual/automatic AGC state (gain) as set by the AnalogueGainMode control * * \var IPAFrameContext::agc.constraintMode * \brief Constraint mode as set by the AeConstraintMode control @@ -306,6 +312,14 @@ namespace libcamera::ipa::rkisp1 { * * \var IPAFrameContext::agc.updateMetering * \brief Indicate if new ISP AGC metering parameters need to be applied + * + * \var IPAFrameContext::agc.autoExposureModeChange + * \brief Indicate if autoExposureEnabled has changed between the previous and + * current frame + * + * \var IPAFrameContext::agc.autoGainModeChange + * \brief Indicate if autoGainEnabled has changed between the previous and + * current frame */ /** diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index deb8c196f1b8..bc3d5a24be3a 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -79,7 +79,8 @@ struct IPAActiveState { double gain; } automatic; - bool autoEnabled; + bool autoExposureEnabled; + bool autoGainEnabled; controls::AeConstraintModeEnum constraintMode; controls::AeExposureModeEnum exposureMode; controls::AeMeteringModeEnum meteringMode; @@ -124,12 +125,15 @@ struct IPAFrameContext : public FrameContext { struct { uint32_t exposure; double gain; - bool autoEnabled; + bool autoExposureEnabled; + bool autoGainEnabled; controls::AeConstraintModeEnum constraintMode; controls::AeExposureModeEnum exposureMode; controls::AeMeteringModeEnum meteringMode; utils::Duration maxFrameDuration; bool updateMetering; + bool autoExposureModeChange; + bool autoGainModeChange; } agc; struct {
The newly introduced controls to drive the AEGC algorithm allow controlling the computation of the exposure time and analogue gain separately. Augument the RkISP1 AEGC implementation to handle the exposure and gain controls separately using the new controls. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> --- Changes in v4: - make auto the default value in the control infos - implement the expected behavior when transitioning between manual and auto modes New in v3 Back 2 years ago in v2 RkISP1 didn't yet support AeEnable properly yet so the AeEnable control was simply removed. --- src/ipa/rkisp1/algorithms/agc.cpp | 102 +++++++++++++++++++++++++----- src/ipa/rkisp1/ipa_context.cpp | 22 +++++-- src/ipa/rkisp1/ipa_context.h | 8 ++- 3 files changed, 110 insertions(+), 22 deletions(-)