[RFC,v2,07/14] libcamera: software_isp: Use multiple parameters buffers in IPA
diff mbox series

Message ID 20260216203034.27558-8-mzamazal@redhat.com
State New
Headers show
Series
  • Software ISP: Share params and stats buffers
Related show

Commit Message

Milan Zamazal Feb. 16, 2026, 8:30 p.m. UTC
Instead of the single parameters buffer file descriptor, pass the file
descriptors of all the parameters buffers to the IPA and let it use them
according to the passed buffer id.

This means:

- The file descriptors of all the buffers must be passed to the IPA.

- The IPA must store mappings of the buffer ids to the corresponding
  buffers.

- The current buffer id is passed to/from the IPA.

The parameters buffers are still copied for debayering, this will be
addressed in the next patch.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 include/libcamera/ipa/soft.mojom            |  2 +-
 src/ipa/simple/soft_simple.cpp              | 41 +++++++++++----------
 src/libcamera/software_isp/software_isp.cpp | 11 ++++--
 3 files changed, 30 insertions(+), 24 deletions(-)

Patch
diff mbox series

diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom
index f37c1e747..4738a1b46 100644
--- a/include/libcamera/ipa/soft.mojom
+++ b/include/libcamera/ipa/soft.mojom
@@ -15,7 +15,7 @@  struct IPAConfigInfo {
 interface IPASoftInterface {
 	init(libcamera.IPASettings settings,
 	     libcamera.SharedFD fdStats,
-	     libcamera.SharedFD fdParams,
+	     array<libcamera.SharedFD> fdParams,
 	     libcamera.IPACameraSensorInfo sensorInfo,
 	     libcamera.ControlInfoMap sensorControls)
 		=> (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled);
diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp
index 1e8b5334c..f212fabe3 100644
--- a/src/ipa/simple/soft_simple.cpp
+++ b/src/ipa/simple/soft_simple.cpp
@@ -53,7 +53,7 @@  public:
 
 	int init(const IPASettings &settings,
 		 const SharedFD &fdStats,
-		 const SharedFD &fdParams,
+		 const std::vector<SharedFD> &fdParams,
 		 const IPACameraSensorInfo &sensorInfo,
 		 const ControlInfoMap &sensorControls,
 		 ControlInfoMap *ipaControls,
@@ -76,7 +76,7 @@  protected:
 private:
 	void updateExposure(double exposureMSV);
 
-	DebayerParams *params_;
+	std::map<unsigned int, DebayerParams *> paramsBuffers_;
 	SwIspStats *stats_;
 	std::unique_ptr<CameraSensorHelper> camHelper_;
 	ControlInfoMap sensorInfoMap_;
@@ -89,13 +89,13 @@  IPASoftSimple::~IPASoftSimple()
 {
 	if (stats_)
 		munmap(stats_, sizeof(SwIspStats));
-	if (params_)
-		munmap(params_, sizeof(DebayerParams));
+	for (auto &item : paramsBuffers_)
+		munmap(item.second, sizeof(DebayerParams));
 }
 
 int IPASoftSimple::init(const IPASettings &settings,
 			const SharedFD &fdStats,
-			const SharedFD &fdParams,
+			const std::vector<SharedFD> &fdParams,
 			const IPACameraSensorInfo &sensorInfo,
 			const ControlInfoMap &sensorControls,
 			ControlInfoMap *ipaControls,
@@ -138,8 +138,6 @@  int IPASoftSimple::init(const IPASettings &settings,
 		return ret;
 
 	*ccmEnabled = context_.ccmEnabled;
-
-	params_ = nullptr;
 	stats_ = nullptr;
 
 	if (!fdStats.isValid()) {
@@ -147,25 +145,27 @@  int IPASoftSimple::init(const IPASettings &settings,
 		return -ENODEV;
 	}
 
-	if (!fdParams.isValid()) {
-		LOG(IPASoft, Error) << "Invalid Parameters handle";
-		return -ENODEV;
-	}
+	for (auto &sharedFd : fdParams) {
+		if (!sharedFd.isValid()) {
+			LOG(IPASoft, Error) << "Invalid Parameters handle";
+			return -ENODEV;
+		}
 
-	{
 		void *mem = mmap(nullptr, sizeof(DebayerParams), PROT_WRITE,
-				 MAP_SHARED, fdParams.get(), 0);
+				 MAP_SHARED, sharedFd.get(), 0);
 		if (mem == MAP_FAILED) {
 			LOG(IPASoft, Error) << "Unable to map Parameters";
 			return -errno;
 		}
 
-		params_ = static_cast<DebayerParams *>(mem);
-		params_->blackLevel = { { 0.0, 0.0, 0.0 } };
-		params_->gamma = 1.0 / algorithms::kDefaultGamma;
-		params_->contrastExp = 1.0;
-		params_->gains = { { 1.0, 1.0, 1.0 } };
+		ASSERT(sharedFd.get() >= 0);
+		DebayerParams *params = static_cast<DebayerParams *>(mem);
+		params->blackLevel = { { 0.0, 0.0, 0.0 } };
+		params->gamma = 1.0 / algorithms::kDefaultGamma;
+		params->contrastExp = 1.0;
+		params->gains = { { 1.0, 1.0, 1.0 } };
 		/* combinedMatrix is reset for each frame. */
+		paramsBuffers_[sharedFd.get()] = params;
 	}
 
 	{
@@ -291,9 +291,10 @@  void IPASoftSimple::computeParams(const uint32_t frame,
 	context_.activeState.combinedMatrix = Matrix<float, 3, 3>::identity();
 
 	IPAFrameContext &frameContext = context_.frameContexts.get(frame);
+	DebayerParams *params = paramsBuffers_.at(paramsBufferId);
 	for (auto const &algo : algorithms())
-		algo->prepare(context_, frame, frameContext, params_);
-	params_->combinedMatrix = context_.activeState.combinedMatrix;
+		algo->prepare(context_, frame, frameContext, params);
+	params->combinedMatrix = context_.activeState.combinedMatrix;
 
 	setIspParams.emit(paramsBufferId);
 }
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index 02d1c4c12..2bc0d30b1 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -14,6 +14,7 @@ 
 #include <unistd.h>
 
 #include <libcamera/base/log.h>
+#include <libcamera/base/shared_fd.h>
 #include <libcamera/base/thread.h>
 #include <libcamera/base/utils.h>
 
@@ -118,6 +119,9 @@  SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
 	if (!debayer_)
 		debayer_ = std::make_unique<DebayerCpu>(std::move(stats), configuration);
 
+	std::vector<SharedFD> fdParams;
+	for (auto &item : sharedParams_)
+		fdParams.emplace_back(item.second.fd());
 	debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);
 	debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);
 	debayer_->releaseIspParams.connect(this, &SoftwareIsp::releaseIspParams);
@@ -146,7 +150,7 @@  SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
 
 	ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() },
 			 debayer_->getStatsFD(),
-			 sharedParams_.begin()->second.fd(),
+			 fdParams,
 			 sensorInfo,
 			 sensor->controls(),
 			 ipaControls,
@@ -422,13 +426,14 @@  void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *outpu
 	const uint32_t paramsBufferId = availableParams_.front();
 	availableParams_.pop();
 	ipa_->computeParams(frame, paramsBufferId);
+	debayerParams_ = *sharedParams_.at(paramsBufferId);
 	debayer_->invokeMethod(&Debayer::process,
 			       ConnectionTypeQueued, frame, paramsBufferId, input, output, debayerParams_);
 }
 
-void SoftwareIsp::saveIspParams([[maybe_unused]] uint32_t paramsBufferId)
+void SoftwareIsp::saveIspParams(uint32_t paramsBufferId)
 {
-	debayerParams_ = *sharedParams_.begin()->second;
+	debayerParams_ = *sharedParams_.at(paramsBufferId);
 }
 
 void SoftwareIsp::releaseIspParams(uint32_t paramsBufferId)