ipa: rpi: common: Handle AEC/AGC flicker controls

We handle the flicker modes by passing the correct period to the
AEC/AGC algorithm which already contains the necessary code.

The "Auto" mode, as well as reporting the detected flicker period via
the "AeFlickerDetected" metadata, are unsupported for now.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
This commit is contained in:
David Plowman 2023-07-18 15:43:01 +01:00 committed by Naushir Patuck
parent 6fdbf3f38c
commit a2eadc40a7
2 changed files with 69 additions and 1 deletions

View file

@ -61,6 +61,10 @@ const ControlInfoMap::Map ipaControls{
{ &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) }, { &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },
{ &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) }, { &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) },
{ &controls::ExposureValue, ControlInfo(-8.0f, 8.0f, 0.0f) }, { &controls::ExposureValue, ControlInfo(-8.0f, 8.0f, 0.0f) },
{ &controls::AeFlickerMode, ControlInfo(static_cast<int>(controls::FlickerOff),
static_cast<int>(controls::FlickerManual),
static_cast<int>(controls::FlickerOff)) },
{ &controls::AeFlickerPeriod, ControlInfo(100, 1000000) },
{ &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) }, { &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },
{ &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) }, { &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },
{ &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) }, { &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },
@ -97,7 +101,7 @@ namespace ipa::RPi {
IpaBase::IpaBase() IpaBase::IpaBase()
: controller_(), frameCount_(0), mistrustCount_(0), lastRunTimestamp_(0), : controller_(), frameCount_(0), mistrustCount_(0), lastRunTimestamp_(0),
firstStart_(true) firstStart_(true), flickerState_({ 0, 0s })
{ {
} }
@ -812,6 +816,64 @@ void IpaBase::applyControls(const ControlList &controls)
break; break;
} }
case controls::AE_FLICKER_MODE: {
RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
controller_.getAlgorithm("agc"));
if (!agc) {
LOG(IPARPI, Warning)
<< "Could not set AeFlickerMode - no AGC algorithm";
break;
}
int32_t mode = ctrl.second.get<int32_t>();
bool modeValid = true;
switch (mode) {
case controls::FlickerOff:
agc->setFlickerPeriod(0us);
break;
case controls::FlickerManual:
agc->setFlickerPeriod(flickerState_.manualPeriod);
break;
default:
LOG(IPARPI, Error) << "Flicker mode " << mode << " is not supported";
modeValid = false;
break;
}
if (modeValid)
flickerState_.mode = mode;
break;
}
case controls::AE_FLICKER_PERIOD: {
RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
controller_.getAlgorithm("agc"));
if (!agc) {
LOG(IPARPI, Warning)
<< "Could not set AeFlickerPeriod - no AGC algorithm";
break;
}
uint32_t manualPeriod = ctrl.second.get<int32_t>();
flickerState_.manualPeriod = manualPeriod * 1.0us;
/*
* We note that it makes no difference if the mode gets set to "manual"
* first, and the period updated after, or vice versa.
*/
if (flickerState_.mode == controls::FlickerManual)
agc->setFlickerPeriod(flickerState_.manualPeriod);
break;
}
case controls::AWB_ENABLE: { case controls::AWB_ENABLE: {
/* Silently ignore this control for a mono sensor. */ /* Silently ignore this control for a mono sensor. */
if (monoSensor_) if (monoSensor_)

View file

@ -116,6 +116,12 @@ private:
/* Frame duration (1/fps) limits. */ /* Frame duration (1/fps) limits. */
utils::Duration minFrameDuration_; utils::Duration minFrameDuration_;
utils::Duration maxFrameDuration_; utils::Duration maxFrameDuration_;
/* The current state of flicker avoidance. */
struct FlickerState {
int32_t mode;
utils::Duration manualPeriod;
} flickerState_;
}; };
} /* namespace ipa::RPi */ } /* namespace ipa::RPi */