diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h
index f05f201f7ca824eb..d4473bf173b815af 100644
--- a/src/libcamera/include/pipeline_handler.h
+++ b/src/libcamera/include/pipeline_handler.h
@@ -17,12 +17,15 @@ namespace libcamera {
 
 class CameraManager;
 class DeviceEnumerator;
+class Stream;
 
 class PipelineHandler
 {
 public:
 	virtual ~PipelineHandler() { };
 
+	virtual std::vector<Stream> streams(const Camera *camera) const = 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 c6106c538f071058..f73479125ed5e21d 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -10,6 +10,7 @@
 
 #include <libcamera/camera.h>
 #include <libcamera/camera_manager.h>
+#include <libcamera/stream.h>
 
 #include "device_enumerator.h"
 #include "log.h"
@@ -26,6 +27,8 @@ public:
 	PipelineHandlerIPU3();
 	~PipelineHandlerIPU3();
 
+	std::vector<Stream> streams(const Camera *camera) const;
+
 	bool match(CameraManager *manager, DeviceEnumerator *enumerator);
 
 private:
@@ -35,6 +38,8 @@ private:
 	std::vector<std::shared_ptr<Camera>> cameras_;
 
 	void registerCameras(CameraManager *manager);
+
+	bool handleCamera(const Camera *camera) const;
 };
 
 PipelineHandlerIPU3::PipelineHandlerIPU3()
@@ -59,6 +64,16 @@ PipelineHandlerIPU3::~PipelineHandlerIPU3()
 	imgu_ = nullptr;
 }
 
+std::vector<Stream> PipelineHandlerIPU3::streams(const Camera *camera) const
+{
+	std::vector<Stream> streams;
+
+	if (handleCamera(camera))
+		streams.push_back(Stream(0));
+
+	return streams;
+}
+
 bool PipelineHandlerIPU3::match(CameraManager *manager, DeviceEnumerator *enumerator)
 {
 	DeviceMatch cio2_dm("ipu3-cio2");
@@ -192,6 +207,18 @@ void PipelineHandlerIPU3::registerCameras(CameraManager *manager)
 	}
 }
 
+bool PipelineHandlerIPU3::handleCamera(const Camera *camera) const
+{
+	if (!camera)
+		return false;
+
+	for (const std::shared_ptr<Camera> &cam : cameras_)
+		if (camera == cam.get())
+			return true;
+
+	return false;
+}
+
 REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3);
 
 } /* namespace libcamera */
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 3e4745ba498e7160..87b556ba0ae17696 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -7,6 +7,7 @@
 
 #include <libcamera/camera.h>
 #include <libcamera/camera_manager.h>
+#include <libcamera/stream.h>
 
 #include "device_enumerator.h"
 #include "log.h"
@@ -23,6 +24,8 @@ public:
 	PipelineHandlerUVC();
 	~PipelineHandlerUVC();
 
+	std::vector<Stream> streams(const Camera *camera) const;
+
 	bool match(CameraManager *manager, DeviceEnumerator *enumerator);
 
 private:
@@ -46,6 +49,16 @@ PipelineHandlerUVC::~PipelineHandlerUVC()
 		dev_->release();
 }
 
+std::vector<Stream> PipelineHandlerUVC::streams(const Camera *camera) const
+{
+	std::vector<Stream> streams;
+
+	if (camera && camera == camera_.get())
+		streams.push_back(Stream(0));
+
+	return streams;
+}
+
 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 e8dbc0932ab0198a..e894367ba6706aaf 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -7,6 +7,7 @@
 
 #include <libcamera/camera.h>
 #include <libcamera/camera_manager.h>
+#include <libcamera/stream.h>
 
 #include "device_enumerator.h"
 #include "log.h"
@@ -23,6 +24,8 @@ public:
 	PipeHandlerVimc();
 	~PipeHandlerVimc();
 
+	std::vector<Stream> streams(const Camera *camera) const;
+
 	bool match(CameraManager *manager, DeviceEnumerator *enumerator);
 
 private:
@@ -46,6 +49,16 @@ PipeHandlerVimc::~PipeHandlerVimc()
 		dev_->release();
 }
 
+std::vector<Stream> PipeHandlerVimc::streams(const Camera *camera) const
+{
+	std::vector<Stream> streams;
+
+	if (camera && camera == camera_.get())
+		streams.push_back(Stream(0));
+
+	return streams;
+}
+
 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 c24feeafc503e9b1..c2bed924dece0ac0 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -34,6 +34,18 @@ LOG_DEFINE_CATEGORY(Pipeline)
  * with the pipelines it supports and creates corresponding Camera devices.
  */
 
+/**
+ * \fn PipelineHandler::streams(const Camera *camera)
+ * \brief Retrive a array of all streams the camera provides
+ * \param[in] camera The camera to retrieve streams from
+ *
+ * This function is the interface to extract information about streams from a
+ * PipelineHandler.
+ *
+ * \return A array of streams from the camera or a empty list if \a camera
+ *         is not part of the PipelineHandler.
+ */
+
 /**
  * \fn PipelineHandler::match(DeviceEnumerator *enumerator)
  * \brief Match media devices and create camera instances
