Let FlexfecReceiveStreamImpl send RTCP RRs.

This CL adds an RTP module to FlexfecReceiveStreamImpl, and wires it up
to send RTCP RRs. It further makes some methods take const refs instead
of values, to make it more clear where packet copies are made. This
change reduces the number of copies by one, for the case when media
packets are added to the FlexFEC receiver.

The end-to-end test is modified to check for RTCP RRs being sent.
Part of this modification involves some indentation changes, and the
diff thus looks bigger than it logically is.

BUG=webrtc:5654

Review-Url: https://codereview.webrtc.org/2625633003
Cr-Commit-Position: refs/heads/master@{#16106}
diff --git a/webrtc/call/flexfec_receive_stream_impl.cc b/webrtc/call/flexfec_receive_stream_impl.cc
index 95bcfc1..f5272c9 100644
--- a/webrtc/call/flexfec_receive_stream_impl.cc
+++ b/webrtc/call/flexfec_receive_stream_impl.cc
@@ -10,10 +10,16 @@
 
 #include "webrtc/call/flexfec_receive_stream_impl.h"
 
-#include <utility>
+#include <string>
 
 #include "webrtc/base/checks.h"
 #include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h"
+#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
+#include "webrtc/modules/utility/include/process_thread.h"
+#include "webrtc/system_wrappers/include/clock.h"
 
 namespace webrtc {
 
@@ -97,33 +103,77 @@
                           recovered_packet_receiver));
 }
 
+std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
+    ReceiveStatistics* receive_statistics,
+    Transport* rtcp_send_transport,
+    RtcpRttStats* rtt_stats) {
+  RtpRtcp::Configuration configuration;
+  configuration.audio = false;
+  configuration.receiver_only = true;
+  configuration.clock = Clock::GetRealTimeClock();
+  configuration.receive_statistics = receive_statistics;
+  configuration.outgoing_transport = rtcp_send_transport;
+  configuration.rtt_stats = rtt_stats;
+  std::unique_ptr<RtpRtcp> rtp_rtcp(RtpRtcp::CreateRtpRtcp(configuration));
+  return rtp_rtcp;
+}
+
 }  // namespace
 
 FlexfecReceiveStreamImpl::FlexfecReceiveStreamImpl(
     const Config& config,
-    RecoveredPacketReceiver* recovered_packet_receiver)
-    : started_(false),
-      config_(config),
-      receiver_(
-          MaybeCreateFlexfecReceiver(config_, recovered_packet_receiver)) {
+    RecoveredPacketReceiver* recovered_packet_receiver,
+    RtcpRttStats* rtt_stats,
+    ProcessThread* process_thread)
+    : config_(config),
+      started_(false),
+      receiver_(MaybeCreateFlexfecReceiver(config_, recovered_packet_receiver)),
+      rtp_receive_statistics_(
+          ReceiveStatistics::Create(Clock::GetRealTimeClock())),
+      rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(),
+                                    config_.rtcp_send_transport,
+                                    rtt_stats)),
+      process_thread_(process_thread) {
   LOG(LS_INFO) << "FlexfecReceiveStreamImpl: " << config_.ToString();
+
+  // RTCP reporting.
+  rtp_rtcp_->SetSendingMediaStatus(false);
+  rtp_rtcp_->SetRTCPStatus(config_.rtcp_mode);
+  rtp_rtcp_->SetSSRC(config_.local_ssrc);
+  process_thread_->RegisterModule(rtp_rtcp_.get());
 }
 
 FlexfecReceiveStreamImpl::~FlexfecReceiveStreamImpl() {
   LOG(LS_INFO) << "~FlexfecReceiveStreamImpl: " << config_.ToString();
   Stop();
+  process_thread_->DeRegisterModule(rtp_rtcp_.get());
 }
 
 bool FlexfecReceiveStreamImpl::AddAndProcessReceivedPacket(
-    RtpPacketReceived packet) {
+    const RtpPacketReceived& packet) {
   {
     rtc::CritScope cs(&crit_);
     if (!started_)
       return false;
   }
+
   if (!receiver_)
     return false;
-  return receiver_->AddAndProcessReceivedPacket(std::move(packet));
+
+  if (!receiver_->AddAndProcessReceivedPacket(packet))
+    return false;
+
+  // Do not report media packets in the RTCP RRs generated by |rtp_rtcp_|.
+  if (packet.Ssrc() == config_.remote_ssrc) {
+    RTPHeader header;
+    packet.GetHeader(&header);
+    // FlexFEC packets are never retransmitted.
+    const bool kNotRetransmitted = false;
+    rtp_receive_statistics_->IncomingPacket(header, packet.size(),
+                                            kNotRetransmitted);
+  }
+
+  return true;
 }
 
 void FlexfecReceiveStreamImpl::Start() {