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

Barnabás Pőcze barnabas.pocze at ideasonboard.com
Thu May 22 11:09:37 CEST 2025


Hi


2025. 05. 20. 14:31 keltezéssel, Milan Zamazal írta:
> 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 78a76f34..12fd28fa 100644
> --- a/src/libcamera/pipeline/simple/simple.cpp
> +++ b/src/libcamera/pipeline/simple/simple.cpp
> @@ -1322,37 +1322,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
> @@ -1361,11 +1374,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);
> +		auto formats = (raw ? rawFormats : processedFormats);

This makes a copy, can you do `const auto &formats = ...`?


Regards,
Barnabás Pőcze


>   		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;



More information about the libcamera-devel mailing list