[RFC,3/6] libcamera: simple: Support StreamRole::Raw in generateConfiguration()
diff mbox series

Message ID 20250716142027.236277-4-uajain@igalia.com
State New
Headers show
Series
  • libcamera: simple: Enable Raw capture
Related show

Commit Message

Umang Jain July 16, 2025, 2:20 p.m. UTC
Add stream role support for raw stream in generateConfiguration.
If multiple raw streams are requested, make sure to invalidate them
accordingly in validate(). Currently, only one raw stream per camera
configuration is allowed.

In order to get access to the raw formats supported by the sensor,
one would require to iterate over SimpleCameraData::formats_ map
in generateConfiguration(). This map not only include output
configuration pixel formats but also the raw format configuration that
can be produced (for raw roles).

Signed-off-by: Umang Jain <uajain@igalia.com>
---
 src/libcamera/pipeline/simple/simple.cpp | 50 ++++++++++++++++++++----
 1 file changed, 43 insertions(+), 7 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index cadc1117..d6c92391 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -1128,6 +1128,23 @@  CameraConfiguration::Status SimpleCameraConfiguration::validate()
 	LOG(SimplePipeline, Debug)
 		<< "Largest stream size is " << maxStreamSize;
 
+	/* Cap the number of raw stream configuration */
+	unsigned int rawCount = 0;
+	PixelFormat requestedRawFormat;
+	for (const StreamConfiguration &cfg : config_) {
+		if (!isFormatRaw(cfg.pixelFormat))
+			continue;
+		requestedRawFormat = cfg.pixelFormat;
+		rawCount++;
+	}
+
+	if (rawCount > 1) {
+		LOG(SimplePipeline, Error)
+			<< "Camera configuration with "
+			<< rawCount << " raw streams not supported";
+		return Invalid;
+	}
+
 	/*
 	 * Find the best configuration for the pipeline using a heuristic.
 	 * First select the pixel format based on the streams (which are
@@ -1289,9 +1306,9 @@  SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo
 	/* Create the formats map. */
 	std::map<PixelFormat, std::vector<SizeRange>> formats;
 
-	for (const SimpleCameraData::Configuration &cfg : data->configs_) {
-		for (PixelFormat format : cfg.outputFormats)
-			formats[format].push_back(cfg.outputSizes);
+	for (const auto &it : data->formats_) {
+		for (const SimpleCameraData::Configuration *cfg : it.second)
+			formats[it.first].push_back(cfg->outputSizes);
 	}
 
 	/* Sort the sizes and merge any consecutive overlapping ranges. */
@@ -1317,14 +1334,33 @@  SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo
 
 	/*
 	 * Create the stream configurations. Take the first entry in the formats
-	 * map as the default, for lack of a better option.
+	 * map as the default for each of role (raw or non-raw), for lack of a
+	 * better option.
 	 *
 	 * \todo Implement a better way to pick the default format
 	 */
-	for ([[maybe_unused]] StreamRole role : roles) {
+	for (StreamRole role : roles) {
 		StreamConfiguration cfg{ StreamFormats{ formats } };
-		cfg.pixelFormat = formats.begin()->first;
-		cfg.size = formats.begin()->second[0].max;
+
+		switch (role) {
+		case StreamRole::Raw:
+			for (auto &[format, sizes] : formats) {
+				if (!isFormatRaw(format))
+					continue;
+				cfg.pixelFormat = format;
+				cfg.size = sizes.back().max;
+				cfg.colorSpace = ColorSpace::Raw;
+				break;
+			}
+			break;
+		default:
+			for (auto &[format, sizes] : formats) {
+				if (isFormatRaw(format))
+					continue;
+				cfg.pixelFormat = format;
+				cfg.size = sizes[0].max;
+			}
+		}
 
 		config->addConfiguration(cfg);
 	}