libcamera: software_isp: Add control to disable statistic collection
Some checks failed
PostmarketOS Build / Prepare (push) Successful in 5s
PostmarketOS Build / Build for aarch64 (push) Failing after 5m29s
PostmarketOS Build / Build for x86_64 (push) Failing after 2m33s
PostmarketOS Build / Clean (push) Successful in 17s

Signed-off-by: Vasiliy Doylov <nekocwd@mainlining.org>
This commit is contained in:
Vasiliy Doylov 2025-05-21 22:24:01 +03:00
parent 892eccda98
commit d52bdb4010
Signed by: NekoCWD
GPG key ID: B7BE22D44474A582
8 changed files with 123 additions and 6 deletions

View file

@ -49,6 +49,15 @@ struct DebayerParams {
CcmLookupTable greenCcm; CcmLookupTable greenCcm;
CcmLookupTable blueCcm; CcmLookupTable blueCcm;
LookupTable gammaLut; 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 */ } /* namespace libcamera */

View file

@ -7,4 +7,5 @@ soft_simple_ipa_algorithms = files([
'ccm.cpp', 'ccm.cpp',
'lut.cpp', 'lut.cpp',
'af.cpp', 'af.cpp',
'stat.cpp',
]) ])

View file

@ -0,0 +1,65 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2025 Vasiliy Doylov <nekodevelopper@gmail.com>
*
* Debayer statistic controls
*/
#include "stat.h"
#include <stdint.h>
#include <libcamera/base/log.h>
#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<bool>();
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 */

View file

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2025 Vasiliy Doylov <nekodevelopper@gmail.com>
*
* 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 */

View file

@ -17,4 +17,5 @@ algorithms:
- Lut: - Lut:
- Agc: - Agc:
- Af: - Af:
- Stat:
... ...

View file

@ -75,6 +75,8 @@ struct IPAActiveState {
std::optional<double> exposure_value; std::optional<double> exposure_value;
/* 0..100 range, 50.0 = normal */ /* 0..100 range, 50.0 = normal */
std::optional<double> focus_pos; std::optional<double> focus_pos;
/* 0..1 range, 1 = normal */
std::optional<bool> stats_enabled;
} knobs; } knobs;
}; };

View file

@ -668,7 +668,7 @@ void DebayerCpu::process2(const uint8_t *src, uint8_t *dst)
for (unsigned int y = window_.y; y < yEnd; y += 2) { for (unsigned int y = window_.y; y < yEnd; y += 2) {
shiftLinePointers(linePointers, src); shiftLinePointers(linePointers, src);
memcpyNextLine(linePointers); memcpyNextLine(linePointers);
stats_->processLine0(y, linePointers); if (this->enable_statistic) stats_->processLine0(y, linePointers);
(this->*debayer0_)(dst, linePointers); (this->*debayer0_)(dst, linePointers);
src += inputConfig_.stride; src += inputConfig_.stride;
dst += outputConfig_.stride; dst += outputConfig_.stride;
@ -683,7 +683,7 @@ void DebayerCpu::process2(const uint8_t *src, uint8_t *dst)
if (window_.y == 0) { if (window_.y == 0) {
shiftLinePointers(linePointers, src); shiftLinePointers(linePointers, src);
memcpyNextLine(linePointers); memcpyNextLine(linePointers);
stats_->processLine0(yEnd, linePointers); if (this->enable_statistic) stats_->processLine0(yEnd, linePointers);
(this->*debayer0_)(dst, linePointers); (this->*debayer0_)(dst, linePointers);
src += inputConfig_.stride; src += inputConfig_.stride;
dst += outputConfig_.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) { for (unsigned int y = window_.y; y < yEnd; y += 4) {
shiftLinePointers(linePointers, src); shiftLinePointers(linePointers, src);
memcpyNextLine(linePointers); memcpyNextLine(linePointers);
stats_->processLine0(y, linePointers); if (this->enable_statistic) stats_->processLine0(y, linePointers);
(this->*debayer0_)(dst, linePointers); (this->*debayer0_)(dst, linePointers);
src += inputConfig_.stride; src += inputConfig_.stride;
dst += outputConfig_.stride; dst += outputConfig_.stride;
@ -733,7 +733,7 @@ void DebayerCpu::process4(const uint8_t *src, uint8_t *dst)
shiftLinePointers(linePointers, src); shiftLinePointers(linePointers, src);
memcpyNextLine(linePointers); memcpyNextLine(linePointers);
stats_->processLine2(y, linePointers); if (this->enable_statistic) stats_->processLine2(y, linePointers);
(this->*debayer2_)(dst, linePointers); (this->*debayer2_)(dst, linePointers);
src += inputConfig_.stride; src += inputConfig_.stride;
dst += outputConfig_.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()) for (const FrameBuffer::Plane &plane : output->planes())
dmaSyncers.emplace_back(plane.fd, DmaSyncer::SyncType::Write); dmaSyncers.emplace_back(plane.fd, DmaSyncer::SyncType::Write);
enable_statistic = params.collect_stats;
green_ = params.green; green_ = params.green;
greenCcm_ = params.greenCcm; greenCcm_ = params.greenCcm;
if (swapRedBlueGains_) { if (swapRedBlueGains_) {
@ -805,7 +805,7 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output
return; return;
} }
stats_->startFrame(); if(this->enable_statistic) stats_->startFrame();
if (inputConfig_.patternSize.height == 2) if (inputConfig_.patternSize.height == 2)
process2(in.planes()[0].data(), out.planes()[0].data()); process2(in.planes()[0].data(), out.planes()[0].data());

View file

@ -165,6 +165,7 @@ private:
/* Skip 30 frames for things to stabilize then measure 30 frames */ /* Skip 30 frames for things to stabilize then measure 30 frames */
static constexpr unsigned int kFramesToSkip = 30; static constexpr unsigned int kFramesToSkip = 30;
static constexpr unsigned int kLastFrameToMeasure = 60; static constexpr unsigned int kLastFrameToMeasure = 60;
bool enable_statistic = true;
}; };
} /* namespace libcamera */ } /* namespace libcamera */