diff --git a/mediapipe/calculators/core/gate_calculator.cc b/mediapipe/calculators/core/gate_calculator.cc index 8fdb9e0a3..448329b88 100644 --- a/mediapipe/calculators/core/gate_calculator.cc +++ b/mediapipe/calculators/core/gate_calculator.cc @@ -125,7 +125,6 @@ class GateCalculator : public CalculatorBase { RET_CHECK_OK(CheckAndInitAllowDisallowInputs(cc)); const int num_data_streams = cc->Inputs().NumEntries(""); - RET_CHECK_GE(num_data_streams, 1); RET_CHECK_EQ(cc->Outputs().NumEntries(""), num_data_streams) << "Number of data output streams must match with data input streams."; diff --git a/mediapipe/calculators/core/gate_calculator_test.cc b/mediapipe/calculators/core/gate_calculator_test.cc index c523bce28..c734ddb5f 100644 --- a/mediapipe/calculators/core/gate_calculator_test.cc +++ b/mediapipe/calculators/core/gate_calculator_test.cc @@ -52,6 +52,15 @@ class GateCalculatorTest : public ::testing::Test { MP_ASSERT_OK(runner_->Run()) << "Calculator execution failed."; } + void RunTimeStepWithoutDataStream(int64_t timestamp, + const std::string& control_tag, + bool control) { + runner_->MutableInputs() + ->Tag(control_tag) + .packets.push_back(MakePacket(control).At(Timestamp(timestamp))); + MP_ASSERT_OK(runner_->Run()) << "Calculator execution failed."; + } + void SetRunner(const std::string& proto) { runner_ = absl::make_unique( ParseTextProtoOrDie(proto)); @@ -332,6 +341,35 @@ TEST_F(GateCalculatorTest, AllowWithStateChange) { EXPECT_EQ(false, output[1].Get()); // Disallow. } +TEST_F(GateCalculatorTest, AllowWithStateChangeNoDataStreams) { + SetRunner(R"( + calculator: "GateCalculator" + input_stream: "ALLOW:gating_stream" + output_stream: "STATE_CHANGE:state_changed" + )"); + + constexpr int64_t kTimestampValue0 = 42; + RunTimeStepWithoutDataStream(kTimestampValue0, "ALLOW", false); + constexpr int64_t kTimestampValue1 = 43; + RunTimeStepWithoutDataStream(kTimestampValue1, "ALLOW", true); + constexpr int64_t kTimestampValue2 = 44; + RunTimeStepWithoutDataStream(kTimestampValue2, "ALLOW", true); + constexpr int64_t kTimestampValue3 = 45; + RunTimeStepWithoutDataStream(kTimestampValue3, "ALLOW", false); + LOG(INFO) << "a"; + const std::vector& output = + runner()->Outputs().Get("STATE_CHANGE", 0).packets; + LOG(INFO) << "s"; + ASSERT_EQ(2, output.size()); + LOG(INFO) << "d"; + EXPECT_EQ(kTimestampValue1, output[0].Timestamp().Value()); + EXPECT_EQ(kTimestampValue3, output[1].Timestamp().Value()); + LOG(INFO) << "f"; + EXPECT_EQ(true, output[0].Get()); // Allow. + EXPECT_EQ(false, output[1].Get()); // Disallow. + LOG(INFO) << "g"; +} + TEST_F(GateCalculatorTest, DisallowWithStateChange) { SetRunner(R"( calculator: "GateCalculator" @@ -359,6 +397,31 @@ TEST_F(GateCalculatorTest, DisallowWithStateChange) { EXPECT_EQ(false, output[1].Get()); // Disallow. } +TEST_F(GateCalculatorTest, DisallowWithStateChangeNoDataStreams) { + SetRunner(R"( + calculator: "GateCalculator" + input_stream: "DISALLOW:gating_stream" + output_stream: "STATE_CHANGE:state_changed" + )"); + + constexpr int64_t kTimestampValue0 = 42; + RunTimeStepWithoutDataStream(kTimestampValue0, "DISALLOW", true); + constexpr int64_t kTimestampValue1 = 43; + RunTimeStepWithoutDataStream(kTimestampValue1, "DISALLOW", false); + constexpr int64_t kTimestampValue2 = 44; + RunTimeStepWithoutDataStream(kTimestampValue2, "DISALLOW", false); + constexpr int64_t kTimestampValue3 = 45; + RunTimeStepWithoutDataStream(kTimestampValue3, "DISALLOW", true); + + const std::vector& output = + runner()->Outputs().Get("STATE_CHANGE", 0).packets; + ASSERT_EQ(2, output.size()); + EXPECT_EQ(kTimestampValue1, output[0].Timestamp().Value()); + EXPECT_EQ(kTimestampValue3, output[1].Timestamp().Value()); + EXPECT_EQ(true, output[0].Get()); // Allow. + EXPECT_EQ(false, output[1].Get()); // Disallow. +} + // Must not detect disallow value for first timestamp as a state change. TEST_F(GateCalculatorTest, DisallowInitialNoStateTransition) { SetRunner(R"(