From patchwork Tue Aug 8 12:52:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18930 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 4D495BDB13 for ; Tue, 8 Aug 2023 12:52:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EF09A627EF; Tue, 8 Aug 2023 14:52:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499175; bh=pSSxhla5CU9zLBFJD8ZnASnLfCNOxKaWLO3D5RiG0mc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=UMt1dRaKthKWomRlRYul8JytVK2Hl2eDXzDGD+np/6zy8E/smqTkltizsjXOGji9y bwprtd+dBUrLL1GdWQYSqVwGpFjoxUqXpfFw6TnWqxtL8v/QNKcCHodIJHnhWRK1Yo 0+pzebsPwaG+iqcu7IRIT8pS/zwZD2uCsHO9OnC6vsC588gArERRDr0LSmN5KNtFIV 6F4v4kZfsMlF4uRNreu549SsJJ7/f640GcYRerWkG0WgvvD377IlYr796yn/4XSaOc W6+q0urTLnVIz9/qDs1L7vC5+8oM879RotQm4xEgNqZlOJsG3+UmECBGWxzmSZIhHf ebmccVi/Ye7rw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 35D6361E19 for ; Tue, 8 Aug 2023 14:52:48 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CHTX8Agx"; dkim-atps=neutral Received: from uno.localdomain (mob-5-90-60-22.net.vodafone.it [5.90.60.22]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5C207396B; Tue, 8 Aug 2023 14:51:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1691499100; bh=pSSxhla5CU9zLBFJD8ZnASnLfCNOxKaWLO3D5RiG0mc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CHTX8AgxqPmKGc13eG7eWv+8F/V64qXomVBMAM0UQ9ClFPQq2JzlopToWG0X/bj0F htJWuDpZ5DS5HB5FfmzF0Bmbk2hE+4fHOScjmdJ0r4YnSH/oJSzA12JXzZ8eXAOOuy a2RsfVMzx79GnRxuUYfHtgQ7f7/xGHLsXcgUkGZk= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:22 +0200 Message-Id: <20230808125228.29043-4-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230808125228.29043-1-jacopo.mondi@ideasonboard.com> References: <20230808125228.29043-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 3/9] libcamera: device_enumerator: Prepare for more device types X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 --- .../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 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 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::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 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 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 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 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);