[libcamera-devel] [PATCH 1/4] libcamera: device_enumerator: Emit a signal when a new device is hotplugged

Umang Jain email at uajain.com
Wed May 6 12:33:52 CEST 2020


Emit a signal whenever is a new MediaDevice is added to the
DeviceEnumerator. This will allow CameraManager to get notified
about the new devices that have been hot-plugged.

Signed-off-by: Umang Jain <email at uajain.com>
---
 src/libcamera/camera_manager.cpp          | 27 +++++++++++++++++++++--
 src/libcamera/device_enumerator.cpp       | 10 +++++++++
 src/libcamera/include/device_enumerator.h |  3 +++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index fddf734..c75979a 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -54,6 +54,7 @@ protected:
 private:
 	int init();
 	void cleanup();
+	void enumerateNewDevices(DeviceEnumerator *enumerator);
 
 	CameraManager *cm_;
 
@@ -144,14 +145,36 @@ int CameraManager::Private::init()
 		}
 	}
 
-	/* TODO: register hot-plug callback here */
+	enumerator_->newDevicesFound.connect(this, &CameraManager::Private::enumerateNewDevices);
 
 	return 0;
 }
 
+void CameraManager::Private::enumerateNewDevices(DeviceEnumerator *enumerator)
+{
+	std::vector<PipelineHandlerFactory *> &factories = PipelineHandlerFactory::factories();
+
+	for (PipelineHandlerFactory *factory : factories) {
+		/*
+		 * Try each pipeline handler until it exhaust
+		 * all pipelines it can provide.
+		 */
+		while (1) {
+			std::shared_ptr<PipelineHandler> pipe = factory->create(cm_);
+			if (!pipe->match(enumerator_.get()))
+				break;
+
+			LOG(Camera, Debug)
+				<< "Pipeline handler \"" << factory->name()
+				<< "\" matched";
+			pipes_.push_back(std::move(pipe));
+		}
+	}
+}
+
 void CameraManager::Private::cleanup()
 {
-	/* TODO: unregister hot-plug callback here */
+	enumerator_->newDevicesFound.disconnect(this, &CameraManager::Private::enumerateNewDevices);
 
 	/*
 	 * Release all references to cameras and pipeline handlers to ensure
diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp
index dd17e3e..2721120 100644
--- a/src/libcamera/device_enumerator.cpp
+++ b/src/libcamera/device_enumerator.cpp
@@ -227,6 +227,15 @@ std::unique_ptr<MediaDevice> DeviceEnumerator::createDevice(const std::string &d
 	return media;
 }
 
+/**
+ * \var DeviceEnumerator::newDevicesFound
+ * \brief Signal emitted when a new MediaDevice is added to the DeviceEnumerator
+ *
+ * CameraManager connects to this signal to know about new MediaDevices being plugged-in,
+ * while it is running. CameraManager will then iterate over the DeviceEnumerator, to match
+ * their respective pipeline-handlers and prepare the newly plugged-in device for use.
+ */
+
 /**
  * \brief Add a media device to the enumerator
  * \param[in] media media device instance to add
@@ -242,6 +251,7 @@ void DeviceEnumerator::addDevice(std::unique_ptr<MediaDevice> &&media)
 		<< "Added device " << media->deviceNode() << ": " << media->driver();
 
 	devices_.push_back(std::move(media));
+	newDevicesFound.emit(this);
 }
 
 /**
diff --git a/src/libcamera/include/device_enumerator.h b/src/libcamera/include/device_enumerator.h
index 433e357..6cc6ec2 100644
--- a/src/libcamera/include/device_enumerator.h
+++ b/src/libcamera/include/device_enumerator.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <libcamera/signal.h>
 #include <linux/media.h>
 
 namespace libcamera {
@@ -43,6 +44,8 @@ public:
 
 	std::shared_ptr<MediaDevice> search(const DeviceMatch &dm);
 
+	Signal<DeviceEnumerator *> newDevicesFound;
+
 protected:
 	std::unique_ptr<MediaDevice> createDevice(const std::string &deviceNode);
 	void addDevice(std::unique_ptr<MediaDevice> &&media);
-- 
2.26.2



More information about the libcamera-devel mailing list