diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom
index 04230d0f852e..6571a6d096f0 100644
--- a/include/libcamera/ipa/rkisp1.mojom
+++ b/include/libcamera/ipa/rkisp1.mojom
@@ -17,6 +17,7 @@ struct IPAConfigInfo {
 struct StartResult {
 	libcamera.ControlList controls;
 	int32 code;
+	uint32 paramBufferBytesUsed;
 };
 
 interface IPARkISP1Interface {
@@ -25,7 +26,9 @@ interface IPARkISP1Interface {
 	     libcamera.IPACameraSensorInfo sensorInfo,
 	     libcamera.ControlInfoMap sensorControls)
 		=> (int32 ret, libcamera.ControlInfoMap ipaControls);
-	start(libcamera.ControlList controls) => (StartResult result);
+	start(libcamera.ControlList controls,
+	      uint32 paramBufferId)
+		=> (StartResult result);
 	stop();
 
 	configure(IPAConfigInfo configInfo,
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 3a65dab75cb7..b8b4a79830c8 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -54,7 +54,8 @@ public:
 		 const IPACameraSensorInfo &sensorInfo,
 		 const ControlInfoMap &sensorControls,
 		 ControlInfoMap *ipaControls) override;
-	void start(const ControlList &controls, StartResult *result) override;
+	void start(const ControlList &controls, const uint32_t paramBufferId,
+		   StartResult *result) override;
 	void stop() override;
 
 	int configure(const IPAConfigInfo &ipaConfig,
@@ -74,6 +75,8 @@ protected:
 	std::string logPrefix() const override;
 
 private:
+	uint32_t computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId);
+
 	void updateControls(ControlInfoMap *ipaControls);
 	ControlList getSensorControls(const IPAFrameContext &context);
 
@@ -210,9 +213,17 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
 	return 0;
 }
 
-void IPARkISP1::start(const ControlList &controls, StartResult *result)
+void IPARkISP1::start(const ControlList &controls, const uint32_t paramBufferId,
+		      StartResult *result)
 {
 	IPAFrameContext &frameContext = context_.frameContexts.getOrInitContext(0, controls);
+
+	if (paramBufferId != 0)
+		result->paramBufferBytesUsed = computeParamsInternal(frameContext,
+								     paramBufferId);
+	else
+		result->paramBufferBytesUsed = 0;
+
 	result->controls = getSensorControls(frameContext);
 	result->code = 0;
 }
@@ -312,18 +323,24 @@ void IPARkISP1::initializeFrameContext(IPAFrameContext &fc, const ControlList &c
 	}
 }
 
+uint32_t IPARkISP1::computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId)
+{
+	RkISP1Params params(context_.configuration.paramFormat,
+			    mappedBuffers_.at(bufferId).planes()[0]);
+
+	for (const auto &algo : algorithms())
+		algo->prepare(context_, frameContext.frame(), frameContext, &params);
+
+	return params.bytesused();
+}
+
 void IPARkISP1::computeParams(const uint32_t frame, const uint32_t bufferId)
 {
 	IPAFrameContext &frameContext = context_.frameContexts.getOrInitContext(frame);
 
 	if (bufferId != 0) {
-		RkISP1Params params(context_.configuration.paramFormat,
-				    mappedBuffers_.at(bufferId).planes()[0]);
-
-		for (const auto &algo : algorithms())
-			algo->prepare(context_, frame, frameContext, &params);
-
-		paramsComputed.emit(frame, bufferId, params.bytesused());
+		uint32_t size = computeParamsInternal(frameContext, bufferId);
+		paramsComputed.emit(frame, bufferId, size);
 	}
 
 	ControlList ctrls = getSensorControls(frameContext);
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 832f58e95d37..b051dd21fb4c 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -104,8 +104,8 @@ public:
 	bool canUseDewarper_;
 	bool usesDewarper_;
 
-private:
 	void paramsComputed(unsigned int frame, unsigned int bufferId, unsigned int bytesused);
+private:
 	void setSensorControls(unsigned int frame,
 			       const ControlList &sensorControls);
 
@@ -1200,14 +1200,30 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
 	nextStatsToProcess_ = 0;
 	data->frame_ = 0;
 
+	uint32_t paramBufferId = 0;
+	FrameBuffer *paramBuffer = nullptr;
+	if (!isRaw_) {
+		paramBuffer = availableParamBuffers_.front();
+		paramBufferId = paramBuffer->cookie();
+	}
+
 	ipa::rkisp1::StartResult res;
 	data->ipa_->start(controls ? *controls : ControlList{ controls::controls },
+			  paramBufferId,
 			  &res);
 	if (res.code) {
 		LOG(RkISP1, Error)
 			<< "Failed to start IPA " << camera->id();
 		return ret;
 	}
+
+	if (paramBuffer) {
+		availableParamBuffers_.pop();
+		computingParamBuffers_.push({ paramBuffer, nextParamsSequence_++ });
+		paramsSyncHelper_.pushCorrection(0);
+		data->paramsComputed(0, paramBufferId, res.paramBufferBytesUsed);
+	}
+
 	actions += [&]() { data->ipa_->stop(); };
 	data->sensor_->setControls(&res.controls);
 	data->delayedCtrls_->reset();
