Add periodic compound packet sending to RtcpTransceiver

Bug: webrtc:8239
Change-Id: I1511db63a15e8c5101a933e55e66d3877ff963be
Reviewed-on: https://webrtc-review.googlesource.com/15440
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20480}
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
index c8db3c8..4c4ae95 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
@@ -21,6 +21,8 @@
 #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/ptr_util.h"
+#include "rtc_base/task_queue.h"
 
 namespace webrtc {
 namespace {
@@ -66,13 +68,55 @@
 }  // namespace
 
 RtcpTransceiverImpl::RtcpTransceiverImpl(const RtcpTransceiverConfig& config)
-    : config_(config) {
+    : config_(config), ptr_factory_(this) {
   RTC_CHECK(config_.Validate());
+  if (config_.schedule_periodic_compound_packets)
+    ReschedulePeriodicCompoundPackets(config_.initial_report_delay_ms);
 }
 
 RtcpTransceiverImpl::~RtcpTransceiverImpl() = default;
 
 void RtcpTransceiverImpl::SendCompoundPacket() {
+  SendPacket();
+  if (config_.schedule_periodic_compound_packets)
+    ReschedulePeriodicCompoundPackets(config_.report_period_ms);
+}
+
+void RtcpTransceiverImpl::ReschedulePeriodicCompoundPackets(int64_t delay_ms) {
+  class SendPeriodicCompoundPacket : public rtc::QueuedTask {
+   public:
+    SendPeriodicCompoundPacket(rtc::TaskQueue* task_queue,
+                               rtc::WeakPtr<RtcpTransceiverImpl> ptr)
+        : task_queue_(task_queue), ptr_(std::move(ptr)) {}
+    bool Run() override {
+      RTC_DCHECK(task_queue_->IsCurrent());
+      if (!ptr_)
+        return true;
+      ptr_->SendPacket();
+      task_queue_->PostDelayedTask(rtc::WrapUnique(this),
+                                   ptr_->config_.report_period_ms);
+      return false;
+    }
+
+   private:
+    rtc::TaskQueue* const task_queue_;
+    const rtc::WeakPtr<RtcpTransceiverImpl> ptr_;
+  };
+
+  RTC_DCHECK(config_.schedule_periodic_compound_packets);
+  RTC_DCHECK(config_.task_queue->IsCurrent());
+
+  // Stop existent send task if there is one.
+  ptr_factory_.InvalidateWeakPtrs();
+  auto task = rtc::MakeUnique<SendPeriodicCompoundPacket>(
+      config_.task_queue, ptr_factory_.GetWeakPtr());
+  if (delay_ms > 0)
+    config_.task_queue->PostDelayedTask(std::move(task), delay_ms);
+  else
+    config_.task_queue->PostTask(std::move(task));
+}
+
+void RtcpTransceiverImpl::SendPacket() {
   PacketSender sender(config_.outgoing_transport, config_.max_packet_size);
 
   rtcp::ReceiverReport rr;