diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
index d030e254a552..605ea8136900 100644
--- a/include/libcamera/internal/camera_sensor.h
+++ b/include/libcamera/internal/camera_sensor.h
@@ -53,7 +53,7 @@ public:
 
 	virtual V4L2SubdeviceFormat
 	getFormat(const std::vector<unsigned int> &mbusCodes,
-		  const Size &size) const = 0;
+		  const Size &size, const Size maxSize = Size()) const = 0;
 	virtual int setFormat(V4L2SubdeviceFormat *format,
 			      Transform transform = Transform::Identity) = 0;
 	virtual int tryFormat(V4L2SubdeviceFormat *format) const = 0;
diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp
index 208a1603cb32..a131ac224ec0 100644
--- a/src/libcamera/sensor/camera_sensor.cpp
+++ b/src/libcamera/sensor/camera_sensor.cpp
@@ -116,6 +116,7 @@ CameraSensor::~CameraSensor() = default;
  * \brief Retrieve the best sensor format for a desired output
  * \param[in] mbusCodes The list of acceptable media bus codes
  * \param[in] size The desired size
+ * \param[in] maxSize The maximum size
  *
  * Media bus codes are selected from \a mbusCodes, which lists all acceptable
  * codes in decreasing order of preference. Media bus codes supported by the
@@ -134,6 +135,8 @@ CameraSensor::~CameraSensor() = default;
  *   bandwidth.
  * - The desired \a size shall be supported by one of the media bus code listed
  *   in \a mbusCodes.
+ * - The desired \a size shall fit into the maximum size \a maxSize if it is not
+ *   null.
  *
  * When multiple media bus codes can produce the same size, the code at the
  * lowest position in \a mbusCodes is selected.
diff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp
index 17d6fa680e39..32989c19c019 100644
--- a/src/libcamera/sensor/camera_sensor_legacy.cpp
+++ b/src/libcamera/sensor/camera_sensor_legacy.cpp
@@ -74,7 +74,8 @@ public:
 	Size resolution() const override;
 
 	V4L2SubdeviceFormat getFormat(const std::vector<unsigned int> &mbusCodes,
-				      const Size &size) const override;
+				      const Size &size,
+				      const Size maxSize) const override;
 	int setFormat(V4L2SubdeviceFormat *format,
 		      Transform transform = Transform::Identity) override;
 	int tryFormat(V4L2SubdeviceFormat *format) const override;
@@ -699,7 +700,7 @@ Size CameraSensorLegacy::resolution() const
 
 V4L2SubdeviceFormat
 CameraSensorLegacy::getFormat(const std::vector<unsigned int> &mbusCodes,
-			      const Size &size) const
+			      const Size &size, Size maxSize) const
 {
 	unsigned int desiredArea = size.width * size.height;
 	unsigned int bestArea = UINT_MAX;
@@ -716,6 +717,10 @@ CameraSensorLegacy::getFormat(const std::vector<unsigned int> &mbusCodes,
 		for (const SizeRange &range : formats->second) {
 			const Size &sz = range.max;
 
+			if (!maxSize.isNull() &&
+			    (sz.width > maxSize.width || sz.height > maxSize.height))
+				continue;
+
 			if (sz.width < size.width || sz.height < size.height)
 				continue;
 
