diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom
index 4c29b53cd7f9..56c9fe8ab92a 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 b714e2f10c65..a887214c63a9 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -56,7 +56,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,
@@ -77,6 +78,8 @@ protected:
 	std::string logPrefix() const override;
 
 private:
+	uint32_t computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId);
+
 	void updateControls(const IPACameraSensorInfo &sensorInfo,
 			    const ControlInfoMap &sensorControls,
 			    ControlInfoMap *ipaControls);
@@ -216,10 +219,12 @@ 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 = {};
 	initializeFrameContext(0, frameContext, controls);
+	result->paramBufferBytesUsed = computeParamsInternal(frameContext, paramBufferId);
 	result->controls = getSensorControls(frameContext);
 	result->code = 0;
 }
@@ -373,6 +378,19 @@ void IPARkISP1::initializeFrameContext(const uint32_t frame,
 	controlsToApply_.clear();
 }
 
+uint32_t IPARkISP1::computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId)
+{
+	ASSERT(bufferId);
+
+	RkISP1Params params(context_.configuration.paramFormat,
+			    mappedBuffers_.at(bufferId).planes()[0]);
+
+	for (auto const &algo : algorithms())
+		algo->prepare(context_, frameContext.frame(), frameContext, &params);
+
+	return params.size();
+}
+
 void IPARkISP1::computeParams(const uint32_t frame, const uint32_t bufferId)
 {
 	IPAFrameContext &frameContext = context_.frameContexts.get(frame);
@@ -390,16 +408,11 @@ void IPARkISP1::computeParams(const uint32_t frame, const uint32_t bufferId)
 		return;
 	}
 
-	RkISP1Params params(context_.configuration.paramFormat,
-			    mappedBuffers_.at(bufferId).planes()[0]);
-
-	for (auto const &algo : algorithms())
-		algo->prepare(context_, frame, frameContext, &params);
-
+	uint32_t size = computeParamsInternal(frameContext, bufferId);
 	ControlList ctrls = getSensorControls(frameContext);
 	setSensorControls.emit(frame, ctrls);
 
-	paramsComputed.emit(frame, params.size());
+	paramsComputed.emit(frame, size);
 }
 
 void IPARkISP1::processStats(const uint32_t frame, const uint32_t bufferId,
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 2d78721be63a..1e39acc5cc37 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -110,8 +110,8 @@ public:
 	bool canUseDewarper_;
 	bool usesDewarper_;
 
-private:
 	void paramsComputed(unsigned int frame, unsigned int bytesused);
+private:
 	void setSensorControls(unsigned int frame,
 			       const ControlList &sensorControls);
 
@@ -1251,23 +1251,38 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
 	if (!!controls)
 		ctrls = *controls;
 
+	data->frame_ = 0;
+	nextParamsSequence_ = 0;
+	nextStatsToProcess_ = 0;
+	paramsSyncHelper_.reset();
+	imageSyncHelper_.reset();
+
+	uint32_t paramBufferId = 0;
+	FrameBuffer *paramBuffer = nullptr;
+	if (!isRaw_) {
+		paramBuffer = availableParamBuffers_.front();
+		paramBufferId = paramBuffer->cookie();
+	}
+
 	ipa::rkisp1::StartResult res;
-	data->ipa_->start(ctrls, &res);
+	data->ipa_->start(ctrls, 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, res.paramBufferBytesUsed);
+	}
+
 	actions += [&]() { data->ipa_->stop(); };
 	data->sensor_->setControls(&res.controls);
 	data->delayedCtrls_->reset();
 
-	data->frame_ = 0;
-	nextParamsSequence_ = 0;
-	nextStatsToProcess_ = 0;
-	paramsSyncHelper_.reset();
-	imageSyncHelper_.reset();
-
 	if (!isRaw_) {
 		ret = param_->streamOn();
 		if (ret) {
