diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h
index dc6b6f7c1..a8b7b1eb1 100644
--- a/include/libcamera/internal/software_isp/software_isp.h
+++ b/include/libcamera/internal/software_isp/software_isp.h
@@ -11,6 +11,7 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <queue>
 #include <stdint.h>
 #include <string>
 #include <tuple>
@@ -98,6 +99,7 @@ private:
 	Thread ispWorkerThread_;
 	SharedMemObject<DebayerParams> sharedParams_;
 	DebayerParams debayerParams_;
+	std::queue<uint32_t> availableParams_;
 	bool allocateParamsBuffers();
 	DmaBufAllocator dmaHeap_;
 	bool ccmEnabled_;
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index dc0a8eb84..adf2a03ab 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -180,6 +180,10 @@ bool SoftwareIsp::allocateParamsBuffers()
 		return false;
 	}
 
+	ASSERT(sharedParams_.fd().get() >= 0);
+	const uint32_t bufferId = sharedParams_.fd().get();
+	availableParams_.push(bufferId);
+
 	return true;
 }
 
@@ -404,8 +408,15 @@ void SoftwareIsp::stop()
  */
 void 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";
+		/* Well, busy loop, but this situation shouldn't normally happen. */
+		while (availableParams_.empty())
+			;
+	}
+
+	const uint32_t paramsBufferId = availableParams_.front();
+	availableParams_.pop();
 	ipa_->computeParams(frame, paramsBufferId);
 	debayer_->invokeMethod(&Debayer::process,
 			       ConnectionTypeQueued, frame, paramsBufferId, input, output, debayerParams_);
@@ -416,8 +427,9 @@ void SoftwareIsp::saveIspParams([[maybe_unused]] uint32_t paramsBufferId)
 	debayerParams_ = *sharedParams_;
 }
 
-void SoftwareIsp::releaseIspParams([[maybe_unused]] uint32_t paramsBufferId)
+void SoftwareIsp::releaseIspParams(uint32_t paramsBufferId)
 {
+	availableParams_.push(paramsBufferId);
 }
 
 void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls)
