Index: webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc |
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..68f3b109b18176a9f52844869f23db9b88e33098 |
--- /dev/null |
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc |
@@ -0,0 +1,301 @@ |
+/* |
+ * Copyright (c) 2016 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 <memory> |
+#include <utility> |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h" |
+ |
+namespace webrtc { |
+ |
+namespace { |
+ |
+constexpr float kFlIncreasingPacketLossFraction = 0.04f; |
+constexpr float kFlDecreasingPacketLossFraction = 0.05f; |
+constexpr int kFl20msTo60msBandwidthBps = 22000; |
+constexpr int kFl60msTo20msBandwidthBps = 88000; |
+constexpr int kMinReceiverFrameLengthMs = 10; |
+constexpr int kMaxReceiverFrameLengthMs = 120; |
+constexpr int kMediumBandwidthBps = |
+ (kFl60msTo20msBandwidthBps + kFl20msTo60msBandwidthBps) / 2; |
+constexpr float kMediumPacketLossFraction = |
+ (kFlDecreasingPacketLossFraction + kFlIncreasingPacketLossFraction) / 2; |
+ |
+void SetReceiverFrameLengthRange(FrameLengthController* controller, |
+ int min_frame_length_ms, |
+ int max_frame_length_ms) { |
+ Controller::Constraints constraints; |
+ using FrameLengthRange = Controller::Constraints::FrameLengthRange; |
+ constraints.receiver_frame_length_range = rtc::Optional<FrameLengthRange>( |
+ FrameLengthRange(min_frame_length_ms, max_frame_length_ms)); |
+ controller->SetConstraints(constraints); |
+} |
+ |
+std::unique_ptr<FrameLengthController> CreateController( |
+ int initial_frame_length_ms) { |
+ std::unique_ptr<FrameLengthController> controller( |
+ new FrameLengthController(FrameLengthController::Config( |
+ {20, 60}, initial_frame_length_ms, kFlIncreasingPacketLossFraction, |
+ kFlDecreasingPacketLossFraction, kFl20msTo60msBandwidthBps, |
+ kFl60msTo20msBandwidthBps))); |
+ SetReceiverFrameLengthRange(controller.get(), kMinReceiverFrameLengthMs, |
+ kMaxReceiverFrameLengthMs); |
+ return controller; |
+} |
+ |
+void CheckDecision(FrameLengthController* controller, |
+ const rtc::Optional<int>& uplink_bandwidth_bps, |
+ const rtc::Optional<float>& uplink_packet_loss_fraction, |
+ const rtc::Optional<bool>& enable_fec, |
+ int expected_frame_length_ms) { |
+ Controller::NetworkMetrics metrics; |
+ metrics.uplink_bandwidth_bps = uplink_bandwidth_bps; |
+ metrics.uplink_packet_loss_fraction = uplink_packet_loss_fraction; |
+ AudioNetworkAdaptor::EncoderRuntimeConfig config; |
+ config.enable_fec = enable_fec; |
+ controller->MakeDecision(metrics, &config); |
+ EXPECT_EQ(rtc::Optional<int>(expected_frame_length_ms), |
+ config.frame_length_ms); |
+} |
+ |
+} // namespace |
+ |
+TEST(FrameLengthControllerTest, |
+ OutputInitValueWhenReceiverFrameLengthRangeUnset) { |
+ constexpr int kInitialFrameLenghtMs = 60; |
+ std::unique_ptr<FrameLengthController> controller( |
+ new FrameLengthController(FrameLengthController::Config( |
+ {20, 60}, kInitialFrameLenghtMs, kFlIncreasingPacketLossFraction, |
+ kFlDecreasingPacketLossFraction, kFl20msTo60msBandwidthBps, |
+ kFl60msTo20msBandwidthBps))); |
+ // Use a high uplink bandwidth that would cause frame length to decrease if |
+ // receiver frame length is set. |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl60msTo20msBandwidthBps), |
+ rtc::Optional<float>(), rtc::Optional<bool>(), |
+ kInitialFrameLenghtMs); |
+} |
+ |
+TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkBandwidth) { |
+ auto controller = CreateController(60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl60msTo20msBandwidthBps), |
+ rtc::Optional<float>(), rtc::Optional<bool>(), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkPacketLossFraction) { |
+ auto controller = CreateController(60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(), |
+ rtc::Optional<float>(kFlDecreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, DecreaseTo20MsWhenFecIsOn) { |
+ auto controller = CreateController(60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(), rtc::Optional<float>(), |
+ rtc::Optional<bool>(true), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, |
+ Maintain60MsIf20MsNotInReceiverFrameLengthRange) { |
+ auto controller = CreateController(60); |
+ SetReceiverFrameLengthRange(controller.get(), 21, 60); |
+ // Set FEC on that would cause frame length to decrease if receiver frame |
+ // length range included 20ms. |
+ CheckDecision(controller.get(), rtc::Optional<int>(), rtc::Optional<float>(), |
+ rtc::Optional<bool>(true), 60); |
+} |
+ |
+TEST(FrameLengthControllerTest, Maintain60MsOnMultipleConditions) { |
+ // Maintain 60ms frame length if |
+ // 1. |uplink_bandwidth_bps| is at medium level, |
+ // 2. |uplink_packet_loss_fraction| is at medium, |
+ // 3. FEC is not decided ON. |
+ auto controller = CreateController(60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(kMediumBandwidthBps), |
+ rtc::Optional<float>(kMediumPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+} |
+ |
+TEST(FrameLengthControllerTest, IncreaseTo60MsOnMultipleConditions) { |
+ // Increase to 60ms frame length if |
+ // 1. |uplink_bandwidth_bps| is known to be smaller than a threshold AND |
+ // 2. |uplink_packet_loss_fraction| is known to be smaller than a threshold |
+ // AND |
+ // 3. FEC is not decided or OFF. |
+ auto controller = CreateController(20); |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl20msTo60msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+} |
+ |
+TEST(FrameLengthControllerTest, |
+ Maintain20MsIf60MsNotInReceiverFrameLengthRange) { |
+ auto controller = CreateController(20); |
+ SetReceiverFrameLengthRange(controller.get(), 10, 59); |
+ // Use a low uplink bandwidth and a low uplink packet loss fraction that would |
+ // cause frame length to increase if receiver frame length included 60ms. |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl20msTo60msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkBandwidth) { |
+ auto controller = CreateController(20); |
+ CheckDecision(controller.get(), rtc::Optional<int>(kMediumBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkPacketLossFraction) { |
+ auto controller = CreateController(20); |
+ // Use a low uplink bandwidth that would cause frame length to increase if |
+ // uplink packet loss fraction was low. |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl20msTo60msBandwidthBps), |
+ rtc::Optional<float>(kMediumPacketLossFraction), |
+ rtc::Optional<bool>(), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, Maintain20MsWhenFecIsOn) { |
+ auto controller = CreateController(20); |
+ // Use a low uplink bandwidth and a low uplink packet loss fraction that would |
+ // cause frame length to increase if FEC was not ON. |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl20msTo60msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(true), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, |
+ MaintainFrameLengthOnSetReceiverFrameLengthRange) { |
+ auto controller = CreateController(60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(), rtc::Optional<float>(), |
+ rtc::Optional<bool>(true), 20); |
+ SetReceiverFrameLengthRange(controller.get(), 10, 60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(), rtc::Optional<float>(), |
+ rtc::Optional<bool>(), 20); |
+} |
+ |
+namespace { |
+constexpr int kFl60msTo120msBandwidthBps = 18000; |
+constexpr int kFl120msTo60msBandwidthBps = 72000; |
+} |
+ |
+class FrameLengthControllerForTest { |
+ public: |
+ // This class is to test multiple frame lengths. FrameLengthController is |
+ // implemented to support this, but is not enabled for the default constructor |
+ // for the time being. We use this class to test it. |
+ explicit FrameLengthControllerForTest(int initial_frame_length_ms) |
+ : frame_length_controller_( |
+ FrameLengthController::Config({20, 60, 120}, |
+ initial_frame_length_ms, |
+ kFlIncreasingPacketLossFraction, |
+ kFlDecreasingPacketLossFraction, |
+ kFl20msTo60msBandwidthBps, |
+ kFl60msTo20msBandwidthBps)) { |
+ frame_length_controller_.frame_length_change_criteria_.insert( |
+ std::make_pair(FrameLengthController::FrameLengthChange(60, 120), |
+ kFl60msTo120msBandwidthBps)); |
+ frame_length_controller_.frame_length_change_criteria_.insert( |
+ std::make_pair(FrameLengthController::FrameLengthChange(120, 60), |
+ kFl120msTo60msBandwidthBps)); |
+ frame_length_controller_.SetReceiverFrameLengthRange(20, 120); |
+ } |
+ FrameLengthController* get() { return &frame_length_controller_; } |
+ |
+ private: |
+ FrameLengthController frame_length_controller_; |
+}; |
+ |
+TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkBandwidth) { |
+ FrameLengthControllerForTest controller(120); |
+ // It takes two steps for frame length to go from 120ms to 20ms. |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl60msTo20msBandwidthBps), |
+ rtc::Optional<float>(), rtc::Optional<bool>(), 60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl60msTo20msBandwidthBps), |
+ rtc::Optional<float>(), rtc::Optional<bool>(), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkPacketLossFraction) { |
+ FrameLengthControllerForTest controller(120); |
+ // It takes two steps for frame length to go from 120ms to 20ms. |
+ CheckDecision(controller.get(), rtc::Optional<int>(), |
+ rtc::Optional<float>(kFlDecreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(), |
+ rtc::Optional<float>(kFlDecreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, From120MsTo20MsWhenFecIsOn) { |
+ FrameLengthControllerForTest controller(120); |
+ // It takes two steps for frame length to go from 120ms to 20ms. |
+ CheckDecision(controller.get(), rtc::Optional<int>(), rtc::Optional<float>(), |
+ rtc::Optional<bool>(true), 60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(), rtc::Optional<float>(), |
+ rtc::Optional<bool>(true), 20); |
+} |
+ |
+TEST(FrameLengthControllerTest, From20MsTo120MsOnMultipleConditions) { |
+ // Increase to 120ms frame length if |
+ // 1. |uplink_bandwidth_bps| is known to be smaller than a threshold AND |
+ // 2. |uplink_packet_loss_fraction| is known to be smaller than a threshold |
+ // AND |
+ // 3. FEC is not decided or OFF. |
+ FrameLengthControllerForTest controller(20); |
+ // It takes two steps for frame length to go from 20ms to 120ms. |
+ CheckDecision(controller.get(), |
+ rtc::Optional<int>(kFl60msTo120msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+ CheckDecision(controller.get(), |
+ rtc::Optional<int>(kFl60msTo120msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 120); |
+} |
+ |
+TEST(FrameLengthControllerTest, Stall60MsIf120MsNotInReceiverFrameLengthRange) { |
+ FrameLengthControllerForTest controller(20); |
+ SetReceiverFrameLengthRange(controller.get(), 20, 119); |
+ CheckDecision(controller.get(), |
+ rtc::Optional<int>(kFl60msTo120msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+ CheckDecision(controller.get(), |
+ rtc::Optional<int>(kFl60msTo120msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+} |
+ |
+TEST(FrameLengthControllerTest, CheckBehaviorOnChangingNetworkMetrics) { |
+ FrameLengthControllerForTest controller(20); |
+ CheckDecision(controller.get(), rtc::Optional<int>(kMediumBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 20); |
+ CheckDecision(controller.get(), rtc::Optional<int>(kFl20msTo60msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+ CheckDecision(controller.get(), |
+ rtc::Optional<int>(kFl60msTo120msBandwidthBps), |
+ rtc::Optional<float>(kMediumPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+ CheckDecision(controller.get(), |
+ rtc::Optional<int>(kFl60msTo120msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 120); |
+ CheckDecision(controller.get(), |
+ rtc::Optional<int>(kFl120msTo60msBandwidthBps), |
+ rtc::Optional<float>(kFlIncreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 60); |
+ CheckDecision(controller.get(), rtc::Optional<int>(kMediumPacketLossFraction), |
+ rtc::Optional<float>(kFlDecreasingPacketLossFraction), |
+ rtc::Optional<bool>(), 20); |
+} |
+ |
+} // namespace webrtc |