Added configurable offsets to the per-packet overhead in the ANA frame length and bitrate controllers.

This adds four parameters to the protobuf that is used to configure the ANA controllers. These extra parameters allow for setting an offset to the per-packet overhead that is used when changing the frame length size and when changing bitrate.

BUG=webrtc:8179

Review-Url: https://codereview.webrtc.org/3013613002
Cr-Commit-Position: refs/heads/master@{#20011}
diff --git a/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc b/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc
index 587c858..16c4bc4 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 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 @@
         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<int>(*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<int>(
+        (*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<int>(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 cad6d6a..601f794 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 @@
 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 9726992..b6060a9 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 @@
   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<int>(),
                        rtc::Optional<size_t>(kOverheadBytesPerPacket));
   CheckDecision(&controller, rtc::Optional<int>(kInitialFrameLengthMs * 2),
@@ -67,8 +67,8 @@
   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<int>(kTargetBitrateBps),
                        rtc::Optional<size_t>());
   CheckDecision(&controller, rtc::Optional<int>(kInitialFrameLengthMs * 2),
@@ -80,7 +80,7 @@
       "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 @@
       "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 @@
       "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 @@
       "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 @@
       "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, 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, 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 d510e41..6d1cd42 100644
--- a/modules/audio_coding/audio_network_adaptor/config.proto
+++ b/modules/audio_coding/audio_network_adaptor/config.proto
@@ -92,6 +92,12 @@
 
   // 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 @@
   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 319e752..d573960 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 @@
         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<int>(), 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 @@
 
 using audio_network_adaptor::BitrateController;
 std::unique_ptr<BitrateController> CreateBitrateController(
+    const audio_network_adaptor::config::BitrateController& bitrate_config,
     int initial_bitrate_bps,
     int initial_frame_length_ms) {
-  return std::unique_ptr<BitrateController>(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<BitrateController>(
+      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 @@
                                          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 9a5f03221..5ae78b0 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 <algorithm>
 #include <utility>
 
 #include "rtc_base/checks.h"
@@ -32,12 +33,16 @@
     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<FrameLengthChange, int> 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 @@
 
   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<int>(*frame_length_ms_);
 }
 
@@ -110,10 +118,22 @@
   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<size_t>(std::max(0, -config_.fl_increase_overhead_offset)) <=
+           *overhead_bytes_per_packet_ &&
+       static_cast<size_t>(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 @@
     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 bbda77e..c254b3d 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 @@
            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<FrameLengthChange, int> fl_changing_bandwidths_bps);
     Config(const Config& other);
     ~Config();
@@ -45,6 +47,10 @@
     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<FrameLengthChange, int> fl_changing_bandwidths_bps;
   };
 
@@ -73,6 +79,10 @@
 
   rtc::Optional<size_t> 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 fa0af7d..4c96c96 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 @@
 
 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 @@
       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 5b2d113..5af3e09 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 @@
   // better use of the bandwidth. |num_channels| sets the number of channels
   // to encode.
   rtc::Optional<size_t> 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