| /* |
| * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include <random> |
| #include <utility> |
| |
| #include "modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.h" |
| #include "test/gtest.h" |
| |
| namespace webrtc { |
| |
| namespace { |
| |
| // The test uses the following settings: |
| // |
| // recoverable ^ |
| // packet-loss | | | |
| // | A| C| FEC |
| // | \ \ ON |
| // | FEC \ D\_______ |
| // | OFF B\_________ |
| // |-----------------> bandwidth |
| // |
| // A : (kDisablingBandwidthLow, kDisablingRecoverablePacketLossAtLowBw) |
| // B : (kDisablingBandwidthHigh, kDisablingRecoverablePacketLossAtHighBw) |
| // C : (kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw) |
| // D : (kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw) |
| |
| constexpr int kDisablingBandwidthLow = 15000; |
| constexpr float kDisablingRecoverablePacketLossAtLowBw = 0.08f; |
| constexpr int kDisablingBandwidthHigh = 64000; |
| constexpr float kDisablingRecoverablePacketLossAtHighBw = 0.01f; |
| constexpr int kEnablingBandwidthLow = 17000; |
| constexpr float kEnablingRecoverablePacketLossAtLowBw = 0.1f; |
| constexpr int kEnablingBandwidthHigh = 64000; |
| constexpr float kEnablingRecoverablePacketLossAtHighBw = 0.05f; |
| |
| constexpr float kEpsilon = 1e-5f; |
| |
| absl::optional<float> GetRandomProbabilityOrUnknown() { |
| std::random_device rd; |
| std::mt19937 generator(rd()); |
| std::uniform_real_distribution<> distribution(0, 1); |
| |
| return (distribution(generator) < 0.2) |
| ? absl::nullopt |
| : absl::optional<float>(distribution(generator)); |
| } |
| |
| std::unique_ptr<FecControllerRplrBased> CreateFecControllerRplrBased( |
| bool initial_fec_enabled) { |
| return std::unique_ptr<FecControllerRplrBased>( |
| new FecControllerRplrBased(FecControllerRplrBased::Config( |
| initial_fec_enabled, |
| ThresholdCurve( |
| kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw, |
| kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw), |
| ThresholdCurve(kDisablingBandwidthLow, |
| kDisablingRecoverablePacketLossAtLowBw, |
| kDisablingBandwidthHigh, |
| kDisablingRecoverablePacketLossAtHighBw)))); |
| } |
| |
| void UpdateNetworkMetrics( |
| FecControllerRplrBased* controller, |
| const absl::optional<int>& uplink_bandwidth_bps, |
| const absl::optional<float>& uplink_packet_loss, |
| const absl::optional<float>& uplink_recoveralbe_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; |
| controller->UpdateNetworkMetrics(network_metrics); |
| } |
| if (uplink_packet_loss) { |
| Controller::NetworkMetrics network_metrics; |
| network_metrics.uplink_packet_loss_fraction = uplink_packet_loss; |
| controller->UpdateNetworkMetrics(network_metrics); |
| } |
| if (uplink_recoveralbe_packet_loss) { |
| Controller::NetworkMetrics network_metrics; |
| network_metrics.uplink_recoverable_packet_loss_fraction = |
| uplink_recoveralbe_packet_loss; |
| controller->UpdateNetworkMetrics(network_metrics); |
| } |
| } |
| |
| void UpdateNetworkMetrics( |
| FecControllerRplrBased* controller, |
| const absl::optional<int>& uplink_bandwidth_bps, |
| const absl::optional<float>& uplink_recoveralbe_packet_loss) { |
| // FecControllerRplrBased doesn't currently use the PLR (general packet-loss |
| // rate) at all. (This might be changed in the future.) The unit-tests will |
| // use a random value (including unknown), to show this does not interfere. |
| UpdateNetworkMetrics(controller, uplink_bandwidth_bps, |
| GetRandomProbabilityOrUnknown(), |
| uplink_recoveralbe_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(FecControllerRplrBased* controller, |
| bool expected_enable_fec, |
| float expected_uplink_packet_loss_fraction) { |
| AudioEncoderRuntimeConfig config; |
| controller->MakeDecision(&config); |
| |
| // Less compact than comparing optionals, but yields more readable errors. |
| EXPECT_TRUE(config.enable_fec); |
| if (config.enable_fec) { |
| EXPECT_EQ(expected_enable_fec, *config.enable_fec); |
| } |
| EXPECT_TRUE(config.uplink_packet_loss_fraction); |
| if (config.uplink_packet_loss_fraction) { |
| EXPECT_EQ(expected_uplink_packet_loss_fraction, |
| *config.uplink_packet_loss_fraction); |
| } |
| } |
| |
| } // namespace |
| |
| TEST(FecControllerRplrBasedTest, OutputInitValueBeforeAnyInputsAreReceived) { |
| for (bool initial_fec_enabled : {false, true}) { |
| auto controller = CreateFecControllerRplrBased(initial_fec_enabled); |
| CheckDecision(controller.get(), initial_fec_enabled, 0); |
| } |
| } |
| |
| TEST(FecControllerRplrBasedTest, OutputInitValueWhenUplinkBandwidthUnknown) { |
| // Regardless of the initial FEC state and the recoverable-packet-loss |
| // rate, the initial FEC state is maintained as long as the BWE is unknown. |
| for (bool initial_fec_enabled : {false, true}) { |
| for (float recoverable_packet_loss : |
| {kDisablingRecoverablePacketLossAtHighBw - kEpsilon, |
| kDisablingRecoverablePacketLossAtHighBw, |
| kDisablingRecoverablePacketLossAtHighBw + kEpsilon, |
| kEnablingRecoverablePacketLossAtHighBw - kEpsilon, |
| kEnablingRecoverablePacketLossAtHighBw, |
| kEnablingRecoverablePacketLossAtHighBw + kEpsilon}) { |
| auto controller = CreateFecControllerRplrBased(initial_fec_enabled); |
| UpdateNetworkMetrics(controller.get(), absl::nullopt, |
| recoverable_packet_loss); |
| CheckDecision(controller.get(), initial_fec_enabled, |
| recoverable_packet_loss); |
| } |
| } |
| } |
| |
| TEST(FecControllerRplrBasedTest, |
| OutputInitValueWhenUplinkRecoverablePacketLossFractionUnknown) { |
| // Regardless of the initial FEC state and the BWE, the initial FEC state |
| // is maintained as long as the recoverable-packet-loss rate is unknown. |
| for (bool initial_fec_enabled : {false, true}) { |
| for (int bandwidth : {kDisablingBandwidthLow - 1, kDisablingBandwidthLow, |
| kDisablingBandwidthLow + 1, kEnablingBandwidthLow - 1, |
| kEnablingBandwidthLow, kEnablingBandwidthLow + 1}) { |
| auto controller = CreateFecControllerRplrBased(initial_fec_enabled); |
| UpdateNetworkMetrics(controller.get(), bandwidth, absl::nullopt); |
| CheckDecision(controller.get(), initial_fec_enabled, 0.0); |
| } |
| } |
| } |
| |
| TEST(FecControllerRplrBasedTest, EnableFecForHighBandwidth) { |
| auto controller = CreateFecControllerRplrBased(false); |
| UpdateNetworkMetrics(controller.get(), kEnablingBandwidthHigh, |
| kEnablingRecoverablePacketLossAtHighBw); |
| CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw); |
| } |
| |
| TEST(FecControllerRplrBasedTest, UpdateMultipleNetworkMetricsAtOnce) { |
| // This test is similar to EnableFecForHighBandwidth. But instead of |
| // using ::UpdateNetworkMetrics(...), which calls |
| // FecControllerRplrBasedTest::UpdateNetworkMetrics(...) multiple times, we |
| // we call it only once. This is to verify that |
| // FecControllerRplrBasedTest::UpdateNetworkMetrics(...) can handle multiple |
| // network updates at once. This is, however, not a common use case in current |
| // audio_network_adaptor_impl.cc. |
| auto controller = CreateFecControllerRplrBased(false); |
| Controller::NetworkMetrics network_metrics; |
| network_metrics.uplink_bandwidth_bps = kEnablingBandwidthHigh; |
| network_metrics.uplink_packet_loss_fraction = GetRandomProbabilityOrUnknown(); |
| network_metrics.uplink_recoverable_packet_loss_fraction = |
| kEnablingRecoverablePacketLossAtHighBw; |
| controller->UpdateNetworkMetrics(network_metrics); |
| CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw); |
| } |
| |
| TEST(FecControllerRplrBasedTest, MaintainFecOffForHighBandwidth) { |
| auto controller = CreateFecControllerRplrBased(false); |
| constexpr float kRecoverablePacketLoss = |
| kEnablingRecoverablePacketLossAtHighBw * 0.99f; |
| UpdateNetworkMetrics(controller.get(), kEnablingBandwidthHigh, |
| kRecoverablePacketLoss); |
| CheckDecision(controller.get(), false, kRecoverablePacketLoss); |
| } |
| |
| TEST(FecControllerRplrBasedTest, EnableFecForMediumBandwidth) { |
| auto controller = CreateFecControllerRplrBased(false); |
| constexpr float kRecoverablePacketLoss = |
| (kEnablingRecoverablePacketLossAtLowBw + |
| kEnablingRecoverablePacketLossAtHighBw) / |
| 2.0; |
| UpdateNetworkMetrics(controller.get(), |
| (kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2, |
| kRecoverablePacketLoss); |
| CheckDecision(controller.get(), true, kRecoverablePacketLoss); |
| } |
| |
| TEST(FecControllerRplrBasedTest, MaintainFecOffForMediumBandwidth) { |
| auto controller = CreateFecControllerRplrBased(false); |
| constexpr float kRecoverablePacketLoss = |
| kEnablingRecoverablePacketLossAtLowBw * 0.49f + |
| kEnablingRecoverablePacketLossAtHighBw * 0.51f; |
| UpdateNetworkMetrics(controller.get(), |
| (kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2, |
| kRecoverablePacketLoss); |
| CheckDecision(controller.get(), false, kRecoverablePacketLoss); |
| } |
| |
| TEST(FecControllerRplrBasedTest, EnableFecForLowBandwidth) { |
| auto controller = CreateFecControllerRplrBased(false); |
| UpdateNetworkMetrics(controller.get(), kEnablingBandwidthLow, |
| kEnablingRecoverablePacketLossAtLowBw); |
| CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtLowBw); |
| } |
| |
| TEST(FecControllerRplrBasedTest, MaintainFecOffForLowBandwidth) { |
| auto controller = CreateFecControllerRplrBased(false); |
| constexpr float kRecoverablePacketLoss = |
| kEnablingRecoverablePacketLossAtLowBw * 0.99f; |
| UpdateNetworkMetrics(controller.get(), kEnablingBandwidthLow, |
| kRecoverablePacketLoss); |
| CheckDecision(controller.get(), false, kRecoverablePacketLoss); |
| } |
| |
| TEST(FecControllerRplrBasedTest, MaintainFecOffForVeryLowBandwidth) { |
| auto controller = CreateFecControllerRplrBased(false); |
| // Below |kEnablingBandwidthLow|, no recoverable packet loss fraction can |
| // cause FEC to turn on. |
| UpdateNetworkMetrics(controller.get(), kEnablingBandwidthLow - 1, 1.0); |
| CheckDecision(controller.get(), false, 1.0); |
| } |
| |
| TEST(FecControllerRplrBasedTest, DisableFecForHighBandwidth) { |
| auto controller = CreateFecControllerRplrBased(true); |
| constexpr float kRecoverablePacketLoss = |
| kDisablingRecoverablePacketLossAtHighBw - kEpsilon; |
| UpdateNetworkMetrics(controller.get(), kDisablingBandwidthHigh, |
| kRecoverablePacketLoss); |
| CheckDecision(controller.get(), false, kRecoverablePacketLoss); |
| } |
| |
| TEST(FecControllerRplrBasedTest, MaintainFecOnForHighBandwidth) { |
| // Note: Disabling happens when the value is strictly below the threshold. |
| auto controller = CreateFecControllerRplrBased(true); |
| UpdateNetworkMetrics(controller.get(), kDisablingBandwidthHigh, |
| kDisablingRecoverablePacketLossAtHighBw); |
| CheckDecision(controller.get(), true, |
| kDisablingRecoverablePacketLossAtHighBw); |
| } |
| |
| TEST(FecControllerRplrBasedTest, DisableFecOnMediumBandwidth) { |
| auto controller = CreateFecControllerRplrBased(true); |
| constexpr float kRecoverablePacketLoss = |
| ((kDisablingRecoverablePacketLossAtLowBw + |
| kDisablingRecoverablePacketLossAtHighBw) / |
| 2.0f) - |
| kEpsilon; |
| UpdateNetworkMetrics(controller.get(), |
| (kDisablingBandwidthHigh + kDisablingBandwidthLow) / 2, |
| kRecoverablePacketLoss); |
| CheckDecision(controller.get(), false, kRecoverablePacketLoss); |
| } |
| |
| TEST(FecControllerRplrBasedTest, MaintainFecOnForMediumBandwidth) { |
| auto controller = CreateFecControllerRplrBased(true); |
| constexpr float kRecoverablePacketLoss = |
| kDisablingRecoverablePacketLossAtLowBw * 0.51f + |
| kDisablingRecoverablePacketLossAtHighBw * 0.49f - kEpsilon; |
| UpdateNetworkMetrics(controller.get(), |
| (kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2, |
| kRecoverablePacketLoss); |
| CheckDecision(controller.get(), true, kRecoverablePacketLoss); |
| } |
| |
| TEST(FecControllerRplrBasedTest, DisableFecForLowBandwidth) { |
| auto controller = CreateFecControllerRplrBased(true); |
| constexpr float kRecoverablePacketLoss = |
| kDisablingRecoverablePacketLossAtLowBw - kEpsilon; |
| UpdateNetworkMetrics(controller.get(), kDisablingBandwidthLow, |
| kRecoverablePacketLoss); |
| CheckDecision(controller.get(), false, kRecoverablePacketLoss); |
| } |
| |
| TEST(FecControllerRplrBasedTest, DisableFecForVeryLowBandwidth) { |
| auto controller = CreateFecControllerRplrBased(true); |
| // Below |kEnablingBandwidthLow|, any recoverable packet loss fraction can |
| // cause FEC to turn off. |
| UpdateNetworkMetrics(controller.get(), kDisablingBandwidthLow - 1, 1.0); |
| CheckDecision(controller.get(), false, 1.0); |
| } |
| |
| TEST(FecControllerRplrBasedTest, CheckBehaviorOnChangingNetworkMetrics) { |
| // In this test, we let the network metrics to traverse from 1 to 5. |
| // |
| // recoverable ^ |
| // packet-loss | 1 | | |
| // | | 2| |
| // | \ \ 3 |
| // | \4 \_______ |
| // | \_________ |
| // |---------5-------> bandwidth |
| |
| auto controller = CreateFecControllerRplrBased(true); |
| UpdateNetworkMetrics(controller.get(), kDisablingBandwidthLow - 1, 1.0); |
| CheckDecision(controller.get(), false, 1.0); |
| |
| UpdateNetworkMetrics(controller.get(), kEnablingBandwidthLow, |
| kEnablingRecoverablePacketLossAtLowBw * 0.99f); |
| CheckDecision(controller.get(), false, |
| kEnablingRecoverablePacketLossAtLowBw * 0.99f); |
| |
| UpdateNetworkMetrics(controller.get(), kEnablingBandwidthHigh, |
| kEnablingRecoverablePacketLossAtHighBw); |
| CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw); |
| |
| UpdateNetworkMetrics(controller.get(), kDisablingBandwidthHigh, |
| kDisablingRecoverablePacketLossAtHighBw); |
| CheckDecision(controller.get(), true, |
| kDisablingRecoverablePacketLossAtHighBw); |
| |
| UpdateNetworkMetrics(controller.get(), kDisablingBandwidthHigh + 1, 0.0); |
| CheckDecision(controller.get(), false, 0.0); |
| } |
| |
| TEST(FecControllerRplrBasedTest, CheckBehaviorOnSpecialCurves) { |
| // We test a special configuration, where the points to define the FEC |
| // enabling/disabling curves are placed like the following, otherwise the test |
| // is the same as CheckBehaviorOnChangingNetworkMetrics. |
| // |
| // recoverable ^ |
| // packet-loss | | | |
| // | | C| |
| // | | | |
| // | | D|_______ |
| // | A|___B______ |
| // |-----------------> bandwidth |
| |
| constexpr int kEnablingBandwidthHigh = kEnablingBandwidthLow; |
| constexpr float kDisablingRecoverablePacketLossAtLowBw = |
| kDisablingRecoverablePacketLossAtHighBw; |
| FecControllerRplrBased controller(FecControllerRplrBased::Config( |
| true, |
| ThresholdCurve( |
| kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw, |
| kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw), |
| ThresholdCurve( |
| kDisablingBandwidthLow, kDisablingRecoverablePacketLossAtLowBw, |
| kDisablingBandwidthHigh, kDisablingRecoverablePacketLossAtHighBw))); |
| |
| UpdateNetworkMetrics(&controller, kDisablingBandwidthLow - 1, 1.0); |
| CheckDecision(&controller, false, 1.0); |
| |
| UpdateNetworkMetrics(&controller, kEnablingBandwidthLow, |
| kEnablingRecoverablePacketLossAtHighBw * 0.99f); |
| CheckDecision(&controller, false, |
| kEnablingRecoverablePacketLossAtHighBw * 0.99f); |
| |
| UpdateNetworkMetrics(&controller, kEnablingBandwidthHigh, |
| kEnablingRecoverablePacketLossAtHighBw); |
| CheckDecision(&controller, true, kEnablingRecoverablePacketLossAtHighBw); |
| |
| UpdateNetworkMetrics(&controller, kDisablingBandwidthHigh, |
| kDisablingRecoverablePacketLossAtHighBw); |
| CheckDecision(&controller, true, kDisablingRecoverablePacketLossAtHighBw); |
| |
| UpdateNetworkMetrics(&controller, kDisablingBandwidthHigh + 1, 0.0); |
| CheckDecision(&controller, false, 0.0); |
| } |
| |
| TEST(FecControllerRplrBasedTest, SingleThresholdCurveForEnablingAndDisabling) { |
| // Note: To avoid numerical errors, keep kRecoverablePacketLossAtLowBw and |
| // kRecoverablePacketLossAthighBw as (negative) integer powers of 2. |
| // This is mostly relevant for the O3 case. |
| constexpr int kBandwidthLow = 10000; |
| constexpr float kRecoverablePacketLossAtLowBw = 0.25f; |
| constexpr int kBandwidthHigh = 20000; |
| constexpr float kRecoverablePacketLossAtHighBw = 0.125f; |
| auto curve = ThresholdCurve(kBandwidthLow, kRecoverablePacketLossAtLowBw, |
| kBandwidthHigh, kRecoverablePacketLossAtHighBw); |
| |
| // B* stands for "below-curve", O* for "on-curve", and A* for "above-curve". |
| // |
| // // |
| // recoverable ^ // |
| // packet-loss | | // |
| // | B1 O1 // |
| // | | // |
| // | O2 // |
| // | \ A1 // |
| // | \ // |
| // | O3 A2 // |
| // | B2 \ // |
| // | \ // |
| // | O4--O5---- // |
| // | // |
| // | B3 // |
| // |-----------------> bandwidth // |
| |
| struct NetworkState { |
| int bandwidth; |
| float recoverable_packet_loss; |
| }; |
| |
| std::vector<NetworkState> below{ |
| {kBandwidthLow - 1, kRecoverablePacketLossAtLowBw + 0.1f}, // B1 |
| {(kBandwidthLow + kBandwidthHigh) / 2, |
| (kRecoverablePacketLossAtLowBw + kRecoverablePacketLossAtHighBw) / 2 - |
| kEpsilon}, // B2 |
| {kBandwidthHigh + 1, kRecoverablePacketLossAtHighBw - kEpsilon} // B3 |
| }; |
| |
| std::vector<NetworkState> on{ |
| {kBandwidthLow, kRecoverablePacketLossAtLowBw + 0.1f}, // O1 |
| {kBandwidthLow, kRecoverablePacketLossAtLowBw}, // O2 |
| {(kBandwidthLow + kBandwidthHigh) / 2, |
| (kRecoverablePacketLossAtLowBw + kRecoverablePacketLossAtHighBw) / |
| 2}, // O3 |
| {kBandwidthHigh, kRecoverablePacketLossAtHighBw}, // O4 |
| {kBandwidthHigh + 1, kRecoverablePacketLossAtHighBw}, // O5 |
| }; |
| |
| std::vector<NetworkState> above{ |
| {(kBandwidthLow + kBandwidthHigh) / 2, |
| (kRecoverablePacketLossAtLowBw + kRecoverablePacketLossAtHighBw) / 2 + |
| kEpsilon}, // A1 |
| {kBandwidthHigh + 1, kRecoverablePacketLossAtHighBw + kEpsilon}, // A2 |
| }; |
| |
| // Test that FEC is turned off whenever we're below the curve, independent |
| // of the starting FEC state. |
| for (NetworkState net_state : below) { |
| for (bool initial_fec_enabled : {false, true}) { |
| FecControllerRplrBased controller( |
| FecControllerRplrBased::Config(initial_fec_enabled, curve, curve)); |
| UpdateNetworkMetrics(&controller, net_state.bandwidth, |
| net_state.recoverable_packet_loss); |
| CheckDecision(&controller, false, net_state.recoverable_packet_loss); |
| } |
| } |
| |
| // Test that FEC is turned on whenever we're on the curve or above it, |
| // independent of the starting FEC state. |
| for (const std::vector<NetworkState>& states_list : {on, above}) { |
| for (NetworkState net_state : states_list) { |
| for (bool initial_fec_enabled : {false, true}) { |
| FecControllerRplrBased controller( |
| FecControllerRplrBased::Config(initial_fec_enabled, curve, curve)); |
| UpdateNetworkMetrics(&controller, net_state.bandwidth, |
| net_state.recoverable_packet_loss); |
| CheckDecision(&controller, true, net_state.recoverable_packet_loss); |
| } |
| } |
| } |
| } |
| |
| TEST(FecControllerRplrBasedTest, FecAlwaysOff) { |
| ThresholdCurve always_off_curve(0, 1.0f + kEpsilon, 0, 1.0f + kEpsilon); |
| for (bool initial_fec_enabled : {false, true}) { |
| for (int bandwidth : {0, 10000}) { |
| for (float recoverable_packet_loss : {0.0f, 0.5f, 1.0f}) { |
| FecControllerRplrBased controller(FecControllerRplrBased::Config( |
| initial_fec_enabled, always_off_curve, always_off_curve)); |
| UpdateNetworkMetrics(&controller, bandwidth, recoverable_packet_loss); |
| CheckDecision(&controller, false, recoverable_packet_loss); |
| } |
| } |
| } |
| } |
| |
| TEST(FecControllerRplrBasedTest, FecAlwaysOn) { |
| ThresholdCurve always_on_curve(0, 0.0f, 0, 0.0f); |
| for (bool initial_fec_enabled : {false, true}) { |
| for (int bandwidth : {0, 10000}) { |
| for (float recoverable_packet_loss : {0.0f, 0.5f, 1.0f}) { |
| FecControllerRplrBased controller(FecControllerRplrBased::Config( |
| initial_fec_enabled, always_on_curve, always_on_curve)); |
| UpdateNetworkMetrics(&controller, bandwidth, recoverable_packet_loss); |
| CheckDecision(&controller, true, recoverable_packet_loss); |
| } |
| } |
| } |
| } |
| |
| #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
| TEST(FecControllerRplrBasedDeathTest, InvalidConfig) { |
| EXPECT_DEATH( |
| FecControllerRplrBased controller(FecControllerRplrBased::Config( |
| true, |
| ThresholdCurve( |
| kDisablingBandwidthLow - 1, kEnablingRecoverablePacketLossAtLowBw, |
| kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw), |
| ThresholdCurve(kDisablingBandwidthLow, |
| kDisablingRecoverablePacketLossAtLowBw, |
| kDisablingBandwidthHigh, |
| kDisablingRecoverablePacketLossAtHighBw))), |
| "Check failed"); |
| } |
| #endif |
| } // namespace webrtc |