From 37053e550b9d841e6c123c2f660410db522e8955 Mon Sep 17 00:00:00 2001 From: Vasiliy Doylov Date: Wed, 21 May 2025 22:24:01 +0300 Subject: [PATCH] libcamera: software_isp: Add control to disable statistic collection Signed-off-by: Vasiliy Doylov --- .../internal/software_isp/debayer_params.h | 9 +++ src/ipa/simple/algorithms/meson.build | 1 + src/ipa/simple/algorithms/stat.cpp | 65 +++++++++++++++++++ src/ipa/simple/algorithms/stat.h | 38 +++++++++++ src/ipa/simple/data/uncalibrated.yaml | 1 + src/ipa/simple/ipa_context.h | 2 + src/libcamera/software_isp/debayer_cpu.cpp | 12 ++-- src/libcamera/software_isp/debayer_cpu.h | 1 + 8 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 src/ipa/simple/algorithms/stat.cpp create mode 100644 src/ipa/simple/algorithms/stat.h diff --git a/include/libcamera/internal/software_isp/debayer_params.h b/include/libcamera/internal/software_isp/debayer_params.h index 217cd5d92..6c36defc9 100644 --- a/include/libcamera/internal/software_isp/debayer_params.h +++ b/include/libcamera/internal/software_isp/debayer_params.h @@ -49,6 +49,15 @@ struct DebayerParams { CcmLookupTable greenCcm; CcmLookupTable blueCcm; LookupTable gammaLut; + + /* + * Statistic controls + * + * Statistic collecting are very slow. We can disable it for some actions like + * video capture or streaming. + * TODO: Add statistic window control + */ + bool collect_stats; }; } /* namespace libcamera */ diff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build index dec59ee8c..e5666b262 100644 --- a/src/ipa/simple/algorithms/meson.build +++ b/src/ipa/simple/algorithms/meson.build @@ -7,4 +7,5 @@ soft_simple_ipa_algorithms = files([ 'ccm.cpp', 'lut.cpp', 'af.cpp', + 'stat.cpp', ]) diff --git a/src/ipa/simple/algorithms/stat.cpp b/src/ipa/simple/algorithms/stat.cpp new file mode 100644 index 000000000..181a5d818 --- /dev/null +++ b/src/ipa/simple/algorithms/stat.cpp @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025 Vasiliy Doylov + * + * Debayer statistic controls + */ + +#include "stat.h" + +#include + +#include + +#include "control_ids.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(IPASoftStatistic) + +namespace ipa::soft::algorithms { + +Stat::Stat() +{ +} + +int Stat::init(IPAContext &context, + [[maybe_unused]] const YamlObject &tuningData) +{ + context.ctrlMap[&controls::DebugMetadataEnable] = ControlInfo(false, true, true); + return 0; +} + +int Stat::configure(IPAContext &context, + [[maybe_unused]] const IPAConfigInfo &configInfo) +{ + context.activeState.knobs.stats_enabled = std::optional(); + + return 0; +} + +void Stat::queueRequest([[maybe_unused]] typename Module::Context &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] typename Module::FrameContext &frameContext, + const ControlList &controls) +{ + const auto &stats_enabled = controls.get(controls::DebugMetadataEnable); + if (stats_enabled.has_value()) { + context.activeState.knobs.stats_enabled = stats_enabled; + LOG(IPASoftStatistic, Debug) << "Setting debayer enabled to " << stats_enabled.value(); + } +} + +void Stat::prepare([[maybe_unused]]IPAContext &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]]IPAFrameContext &frameContext, + [[maybe_unused]] DebayerParams *params) +{ + params->collect_stats = context.activeState.knobs.stats_enabled.value_or(true); +} + +REGISTER_IPA_ALGORITHM(Stat, "Stat") + +} /* namespace ipa::soft::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/simple/algorithms/stat.h b/src/ipa/simple/algorithms/stat.h new file mode 100644 index 000000000..dc0051cb0 --- /dev/null +++ b/src/ipa/simple/algorithms/stat.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025 Vasiliy Doylov + * + * Debayer statistic controls + */ + +#pragma once + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::soft::algorithms { + +class Stat : public Algorithm +{ +public: + Stat(); + ~Stat() = default; + + int init(IPAContext &context, const YamlObject &tuningData) override; + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; + void queueRequest(typename Module::Context &context, + const uint32_t frame, + typename Module::FrameContext &frameContext, + const ControlList &controls) + override; + void prepare(IPAContext &context, + const uint32_t frame, + IPAFrameContext &frameContext, + DebayerParams *params) override; + +}; + +} /* namespace ipa::soft::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/simple/data/uncalibrated.yaml b/src/ipa/simple/data/uncalibrated.yaml index d14b34294..47eaf9c61 100644 --- a/src/ipa/simple/data/uncalibrated.yaml +++ b/src/ipa/simple/data/uncalibrated.yaml @@ -17,4 +17,5 @@ algorithms: - Lut: - Agc: - Af: + - Stat: ... diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index c5b5527b5..cfc524a13 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -75,6 +75,8 @@ struct IPAActiveState { std::optional exposure_value; /* 0..100 range, 50.0 = normal */ std::optional focus_pos; + /* 0..1 range, 1 = normal */ + std::optional stats_enabled; } knobs; }; diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 66f6038c1..c6f070225 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -668,7 +668,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); + if (this->enable_statistic) stats_->processLine0(y, linePointers); (this->*debayer0_)(dst, linePointers); src += inputConfig_.stride; dst += outputConfig_.stride; @@ -683,7 +683,7 @@ void DebayerCpu::process2(const uint8_t *src, uint8_t *dst) if (window_.y == 0) { shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - stats_->processLine0(yEnd, linePointers); + if (this->enable_statistic) stats_->processLine0(yEnd, linePointers); (this->*debayer0_)(dst, linePointers); src += inputConfig_.stride; dst += outputConfig_.stride; @@ -720,7 +720,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); + if (this->enable_statistic) stats_->processLine0(y, linePointers); (this->*debayer0_)(dst, linePointers); src += inputConfig_.stride; dst += outputConfig_.stride; @@ -733,7 +733,7 @@ void DebayerCpu::process4(const uint8_t *src, uint8_t *dst) shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - stats_->processLine2(y, linePointers); + if (this->enable_statistic) stats_->processLine2(y, linePointers); (this->*debayer2_)(dst, linePointers); src += inputConfig_.stride; dst += outputConfig_.stride; @@ -771,7 +771,7 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output for (const FrameBuffer::Plane &plane : output->planes()) dmaSyncers.emplace_back(plane.fd, DmaSyncer::SyncType::Write); - + enable_statistic = params.collect_stats; green_ = params.green; greenCcm_ = params.greenCcm; if (swapRedBlueGains_) { @@ -805,7 +805,7 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output return; } - stats_->startFrame(); + if(this->enable_statistic) stats_->startFrame(); if (inputConfig_.patternSize.height == 2) process2(in.planes()[0].data(), out.planes()[0].data()); diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 926195e98..54304053f 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -165,6 +165,7 @@ private: /* Skip 30 frames for things to stabilize then measure 30 frames */ static constexpr unsigned int kFramesToSkip = 30; static constexpr unsigned int kLastFrameToMeasure = 60; + bool enable_statistic = true; }; } /* namespace libcamera */