@@ -12,6 +12,7 @@
#pragma once
#include <map>
+#include <memory>
#include <stdint.h>
#include <vector>
@@ -47,10 +48,6 @@ public:
*/
static constexpr uint32_t kStatPerNumFrames = 4;
- bool isValid() const { return sharedStats_->begin()->second.fd().isValid(); }
-
- const SharedFD &getStatsFD() { return sharedStats_->begin()->second.fd(); }
-
const Size &patternSize() { return patternSize_; }
int configure(const StreamConfiguration &inputCfg, unsigned int statsBufferCount = 1);
@@ -14,7 +14,7 @@ struct IPAConfigInfo {
interface IPASoftInterface {
init(libcamera.IPASettings settings,
- libcamera.SharedFD fdStats,
+ map<uint32, libcamera.SharedFD> fdStats,
map<uint32, libcamera.SharedFD> fdParams,
libcamera.IPACameraSensorInfo sensorInfo,
libcamera.ControlInfoMap sensorControls)
@@ -52,7 +52,7 @@ public:
~IPASoftSimple();
int init(const IPASettings &settings,
- const SharedFD &fdStats,
+ const std::map<uint32_t, SharedFD> &fdStats,
const std::map<uint32_t, SharedFD> &fdParams,
const IPACameraSensorInfo &sensorInfo,
const ControlInfoMap &sensorControls,
@@ -76,7 +76,7 @@ private:
void updateExposure(double exposureMSV);
std::map<unsigned int, DebayerParams *> paramsBuffers_;
- SwIspStats *stats_;
+ std::map<unsigned int, SwIspStats *> statsBuffers_;
std::unique_ptr<CameraSensorHelper> camHelper_;
ControlInfoMap sensorInfoMap_;
@@ -86,14 +86,14 @@ private:
IPASoftSimple::~IPASoftSimple()
{
- if (stats_)
- munmap(stats_, sizeof(SwIspStats));
+ for (auto &item : statsBuffers_)
+ munmap(item.second, sizeof(SwIspStats));
for (auto &item : paramsBuffers_)
munmap(item.second, sizeof(DebayerParams));
}
int IPASoftSimple::init(const IPASettings &settings,
- const SharedFD &fdStats,
+ const std::map<uint32_t, SharedFD> &fdStats,
const std::map<uint32_t, SharedFD> &fdParams,
const IPACameraSensorInfo &sensorInfo,
const ControlInfoMap &sensorControls,
@@ -137,11 +137,20 @@ int IPASoftSimple::init(const IPASettings &settings,
return ret;
*ccmEnabled = context_.ccmEnabled;
- stats_ = nullptr;
+ for (auto &[bufferId, sharedFd] : fdStats) {
+ if (!sharedFd.isValid()) {
+ LOG(IPASoft, Error) << "Invalid Statistics handle";
+ return -ENODEV;
+ }
+
+ void *mem = mmap(nullptr, sizeof(SwIspStats), PROT_READ,
+ MAP_SHARED, sharedFd.get(), 0);
+ if (mem == MAP_FAILED) {
+ LOG(IPASoft, Error) << "Unable to map Statistics";
+ return -errno;
+ }
- if (!fdStats.isValid()) {
- LOG(IPASoft, Error) << "Invalid Statistics handle";
- return -ENODEV;
+ statsBuffers_[bufferId] = static_cast<SwIspStats *>(mem);
}
for (auto &[bufferId, sharedFd] : fdParams) {
@@ -166,17 +175,6 @@ int IPASoftSimple::init(const IPASettings &settings,
paramsBuffers_[bufferId] = params;
}
- {
- void *mem = mmap(nullptr, sizeof(SwIspStats), PROT_READ,
- MAP_SHARED, fdStats.get(), 0);
- if (mem == MAP_FAILED) {
- LOG(IPASoft, Error) << "Unable to map Statistics";
- return -errno;
- }
-
- stats_ = static_cast<SwIspStats *>(mem);
- }
-
ControlInfoMap::Map ctrlMap = context_.ctrlMap;
*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
@@ -303,6 +301,8 @@ void IPASoftSimple::processStats(const uint32_t frame,
{
IPAFrameContext &frameContext = context_.frameContexts.get(frame);
+ const SwIspStats *stats = statsBuffers_.at(statsBufferId);
+
frameContext.sensor.exposure =
sensorControls.get(V4L2_CID_EXPOSURE).get<int32_t>();
int32_t again = sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>();
@@ -310,7 +310,7 @@ void IPASoftSimple::processStats(const uint32_t frame,
ControlList metadata(controls::controls);
for (const auto &algo : algorithms())
- algo->process(context_, frame, frameContext, stats_, metadata);
+ algo->process(context_, frame, frameContext, stats, metadata);
metadataReady.emit(frame, metadata);
statsProcessed.emit(statsBufferId);
@@ -138,16 +138,6 @@ Debayer::~Debayer()
* \return The valid size ranges or an empty range if there are none
*/
-/**
- * \fn const SharedFD &Debayer::getStatsFD()
- * \brief Get the file descriptor for the statistics
- *
- * This file descriptor provides access to the output statistics buffer
- * associated with the current debayering process.
- *
- * \return The file descriptor pointing to the statistics data
- */
-
/**
* \fn unsigned int Debayer::frameSize()
* \brief Get the output frame size
@@ -57,8 +57,6 @@ public:
virtual SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) = 0;
- virtual const SharedFD &getStatsFD() = 0;
-
unsigned int frameSize() { return outputConfig_.frameSize; }
Signal<FrameBuffer *> inputBufferReady;
@@ -53,7 +53,6 @@ public:
int start() override;
void stop() override;
SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override;
- const SharedFD &getStatsFD() override { return stats_->getStatsFD(); }
private:
friend class DebayerCpuThread;
@@ -61,8 +61,6 @@ public:
int start() override;
void stop() override;
- const SharedFD &getStatsFD() override { return stats_->getStatsFD(); }
-
SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override;
private:
@@ -162,7 +162,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe,
}
ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() },
- debayer_->getStatsFD(),
+ fdStats,
fdParams,
sensorInfo,
sensor->controls(),
@@ -48,20 +48,6 @@ namespace libcamera {
* exchange.
*/
-/**
- * \fn bool SwStatsCpu::isValid() const
- * \brief Gets whether the statistics object is valid
- *
- * \return True if it's valid, false otherwise
- */
-
-/**
- * \fn const SharedFD &SwStatsCpu::getStatsFD()
- * \brief Get the file descriptor for the statistics
- *
- * \return The file descriptor
- */
-
/**
* \fn const Size &SwStatsCpu::patternSize()
* \brief Get the pattern size
@@ -355,21 +341,21 @@ void SwStatsCpu::finishFrame(uint32_t frame,
const uint32_t statsBufferId)
{
bool valid = frame % kStatPerNumFrames == 0;
- SharedMemObject<SwIspStats> &stats = sharedStats_->at(statsBufferId);
+ SharedMemObject<SwIspStats> &shared = sharedStats_->at(statsBufferId);
if (valid) {
- stats->sum_ = RGB<uint64_t>({ 0, 0, 0 });
- stats->yHistogram.fill(0);
+ shared->sum_ = RGB<uint64_t>({ 0, 0, 0 });
+ shared->yHistogram.fill(0);
for (const auto &s : stats_) {
- stats->sum_ += s.sum_;
+ shared->sum_ += s.sum_;
for (unsigned int j = 0; j < SwIspStats::kYHistogramSize; j++)
- stats->yHistogram[j] += s.yHistogram[j];
+ shared->yHistogram[j] += s.yHistogram[j];
}
- stats->sum_ >>= sumShift_;
+ shared->sum_ >>= sumShift_;
}
- stats->valid = valid;
+ shared->valid = valid;
statsReady.emit(frame, statsBufferId);
}
The last step to complete statistics buffer sharing is to pass all the allocated statistics buffers to the IPA and refer to them using their ids. This allows to remove the buffer copying in SwStatsCpu::finishFrame. We can also remove now the methods that served for handling the former single buffer shared between debayering and IPA. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> --- .../internal/software_isp/swstats_cpu.h | 5 +-- include/libcamera/ipa/soft.mojom | 2 +- src/ipa/simple/soft_simple.cpp | 42 +++++++++---------- src/libcamera/software_isp/debayer.cpp | 10 ----- src/libcamera/software_isp/debayer.h | 2 - src/libcamera/software_isp/debayer_cpu.h | 1 - src/libcamera/software_isp/debayer_egl.h | 2 - src/libcamera/software_isp/software_isp.cpp | 2 +- src/libcamera/software_isp/swstats_cpu.cpp | 28 ++++--------- 9 files changed, 31 insertions(+), 63 deletions(-)