From ba72e4202f1958028c9b40cd858fdfb46508335b Mon Sep 17 00:00:00 2001
From: Han-Lin Chen via libcamera-devel <libcamera-devel@lists.libcamera.org>
Date: Fri, 12 Aug 2022 17:01:03 +0800
Subject: libcamera: ipu3: Use std::max() instead of expandTo() to get the max
 resolution

Using Size::expandTo() to find the max resolution might generate a non-existent
resolution. For example, when application request streams for 1920x1080 and
1600x1200, the max resolution will be wrongly 1920x1200 and fails the
configuration.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=139
Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 9df24603..93219a6c 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -243,6 +243,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()
 	 */
 	unsigned int rawCount = 0;
 	unsigned int yuvCount = 0;
+	Size rawRequirement;
 	Size maxYuvSize;
 	Size rawSize;
 
@@ -251,10 +252,11 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()
 
 		if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) {
 			rawCount++;
-			rawSize.expandTo(cfg.size);
+			rawSize = std::max(rawSize, cfg.size);
 		} else {
 			yuvCount++;
-			maxYuvSize.expandTo(cfg.size);
+			maxYuvSize = std::max(maxYuvSize, cfg.size);
+			rawRequirement.expandTo(cfg.size);
 		}
 	}
 
@@ -283,17 +285,17 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()
 	 * The output YUV streams will be limited in size to the maximum frame
 	 * size requested for the RAW stream, if present.
 	 *
-	 * If no raw stream is requested generate a size as large as the maximum
-	 * requested YUV size aligned to the ImgU constraints and bound by the
-	 * sensor's maximum resolution. See
+	 * If no raw stream is requested, generate a size from the largest YUV
+	 * stream, aligned to the ImgU constraints and bound
+	 * by the sensor's maximum resolution. See
 	 * https://bugs.libcamera.org/show_bug.cgi?id=32
 	 */
 	if (rawSize.isNull())
-		rawSize = maxYuvSize.expandedTo({ ImgUDevice::kIFMaxCropWidth,
-						  ImgUDevice::kIFMaxCropHeight })
-				    .grownBy({ ImgUDevice::kOutputMarginWidth,
-					       ImgUDevice::kOutputMarginHeight })
-				    .boundedTo(data_->cio2_.sensor()->resolution());
+		rawSize = rawRequirement.expandedTo({ ImgUDevice::kIFMaxCropWidth,
+						      ImgUDevice::kIFMaxCropHeight })
+				  .grownBy({ ImgUDevice::kOutputMarginWidth,
+					     ImgUDevice::kOutputMarginHeight })
+				  .boundedTo(data_->cio2_.sensor()->resolution());
 
 	cio2Configuration_ = data_->cio2_.generateConfiguration(rawSize);
 	if (!cio2Configuration_.pixelFormat.isValid())
-- 
cgit v1.2.1