[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