[libcamera-devel] [PATCH 12/13] libcamera: pipeline: simple: Don't disable links carrying other streams

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Aug 1 02:05:42 CEST 2022


From: Phi-Bang Nguyen <pnguyen at baylibre.com>

If a subdev supports the internal routing API, pads unrelated to the
pipeline for a given camera sensor may carry streams for other cameras.
The link setup logic is updated to take this into account, by avoiding
disabling links to unrelated pads.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/libcamera/pipeline/simple/simple.cpp | 28 +++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 2a8811183907..c80e462bc449 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -221,6 +221,11 @@ public:
 	struct Entity {
 		/* The media entity, always valid. */
 		MediaEntity *entity;
+		/*
+		 * Whether or not the entity is a subdev that supports the
+		 * routing API.
+		 */
+		bool supportsRouting;
 		/*
 		 * The local sink pad connected to the upstream entity, null for
 		 * the camera sensor at the beginning of the pipeline.
@@ -404,9 +409,13 @@ SimpleCameraData::SimpleCameraData(SimplePipelineHandler *pipe,
 		 */
 
 		std::vector<const MediaPad *> pads;
+		bool supportsRouting = false;
 
-		if (sinkPad)
+		if (sinkPad) {
 			pads = routedSourcePads(sinkPad);
+			if (!pads.empty())
+				supportsRouting = true;
+		}
 
 		if (pads.empty()) {
 			for (const MediaPad *pad : entity->pads()) {
@@ -421,7 +430,9 @@ SimpleCameraData::SimpleCameraData(SimplePipelineHandler *pipe,
 				MediaEntity *next = link->sink()->entity();
 				if (visited.find(next) == visited.end()) {
 					queue.push({ next, link->sink() });
-					parents.insert({ next, { entity, sinkPad, pad, link } });
+
+					Entity e{ entity, supportsRouting, sinkPad, pad, link };
+					parents.insert({ next, e });
 				}
 			}
 		}
@@ -435,7 +446,7 @@ SimpleCameraData::SimpleCameraData(SimplePipelineHandler *pipe,
 	 * to the sensor. Store all the entities in the pipeline, from the
 	 * camera sensor to the video node, in entities_.
 	 */
-	entities_.push_front({ entity, sinkPad, nullptr, nullptr });
+	entities_.push_front({ entity, false, sinkPad, nullptr, nullptr });
 
 	for (auto it = parents.find(entity); it != parents.end();
 	     it = parents.find(entity)) {
@@ -617,6 +628,17 @@ int SimpleCameraData::setupLinks()
 		}
 
 		for (MediaPad *pad : e.entity->pads()) {
+			/*
+			 * If the entity supports the V4L2 internal routing API,
+			 * assume that it may carry multiple independent streams
+			 * concurrently, and only disable links on the sink and
+			 * source pads used by the pipeline.
+			 */
+			if (e.supportsRouting) {
+				if (pad != e.sink && pad != e.source)
+					continue;
+			}
+
 			for (MediaLink *link : pad->links()) {
 				if (link == sinkLink)
 					continue;
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list