[PATCH v3 6/8] libcamera: simple: Validate raw stream configurations

Milan Zamazal mzamazal at redhat.com
Wed Mar 5 20:26:13 CET 2025


SimpleCameraConfiguration::validate() looks for the best configuration.
As part of enabling raw stream support, the method must consider raw
streams in addition to the processed streams.

If only a processed stream is requested, nothing changes.

If only a raw stream is requested, the pixel format and output size may
not be adjusted.  The patch adds checks for this.

If both processed and raw streams are requested, things get more
complicated.  The raw stream is expected to be passed through intact and
all the adjustments are made for the processed streams.  We select a
pipe configuration for the processed streams.

Note that with both processed and raw streams, the requested sizes must
be mutually matching, including resizing due to debayer requirements.
For example, the following `cam' setup is valid for imx219

  cam -s role=viewfinder,width=1920,height=1080 \
      -s role=raw,width=3280,height=2464

rather than

  cam -s role=viewfinder,width=1920,height=1080 \
      -s role=raw,width=1920,height=1080

due to the resolution of 1924x1080 actually selected for debayering to
1920x1080.  It is the application responsibility to select the right
parameters for the raw stream.

Setting up the right configurations is still not enough to make the raw
streams working.  Buffer handling must be changed in the simple
pipeline, which is addressed in followup patches.

Signed-off-by: Milan Zamazal <mzamazal at redhat.com>
---
 src/libcamera/pipeline/simple/simple.cpp | 74 +++++++++++++++++++-----
 1 file changed, 59 insertions(+), 15 deletions(-)

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 92b9608b..a387d34b 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -27,6 +27,7 @@
 #include <libcamera/camera.h>
 #include <libcamera/color_space.h>
 #include <libcamera/control_ids.h>
+#include <libcamera/geometry.h>
 #include <libcamera/pixel_format.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
@@ -1055,6 +1056,9 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
 	pipeConfig_ = nullptr;
 
 	for (const SimpleCameraData::Configuration *pipeConfig : *configs) {
+		if (data_->processedRequested_ && pipeConfig->raw)
+			continue;
+
 		const Size &size = pipeConfig->captureSize;
 
 		if (size.width >= maxStreamSize.width &&
@@ -1096,21 +1100,43 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
 	for (unsigned int i = 0; i < config_.size(); ++i) {
 		StreamConfiguration &cfg = config_[i];
 
+		/*
+		 * If both processed and raw streams are requested, the pipe
+		 * configuration is set up for the processed stream. The raw
+		 * configuration needs to be compared against the capture format and
+		 * size in such a case.
+		 */
+		const bool rawStream = cfg.colorSpace == ColorSpace::Raw;
+		const bool sideRawStream = rawStream && data_->processedRequested_;
+
 		/* Adjust the pixel format and size. */
-		auto it = std::find(pipeConfig_->outputFormats.begin(),
-				    pipeConfig_->outputFormats.end(),
-				    cfg.pixelFormat);
-		if (it == pipeConfig_->outputFormats.end())
-			it = pipeConfig_->outputFormats.begin();
-
-		PixelFormat pixelFormat = *it;
-		if (cfg.pixelFormat != pixelFormat) {
-			LOG(SimplePipeline, Debug) << "Adjusting pixel format";
-			cfg.pixelFormat = pixelFormat;
-			status = Adjusted;
+
+		if (!sideRawStream) {
+			auto it = std::find(pipeConfig_->outputFormats.begin(),
+					    pipeConfig_->outputFormats.end(),
+					    cfg.pixelFormat);
+			if (it == pipeConfig_->outputFormats.end())
+				it = pipeConfig_->outputFormats.begin();
+
+			PixelFormat pixelFormat = *it;
+
+			if (cfg.pixelFormat != pixelFormat) {
+				if (rawStream) {
+					LOG(SimplePipeline, Info)
+						<< "Raw pixel format "
+						<< cfg.pixelFormat
+						<< " doesn't match any of the pipe output formats";
+					return Invalid;
+				}
+				LOG(SimplePipeline, Debug)
+					<< "Adjusting pixel format from " << cfg.pixelFormat
+					<< " to " << pixelFormat;
+				cfg.pixelFormat = pixelFormat;
+				status = Adjusted;
+			}
 		}
 
-		if (!pipeConfig_->outputSizes.contains(cfg.size)) {
+		if (!sideRawStream && !pipeConfig_->outputSizes.contains(cfg.size)) {
 			Size adjustedSize = pipeConfig_->captureSize;
 			/*
 			 * The converter (when present) may not be able to output
@@ -1118,8 +1144,17 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
 			 * not guaranteed to be a valid output size. In such cases, use
 			 * the smaller valid output size closest to the requested.
 			 */
-			if (!pipeConfig_->outputSizes.contains(adjustedSize))
+			if (!pipeConfig_->outputSizes.contains(adjustedSize)) {
+				if (rawStream) {
+					LOG(SimplePipeline, Info)
+						<< "Raw output size "
+						<< cfg.size
+						<< " doesn't match any of the pipe output sizes: "
+						<< pipeConfig_->outputSizes;
+					return Invalid;
+				}
 				adjustedSize = adjustSize(cfg.size, pipeConfig_->outputSizes);
+			}
 			LOG(SimplePipeline, Debug)
 				<< "Adjusting size from " << cfg.size
 				<< " to " << adjustedSize;
@@ -1129,11 +1164,20 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
 
 		/* \todo Create a libcamera core class to group format and size */
 		if (cfg.pixelFormat != pipeConfig_->captureFormat ||
-		    cfg.size != pipeConfig_->captureSize)
+		    cfg.size != pipeConfig_->captureSize) {
+			if (rawStream) {
+				LOG(SimplePipeline, Info)
+					<< "Raw output format " << cfg.pixelFormat
+					<< " and size " << cfg.size
+					<< " not matching pipe format " << pipeConfig_->captureFormat
+					<< " and size " << pipeConfig_->captureSize;
+				return Invalid;
+			}
 			needConversion_ = true;
+		}
 
 		/* Set the stride, frameSize and bufferCount. */
-		if (needConversion_) {
+		if (needConversion_ && !rawStream) {
 			std::tie(cfg.stride, cfg.frameSize) =
 				data_->converter_
 					? data_->converter_->strideAndFrameSize(cfg.pixelFormat,
-- 
2.48.1



More information about the libcamera-devel mailing list