[libcamera-devel] [RFC 3/9] libcamera: device_enumerator: Prepare for more device types

Jacopo Mondi jacopo.mondi at ideasonboard.com
Tue Aug 8 14:52:22 CEST 2023


Modify the existing device_enumerator implementation and documentation
to prepare to support enumeration and matching of more device types than
MediaDevice instances.

Move all media device related types and function to use the
"mediaDevice" name in place of a more generic "device" and modify the
derived sysfs and udev based derived classes accordingly.

Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 .../libcamera/internal/device_enumerator.h    |  8 +--
 src/libcamera/device_enumerator.cpp           | 70 ++++++++++---------
 src/libcamera/device_enumerator_sysfs.cpp     |  4 +-
 src/libcamera/device_enumerator_udev.cpp      |  8 +--
 4 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h
index 2afb9fa0dea8..8df6a3e2ac92 100644
--- a/include/libcamera/internal/device_enumerator.h
+++ b/include/libcamera/internal/device_enumerator.h
@@ -34,12 +34,12 @@ public:
 	Signal<> devicesAdded;
 
 protected:
-	std::unique_ptr<MediaDevice> createDevice(const std::string &deviceNode);
-	void addDevice(std::unique_ptr<MediaDevice> media);
-	void removeDevice(const std::string &deviceNode);
+	std::unique_ptr<MediaDevice> createMediaDevice(const std::string &deviceNode);
+	void addMediaDevice(std::unique_ptr<MediaDevice> media);
+	void removeMediaDevice(const std::string &deviceNode);
 
 private:
-	std::vector<std::shared_ptr<MediaDevice>> devices_;
+	std::vector<std::shared_ptr<MediaDevice>> mediaDevices_;
 };
 
 } /* namespace libcamera */
diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp
index 3dda08380e6e..2ab731c68db9 100644
--- a/src/libcamera/device_enumerator.cpp
+++ b/src/libcamera/device_enumerator.cpp
@@ -17,23 +17,26 @@
 
 /**
  * \file device_enumerator.h
- * \brief Enumeration and matching of media devices
+ * \brief Enumeration and matching of camera devices
  *
- * The purpose of device enumeration and matching is to find media devices in
- * the system and map them to pipeline handlers.
+ * The purpose of device enumeration and matching is to find devices in the
+ * system from which a camera can be created and map them to pipeline handlers.
  *
- * At the core of the enumeration is the DeviceEnumerator class, responsible
- * for enumerating all media devices in the system. It handles all interactions
- * with the operating system in a platform-specific way. For each media device
- * found an instance of MediaDevice is created to store information about the
- * device gathered from the kernel through the Media Controller API.
+ * At the core of the enumeration is the DeviceEnumerator class, responsible for
+ * enumerating all devices in the system used to create cameras. It handles all
+ * interactions with the operating system in a platform-specific way. For each
+ * system device found an instance of the opportune class is created to store
+ * information about the device gathered from the kernel through the supported
+ * Linux kernel API, which include the Media Controller API, USB-based devices
+ * and more.
  *
- * The DeviceEnumerator can enumerate all or specific media devices in the
- * system. When a new media device is added the enumerator creates a
- * corresponding MediaDevice instance.
+ * The DeviceEnumerator can enumerate all or specific devices in the system.
+ * When a new device is added the enumerator creates a corresponding instance of
+ * the opportune class. In example, for each enumerated media device a
+ * MediaDevice class instance is created.
  *
  * The enumerator supports searching among enumerated devices based on criteria
- * expressed in a DeviceMatch object.
+ * expressed in a DeviceMatch derived classes instance.
  */
 
 namespace libcamera {
@@ -42,13 +45,14 @@ LOG_DEFINE_CATEGORY(DeviceEnumerator)
 
 /**
  * \class DeviceEnumerator
- * \brief Enumerate, store and search media devices
+ * \brief Enumerate, store and search system devices
  *
  * The DeviceEnumerator class is responsible for all interactions with the
- * operating system related to media devices. It enumerates all media devices
- * in the system, and for each device found creates an instance of the
- * MediaDevice class and stores it internally. The list of media devices can
- * then be searched using DeviceMatch search patterns.
+ * operating system related to camera devices. It enumerates the devices in the
+ * system from which a camera can be created, and for each device found creates
+ * an instance of the opportune class and stores it internally. The list of
+ * devices can then be searched using the corresponding DeviceMatch derived
+ * class search patterns.
  *
  * The enumerator also associates media device entities with device node paths.
  */
@@ -88,7 +92,7 @@ std::unique_ptr<DeviceEnumerator> DeviceEnumerator::create()
 
 DeviceEnumerator::~DeviceEnumerator()
 {
-	for (const std::shared_ptr<MediaDevice> &media : devices_) {
+	for (const std::shared_ptr<MediaDevice> &media : mediaDevices_) {
 		if (media->busy())
 			LOG(DeviceEnumerator, Error)
 				<< "Removing media device " << media->deviceNode()
@@ -106,15 +110,15 @@ DeviceEnumerator::~DeviceEnumerator()
 
 /**
  * \fn DeviceEnumerator::enumerate()
- * \brief Enumerate all media devices in the system
+ * \brief Enumerate all camera devices in the system
  *
- * This function finds and add all media devices in the system to the
+ * This function finds and add all camera devices in the system to the
  * enumerator. It shall be implemented by all subclasses of DeviceEnumerator
  * using system-specific methods.
  *
- * Individual media devices that can't be properly enumerated shall be skipped
- * with a warning message logged, without returning an error. Only errors that
- * prevent enumeration altogether shall be fatal.
+ * Individual devices that can't be properly enumerated shall be skipped with a
+ * warning message logged, without returning an error. Only errors that prevent
+ * enumeration altogether shall be fatal.
  *
  * \context This function is \threadbound.
  *
@@ -132,11 +136,11 @@ DeviceEnumerator::~DeviceEnumerator()
  * shall ensure that device nodes are ready to be used (for instance, if
  * applicable, by waiting for device nodes to be created and access permissions
  * to be set by the system). Once done, it shall add the media device to the
- * system with addDevice().
+ * system with addMediaDevice().
  *
  * \return Created media device instance on success, or nullptr otherwise
  */
-std::unique_ptr<MediaDevice> DeviceEnumerator::createDevice(const std::string &deviceNode)
+std::unique_ptr<MediaDevice> DeviceEnumerator::createMediaDevice(const std::string &deviceNode)
 {
 	std::unique_ptr<MediaDevice> media = std::make_unique<MediaDevice>(deviceNode);
 
@@ -174,12 +178,12 @@ std::unique_ptr<MediaDevice> DeviceEnumerator::createDevice(const std::string &d
  * This function shall be called after all members of the entities of the
  * media graph have been confirmed to be initialized.
  */
-void DeviceEnumerator::addDevice(std::unique_ptr<MediaDevice> media)
+void DeviceEnumerator::addMediaDevice(std::unique_ptr<MediaDevice> media)
 {
 	LOG(DeviceEnumerator, Debug)
 		<< "Added device " << media->deviceNode() << ": " << media->driver();
 
-	devices_.push_back(std::move(media));
+	mediaDevices_.push_back(std::move(media));
 
 	/* \todo To batch multiple additions, emit with a small delay here. */
 	devicesAdded.emit();
@@ -190,17 +194,17 @@ void DeviceEnumerator::addDevice(std::unique_ptr<MediaDevice> media)
  * \param[in] deviceNode Path to the media device to remove
  *
  * Remove the media device identified by \a deviceNode previously added to the
- * enumerator with addDevice(). The media device's MediaDevice::disconnected
- * signal is emitted.
+ * enumerator with addMediaDevice(). The media device's
+ * MediaDevice::disconnected signal is emitted.
  */
-void DeviceEnumerator::removeDevice(const std::string &deviceNode)
+void DeviceEnumerator::removeMediaDevice(const std::string &deviceNode)
 {
 	std::shared_ptr<MediaDevice> media;
 
-	for (auto iter = devices_.begin(); iter != devices_.end(); ++iter) {
+	for (auto iter = mediaDevices_.begin(); iter != mediaDevices_.end(); ++iter) {
 		if ((*iter)->deviceNode() == deviceNode) {
 			media = std::move(*iter);
-			devices_.erase(iter);
+			mediaDevices_.erase(iter);
 			break;
 		}
 	}
@@ -231,7 +235,7 @@ void DeviceEnumerator::removeDevice(const std::string &deviceNode)
  */
 std::shared_ptr<MediaDevice> DeviceEnumerator::search(const MediaDeviceMatch &dm)
 {
-	for (std::shared_ptr<MediaDevice> &media : devices_) {
+	for (std::shared_ptr<MediaDevice> &media : mediaDevices_) {
 		if (media->busy())
 			continue;
 
diff --git a/src/libcamera/device_enumerator_sysfs.cpp b/src/libcamera/device_enumerator_sysfs.cpp
index 686bb8099485..71730f54c3e8 100644
--- a/src/libcamera/device_enumerator_sysfs.cpp
+++ b/src/libcamera/device_enumerator_sysfs.cpp
@@ -73,7 +73,7 @@ int DeviceEnumeratorSysfs::enumerate()
 			continue;
 		}
 
-		std::unique_ptr<MediaDevice> media = createDevice(devnode);
+		std::unique_ptr<MediaDevice> media = createMediaDevice(devnode);
 		if (!media)
 			continue;
 
@@ -85,7 +85,7 @@ int DeviceEnumeratorSysfs::enumerate()
 			continue;
 		}
 
-		addDevice(std::move(media));
+		addMediaDevice(std::move(media));
 	}
 
 	closedir(dir);
diff --git a/src/libcamera/device_enumerator_udev.cpp b/src/libcamera/device_enumerator_udev.cpp
index 0abc1248887b..3cb0044a9434 100644
--- a/src/libcamera/device_enumerator_udev.cpp
+++ b/src/libcamera/device_enumerator_udev.cpp
@@ -78,7 +78,7 @@ int DeviceEnumeratorUdev::addUdevDevice(struct udev_device *dev)
 
 	if (!strcmp(subsystem, "media")) {
 		std::unique_ptr<MediaDevice> media =
-			createDevice(udev_device_get_devnode(dev));
+			createMediaDevice(udev_device_get_devnode(dev));
 		if (!media)
 			return -ENODEV;
 
@@ -106,7 +106,7 @@ int DeviceEnumeratorUdev::addUdevDevice(struct udev_device *dev)
 			return 0;
 		}
 
-		addDevice(std::move(media));
+		addMediaDevice(std::move(media));
 		return 0;
 	}
 
@@ -322,7 +322,7 @@ int DeviceEnumeratorUdev::addV4L2Device(dev_t devnum)
 		LOG(DeviceEnumerator, Debug)
 			<< "All dependencies for media device "
 			<< deps->media_->deviceNode() << " found";
-		addDevice(std::move(deps->media_));
+		addMediaDevice(std::move(deps->media_));
 		pending_.remove(*deps);
 	}
 
@@ -343,7 +343,7 @@ void DeviceEnumeratorUdev::udevNotify()
 	} else if (action == "remove") {
 		const char *subsystem = udev_device_get_subsystem(dev);
 		if (subsystem && !strcmp(subsystem, "media"))
-			removeDevice(std::string(deviceNode));
+			removeMediaDevice(std::string(deviceNode));
 	}
 
 	udev_device_unref(dev);
-- 
2.40.1



More information about the libcamera-devel mailing list