From 3f695daa17a5c5d5e70fe63bd171d3a164b4c0bb Mon Sep 17 00:00:00 2001 From: Firefly35 Date: Thu, 20 Apr 2023 11:48:33 +0200 Subject: [PATCH] feat[resource_management]: add ResourcePathManager class to allow users to specify alternate search paths for resources in order to fit with their own deployment structure layout. The ResourcePathManager class allows to add absolute or relative additionnal search paths where resources can be located (for instance tflite files). --- mediapipe/util/BUILD | 2 ++ mediapipe/util/resource_path_manager.cc | 47 +++++++++++++++++++++++++ mediapipe/util/resource_path_manager.h | 36 +++++++++++++++++++ mediapipe/util/resource_util_android.cc | 10 ++++++ mediapipe/util/resource_util_apple.cc | 10 ++++++ mediapipe/util/resource_util_default.cc | 10 ++++++ 6 files changed, 115 insertions(+) create mode 100644 mediapipe/util/resource_path_manager.cc create mode 100644 mediapipe/util/resource_path_manager.h diff --git a/mediapipe/util/BUILD b/mediapipe/util/BUILD index cd82a850a..e12e04050 100644 --- a/mediapipe/util/BUILD +++ b/mediapipe/util/BUILD @@ -188,6 +188,8 @@ cc_library( srcs = [ "resource_util.cc", "resource_util_internal.h", + "resource_path_manager.cc", + "resource_path_manager.h", ] + select({ "//conditions:default": ["resource_util_default.cc"], "//mediapipe:android": ["resource_util_android.cc"], diff --git a/mediapipe/util/resource_path_manager.cc b/mediapipe/util/resource_path_manager.cc new file mode 100644 index 000000000..f3806be8d --- /dev/null +++ b/mediapipe/util/resource_path_manager.cc @@ -0,0 +1,47 @@ +// Copyright 2019 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "mediapipe/util/resource_path_manager.h" + +#include + +#include "absl/strings/str_split.h" +#include "mediapipe/framework/deps/file_path.h" +#include "mediapipe/framework/port/file_helpers.h" +#include "mediapipe/framework/port/ret_check.h" + +namespace mediapipe { + +std::vector resource_search_paths_; + +void ResourcePathManager::AddSearchPath(const std::string& path) +{ + resource_search_paths_.push_back(path); +} + +absl::StatusOr ResourcePathManager::ResolveFilePath(const std::string& path) +{ + if (absl::StartsWith(path, "/")) { + return path; + } + for (auto & resource_path: resource_search_paths_) { + auto file_path = file::JoinPath(resource_path, path); + if (file::Exists(file_path).ok()) { + return file_path; + } + } + return absl::NotFoundError("No file " + path + " found in declared search paths"); +} + +} // namespace mediapipe diff --git a/mediapipe/util/resource_path_manager.h b/mediapipe/util/resource_path_manager.h new file mode 100644 index 000000000..ad91c0760 --- /dev/null +++ b/mediapipe/util/resource_path_manager.h @@ -0,0 +1,36 @@ +// Copyright 2019 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MEDIAPIPE_UTIL_RESOURCE_PATH_MANAGER_H_ +#define MEDIAPIPE_UTIL_RESOURCE_PATH_MANAGER_H_ + +#include + +#include "mediapipe/framework/port/statusor.h" + +namespace mediapipe { + +// The ResourcePathManager provides additionnal search paths handling for resources (tflite...) locations. +class ResourcePathManager { + public: + // Adds a path to search resources for. + static void AddSearchPath(const std::string& path); + // Tries to resolve a filepath from path and previously added search path. + // Either return the filepath when it exists, or absl::NotFoundError when the path doesn't exists. + static absl::StatusOr ResolveFilePath(const std::string& path); +}; + +} // namespace mediapipe + +#endif // MEDIAPIPE_UTIL_RESOURCE_UTIL_H_ diff --git a/mediapipe/util/resource_util_android.cc b/mediapipe/util/resource_util_android.cc index 1e970f212..65d413456 100644 --- a/mediapipe/util/resource_util_android.cc +++ b/mediapipe/util/resource_util_android.cc @@ -21,6 +21,7 @@ #include "mediapipe/framework/port/statusor.h" #include "mediapipe/util/android/asset_manager_util.h" #include "mediapipe/util/android/file/base/helpers.h" +#include "mediapipe/util/resource_path_manager.h" namespace mediapipe { @@ -79,6 +80,15 @@ absl::StatusOr PathToResourceAsFile(const std::string& path) { } } + // try to load file in potentially declared resource paths + { + auto status_or_path = ResourcePathManager::ResolveFilePath(path); + if (status_or_path.ok()) { + LOG(INFO) << "Successfully loaded: " << path; + return status_or_path; + } + } + // If that fails, assume it was a relative path, and try just the base name. { const size_t last_slash_idx = path.find_last_of("\\/"); diff --git a/mediapipe/util/resource_util_apple.cc b/mediapipe/util/resource_util_apple.cc index f64718348..8d21c0b0d 100644 --- a/mediapipe/util/resource_util_apple.cc +++ b/mediapipe/util/resource_util_apple.cc @@ -22,6 +22,7 @@ #include "mediapipe/framework/port/ret_check.h" #include "mediapipe/framework/port/statusor.h" #include "mediapipe/util/resource_util.h" +#include "mediapipe/util/resource_path_manager.h" namespace mediapipe { @@ -59,6 +60,15 @@ absl::StatusOr PathToResourceAsFile(const std::string& path) { return path; } + // try to load file in potentially declared resource paths + { + auto status_or_path = ResourcePathManager::ResolveFilePath(path); + if (status_or_path.ok()) { + LOG(INFO) << "Successfully loaded: " << path; + return status_or_path; + } + } + // Try to load a relative path or a base filename as is. { auto status_or_path = PathToResourceAsFileInternal(path); diff --git a/mediapipe/util/resource_util_default.cc b/mediapipe/util/resource_util_default.cc index 3ebbd1f34..328f25b67 100644 --- a/mediapipe/util/resource_util_default.cc +++ b/mediapipe/util/resource_util_default.cc @@ -18,6 +18,7 @@ #include "mediapipe/framework/deps/file_path.h" #include "mediapipe/framework/port/file_helpers.h" #include "mediapipe/framework/port/statusor.h" +#include "mediapipe/util/resource_path_manager.h" ABSL_FLAG( std::string, resource_root_dir, "", @@ -43,6 +44,15 @@ absl::StatusOr PathToResourceAsFile(const std::string& path) { return path; } + // try to load file in potentially declared resource paths + { + auto status_or_path = ResourcePathManager::ResolveFilePath(path); + if (status_or_path.ok()) { + LOG(INFO) << "Successfully loaded: " << path; + return status_or_path; + } + } + // Try to load the file from bazel-bin. If it does not exist, fall back to the // resource folder. auto bazel_path = JoinPath("bazel-bin", path);