diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 3fe40feb88be7324..f3a7578d0834a9d6 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -726,12 +726,6 @@ int Camera::allocateBuffers()
 		return -EINVAL;
 	}
 
-	int ret = pipe_->allocateBuffers(this, activeStreams_);
-	if (ret) {
-		LOG(Camera, Error) << "Failed to allocate buffers";
-		return ret;
-	}
-
 	state_ = CameraPrepared;
 
 	return 0;
@@ -752,7 +746,7 @@ int Camera::freeBuffers()
 
 	state_ = CameraConfigured;
 
-	return pipe_->freeBuffers(this, activeStreams_);
+	return 0;
 }
 
 /**
diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h
index 27f3852c6c87843f..a6c1e1fbae384405 100644
--- a/src/libcamera/include/pipeline_handler.h
+++ b/src/libcamera/include/pipeline_handler.h
@@ -75,11 +75,6 @@ public:
 	virtual int importFrameBuffers(Camera *camera, Stream *stream) = 0;
 	virtual void freeFrameBuffers(Camera *camera, Stream *stream) = 0;
 
-	virtual int allocateBuffers(Camera *camera,
-				    const std::set<Stream *> &streams) = 0;
-	virtual int freeBuffers(Camera *camera,
-				const std::set<Stream *> &streams) = 0;
-
 	virtual int start(Camera *camera) = 0;
 	virtual void stop(Camera *camera) = 0;
 
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 1ea4d938ad88ae21..7894084a025e9946 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -211,11 +211,6 @@ public:
 	int importFrameBuffers(Camera *camera, Stream *stream) override;
 	void freeFrameBuffers(Camera *camera, Stream *stream) override;
 
-	int allocateBuffers(Camera *camera,
-			    const std::set<Stream *> &streams) override;
-	int freeBuffers(Camera *camera,
-			const std::set<Stream *> &streams) override;
-
 	int start(Camera *camera) override;
 	void stop(Camera *camera) override;
 
@@ -232,6 +227,9 @@ private:
 
 	int registerCameras();
 
+	int allocateBuffers(Camera *camera);
+	int freeBuffers(Camera *camera);
+
 	ImgUDevice imgu0_;
 	ImgUDevice imgu1_;
 	MediaDevice *cio2MediaDev_;
@@ -652,8 +650,7 @@ void PipelineHandlerIPU3::freeFrameBuffers(Camera *camera, Stream *stream)
  * In order to be able to start the 'viewfinder' and 'stat' nodes, we need
  * memory to be reserved.
  */
-int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
-					 const std::set<Stream *> &streams)
+int PipelineHandlerIPU3::allocateBuffers(Camera *camera)
 {
 	IPU3CameraData *data = cameraData(camera);
 	IPU3Stream *outStream = &data->outStream_;
@@ -716,13 +713,12 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 	return 0;
 
 error:
-	freeBuffers(camera, streams);
+	freeBuffers(camera);
 
 	return ret;
 }
 
-int PipelineHandlerIPU3::freeBuffers(Camera *camera,
-				     const std::set<Stream *> &streams)
+int PipelineHandlerIPU3::freeBuffers(Camera *camera)
 {
 	IPU3CameraData *data = cameraData(camera);
 
@@ -739,6 +735,11 @@ int PipelineHandlerIPU3::start(Camera *camera)
 	ImgUDevice *imgu = data->imgu_;
 	int ret;
 
+	/* Allocate buffers for internal pipeline usage. */
+	ret = allocateBuffers(camera);
+	if (ret)
+		return ret;
+
 	/*
 	 * Start the ImgU video devices, buffers will be queued to the
 	 * ImgU output and viewfinder when requests will be queued.
@@ -757,6 +758,7 @@ int PipelineHandlerIPU3::start(Camera *camera)
 	return 0;
 
 error:
+	freeBuffers(camera);
 	LOG(IPU3, Error) << "Failed to start camera " << camera->name();
 
 	return ret;
@@ -772,6 +774,8 @@ void PipelineHandlerIPU3::stop(Camera *camera)
 	if (ret)
 		LOG(IPU3, Warning) << "Failed to stop camera "
 				   << camera->name();
+
+	freeBuffers(camera);
 }
 
 int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index da6e079f51620234..389a99cf52bd1cea 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -178,11 +178,6 @@ public:
 	int importFrameBuffers(Camera *camera, Stream *stream) override;
 	void freeFrameBuffers(Camera *camera, Stream *stream) override;
 
-	int allocateBuffers(Camera *camera,
-		const std::set<Stream *> &streams) override;
-	int freeBuffers(Camera *camera,
-		const std::set<Stream *> &streams) override;
-
 	int start(Camera *camera) override;
 	void stop(Camera *camera) override;
 
@@ -208,6 +203,9 @@ private:
 	void paramReady(FrameBuffer *buffer);
 	void statReady(FrameBuffer *buffer);
 
+	int allocateBuffers(Camera *camera);
+	int freeBuffers(Camera *camera);
+
 	MediaDevice *media_;
 	V4L2Subdevice *dphy_;
 	V4L2Subdevice *isp_;
@@ -675,8 +673,7 @@ void PipelineHandlerRkISP1::freeFrameBuffers(Camera *camera, Stream *stream)
 	video_->releaseBuffers();
 }
 
-int PipelineHandlerRkISP1::allocateBuffers(Camera *camera,
-					   const std::set<Stream *> &streams)
+int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
 {
 	RkISP1CameraData *data = cameraData(camera);
 	unsigned int count = 1;
@@ -720,8 +717,7 @@ error:
 	return ret;
 }
 
-int PipelineHandlerRkISP1::freeBuffers(Camera *camera,
-				       const std::set<Stream *> &streams)
+int PipelineHandlerRkISP1::freeBuffers(Camera *camera)
 {
 	RkISP1CameraData *data = cameraData(camera);
 
@@ -755,10 +751,16 @@ int PipelineHandlerRkISP1::start(Camera *camera)
 	RkISP1CameraData *data = cameraData(camera);
 	int ret;
 
+	/* Allocate buffers for internal pipeline usage. */
+	ret = allocateBuffers(camera);
+	if (ret)
+		return ret;
+
 	data->frame_ = 0;
 
 	ret = param_->streamOn();
 	if (ret) {
+		freeBuffers(camera);
 		LOG(RkISP1, Error)
 			<< "Failed to start parameters " << camera->name();
 		return ret;
@@ -767,6 +769,7 @@ int PipelineHandlerRkISP1::start(Camera *camera)
 	ret = stat_->streamOn();
 	if (ret) {
 		param_->streamOff();
+		freeBuffers(camera);
 		LOG(RkISP1, Error)
 			<< "Failed to start statistics " << camera->name();
 		return ret;
@@ -776,6 +779,7 @@ int PipelineHandlerRkISP1::start(Camera *camera)
 	if (ret) {
 		param_->streamOff();
 		stat_->streamOff();
+		freeBuffers(camera);
 
 		LOG(RkISP1, Error)
 			<< "Failed to start camera " << camera->name();
@@ -820,6 +824,8 @@ void PipelineHandlerRkISP1::stop(Camera *camera)
 
 	data->timeline_.reset();
 
+	freeBuffers(camera);
+
 	activeCamera_ = nullptr;
 }
 
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 67d29b7919e46801..47916ffb453672d4 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -70,11 +70,6 @@ public:
 	int importFrameBuffers(Camera *camera, Stream *stream) override;
 	void freeFrameBuffers(Camera *camera, Stream *stream) override;
 
-	int allocateBuffers(Camera *camera,
-			    const std::set<Stream *> &streams) override;
-	int freeBuffers(Camera *camera,
-			const std::set<Stream *> &streams) override;
-
 	int start(Camera *camera) override;
 	void stop(Camera *camera) override;
 
@@ -222,18 +217,6 @@ void PipelineHandlerUVC::freeFrameBuffers(Camera *camera, Stream *stream)
 	data->video_->releaseBuffers();
 }
 
-int PipelineHandlerUVC::allocateBuffers(Camera *camera,
-					const std::set<Stream *> &streams)
-{
-	return 0;
-}
-
-int PipelineHandlerUVC::freeBuffers(Camera *camera,
-				    const std::set<Stream *> &streams)
-{
-	return 0;
-}
-
 int PipelineHandlerUVC::start(Camera *camera)
 {
 	UVCCameraData *data = cameraData(camera);
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 4cfdb5ae79ce5779..1700ac967299b106 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -87,11 +87,6 @@ public:
 	int importFrameBuffers(Camera *camera, Stream *stream) override;
 	void freeFrameBuffers(Camera *camera, Stream *stream) override;
 
-	int allocateBuffers(Camera *camera,
-			    const std::set<Stream *> &streams) override;
-	int freeBuffers(Camera *camera,
-			const std::set<Stream *> &streams) override;
-
 	int start(Camera *camera) override;
 	void stop(Camera *camera) override;
 
@@ -288,18 +283,6 @@ void PipelineHandlerVimc::freeFrameBuffers(Camera *camera, Stream *stream)
 	data->video_->releaseBuffers();
 }
 
-int PipelineHandlerVimc::allocateBuffers(Camera *camera,
-					 const std::set<Stream *> &streams)
-{
-	return 0;
-}
-
-int PipelineHandlerVimc::freeBuffers(Camera *camera,
-				     const std::set<Stream *> &streams)
-{
-	return 0;
-}
-
 int PipelineHandlerVimc::start(Camera *camera)
 {
 	VimcCameraData *data = cameraData(camera);
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 0348e3cfa68ed6ec..2fd65b468b9cd84f 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -356,35 +356,6 @@ const ControlInfoMap &PipelineHandler::controls(Camera *camera)
  * helper.
  */
 
-/**
- * \fn PipelineHandler::allocateBuffers()
- * \brief Allocate buffers for a stream
- * \param[in] camera The camera the \a stream belongs to
- * \param[in] streams The set of streams to allocate buffers for
- *
- * This method allocates buffers internally in the pipeline handler for each
- * stream in the \a streams buffer set, and associates them with the stream's
- * buffer pool.
- *
- * The intended caller of this method is the Camera class.
- *
- * \return 0 on success or a negative error code otherwise
- */
-
-/**
- * \fn PipelineHandler::freeBuffers()
- * \brief Free all buffers associated with a stream
- * \param[in] camera The camera the \a stream belongs to
- * \param[in] streams The set of streams to free buffers from
- *
- * After a capture session has been stopped all buffers associated with each
- * stream shall be freed.
- *
- * The intended caller of this method is the Camera class.
- *
- * \return 0 on success or a negative error code otherwise
- */
-
 /**
  * \fn PipelineHandler::start()
  * \brief Start capturing from a group of streams
