@@ -11,6 +11,7 @@
#include <string>
#include <vector>
+#include <libcamera/base/regex.h>
#include <libcamera/base/signal.h>
namespace libcamera {
@@ -23,12 +24,14 @@ public:
DeviceMatch(const std::string &driver);
void add(const std::string &entity);
+ void add(const std::regex entity);
bool match(const MediaDevice *device) const;
private:
std::string driver_;
std::vector<std::string> entities_;
+ std::vector<std::regex> entityRegexs_;
};
class DeviceEnumerator
@@ -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(const 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;
}