[PATCH] libcamera: simple: Check all media devices matched the pipeline
Kieran Bingham
kieran.bingham at ideasonboard.com
Thu Feb 27 20:56:46 CET 2025
Hi Fang,
Quoting Fang Hui (2025-02-25 02:10:23)
> The current implementation of SimplePipelineHandler::match() will return false
> once meet an un-complete media device such as no sensor plugged. Thus the rest
> media devices will lost the chance to be discovered.
> To discover all the cameras present, this change instanciates the cameras
> discovery procedure for each media device that contains a supported camera port.
>
> Signed-off-by: Fang Hui <hui.fang at nxp.com>
> ---
> src/libcamera/pipeline/simple/simple.cpp | 50 +++++++++++++++++-------
> 1 file changed, 35 insertions(+), 15 deletions(-)
>
> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
> index 6e039bf3..134f0a07 100644
> --- a/src/libcamera/pipeline/simple/simple.cpp
> +++ b/src/libcamera/pipeline/simple/simple.cpp
> @@ -379,6 +379,8 @@ private:
> const MediaPad *acquirePipeline(SimpleCameraData *data);
> void releasePipeline(SimpleCameraData *data);
>
> + bool matchMedia(DeviceEnumerator *enumerator, const SimplePipelineInfo *info, MediaDevice *media);
> +
> std::map<const MediaEntity *, EntityData> entities_;
>
> MediaDevice *converter_;
> @@ -1532,23 +1534,9 @@ int SimplePipelineHandler::resetRoutingTable(V4L2Subdevice *subdev)
> return 0;
> }
>
> -bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
> +bool SimplePipelineHandler::matchMedia(DeviceEnumerator *enumerator, const SimplePipelineInfo *info, MediaDevice *media)
> {
> - const SimplePipelineInfo *info = nullptr;
> unsigned int numStreams = 1;
> - MediaDevice *media;
> -
> - for (const SimplePipelineInfo &inf : supportedDevices) {
> - DeviceMatch dm(inf.driver);
> - media = acquireMediaDevice(enumerator, dm);
> - if (media) {
> - info = &inf;
> - break;
> - }
> - }
> -
> - if (!media)
> - return false;
>
> for (const auto &[name, streams] : info->converters) {
> DeviceMatch converterMatch(name);
> @@ -1678,6 +1666,38 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
> return registered;
> }
>
> +bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
> +{
> + MediaDevice *media;
> + std::map<MediaDevice *, const SimplePipelineInfo *> mediaDevices;
> +
> + for (const SimplePipelineInfo &inf : supportedDevices) {
> + LOG(SimplePipeline, Debug) << "check simple pipeline " << inf.driver;
> + DeviceMatch dm(inf.driver);
> +
> + do {
> + media = acquireMediaDevice(enumerator, dm);
> + if (media) {
> + mediaDevices[media] = &inf;
> + LOG(SimplePipeline, Debug) << "found media " << media->deviceNode();
> + }
> + } while (media);
> + }
> +
> + bool matched = false;
> +
> + for (auto it = mediaDevices.begin(); it != mediaDevices.end(); it++) {
> + MediaDevice *media = it->first;
> + const SimplePipelineInfo *info = it->second;
> + LOG(SimplePipeline, Debug)
> + << "call matchMedia for pipeline "
> + << info->driver << ", media " << media->deviceNode();
> + matched |= matchMedia(enumerator, info, media);
> + }
I'm not 100% sure I understand the implications here. I also tried to
tackle this topic at https://patchwork.libcamera.org/patch/20849/, and I
see your version differs slightly that first you will try to find all
compatible graphs, but then match each of the successfully acquired
ones.
But I think this will be problematic as you will then register (or try
to register) multiple graphs in a single pipeline handler ?
Have you checked what happens here if there are more than one simple
pipeline handler supported in the system ?
> +
> + return matched;
> +}
> +
> V4L2VideoDevice *SimplePipelineHandler::video(const MediaEntity *entity)
> {
> auto iter = entities_.find(entity);
> --
> 2.25.1
>
More information about the libcamera-devel
mailing list