libcamera: software_isp: Run sw-statistics once every 4th frame

Run sw-statistics once every 4th frame, instead of every frame. There are
2 reasons for this:

1. There really is no need to have statistics for every frame and only
doing this every 4th frame helps save some CPU time.

2. The generic nature of the simple pipeline-handler, so no information
about possible CSI receiver frame-delays. In combination with the software
ISP often being used with sensors without sensor info in the sensor-helper
code, so no reliable control-delay information means that the software ISP
is prone to AGC oscillation. Skipping statistics gathering also means
skipping running the AGC algorithm slowing it down, avoiding this
oscillation.

Note ideally the AGC oscillation problem would be fixed by adding sensor
metadata support all through the stack so that the exact gain and exposure
used for a specific frame are reliably provided by the sensor metadata.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Hans de Goede <hansg@kernel.org>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Hans de Goede
2025-09-30 17:04:28 +02:00
committed by Kieran Bingham
parent 9b441cf198
commit c28bb6a6a4
4 changed files with 43 additions and 18 deletions

View File

@@ -655,7 +655,7 @@ void DebayerCpu::memcpyNextLine(const uint8_t *linePointers[])
lineBufferIndex_ = (lineBufferIndex_ + 1) % (patternHeight + 1);
}
void DebayerCpu::process2(const uint8_t *src, uint8_t *dst)
void DebayerCpu::process2(uint32_t frame, const uint8_t *src, uint8_t *dst)
{
unsigned int yEnd = window_.y + window_.height;
/* Holds [0] previous- [1] current- [2] next-line */
@@ -681,7 +681,7 @@ void DebayerCpu::process2(const uint8_t *src, uint8_t *dst)
for (unsigned int y = window_.y; y < yEnd; y += 2) {
shiftLinePointers(linePointers, src);
memcpyNextLine(linePointers);
stats_->processLine0(y, linePointers);
stats_->processLine0(frame, y, linePointers);
(this->*debayer0_)(dst, linePointers);
src += inputConfig_.stride;
dst += outputConfig_.stride;
@@ -696,7 +696,7 @@ void DebayerCpu::process2(const uint8_t *src, uint8_t *dst)
if (window_.y == 0) {
shiftLinePointers(linePointers, src);
memcpyNextLine(linePointers);
stats_->processLine0(yEnd, linePointers);
stats_->processLine0(frame, yEnd, linePointers);
(this->*debayer0_)(dst, linePointers);
src += inputConfig_.stride;
dst += outputConfig_.stride;
@@ -710,7 +710,7 @@ void DebayerCpu::process2(const uint8_t *src, uint8_t *dst)
}
}
void DebayerCpu::process4(const uint8_t *src, uint8_t *dst)
void DebayerCpu::process4(uint32_t frame, const uint8_t *src, uint8_t *dst)
{
const unsigned int yEnd = window_.y + window_.height;
/*
@@ -733,7 +733,7 @@ void DebayerCpu::process4(const uint8_t *src, uint8_t *dst)
for (unsigned int y = window_.y; y < yEnd; y += 4) {
shiftLinePointers(linePointers, src);
memcpyNextLine(linePointers);
stats_->processLine0(y, linePointers);
stats_->processLine0(frame, y, linePointers);
(this->*debayer0_)(dst, linePointers);
src += inputConfig_.stride;
dst += outputConfig_.stride;
@@ -746,7 +746,7 @@ void DebayerCpu::process4(const uint8_t *src, uint8_t *dst)
shiftLinePointers(linePointers, src);
memcpyNextLine(linePointers);
stats_->processLine2(y, linePointers);
stats_->processLine2(frame, y, linePointers);
(this->*debayer2_)(dst, linePointers);
src += inputConfig_.stride;
dst += outputConfig_.stride;
@@ -821,12 +821,12 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output
return;
}
stats_->startFrame();
stats_->startFrame(frame);
if (inputConfig_.patternSize.height == 2)
process2(in.planes()[0].data(), out.planes()[0].data());
process2(frame, in.planes()[0].data(), out.planes()[0].data());
else
process4(in.planes()[0].data(), out.planes()[0].data());
process4(frame, in.planes()[0].data(), out.planes()[0].data());
metadata.planes()[0].bytesused = out.planes()[0].size();