| Message ID | 20251021182716.29274-4-mzamazal@redhat.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
On Tue, Oct 21, 2025 at 08:27:10PM +0200, Milan Zamazal wrote: > Let's handle both processed and/or raw output configurations. In > addition to the already handled processed formats and sizes, this patch > adds handling of raw formats and sizes, which correspond to the capture > formats and sizes. > > When creating stream configurations, raw or processed formats are > selected according to the requested stream roles. > > This is another preparatory patch without making raw outputs working. > > Signed-off-by: Milan Zamazal <mzamazal@redhat.com> > --- > src/libcamera/pipeline/simple/simple.cpp | 79 +++++++++++++++++------- > 1 file changed, 56 insertions(+), 23 deletions(-) > > diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp > index 1f67094db..d7675538f 100644 > --- a/src/libcamera/pipeline/simple/simple.cpp > +++ b/src/libcamera/pipeline/simple/simple.cpp > @@ -1343,42 +1343,75 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo > if (roles.empty()) > return config; > > - /* Create the formats map. */ > - std::map<PixelFormat, std::vector<SizeRange>> formats; > + bool processedRequested = false; > + bool rawRequested = false; > + for (const auto &role : roles) > + if (role == StreamRole::Raw) { > + if (rawRequested) { > + LOG(SimplePipeline, Error) > + << "Can't capture multiple raw streams"; > + return nullptr; > + } > + rawRequested = true; > + } else { > + processedRequested = true; For me, I find processed stream request is implicit to libcamera but if you find you need to track these separately, I can live with that. > + } > + > + /* Create the formats maps. */ > + std::map<PixelFormat, std::vector<SizeRange>> processedFormats; > + std::map<PixelFormat, std::vector<SizeRange>> rawFormats; > > for (const SimpleCameraData::Configuration &cfg : data->configs_) { > + rawFormats[cfg.captureFormat].push_back(cfg.captureSize); > for (PixelFormat format : cfg.outputFormats) > - formats[format].push_back(cfg.outputSizes); > + processedFormats[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; > - } > - > - sizes.erase(++cur, sizes.end()); > + if (processedRequested && processedFormats.empty()) { > + LOG(SimplePipeline, Error) > + << "Processed stream requsted but no corresponding output configuration found"; s/requsted/requested > + return nullptr; > + } > + if (rawRequested && rawFormats.empty()) { > + LOG(SimplePipeline, Error) > + << "Raw stream requsted but no corresponding output configuration found"; Ditto. Reviewed-by: Umang Jain <uajain@igalia.com> > + 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 > * map as the default, 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) { > + const auto &formats = (role == StreamRole::Raw ? rawFormats : processedFormats); > StreamConfiguration cfg{ StreamFormats{ formats } }; > cfg.pixelFormat = formats.begin()->first; > cfg.size = formats.begin()->second[0].max; > -- > 2.51.0 >
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 1f67094db..d7675538f 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1343,42 +1343,75 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo if (roles.empty()) return config; - /* Create the formats map. */ - std::map<PixelFormat, std::vector<SizeRange>> formats; + bool processedRequested = false; + bool rawRequested = false; + for (const auto &role : roles) + if (role == StreamRole::Raw) { + if (rawRequested) { + LOG(SimplePipeline, Error) + << "Can't capture multiple raw streams"; + return nullptr; + } + rawRequested = true; + } else { + processedRequested = true; + } + + /* Create the formats maps. */ + std::map<PixelFormat, std::vector<SizeRange>> processedFormats; + std::map<PixelFormat, std::vector<SizeRange>> rawFormats; for (const SimpleCameraData::Configuration &cfg : data->configs_) { + rawFormats[cfg.captureFormat].push_back(cfg.captureSize); for (PixelFormat format : cfg.outputFormats) - formats[format].push_back(cfg.outputSizes); + processedFormats[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; - } - - sizes.erase(++cur, sizes.end()); + if (processedRequested && processedFormats.empty()) { + LOG(SimplePipeline, Error) + << "Processed stream requsted but no corresponding output configuration found"; + return nullptr; + } + if (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 * map as the default, 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) { + const auto &formats = (role == StreamRole::Raw ? rawFormats : processedFormats); StreamConfiguration cfg{ StreamFormats{ formats } }; cfg.pixelFormat = formats.begin()->first; cfg.size = formats.begin()->second[0].max;
Let's handle both processed and/or raw output configurations. In addition to the already handled processed formats and sizes, this patch adds handling of raw formats and sizes, which correspond to the capture formats and sizes. When creating stream configurations, raw or processed formats are selected according to the requested stream roles. This is another preparatory patch without making raw outputs working. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> --- src/libcamera/pipeline/simple/simple.cpp | 79 +++++++++++++++++------- 1 file changed, 56 insertions(+), 23 deletions(-)