[RFC,v3,07/17] libcamera: software_isp: Track unused parameters buffers
diff mbox series

Message ID 20260604095105.68798-12-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:50 a.m. UTC
As a preparation for introducing a ring of parameters buffers, this
patch introduces tracking of parameters buffers available for use.

SoftwareIsp::availableParams_ is a vector of ids of the buffers available
for use.  When a fresh parameter 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.

If a parameters buffer is requested but there is no free available, it
is an erroneous situation.  To recover from it, we have currently no
better mechanism than to wait for an available buffer.  Simply returning
from the processing would mean the finishing signals are not called,
resulting in e.g. the input buffer not being returned.  This is
different from the hardware pipelines, which are structured somewhat
differently.

We use 0 as the buffer id for now.  In followup patches, we will have to
make and pass a special id->buffer mapping to the IPA and debayering on
initialisation.

Note that the parameters buffer id is still actually unused and the only
buffer currently used is still copied when passed to debayering.  This
patch is just preparation for followup patches that will introduce
multiple buffers.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 .../internal/software_isp/software_isp.h      |  3 ++-
 src/libcamera/software_isp/software_isp.cpp   | 27 +++++++++++++++----
 2 files changed, 24 insertions(+), 6 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 f97d25f0a..58fb9d752 100644
--- a/include/libcamera/internal/software_isp/software_isp.h
+++ b/include/libcamera/internal/software_isp/software_isp.h
@@ -79,7 +79,7 @@  public:
 	int queueBuffers(uint32_t frame, FrameBuffer *input,
 			 const std::map<const Stream *, FrameBuffer *> &outputs);
 
-	void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output);
+	int process(uint32_t frame, FrameBuffer *input, FrameBuffer *output);
 
 	Signal<FrameBuffer *> inputBufferReady;
 	Signal<FrameBuffer *> outputBufferReady;
@@ -99,6 +99,7 @@  private:
 	Thread ispWorkerThread_;
 	SharedMemObject<DebayerParams> sharedParams_;
 	DebayerParams debayerParams_;
+	std::vector<uint32_t> availableParams_;
 	DmaBufAllocator dmaHeap_;
 	bool ccmEnabled_;
 
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index 774f2bf75..d48cd00ad 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -185,6 +185,9 @@  bool SoftwareIsp::allocateParamsBuffers()
 		return false;
 	}
 
+	/* Just a single buffer for now, let's use 0 as its id. */
+	availableParams_.push_back(0);
+
 	return true;
 }
 
@@ -353,7 +356,12 @@  int SoftwareIsp::queueBuffers(uint32_t frame, FrameBuffer *input,
 	for (const auto &[stream, buffer] : outputs) {
 		queuedInputBuffers_.push_back(input);
 		queuedOutputBuffers_.push_back(buffer);
-		process(frame, input, buffer);
+		int ret = process(frame, input, buffer);
+		if (ret) {
+			queuedInputBuffers_.pop_back();
+			queuedOutputBuffers_.pop_back();
+			return ret;
+		}
 	}
 
 	return 0;
@@ -413,15 +421,23 @@  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
  */
-void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output)
+int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output)
 {
-	/* \todo Provide a real value */
-	constexpr uint32_t paramsBufferId = 0;
+	if (availableParams_.empty()) {
+		LOG(SoftwareIsp, Error) << "Parameters buffer underrun";
+		return -EAGAIN;
+	}
+
+	const uint32_t paramsBufferId = availableParams_.back();
+	availableParams_.pop_back();
 	ipa_->computeParams(frame, paramsBufferId);
 	debayer_->invokeMethod(&Debayer::process,
 			       ConnectionTypeQueued, frame, paramsBufferId,
 			       input, output, debayerParams_);
+
+	return 0;
 }
 
 void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId)
@@ -429,8 +445,9 @@  void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId)
 	debayerParams_ = *sharedParams_;
 }
 
-void SoftwareIsp::paramsBufferReady([[maybe_unused]] const uint32_t paramsBufferId)
+void SoftwareIsp::paramsBufferReady(const uint32_t paramsBufferId)
 {
+	availableParams_.push_back(paramsBufferId);
 }
 
 void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls)