Reland of actor NACK bitrate allocation (patchset #1 id:1 of https://codereview.webrtc.org/2131913003/ )

Reason for revert:
Upstream fixes in place, should be OK now.

Original issue's description:
> Revert of Refactor NACK bitrate allocation (patchset #16 id:300001 of https://codereview.webrtc.org/2061423003/ )
>
> Reason for revert:
> Breaks upstream code.
>
> Original issue's description:
> > Refactor NACK bitrate allocation
> >
> > Nack bitrate allocation should not be done on a per-rtp-module basis,
> > but rather shared bitrate pool per call. This CL moves allocation to the
> > pacer and cleans up a bunch if bitrate stats handling.
> >
> > BUG=
> > R=danilchap@webrtc.org, stefan@webrtc.org, tommi@webrtc.org
> >
> > Committed: https://chromium.googlesource.com/external/webrtc/+/5fc59e810b8ea848702f2dbc740fe190608e1413
>
> TBR=tommi@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=
>
> Committed: https://crrev.com/e5dd44101eca485f5ad12e5f7ce6f6b0d204116b
> Cr-Commit-Position: refs/heads/master@{#13417}

TBR=tommi@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=

Review-Url: https://codereview.webrtc.org/2146013002
Cr-Commit-Position: refs/heads/master@{#13465}
diff --git a/webrtc/base/rate_limiter_unittest.cc b/webrtc/base/rate_limiter_unittest.cc
new file mode 100644
index 0000000..d441128
--- /dev/null
+++ b/webrtc/base/rate_limiter_unittest.cc
@@ -0,0 +1,205 @@
+/*
+ *  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 <algorithm>
+#include <memory>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "webrtc/base/event.h"
+#include "webrtc/base/platform_thread.h"
+#include "webrtc/base/rate_limiter.h"
+#include "webrtc/base/task_queue.h"
+#include "webrtc/system_wrappers/include/clock.h"
+
+namespace webrtc {
+
+class RateLimitTest : public ::testing::Test {
+ public:
+  RateLimitTest()
+      : clock_(0), rate_limiter(new RateLimiter(&clock_, kWindowSizeMs)) {}
+  virtual ~RateLimitTest() {}
+
+  void SetUp() override { rate_limiter->SetMaxRate(kMaxRateBps); }
+
+ protected:
+  static constexpr int64_t kWindowSizeMs = 1000;
+  static constexpr uint32_t kMaxRateBps = 100000;
+  // Bytes needed to completely saturate the rate limiter.
+  static constexpr size_t kRateFillingBytes =
+      (kMaxRateBps * kWindowSizeMs) / (8 * 1000);
+  SimulatedClock clock_;
+  std::unique_ptr<RateLimiter> rate_limiter;
+};
+
+TEST_F(RateLimitTest, IncreasingMaxRate) {
+  // Fill rate, extend window to full size.
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
+  clock_.AdvanceTimeMilliseconds(kWindowSizeMs - 1);
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
+
+  // All rate consumed.
+  EXPECT_FALSE(rate_limiter->TryUseRate(1));
+
+  // Double the available rate and fill that too.
+  rate_limiter->SetMaxRate(kMaxRateBps * 2);
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes));
+
+  // All rate consumed again.
+  EXPECT_FALSE(rate_limiter->TryUseRate(1));
+}
+
+TEST_F(RateLimitTest, DecreasingMaxRate) {
+  // Fill rate, extend window to full size.
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
+  clock_.AdvanceTimeMilliseconds(kWindowSizeMs - 1);
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
+
+  // All rate consumed.
+  EXPECT_FALSE(rate_limiter->TryUseRate(1));
+
+  // Halve the available rate and move window so half of the data falls out.
+  rate_limiter->SetMaxRate(kMaxRateBps / 2);
+  clock_.AdvanceTimeMilliseconds(1);
+
+  // All rate still consumed.
+  EXPECT_FALSE(rate_limiter->TryUseRate(1));
+}
+
+TEST_F(RateLimitTest, ChangingWindowSize) {
+  // Fill rate, extend window to full size.
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
+  clock_.AdvanceTimeMilliseconds(kWindowSizeMs - 1);
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
+
+  // All rate consumed.
+  EXPECT_FALSE(rate_limiter->TryUseRate(1));
+
+  // Decrease window size so half of the data falls out.
+  rate_limiter->SetWindowSize(kWindowSizeMs / 2);
+  // Average rate should still be the same, so rate is still all consumed.
+  EXPECT_FALSE(rate_limiter->TryUseRate(1));
+
+  // Increase window size again. Now the rate is only half used (removed data
+  // points don't come back to life).
+  rate_limiter->SetWindowSize(kWindowSizeMs);
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
+
+  // All rate consumed again.
+  EXPECT_FALSE(rate_limiter->TryUseRate(1));
+}
+
+TEST_F(RateLimitTest, SingleUsageAlwaysOk) {
+  // Using more bytes than can fit in a window is OK for a single packet.
+  EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes + 1));
+}
+
+TEST_F(RateLimitTest, WindowSizeLimits) {
+  EXPECT_TRUE(rate_limiter->SetWindowSize(1));
+  EXPECT_FALSE(rate_limiter->SetWindowSize(0));
+  EXPECT_TRUE(rate_limiter->SetWindowSize(kWindowSizeMs));
+  EXPECT_FALSE(rate_limiter->SetWindowSize(kWindowSizeMs + 1));
+}
+
+static const int64_t kMaxTimeoutMs = 30000;
+
+class ThreadTask {
+ public:
+  explicit ThreadTask(RateLimiter* rate_limiter)
+      : rate_limiter_(rate_limiter),
+        start_signal_(false, false),
+        end_signal_(false, false) {}
+  virtual ~ThreadTask() {}
+
+  void Run() {
+    start_signal_.Wait(kMaxTimeoutMs);
+    DoRun();
+    end_signal_.Set();
+  }
+
+  virtual void DoRun() = 0;
+
+  RateLimiter* const rate_limiter_;
+  rtc::Event start_signal_;
+  rtc::Event end_signal_;
+};
+
+bool RunTask(void* thread_task) {
+  reinterpret_cast<ThreadTask*>(thread_task)->Run();
+  return false;
+}
+
+TEST_F(RateLimitTest, MultiThreadedUsage) {
+  // Simple sanity test, with different threads calling the various methods.
+  // Runs a few simple tasks, each on its own thread, but coordinated with
+  // events so that they run in a serialized order. Intended to catch data
+  // races when run with tsan et al.
+
+  // Half window size, double rate -> same amount of bytes needed to fill rate.
+
+  class SetWindowSizeTask : public ThreadTask {
+   public:
+    explicit SetWindowSizeTask(RateLimiter* rate_limiter)
+        : ThreadTask(rate_limiter) {}
+    virtual ~SetWindowSizeTask() {}
+
+    void DoRun() override {
+      EXPECT_TRUE(rate_limiter_->SetWindowSize(kWindowSizeMs / 2));
+    }
+  } set_window_size_task(rate_limiter.get());
+  rtc::PlatformThread thread1(RunTask, &set_window_size_task, "Thread1");
+  thread1.Start();
+
+  class SetMaxRateTask : public ThreadTask {
+   public:
+    explicit SetMaxRateTask(RateLimiter* rate_limiter)
+        : ThreadTask(rate_limiter) {}
+    virtual ~SetMaxRateTask() {}
+
+    void DoRun() override { rate_limiter_->SetMaxRate(kMaxRateBps * 2); }
+  } set_max_rate_task(rate_limiter.get());
+  rtc::PlatformThread thread2(RunTask, &set_max_rate_task, "Thread2");
+  thread2.Start();
+
+  class UseRateTask : public ThreadTask {
+   public:
+    UseRateTask(RateLimiter* rate_limiter, SimulatedClock* clock)
+        : ThreadTask(rate_limiter), clock_(clock) {}
+    virtual ~UseRateTask() {}
+
+    void DoRun() override {
+      EXPECT_TRUE(rate_limiter_->TryUseRate(kRateFillingBytes / 2));
+      clock_->AdvanceTimeMilliseconds((kWindowSizeMs / 2) - 1);
+      EXPECT_TRUE(rate_limiter_->TryUseRate(kRateFillingBytes / 2));
+    }
+
+    SimulatedClock* const clock_;
+  } use_rate_task(rate_limiter.get(), &clock_);
+  rtc::PlatformThread thread3(RunTask, &use_rate_task, "Thread3");
+  thread3.Start();
+
+  set_window_size_task.start_signal_.Set();
+  EXPECT_TRUE(set_window_size_task.end_signal_.Wait(kMaxTimeoutMs));
+
+  set_max_rate_task.start_signal_.Set();
+  EXPECT_TRUE(set_max_rate_task.end_signal_.Wait(kMaxTimeoutMs));
+
+  use_rate_task.start_signal_.Set();
+  EXPECT_TRUE(use_rate_task.end_signal_.Wait(kMaxTimeoutMs));
+
+  // All rate consumed.
+  EXPECT_FALSE(rate_limiter->TryUseRate(1));
+
+  thread1.Stop();
+  thread2.Stop();
+  thread3.Stop();
+}
+
+}  // namespace webrtc