ipa: ipu3: Return filtered value

When the current exposure value is calculated, it is cached and used by
filterExposure(). Use private filteredExposure_ and pass currentExposure
as a parameter.

In order to limit the use of filteredExposure_, return the value from
filterExposure().

While at it, remove a stale comment.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
This commit is contained in:
Jean-Michel Hautbois 2022-02-24 16:11:10 +01:00 committed by Umang Jain
parent ed13310b1f
commit 046ca79086
2 changed files with 40 additions and 35 deletions

View file

@ -72,7 +72,7 @@ static constexpr double kRelativeLuminanceTarget = 0.16;
Agc::Agc() Agc::Agc()
: frameCount_(0), lineDuration_(0s), minShutterSpeed_(0s), : frameCount_(0), lineDuration_(0s), minShutterSpeed_(0s),
maxShutterSpeed_(0s), filteredExposure_(0s), currentExposure_(0s) maxShutterSpeed_(0s), filteredExposure_(0s)
{ {
} }
@ -143,33 +143,37 @@ double Agc::measureBrightness(const ipu3_uapi_stats_3a *stats,
/** /**
* \brief Apply a filter on the exposure value to limit the speed of changes * \brief Apply a filter on the exposure value to limit the speed of changes
* \param[in] exposureValue The target exposure from the AGC algorithm
*
* The speed of the filter is adaptive, and will produce the target quicker
* during startup, or when the target exposure is within 20% of the most recent
* filter output.
*
* \return The filtered exposure
*/ */
void Agc::filterExposure() utils::Duration Agc::filterExposure(utils::Duration exposureValue)
{ {
double speed = 0.2; double speed = 0.2;
/* Adapt instantly if we are in startup phase */ /* Adapt instantly if we are in startup phase. */
if (frameCount_ < kNumStartupFrames) if (frameCount_ < kNumStartupFrames)
speed = 1.0; speed = 1.0;
if (filteredExposure_ == 0s) { /*
/* DG stands for digital gain.*/ * If we are close to the desired result, go faster to avoid making
filteredExposure_ = currentExposure_; * multiple micro-adjustments.
} else { * \todo Make this customisable?
/* */
* If we are close to the desired result, go faster to avoid making if (filteredExposure_ < 1.2 * exposureValue &&
* multiple micro-adjustments. filteredExposure_ > 0.8 * exposureValue)
* \todo Make this customisable? speed = sqrt(speed);
*/
if (filteredExposure_ < 1.2 * currentExposure_ &&
filteredExposure_ > 0.8 * currentExposure_)
speed = sqrt(speed);
filteredExposure_ = speed * currentExposure_ + filteredExposure_ = speed * exposureValue +
filteredExposure_ * (1.0 - speed); filteredExposure_ * (1.0 - speed);
}
LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << filteredExposure_; LOG(IPU3Agc, Debug) << "After filtering, exposure " << filteredExposure_;
return filteredExposure_;
} }
/** /**
@ -213,27 +217,29 @@ void Agc::computeExposure(IPAFrameContext &frameContext, double yGain,
* Calculate the current exposure value for the scene as the latest * Calculate the current exposure value for the scene as the latest
* exposure value applied multiplied by the new estimated gain. * exposure value applied multiplied by the new estimated gain.
*/ */
currentExposure_ = effectiveExposureValue * evGain; utils::Duration exposureValue = effectiveExposureValue * evGain;
/* Clamp the exposure value to the min and max authorized */ /* Clamp the exposure value to the min and max authorized */
utils::Duration maxTotalExposure = maxShutterSpeed_ * maxAnalogueGain_; utils::Duration maxTotalExposure = maxShutterSpeed_ * maxAnalogueGain_;
currentExposure_ = std::min(currentExposure_, maxTotalExposure); exposureValue = std::min(exposureValue, maxTotalExposure);
LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ LOG(IPU3Agc, Debug) << "Target total exposure " << exposureValue
<< ", maximum is " << maxTotalExposure; << ", maximum is " << maxTotalExposure;
/* \todo: estimate if we need to desaturate */ /*
filterExposure(); * Filter the exposure.
* \todo: estimate if we need to desaturate
/* Divide the exposure value as new exposure and gain values */ */
utils::Duration exposureValue = filteredExposure_; exposureValue = filterExposure(exposureValue);
utils::Duration shutterTime;
/* /*
* Push the shutter time up to the maximum first, and only then * Divide the exposure value as new exposure and gain values.
* increase the gain. *
*/ * Push the shutter time up to the maximum first, and only then
shutterTime = std::clamp<utils::Duration>(exposureValue / minAnalogueGain_, * increase the gain.
minShutterSpeed_, maxShutterSpeed_); */
utils::Duration shutterTime =
std::clamp<utils::Duration>(exposureValue / minAnalogueGain_,
minShutterSpeed_, maxShutterSpeed_);
double stepGain = std::clamp(exposureValue / shutterTime, double stepGain = std::clamp(exposureValue / shutterTime,
minAnalogueGain_, maxAnalogueGain_); minAnalogueGain_, maxAnalogueGain_);
LOG(IPU3Agc, Debug) << "Divided up shutter and gain are " LOG(IPU3Agc, Debug) << "Divided up shutter and gain are "

View file

@ -33,7 +33,7 @@ public:
private: private:
double measureBrightness(const ipu3_uapi_stats_3a *stats, double measureBrightness(const ipu3_uapi_stats_3a *stats,
const ipu3_uapi_grid_config &grid) const; const ipu3_uapi_grid_config &grid) const;
void filterExposure(); utils::Duration filterExposure(utils::Duration currentExposure);
void computeExposure(IPAFrameContext &frameContext, double yGain, void computeExposure(IPAFrameContext &frameContext, double yGain,
double iqMeanGain); double iqMeanGain);
double estimateLuminance(IPAFrameContext &frameContext, double estimateLuminance(IPAFrameContext &frameContext,
@ -51,7 +51,6 @@ private:
double maxAnalogueGain_; double maxAnalogueGain_;
utils::Duration filteredExposure_; utils::Duration filteredExposure_;
utils::Duration currentExposure_;
uint32_t stride_; uint32_t stride_;
}; };