libcamera: software_isp: Add control to disable statistic collection
Signed-off-by: Vasiliy Doylov <nekocwd@mainlining.org>
This commit is contained in:
parent
d0bf6e7f88
commit
6e8d4d86d7
8 changed files with 123 additions and 6 deletions
|
@ -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 */
|
||||||
|
|
|
@ -7,4 +7,5 @@ soft_simple_ipa_algorithms = files([
|
||||||
'ccm.cpp',
|
'ccm.cpp',
|
||||||
'lut.cpp',
|
'lut.cpp',
|
||||||
'af.cpp',
|
'af.cpp',
|
||||||
|
'stat.cpp',
|
||||||
])
|
])
|
||||||
|
|
65
src/ipa/simple/algorithms/stat.cpp
Normal file
65
src/ipa/simple/algorithms/stat.cpp
Normal 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 */
|
38
src/ipa/simple/algorithms/stat.h
Normal file
38
src/ipa/simple/algorithms/stat.h
Normal 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 */
|
|
@ -17,4 +17,5 @@ algorithms:
|
||||||
- Lut:
|
- Lut:
|
||||||
- Agc:
|
- Agc:
|
||||||
- Af:
|
- Af:
|
||||||
|
- Stat:
|
||||||
...
|
...
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue