summaryrefslogtreecommitdiff
path: root/src/libcamera
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcamera')
-rw-r--r--src/libcamera/software_isp/TODO10
-rw-r--r--src/libcamera/software_isp/debayer_cpu.cpp13
-rw-r--r--src/libcamera/software_isp/debayer_cpu.h1
-rw-r--r--src/libcamera/software_isp/software_isp.cpp2
4 files changed, 21 insertions, 5 deletions
diff --git a/src/libcamera/software_isp/TODO b/src/libcamera/software_isp/TODO
index fcb02588..4fcee39b 100644
--- a/src/libcamera/software_isp/TODO
+++ b/src/libcamera/software_isp/TODO
@@ -267,3 +267,13 @@ This could be handled better with DelayedControls.
> V4L2_CID_EXPOSURE }));
You should use the DelayedControls class.
+
+---
+
+13. Improve black level and colour gains application
+
+I think the black level should eventually be moved before debayering, and
+ideally the colour gains as well. I understand the need for optimizations to
+lower the CPU consumption, but at the same time I don't feel comfortable
+building up on top of an implementation that may work a bit more by chance than
+by correctness, as that's not very maintainable.
diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp
index 5b553162..88d6578b 100644
--- a/src/libcamera/software_isp/debayer_cpu.cpp
+++ b/src/libcamera/software_isp/debayer_cpu.cpp
@@ -35,7 +35,7 @@ namespace libcamera {
* \param[in] stats Pointer to the stats object to use
*/
DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats)
- : stats_(std::move(stats)), gammaCorrection_(1.0)
+ : stats_(std::move(stats)), gammaCorrection_(1.0), blackLevel_(0)
{
/*
* Reading from uncached buffers may be very slow.
@@ -699,11 +699,16 @@ void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams
}
/* Apply DebayerParams */
- if (params.gamma != gammaCorrection_) {
- for (unsigned int i = 0; i < kGammaLookupSize; i++)
- gamma_[i] = UINT8_MAX * powf(i / (kGammaLookupSize - 1.0), params.gamma);
+ if (params.gamma != gammaCorrection_ || params.blackLevel != blackLevel_) {
+ const unsigned int blackIndex =
+ params.blackLevel * kGammaLookupSize / 256;
+ std::fill(gamma_.begin(), gamma_.begin() + blackIndex, 0);
+ const float divisor = kGammaLookupSize - blackIndex - 1.0;
+ for (unsigned int i = blackIndex; i < kGammaLookupSize; i++)
+ gamma_[i] = UINT8_MAX * powf((i - blackIndex) / divisor, params.gamma);
gammaCorrection_ = params.gamma;
+ blackLevel_ = params.blackLevel;
}
if (swapRedBlueGains_)
diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h
index e7a8ba74..689c1075 100644
--- a/src/libcamera/software_isp/debayer_cpu.h
+++ b/src/libcamera/software_isp/debayer_cpu.h
@@ -147,6 +147,7 @@ private:
bool enableInputMemcpy_;
bool swapRedBlueGains_;
float gammaCorrection_;
+ unsigned int blackLevel_;
unsigned int measuredFrames_;
int64_t frameProcessTime_;
/* Skip 30 frames for things to stabilize then measure 30 frames */
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index d746d893..e4e56086 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -64,7 +64,7 @@ LOG_DEFINE_CATEGORY(SoftwareIsp)
*/
SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor)
: debayerParams_{ DebayerParams::kGain10, DebayerParams::kGain10,
- DebayerParams::kGain10, 0.5f },
+ DebayerParams::kGain10, 0.5f, 0 },
dmaHeap_(DmaHeap::DmaHeapFlag::Cma | DmaHeap::DmaHeapFlag::System)
{
if (!dmaHeap_.isValid()) {