diff --git a/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc b/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc index 587c858ece..16c4bc4e55 100644 --- a/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc +++ b/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc @@ -19,9 +19,13 @@ namespace webrtc { namespace audio_network_adaptor { BitrateController::Config::Config(int initial_bitrate_bps, - int initial_frame_length_ms) + int initial_frame_length_ms, + int fl_increase_overhead_offset, + int fl_decrease_overhead_offset) : initial_bitrate_bps(initial_bitrate_bps), - initial_frame_length_ms(initial_frame_length_ms) {} + initial_frame_length_ms(initial_frame_length_ms), + fl_increase_overhead_offset(fl_increase_overhead_offset), + fl_decrease_overhead_offset(fl_decrease_overhead_offset) {} BitrateController::Config::~Config() = default; @@ -54,9 +58,15 @@ void BitrateController::MakeDecision(AudioEncoderRuntimeConfig* config) { webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")); if (config->frame_length_ms) frame_length_ms_ = *config->frame_length_ms; - int overhead_rate_bps = - static_cast(*overhead_bytes_per_packet_ * 8 * 1000 / - frame_length_ms_); + int offset = config->last_fl_change_increase + ? config_.fl_increase_overhead_offset + : config_.fl_decrease_overhead_offset; + // Check that + // -(*overhead_bytes_per_packet_) <= offset <= (*overhead_bytes_per_packet_) + RTC_DCHECK_GE(*overhead_bytes_per_packet_, -offset); + RTC_DCHECK_LE(offset, *overhead_bytes_per_packet_); + int overhead_rate_bps = static_cast( + (*overhead_bytes_per_packet_ + offset) * 8 * 1000 / frame_length_ms_); bitrate_bps_ = std::max(0, *target_audio_bitrate_bps_ - overhead_rate_bps); } config->bitrate_bps = rtc::Optional(bitrate_bps_); diff --git a/modules/audio_coding/audio_network_adaptor/bitrate_controller.h b/modules/audio_coding/audio_network_adaptor/bitrate_controller.h index cad6d6a71b..601f794b6a 100644 --- a/modules/audio_coding/audio_network_adaptor/bitrate_controller.h +++ b/modules/audio_coding/audio_network_adaptor/bitrate_controller.h @@ -20,10 +20,15 @@ namespace audio_network_adaptor { class BitrateController final : public Controller { public: struct Config { - Config(int initial_bitrate_bps, int initial_frame_length_ms); + Config(int initial_bitrate_bps, + int initial_frame_length_ms, + int fl_increase_overhead_offset, + int fl_decrease_overhead_offset); ~Config(); int initial_bitrate_bps; int initial_frame_length_ms; + int fl_increase_overhead_offset; + int fl_decrease_overhead_offset; }; explicit BitrateController(const Config& config); diff --git a/modules/audio_coding/audio_network_adaptor/bitrate_controller_unittest.cc b/modules/audio_coding/audio_network_adaptor/bitrate_controller_unittest.cc index 97269923c3..b6060a99e6 100644 --- a/modules/audio_coding/audio_network_adaptor/bitrate_controller_unittest.cc +++ b/modules/audio_coding/audio_network_adaptor/bitrate_controller_unittest.cc @@ -55,8 +55,8 @@ TEST(AnaBitrateControllerTest, OutputInitValueWhenTargetBitrateUnknown) { constexpr int kInitialBitrateBps = 32000; constexpr int kInitialFrameLengthMs = 20; constexpr size_t kOverheadBytesPerPacket = 64; - BitrateController controller( - BitrateController::Config(kInitialBitrateBps, kInitialFrameLengthMs)); + BitrateController controller(BitrateController::Config( + kInitialBitrateBps, kInitialFrameLengthMs, 0, 0)); UpdateNetworkMetrics(&controller, rtc::Optional(), rtc::Optional(kOverheadBytesPerPacket)); CheckDecision(&controller, rtc::Optional(kInitialFrameLengthMs * 2), @@ -67,8 +67,8 @@ TEST(AnaBitrateControllerTest, OutputInitValueWhenOverheadUnknown) { constexpr int kInitialBitrateBps = 32000; constexpr int kInitialFrameLengthMs = 20; constexpr int kTargetBitrateBps = 48000; - BitrateController controller( - BitrateController::Config(kInitialBitrateBps, kInitialFrameLengthMs)); + BitrateController controller(BitrateController::Config( + kInitialBitrateBps, kInitialFrameLengthMs, 0, 0)); UpdateNetworkMetrics(&controller, rtc::Optional(kTargetBitrateBps), rtc::Optional()); CheckDecision(&controller, rtc::Optional(kInitialFrameLengthMs * 2), @@ -80,7 +80,7 @@ TEST(AnaBitrateControllerTest, ChangeBitrateOnTargetBitrateChanged) { "WebRTC-SendSideBwe-WithOverhead/Enabled/"); constexpr int kInitialFrameLengthMs = 20; BitrateController controller( - BitrateController::Config(32000, kInitialFrameLengthMs)); + BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0)); constexpr int kTargetBitrateBps = 48000; constexpr size_t kOverheadBytesPerPacket = 64; constexpr int kBitrateBps = @@ -106,7 +106,7 @@ TEST(AnaBitrateControllerTest, UpdateMultipleNetworkMetricsAtOnce) { "WebRTC-SendSideBwe-WithOverhead/Enabled/"); constexpr int kInitialFrameLengthMs = 20; BitrateController controller( - BitrateController::Config(32000, kInitialFrameLengthMs)); + BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0)); constexpr int kTargetBitrateBps = 48000; constexpr size_t kOverheadBytesPerPacket = 64; constexpr int kBitrateBps = @@ -127,7 +127,7 @@ TEST(AnaBitrateControllerTest, TreatUnknownFrameLengthAsFrameLengthUnchanged) { "WebRTC-SendSideBwe-WithOverhead/Enabled/"); constexpr int kInitialFrameLengthMs = 20; BitrateController controller( - BitrateController::Config(32000, kInitialFrameLengthMs)); + BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0)); constexpr int kTargetBitrateBps = 48000; constexpr size_t kOverheadBytesPerPacket = 64; constexpr int kBitrateBps = @@ -143,7 +143,7 @@ TEST(AnaBitrateControllerTest, IncreaseBitrateOnFrameLengthIncreased) { "WebRTC-SendSideBwe-WithOverhead/Enabled/"); constexpr int kInitialFrameLengthMs = 20; BitrateController controller( - BitrateController::Config(32000, kInitialFrameLengthMs)); + BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0)); constexpr int kTargetBitrateBps = 48000; constexpr size_t kOverheadBytesPerPacket = 64; @@ -169,7 +169,7 @@ TEST(AnaBitrateControllerTest, DecreaseBitrateOnFrameLengthDecreased) { "WebRTC-SendSideBwe-WithOverhead/Enabled/"); constexpr int kInitialFrameLengthMs = 60; BitrateController controller( - BitrateController::Config(32000, kInitialFrameLengthMs)); + BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0)); constexpr int kTargetBitrateBps = 48000; constexpr size_t kOverheadBytesPerPacket = 64; @@ -193,7 +193,7 @@ TEST(AnaBitrateControllerTest, DecreaseBitrateOnFrameLengthDecreased) { TEST(AnaBitrateControllerTest, BitrateNeverBecomesNegative) { test::ScopedFieldTrials override_field_trials( "WebRTC-SendSideBwe-WithOverhead/Enabled/"); - BitrateController controller(BitrateController::Config(32000, 20)); + BitrateController controller(BitrateController::Config(32000, 20, 0, 0)); constexpr size_t kOverheadBytesPerPacket = 64; constexpr int kFrameLengthMs = 60; // Set a target rate smaller than overhead rate, the bitrate is bounded by 0. @@ -207,7 +207,7 @@ TEST(AnaBitrateControllerTest, BitrateNeverBecomesNegative) { TEST(AnaBitrateControllerTest, CheckBehaviorOnChangingCondition) { test::ScopedFieldTrials override_field_trials( "WebRTC-SendSideBwe-WithOverhead/Enabled/"); - BitrateController controller(BitrateController::Config(32000, 20)); + BitrateController controller(BitrateController::Config(32000, 20, 0, 0)); // Start from an arbitrary overall bitrate. int overall_bitrate = 34567; diff --git a/modules/audio_coding/audio_network_adaptor/config.proto b/modules/audio_coding/audio_network_adaptor/config.proto index d510e41a29..6d1cd42d46 100644 --- a/modules/audio_coding/audio_network_adaptor/config.proto +++ b/modules/audio_coding/audio_network_adaptor/config.proto @@ -92,6 +92,12 @@ message FrameLengthController { // Uplink bandwidth above which frame length should switch from 120ms to 60ms. optional int32 fl_120ms_to_60ms_bandwidth_bps = 6; + + // Offset to apply to the per-packet overhead when increasing frame length. + optional int32 fl_increase_overhead_offset = 7; + + // Offset to apply to the per-packet overhead when decreasing frame length. + optional int32 fl_decrease_overhead_offset = 8; } message ChannelController { @@ -112,7 +118,12 @@ message DtxController { optional int32 dtx_disabling_bandwidth_bps = 2; } -message BitrateController {} +message BitrateController { + // Offset to apply to per-packet overhead when the frame length is increased. + optional int32 fl_increase_overhead_offset = 1; + // Offset to apply to per-packet overhead when the frame length is decreased. + optional int32 fl_decrease_overhead_offset = 2; +} message Controller { message ScoringPoint { diff --git a/modules/audio_coding/audio_network_adaptor/controller_manager.cc b/modules/audio_coding/audio_network_adaptor/controller_manager.cc index 319e752d7b..d57396038e 100644 --- a/modules/audio_coding/audio_network_adaptor/controller_manager.cc +++ b/modules/audio_coding/audio_network_adaptor/controller_manager.cc @@ -137,11 +137,20 @@ std::unique_ptr CreateFrameLengthController( config.fl_120ms_to_60ms_bandwidth_bps())); } + int fl_increase_overhead_offset = 0; + if (config.has_fl_increase_overhead_offset()) { + fl_increase_overhead_offset = config.fl_increase_overhead_offset(); + } + int fl_decrease_overhead_offset = 0; + if (config.has_fl_decrease_overhead_offset()) { + fl_decrease_overhead_offset = config.fl_decrease_overhead_offset(); + } + FrameLengthController::Config ctor_config( 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)); + config.fl_decreasing_packet_loss_fraction(), fl_increase_overhead_offset, + fl_decrease_overhead_offset, std::move(fl_changing_bandwidths_bps)); for (auto frame_length : encoder_frame_lengths_ms) ctor_config.encoder_frame_lengths_ms.push_back(frame_length); @@ -176,10 +185,21 @@ std::unique_ptr CreateDtxController( using audio_network_adaptor::BitrateController; std::unique_ptr CreateBitrateController( + const audio_network_adaptor::config::BitrateController& bitrate_config, int initial_bitrate_bps, int initial_frame_length_ms) { - return std::unique_ptr(new BitrateController( - BitrateController::Config(initial_bitrate_bps, initial_frame_length_ms))); + int fl_increase_overhead_offset = 0; + if (bitrate_config.has_fl_increase_overhead_offset()) { + fl_increase_overhead_offset = bitrate_config.fl_increase_overhead_offset(); + } + int fl_decrease_overhead_offset = 0; + if (bitrate_config.has_fl_decrease_overhead_offset()) { + fl_decrease_overhead_offset = bitrate_config.fl_decrease_overhead_offset(); + } + return std::unique_ptr( + new BitrateController(BitrateController::Config( + initial_bitrate_bps, initial_frame_length_ms, + fl_increase_overhead_offset, fl_decrease_overhead_offset))); } #endif // WEBRTC_ENABLE_PROTOBUF @@ -257,8 +277,9 @@ std::unique_ptr ControllerManagerImpl::Create( initial_dtx_enabled); break; case audio_network_adaptor::config::Controller::kBitrateController: - controller = CreateBitrateController(initial_bitrate_bps, - initial_frame_length_ms); + controller = CreateBitrateController( + controller_config.bitrate_controller(), initial_bitrate_bps, + initial_frame_length_ms); break; default: RTC_NOTREACHED(); diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc b/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc index 9a5f032213..5ae78b031c 100644 --- a/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc +++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc @@ -10,6 +10,7 @@ #include "modules/audio_coding/audio_network_adaptor/frame_length_controller.h" +#include #include #include "rtc_base/checks.h" @@ -32,12 +33,16 @@ FrameLengthController::Config::Config( int min_encoder_bitrate_bps, float fl_increasing_packet_loss_fraction, float fl_decreasing_packet_loss_fraction, + int fl_increase_overhead_offset, + int fl_decrease_overhead_offset, 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_increase_overhead_offset(fl_increase_overhead_offset), + fl_decrease_overhead_offset(fl_decrease_overhead_offset), fl_changing_bandwidths_bps(std::move(fl_changing_bandwidths_bps)) {} FrameLengthController::Config::Config(const Config& other) = default; @@ -71,9 +76,12 @@ void FrameLengthController::MakeDecision(AudioEncoderRuntimeConfig* config) { if (FrameLengthIncreasingDecision(*config)) { ++frame_length_ms_; + prev_decision_increase_ = true; } else if (FrameLengthDecreasingDecision(*config)) { --frame_length_ms_; + prev_decision_increase_ = false; } + config->last_fl_change_increase = prev_decision_increase_; config->frame_length_ms = rtc::Optional(*frame_length_ms_); } @@ -110,10 +118,22 @@ bool FrameLengthController::FrameLengthIncreasingDecision( if (increase_threshold == config_.fl_changing_bandwidths_bps.end()) return false; + // Check that + // -(*overhead_bytes_per_packet_) <= offset <= (*overhead_bytes_per_packet_) + RTC_DCHECK( + !overhead_bytes_per_packet_ || + (overhead_bytes_per_packet_ && + static_cast(std::max(0, -config_.fl_increase_overhead_offset)) <= + *overhead_bytes_per_packet_ && + static_cast(std::max(0, config_.fl_increase_overhead_offset)) <= + *overhead_bytes_per_packet_)); + 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_)) { + OverheadRateBps(*overhead_bytes_per_packet_ + + config_.fl_increase_overhead_offset, + *frame_length_ms_)) { return true; } @@ -145,10 +165,11 @@ bool FrameLengthController::FrameLengthDecreasingDecision( 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)) { + *uplink_bandwidth_bps_ <= + config_.min_encoder_bitrate_bps + kPreventOveruseMarginBps + + OverheadRateBps(*overhead_bytes_per_packet_ + + config_.fl_decrease_overhead_offset, + *shorter_frame_length_ms)) { return false; } diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller.h b/modules/audio_coding/audio_network_adaptor/frame_length_controller.h index bbda77ed52..c254b3dcf6 100644 --- a/modules/audio_coding/audio_network_adaptor/frame_length_controller.h +++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller.h @@ -35,6 +35,8 @@ class FrameLengthController final : public Controller { int min_encoder_bitrate_bps, float fl_increasing_packet_loss_fraction, float fl_decreasing_packet_loss_fraction, + int fl_increase_overhead_offset, + int fl_decrease_overhead_offset, std::map fl_changing_bandwidths_bps); Config(const Config& other); ~Config(); @@ -45,6 +47,10 @@ class FrameLengthController final : public Controller { float fl_increasing_packet_loss_fraction; // Uplink packet loss fraction below which frame length should decrease. float fl_decreasing_packet_loss_fraction; + // Offset to apply to overhead calculation when increasing frame length. + int fl_increase_overhead_offset; + // Offset to apply to overhead calculation when decreasing frame length. + int fl_decrease_overhead_offset; std::map fl_changing_bandwidths_bps; }; @@ -73,6 +79,10 @@ class FrameLengthController final : public Controller { rtc::Optional overhead_bytes_per_packet_; + // True if the previous frame length decision was an increase, otherwise + // false. + bool prev_decision_increase_ = false; + RTC_DISALLOW_COPY_AND_ASSIGN(FrameLengthController); }; diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc b/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc index fa0af7dde6..4c96c96f6f 100644 --- a/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc +++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc @@ -20,6 +20,8 @@ namespace { constexpr float kFlIncreasingPacketLossFraction = 0.04f; constexpr float kFlDecreasingPacketLossFraction = 0.05f; +constexpr int kFlIncreaseOverheadOffset = 0; +constexpr int kFlDecreaseOverheadOffset = 0; constexpr int kMinEncoderBitrateBps = 6000; constexpr int kPreventOveruseMarginBps = 5000; constexpr size_t kOverheadBytesPerPacket = 20; @@ -46,7 +48,8 @@ std::unique_ptr CreateController( new FrameLengthController(FrameLengthController::Config( encoder_frame_lengths_ms, initial_frame_length_ms, kMinEncoderBitrateBps, kFlIncreasingPacketLossFraction, - kFlDecreasingPacketLossFraction, frame_length_change_criteria))); + kFlDecreasingPacketLossFraction, kFlIncreaseOverheadOffset, + kFlDecreaseOverheadOffset, frame_length_change_criteria))); return controller; } diff --git a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h index 5b2d11371b..5af3e09ec8 100644 --- a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h +++ b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h @@ -32,6 +32,15 @@ struct AudioEncoderRuntimeConfig { // better use of the bandwidth. |num_channels| sets the number of channels // to encode. rtc::Optional num_channels; + + // This is true if the last frame length change was an increase, and otherwise + // false. + // The value of this boolean is used to apply a different offset to the + // per-packet overhead that is reported by the BWE. The exact offset value + // is most important right after a frame length change, because the frame + // length change affects the overhead. In the steady state, the exact value is + // not important because the BWE will compensate. + bool last_fl_change_increase = false; }; } // namespace webrtc