[PATCH 13/16] libcamera: software_isp: Allocate statistics buffers

Milan Zamazal mzamazal at redhat.com
Mon Aug 12 13:50:02 CEST 2024


In order to be able to use multiple shared statistics buffers, we must
allocate them.  They are allocated in SoftwareIsp and passed to
SwIspStats.  This changes the previous behavior when the (single) shared
statistics buffer was created in SwIspStats.  Centralizing it to
SoftwareIsp makes sharing multiple buffers with IPA easier.

Currently only one of the allocated buffers is used.  This will be
changed once the buffers are shared with IPA in a followup patch.

Signed-off-by: Milan Zamazal <mzamazal at redhat.com>
---
 .../internal/software_isp/software_isp.h      |  5 +++
 src/libcamera/software_isp/software_isp.cpp   | 44 ++++++++++++++++---
 src/libcamera/software_isp/swstats_cpu.cpp    | 16 ++++---
 src/libcamera/software_isp/swstats_cpu.h      |  9 ++--
 4 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h
index ae64b247..a6ba4a07 100644
--- a/include/libcamera/internal/software_isp/software_isp.h
+++ b/include/libcamera/internal/software_isp/software_isp.h
@@ -33,6 +33,8 @@
 #include "libcamera/internal/shared_mem_object.h"
 #include "libcamera/internal/software_isp/debayer_params.h"
 
+#include "software_isp/swstats_cpu.h"
+
 namespace libcamera {
 
 class DebayerCpu;
@@ -100,6 +102,9 @@ private:
 	DebayerParams debayerParams_;
 	std::queue<uint32_t> availableParams_;
 	bool allocateParamsBuffers(const unsigned int bufferCount);
+	std::unique_ptr<SwStatsCpu> allocateStatsBuffers(
+		std::vector<SharedFD> &fdStats,
+		const unsigned int bufferCount);
 	DmaBufAllocator dmaHeap_;
 
 	std::unique_ptr<ipa::soft::IPAProxySoft> ipa_;
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index 5d9f5008..1e224b6f 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -12,6 +12,8 @@
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <utility>
+#include <vector>
 
 #include <libcamera/base/shared_fd.h>
 
@@ -20,7 +22,9 @@
 #include <libcamera/stream.h>
 
 #include "libcamera/internal/ipa_manager.h"
+#include "libcamera/internal/shared_mem_object.h"
 #include "libcamera/internal/software_isp/debayer_params.h"
+#include "libcamera/internal/software_isp/swisp_stats.h"
 
 #include "debayer_cpu.h"
 
@@ -79,17 +83,15 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
 	if (!allocateParamsBuffers(bufferCount))
 		return;
 
-	auto stats = std::make_unique<SwStatsCpu>();
-	if (!stats->isValid()) {
-		LOG(SoftwareIsp, Error) << "Failed to create SwStatsCpu object";
-		return;
-	}
-	stats->statsReady.connect(this, &SoftwareIsp::statsReady);
-
 	std::vector<SharedFD> fdParams;
 	for (auto &item : sharedParams_)
 		fdParams.emplace_back(item.second.fd());
 
+	std::vector<SharedFD> fdStats;
+	auto stats = allocateStatsBuffers(fdStats, bufferCount);
+	if (!stats)
+		return;
+
 	debayer_ = std::make_unique<DebayerCpu>(std::move(stats), fdParams);
 	debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);
 	debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);
@@ -169,6 +171,34 @@ bool SoftwareIsp::allocateParamsBuffers(const unsigned int bufferCount)
 	return true;
 }
 
+std::unique_ptr<SwStatsCpu> SoftwareIsp::allocateStatsBuffers(
+	std::vector<SharedFD> &fdStats,
+	const unsigned int bufferCount)
+{
+	auto sharedStats = std::make_unique<std::map<uint32_t, SharedMemObject<SwIspStats>>>();
+	for (unsigned int i = 0; i < bufferCount; i++) {
+		auto shared = SharedMemObject<SwIspStats>("softIsp_stats");
+		if (!shared) {
+			LOG(SoftwareIsp, Error) << "Failed to create shared memory for statistics";
+			return std::unique_ptr<SwStatsCpu>();
+		}
+		if (!shared.fd().isValid()) {
+			LOG(SoftwareIsp, Error) << "Invalid fd of shared statistics";
+			return std::unique_ptr<SwStatsCpu>();
+		}
+
+		ASSERT(shared.fd().get() >= 0);
+		unsigned int bufferId = shared.fd().get();
+		fdStats.emplace_back(shared.fd());
+		sharedStats->emplace(bufferId, std::move(shared));
+	}
+
+	auto stats = std::make_unique<SwStatsCpu>(std::move(sharedStats));
+	stats->statsReady.connect(this, &SoftwareIsp::statsReady);
+
+	return stats;
+}
+
 /**
  * \fn int SoftwareIsp::loadConfiguration([[maybe_unused]] const std::string &filename)
  * \brief Load a configuration from a file
diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp
index b8ee06a0..cb411a18 100644
--- a/src/libcamera/software_isp/swstats_cpu.cpp
+++ b/src/libcamera/software_isp/swstats_cpu.cpp
@@ -11,6 +11,8 @@
 
 #include "swstats_cpu.h"
 
+#include <memory>
+
 #include <libcamera/base/log.h>
 
 #include <libcamera/stream.h>
@@ -129,12 +131,14 @@ namespace libcamera {
 
 LOG_DEFINE_CATEGORY(SwStatsCpu)
 
-SwStatsCpu::SwStatsCpu()
-	: sharedStats_("softIsp_stats")
+/**
+ * \brief The constructor of SwStatsCpu
+ * \param [in] sharedStats Mapping of statistics buffer ids to statistics
+ *   instances that are shared with the IPA
+ */
+SwStatsCpu::SwStatsCpu(std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats)
+	: sharedStats_(std::move(sharedStats))
 {
-	if (!sharedStats_)
-		LOG(SwStatsCpu, Error)
-			<< "Failed to create shared memory for statistics";
 }
 
 static constexpr unsigned int kRedYMul = 77; /* 0.299 * 256 */
@@ -316,7 +320,7 @@ void SwStatsCpu::startFrame([[maybe_unused]] const uint32_t statsBufferId)
  */
 void SwStatsCpu::finishFrame(uint32_t frame, const uint32_t statsBufferId)
 {
-	*sharedStats_ = stats_;
+	*(sharedStats_->at(statsBufferId)) = stats_;
 	statsReady.emit(frame, statsBufferId);
 }
 
diff --git a/src/libcamera/software_isp/swstats_cpu.h b/src/libcamera/software_isp/swstats_cpu.h
index 402eef2d..fbdea4a3 100644
--- a/src/libcamera/software_isp/swstats_cpu.h
+++ b/src/libcamera/software_isp/swstats_cpu.h
@@ -11,6 +11,7 @@
 
 #pragma once
 
+#include <map>
 #include <stdint.h>
 
 #include <libcamera/base/signal.h>
@@ -29,12 +30,12 @@ struct StreamConfiguration;
 class SwStatsCpu
 {
 public:
-	SwStatsCpu();
+	SwStatsCpu(std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats);
 	~SwStatsCpu() = default;
 
-	bool isValid() const { return sharedStats_.fd().isValid(); }
+	bool isValid() const { return sharedStats_->begin()->second.fd().isValid(); }
 
-	const SharedFD &getStatsFD() { return sharedStats_.fd(); }
+	const SharedFD &getStatsFD() { return sharedStats_->begin()->second.fd(); }
 
 	const Size &patternSize() { return patternSize_; }
 
@@ -90,7 +91,7 @@ private:
 
 	unsigned int xShift_;
 
-	SharedMemObject<SwIspStats> sharedStats_;
+	std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats_;
 	SwIspStats stats_;
 };
 
-- 
2.44.1



More information about the libcamera-devel mailing list