diff --git a/mediapipe/framework/BUILD b/mediapipe/framework/BUILD index d987e1bb1b..d54f479c4b 100644 --- a/mediapipe/framework/BUILD +++ b/mediapipe/framework/BUILD @@ -667,11 +667,12 @@ cc_library( hdrs = ["resources.h"], visibility = ["//visibility:public"], deps = [ - "//mediapipe/framework/port:status", + "//mediapipe/framework/tool:status_util", "//mediapipe/util:resource_util", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:string_view", ], ) @@ -687,7 +688,7 @@ cc_test( "//mediapipe/framework/port:gtest_main", "//mediapipe/framework/port:status_matchers", "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", + "@com_google_absl//absl/flags:flag", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings:string_view", ], diff --git a/mediapipe/framework/resources.cc b/mediapipe/framework/resources.cc index ebdbb7744f..e8daefa1e1 100644 --- a/mediapipe/framework/resources.cc +++ b/mediapipe/framework/resources.cc @@ -6,9 +6,11 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" -#include "mediapipe/framework/port/status_macros.h" +#include "mediapipe/framework/tool/status_util.h" #include "mediapipe/util/resource_util.h" namespace mediapipe { @@ -37,10 +39,32 @@ class DefaultResources : public Resources { public: absl::StatusOr> Get( absl::string_view resource_id, const Options& options) const final { - std::string contents; - MP_RETURN_IF_ERROR(GetResourceContents(std::string(resource_id), &contents, - options.read_as_binary)); - return MakeStringResource(std::move(contents)); + // First try to load resource as is. + std::string path(resource_id); + std::string output; + absl::Status status = + GetResourceContents(path, &output, options.read_as_binary); + if (status.ok()) { + return MakeStringResource(std::move(output)); + } + + // Try to resolve resource_id. + absl::StatusOr resolved_path = PathToResourceAsFile(path); + if (!resolved_path.ok() || resolved_path.value() == path) { + return tool::CombinedStatus( + absl::StrCat("Failed to load resource: ", resource_id), + {status, resolved_path.status()}); + } + + // Try to load by resolved path. + absl::Status status_for_resolved = GetResourceContents( + resolved_path.value(), &output, options.read_as_binary); + if (status_for_resolved.ok()) { + return MakeStringResource(std::move(output)); + } + return tool::CombinedStatus( + absl::StrCat("Failed to load resource: ", resource_id), + {status, status_for_resolved}); } }; diff --git a/mediapipe/framework/resources_test.cc b/mediapipe/framework/resources_test.cc index 7666994822..83e922e69a 100644 --- a/mediapipe/framework/resources_test.cc +++ b/mediapipe/framework/resources_test.cc @@ -5,13 +5,16 @@ #include #include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" +#include "absl/flags/declare.h" +#include "absl/flags/flag.h" #include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "mediapipe/framework/port/gmock.h" #include "mediapipe/framework/port/gtest.h" #include "mediapipe/framework/port/status_matchers.h" +ABSL_DECLARE_FLAG(std::string, resource_root_dir); + namespace mediapipe { namespace { @@ -36,6 +39,27 @@ TEST(Resources, CanCreateDefaultResourcesAndReadFileContents) { EXPECT_EQ(resource->ToStringView(), "File system calculator contents\n"); } +TEST(Resources, CanReadFileContentsByUnresolvedId) { + absl::SetFlag(&FLAGS_resource_root_dir, "mediapipe/framework/testdata"); + std::unique_ptr resources = CreateDefaultResources(); + + MP_ASSERT_OK_AND_ASSIGN(std::unique_ptr resource, + resources->Get("resource_calculator.data")); + EXPECT_EQ(resource->ToStringView(), "File system calculator contents\n"); +} + +// PathToResourceFile is called in many in places and Resource object may +// receive an already resolved id. +TEST(Resources, CanReadFileContentsByResolvedIdWhenRootDirSpecified) { + absl::SetFlag(&FLAGS_resource_root_dir, "mediapipe/framework/testdata"); + std::unique_ptr resources = CreateDefaultResources(); + + MP_ASSERT_OK_AND_ASSIGN( + std::unique_ptr resource, + resources->Get("mediapipe/framework/testdata/resource_calculator.data")); + EXPECT_EQ(resource->ToStringView(), "File system calculator contents\n"); +} + TEST(Resources, CanCreateDefaultResourcesWithMappingAndReadFileContents) { absl::flat_hash_map mapping = { {"$CUSTOM_ID", "mediapipe/framework/testdata/resource_calculator.data"}}; diff --git a/mediapipe/modules/face_landmark/BUILD b/mediapipe/modules/face_landmark/BUILD index 786d5f1727..00c3388afa 100644 --- a/mediapipe/modules/face_landmark/BUILD +++ b/mediapipe/modules/face_landmark/BUILD @@ -168,7 +168,7 @@ mediapipe_simple_subgraph( deps = [ "//mediapipe/calculators/core:constant_side_packet_calculator", "//mediapipe/calculators/tflite:tflite_model_calculator", - "//mediapipe/calculators/util:local_file_contents_calculator", + "//mediapipe/calculators/util:resource_provider_calculator", "//mediapipe/framework/tool:switch_container", ], ) diff --git a/mediapipe/modules/face_landmark/face_landmarks_model_loader.pbtxt b/mediapipe/modules/face_landmark/face_landmarks_model_loader.pbtxt index ecac1a6b9e..1477ffadfc 100644 --- a/mediapipe/modules/face_landmark/face_landmarks_model_loader.pbtxt +++ b/mediapipe/modules/face_landmark/face_landmarks_model_loader.pbtxt @@ -43,16 +43,16 @@ node { } } -# Loads the file in the specified path into a blob. +# Loads the file in the specified path as a resource. node { - calculator: "LocalFileContentsCalculator" - input_side_packet: "FILE_PATH:model_path" - output_side_packet: "CONTENTS:model_blob" + calculator: "ResourceProviderCalculator" + input_side_packet: "RESOURCE_ID:model_path" + output_side_packet: "RESOURCE:model_resource" } -# Converts the input blob into a TF Lite model. +# Converts the provided resource into a TF Lite model. node { calculator: "TfLiteModelCalculator" - input_side_packet: "MODEL_BLOB:model_blob" + input_side_packet: "MODEL_RESOURCE:model_resource" output_side_packet: "MODEL:model" } diff --git a/mediapipe/modules/hand_landmark/BUILD b/mediapipe/modules/hand_landmark/BUILD index 491c1d2535..140364cb2d 100644 --- a/mediapipe/modules/hand_landmark/BUILD +++ b/mediapipe/modules/hand_landmark/BUILD @@ -39,7 +39,7 @@ mediapipe_simple_subgraph( deps = [ "//mediapipe/calculators/core:constant_side_packet_calculator", "//mediapipe/calculators/tflite:tflite_model_calculator", - "//mediapipe/calculators/util:local_file_contents_calculator", + "//mediapipe/calculators/util:resource_provider_calculator", "//mediapipe/framework/tool:switch_container", ], ) diff --git a/mediapipe/modules/hand_landmark/hand_landmark_model_loader.pbtxt b/mediapipe/modules/hand_landmark/hand_landmark_model_loader.pbtxt index c9ecf8a0c5..5941ce2ba4 100644 --- a/mediapipe/modules/hand_landmark/hand_landmark_model_loader.pbtxt +++ b/mediapipe/modules/hand_landmark/hand_landmark_model_loader.pbtxt @@ -43,21 +43,16 @@ node { } } -# Loads the file in the specified path into a blob. +# Loads the file in the specified path as a resource. node { - calculator: "LocalFileContentsCalculator" - input_side_packet: "FILE_PATH:model_path" - output_side_packet: "CONTENTS:model_blob" - options: { - [mediapipe.LocalFileContentsCalculatorOptions.ext]: { - text_mode: false - } - } + calculator: "ResourceProviderCalculator" + input_side_packet: "RESOURCE_ID:model_path" + output_side_packet: "RESOURCE:model_resource" } -# Converts the input blob into a TF Lite model. +# Converts the provided resource into a TF Lite model. node { calculator: "TfLiteModelCalculator" - input_side_packet: "MODEL_BLOB:model_blob" + input_side_packet: "MODEL_RESOURCE:model_resource" output_side_packet: "MODEL:model" } diff --git a/mediapipe/modules/objectron/BUILD b/mediapipe/modules/objectron/BUILD index abba3fb36f..6860d43fb8 100644 --- a/mediapipe/modules/objectron/BUILD +++ b/mediapipe/modules/objectron/BUILD @@ -159,7 +159,7 @@ mediapipe_simple_subgraph( "//mediapipe/calculators/util:association_norm_rect_calculator", "//mediapipe/calculators/util:collection_has_min_size_calculator", "//mediapipe/calculators/util:detections_to_rects_calculator", - "//mediapipe/calculators/util:local_file_contents_calculator", + "//mediapipe/calculators/util:resource_provider_calculator", "//mediapipe/modules/objectron/calculators:frame_annotation_to_rect_calculator", "//mediapipe/modules/objectron/calculators:landmarks_to_frame_annotation_calculator", "//mediapipe/modules/objectron/calculators:lift_2d_frame_annotation_to_3d_calculator", diff --git a/mediapipe/modules/objectron/objectron_cpu.pbtxt b/mediapipe/modules/objectron/objectron_cpu.pbtxt index 884da057b7..6e3c133696 100644 --- a/mediapipe/modules/objectron/objectron_cpu.pbtxt +++ b/mediapipe/modules/objectron/objectron_cpu.pbtxt @@ -37,17 +37,17 @@ output_stream: "MULTI_LANDMARKS:multi_box_landmarks" # Crop rectangles derived from bounding box landmarks. output_stream: "NORM_RECTS:multi_box_rects" -# Loads the file in the specified path into a blob. +# Loads the file in the specified path as a resource. node { - calculator: "LocalFileContentsCalculator" - input_side_packet: "FILE_PATH:0:box_landmark_model_path" - output_side_packet: "CONTENTS:0:box_landmark_model_blob" + calculator: "ResourceProviderCalculator" + input_side_packet: "RESOURCE_ID:0:box_landmark_model_path" + output_side_packet: "RESOURCE:0:box_landmark_model_resource" } -# Converts the input blob into a TF Lite model. +# Converts the resource into a TF Lite model. node { calculator: "TfLiteModelCalculator" - input_side_packet: "MODEL_BLOB:box_landmark_model_blob" + input_side_packet: "MODEL_RESOURCE:box_landmark_model_resource" output_side_packet: "MODEL:box_landmark_model" } diff --git a/mediapipe/modules/palm_detection/BUILD b/mediapipe/modules/palm_detection/BUILD index e1abb1e714..3784a49201 100644 --- a/mediapipe/modules/palm_detection/BUILD +++ b/mediapipe/modules/palm_detection/BUILD @@ -37,7 +37,7 @@ mediapipe_simple_subgraph( deps = [ "//mediapipe/calculators/core:constant_side_packet_calculator", "//mediapipe/calculators/tflite:tflite_model_calculator", - "//mediapipe/calculators/util:local_file_contents_calculator", + "//mediapipe/calculators/util:resource_provider_calculator", "//mediapipe/framework/tool:switch_container", ], ) diff --git a/mediapipe/modules/palm_detection/palm_detection_model_loader.pbtxt b/mediapipe/modules/palm_detection/palm_detection_model_loader.pbtxt index f33a76ec22..587098a737 100644 --- a/mediapipe/modules/palm_detection/palm_detection_model_loader.pbtxt +++ b/mediapipe/modules/palm_detection/palm_detection_model_loader.pbtxt @@ -43,21 +43,16 @@ node { } } -# Loads the file in the specified path into a blob. +# Loads the file in the specified path as a resource. node { - calculator: "LocalFileContentsCalculator" - input_side_packet: "FILE_PATH:model_path" - output_side_packet: "CONTENTS:model_blob" - options: { - [mediapipe.LocalFileContentsCalculatorOptions.ext]: { - text_mode: false - } - } + calculator: "ResourceProviderCalculator" + input_side_packet: "RESOURCE_ID:model_path" + output_side_packet: "RESOURCE:model_resource" } -# Converts the input blob into a TF Lite model. +# Converts the provided resource into a TF Lite model. node { calculator: "TfLiteModelCalculator" - input_side_packet: "MODEL_BLOB:model_blob" + input_side_packet: "MODEL_RESOURCE:model_resource" output_side_packet: "MODEL:model" } diff --git a/mediapipe/modules/pose_landmark/BUILD b/mediapipe/modules/pose_landmark/BUILD index d374ad43c1..012882501c 100644 --- a/mediapipe/modules/pose_landmark/BUILD +++ b/mediapipe/modules/pose_landmark/BUILD @@ -32,7 +32,7 @@ mediapipe_simple_subgraph( deps = [ "//mediapipe/calculators/core:constant_side_packet_calculator", "//mediapipe/calculators/tflite:tflite_model_calculator", - "//mediapipe/calculators/util:local_file_contents_calculator", + "//mediapipe/calculators/util:resource_provider_calculator", "//mediapipe/framework/tool:switch_container", ], ) diff --git a/mediapipe/modules/pose_landmark/pose_landmark_model_loader.pbtxt b/mediapipe/modules/pose_landmark/pose_landmark_model_loader.pbtxt index ce7036ebb4..334e55c4a6 100644 --- a/mediapipe/modules/pose_landmark/pose_landmark_model_loader.pbtxt +++ b/mediapipe/modules/pose_landmark/pose_landmark_model_loader.pbtxt @@ -53,21 +53,16 @@ node { } } -# Loads the file in the specified path into a blob. +# Loads the file in the specified path as a resource. node { - calculator: "LocalFileContentsCalculator" - input_side_packet: "FILE_PATH:model_path" - output_side_packet: "CONTENTS:model_blob" - options: { - [mediapipe.LocalFileContentsCalculatorOptions.ext]: { - text_mode: false - } - } + calculator: "ResourceProviderCalculator" + input_side_packet: "RESOURCE_ID:model_path" + output_side_packet: "RESOURCE:model_resource" } -# Converts the input blob into a TF Lite model. +# Converts the provided resource into a TF Lite model. node { calculator: "TfLiteModelCalculator" - input_side_packet: "MODEL_BLOB:model_blob" + input_side_packet: "MODEL_RESOURCE:model_resource" output_side_packet: "MODEL:model" } diff --git a/mediapipe/modules/selfie_segmentation/BUILD b/mediapipe/modules/selfie_segmentation/BUILD index 665cbc8afd..42a24086c5 100644 --- a/mediapipe/modules/selfie_segmentation/BUILD +++ b/mediapipe/modules/selfie_segmentation/BUILD @@ -32,7 +32,7 @@ mediapipe_simple_subgraph( deps = [ "//mediapipe/calculators/core:constant_side_packet_calculator", "//mediapipe/calculators/tflite:tflite_model_calculator", - "//mediapipe/calculators/util:local_file_contents_calculator", + "//mediapipe/calculators/util:resource_provider_calculator", "//mediapipe/framework/tool:switch_container", ], ) diff --git a/mediapipe/modules/selfie_segmentation/selfie_segmentation_model_loader.pbtxt b/mediapipe/modules/selfie_segmentation/selfie_segmentation_model_loader.pbtxt index e4b4e7cc2d..5de0c70b8c 100644 --- a/mediapipe/modules/selfie_segmentation/selfie_segmentation_model_loader.pbtxt +++ b/mediapipe/modules/selfie_segmentation/selfie_segmentation_model_loader.pbtxt @@ -47,21 +47,16 @@ node { } } -# Loads the file in the specified path into a blob. +# Loads the file in the specified path as a resource. node { - calculator: "LocalFileContentsCalculator" - input_side_packet: "FILE_PATH:model_path" - output_side_packet: "CONTENTS:model_blob" - options: { - [mediapipe.LocalFileContentsCalculatorOptions.ext]: { - text_mode: false - } - } + calculator: "ResourceProviderCalculator" + input_side_packet: "RESOURCE_ID:model_path" + output_side_packet: "RESOURCE:model_resource" } -# Converts the input blob into a TF Lite model. +# Converts the provided resource into a TF Lite model. node { calculator: "TfLiteModelCalculator" - input_side_packet: "MODEL_BLOB:model_blob" + input_side_packet: "MODEL_RESOURCE:model_resource" output_side_packet: "MODEL:model" }