Index: webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc |
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc |
index 823763f091985c3fda5128ef1d8dcd89a45fabdc..8fd62dfbd41bff3c861104b2df455d62b6f82e98 100644 |
--- a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc |
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc |
@@ -47,14 +47,14 @@ constexpr float kEnablingPacketLossAtHighBw = 0.05f; |
struct FecControllerStates { |
std::unique_ptr<FecController> controller; |
- MockSmoothingFilter* packet_loss_smoothed; |
+ MockSmoothingFilter* packet_loss_smoother; |
}; |
FecControllerStates CreateFecController(bool initial_fec_enabled) { |
FecControllerStates states; |
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter( |
new NiceMock<MockSmoothingFilter>()); |
- states.packet_loss_smoothed = mock_smoothing_filter.get(); |
+ states.packet_loss_smoother = mock_smoothing_filter.get(); |
using Threshold = FecController::Config::Threshold; |
states.controller.reset(new FecController( |
FecController::Config( |
@@ -68,32 +68,38 @@ FecControllerStates CreateFecController(bool initial_fec_enabled) { |
return states; |
} |
-// Checks that the FEC decision given by |states->controller->MakeDecision| |
-// matches |expected_enable_fec|. It also checks that |
-// |uplink_packet_loss_fraction| returned by |states->controller->MakeDecision| |
-// matches |uplink_packet_loss|. |
-void CheckDecision(FecControllerStates* states, |
- const rtc::Optional<int>& uplink_bandwidth_bps, |
- const rtc::Optional<float>& uplink_packet_loss, |
- bool expected_enable_fec) { |
- Controller::NetworkMetrics metrics; |
- metrics.uplink_bandwidth_bps = uplink_bandwidth_bps; |
- metrics.uplink_packet_loss_fraction = uplink_packet_loss; |
- |
+void UpdateNetworkMetrics(FecControllerStates* states, |
+ const rtc::Optional<int>& uplink_bandwidth_bps, |
+ const rtc::Optional<float>& uplink_packet_loss) { |
+ // UpdateNetworkMetrics can accept multiple network metric updates at once. |
+ // However, currently, the most used case is to update one metric at a time. |
+ // To reflect this fact, we separate the calls. |
+ if (uplink_bandwidth_bps) { |
+ Controller::NetworkMetrics network_metrics; |
+ network_metrics.uplink_bandwidth_bps = uplink_bandwidth_bps; |
+ states->controller->UpdateNetworkMetrics(network_metrics); |
+ } |
if (uplink_packet_loss) { |
- // Check that smoothing filter is updated. |
- EXPECT_CALL(*states->packet_loss_smoothed, AddSample(*uplink_packet_loss)); |
+ Controller::NetworkMetrics network_metrics; |
+ network_metrics.uplink_packet_loss_fraction = uplink_packet_loss; |
+ EXPECT_CALL(*states->packet_loss_smoother, AddSample(*uplink_packet_loss)); |
+ states->controller->UpdateNetworkMetrics(network_metrics); |
+ // This is called during CheckDecision(). |
+ EXPECT_CALL(*states->packet_loss_smoother, GetAverage()) |
+ .WillOnce(Return(rtc::Optional<float>(*uplink_packet_loss))); |
} |
+} |
- EXPECT_CALL(*states->packet_loss_smoothed, GetAverage()) |
- .WillRepeatedly(Return(uplink_packet_loss)); |
- |
+// Checks that the FEC decision and |uplink_packet_loss_fraction| given by |
+// |states->controller->MakeDecision| matches |expected_enable_fec| and |
+// |expected_uplink_packet_loss_fraction|, respectively. |
+void CheckDecision(FecControllerStates* states, |
+ bool expected_enable_fec, |
+ float expected_uplink_packet_loss_fraction) { |
AudioNetworkAdaptor::EncoderRuntimeConfig config; |
- states->controller->MakeDecision(metrics, &config); |
+ states->controller->MakeDecision(&config); |
EXPECT_EQ(rtc::Optional<bool>(expected_enable_fec), config.enable_fec); |
- |
- // Check that |config.uplink_packet_loss_fraction| is properly filled. |
- EXPECT_EQ(uplink_packet_loss ? uplink_packet_loss : rtc::Optional<float>(0.0), |
+ EXPECT_EQ(rtc::Optional<float>(expected_uplink_packet_loss_fraction), |
config.uplink_packet_loss_fraction); |
} |
@@ -104,9 +110,9 @@ TEST(FecControllerTest, OutputInitValueWhenUplinkBandwidthUnknown) { |
auto states = CreateFecController(kInitialFecEnabled); |
// Let uplink packet loss fraction be so low that would cause FEC to turn off |
// if uplink bandwidth was known. |
- CheckDecision(&states, rtc::Optional<int>(), |
- rtc::Optional<float>(kDisablingPacketLossAtHighBw), |
- kInitialFecEnabled); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(), |
+ rtc::Optional<float>(kDisablingPacketLossAtHighBw)); |
+ CheckDecision(&states, kInitialFecEnabled, kDisablingPacketLossAtHighBw); |
} |
TEST(FecControllerTest, OutputInitValueWhenUplinkPacketLossFractionUnknown) { |
@@ -114,109 +120,143 @@ TEST(FecControllerTest, OutputInitValueWhenUplinkPacketLossFractionUnknown) { |
auto states = CreateFecController(kInitialFecEnabled); |
// Let uplink bandwidth be so low that would cause FEC to turn off if uplink |
// bandwidth packet loss fraction was known. |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1), |
- rtc::Optional<float>(), kInitialFecEnabled); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1), |
+ rtc::Optional<float>()); |
+ CheckDecision(&states, kInitialFecEnabled, 0.0); |
} |
TEST(FecControllerTest, EnableFecForHighBandwidth) { |
auto states = CreateFecController(false); |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthHigh), |
- rtc::Optional<float>(kEnablingPacketLossAtHighBw), true); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthHigh), |
+ rtc::Optional<float>(kEnablingPacketLossAtHighBw)); |
+ CheckDecision(&states, true, kEnablingPacketLossAtHighBw); |
+} |
+ |
+TEST(FecControllerTest, UpdateMultipleNetworkMetricsAtOnce) { |
+ // This test is similar to EnableFecForHighBandwidth. But instead of |
+ // using ::UpdateNetworkMetrics(...), which calls |
+ // FecController::UpdateNetworkMetrics(...) multiple times, we |
+ // we call it only once. This is to verify that |
+ // FecController::UpdateNetworkMetrics(...) can handle multiple |
+ // network updates at once. This is, however, not a common use case in current |
+ // audio_network_adaptor_impl.cc. |
+ auto states = CreateFecController(false); |
+ Controller::NetworkMetrics network_metrics; |
+ network_metrics.uplink_bandwidth_bps = |
+ rtc::Optional<int>(kEnablingBandwidthHigh); |
+ network_metrics.uplink_packet_loss_fraction = |
+ rtc::Optional<float>(kEnablingPacketLossAtHighBw); |
+ EXPECT_CALL(*states.packet_loss_smoother, GetAverage()) |
+ .WillOnce(Return(rtc::Optional<float>(kEnablingPacketLossAtHighBw))); |
+ states.controller->UpdateNetworkMetrics(network_metrics); |
+ CheckDecision(&states, true, kEnablingPacketLossAtHighBw); |
} |
TEST(FecControllerTest, MaintainFecOffForHighBandwidth) { |
auto states = CreateFecController(false); |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthHigh), |
- rtc::Optional<float>(kEnablingPacketLossAtHighBw * 0.99f), |
- false); |
+ constexpr float kPacketLoss = kEnablingPacketLossAtHighBw * 0.99f; |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthHigh), |
+ rtc::Optional<float>(kPacketLoss)); |
+ CheckDecision(&states, false, kPacketLoss); |
} |
TEST(FecControllerTest, EnableFecForMediumBandwidth) { |
auto states = CreateFecController(false); |
- CheckDecision( |
+ constexpr float kPacketLoss = |
+ (kEnablingPacketLossAtLowBw + kEnablingPacketLossAtHighBw) / 2.0; |
+ UpdateNetworkMetrics( |
&states, |
rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2), |
- rtc::Optional<float>( |
- (kEnablingPacketLossAtLowBw + kEnablingPacketLossAtHighBw) / 2.0), |
- true); |
+ rtc::Optional<float>(kPacketLoss)); |
+ CheckDecision(&states, true, kPacketLoss); |
} |
TEST(FecControllerTest, MaintainFecOffForMediumBandwidth) { |
auto states = CreateFecController(false); |
- CheckDecision( |
+ constexpr float kPacketLoss = |
+ kEnablingPacketLossAtLowBw * 0.49f + kEnablingPacketLossAtHighBw * 0.51f; |
+ UpdateNetworkMetrics( |
&states, |
rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2), |
- rtc::Optional<float>(kEnablingPacketLossAtLowBw * 0.49f + |
- kEnablingPacketLossAtHighBw * 0.51f), |
- false); |
+ rtc::Optional<float>(kPacketLoss)); |
+ CheckDecision(&states, false, kPacketLoss); |
} |
TEST(FecControllerTest, EnableFecForLowBandwidth) { |
auto states = CreateFecController(false); |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow), |
- rtc::Optional<float>(kEnablingPacketLossAtLowBw), true); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthLow), |
+ rtc::Optional<float>(kEnablingPacketLossAtLowBw)); |
+ CheckDecision(&states, true, kEnablingPacketLossAtLowBw); |
} |
TEST(FecControllerTest, MaintainFecOffForLowBandwidth) { |
auto states = CreateFecController(false); |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow), |
- rtc::Optional<float>(kEnablingPacketLossAtLowBw * 0.99f), |
- false); |
+ constexpr float kPacketLoss = kEnablingPacketLossAtLowBw * 0.99f; |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthLow), |
+ rtc::Optional<float>(kPacketLoss)); |
+ CheckDecision(&states, false, kPacketLoss); |
} |
TEST(FecControllerTest, MaintainFecOffForVeryLowBandwidth) { |
auto states = CreateFecController(false); |
// Below |kEnablingBandwidthLow|, no packet loss fraction can cause FEC to |
// turn on. |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow - 1), |
- rtc::Optional<float>(1.0), false); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthLow - 1), |
+ rtc::Optional<float>(1.0)); |
+ CheckDecision(&states, false, 1.0); |
} |
TEST(FecControllerTest, DisableFecForHighBandwidth) { |
auto states = CreateFecController(true); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh), |
- rtc::Optional<float>(kDisablingPacketLossAtHighBw), false); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthHigh), |
+ rtc::Optional<float>(kDisablingPacketLossAtHighBw)); |
+ CheckDecision(&states, false, kDisablingPacketLossAtHighBw); |
} |
TEST(FecControllerTest, MaintainFecOnForHighBandwidth) { |
auto states = CreateFecController(true); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh), |
- rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f), |
- true); |
+ constexpr float kPacketLoss = kDisablingPacketLossAtHighBw * 1.01f; |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthHigh), |
+ rtc::Optional<float>(kPacketLoss)); |
+ CheckDecision(&states, true, kPacketLoss); |
} |
TEST(FecControllerTest, DisableFecOnMediumBandwidth) { |
auto states = CreateFecController(true); |
- CheckDecision( |
+ constexpr float kPacketLoss = |
+ (kDisablingPacketLossAtLowBw + kDisablingPacketLossAtHighBw) / 2.0f; |
+ UpdateNetworkMetrics( |
&states, rtc::Optional<int>( |
(kDisablingBandwidthHigh + kDisablingBandwidthLow) / 2), |
- rtc::Optional<float>( |
- (kDisablingPacketLossAtLowBw + kDisablingPacketLossAtHighBw) / 2.0f), |
- false); |
+ rtc::Optional<float>(kPacketLoss)); |
+ CheckDecision(&states, false, kPacketLoss); |
} |
TEST(FecControllerTest, MaintainFecOnForMediumBandwidth) { |
auto states = CreateFecController(true); |
- CheckDecision( |
+ constexpr float kPacketLoss = kDisablingPacketLossAtLowBw * 0.51f + |
+ kDisablingPacketLossAtHighBw * 0.49f; |
+ UpdateNetworkMetrics( |
&states, |
rtc::Optional<int>((kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2), |
- rtc::Optional<float>(kDisablingPacketLossAtLowBw * 0.51f + |
- kDisablingPacketLossAtHighBw * 0.49f), |
- true); |
+ rtc::Optional<float>(kPacketLoss)); |
+ CheckDecision(&states, true, kPacketLoss); |
} |
TEST(FecControllerTest, DisableFecForLowBandwidth) { |
auto states = CreateFecController(true); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow), |
- rtc::Optional<float>(kDisablingPacketLossAtLowBw), false); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow), |
+ rtc::Optional<float>(kDisablingPacketLossAtLowBw)); |
+ CheckDecision(&states, false, kDisablingPacketLossAtLowBw); |
} |
TEST(FecControllerTest, DisableFecForVeryLowBandwidth) { |
auto states = CreateFecController(true); |
// Below |kEnablingBandwidthLow|, any packet loss fraction can cause FEC to |
// turn off. |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1), |
- rtc::Optional<float>(1.0), false); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1), |
+ rtc::Optional<float>(1.0)); |
+ CheckDecision(&states, false, 1.0); |
} |
TEST(FecControllerTest, CheckBehaviorOnChangingNetworkMetrics) { |
@@ -229,18 +269,27 @@ TEST(FecControllerTest, CheckBehaviorOnChangingNetworkMetrics) { |
// |---------5-------> bandwidth |
auto states = CreateFecController(true); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1), |
- rtc::Optional<float>(1.0), false); |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow), |
- rtc::Optional<float>(kEnablingPacketLossAtLowBw * 0.99f), |
- false); |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthHigh), |
- rtc::Optional<float>(kEnablingPacketLossAtHighBw), true); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh), |
- rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f), |
- true); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh + 1), |
- rtc::Optional<float>(0.0), false); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1), |
+ rtc::Optional<float>(1.0)); |
+ CheckDecision(&states, false, 1.0); |
+ |
+ UpdateNetworkMetrics( |
+ &states, rtc::Optional<int>(kEnablingBandwidthLow), |
+ rtc::Optional<float>(kEnablingPacketLossAtLowBw * 0.99f)); |
+ CheckDecision(&states, false, kEnablingPacketLossAtLowBw * 0.99f); |
+ |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthHigh), |
+ rtc::Optional<float>(kEnablingPacketLossAtHighBw)); |
+ CheckDecision(&states, true, kEnablingPacketLossAtHighBw); |
+ |
+ UpdateNetworkMetrics( |
+ &states, rtc::Optional<int>(kDisablingBandwidthHigh), |
+ rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f)); |
+ CheckDecision(&states, true, kDisablingPacketLossAtHighBw * 1.01f); |
+ |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthHigh + 1), |
+ rtc::Optional<float>(0.0)); |
+ CheckDecision(&states, false, 0.0); |
} |
TEST(FecControllerTest, CheckBehaviorOnSpecialCurves) { |
@@ -260,7 +309,7 @@ TEST(FecControllerTest, CheckBehaviorOnSpecialCurves) { |
FecControllerStates states; |
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter( |
new NiceMock<MockSmoothingFilter>()); |
- states.packet_loss_smoothed = mock_smoothing_filter.get(); |
+ states.packet_loss_smoother = mock_smoothing_filter.get(); |
using Threshold = FecController::Config::Threshold; |
states.controller.reset(new FecController( |
FecController::Config( |
@@ -271,18 +320,27 @@ TEST(FecControllerTest, CheckBehaviorOnSpecialCurves) { |
0, nullptr), |
std::move(mock_smoothing_filter))); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1), |
- rtc::Optional<float>(1.0), false); |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow), |
- rtc::Optional<float>(kEnablingPacketLossAtHighBw * 0.99f), |
- false); |
- CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthHigh), |
- rtc::Optional<float>(kEnablingPacketLossAtHighBw), true); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh), |
- rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f), |
- true); |
- CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh + 1), |
- rtc::Optional<float>(0.0), false); |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1), |
+ rtc::Optional<float>(1.0)); |
+ CheckDecision(&states, false, 1.0); |
+ |
+ UpdateNetworkMetrics( |
+ &states, rtc::Optional<int>(kEnablingBandwidthLow), |
+ rtc::Optional<float>(kEnablingPacketLossAtHighBw * 0.99f)); |
+ CheckDecision(&states, false, kEnablingPacketLossAtHighBw * 0.99f); |
+ |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthHigh), |
+ rtc::Optional<float>(kEnablingPacketLossAtHighBw)); |
+ CheckDecision(&states, true, kEnablingPacketLossAtHighBw); |
+ |
+ UpdateNetworkMetrics( |
+ &states, rtc::Optional<int>(kDisablingBandwidthHigh), |
+ rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f)); |
+ CheckDecision(&states, true, kDisablingPacketLossAtHighBw * 1.01f); |
+ |
+ UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthHigh + 1), |
+ rtc::Optional<float>(0.0)); |
+ CheckDecision(&states, false, 0.0); |
} |
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
@@ -290,7 +348,7 @@ TEST(FecControllerDeathTest, InvalidConfig) { |
FecControllerStates states; |
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter( |
new NiceMock<MockSmoothingFilter>()); |
- states.packet_loss_smoothed = mock_smoothing_filter.get(); |
+ states.packet_loss_smoother = mock_smoothing_filter.get(); |
using Threshold = FecController::Config::Threshold; |
EXPECT_DEATH( |
states.controller.reset(new FecController( |