From 6f08d7d68d3ba41d65b61728266ad70391f009fc Mon Sep 17 00:00:00 2001 From: michaelt Date: Wed, 22 Feb 2017 07:35:05 -0800 Subject: [PATCH] Change frame length on very low bandwidth. BUG=webrtc:7199 Review-Url: https://codereview.webrtc.org/2703353002 Cr-Commit-Position: refs/heads/master@{#16777} --- .../audio_network_adaptor/config.proto | 2 +- .../controller_manager.cc | 9 +- .../controller_manager.h | 1 + .../controller_manager_unittest.cc | 6 +- .../frame_length_controller.cc | 52 ++++++- .../frame_length_controller.h | 4 + .../frame_length_controller_unittest.cc | 146 ++++++++++++++---- .../codecs/opus/audio_encoder_opus.cc | 9 +- 8 files changed, 179 insertions(+), 50 deletions(-) diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/config.proto b/webrtc/modules/audio_coding/audio_network_adaptor/config.proto index 53a4de0217..6162a155ca 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/config.proto +++ b/webrtc/modules/audio_coding/audio_network_adaptor/config.proto @@ -43,7 +43,7 @@ message FrameLengthController { // Uplink packet loss fraction below which frame length can increase. optional float fl_increasing_packet_loss_fraction = 1; - // Uplink packet loss fraction below which frame length should decrease. + // Uplink packet loss fraction above which frame length should decrease. optional float fl_decreasing_packet_loss_fraction = 2; // Uplink bandwidth below which frame length can switch from 20ms to 60ms. diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc index 95ed4d61c3..1eb0857cd0 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc @@ -75,7 +75,8 @@ std::unique_ptr CreateFecController( std::unique_ptr CreateFrameLengthController( const audio_network_adaptor::config::FrameLengthController& config, rtc::ArrayView encoder_frame_lengths_ms, - int initial_frame_length_ms) { + int initial_frame_length_ms, + int min_encoder_bitrate_bps) { RTC_CHECK(config.has_fl_increasing_packet_loss_fraction()); RTC_CHECK(config.has_fl_decreasing_packet_loss_fraction()); RTC_CHECK(config.has_fl_20ms_to_60ms_bandwidth_bps()); @@ -99,7 +100,7 @@ std::unique_ptr CreateFrameLengthController( } FrameLengthController::Config ctor_config( - std::vector(), initial_frame_length_ms, + std::vector(), initial_frame_length_ms, min_encoder_bitrate_bps, config.fl_increasing_packet_loss_fraction(), config.fl_decreasing_packet_loss_fraction(), std::move(fl_changing_bandwidths_bps)); @@ -159,6 +160,7 @@ std::unique_ptr ControllerManagerImpl::Create( const std::string& config_string, size_t num_encoder_channels, rtc::ArrayView encoder_frame_lengths_ms, + int min_encoder_bitrate_bps, size_t intial_channels_to_encode, int initial_frame_length_ms, int initial_bitrate_bps, @@ -183,7 +185,8 @@ std::unique_ptr ControllerManagerImpl::Create( case audio_network_adaptor::config::Controller::kFrameLengthController: controller = CreateFrameLengthController( controller_config.frame_length_controller(), - encoder_frame_lengths_ms, initial_frame_length_ms); + encoder_frame_lengths_ms, initial_frame_length_ms, + min_encoder_bitrate_bps); break; case audio_network_adaptor::config::Controller::kChannelController: controller = CreateChannelController( diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h index 806042e501..338a3657e2 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h @@ -52,6 +52,7 @@ class ControllerManagerImpl final : public ControllerManager { const std::string& config_string, size_t num_encoder_channels, rtc::ArrayView encoder_frame_lengths_ms, + int min_encoder_bitrate_bps, size_t intial_channels_to_encode, int initial_frame_length_ms, int initial_bitrate_bps, diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc index 1336166107..ed96e1b9c6 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc @@ -270,6 +270,7 @@ constexpr size_t kIntialChannelsToEncode = 1; constexpr bool kInitialDtxEnabled = true; constexpr bool kInitialFecEnabled = true; constexpr int kInitialFrameLengthMs = 60; +constexpr int kMinBitrateBps = 6000; ControllerManagerStates CreateControllerManager( const std::string& config_string) { @@ -279,8 +280,9 @@ ControllerManagerStates CreateControllerManager( const std::vector encoder_frame_lengths_ms = {20, 60}; states.controller_manager = ControllerManagerImpl::Create( config_string, kNumEncoderChannels, encoder_frame_lengths_ms, - kIntialChannelsToEncode, kInitialFrameLengthMs, kInitialBitrateBps, - kInitialFecEnabled, kInitialDtxEnabled, states.simulated_clock.get()); + kMinBitrateBps, kIntialChannelsToEncode, kInitialFrameLengthMs, + kInitialBitrateBps, kInitialFecEnabled, kInitialDtxEnabled, + states.simulated_clock.get()); return states; } diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc index d684e956a8..580d08087b 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc @@ -17,14 +17,25 @@ namespace webrtc { +namespace { +constexpr int kPreventOveruseMarginBps = 5000; + +int OverheadRateBps(size_t overhead_bytes_per_packet, int frame_length_ms) { + return static_cast(overhead_bytes_per_packet * 8 * 1000 / + frame_length_ms); +} +} + FrameLengthController::Config::Config( const std::vector& encoder_frame_lengths_ms, int initial_frame_length_ms, + int min_encoder_bitrate_bps, float fl_increasing_packet_loss_fraction, float fl_decreasing_packet_loss_fraction, std::map fl_changing_bandwidths_bps) : encoder_frame_lengths_ms(encoder_frame_lengths_ms), initial_frame_length_ms(initial_frame_length_ms), + min_encoder_bitrate_bps(min_encoder_bitrate_bps), fl_increasing_packet_loss_fraction(fl_increasing_packet_loss_fraction), fl_decreasing_packet_loss_fraction(fl_decreasing_packet_loss_fraction), fl_changing_bandwidths_bps(std::move(fl_changing_bandwidths_bps)) {} @@ -50,6 +61,8 @@ void FrameLengthController::UpdateNetworkMetrics( uplink_bandwidth_bps_ = network_metrics.uplink_bandwidth_bps; if (network_metrics.uplink_packet_loss_fraction) uplink_packet_loss_fraction_ = network_metrics.uplink_packet_loss_fraction; + if (network_metrics.overhead_bytes_per_packet) + overhead_bytes_per_packet_ = network_metrics.overhead_bytes_per_packet; } void FrameLengthController::MakeDecision( @@ -81,11 +94,15 @@ bool FrameLengthController::Config::FrameLengthChange::operator<( bool FrameLengthController::FrameLengthIncreasingDecision( const AudioNetworkAdaptor::EncoderRuntimeConfig& config) const { // Increase frame length if - // 1. longer frame length is available AND - // 2. |uplink_bandwidth_bps| is known to be smaller than a threshold AND - // 3. |uplink_packet_loss_fraction| is known to be smaller than a threshold + // 1. |uplink_bandwidth_bps| is known to be smaller or equal than + // |min_encoder_bitrate_bps| plus |prevent_overuse_margin_bps| plus the + // current overhead rate OR all the following: + // 2. longer frame length is available AND + // 3. |uplink_bandwidth_bps| is known to be smaller than a threshold AND + // 4. |uplink_packet_loss_fraction| is known to be smaller than a threshold // AND - // 4. FEC is not decided or is OFF. + // 5. FEC is not decided or is OFF. + auto longer_frame_length_ms = std::next(frame_length_ms_); if (longer_frame_length_ms == config_.encoder_frame_lengths_ms.end()) return false; @@ -96,6 +113,13 @@ bool FrameLengthController::FrameLengthIncreasingDecision( if (increase_threshold == config_.fl_changing_bandwidths_bps.end()) return false; + if (uplink_bandwidth_bps_ && overhead_bytes_per_packet_ && + *uplink_bandwidth_bps_ <= + config_.min_encoder_bitrate_bps + kPreventOveruseMarginBps + + OverheadRateBps(*overhead_bytes_per_packet_, *frame_length_ms_)) { + return true; + } + return (uplink_bandwidth_bps_ && *uplink_bandwidth_bps_ <= increase_threshold->second) && (uplink_packet_loss_fraction_ && @@ -107,10 +131,14 @@ bool FrameLengthController::FrameLengthIncreasingDecision( bool FrameLengthController::FrameLengthDecreasingDecision( const AudioNetworkAdaptor::EncoderRuntimeConfig& config) const { // Decrease frame length if - // 1. shorter frame length is available AND one or more of the followings: - // 2. |uplink_bandwidth_bps| is known to be larger than a threshold, - // 3. |uplink_packet_loss_fraction| is known to be larger than a threshold, - // 4. FEC is decided ON. + // 1. shorter frame length is available AND + // 2. |uplink_bandwidth_bps| is known to be bigger than + // |min_encoder_bitrate_bps| plus |prevent_overuse_margin_bps| plus the + // overhead which would be produced with the shorter frame length AND + // one or more of the followings: + // 3. |uplink_bandwidth_bps| is known to be larger than a threshold, + // 4. |uplink_packet_loss_fraction| is known to be larger than a threshold, + // 5. FEC is decided ON. if (frame_length_ms_ == config_.encoder_frame_lengths_ms.begin()) return false; @@ -121,6 +149,14 @@ bool FrameLengthController::FrameLengthDecreasingDecision( if (decrease_threshold == config_.fl_changing_bandwidths_bps.end()) return false; + if (uplink_bandwidth_bps_ && overhead_bytes_per_packet_ && + *uplink_bandwidth_bps_ <= config_.min_encoder_bitrate_bps + + kPreventOveruseMarginBps + + OverheadRateBps(*overhead_bytes_per_packet_, + *shorter_frame_length_ms)) { + return false; + } + return (uplink_bandwidth_bps_ && *uplink_bandwidth_bps_ >= decrease_threshold->second) || (uplink_packet_loss_fraction_ && diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h index fa6e753b34..74cbb5638d 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h @@ -32,6 +32,7 @@ class FrameLengthController final : public Controller { }; Config(const std::vector& encoder_frame_lengths_ms, int initial_frame_length_ms, + int min_encoder_bitrate_bps, float fl_increasing_packet_loss_fraction, float fl_decreasing_packet_loss_fraction, std::map fl_changing_bandwidths_bps); @@ -39,6 +40,7 @@ class FrameLengthController final : public Controller { ~Config(); std::vector encoder_frame_lengths_ms; int initial_frame_length_ms; + int min_encoder_bitrate_bps; // Uplink packet loss fraction below which frame length can increase. float fl_increasing_packet_loss_fraction; // Uplink packet loss fraction below which frame length should decrease. @@ -69,6 +71,8 @@ class FrameLengthController final : public Controller { rtc::Optional uplink_packet_loss_fraction_; + rtc::Optional overhead_bytes_per_packet_; + RTC_DISALLOW_COPY_AND_ASSIGN(FrameLengthController); }; 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 index 97ff4b4ac2..ac888b6c6e 100644 --- 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 @@ -20,6 +20,9 @@ namespace { constexpr float kFlIncreasingPacketLossFraction = 0.04f; constexpr float kFlDecreasingPacketLossFraction = 0.05f; +constexpr int kMinEncoderBitrateBps = 6000; +constexpr int kPreventOveruseMarginBps = 5000; +constexpr size_t kOverheadBytesPerPacket = 20; constexpr int kFl20msTo60msBandwidthBps = 40000; constexpr int kFl60msTo20msBandwidthBps = 50000; constexpr int kFl60msTo120msBandwidthBps = 30000; @@ -29,6 +32,11 @@ constexpr int kMediumBandwidthBps = constexpr float kMediumPacketLossFraction = (kFlDecreasingPacketLossFraction + kFlIncreasingPacketLossFraction) / 2; +int VeryLowBitrate(int frame_length_ms) { + return kMinEncoderBitrateBps + kPreventOveruseMarginBps + + (kOverheadBytesPerPacket * 8 * 1000 / frame_length_ms); +} + std::unique_ptr CreateController( const std::map& frame_length_change_criteria, @@ -37,8 +45,8 @@ std::unique_ptr CreateController( std::unique_ptr controller( new FrameLengthController(FrameLengthController::Config( encoder_frame_lengths_ms, initial_frame_length_ms, - kFlIncreasingPacketLossFraction, kFlDecreasingPacketLossFraction, - frame_length_change_criteria))); + kMinEncoderBitrateBps, kFlIncreasingPacketLossFraction, + kFlDecreasingPacketLossFraction, frame_length_change_criteria))); return controller; } @@ -68,7 +76,8 @@ CreateChangeCriteriaFor20ms60msAnd120ms() { void UpdateNetworkMetrics( FrameLengthController* controller, const rtc::Optional& uplink_bandwidth_bps, - const rtc::Optional& uplink_packet_loss_fraction) { + const rtc::Optional& uplink_packet_loss_fraction, + const rtc::Optional& overhead_bytes_per_packet) { // 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. @@ -82,6 +91,11 @@ void UpdateNetworkMetrics( network_metrics.uplink_packet_loss_fraction = uplink_packet_loss_fraction; controller->UpdateNetworkMetrics(network_metrics); } + if (overhead_bytes_per_packet) { + Controller::NetworkMetrics network_metrics; + network_metrics.overhead_bytes_per_packet = overhead_bytes_per_packet; + controller->UpdateNetworkMetrics(network_metrics); + } } void CheckDecision(FrameLengthController* controller, @@ -99,9 +113,9 @@ void CheckDecision(FrameLengthController* controller, TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkBandwidth) { auto controller = CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60); - UpdateNetworkMetrics(controller.get(), - rtc::Optional(kFl60msTo20msBandwidthBps), - rtc::Optional()); + UpdateNetworkMetrics( + controller.get(), rtc::Optional(kFl60msTo20msBandwidthBps), + rtc::Optional(), rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); } @@ -109,7 +123,8 @@ TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkPacketLossFraction) { auto controller = CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(), - rtc::Optional(kFlDecreasingPacketLossFraction)); + rtc::Optional(kFlDecreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); } @@ -137,7 +152,8 @@ TEST(FrameLengthControllerTest, Maintain60MsOnMultipleConditions) { CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(kMediumBandwidthBps), - rtc::Optional(kMediumPacketLossFraction)); + rtc::Optional(kMediumPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); } @@ -151,10 +167,35 @@ TEST(FrameLengthControllerTest, IncreaseTo60MsOnMultipleConditions) { CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl20msTo60msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); } +TEST(FrameLengthControllerTest, IncreaseTo60MsOnVeryLowUplinkBandwidth) { + auto controller = + CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20); + // We set packet loss fraction to kFlDecreasingPacketLossFraction, and FEC on, + // both of which should have prevented frame length to increase, if the uplink + // bandwidth was not this low. + UpdateNetworkMetrics(controller.get(), rtc::Optional(VeryLowBitrate(20)), + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); + CheckDecision(controller.get(), rtc::Optional(true), 60); +} + +TEST(FrameLengthControllerTest, Maintain60MsOnVeryLowUplinkBandwidth) { + auto controller = + CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60); + // We set packet loss fraction to FlDecreasingPacketLossFraction, and FEC on, + // both of which should have caused the frame length to decrease, if the + // uplink bandwidth was not this low. + UpdateNetworkMetrics(controller.get(), rtc::Optional(VeryLowBitrate(20)), + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); + CheckDecision(controller.get(), rtc::Optional(true), 60); +} + TEST(FrameLengthControllerTest, UpdateMultipleNetworkMetricsAtOnce) { // This test is similar to IncreaseTo60MsOnMultipleConditions. But instead of // using ::UpdateNetworkMetrics(...), which calls @@ -182,7 +223,8 @@ TEST(FrameLengthControllerTest, // cause frame length to increase if receiver frame length included 60ms. UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl20msTo60msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); } @@ -191,7 +233,8 @@ TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkBandwidth) { CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20); UpdateNetworkMetrics(controller.get(), rtc::Optional(kMediumBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); } @@ -202,7 +245,8 @@ TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkPacketLossFraction) { // uplink packet loss fraction was low. UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl20msTo60msBandwidthBps), - rtc::Optional(kMediumPacketLossFraction)); + rtc::Optional(kMediumPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); } @@ -213,7 +257,8 @@ TEST(FrameLengthControllerTest, Maintain20MsWhenFecIsOn) { // cause frame length to increase if FEC was not ON. UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl20msTo60msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kMediumPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(true), 20); } @@ -222,7 +267,8 @@ TEST(FrameLengthControllerTest, Maintain60MsWhenNo120msCriteriaIsSet) { CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60, 120}, 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl60msTo120msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); } @@ -230,14 +276,14 @@ TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkBandwidth) { auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(), {20, 60, 120}, 120); // It takes two steps for frame length to go from 120ms to 20ms. - UpdateNetworkMetrics(controller.get(), - rtc::Optional(kFl60msTo20msBandwidthBps), - rtc::Optional()); + UpdateNetworkMetrics( + controller.get(), rtc::Optional(kFl60msTo20msBandwidthBps), + rtc::Optional(), rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); - UpdateNetworkMetrics(controller.get(), - rtc::Optional(kFl60msTo20msBandwidthBps), - rtc::Optional()); + UpdateNetworkMetrics( + controller.get(), rtc::Optional(kFl60msTo20msBandwidthBps), + rtc::Optional(), rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); } @@ -246,11 +292,13 @@ TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkPacketLossFraction) { {20, 60, 120}, 120); // It takes two steps for frame length to go from 120ms to 20ms. UpdateNetworkMetrics(controller.get(), rtc::Optional(), - rtc::Optional(kFlDecreasingPacketLossFraction)); + rtc::Optional(kFlDecreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(), - rtc::Optional(kFlDecreasingPacketLossFraction)); + rtc::Optional(kFlDecreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); } @@ -262,6 +310,30 @@ TEST(FrameLengthControllerTest, From120MsTo20MsWhenFecIsOn) { CheckDecision(controller.get(), rtc::Optional(true), 20); } +TEST(FrameLengthControllerTest, Maintain120MsOnVeryLowUplinkBandwidth) { + auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(), + {20, 60, 120}, 120); + // We set packet loss fraction to FlDecreasingPacketLossFraction, and FEC on, + // both of which should have caused the frame length to decrease, if the + // uplink bandwidth was not this low. + UpdateNetworkMetrics(controller.get(), rtc::Optional(VeryLowBitrate(60)), + rtc::Optional(kFlDecreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); + CheckDecision(controller.get(), rtc::Optional(true), 120); +} + +TEST(FrameLengthControllerTest, From60MsTo120MsOnVeryLowUplinkBandwidth) { + auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(), + {20, 60, 120}, 60); + // We set packet loss fraction to FlDecreasingPacketLossFraction, and FEC on, + // both of which should have prevented frame length to increase, if the uplink + // bandwidth was not this low. + UpdateNetworkMetrics(controller.get(), rtc::Optional(VeryLowBitrate(60)), + rtc::Optional(kFlDecreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); + CheckDecision(controller.get(), rtc::Optional(true), 120); +} + TEST(FrameLengthControllerTest, From20MsTo120MsOnMultipleConditions) { // Increase to 120ms frame length if // 1. |uplink_bandwidth_bps| is known to be smaller than a threshold AND @@ -273,11 +345,13 @@ TEST(FrameLengthControllerTest, From20MsTo120MsOnMultipleConditions) { // It takes two steps for frame length to go from 20ms to 120ms. UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl60msTo120msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl60msTo120msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 120); } @@ -286,11 +360,13 @@ TEST(FrameLengthControllerTest, Stall60MsIf120MsNotInReceiverFrameLengthRange) { CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(), {20, 60}, 20); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl60msTo120msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl60msTo120msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); } @@ -299,32 +375,38 @@ TEST(FrameLengthControllerTest, CheckBehaviorOnChangingNetworkMetrics) { {20, 60, 120}, 20); UpdateNetworkMetrics(controller.get(), rtc::Optional(kMediumBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl20msTo60msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl60msTo120msBandwidthBps), - rtc::Optional(kMediumPacketLossFraction)); + rtc::Optional(kMediumPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl60msTo120msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 120); UpdateNetworkMetrics(controller.get(), rtc::Optional(kFl120msTo60msBandwidthBps), - rtc::Optional(kFlIncreasingPacketLossFraction)); + rtc::Optional(kFlIncreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 60); UpdateNetworkMetrics(controller.get(), rtc::Optional(kMediumBandwidthBps), - rtc::Optional(kFlDecreasingPacketLossFraction)); + rtc::Optional(kFlDecreasingPacketLossFraction), + rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(controller.get(), rtc::Optional(), 20); } diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc index 515f6c0f42..c031756696 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc @@ -546,10 +546,11 @@ AudioEncoderOpus::DefaultAudioNetworkAdaptorCreator( config.clock = clock; config.event_log = event_log; return std::unique_ptr(new AudioNetworkAdaptorImpl( - config, ControllerManagerImpl::Create( - config_string, NumChannels(), supported_frame_lengths_ms(), - num_channels_to_encode_, next_frame_length_ms_, - GetTargetBitrate(), config_.fec_enabled, GetDtx(), clock))); + config, + ControllerManagerImpl::Create( + config_string, NumChannels(), supported_frame_lengths_ms(), + kMinBitrateBps, num_channels_to_encode_, next_frame_length_ms_, + GetTargetBitrate(), config_.fec_enabled, GetDtx(), clock))); } void AudioEncoderOpus::MaybeUpdateUplinkBandwidth() {