Add NACK rate throttling for audio channels.

Not really used for audio today (already in place for video), but should
still function anyway.

BUG=
R=henrika@webrtc.org, minyue@webrtc.org, stefan@webrtc.org

Review URL: https://codereview.webrtc.org/2181383002 .

Cr-Commit-Position: refs/heads/master@{#13571}
diff --git a/webrtc/call/rtc_event_log_unittest.cc b/webrtc/call/rtc_event_log_unittest.cc
index f8b555b..57d18b7 100644
--- a/webrtc/call/rtc_event_log_unittest.cc
+++ b/webrtc/call/rtc_event_log_unittest.cc
@@ -20,6 +20,7 @@
 #include "webrtc/base/buffer.h"
 #include "webrtc/base/checks.h"
 #include "webrtc/base/random.h"
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/call.h"
 #include "webrtc/call/rtc_event_log.h"
 #include "webrtc/call/rtc_event_log_parser.h"
@@ -111,19 +112,20 @@
                          Random* prng) {
   RTC_CHECK_GE(packet_size, 16 + 4 * csrcs_count + 4 * kNumExtensions);
   Clock* clock = Clock::GetRealTimeClock();
+  RateLimiter retranmission_rate_limiter(clock, 1000);
 
-  RTPSender rtp_sender(false,     // bool audio
-                       clock,     // Clock* clock
-                       nullptr,   // Transport*
-                       nullptr,   // PacedSender*
-                       nullptr,   // PacketRouter*
-                       nullptr,   // SendTimeObserver*
-                       nullptr,   // BitrateStatisticsObserver*
-                       nullptr,   // FrameCountObserver*
-                       nullptr,   // SendSideDelayObserver*
-                       nullptr,   // RtcEventLog*
-                       nullptr,   // SendPacketObserver*
-                       nullptr);  // NackRateLimiter*
+  RTPSender rtp_sender(false,    // bool audio
+                       clock,    // Clock* clock
+                       nullptr,  // Transport*
+                       nullptr,  // PacedSender*
+                       nullptr,  // PacketRouter*
+                       nullptr,  // SendTimeObserver*
+                       nullptr,  // BitrateStatisticsObserver*
+                       nullptr,  // FrameCountObserver*
+                       nullptr,  // SendSideDelayObserver*
+                       nullptr,  // RtcEventLog*
+                       nullptr,  // SendPacketObserver*
+                       &retranmission_rate_limiter);
 
   std::vector<uint32_t> csrcs;
   for (unsigned i = 0; i < csrcs_count; i++) {
diff --git a/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
index b12c08e..a0e0cec 100644
--- a/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
@@ -175,7 +175,7 @@
         receiver_(),
         payload_data_length(sizeof(payload_data)),
         fake_clock(123456),
-        retranmission_rate_limiter_(&fake_clock, kMaxRttMs) {}
+        retransmission_rate_limiter_(&fake_clock, kMaxRttMs) {}
   ~RtpRtcpRtxNackTest() {}
 
   void SetUp() override {
@@ -185,7 +185,7 @@
     receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock));
     configuration.receive_statistics = receive_statistics_.get();
     configuration.outgoing_transport = &transport_;
-    configuration.retransmission_rate_limiter = &retranmission_rate_limiter_;
+    configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
     rtp_rtcp_module_ = RtpRtcp::CreateRtpRtcp(configuration);
 
     rtp_feedback_.reset(new TestRtpFeedback(rtp_rtcp_module_));
@@ -292,7 +292,7 @@
   uint8_t payload_data[65000];
   size_t payload_data_length;
   SimulatedClock fake_clock;
-  RateLimiter retranmission_rate_limiter_;
+  RateLimiter retransmission_rate_limiter_;
 };
 
 TEST_F(RtpRtcpRtxNackTest, LongNackList) {
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
index bbfb52c..0e0d7f5 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
@@ -12,6 +12,7 @@
 
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/common_types.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
@@ -69,7 +70,8 @@
         remote_bitrate_observer_(),
         remote_bitrate_estimator_(
             new RemoteBitrateEstimatorSingleStream(&remote_bitrate_observer_,
-                                                   system_clock_)) {}
+                                                   system_clock_)),
+        retransmission_rate_limiter_(Clock::GetRealTimeClock(), 1000) {}
   void SetUp() override;
   void TearDown() override;
 
@@ -83,6 +85,7 @@
   test::NullTransport null_transport_;
   MockRemoteBitrateObserver remote_bitrate_observer_;
   std::unique_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
+  RateLimiter retransmission_rate_limiter_;
 };
 
 void RtcpFormatRembTest::SetUp() {
@@ -91,6 +94,7 @@
   configuration.clock = system_clock_;
   configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get();
   configuration.outgoing_transport = &null_transport_;
+  configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
   dummy_rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration);
   rtcp_receiver_ = new RTCPReceiver(system_clock_, false, nullptr, nullptr,
                                     nullptr, nullptr, dummy_rtp_rtcp_impl_);
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 924d009..cdb71be 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -13,6 +13,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/common_types.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
@@ -80,24 +81,24 @@
         remote_bitrate_observer_(),
         remote_bitrate_estimator_(
             new RemoteBitrateEstimatorSingleStream(&remote_bitrate_observer_,
-                                                   &system_clock_)) {
-    test_transport_ = new TestTransport();
+                                                   &system_clock_)),
+        retransmission_rate_limiter_(&system_clock_, 1000) {
+    test_transport_.reset(new TestTransport());
 
     RtpRtcp::Configuration configuration;
     configuration.audio = false;
     configuration.clock = &system_clock_;
-    configuration.outgoing_transport = test_transport_;
+    configuration.outgoing_transport = test_transport_.get();
     configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get();
-    rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration);
-    rtcp_receiver_ = new RTCPReceiver(&system_clock_, false, nullptr, nullptr,
-                                      nullptr, nullptr, rtp_rtcp_impl_);
-    test_transport_->SetRTCPReceiver(rtcp_receiver_);
+    configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
+    rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
+    rtcp_receiver_.reset(new RTCPReceiver(&system_clock_, false, nullptr,
+                                          nullptr, nullptr, nullptr,
+                                          rtp_rtcp_impl_.get()));
+    test_transport_->SetRTCPReceiver(rtcp_receiver_.get());
   }
-  ~RtcpReceiverTest() {
-    delete rtcp_receiver_;
-    delete rtp_rtcp_impl_;
-    delete test_transport_;
-  }
+
+  ~RtcpReceiverTest() {}
 
   // Injects an RTCP packet into the receiver.
   // Returns 0 for OK, non-0 for failure.
@@ -142,12 +143,13 @@
 
   OverUseDetectorOptions over_use_detector_options_;
   SimulatedClock system_clock_;
-  ModuleRtpRtcpImpl* rtp_rtcp_impl_;
-  RTCPReceiver* rtcp_receiver_;
-  TestTransport* test_transport_;
+  std::unique_ptr<TestTransport> test_transport_;
+  std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
+  std::unique_ptr<RTCPReceiver> rtcp_receiver_;
   RTCPHelp::RTCPPacketInformation rtcp_packet_info_;
   MockRemoteBitrateObserver remote_bitrate_observer_;
   std::unique_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
+  RateLimiter retransmission_rate_limiter_;
 };
 
 
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index ec83308..270088e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -13,6 +13,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/common_types.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
@@ -229,11 +230,13 @@
  protected:
   RtcpSenderTest()
       : clock_(1335900000),
-        receive_statistics_(ReceiveStatistics::Create(&clock_)) {
+        receive_statistics_(ReceiveStatistics::Create(&clock_)),
+        retransmission_rate_limiter_(&clock_, 1000) {
     RtpRtcp::Configuration configuration;
     configuration.audio = false;
     configuration.clock = &clock_;
     configuration.outgoing_transport = &test_transport_;
+    configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
 
     rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
     rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
@@ -265,6 +268,7 @@
   std::unique_ptr<ReceiveStatistics> receive_statistics_;
   std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
   std::unique_ptr<RTCPSender> rtcp_sender_;
+  RateLimiter retransmission_rate_limiter_;
 };
 
 TEST_F(RtcpSenderTest, SetRtcpStatus) {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
index 0afc8d2..3f2371e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -127,6 +127,8 @@
       csrcs_(),
       rtx_(kRtxOff),
       retransmission_rate_limiter_(retransmission_rate_limiter) {
+  RTC_DCHECK(retransmission_rate_limiter_ != nullptr);
+
   // We need to seed the random generator for BuildPaddingPacket() below.
   // TODO(holmer,tommi): Note that TimeInMilliseconds might return 0 on Mac
   // early on in the process.
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index 302f6dd..fed767b 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -1013,7 +1013,7 @@
   rtp_sender_.reset(new RTPSender(
       false, &fake_clock_, &transport_, &mock_paced_sender_,
       nullptr /* TransportSequenceNumberAllocator */, nullptr, nullptr, nullptr,
-      nullptr, nullptr, &send_packet_observer_, nullptr));
+      nullptr, nullptr, &send_packet_observer_, &retransmission_rate_limiter_));
   EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                    kRtpExtensionTransportSequenceNumber,
                    kTransportSequenceNumberExtensionId));
@@ -1034,7 +1034,8 @@
   MockTransport transport;
   rtp_sender_.reset(new RTPSender(
       false, &fake_clock_, &transport, &mock_paced_sender_, nullptr, nullptr,
-      nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr, nullptr));
+      nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr,
+      &retransmission_rate_limiter_));
 
   rtp_sender_->SetSequenceNumber(kSeqNum);
   rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
@@ -1178,9 +1179,10 @@
     FrameCounts frame_counts_;
   } callback;
 
-  rtp_sender_.reset(new RTPSender(
-      false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr, nullptr,
-      nullptr, &callback, nullptr, nullptr, nullptr, nullptr));
+  rtp_sender_.reset(new RTPSender(false, &fake_clock_, &transport_,
+                                  &mock_paced_sender_, nullptr, nullptr,
+                                  nullptr, &callback, nullptr, nullptr, nullptr,
+                                  &retransmission_rate_limiter_));
 
   char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC";
   const uint8_t payload_type = 127;
@@ -1239,9 +1241,9 @@
     uint32_t total_bitrate_;
     uint32_t retransmit_bitrate_;
   } callback;
-  rtp_sender_.reset(new RTPSender(false, &fake_clock_, &transport_, nullptr,
-                                  nullptr, nullptr, &callback, nullptr, nullptr,
-                                  nullptr, nullptr, nullptr));
+  rtp_sender_.reset(new RTPSender(
+      false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, &callback,
+      nullptr, nullptr, nullptr, nullptr, &retransmission_rate_limiter_));
 
   // Simulate kNumPackets sent with kPacketInterval ms intervals, with the
   // number of packets selected so that we fill (but don't overflow) the one
@@ -1296,9 +1298,9 @@
 
   void SetUp() override {
     payload_ = kAudioPayload;
-    rtp_sender_.reset(new RTPSender(true, &fake_clock_, &transport_, nullptr,
-                                    nullptr, nullptr, nullptr, nullptr, nullptr,
-                                    nullptr, nullptr, nullptr));
+    rtp_sender_.reset(new RTPSender(
+        true, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
+        nullptr, nullptr, nullptr, nullptr, &retransmission_rate_limiter_));
     rtp_sender_->SetSequenceNumber(kSeqNum);
   }
 };
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
index d4c1111..ab666ce 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
@@ -14,6 +14,7 @@
 #include <memory>
 #include <vector>
 
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/test/null_transport.h"
 
 namespace webrtc {
@@ -80,7 +81,8 @@
 
 class RtpRtcpAPITest : public ::testing::Test {
  protected:
-  RtpRtcpAPITest() : fake_clock_(123456) {
+  RtpRtcpAPITest()
+      : fake_clock_(123456), retransmission_rate_limiter_(&fake_clock_, 1000) {
     test_csrcs_.push_back(1234);
     test_csrcs_.push_back(2345);
     test_ssrc_ = 3456;
@@ -94,6 +96,7 @@
     configuration.audio = true;
     configuration.clock = &fake_clock_;
     configuration.outgoing_transport = &null_transport_;
+    configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
     module_.reset(RtpRtcp::CreateRtpRtcp(configuration));
     rtp_payload_registry_.reset(new RTPPayloadRegistry(
             RTPPayloadStrategy::CreateStrategy(true)));
@@ -110,6 +113,7 @@
   std::vector<uint32_t> test_csrcs_;
   SimulatedClock fake_clock_;
   test::NullTransport null_transport_;
+  RateLimiter retransmission_rate_limiter_;
 };
 
 TEST_F(RtpRtcpAPITest, Basic) {
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
index 0fb9845..f9e5001 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
@@ -15,6 +15,7 @@
 
 #include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
 
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/common_types.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -77,7 +78,8 @@
 
 class RtpRtcpAudioTest : public ::testing::Test {
  protected:
-  RtpRtcpAudioTest() : fake_clock(123456) {
+  RtpRtcpAudioTest()
+      : fake_clock(123456), retransmission_rate_limiter_(&fake_clock, 1000) {
     test_CSRC[0] = 1234;
     test_CSRC[2] = 2345;
     test_ssrc = 3456;
@@ -106,6 +108,7 @@
     configuration.clock = &fake_clock;
     configuration.receive_statistics = receive_statistics1_.get();
     configuration.outgoing_transport = transport1;
+    configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
 
     module1 = RtpRtcp::CreateRtpRtcp(configuration);
     rtp_receiver1_.reset(RtpReceiver::CreateAudioReceiver(
@@ -152,6 +155,7 @@
   uint16_t test_sequence_number;
   uint32_t test_CSRC[webrtc::kRtpCsrcSize];
   SimulatedClock fake_clock;
+  RateLimiter retransmission_rate_limiter_;
 };
 
 TEST_F(RtpRtcpAudioTest, Basic) {
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
index c1359df..f33507e 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
@@ -14,6 +14,7 @@
 
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/common_types.h"
 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
@@ -66,7 +67,8 @@
 
 class RtpRtcpRtcpTest : public ::testing::Test {
  protected:
-  RtpRtcpRtcpTest() : fake_clock(123456) {
+  RtpRtcpRtcpTest()
+      : fake_clock(123456), retransmission_rate_limiter_(&fake_clock, 1000) {
     test_csrcs.push_back(1234);
     test_csrcs.push_back(2345);
     test_ssrc = 3456;
@@ -91,6 +93,7 @@
     configuration.receive_statistics = receive_statistics1_.get();
     configuration.outgoing_transport = transport1;
     configuration.intra_frame_callback = myRTCPFeedback1;
+    configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
 
     rtp_payload_registry1_.reset(new RTPPayloadRegistry(
             RTPPayloadStrategy::CreateStrategy(true)));
@@ -197,6 +200,7 @@
   uint16_t test_sequence_number;
   std::vector<uint32_t> test_csrcs;
   SimulatedClock fake_clock;
+  RateLimiter retransmission_rate_limiter_;
 };
 
 TEST_F(RtpRtcpRtcpTest, RTCP_PLI_RPSI) {
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc
index d84ff37..e784386 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/common_types.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
@@ -38,7 +39,8 @@
         test_ssrc_(3456),
         test_timestamp_(4567),
         test_sequence_number_(2345),
-        fake_clock(123456) {}
+        fake_clock(123456),
+        retransmission_rate_limiter_(&fake_clock, 1000) {}
   ~RtpRtcpVideoTest() {}
 
   virtual void SetUp() {
@@ -49,6 +51,7 @@
     configuration.audio = false;
     configuration.clock = &fake_clock;
     configuration.outgoing_transport = transport_;
+    configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
 
     video_module_ = RtpRtcp::CreateRtpRtcp(configuration);
     rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
@@ -139,6 +142,7 @@
   uint8_t  video_frame_[65000];
   size_t payload_data_length_;
   SimulatedClock fake_clock;
+  RateLimiter retransmission_rate_limiter_;
 };
 
 TEST_F(RtpRtcpVideoTest, BasicVideo) {
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index 034d063..b2a29d2 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -19,12 +19,15 @@
 
 #include "webrtc/base/checks.h"
 #include "webrtc/base/event.h"
+#include "webrtc/base/optional.h"
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/call.h"
 #include "webrtc/call/transport_adapter.h"
 #include "webrtc/common_video/include/frame_callback.h"
 #include "webrtc/modules/include/module_common_types.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
@@ -487,6 +490,77 @@
   RunBaseTest(&test);
 }
 
+TEST_F(EndToEndTest, ReceivesNackAndRetransmitsAudio) {
+  class NackObserver : public test::EndToEndTest {
+   public:
+    NackObserver()
+        : EndToEndTest(kLongTimeoutMs),
+          local_ssrc_(0),
+          remote_ssrc_(0),
+          receive_transport_(nullptr) {}
+
+   private:
+    size_t GetNumVideoStreams() const override { return 0; }
+    size_t GetNumAudioStreams() const override { return 1; }
+
+    test::PacketTransport* CreateReceiveTransport() override {
+      test::PacketTransport* receive_transport = new test::PacketTransport(
+          nullptr, this, test::PacketTransport::kReceiver,
+          FakeNetworkPipe::Config());
+      receive_transport_ = receive_transport;
+      return receive_transport;
+    }
+
+    Action OnSendRtp(const uint8_t* packet, size_t length) override {
+      RTPHeader header;
+      EXPECT_TRUE(parser_->Parse(packet, length, &header));
+
+      if (!sequence_number_to_retransmit_) {
+        sequence_number_to_retransmit_ =
+            rtc::Optional<uint16_t>(header.sequenceNumber);
+
+        // Don't ask for retransmission straight away, may be deduped in pacer.
+      } else if (header.sequenceNumber == *sequence_number_to_retransmit_) {
+        observation_complete_.Set();
+      } else {
+        // Send a NACK as often as necessary until retransmission is received.
+        rtcp::Nack nack;
+        nack.From(local_ssrc_);
+        nack.To(remote_ssrc_);
+        uint16_t nack_list[] = {*sequence_number_to_retransmit_};
+        nack.WithList(nack_list, 1);
+        rtc::Buffer buffer = nack.Build();
+
+        EXPECT_TRUE(receive_transport_->SendRtcp(buffer.data(), buffer.size()));
+      }
+
+      return SEND_PACKET;
+    }
+
+    void ModifyAudioConfigs(
+        AudioSendStream::Config* send_config,
+        std::vector<AudioReceiveStream::Config>* receive_configs) override {
+      send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
+      (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
+      local_ssrc_ = (*receive_configs)[0].rtp.local_ssrc;
+      remote_ssrc_ = (*receive_configs)[0].rtp.remote_ssrc;
+    }
+
+    void PerformTest() override {
+      EXPECT_TRUE(Wait())
+          << "Timed out waiting for packets to be NACKed, retransmitted and "
+             "rendered.";
+    }
+
+    uint32_t local_ssrc_;
+    uint32_t remote_ssrc_;
+    Transport* receive_transport_;
+    rtc::Optional<uint16_t> sequence_number_to_retransmit_;
+  } test;
+
+  RunBaseTest(&test);
+}
+
 TEST_F(EndToEndTest, CanReceiveFec) {
   class FecRenderObserver : public test::EndToEndTest,
                             public rtc::VideoSinkInterface<VideoFrame> {
@@ -1807,7 +1881,8 @@
           poller_thread_(&BitrateStatsPollingThread,
                          this,
                          "BitrateStatsPollingThread"),
-          state_(kWaitForFirstRampUp) {}
+          state_(kWaitForFirstRampUp),
+          retransmission_rate_limiter_(clock_, 1000) {}
 
     ~BweObserver() {}
 
@@ -1847,6 +1922,7 @@
       config.receiver_only = true;
       config.clock = clock_;
       config.outgoing_transport = receive_transport_;
+      config.retransmission_rate_limiter = &retransmission_rate_limiter_;
       rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
       rtp_rtcp_->SetRemoteSSRC((*receive_configs)[0].rtp.remote_ssrc);
       rtp_rtcp_->SetSSRC((*receive_configs)[0].rtp.local_ssrc);
@@ -1919,6 +1995,7 @@
     rtc::Event event_;
     rtc::PlatformThread poller_thread_;
     TestState state_;
+    RateLimiter retransmission_rate_limiter_;
   } test;
 
   RunBaseTest(&test);
diff --git a/webrtc/video/rtp_stream_receiver.cc b/webrtc/video/rtp_stream_receiver.cc
index 4caf55a..e7367d8 100644
--- a/webrtc/video/rtp_stream_receiver.cc
+++ b/webrtc/video/rtp_stream_receiver.cc
@@ -39,7 +39,8 @@
     RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
     RemoteBitrateEstimator* remote_bitrate_estimator,
     RtpPacketSender* paced_sender,
-    TransportSequenceNumberAllocator* transport_sequence_number_allocator) {
+    TransportSequenceNumberAllocator* transport_sequence_number_allocator,
+    RateLimiter* retransmission_rate_limiter) {
   RtpRtcp::Configuration configuration;
   configuration.audio = false;
   configuration.receiver_only = true;
@@ -58,7 +59,7 @@
   configuration.send_packet_observer = nullptr;
   configuration.bandwidth_callback = nullptr;
   configuration.transport_feedback_callback = nullptr;
-  configuration.retransmission_rate_limiter = nullptr;
+  configuration.retransmission_rate_limiter = retransmission_rate_limiter;
 
   std::unique_ptr<RtpRtcp> rtp_rtcp(RtpRtcp::CreateRtpRtcp(configuration));
   rtp_rtcp->SetSendingStatus(false);
@@ -80,7 +81,8 @@
     VieRemb* remb,
     const VideoReceiveStream::Config* config,
     ReceiveStatisticsProxy* receive_stats_proxy,
-    ProcessThread* process_thread)
+    ProcessThread* process_thread,
+    RateLimiter* retransmission_rate_limiter)
     : clock_(Clock::GetRealTimeClock()),
       config_(*config),
       video_receiver_(video_receiver),
@@ -106,7 +108,8 @@
                                     receive_stats_proxy,
                                     remote_bitrate_estimator_,
                                     paced_sender,
-                                    packet_router)) {
+                                    packet_router,
+                                    retransmission_rate_limiter)) {
   packet_router_->AddRtpModule(rtp_rtcp_.get());
   rtp_receive_statistics_->RegisterRtpStatisticsCallback(receive_stats_proxy);
   rtp_receive_statistics_->RegisterRtcpStatisticsCallback(receive_stats_proxy);
diff --git a/webrtc/video/rtp_stream_receiver.h b/webrtc/video/rtp_stream_receiver.h
index efe7181..2af15b0 100644
--- a/webrtc/video/rtp_stream_receiver.h
+++ b/webrtc/video/rtp_stream_receiver.h
@@ -62,7 +62,8 @@
                     VieRemb* remb,
                     const VideoReceiveStream::Config* config,
                     ReceiveStatisticsProxy* receive_stats_proxy,
-                    ProcessThread* process_thread);
+                    ProcessThread* process_thread,
+                    RateLimiter* retransmission_rate_limiter);
   ~RtpStreamReceiver();
 
   bool SetReceiveCodec(const VideoCodec& video_codec);
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc
index 609a789..bc51269 100644
--- a/webrtc/video/video_receive_stream.cc
+++ b/webrtc/video/video_receive_stream.cc
@@ -14,6 +14,7 @@
 
 #include <set>
 #include <string>
+#include <utility>
 
 #include "webrtc/base/checks.h"
 #include "webrtc/base/logging.h"
@@ -162,17 +163,19 @@
       call_stats_(call_stats),
       video_receiver_(clock_, nullptr, this, this, this),
       stats_proxy_(&config_, clock_),
-      rtp_stream_receiver_(&video_receiver_,
-                           congestion_controller_->GetRemoteBitrateEstimator(
-                               UseSendSideBwe(config_)),
-                           &transport_adapter_,
-                           call_stats_->rtcp_rtt_stats(),
-                           congestion_controller_->pacer(),
-                           congestion_controller_->packet_router(),
-                           remb,
-                           &config_,
-                           &stats_proxy_,
-                           process_thread_),
+      rtp_stream_receiver_(
+          &video_receiver_,
+          congestion_controller_->GetRemoteBitrateEstimator(
+              UseSendSideBwe(config_)),
+          &transport_adapter_,
+          call_stats_->rtcp_rtt_stats(),
+          congestion_controller_->pacer(),
+          congestion_controller_->packet_router(),
+          remb,
+          &config_,
+          &stats_proxy_,
+          process_thread_,
+          congestion_controller_->GetRetransmissionRateLimiter()),
       vie_sync_(&video_receiver_) {
   LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString();
 
diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc
index 3a8acbc..623cd34 100644
--- a/webrtc/video/video_send_stream_tests.cc
+++ b/webrtc/video/video_send_stream_tests.cc
@@ -19,6 +19,7 @@
 #include "webrtc/base/event.h"
 #include "webrtc/base/logging.h"
 #include "webrtc/base/platform_thread.h"
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/call.h"
 #include "webrtc/call/transport_adapter.h"
 #include "webrtc/common_video/include/frame_callback.h"
@@ -819,13 +820,13 @@
     RembObserver()
         : SendTest(kDefaultTimeoutMs),
           clock_(Clock::GetRealTimeClock()),
+          stream_(nullptr),
           test_state_(kBeforeSuspend),
           rtp_count_(0),
           last_sequence_number_(0),
           suspended_frame_count_(0),
           low_remb_bps_(0),
-          high_remb_bps_(0) {
-    }
+          high_remb_bps_(0) {}
 
    private:
     Action OnSendRtp(const uint8_t* packet, size_t length) override {
@@ -1049,8 +1050,9 @@
    public:
     BitrateObserver()
         : SendTest(kDefaultTimeoutMs),
-          bitrate_capped_(false) {
-    }
+          retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
+          stream_(nullptr),
+          bitrate_capped_(false) {}
 
    private:
     Action OnSendRtp(const uint8_t* packet, size_t length) override {
@@ -1092,6 +1094,7 @@
       stream_ = send_stream;
       RtpRtcp::Configuration config;
       config.outgoing_transport = feedback_transport_.get();
+      config.retransmission_rate_limiter = &retranmission_rate_limiter_;
       rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
       rtp_rtcp_->SetREMBStatus(true);
       rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
@@ -1114,6 +1117,7 @@
 
     std::unique_ptr<RtpRtcp> rtp_rtcp_;
     std::unique_ptr<internal::TransportAdapter> feedback_transport_;
+    RateLimiter retranmission_rate_limiter_;
     VideoSendStream* stream_;
     bool bitrate_capped_;
   } test;
@@ -1504,6 +1508,7 @@
    public:
     EncoderStateObserver()
         : SendTest(kDefaultTimeoutMs),
+          stream_(nullptr),
           initialized_(false),
           callback_registered_(false),
           num_releases_(0),
@@ -1624,7 +1629,8 @@
         : SendTest(kDefaultTimeoutMs),
           FakeEncoder(Clock::GetRealTimeClock()),
           init_encode_event_(false, false),
-          num_initializations_(0) {}
+          num_initializations_(0),
+          stream_(nullptr) {}
 
    private:
     void ModifyVideoConfigs(
@@ -1689,7 +1695,8 @@
         video_codec_type_(video_codec_type),
         codec_name_(codec_name),
         init_encode_event_(false, false),
-        num_initializations_(0) {
+        num_initializations_(0),
+        stream_(nullptr) {
     memset(&encoder_settings_, 0, sizeof(encoder_settings_));
   }
 
@@ -1931,7 +1938,9 @@
         : SendTest(kDefaultTimeoutMs),
           FakeEncoder(Clock::GetRealTimeClock()),
           init_encode_event_(false, false),
-          num_initializations_(0) {}
+          num_initializations_(0),
+          call_(nullptr),
+          send_stream_(nullptr) {}
 
    private:
     int32_t InitEncode(const VideoCodec* codecSettings,
@@ -2045,7 +2054,8 @@
    public:
     ScreencastTargetBitrateTest()
         : SendTest(kDefaultTimeoutMs),
-          test::FakeEncoder(Clock::GetRealTimeClock()) {}
+          test::FakeEncoder(Clock::GetRealTimeClock()),
+          send_stream_(nullptr) {}
 
    private:
     int32_t Encode(const VideoFrame& input_image,
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index dcedd75..f5be7ef 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -17,6 +17,7 @@
 #include "webrtc/base/criticalsection.h"
 #include "webrtc/base/format_macros.h"
 #include "webrtc/base/logging.h"
+#include "webrtc/base/rate_limiter.h"
 #include "webrtc/base/thread_checker.h"
 #include "webrtc/base/timeutils.h"
 #include "webrtc/call/rtc_event_log.h"
@@ -47,6 +48,9 @@
 
 namespace {
 
+constexpr int64_t kMaxRetransmissionWindowMs = 1000;
+constexpr int64_t kMinRetransmissionWindowMs = 30;
+
 bool RegisterReceiveCodec(std::unique_ptr<AudioCodingModule>* acm,
                           acm2::RentACodec* rac,
                           const CodecInst& ci) {
@@ -902,6 +906,8 @@
       feedback_observer_proxy_(new TransportFeedbackProxy()),
       seq_num_allocator_proxy_(new TransportSequenceNumberProxy()),
       rtp_packet_sender_proxy_(new RtpPacketSenderProxy()),
+      retransmission_rate_limiter_(new RateLimiter(Clock::GetRealTimeClock(),
+                                                   kMaxRetransmissionWindowMs)),
       decoder_factory_(decoder_factory) {
   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, _channelId),
                "Channel::Channel() - ctor");
@@ -933,6 +939,8 @@
     configuration.transport_feedback_callback = feedback_observer_proxy_.get();
   }
   configuration.event_log = &(*event_log_proxy_);
+  configuration.retransmission_rate_limiter =
+      retransmission_rate_limiter_.get();
 
   _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration));
   _rtpRtcpModule->SetSendingMediaStatus(false);
@@ -1352,6 +1360,7 @@
   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
                "Channel::SetBitRate(bitrate_bps=%d)", bitrate_bps);
   audio_coding_->SetBitRate(bitrate_bps);
+  retransmission_rate_limiter_->SetMaxRate(bitrate_bps);
 }
 
 void Channel::OnIncomingFractionLoss(int fraction_lost) {
@@ -1710,6 +1719,15 @@
     // Waiting for valid RTT.
     return 0;
   }
+
+  int64_t nack_window_ms = rtt;
+  if (nack_window_ms < kMinRetransmissionWindowMs) {
+    nack_window_ms = kMinRetransmissionWindowMs;
+  } else if (nack_window_ms > kMaxRetransmissionWindowMs) {
+    nack_window_ms = kMaxRetransmissionWindowMs;
+  }
+  retransmission_rate_limiter_->SetWindowSize(nack_window_ms);
+
   uint32_t ntp_secs = 0;
   uint32_t ntp_frac = 0;
   uint32_t rtp_timestamp = 0;
diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h
index b51b7ec..34e5c5a 100644
--- a/webrtc/voice_engine/channel.h
+++ b/webrtc/voice_engine/channel.h
@@ -36,7 +36,6 @@
 #include "webrtc/voice_engine/voice_engine_defines.h"
 
 namespace rtc {
-
 class TimestampWrapAroundHandler;
 }
 
@@ -47,6 +46,7 @@
 class FileWrapper;
 class PacketRouter;
 class ProcessThread;
+class RateLimiter;
 class ReceiveStatistics;
 class RemoteNtpTimeEstimator;
 class RtcEventLog;
@@ -589,6 +589,7 @@
   std::unique_ptr<TransportFeedbackProxy> feedback_observer_proxy_;
   std::unique_ptr<TransportSequenceNumberProxy> seq_num_allocator_proxy_;
   std::unique_ptr<RtpPacketSenderProxy> rtp_packet_sender_proxy_;
+  std::unique_ptr<RateLimiter> retransmission_rate_limiter_;
 
   // TODO(ossu): Remove once GetAudioDecoderFactory() is no longer needed.
   rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;