[RFC,v3,15/17] libcamera: software_isp: Track statistics buffers
diff mbox series

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

Commit Message

Milan Zamazal June 4, 2026, 9:51 a.m. UTC
As a preparation for passing the shared statistics buffers to IPA, this
patch introduces tracking statistics buffer ids.

SofwareIsp::availableStats_ is a vector of ids of the buffers available
for use.  When a fresh statistics buffer is needed, its id is retrieved
from there and once the buffer is no longer needed, it's put back there,
in a method invoked by a signal.  This is similar to what the hardware
pipelines do.

We use buffers' file descriptors as buffer ids.  The statistics buffers
will be shared with the IPA, SwIspStats and debayering and we need their
common identification everywhere.  The buffer file descriptors are
shared unchanged so they can be used for the purpose, avoiding a need to
pass a special mapping to the IPA and debayering on initialization.

Note that the statistics buffer id is still actually unused, this will
be changed once the buffers are shared with the IPA.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 .../libcamera/internal/software_isp/software_isp.h |  1 +
 src/libcamera/software_isp/debayer_egl.cpp         |  4 ++--
 src/libcamera/software_isp/software_isp.cpp        | 14 +++++++++++---
 3 files changed, 14 insertions(+), 5 deletions(-)

Patch
diff mbox series

diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h
index 451596163..24eeaeb86 100644
--- a/include/libcamera/internal/software_isp/software_isp.h
+++ b/include/libcamera/internal/software_isp/software_isp.h
@@ -105,6 +105,7 @@  private:
 	Thread ispWorkerThread_;
 	std::map<uint32_t, SharedMemObject<DebayerParams>> sharedParams_;
 	std::vector<uint32_t> availableParams_;
+	std::vector<uint32_t> availableStats_;
 	DmaBufAllocator dmaHeap_;
 	bool ccmEnabled_;
 
diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp
index 09e7833ed..f43428432 100644
--- a/src/libcamera/software_isp/debayer_egl.cpp
+++ b/src/libcamera/software_isp/debayer_egl.cpp
@@ -550,7 +550,7 @@  int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye
 }
 
 void DebayerEGL::process(uint32_t frame,
-			 [[maybe_unused]] const uint32_t statsBufferId,
+			 const uint32_t statsBufferId,
 			 const uint32_t paramsBufferId,
 			 FrameBuffer *input,
 			 FrameBuffer *output)
@@ -590,7 +590,7 @@  void DebayerEGL::process(uint32_t frame,
 			inDmaSyncer.emplace(input->planes()[0].fd, DmaSyncer::SyncType::Read);
 			inMapped.emplace(input, MappedFrameBuffer::MapFlag::Read);
 		}
-		stats_->processFrame(frame, 0, inMapped.value());
+		stats_->processFrame(frame, statsBufferId, inMapped.value());
 	}
 	inDmaSyncer.reset();
 
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index c4da647e8..2a019e6bc 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -225,6 +225,7 @@  std::unique_ptr<SwStatsCpu> SoftwareIsp::allocateStatsBuffers(
 
 		fdStats[bufferId] = shared.fd();
 		sharedStats->emplace(bufferId, std::move(shared));
+		availableStats_.push_back(bufferId);
 	}
 
 	auto stats = std::make_unique<SwStatsCpu>(cm, std::move(sharedStats));
@@ -463,7 +464,8 @@  void SoftwareIsp::stop()
  * \param[in] frame The frame number
  * \param[in] input The input framebuffer
  * \param[out] output The framebuffer to write the processed frame to
- * \return 0 on success, -EAGAIN if a parameter buffer underrun occurs
+ * \return 0 on success, -EAGAIN if a parameter or statistics buffer underrun
+ *   occurs
  */
 int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output)
 {
@@ -471,11 +473,16 @@  int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output
 		LOG(SoftwareIsp, Error) << "Parameters buffer underrun";
 		return -EAGAIN;
 	}
+	if (availableStats_.empty()) {
+		LOG(SoftwareIsp, Error) << "Statistics buffer underrun";
+		return -EAGAIN;
+	}
 
 	const uint32_t paramsBufferId = availableParams_.back();
 	availableParams_.pop_back();
+	const uint32_t statsBufferId = availableStats_.back();
+	availableStats_.pop_back();
 	ipa_->computeParams(frame, paramsBufferId);
-	const uint32_t statsBufferId = 0;
 	debayer_->invokeMethod(&Debayer::process,
 			       ConnectionTypeQueued, frame,
 			       statsBufferId, paramsBufferId, input, output);
@@ -498,8 +505,9 @@  void SoftwareIsp::statsReady(uint32_t frame, const uint32_t statsBufferId)
 	ispStatsReady.emit(frame, statsBufferId);
 }
 
-void SoftwareIsp::statsProcessed([[maybe_unused]] const uint32_t statsBufferId)
+void SoftwareIsp::statsProcessed(const uint32_t statsBufferId)
 {
+	availableStats_.push_back(statsBufferId);
 }
 
 void SoftwareIsp::inputReady(FrameBuffer *input)