mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-16 08:55:06 +03:00
ipa: raspberrypi: Pass lineLength into the CamHelper API
Update CamHelper::exposureLines() and CamHelper::exposure() to take a line length duration parameter for use in the exposure calculations. For now, only use the minimum line length for all the calculations to match the existing IPA behavior. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Tested-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
c513522f3f
commit
f9c490ab25
7 changed files with 30 additions and 23 deletions
|
@ -61,16 +61,16 @@ void CamHelper::process([[maybe_unused]] StatisticsPtr &stats,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CamHelper::exposureLines(const Duration exposure) const
|
uint32_t CamHelper::exposureLines(const Duration exposure, const Duration lineLength) const
|
||||||
{
|
{
|
||||||
assert(initialized_);
|
assert(initialized_);
|
||||||
return exposure / mode_.minLineLength;
|
return exposure / lineLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
Duration CamHelper::exposure(uint32_t exposureLines) const
|
Duration CamHelper::exposure(uint32_t exposureLines, const Duration lineLength) const
|
||||||
{
|
{
|
||||||
assert(initialized_);
|
assert(initialized_);
|
||||||
return exposureLines * mode_.minLineLength;
|
return exposureLines * lineLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CamHelper::getVBlanking(Duration &exposure,
|
uint32_t CamHelper::getVBlanking(Duration &exposure,
|
||||||
|
@ -78,7 +78,7 @@ uint32_t CamHelper::getVBlanking(Duration &exposure,
|
||||||
Duration maxFrameDuration) const
|
Duration maxFrameDuration) const
|
||||||
{
|
{
|
||||||
uint32_t frameLengthMin, frameLengthMax, vblank;
|
uint32_t frameLengthMin, frameLengthMax, vblank;
|
||||||
uint32_t exposureLines = CamHelper::exposureLines(exposure);
|
uint32_t exposureLines = CamHelper::exposureLines(exposure, mode_.minLineLength);
|
||||||
|
|
||||||
assert(initialized_);
|
assert(initialized_);
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ uint32_t CamHelper::getVBlanking(Duration &exposure,
|
||||||
* re-calculate if it has been clipped.
|
* re-calculate if it has been clipped.
|
||||||
*/
|
*/
|
||||||
exposureLines = std::min(frameLengthMax - frameIntegrationDiff_, exposureLines);
|
exposureLines = std::min(frameLengthMax - frameIntegrationDiff_, exposureLines);
|
||||||
exposure = CamHelper::exposure(exposureLines);
|
exposure = CamHelper::exposure(exposureLines, mode_.minLineLength);
|
||||||
|
|
||||||
/* Limit the vblank to the range allowed by the frame length limits. */
|
/* Limit the vblank to the range allowed by the frame length limits. */
|
||||||
vblank = std::clamp(exposureLines + frameIntegrationDiff_,
|
vblank = std::clamp(exposureLines + frameIntegrationDiff_,
|
||||||
|
|
|
@ -78,8 +78,10 @@ public:
|
||||||
virtual void prepare(libcamera::Span<const uint8_t> buffer,
|
virtual void prepare(libcamera::Span<const uint8_t> buffer,
|
||||||
Metadata &metadata);
|
Metadata &metadata);
|
||||||
virtual void process(StatisticsPtr &stats, Metadata &metadata);
|
virtual void process(StatisticsPtr &stats, Metadata &metadata);
|
||||||
virtual uint32_t exposureLines(libcamera::utils::Duration exposure) const;
|
virtual uint32_t exposureLines(const libcamera::utils::Duration exposure,
|
||||||
virtual libcamera::utils::Duration exposure(uint32_t exposureLines) const;
|
const libcamera::utils::Duration lineLength) const;
|
||||||
|
virtual libcamera::utils::Duration exposure(uint32_t exposureLines,
|
||||||
|
const libcamera::utils::Duration lineLength) const;
|
||||||
virtual uint32_t getVBlanking(libcamera::utils::Duration &exposure,
|
virtual uint32_t getVBlanking(libcamera::utils::Duration &exposure,
|
||||||
libcamera::utils::Duration minFrameDuration,
|
libcamera::utils::Duration minFrameDuration,
|
||||||
libcamera::utils::Duration maxFrameDuration) const;
|
libcamera::utils::Duration maxFrameDuration) const;
|
||||||
|
|
|
@ -94,7 +94,8 @@ void CamHelperImx219::populateMetadata(const MdParser::RegisterMap ®isters,
|
||||||
{
|
{
|
||||||
DeviceStatus deviceStatus;
|
DeviceStatus deviceStatus;
|
||||||
|
|
||||||
deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg));
|
deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
|
||||||
|
mode_.minLineLength);
|
||||||
deviceStatus.analogueGain = gain(registers.at(gainReg));
|
deviceStatus.analogueGain = gain(registers.at(gainReg));
|
||||||
deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
|
deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ public:
|
||||||
CamHelperImx296();
|
CamHelperImx296();
|
||||||
uint32_t gainCode(double gain) const override;
|
uint32_t gainCode(double gain) const override;
|
||||||
double gain(uint32_t gainCode) const override;
|
double gain(uint32_t gainCode) const override;
|
||||||
uint32_t exposureLines(Duration exposure) const override;
|
uint32_t exposureLines(const Duration exposure, const Duration lineLength) const override;
|
||||||
Duration exposure(uint32_t exposureLines) const override;
|
Duration exposure(uint32_t exposureLines, const Duration lineLength) const override;
|
||||||
void getDelays(int &exposureDelay, int &gainDelay, int &vblankDelay) const override;
|
void getDelays(int &exposureDelay, int &gainDelay, int &vblankDelay) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -53,12 +53,14 @@ double CamHelperImx296::gain(uint32_t gainCode) const
|
||||||
return std::pow(10.0, gainCode / 200.0);
|
return std::pow(10.0, gainCode / 200.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CamHelperImx296::exposureLines(Duration exposure) const
|
uint32_t CamHelperImx296::exposureLines(const Duration exposure,
|
||||||
|
[[maybe_unused]] const Duration lineLength) const
|
||||||
{
|
{
|
||||||
return std::max<uint32_t>(minExposureLines, (exposure - 14.26us) / timePerLine);
|
return std::max<uint32_t>(minExposureLines, (exposure - 14.26us) / timePerLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
Duration CamHelperImx296::exposure(uint32_t exposureLines) const
|
Duration CamHelperImx296::exposure(uint32_t exposureLines,
|
||||||
|
[[maybe_unused]] const Duration lineLength) const
|
||||||
{
|
{
|
||||||
return std::max<uint32_t>(minExposureLines, exposureLines) * timePerLine + 14.26us;
|
return std::max<uint32_t>(minExposureLines, exposureLines) * timePerLine + 14.26us;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,9 +144,9 @@ uint32_t CamHelperImx477::getVBlanking(Duration &exposure,
|
||||||
if (shift) {
|
if (shift) {
|
||||||
/* Account for any rounding in the scaled frame length value. */
|
/* Account for any rounding in the scaled frame length value. */
|
||||||
frameLength <<= shift;
|
frameLength <<= shift;
|
||||||
exposureLines = CamHelperImx477::exposureLines(exposure);
|
exposureLines = CamHelperImx477::exposureLines(exposure, mode_.minLineLength);
|
||||||
exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff);
|
exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff);
|
||||||
exposure = CamHelperImx477::exposure(exposureLines);
|
exposure = CamHelperImx477::exposure(exposureLines, mode_.minLineLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameLength - mode_.height;
|
return frameLength - mode_.height;
|
||||||
|
@ -170,7 +170,8 @@ void CamHelperImx477::populateMetadata(const MdParser::RegisterMap ®isters,
|
||||||
{
|
{
|
||||||
DeviceStatus deviceStatus;
|
DeviceStatus deviceStatus;
|
||||||
|
|
||||||
deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg));
|
deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
|
||||||
|
mode_.minLineLength);
|
||||||
deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg));
|
deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg));
|
||||||
deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
|
deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
|
||||||
deviceStatus.sensorTemperature = std::clamp<int8_t>(registers.at(temperatureReg), -20, 80);
|
deviceStatus.sensorTemperature = std::clamp<int8_t>(registers.at(temperatureReg), -20, 80);
|
||||||
|
|
|
@ -144,9 +144,9 @@ uint32_t CamHelperImx519::getVBlanking(Duration &exposure,
|
||||||
if (shift) {
|
if (shift) {
|
||||||
/* Account for any rounding in the scaled frame length value. */
|
/* Account for any rounding in the scaled frame length value. */
|
||||||
frameLength <<= shift;
|
frameLength <<= shift;
|
||||||
exposureLines = CamHelperImx519::exposureLines(exposure);
|
exposureLines = CamHelperImx519::exposureLines(exposure, mode_.minLineLength);
|
||||||
exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff);
|
exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff);
|
||||||
exposure = CamHelperImx519::exposure(exposureLines);
|
exposure = CamHelperImx519::exposure(exposureLines, mode_.minLineLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameLength - mode_.height;
|
return frameLength - mode_.height;
|
||||||
|
@ -170,7 +170,8 @@ void CamHelperImx519::populateMetadata(const MdParser::RegisterMap ®isters,
|
||||||
{
|
{
|
||||||
DeviceStatus deviceStatus;
|
DeviceStatus deviceStatus;
|
||||||
|
|
||||||
deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg));
|
deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
|
||||||
|
mode_.minLineLength);
|
||||||
deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg));
|
deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg));
|
||||||
deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
|
deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
|
||||||
|
|
||||||
|
|
|
@ -477,7 +477,7 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo,
|
||||||
const uint32_t exposureMin = sensorCtrls_.at(V4L2_CID_EXPOSURE).min().get<int32_t>();
|
const uint32_t exposureMin = sensorCtrls_.at(V4L2_CID_EXPOSURE).min().get<int32_t>();
|
||||||
|
|
||||||
ctrlMap[&controls::ExposureTime] =
|
ctrlMap[&controls::ExposureTime] =
|
||||||
ControlInfo(static_cast<int32_t>(helper_->exposure(exposureMin).get<std::micro>()),
|
ControlInfo(static_cast<int32_t>(helper_->exposure(exposureMin, mode_.minLineLength).get<std::micro>()),
|
||||||
static_cast<int32_t>(maxShutter.get<std::micro>()));
|
static_cast<int32_t>(maxShutter.get<std::micro>()));
|
||||||
|
|
||||||
result->controlInfo = ControlInfoMap(std::move(ctrlMap), controls::controls);
|
result->controlInfo = ControlInfoMap(std::move(ctrlMap), controls::controls);
|
||||||
|
@ -550,7 +550,7 @@ void IPARPi::reportMetadata()
|
||||||
deviceStatus->shutterSpeed.get<std::micro>());
|
deviceStatus->shutterSpeed.get<std::micro>());
|
||||||
libcameraMetadata_.set(controls::AnalogueGain, deviceStatus->analogueGain);
|
libcameraMetadata_.set(controls::AnalogueGain, deviceStatus->analogueGain);
|
||||||
libcameraMetadata_.set(controls::FrameDuration,
|
libcameraMetadata_.set(controls::FrameDuration,
|
||||||
helper_->exposure(deviceStatus->frameLength).get<std::micro>());
|
helper_->exposure(deviceStatus->frameLength, mode_.minLineLength).get<std::micro>());
|
||||||
if (deviceStatus->sensorTemperature)
|
if (deviceStatus->sensorTemperature)
|
||||||
libcameraMetadata_.set(controls::SensorTemperature, *deviceStatus->sensorTemperature);
|
libcameraMetadata_.set(controls::SensorTemperature, *deviceStatus->sensorTemperature);
|
||||||
}
|
}
|
||||||
|
@ -1105,7 +1105,7 @@ void IPARPi::fillDeviceStatus(const ControlList &sensorControls)
|
||||||
int32_t gainCode = sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>();
|
int32_t gainCode = sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>();
|
||||||
int32_t vblank = sensorControls.get(V4L2_CID_VBLANK).get<int32_t>();
|
int32_t vblank = sensorControls.get(V4L2_CID_VBLANK).get<int32_t>();
|
||||||
|
|
||||||
deviceStatus.shutterSpeed = helper_->exposure(exposureLines);
|
deviceStatus.shutterSpeed = helper_->exposure(exposureLines, mode_.minLineLength);
|
||||||
deviceStatus.analogueGain = helper_->gain(gainCode);
|
deviceStatus.analogueGain = helper_->gain(gainCode);
|
||||||
deviceStatus.frameLength = mode_.height + vblank;
|
deviceStatus.frameLength = mode_.height + vblank;
|
||||||
|
|
||||||
|
@ -1197,7 +1197,7 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)
|
||||||
/* getVBlanking might clip exposure time to the fps limits. */
|
/* getVBlanking might clip exposure time to the fps limits. */
|
||||||
Duration exposure = agcStatus->shutterTime;
|
Duration exposure = agcStatus->shutterTime;
|
||||||
int32_t vblanking = helper_->getVBlanking(exposure, minFrameDuration_, maxFrameDuration_);
|
int32_t vblanking = helper_->getVBlanking(exposure, minFrameDuration_, maxFrameDuration_);
|
||||||
int32_t exposureLines = helper_->exposureLines(exposure);
|
int32_t exposureLines = helper_->exposureLines(exposure, mode_.minLineLength);
|
||||||
|
|
||||||
LOG(IPARPI, Debug) << "Applying AGC Exposure: " << exposure
|
LOG(IPARPI, Debug) << "Applying AGC Exposure: " << exposure
|
||||||
<< " (Shutter lines: " << exposureLines << ", AGC requested "
|
<< " (Shutter lines: " << exposureLines << ", AGC requested "
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue