summaryrefslogtreecommitdiff
path: root/src/ipa/rpi/common/ipa_base.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa/rpi/common/ipa_base.cpp')
-rw-r--r--src/ipa/rpi/common/ipa_base.cpp157
1 files changed, 119 insertions, 38 deletions
diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
index 5fce17e6..6734c32e 100644
--- a/src/ipa/rpi/common/ipa_base.cpp
+++ b/src/ipa/rpi/common/ipa_base.cpp
@@ -55,9 +55,19 @@ 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) },
- { &controls::ExposureTime, ControlInfo(0, 66666) },
- { &controls::AnalogueGain, ControlInfo(1.0f, 16.0f) },
+ /* \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(1, 66666, static_cast<int32_t>(defaultExposureTime.get<std::micro>())) },
+ { &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, 1.0f) },
{ &controls::AeMeteringMode, ControlInfo(controls::AeMeteringModeValues) },
{ &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },
{ &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) },
@@ -71,7 +81,9 @@ const ControlInfoMap::Map ipaControls{
{ &controls::HdrMode, ControlInfo(controls::HdrModeValues) },
{ &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },
{ &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },
- { &controls::FrameDurationLimits, ControlInfo(INT64_C(33333), INT64_C(120000)) },
+ { &controls::FrameDurationLimits,
+ ControlInfo(INT64_C(33333), INT64_C(120000),
+ static_cast<int64_t>(defaultMinFrameDuration.get<std::micro>())) },
{ &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) },
{ &controls::rpi::StatsOutputEnable, ControlInfo(false, true, false) },
};
@@ -81,6 +93,7 @@ const ControlInfoMap::Map ipaColourControls{
{ &controls::AwbEnable, ControlInfo(false, true) },
{ &controls::AwbMode, ControlInfo(controls::AwbModeValues) },
{ &controls::ColourGains, ControlInfo(0.0f, 32.0f) },
+ { &controls::ColourTemperature, ControlInfo(100, 100000) },
{ &controls::Saturation, ControlInfo(0.0f, 32.0f, 1.0f) },
};
@@ -134,18 +147,8 @@ int32_t IpaBase::init(const IPASettings &settings, const InitParams &params, Ini
return -EINVAL;
}
- /*
- * Pass out the sensor config to the pipeline handler in order
- * to setup the staggered writer class.
- */
- int gainDelay, exposureDelay, vblankDelay, hblankDelay, sensorMetadata;
- helper_->getDelays(exposureDelay, gainDelay, vblankDelay, hblankDelay);
- sensorMetadata = helper_->sensorEmbeddedDataPresent();
-
- result->sensorConfig.gainDelay = gainDelay;
- result->sensorConfig.exposureDelay = exposureDelay;
- result->sensorConfig.vblankDelay = vblankDelay;
- result->sensorConfig.hblankDelay = hblankDelay;
+ /* Pass out the sensor metadata to the pipeline handler */
+ int sensorMetadata = helper_->sensorEmbeddedDataPresent();
result->sensorConfig.sensorMetadata = sensorMetadata;
/* Load the tuning file for this sensor. */
@@ -160,6 +163,7 @@ int32_t IpaBase::init(const IPASettings &settings, const InitParams &params, Ini
lensPresent_ = params.lensPresent;
controller_.initialise();
+ helper_->setHwConfig(controller_.getHardwareConfig());
/* Return the controls handled by the IPA */
ControlInfoMap::Map ctrlMap = ipaControls;
@@ -258,15 +262,18 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa
ControlInfoMap::Map ctrlMap = ipaControls;
ctrlMap[&controls::FrameDurationLimits] =
ControlInfo(static_cast<int64_t>(mode_.minFrameDuration.get<std::micro>()),
- static_cast<int64_t>(mode_.maxFrameDuration.get<std::micro>()));
+ static_cast<int64_t>(mode_.maxFrameDuration.get<std::micro>()),
+ static_cast<int64_t>(defaultMinFrameDuration.get<std::micro>()));
ctrlMap[&controls::AnalogueGain] =
ControlInfo(static_cast<float>(mode_.minAnalogueGain),
- static_cast<float>(mode_.maxAnalogueGain));
+ static_cast<float>(mode_.maxAnalogueGain),
+ static_cast<float>(defaultAnalogueGain));
ctrlMap[&controls::ExposureTime] =
ControlInfo(static_cast<int32_t>(mode_.minExposureTime.get<std::micro>()),
- static_cast<int32_t>(mode_.maxExposureTime.get<std::micro>()));
+ static_cast<int32_t>(mode_.maxExposureTime.get<std::micro>()),
+ static_cast<int32_t>(defaultExposureTime.get<std::micro>()));
/* Declare colour processing related controls for non-mono sensors. */
if (!monoSensor_)
@@ -757,6 +764,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: "
@@ -764,23 +807,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 *>(
@@ -791,6 +819,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);
@@ -798,6 +833,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"));
@@ -807,6 +845,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,
@@ -863,6 +908,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));
@@ -1021,6 +1073,25 @@ void IpaBase::applyControls(const ControlList &controls)
break;
}
+ case controls::COLOUR_TEMPERATURE: {
+ /* Silently ignore this control for a mono sensor. */
+ if (monoSensor_)
+ break;
+
+ auto temperatureK = ctrl.second.get<int32_t>();
+ RPiController::AwbAlgorithm *awb = dynamic_cast<RPiController::AwbAlgorithm *>(
+ controller_.getAlgorithm("awb"));
+ if (!awb) {
+ LOG(IPARPI, Warning)
+ << "Could not set COLOUR_TEMPERATURE - no AWB algorithm";
+ break;
+ }
+
+ awb->setColourTemperature(temperatureK);
+ /* This metadata will get reported back automatically. */
+ break;
+ }
+
case controls::BRIGHTNESS: {
RPiController::ContrastAlgorithm *contrast = dynamic_cast<RPiController::ContrastAlgorithm *>(
controller_.getAlgorithm("contrast"));
@@ -1323,9 +1394,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");