From 796adbe28e3c28547947eebf575dd55af5d7dcf2 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Mon, 7 Aug 2023 10:42:03 +0200 Subject: libcamera: device_enumerator: Prepare for more device types 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 --- include/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 2afb9fa0..8df6a3e2 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 createDevice(const std::string &deviceNode); - void addDevice(std::unique_ptr media); - void removeDevice(const std::string &deviceNode); + std::unique_ptr createMediaDevice(const std::string &deviceNode); + void addMediaDevice(std::unique_ptr media); + void removeMediaDevice(const std::string &deviceNode); private: - std::vector> devices_; + std::vector> mediaDevices_; }; } /* namespace libcamera */ diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index 3dda0838..2ab731c6 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::create() DeviceEnumerator::~DeviceEnumerator() { - for (const std::shared_ptr &media : devices_) { + for (const std::shared_ptr &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 DeviceEnumerator::createDevice(const std::string &deviceNode) +std::unique_ptr DeviceEnumerator::createMediaDevice(const std::string &deviceNode) { std::unique_ptr media = std::make_unique(deviceNode); @@ -174,12 +178,12 @@ std::unique_ptr 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 media) +void DeviceEnumerator::addMediaDevice(std::unique_ptr 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 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 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 DeviceEnumerator::search(const MediaDeviceMatch &dm) { - for (std::shared_ptr &media : devices_) { + for (std::shared_ptr &media : mediaDevices_) { if (media->busy()) continue; diff --git a/src/libcamera/device_enumerator_sysfs.cpp b/src/libcamera/device_enumerator_sysfs.cpp index 686bb809..71730f54 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 media = createDevice(devnode); + std::unique_ptr 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 0abc1248..3cb0044a 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 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); -- cgit v1.2.1