[PATCH] libcamera: simple: Check all media devices matched the pipeline

Fang Hui hui.fang at nxp.com
Tue Feb 25 03:10:23 CET 2025


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);
+	}
+
+	return matched;
+}
+
 V4L2VideoDevice *SimplePipelineHandler::video(const MediaEntity *entity)
 {
 	auto iter = entities_.find(entity);
-- 
2.25.1



More information about the libcamera-devel mailing list