From be9feda2ad0aab53f8c79abcc750bddf31240dcd Mon Sep 17 00:00:00 2001
From: Jacopo Mondi <jacopo@jmondi.org>
Date: Thu, 24 Sep 2020 15:54:16 +0200
Subject: libcamera: ipu3: Fix RAW+YUV capture
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When requesting one RAW stream and one YUV stream the
StreamConfiguration assigned to the RAW stream is the first one
added to the CameraConfiguration, while the YUV stream gets assigned to
the main output.

At configure() time the viewfinder output needs to be configured with
the same format as the main output, but since the introduction of RAW
capture support, the pipeline has not been updated and still assumes
the main output configuration is the first one in the
CameraConfiguration. This causes the viewfinder to be configured
with the same format as the raw stream, breaking capture operations.

Before this commit the following command fails and the ImgU does not
produce frames:
cam -srole=stillraw -srole=viewfinder -c2 -C

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 7bb05efa..f6e7ab46 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -481,25 +481,23 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
 		return ret;
 
 	/* Apply the format to the configured streams output devices. */
-	bool outActive = false;
-	bool vfActive = false;
+	StreamConfiguration *mainCfg = nullptr;
+	StreamConfiguration *vfCfg = nullptr;
 
 	for (unsigned int i = 0; i < config->size(); ++i) {
 		StreamConfiguration &cfg = (*config)[i];
 		Stream *stream = cfg.stream();
 
 		if (stream == outStream) {
+			mainCfg = &cfg;
 			ret = imgu->configureOutput(cfg, &outputFormat);
 			if (ret)
 				return ret;
-
-			outActive = true;
 		} else if (stream == vfStream) {
+			vfCfg = &cfg;
 			ret = imgu->configureViewfinder(cfg, &outputFormat);
 			if (ret)
 				return ret;
-
-			vfActive = true;
 		}
 	}
 
@@ -508,14 +506,14 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
 	 * the configuration of the active one for that purpose (there should
 	 * be at least one active stream in the configuration request).
 	 */
-	if (!outActive) {
-		ret = imgu->configureOutput(config->at(0), &outputFormat);
+	if (!mainCfg) {
+		ret = imgu->configureOutput(*vfCfg, &outputFormat);
 		if (ret)
 			return ret;
 	}
 
-	if (!vfActive) {
-		ret = imgu->configureViewfinder(config->at(0), &outputFormat);
+	if (!vfCfg) {
+		ret = imgu->configureViewfinder(*mainCfg, &outputFormat);
 		if (ret)
 			return ret;
 	}
@@ -534,7 +532,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
 	/* Apply the "pipe_mode" control to the ImgU subdevice. */
 	ControlList ctrls(imgu->imgu_->controls());
 	ctrls.set(V4L2_CID_IPU3_PIPE_MODE,
-		  static_cast<int32_t>(vfActive ? IPU3PipeModeVideo :
+		  static_cast<int32_t>(vfCfg ? IPU3PipeModeVideo :
 				       IPU3PipeModeStillCapture));
 	ret = imgu->imgu_->setControls(&ctrls);
 	if (ret) {
-- 
cgit v1.2.1