summaryrefslogtreecommitdiff
path: root/src/ipa
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa')
-rw-r--r--src/ipa/rkisp1/algorithms/agc.cpp133
-rw-r--r--src/ipa/rkisp1/ipa_context.cpp24
-rw-r--r--src/ipa/rkisp1/ipa_context.h8
-rw-r--r--src/ipa/rpi/common/ipa_base.cpp104
-rw-r--r--src/ipa/rpi/controller/agc_algorithm.h8
-rw-r--r--src/ipa/rpi/controller/rpi/agc.cpp52
-rw-r--r--src/ipa/rpi/controller/rpi/agc.h8
-rw-r--r--src/ipa/rpi/controller/rpi/agc_channel.cpp24
-rw-r--r--src/ipa/rpi/controller/rpi/agc_channel.h8
9 files changed, 304 insertions, 65 deletions
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index 40e5a8f4..1680669c 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -148,7 +148,16 @@ 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));
+ /* \todo Move this to the Camera class */
+ context.ctrlMap[&controls::AeEnable] = ControlInfo(false, true, true);
context.ctrlMap.merge(controls());
return 0;
@@ -169,7 +178,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 +225,47 @@ 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.
+ *
+ * \todo Check the previous frame at prepare() time
+ * instead of saving a flag here
+ */
+ 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 +274,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 +323,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 +390,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
@@ -424,14 +488,35 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
[](uint32_t x) { return x >> 4; });
expMeans_ = { params->ae.exp_mean, context.hw->numAeCells };
- utils::Duration maxExposureTime =
- std::clamp(frameContext.agc.maxFrameDuration,
- context.configuration.sensor.minExposureTime,
- context.configuration.sensor.maxExposureTime);
- setLimits(context.configuration.sensor.minExposureTime,
- maxExposureTime,
- context.configuration.sensor.minAnalogueGain,
- context.configuration.sensor.maxAnalogueGain);
+ /*
+ * Set the AGC limits using the fixed exposure time and/or gain in
+ * manual mode, or the sensor limits in auto mode.
+ */
+ utils::Duration minExposureTime;
+ utils::Duration maxExposureTime;
+ double minAnalogueGain;
+ double maxAnalogueGain;
+
+ if (frameContext.agc.autoExposureEnabled) {
+ minExposureTime = context.configuration.sensor.minExposureTime;
+ maxExposureTime = std::clamp(frameContext.agc.maxFrameDuration,
+ context.configuration.sensor.minExposureTime,
+ context.configuration.sensor.maxExposureTime);
+ } else {
+ minExposureTime = context.configuration.sensor.lineDuration
+ * frameContext.agc.exposure;
+ maxExposureTime = minExposureTime;
+ }
+
+ if (frameContext.agc.autoGainEnabled) {
+ minAnalogueGain = context.configuration.sensor.minAnalogueGain;
+ maxAnalogueGain = context.configuration.sensor.maxAnalogueGain;
+ } else {
+ minAnalogueGain = frameContext.agc.gain;
+ maxAnalogueGain = frameContext.agc.gain;
+ }
+
+ setLimits(minExposureTime, maxExposureTime, minAnalogueGain, maxAnalogueGain);
/*
* The Agc algorithm needs to know the effective exposure value that was
diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp
index 80b99df8..261c0472 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,16 @@ 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 from true in the previous
+ * frame to false in the current frame, and no manual exposure value has been
+ * supplied in the current frame.
+ *
+ * \var IPAFrameContext::agc.autoGainModeChange
+ * \brief Indicate if autoGainEnabled has changed from true in the previous
+ * frame to false in the current frame, and no manual gain value has been
+ * supplied in the current frame.
*/
/**
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index b83c1822..5d5b79fa 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/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
index 6ff1e22b..bd3c2200 100644
--- a/src/ipa/rpi/common/ipa_base.cpp
+++ b/src/ipa/rpi/common/ipa_base.cpp
@@ -55,8 +55,17 @@ constexpr Duration controllerMinFrameDuration = 1.0s / 30.0;
/* List of controls handled by the Raspberry Pi IPA */
const ControlInfoMap::Map ipaControls{
- { &controls::AeEnable, ControlInfo(false, true) },
+ /* \todo Move this to the Camera class */
+ { &controls::AeEnable, ControlInfo(false, true, true) },
+ { &controls::ExposureTimeMode,
+ ControlInfo(static_cast<int32_t>(controls::ExposureTimeModeAuto),
+ static_cast<int32_t>(controls::ExposureTimeModeManual),
+ static_cast<int32_t>(controls::ExposureTimeModeAuto)) },
{ &controls::ExposureTime, ControlInfo(0, 66666) },
+ { &controls::AnalogueGainMode,
+ ControlInfo(static_cast<int32_t>(controls::AnalogueGainModeAuto),
+ static_cast<int32_t>(controls::AnalogueGainModeManual),
+ static_cast<int32_t>(controls::AnalogueGainModeAuto)) },
{ &controls::AnalogueGain, ControlInfo(1.0f, 16.0f) },
{ &controls::AeMeteringMode, ControlInfo(controls::AeMeteringModeValues) },
{ &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },
@@ -749,6 +758,42 @@ void IpaBase::applyControls(const ControlList &controls)
af->setMode(mode->second);
}
+ /*
+ * Because some AE controls are mode-specific, handle the AE-related
+ * mode changes first.
+ */
+ const auto analogueGainMode = controls.get(controls::AnalogueGainMode);
+ const auto exposureTimeMode = controls.get(controls::ExposureTimeMode);
+
+ if (analogueGainMode || exposureTimeMode) {
+ RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
+ controller_.getAlgorithm("agc"));
+ if (agc) {
+ if (analogueGainMode) {
+ if (*analogueGainMode == controls::AnalogueGainModeManual)
+ agc->disableAutoGain();
+ else
+ agc->enableAutoGain();
+
+ libcameraMetadata_.set(controls::AnalogueGainMode,
+ *analogueGainMode);
+ }
+
+ if (exposureTimeMode) {
+ if (*exposureTimeMode == controls::ExposureTimeModeManual)
+ agc->disableAutoExposure();
+ else
+ agc->enableAutoExposure();
+
+ libcameraMetadata_.set(controls::ExposureTimeMode,
+ *exposureTimeMode);
+ }
+ } else {
+ LOG(IPARPI, Warning)
+ << "Could not set AnalogueGainMode or ExposureTimeMode - no AGC algorithm";
+ }
+ }
+
/* Iterate over controls */
for (auto const &ctrl : controls) {
LOG(IPARPI, Debug) << "Request ctrl: "
@@ -756,23 +801,8 @@ void IpaBase::applyControls(const ControlList &controls)
<< " = " << ctrl.second.toString();
switch (ctrl.first) {
- case controls::AE_ENABLE: {
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.getAlgorithm("agc"));
- if (!agc) {
- LOG(IPARPI, Warning)
- << "Could not set AE_ENABLE - no AGC algorithm";
- break;
- }
-
- if (ctrl.second.get<bool>() == false)
- agc->disableAuto();
- else
- agc->enableAuto();
-
- libcameraMetadata_.set(controls::AeEnable, ctrl.second.get<bool>());
- break;
- }
+ case controls::EXPOSURE_TIME_MODE:
+ break; /* We already handled this one above */
case controls::EXPOSURE_TIME: {
RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
@@ -783,6 +813,13 @@ void IpaBase::applyControls(const ControlList &controls)
break;
}
+ /*
+ * Ignore manual exposure time when the auto exposure
+ * algorithm is running.
+ */
+ if (agc->autoExposureEnabled())
+ break;
+
/* The control provides units of microseconds. */
agc->setFixedExposureTime(0, ctrl.second.get<int32_t>() * 1.0us);
@@ -790,6 +827,9 @@ void IpaBase::applyControls(const ControlList &controls)
break;
}
+ case controls::ANALOGUE_GAIN_MODE:
+ break; /* We already handled this one above */
+
case controls::ANALOGUE_GAIN: {
RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
controller_.getAlgorithm("agc"));
@@ -799,6 +839,13 @@ void IpaBase::applyControls(const ControlList &controls)
break;
}
+ /*
+ * Ignore manual analogue gain value when the auto gain
+ * algorithm is running.
+ */
+ if (agc->autoGainEnabled())
+ break;
+
agc->setFixedAnalogueGain(0, ctrl.second.get<float>());
libcameraMetadata_.set(controls::AnalogueGain,
@@ -855,6 +902,13 @@ void IpaBase::applyControls(const ControlList &controls)
break;
}
+ /*
+ * Ignore AE_EXPOSURE_MODE if the shutter or the gain
+ * are in auto mode.
+ */
+ if (agc->autoExposureEnabled() || agc->autoGainEnabled())
+ break;
+
int32_t idx = ctrl.second.get<int32_t>();
if (ExposureModeTable.count(idx)) {
agc->setExposureMode(ExposureModeTable.at(idx));
@@ -1334,9 +1388,19 @@ void IpaBase::reportMetadata(unsigned int ipaContext)
}
AgcPrepareStatus *agcPrepareStatus = rpiMetadata.getLocked<AgcPrepareStatus>("agc.prepare_status");
- if (agcPrepareStatus) {
- libcameraMetadata_.set(controls::AeLocked, agcPrepareStatus->locked);
+ if (agcPrepareStatus)
libcameraMetadata_.set(controls::DigitalGain, agcPrepareStatus->digitalGain);
+
+ RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
+ controller_.getAlgorithm("agc"));
+ if (agc) {
+ if (!agc->autoExposureEnabled() && !agc->autoGainEnabled())
+ libcameraMetadata_.set(controls::AeState, controls::AeStateIdle);
+ else if (agcPrepareStatus)
+ libcameraMetadata_.set(controls::AeState,
+ agcPrepareStatus->locked
+ ? controls::AeStateConverged
+ : controls::AeStateSearching);
}
LuxStatus *luxStatus = rpiMetadata.getLocked<LuxStatus>("lux.status");
diff --git a/src/ipa/rpi/controller/agc_algorithm.h b/src/ipa/rpi/controller/agc_algorithm.h
index c9782857..fdaa10e6 100644
--- a/src/ipa/rpi/controller/agc_algorithm.h
+++ b/src/ipa/rpi/controller/agc_algorithm.h
@@ -30,8 +30,12 @@ public:
virtual void setMeteringMode(std::string const &meteringModeName) = 0;
virtual void setExposureMode(std::string const &exposureModeName) = 0;
virtual void setConstraintMode(std::string const &contraintModeName) = 0;
- virtual void enableAuto() = 0;
- virtual void disableAuto() = 0;
+ virtual void enableAutoExposure() = 0;
+ virtual void disableAutoExposure() = 0;
+ virtual bool autoExposureEnabled() const = 0;
+ virtual void enableAutoGain() = 0;
+ virtual void disableAutoGain() = 0;
+ virtual bool autoGainEnabled() const = 0;
virtual void setActiveChannels(const std::vector<unsigned int> &activeChannels) = 0;
};
diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp
index c48fdf15..02bfdb4a 100644
--- a/src/ipa/rpi/controller/rpi/agc.cpp
+++ b/src/ipa/rpi/controller/rpi/agc.cpp
@@ -74,22 +74,62 @@ int Agc::checkChannel(unsigned int channelIndex) const
return 0;
}
-void Agc::disableAuto()
+void Agc::disableAutoExposure()
{
- LOG(RPiAgc, Debug) << "disableAuto";
+ LOG(RPiAgc, Debug) << "disableAutoExposure";
/* All channels are enabled/disabled together. */
for (auto &data : channelData_)
- data.channel.disableAuto();
+ data.channel.disableAutoExposure();
}
-void Agc::enableAuto()
+void Agc::enableAutoExposure()
{
- LOG(RPiAgc, Debug) << "enableAuto";
+ LOG(RPiAgc, Debug) << "enableAutoExposure";
/* All channels are enabled/disabled together. */
for (auto &data : channelData_)
- data.channel.enableAuto();
+ data.channel.enableAutoExposure();
+}
+
+bool Agc::autoExposureEnabled() const
+{
+ LOG(RPiAgc, Debug) << "autoExposureEnabled";
+
+ /*
+ * We always have at least one channel, and since all channels are
+ * enabled and disabled together we can simply check the first one.
+ */
+ return channelData_[0].channel.autoExposureEnabled();
+}
+
+void Agc::disableAutoGain()
+{
+ LOG(RPiAgc, Debug) << "disableAutoGain";
+
+ /* All channels are enabled/disabled together. */
+ for (auto &data : channelData_)
+ data.channel.disableAutoGain();
+}
+
+void Agc::enableAutoGain()
+{
+ LOG(RPiAgc, Debug) << "enableAutoGain";
+
+ /* All channels are enabled/disabled together. */
+ for (auto &data : channelData_)
+ data.channel.enableAutoGain();
+}
+
+bool Agc::autoGainEnabled() const
+{
+ LOG(RPiAgc, Debug) << "autoGainEnabled";
+
+ /*
+ * We always have at least one channel, and since all channels are
+ * enabled and disabled together we can simply check the first one.
+ */
+ return channelData_[0].channel.autoGainEnabled();
}
unsigned int Agc::getConvergenceFrames() const
diff --git a/src/ipa/rpi/controller/rpi/agc.h b/src/ipa/rpi/controller/rpi/agc.h
index 3aca000b..c3a940bf 100644
--- a/src/ipa/rpi/controller/rpi/agc.h
+++ b/src/ipa/rpi/controller/rpi/agc.h
@@ -40,8 +40,12 @@ public:
void setMeteringMode(std::string const &meteringModeName) override;
void setExposureMode(std::string const &exposureModeName) override;
void setConstraintMode(std::string const &contraintModeName) override;
- void enableAuto() override;
- void disableAuto() override;
+ void enableAutoExposure() override;
+ void disableAutoExposure() override;
+ bool autoExposureEnabled() const override;
+ void enableAutoGain() override;
+ void disableAutoGain() override;
+ bool autoGainEnabled() const override;
void switchMode(CameraMode const &cameraMode, Metadata *metadata) override;
void prepare(Metadata *imageMetadata) override;
void process(StatisticsPtr &stats, Metadata *imageMetadata) override;
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
index 79c45973..e79184b7 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
+++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
@@ -319,18 +319,36 @@ int AgcChannel::read(const libcamera::YamlObject &params,
return 0;
}
-void AgcChannel::disableAuto()
+void AgcChannel::disableAutoExposure()
{
fixedExposureTime_ = status_.exposureTime;
- fixedAnalogueGain_ = status_.analogueGain;
}
-void AgcChannel::enableAuto()
+void AgcChannel::enableAutoExposure()
{
fixedExposureTime_ = 0s;
+}
+
+bool AgcChannel::autoExposureEnabled() const
+{
+ return fixedExposureTime_ == 0s;
+}
+
+void AgcChannel::disableAutoGain()
+{
+ fixedAnalogueGain_ = status_.analogueGain;
+}
+
+void AgcChannel::enableAutoGain()
+{
fixedAnalogueGain_ = 0;
}
+bool AgcChannel::autoGainEnabled() const
+{
+ return fixedAnalogueGain_ == 0;
+}
+
unsigned int AgcChannel::getConvergenceFrames() const
{
/*
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h
index 734e5efd..fa697e6f 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.h
+++ b/src/ipa/rpi/controller/rpi/agc_channel.h
@@ -96,8 +96,12 @@ public:
void setMeteringMode(std::string const &meteringModeName);
void setExposureMode(std::string const &exposureModeName);
void setConstraintMode(std::string const &contraintModeName);
- void enableAuto();
- void disableAuto();
+ void enableAutoExposure();
+ void disableAutoExposure();
+ bool autoExposureEnabled() const;
+ void enableAutoGain();
+ void disableAutoGain();
+ bool autoGainEnabled() const;
void switchMode(CameraMode const &cameraMode, Metadata *metadata);
void prepare(Metadata *imageMetadata);
void process(StatisticsPtr &stats, DeviceStatus const &deviceStatus, Metadata *imageMetadata,