[libcamera-devel] [PATCH v5 08/19] libcamera: ipu3: Cache the camera sizes

Jacopo Mondi jacopo at jmondi.org
Tue Mar 26 09:38:51 CET 2019


When creating a camera, make sure a the image sensor provides images in
a format compatible with IPU3 CIO2 unit requirements and cache the
minimum and maximum camera sizes.

Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 56 +++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 55489c31df2d..d42c81273cc6 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -8,11 +8,14 @@
 #include <memory>
 #include <vector>
 
+#include <linux/media-bus-format.h>
+
 #include <libcamera/camera.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
 
 #include "device_enumerator.h"
+#include "geometry.h"
 #include "log.h"
 #include "media_device.h"
 #include "pipeline_handler.h"
@@ -24,6 +27,22 @@ namespace libcamera {
 
 LOG_DEFINE_CATEGORY(IPU3)
 
+static int mediaBusToCIO2Format(unsigned int code)
+{
+	switch (code) {
+	case MEDIA_BUS_FMT_SBGGR10_1X10:
+		return V4L2_PIX_FMT_IPU3_SBGGR10;
+	case MEDIA_BUS_FMT_SGBRG10_1X10:
+		return V4L2_PIX_FMT_IPU3_SGBRG10;
+	case MEDIA_BUS_FMT_SGRBG10_1X10:
+		return V4L2_PIX_FMT_IPU3_SGRBG10;
+	case MEDIA_BUS_FMT_SRGGB10_1X10:
+		return V4L2_PIX_FMT_IPU3_SRGGB10;
+	default:
+		return -EINVAL;
+	}
+}
+
 class PipelineHandlerIPU3 : public PipelineHandler
 {
 public:
@@ -70,6 +89,9 @@ private:
 		V4L2Subdevice *sensor_;
 
 		Stream stream_;
+
+		/* Maximum sizes and the mbus code used to produce them. */
+		std::pair<unsigned int, SizeRange> maxSizes_;
 	};
 
 	IPU3CameraData *cameraData(const Camera *camera)
@@ -404,18 +426,48 @@ void PipelineHandlerIPU3::registerCameras()
 		if (ret)
 			continue;
 
-		data->cio2_->bufferReady.connect(data.get(), &IPU3CameraData::bufferReady);
-
+		/*
+		 * Make sure the sensor produces at least one image format
+		 * compatible with IPU3 CIO2 requirements and cache the camera
+		 * maximum sizes.
+		 */
 		data->sensor_ = new V4L2Subdevice(sensor);
 		ret = data->sensor_->open();
 		if (ret)
 			continue;
 
+		for (auto it : data->sensor_->formats(0)) {
+			int mbusCode = mediaBusToCIO2Format(it.first);
+			if (mbusCode < 0)
+				continue;
+
+			for (const SizeRange &size : it.second) {
+				SizeRange &maxSize = data->maxSizes_.second;
+
+				if (maxSize.maxWidth < size.maxWidth &&
+				    maxSize.maxHeight < size.maxHeight) {
+					maxSize.maxWidth = size.maxWidth;
+					maxSize.maxHeight = size.maxHeight;
+					data->maxSizes_.first = mbusCode;
+				}
+			}
+		}
+		if (data->maxSizes_.second.maxWidth == 0) {
+			LOG(IPU3, Info)
+				<< "Sensor '" << data->sensor_->entityName()
+				<< "' detected, but no supported image format "
+				<< " found: skip camera creation";
+			continue;
+		}
+
 		data->csi2_ = new V4L2Subdevice(csi2);
 		ret = data->csi2_->open();
 		if (ret)
 			continue;
 
+		data->cio2_->bufferReady.connect(data.get(),
+						 &IPU3CameraData::bufferReady);
+
 		registerCamera(std::move(camera), std::move(data));
 
 		LOG(IPU3, Info)
-- 
2.21.0



More information about the libcamera-devel mailing list