Skip to content

Commit

Permalink
feat(sdk): implement AssetManager
Browse files Browse the repository at this point in the history
  • Loading branch information
homuler committed Oct 10, 2020
1 parent 6ebac7d commit 3a782c6
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 100 deletions.
7 changes: 0 additions & 7 deletions Assets/MediaPipe/SDK/Scripts/ResourceUtil.cs

This file was deleted.

8 changes: 7 additions & 1 deletion Assets/MediaPipe/SDK/Scripts/UnsafeNativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
using MpStatusOrImageFrame = System.IntPtr;
using MpStatusOrPoller = System.IntPtr;

using CacheFilePathResolverPtr = System.IntPtr;
using GlContextPtr = System.IntPtr;
using GlTexturePtr = System.IntPtr;
using GlTextureInfoPtr = System.IntPtr;
Expand All @@ -36,6 +37,7 @@
using ImageFramePtr = System.IntPtr;
using OutputStreamPollerPtr = System.IntPtr;
using ProtobufLogHandlerPtr = System.IntPtr;
using ReadFileHandlerPtr = System.IntPtr;

namespace Mediapipe {
[SuppressUnmanagedCodeSecurityAttribute]
Expand Down Expand Up @@ -344,10 +346,14 @@ internal static class UnsafeNativeMethods {
public static extern unsafe MpNormalizedRectVector MpPacketGetNormalizedRectVector(MpPacket packet);


#if UNITY_EDITOR || UNITY_STANDALONE
/// Resource Util API
[DllImport (MediaPipeLibrary)]
public static extern unsafe void MpSetResourceRootPath(string path);
public static extern unsafe void MpAssetManagerInitialize([MarshalAs(UnmanagedType.FunctionPtr)]CacheFilePathResolverPtr resolver,[MarshalAs(UnmanagedType.FunctionPtr)]ReadFileHandlerPtr handler);

[DllImport (MediaPipeLibrary)]
public static extern unsafe void MpStringCopy(IntPtr dest, byte[] src, int size);
#endif

/// SidePacket API

Expand Down
8 changes: 8 additions & 0 deletions Assets/MediaPipe/SDK/Scripts/Util.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions Assets/MediaPipe/SDK/Scripts/Util/AssetManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Runtime.InteropServices;

namespace Mediapipe {
public abstract class AssetManager {
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate string CacheFilePathResolver(string path);
private readonly CacheFilePathResolver cacheFilePathResolver;

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate bool ReadFileHandler(string path, IntPtr dst);
private readonly ReadFileHandler readFileHandler;

protected AssetManager() {
cacheFilePathResolver = CacheFileFromAsset;
readFileHandler = ReadFile;
}

public IntPtr GetCacheFilePathResolverPtr() {
return Marshal.GetFunctionPointerForDelegate(cacheFilePathResolver);
}

public IntPtr GetReadFileHandlerPtr() {
return Marshal.GetFunctionPointerForDelegate(readFileHandler);
}

public abstract string CacheFileFromAsset(string assetPath);

public abstract bool ReadFile(string path, IntPtr dst);
}
}
11 changes: 11 additions & 0 deletions Assets/MediaPipe/SDK/Scripts/Util/AssetManager.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions Assets/MediaPipe/SDK/Scripts/Util/ResourceUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;

namespace Mediapipe {
public class ResourceUtil {
public static void InitializeAssetManager(AssetManager assetManager) {
UnsafeNativeMethods.MpAssetManagerInitialize(assetManager.GetCacheFilePathResolverPtr(), assetManager.GetReadFileHandlerPtr());
}

public static void CopyBytes(IntPtr dst, byte[] src) {
UnsafeNativeMethods.MpStringCopy(dst, src, src.Length);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion C/mediapipe_api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ cc_library(
"//mediapipe_api/framework/formats:landmark",
"//mediapipe_api/framework/formats:rect",
"//mediapipe_api/framework/port:logging",
"//mediapipe_api/util:resource_util",
"//mediapipe_api/util:asset_manager",
] + select({
"@com_google_mediapipe//mediapipe/gpu:disable_gpu": [],
"//conditions:default": [
Expand Down
11 changes: 7 additions & 4 deletions C/mediapipe_api/util/BUILD
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
cc_library(
name = "resource_util",
srcs = ["resource_util.cc"],
hdrs = ["resource_util.h"],
name = "asset_manager",
srcs = ["asset_manager.cc"],
hdrs = ["asset_manager.h"],
deps = [
"@com_google_mediapipe//mediapipe/util:resource_util",
"@com_google_mediapipe//mediapipe/framework/port:logging",
"@com_google_mediapipe//mediapipe/framework/port:ret_check",
"@com_google_mediapipe//mediapipe/framework/port:status",
"@com_google_mediapipe//mediapipe/util:asset_manager",
"//mediapipe_api:common",
],
visibility = ["//visibility:public"],
Expand Down
42 changes: 42 additions & 0 deletions C/mediapipe_api/util/asset_manager.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "mediapipe/framework/port/canonical_errors.h"
#include "mediapipe/framework/port/logging.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe_api/util/asset_manager.h"

namespace {
CacheFilePathResolver* cache_file_path_resolver_ = nullptr;
ReadFileHandler* read_file_handler_ = nullptr;
}

void MpAssetManagerInitialize(CacheFilePathResolver* resolver, ReadFileHandler* handler) {
cache_file_path_resolver_ = resolver;
read_file_handler_ = handler;
}

void MpStringCopy(std::string* dst, const char* src, int size) {
std::string(src, size).swap(*dst);
}

namespace mediapipe {

bool AssetManager::ReadFile(const std::string& filename, std::string* output) {
if (read_file_handler_ == nullptr) {
LOG(ERROR) << "AssetManager is not initialized";
return false;
}

return read_file_handler_(filename.c_str(), output);
}

::mediapipe::StatusOr<std::string> AssetManager::CachedFileFromAsset(const std::string& filename) {
if (cache_file_path_resolver_ == nullptr) {
return ::mediapipe::FailedPreconditionError("AssetManager is not initialized");
}

auto asset_path = cache_file_path_resolver_(filename.c_str());
RET_CHECK_NE(asset_path, nullptr);

return std::string(asset_path);
}

} // namespace mediapipe
18 changes: 18 additions & 0 deletions C/mediapipe_api/util/asset_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef C_MEDIAPIPE_API_UTIL_ASSET_MANAGER_H_
#define C_MEDIAPIPE_API_UTIL_ASSET_MANAGER_H_

#include <string>
#include "mediapipe/util/asset_manager.h"
#include "mediapipe_api/common.h"

extern "C" {

typedef const char* CacheFilePathResolver(const char* path);
typedef bool ReadFileHandler(const char* path, std::string* output);

MP_CAPI_EXPORT extern void MpAssetManagerInitialize(CacheFilePathResolver* resolver, ReadFileHandler* handler);
MP_CAPI_EXPORT extern void MpStringCopy(std::string* dst, const char* src, int size);

} // extern "C"

#endif // C_MEDIAPIPE_API_UTIL_ASSET_MANAGER_H_
149 changes: 63 additions & 86 deletions C/third_party/mediapipe_model_path.diff
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
diff --git a/mediapipe/util/BUILD b/mediapipe/util/BUILD
index 9347fc0..a346675 100644
index 9347fc0..b42c20e 100644
--- a/mediapipe/util/BUILD
+++ b/mediapipe/util/BUILD
@@ -149,7 +149,7 @@ cc_library(
@@ -146,10 +146,20 @@ cc_library(
],
)

+cc_library(
+ name = "asset_manager",
+ hdrs = ["asset_manager.h"],
+ deps = [
+ "//mediapipe/framework/port:singleton",
+ "//mediapipe/framework/port:statusor",
+ ],
+ visibility = ["//visibility:public"],
+)
+
cc_library(
name = "resource_util",
srcs = select({
Expand All @@ -11,35 +24,20 @@ index 9347fc0..a346675 100644
"//mediapipe:android": ["resource_util_android.cc"],
"//mediapipe:ios": ["resource_util_apple.cc"],
"//mediapipe:macos": ["resource_util.cc"],
@@ -164,7 +164,7 @@ cc_library(
"//mediapipe:macos": [],
}),
visibility = [
- "//mediapipe/framework:mediapipe_internal",
+ "//visibility:public",
],
deps = [
"//mediapipe/framework/port:ret_check",
diff --git a/mediapipe/util/resource_util.h b/mediapipe/util/resource_util.h
index d55706a..b7d9b39 100644
--- a/mediapipe/util/resource_util.h
+++ b/mediapipe/util/resource_util.h
@@ -22,6 +22,9 @@

namespace mediapipe {

+const char* GetResourceRootPath();
+void SetResourceRootPath(const std::string& path);
+
// Given a path to a resource, this function attempts to provide an absolute
// path with which it can be accessed as a file.
// - If the input path is an absolute path, it is returned as-is.
diff --git a/mediapipe/util/resource_util_unity.cc b/mediapipe/util/resource_util_unity.cc
@@ -173,6 +183,7 @@ cc_library(
"@com_google_absl//absl/strings",
] + select({
"//conditions:default": [
+ ":asset_manager",
"//mediapipe/framework/deps:file_path",
"//mediapipe/framework/port:file_helpers",
"@com_google_absl//absl/flags:flag",
diff --git a/mediapipe/util/asset_manager.h b/mediapipe/util/asset_manager.h
new file mode 100644
index 0000000..f9523fe
index 0000000..bd47f39
--- /dev/null
+++ b/mediapipe/util/resource_util_unity.cc
@@ -0,0 +1,93 @@
+++ b/mediapipe/util/asset_manager.h
@@ -0,0 +1,46 @@
+// Copyright 2019 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -54,82 +52,61 @@ index 0000000..f9523fe
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// `PathToResourceAsFile` is based on mediapipe/util/resource_util_android.cc and
+// `GetResourceContents' is copied from mediapipe/util/resource_util.cc
+#ifndef MEDIAPIPE_UTIL_ASSET_MANAGER_H_
+#define MEDIAPIPE_UTIL_ASSET_MANAGER_H_
+
+#include "mediapipe/util/resource_util.h"
+#include <string>
+#include <vector>
+
+#include "absl/flags/flag.h"
+#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"
+#include "mediapipe/framework/port/singleton.h"
+#include "mediapipe/framework/port/statusor.h"
+
+namespace mediapipe {
+
+namespace {
+const char* resourceRootPath;
+// see mediapipe/util/android/asset_manager_util.h
+class AssetManager {
+ public:
+ AssetManager(const AssetManager&) = delete;
+ AssetManager& operator=(const AssetManager&) = delete;
+
+::mediapipe::StatusOr<std::string> PathToResourceAsFileInternal(const std::string& path) {
+ RET_CHECK_OK(mediapipe::file::Exists(path));
+ // Reads a file into output. Returns true on success, false otherwise.
+ bool ReadFile(const std::string& filename, std::string* output);
+
+ return path;
+}
+}
+ ::mediapipe::StatusOr<std::string> CachedFileFromAsset(const std::string& asset_path);
+
+const char* GetResourceRootPath() {
+ if (resourceRootPath == nullptr) {
+ return "";
+ }
+ private:
+ // Private constructor since this class is meant to be a singleton.
+ AssetManager() = default;
+
+ return resourceRootPath;
+}
+ friend class Singleton<AssetManager>;
+};
+
+void SetResourceRootPath(const std::string& path) {
+ auto str_ptr = new char[path.length() + 1];
+ snprintf(str_ptr, path.length() + 1, path.c_str());
+} // namespace mediapipe
+
+ if (resourceRootPath != nullptr) {
+ delete[] resourceRootPath;
+ }
+#endif // MEDIAPIPE_UTIL_ASSET_MANAGER_H_
diff --git a/mediapipe/util/resource_util_unity.cc b/mediapipe/util/resource_util_unity.cc
new file mode 100644
index 0000000..62544ed
--- /dev/null
+++ b/mediapipe/util/resource_util_unity.cc
@@ -0,0 +1,20 @@
+#include "mediapipe/util/asset_manager.h"
+#include "mediapipe/util/resource_util.h"
+#include "mediapipe/framework/port/singleton.h"
+#include "mediapipe/framework/port/ret_check.h"
+
+ resourceRootPath = str_ptr;
+}
+namespace mediapipe {
+
+::mediapipe::StatusOr<std::string> PathToResourceAsFile(
+ const std::string& path) {
+
+ if (absl::StartsWith(path, "/")) {
+ return path;
+ }
+
+ LOG(INFO) << "Path: " << path;
+
+ // Try to load a relative path
+ {
+ auto resource_path = mediapipe::file::JoinPath(GetResourceRootPath(), path);
+ auto status_or_path = PathToResourceAsFileInternal(resource_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("\\/");
+ CHECK_NE(last_slash_idx, std::string::npos); // Make sure it's a path.
+ auto base_name = path.substr(last_slash_idx + 1);
+ auto asset_path = mediapipe::file::JoinPath(GetResourceRootPath(), base_name);
+ auto status_or_path = PathToResourceAsFileInternal(asset_path);
+ if (status_or_path.ok()) LOG(INFO) << "Successfully loaded: " << asset_path;
+ return status_or_path;
+ }
+ return Singleton<AssetManager>::get()->CachedFileFromAsset(path);
+}
+
+::mediapipe::Status GetResourceContents(const std::string& path,
+ std::string* output) {
+ return mediapipe::file::GetContents(path, output);
+ RET_CHECK(Singleton<AssetManager>::get()->ReadFile(path, output))
+ << "could not read asset: " << path;
+ return mediapipe::OkStatus();
+}
+
+} // namespace mediapipe

0 comments on commit 3a782c6

Please sign in to comment.