ipa: rpi: agc: Implementation of multi-channel AGC

The switchMode, prepare and process methods are updated to implement
multi-channel AGC correctly:

* switchMode now invokes switchMode on all the channels (whether
  active or not).

* prepare must find what channel the current frame is, and run on
  behalf of that channel.

* process updates the most recent DeviceStatus and statistics for the
  channel of the frame that has just arrived, but generates updated
  values working through the active channels in round-robin fashion.

One minor detail in process is that we don't want to change the
DeviceStatus metadata of the current frame, so we now pass this to the
AgcChannel's process method, rather than letting it find the
DeviceStatus in the metadata.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
This commit is contained in:
David Plowman 2023-09-15 16:58:42 +01:00 committed by Jacopo Mondi
parent b2cb498a1a
commit beab3a229f
5 changed files with 116 additions and 22 deletions

View file

@ -444,7 +444,7 @@ void AgcChannel::prepare(Metadata *imageMetadata)
}
}
void AgcChannel::process(StatisticsPtr &stats, Metadata *imageMetadata)
void AgcChannel::process(StatisticsPtr &stats, DeviceStatus const &deviceStatus, Metadata *imageMetadata)
{
frameCount_++;
/*
@ -455,7 +455,7 @@ void AgcChannel::process(StatisticsPtr &stats, Metadata *imageMetadata)
/* Fetch the AWB status immediately, so that we can assume it's there. */
fetchAwbStatus(imageMetadata);
/* Get the current exposure values for the frame that's just arrived. */
fetchCurrentExposure(imageMetadata);
fetchCurrentExposure(deviceStatus);
/* Compute the total gain we require relative to the current exposure. */
double gain, targetY;
computeGain(stats, imageMetadata, gain, targetY);
@ -567,18 +567,11 @@ void AgcChannel::housekeepConfig()
<< meteringModeName_;
}
void AgcChannel::fetchCurrentExposure(Metadata *imageMetadata)
void AgcChannel::fetchCurrentExposure(DeviceStatus const &deviceStatus)
{
std::unique_lock<Metadata> lock(*imageMetadata);
DeviceStatus *deviceStatus =
imageMetadata->getLocked<DeviceStatus>("device.status");
if (!deviceStatus)
LOG(RPiAgc, Fatal) << "No device metadata";
current_.shutter = deviceStatus->shutterSpeed;
current_.analogueGain = deviceStatus->analogueGain;
AgcStatus *agcStatus =
imageMetadata->getLocked<AgcStatus>("agc.status");
current_.totalExposure = agcStatus ? agcStatus->totalExposureValue : 0s;
current_.shutter = deviceStatus.shutterSpeed;
current_.analogueGain = deviceStatus.analogueGain;
current_.totalExposure = 0s; /* this value is unused */
current_.totalExposureNoDG = current_.shutter * current_.analogueGain;
}