diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h
index d4473bf173b815af..751eb4e1bb4bf69b 100644
--- a/src/libcamera/include/pipeline_handler.h
+++ b/src/libcamera/include/pipeline_handler.h
@@ -18,6 +18,7 @@ namespace libcamera {
 class CameraManager;
 class DeviceEnumerator;
 class Stream;
+class StreamConfiguration;
 
 class PipelineHandler
 {
@@ -26,6 +27,8 @@ public:
 
 	virtual std::vector<Stream> streams(const Camera *camera) const = 0;
 
+	virtual int configure(const Camera *camera, std::vector<StreamConfiguration *> &config) = 0;
+
 	virtual bool match(CameraManager *manager, DeviceEnumerator *enumerator) = 0;
 };
 
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index f73479125ed5e21d..5252fab226a1da71 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -29,6 +29,8 @@ public:
 
 	std::vector<Stream> streams(const Camera *camera) const;
 
+	int configure(const Camera *camera, std::vector<StreamConfiguration *> &config);
+
 	bool match(CameraManager *manager, DeviceEnumerator *enumerator);
 
 private:
@@ -74,6 +76,28 @@ std::vector<Stream> PipelineHandlerIPU3::streams(const Camera *camera) const
 	return streams;
 }
 
+int PipelineHandlerIPU3::configure(const Camera *camera,
+				   std::vector<StreamConfiguration *> &config)
+{
+	StreamConfiguration *cfg;
+
+	if (!handleCamera(camera))
+		return -EINVAL;
+
+	if (config.size() != 1)
+		return -EINVAL;
+
+	cfg = config.front();
+
+	if (!cfg || cfg->id() != 0)
+		return -EINVAL;
+
+	LOG(IPU3, Info) << "TODO: Configure the camera for resolution " <<
+		cfg->width() << "x" << cfg->height();
+
+	return 0;
+}
+
 bool PipelineHandlerIPU3::match(CameraManager *manager, DeviceEnumerator *enumerator)
 {
 	DeviceMatch cio2_dm("ipu3-cio2");
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 87b556ba0ae17696..dd494d2599bef813 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -26,6 +26,8 @@ public:
 
 	std::vector<Stream> streams(const Camera *camera) const;
 
+	int configure(const Camera *camera, std::vector<StreamConfiguration *> &config);
+
 	bool match(CameraManager *manager, DeviceEnumerator *enumerator);
 
 private:
@@ -59,6 +61,28 @@ std::vector<Stream> PipelineHandlerUVC::streams(const Camera *camera) const
 	return streams;
 }
 
+int PipelineHandlerUVC::configure(const Camera *camera,
+				  std::vector<StreamConfiguration *> &config)
+{
+	StreamConfiguration *cfg;
+
+	if (!camera || camera != camera_.get())
+		return -EINVAL;
+
+	if (config.size() != 1)
+		return -EINVAL;
+
+	cfg = config.front();
+
+	if (!cfg || cfg->id() != 0)
+		return -EINVAL;
+
+	LOG(UVC, Info) << "TODO: Configure the camera for resolution " <<
+		cfg->width() << "x" << cfg->height();
+
+	return 0;
+}
+
 bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumerator)
 {
 	DeviceMatch dm("uvcvideo");
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index e894367ba6706aaf..31b08a766cb32702 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -26,6 +26,8 @@ public:
 
 	std::vector<Stream> streams(const Camera *camera) const;
 
+	int configure(const Camera *camera, std::vector<StreamConfiguration *> &config);
+
 	bool match(CameraManager *manager, DeviceEnumerator *enumerator);
 
 private:
@@ -59,6 +61,28 @@ std::vector<Stream> PipeHandlerVimc::streams(const Camera *camera) const
 	return streams;
 }
 
+int PipeHandlerVimc::configure(const Camera *camera,
+			       std::vector<StreamConfiguration *> &config)
+{
+	StreamConfiguration *cfg;
+
+	if (!camera || camera != camera_.get())
+		return -EINVAL;
+
+	if (config.size() != 1)
+		return -EINVAL;
+
+	cfg = config.front();
+
+	if (!cfg || cfg->id() != 0)
+		return -EINVAL;
+
+	LOG(VIMC, Info) << "TODO: Configure the camera for resolution " <<
+		cfg->width() << "x" << cfg->height();
+
+	return 0;
+}
+
 bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator)
 {
 	DeviceMatch dm("vimc");
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index c2bed924dece0ac0..533ee64d6ce318c4 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -46,6 +46,24 @@ LOG_DEFINE_CATEGORY(Pipeline)
  *         is not part of the PipelineHandler.
  */
 
+/**
+ * \fn PipelineHandler::configure(const Camera *camera, std::vector<StreamConfiguration *> &config)
+ * \brief Configure a set of streams for a camera
+ * \param[in] camera The camera to configure streams for
+ * \param[in] config A array of stream configurations to try and setup
+ *
+ * This function is the interface to configure one or more streams of a camera
+ * for capture. The intended user for this interface is the Camera class which
+ * will receive the array of configurations to apply from the application.
+ *
+ * The caller needs to verify the StreamConfiguration objects in the passed
+ * array after the call as it might remove one or more to satisfy hardware
+ * limitations. The call might also alter any or all of the configuration
+ * parameters of any stream to fit within valid operational conditions.
+ *
+ * \return 0 on success or a negative error code on error.
+ */
+
 /**
  * \fn PipelineHandler::match(DeviceEnumerator *enumerator)
  * \brief Match media devices and create camera instances
