ipa: rkisp1: agc: Support raw capture

Support raw capture by allowing manual control of the exposure time and
analogue gain.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Laurent Pinchart 2022-10-22 01:43:21 +03:00
parent 4cf3c96493
commit 72721611fa
2 changed files with 34 additions and 17 deletions

View file

@ -62,6 +62,7 @@ static constexpr double kRelativeLuminanceTarget = 0.4;
Agc::Agc()
: frameCount_(0), numCells_(0), numHistBins_(0), filteredExposure_(0s)
{
supportsRaw_ = true;
}
/**
@ -81,7 +82,7 @@ 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 = true;
context.activeState.agc.autoEnabled = !context.configuration.raw;
/*
* According to the RkISP1 documentation:
@ -123,12 +124,15 @@ void Agc::queueRequest(IPAContext &context,
{
auto &agc = context.activeState.agc;
const auto &agcEnable = controls.get(controls::AeEnable);
if (agcEnable && *agcEnable != agc.autoEnabled) {
agc.autoEnabled = *agcEnable;
if (!context.configuration.raw) {
const auto &agcEnable = controls.get(controls::AeEnable);
if (agcEnable && *agcEnable != agc.autoEnabled) {
agc.autoEnabled = *agcEnable;
LOG(RkISP1Agc, Debug)
<< (agc.autoEnabled ? "Enabling" : "Disabling") << " AGC";
LOG(RkISP1Agc, Debug)
<< (agc.autoEnabled ? "Enabling" : "Disabling")
<< " AGC";
}
}
const auto &exposure = controls.get(controls::ExposureTime);
@ -368,6 +372,22 @@ double Agc::measureBrightness(const rkisp1_cif_isp_hist_stat *hist) const
return histogram.interQuantileMean(0.98, 1.0);
}
void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext,
ControlList &metadata)
{
utils::Duration exposureTime = context.configuration.sensor.lineDuration
* frameContext.sensor.exposure;
metadata.set(controls::AnalogueGain, frameContext.sensor.gain);
metadata.set(controls::ExposureTime, exposureTime.get<std::micro>());
/* \todo Use VBlank value calculated from each frame exposure. */
uint32_t vTotal = context.configuration.sensor.size.height
+ context.configuration.sensor.defVBlank;
utils::Duration frameDuration = context.configuration.sensor.lineDuration
* vTotal;
metadata.set(controls::FrameDuration, frameDuration.get<std::micro>());
}
/**
* \brief Process RkISP1 statistics, and run AGC operations
* \param[in] context The shared IPA context
@ -383,6 +403,11 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
IPAFrameContext &frameContext, const rkisp1_stat_buffer *stats,
ControlList &metadata)
{
if (!stats) {
fillMetadata(context, frameContext, metadata);
return;
}
/*
* \todo Verify that the exposure and gain applied by the sensor for
* this frame match what has been requested. This isn't a hard
@ -425,17 +450,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
computeExposure(context, frameContext, yGain, iqMeanGain);
frameCount_++;
utils::Duration exposureTime = context.configuration.sensor.lineDuration
* frameContext.sensor.exposure;
metadata.set(controls::AnalogueGain, frameContext.sensor.gain);
metadata.set(controls::ExposureTime, exposureTime.get<std::micro>());
/* \todo Use VBlank value calculated from each frame exposure. */
uint32_t vTotal = context.configuration.sensor.size.height
+ context.configuration.sensor.defVBlank;
utils::Duration frameDuration = context.configuration.sensor.lineDuration
* vTotal;
metadata.set(controls::FrameDuration, frameDuration.get<std::micro>());
fillMetadata(context, frameContext, metadata);
}
REGISTER_IPA_ALGORITHM(Agc, "Agc")