diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom
index 1498aedf..86dd988f 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.ControlInfoMap sensorCtrlInfoMap)
 		=> (int32 ret);
 	start() => (int32 ret);
diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp
index 9d5fe923..50f8f194 100644
--- a/src/ipa/simple/soft_simple.cpp
+++ b/src/ipa/simple/soft_simple.cpp
@@ -48,7 +48,7 @@ public:
 
 	int init(const IPASettings &settings,
 		 const SharedFD &fdStats,
-		 const SharedFD &fdParams,
+		 const std::vector<SharedFD> &fdParams,
 		 const ControlInfoMap &sensorInfoMap) override;
 	int configure(const IPAConfigInfo &configInfo) override;
 
@@ -66,7 +66,7 @@ protected:
 private:
 	void updateExposure(double exposureMSV);
 
-	DebayerParams *params_;
+	std::map<unsigned int, DebayerParams *> paramsBuffers_;
 	SwIspStats *stats_;
 	std::unique_ptr<CameraSensorHelper> camHelper_;
 	ControlInfoMap sensorInfoMap_;
@@ -79,13 +79,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 ControlInfoMap &sensorInfoMap)
 {
 	camHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel);
@@ -122,7 +122,6 @@ int IPASoftSimple::init(const IPASettings &settings,
 	if (ret)
 		return ret;
 
-	params_ = nullptr;
 	stats_ = nullptr;
 
 	if (!fdStats.isValid()) {
@@ -130,20 +129,21 @@ 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);
+		ASSERT(sharedFd.get() >= 0);
+		paramsBuffers_[sharedFd.get()] = static_cast<DebayerParams *>(mem);
 	}
 
 	{
@@ -258,8 +258,9 @@ void IPASoftSimple::prepare(const uint32_t frame,
 			    const uint32_t paramsBufferId)
 {
 	IPAFrameContext &frameContext = context_.frameContexts.get(frame);
+	DebayerParams *params = paramsBuffers_.at(paramsBufferId);
 	for (auto const &algo : algorithms())
-		algo->prepare(context_, frame, frameContext, params_);
+		algo->prepare(context_, frame, frameContext, params);
 	setIspParams.emit(paramsBufferId);
 }
 
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index d48be2d2..480ecf6e 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -13,6 +13,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <libcamera/base/shared_fd.h>
+
 #include <libcamera/formats.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
@@ -85,6 +87,9 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
 	stats->statsReady.connect(this, &SoftwareIsp::statsReady);
 
 	debayer_ = std::make_unique<DebayerCpu>(std::move(stats));
+	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);
@@ -106,7 +111,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
 
 	int ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() },
 			     debayer_->getStatsFD(),
-			     sharedParams_.begin()->second.fd(),
+			     fdParams,
 			     sensor->controls());
 	if (ret) {
 		LOG(SoftwareIsp, Error) << "IPA init failed";
@@ -380,13 +385,14 @@ void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *outpu
 	const uint32_t paramsBufferId = availableParams_.front();
 	availableParams_.pop();
 	ipa_->prepare(frame, paramsBufferId);
+	debayerParams_ = *sharedParams_.at(paramsBufferId);
 	debayer_->invokeMethod(&DebayerCpu::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)
