diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h
index 970c479627fab064..adcf20d336347dad 100644
--- a/include/libcamera/stream.h
+++ b/include/libcamera/stream.h
@@ -21,9 +21,50 @@ struct StreamConfiguration {
 	unsigned int bufferCount;
 };
 
+class StreamRole
+{
+public:
+	enum Role {
+		StillCapture,
+		VideoRecording,
+		Viewfinder,
+	};
+
+	Role role() const { return role_; }
+	int width() const { return width_; }
+	int height() const { return height_; }
+
+protected:
+	StreamRole(Role role);
+	StreamRole(Role role, int width, int height);
+
+private:
+	Role role_;
+	int width_;
+	int height_;
+};
+
 class Stream final
 {
 public:
+	class StillCapture : public StreamRole
+	{
+	public:
+		StillCapture();
+	};
+
+	class VideoRecording : public StreamRole
+	{
+	public:
+		VideoRecording();
+	};
+
+	class Viewfinder : public StreamRole
+	{
+	public:
+		Viewfinder(int width, int height);
+	};
+
 	Stream();
 	BufferPool &bufferPool() { return bufferPool_; }
 	const StreamConfiguration &configuration() const { return configuration_; }
diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp
index c4943c91b2e6ce13..f4be5d265e872842 100644
--- a/src/libcamera/stream.cpp
+++ b/src/libcamera/stream.cpp
@@ -60,6 +60,61 @@ namespace libcamera {
  * \brief Requested number of buffers to allocate for the stream
  */
 
+/**
+ * \class StreamRole
+ * \brief Stream role information
+ *
+ * The StreamRole class carries information about stream usage hints from the
+ * application to the camera. The camera shall take the usage hints into account
+ * when select which stream to use for the desired operation.
+ */
+
+/**
+ * \enum StreamRole::Role
+ * \brief List of different stream roles
+ */
+
+/**
+ * \fn StreamRole::role()
+ * \brief Retrieve the stream role
+ *
+ * \return The stream role hint
+ */
+
+/**
+ * \fn StreamRole::width()
+ * \brief Retrieve desired width
+ *
+ * \return The desired width if defined, -1 otherwise
+ */
+
+/**
+ * \fn StreamRole::height()
+ * \brief Retrieve desired height
+ *
+ * \return The desired height if defined, -1 otherwise
+ */
+
+/**
+ * \brief Create a stream role
+ * \param[in] role Stream role hint
+ */
+StreamRole::StreamRole(Role role)
+	: role_(role), width_(-1), height_(-1)
+{
+}
+
+/**
+ * \brief Create a stream role with dimension hints
+ * \param[in] role Stream role hint
+ * \param[in] width Desired width
+ * \param[in] height Desired height
+ */
+StreamRole::StreamRole(Role role, int width, int height)
+	: role_(role), width_(width), height_(height)
+{
+}
+
 /**
  * \class Stream
  * \brief Video stream for a camera
@@ -78,6 +133,39 @@ namespace libcamera {
  * optimal stream for the task.
  */
 
+/**
+ * \class Stream::StillCapture
+ * \brief Describes a still capture role
+ */
+Stream::StillCapture::StillCapture()
+	: StreamRole(Role::StillCapture)
+{
+}
+
+/**
+ * \class Stream::VideoRecording
+ * \brief Describes a video recording role
+ */
+Stream::VideoRecording::VideoRecording()
+	: StreamRole(Role::VideoRecording)
+{
+}
+
+/**
+ * \class Stream::Viewfinder
+ * \brief Describes a viewfinder role
+ */
+
+/**
+ * \brief Create a viewfinder role with dimension hints
+ * \param[in] width Desired viewfinder width
+ * \param[in] height Desired viewfinder height
+ */
+Stream::Viewfinder::Viewfinder(int width, int height)
+	: StreamRole(Role::Viewfinder, width, height)
+{
+}
+
 /**
  * \brief Construct a stream with default parameters
  */
