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; }