Skip to content

Commit

Permalink
Add ResourceProviderCalculator (replacement for LocalFileContentsCalc…
Browse files Browse the repository at this point in the history
…ulator)

PiperOrigin-RevId: 675640351
  • Loading branch information
MediaPipe Team authored and copybara-github committed Sep 17, 2024
1 parent 7d9d336 commit c0fa667
Show file tree
Hide file tree
Showing 5 changed files with 413 additions and 0 deletions.
48 changes: 48 additions & 0 deletions mediapipe/calculators/util/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,54 @@ cc_library(
alwayslink = 1,
)

mediapipe_proto_library(
name = "resource_provider_calculator_proto",
srcs = ["resource_provider_calculator.proto"],
deps = [
"//mediapipe/framework:calculator_options_proto",
"//mediapipe/framework:calculator_proto",
],
)

cc_library(
name = "resource_provider_calculator",
srcs = ["resource_provider_calculator.cc"],
hdrs = ["resource_provider_calculator.h"],
deps = [
":resource_provider_calculator_cc_proto",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:resources",
"//mediapipe/framework/api2:node",
"//mediapipe/framework/api2:packet",
"//mediapipe/framework/api2:port",
"//mediapipe/framework/port:ret_check",
"//mediapipe/framework/port:status",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings:string_view",
],
alwayslink = 1,
)

cc_test(
name = "resource_provider_calculator_test",
srcs = ["resource_provider_calculator_test.cc"],
deps = [
":resource_provider_calculator",
":resource_provider_calculator_cc_proto",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:resources",
"//mediapipe/framework:resources_service",
"//mediapipe/framework/api2:builder",
"//mediapipe/framework/api2:packet",
"//mediapipe/framework/port:gtest_main",
"//mediapipe/util:resources_test_util",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
],
)

cc_library(
name = "local_file_pattern_contents_calculator",
srcs = ["local_file_pattern_contents_calculator.cc"],
Expand Down
77 changes: 77 additions & 0 deletions mediapipe/calculators/util/resource_provider_calculator.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2024 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/calculators/util/resource_provider_calculator.h"

#include <memory>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "mediapipe/calculators/util/resource_provider_calculator.pb.h"
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/api2/packet.h"
#include "mediapipe/framework/api2/port.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/port/status_macros.h"
#include "mediapipe/framework/resources.h"

namespace mediapipe::api2 {

absl::Status ResourceProviderCalculator::UpdateContract(CalculatorContext* cc) {
RET_CHECK_GT(kResources(cc).Count(), 0)
<< "At least one output resource must be specified.";
const bool uses_side_packets = kIds(cc).Count() > 0;
const auto& opts = cc->Options<ResourceProviderCalculatorOptions>();
const bool uses_options = opts.resource_id_size() > 0;
RET_CHECK(uses_side_packets ^ uses_options)
<< "Either side packets or options must be used, not both.";

if (uses_side_packets) {
RET_CHECK_EQ(kIds(cc).Count(), kResources(cc).Count());
} else if (uses_options) {
RET_CHECK_EQ(opts.resource_id_size(), kResources(cc).Count());
}
return absl::OkStatus();
}

absl::Status ResourceProviderCalculator::Open(CalculatorContext* cc) {
const bool uses_side_packets = kIds(cc).Count() > 0;
const auto& opts = cc->Options<ResourceProviderCalculatorOptions>();
Resources::Options res_opts = {};
res_opts.read_as_binary =
opts.read_mode() != ResourceProviderCalculatorOptions::READ_MODE_TEXT;

auto get_resource_id_fn = [&](int i) -> absl::StatusOr<absl::string_view> {
if (uses_side_packets) {
return kIds(cc)[i].Get();
}
return opts.resource_id(i);
};

for (int i = 0; i < kResources(cc).Count(); ++i) {
MP_ASSIGN_OR_RETURN(absl::string_view res_id, get_resource_id_fn(i));
MP_ASSIGN_OR_RETURN(std::unique_ptr<Resource> res,
cc->GetResources().Get(res_id, res_opts));
Packet<Resource> res_packet = api2::PacketAdopting(std::move(res));
kResources(cc)[i].Set(std::move(res_packet));
}
return absl::OkStatus();
}

MEDIAPIPE_REGISTER_NODE(ResourceProviderCalculator)

} // namespace mediapipe::api2
66 changes: 66 additions & 0 deletions mediapipe/calculators/util/resource_provider_calculator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef MEDIAPIPE_CALCULATORS_UTIL_RESOURCE_PROVIDER_CALCULATOR_H_
#define MEDIAPIPE_CALCULATORS_UTIL_RESOURCE_PROVIDER_CALCULATOR_H_

#include <string>

#include "absl/status/status.h"
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/api2/port.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/resources.h"
namespace mediapipe::api2 {

// The calculator takes resource id (e.g. file path) as input side packet or
// calculator options and provides the corresponding resource.
//
// NOTE: calculator supports loading multiple resources.
//
// Example config:
//
// node {
// calculator: "ResourceProviderCalculator"
// output_side_packet: "RESOURCE:0:resource0"
// output_side_packet: "RESOURCE:1:resource1"
// node_options {
// [type.googleapis.com/mediapipe.ResourceProviderCalculatorOptions]: {
// resource_id: "path/to/resource0"
// resource_id: "path/to/resource1"
// }
// }
// }
//
// node {
// calculator: "ResourceProviderCalculator"
// input_side_packet: "RESOURCE_ID:resource_id"
// output_side_packet: "RESOURCE:resource"
// }
//
// node {
// calculator: "ResourceProviderCalculator"
// input_side_packet: "RESOURCE_ID:0:resource_id0"
// input_side_packet: "RESOURCE_ID:1:resource_id1"
// ...
// output_side_packet: "RESOURCE:0:resource0"
// output_side_packet: "RESOURCE:1:resource1"
// ...
// }
//
class ResourceProviderCalculator : public mediapipe::api2::Node {
public:
static constexpr api2::SideInput<std::string>::Multiple kIds{"RESOURCE_ID"};
static constexpr api2::SideOutput<Resource>::Multiple kResources{"RESOURCE"};

MEDIAPIPE_NODE_INTERFACE(ResourceProviderCalculator, kIds, kResources);

static absl::Status UpdateContract(CalculatorContext* cc);

absl::Status Open(CalculatorContext* cc) override;

absl::Status Process(CalculatorContext* cc) override {
return absl::OkStatus();
}
};

} // namespace mediapipe::api2

#endif // MEDIAPIPE_CALCULATORS_UTIL_RESOURCE_PROVIDER_CALCULATOR_H_
34 changes: 34 additions & 0 deletions mediapipe/calculators/util/resource_provider_calculator.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2024 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.

syntax = "proto3";

package mediapipe;

message ResourceProviderCalculatorOptions {
// The calculator will use `resource_id` to load and provide the resource
// through `CalculatorContext::GetResources`.
//
// Resource ID can be a file path, but is not limited to just that. (Clients
// can override resource loading through `kResourcesService`)
repeated string resource_id = 1;

enum ReadMode {
READ_MODE_UNDEFINED = 0; // Defaults to BINARY
READ_MODE_BINARY = 1;
READ_MODE_TEXT = 2;
}

ReadMode read_mode = 2;
}
Loading

0 comments on commit c0fa667

Please sign in to comment.