Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(742)

Unified Diff: webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc

Issue 2906663002: FecControler disables FEC when *below* threshold (Closed)
Patch Set: . Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc
index 3884df61a0bc3b7b0fd950fbf2dc647ed6392687..f0272d4831bca0bef6ebcdf6ef5c1a3a961ac53e 100644
--- a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc
@@ -42,6 +42,8 @@ constexpr float kEnablingRecoverablePacketLossAtLowBw = 0.1f;
constexpr int kEnablingBandwidthHigh = 64000;
constexpr float kEnablingRecoverablePacketLossAtHighBw = 0.05f;
+constexpr float kEpsilon = 1e-5f;
+
rtc::Optional<float> GetRandomProbabilityOrUnknown() {
std::random_device rd;
std::mt19937 generator(rd());
@@ -98,7 +100,7 @@ void UpdateNetworkMetrics(
FecControllerRplrBased* controller,
const rtc::Optional<int>& uplink_bandwidth_bps,
const rtc::Optional<float>& uplink_recoveralbe_packet_loss) {
- // FecControllerRplrBased doesn't current use the PLR (general 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,
@@ -106,6 +108,15 @@ void UpdateNetworkMetrics(
uplink_recoveralbe_packet_loss);
}
+// TODO(eladalon): In a separate CL (to make reviewers' lives easier), use
+// this where applicable.
+void UpdateNetworkMetrics(FecControllerRplrBased* controller,
+ int uplink_bandwidth_bps,
+ float uplink_recoveralbe_packet_loss) {
+ UpdateNetworkMetrics(controller, rtc::Optional<int>(uplink_bandwidth_bps),
+ rtc::Optional<float>(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.
@@ -129,29 +140,46 @@ void CheckDecision(FecControllerRplrBased* controller,
} // namespace
-TEST(FecControllerRplrBasedTest, OutputInitValueWhenUplinkBandwidthUnknown) {
+TEST(FecControllerRplrBasedTest, OutputInitValueBeforeAnyInputsAreReceived) {
for (bool initial_fec_enabled : {false, true}) {
auto controller = CreateFecControllerRplrBased(initial_fec_enabled);
- // Let uplink recoverable packet loss fraction be so low that it
- // would cause FEC to turn off if uplink bandwidth was known.
- UpdateNetworkMetrics(
- controller.get(), rtc::Optional<int>(),
- rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw));
- CheckDecision(controller.get(), initial_fec_enabled,
- kDisablingRecoverablePacketLossAtHighBw);
+ 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(), rtc::Optional<int>(),
+ rtc::Optional<float>(recoverable_packet_loss));
+ CheckDecision(controller.get(), initial_fec_enabled,
+ recoverable_packet_loss);
+ }
}
}
TEST(FecControllerRplrBasedTest,
- OutputInitValueWhenUplinkPacketLossFractionUnknown) {
+ 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}) {
- auto controller = CreateFecControllerRplrBased(initial_fec_enabled);
- // Let uplink bandwidth be so low that it would cause FEC to turn off
- // if uplink bandwidth packet loss fraction was known.
- UpdateNetworkMetrics(controller.get(),
- rtc::Optional<int>(kDisablingBandwidthLow - 1),
- rtc::Optional<float>());
- CheckDecision(controller.get(), initial_fec_enabled, 0.0);
+ for (int bandwidth : {kDisablingBandwidthLow - 1, kDisablingBandwidthLow,
+ kDisablingBandwidthLow + 1, kEnablingBandwidthLow - 1,
+ kEnablingBandwidthLow, kEnablingBandwidthLow + 1}) {
+ auto controller = CreateFecControllerRplrBased(initial_fec_enabled);
+ UpdateNetworkMetrics(controller.get(), rtc::Optional<int>(bandwidth),
+ rtc::Optional<float>());
+ CheckDecision(controller.get(), initial_fec_enabled, 0.0);
+ }
}
}
@@ -185,34 +213,36 @@ TEST(FecControllerRplrBasedTest, UpdateMultipleNetworkMetricsAtOnce) {
TEST(FecControllerRplrBasedTest, MaintainFecOffForHighBandwidth) {
auto controller = CreateFecControllerRplrBased(false);
- constexpr float kPacketLoss = kEnablingRecoverablePacketLossAtHighBw * 0.99f;
+ constexpr float kRecoverablePacketLoss =
+ kEnablingRecoverablePacketLossAtHighBw * 0.99f;
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kEnablingBandwidthHigh),
- rtc::Optional<float>(kPacketLoss));
- CheckDecision(controller.get(), false, kPacketLoss);
+ rtc::Optional<float>(kRecoverablePacketLoss));
+ CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}
TEST(FecControllerRplrBasedTest, EnableFecForMediumBandwidth) {
auto controller = CreateFecControllerRplrBased(false);
- constexpr float kPacketLoss = (kEnablingRecoverablePacketLossAtLowBw +
- kEnablingRecoverablePacketLossAtHighBw) /
- 2.0;
+ constexpr float kRecoverablePacketLoss =
+ (kEnablingRecoverablePacketLossAtLowBw +
+ kEnablingRecoverablePacketLossAtHighBw) / 2.0;
UpdateNetworkMetrics(
controller.get(),
rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2),
- rtc::Optional<float>(kPacketLoss));
- CheckDecision(controller.get(), true, kPacketLoss);
+ rtc::Optional<float>(kRecoverablePacketLoss));
+ CheckDecision(controller.get(), true, kRecoverablePacketLoss);
}
TEST(FecControllerRplrBasedTest, MaintainFecOffForMediumBandwidth) {
auto controller = CreateFecControllerRplrBased(false);
- constexpr float kPacketLoss = kEnablingRecoverablePacketLossAtLowBw * 0.49f +
- kEnablingRecoverablePacketLossAtHighBw * 0.51f;
+ constexpr float kRecoverablePacketLoss =
+ kEnablingRecoverablePacketLossAtLowBw * 0.49f +
+ kEnablingRecoverablePacketLossAtHighBw * 0.51f;
UpdateNetworkMetrics(
controller.get(),
rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2),
- rtc::Optional<float>(kPacketLoss));
- CheckDecision(controller.get(), false, kPacketLoss);
+ rtc::Optional<float>(kRecoverablePacketLoss));
+ CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}
TEST(FecControllerRplrBasedTest, EnableFecForLowBandwidth) {
@@ -225,11 +255,12 @@ TEST(FecControllerRplrBasedTest, EnableFecForLowBandwidth) {
TEST(FecControllerRplrBasedTest, MaintainFecOffForLowBandwidth) {
auto controller = CreateFecControllerRplrBased(false);
- constexpr float kPacketLoss = kEnablingRecoverablePacketLossAtLowBw * 0.99f;
+ constexpr float kRecoverablePacketLoss =
+ kEnablingRecoverablePacketLossAtLowBw * 0.99f;
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kEnablingBandwidthLow),
- rtc::Optional<float>(kPacketLoss));
- CheckDecision(controller.get(), false, kPacketLoss);
+ rtc::Optional<float>(kRecoverablePacketLoss));
+ CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}
TEST(FecControllerRplrBasedTest, MaintainFecOffForVeryLowBandwidth) {
@@ -244,53 +275,57 @@ TEST(FecControllerRplrBasedTest, MaintainFecOffForVeryLowBandwidth) {
TEST(FecControllerRplrBasedTest, DisableFecForHighBandwidth) {
auto controller = CreateFecControllerRplrBased(true);
- UpdateNetworkMetrics(
- controller.get(), rtc::Optional<int>(kDisablingBandwidthHigh),
- rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw));
- CheckDecision(controller.get(), false,
- kDisablingRecoverablePacketLossAtHighBw);
+ constexpr float kRecoverablePacketLoss =
+ kDisablingRecoverablePacketLossAtHighBw - kEpsilon;
+ UpdateNetworkMetrics(controller.get(),
+ rtc::Optional<int>(kDisablingBandwidthHigh),
+ rtc::Optional<float>(kRecoverablePacketLoss));
+ CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}
TEST(FecControllerRplrBasedTest, MaintainFecOnForHighBandwidth) {
+ // Note: Disabling happens when the value is strictly below the threshold.
auto controller = CreateFecControllerRplrBased(true);
- constexpr float kPacketLoss = kDisablingRecoverablePacketLossAtHighBw * 1.01f;
- UpdateNetworkMetrics(controller.get(),
- rtc::Optional<int>(kDisablingBandwidthHigh),
- rtc::Optional<float>(kPacketLoss));
- CheckDecision(controller.get(), true, kPacketLoss);
+ UpdateNetworkMetrics(
+ controller.get(), rtc::Optional<int>(kDisablingBandwidthHigh),
+ rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw));
+ CheckDecision(controller.get(), true,
+ kDisablingRecoverablePacketLossAtHighBw);
}
TEST(FecControllerRplrBasedTest, DisableFecOnMediumBandwidth) {
auto controller = CreateFecControllerRplrBased(true);
- constexpr float kPacketLoss = (kDisablingRecoverablePacketLossAtLowBw +
- kDisablingRecoverablePacketLossAtHighBw) /
- 2.0f;
+ constexpr float kRecoverablePacketLoss =
+ ((kDisablingRecoverablePacketLossAtLowBw +
+ kDisablingRecoverablePacketLossAtHighBw) / 2.0f) - kEpsilon;
UpdateNetworkMetrics(
controller.get(),
rtc::Optional<int>((kDisablingBandwidthHigh + kDisablingBandwidthLow) /
2),
- rtc::Optional<float>(kPacketLoss));
- CheckDecision(controller.get(), false, kPacketLoss);
+ rtc::Optional<float>(kRecoverablePacketLoss));
+ CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}
TEST(FecControllerRplrBasedTest, MaintainFecOnForMediumBandwidth) {
auto controller = CreateFecControllerRplrBased(true);
- constexpr float kPacketLoss = kDisablingRecoverablePacketLossAtLowBw * 0.51f +
- kDisablingRecoverablePacketLossAtHighBw * 0.49f;
+ constexpr float kRecoverablePacketLoss =
+ kDisablingRecoverablePacketLossAtLowBw * 0.51f +
+ kDisablingRecoverablePacketLossAtHighBw * 0.49f - kEpsilon;
UpdateNetworkMetrics(
controller.get(),
rtc::Optional<int>((kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2),
- rtc::Optional<float>(kPacketLoss));
- CheckDecision(controller.get(), true, kPacketLoss);
+ rtc::Optional<float>(kRecoverablePacketLoss));
+ CheckDecision(controller.get(), true, kRecoverablePacketLoss);
}
TEST(FecControllerRplrBasedTest, DisableFecForLowBandwidth) {
auto controller = CreateFecControllerRplrBased(true);
- UpdateNetworkMetrics(
- controller.get(), rtc::Optional<int>(kDisablingBandwidthLow),
- rtc::Optional<float>(kDisablingRecoverablePacketLossAtLowBw));
- CheckDecision(controller.get(), false,
- kDisablingRecoverablePacketLossAtLowBw);
+ constexpr float kRecoverablePacketLoss =
+ kDisablingRecoverablePacketLossAtLowBw - kEpsilon;
+ UpdateNetworkMetrics(controller.get(),
+ rtc::Optional<int>(kDisablingBandwidthLow),
+ rtc::Optional<float>(kRecoverablePacketLoss));
+ CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}
TEST(FecControllerRplrBasedTest, DisableFecForVeryLowBandwidth) {
@@ -333,9 +368,9 @@ TEST(FecControllerRplrBasedTest, CheckBehaviorOnChangingNetworkMetrics) {
UpdateNetworkMetrics(
controller.get(), rtc::Optional<int>(kDisablingBandwidthHigh),
- rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw * 1.01f));
+ rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw));
CheckDecision(controller.get(), true,
- kDisablingRecoverablePacketLossAtHighBw * 1.01f);
+ kDisablingRecoverablePacketLossAtHighBw);
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kDisablingBandwidthHigh + 1),
@@ -386,9 +421,8 @@ TEST(FecControllerRplrBasedTest, CheckBehaviorOnSpecialCurves) {
UpdateNetworkMetrics(
&controller, rtc::Optional<int>(kDisablingBandwidthHigh),
- rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw * 1.01f));
- CheckDecision(&controller, true,
- kDisablingRecoverablePacketLossAtHighBw * 1.01f);
+ rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw));
+ CheckDecision(&controller, true, kDisablingRecoverablePacketLossAtHighBw);
UpdateNetworkMetrics(&controller,
rtc::Optional<int>(kDisablingBandwidthHigh + 1),
@@ -396,6 +430,120 @@ TEST(FecControllerRplrBasedTest, CheckBehaviorOnSpecialCurves) {
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 (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(
« no previous file with comments | « webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698