ipa: raspberrypi: agc: Fix digital gain calculation for manual mode

The digital gain calculation uses a total exposure value computed with the
current AGC state. However, this is wrong in the case of manual shutter/gain
controls, as the total exposure value used must be the value computed when the
AGC sent the manual shutter/gain controls to the pipeline handler to action.

To fix this, the IPA now adds the historical AgcStatus structure to the metadata
(tagged with "agc.delayed_status"). This historical AgcStatus structure contains
the total exposure value calculated when the AGC sent the manual shutter/gain
controls to the pipeline handler.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Tested-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Naushir Patuck 2022-11-15 09:07:55 +00:00 committed by Laurent Pinchart
parent 546154b134
commit ac42f9278e
2 changed files with 19 additions and 2 deletions

View file

@ -403,6 +403,12 @@ void Agc::switchMode(CameraMode const &cameraMode,
void Agc::prepare(Metadata *imageMetadata) void Agc::prepare(Metadata *imageMetadata)
{ {
Duration totalExposureValue = status_.totalExposureValue;
AgcStatus delayedStatus;
if (!imageMetadata->get("agc.delayed_status", delayedStatus))
totalExposureValue = delayedStatus.totalExposureValue;
status_.digitalGain = 1.0; status_.digitalGain = 1.0;
fetchAwbStatus(imageMetadata); /* always fetch it so that Process knows it's been done */ fetchAwbStatus(imageMetadata); /* always fetch it so that Process knows it's been done */
@ -413,8 +419,8 @@ void Agc::prepare(Metadata *imageMetadata)
Duration actualExposure = deviceStatus.shutterSpeed * Duration actualExposure = deviceStatus.shutterSpeed *
deviceStatus.analogueGain; deviceStatus.analogueGain;
if (actualExposure) { if (actualExposure) {
status_.digitalGain = status_.totalExposureValue / actualExposure; status_.digitalGain = totalExposureValue / actualExposure;
LOG(RPiAgc, Debug) << "Want total exposure " << status_.totalExposureValue; LOG(RPiAgc, Debug) << "Want total exposure " << totalExposureValue;
/* /*
* Never ask for a gain < 1.0, and also impose * Never ask for a gain < 1.0, and also impose
* some upper limit. Make it customisable? * some upper limit. Make it customisable?

View file

@ -1030,6 +1030,17 @@ void IPARPi::prepareISP(const ISPConfig &data)
embeddedBuffer = it->second.planes()[0]; embeddedBuffer = it->second.planes()[0];
} }
/*
* AGC wants to know the algorithm status from the time it actioned the
* sensor exposure/gain changes. So fetch it from the metadata list
* indexed by the IPA cookie returned, and put it in the current frame
* metadata.
*/
AgcStatus agcStatus;
RPiController::Metadata &delayedMetadata = rpiMetadata_[data.delayContext];
if (!delayedMetadata.get<AgcStatus>("agc.status", agcStatus))
rpiMetadata.set("agc.delayed_status", agcStatus);
/* /*
* This may overwrite the DeviceStatus using values from the sensor * This may overwrite the DeviceStatus using values from the sensor
* metadata, and may also do additional custom processing. * metadata, and may also do additional custom processing.