[libcamera-devel,v4,7/9] ipu3: Assign |outCaptureStream| to StillCapture configuration
diff mbox series

Message ID 20220802102943.3221109-8-chenghaoyang@google.com
State New
Headers show
Series
  • Use two imgus in ipu3 pipeline handler
Related show

Commit Message

Cheng-Hao Yang Aug. 2, 2022, 10:29 a.m. UTC
When StillCapture and other non-raw configurations are requested,
assigns |outCaptureStream| instead of |outStream| to the StillCapture
configuration.

Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 56 ++++++++++++++++++++++++----
 1 file changed, 48 insertions(+), 8 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 73f361f8..f8101c6c 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -254,8 +254,10 @@  CameraConfiguration::Status IPU3CameraConfiguration::validate()
 	 * \todo Clarify the IF and BDS margins requirements.
 	 */
 	unsigned int rawCount = 0;
-	unsigned int yuvCount = 0;
+	unsigned int videoCount = 0;
+	unsigned int stillCount = 0;
 	Size maxYuvSize;
+	Size maxVideoSize;
 	Size rawSize;
 
 	for (const StreamConfiguration &cfg : config_) {
@@ -264,16 +266,34 @@  CameraConfiguration::Status IPU3CameraConfiguration::validate()
 		if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) {
 			rawCount++;
 			rawSize.expandTo(cfg.size);
+		} else if (cfg.streamRole == StreamRole::StillCapture) {
+			if (stillCount != 0)
+				return Invalid;
+
+			stillCount++;
+			maxYuvSize.expandTo(cfg.size);
 		} else {
-			yuvCount++;
+			videoCount++;
 			maxYuvSize.expandTo(cfg.size);
+			maxVideoSize.expandTo(cfg.size);
 		}
 	}
 
-	if (rawCount > 1 || yuvCount > 2) {
+	if (videoCount == 0 && stillCount == 1) {
+		/*
+		 * If only the StillCapture stream is requested, it cannot be
+		 * supported natively, as we need a video stream that enables
+		 * the 3A. Therefore, use video snapshot instead.
+		 */
+		stillCount = 0;
+		videoCount = 1;
+		maxVideoSize.expandTo(maxYuvSize);
+	}
+
+	if (rawCount > 1 || videoCount > 2) {
 		LOG(IPU3, Debug) << "Camera configuration not supported";
 		return Invalid;
-	} else if (rawCount && !yuvCount) {
+	} else if (rawCount && !stillCount && !videoCount) {
 		/*
 		 * Disallow raw-only camera configuration. Currently, ImgU does
 		 * not get configured for raw-only streams and has early return
@@ -316,6 +336,9 @@  CameraConfiguration::Status IPU3CameraConfiguration::validate()
 	ImgUDevice::Pipe pipe{};
 	pipe.input = cio2Configuration_.size;
 
+	ImgUDevice::Pipe pipe1{};
+	pipe1.input = cio2Configuration_.size;
+
 	/*
 	 * Adjust the configurations if needed and assign streams while
 	 * iterating them.
@@ -380,18 +403,35 @@  CameraConfiguration::Status IPU3CameraConfiguration::validate()
 			cfg->stride = info.stride(cfg->size.width, 0, 1);
 			cfg->frameSize = info.frameSize(cfg->size, 1);
 
+			if (cfg->streamRole == StreamRole::StillCapture) {
+				ASSERT(stillCount == 1);
+				LOG(IPU3, Debug) << "Assigned "
+						 << cfg->toString()
+						 << " to the imgu1 main output";
+				cfg->setStream(const_cast<Stream *>(&data_->outCaptureStream_));
+
+				pipe1.main = cfg->size;
+				pipe1.viewfinder = pipe1.main;
+
+				pipeConfig1_ = data_->imgu1_->calculatePipeConfig(&pipe1);
+				if (pipeConfig1_.isNull()) {
+					LOG(IPU3, Error) << "Failed to calculate pipe configuration: "
+							 << "unsupported resolutions.";
+					return Invalid;
+				}
 			/*
 			 * Use the main output stream in case only one stream is
 			 * requested or if the current configuration is the one
 			 * with the maximum YUV output size.
 			 */
-			if (mainOutputAvailable &&
-			    (originalCfg.size == maxYuvSize || yuvCount == 1)) {
+			} else if (mainOutputAvailable &&
+				   (originalCfg.size == maxVideoSize ||
+				    videoCount == 1)) {
 				cfg->setStream(const_cast<Stream *>(&data_->outStream_));
 				mainOutputAvailable = false;
 
 				pipe.main = cfg->size;
-				if (yuvCount == 1)
+				if (videoCount == 1)
 					pipe.viewfinder = pipe.main;
 
 				LOG(IPU3, Debug) << "Assigned " << cfg->toString()
@@ -415,7 +455,7 @@  CameraConfiguration::Status IPU3CameraConfiguration::validate()
 	}
 
 	/* Only compute the ImgU configuration if a YUV stream has been requested. */
-	if (yuvCount) {
+	if (videoCount) {
 		pipeConfig0_ = data_->imgu0_->calculatePipeConfig(&pipe);
 		if (pipeConfig0_.isNull()) {
 			LOG(IPU3, Error) << "Failed to calculate pipe configuration: "