Add RequestKeyFrame with Pli to RtcpTransceiver
Add support for reduced size mode.
Bug: webrtc:8239
Change-Id: I1d646f0d7848af6632c9204ce5b96ae24cfc0ad3
Reviewed-on: https://webrtc-review.googlesource.com/23681
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20812}
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
index 2c6eb8d..52bc489 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
@@ -17,6 +17,7 @@
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtcp_packet.h"
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
@@ -28,11 +29,13 @@
#include "rtc_base/timeutils.h"
namespace webrtc {
-namespace {
// Helper to put several RTCP packets into lower layer datagram composing
// Compound or Reduced-Size RTCP packet, as defined by RFC 5506 section 2.
-class PacketSender : public rtcp::RtcpPacket::PacketReadyCallback {
+// TODO(danilchap): When in compound mode and packets are so many that several
+// compound RTCP packets need to be generated, ensure each packet is compound.
+class RtcpTransceiverImpl::PacketSender
+ : public rtcp::RtcpPacket::PacketReadyCallback {
public:
PacketSender(Transport* transport, size_t max_packet_size)
: transport_(transport), max_packet_size_(max_packet_size) {
@@ -56,6 +59,8 @@
}
}
+ bool IsEmpty() const { return index_ == 0; }
+
private:
// Implements RtcpPacket::PacketReadyCallback
void OnPacketReady(uint8_t* data, size_t length) override {
@@ -68,8 +73,6 @@
uint8_t buffer_[IP_PACKET_SIZE];
};
-} // namespace
-
RtcpTransceiverImpl::RtcpTransceiverImpl(const RtcpTransceiverConfig& config)
: config_(config), ptr_factory_(this) {
RTC_CHECK(config_.Validate());
@@ -94,12 +97,8 @@
}
void RtcpTransceiverImpl::SendCompoundPacket() {
- SendPacket();
- if (config_.schedule_periodic_compound_packets) {
- // Stop existent send task.
- ptr_factory_.InvalidateWeakPtrs();
- SchedulePeriodicCompoundPackets(config_.report_period_ms);
- }
+ SendPeriodicCompoundPacket();
+ ReschedulePeriodicCompoundPackets();
}
void RtcpTransceiverImpl::SetRemb(int bitrate_bps,
@@ -117,6 +116,27 @@
remb_.reset();
}
+void RtcpTransceiverImpl::RequestKeyFrame(
+ rtc::ArrayView<const uint32_t> ssrcs) {
+ RTC_DCHECK(!ssrcs.empty());
+ const uint32_t sender_ssrc = config_.feedback_ssrc;
+ PacketSender sender(config_.outgoing_transport, config_.max_packet_size);
+ if (config_.rtcp_mode == RtcpMode::kCompound)
+ CreateCompoundPacket(&sender);
+
+ for (uint32_t media_ssrc : ssrcs) {
+ rtcp::Pli pli;
+ pli.SetSenderSsrc(sender_ssrc);
+ pli.SetMediaSsrc(media_ssrc);
+ sender.AppendPacket(pli);
+ }
+
+ sender.Send();
+
+ if (config_.rtcp_mode == RtcpMode::kCompound)
+ ReschedulePeriodicCompoundPackets();
+}
+
void RtcpTransceiverImpl::HandleReceivedPacket(
const rtcp::CommonHeader& rtcp_packet_header,
int64_t now_us) {
@@ -134,17 +154,25 @@
}
}
+void RtcpTransceiverImpl::ReschedulePeriodicCompoundPackets() {
+ if (!config_.schedule_periodic_compound_packets)
+ return;
+ // Stop existent send task.
+ ptr_factory_.InvalidateWeakPtrs();
+ SchedulePeriodicCompoundPackets(config_.report_period_ms);
+}
+
void RtcpTransceiverImpl::SchedulePeriodicCompoundPackets(int64_t delay_ms) {
- class SendPeriodicCompoundPacket : public rtc::QueuedTask {
+ class SendPeriodicCompoundPacketTask : public rtc::QueuedTask {
public:
- SendPeriodicCompoundPacket(rtc::TaskQueue* task_queue,
- rtc::WeakPtr<RtcpTransceiverImpl> ptr)
+ SendPeriodicCompoundPacketTask(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();
+ ptr_->SendPeriodicCompoundPacket();
task_queue_->PostDelayedTask(rtc::WrapUnique(this),
ptr_->config_.report_period_ms);
return false;
@@ -157,7 +185,7 @@
RTC_DCHECK(config_.schedule_periodic_compound_packets);
- auto task = rtc::MakeUnique<SendPeriodicCompoundPacket>(
+ auto task = rtc::MakeUnique<SendPeriodicCompoundPacketTask>(
config_.task_queue, ptr_factory_.GetWeakPtr());
if (delay_ms > 0)
config_.task_queue->PostDelayedTask(std::move(task), delay_ms);
@@ -165,27 +193,30 @@
config_.task_queue->PostTask(std::move(task));
}
-void RtcpTransceiverImpl::SendPacket() {
- PacketSender sender(config_.outgoing_transport, config_.max_packet_size);
+void RtcpTransceiverImpl::CreateCompoundPacket(PacketSender* sender) {
+ RTC_DCHECK(sender->IsEmpty());
const uint32_t sender_ssrc = config_.feedback_ssrc;
-
rtcp::ReceiverReport receiver_report;
receiver_report.SetSenderSsrc(sender_ssrc);
receiver_report.SetReportBlocks(CreateReportBlocks());
- sender.AppendPacket(receiver_report);
+ sender->AppendPacket(receiver_report);
if (!config_.cname.empty()) {
rtcp::Sdes sdes;
bool added = sdes.AddCName(config_.feedback_ssrc, config_.cname);
RTC_DCHECK(added) << "Failed to add cname " << config_.cname
<< " to rtcp sdes packet.";
- sender.AppendPacket(sdes);
+ sender->AppendPacket(sdes);
}
if (remb_) {
remb_->SetSenderSsrc(sender_ssrc);
- sender.AppendPacket(*remb_);
+ sender->AppendPacket(*remb_);
}
+}
+void RtcpTransceiverImpl::SendPeriodicCompoundPacket() {
+ PacketSender sender(config_.outgoing_transport, config_.max_packet_size);
+ CreateCompoundPacket(&sender);
sender.Send();
}