| 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(
|
|
|