diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn
index c9a3161..eda27ba 100644
--- a/modules/rtp_rtcp/BUILD.gn
+++ b/modules/rtp_rtcp/BUILD.gn
@@ -186,6 +186,8 @@
     "source/rtp_rtcp_config.h",
     "source/rtp_rtcp_impl.cc",
     "source/rtp_rtcp_impl.h",
+    "source/rtp_rtcp_impl2.cc",
+    "source/rtp_rtcp_impl2.h",
     "source/rtp_sender.cc",
     "source/rtp_sender.h",
     "source/rtp_sender_audio.cc",
@@ -478,6 +480,7 @@
       "source/rtp_packet_history_unittest.cc",
       "source/rtp_packet_unittest.cc",
       "source/rtp_packetizer_av1_unittest.cc",
+      "source/rtp_rtcp_impl2_unittest.cc",
       "source/rtp_rtcp_impl_unittest.cc",
       "source/rtp_sender_audio_unittest.cc",
       "source/rtp_sender_unittest.cc",
diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h
index f91f0d1..2db523c 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -53,8 +53,8 @@
 class RtpRtcp : public Module, public RtcpFeedbackSenderInterface {
  public:
   struct Configuration {
-    Configuration();
-    Configuration(Configuration&& rhs);
+    Configuration() = default;
+    Configuration(Configuration&& rhs) = default;
 
     // True for a audio version of the RTP/RTCP module object false will create
     // a video version.
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 269a735..c12fb68 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -33,7 +33,7 @@
 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
-#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
+#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
 #include "modules/rtp_rtcp/source/time_util.h"
 #include "modules/rtp_rtcp/source/tmmbr_help.h"
 #include "rtc_base/checks.h"
@@ -123,7 +123,7 @@
       last_rr_ntp_secs(0),
       last_rr_ntp_frac(0),
       remote_sr(0),
-      module(nullptr) {}
+      receiver(nullptr) {}
 
 RTCPSender::FeedbackState::FeedbackState(const FeedbackState&) = default;
 
@@ -544,7 +544,7 @@
 
 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBR(
     const RtcpContext& ctx) {
-  if (ctx.feedback_state_.module == nullptr)
+  if (ctx.feedback_state_.receiver == nullptr)
     return nullptr;
   // Before sending the TMMBR check the received TMMBN, only an owner is
   // allowed to raise the bitrate:
@@ -558,7 +558,7 @@
   // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but
   // since RTCPreceiver is not doing the reverse we should be fine
   std::vector<rtcp::TmmbItem> candidates =
-      ctx.feedback_state_.module->BoundingSet(&tmmbr_owner);
+      ctx.feedback_state_.receiver->BoundingSet(&tmmbr_owner);
 
   if (!candidates.empty()) {
     for (const auto& candidate : candidates) {
diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h
index 7da2546..61081d4 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/modules/rtp_rtcp/source/rtcp_sender.h
@@ -38,10 +38,10 @@
 
 namespace webrtc {
 
-class ModuleRtpRtcpImpl;
+class RTCPReceiver;
 class RtcEventLog;
 
-class RTCPSender {
+class RTCPSender final {
  public:
   struct FeedbackState {
     FeedbackState();
@@ -61,7 +61,7 @@
     std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis;
 
     // Used when generating TMMBR.
-    ModuleRtpRtcpImpl* module;
+    RTCPReceiver* receiver;
   };
 
   explicit RTCPSender(const RtpRtcp::Configuration& config);
diff --git a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index 754ad89..d187b16 100644
--- a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -18,7 +18,7 @@
 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
-#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
+#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
 #include "modules/rtp_rtcp/source/time_util.h"
 #include "rtc_base/rate_limiter.h"
 #include "test/gmock.h"
@@ -77,7 +77,7 @@
         receive_statistics_(ReceiveStatistics::Create(&clock_)),
         retransmission_rate_limiter_(&clock_, 1000) {
     RtpRtcp::Configuration configuration = GetDefaultConfig();
-    rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
+    rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl2(configuration));
     rtcp_sender_.reset(new RTCPSender(configuration));
     rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
     rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
@@ -115,7 +115,7 @@
   SimulatedClock clock_;
   TestTransport test_transport_;
   std::unique_ptr<ReceiveStatistics> receive_statistics_;
-  std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
+  std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_impl_;
   std::unique_ptr<RTCPSender> rtcp_sender_;
   RateLimiter retransmission_rate_limiter_;
 };
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 07a0485..0bd37eb 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -48,14 +48,6 @@
           &packet_history,
           config.paced_sender ? config.paced_sender : &non_paced_sender) {}
 
-RtpRtcp::Configuration::Configuration() = default;
-RtpRtcp::Configuration::Configuration(Configuration&& rhs) = default;
-
-std::unique_ptr<RtpRtcp> RtpRtcp::Create(const Configuration& configuration) {
-  RTC_DCHECK(configuration.clock);
-  return std::make_unique<ModuleRtpRtcpImpl>(configuration);
-}
-
 ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
     : rtcp_sender_(configuration),
       rtcp_receiver_(configuration, this),
@@ -312,7 +304,7 @@
     state.send_bitrate =
         rtp_sender_->packet_sender.GetSendRates().Sum().bps<uint32_t>();
   }
-  state.module = this;
+  state.receiver = &rtcp_receiver_;
 
   LastReceivedNTP(&state.last_rr_ntp_secs, &state.last_rr_ntp_frac,
                   &state.remote_sr);
@@ -793,11 +785,6 @@
   return true;
 }
 
-// Called from RTCPsender.
-std::vector<rtcp::TmmbItem> ModuleRtpRtcpImpl::BoundingSet(bool* tmmbr_owner) {
-  return rtcp_receiver_.BoundingSet(tmmbr_owner);
-}
-
 void ModuleRtpRtcpImpl::set_rtt_ms(int64_t rtt_ms) {
   {
     rtc::CritScope cs(&critical_section_rtt_);
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index debb433..2d07060 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -42,6 +42,7 @@
 struct PacedPacketInfo;
 struct RTPVideoHeader;
 
+// DEPRECATED.
 class ModuleRtpRtcpImpl : public RtpRtcp, public RTCPReceiver::ModuleRtpRtcp {
  public:
   explicit ModuleRtpRtcpImpl(const RtpRtcp::Configuration& configuration);
@@ -257,8 +258,6 @@
                        uint32_t* NTPfrac,
                        uint32_t* remote_sr) const;
 
-  std::vector<rtcp::TmmbItem> BoundingSet(bool* tmmbr_owner);
-
   void BitrateSent(uint32_t* total_rate,
                    uint32_t* video_rate,
                    uint32_t* fec_rate,
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc
new file mode 100644
index 0000000..c8f10ac
--- /dev/null
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc
@@ -0,0 +1,837 @@
+/*
+ *  Copyright (c) 2012 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 "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "api/transport/field_trial_based_config.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
+#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+
+#ifdef _WIN32
+// Disable warning C4355: 'this' : used in base member initializer list.
+#pragma warning(disable : 4355)
+#endif
+
+namespace webrtc {
+namespace {
+const int64_t kRtpRtcpMaxIdleTimeProcessMs = 5;
+const int64_t kRtpRtcpRttProcessTimeMs = 1000;
+const int64_t kRtpRtcpBitrateProcessTimeMs = 10;
+const int64_t kDefaultExpectedRetransmissionTimeMs = 125;
+}  // namespace
+
+ModuleRtpRtcpImpl2::RtpSenderContext::RtpSenderContext(
+    const RtpRtcp::Configuration& config)
+    : packet_history(config.clock, config.enable_rtx_padding_prioritization),
+      packet_sender(config, &packet_history),
+      non_paced_sender(&packet_sender),
+      packet_generator(
+          config,
+          &packet_history,
+          config.paced_sender ? config.paced_sender : &non_paced_sender) {}
+
+std::unique_ptr<RtpRtcp> RtpRtcp::Create(const Configuration& configuration) {
+  RTC_DCHECK(configuration.clock);
+  return std::make_unique<ModuleRtpRtcpImpl2>(configuration);
+}
+
+ModuleRtpRtcpImpl2::ModuleRtpRtcpImpl2(const Configuration& configuration)
+    : rtcp_sender_(configuration),
+      rtcp_receiver_(configuration, this),
+      clock_(configuration.clock),
+      last_bitrate_process_time_(clock_->TimeInMilliseconds()),
+      last_rtt_process_time_(clock_->TimeInMilliseconds()),
+      next_process_time_(clock_->TimeInMilliseconds() +
+                         kRtpRtcpMaxIdleTimeProcessMs),
+      packet_overhead_(28),  // IPV4 UDP.
+      nack_last_time_sent_full_ms_(0),
+      nack_last_seq_number_sent_(0),
+      remote_bitrate_(configuration.remote_bitrate_estimator),
+      rtt_stats_(configuration.rtt_stats),
+      rtt_ms_(0) {
+  process_thread_checker_.Detach();
+  if (!configuration.receiver_only) {
+    rtp_sender_ = std::make_unique<RtpSenderContext>(configuration);
+    // Make sure rtcp sender use same timestamp offset as rtp sender.
+    rtcp_sender_.SetTimestampOffset(
+        rtp_sender_->packet_generator.TimestampOffset());
+  }
+
+  // Set default packet size limit.
+  // TODO(nisse): Kind-of duplicates
+  // webrtc::VideoSendStream::Config::Rtp::kDefaultMaxPacketSize.
+  const size_t kTcpOverIpv4HeaderSize = 40;
+  SetMaxRtpPacketSize(IP_PACKET_SIZE - kTcpOverIpv4HeaderSize);
+}
+
+ModuleRtpRtcpImpl2::~ModuleRtpRtcpImpl2() {
+  RTC_DCHECK_RUN_ON(&construction_thread_checker_);
+}
+
+// Returns the number of milliseconds until the module want a worker thread
+// to call Process.
+int64_t ModuleRtpRtcpImpl2::TimeUntilNextProcess() {
+  RTC_DCHECK_RUN_ON(&process_thread_checker_);
+  return std::max<int64_t>(0,
+                           next_process_time_ - clock_->TimeInMilliseconds());
+}
+
+// Process any pending tasks such as timeouts (non time critical events).
+void ModuleRtpRtcpImpl2::Process() {
+  RTC_DCHECK_RUN_ON(&process_thread_checker_);
+  const int64_t now = clock_->TimeInMilliseconds();
+  // TODO(bugs.webrtc.org/11581): Figure out why we need to call Process() 200
+  // times a second.
+  next_process_time_ = now + kRtpRtcpMaxIdleTimeProcessMs;
+
+  if (rtp_sender_) {
+    if (now >= last_bitrate_process_time_ + kRtpRtcpBitrateProcessTimeMs) {
+      rtp_sender_->packet_sender.ProcessBitrateAndNotifyObservers();
+      last_bitrate_process_time_ = now;
+      // TODO(bugs.webrtc.org/11581): Is this a bug? At the top of the function,
+      // next_process_time_ is incremented by 5ms, here we effectively do a
+      // std::min() of (now + 5ms, now + 10ms). Seems like this is a no-op?
+      next_process_time_ =
+          std::min(next_process_time_, now + kRtpRtcpBitrateProcessTimeMs);
+    }
+  }
+
+  // TODO(bugs.webrtc.org/11581): We update the RTT once a second, whereas other
+  // things that run in this method are updated much more frequently. Move the
+  // RTT checking over to the worker thread, which matches better with where the
+  // stats are maintained.
+  bool process_rtt = now >= last_rtt_process_time_ + kRtpRtcpRttProcessTimeMs;
+  if (rtcp_sender_.Sending()) {
+    // Process RTT if we have received a report block and we haven't
+    // processed RTT for at least |kRtpRtcpRttProcessTimeMs| milliseconds.
+    // Note that LastReceivedReportBlockMs() grabs a lock, so check
+    // |process_rtt| first.
+    if (process_rtt &&
+        rtcp_receiver_.LastReceivedReportBlockMs() > last_rtt_process_time_) {
+      std::vector<RTCPReportBlock> receive_blocks;
+      rtcp_receiver_.StatisticsReceived(&receive_blocks);
+      int64_t max_rtt = 0;
+      for (std::vector<RTCPReportBlock>::iterator it = receive_blocks.begin();
+           it != receive_blocks.end(); ++it) {
+        int64_t rtt = 0;
+        rtcp_receiver_.RTT(it->sender_ssrc, &rtt, NULL, NULL, NULL);
+        max_rtt = (rtt > max_rtt) ? rtt : max_rtt;
+      }
+      // Report the rtt.
+      if (rtt_stats_ && max_rtt != 0)
+        rtt_stats_->OnRttUpdate(max_rtt);
+    }
+
+    // Verify receiver reports are delivered and the reported sequence number
+    // is increasing.
+    // TODO(bugs.webrtc.org/11581): The timeout value needs to be checked every
+    // few seconds (see internals of RtcpRrTimeout). Here, we may be polling it
+    // a couple of hundred times a second, which isn't great since it grabs a
+    // lock. Note also that LastReceivedReportBlockMs() (called above) and
+    // RtcpRrTimeout() both grab the same lock and check the same timer, so
+    // it should be possible to consolidate that work somehow.
+    if (rtcp_receiver_.RtcpRrTimeout()) {
+      RTC_LOG_F(LS_WARNING) << "Timeout: No RTCP RR received.";
+    } else if (rtcp_receiver_.RtcpRrSequenceNumberTimeout()) {
+      RTC_LOG_F(LS_WARNING) << "Timeout: No increase in RTCP RR extended "
+                               "highest sequence number.";
+    }
+
+    if (remote_bitrate_ && rtcp_sender_.TMMBR()) {
+      unsigned int target_bitrate = 0;
+      std::vector<unsigned int> ssrcs;
+      if (remote_bitrate_->LatestEstimate(&ssrcs, &target_bitrate)) {
+        if (!ssrcs.empty()) {
+          target_bitrate = target_bitrate / ssrcs.size();
+        }
+        rtcp_sender_.SetTargetBitrate(target_bitrate);
+      }
+    }
+  } else {
+    // Report rtt from receiver.
+    if (process_rtt) {
+      int64_t rtt_ms;
+      if (rtt_stats_ && rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms)) {
+        rtt_stats_->OnRttUpdate(rtt_ms);
+      }
+    }
+  }
+
+  // Get processed rtt.
+  if (process_rtt) {
+    last_rtt_process_time_ = now;
+    // TODO(bugs.webrtc.org/11581): Is this a bug? At the top of the function,
+    // next_process_time_ is incremented by 5ms, here we effectively do a
+    // std::min() of (now + 5ms, now + 1000ms). Seems like this is a no-op?
+    next_process_time_ = std::min(
+        next_process_time_, last_rtt_process_time_ + kRtpRtcpRttProcessTimeMs);
+    if (rtt_stats_) {
+      // Make sure we have a valid RTT before setting.
+      int64_t last_rtt = rtt_stats_->LastProcessedRtt();
+      if (last_rtt >= 0)
+        set_rtt_ms(last_rtt);
+    }
+  }
+
+  if (rtcp_sender_.TimeToSendRTCPReport())
+    rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
+
+  if (TMMBR() && rtcp_receiver_.UpdateTmmbrTimers()) {
+    rtcp_receiver_.NotifyTmmbrUpdated();
+  }
+}
+
+void ModuleRtpRtcpImpl2::SetRtxSendStatus(int mode) {
+  rtp_sender_->packet_generator.SetRtxStatus(mode);
+}
+
+int ModuleRtpRtcpImpl2::RtxSendStatus() const {
+  return rtp_sender_ ? rtp_sender_->packet_generator.RtxStatus() : kRtxOff;
+}
+
+void ModuleRtpRtcpImpl2::SetRtxSendPayloadType(int payload_type,
+                                               int associated_payload_type) {
+  rtp_sender_->packet_generator.SetRtxPayloadType(payload_type,
+                                                  associated_payload_type);
+}
+
+absl::optional<uint32_t> ModuleRtpRtcpImpl2::RtxSsrc() const {
+  return rtp_sender_ ? rtp_sender_->packet_generator.RtxSsrc() : absl::nullopt;
+}
+
+absl::optional<uint32_t> ModuleRtpRtcpImpl2::FlexfecSsrc() const {
+  if (rtp_sender_) {
+    return rtp_sender_->packet_generator.FlexfecSsrc();
+  }
+  return absl::nullopt;
+}
+
+void ModuleRtpRtcpImpl2::IncomingRtcpPacket(const uint8_t* rtcp_packet,
+                                            const size_t length) {
+  rtcp_receiver_.IncomingPacket(rtcp_packet, length);
+}
+
+void ModuleRtpRtcpImpl2::RegisterSendPayloadFrequency(int payload_type,
+                                                      int payload_frequency) {
+  rtcp_sender_.SetRtpClockRate(payload_type, payload_frequency);
+}
+
+int32_t ModuleRtpRtcpImpl2::DeRegisterSendPayload(const int8_t payload_type) {
+  return 0;
+}
+
+uint32_t ModuleRtpRtcpImpl2::StartTimestamp() const {
+  return rtp_sender_->packet_generator.TimestampOffset();
+}
+
+// Configure start timestamp, default is a random number.
+void ModuleRtpRtcpImpl2::SetStartTimestamp(const uint32_t timestamp) {
+  rtcp_sender_.SetTimestampOffset(timestamp);
+  rtp_sender_->packet_generator.SetTimestampOffset(timestamp);
+  rtp_sender_->packet_sender.SetTimestampOffset(timestamp);
+}
+
+uint16_t ModuleRtpRtcpImpl2::SequenceNumber() const {
+  return rtp_sender_->packet_generator.SequenceNumber();
+}
+
+// Set SequenceNumber, default is a random number.
+void ModuleRtpRtcpImpl2::SetSequenceNumber(const uint16_t seq_num) {
+  rtp_sender_->packet_generator.SetSequenceNumber(seq_num);
+}
+
+void ModuleRtpRtcpImpl2::SetRtpState(const RtpState& rtp_state) {
+  rtp_sender_->packet_generator.SetRtpState(rtp_state);
+  rtp_sender_->packet_sender.SetMediaHasBeenSent(rtp_state.media_has_been_sent);
+  rtcp_sender_.SetTimestampOffset(rtp_state.start_timestamp);
+}
+
+void ModuleRtpRtcpImpl2::SetRtxState(const RtpState& rtp_state) {
+  rtp_sender_->packet_generator.SetRtxRtpState(rtp_state);
+}
+
+RtpState ModuleRtpRtcpImpl2::GetRtpState() const {
+  RtpState state = rtp_sender_->packet_generator.GetRtpState();
+  state.media_has_been_sent = rtp_sender_->packet_sender.MediaHasBeenSent();
+  return state;
+}
+
+RtpState ModuleRtpRtcpImpl2::GetRtxState() const {
+  return rtp_sender_->packet_generator.GetRtxRtpState();
+}
+
+void ModuleRtpRtcpImpl2::SetRid(const std::string& rid) {
+  if (rtp_sender_) {
+    rtp_sender_->packet_generator.SetRid(rid);
+  }
+}
+
+void ModuleRtpRtcpImpl2::SetMid(const std::string& mid) {
+  if (rtp_sender_) {
+    rtp_sender_->packet_generator.SetMid(mid);
+  }
+  // TODO(bugs.webrtc.org/4050): If we end up supporting the MID SDES item for
+  // RTCP, this will need to be passed down to the RTCPSender also.
+}
+
+void ModuleRtpRtcpImpl2::SetCsrcs(const std::vector<uint32_t>& csrcs) {
+  rtcp_sender_.SetCsrcs(csrcs);
+  rtp_sender_->packet_generator.SetCsrcs(csrcs);
+}
+
+// TODO(pbos): Handle media and RTX streams separately (separate RTCP
+// feedbacks).
+RTCPSender::FeedbackState ModuleRtpRtcpImpl2::GetFeedbackState() {
+  RTCPSender::FeedbackState state;
+  // This is called also when receiver_only is true. Hence below
+  // checks that rtp_sender_ exists.
+  if (rtp_sender_) {
+    StreamDataCounters rtp_stats;
+    StreamDataCounters rtx_stats;
+    rtp_sender_->packet_sender.GetDataCounters(&rtp_stats, &rtx_stats);
+    state.packets_sent =
+        rtp_stats.transmitted.packets + rtx_stats.transmitted.packets;
+    state.media_bytes_sent = rtp_stats.transmitted.payload_bytes +
+                             rtx_stats.transmitted.payload_bytes;
+    state.send_bitrate =
+        rtp_sender_->packet_sender.GetSendRates().Sum().bps<uint32_t>();
+  }
+  state.receiver = &rtcp_receiver_;
+
+  LastReceivedNTP(&state.last_rr_ntp_secs, &state.last_rr_ntp_frac,
+                  &state.remote_sr);
+
+  state.last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
+
+  return state;
+}
+
+// TODO(nisse): This method shouldn't be called for a receive-only
+// stream. Delete rtp_sender_ check as soon as all applications are
+// updated.
+int32_t ModuleRtpRtcpImpl2::SetSendingStatus(const bool sending) {
+  if (rtcp_sender_.Sending() != sending) {
+    // Sends RTCP BYE when going from true to false
+    if (rtcp_sender_.SetSendingStatus(GetFeedbackState(), sending) != 0) {
+      RTC_LOG(LS_WARNING) << "Failed to send RTCP BYE";
+    }
+  }
+  return 0;
+}
+
+bool ModuleRtpRtcpImpl2::Sending() const {
+  return rtcp_sender_.Sending();
+}
+
+// TODO(nisse): This method shouldn't be called for a receive-only
+// stream. Delete rtp_sender_ check as soon as all applications are
+// updated.
+void ModuleRtpRtcpImpl2::SetSendingMediaStatus(const bool sending) {
+  if (rtp_sender_) {
+    rtp_sender_->packet_generator.SetSendingMediaStatus(sending);
+  } else {
+    RTC_DCHECK(!sending);
+  }
+}
+
+bool ModuleRtpRtcpImpl2::SendingMedia() const {
+  return rtp_sender_ ? rtp_sender_->packet_generator.SendingMedia() : false;
+}
+
+bool ModuleRtpRtcpImpl2::IsAudioConfigured() const {
+  return rtp_sender_ ? rtp_sender_->packet_generator.IsAudioConfigured()
+                     : false;
+}
+
+void ModuleRtpRtcpImpl2::SetAsPartOfAllocation(bool part_of_allocation) {
+  RTC_CHECK(rtp_sender_);
+  rtp_sender_->packet_sender.ForceIncludeSendPacketsInAllocation(
+      part_of_allocation);
+}
+
+bool ModuleRtpRtcpImpl2::OnSendingRtpFrame(uint32_t timestamp,
+                                           int64_t capture_time_ms,
+                                           int payload_type,
+                                           bool force_sender_report) {
+  if (!Sending())
+    return false;
+
+  rtcp_sender_.SetLastRtpTime(timestamp, capture_time_ms, payload_type);
+  // Make sure an RTCP report isn't queued behind a key frame.
+  if (rtcp_sender_.TimeToSendRTCPReport(force_sender_report))
+    rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
+
+  return true;
+}
+
+bool ModuleRtpRtcpImpl2::TrySendPacket(RtpPacketToSend* packet,
+                                       const PacedPacketInfo& pacing_info) {
+  RTC_DCHECK(rtp_sender_);
+  // TODO(sprang): Consider if we can remove this check.
+  if (!rtp_sender_->packet_generator.SendingMedia()) {
+    return false;
+  }
+  rtp_sender_->packet_sender.SendPacket(packet, pacing_info);
+  return true;
+}
+
+void ModuleRtpRtcpImpl2::OnPacketsAcknowledged(
+    rtc::ArrayView<const uint16_t> sequence_numbers) {
+  RTC_DCHECK(rtp_sender_);
+  rtp_sender_->packet_history.CullAcknowledgedPackets(sequence_numbers);
+}
+
+bool ModuleRtpRtcpImpl2::SupportsPadding() const {
+  RTC_DCHECK(rtp_sender_);
+  return rtp_sender_->packet_generator.SupportsPadding();
+}
+
+bool ModuleRtpRtcpImpl2::SupportsRtxPayloadPadding() const {
+  RTC_DCHECK(rtp_sender_);
+  return rtp_sender_->packet_generator.SupportsRtxPayloadPadding();
+}
+
+std::vector<std::unique_ptr<RtpPacketToSend>>
+ModuleRtpRtcpImpl2::GeneratePadding(size_t target_size_bytes) {
+  RTC_DCHECK(rtp_sender_);
+  return rtp_sender_->packet_generator.GeneratePadding(
+      target_size_bytes, rtp_sender_->packet_sender.MediaHasBeenSent());
+}
+
+std::vector<RtpSequenceNumberMap::Info>
+ModuleRtpRtcpImpl2::GetSentRtpPacketInfos(
+    rtc::ArrayView<const uint16_t> sequence_numbers) const {
+  RTC_DCHECK(rtp_sender_);
+  return rtp_sender_->packet_sender.GetSentRtpPacketInfos(sequence_numbers);
+}
+
+size_t ModuleRtpRtcpImpl2::ExpectedPerPacketOverhead() const {
+  if (!rtp_sender_) {
+    return 0;
+  }
+  return rtp_sender_->packet_generator.ExpectedPerPacketOverhead();
+}
+
+size_t ModuleRtpRtcpImpl2::MaxRtpPacketSize() const {
+  RTC_DCHECK(rtp_sender_);
+  return rtp_sender_->packet_generator.MaxRtpPacketSize();
+}
+
+void ModuleRtpRtcpImpl2::SetMaxRtpPacketSize(size_t rtp_packet_size) {
+  RTC_DCHECK_LE(rtp_packet_size, IP_PACKET_SIZE)
+      << "rtp packet size too large: " << rtp_packet_size;
+  RTC_DCHECK_GT(rtp_packet_size, packet_overhead_)
+      << "rtp packet size too small: " << rtp_packet_size;
+
+  rtcp_sender_.SetMaxRtpPacketSize(rtp_packet_size);
+  if (rtp_sender_) {
+    rtp_sender_->packet_generator.SetMaxRtpPacketSize(rtp_packet_size);
+  }
+}
+
+RtcpMode ModuleRtpRtcpImpl2::RTCP() const {
+  return rtcp_sender_.Status();
+}
+
+// Configure RTCP status i.e on/off.
+void ModuleRtpRtcpImpl2::SetRTCPStatus(const RtcpMode method) {
+  rtcp_sender_.SetRTCPStatus(method);
+}
+
+int32_t ModuleRtpRtcpImpl2::SetCNAME(const char* c_name) {
+  return rtcp_sender_.SetCNAME(c_name);
+}
+
+int32_t ModuleRtpRtcpImpl2::AddMixedCNAME(uint32_t ssrc, const char* c_name) {
+  return rtcp_sender_.AddMixedCNAME(ssrc, c_name);
+}
+
+int32_t ModuleRtpRtcpImpl2::RemoveMixedCNAME(const uint32_t ssrc) {
+  return rtcp_sender_.RemoveMixedCNAME(ssrc);
+}
+
+int32_t ModuleRtpRtcpImpl2::RemoteCNAME(const uint32_t remote_ssrc,
+                                        char c_name[RTCP_CNAME_SIZE]) const {
+  return rtcp_receiver_.CNAME(remote_ssrc, c_name);
+}
+
+int32_t ModuleRtpRtcpImpl2::RemoteNTP(uint32_t* received_ntpsecs,
+                                      uint32_t* received_ntpfrac,
+                                      uint32_t* rtcp_arrival_time_secs,
+                                      uint32_t* rtcp_arrival_time_frac,
+                                      uint32_t* rtcp_timestamp) const {
+  return rtcp_receiver_.NTP(received_ntpsecs, received_ntpfrac,
+                            rtcp_arrival_time_secs, rtcp_arrival_time_frac,
+                            rtcp_timestamp)
+             ? 0
+             : -1;
+}
+
+// Get RoundTripTime.
+int32_t ModuleRtpRtcpImpl2::RTT(const uint32_t remote_ssrc,
+                                int64_t* rtt,
+                                int64_t* avg_rtt,
+                                int64_t* min_rtt,
+                                int64_t* max_rtt) const {
+  int32_t ret = rtcp_receiver_.RTT(remote_ssrc, rtt, avg_rtt, min_rtt, max_rtt);
+  if (rtt && *rtt == 0) {
+    // Try to get RTT from RtcpRttStats class.
+    *rtt = rtt_ms();
+  }
+  return ret;
+}
+
+int64_t ModuleRtpRtcpImpl2::ExpectedRetransmissionTimeMs() const {
+  int64_t expected_retransmission_time_ms = rtt_ms();
+  if (expected_retransmission_time_ms > 0) {
+    return expected_retransmission_time_ms;
+  }
+  // No rtt available (|kRtpRtcpRttProcessTimeMs| not yet passed?), so try to
+  // poll avg_rtt_ms directly from rtcp receiver.
+  if (rtcp_receiver_.RTT(rtcp_receiver_.RemoteSSRC(), nullptr,
+                         &expected_retransmission_time_ms, nullptr,
+                         nullptr) == 0) {
+    return expected_retransmission_time_ms;
+  }
+  return kDefaultExpectedRetransmissionTimeMs;
+}
+
+// Force a send of an RTCP packet.
+// Normal SR and RR are triggered via the process function.
+int32_t ModuleRtpRtcpImpl2::SendRTCP(RTCPPacketType packet_type) {
+  return rtcp_sender_.SendRTCP(GetFeedbackState(), packet_type);
+}
+
+int32_t ModuleRtpRtcpImpl2::SetRTCPApplicationSpecificData(
+    const uint8_t sub_type,
+    const uint32_t name,
+    const uint8_t* data,
+    const uint16_t length) {
+  return rtcp_sender_.SetApplicationSpecificData(sub_type, name, data, length);
+}
+
+void ModuleRtpRtcpImpl2::SetRtcpXrRrtrStatus(bool enable) {
+  rtcp_receiver_.SetRtcpXrRrtrStatus(enable);
+  rtcp_sender_.SendRtcpXrReceiverReferenceTime(enable);
+}
+
+bool ModuleRtpRtcpImpl2::RtcpXrRrtrStatus() const {
+  return rtcp_sender_.RtcpXrReceiverReferenceTime();
+}
+
+// TODO(asapersson): Replace this method with the one below.
+int32_t ModuleRtpRtcpImpl2::DataCountersRTP(size_t* bytes_sent,
+                                            uint32_t* packets_sent) const {
+  StreamDataCounters rtp_stats;
+  StreamDataCounters rtx_stats;
+  rtp_sender_->packet_sender.GetDataCounters(&rtp_stats, &rtx_stats);
+
+  if (bytes_sent) {
+    // TODO(http://crbug.com/webrtc/10525): Bytes sent should only include
+    // payload bytes, not header and padding bytes.
+    *bytes_sent = rtp_stats.transmitted.payload_bytes +
+                  rtp_stats.transmitted.padding_bytes +
+                  rtp_stats.transmitted.header_bytes +
+                  rtx_stats.transmitted.payload_bytes +
+                  rtx_stats.transmitted.padding_bytes +
+                  rtx_stats.transmitted.header_bytes;
+  }
+  if (packets_sent) {
+    *packets_sent =
+        rtp_stats.transmitted.packets + rtx_stats.transmitted.packets;
+  }
+  return 0;
+}
+
+void ModuleRtpRtcpImpl2::GetSendStreamDataCounters(
+    StreamDataCounters* rtp_counters,
+    StreamDataCounters* rtx_counters) const {
+  rtp_sender_->packet_sender.GetDataCounters(rtp_counters, rtx_counters);
+}
+
+// Received RTCP report.
+int32_t ModuleRtpRtcpImpl2::RemoteRTCPStat(
+    std::vector<RTCPReportBlock>* receive_blocks) const {
+  return rtcp_receiver_.StatisticsReceived(receive_blocks);
+}
+
+std::vector<ReportBlockData> ModuleRtpRtcpImpl2::GetLatestReportBlockData()
+    const {
+  return rtcp_receiver_.GetLatestReportBlockData();
+}
+
+// (REMB) Receiver Estimated Max Bitrate.
+void ModuleRtpRtcpImpl2::SetRemb(int64_t bitrate_bps,
+                                 std::vector<uint32_t> ssrcs) {
+  rtcp_sender_.SetRemb(bitrate_bps, std::move(ssrcs));
+}
+
+void ModuleRtpRtcpImpl2::UnsetRemb() {
+  rtcp_sender_.UnsetRemb();
+}
+
+void ModuleRtpRtcpImpl2::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+  rtp_sender_->packet_generator.SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
+int32_t ModuleRtpRtcpImpl2::RegisterSendRtpHeaderExtension(
+    const RTPExtensionType type,
+    const uint8_t id) {
+  return rtp_sender_->packet_generator.RegisterRtpHeaderExtension(type, id);
+}
+
+void ModuleRtpRtcpImpl2::RegisterRtpHeaderExtension(absl::string_view uri,
+                                                    int id) {
+  bool registered =
+      rtp_sender_->packet_generator.RegisterRtpHeaderExtension(uri, id);
+  RTC_CHECK(registered);
+}
+
+int32_t ModuleRtpRtcpImpl2::DeregisterSendRtpHeaderExtension(
+    const RTPExtensionType type) {
+  return rtp_sender_->packet_generator.DeregisterRtpHeaderExtension(type);
+}
+void ModuleRtpRtcpImpl2::DeregisterSendRtpHeaderExtension(
+    absl::string_view uri) {
+  rtp_sender_->packet_generator.DeregisterRtpHeaderExtension(uri);
+}
+
+// (TMMBR) Temporary Max Media Bit Rate.
+bool ModuleRtpRtcpImpl2::TMMBR() const {
+  return rtcp_sender_.TMMBR();
+}
+
+void ModuleRtpRtcpImpl2::SetTMMBRStatus(const bool enable) {
+  rtcp_sender_.SetTMMBRStatus(enable);
+}
+
+void ModuleRtpRtcpImpl2::SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) {
+  rtcp_sender_.SetTmmbn(std::move(bounding_set));
+}
+
+// Send a Negative acknowledgment packet.
+int32_t ModuleRtpRtcpImpl2::SendNACK(const uint16_t* nack_list,
+                                     const uint16_t size) {
+  uint16_t nack_length = size;
+  uint16_t start_id = 0;
+  int64_t now_ms = clock_->TimeInMilliseconds();
+  if (TimeToSendFullNackList(now_ms)) {
+    nack_last_time_sent_full_ms_ = now_ms;
+  } else {
+    // Only send extended list.
+    if (nack_last_seq_number_sent_ == nack_list[size - 1]) {
+      // Last sequence number is the same, do not send list.
+      return 0;
+    }
+    // Send new sequence numbers.
+    for (int i = 0; i < size; ++i) {
+      if (nack_last_seq_number_sent_ == nack_list[i]) {
+        start_id = i + 1;
+        break;
+      }
+    }
+    nack_length = size - start_id;
+  }
+
+  // Our RTCP NACK implementation is limited to kRtcpMaxNackFields sequence
+  // numbers per RTCP packet.
+  if (nack_length > kRtcpMaxNackFields) {
+    nack_length = kRtcpMaxNackFields;
+  }
+  nack_last_seq_number_sent_ = nack_list[start_id + nack_length - 1];
+
+  return rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpNack, nack_length,
+                               &nack_list[start_id]);
+}
+
+void ModuleRtpRtcpImpl2::SendNack(
+    const std::vector<uint16_t>& sequence_numbers) {
+  rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpNack, sequence_numbers.size(),
+                        sequence_numbers.data());
+}
+
+bool ModuleRtpRtcpImpl2::TimeToSendFullNackList(int64_t now) const {
+  // Use RTT from RtcpRttStats class if provided.
+  int64_t rtt = rtt_ms();
+  if (rtt == 0) {
+    rtcp_receiver_.RTT(rtcp_receiver_.RemoteSSRC(), NULL, &rtt, NULL, NULL);
+  }
+
+  const int64_t kStartUpRttMs = 100;
+  int64_t wait_time = 5 + ((rtt * 3) >> 1);  // 5 + RTT * 1.5.
+  if (rtt == 0) {
+    wait_time = kStartUpRttMs;
+  }
+
+  // Send a full NACK list once within every |wait_time|.
+  return now - nack_last_time_sent_full_ms_ > wait_time;
+}
+
+// Store the sent packets, needed to answer to Negative acknowledgment requests.
+void ModuleRtpRtcpImpl2::SetStorePacketsStatus(const bool enable,
+                                               const uint16_t number_to_store) {
+  rtp_sender_->packet_history.SetStorePacketsStatus(
+      enable ? RtpPacketHistory::StorageMode::kStoreAndCull
+             : RtpPacketHistory::StorageMode::kDisabled,
+      number_to_store);
+}
+
+bool ModuleRtpRtcpImpl2::StorePackets() const {
+  return rtp_sender_->packet_history.GetStorageMode() !=
+         RtpPacketHistory::StorageMode::kDisabled;
+}
+
+void ModuleRtpRtcpImpl2::SendCombinedRtcpPacket(
+    std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) {
+  rtcp_sender_.SendCombinedRtcpPacket(std::move(rtcp_packets));
+}
+
+int32_t ModuleRtpRtcpImpl2::SendLossNotification(uint16_t last_decoded_seq_num,
+                                                 uint16_t last_received_seq_num,
+                                                 bool decodability_flag,
+                                                 bool buffering_allowed) {
+  return rtcp_sender_.SendLossNotification(
+      GetFeedbackState(), last_decoded_seq_num, last_received_seq_num,
+      decodability_flag, buffering_allowed);
+}
+
+void ModuleRtpRtcpImpl2::SetRemoteSSRC(const uint32_t ssrc) {
+  // Inform about the incoming SSRC.
+  rtcp_sender_.SetRemoteSSRC(ssrc);
+  rtcp_receiver_.SetRemoteSSRC(ssrc);
+}
+
+// TODO(nisse): Delete video_rate amd fec_rate arguments.
+void ModuleRtpRtcpImpl2::BitrateSent(uint32_t* total_rate,
+                                     uint32_t* video_rate,
+                                     uint32_t* fec_rate,
+                                     uint32_t* nack_rate) const {
+  RtpSendRates send_rates = rtp_sender_->packet_sender.GetSendRates();
+  *total_rate = send_rates.Sum().bps<uint32_t>();
+  if (video_rate)
+    *video_rate = 0;
+  if (fec_rate)
+    *fec_rate = 0;
+  *nack_rate = send_rates[RtpPacketMediaType::kRetransmission].bps<uint32_t>();
+}
+
+RtpSendRates ModuleRtpRtcpImpl2::GetSendRates() const {
+  return rtp_sender_->packet_sender.GetSendRates();
+}
+
+void ModuleRtpRtcpImpl2::OnRequestSendReport() {
+  SendRTCP(kRtcpSr);
+}
+
+void ModuleRtpRtcpImpl2::OnReceivedNack(
+    const std::vector<uint16_t>& nack_sequence_numbers) {
+  if (!rtp_sender_)
+    return;
+
+  if (!StorePackets() || nack_sequence_numbers.empty()) {
+    return;
+  }
+  // Use RTT from RtcpRttStats class if provided.
+  int64_t rtt = rtt_ms();
+  if (rtt == 0) {
+    rtcp_receiver_.RTT(rtcp_receiver_.RemoteSSRC(), NULL, &rtt, NULL, NULL);
+  }
+  rtp_sender_->packet_generator.OnReceivedNack(nack_sequence_numbers, rtt);
+}
+
+void ModuleRtpRtcpImpl2::OnReceivedRtcpReportBlocks(
+    const ReportBlockList& report_blocks) {
+  if (rtp_sender_) {
+    uint32_t ssrc = SSRC();
+    absl::optional<uint32_t> rtx_ssrc;
+    if (rtp_sender_->packet_generator.RtxStatus() != kRtxOff) {
+      rtx_ssrc = rtp_sender_->packet_generator.RtxSsrc();
+    }
+
+    for (const RTCPReportBlock& report_block : report_blocks) {
+      if (ssrc == report_block.source_ssrc) {
+        rtp_sender_->packet_generator.OnReceivedAckOnSsrc(
+            report_block.extended_highest_sequence_number);
+      } else if (rtx_ssrc && *rtx_ssrc == report_block.source_ssrc) {
+        rtp_sender_->packet_generator.OnReceivedAckOnRtxSsrc(
+            report_block.extended_highest_sequence_number);
+      }
+    }
+  }
+}
+
+bool ModuleRtpRtcpImpl2::LastReceivedNTP(
+    uint32_t* rtcp_arrival_time_secs,  // When we got the last report.
+    uint32_t* rtcp_arrival_time_frac,
+    uint32_t* remote_sr) const {
+  // Remote SR: NTP inside the last received (mid 16 bits from sec and frac).
+  uint32_t ntp_secs = 0;
+  uint32_t ntp_frac = 0;
+
+  if (!rtcp_receiver_.NTP(&ntp_secs, &ntp_frac, rtcp_arrival_time_secs,
+                          rtcp_arrival_time_frac, NULL)) {
+    return false;
+  }
+  *remote_sr =
+      ((ntp_secs & 0x0000ffff) << 16) + ((ntp_frac & 0xffff0000) >> 16);
+  return true;
+}
+
+void ModuleRtpRtcpImpl2::set_rtt_ms(int64_t rtt_ms) {
+  {
+    rtc::CritScope cs(&critical_section_rtt_);
+    rtt_ms_ = rtt_ms;
+  }
+  if (rtp_sender_) {
+    rtp_sender_->packet_history.SetRtt(rtt_ms);
+  }
+}
+
+int64_t ModuleRtpRtcpImpl2::rtt_ms() const {
+  rtc::CritScope cs(&critical_section_rtt_);
+  return rtt_ms_;
+}
+
+void ModuleRtpRtcpImpl2::SetVideoBitrateAllocation(
+    const VideoBitrateAllocation& bitrate) {
+  rtcp_sender_.SetVideoBitrateAllocation(bitrate);
+}
+
+RTPSender* ModuleRtpRtcpImpl2::RtpSender() {
+  return rtp_sender_ ? &rtp_sender_->packet_generator : nullptr;
+}
+
+const RTPSender* ModuleRtpRtcpImpl2::RtpSender() const {
+  return rtp_sender_ ? &rtp_sender_->packet_generator : nullptr;
+}
+
+DataRate ModuleRtpRtcpImpl2::SendRate() const {
+  RTC_DCHECK(rtp_sender_);
+  return rtp_sender_->packet_sender.GetSendRates().Sum();
+}
+
+DataRate ModuleRtpRtcpImpl2::NackOverheadRate() const {
+  RTC_DCHECK(rtp_sender_);
+  return rtp_sender_->packet_sender
+      .GetSendRates()[RtpPacketMediaType::kRetransmission];
+}
+
+}  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.h b/modules/rtp_rtcp/source/rtp_rtcp_impl2.h
new file mode 100644
index 0000000..67409c0
--- /dev/null
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.h
@@ -0,0 +1,355 @@
+/*
+ *  Copyright (c) 2012 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.
+ */
+
+#ifndef MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL2_H_
+#define MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL2_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/rtp_headers.h"
+#include "api/video/video_bitrate_allocation.h"
+#include "modules/include/module_fec_types.h"
+#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
+#include "modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"  // RTCPPacketType
+#include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
+#include "modules/rtp_rtcp/source/rtcp_receiver.h"
+#include "modules/rtp_rtcp/source/rtcp_sender.h"
+#include "modules/rtp_rtcp/source/rtp_packet_history.h"
+#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "modules/rtp_rtcp/source/rtp_sender.h"
+#include "modules/rtp_rtcp/source/rtp_sender_egress.h"
+#include "rtc_base/critical_section.h"
+#include "rtc_base/gtest_prod_util.h"
+#include "rtc_base/synchronization/sequence_checker.h"
+
+namespace webrtc {
+
+class Clock;
+struct PacedPacketInfo;
+struct RTPVideoHeader;
+
+class ModuleRtpRtcpImpl2 final : public RtpRtcp,
+                                 public RTCPReceiver::ModuleRtpRtcp {
+ public:
+  explicit ModuleRtpRtcpImpl2(const RtpRtcp::Configuration& configuration);
+  ~ModuleRtpRtcpImpl2() override;
+
+  // Returns the number of milliseconds until the module want a worker thread to
+  // call Process.
+  int64_t TimeUntilNextProcess() override;
+
+  // Process any pending tasks such as timeouts.
+  void Process() override;
+
+  // Receiver part.
+
+  // Called when we receive an RTCP packet.
+  void IncomingRtcpPacket(const uint8_t* incoming_packet,
+                          size_t incoming_packet_length) override;
+
+  void SetRemoteSSRC(uint32_t ssrc) override;
+
+  // Sender part.
+  void RegisterSendPayloadFrequency(int payload_type,
+                                    int payload_frequency) override;
+
+  int32_t DeRegisterSendPayload(int8_t payload_type) override;
+
+  void SetExtmapAllowMixed(bool extmap_allow_mixed) override;
+
+  // Register RTP header extension.
+  int32_t RegisterSendRtpHeaderExtension(RTPExtensionType type,
+                                         uint8_t id) override;
+  void RegisterRtpHeaderExtension(absl::string_view uri, int id) override;
+  int32_t DeregisterSendRtpHeaderExtension(RTPExtensionType type) override;
+  void DeregisterSendRtpHeaderExtension(absl::string_view uri) override;
+
+  bool SupportsPadding() const override;
+  bool SupportsRtxPayloadPadding() const override;
+
+  // Get start timestamp.
+  uint32_t StartTimestamp() const override;
+
+  // Configure start timestamp, default is a random number.
+  void SetStartTimestamp(uint32_t timestamp) override;
+
+  uint16_t SequenceNumber() const override;
+
+  // Set SequenceNumber, default is a random number.
+  void SetSequenceNumber(uint16_t seq) override;
+
+  void SetRtpState(const RtpState& rtp_state) override;
+  void SetRtxState(const RtpState& rtp_state) override;
+  RtpState GetRtpState() const override;
+  RtpState GetRtxState() const override;
+
+  uint32_t SSRC() const override { return rtcp_sender_.SSRC(); }
+
+  void SetRid(const std::string& rid) override;
+
+  void SetMid(const std::string& mid) override;
+
+  void SetCsrcs(const std::vector<uint32_t>& csrcs) override;
+
+  RTCPSender::FeedbackState GetFeedbackState();
+
+  void SetRtxSendStatus(int mode) override;
+  int RtxSendStatus() const override;
+  absl::optional<uint32_t> RtxSsrc() const override;
+
+  void SetRtxSendPayloadType(int payload_type,
+                             int associated_payload_type) override;
+
+  absl::optional<uint32_t> FlexfecSsrc() const override;
+
+  // Sends kRtcpByeCode when going from true to false.
+  int32_t SetSendingStatus(bool sending) override;
+
+  bool Sending() const override;
+
+  // Drops or relays media packets.
+  void SetSendingMediaStatus(bool sending) override;
+
+  bool SendingMedia() const override;
+
+  bool IsAudioConfigured() const override;
+
+  void SetAsPartOfAllocation(bool part_of_allocation) override;
+
+  bool OnSendingRtpFrame(uint32_t timestamp,
+                         int64_t capture_time_ms,
+                         int payload_type,
+                         bool force_sender_report) override;
+
+  bool TrySendPacket(RtpPacketToSend* packet,
+                     const PacedPacketInfo& pacing_info) override;
+
+  void OnPacketsAcknowledged(
+      rtc::ArrayView<const uint16_t> sequence_numbers) override;
+
+  std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
+      size_t target_size_bytes) override;
+
+  std::vector<RtpSequenceNumberMap::Info> GetSentRtpPacketInfos(
+      rtc::ArrayView<const uint16_t> sequence_numbers) const override;
+
+  size_t ExpectedPerPacketOverhead() const override;
+
+  // RTCP part.
+
+  // Get RTCP status.
+  RtcpMode RTCP() const override;
+
+  // Configure RTCP status i.e on/off.
+  void SetRTCPStatus(RtcpMode method) override;
+
+  // Set RTCP CName.
+  int32_t SetCNAME(const char* c_name) override;
+
+  // Get remote CName.
+  int32_t RemoteCNAME(uint32_t remote_ssrc,
+                      char c_name[RTCP_CNAME_SIZE]) const override;
+
+  // Get remote NTP.
+  int32_t RemoteNTP(uint32_t* received_ntp_secs,
+                    uint32_t* received_ntp_frac,
+                    uint32_t* rtcp_arrival_time_secs,
+                    uint32_t* rtcp_arrival_time_frac,
+                    uint32_t* rtcp_timestamp) const override;
+
+  int32_t AddMixedCNAME(uint32_t ssrc, const char* c_name) override;
+
+  int32_t RemoveMixedCNAME(uint32_t ssrc) override;
+
+  // Get RoundTripTime.
+  int32_t RTT(uint32_t remote_ssrc,
+              int64_t* rtt,
+              int64_t* avg_rtt,
+              int64_t* min_rtt,
+              int64_t* max_rtt) const override;
+
+  int64_t ExpectedRetransmissionTimeMs() const override;
+
+  // Force a send of an RTCP packet.
+  // Normal SR and RR are triggered via the process function.
+  int32_t SendRTCP(RTCPPacketType rtcpPacketType) override;
+
+  // Statistics of the amount of data sent and received.
+  int32_t DataCountersRTP(size_t* bytes_sent,
+                          uint32_t* packets_sent) const override;
+
+  void GetSendStreamDataCounters(
+      StreamDataCounters* rtp_counters,
+      StreamDataCounters* rtx_counters) const override;
+
+  // Get received RTCP report, report block.
+  int32_t RemoteRTCPStat(
+      std::vector<RTCPReportBlock>* receive_blocks) const override;
+  // A snapshot of the most recent Report Block with additional data of
+  // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats.
+  // Within this list, the ReportBlockData::RTCPReportBlock::source_ssrc(),
+  // which is the SSRC of the corresponding outbound RTP stream, is unique.
+  std::vector<ReportBlockData> GetLatestReportBlockData() const override;
+
+  // (REMB) Receiver Estimated Max Bitrate.
+  void SetRemb(int64_t bitrate_bps, std::vector<uint32_t> ssrcs) override;
+  void UnsetRemb() override;
+
+  // (TMMBR) Temporary Max Media Bit Rate.
+  bool TMMBR() const override;
+
+  void SetTMMBRStatus(bool enable) override;
+
+  void SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) override;
+
+  size_t MaxRtpPacketSize() const override;
+
+  void SetMaxRtpPacketSize(size_t max_packet_size) override;
+
+  // (NACK) Negative acknowledgment part.
+
+  // Send a Negative acknowledgment packet.
+  // TODO(philipel): Deprecate SendNACK and use SendNack instead.
+  int32_t SendNACK(const uint16_t* nack_list, uint16_t size) override;
+
+  void SendNack(const std::vector<uint16_t>& sequence_numbers) override;
+
+  // Store the sent packets, needed to answer to a negative acknowledgment
+  // requests.
+  void SetStorePacketsStatus(bool enable, uint16_t number_to_store) override;
+
+  bool StorePackets() const override;
+
+  void SendCombinedRtcpPacket(
+      std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) override;
+
+  // (APP) Application specific data.
+  int32_t SetRTCPApplicationSpecificData(uint8_t sub_type,
+                                         uint32_t name,
+                                         const uint8_t* data,
+                                         uint16_t length) override;
+
+  // (XR) Receiver reference time report.
+  void SetRtcpXrRrtrStatus(bool enable) override;
+
+  bool RtcpXrRrtrStatus() const override;
+
+  // Video part.
+  int32_t SendLossNotification(uint16_t last_decoded_seq_num,
+                               uint16_t last_received_seq_num,
+                               bool decodability_flag,
+                               bool buffering_allowed) override;
+
+  bool LastReceivedNTP(uint32_t* NTPsecs,
+                       uint32_t* NTPfrac,
+                       uint32_t* remote_sr) const;
+
+  void BitrateSent(uint32_t* total_rate,
+                   uint32_t* video_rate,
+                   uint32_t* fec_rate,
+                   uint32_t* nackRate) const override;
+
+  RtpSendRates GetSendRates() const override;
+
+  void OnReceivedNack(
+      const std::vector<uint16_t>& nack_sequence_numbers) override;
+  void OnReceivedRtcpReportBlocks(
+      const ReportBlockList& report_blocks) override;
+  void OnRequestSendReport() override;
+
+  void SetVideoBitrateAllocation(
+      const VideoBitrateAllocation& bitrate) override;
+
+  RTPSender* RtpSender() override;
+  const RTPSender* RtpSender() const override;
+
+ protected:
+  bool UpdateRTCPReceiveInformationTimers();
+
+  RTPSender* rtp_sender() {
+    return rtp_sender_ ? &rtp_sender_->packet_generator : nullptr;
+  }
+  const RTPSender* rtp_sender() const {
+    return rtp_sender_ ? &rtp_sender_->packet_generator : nullptr;
+  }
+
+  RTCPSender* rtcp_sender() { return &rtcp_sender_; }
+  const RTCPSender* rtcp_sender() const { return &rtcp_sender_; }
+
+  RTCPReceiver* rtcp_receiver() { return &rtcp_receiver_; }
+  const RTCPReceiver* rtcp_receiver() const { return &rtcp_receiver_; }
+
+  Clock* clock() const { return clock_; }
+
+  // TODO(sprang): Remove when usage is gone.
+  DataRate SendRate() const;
+  DataRate NackOverheadRate() const;
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(RtpRtcpImpl2Test, Rtt);
+  FRIEND_TEST_ALL_PREFIXES(RtpRtcpImpl2Test, RttForReceiverOnly);
+
+  struct RtpSenderContext {
+    explicit RtpSenderContext(const RtpRtcp::Configuration& config);
+    // Storage of packets, for retransmissions and padding, if applicable.
+    RtpPacketHistory packet_history;
+    // Handles final time timestamping/stats/etc and handover to Transport.
+    RtpSenderEgress packet_sender;
+    // If no paced sender configured, this class will be used to pass packets
+    // from |packet_generator_| to |packet_sender_|.
+    RtpSenderEgress::NonPacedPacketSender non_paced_sender;
+    // Handles creation of RTP packets to be sent.
+    RTPSender packet_generator;
+  };
+
+  void set_rtt_ms(int64_t rtt_ms);
+  int64_t rtt_ms() const;
+
+  bool TimeToSendFullNackList(int64_t now) const;
+
+  SequenceChecker construction_thread_checker_;
+  SequenceChecker process_thread_checker_;
+
+  std::unique_ptr<RtpSenderContext> rtp_sender_;
+
+  RTCPSender rtcp_sender_;
+  RTCPReceiver rtcp_receiver_;
+
+  Clock* const clock_;
+
+  int64_t last_bitrate_process_time_;
+  int64_t last_rtt_process_time_;
+  int64_t next_process_time_;
+  uint16_t packet_overhead_;
+
+  // Send side
+  int64_t nack_last_time_sent_full_ms_;
+  uint16_t nack_last_seq_number_sent_;
+
+  RemoteBitrateEstimator* const remote_bitrate_;
+
+  RtcpRttStats* const rtt_stats_;
+
+  // The processed RTT from RtcpRttStats.
+  rtc::CriticalSection critical_section_rtt_;
+  int64_t rtt_ms_;
+};
+
+}  // namespace webrtc
+
+#endif  // MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL2_H_
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc
new file mode 100644
index 0000000..7627283
--- /dev/null
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc
@@ -0,0 +1,630 @@
+/*
+ *  Copyright (c) 2013 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 "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
+
+#include <map>
+#include <memory>
+#include <set>
+
+#include "api/transport/field_trial_based_config.h"
+#include "api/video_codecs/video_codec.h"
+#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "modules/rtp_rtcp/source/rtcp_packet.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
+#include "modules/rtp_rtcp/source/rtp_packet_received.h"
+#include "modules/rtp_rtcp/source/rtp_sender_video.h"
+#include "rtc_base/rate_limiter.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/rtcp_packet_parser.h"
+#include "test/rtp_header_parser.h"
+
+using ::testing::ElementsAre;
+
+namespace webrtc {
+namespace {
+const uint32_t kSenderSsrc = 0x12345;
+const uint32_t kReceiverSsrc = 0x23456;
+const int64_t kOneWayNetworkDelayMs = 100;
+const uint8_t kBaseLayerTid = 0;
+const uint8_t kHigherLayerTid = 1;
+const uint16_t kSequenceNumber = 100;
+
+class RtcpRttStatsTestImpl : public RtcpRttStats {
+ public:
+  RtcpRttStatsTestImpl() : rtt_ms_(0) {}
+  ~RtcpRttStatsTestImpl() override = default;
+
+  void OnRttUpdate(int64_t rtt_ms) override { rtt_ms_ = rtt_ms; }
+  int64_t LastProcessedRtt() const override { return rtt_ms_; }
+  int64_t rtt_ms_;
+};
+
+class SendTransport : public Transport {
+ public:
+  SendTransport()
+      : receiver_(nullptr),
+        clock_(nullptr),
+        delay_ms_(0),
+        rtp_packets_sent_(0),
+        rtcp_packets_sent_(0) {}
+
+  void SetRtpRtcpModule(ModuleRtpRtcpImpl2* receiver) { receiver_ = receiver; }
+  void SimulateNetworkDelay(int64_t delay_ms, SimulatedClock* clock) {
+    clock_ = clock;
+    delay_ms_ = delay_ms;
+  }
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const PacketOptions& options) override {
+    RTPHeader header;
+    std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::CreateForTest());
+    EXPECT_TRUE(parser->Parse(static_cast<const uint8_t*>(data), len, &header));
+    ++rtp_packets_sent_;
+    last_rtp_header_ = header;
+    return true;
+  }
+  bool SendRtcp(const uint8_t* data, size_t len) override {
+    test::RtcpPacketParser parser;
+    parser.Parse(data, len);
+    last_nack_list_ = parser.nack()->packet_ids();
+
+    if (clock_) {
+      clock_->AdvanceTimeMilliseconds(delay_ms_);
+    }
+    EXPECT_TRUE(receiver_);
+    receiver_->IncomingRtcpPacket(data, len);
+    ++rtcp_packets_sent_;
+    return true;
+  }
+  size_t NumRtcpSent() { return rtcp_packets_sent_; }
+  ModuleRtpRtcpImpl2* receiver_;
+  SimulatedClock* clock_;
+  int64_t delay_ms_;
+  int rtp_packets_sent_;
+  size_t rtcp_packets_sent_;
+  RTPHeader last_rtp_header_;
+  std::vector<uint16_t> last_nack_list_;
+};
+
+class RtpRtcpModule : public RtcpPacketTypeCounterObserver {
+ public:
+  RtpRtcpModule(SimulatedClock* clock, bool is_sender)
+      : is_sender_(is_sender),
+        receive_statistics_(ReceiveStatistics::Create(clock)),
+        clock_(clock) {
+    CreateModuleImpl();
+    transport_.SimulateNetworkDelay(kOneWayNetworkDelayMs, clock);
+  }
+
+  const bool is_sender_;
+  RtcpPacketTypeCounter packets_sent_;
+  RtcpPacketTypeCounter packets_received_;
+  std::unique_ptr<ReceiveStatistics> receive_statistics_;
+  SendTransport transport_;
+  RtcpRttStatsTestImpl rtt_stats_;
+  std::unique_ptr<ModuleRtpRtcpImpl2> impl_;
+  int rtcp_report_interval_ms_ = 0;
+
+  void RtcpPacketTypesCounterUpdated(
+      uint32_t ssrc,
+      const RtcpPacketTypeCounter& packet_counter) override {
+    counter_map_[ssrc] = packet_counter;
+  }
+
+  RtcpPacketTypeCounter RtcpSent() {
+    // RTCP counters for remote SSRC.
+    return counter_map_[is_sender_ ? kReceiverSsrc : kSenderSsrc];
+  }
+
+  RtcpPacketTypeCounter RtcpReceived() {
+    // Received RTCP stats for (own) local SSRC.
+    return counter_map_[impl_->SSRC()];
+  }
+  int RtpSent() { return transport_.rtp_packets_sent_; }
+  uint16_t LastRtpSequenceNumber() {
+    return transport_.last_rtp_header_.sequenceNumber;
+  }
+  std::vector<uint16_t> LastNackListSent() {
+    return transport_.last_nack_list_;
+  }
+  void SetRtcpReportIntervalAndReset(int rtcp_report_interval_ms) {
+    rtcp_report_interval_ms_ = rtcp_report_interval_ms;
+    CreateModuleImpl();
+  }
+
+ private:
+  void CreateModuleImpl() {
+    RtpRtcp::Configuration config;
+    config.audio = false;
+    config.clock = clock_;
+    config.outgoing_transport = &transport_;
+    config.receive_statistics = receive_statistics_.get();
+    config.rtcp_packet_type_counter_observer = this;
+    config.rtt_stats = &rtt_stats_;
+    config.rtcp_report_interval_ms = rtcp_report_interval_ms_;
+    config.local_media_ssrc = is_sender_ ? kSenderSsrc : kReceiverSsrc;
+    config.need_rtp_packet_infos = true;
+
+    impl_.reset(new ModuleRtpRtcpImpl2(config));
+    impl_->SetRemoteSSRC(is_sender_ ? kReceiverSsrc : kSenderSsrc);
+    impl_->SetRTCPStatus(RtcpMode::kCompound);
+  }
+
+  SimulatedClock* const clock_;
+  std::map<uint32_t, RtcpPacketTypeCounter> counter_map_;
+};
+}  // namespace
+
+class RtpRtcpImpl2Test : public ::testing::Test {
+ protected:
+  RtpRtcpImpl2Test()
+      : clock_(133590000000000),
+        sender_(&clock_, /*is_sender=*/true),
+        receiver_(&clock_, /*is_sender=*/false) {}
+
+  void SetUp() override {
+    // Send module.
+    EXPECT_EQ(0, sender_.impl_->SetSendingStatus(true));
+    sender_.impl_->SetSendingMediaStatus(true);
+    sender_.impl_->SetSequenceNumber(kSequenceNumber);
+    sender_.impl_->SetStorePacketsStatus(true, 100);
+
+    FieldTrialBasedConfig field_trials;
+    RTPSenderVideo::Config video_config;
+    video_config.clock = &clock_;
+    video_config.rtp_sender = sender_.impl_->RtpSender();
+    video_config.field_trials = &field_trials;
+    sender_video_ = std::make_unique<RTPSenderVideo>(video_config);
+
+    memset(&codec_, 0, sizeof(VideoCodec));
+    codec_.plType = 100;
+    codec_.width = 320;
+    codec_.height = 180;
+
+    // Receive module.
+    EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false));
+    receiver_.impl_->SetSendingMediaStatus(false);
+    // Transport settings.
+    sender_.transport_.SetRtpRtcpModule(receiver_.impl_.get());
+    receiver_.transport_.SetRtpRtcpModule(sender_.impl_.get());
+  }
+
+  SimulatedClock clock_;
+  RtpRtcpModule sender_;
+  std::unique_ptr<RTPSenderVideo> sender_video_;
+  RtpRtcpModule receiver_;
+  VideoCodec codec_;
+
+  void SendFrame(const RtpRtcpModule* module,
+                 RTPSenderVideo* sender,
+                 uint8_t tid) {
+    RTPVideoHeaderVP8 vp8_header = {};
+    vp8_header.temporalIdx = tid;
+    RTPVideoHeader rtp_video_header;
+    rtp_video_header.frame_type = VideoFrameType::kVideoFrameKey;
+    rtp_video_header.width = codec_.width;
+    rtp_video_header.height = codec_.height;
+    rtp_video_header.rotation = kVideoRotation_0;
+    rtp_video_header.content_type = VideoContentType::UNSPECIFIED;
+    rtp_video_header.playout_delay = {-1, -1};
+    rtp_video_header.is_first_packet_in_frame = true;
+    rtp_video_header.simulcastIdx = 0;
+    rtp_video_header.codec = kVideoCodecVP8;
+    rtp_video_header.video_type_header = vp8_header;
+    rtp_video_header.video_timing = {0u, 0u, 0u, 0u, 0u, 0u, false};
+
+    const uint8_t payload[100] = {0};
+    EXPECT_TRUE(module->impl_->OnSendingRtpFrame(0, 0, codec_.plType, true));
+    EXPECT_TRUE(sender->SendVideo(codec_.plType, VideoCodecType::kVideoCodecVP8,
+                                  0, 0, payload, nullptr, rtp_video_header, 0));
+  }
+
+  void IncomingRtcpNack(const RtpRtcpModule* module, uint16_t sequence_number) {
+    bool sender = module->impl_->SSRC() == kSenderSsrc;
+    rtcp::Nack nack;
+    uint16_t list[1];
+    list[0] = sequence_number;
+    const uint16_t kListLength = sizeof(list) / sizeof(list[0]);
+    nack.SetSenderSsrc(sender ? kReceiverSsrc : kSenderSsrc);
+    nack.SetMediaSsrc(sender ? kSenderSsrc : kReceiverSsrc);
+    nack.SetPacketIds(list, kListLength);
+    rtc::Buffer packet = nack.Build();
+    module->impl_->IncomingRtcpPacket(packet.data(), packet.size());
+  }
+};
+
+TEST_F(RtpRtcpImpl2Test, RetransmitsAllLayers) {
+  // Send frames.
+  EXPECT_EQ(0, sender_.RtpSent());
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);  // kSequenceNumber
+  SendFrame(&sender_, sender_video_.get(),
+            kHigherLayerTid);  // kSequenceNumber + 1
+  SendFrame(&sender_, sender_video_.get(),
+            kNoTemporalIdx);  // kSequenceNumber + 2
+  EXPECT_EQ(3, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
+
+  // Min required delay until retransmit = 5 + RTT ms (RTT = 0).
+  clock_.AdvanceTimeMilliseconds(5);
+
+  // Frame with kBaseLayerTid re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber);
+  EXPECT_EQ(4, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber, sender_.LastRtpSequenceNumber());
+  // Frame with kHigherLayerTid re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber + 1);
+  EXPECT_EQ(5, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber + 1, sender_.LastRtpSequenceNumber());
+  // Frame with kNoTemporalIdx re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber + 2);
+  EXPECT_EQ(6, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
+}
+
+TEST_F(RtpRtcpImpl2Test, Rtt) {
+  RtpPacketReceived packet;
+  packet.SetTimestamp(1);
+  packet.SetSequenceNumber(123);
+  packet.SetSsrc(kSenderSsrc);
+  packet.AllocatePayload(100 - 12);
+  receiver_.receive_statistics_->OnRtpPacket(packet);
+
+  // Send Frame before sending an SR.
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
+  // Sender module should send an SR.
+  EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
+
+  // Receiver module should send a RR with a response to the last received SR.
+  clock_.AdvanceTimeMilliseconds(1000);
+  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
+
+  // Verify RTT.
+  int64_t rtt;
+  int64_t avg_rtt;
+  int64_t min_rtt;
+  int64_t max_rtt;
+  EXPECT_EQ(
+      0, sender_.impl_->RTT(kReceiverSsrc, &rtt, &avg_rtt, &min_rtt, &max_rtt));
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, rtt, 1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, avg_rtt, 1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, min_rtt, 1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, max_rtt, 1);
+
+  // No RTT from other ssrc.
+  EXPECT_EQ(-1, sender_.impl_->RTT(kReceiverSsrc + 1, &rtt, &avg_rtt, &min_rtt,
+                                   &max_rtt));
+
+  // Verify RTT from rtt_stats config.
+  EXPECT_EQ(0, sender_.rtt_stats_.LastProcessedRtt());
+  EXPECT_EQ(0, sender_.impl_->rtt_ms());
+  sender_.impl_->Process();
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, sender_.rtt_stats_.LastProcessedRtt(),
+              1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, sender_.impl_->rtt_ms(), 1);
+}
+
+TEST_F(RtpRtcpImpl2Test, SetRtcpXrRrtrStatus) {
+  EXPECT_FALSE(receiver_.impl_->RtcpXrRrtrStatus());
+  receiver_.impl_->SetRtcpXrRrtrStatus(true);
+  EXPECT_TRUE(receiver_.impl_->RtcpXrRrtrStatus());
+}
+
+TEST_F(RtpRtcpImpl2Test, RttForReceiverOnly) {
+  receiver_.impl_->SetRtcpXrRrtrStatus(true);
+
+  // Receiver module should send a Receiver time reference report (RTRR).
+  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
+
+  // Sender module should send a response to the last received RTRR (DLRR).
+  clock_.AdvanceTimeMilliseconds(1000);
+  // Send Frame before sending a SR.
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
+  EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
+
+  // Verify RTT.
+  EXPECT_EQ(0, receiver_.rtt_stats_.LastProcessedRtt());
+  EXPECT_EQ(0, receiver_.impl_->rtt_ms());
+  receiver_.impl_->Process();
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs,
+              receiver_.rtt_stats_.LastProcessedRtt(), 1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms(), 1);
+}
+
+TEST_F(RtpRtcpImpl2Test, NoSrBeforeMedia) {
+  // Ignore fake transport delays in this test.
+  sender_.transport_.SimulateNetworkDelay(0, &clock_);
+  receiver_.transport_.SimulateNetworkDelay(0, &clock_);
+
+  sender_.impl_->Process();
+  EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
+
+  // Verify no SR is sent before media has been sent, RR should still be sent
+  // from the receiving module though.
+  clock_.AdvanceTimeMilliseconds(2000);
+  int64_t current_time = clock_.TimeInMilliseconds();
+  sender_.impl_->Process();
+  receiver_.impl_->Process();
+  EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
+  EXPECT_EQ(receiver_.RtcpSent().first_packet_time_ms, current_time);
+
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
+  EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, current_time);
+}
+
+TEST_F(RtpRtcpImpl2Test, RtcpPacketTypeCounter_Nack) {
+  EXPECT_EQ(-1, receiver_.RtcpSent().first_packet_time_ms);
+  EXPECT_EQ(-1, sender_.RtcpReceived().first_packet_time_ms);
+  EXPECT_EQ(0U, sender_.RtcpReceived().nack_packets);
+  EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
+
+  // Receive module sends a NACK.
+  const uint16_t kNackLength = 1;
+  uint16_t nack_list[kNackLength] = {123};
+  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
+  EXPECT_GT(receiver_.RtcpSent().first_packet_time_ms, -1);
+
+  // Send module receives the NACK.
+  EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
+  EXPECT_GT(sender_.RtcpReceived().first_packet_time_ms, -1);
+}
+
+TEST_F(RtpRtcpImpl2Test, AddStreamDataCounters) {
+  StreamDataCounters rtp;
+  const int64_t kStartTimeMs = 1;
+  rtp.first_packet_time_ms = kStartTimeMs;
+  rtp.transmitted.packets = 1;
+  rtp.transmitted.payload_bytes = 1;
+  rtp.transmitted.header_bytes = 2;
+  rtp.transmitted.padding_bytes = 3;
+  EXPECT_EQ(rtp.transmitted.TotalBytes(), rtp.transmitted.payload_bytes +
+                                              rtp.transmitted.header_bytes +
+                                              rtp.transmitted.padding_bytes);
+
+  StreamDataCounters rtp2;
+  rtp2.first_packet_time_ms = -1;
+  rtp2.transmitted.packets = 10;
+  rtp2.transmitted.payload_bytes = 10;
+  rtp2.retransmitted.header_bytes = 4;
+  rtp2.retransmitted.payload_bytes = 5;
+  rtp2.retransmitted.padding_bytes = 6;
+  rtp2.retransmitted.packets = 7;
+  rtp2.fec.packets = 8;
+
+  StreamDataCounters sum = rtp;
+  sum.Add(rtp2);
+  EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms);
+  EXPECT_EQ(11U, sum.transmitted.packets);
+  EXPECT_EQ(11U, sum.transmitted.payload_bytes);
+  EXPECT_EQ(2U, sum.transmitted.header_bytes);
+  EXPECT_EQ(3U, sum.transmitted.padding_bytes);
+  EXPECT_EQ(4U, sum.retransmitted.header_bytes);
+  EXPECT_EQ(5U, sum.retransmitted.payload_bytes);
+  EXPECT_EQ(6U, sum.retransmitted.padding_bytes);
+  EXPECT_EQ(7U, sum.retransmitted.packets);
+  EXPECT_EQ(8U, sum.fec.packets);
+  EXPECT_EQ(sum.transmitted.TotalBytes(),
+            rtp.transmitted.TotalBytes() + rtp2.transmitted.TotalBytes());
+
+  StreamDataCounters rtp3;
+  rtp3.first_packet_time_ms = kStartTimeMs + 10;
+  sum.Add(rtp3);
+  EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms);  // Holds oldest time.
+}
+
+TEST_F(RtpRtcpImpl2Test, SendsInitialNackList) {
+  // Send module sends a NACK.
+  const uint16_t kNackLength = 1;
+  uint16_t nack_list[kNackLength] = {123};
+  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
+  // Send Frame before sending a compound RTCP that starts with SR.
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
+  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
+  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
+}
+
+TEST_F(RtpRtcpImpl2Test, SendsExtendedNackList) {
+  // Send module sends a NACK.
+  const uint16_t kNackLength = 1;
+  uint16_t nack_list[kNackLength] = {123};
+  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
+  // Send Frame before sending a compound RTCP that starts with SR.
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
+  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
+  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
+
+  // Same list not re-send.
+  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
+  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
+
+  // Only extended list sent.
+  const uint16_t kNackExtLength = 2;
+  uint16_t nack_list_ext[kNackExtLength] = {123, 124};
+  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list_ext, kNackExtLength));
+  EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
+  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(124));
+}
+
+TEST_F(RtpRtcpImpl2Test, ReSendsNackListAfterRttMs) {
+  sender_.transport_.SimulateNetworkDelay(0, &clock_);
+  // Send module sends a NACK.
+  const uint16_t kNackLength = 2;
+  uint16_t nack_list[kNackLength] = {123, 125};
+  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
+  // Send Frame before sending a compound RTCP that starts with SR.
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
+  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
+  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
+
+  // Same list not re-send, rtt interval has not passed.
+  const int kStartupRttMs = 100;
+  clock_.AdvanceTimeMilliseconds(kStartupRttMs);
+  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
+
+  // Rtt interval passed, full list sent.
+  clock_.AdvanceTimeMilliseconds(1);
+  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
+  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
+}
+
+TEST_F(RtpRtcpImpl2Test, UniqueNackRequests) {
+  receiver_.transport_.SimulateNetworkDelay(0, &clock_);
+  EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
+  EXPECT_EQ(0U, receiver_.RtcpSent().nack_requests);
+  EXPECT_EQ(0U, receiver_.RtcpSent().unique_nack_requests);
+  EXPECT_EQ(0, receiver_.RtcpSent().UniqueNackRequestsInPercent());
+
+  // Receive module sends NACK request.
+  const uint16_t kNackLength = 4;
+  uint16_t nack_list[kNackLength] = {10, 11, 13, 18};
+  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
+  EXPECT_EQ(4U, receiver_.RtcpSent().nack_requests);
+  EXPECT_EQ(4U, receiver_.RtcpSent().unique_nack_requests);
+  EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(10, 11, 13, 18));
+
+  // Send module receives the request.
+  EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
+  EXPECT_EQ(4U, sender_.RtcpReceived().nack_requests);
+  EXPECT_EQ(4U, sender_.RtcpReceived().unique_nack_requests);
+  EXPECT_EQ(100, sender_.RtcpReceived().UniqueNackRequestsInPercent());
+
+  // Receive module sends new request with duplicated packets.
+  const int kStartupRttMs = 100;
+  clock_.AdvanceTimeMilliseconds(kStartupRttMs + 1);
+  const uint16_t kNackLength2 = 4;
+  uint16_t nack_list2[kNackLength2] = {11, 18, 20, 21};
+  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list2, kNackLength2));
+  EXPECT_EQ(2U, receiver_.RtcpSent().nack_packets);
+  EXPECT_EQ(8U, receiver_.RtcpSent().nack_requests);
+  EXPECT_EQ(6U, receiver_.RtcpSent().unique_nack_requests);
+  EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(11, 18, 20, 21));
+
+  // Send module receives the request.
+  EXPECT_EQ(2U, sender_.RtcpReceived().nack_packets);
+  EXPECT_EQ(8U, sender_.RtcpReceived().nack_requests);
+  EXPECT_EQ(6U, sender_.RtcpReceived().unique_nack_requests);
+  EXPECT_EQ(75, sender_.RtcpReceived().UniqueNackRequestsInPercent());
+}
+
+TEST_F(RtpRtcpImpl2Test, ConfigurableRtcpReportInterval) {
+  const int kVideoReportInterval = 3000;
+
+  // Recreate sender impl with new configuration, and redo setup.
+  sender_.SetRtcpReportIntervalAndReset(kVideoReportInterval);
+  SetUp();
+
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
+
+  // Initial state
+  sender_.impl_->Process();
+  EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, -1);
+  EXPECT_EQ(0u, sender_.transport_.NumRtcpSent());
+
+  // Move ahead to the last ms before a rtcp is expected, no action.
+  clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2 - 1);
+  sender_.impl_->Process();
+  EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, -1);
+  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 0u);
+
+  // Move ahead to the first rtcp. Send RTCP.
+  clock_.AdvanceTimeMilliseconds(1);
+  sender_.impl_->Process();
+  EXPECT_GT(sender_.RtcpSent().first_packet_time_ms, -1);
+  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);
+
+  SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
+
+  // Move ahead to the last possible second before second rtcp is expected.
+  clock_.AdvanceTimeMilliseconds(kVideoReportInterval * 1 / 2 - 1);
+  sender_.impl_->Process();
+  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);
+
+  // Move ahead into the range of second rtcp, the second rtcp may be sent.
+  clock_.AdvanceTimeMilliseconds(1);
+  sender_.impl_->Process();
+  EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u);
+
+  clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2);
+  sender_.impl_->Process();
+  EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u);
+
+  // Move out the range of second rtcp, the second rtcp must have been sent.
+  clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2);
+  sender_.impl_->Process();
+  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 2u);
+}
+
+TEST_F(RtpRtcpImpl2Test, StoresPacketInfoForSentPackets) {
+  const uint32_t kStartTimestamp = 1u;
+  SetUp();
+  sender_.impl_->SetStartTimestamp(kStartTimestamp);
+
+  PacedPacketInfo pacing_info;
+  RtpPacketToSend packet(nullptr);
+  packet.set_packet_type(RtpPacketToSend::Type::kVideo);
+  packet.SetSsrc(kSenderSsrc);
+
+  // Single-packet frame.
+  packet.SetTimestamp(1);
+  packet.SetSequenceNumber(1);
+  packet.set_first_packet_of_frame(true);
+  packet.SetMarker(true);
+  sender_.impl_->TrySendPacket(&packet, pacing_info);
+
+  std::vector<RtpSequenceNumberMap::Info> seqno_info =
+      sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{1});
+
+  EXPECT_THAT(seqno_info, ElementsAre(RtpSequenceNumberMap::Info(
+                              /*timestamp=*/1 - kStartTimestamp,
+                              /*is_first=*/1,
+                              /*is_last=*/1)));
+
+  // Three-packet frame.
+  packet.SetTimestamp(2);
+  packet.SetSequenceNumber(2);
+  packet.set_first_packet_of_frame(true);
+  packet.SetMarker(false);
+  sender_.impl_->TrySendPacket(&packet, pacing_info);
+
+  packet.SetSequenceNumber(3);
+  packet.set_first_packet_of_frame(false);
+  sender_.impl_->TrySendPacket(&packet, pacing_info);
+
+  packet.SetSequenceNumber(4);
+  packet.SetMarker(true);
+  sender_.impl_->TrySendPacket(&packet, pacing_info);
+
+  seqno_info =
+      sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{2, 3, 4});
+
+  EXPECT_THAT(seqno_info, ElementsAre(RtpSequenceNumberMap::Info(
+                                          /*timestamp=*/2 - kStartTimestamp,
+                                          /*is_first=*/1,
+                                          /*is_last=*/0),
+                                      RtpSequenceNumberMap::Info(
+                                          /*timestamp=*/2 - kStartTimestamp,
+                                          /*is_first=*/0,
+                                          /*is_last=*/0),
+                                      RtpSequenceNumberMap::Info(
+                                          /*timestamp=*/2 - kStartTimestamp,
+                                          /*is_first=*/0,
+                                          /*is_last=*/1)));
+}
+
+}  // namespace webrtc
diff --git a/video/end_to_end_tests/bandwidth_tests.cc b/video/end_to_end_tests/bandwidth_tests.cc
index 16b35d6..6e8e11d 100644
--- a/video/end_to_end_tests/bandwidth_tests.cc
+++ b/video/end_to_end_tests/bandwidth_tests.cc
@@ -205,8 +205,9 @@
 
     ~BweObserver() override {
       // Block until all already posted tasks run to avoid races when such task
-      // accesses |this|.
-      SendTask(RTC_FROM_HERE, task_queue_, [] {});
+      // accesses |this|. Also make sure we free |rtp_rtcp_| on the correct
+      // thread/task queue.
+      SendTask(RTC_FROM_HERE, task_queue_, [this]() { rtp_rtcp_ = nullptr; });
     }
 
     std::unique_ptr<test::PacketTransport> CreateReceiveTransport(
diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc
index e386538..63acb80 100644
--- a/video/video_send_stream_tests.cc
+++ b/video/video_send_stream_tests.cc
@@ -1627,12 +1627,18 @@
   static const int kRembRespectedBitrateBps = 100000;
   class BitrateObserver : public test::SendTest {
    public:
-    BitrateObserver()
+    explicit BitrateObserver(TaskQueueBase* task_queue)
         : SendTest(kDefaultTimeoutMs),
+          task_queue_(task_queue),
           retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
           stream_(nullptr),
           bitrate_capped_(false) {}
 
+    ~BitrateObserver() override {
+      // Make sure we free |rtp_rtcp_| in the same context as we constructed it.
+      SendTask(RTC_FROM_HERE, task_queue_, [this]() { rtp_rtcp_ = nullptr; });
+    }
+
    private:
     Action OnSendRtp(const uint8_t* packet, size_t length) override {
       if (RtpHeaderParser::IsRtcp(packet, length))
@@ -1690,12 +1696,13 @@
           << "Timeout while waiting for low bitrate stats after REMB.";
     }
 
+    TaskQueueBase* const task_queue_;
     std::unique_ptr<RtpRtcp> rtp_rtcp_;
     std::unique_ptr<internal::TransportAdapter> feedback_transport_;
     RateLimiter retranmission_rate_limiter_;
     VideoSendStream* stream_;
     bool bitrate_capped_;
-  } test;
+  } test(task_queue());
 
   RunBaseTest(&test);
 }
