[libcamera-devel] [PATCH 05/10] libcamera: pipeline: simple: Store all entity devices in common map

Laurent Pinchart laurent.pinchart at ideasonboard.com
Fri Aug 6 00:24:31 CEST 2021


Merge the SimplePipelineHandler videos_ and subdevs_ maps, which
respectively store V4L2 video devices and subdevices associated with
entities, into a single entities_ map that contains an EntityData
structure. This gathers all data about entities in a single place,
allowing for easy extension of entity data in the future.

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

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 99ecd640349c..6b808bfbe6fa 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -265,6 +265,11 @@ protected:
 private:
 	static constexpr unsigned int kNumInternalBuffers = 3;
 
+	struct EntityData {
+		std::unique_ptr<V4L2VideoDevice> video;
+		std::unique_ptr<V4L2Subdevice> subdev;
+	};
+
 	SimpleCameraData *cameraData(const Camera *camera)
 	{
 		return static_cast<SimpleCameraData *>(
@@ -278,8 +283,7 @@ private:
 	void converterOutputDone(FrameBuffer *buffer);
 
 	MediaDevice *media_;
-	std::map<const MediaEntity *, std::unique_ptr<V4L2VideoDevice>> videos_;
-	std::map<const MediaEntity *, V4L2Subdevice> subdevs_;
+	std::map<const MediaEntity *, EntityData> entities_;
 
 	std::unique_ptr<SimpleConverter> converter_;
 
@@ -1064,24 +1068,25 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
 		return false;
 
 	/*
-	 * Create and open V4L2Subdevice instances for all entities
-	 * corresponding to a V4L2 subdevice.
+	 * Insert all entities in the global entities list. Create and open
+	 * V4L2Subdevice instances for each entity corresponding to a V4L2
+	 * subdevice.
 	 */
 	for (MediaEntity *entity : entities) {
-		if (entity->type() != MediaEntity::Type::V4L2Subdevice)
-			continue;
+		std::unique_ptr<V4L2Subdevice> subdev;
 
-		auto elem = subdevs_.emplace(std::piecewise_construct,
-					     std::forward_as_tuple(entity),
-					     std::forward_as_tuple(entity));
-		V4L2Subdevice *subdev = &elem.first->second;
-		int ret = subdev->open();
-		if (ret < 0) {
-			LOG(SimplePipeline, Error)
-				<< "Failed to open " << subdev->deviceNode()
-				<< ": " << strerror(-ret);
-			return false;
+		if (entity->type() == MediaEntity::Type::V4L2Subdevice) {
+			subdev = std::make_unique<V4L2Subdevice>(entity);
+			int ret = subdev->open();
+			if (ret < 0) {
+				LOG(SimplePipeline, Error)
+					<< "Failed to open " << subdev->deviceNode()
+					<< ": " << strerror(-ret);
+				return false;
+			}
 		}
+
+		entities_[entity] = { nullptr, std::move(subdev) };
 	}
 
 	/* Initialize each pipeline and register a corresponding camera. */
@@ -1114,28 +1119,30 @@ V4L2VideoDevice *SimplePipelineHandler::video(const MediaEntity *entity)
 	 * by constructing a new one.
 	 */
 
-	auto iter = videos_.find(entity);
-	if (iter != videos_.end())
-		return iter->second.get();
+	auto iter = entities_.find(entity);
+	if (iter == entities_.end())
+		return nullptr;
+
+	EntityData &data = iter->second;
+	if (data.video)
+		return data.video.get();
 
-	std::unique_ptr<V4L2VideoDevice> video =
-		std::make_unique<V4L2VideoDevice>(entity);
-	if (video->open() < 0)
+	data.video = std::make_unique<V4L2VideoDevice>(entity);
+	if (data.video->open() < 0)
 		return nullptr;
 
-	video->bufferReady.connect(this, &SimplePipelineHandler::bufferReady);
+	data.video->bufferReady.connect(this, &SimplePipelineHandler::bufferReady);
 
-	auto element = videos_.emplace(entity, std::move(video));
-	return element.first->second.get();
+	return data.video.get();
 }
 
 V4L2Subdevice *SimplePipelineHandler::subdev(const MediaEntity *entity)
 {
-	auto iter = subdevs_.find(entity);
-	if (iter == subdevs_.end())
+	auto iter = entities_.find(entity);
+	if (iter == entities_.end())
 		return nullptr;
 
-	return &iter->second;
+	return iter->second.subdev.get();
 }
 
 /* -----------------------------------------------------------------------------
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list