Project import generated by Copybara.
GitOrigin-RevId: 73d686c40057684f8bfaca285368bf1813f9fc26
This commit is contained in:
@@ -43,6 +43,7 @@ bzl_library(
|
||||
"//mediapipe/framework:transitive_protos_bzl",
|
||||
"//mediapipe/framework/deps:descriptor_set_bzl",
|
||||
"//mediapipe/framework/deps:expand_template_bzl",
|
||||
"@org_tensorflow//tensorflow/lite/core/shims:cc_library_with_tflite_bzl",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -52,6 +53,7 @@ bzl_library(
|
||||
"build_defs.bzl",
|
||||
],
|
||||
visibility = [
|
||||
"//mediapipe/app/xeno/catalog:__subpackages__",
|
||||
"//mediapipe/framework:__subpackages__",
|
||||
],
|
||||
)
|
||||
@@ -286,6 +288,7 @@ cc_library(
|
||||
mediapipe_cc_test(
|
||||
name = "options_util_test",
|
||||
size = "small",
|
||||
timeout = "moderate",
|
||||
srcs = ["options_util_test.cc"],
|
||||
# A non-empty "data" param is needed to build the "_test_wasm" target.
|
||||
data = [":node_chain_subgraph.proto"],
|
||||
@@ -858,11 +861,9 @@ cc_library(
|
||||
"//mediapipe/framework:calculator_cc_proto",
|
||||
"//mediapipe/framework:calculator_framework",
|
||||
"//mediapipe/framework:mediapipe_options_cc_proto",
|
||||
"//mediapipe/framework:stream_handler_cc_proto",
|
||||
"//mediapipe/framework:subgraph",
|
||||
"//mediapipe/framework/port:ret_check",
|
||||
"//mediapipe/framework/port:status",
|
||||
"//mediapipe/framework/stream_handler:sync_set_input_stream_handler_cc_proto",
|
||||
"//mediapipe/framework/tool:switch_container_cc_proto",
|
||||
],
|
||||
alwayslink = 1,
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// This program takes one input file and encodes its contents as a C++
|
||||
// std::string, which can be included in a C++ source file. It is similar to
|
||||
// filewrapper (and borrows some of its code), but simpler.
|
||||
// This program takes one input file and encodes its contents as a C++ string,
|
||||
// which can be included in a C++ source file. It is similar to filewrapper
|
||||
// (and borrows some of its code), but simpler.
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
@@ -20,6 +20,7 @@ load("//mediapipe/framework:transitive_protos.bzl", "transitive_protos")
|
||||
load("//mediapipe/framework/deps:expand_template.bzl", "expand_template")
|
||||
load("//mediapipe/framework/tool:build_defs.bzl", "clean_dep")
|
||||
load("//mediapipe/framework/deps:descriptor_set.bzl", "direct_descriptor_set", "transitive_descriptor_set")
|
||||
load("@org_tensorflow//tensorflow/lite/core/shims:cc_library_with_tflite.bzl", "cc_library_with_tflite")
|
||||
|
||||
def mediapipe_binary_graph(name, graph = None, output_name = None, deps = [], testonly = False, **kwargs):
|
||||
"""Converts a graph from text format to binary format."""
|
||||
@@ -98,6 +99,7 @@ def mediapipe_simple_subgraph(
|
||||
register_as,
|
||||
graph,
|
||||
deps = [],
|
||||
tflite_deps = None,
|
||||
visibility = None,
|
||||
testonly = None,
|
||||
**kwargs):
|
||||
@@ -109,6 +111,7 @@ def mediapipe_simple_subgraph(
|
||||
CamelCase.
|
||||
graph: the BUILD label of a text-format MediaPipe graph.
|
||||
deps: any calculators or subgraphs used by this graph.
|
||||
tflite_deps: any calculators or subgraphs used by this graph that may use different TFLite implementation.
|
||||
visibility: The list of packages the subgraph should be visible to.
|
||||
testonly: pass 1 if the graph is to be used only for tests.
|
||||
**kwargs: Remaining keyword args, forwarded to cc_library.
|
||||
@@ -138,21 +141,39 @@ def mediapipe_simple_subgraph(
|
||||
},
|
||||
testonly = testonly,
|
||||
)
|
||||
native.cc_library(
|
||||
name = name,
|
||||
srcs = [
|
||||
name + "_linked.cc",
|
||||
graph_base_name + ".inc",
|
||||
],
|
||||
deps = [
|
||||
clean_dep("//mediapipe/framework:calculator_framework"),
|
||||
clean_dep("//mediapipe/framework:subgraph"),
|
||||
] + deps,
|
||||
alwayslink = 1,
|
||||
visibility = visibility,
|
||||
testonly = testonly,
|
||||
**kwargs
|
||||
)
|
||||
if not tflite_deps:
|
||||
native.cc_library(
|
||||
name = name,
|
||||
srcs = [
|
||||
name + "_linked.cc",
|
||||
graph_base_name + ".inc",
|
||||
],
|
||||
deps = [
|
||||
clean_dep("//mediapipe/framework:calculator_framework"),
|
||||
clean_dep("//mediapipe/framework:subgraph"),
|
||||
] + deps,
|
||||
alwayslink = 1,
|
||||
visibility = visibility,
|
||||
testonly = testonly,
|
||||
**kwargs
|
||||
)
|
||||
else:
|
||||
cc_library_with_tflite(
|
||||
name = name,
|
||||
srcs = [
|
||||
name + "_linked.cc",
|
||||
graph_base_name + ".inc",
|
||||
],
|
||||
tflite_deps = tflite_deps,
|
||||
deps = [
|
||||
clean_dep("//mediapipe/framework:calculator_framework"),
|
||||
clean_dep("//mediapipe/framework:subgraph"),
|
||||
] + deps,
|
||||
alwayslink = 1,
|
||||
visibility = visibility,
|
||||
testonly = testonly,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def mediapipe_reexport_library(
|
||||
name,
|
||||
|
||||
@@ -85,7 +85,7 @@ std::pair<std::string, int> ParseTagIndexFromStream(const std::string& stream);
|
||||
// Formats to "tag:index".
|
||||
std::string CatTag(const std::string& tag, int index);
|
||||
|
||||
// Concatenates "tag:index:name" into a single std::string.
|
||||
// Concatenates "tag:index:name" into a single string.
|
||||
std::string CatStream(const std::pair<std::string, int>& tag_index,
|
||||
const std::string& name);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class OptionsSyntaxUtil {
|
||||
FieldPath OptionFieldPath(absl::string_view tag,
|
||||
const Descriptor* descriptor);
|
||||
|
||||
// Splits a std::string into "tag" and "name" delimited by a single colon.
|
||||
// Splits a string into "tag" and "name" delimited by a single colon.
|
||||
std::vector<absl::string_view> StrSplitTags(absl::string_view tag_and_name);
|
||||
|
||||
private:
|
||||
|
||||
@@ -228,7 +228,7 @@ absl::Status SyntaxStatus(bool ok, const std::string& text, T* result) {
|
||||
" for type: ", MediaPipeTypeStringOrDemangled<T>(), "."));
|
||||
}
|
||||
|
||||
// Templated parsing of a std::string value.
|
||||
// Templated parsing of a string value.
|
||||
template <typename T>
|
||||
absl::Status ParseValue(const std::string& text, T* result) {
|
||||
return SyntaxStatus(absl::SimpleAtoi(text, result), text, result);
|
||||
|
||||
@@ -31,7 +31,7 @@ class {{SUBGRAPH_CLASS_NAME}} : public Subgraph {
|
||||
const SubgraphOptions& /*options*/) {
|
||||
CalculatorGraphConfig config;
|
||||
// Note: this is a binary protobuf serialization, and may include NUL
|
||||
// bytes. The trailing NUL added to the std::string literal should be excluded.
|
||||
// bytes. The trailing NUL added to the string literal should be excluded.
|
||||
if (config.ParseFromArray(binary_graph, sizeof(binary_graph) - 1)) {
|
||||
return config;
|
||||
} else {
|
||||
|
||||
@@ -40,7 +40,7 @@ absl::Status StatusInvalid(const std::string& error_message);
|
||||
ABSL_DEPRECATED("Use absl::UnknownError(error_message) instead.")
|
||||
absl::Status StatusFail(const std::string& error_message);
|
||||
|
||||
// Prefixes the given std::string to the error message in status.
|
||||
// Prefixes the given string to the error message in status.
|
||||
// This function should be considered internal to the framework.
|
||||
// TODO Replace usage of AddStatusPrefix with util::Annotate().
|
||||
absl::Status AddStatusPrefix(const std::string& prefix,
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#include "mediapipe/framework/port/canonical_errors.h"
|
||||
#include "mediapipe/framework/port/ret_check.h"
|
||||
#include "mediapipe/framework/port/status.h"
|
||||
#include "mediapipe/framework/stream_handler.pb.h"
|
||||
#include "mediapipe/framework/stream_handler/sync_set_input_stream_handler.pb.h"
|
||||
#include "mediapipe/framework/tool/container_util.h"
|
||||
#include "mediapipe/framework/tool/name_util.h"
|
||||
#include "mediapipe/framework/tool/subgraph_expansion.h"
|
||||
@@ -88,12 +86,6 @@ CalculatorGraphConfig::Node* BuildDemuxNode(
|
||||
CalculatorGraphConfig* config) {
|
||||
CalculatorGraphConfig::Node* result = config->add_node();
|
||||
*result->mutable_calculator() = "SwitchDemuxCalculator";
|
||||
*result->mutable_input_stream_handler()->mutable_input_stream_handler() =
|
||||
"ImmediateInputStreamHandler";
|
||||
if (container_node.has_input_stream_handler()) {
|
||||
*result->mutable_input_stream_handler() =
|
||||
container_node.input_stream_handler();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -103,8 +95,6 @@ CalculatorGraphConfig::Node* BuildMuxNode(
|
||||
CalculatorGraphConfig* config) {
|
||||
CalculatorGraphConfig::Node* result = config->add_node();
|
||||
*result->mutable_calculator() = "SwitchMuxCalculator";
|
||||
*result->mutable_input_stream_handler()->mutable_input_stream_handler() =
|
||||
"ImmediateInputStreamHandler";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,4 +24,7 @@ message SwitchContainerOptions {
|
||||
|
||||
// Activates channel 1 for enable = true, channel 0 otherwise.
|
||||
optional bool enable = 4;
|
||||
|
||||
// Use DefaultInputStreamHandler for muxing & demuxing.
|
||||
optional bool synchronize_io = 5;
|
||||
}
|
||||
|
||||
@@ -66,8 +66,7 @@ REGISTER_CALCULATOR(TripleIntCalculator);
|
||||
// A testing example of a SwitchContainer containing two subnodes.
|
||||
// Note that the input and output tags supplied to the container node,
|
||||
// must match the input and output tags required by the subnodes.
|
||||
CalculatorGraphConfig SubnodeContainerExample(
|
||||
const std::string& input_stream_handler = "") {
|
||||
CalculatorGraphConfig SubnodeContainerExample(const std::string& options = "") {
|
||||
std::string config = R"pb(
|
||||
input_stream: "foo"
|
||||
input_stream: "enable"
|
||||
@@ -80,9 +79,9 @@ CalculatorGraphConfig SubnodeContainerExample(
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {
|
||||
contained_node: { calculator: "TripleIntCalculator" }
|
||||
contained_node: { calculator: "PassThroughCalculator" }
|
||||
contained_node: { calculator: "PassThroughCalculator" } $options
|
||||
}
|
||||
} $input_stream_handler
|
||||
}
|
||||
}
|
||||
node {
|
||||
calculator: "PassThroughCalculator"
|
||||
@@ -94,8 +93,7 @@ CalculatorGraphConfig SubnodeContainerExample(
|
||||
)pb";
|
||||
|
||||
return mediapipe::ParseTextProtoOrDie<CalculatorGraphConfig>(
|
||||
absl::StrReplaceAll(config,
|
||||
{{"$input_stream_handler", input_stream_handler}}));
|
||||
absl::StrReplaceAll(config, {{"$options", options}}));
|
||||
}
|
||||
|
||||
// A testing example of a SwitchContainer containing two subnodes.
|
||||
@@ -248,9 +246,6 @@ TEST(SwitchContainerTest, ApplyToSubnodes) {
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {}
|
||||
}
|
||||
input_stream_handler {
|
||||
input_stream_handler: "ImmediateInputStreamHandler"
|
||||
}
|
||||
}
|
||||
node {
|
||||
name: "switchcontainer__TripleIntCalculator"
|
||||
@@ -274,9 +269,6 @@ TEST(SwitchContainerTest, ApplyToSubnodes) {
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {}
|
||||
}
|
||||
input_stream_handler {
|
||||
input_stream_handler: "ImmediateInputStreamHandler"
|
||||
}
|
||||
}
|
||||
node {
|
||||
calculator: "PassThroughCalculator"
|
||||
@@ -322,9 +314,7 @@ TEST(SwitchContainerTest, ValidateInputStreamHandler) {
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {}
|
||||
}
|
||||
input_stream_handler {
|
||||
input_stream_handler: "ImmediateInputStreamHandler"
|
||||
}
|
||||
input_stream_handler { input_stream_handler: "DefaultInputStreamHandler" }
|
||||
}
|
||||
node {
|
||||
name: "switchcontainer__TripleIntCalculator"
|
||||
@@ -350,9 +340,7 @@ TEST(SwitchContainerTest, ValidateInputStreamHandler) {
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {}
|
||||
}
|
||||
input_stream_handler {
|
||||
input_stream_handler: "ImmediateInputStreamHandler"
|
||||
}
|
||||
input_stream_handler { input_stream_handler: "DefaultInputStreamHandler" }
|
||||
}
|
||||
node {
|
||||
calculator: "PassThroughCalculator"
|
||||
@@ -371,83 +359,12 @@ TEST(SwitchContainerTest, ValidateInputStreamHandler) {
|
||||
EXPECT_THAT(graph.Config(), mediapipe::EqualsProto(expected_graph));
|
||||
}
|
||||
|
||||
// Expands the SwitchContainer with a node-level input_stream_handler.
|
||||
TEST(SwitchContainerTest, OverrideInputStreamHandler) {
|
||||
EXPECT_TRUE(SubgraphRegistry::IsRegistered("SwitchContainer"));
|
||||
CalculatorGraph graph;
|
||||
CalculatorGraphConfig supergraph = SubnodeContainerExample(
|
||||
R"pb(input_stream_handler {
|
||||
input_stream_handler: "DefaultInputStreamHandler"
|
||||
})pb");
|
||||
*supergraph.mutable_node(0)
|
||||
->mutable_input_stream_handler()
|
||||
->mutable_input_stream_handler() = "DefaultInputStreamHandler";
|
||||
MP_ASSERT_OK(graph.Initialize(supergraph, {}));
|
||||
CalculatorGraphConfig expected_graph =
|
||||
mediapipe::ParseTextProtoOrDie<CalculatorGraphConfig>(R"pb(
|
||||
node {
|
||||
name: "switchcontainer__SwitchDemuxCalculator"
|
||||
calculator: "SwitchDemuxCalculator"
|
||||
input_stream: "ENABLE:enable"
|
||||
input_stream: "foo"
|
||||
output_stream: "C0__:switchcontainer__c0__foo"
|
||||
output_stream: "C1__:switchcontainer__c1__foo"
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {}
|
||||
}
|
||||
input_stream_handler {
|
||||
input_stream_handler: "DefaultInputStreamHandler"
|
||||
}
|
||||
}
|
||||
node {
|
||||
name: "switchcontainer__TripleIntCalculator"
|
||||
calculator: "TripleIntCalculator"
|
||||
input_stream: "switchcontainer__c0__foo"
|
||||
output_stream: "switchcontainer__c0__bar"
|
||||
}
|
||||
node {
|
||||
name: "switchcontainer__PassThroughCalculator"
|
||||
calculator: "PassThroughCalculator"
|
||||
input_stream: "switchcontainer__c1__foo"
|
||||
output_stream: "switchcontainer__c1__bar"
|
||||
}
|
||||
node {
|
||||
name: "switchcontainer__SwitchMuxCalculator"
|
||||
calculator: "SwitchMuxCalculator"
|
||||
input_stream: "ENABLE:enable"
|
||||
input_stream: "C0__:switchcontainer__c0__bar"
|
||||
input_stream: "C1__:switchcontainer__c1__bar"
|
||||
output_stream: "bar"
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {}
|
||||
}
|
||||
input_stream_handler {
|
||||
input_stream_handler: "ImmediateInputStreamHandler"
|
||||
}
|
||||
}
|
||||
node {
|
||||
calculator: "PassThroughCalculator"
|
||||
input_stream: "foo"
|
||||
input_stream: "bar"
|
||||
output_stream: "output_foo"
|
||||
output_stream: "output_bar"
|
||||
}
|
||||
input_stream: "foo"
|
||||
input_stream: "enable"
|
||||
executor {}
|
||||
input_side_packet: "timezone"
|
||||
)pb");
|
||||
EXPECT_THAT(graph.Config(), mediapipe::EqualsProto(expected_graph));
|
||||
}
|
||||
|
||||
// Runs the SwitchContainer with a node-level input_stream_handler.
|
||||
TEST(SwitchContainerTest, RunsWithInputStreamHandler) {
|
||||
EXPECT_TRUE(SubgraphRegistry::IsRegistered("SwitchContainer"));
|
||||
CalculatorGraphConfig supergraph = SubnodeContainerExample(
|
||||
R"pb(input_stream_handler {
|
||||
input_stream_handler: "DefaultInputStreamHandler"
|
||||
})pb");
|
||||
CalculatorGraphConfig supergraph =
|
||||
SubnodeContainerExample(R"pb(synchronize_io: true)pb");
|
||||
MP_EXPECT_OK(tool::ExpandSubgraphs(&supergraph));
|
||||
LOG(INFO) << supergraph.DebugString();
|
||||
RunTestContainer(supergraph, true);
|
||||
}
|
||||
|
||||
@@ -470,9 +387,6 @@ TEST(SwitchContainerTest, ApplyToSideSubnodes) {
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {}
|
||||
}
|
||||
input_stream_handler {
|
||||
input_stream_handler: "ImmediateInputStreamHandler"
|
||||
}
|
||||
}
|
||||
node {
|
||||
name: "switchcontainer__TripleIntCalculator"
|
||||
@@ -496,9 +410,6 @@ TEST(SwitchContainerTest, ApplyToSideSubnodes) {
|
||||
options {
|
||||
[mediapipe.SwitchContainerOptions.ext] {}
|
||||
}
|
||||
input_stream_handler {
|
||||
input_stream_handler: "ImmediateInputStreamHandler"
|
||||
}
|
||||
}
|
||||
node {
|
||||
calculator: "PassThroughCalculator"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "mediapipe/framework/port/status.h"
|
||||
#include "mediapipe/framework/port/status_macros.h"
|
||||
#include "mediapipe/framework/tool/container_util.h"
|
||||
#include "mediapipe/framework/tool/switch_container.pb.h"
|
||||
|
||||
namespace mediapipe {
|
||||
|
||||
@@ -113,7 +114,10 @@ absl::Status SwitchDemuxCalculator::GetContract(CalculatorContract* cc) {
|
||||
}
|
||||
}
|
||||
}
|
||||
cc->SetInputStreamHandler("ImmediateInputStreamHandler");
|
||||
auto& options = cc->Options<mediapipe::SwitchContainerOptions>();
|
||||
if (!options.synchronize_io()) {
|
||||
cc->SetInputStreamHandler("ImmediateInputStreamHandler");
|
||||
}
|
||||
cc->SetProcessTimestampBounds(true);
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "mediapipe/framework/port/status.h"
|
||||
#include "mediapipe/framework/port/status_macros.h"
|
||||
#include "mediapipe/framework/tool/container_util.h"
|
||||
#include "mediapipe/framework/tool/switch_container.pb.h"
|
||||
|
||||
namespace mediapipe {
|
||||
|
||||
@@ -68,6 +69,17 @@ class SwitchMuxCalculator : public CalculatorBase {
|
||||
private:
|
||||
int channel_index_;
|
||||
std::set<std::string> channel_tags_;
|
||||
mediapipe::SwitchContainerOptions options_;
|
||||
// This is used to keep around packets that we've received but not
|
||||
// relayed yet (because we may not know which channel we should yet be using
|
||||
// when synchronized_io flag is set).
|
||||
std::map<Timestamp, std::map<CollectionItemId, Packet>> packet_history_;
|
||||
// Historical channel index values for timestamps where we don't have all
|
||||
// packets available yet (when synchronized_io flag is set).
|
||||
std::map<Timestamp, int> channel_history_;
|
||||
// Number of output steams that we already processed for the current output
|
||||
// timestamp.
|
||||
int current_processed_stream_count_ = 0;
|
||||
};
|
||||
REGISTER_CALCULATOR(SwitchMuxCalculator);
|
||||
|
||||
@@ -122,6 +134,7 @@ absl::Status SwitchMuxCalculator::GetContract(CalculatorContract* cc) {
|
||||
}
|
||||
|
||||
absl::Status SwitchMuxCalculator::Open(CalculatorContext* cc) {
|
||||
options_ = cc->Options<mediapipe::SwitchContainerOptions>();
|
||||
channel_index_ = tool::GetChannelIndex(*cc, channel_index_);
|
||||
channel_tags_ = ChannelTags(cc->Inputs().TagMap());
|
||||
|
||||
@@ -141,13 +154,79 @@ absl::Status SwitchMuxCalculator::Process(CalculatorContext* cc) {
|
||||
// Update the input channel index if specified.
|
||||
channel_index_ = tool::GetChannelIndex(*cc, channel_index_);
|
||||
|
||||
// Relay packets and timestamps only from channel_index_.
|
||||
for (const std::string& tag : channel_tags_) {
|
||||
for (int index = 0; index < cc->Outputs().NumEntries(tag); ++index) {
|
||||
auto& output = cc->Outputs().Get(tag, index);
|
||||
std::string input_tag = tool::ChannelTag(tag, channel_index_);
|
||||
auto& input = cc->Inputs().Get(input_tag, index);
|
||||
tool::Relay(input, &output);
|
||||
if (options_.synchronize_io()) {
|
||||
// Start with adding input signals into channel_history_ and packet_history_
|
||||
if (cc->Inputs().HasTag("ENABLE") &&
|
||||
!cc->Inputs().Tag("ENABLE").IsEmpty()) {
|
||||
channel_history_[cc->Inputs().Tag("ENABLE").Value().Timestamp()] =
|
||||
channel_index_;
|
||||
}
|
||||
if (cc->Inputs().HasTag("SELECT") &&
|
||||
!cc->Inputs().Tag("SELECT").IsEmpty()) {
|
||||
channel_history_[cc->Inputs().Tag("SELECT").Value().Timestamp()] =
|
||||
channel_index_;
|
||||
}
|
||||
for (auto input_id = cc->Inputs().BeginId();
|
||||
input_id < cc->Inputs().EndId(); ++input_id) {
|
||||
auto& entry = cc->Inputs().Get(input_id);
|
||||
if (entry.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
packet_history_[entry.Value().Timestamp()][input_id] = entry.Value();
|
||||
}
|
||||
// Now check if we have enough information to produce any outputs.
|
||||
while (!channel_history_.empty()) {
|
||||
// Look at the oldest unprocessed timestamp.
|
||||
auto it = channel_history_.begin();
|
||||
auto& packets = packet_history_[it->first];
|
||||
int total_streams = 0;
|
||||
// Loop over all outputs to see if we have anything new that we can relay.
|
||||
for (const std::string& tag : channel_tags_) {
|
||||
for (int index = 0; index < cc->Outputs().NumEntries(tag); ++index) {
|
||||
++total_streams;
|
||||
auto input_id =
|
||||
cc->Inputs().GetId(tool::ChannelTag(tag, it->second), index);
|
||||
auto packet_it = packets.find(input_id);
|
||||
if (packet_it != packets.end()) {
|
||||
cc->Outputs().Get(tag, index).AddPacket(packet_it->second);
|
||||
++current_processed_stream_count_;
|
||||
} else if (it->first <
|
||||
cc->Inputs().Get(input_id).Value().Timestamp()) {
|
||||
// Getting here means that input stream that corresponds to this
|
||||
// output at the timestamp we're trying to process right now has
|
||||
// already advanced beyond this timestamp. This means that we will
|
||||
// shouldn't expect a packet for this timestamp anymore, and we can
|
||||
// safely advance timestamp on the output.
|
||||
cc->Outputs()
|
||||
.Get(tag, index)
|
||||
.SetNextTimestampBound(it->first.NextAllowedInStream());
|
||||
++current_processed_stream_count_;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current_processed_stream_count_ == total_streams) {
|
||||
// There's nothing else to wait for at the current timestamp, do the
|
||||
// cleanup and move on to the next one.
|
||||
packet_history_.erase(it->first);
|
||||
channel_history_.erase(it);
|
||||
current_processed_stream_count_ = 0;
|
||||
} else {
|
||||
// We're still missing some packets for the current timestamp. Clean up
|
||||
// those that we just relayed and let the rest wait until the next
|
||||
// Process() call.
|
||||
packets.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Relay packets and timestamps only from channel_index_.
|
||||
for (const std::string& tag : channel_tags_) {
|
||||
for (int index = 0; index < cc->Outputs().NumEntries(tag); ++index) {
|
||||
auto& output = cc->Outputs().Get(tag, index);
|
||||
std::string input_tag = tool::ChannelTag(tag, channel_index_);
|
||||
auto& input = cc->Inputs().Get(input_tag, index);
|
||||
tool::Relay(input, &output);
|
||||
}
|
||||
}
|
||||
}
|
||||
return absl::OkStatus();
|
||||
|
||||
@@ -51,8 +51,8 @@ class TagMap {
|
||||
int count;
|
||||
};
|
||||
|
||||
// Create a TagMap from a repeated std::string proto field of
|
||||
// TAG:<index>:name. This is the most common usage:
|
||||
// Create a TagMap from a repeated string proto field of TAG:<index>:name.
|
||||
// This is the most common usage:
|
||||
// ASSIGN_OR_RETURN(std::shared_ptr<TagMap> tag_map,
|
||||
// tool::TagMap::Create(node.input_streams()));
|
||||
static absl::StatusOr<std::shared_ptr<TagMap>> Create(
|
||||
@@ -87,7 +87,7 @@ class TagMap {
|
||||
|
||||
// Returns canonicalized strings describing the TagMap.
|
||||
proto_ns::RepeatedPtrField<ProtoString> CanonicalEntries() const;
|
||||
// Returns a std::string description for debug purposes.
|
||||
// Returns a string description for debug purposes.
|
||||
std::string DebugString() const;
|
||||
// Returns a shorter description for debug purposes (doesn't include
|
||||
// stream/side packet names).
|
||||
|
||||
@@ -318,8 +318,8 @@ TEST(TagMapTest, SameAs) {
|
||||
}
|
||||
}
|
||||
|
||||
// A helper function to test that a TagMap's debug std::string and short
|
||||
// debug std::string each satisfy a matcher.
|
||||
// A helper function to test that a TagMap's debug string and short
|
||||
// debug string each satisfy a matcher.
|
||||
template <typename Matcher>
|
||||
void TestDebugString(
|
||||
const absl::StatusOr<std::shared_ptr<tool::TagMap>>& statusor_tag_map,
|
||||
|
||||
@@ -433,7 +433,7 @@ class TemplateExpanderImpl {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Converts a TemplateArgument to std::string.
|
||||
// Converts a TemplateArgument to string.
|
||||
std::string AsString(const TemplateArgument& value) {
|
||||
std::string result;
|
||||
if (value.has_num()) {
|
||||
|
||||
@@ -260,7 +260,7 @@ class TemplateParser::Parser::ParserImpl {
|
||||
typedef proto_ns::TextFormat::ParseLocation ParseLocation;
|
||||
|
||||
// Determines if repeated values for non-repeated fields and
|
||||
// oneofs are permitted, e.g., the std::string "foo: 1 foo: 2" for a
|
||||
// oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a
|
||||
// required/optional field named "foo", or "baz: 1 qux: 2"
|
||||
// where "baz" and "qux" are members of the same oneof.
|
||||
enum SingularOverwritePolicy {
|
||||
@@ -401,7 +401,7 @@ class TemplateParser::Parser::ParserImpl {
|
||||
}
|
||||
|
||||
#ifndef PROTO2_OPENSOURCE
|
||||
// Consumes a std::string value and parses it as a packed repeated field into
|
||||
// Consumes a string value and parses it as a packed repeated field into
|
||||
// the given field of the given message.
|
||||
bool ConsumePackedFieldAsString(const std::string& field_name,
|
||||
const FieldDescriptor* field,
|
||||
@@ -409,7 +409,7 @@ class TemplateParser::Parser::ParserImpl {
|
||||
std::string packed;
|
||||
DO(ConsumeString(&packed));
|
||||
|
||||
// Prepend field tag and varint-encoded std::string length to turn into
|
||||
// Prepend field tag and varint-encoded string length to turn into
|
||||
// encoded message.
|
||||
std::string tagged;
|
||||
{
|
||||
@@ -428,7 +428,7 @@ class TemplateParser::Parser::ParserImpl {
|
||||
io::CodedInputStream coded_input(&array_input);
|
||||
if (!message->MergePartialFromCodedStream(&coded_input)) {
|
||||
ReportError("Could not parse packed field \"" + field_name +
|
||||
"\" as wire-encoded std::string.");
|
||||
"\" as wire-encoded string.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -607,7 +607,7 @@ class TemplateParser::Parser::ParserImpl {
|
||||
bool consumed_semicolon = TryConsume(":");
|
||||
if (consumed_semicolon && field->options().weak() &&
|
||||
LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||
// we are getting a bytes std::string for a weak field.
|
||||
// we are getting a bytes string for a weak field.
|
||||
std::string tmp;
|
||||
DO(ConsumeString(&tmp));
|
||||
reflection->MutableMessage(message, field)->ParseFromString(tmp);
|
||||
@@ -640,8 +640,8 @@ class TemplateParser::Parser::ParserImpl {
|
||||
#ifndef PROTO2_OPENSOURCE
|
||||
} else if (field->is_packable() &&
|
||||
LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||
// Packable field printed as wire-formatted std::string: "foo: "abc\123"".
|
||||
// Fields of type std::string cannot be packed themselves, so this is
|
||||
// Packable field printed as wire-formatted string: "foo: "abc\123"".
|
||||
// Fields of type string cannot be packed themselves, so this is
|
||||
// unambiguous.
|
||||
DO(ConsumePackedFieldAsString(field_name, field, message));
|
||||
#endif // !PROTO2_OPENSOURCE
|
||||
@@ -908,7 +908,7 @@ class TemplateParser::Parser::ParserImpl {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Possible field values other than std::string:
|
||||
// Possible field values other than string:
|
||||
// 12345 => TYPE_INTEGER
|
||||
// -12345 => TYPE_SYMBOL + TYPE_INTEGER
|
||||
// 1.2345 => TYPE_FLOAT
|
||||
@@ -992,7 +992,7 @@ class TemplateParser::Parser::ParserImpl {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Consume a std::string of form "<id1>.<id2>....<idN>".
|
||||
// Consume a string of form "<id1>.<id2>....<idN>".
|
||||
bool ConsumeFullTypeName(std::string* name) {
|
||||
DO(ConsumeIdentifier(name));
|
||||
while (TryConsume(".")) {
|
||||
@@ -1013,11 +1013,11 @@ class TemplateParser::Parser::ParserImpl {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Consumes a std::string and saves its value in the text parameter.
|
||||
// Consumes a string and saves its value in the text parameter.
|
||||
// Returns false if the token is not of type STRING.
|
||||
bool ConsumeString(std::string* text) {
|
||||
if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||
ReportError("Expected std::string, got: " + tokenizer_.current().text);
|
||||
ReportError("Expected string, got: " + tokenizer_.current().text);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1391,7 +1391,7 @@ void StowFieldValue(Message* message, TemplateExpression* expression) {
|
||||
}
|
||||
}
|
||||
|
||||
// Strips first and last quotes from a std::string.
|
||||
// Strips first and last quotes from a string.
|
||||
static void StripQuotes(std::string* str) {
|
||||
// Strip off the leading and trailing quotation marks from the value, if
|
||||
// there are any.
|
||||
@@ -1585,7 +1585,7 @@ class TemplateParser::Parser::MediaPipeParserImpl
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses a numeric or a std::string literal.
|
||||
// Parses a numeric or a string literal.
|
||||
bool ConsumeLiteral(TemplateExpression* result) {
|
||||
std::string token = tokenizer_.current().text;
|
||||
StripQuotes(&token);
|
||||
|
||||
@@ -215,6 +215,11 @@ std::string GetTestRootDir() {
|
||||
std::string GetTestOutputsDir() {
|
||||
const char* output_dir = getenv("TEST_UNDECLARED_OUTPUTS_DIR");
|
||||
if (!output_dir) {
|
||||
#ifdef __APPLE__
|
||||
char path[PATH_MAX];
|
||||
size_t n = confstr(_CS_DARWIN_USER_TEMP_DIR, path, sizeof(path));
|
||||
if (n > 0 && n < sizeof(path)) return path;
|
||||
#endif // __APPLE__
|
||||
output_dir = "/tmp";
|
||||
}
|
||||
return output_dir;
|
||||
|
||||
@@ -66,7 +66,7 @@ absl::Status SetFromTagAndNameInfo(
|
||||
const TagAndNameInfo& info,
|
||||
proto_ns::RepeatedPtrField<ProtoString>* tags_and_names);
|
||||
|
||||
// The std::string is a valid name for an input stream, output stream,
|
||||
// The string is a valid name for an input stream, output stream,
|
||||
// side packet, and input collection. Names use only lower case letters,
|
||||
// numbers, and underscores.
|
||||
//
|
||||
@@ -77,18 +77,18 @@ absl::Status SetFromTagAndNameInfo(
|
||||
// (3) Because input side packet names end up in model directory names,
|
||||
// where lower case naming is the norm.
|
||||
absl::Status ValidateName(const std::string& name);
|
||||
// The std::string is a valid tag name. Tags use only upper case letters,
|
||||
// The string is a valid tag name. Tags use only upper case letters,
|
||||
// numbers, and underscores.
|
||||
absl::Status ValidateTag(const std::string& tag);
|
||||
|
||||
// Parse a "Tag and Name" std::string into a tag and a name.
|
||||
// Parse a "Tag and Name" string into a tag and a name.
|
||||
// The format is an optional tag and colon, followed by a name.
|
||||
// Example 1: "VIDEO:frames2" -> tag: "VIDEO", name: "frames2"
|
||||
// Example 2: "video_frames_1" -> tag: "", name: "video_frames_1"
|
||||
absl::Status ParseTagAndName(const std::string& tag_and_name, std::string* tag,
|
||||
std::string* name);
|
||||
|
||||
// Parse a generic TAG:index:name std::string. The format is a tag, then an
|
||||
// Parse a generic TAG:index:name string. The format is a tag, then an
|
||||
// index, then a name. The tag and index are optional. If the index
|
||||
// is included, then the tag must be included. If no tag is used then
|
||||
// index is set to -1 (and should be assigned by argument position).
|
||||
@@ -99,7 +99,7 @@ absl::Status ParseTagAndName(const std::string& tag_and_name, std::string* tag,
|
||||
absl::Status ParseTagIndexName(const std::string& tag_and_name,
|
||||
std::string* tag, int* index, std::string* name);
|
||||
|
||||
// Parse a generic TAG:index std::string. The format is a tag, then an index
|
||||
// Parse a generic TAG:index string. The format is a tag, then an index
|
||||
// with both being optional. If the tag is missing it is assumed to be
|
||||
// "" and if the index is missing then it is assumed to be 0. If the
|
||||
// index is provided then a colon (':') must be used.
|
||||
|
||||
Reference in New Issue
Block a user