[libcamera-devel,4/7] libcamera: pipeline: vimc: Configure the entities of VIMC pipeline

Message ID 20200722133009.26528-5-kgupta@es.iitr.ac.in
State New
Delegated to: Kieran Bingham
Headers show
Series
  • vimc: Introduce multiple streaming
Related show

Commit Message

Kaaira Gupta July 22, 2020, 1:30 p.m. UTC
Configure the pads according to the configuration asked for. In case
only one stream (RBG or RAW) is asked for, configurations still need to
be set on the other entities in the pipeline.

Signed-off-by: Kaaira Gupta <kgupta@es.iitr.ac.in>
---
 src/libcamera/pipeline/vimc/vimc.cpp | 175 ++++++++++++++++++---------
 1 file changed, 121 insertions(+), 54 deletions(-)

Patch

diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index 83dd541..c2ed5b6 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -295,68 +295,135 @@  CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera,
 int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config)
 {
 	VimcCameraData *data = cameraData(camera);
-	StreamConfiguration &cfg = config->at(0);
-	int ret;
+	for (unsigned i = 0; i < config->size(); i++) {
+		StreamConfiguration &cfg = config->at(i);
+		const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat);
+		int ret;
+		if (info.isRaw(cfg.pixelFormat)) {
+			V4L2SubdeviceFormat subformat = {};
+			subformat.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8;
+			subformat.size = cfg.size;
+			ret = data->sensor_->setFormat(&subformat);
+			if (ret)
+				return ret;
+
+			V4L2DeviceFormat format = {};
+			format.fourcc = data->raw_->toV4L2PixelFormat(cfg.pixelFormat);
+			format.size = cfg.size;
+			ret = data->raw_->setFormat(&format);
+			if (ret)
+				return ret;
+
+			/*
+			 * Formats have to be set on debayer, scaler, and RGB/YUB Capture
+			 * otherwise the VIMC driver will fail pipeline validation
+			 */
+
+			ret = data->debayer_->setFormat(0, &subformat);
+			if (ret)
+				return ret;
+
+			subformat.mbus_code = MEDIA_BUS_FMT_RGB888_1X24;
+			ret = data->debayer_->setFormat(1, &subformat);
+			if (ret)
+				return ret;
+
+			ret = data->scaler_->setFormat(0, &subformat);
+			if (ret)
+				return ret;
+
+			if (data->media_->version() >= KERNEL_VERSION(5, 6, 0)) {
+				Rectangle crop = {
+					.x = 0,
+					.y = 0,
+					.width = subformat.size.width,
+					.height = subformat.size.height,
+				};
+				ret = data->scaler_->setSelection(0, V4L2_SEL_TGT_CROP, &crop);
+				if (ret)
+					return ret;
+			}
 
-	/* The scaler hardcodes a x3 scale-up ratio. */
-	V4L2SubdeviceFormat subformat = {};
-	subformat.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8;
-	subformat.size = { cfg.size.width / 3, cfg.size.height / 3 };
+			subformat.mbus_code = MEDIA_BUS_FMT_RGB888_1X24;
+			subformat.size = { cfg.size.width * 3, cfg.size.height * 3 };
+			ret = data->scaler_->setFormat(1, &subformat);
+			if (ret)
+				return ret;
 
-	ret = data->sensor_->setFormat(&subformat);
-	if (ret)
-		return ret;
+			format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_RGB24);
+			format.size = { cfg.size.width * 3, cfg.size.height * 3 };
+			ret = data->video_->setFormat(&format);
+			if (ret)
+				return ret;
 
-	ret = data->debayer_->setFormat(0, &subformat);
-	if (ret)
-		return ret;
+			cfg.setStream(&data->rawStream_);
 
-	subformat.mbus_code = pixelformats.find(cfg.pixelFormat)->second;
-	ret = data->debayer_->setFormat(1, &subformat);
-	if (ret)
-		return ret;
+		} else {
+			/* The scaler hardcodes a x3 scale-up ratio. */
+			V4L2SubdeviceFormat subformat = {};
+			subformat.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8;
+			subformat.size = { cfg.size.width / 3, cfg.size.height / 3 };
+
+			ret = data->sensor_->setFormat(&subformat);
+			if (ret)
+				return ret;
+
+			ret = data->debayer_->setFormat(0, &subformat);
+			if (ret)
+				return ret;
+
+			subformat.mbus_code = pixelformats.find(cfg.pixelFormat)->second;
+			ret = data->debayer_->setFormat(1, &subformat);
+			if (ret)
+				return ret;
+
+			ret = data->scaler_->setFormat(0, &subformat);
+			if (ret)
+				return ret;
+
+			if (data->media_->version() >= KERNEL_VERSION(5, 6, 0)) {
+				Rectangle crop = {
+					.x = 0,
+					.y = 0,
+					.width = subformat.size.width,
+					.height = subformat.size.height,
+				};
+				ret = data->scaler_->setSelection(0, V4L2_SEL_TGT_CROP, &crop);
+				if (ret)
+					return ret;
+			}
 
-	ret = data->scaler_->setFormat(0, &subformat);
-	if (ret)
-		return ret;
+			subformat.size = cfg.size;
+			ret = data->scaler_->setFormat(1, &subformat);
+			if (ret)
+				return ret;
 
-	if (data->media_->version() >= KERNEL_VERSION(5, 6, 0)) {
-		Rectangle crop{ 0, 0, subformat.size };
-		ret = data->scaler_->setSelection(0, V4L2_SEL_TGT_CROP, &crop);
-		if (ret)
-			return ret;
+			V4L2DeviceFormat format = {};
+			format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat);
+			format.size = cfg.size;
+			ret = data->video_->setFormat(&format);
+			if (ret)
+				return ret;
+
+			if (format.size != cfg.size ||
+			    format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat))
+				return -EINVAL;
+
+			/*
+			 * Format has to be set on the raw capture video node, otherwise the
+			 * vimc driver will fail pipeline validation.
+			 */
+			format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8);
+			format.size = { cfg.size.width / 3, cfg.size.height / 3 };
+
+			ret = data->raw_->setFormat(&format);
+			if (ret)
+				return ret;
+
+			cfg.setStream(&data->rgbStream_);
+		}
 	}
 
-	subformat.size = cfg.size;
-	ret = data->scaler_->setFormat(1, &subformat);
-	if (ret)
-		return ret;
-
-	V4L2DeviceFormat format = {};
-	format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat);
-	format.size = cfg.size;
-
-	ret = data->video_->setFormat(&format);
-	if (ret)
-		return ret;
-
-	if (format.size != cfg.size ||
-	    format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat))
-		return -EINVAL;
-
-	/*
-	 * Format has to be set on the raw capture video node, otherwise the
-	 * vimc driver will fail pipeline validation.
-	 */
-	format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8);
-	format.size = { cfg.size.width / 3, cfg.size.height / 3 };
-
-	ret = data->raw_->setFormat(&format);
-	if (ret)
-		return ret;
-
-	cfg.setStream(&data->rgbStream_);
-
 	return 0;
 }