From 8d068b7470fc764dcb51f12d191448602639a9d7 Mon Sep 17 00:00:00 2001 From: Daniel Scally Date: Wed, 25 Jun 2025 12:54:54 +0100 Subject: [PATCH] libcamera: device_enumerator: Support regex to match entity names Some entities in a media graph have names that might differ from implementation to implementation; for example the Camera Receiver Unit and CSI-2 receiver on the RZ/V2H(P) SoC have entities with names that include their address, in the form "csi-16000400.csi2". Passing that entity name to DeviceMatch is too inflexible given it would only work if that specific CSI-2 receiver were the one being used. Add an overload for DeviceMatch::add() such that users can pass in a std::regex instead of a string. Update DeviceMatch::match() to check for entities that are matched by the regular expressions added with the new overload after checking for any exact matches from the vector of strings. This allows us to use regex to match on patterns like "csi-[0-9a-f]{8}.csi2". Signed-off-by: Daniel Scally Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi --- .../libcamera/internal/device_enumerator.h | 3 ++ src/libcamera/device_enumerator.cpp | 39 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h index db3532a9..5e1aec99 100644 --- a/include/libcamera/internal/device_enumerator.h +++ b/include/libcamera/internal/device_enumerator.h @@ -11,6 +11,7 @@ #include #include +#include #include namespace libcamera { @@ -23,12 +24,14 @@ public: DeviceMatch(const std::string &driver); void add(const std::string &entity); + void add(std::regex entity); bool match(const MediaDevice *device) const; private: std::string driver_; std::vector entities_; + std::vector entityRegexs_; }; class DeviceEnumerator diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index ae17862f..0ce65e89 100644 --- a/src/libcamera/device_enumerator.cpp +++ b/src/libcamera/device_enumerator.cpp @@ -53,7 +53,8 @@ LOG_DEFINE_CATEGORY(DeviceEnumerator) * * 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. + * names (or regular expressions designed to match an entity name) can be added + * as match criteria. * * Pipeline handlers are recommended to add entities to DeviceMatch as * appropriate to ensure that the media device they need can be uniquely @@ -81,6 +82,15 @@ void DeviceMatch::add(const std::string &entity) entities_.push_back(entity); } +/** + * \brief Add a regex to match a media entity name to the search pattern + * \param[in] entity The regex intended to match to an entity in the media graph + */ +void DeviceMatch::add(std::regex entity) +{ + entityRegexs_.push_back(std::move(entity)); +} + /** * \brief Compare a search pattern with a media device * \param[in] device The media device @@ -116,6 +126,33 @@ bool DeviceMatch::match(const MediaDevice *device) const return false; } + for (const std::regex &nameRegex : entityRegexs_) { + bool found = false; + + for (const MediaEntity *entity : device->entities()) { + if (!std::regex_search(entity->name(), nameRegex)) + continue; + + if (found) { + LOG(DeviceEnumerator, Error) + << "Multiple entities match regex"; + return false; + } + + if (entity->deviceNode().empty()) { + LOG(DeviceEnumerator, Debug) + << "Skip " << entity->name() + << ": no device node"; + continue; + } + + found = true; + } + + if (!found) + return false; + } + return true; }