From 887754af7576aca2766ffbed8018e850a75d801a Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Fri, 18 Mar 2022 17:48:57 +0100 Subject: [PATCH] Implement recieving PLI in RtcpTranceiver Bug: webrtc:8239 Change-Id: I99f818991f4a0edd8afa90044bcb1db7e4a478d9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/256105 Reviewed-by: Emil Lundmark Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#36330} --- .../rtp_rtcp/source/rtcp_transceiver_config.h | 1 + .../rtp_rtcp/source/rtcp_transceiver_impl.cc | 36 +++++++++++++++---- .../rtp_rtcp/source/rtcp_transceiver_impl.h | 2 ++ .../source/rtcp_transceiver_impl_unittest.cc | 22 ++++++++++++ 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_config.h b/modules/rtp_rtcp/source/rtcp_transceiver_config.h index 8b0a8fad62..568abb5c12 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_config.h +++ b/modules/rtp_rtcp/source/rtcp_transceiver_config.h @@ -100,6 +100,7 @@ class RtpStreamRtcpHandler { virtual void OnNack(uint32_t sender_ssrc, rtc::ArrayView sequence_numbers) {} + virtual void OnPli(uint32_t sender_ssrc) {} }; struct RtcpTransceiverConfig { diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc index a43edbde17..ccce613e45 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc +++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc @@ -336,18 +336,40 @@ void RtcpTransceiverImpl::HandleReceiverReport( void RtcpTransceiverImpl::HandlePayloadSpecificFeedback( const rtcp::CommonHeader& rtcp_packet_header, Timestamp now) { - // Remb is the only payload specific message handled right now. - if (rtcp_packet_header.fmt() != rtcp::Psfb::kAfbMessageType || - config_.network_link_observer == nullptr) { + switch (rtcp_packet_header.fmt()) { + case rtcp::Pli::kFeedbackMessageType: + HandlePli(rtcp_packet_header); + break; + case rtcp::Psfb::kAfbMessageType: + HandleRemb(rtcp_packet_header, now); + break; + } +} + +void RtcpTransceiverImpl::HandlePli( + const rtcp::CommonHeader& rtcp_packet_header) { + rtcp::Pli pli; + if (local_senders_.empty() || !pli.Parse(rtcp_packet_header)) { return; } - rtcp::Remb remb; - if (remb.Parse(rtcp_packet_header)) { - config_.network_link_observer->OnReceiverEstimatedMaxBitrate( - now, DataRate::BitsPerSec(remb.bitrate_bps())); + auto it = local_senders_by_ssrc_.find(pli.media_ssrc()); + if (it != local_senders_by_ssrc_.end()) { + it->second->handler->OnPli(pli.sender_ssrc()); } } +void RtcpTransceiverImpl::HandleRemb( + const rtcp::CommonHeader& rtcp_packet_header, + Timestamp now) { + rtcp::Remb remb; + if (config_.network_link_observer == nullptr || + !remb.Parse(rtcp_packet_header)) { + return; + } + config_.network_link_observer->OnReceiverEstimatedMaxBitrate( + now, DataRate::BitsPerSec(remb.bitrate_bps())); +} + void RtcpTransceiverImpl::HandleRtpFeedback( const rtcp::CommonHeader& rtcp_packet_header, Timestamp now) { diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.h b/modules/rtp_rtcp/source/rtcp_transceiver_impl.h index 9e0da6a42d..9332691a8b 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.h +++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.h @@ -105,6 +105,8 @@ class RtcpTransceiverImpl { Timestamp now); void HandleRtpFeedback(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now); + void HandlePli(const rtcp::CommonHeader& rtcp_packet_header); + void HandleRemb(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now); void HandleNack(const rtcp::CommonHeader& rtcp_packet_header); void HandleTransportFeedback(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now); diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc index ea6b49525a..5da10c898a 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc +++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc @@ -87,6 +87,7 @@ class MockRtpStreamRtcpHandler : public RtpStreamRtcpHandler { OnNack, (uint32_t, rtc::ArrayView), (override)); + MOCK_METHOD(void, OnPli, (uint32_t), (override)); private: int num_calls_ = 0; @@ -1094,6 +1095,27 @@ TEST(RtcpTransceiverImplTest, RequestKeyFrameWithPictureLossIndication) { EXPECT_EQ(rtcp_parser.pli()->media_ssrc(), kRemoteSsrc); } +TEST(RtcpTransceiverImplTest, ReceivesPictureLossIndication) { + static constexpr uint32_t kRemoteSsrc = 4321; + static constexpr uint32_t kMediaSsrc1 = 1234; + static constexpr uint32_t kMediaSsrc2 = 1235; + RtcpTransceiverConfig config = DefaultTestConfig(); + RtcpTransceiverImpl rtcp_transceiver(config); + + MockRtpStreamRtcpHandler local_stream1; + MockRtpStreamRtcpHandler local_stream2; + EXPECT_CALL(local_stream1, OnPli(kRemoteSsrc)); + EXPECT_CALL(local_stream2, OnPli).Times(0); + + EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc1, &local_stream1)); + EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc2, &local_stream2)); + + rtcp::Pli pli; + pli.SetSenderSsrc(kRemoteSsrc); + pli.SetMediaSsrc(kMediaSsrc1); + rtcp_transceiver.ReceivePacket(pli.Build(), config.clock->CurrentTime()); +} + TEST(RtcpTransceiverImplTest, RequestKeyFrameWithFullIntraRequest) { const uint32_t kSenderSsrc = 1234; const uint32_t kRemoteSsrcs[] = {4321, 5321};