ipa: rpi: agc: Filter exposures before dealing with digital gain
We now time-filter the exposure before sorting out how much digital gain is required. This is actually a little more natural and simplifies the code. It also prepares us for some future work where this arrangement will be helpful. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Naushir Patuck <naush@raspberrpyi.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
2ea57d0b77
commit
84b6327789
2 changed files with 6 additions and 26 deletions
|
@ -469,14 +469,14 @@ void Agc::process(StatisticsPtr &stats, Metadata *imageMetadata)
|
||||||
computeGain(stats, imageMetadata, gain, targetY);
|
computeGain(stats, imageMetadata, gain, targetY);
|
||||||
/* Now compute the target (final) exposure which we think we want. */
|
/* Now compute the target (final) exposure which we think we want. */
|
||||||
computeTargetExposure(gain);
|
computeTargetExposure(gain);
|
||||||
|
/* The results have to be filtered so as not to change too rapidly. */
|
||||||
|
filterExposure();
|
||||||
/*
|
/*
|
||||||
* Some of the exposure has to be applied as digital gain, so work out
|
* Some of the exposure has to be applied as digital gain, so work out
|
||||||
* what that is. This function also tells us whether it's decided to
|
* what that is. This function also tells us whether it's decided to
|
||||||
* "desaturate" the image more quickly.
|
* "desaturate" the image more quickly.
|
||||||
*/
|
*/
|
||||||
bool desaturate = applyDigitalGain(gain, targetY);
|
bool desaturate = applyDigitalGain(gain, targetY);
|
||||||
/* The results have to be filtered so as not to change too rapidly. */
|
|
||||||
filterExposure(desaturate);
|
|
||||||
/*
|
/*
|
||||||
* The last thing is to divide up the exposure value into a shutter time
|
* The last thing is to divide up the exposure value into a shutter time
|
||||||
* and analogue gain, according to the current exposure mode.
|
* and analogue gain, according to the current exposure mode.
|
||||||
|
@ -757,12 +757,12 @@ bool Agc::applyDigitalGain(double gain, double targetY)
|
||||||
if (desaturate)
|
if (desaturate)
|
||||||
dg /= config_.fastReduceThreshold;
|
dg /= config_.fastReduceThreshold;
|
||||||
LOG(RPiAgc, Debug) << "Digital gain " << dg << " desaturate? " << desaturate;
|
LOG(RPiAgc, Debug) << "Digital gain " << dg << " desaturate? " << desaturate;
|
||||||
target_.totalExposureNoDG = target_.totalExposure / dg;
|
filtered_.totalExposureNoDG = filtered_.totalExposure / dg;
|
||||||
LOG(RPiAgc, Debug) << "Target totalExposureNoDG " << target_.totalExposureNoDG;
|
LOG(RPiAgc, Debug) << "Target totalExposureNoDG " << filtered_.totalExposureNoDG;
|
||||||
return desaturate;
|
return desaturate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Agc::filterExposure(bool desaturate)
|
void Agc::filterExposure()
|
||||||
{
|
{
|
||||||
double speed = config_.speed;
|
double speed = config_.speed;
|
||||||
/*
|
/*
|
||||||
|
@ -774,7 +774,6 @@ void Agc::filterExposure(bool desaturate)
|
||||||
speed = 1.0;
|
speed = 1.0;
|
||||||
if (!filtered_.totalExposure) {
|
if (!filtered_.totalExposure) {
|
||||||
filtered_.totalExposure = target_.totalExposure;
|
filtered_.totalExposure = target_.totalExposure;
|
||||||
filtered_.totalExposureNoDG = target_.totalExposureNoDG;
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* If close to the result go faster, to save making so many
|
* If close to the result go faster, to save making so many
|
||||||
|
@ -785,26 +784,7 @@ void Agc::filterExposure(bool desaturate)
|
||||||
speed = sqrt(speed);
|
speed = sqrt(speed);
|
||||||
filtered_.totalExposure = speed * target_.totalExposure +
|
filtered_.totalExposure = speed * target_.totalExposure +
|
||||||
filtered_.totalExposure * (1.0 - speed);
|
filtered_.totalExposure * (1.0 - speed);
|
||||||
/*
|
|
||||||
* When desaturing, take a big jump down in totalExposureNoDG,
|
|
||||||
* which we'll hide with digital gain.
|
|
||||||
*/
|
|
||||||
if (desaturate)
|
|
||||||
filtered_.totalExposureNoDG =
|
|
||||||
target_.totalExposureNoDG;
|
|
||||||
else
|
|
||||||
filtered_.totalExposureNoDG =
|
|
||||||
speed * target_.totalExposureNoDG +
|
|
||||||
filtered_.totalExposureNoDG * (1.0 - speed);
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* We can't let the totalExposureNoDG exposure deviate too far below the
|
|
||||||
* total exposure, as there might not be enough digital gain available
|
|
||||||
* in the ISP to hide it (which will cause nasty oscillation).
|
|
||||||
*/
|
|
||||||
if (filtered_.totalExposureNoDG <
|
|
||||||
filtered_.totalExposure * config_.fastReduceThreshold)
|
|
||||||
filtered_.totalExposureNoDG = filtered_.totalExposure * config_.fastReduceThreshold;
|
|
||||||
LOG(RPiAgc, Debug) << "After filtering, totalExposure " << filtered_.totalExposure
|
LOG(RPiAgc, Debug) << "After filtering, totalExposure " << filtered_.totalExposure
|
||||||
<< " no dg " << filtered_.totalExposureNoDG;
|
<< " no dg " << filtered_.totalExposureNoDG;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,8 +93,8 @@ private:
|
||||||
void computeGain(StatisticsPtr &statistics, Metadata *imageMetadata,
|
void computeGain(StatisticsPtr &statistics, Metadata *imageMetadata,
|
||||||
double &gain, double &targetY);
|
double &gain, double &targetY);
|
||||||
void computeTargetExposure(double gain);
|
void computeTargetExposure(double gain);
|
||||||
|
void filterExposure();
|
||||||
bool applyDigitalGain(double gain, double targetY);
|
bool applyDigitalGain(double gain, double targetY);
|
||||||
void filterExposure(bool desaturate);
|
|
||||||
void divideUpExposure();
|
void divideUpExposure();
|
||||||
void writeAndFinish(Metadata *imageMetadata, bool desaturate);
|
void writeAndFinish(Metadata *imageMetadata, bool desaturate);
|
||||||
libcamera::utils::Duration limitShutter(libcamera::utils::Duration shutter);
|
libcamera::utils::Duration limitShutter(libcamera::utils::Duration shutter);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue