[libcamera-devel] [PATCH v4 4/6] libcamera: ipa_manager: Allow recursive parsing

Kieran Bingham kieran.bingham at ideasonboard.com
Fri Feb 21 17:31:28 CET 2020


Provide an optional means to recurse into subdirectories to search for IPA
libraries. This allows IPAs contained within their own build directory
to be found when loading from a non-installed build.

Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/libcamera/include/ipa_manager.h |  4 +-
 src/libcamera/ipa_manager.cpp       | 62 +++++++++++++++++++++++------
 2 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/src/libcamera/include/ipa_manager.h b/src/libcamera/include/ipa_manager.h
index f13a93d74498..467658e40ce9 100644
--- a/src/libcamera/include/ipa_manager.h
+++ b/src/libcamera/include/ipa_manager.h
@@ -32,7 +32,9 @@ private:
 	IPAManager();
 	~IPAManager();
 
-	unsigned int addDir(const char *libDir);
+	void parseDir(const char *libDir, unsigned int maxDepth,
+		      std::vector<std::string> &files);
+	unsigned int addDir(const char *libDir, unsigned int maxDepth = 0);
 };
 
 } /* namespace libcamera */
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index 90dd30030dcb..de99a0bc3ce1 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++;
-- 
2.20.1



More information about the libcamera-devel mailing list