From a18c9f04906d8a6bc3f2887687fee344b2316cab Mon Sep 17 00:00:00 2001
From: Umang Jain <umang.jain@ideasonboard.com>
Date: Tue, 10 Aug 2021 13:28:51 +0530
Subject: libcamera: camera_sensor: Transform CameraSensor::sizes()

In CameraSensor, the mbusCodes() and sizes() accessor functions
retrieves all the supported media bus codes and the supported sizes
respectively. However, this is quite limiting since the caller
probably isn't in a position to match which range of sizes are
supported for a particular mbusCode.

Hence, the caller is most likely interested to know about the sizes
supported for a particular media bus code. This patch transforms the
existing CameraSensor::sizes() to CameraSensor::sizes(mbuscode) to
achieve that goal.

The patch also transforms existing CIO2Device::sizes() in IPU3 pipeline
handler to CIO2Device::sizes(PixelFormat) on a similar principle. The
function is then plumbed to CameraSensor::sizes(mbusCode) to enumerate
the per-format sizes as required in
PipelineHandlerIPU3::generateConfiguration().

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/libcamera/camera_sensor.cpp      | 25 +++++++++++++++++++------
 src/libcamera/pipeline/ipu3/cio2.cpp | 27 +++++++++++++++++++++++----
 src/libcamera/pipeline/ipu3/cio2.h   |  2 +-
 src/libcamera/pipeline/ipu3/ipu3.cpp |  2 +-
 4 files changed, 44 insertions(+), 12 deletions(-)

(limited to 'src')

diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 7a386415..87668509 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -472,14 +472,27 @@ int CameraSensor::initProperties()
  */
 
 /**
- * \fn CameraSensor::sizes()
- * \brief Retrieve the frame sizes supported by the camera sensor
+ * \brief Retrieve the supported frame sizes for a media bus code
+ * \param[in] mbusCode The media bus code for which sizes are requested
  *
- * The reported sizes span all media bus codes supported by the camera sensor.
- * Not all sizes may be supported by all media bus codes.
- *
- * \return The supported frame sizes sorted in increasing order
+ * \return The supported frame sizes for \a mbusCode sorted in increasing order
  */
+const std::vector<Size> CameraSensor::sizes(unsigned int mbusCode) const
+{
+	std::vector<Size> sizes;
+
+	const auto &format = formats_.find(mbusCode);
+	if (format == formats_.end())
+		return sizes;
+
+	const std::vector<SizeRange> &ranges = format->second;
+	std::transform(ranges.begin(), ranges.end(), std::back_inserter(sizes),
+		       [](const SizeRange &range) { return range.max; });
+
+	std::sort(sizes.begin(), sizes.end());
+
+	return sizes;
+}
 
 /**
  * \brief Retrieve the camera sensor resolution
diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp
index 1bcd580e..07025b09 100644
--- a/src/libcamera/pipeline/ipu3/cio2.cpp
+++ b/src/libcamera/pipeline/ipu3/cio2.cpp
@@ -62,16 +62,35 @@ std::vector<PixelFormat> CIO2Device::formats() const
 
 /**
  * \brief Retrieve the list of supported size ranges
- * \return The list of supported SizeRange
+ * \param[in] format The pixel format
+ *
+ * Retrieve the list of supported sizes for a particular \a format by matching
+ * the sensor produced media bus codes formats supported by the CIO2 unit.
+ *
+ * \return A list of supported sizes for the \a format or an empty list
+ * otherwise
  */
-std::vector<SizeRange> CIO2Device::sizes() const
+std::vector<SizeRange> CIO2Device::sizes(const PixelFormat &format) const
 {
+	int mbusCode = -1;
+
 	if (!sensor_)
 		return {};
 
 	std::vector<SizeRange> sizes;
-	for (const Size &size : sensor_->sizes())
-		sizes.emplace_back(size, size);
+	for (const auto &iter : mbusCodesToPixelFormat) {
+		if (iter.second != format)
+			continue;
+
+		mbusCode = iter.first;
+		break;
+	}
+
+	if (mbusCode == -1)
+		return {};
+
+	for (const Size &sz : sensor_->sizes(mbusCode))
+		sizes.emplace_back(sz);
 
 	return sizes;
 }
diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h
index f28e9f1d..24272dc5 100644
--- a/src/libcamera/pipeline/ipu3/cio2.h
+++ b/src/libcamera/pipeline/ipu3/cio2.h
@@ -35,7 +35,7 @@ public:
 	CIO2Device();
 
 	std::vector<PixelFormat> formats() const;
-	std::vector<SizeRange> sizes() const;
+	std::vector<SizeRange> sizes(const PixelFormat &format) const;
 
 	int init(const MediaDevice *media, unsigned int index);
 	int configure(const Size &size, V4L2DeviceFormat *outputFormat);
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index a98d7eff..c287bf86 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -457,7 +457,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
 			bufferCount = cio2Config.bufferCount;
 
 			for (const PixelFormat &format : data->cio2_.formats())
-				streamFormats[format] = data->cio2_.sizes();
+				streamFormats[format] = data->cio2_.sizes(format);
 
 			break;
 		}
-- 
cgit v1.2.1