From patchwork Tue Aug 8 12:52:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18928 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 C28E6C32A9 for ; Tue, 8 Aug 2023 12:52:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EF049627F0; Tue, 8 Aug 2023 14:52:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499169; bh=u/+aVEYmwldsZIs13/MxapmxB2C5bS5FSopQsWJA0vI=; 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=dlrpOgskQWJSaGK6xOGFTyjfCeoSVEOzKhPZQZCSTZlrEZFybLTZaUWVqk32KWzT3 hrP2Yl4KzJIgPZuac+sFfy/UnuiJvMFLhH+YO5fV0h2JEENCfKsSM4Qhi4qo/V1CgJ 69K3zzn/YUpafbVTnDeuprM8FuHHbILpouRgfY8D0v1j77NshWFLp65FKW8FL4Vo8w Ffo1niyK1m+hbT9rtCjINp29KNJ/yiGVeusJ/l+aJNAr2FC0fohLXTxUFlKlmNokVU 4z8jxCWIKUnDsGXFdxGX0e1dE5yvvLiWGtdrj29Q6CY037ENa+QCMdB1yZGO3SMEMU YlTkoxX44Qsnw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id ED43C60562 for ; Tue, 8 Aug 2023 14:52:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BKAal0EP"; 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 0449138B3; Tue, 8 Aug 2023 14:51:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1691499099; bh=u/+aVEYmwldsZIs13/MxapmxB2C5bS5FSopQsWJA0vI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BKAal0EPG7HCbobfixm499uHdRWaglLnpMejXEyZnKbIEtwhGBanPww9O4LniPvOA 9++eAbW0zTYil/sIFGAQcrdmz4SM4Zg+Sx4ZW3hCMrzlWbVrwyjAsTaD5kWz7nJfII gDxceWGA9fqRHgY0J6KOZy/fl4LRApxvcaJpLr2w= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:20 +0200 Message-Id: <20230808125228.29043-2-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 1/9] libcamera: Break-out DeviceMatch 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" The DeviceMatch class is defined inside the 'device_enumerator' file. Break it out to a dedicated file and header in order to expand it to support multiple matching criteria. Signed-off-by: Jacopo Mondi --- .../libcamera/internal/device_enumerator.h | 16 +--- include/libcamera/internal/device_match.h | 31 +++++++ include/libcamera/internal/meson.build | 1 + src/libcamera/device_enumerator.cpp | 73 --------------- src/libcamera/device_match.cpp | 92 +++++++++++++++++++ src/libcamera/meson.build | 1 + 6 files changed, 127 insertions(+), 87 deletions(-) create mode 100644 include/libcamera/internal/device_match.h create mode 100644 src/libcamera/device_match.cpp diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h index 72ec9a60b19a..259a9e4621ea 100644 --- a/include/libcamera/internal/device_enumerator.h +++ b/include/libcamera/internal/device_enumerator.h @@ -13,24 +13,12 @@ #include +#include "libcamera/internal/device_match.h" + namespace libcamera { class MediaDevice; -class DeviceMatch -{ -public: - DeviceMatch(const std::string &driver); - - void add(const std::string &entity); - - bool match(const MediaDevice *device) const; - -private: - std::string driver_; - std::vector entities_; -}; - class DeviceEnumerator { public: diff --git a/include/libcamera/internal/device_match.h b/include/libcamera/internal/device_match.h new file mode 100644 index 000000000000..9f190f0c8a84 --- /dev/null +++ b/include/libcamera/internal/device_match.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas On Board Oy + * + * device_match.h - Match and identify devices to create cameras with + */ + +#pragma once + +#include +#include + +namespace libcamera { + +class MediaDevice; + +class DeviceMatch +{ +public: + DeviceMatch(const std::string &driver); + + void add(const std::string &entity); + + bool match(const MediaDevice *device) const; + +private: + std::string driver_; + std::vector entities_; +}; + +}; /* namespace libcamera */ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 7f1f344014c4..169e06557106 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -25,6 +25,7 @@ libcamera_internal_headers = files([ 'device_enumerator.h', 'device_enumerator_sysfs.h', 'device_enumerator_udev.h', + 'device_match.h', 'formats.h', 'framebuffer.h', 'ipa_manager.h', diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index f2e055de6477..49afd7834db2 100644 --- a/src/libcamera/device_enumerator.cpp +++ b/src/libcamera/device_enumerator.cpp @@ -40,79 +40,6 @@ namespace libcamera { LOG_DEFINE_CATEGORY(DeviceEnumerator) -/** - * \class DeviceMatch - * \brief Description of a media device search pattern - * - * The DeviceMatch class describes a media device using properties from the - * Media Controller struct media_device_info, entity names in the media graph - * or other properties that can be used to identify a media device. - * - * The description is meant to be filled by pipeline managers and passed to a - * device enumerator to find matching media devices. - * - * A DeviceMatch is created with a specific Linux device driver in mind, - * therefore the name of the driver is a required property. One or more Entity - * names can be added as match criteria. - * - * Pipeline handlers are recommended to add entities to DeviceMatch as - * appropriare to ensure that the media device they need can be uniquely - * identified. This is useful when the corresponding kernel driver can produce - * different graphs, for instance as a result of different driver versions or - * hardware configurations, and not all those graphs are suitable for a pipeline - * handler. - */ - -/** - * \brief Construct a media device search pattern - * \param[in] driver The Linux device driver name that created the media device - */ -DeviceMatch::DeviceMatch(const std::string &driver) - : driver_(driver) -{ -} - -/** - * \brief Add a media entity name to the search pattern - * \param[in] entity The name of the entity in the media graph - */ -void DeviceMatch::add(const std::string &entity) -{ - entities_.push_back(entity); -} - -/** - * \brief Compare a search pattern with a media device - * \param[in] device The media device - * - * Matching is performed on the Linux device driver name and entity names from - * the media graph. A match is found if both the driver name matches and the - * media device contains all the entities listed in the search pattern. - * - * \return true if the media device matches the search pattern, false otherwise - */ -bool DeviceMatch::match(const MediaDevice *device) const -{ - if (driver_ != device->driver()) - return false; - - for (const std::string &name : entities_) { - bool found = false; - - for (const MediaEntity *entity : device->entities()) { - if (name == entity->name()) { - found = true; - break; - } - } - - if (!found) - return false; - } - - return true; -} - /** * \class DeviceEnumerator * \brief Enumerate, store and search media devices diff --git a/src/libcamera/device_match.cpp b/src/libcamera/device_match.cpp new file mode 100644 index 000000000000..a51b9081d398 --- /dev/null +++ b/src/libcamera/device_match.cpp @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas On Board Oy + * + * device_match.cpp - Match and identify devices to create cameras with + */ + +#include "libcamera/internal/device_match.h" + +#include "libcamera/internal/media_device.h" + +/** + * \file device_match.h + * \brief Define types and functions to identify devices used to create cameras + */ + +namespace libcamera { + +/** + * \class DeviceMatch + * \brief Description of a media device search pattern + * + * The DeviceMatch class describes a media device using properties from the + * Media Controller struct media_device_info, entity names in the media graph + * or other properties that can be used to identify a media device. + * + * The description is meant to be filled by pipeline managers and passed to a + * device enumerator to find matching media devices. + * + * A DeviceMatch is created with a specific Linux device driver in mind, + * therefore the name of the driver is a required property. One or more Entity + * names can be added as match criteria. + * + * Pipeline handlers are recommended to add entities to DeviceMatch as + * appropriare to ensure that the media device they need can be uniquely + * identified. This is useful when the corresponding kernel driver can produce + * different graphs, for instance as a result of different driver versions or + * hardware configurations, and not all those graphs are suitable for a pipeline + * handler. + */ + +/** + * \brief Construct a media device search pattern + * \param[in] driver The Linux device driver name that created the media device + */ +DeviceMatch::DeviceMatch(const std::string &driver) + : driver_(driver) +{ +} + +/** + * \brief Add a media entity name to the search pattern + * \param[in] entity The name of the entity in the media graph + */ +void DeviceMatch::add(const std::string &entity) +{ + entities_.push_back(entity); +} + +/** + * \brief Compare a search pattern with a media device + * \param[in] device The media device + * + * Matching is performed on the Linux device driver name and entity names from + * the media graph. A match is found if both the driver name matches and the + * media device contains all the entities listed in the search pattern. + * + * \return True if the media device matches the search pattern, false otherwise + */ +bool DeviceMatch::match(const MediaDevice *device) const +{ + if (driver_ != device->driver()) + return false; + + for (const std::string &name : entities_) { + bool found = false; + + for (const MediaEntity *entity : device->entities()) { + if (name == entity->name()) { + found = true; + break; + } + } + + if (!found) + return false; + } + + return true; +} + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index b24f82965764..d5562afc50c7 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -17,6 +17,7 @@ libcamera_sources = files([ 'delayed_controls.cpp', 'device_enumerator.cpp', 'device_enumerator_sysfs.cpp', + 'device_match.cpp', 'fence.cpp', 'formats.cpp', 'framebuffer.cpp', From patchwork Tue Aug 8 12:52:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18929 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 2F0FABDB13 for ; Tue, 8 Aug 2023 12:52:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B409D627F7; Tue, 8 Aug 2023 14:52:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499170; bh=9UO8Ks6Nkymmev/NMNhwFvpBCxbTK5Z3Uz4dlZfNIhc=; 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=wsml1F0AIMcvqrgP4qQK+9LkFXCgCR9IYRIs87vHIElmCen0+RaOHXDNUkyTyuVfT YgdzAdCSx5Yq5PNeziAHOwfk7MbSorX2O2F2sFqeoAjFONGqejxVgmRHRL+U6mhVpq k0zN57Ku8p623doKRVT60cn89f5o6rr8Xt5SFFUvEil8pc7TWoy+0HlLDnAnffHrSL SQUM/STSt4Qyd/d1htI+899g0nIcpJjy2Gkw5nH+Ot70nux5p0ncItPeAE27r2A9g5 R47vSWXYmq85Mwsav6Uy/bWfjz3vhg0P2Jrlh/Gb4uOpHgqcyEEeqoZ3NKcU8KQAMM eZcfjecdqkMOg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D2DFB627EE for ; Tue, 8 Aug 2023 14:52:47 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="DNeXDtwE"; 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 9182738DA; Tue, 8 Aug 2023 14:51:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1691499100; bh=9UO8Ks6Nkymmev/NMNhwFvpBCxbTK5Z3Uz4dlZfNIhc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DNeXDtwERuGDarBmMEuV2L0RDuVYrFfbukBOTfoYFc2TDC9cIbDi9hLVKw53FNofP SE0e5DOAUkGzZBljD92As6f7adn7H9IMJVZx7XTI3aPTmZ2YNRH2KeFQ9AoqaVGQ9I BbuhLCUVxcrQ4LkUSUoRLJsMISLWhoIZrx5ZN2r0= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:21 +0200 Message-Id: <20230808125228.29043-3-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 2/9] libcamera: Define and use MediaDeviceMatch 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" The xistingdevice search and match criteria implemented by libcamera only supports 'media device' based cameras, which are supported in the Linux kernel by the usage of the V4L2/MC API. Define a MediaDeviceMatch class derived from DeviceMatch and use it wherever DeviceMatch was used in order to later introduce new derived classes to support searching and matching devices of a different type. Signed-off-by: Jacopo Mondi --- Documentation/guides/pipeline-handler.rst | 10 +++--- .../libcamera/internal/device_enumerator.h | 2 +- include/libcamera/internal/device_match.h | 9 ++++-- include/libcamera/internal/pipeline_handler.h | 4 +-- src/libcamera/device_enumerator.cpp | 2 +- src/libcamera/device_match.cpp | 31 ++++++++++++++----- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 4 +-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 +- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 4 +-- src/libcamera/pipeline/simple/simple.cpp | 4 +-- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc/vimc.cpp | 2 +- src/libcamera/pipeline_handler.cpp | 3 +- test/camera-sensor.cpp | 2 +- test/delayed_controls.cpp | 2 +- test/libtest/buffer_source.cpp | 2 +- test/media_device/media_device_test.cpp | 2 +- test/v4l2_subdevice/v4l2_subdevice_test.cpp | 2 +- test/v4l2_videodevice/v4l2_m2mdevice.cpp | 2 +- .../v4l2_videodevice_test.cpp | 2 +- 21 files changed, 59 insertions(+), 36 deletions(-) diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst index 10b9c75c2a7f..c3b21a885e19 100644 --- a/Documentation/guides/pipeline-handler.rst +++ b/Documentation/guides/pipeline-handler.rst @@ -90,7 +90,7 @@ functionalities described above. Below is a brief overview of each of those: registered with it, by creating instances of the ``MediaDevice`` class and storing them. -- `DeviceMatch `_: +- `MediaDeviceMatch `_: Describes a media device search pattern using entity names, or other properties. @@ -316,10 +316,10 @@ Matching devices ~~~~~~~~~~~~~~~~ Each pipeline handler registered in libcamera gets tested against the current -system configuration, by matching a ``DeviceMatch`` with the system -``DeviceEnumerator``. A successful match makes sure all the requested components -have been registered in the system and allows the pipeline handler to be -initialized. +system configuration, by matching an instance of a class derived from +``DeviceMatch`` with the system ``DeviceEnumerator``. A successful match makes +sure all the requested components have been registered in the system and allows +the pipeline handler to be initialized. The main entry point of a pipeline handler is the `match()`_ class member function. When the ``CameraManager`` is started (using the `start()`_ function), diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h index 259a9e4621ea..2afb9fa0dea8 100644 --- a/include/libcamera/internal/device_enumerator.h +++ b/include/libcamera/internal/device_enumerator.h @@ -29,7 +29,7 @@ public: virtual int init() = 0; virtual int enumerate() = 0; - std::shared_ptr search(const DeviceMatch &dm); + std::shared_ptr search(const MediaDeviceMatch &dm); Signal<> devicesAdded; diff --git a/include/libcamera/internal/device_match.h b/include/libcamera/internal/device_match.h index 9f190f0c8a84..6df7dece1031 100644 --- a/include/libcamera/internal/device_match.h +++ b/include/libcamera/internal/device_match.h @@ -17,11 +17,16 @@ class MediaDevice; class DeviceMatch { public: - DeviceMatch(const std::string &driver); + virtual bool match(const MediaDevice *device) const = 0; +}; +class MediaDeviceMatch : public DeviceMatch +{ +public: void add(const std::string &entity); + MediaDeviceMatch(const std::string &driver); - bool match(const MediaDevice *device) const; + bool match(const MediaDevice *device) const override; private: std::string driver_; diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index c96944f4ecc4..02b2f33727a3 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -28,7 +28,7 @@ class Camera; class CameraConfiguration; class CameraManager; class DeviceEnumerator; -class DeviceMatch; +class MediaDeviceMatch; class FrameBuffer; class MediaDevice; class PipelineHandler; @@ -43,7 +43,7 @@ public: virtual bool match(DeviceEnumerator *enumerator) = 0; MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator, - const DeviceMatch &dm); + const MediaDeviceMatch &dm); bool acquire(); void release(Camera *camera); diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index 49afd7834db2..3dda08380e6e 100644 --- a/src/libcamera/device_enumerator.cpp +++ b/src/libcamera/device_enumerator.cpp @@ -229,7 +229,7 @@ void DeviceEnumerator::removeDevice(const std::string &deviceNode) * * \return pointer to the matching MediaDevice, or nullptr if no match is found */ -std::shared_ptr DeviceEnumerator::search(const DeviceMatch &dm) +std::shared_ptr DeviceEnumerator::search(const MediaDeviceMatch &dm) { for (std::shared_ptr &media : devices_) { if (media->busy()) diff --git a/src/libcamera/device_match.cpp b/src/libcamera/device_match.cpp index a51b9081d398..17937d435c88 100644 --- a/src/libcamera/device_match.cpp +++ b/src/libcamera/device_match.cpp @@ -18,21 +18,38 @@ namespace libcamera { /** * \class DeviceMatch + * \brief Pure virtual base class for device serch pattern + * + * The DeviceMatch class defines the interface to implement device search + * patterns to allow searching and matching different device typologies, such as + * media devices for V4L2/MC cameras, USB for cameras controlled through the USB + * protocol which do not implement the UVC specification and for virtual + * cameras. + * + * Pipeline handlers are expected to instantiate the correct derived class + * depending on the device type they support and populate it with their desired + * matching criteria. Derived classes of DeviceMatch override the pure virtual + * match() function to implement custom matching criteria based on the device + * type they represent. + */ + +/** + * \class MediaDeviceMatch * \brief Description of a media device search pattern * - * The DeviceMatch class describes a media device using properties from the + * The MediaDeviceMatch class describes a media device using properties from the * Media Controller struct media_device_info, entity names in the media graph * or other properties that can be used to identify a media device. * * The description is meant to be filled by pipeline managers and passed to a * device enumerator to find matching media devices. * - * A DeviceMatch is created with a specific Linux device driver in mind, + * A MediaDeviceMatch is created with a specific Linux device driver in mind, * therefore the name of the driver is a required property. One or more Entity * names can be added as match criteria. * - * Pipeline handlers are recommended to add entities to DeviceMatch as - * appropriare to ensure that the media device they need can be uniquely + * Pipeline handlers are recommended to add entities to MediaDeviceMatch as + * appropriate to ensure that the media device they need can be uniquely * identified. This is useful when the corresponding kernel driver can produce * different graphs, for instance as a result of different driver versions or * hardware configurations, and not all those graphs are suitable for a pipeline @@ -43,7 +60,7 @@ namespace libcamera { * \brief Construct a media device search pattern * \param[in] driver The Linux device driver name that created the media device */ -DeviceMatch::DeviceMatch(const std::string &driver) +MediaDeviceMatch::MediaDeviceMatch(const std::string &driver) : driver_(driver) { } @@ -52,7 +69,7 @@ DeviceMatch::DeviceMatch(const std::string &driver) * \brief Add a media entity name to the search pattern * \param[in] entity The name of the entity in the media graph */ -void DeviceMatch::add(const std::string &entity) +void MediaDeviceMatch::add(const std::string &entity) { entities_.push_back(entity); } @@ -67,7 +84,7 @@ void DeviceMatch::add(const std::string &entity) * * \return True if the media device matches the search pattern, false otherwise */ -bool DeviceMatch::match(const MediaDevice *device) const +bool MediaDeviceMatch::match(const MediaDevice *device) const { if (driver_ != device->driver()) return false; diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index 9bdfff0b155e..b7670a3cad8c 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -971,7 +971,7 @@ int PipelineHandlerISI::queueRequestDevice(Camera *camera, Request *request) bool PipelineHandlerISI::match(DeviceEnumerator *enumerator) { - DeviceMatch dm("mxc-isi"); + MediaDeviceMatch dm("mxc-isi"); dm.add("crossbar"); dm.add("mxc_isi.0"); dm.add("mxc_isi.0.capture"); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index a81c817a1255..5eca9eb0b922 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -846,7 +846,7 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) { int ret; - DeviceMatch cio2_dm("ipu3-cio2"); + MediaDeviceMatch cio2_dm("ipu3-cio2"); cio2_dm.add("ipu3-csi2 0"); cio2_dm.add("ipu3-cio2 0"); cio2_dm.add("ipu3-csi2 1"); @@ -856,7 +856,7 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) cio2_dm.add("ipu3-csi2 3"); cio2_dm.add("ipu3-cio2 3"); - DeviceMatch imgu_dm("ipu3-imgu"); + MediaDeviceMatch imgu_dm("ipu3-imgu"); imgu_dm.add("ipu3-imgu 0"); imgu_dm.add("ipu3-imgu 0 input"); imgu_dm.add("ipu3-imgu 0 parameters"); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 6efa79f29f66..5855c9d3cacc 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1155,7 +1155,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) { const MediaPad *pad; - DeviceMatch dm("rkisp1"); + MediaDeviceMatch dm("rkisp1"); dm.add("rkisp1_isp"); dm.add("rkisp1_resizer_mainpath"); dm.add("rkisp1_mainpath"); diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index 018cf4881d0e..78fd392256e1 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -175,7 +175,7 @@ bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator) * device nodes due to a sensor subdevice failure. */ for (unsigned int i = 0; i < numUnicamDevices; i++) { - DeviceMatch unicam("unicam"); + MediaDeviceMatch unicam("unicam"); MediaDevice *unicamDevice = acquireMediaDevice(enumerator, unicam); if (!unicamDevice) { @@ -183,7 +183,7 @@ bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator) continue; } - DeviceMatch isp("bcm2835-isp"); + MediaDeviceMatch isp("bcm2835-isp"); MediaDevice *ispDevice = acquireMediaDevice(enumerator, isp); if (!ispDevice) { diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 05ba76bce630..88159a0c4197 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1398,7 +1398,7 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) unsigned int numStreams = 1; for (const SimplePipelineInfo &inf : supportedDevices) { - DeviceMatch dm(inf.driver); + MediaDeviceMatch dm(inf.driver); media_ = acquireMediaDevice(enumerator, dm); if (media_) { info = &inf; @@ -1410,7 +1410,7 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) return false; for (const auto &[name, streams] : info->converters) { - DeviceMatch converterMatch(name); + MediaDeviceMatch converterMatch(name); converter_ = acquireMediaDevice(enumerator, converterMatch); if (converter_) { numStreams = streams; diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 38f48a5d9269..2114d48a2a66 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -387,7 +387,7 @@ int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request) bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) { MediaDevice *media; - DeviceMatch dm("uvcvideo"); + MediaDeviceMatch dm("uvcvideo"); media = acquireMediaDevice(enumerator, dm); if (!media) diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 00e6f4c6a51f..f97209ba26b0 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -442,7 +442,7 @@ int PipelineHandlerVimc::queueRequestDevice(Camera *camera, Request *request) bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator) { - DeviceMatch dm("vimc"); + MediaDeviceMatch dm("vimc"); dm.add("Raw Capture 0"); dm.add("Raw Capture 1"); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 9c74c6cfda70..ca177cad985c 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -22,6 +22,7 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_manager.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/device_match.h" #include "libcamera/internal/framebuffer.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/request.h" @@ -129,7 +130,7 @@ PipelineHandler::~PipelineHandler() * \return A pointer to the matching MediaDevice, or nullptr if no match is found */ MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator, - const DeviceMatch &dm) + const MediaDeviceMatch &dm) { std::shared_ptr media = enumerator->search(dm); if (!media) diff --git a/test/camera-sensor.cpp b/test/camera-sensor.cpp index 2a17cc79ea76..e35126ca1831 100644 --- a/test/camera-sensor.cpp +++ b/test/camera-sensor.cpp @@ -39,7 +39,7 @@ protected: return TestFail; } - DeviceMatch dm("vimc"); + MediaDeviceMatch dm("vimc"); media_ = enumerator_->search(dm); if (!media_) { cerr << "Unable to find \'vimc\' media device node" << endl; diff --git a/test/delayed_controls.cpp b/test/delayed_controls.cpp index a8ce9828d73d..9063ef3e7a20 100644 --- a/test/delayed_controls.cpp +++ b/test/delayed_controls.cpp @@ -38,7 +38,7 @@ protected: return TestFail; } - DeviceMatch dm("vivid"); + MediaDeviceMatch dm("vivid"); dm.add("vivid-000-vid-cap"); media_ = enumerator_->search(dm); diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp index dde11f365e43..8cb6f6353b99 100644 --- a/test/libtest/buffer_source.cpp +++ b/test/libtest/buffer_source.cpp @@ -43,7 +43,7 @@ int BufferSource::allocate(const StreamConfiguration &config) return TestFail; } - DeviceMatch dm("vivid"); + MediaDeviceMatch dm("vivid"); dm.add(videoDeviceName); media_ = enumerator->search(dm); diff --git a/test/media_device/media_device_test.cpp b/test/media_device/media_device_test.cpp index 1397d1236697..8189e068212c 100644 --- a/test/media_device/media_device_test.cpp +++ b/test/media_device/media_device_test.cpp @@ -25,7 +25,7 @@ int MediaDeviceTest::init() return TestFail; } - DeviceMatch dm("vimc"); + MediaDeviceMatch dm("vimc"); media_ = enumerator_->search(dm); if (!media_) { cerr << "No VIMC media device found: skip test" << endl; diff --git a/test/v4l2_subdevice/v4l2_subdevice_test.cpp b/test/v4l2_subdevice/v4l2_subdevice_test.cpp index d8fbfd9f6b0f..56e5cc8377c4 100644 --- a/test/v4l2_subdevice/v4l2_subdevice_test.cpp +++ b/test/v4l2_subdevice/v4l2_subdevice_test.cpp @@ -39,7 +39,7 @@ int V4L2SubdeviceTest::init() return TestFail; } - DeviceMatch dm("vimc"); + MediaDeviceMatch dm("vimc"); media_ = enumerator_->search(dm); if (!media_) { cerr << "Unable to find \'vimc\' media device node" << endl; diff --git a/test/v4l2_videodevice/v4l2_m2mdevice.cpp b/test/v4l2_videodevice/v4l2_m2mdevice.cpp index c45f581a8653..0effbf191966 100644 --- a/test/v4l2_videodevice/v4l2_m2mdevice.cpp +++ b/test/v4l2_videodevice/v4l2_m2mdevice.cpp @@ -65,7 +65,7 @@ protected: return TestFail; } - DeviceMatch dm("vim2m"); + MediaDeviceMatch dm("vim2m"); dm.add("vim2m-source"); dm.add("vim2m-sink"); diff --git a/test/v4l2_videodevice/v4l2_videodevice_test.cpp b/test/v4l2_videodevice/v4l2_videodevice_test.cpp index 125aafd65041..addc47d2b62a 100644 --- a/test/v4l2_videodevice/v4l2_videodevice_test.cpp +++ b/test/v4l2_videodevice/v4l2_videodevice_test.cpp @@ -30,7 +30,7 @@ int V4L2VideoDeviceTest::init() return TestFail; } - DeviceMatch dm(driver_); + MediaDeviceMatch dm(driver_); dm.add(entity_); media_ = enumerator_->search(dm); 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); From patchwork Tue Aug 8 12:52:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18931 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 3F784C32A9 for ; Tue, 8 Aug 2023 12:52:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BC358627ED; Tue, 8 Aug 2023 14:52:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499175; bh=+/Rkd7Z+xBQAH+rNSIjq7t7JFy+zXhHsZnkvSO6d3VU=; 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=bfWEJunW0+NUqZoQxpI7FlAxLnsKTdM4Qu45OCuxw1zE55/N+w50N2EvPFndqUYZf CKFG73CLlbT6gLdPZg49st5tSiyPmqFzMZxvcPcEOY010Iw/J5Zxq/2NUvgHAa5lV2 JTxkDOn2o7axdYbZozmaMFoR6rxCoEET+BmHBxEaUn6dfWg4/WlYsMhWul5K9XNgzE e29aMdamU/wPndOSwf9IMQc/dH/ggKmf+LaMeF/V5bu0reXB82V0djQID/0Fi2fOqg /uMWGrBETW/QxZUfmVTwbK71OF8Iys3Eu1c3JU4nMjpqS/j05OC4ke0r40tghlYmKx Q4fyx6Jk0yiZQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B88C8627EC 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="AOQ82FU+"; 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 D4B72396D; 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=1691499101; bh=+/Rkd7Z+xBQAH+rNSIjq7t7JFy+zXhHsZnkvSO6d3VU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AOQ82FU+V3At2vgtArnZHPv83zvtHWXBOv1rAx6EbWi8M1VUfbuYXsuuUQyJsZo+j dSxYAsODXX6QURNeiYbXaY36WOHeABW1Nja0QkEzNfxl98uyBKyFhgLpVLu1Vuiphj TSAuncmqD7+Jl8hz1oVVebQArAdq+5cGjhuc1atQ= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:23 +0200 Message-Id: <20230808125228.29043-5-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 4/9] libcamera: Introduce CameraDevice and USBDevice 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" Introduce a CameraDevice base class from which the MediaDevice and USBDevice derive from. This allows to generalize the PipelineHandler base class implementation to use a generic 'CameraDevice' type in the later patches. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/camera_device.h | 31 +++++++++++++ include/libcamera/internal/media_device.h | 13 +++--- include/libcamera/internal/meson.build | 2 + include/libcamera/internal/usb_device.h | 52 ++++++++++++++++++++++ src/libcamera/camera_device.cpp | 22 +++++++++ src/libcamera/media_device.cpp | 2 +- src/libcamera/meson.build | 1 + 7 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 include/libcamera/internal/camera_device.h create mode 100644 include/libcamera/internal/usb_device.h create mode 100644 src/libcamera/camera_device.cpp diff --git a/include/libcamera/internal/camera_device.h b/include/libcamera/internal/camera_device.h new file mode 100644 index 000000000000..421d77e8d6cf --- /dev/null +++ b/include/libcamera/internal/camera_device.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas On Board Oy + * + * camera_device.h - Base class for camera devices + */ + +#pragma once + +namespace libcamera { + +class CameraDevice +{ +public: + CameraDevice() + : acquired_(false) + { + } + + virtual bool acquire() = 0; + virtual void release() = 0; + bool busy() const { return acquired_; } + + virtual bool lock() = 0; + virtual void unlock() = 0; + +protected: + bool acquired_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/media_device.h b/include/libcamera/internal/media_device.h index eb8cfde48e20..2c748ae66545 100644 --- a/include/libcamera/internal/media_device.h +++ b/include/libcamera/internal/media_device.h @@ -18,22 +18,22 @@ #include #include +#include "libcamera/internal/camera_device.h" #include "libcamera/internal/media_object.h" namespace libcamera { -class MediaDevice : protected Loggable +class MediaDevice : protected Loggable, public CameraDevice { public: MediaDevice(const std::string &deviceNode); ~MediaDevice(); - bool acquire(); - void release(); - bool busy() const { return acquired_; } + bool acquire() override; + void release() override; - bool lock(); - void unlock(); + bool lock() override; + void unlock() override; int populate(); bool isValid() const { return valid_; } @@ -85,7 +85,6 @@ private: UniqueFD fd_; bool valid_; - bool acquired_; std::map objects_; std::vector entities_; diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 169e06557106..c683283da37d 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -14,6 +14,7 @@ libcamera_internal_headers = files([ 'byte_stream_buffer.h', 'camera.h', 'camera_controls.h', + 'camera_device.h', 'camera_lens.h', 'camera_manager.h', 'camera_sensor.h', @@ -41,6 +42,7 @@ libcamera_internal_headers = files([ 'request.h', 'source_paths.h', 'sysfs.h', + 'usb_device.h', 'v4l2_device.h', 'v4l2_pixelformat.h', 'v4l2_subdevice.h', diff --git a/include/libcamera/internal/usb_device.h b/include/libcamera/internal/usb_device.h new file mode 100644 index 000000000000..7fe0f7c4d6a9 --- /dev/null +++ b/include/libcamera/internal/usb_device.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas On Board Oy + * + * usb_device.h - Description of a USB device + */ + +#pragma once + +#include "libcamera/internal/camera_device.h" + +namespace libcamera { + +class USBDevice : public CameraDevice +{ +public: + USBDevice(const char *vid, const char *pid) + : CameraDevice(), vid_(vid), pid_(pid) + { + } + + /* \todo Implement acquire/release and lock/unlock */ + bool acquire() override + { + /* This only works within the same process!! */ + if (acquired_) + return false; + + acquired_ = true; + return true; + } + void release() override + { + } + + bool lock() override + { + return true; + } + void unlock() override + { + } + + const std::string &vid() const { return vid_; }; + const std::string &pid() const { return pid_; }; + +private: + std::string vid_; + std::string pid_; +}; + +} /* namespace libcamera */ diff --git a/src/libcamera/camera_device.cpp b/src/libcamera/camera_device.cpp new file mode 100644 index 000000000000..a0ceba0db5af --- /dev/null +++ b/src/libcamera/camera_device.cpp @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas On Board Oy + * + * camera_device.cpp - Base class for camera devices + */ + +#include "libcamera/internal/camera_device.h" + +/** + * \file camera_device.h + * \brief Base class for camera devices + */ + +namespace libcamera { + +/** + * \class CameraDevice + * \brief Base class for camera devices + */ + +} /* namespace libcamera */ diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index 2949816b4a64..f9c2dbf289f1 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -63,7 +63,7 @@ LOG_DEFINE_CATEGORY(MediaDevice) * populate() before the media graph can be queried. */ MediaDevice::MediaDevice(const std::string &deviceNode) - : deviceNode_(deviceNode), valid_(false), acquired_(false) + : CameraDevice(), deviceNode_(deviceNode), valid_(false) { } diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index d5562afc50c7..3a70946a6f78 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -5,6 +5,7 @@ libcamera_sources = files([ 'byte_stream_buffer.cpp', 'camera.cpp', 'camera_controls.cpp', + 'camera_device.cpp', 'camera_lens.cpp', 'camera_manager.cpp', 'camera_sensor.cpp', From patchwork Tue Aug 8 12:52:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18932 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 6970DC32B0 for ; Tue, 8 Aug 2023 12:52:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 958BB627F2; Tue, 8 Aug 2023 14:52:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499176; bh=36EIHG1L7eU/PrrksaiwvW43iuhdztySZBLII9guvtE=; 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=sBGXxXi556sPKUtNQ+/U0lKqXWAsrwwANT9SOp0tBlALLKxfQG87Fky0/TmMmemah 6Sxhya+FY9NiPDpNwxxRbZuFCOIY8iWWqqcBSCS6NNqNW+QJdT4VdvpBaLtd/ui+DH lJlo4NpwrZ9PoD8CvHe86fkJy7NEc+MmUvRElxmf2V9SXbsnqkY/lbIoVxyCrtBkF3 mCKNGbm14oQjJhovnYmn+hbpZDMCMr9ZDfSkCjXWggkVFQ4hbuh2IvGkxIX1BM2JOG ebQ6pminU7YTN7VScVAmH909KttRJ3gdCjty/FaxrBlbEuq6rN+JFi2+dCgfcaFmEv +gDZHl99ionbg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4563B627F2 for ; Tue, 8 Aug 2023 14:52:49 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Q+S9blwO"; 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 657238611; Tue, 8 Aug 2023 14:51:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1691499101; bh=36EIHG1L7eU/PrrksaiwvW43iuhdztySZBLII9guvtE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q+S9blwOPvSwl/dbB9Dk/CmzvAbX403QGcF9xdzxGlMNWXxubN092ZiGwiHQPB0Zw bdOAiqfVDS+4AQPWhjSTXhLZYpGpMHJiYqqO+L4rm1RpPYjTCspmkEkigAlOkrFzff gMF1CoQGxD3XY2DrSO5LgYJn4OF9WLWatyeaF1Mk= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:24 +0200 Message-Id: <20230808125228.29043-6-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 5/9] libcamera: device_enumerator_udev: Enumerate USB devices 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" Add experimental support for USB device enumeration in the udev-based device enumerator. Signed-off-by: Jacopo Mondi --- .../libcamera/internal/device_enumerator.h | 5 +++ .../internal/device_enumerator_udev.h | 1 + src/libcamera/device_enumerator.cpp | 21 ++++++++++++ src/libcamera/device_enumerator_udev.cpp | 32 +++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h index 8df6a3e2ac92..1d6dbcb104b8 100644 --- a/include/libcamera/internal/device_enumerator.h +++ b/include/libcamera/internal/device_enumerator.h @@ -18,6 +18,7 @@ namespace libcamera { class MediaDevice; +class USBDevice; class DeviceEnumerator { @@ -38,8 +39,12 @@ protected: void addMediaDevice(std::unique_ptr media); void removeMediaDevice(const std::string &deviceNode); + void addUSBDevice(std::unique_ptr usb); + /* \todo implement remove() */ + private: std::vector> mediaDevices_; + std::vector> usbDevices_; }; } /* namespace libcamera */ diff --git a/include/libcamera/internal/device_enumerator_udev.h b/include/libcamera/internal/device_enumerator_udev.h index 1b3360df31ba..e67ee31e0376 100644 --- a/include/libcamera/internal/device_enumerator_udev.h +++ b/include/libcamera/internal/device_enumerator_udev.h @@ -59,6 +59,7 @@ private: std::string lookupDeviceNode(dev_t devnum); int addV4L2Device(dev_t devnum); + int createUSBDevice(struct udev_device *dev); void udevNotify(); struct udev *udev_; diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index 2ab731c68db9..1fde7367cfa8 100644 --- a/src/libcamera/device_enumerator.cpp +++ b/src/libcamera/device_enumerator.cpp @@ -7,6 +7,7 @@ #include "libcamera/internal/device_enumerator.h" +#include #include #include @@ -14,6 +15,7 @@ #include "libcamera/internal/device_enumerator_sysfs.h" #include "libcamera/internal/device_enumerator_udev.h" #include "libcamera/internal/media_device.h" +#include "libcamera/internal/usb_device.h" /** * \file device_enumerator.h @@ -189,6 +191,25 @@ void DeviceEnumerator::addMediaDevice(std::unique_ptr media) devicesAdded.emit(); } +void DeviceEnumerator::addUSBDevice(std::unique_ptr usb) +{ + /* + * This is a bit of an hack and could be improved! + * + * Can't use std::sort() + std::unique() because we're storing + * unique_ptr<> + */ + for (const auto &dev : usbDevices_) { + if (dev->pid() == usb->pid() && dev->vid() == usb->vid()) + return; + } + + LOG(DeviceEnumerator, Debug) + << "Added USB device " << usb->vid() << "-" << usb->pid(); + + usbDevices_.push_back(std::move(usb)); +} + /** * \brief Remove a media device from the enumerator * \param[in] deviceNode Path to the media device to remove diff --git a/src/libcamera/device_enumerator_udev.cpp b/src/libcamera/device_enumerator_udev.cpp index 3cb0044a9434..ce4543698ed4 100644 --- a/src/libcamera/device_enumerator_udev.cpp +++ b/src/libcamera/device_enumerator_udev.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include "libcamera/internal/media_device.h" +#include "libcamera/internal/usb_device.h" namespace libcamera { @@ -115,6 +117,9 @@ int DeviceEnumeratorUdev::addUdevDevice(struct udev_device *dev) return 0; } + if (!strcmp(subsystem, "input")) + return createUSBDevice(dev); + return -ENODEV; } @@ -136,6 +141,14 @@ int DeviceEnumeratorUdev::enumerate() if (ret < 0) goto done; + /* + * FIXME: this should use the appoprtiate subsystem for USB cameras. + * As a test, match on USB input devices. + */ + ret = udev_enumerate_add_match_subsystem(udev_enum, "input"); + if (ret < 0) + goto done; + ret = udev_enumerate_add_match_is_initialized(udev_enum); if (ret < 0) goto done; @@ -329,6 +342,25 @@ int DeviceEnumeratorUdev::addV4L2Device(dev_t devnum) return 0; } +int DeviceEnumeratorUdev::createUSBDevice(struct udev_device *dev) +{ + /* Get the USB parent device to get VID/PID information. */ + struct udev_device *usb_device = + udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); + if (!usb_device) + return -ENODEV; + + const char *vid = udev_device_get_sysattr_value(usb_device, "idVendor"); + const char *pid = udev_device_get_sysattr_value(usb_device, "idProduct"); + if (!vid || !pid) + return -ENODEV; + + std::unique_ptr usbDev = std::make_unique(vid, pid); + addUSBDevice(std::move(usbDev)); + + return 0; +} + void DeviceEnumeratorUdev::udevNotify() { struct udev_device *dev = udev_monitor_receive_device(monitor_); From patchwork Tue Aug 8 12:52:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18933 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 014CCBDB13 for ; Tue, 8 Aug 2023 12:52:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 40F2B627F6; Tue, 8 Aug 2023 14:52:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499177; bh=YwkM69XCB4/whxxS4LwF7y8ZyetkH0w+mBXx1IjHZVM=; 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=QGjooKJQP7WwQbeSmkd6f5zf9m6+En2UHG2HvViSr6+bcXqqzuaTKu6buOgWZs+NO ljkDkMteqzRBV195BECEeulN25SRgLdW6j0AC36oA7umxgYgEnBUjflqC44KCfht+w EB+FRxRk6YiIStXQ8V5T92XIaIpcCbOwqQ7mdTkY9HzjFctMtyPtNiBNNDhzBhafFU 5B2TU3m1UzqUY1CMrvDAcI9tVYnxfFELfkIcRKisqabxkij/8hQmrBiXTkf4V8Vap6 HoQauc7Tzo1YV7dG7IoXhUF0mQ0nG5O3I4l/GRx9qA/y4HgAp2NOlnErQPe5B0nFJc P83qj0FXPfBeg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1EA46627EF for ; Tue, 8 Aug 2023 14:52:50 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="OoIZt5k1"; 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 EE29E8624; Tue, 8 Aug 2023 14:51:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1691499102; bh=YwkM69XCB4/whxxS4LwF7y8ZyetkH0w+mBXx1IjHZVM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OoIZt5k1oVNT2B9CGaCjCB4KVcmEXbglw9rle/gK+kK1C5skDJOPhjRw8CBXeIzJT 7S/WIFJ1Mosoy/gu8C7GZz+Lb8EGscr3CIR7ZEXfroeGwFxRhM7u6Vf4QKVtFe9JAG btTjA1raOE2Tk/p7UlQzxLnm0MckQ31phjPHtkzU= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:25 +0200 Message-Id: <20230808125228.29043-7-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 6/9] libcamera: device_match: Introduce USBDeviceMatch 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" Introduce a USB-specific DeviceMatch derived class. Generalize the DeviceMatch::match() function by making its only parameter a CameraDevice instance and dynamically cast to the correct derived class in the overloaded match() functions. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/device_match.h | 21 ++++++++++++++++--- src/libcamera/device_match.cpp | 25 ++++++++++++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/include/libcamera/internal/device_match.h b/include/libcamera/internal/device_match.h index 6df7dece1031..e6608cac2f85 100644 --- a/include/libcamera/internal/device_match.h +++ b/include/libcamera/internal/device_match.h @@ -12,12 +12,12 @@ namespace libcamera { -class MediaDevice; +class CameraDevice; class DeviceMatch { public: - virtual bool match(const MediaDevice *device) const = 0; + virtual bool match(const CameraDevice *device) const = 0; }; class MediaDeviceMatch : public DeviceMatch @@ -26,11 +26,26 @@ public: void add(const std::string &entity); MediaDeviceMatch(const std::string &driver); - bool match(const MediaDevice *device) const override; + bool match(const CameraDevice *device) const override; private: std::string driver_; std::vector entities_; }; +class USBDeviceMatch : public DeviceMatch +{ +public: + USBDeviceMatch(const std::string &vid, const std::string &pid) + : vid_(vid), pid_(pid) + { + } + + bool match(const CameraDevice *device) const override; + +private: + std::string vid_; + std::string pid_; +}; + }; /* namespace libcamera */ diff --git a/src/libcamera/device_match.cpp b/src/libcamera/device_match.cpp index 17937d435c88..8870649cb53b 100644 --- a/src/libcamera/device_match.cpp +++ b/src/libcamera/device_match.cpp @@ -7,7 +7,9 @@ #include "libcamera/internal/device_match.h" +#include "libcamera/internal/camera_device.h" #include "libcamera/internal/media_device.h" +#include "libcamera/internal/usb_device.h" /** * \file device_match.h @@ -84,15 +86,17 @@ void MediaDeviceMatch::add(const std::string &entity) * * \return True if the media device matches the search pattern, false otherwise */ -bool MediaDeviceMatch::match(const MediaDevice *device) const +bool MediaDeviceMatch::match(const CameraDevice *device) const { - if (driver_ != device->driver()) + const MediaDevice *media = static_cast(device); + + if (driver_ != media->driver()) return false; for (const std::string &name : entities_) { bool found = false; - for (const MediaEntity *entity : device->entities()) { + for (const MediaEntity *entity : media->entities()) { if (name == entity->name()) { found = true; break; @@ -106,4 +110,19 @@ bool MediaDeviceMatch::match(const MediaDevice *device) const return true; } +/** + * \brief Compare a search pattern with a USB device + * \param[in] device The USB device + * + * Matching is performed on the USB device vendorId and productId. + * + * \return True if the USB device matches the search pattern, false otherwise + */ +bool USBDeviceMatch::match(const CameraDevice *device) const +{ + const USBDevice *usb = static_cast(device); + + return usb->vid() == vid_ && usb->pid() == pid_; +} + } /* namespace libcamera */ From patchwork Tue Aug 8 12:52:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18934 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 A72C2C32B1 for ; Tue, 8 Aug 2023 12:52:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D68E8627F1; Tue, 8 Aug 2023 14:52:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499178; bh=poC0tU/raVEL68/bMsRJ6XkKvmnAQXlmX95+AFg0C6o=; 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=OrLME9fcSON9KmURyDyh3W1sZlWLq7SZ5LshOGiZcfujwUa0m0TYKmis9bzs++I9L esHiYwmuMHKhcY26ntdyRgotYO9BgKl+4ow113A7PM8fnNL0lrQ/pejx/6tzFhmPTA FUPg0FJ9jOI92UOniPhNG8aPLqb19HW8YvH4HoUlPTDzoDpBvP5DnS5dLz4y6XywyD gDSkPbybMgxUQdBt0IprdiSvnV3ffuUpdrdzTo0f4mSl+YQtFxGyIjvh+aUUgrwB0w OnO/VfxWBiqh1DEOA6VKbhwsKoA73GNEIdROU4rqgDr8+QmiifibH44ML0l5af8xce VpnZrVrmdPZSw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9C920627EE for ; Tue, 8 Aug 2023 14:52:50 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="R+YarRLb"; 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 C0B308625; Tue, 8 Aug 2023 14:51:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1691499103; bh=poC0tU/raVEL68/bMsRJ6XkKvmnAQXlmX95+AFg0C6o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R+YarRLb2KZ7mJXlNlwvM6AWS0VOHQl7YD+151uUYmRjNtI6f1B3fenMvkACGTXub wNBhaGYl9tAlUJpZkaB3+FC7esLfJDDiqg7qRrYsvanv5hfGKE5VhYcLnb6Cdvjuou 5U7L8TSSbPPRo3By+txoISlzR2iGUbYiSVfRFZ4Q= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:26 +0200 Message-Id: <20230808125228.29043-8-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 7/9] libcamera: device_enumerator: Search for USB devices 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" Add support for searching a USBDevice by providing a USBDeviceMatch to the device enumerator. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/device_enumerator.h | 1 + src/libcamera/device_enumerator.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h index 1d6dbcb104b8..f4ee349906f2 100644 --- a/include/libcamera/internal/device_enumerator.h +++ b/include/libcamera/internal/device_enumerator.h @@ -31,6 +31,7 @@ public: virtual int enumerate() = 0; std::shared_ptr search(const MediaDeviceMatch &dm); + std::shared_ptr search(const USBDeviceMatch &dm); Signal<> devicesAdded; diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index 1fde7367cfa8..0d983032e2c6 100644 --- a/src/libcamera/device_enumerator.cpp +++ b/src/libcamera/device_enumerator.cpp @@ -271,4 +271,18 @@ std::shared_ptr DeviceEnumerator::search(const MediaDeviceMatch &dm return nullptr; } +std::shared_ptr DeviceEnumerator::search(const USBDeviceMatch &dm) +{ + for (std::shared_ptr &usb : usbDevices_) { + if (dm.match(usb.get())) { + LOG(DeviceEnumerator, Debug) + << "Successful match for USB device " + << usb->vid() << "-" << usb->pid(); + return usb; + } + } + + return nullptr; +} + } /* namespace libcamera */ From patchwork Tue Aug 8 12:52:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18935 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 55C65C32B2 for ; Tue, 8 Aug 2023 12:52:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8722A62806; Tue, 8 Aug 2023 14:52:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499178; bh=mtyz3Oza0nU6tQb7l72g9z6aNbT0OdIHbijtg8CYxEU=; 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=sTu09M1uHJ36VhfUOltLAh3oVGvD+rWbnDyXC7APeW/Taw/r1jJMn/lKV6C6p+9vH fZm9A5wMOl7bgs/RSSRmoG/omY4Dm9WoGsZWWhlI3tMo4p8uaG7Tdr62xYi2hbn7st UHKHYfpkhXIef7qYiW5KWRXdYvtwZDxMh8SZEK4c5MO3Wyjtw1EOWZ19pi1wkqA9ze cOX5uxkzlNFuMnx7cRE94A6HCaMjw9aLlcDraME4Xf9020txRyRbPSOpHSalVsnKXB FpqdK0mf1WlT2xaE4xcGyRT1nodUisCR9K8BGkxPsf0+HExgRm64hqZMsP187Qkhbk SX5cn39K2xQaw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 28D71627EB for ; Tue, 8 Aug 2023 14:52:51 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="MPsnwXhN"; 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 4D062864C; Tue, 8 Aug 2023 14:51:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1691499103; bh=mtyz3Oza0nU6tQb7l72g9z6aNbT0OdIHbijtg8CYxEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MPsnwXhNvYrfm5q3UI4RfY0JHbYMsR5/lfqWt9W3DAOoum0aL+HAmSiXfhiJZqODg 1HcqcJUmbXvsIHRP+t2R5zFSCfb4eEd+nH3TmLXRuTSjIunrynEicWMi4bV18jX1TP zulMwnEWQer6EeEpgyCSK48/wMLRfVxrhzY5Lpao= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:27 +0200 Message-Id: <20230808125228.29043-9-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 8/9] libcamera: pipeline_handler: Add function to acquire a USB device 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" Add a function to the PipelineHandler base class to acquire a USB device by providing a USBDeviceMatch class instance. Support multiple CameraDevice derived classes by generalizing whenever possible the device type in use. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/pipeline_handler.h | 9 ++- src/libcamera/pipeline_handler.cpp | 69 +++++++++++++++---- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 02b2f33727a3..b6b68aab1521 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -26,6 +26,7 @@ namespace libcamera { class Camera; class CameraConfiguration; +class CameraDevice; class CameraManager; class DeviceEnumerator; class MediaDeviceMatch; @@ -33,6 +34,8 @@ class FrameBuffer; class MediaDevice; class PipelineHandler; class Request; +class USBDevice; +class USBDeviceMatch; class PipelineHandler : public std::enable_shared_from_this, public Object @@ -44,6 +47,8 @@ public: virtual bool match(DeviceEnumerator *enumerator) = 0; MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator, const MediaDeviceMatch &dm); + USBDevice *acquireUSBDevice(DeviceEnumerator *enumerator, + const USBDeviceMatch &dm); bool acquire(); void release(Camera *camera); @@ -82,7 +87,7 @@ protected: CameraManager *manager_; private: - void unlockMediaDevices(); + void unlockCameraDevices(); void mediaDeviceDisconnected(MediaDevice *media); virtual void disconnect(); @@ -90,7 +95,7 @@ private: void doQueueRequest(Request *request); void doQueueRequests(); - std::vector> mediaDevices_; + std::vector> cameraDevices_; std::vector> cameras_; std::queue waitingRequests_; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index ca177cad985c..0b3e0fd8fa8b 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -27,6 +27,7 @@ #include "libcamera/internal/media_device.h" #include "libcamera/internal/request.h" #include "libcamera/internal/tracepoints.h" +#include "libcamera/internal/usb_device.h" /** * \file pipeline_handler.h @@ -76,8 +77,8 @@ PipelineHandler::PipelineHandler(CameraManager *manager) PipelineHandler::~PipelineHandler() { - for (std::shared_ptr media : mediaDevices_) - media->release(); + for (std::shared_ptr device : cameraDevices_) + device->release(); } /** @@ -139,11 +140,42 @@ MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator, if (!media->acquire()) return nullptr; - mediaDevices_.push_back(media); + cameraDevices_.push_back(media); return media.get(); } +/** + * \brief Search and acquire a USBDevice matching a device pattern + * \param[in] enumerator Enumerator containing all media devices in the system + * \param[in] dm Device match pattern + * + * Search the device \a enumerator for an available USB device matching the + * device match pattern \a dm. Matching devices that have previously been + * acquired by MediaDevice::acquire() are not considered. If a match is found, + * the USB device is acquired and returned. The caller shall not release the + * device explicitly, it will be automatically released when the pipeline + * handler is destroyed. + * + * \context This function shall be called from the CameraManager thread. + * + * \return A pointer to the matching USBDevice, or nullptr if no match is found + */ +USBDevice *PipelineHandler::acquireUSBDevice(DeviceEnumerator *enumerator, + const USBDeviceMatch &dm) +{ + std::shared_ptr usb = enumerator->search(dm); + if (!usb) + return nullptr; + + if (!usb->acquire()) + return nullptr; + + cameraDevices_.push_back(usb); + + return usb.get(); +} + /** * \brief Acquire exclusive access to the pipeline handler for the process * @@ -173,9 +205,9 @@ bool PipelineHandler::acquire() return true; } - for (std::shared_ptr &media : mediaDevices_) { - if (!media->lock()) { - unlockMediaDevices(); + for (std::shared_ptr &device : cameraDevices_) { + if (!device->lock()) { + unlockCameraDevices(); return false; } } @@ -206,7 +238,7 @@ void PipelineHandler::release(Camera *camera) ASSERT(useCount_); - unlockMediaDevices(); + unlockCameraDevices(); releaseDevice(camera); @@ -224,10 +256,10 @@ void PipelineHandler::releaseDevice([[maybe_unused]] Camera *camera) { } -void PipelineHandler::unlockMediaDevices() +void PipelineHandler::unlockCameraDevices() { - for (std::shared_ptr &media : mediaDevices_) - media->unlock(); + for (std::shared_ptr &device : cameraDevices_) + device->unlock(); } /** @@ -606,7 +638,7 @@ void PipelineHandler::registerCamera(std::shared_ptr camera) { cameras_.push_back(camera); - if (mediaDevices_.empty()) + if (cameraDevices_.empty()) LOG(Pipeline, Fatal) << "Registering camera with no media devices!"; @@ -615,7 +647,20 @@ void PipelineHandler::registerCamera(std::shared_ptr camera) * to the camera. */ std::vector devnums; - for (const std::shared_ptr &media : mediaDevices_) { + for (const std::shared_ptr &device : cameraDevices_) { + /* + * Only MediaDevice has entities and devnums. + * + * FIXME: This code path "abuses" RTTI. In general, conditional + * execution based on type information is discouraged and is + * a symptom of a fragile design. However this could be + * considered a temporary workaround, as USB-based devices + * should report devnums as well in future. + */ + MediaDevice *media = dynamic_cast(device.get()); + if (!media) + continue; + for (const MediaEntity *entity : media->entities()) { if (entity->pads().size() == 1 && (entity->pads()[0]->flags() & MEDIA_PAD_FL_SINK) && From patchwork Tue Aug 8 12:52:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18936 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 15CF2C32B3 for ; Tue, 8 Aug 2023 12:52:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 82470627F6; Tue, 8 Aug 2023 14:52:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1691499179; bh=bVaPL/jKTBsyEmGOyaB8CwG8+poD9A6OtASWtadqCw4=; 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=mi7Ff+/HW1hj/q+GqByY1rtKLLblV0zBGRneP4NcSB2wlAGfG0wZPXAIbXQCKEA0Y tb3/BAX8yH6WDea9F8x0N65r0/22TfLaQOxjDh+QgX5Tf34cIDAzZDHBYgum68ezBo gKXaEP6rMslRNcZpiaFzWZV5EGAucpISbMO/0TVkiEkoD1cGrjwPxdO104lsjK3E7r ClJsHcu84FdVGU3KXeFX+GZb4ac1EL+DC7E/KuTXI3hoqvhIX+CpXCrhDZcGz1Yg6L v0nr31XxUROHt4ZAlzneU4P41M+jbGGoW954GqijxFMSf1IZZG8lDBjdQdXVzokzwE ax83mZHlZkvXA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BCD49627F0 for ; Tue, 8 Aug 2023 14:52:51 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WMy/mt9Q"; 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 CC15B87CC; Tue, 8 Aug 2023 14:51:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1691499104; bh=bVaPL/jKTBsyEmGOyaB8CwG8+poD9A6OtASWtadqCw4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WMy/mt9Q0VIC2pwET4rg3CDLAq6DxE9D8cPbwGJQjreeQ3v9Ona+QjJs06XP5Wlg3 lV5zsgSxqUWikZ+XL/tys0YhrcXUuD5LKS+Ap+1UF6RykvG2ve+puOrVUVMRpJEeRw cTK16uq2nObX0F0TBky2nIqyFwVxWqEuH+3X/rdg= To: libcamera-devel@lists.libcamera.org, Sophie Friedrich Date: Tue, 8 Aug 2023 14:52:28 +0200 Message-Id: <20230808125228.29043-10-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 9/9] [HACK] libcamera: pipeline: Add usb-test pipeline 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" Add a test pipeline to match on a USBDevice. This is a proof of concept as the pipeline handler matches on my mouse VID/PID pair. Signed-off-by: Jacopo Mondi --- meson_options.txt | 1 + src/libcamera/pipeline/usb-test/meson.build | 5 ++ src/libcamera/pipeline/usb-test/usb_test.cpp | 93 ++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/libcamera/pipeline/usb-test/meson.build create mode 100644 src/libcamera/pipeline/usb-test/usb_test.cpp diff --git a/meson_options.txt b/meson_options.txt index fad928af4b62..e706484be109 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -46,6 +46,7 @@ option('pipelines', 'rkisp1', 'rpi/vc4', 'simple', + 'usb-test', 'uvcvideo', 'vimc' ], diff --git a/src/libcamera/pipeline/usb-test/meson.build b/src/libcamera/pipeline/usb-test/meson.build new file mode 100644 index 000000000000..bafff18e7b0b --- /dev/null +++ b/src/libcamera/pipeline/usb-test/meson.build @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: CC0-1.0 + +libcamera_sources += files([ + 'usb_test.cpp', +]) diff --git a/src/libcamera/pipeline/usb-test/usb_test.cpp b/src/libcamera/pipeline/usb-test/usb_test.cpp new file mode 100644 index 000000000000..5df1a137f81f --- /dev/null +++ b/src/libcamera/pipeline/usb-test/usb_test.cpp @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas On Board Oy + * + * usb_test.cpp - Test USB device matching + */ + +#include + +#include +#include + +#include "libcamera/internal/camera.h" +#include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/usb_device.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(USBTest) + +class USBCameraData : public Camera::Private +{ +public: + USBCameraData(PipelineHandler *pipe) + : Camera::Private(pipe) + { + } + + Stream stream_; +}; + +class PipelineHandlerUSB : public PipelineHandler +{ +public: + PipelineHandlerUSB(CameraManager *manager) + : PipelineHandler(manager) + { + } + + std::unique_ptr generateConfiguration([[maybe_unused]] Camera *camera, + [[maybe_unused]] Span roles) override + { + return {}; + } + int configure([[maybe_unused]] Camera *camera, [[maybe_unused]] CameraConfiguration *config) override + { + return 0; + } + + int exportFrameBuffers([[maybe_unused]] Camera *camera, [[maybe_unused]] Stream *stream, + [[maybe_unused]] std::vector> *buffers) override + { + return 0; + } + + int start([[maybe_unused]] Camera *camera, [[maybe_unused]] const ControlList *controls) override + { + return 0; + } + void stopDevice([[maybe_unused]] Camera *camera) override + { + } + + int queueRequestDevice([[maybe_unused]] Camera *camera, [[maybe_unused]] Request *request) override + { + return 0; + } + + bool match(DeviceEnumerator *enumerator) override; +}; + +bool PipelineHandlerUSB::match(DeviceEnumerator *enumerator) +{ + USBDeviceMatch dm("046d", "c52b"); + USBDevice *usbDev = acquireUSBDevice(enumerator, dm); + if (!usbDev) + return false; + + std::unique_ptr data = std::make_unique(this); + std::string id = usbDev->vid() + "/" + usbDev->pid(); + std::set streams{ &data->stream_ }; + + std::shared_ptr camera = + Camera::create(std::move(data), id, streams); + registerCamera(std::move(camera)); + + return true; +} + +REGISTER_PIPELINE_HANDLER(PipelineHandlerUSB) + +} /* namespace libcamera */