Add RequestKeyFrame with Fir to RtcpTransceiver
Bug: webrtc:8239
Change-Id: If094d434a7be20cdff5c80447322d68a4a7a4580
Reviewed-on: https://webrtc-review.googlesource.com/22961
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20833}
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
index 52bc489..b870dd1 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/fir.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"
@@ -29,6 +30,19 @@
#include "rtc_base/timeutils.h"
namespace webrtc {
+namespace {
+
+struct SenderReportTimes {
+ int64_t local_received_time_us;
+ NtpTime remote_sent_time;
+};
+
+} // namespace
+
+struct RtcpTransceiverImpl::RemoteSenderState {
+ uint8_t fir_sequence_number = 0;
+ rtc::Optional<SenderReportTimes> last_received_sender_report;
+};
// Helper to put several RTCP packets into lower layer datagram composing
// Compound or Reduced-Size RTCP packet, as defined by RFC 5506 section 2.
@@ -116,25 +130,30 @@
remb_.reset();
}
-void RtcpTransceiverImpl::RequestKeyFrame(
+void RtcpTransceiverImpl::SendPictureLossIndication(
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);
+ SendImmediateFeedback([this, ssrcs](PacketSender* sender) {
+ for (uint32_t media_ssrc : ssrcs) {
+ rtcp::Pli pli;
+ pli.SetSenderSsrc(config_.feedback_ssrc);
+ pli.SetMediaSsrc(media_ssrc);
+ sender->AppendPacket(pli);
+ }
+ });
+}
- 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::SendFullIntraRequest(
+ rtc::ArrayView<const uint32_t> ssrcs) {
+ RTC_DCHECK(!ssrcs.empty());
+ SendImmediateFeedback([this, ssrcs](PacketSender* sender) {
+ rtcp::Fir fir;
+ fir.SetSenderSsrc(config_.feedback_ssrc);
+ for (uint32_t media_ssrc : ssrcs)
+ fir.AddRequestTo(media_ssrc,
+ remote_senders_[media_ssrc].fir_sequence_number++);
+ sender->AppendPacket(fir);
+ });
}
void RtcpTransceiverImpl::HandleReceivedPacket(
@@ -145,10 +164,12 @@
rtcp::SenderReport sender_report;
if (!sender_report.Parse(rtcp_packet_header))
return;
- SenderReportTimes& last =
- last_received_sender_reports_[sender_report.sender_ssrc()];
- last.local_received_time_us = now_us;
- last.remote_sent_time = sender_report.ntp();
+ rtc::Optional<SenderReportTimes>& last =
+ remote_senders_[sender_report.sender_ssrc()]
+ .last_received_sender_report;
+ last.emplace();
+ last->local_received_time_us = now_us;
+ last->remote_sent_time = sender_report.ntp();
break;
}
}
@@ -220,6 +241,20 @@
sender.Send();
}
+void RtcpTransceiverImpl::SendImmediateFeedback(
+ rtc::FunctionView<void(PacketSender*)> append_feedback) {
+ PacketSender sender(config_.outgoing_transport, config_.max_packet_size);
+ if (config_.rtcp_mode == RtcpMode::kCompound)
+ CreateCompoundPacket(&sender);
+
+ append_feedback(&sender);
+
+ sender.Send();
+
+ if (config_.rtcp_mode == RtcpMode::kCompound)
+ ReschedulePeriodicCompoundPackets();
+}
+
std::vector<rtcp::ReportBlock> RtcpTransceiverImpl::CreateReportBlocks() {
if (!config_.receive_statistics)
return {};
@@ -229,10 +264,11 @@
config_.receive_statistics->RtcpReportBlocks(
rtcp::ReceiverReport::kMaxNumberOfReportBlocks);
for (rtcp::ReportBlock& report_block : report_blocks) {
- auto it = last_received_sender_reports_.find(report_block.source_ssrc());
- if (it == last_received_sender_reports_.end())
+ auto it = remote_senders_.find(report_block.source_ssrc());
+ if (it == remote_senders_.end() || !it->second.last_received_sender_report)
continue;
- const SenderReportTimes& last_sender_report = it->second;
+ const SenderReportTimes& last_sender_report =
+ *it->second.last_received_sender_report;
report_block.SetLastSr(CompactNtp(last_sender_report.remote_sent_time));
report_block.SetDelayLastSr(SaturatedUsToCompactNtp(
rtc::TimeMicros() - last_sender_report.local_received_time_us));