From 34554815540ebb8d1f296124ceb42aed6e11bc74 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Thu, 31 Mar 2022 14:43:56 +0200 Subject: [PATCH] In RtcpTrasnceiver notify RtpStreamRtcpHandler on related report blocks Bug: webrtc:8239 Change-Id: Ib914775020b5d889b68d1fe178a9fff6acbaeb8f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257283 Reviewed-by: Emil Lundmark Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#36398} --- .../rtp_rtcp/source/rtcp_transceiver_config.h | 2 + .../rtp_rtcp/source/rtcp_transceiver_impl.cc | 16 ++++++ .../rtp_rtcp/source/rtcp_transceiver_impl.h | 3 ++ .../source/rtcp_transceiver_impl_unittest.cc | 52 +++++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_config.h b/modules/rtp_rtcp/source/rtcp_transceiver_config.h index 774e2510af..89792ef637 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_config.h +++ b/modules/rtp_rtcp/source/rtcp_transceiver_config.h @@ -102,6 +102,8 @@ class RtpStreamRtcpHandler { rtc::ArrayView sequence_numbers) {} virtual void OnFir(uint32_t sender_ssrc) {} virtual void OnPli(uint32_t sender_ssrc) {} + virtual void OnReportBlock(uint32_t sender_ssrc, + const rtcp::ReportBlock& report_block) {} }; struct RtcpTransceiverConfig { diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc index b85d1bc967..9dcf14ce9a 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc +++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc @@ -316,6 +316,7 @@ void RtcpTransceiverImpl::HandleSenderReport( remote_senders_[sender_report.sender_ssrc()]; remote_sender.last_received_sender_report = {{now, sender_report.ntp()}}; const auto& received_report_blocks = sender_report.report_blocks(); + CallbackOnReportBlocks(sender_report.sender_ssrc(), received_report_blocks); report_blocks.insert(report_blocks.end(), received_report_blocks.begin(), received_report_blocks.end()); @@ -332,10 +333,25 @@ void RtcpTransceiverImpl::HandleReceiverReport( return; } const auto& received_report_blocks = receiver_report.report_blocks(); + CallbackOnReportBlocks(receiver_report.sender_ssrc(), received_report_blocks); report_blocks.insert(report_blocks.end(), received_report_blocks.begin(), received_report_blocks.end()); } +void RtcpTransceiverImpl::CallbackOnReportBlocks( + uint32_t sender_ssrc, + rtc::ArrayView report_blocks) { + if (local_senders_.empty()) { + return; + } + for (const rtcp::ReportBlock& block : report_blocks) { + auto sender_it = local_senders_by_ssrc_.find(block.source_ssrc()); + if (sender_it != local_senders_by_ssrc_.end()) { + sender_it->second->handler->OnReportBlock(sender_ssrc, block); + } + } +} + void RtcpTransceiverImpl::HandlePayloadSpecificFeedback( 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 d4483f084d..fcae78dd0a 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.h +++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.h @@ -100,6 +100,9 @@ class RtcpTransceiverImpl { std::vector& report_blocks); void HandleReceiverReport(const rtcp::CommonHeader& rtcp_packet_header, std::vector& report_blocks); + void CallbackOnReportBlocks( + uint32_t sender_ssrc, + rtc::ArrayView report_blocks); void HandlePayloadSpecificFeedback( 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 08bc4632a9..19ccdac670 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc +++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc @@ -89,6 +89,10 @@ class MockRtpStreamRtcpHandler : public RtpStreamRtcpHandler { (override)); MOCK_METHOD(void, OnFir, (uint32_t), (override)); MOCK_METHOD(void, OnPli, (uint32_t), (override)); + MOCK_METHOD(void, + OnReportBlock, + (uint32_t, const rtcp::ReportBlock&), + (override)); private: int num_calls_ = 0; @@ -1539,6 +1543,54 @@ TEST(RtcpTransceiverImplTest, rtcp_transceiver.ReceivePacket(packet.Build(), receive_time); } +TEST(RtcpTransceiverImplTest, + CallbackOnReportBlocksFromSenderAndReceiverReports) { + static constexpr uint32_t kRemoteSsrc = 5678; + // Has registered sender, report block attached to sender report. + static constexpr uint32_t kMediaSsrc1 = 1234; + // No registered sender, report block attached to receiver report. + // Such report block shouldn't prevent handling following report block. + static constexpr uint32_t kMediaSsrc2 = 1235; + // Has registered sender, no report block attached. + static constexpr uint32_t kMediaSsrc3 = 1236; + // Has registered sender, report block attached to receiver report. + static constexpr uint32_t kMediaSsrc4 = 1237; + + MockNetworkLinkRtcpObserver link_observer; + RtcpTransceiverConfig config = DefaultTestConfig(); + Timestamp receive_time = Timestamp::Seconds(5678); + RtcpTransceiverImpl rtcp_transceiver(config); + + MockRtpStreamRtcpHandler local_stream1; + MockRtpStreamRtcpHandler local_stream3; + MockRtpStreamRtcpHandler local_stream4; + EXPECT_CALL(local_stream1, OnReportBlock(kRemoteSsrc, _)); + EXPECT_CALL(local_stream3, OnReportBlock).Times(0); + EXPECT_CALL(local_stream4, OnReportBlock(kRemoteSsrc, _)); + + ASSERT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc1, &local_stream1)); + ASSERT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc3, &local_stream3)); + ASSERT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc4, &local_stream4)); + + // Assemble compound packet with multiple RTCP packets in it. + rtcp::CompoundPacket packet; + auto sr = std::make_unique(); + sr->SetSenderSsrc(kRemoteSsrc); + std::vector rb(1); + rb[0].SetMediaSsrc(kMediaSsrc1); + sr->SetReportBlocks(std::move(rb)); + packet.Append(std::move(sr)); + auto rr = std::make_unique(); + rr->SetSenderSsrc(kRemoteSsrc); + rb = std::vector(2); + rb[0].SetMediaSsrc(kMediaSsrc2); + rb[1].SetMediaSsrc(kMediaSsrc4); + rr->SetReportBlocks(std::move(rb)); + packet.Append(std::move(rr)); + + rtcp_transceiver.ReceivePacket(packet.Build(), receive_time); +} + TEST(RtcpTransceiverImplTest, FailsToRegisterTwoSendersWithTheSameSsrc) { RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig()); MockRtpStreamRtcpHandler sender1;