summaryrefslogtreecommitdiff
path: root/src/libcamera/ipa_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcamera/ipa_manager.cpp')
-rw-r--r--src/libcamera/ipa_manager.cpp62
1 files changed, 49 insertions, 13 deletions
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index 90dd3003..de99a0bc 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -142,47 +142,83 @@ IPAManager *IPAManager::instance()
}
/**
- * \brief Load IPA modules from a directory
- * \param[in] libDir directory to search for IPA modules
+ * \brief Identify shared library objects within a directory
+ * \param[in] libDir The directory to search for shared objects
+ * \param[in] maxDepth The maximum depth of sub-directories to parse
+ * \param[out] files A vector of paths to shared object library files
*
- * This method tries to create an IPAModule instance for every shared object
- * found in \a libDir, and skips invalid IPA modules.
+ * Search a directory for .so files, allowing recursion down to sub-directories
+ * no further than the depth specified by \a maxDepth.
*
- * \return Number of modules loaded by this call
+ * Discovered shared objects are added to the \a files vector.
*/
-unsigned int IPAManager::addDir(const char *libDir)
+void IPAManager::parseDir(const char *libDir, unsigned int maxDepth,
+ std::vector<std::string> &files)
{
struct dirent *ent;
DIR *dir;
dir = opendir(libDir);
if (!dir)
- return 0;
+ return;
- std::vector<std::string> paths;
while ((ent = readdir(dir)) != nullptr) {
+ if (ent->d_type == DT_DIR && maxDepth) {
+ if (strcmp(ent->d_name, ".") == 0 ||
+ strcmp(ent->d_name, "..") == 0)
+ continue;
+
+ std::string subdir = std::string(libDir) + "/" + ent->d_name;
+
+ /* Recursion is limited to maxDepth. */
+ parseDir(subdir.c_str(), maxDepth - 1, files);
+
+ continue;
+ }
+
int offset = strlen(ent->d_name) - 3;
if (offset < 0)
continue;
if (strcmp(&ent->d_name[offset], ".so"))
continue;
- paths.push_back(std::string(libDir) + "/" + ent->d_name);
+ files.push_back(std::string(libDir) + "/" + ent->d_name);
}
+
closedir(dir);
+}
+
+/**
+ * \brief Load IPA modules from a directory
+ * \param[in] libDir The directory to search for IPA modules
+ * \param[in] maxDepth The maximum depth of sub-directories to search
+ *
+ * This method tries to create an IPAModule instance for every shared object
+ * found in \a libDir, and skips invalid IPA modules.
+ *
+ * Sub-directories are searched up to a depth of \a maxDepth. A \a maxDepth
+ * value of 0 only searches the directory specified in \a libDir.
+ *
+ * \return Number of modules loaded by this call
+ */
+unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth)
+{
+ std::vector<std::string> files;
+
+ parseDir(libDir, maxDepth, files);
/* Ensure a stable ordering of modules. */
- std::sort(paths.begin(), paths.end());
+ std::sort(files.begin(), files.end());
unsigned int count = 0;
- for (const std::string &path : paths) {
- IPAModule *ipaModule = new IPAModule(path);
+ for (const std::string &file : files) {
+ IPAModule *ipaModule = new IPAModule(file);
if (!ipaModule->isValid()) {
delete ipaModule;
continue;
}
- LOG(IPAManager, Debug) << "Loaded IPA module '" << path << "'";
+ LOG(IPAManager, Debug) << "Loaded IPA module '" << file << "'";
modules_.push_back(ipaModule);
count++;