[PATCH v6 08/12] libcamera: simple: Consider raw output configurations

Milan Zamazal mzamazal at redhat.com
Mon May 26 12:15:28 CEST 2025


When generating simple pipeline configuration, raw output configurations
are generated but later filtered out.  Let's include processed and/or
raw output configurations depending on the requested stream roles.

Raw and processed formats are handled separately.  The intention is that
in case both raw and processed formats are requested then the raw
formats should be left intact to the extent possible and not be
influenced by the processed formats (implying that raw parameters
compatible with the processed output requirements must be requested by
the application).

Raw output configurations are identified by colorSpace being set to
ColorSpace::Raw.

This is another preparatory patch without making raw outputs working.

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

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 0219a393..91fd4323 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -1323,37 +1323,50 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo
 			config->processedRequested_ = true;
 		}
 
-	/* Create the formats map. */
-	std::map<PixelFormat, std::vector<SizeRange>> formats;
+	/* Create the formats maps. */
+	std::map<PixelFormat, std::vector<SizeRange>> processedFormats;
+	std::map<PixelFormat, std::vector<SizeRange>> rawFormats;
 
-	const bool rawOnly = std::all_of(data->configs_.cbegin(),
-					 data->configs_.cend(),
-					 [](const auto &c) { return c.raw; });
 	for (const SimpleCameraData::Configuration &cfg : data->configs_)
-		if (!cfg.raw || rawOnly)
-			for (PixelFormat format : cfg.outputFormats)
-				formats[format].push_back(cfg.outputSizes);
-
-	/* Sort the sizes and merge any consecutive overlapping ranges. */
-	for (auto &[format, sizes] : formats) {
-		std::sort(sizes.begin(), sizes.end(),
-			  [](SizeRange &a, SizeRange &b) {
-				  return a.min < b.min;
-			  });
-
-		auto cur = sizes.begin();
-		auto next = cur;
-
-		while (++next != sizes.end()) {
-			if (cur->max.width >= next->min.width &&
-			    cur->max.height >= next->min.height)
-				cur->max = next->max;
-			else if (++cur != next)
-				*cur = *next;
-		}
+		for (PixelFormat format : cfg.outputFormats)
+			(cfg.raw ? rawFormats : processedFormats)[format].push_back(cfg.outputSizes);
 
-		sizes.erase(++cur, sizes.end());
+	if (config->processedRequested_ && processedFormats.empty()) {
+		LOG(SimplePipeline, Error)
+			<< "Processed stream requsted but no corresponding output configuration found";
+		return nullptr;
 	}
+	if (config->rawRequested_ && rawFormats.empty()) {
+		LOG(SimplePipeline, Error)
+			<< "Raw stream requsted but no corresponding output configuration found";
+		return nullptr;
+	}
+
+	auto setUpFormatSizes = [](std::map<PixelFormat, std::vector<SizeRange>> &formats) {
+		/* Sort the sizes and merge any consecutive overlapping ranges. */
+
+		for (auto &[format, sizes] : formats) {
+			std::sort(sizes.begin(), sizes.end(),
+				  [](SizeRange &a, SizeRange &b) {
+					  return a.min < b.min;
+				  });
+
+			auto cur = sizes.begin();
+			auto next = cur;
+
+			while (++next != sizes.end()) {
+				if (cur->max.width >= next->min.width &&
+				    cur->max.height >= next->min.height)
+					cur->max = next->max;
+				else if (++cur != next)
+					*cur = *next;
+			}
+
+			sizes.erase(++cur, sizes.end());
+		}
+	};
+	setUpFormatSizes(processedFormats);
+	setUpFormatSizes(rawFormats);
 
 	/*
 	 * Create the stream configurations. Take the first entry in the formats
@@ -1362,11 +1375,13 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo
 	 * \todo Implement a better way to pick the default format
 	 */
 	for (StreamRole role : roles) {
+		bool raw = (role == StreamRole::Raw);
+		const auto &formats = (raw ? rawFormats : processedFormats);
 		StreamConfiguration cfg{ StreamFormats{ formats } };
 		cfg.pixelFormat = formats.begin()->first;
 		cfg.size = formats.begin()->second[0].max;
 
-		if (role == StreamRole::Raw)
+		if (raw)
 			cfg.colorSpace = ColorSpace::Raw;
 		else if (data->swIsp_)
 			cfg.colorSpace = ColorSpace::Srgb;
-- 
2.49.0



More information about the libcamera-devel mailing list