[libcamera-devel,04/10] libcamera: pipeline: simple: Store video node entity in camera data
diff mbox series

Message ID 20210805222436.6263-5-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • Concurrent camera support in simple pipeline handler
Related show

Commit Message

Laurent Pinchart Aug. 5, 2021, 10:24 p.m. UTC
Store the entity corresponding to the video node at the end of the
pipeline in the SimpleCameraData::entities_ list. This requires special
handling of the video node in the loops that iterate over all entities,
but will be useful to implement mutually exclusive access to entities
for concurrent camera usage.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/libcamera/pipeline/simple/simple.cpp | 29 ++++++++++++++++++++----
 1 file changed, 24 insertions(+), 5 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 744f842dbfe6..99ecd640349c 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -194,8 +194,13 @@  public:
 	};
 
 	std::vector<Stream> streams_;
-	std::unique_ptr<CameraSensor> sensor_;
+
+	/*
+	 * All entities in the pipeline, from the camera sensor to the video
+	 * node.
+	 */
 	std::list<Entity> entities_;
+	std::unique_ptr<CameraSensor> sensor_;
 	V4L2VideoDevice *video_;
 
 	std::vector<Configuration> configs_;
@@ -309,12 +314,11 @@  SimpleCameraData::SimpleCameraData(SimplePipelineHandler *pipe,
 	std::unordered_map<MediaEntity *, Entity> parents;
 	MediaEntity *entity = nullptr;
 	MediaEntity *video = nullptr;
+	MediaPad *sinkPad;
 
 	queue.push({ sensor, nullptr });
 
 	while (!queue.empty()) {
-		MediaPad *sinkPad;
-
 		std::tie(entity, sinkPad) = queue.front();
 		queue.pop();
 
@@ -347,8 +351,11 @@  SimpleCameraData::SimpleCameraData(SimplePipelineHandler *pipe,
 
 	/*
 	 * With the parents, we can follow back our way from the capture device
-	 * to the sensor.
+	 * 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 });
+
 	for (auto it = parents.find(entity); it != parents.end();
 	     it = parents.find(entity)) {
 		const Entity &e = it->second;
@@ -484,6 +491,9 @@  int SimpleCameraData::setupLinks()
 	 * want to enable) before enabling the pipeline link.
 	 */
 	for (SimpleCameraData::Entity &e : entities_) {
+		if (!e.link)
+			break;
+
 		MediaEntity *remote = e.link->sink()->entity();
 		for (MediaPad *pad : remote->pads()) {
 			for (MediaLink *link : pad->links()) {
@@ -524,6 +534,9 @@  int SimpleCameraData::setupFormats(V4L2SubdeviceFormat *format,
 		return ret;
 
 	for (const Entity &e : entities_) {
+		if (!e.link)
+			break;
+
 		MediaLink *link = e.link;
 		MediaPad *source = link->source();
 		MediaPad *sink = link->sink();
@@ -1050,8 +1063,14 @@  bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
 	if (entities.empty())
 		return false;
 
-	/* Create and open V4L2Subdev instances for all the entities. */
+	/*
+	 * Create and open V4L2Subdevice instances for all entities
+	 * corresponding to a V4L2 subdevice.
+	 */
 	for (MediaEntity *entity : entities) {
+		if (entity->type() != MediaEntity::Type::V4L2Subdevice)
+			continue;
+
 		auto elem = subdevs_.emplace(std::piecewise_construct,
 					     std::forward_as_tuple(entity),
 					     std::forward_as_tuple(entity));