<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<pre class="elementToProof" style="margin: 0px 0px 10px; padding: 9.5px; border-radius: 0px; display: block;"><pre class="elementToProof" style="margin: 0px 0px 10px; padding: 9.5px; border-radius: 0px; display: block;"><div class="elementToProof" style="text-align: left; text-indent: 0px; line-height: 14.3px; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);"> Although one pipeline handler for 2 sensors, the specific "Camera" is passed to SimplePipelineHandler's interfaces, so will not mess up if 2 cameras work at same time.</div><div class="elementToProof" style="text-align: left; text-indent: 0px; line-height: 14.3px; white-space: normal; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);"><br></div><div class="elementToProof" style="text-align: left; text-indent: 0px; line-height: 14.3px; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">BRs,</div><div class="elementToProof" style="text-align: left; text-indent: 0px; line-height: 14.3px; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">Fang Hui</div></pre></pre>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Hui Fang<br>
<b>Sent:</b> Wednesday, June 4, 2025 5:16 PM<br>
<b>To:</b> Kieran Bingham <kieran.bingham@ideasonboard.com>; libcamera-devel@lists.libcamera.org <libcamera-devel@lists.libcamera.org><br>
<b>Cc:</b> jacopo.mondi@ideasonboard.com <jacopo.mondi@ideasonboard.com>; mzamazal@redhat.com <mzamazal@redhat.com>; dan.scally@ideasonboard.com <dan.scally@ideasonboard.com>; Antoine Bouyer <antoine.bouyer@nxp.com>; Julien Vuillaumier <julien.vuillaumier@nxp.com><br>
<b>Subject:</b> RE: [EXT] Re: [PATCH] libcamera: simple: Check all media devices matched the pipeline</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi, Kieran<br>
As you mentioned, there's a similar patch <a href="https://patchwork.libcamera.org/patch/20849/">
https://patchwork.libcamera.org/patch/20849/</a>, is there plan to merge it?<br>
Also I have already tested that 2 sensors work ok at same time. Are there other concerns? Thanks!<br>
<br>
<br>
BRs,<br>
Fang Hui<br>
<br>
> -----Original Message-----<br>
> From: Hui Fang<br>
> Sent: 2025年2月28日 16:39<br>
> To: 'Kieran Bingham' <kieran.bingham@ideasonboard.com>;<br>
> 'libcamera-devel@lists.libcamera.org' <libcamera-devel@lists.libcamera.org><br>
> Cc: 'jacopo.mondi@ideasonboard.com' <jacopo.mondi@ideasonboard.com>;<br>
> 'mzamazal@redhat.com' <mzamazal@redhat.com>;<br>
> 'dan.scally@ideasonboard.com' <dan.scally@ideasonboard.com>; Antoine<br>
> Bouyer <antoine.bouyer@nxp.com>; Julien Vuillaumier<br>
> <julien.vuillaumier@nxp.com><br>
> Subject: RE: [EXT] Re: [PATCH] libcamera: simple: Check all media devices<br>
> matched the pipeline<br>
> <br>
> Use "cam" to capture from 2 cameras at same time, ok.<br>
> <br>
> export W=1920<br>
> export H=1080<br>
> cam \<br>
> --camera 1 \<br>
> --stream width=${W},height=${H},pixelformat=YUYV \<br>
> --file=frame-#.yuv \<br>
> --capture=5 \<br>
> --camera 2 \<br>
> --stream width=${W},height=${H},pixelformat=YUYV \<br>
> --file=frame-#.yuv \<br>
> --capture=5<br>
> <br>
> Using camera<br>
> /base/soc@0/bus@30800000/i2c@30a20000/ov5640_mipi2@3c as cam0<br>
> Using camera<br>
> /base/soc@0/bus@30800000/i2c@30a30000/ov5640_mipi@3c as cam1<br>
> cam0: Capture 5 frames<br>
> cam1: Capture 5 frames<br>
> <br>
> 17475.769932 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 4147200<br>
> 17475.784579 (0.00 fps) cam1-stream0 seq: 000000 bytesused: 4147200<br>
> 17475.817831 (30.07 fps) cam1-stream0 seq: 000001 bytesused: 4147200<br>
> 17475.836441 (15.04 fps) cam0-stream0 seq: 000002 bytesused: 4147200<br>
> 17475.851084 (30.07 fps) cam1-stream0 seq: 000002 bytesused: 4147200<br>
> 17475.869695 (30.07 fps) cam0-stream0 seq: 000003 bytesused: 4147200<br>
> 17475.884338 (30.07 fps) cam1-stream0 seq: 000003 bytesused: 4147200<br>
> 17475.902949 (30.07 fps) cam0-stream0 seq: 000004 bytesused: 4147200<br>
> 17475.936202 (30.07 fps) cam0-stream0 seq: 000005 bytesused: 4147200<br>
> 17475.984099 (10.02 fps) cam1-stream0 seq: 000006 bytesused: 4147200<br>
> <br>
> <br>
> BRs,<br>
> Fang Hui<br>
> <br>
> > -----Original Message-----<br>
> > From: Hui Fang<br>
> > Sent: 2025年2月28日 15:43<br>
> > To: 'Kieran Bingham' <<a href="mailto:kieran.bingham@ideasonboard.com">mailto:kieran.bingham@ideasonboard.com</a>>;<br>
> > 'libcamera-devel@lists.libcamera.org'<br>
> > <<a href="mailto:libcamera-devel@lists.libcamera.org">mailto:libcamera-devel@lists.libcamera.org</a>><br>
> > Cc: 'jacopo.mondi@ideasonboard.com'<br>
> <<a href="mailto:jacopo.mondi@ideasonboard.com">mailto:jacopo.mondi@ideasonboard.com</a>>;<br>
> > 'mzamazal@redhat.com' <<a href="mailto:mzamazal@redhat.com">mailto:mzamazal@redhat.com</a>>;<br>
> > 'dan.scally@ideasonboard.com' <<a href="mailto:dan.scally@ideasonboard.com">mailto:dan.scally@ideasonboard.com</a>>; Antoine<br>
> > Bouyer <<a href="mailto:antoine.bouyer@nxp.com">mailto:antoine.bouyer@nxp.com</a>>; Julien Vuillaumier<br>
> > <<a href="mailto:julien.vuillaumier@nxp.com">mailto:julien.vuillaumier@nxp.com</a>><br>
> > Subject: RE: [EXT] Re: [PATCH] libcamera: simple: Check all media<br>
> > devices matched the pipeline<br>
> ><br>
> > Checked, my patch is similar as<br>
> > <a href="https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatc">
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatc</a><br>
> > h<br>
> ><br>
> work.libcamera.org%2Fpatch%2F20849%2F&data=05%7C02%7Chui.fang%40<br>
> ><br>
> nxp.com%7C7df77e1abad34fc20d4908dd5768dfd0%7C686ea1d3bc2b4c6fa9<br>
> ><br>
> 2cd99c5c301635%7C0%7C0%7C638762830140008274%7CUnknown%7CTW<br>
> ><br>
> FpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW<br>
> ><br>
> 4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Y1vZOi<br>
> > FLPsKslaQ9QjnsgWzAXfVdy6NZ%2BpZc1Gedl%2Fo%3D&reserved=0.<br>
> ><br>
> > For the case to use 2 cameras at same time, if the specific "Camera"<br>
> > is passed to SimplePipelineHandler's interfaces, maybe should ok?<br>
> > Need test to verity.<br>
> ><br>
> > BRs,<br>
> > Fang Hui<br>
> ><br>
> > > -----Original Message-----<br>
> > > From: Hui Fang<br>
> > > Sent: 2025年2月28日 14:17<br>
> > > To: 'Kieran Bingham' <<a href="mailto:kieran.bingham@ideasonboard.com">mailto:kieran.bingham@ideasonboard.com</a>>;<br>
> > > <a href="mailto:libcamera-devel@lists.libcamera.org">mailto:libcamera-devel@lists.libcamera.org</a><br>
> > > Cc: <a href="mailto:jacopo.mondi@ideasonboard.com">mailto:jacopo.mondi@ideasonboard.com</a>;
<a href="mailto:mzamazal@redhat.com">mailto:mzamazal@redhat.com</a>;<br>
> > > <a href="mailto:dan.scally@ideasonboard.com">mailto:dan.scally@ideasonboard.com</a>; Antoine Bouyer<br>
> > <<a href="mailto:antoine.bouyer@nxp.com">mailto:antoine.bouyer@nxp.com</a>>;<br>
> > > Julien Vuillaumier <<a href="mailto:julien.vuillaumier@nxp.com">mailto:julien.vuillaumier@nxp.com</a>><br>
> > > Subject: RE: [EXT] Re: [PATCH] libcamera: simple: Check all media<br>
> > > devices matched the pipeline<br>
> > ><br>
> > > Hi, Bingham<br>
> > > Thanks for your reminding.<br>
> > ><br>
> > > The patch is to fix below issue:<br>
> > > wevk_8mq has 2 camera slots, if just 1 slot plug sensor, if may<br>
> > mis-discovered.<br>
> > > There's 2 media deivces, suggest mediaA(with sensor), mediaB(no<br>
> > > sensor). If mediaB is in the 1st place (depends of readdir()) of the<br>
> > > enumerator,<br>
> > > pipe->match(enumerator_.get() return false and mediaA has no chance<br>
> > > pipe->to be<br>
> > > discovered.<br>
> > ><br>
> > > Ref code in camera_manager.cpp<br>
> > > void CameraManager::Private::pipelineFactoryMatch(const<br>
> > > PipelineHandlerFactoryBase *factory) {<br>
> > > CameraManager *const o = LIBCAMERA_O_PTR();<br>
> > ><br>
> > > /* Provide as many matching pipelines as possible. */<br>
> > > while (1) {<br>
> > > std::shared_ptr<PipelineHandler> pipe = factory->create(o);<br>
> > > if (!pipe->match(enumerator_.get()))<br>
> > > break;<br>
> > ><br>
> > > LOG(Camera, Debug)<br>
> > > << "Pipeline handler \"" << factory->name()<br>
> > > << "\" matched";<br>
> > > }<br>
> > > }<br>
> > ><br>
> > ><br>
> > > I tested on android, APP/CTS just switch back/front camera, no case<br>
> > > to use 2 cameras at same time.<br>
> > > Since the specific "Camera" is register to CameraManager and passed<br>
> > > to SimplePipelineHandler, so no issue.<br>
> > ><br>
> > > But if there's case to use 2 cameras at same time, should have issue.<br>
> > ><br>
> > > Maybe the best resolution is in driver, don't create a media device<br>
> > > if no sensor plugged in the media graph.<br>
> > ><br>
> > ><br>
> > > BRs,<br>
> > > Fang Hui<br>
> > ><br>
> > > > -----Original Message-----<br>
> > > > From: Kieran Bingham <<a href="mailto:kieran.bingham@ideasonboard.com">mailto:kieran.bingham@ideasonboard.com</a>><br>
> > > > Sent: 2025年2月28日 3:57<br>
> > > > To: Hui Fang <<a href="mailto:hui.fang@nxp.com">mailto:hui.fang@nxp.com</a>>;<br>
> > > > <a href="mailto:libcamera-devel@lists.libcamera.org">mailto:libcamera-devel@lists.libcamera.org</a><br>
> > > > Cc: <a href="mailto:jacopo.mondi@ideasonboard.com">mailto:jacopo.mondi@ideasonboard.com</a>;
<a href="mailto:mzamazal@redhat.com">mailto:mzamazal@redhat.com</a>;<br>
> > > > <a href="mailto:dan.scally@ideasonboard.com">mailto:dan.scally@ideasonboard.com</a>; Hui Fang <<a href="mailto:hui.fang@nxp.com">mailto:hui.fang@nxp.com</a>>; Antoine<br>
> > > > Bouyer <<a href="mailto:antoine.bouyer@nxp.com">mailto:antoine.bouyer@nxp.com</a>><br>
> > > > Subject: [EXT] Re: [PATCH] libcamera: simple: Check all media<br>
> > > > devices matched the pipeline<br>
> > > ><br>
> > > > Caution: This is an external email. Please take care when clicking<br>
> > > > links or opening attachments. When in doubt, report the message<br>
> > > > using the 'Report this email' button<br>
> > > ><br>
> > > ><br>
> > > > Hi Fang,<br>
> > > ><br>
> > > > Quoting Fang Hui (2025-02-25 02:10:23)<br>
> > > > > The current implementation of SimplePipelineHandler::match()<br>
> > > > > will return false once meet an un-complete media device such as<br>
> > > > > no sensor plugged. Thus the rest media devices will lost the<br>
> > > > > chance to be<br>
> > > discovered.<br>
> > > > > To discover all the cameras present, this change instanciates<br>
> > > > > the cameras discovery procedure for each media device that<br>
> > > > > contains a<br>
> > > > supported camera port.<br>
> > > > ><br>
> > > > > Signed-off-by: Fang Hui <<a href="mailto:hui.fang@nxp.com">mailto:hui.fang@nxp.com</a>><br>
> > > > > ---<br>
> > > > > src/libcamera/pipeline/simple/simple.cpp | 50<br>
> > > > > +++++++++++++++++-------<br>
> > > > > 1 file changed, 35 insertions(+), 15 deletions(-)<br>
> > > > ><br>
> > > > > diff --git a/src/libcamera/pipeline/simple/simple.cpp<br>
> > > > > b/src/libcamera/pipeline/simple/simple.cpp<br>
> > > > > index 6e039bf3..134f0a07 100644<br>
> > > > > --- a/src/libcamera/pipeline/simple/simple.cpp<br>
> > > > > +++ b/src/libcamera/pipeline/simple/simple.cpp<br>
> > > > > @@ -379,6 +379,8 @@ private:<br>
> > > > > const MediaPad *acquirePipeline(SimpleCameraData<br>
> *data);<br>
> > > > > void releasePipeline(SimpleCameraData *data);<br>
> > > > ><br>
> > > > > + bool matchMedia(DeviceEnumerator *enumerator, const<br>
> > > > > + SimplePipelineInfo *info, MediaDevice *media);<br>
> > > > > +<br>
> > > > > std::map<const MediaEntity *, EntityData> entities_;<br>
> > > > ><br>
> > > > > MediaDevice *converter_; @@ -1532,23 +1534,9 @@ int<br>
> > > > SimplePipelineHandler::resetRoutingTable(V4L2Subdevice *subdev)<br>
> > > > > return 0;<br>
> > > > > }<br>
> > > > ><br>
> > > > > -bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)<br>
> > > > > +bool SimplePipelineHandler::matchMedia(DeviceEnumerator<br>
> > > > > +*enumerator, const SimplePipelineInfo *info, MediaDevice<br>
> > > > > +*media)<br>
> > > > > {<br>
> > > > > - const SimplePipelineInfo *info = nullptr;<br>
> > > > > unsigned int numStreams = 1;<br>
> > > > > - MediaDevice *media;<br>
> > > > > -<br>
> > > > > - for (const SimplePipelineInfo &inf : supportedDevices) {<br>
> > > > > - DeviceMatch dm(inf.driver);<br>
> > > > > - media = acquireMediaDevice(enumerator, dm);<br>
> > > > > - if (media) {<br>
> > > > > - info = &inf;<br>
> > > > > - break;<br>
> > > > > - }<br>
> > > > > - }<br>
> > > > > -<br>
> > > > > - if (!media)<br>
> > > > > - return false;<br>
> > > > ><br>
> > > > > for (const auto &[name, streams] : info->converters) {<br>
> > > > > DeviceMatch converterMatch(name); @@<br>
> -1678,6<br>
> > > > +1666,38<br>
> > > > > @@ bool SimplePipelineHandler::match(DeviceEnumerator<br>
> > *enumerator)<br>
> > > > > return registered;<br>
> > > > > }<br>
> > > > ><br>
> > > > > +bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)<br>
> {<br>
> > > > > + MediaDevice *media;<br>
> > > > > + std::map<MediaDevice *, const SimplePipelineInfo *><br>
> > > > > +mediaDevices;<br>
> > > > > +<br>
> > > > > + for (const SimplePipelineInfo &inf : supportedDevices) {<br>
> > > > > + LOG(SimplePipeline, Debug) << "check simple<br>
> > > > > + pipeline<br>
> > > "<br>
> > > > << inf.driver;<br>
> > > > > + DeviceMatch dm(inf.driver);<br>
> > > > > +<br>
> > > > > + do {<br>
> > > > > + media =<br>
> acquireMediaDevice(enumerator,<br>
> > > > dm);<br>
> > > > > + if (media) {<br>
> > > > > + mediaDevices[media] = &inf;<br>
> > > > > + LOG(SimplePipeline, Debug) <<<br>
> > > > "found media " << media->deviceNode();<br>
> > > > > + }<br>
> > > > > + } while (media);<br>
> > > > > + }<br>
> > > > > +<br>
> > > > > + bool matched = false;<br>
> > > > > +<br>
> > > > > + for (auto it = mediaDevices.begin(); it !=<br>
> > > > > + mediaDevices.end(); it++)<br>
> > > > {<br>
> > > > > + MediaDevice *media = it->first;<br>
> > > > > + const SimplePipelineInfo *info = it->second;<br>
> > > > > + LOG(SimplePipeline, Debug)<br>
> > > > > + << "call matchMedia for pipeline "<br>
> > > > > + << info->driver << ", media " <<<br>
> > > > media->deviceNode();<br>
> > > > > + matched |= matchMedia(enumerator, info,<br>
> media);<br>
> > > > > + }<br>
> > > ><br>
> > > > I'm not 100% sure I understand the implications here. I also tried<br>
> > > > to tackle this topic at<br>
> > > > <a href="https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2F">
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2F</a><br>
> > > > pa<br>
> > > > tc<br>
> > > > h<br>
> > > ><br>
> > ><br>
> ><br>
> work.libcamera.org%2Fpatch%2F20849%2F&data=05%7C02%7Chui.fang%40<br>
> > > ><br>
> > ><br>
> ><br>
> nxp.com%7C7df77e1abad34fc20d4908dd5768dfd0%7C686ea1d3bc2b4c6fa9<br>
> > > ><br>
> > ><br>
> ><br>
> 2cd99c5c301635%7C0%7C0%7C638762830140008274%7CUnknown%7CTW<br>
> > > ><br>
> > ><br>
> ><br>
> FpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW<br>
> > > ><br>
> > ><br>
> ><br>
> 4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Y1vZOi<br>
> > > > FLPsKslaQ9QjnsgWzAXfVdy6NZ%2BpZc1Gedl%2Fo%3D&reserved=0,<br>
> and I<br>
> > > see<br>
> > > > your version differs slightly that first you will try to find all<br>
> > > > compatible graphs, but then match each of the successfully acquired<br>
> ones.<br>
> > > ><br>
> > > > But I think this will be problematic as you will then register (or<br>
> > > > try to register) multiple graphs in a single pipeline handler ?<br>
> > > ><br>
> > > > Have you checked what happens here if there are more than one<br>
> > > > simple pipeline handler supported in the system ?<br>
> > > ><br>
> > > ><br>
> > > ><br>
> > > > > +<br>
> > > > > + return matched;<br>
> > > > > +}<br>
> > > > > +<br>
> > > > > V4L2VideoDevice *SimplePipelineHandler::video(const MediaEntity<br>
> > > > > *entity) {<br>
> > > > > auto iter = entities_.find(entity);<br>
> > > > > --<br>
> > > > > 2.25.1<br>
> > > > ><br>
</div>
</span></font></div>
</body>
</html>