diff --git a/webrtc/call/BUILD.gn b/webrtc/call/BUILD.gn index 8f0f38b9d5..aa98053cb7 100644 --- a/webrtc/call/BUILD.gn +++ b/webrtc/call/BUILD.gn @@ -37,25 +37,16 @@ rtc_source_set("call_interfaces") { # when interfaces have stabilized. rtc_source_set("rtp_interfaces") { sources = [ - "rtcp_packet_sink_interface.h", "rtp_packet_sink_interface.h", "rtp_stream_receiver_controller_interface.h", "rtp_transport_controller_send_interface.h", ] - deps = [ - "//webrtc/base:rtc_base_approved", - ] } rtc_source_set("rtp_receiver") { sources = [ - "rsid_resolution_observer.h", - "rtcp_demuxer.cc", - "rtcp_demuxer.h", "rtp_demuxer.cc", "rtp_demuxer.h", - "rtp_rtcp_demuxer_helper.cc", - "rtp_rtcp_demuxer_helper.h", "rtp_stream_receiver_controller.cc", "rtp_stream_receiver_controller.h", "rtx_receive_stream.cc", @@ -63,9 +54,8 @@ rtc_source_set("rtp_receiver") { ] deps = [ ":rtp_interfaces", + "../base:rtc_base_approved", "../modules/rtp_rtcp", - "//webrtc:webrtc_common", - "//webrtc/base:rtc_base_approved", ] } @@ -137,9 +127,7 @@ if (rtc_include_tests) { "bitrate_estimator_tests.cc", "call_unittest.cc", "flexfec_receive_stream_unittest.cc", - "rtcp_demuxer_unittest.cc", "rtp_demuxer_unittest.cc", - "rtp_rtcp_demuxer_helper_unittest.cc", "rtx_receive_stream_unittest.cc", ] deps = [ @@ -165,7 +153,6 @@ if (rtc_include_tests) { "../test:video_test_common", "//testing/gmock", "//testing/gtest", - "//webrtc:webrtc_common", ] if (!build_with_chromium && is_clang) { # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163). diff --git a/webrtc/call/rsid_resolution_observer.h b/webrtc/call/rsid_resolution_observer.h deleted file mode 100644 index b14fa9da3f..0000000000 --- a/webrtc/call/rsid_resolution_observer.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef WEBRTC_CALL_RSID_RESOLUTION_OBSERVER_H_ -#define WEBRTC_CALL_RSID_RESOLUTION_OBSERVER_H_ - -#include - -#include "webrtc/base/basictypes.h" - -namespace webrtc { - -// One RSID can be associated with one, and only one, SSRC, throughout a call. -// The resolution might either happen during call setup, or during the call. -class RsidResolutionObserver { - public: - virtual ~RsidResolutionObserver() = default; - - virtual void OnRsidResolved(const std::string& rsid, uint32_t ssrc) = 0; -}; - -} // namespace webrtc - -#endif // WEBRTC_CALL_RSID_RESOLUTION_OBSERVER_H_ diff --git a/webrtc/call/rtcp_demuxer.cc b/webrtc/call/rtcp_demuxer.cc deleted file mode 100644 index 6054fc0541..0000000000 --- a/webrtc/call/rtcp_demuxer.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/call/rtcp_demuxer.h" - -#include "webrtc/base/checks.h" -#include "webrtc/call/rtcp_packet_sink_interface.h" -#include "webrtc/call/rtp_rtcp_demuxer_helper.h" -#include "webrtc/common_types.h" - -namespace webrtc { - -RtcpDemuxer::RtcpDemuxer() = default; - -RtcpDemuxer::~RtcpDemuxer() { - RTC_DCHECK(ssrc_sinks_.empty()); - RTC_DCHECK(rsid_sinks_.empty()); - RTC_DCHECK(broadcast_sinks_.empty()); -} - -void RtcpDemuxer::AddSink(uint32_t sender_ssrc, RtcpPacketSinkInterface* sink) { - RTC_DCHECK(sink); - RTC_DCHECK(!ContainerHasKey(broadcast_sinks_, sink)); - RTC_DCHECK(!MultimapAssociationExists(ssrc_sinks_, sender_ssrc, sink)); - ssrc_sinks_.emplace(sender_ssrc, sink); -} - -void RtcpDemuxer::AddSink(const std::string& rsid, - RtcpPacketSinkInterface* sink) { - RTC_DCHECK(StreamId::IsLegalName(rsid)); - RTC_DCHECK(sink); - RTC_DCHECK(!ContainerHasKey(broadcast_sinks_, sink)); - RTC_DCHECK(!MultimapAssociationExists(rsid_sinks_, rsid, sink)); - rsid_sinks_.emplace(rsid, sink); -} - -void RtcpDemuxer::AddBroadcastSink(RtcpPacketSinkInterface* sink) { - RTC_DCHECK(sink); - RTC_DCHECK(!MultimapHasValue(ssrc_sinks_, sink)); - RTC_DCHECK(!MultimapHasValue(rsid_sinks_, sink)); - RTC_DCHECK(!ContainerHasKey(broadcast_sinks_, sink)); - broadcast_sinks_.push_back(sink); -} - -void RtcpDemuxer::RemoveSink(const RtcpPacketSinkInterface* sink) { - RTC_DCHECK(sink); - size_t removal_count = RemoveFromMultimapByValue(&ssrc_sinks_, sink) + - RemoveFromMultimapByValue(&rsid_sinks_, sink); - RTC_DCHECK_GT(removal_count, 0); -} - -void RtcpDemuxer::RemoveBroadcastSink(const RtcpPacketSinkInterface* sink) { - RTC_DCHECK(sink); - auto it = std::find(broadcast_sinks_.begin(), broadcast_sinks_.end(), sink); - RTC_DCHECK(it != broadcast_sinks_.end()); - broadcast_sinks_.erase(it); -} - -void RtcpDemuxer::OnRtcpPacket(rtc::ArrayView packet) { - // Perform sender-SSRC-based demuxing for packets with a sender-SSRC. - rtc::Optional sender_ssrc = ParseRtcpPacketSenderSsrc(packet); - if (sender_ssrc) { - auto it_range = ssrc_sinks_.equal_range(*sender_ssrc); - for (auto it = it_range.first; it != it_range.second; ++it) { - it->second->OnRtcpPacket(packet); - } - } - - // All packets, even those without a sender-SSRC, are broadcast to sinks - // which listen to broadcasts. - for (RtcpPacketSinkInterface* sink : broadcast_sinks_) { - sink->OnRtcpPacket(packet); - } -} - -void RtcpDemuxer::OnRsidResolved(const std::string& rsid, uint32_t ssrc) { - // Record the new SSRC association for all of the sinks that were associated - // with the RSID. - auto it_range = rsid_sinks_.equal_range(rsid); - for (auto it = it_range.first; it != it_range.second; ++it) { - RtcpPacketSinkInterface* sink = it->second; - // Watch out for pre-existing SSRC-based associations. - if (!MultimapAssociationExists(ssrc_sinks_, ssrc, sink)) { - AddSink(ssrc, sink); - } - } - - // RSIDs are uniquely associated with SSRCs; no need to keep in memory - // the RSID-to-sink association of resolved RSIDs. - rsid_sinks_.erase(it_range.first, it_range.second); -} - -} // namespace webrtc diff --git a/webrtc/call/rtcp_demuxer.h b/webrtc/call/rtcp_demuxer.h deleted file mode 100644 index c5c1621036..0000000000 --- a/webrtc/call/rtcp_demuxer.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_CALL_RTCP_DEMUXER_H_ -#define WEBRTC_CALL_RTCP_DEMUXER_H_ - -#include -#include -#include - -#include "webrtc/base/array_view.h" -#include "webrtc/base/basictypes.h" -#include "webrtc/call/rsid_resolution_observer.h" - -namespace webrtc { - -class RtcpPacketSinkInterface; - -// This class represents the RTCP demuxing, for a single RTP session (i.e., one -// SSRC space, see RFC 7656). It isn't thread aware, leaving responsibility of -// multithreading issues to the user of this class. -class RtcpDemuxer : public RsidResolutionObserver { - public: - RtcpDemuxer(); - ~RtcpDemuxer() override; - - // Registers a sink. The sink will be notified of incoming RTCP packets with - // that sender-SSRC. The same sink can be registered for multiple SSRCs, and - // the same SSRC can have multiple sinks. Null pointer is not allowed. - // Sinks may be associated with both an SSRC and an RSID. - // Sinks may be registered as SSRC/RSID-specific or broadcast, but not both. - void AddSink(uint32_t sender_ssrc, RtcpPacketSinkInterface* sink); - - // Registers a sink. Once the RSID is resolved to an SSRC, the sink will be - // notified of all RTCP packets with that sender-SSRC. - // The same sink can be registered for multiple RSIDs, and - // the same RSID can have multiple sinks. Null pointer is not allowed. - // Sinks may be associated with both an SSRC and an RSID. - // Sinks may be registered as SSRC/RSID-specific or broadcast, but not both. - void AddSink(const std::string& rsid, RtcpPacketSinkInterface* sink); - - // Registers a sink. The sink will be notified of any incoming RTCP packet. - // Null pointer is not allowed. - // Sinks may be registered as SSRC/RSID-specific or broadcast, but not both. - void AddBroadcastSink(RtcpPacketSinkInterface* sink); - - // Undo previous AddSink() calls with the given sink. - void RemoveSink(const RtcpPacketSinkInterface* sink); - - // Undo AddBroadcastSink(). - void RemoveBroadcastSink(const RtcpPacketSinkInterface* sink); - - // Process a new RTCP packet and forward it to the appropriate sinks. - void OnRtcpPacket(rtc::ArrayView packet); - - // Implement RsidResolutionObserver - become notified whenever RSIDs resolve - // to an SSRC. - void OnRsidResolved(const std::string& rsid, uint32_t ssrc) override; - - // TODO(eladalon): Add the ability to resolve RSIDs and inform observers, - // like in the RtpDemuxer case, once the relevant standard is finalized. - - private: - // Records the association SSRCs to sinks. - std::multimap ssrc_sinks_; - - // Records the association RSIDs to sinks. - std::multimap rsid_sinks_; - - // Sinks which will receive notifications of all incoming RTCP packets. - // Additional/removal of sinks is expected to be significantly less frequent - // than RTCP message reception; container chosen for iteration performance. - std::vector broadcast_sinks_; -}; - -} // namespace webrtc - -#endif // WEBRTC_CALL_RTCP_DEMUXER_H_ diff --git a/webrtc/call/rtcp_demuxer_unittest.cc b/webrtc/call/rtcp_demuxer_unittest.cc deleted file mode 100644 index 49f037c4f5..0000000000 --- a/webrtc/call/rtcp_demuxer_unittest.cc +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/call/rtcp_demuxer.h" - -#include - -#include "webrtc/base/arraysize.h" -#include "webrtc/base/basictypes.h" -#include "webrtc/base/checks.h" -#include "webrtc/base/ptr_util.h" -#include "webrtc/call/rtcp_packet_sink_interface.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h" -#include "webrtc/test/gmock.h" -#include "webrtc/test/gtest.h" - -namespace webrtc { - -namespace { - -using ::testing::_; -using ::testing::AtLeast; -using ::testing::ElementsAreArray; -using ::testing::InSequence; -using ::testing::NiceMock; - -class MockRtcpPacketSink : public RtcpPacketSinkInterface { - public: - MOCK_METHOD1(OnRtcpPacket, void(rtc::ArrayView)); -}; - -// Produces a packet buffer representing an RTCP packet with a given SSRC, -// as it would look when sent over the wire. -// |distinguishing_string| allows different RTCP packets with the same SSRC -// to be distinguished. How this is set into the actual packet is -// unimportant, and depends on which RTCP message we choose to use. -rtc::Buffer CreateRtcpPacket(uint32_t ssrc, - const std::string& distinguishing_string = "") { - rtcp::Bye packet; - packet.SetSenderSsrc(ssrc); - if (distinguishing_string != "") { - // Actual way we use |distinguishing_string| is unimportant, so long - // as it ends up in the packet. - packet.SetReason(distinguishing_string); - } - return packet.Build(); -} - -} // namespace - -TEST(RtcpDemuxerTest, OnRtcpPacketCalledOnCorrectSinkBySsrc) { - RtcpDemuxer demuxer; - - constexpr uint32_t ssrcs[] = {101, 202, 303}; - MockRtcpPacketSink sinks[arraysize(ssrcs)]; - for (size_t i = 0; i < arraysize(ssrcs); i++) { - demuxer.AddSink(ssrcs[i], &sinks[i]); - } - - for (size_t i = 0; i < arraysize(ssrcs); i++) { - auto packet = CreateRtcpPacket(ssrcs[i]); - EXPECT_CALL(sinks[i], - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) - .Times(1); - demuxer.OnRtcpPacket(packet); - } - - // Test tear-down - for (const auto& sink : sinks) { - demuxer.RemoveSink(&sink); - } -} - -TEST(RtcpDemuxerTest, OnRtcpPacketCalledOnResolvedRsidSink) { - RtcpDemuxer demuxer; - - // Set up some RSID sinks. - const std::string rsids[] = {"a", "b", "c"}; - MockRtcpPacketSink sinks[arraysize(rsids)]; - for (size_t i = 0; i < arraysize(rsids); i++) { - demuxer.AddSink(rsids[i], &sinks[i]); - } - - // Only resolve one of the sinks. - constexpr size_t resolved_sink_index = 0; - constexpr uint32_t ssrc = 345; - demuxer.OnRsidResolved(rsids[resolved_sink_index], ssrc); - - // The resolved sink gets notifications of RTCP messages with its SSRC. - auto packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sinks[resolved_sink_index], - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) - .Times(1); - - // RTCP received; expected calls triggered. - demuxer.OnRtcpPacket(packet); - - // Test tear-down - for (const auto& sink : sinks) { - demuxer.RemoveSink(&sink); - } -} - -TEST(RtcpDemuxerTest, - SingleCallbackAfterResolutionOfAnRsidToAlreadyRegisteredSsrc) { - RtcpDemuxer demuxer; - - // Associate a sink with an SSRC. - MockRtcpPacketSink sink; - constexpr uint32_t ssrc = 999; - demuxer.AddSink(ssrc, &sink); - - // Associate the same sink with an RSID. - const std::string rsid = "r"; - demuxer.AddSink(rsid, &sink); - - // Resolve the RSID to the aforementioned SSRC. - demuxer.OnRsidResolved(rsid, ssrc); - - // OnRtcpPacket still called only a single time for messages with this SSRC. - auto packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sink, - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) - .Times(1); - demuxer.OnRtcpPacket(packet); - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -TEST(RtcpDemuxerTest, OnRtcpPacketCalledOnAllBroadcastSinksForAllRtcpPackets) { - RtcpDemuxer demuxer; - - MockRtcpPacketSink sinks[3]; - for (MockRtcpPacketSink& sink : sinks) { - demuxer.AddBroadcastSink(&sink); - } - - constexpr uint32_t ssrc = 747; - auto packet = CreateRtcpPacket(ssrc); - - for (MockRtcpPacketSink& sink : sinks) { - EXPECT_CALL(sink, - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) - .Times(1); - } - - // RTCP received; expected calls triggered. - demuxer.OnRtcpPacket(packet); - - // Test tear-down - for (const auto& sink : sinks) { - demuxer.RemoveBroadcastSink(&sink); - } -} - -TEST(RtcpDemuxerTest, PacketsDeliveredInRightOrderToNonBroadcastSink) { - RtcpDemuxer demuxer; - - constexpr uint32_t ssrc = 101; - MockRtcpPacketSink sink; - demuxer.AddSink(ssrc, &sink); - - std::vector packets; - for (size_t i = 0; i < 5; i++) { - packets.push_back(CreateRtcpPacket(ssrc, std::to_string(i))); - } - - InSequence sequence; - for (const auto& packet : packets) { - EXPECT_CALL(sink, - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) - .Times(1); - } - - for (const auto& packet : packets) { - demuxer.OnRtcpPacket(packet); - } - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -TEST(RtcpDemuxerTest, PacketsDeliveredInRightOrderToBroadcastSink) { - RtcpDemuxer demuxer; - - MockRtcpPacketSink sink; - demuxer.AddBroadcastSink(&sink); - - std::vector packets; - for (size_t i = 0; i < 5; i++) { - constexpr uint32_t ssrc = 101; - packets.push_back(CreateRtcpPacket(ssrc, std::to_string(i))); - } - - InSequence sequence; - for (const auto& packet : packets) { - EXPECT_CALL(sink, - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) - .Times(1); - } - - for (const auto& packet : packets) { - demuxer.OnRtcpPacket(packet); - } - - // Test tear-down - demuxer.RemoveBroadcastSink(&sink); -} - -TEST(RtcpDemuxerTest, MultipleSinksMappedToSameSsrc) { - RtcpDemuxer demuxer; - - MockRtcpPacketSink sinks[3]; - constexpr uint32_t ssrc = 404; - for (auto& sink : sinks) { - demuxer.AddSink(ssrc, &sink); - } - - // Reception of an RTCP packet associated with the shared SSRC triggers the - // callback on all of the sinks associated with it. - auto packet = CreateRtcpPacket(ssrc); - for (auto& sink : sinks) { - EXPECT_CALL(sink, - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))); - } - demuxer.OnRtcpPacket(packet); - - // Test tear-down - for (const auto& sink : sinks) { - demuxer.RemoveSink(&sink); - } -} - -TEST(RtcpDemuxerTest, SinkMappedToMultipleSsrcs) { - RtcpDemuxer demuxer; - - constexpr uint32_t ssrcs[] = {404, 505, 606}; - MockRtcpPacketSink sink; - for (uint32_t ssrc : ssrcs) { - demuxer.AddSink(ssrc, &sink); - } - - // The sink which is associated with multiple SSRCs gets the callback - // triggered for each of those SSRCs. - for (uint32_t ssrc : ssrcs) { - auto packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sink, - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))); - demuxer.OnRtcpPacket(packet); - } - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -TEST(RtcpDemuxerTest, MultipleRsidsOnSameSink) { - RtcpDemuxer demuxer; - - // Sink associated with multiple sinks. - MockRtcpPacketSink sink; - const std::string rsids[] = {"a", "b", "c"}; - for (const auto& rsid : rsids) { - demuxer.AddSink(rsid, &sink); - } - - // RSIDs resolved to SSRCs. - uint32_t ssrcs[arraysize(rsids)]; - for (size_t i = 0; i < arraysize(rsids); i++) { - ssrcs[i] = 1000 + static_cast(i); - demuxer.OnRsidResolved(rsids[i], ssrcs[i]); - } - - // Set up packets to match those RSIDs/SSRCs. - std::vector packets; - for (size_t i = 0; i < arraysize(rsids); i++) { - packets.push_back(CreateRtcpPacket(ssrcs[i])); - } - - // The sink expects to receive all of the packets. - for (const auto& packet : packets) { - EXPECT_CALL(sink, - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) - .Times(1); - } - - // Packet demuxed correctly; OnRtcpPacket() triggered on sink. - for (const auto& packet : packets) { - demuxer.OnRtcpPacket(packet); - } - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -TEST(RtcpDemuxerTest, RsidUsedByMultipleSinks) { - RtcpDemuxer demuxer; - - MockRtcpPacketSink sinks[3]; - const std::string shared_rsid = "a"; - - for (MockRtcpPacketSink& sink : sinks) { - demuxer.AddSink(shared_rsid, &sink); - } - - constexpr uint32_t shared_ssrc = 888; - demuxer.OnRsidResolved(shared_rsid, shared_ssrc); - - auto packet = CreateRtcpPacket(shared_ssrc); - - for (MockRtcpPacketSink& sink : sinks) { - EXPECT_CALL(sink, - OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) - .Times(1); - } - - demuxer.OnRtcpPacket(packet); - - // Test tear-down - for (MockRtcpPacketSink& sink : sinks) { - demuxer.RemoveSink(&sink); - } -} - -TEST(RtcpDemuxerTest, NoCallbackOnSsrcSinkRemovedBeforeFirstPacket) { - RtcpDemuxer demuxer; - - constexpr uint32_t ssrc = 404; - MockRtcpPacketSink sink; - demuxer.AddSink(ssrc, &sink); - - demuxer.RemoveSink(&sink); - - // The removed sink does not get callbacks. - auto packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. - demuxer.OnRtcpPacket(packet); -} - -TEST(RtcpDemuxerTest, NoCallbackOnSsrcSinkRemovedAfterFirstPacket) { - RtcpDemuxer demuxer; - - constexpr uint32_t ssrc = 404; - NiceMock sink; - demuxer.AddSink(ssrc, &sink); - - auto before_packet = CreateRtcpPacket(ssrc); - demuxer.OnRtcpPacket(before_packet); - - demuxer.RemoveSink(&sink); - - // The removed sink does not get callbacks. - auto after_packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. - demuxer.OnRtcpPacket(after_packet); -} - -TEST(RtcpDemuxerTest, NoCallbackOnRsidSinkRemovedBeforeRsidResolution) { - RtcpDemuxer demuxer; - - const std::string rsid = "a"; - constexpr uint32_t ssrc = 404; - MockRtcpPacketSink sink; - demuxer.AddSink(rsid, &sink); - - // Removal before resolution. - demuxer.RemoveSink(&sink); - demuxer.OnRsidResolved(rsid, ssrc); - - // The removed sink does not get callbacks. - auto packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. - demuxer.OnRtcpPacket(packet); -} - -TEST(RtcpDemuxerTest, NoCallbackOnRsidSinkRemovedAfterRsidResolution) { - RtcpDemuxer demuxer; - - const std::string rsid = "a"; - constexpr uint32_t ssrc = 404; - MockRtcpPacketSink sink; - demuxer.AddSink(rsid, &sink); - - // Removal after resolution. - demuxer.OnRsidResolved(rsid, ssrc); - demuxer.RemoveSink(&sink); - - // The removed sink does not get callbacks. - auto packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. - demuxer.OnRtcpPacket(packet); -} - -TEST(RtcpDemuxerTest, NoCallbackOnBroadcastSinkRemovedBeforeFirstPacket) { - RtcpDemuxer demuxer; - - MockRtcpPacketSink sink; - demuxer.AddBroadcastSink(&sink); - - demuxer.RemoveBroadcastSink(&sink); - - // The removed sink does not get callbacks. - constexpr uint32_t ssrc = 404; - auto packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. - demuxer.OnRtcpPacket(packet); -} - -TEST(RtcpDemuxerTest, NoCallbackOnBroadcastSinkRemovedAfterFirstPacket) { - RtcpDemuxer demuxer; - - NiceMock sink; - demuxer.AddBroadcastSink(&sink); - - constexpr uint32_t ssrc = 404; - auto before_packet = CreateRtcpPacket(ssrc); - demuxer.OnRtcpPacket(before_packet); - - demuxer.RemoveBroadcastSink(&sink); - - // The removed sink does not get callbacks. - auto after_packet = CreateRtcpPacket(ssrc); - EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. - demuxer.OnRtcpPacket(after_packet); -} - -// The RSID to SSRC mapping should be one-to-one. If we end up receiving -// two (or more) packets with the same SSRC, but different RSIDs, we guarantee -// remembering the first one; no guarantees are made about further associations. -TEST(RtcpDemuxerTest, FirstRsolutionOfRsidNotForgotten) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - const std::string rsid = "a"; - demuxer.AddSink(rsid, &sink); - - constexpr uint32_t ssrc_a = 111; // First resolution - guaranteed effective. - demuxer.OnRsidResolved(rsid, ssrc_a); - - constexpr uint32_t ssrc_b = 222; // Second resolution - no guarantees. - demuxer.OnRsidResolved(rsid, ssrc_b); - - auto packet_a = CreateRtcpPacket(ssrc_a); - EXPECT_CALL( - sink, OnRtcpPacket(ElementsAreArray(packet_a.cbegin(), packet_a.cend()))) - .Times(1); - demuxer.OnRtcpPacket(packet_a); - - auto packet_b = CreateRtcpPacket(ssrc_b); - EXPECT_CALL( - sink, OnRtcpPacket(ElementsAreArray(packet_b.cbegin(), packet_b.cend()))) - .Times(AtLeast(0)); - demuxer.OnRtcpPacket(packet_b); - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) -TEST(RtcpDemuxerTest, RepeatedSsrcToSinkAssociationsDisallowed) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - constexpr uint32_t ssrc = 101; - demuxer.AddSink(ssrc, &sink); - EXPECT_DEATH(demuxer.AddSink(ssrc, &sink), ""); - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -TEST(RtcpDemuxerTest, RepeatedRsidToSinkAssociationsDisallowed) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - const std::string rsid = "z"; - demuxer.AddSink(rsid, &sink); - EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -TEST(RtcpDemuxerTest, RepeatedBroadcastSinkRegistrationDisallowed) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - demuxer.AddBroadcastSink(&sink); - EXPECT_DEATH(demuxer.AddBroadcastSink(&sink), ""); - - // Test tear-down - demuxer.RemoveBroadcastSink(&sink); -} - -TEST(RtcpDemuxerTest, SsrcSinkCannotAlsoBeRegisteredAsBroadcast) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - constexpr uint32_t ssrc = 101; - demuxer.AddSink(ssrc, &sink); - EXPECT_DEATH(demuxer.AddBroadcastSink(&sink), ""); - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -TEST(RtcpDemuxerTest, RsidSinkCannotAlsoBeRegisteredAsBroadcast) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - const std::string rsid = "z"; - demuxer.AddSink(rsid, &sink); - EXPECT_DEATH(demuxer.AddBroadcastSink(&sink), ""); - - // Test tear-down - demuxer.RemoveSink(&sink); -} - -TEST(RtcpDemuxerTest, BroadcastSinkCannotAlsoBeRegisteredAsSsrcSink) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - demuxer.AddBroadcastSink(&sink); - constexpr uint32_t ssrc = 101; - EXPECT_DEATH(demuxer.AddSink(ssrc, &sink), ""); - - // Test tear-down - demuxer.RemoveBroadcastSink(&sink); -} - -TEST(RtcpDemuxerTest, BroadcastSinkCannotAlsoBeRegisteredAsRsidSink) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - demuxer.AddBroadcastSink(&sink); - const std::string rsid = "j"; - EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); - - // Test tear-down - demuxer.RemoveBroadcastSink(&sink); -} - -TEST(RtcpDemuxerTest, MayNotCallRemoveSinkOnNeverAddedSink) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - EXPECT_DEATH(demuxer.RemoveSink(&sink), ""); -} - -TEST(RtcpDemuxerTest, MayNotCallRemoveBroadcastSinkOnNeverAddedSink) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - - EXPECT_DEATH(demuxer.RemoveBroadcastSink(&sink), ""); -} - -TEST(RtcpDemuxerTest, RsidMustBeNonEmpty) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - EXPECT_DEATH(demuxer.AddSink("", &sink), ""); -} - -TEST(RtcpDemuxerTest, RsidMustBeAlphaNumeric) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - EXPECT_DEATH(demuxer.AddSink("a_3", &sink), ""); -} - -TEST(RtcpDemuxerTest, RsidMustNotExceedMaximumLength) { - RtcpDemuxer demuxer; - MockRtcpPacketSink sink; - std::string rsid(StreamId::kMaxSize + 1, 'a'); - EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); -} -#endif -} // namespace webrtc diff --git a/webrtc/call/rtcp_packet_sink_interface.h b/webrtc/call/rtcp_packet_sink_interface.h deleted file mode 100644 index e26bd37c50..0000000000 --- a/webrtc/call/rtcp_packet_sink_interface.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef WEBRTC_CALL_RTCP_PACKET_SINK_INTERFACE_H_ -#define WEBRTC_CALL_RTCP_PACKET_SINK_INTERFACE_H_ - -#include "webrtc/base/array_view.h" - -namespace webrtc { - -// This class represents a receiver of unparsed RTCP packets. -// TODO(eladalon): Replace this by demuxing over parsed rather than raw data. -// Whether this should be over an entire RTCP packet, or over RTCP blocks, -// is still under discussion. -class RtcpPacketSinkInterface { - public: - virtual ~RtcpPacketSinkInterface() = default; - virtual void OnRtcpPacket(rtc::ArrayView packet) = 0; -}; - -} // namespace webrtc - -#endif // WEBRTC_CALL_RTCP_PACKET_SINK_INTERFACE_H_ diff --git a/webrtc/call/rtp_demuxer.cc b/webrtc/call/rtp_demuxer.cc index e1957ed554..620d4b17a9 100644 --- a/webrtc/call/rtp_demuxer.cc +++ b/webrtc/call/rtp_demuxer.cc @@ -12,27 +12,50 @@ #include "webrtc/base/checks.h" #include "webrtc/base/logging.h" -#include "webrtc/call/rsid_resolution_observer.h" #include "webrtc/call/rtp_packet_sink_interface.h" -#include "webrtc/call/rtp_rtcp_demuxer_helper.h" #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" namespace webrtc { namespace { + constexpr size_t kMaxProcessedSsrcs = 1000; // Prevent memory overuse. + +template +bool MultimapAssociationExists(const std::multimap& multimap, + Key key, + Value val) { + auto it_range = multimap.equal_range(key); + using Reference = typename std::multimap::const_reference; + return std::any_of(it_range.first, it_range.second, + [val](Reference elem) { return elem.second == val; }); +} + +template +size_t RemoveFromMultimapByValue(std::multimap* multimap, + const Value* value) { + size_t count = 0; + for (auto it = multimap->begin(); it != multimap->end();) { + if (it->second == value) { + it = multimap->erase(it); + ++count; + } else { + ++it; + } + } + return count; +} + } // namespace -RtpDemuxer::RtpDemuxer() = default; +RtpDemuxer::RtpDemuxer() {} RtpDemuxer::~RtpDemuxer() { RTC_DCHECK(sinks_.empty()); - RTC_DCHECK(rsid_sinks_.empty()); } void RtpDemuxer::AddSink(uint32_t ssrc, RtpPacketSinkInterface* sink) { - RTC_DCHECK(sink); RecordSsrcToSinkAssociation(ssrc, sink); } @@ -65,7 +88,7 @@ void RtpDemuxer::RecordSsrcToSinkAssociation(uint32_t ssrc, } bool RtpDemuxer::OnRtpPacket(const RtpPacketReceived& packet) { - ResolveAssociations(packet); + FindSsrcAssociations(packet); auto it_range = sinks_.equal_range(packet.Ssrc()); for (auto it = it_range.first; it != it_range.second; ++it) { it->second->OnRtpPacket(packet); @@ -73,33 +96,27 @@ bool RtpDemuxer::OnRtpPacket(const RtpPacketReceived& packet) { return it_range.first != it_range.second; } -void RtpDemuxer::RegisterRsidResolutionObserver( - RsidResolutionObserver* observer) { - RTC_DCHECK(observer); - RTC_DCHECK(!ContainerHasKey(rsid_resolution_observers_, observer)); - - rsid_resolution_observers_.push_back(observer); - - processed_ssrcs_.clear(); // New observer requires new notifications. -} - -void RtpDemuxer::DeregisterRsidResolutionObserver( - const RsidResolutionObserver* observer) { - RTC_DCHECK(observer); - auto it = std::find(rsid_resolution_observers_.begin(), - rsid_resolution_observers_.end(), observer); - RTC_DCHECK(it != rsid_resolution_observers_.end()); - rsid_resolution_observers_.erase(it); -} - -void RtpDemuxer::ResolveAssociations(const RtpPacketReceived& packet) { +void RtpDemuxer::FindSsrcAssociations(const RtpPacketReceived& packet) { // Avoid expensive string comparisons for RSID by looking the sinks up only // by SSRC whenever possible. if (processed_ssrcs_.find(packet.Ssrc()) != processed_ssrcs_.cend()) { return; } - ResolveRsidToSsrcAssociations(packet); + // RSID-based associations: + std::string rsid; + if (packet.GetExtension(&rsid)) { + // All streams associated with this RSID need to be marked as associated + // with this SSRC (if they aren't already). + auto it_range = rsid_sinks_.equal_range(rsid); + for (auto it = it_range.first; it != it_range.second; ++it) { + RecordSsrcToSinkAssociation(packet.Ssrc(), it->second); + } + + // To prevent memory-overuse attacks, forget this RSID. Future packets + // with this RSID, but a different SSRC, will not spawn new associations. + rsid_sinks_.erase(it_range.first, it_range.second); + } if (processed_ssrcs_.size() < kMaxProcessedSsrcs) { // Prevent memory overuse processed_ssrcs_.insert(packet.Ssrc()); // Avoid re-examining in-depth. @@ -110,30 +127,4 @@ void RtpDemuxer::ResolveAssociations(const RtpPacketReceived& packet) { } } -void RtpDemuxer::ResolveRsidToSsrcAssociations( - const RtpPacketReceived& packet) { - std::string rsid; - if (packet.GetExtension(&rsid)) { - // All streams associated with this RSID need to be marked as associated - // with this SSRC (if they aren't already). - auto it_range = rsid_sinks_.equal_range(rsid); - for (auto it = it_range.first; it != it_range.second; ++it) { - RecordSsrcToSinkAssociation(packet.Ssrc(), it->second); - } - - NotifyObserversOfRsidResolution(rsid, packet.Ssrc()); - - // To prevent memory-overuse attacks, forget this RSID. Future packets - // with this RSID, but a different SSRC, will not spawn new associations. - rsid_sinks_.erase(it_range.first, it_range.second); - } -} - -void RtpDemuxer::NotifyObserversOfRsidResolution(const std::string& rsid, - uint32_t ssrc) { - for (auto* observer : rsid_resolution_observers_) { - observer->OnRsidResolved(rsid, ssrc); - } -} - } // namespace webrtc diff --git a/webrtc/call/rtp_demuxer.h b/webrtc/call/rtp_demuxer.h index 9ec93787de..6a4370d731 100644 --- a/webrtc/call/rtp_demuxer.h +++ b/webrtc/call/rtp_demuxer.h @@ -14,11 +14,9 @@ #include #include #include -#include namespace webrtc { -class RsidResolutionObserver; class RtpPacketReceived; class RtpPacketSinkInterface; @@ -43,16 +41,9 @@ class RtpDemuxer { // Null pointer is not allowed. bool RemoveSink(const RtpPacketSinkInterface* sink); - // Returns true if at least one matching sink was found. + // Returns true if at least one matching sink was found, otherwise false. bool OnRtpPacket(const RtpPacketReceived& packet); - // Allows other objects to be notified when RSID-SSRC associations are - // resolved by this object. - void RegisterRsidResolutionObserver(RsidResolutionObserver* observer); - - // Undo a previous RegisterRsidResolutionObserver(). - void DeregisterRsidResolutionObserver(const RsidResolutionObserver* observer); - private: // Records a sink<->SSRC association. This can happen by explicit // configuration by AddSink(ssrc...), or by inferred configuration from an @@ -60,14 +51,9 @@ class RtpDemuxer { // packet reception. void RecordSsrcToSinkAssociation(uint32_t ssrc, RtpPacketSinkInterface* sink); - // When a new packet arrives, we attempt to resolve extra associations. - void ResolveAssociations(const RtpPacketReceived& packet); - - // Find the associations of RSID to SSRCs. - void ResolveRsidToSsrcAssociations(const RtpPacketReceived& packet); - - // Notify observers of the resolution of an RSID to an SSRC. - void NotifyObserversOfRsidResolution(const std::string& rsid, uint32_t ssrc); + // When a new packet arrives, we attempt to resolve extra associations, + // such as which RSIDs are associated with which SSRCs. + void FindSsrcAssociations(const RtpPacketReceived& packet); // This records the association SSRCs to sinks. Other associations, such // as by RSID, also end up here once the RSID, etc., is resolved to an SSRC. @@ -87,10 +73,6 @@ class RtpDemuxer { // Avoid an attack that would create excessive logging. bool logged_max_processed_ssrcs_exceeded_ = false; - - // Observers which will be notified when an RSID association to an SSRC is - // resolved by this object. - std::vector rsid_resolution_observers_; }; } // namespace webrtc diff --git a/webrtc/call/rtp_demuxer_unittest.cc b/webrtc/call/rtp_demuxer_unittest.cc index 56bfe3c65f..8ca827c94b 100644 --- a/webrtc/call/rtp_demuxer_unittest.cc +++ b/webrtc/call/rtp_demuxer_unittest.cc @@ -14,12 +14,9 @@ #include #include "webrtc/base/arraysize.h" -#include "webrtc/base/basictypes.h" #include "webrtc/base/checks.h" #include "webrtc/base/ptr_util.h" -#include "webrtc/call/rsid_resolution_observer.h" #include "webrtc/call/rtp_packet_sink_interface.h" -#include "webrtc/common_types.h" #include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" @@ -40,11 +37,6 @@ class MockRtpPacketSink : public RtpPacketSinkInterface { MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); }; -class MockRsidResolutionObserver : public RsidResolutionObserver { - public: - MOCK_METHOD2(OnRsidResolved, void(const std::string& rsid, uint32_t ssrc)); -}; - MATCHER_P(SamePacketAs, other, "") { return arg.Ssrc() == other.Ssrc() && arg.SequenceNumber() == other.SequenceNumber(); @@ -127,18 +119,20 @@ TEST(RtpDemuxerTest, OnRtpPacketCalledOnCorrectSinkByRsid) { TEST(RtpDemuxerTest, PacketsDeliveredInRightOrder) { RtpDemuxer demuxer; - constexpr uint32_t ssrc = 101; - MockRtpPacketSink sink; - demuxer.AddSink(ssrc, &sink); + constexpr uint32_t ssrcs[] = {101, 202, 303}; + MockRtpPacketSink sinks[arraysize(ssrcs)]; + for (size_t i = 0; i < arraysize(ssrcs); i++) { + demuxer.AddSink(ssrcs[i], &sinks[i]); + } std::unique_ptr packets[5]; for (size_t i = 0; i < arraysize(packets); i++) { - packets[i] = CreateRtpPacketReceived(ssrc, i); + packets[i] = CreateRtpPacketReceived(ssrcs[0], i); } InSequence sequence; for (const auto& packet : packets) { - EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); + EXPECT_CALL(sinks[0], OnRtpPacket(SamePacketAs(*packet))).Times(1); } for (const auto& packet : packets) { @@ -146,7 +140,9 @@ TEST(RtpDemuxerTest, PacketsDeliveredInRightOrder) { } // Test tear-down - demuxer.RemoveSink(&sink); + for (const auto& sink : sinks) { + demuxer.RemoveSink(&sink); + } } TEST(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { @@ -428,31 +424,6 @@ TEST(RtpDemuxerTest, MultipleRsidsOnSameSink) { demuxer.RemoveSink(&sink); } -TEST(RtpDemuxerTest, RsidUsedByMultipleSinks) { - RtpDemuxer demuxer; - - MockRtpPacketSink sinks[3]; - const std::string shared_rsid = "a"; - - for (MockRtpPacketSink& sink : sinks) { - demuxer.AddSink(shared_rsid, &sink); - } - - constexpr uint32_t shared_ssrc = 888; - auto packet = CreateRtpPacketReceivedWithRsid(shared_rsid, shared_ssrc); - - for (auto& sink : sinks) { - EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); - } - - EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); - - // Test tear-down - for (MockRtpPacketSink& sink : sinks) { - demuxer.RemoveSink(&sink); - } -} - TEST(RtpDemuxerTest, SinkWithBothRsidAndSsrcAssociations) { RtpDemuxer demuxer; @@ -497,88 +468,6 @@ TEST(RtpDemuxerTest, AssociatingByRsidAndBySsrcCannotTriggerDoubleCall) { demuxer.RemoveSink(&sink); } -TEST(RtpDemuxerTest, RsidObserversInformedOfResolutions) { - RtpDemuxer demuxer; - - constexpr uint32_t ssrc = 111; - const std::string rsid = "a"; - - MockRsidResolutionObserver rsid_resolution_observers[3]; - for (auto& observer : rsid_resolution_observers) { - demuxer.RegisterRsidResolutionObserver(&observer); - EXPECT_CALL(observer, OnRsidResolved(rsid, ssrc)).Times(1); - } - - // The expected calls to OnRsidResolved() will be triggered by this. - demuxer.OnRtpPacket(*CreateRtpPacketReceivedWithRsid(rsid, ssrc)); - - // Test tear-down - for (auto& observer : rsid_resolution_observers) { - demuxer.DeregisterRsidResolutionObserver(&observer); - } -} - -// Normally, we only produce one notification per resolution (though no such -// guarantee is made), but when a new observer is added, we reset -// this suppression - we "re-resolve" associations for the benefit of the -// new observer.. -TEST(RtpDemuxerTest, NotificationSuppressionResetWhenNewObserverAdded) { - RtpDemuxer demuxer; - - constexpr uint32_t ssrc = 111; - const std::string rsid = "a"; - - // First observer registered, then gets a notification. - NiceMock first_observer; - demuxer.RegisterRsidResolutionObserver(&first_observer); - demuxer.OnRtpPacket(*CreateRtpPacketReceivedWithRsid(rsid, ssrc)); - - // Second observer registered, then gets a notification. No guarantee is made - // about whether the first observer would get an additional notification. - MockRsidResolutionObserver second_observer; - demuxer.RegisterRsidResolutionObserver(&second_observer); - EXPECT_CALL(first_observer, OnRsidResolved(rsid, ssrc)).Times(AtLeast(0)); - EXPECT_CALL(second_observer, OnRsidResolved(rsid, ssrc)).Times(1); - demuxer.OnRtpPacket(*CreateRtpPacketReceivedWithRsid(rsid, ssrc)); - - // Test tear-down - demuxer.DeregisterRsidResolutionObserver(&first_observer); - demuxer.DeregisterRsidResolutionObserver(&second_observer); -} - -TEST(RtpDemuxerTest, DeregisteredRsidObserversNotInformedOfResolutions) { - RtpDemuxer demuxer; - - constexpr uint32_t ssrc = 111; - const std::string rsid = "a"; - NiceMock sink; - demuxer.AddSink(rsid, &sink); - - // Register several, then deregister only one, to show that not all of the - // observers had been forgotten when one was removed. - MockRsidResolutionObserver observer_1; - MockRsidResolutionObserver observer_2_removed; - MockRsidResolutionObserver observer_3; - - demuxer.RegisterRsidResolutionObserver(&observer_1); - demuxer.RegisterRsidResolutionObserver(&observer_2_removed); - demuxer.RegisterRsidResolutionObserver(&observer_3); - - demuxer.DeregisterRsidResolutionObserver(&observer_2_removed); - - EXPECT_CALL(observer_1, OnRsidResolved(rsid, ssrc)).Times(1); - EXPECT_CALL(observer_2_removed, OnRsidResolved(_, _)).Times(0); - EXPECT_CALL(observer_3, OnRsidResolved(rsid, ssrc)).Times(1); - - // The expected calls to OnRsidResolved() will be triggered by this. - demuxer.OnRtpPacket(*CreateRtpPacketReceivedWithRsid(rsid, ssrc)); - - // Test tear-down - demuxer.RemoveSink(&sink); - demuxer.DeregisterRsidResolutionObserver(&observer_1); - demuxer.DeregisterRsidResolutionObserver(&observer_3); -} - #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) TEST(RtpDemuxerTest, RsidMustBeNonEmpty) { RtpDemuxer demuxer; @@ -604,25 +493,7 @@ TEST(RtpDemuxerTest, RepeatedRsidAssociationsDisallowed) { MockRtpPacketSink sink; demuxer.AddSink("a", &sink); EXPECT_DEATH(demuxer.AddSink("a", &sink), ""); - demuxer.RemoveSink(&sink); } - -TEST(RtpDemuxerTest, - DoubleRegisterationOfNeverRegisteredRsidResolutionObserverDisallowed) { - RtpDemuxer demuxer; - MockRsidResolutionObserver observer; - demuxer.RegisterRsidResolutionObserver(&observer); - EXPECT_DEATH(demuxer.RegisterRsidResolutionObserver(&observer), ""); - demuxer.DeregisterRsidResolutionObserver(&observer); -} - -TEST(RtpDemuxerTest, - DregisterationOfNeverRegisteredRsidResolutionObserverDisallowed) { - RtpDemuxer demuxer; - MockRsidResolutionObserver observer; - EXPECT_DEATH(demuxer.DeregisterRsidResolutionObserver(&observer), ""); -} - #endif } // namespace diff --git a/webrtc/call/rtp_packet_sink_interface.h b/webrtc/call/rtp_packet_sink_interface.h index 0b3e64e313..900ca354d4 100644 --- a/webrtc/call/rtp_packet_sink_interface.h +++ b/webrtc/call/rtp_packet_sink_interface.h @@ -14,10 +14,10 @@ namespace webrtc { class RtpPacketReceived; -// This class represents a receiver of already parsed RTP packets. +// This class represents a receiver of an already parsed RTP packets. class RtpPacketSinkInterface { public: - virtual ~RtpPacketSinkInterface() = default; + virtual ~RtpPacketSinkInterface() {} virtual void OnRtpPacket(const RtpPacketReceived& packet) = 0; }; diff --git a/webrtc/call/rtp_rtcp_demuxer_helper.cc b/webrtc/call/rtp_rtcp_demuxer_helper.cc deleted file mode 100644 index e8d3cbfadb..0000000000 --- a/webrtc/call/rtp_rtcp_demuxer_helper.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/call/rtp_rtcp_demuxer_helper.h" - -#include "webrtc/modules/rtp_rtcp/source/byte_io.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/common_header.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h" - -namespace webrtc { - -rtc::Optional ParseRtcpPacketSenderSsrc( - rtc::ArrayView packet) { - rtcp::CommonHeader header; - for (const uint8_t* next_packet = packet.begin(); next_packet < packet.end(); - next_packet = header.NextPacket()) { - if (!header.Parse(next_packet, packet.end() - next_packet)) { - return rtc::Optional(); - } - - switch (header.type()) { - case rtcp::Bye::kPacketType: - case rtcp::ExtendedReports::kPacketType: - case rtcp::Psfb::kPacketType: - case rtcp::ReceiverReport::kPacketType: - case rtcp::Rtpfb::kPacketType: - case rtcp::SenderReport::kPacketType: { - // Sender SSRC at the beginning of the RTCP payload. - if (header.payload_size_bytes() >= sizeof(uint32_t)) { - const uint32_t ssrc_sender = - ByteReader::ReadBigEndian(header.payload()); - return rtc::Optional(ssrc_sender); - } else { - return rtc::Optional(); - } - } - } - } - - return rtc::Optional(); -} - -} // namespace webrtc diff --git a/webrtc/call/rtp_rtcp_demuxer_helper.h b/webrtc/call/rtp_rtcp_demuxer_helper.h deleted file mode 100644 index 19bd603244..0000000000 --- a/webrtc/call/rtp_rtcp_demuxer_helper.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_CALL_RTP_RTCP_DEMUXER_HELPER_H_ -#define WEBRTC_CALL_RTP_RTCP_DEMUXER_HELPER_H_ - -#include -#include -#include - -#include "webrtc/base/array_view.h" -#include "webrtc/base/basictypes.h" -#include "webrtc/base/optional.h" - -namespace webrtc { - -template -bool MultimapAssociationExists(const Container& multimap, - const typename Container::key_type& key, - const typename Container::mapped_type& val) { - auto it_range = multimap.equal_range(key); - using Reference = typename Container::const_reference; - return std::any_of(it_range.first, it_range.second, - [val](Reference elem) { return elem.second == val; }); -} - -template -size_t RemoveFromMultimapByValue(Container* multimap, const Value& value) { - size_t count = 0; - for (auto it = multimap->begin(); it != multimap->end();) { - if (it->second == value) { - it = multimap->erase(it); - ++count; - } else { - ++it; - } - } - return count; -} - -template -bool ContainerHasKey(const Container& c, const Key& k) { - return std::find(c.cbegin(), c.cend(), k) != c.cend(); -} - -template -bool MultimapHasValue(const Container& c, - const typename Container::mapped_type& v) { - auto predicate = [v](const typename Container::value_type& it) { - return it.second == v; - }; - return std::any_of(c.cbegin(), c.cend(), predicate); -} - -rtc::Optional ParseRtcpPacketSenderSsrc( - rtc::ArrayView packet); - -} // namespace webrtc - -#endif // WEBRTC_CALL_RTP_RTCP_DEMUXER_HELPER_H_ diff --git a/webrtc/call/rtp_rtcp_demuxer_helper_unittest.cc b/webrtc/call/rtp_rtcp_demuxer_helper_unittest.cc deleted file mode 100644 index e51002f6ad..0000000000 --- a/webrtc/call/rtp_rtcp_demuxer_helper_unittest.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/call/rtp_rtcp_demuxer_helper.h" - -#include "webrtc/base/arraysize.h" -#include "webrtc/base/basictypes.h" -#include "webrtc/base/buffer.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" -#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h" -#include "webrtc/test/gtest.h" - -namespace webrtc { - -namespace { -constexpr uint32_t kSsrc = 8374; -} // namespace - -TEST(RtpRtcpDemuxerHelperTest, ParseRtcpPacketSenderSsrc_ByePacket) { - webrtc::rtcp::Bye rtcp_packet; - rtcp_packet.SetSenderSsrc(kSsrc); - rtc::Buffer raw_packet = rtcp_packet.Build(); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc(raw_packet); - EXPECT_EQ(ssrc, kSsrc); -} - -TEST(RtpRtcpDemuxerHelperTest, - ParseRtcpPacketSenderSsrc_ExtendedReportsPacket) { - webrtc::rtcp::ExtendedReports rtcp_packet; - rtcp_packet.SetSenderSsrc(kSsrc); - rtc::Buffer raw_packet = rtcp_packet.Build(); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc(raw_packet); - EXPECT_EQ(ssrc, kSsrc); -} - -TEST(RtpRtcpDemuxerHelperTest, ParseRtcpPacketSenderSsrc_PsfbPacket) { - webrtc::rtcp::Pli rtcp_packet; // Psfb is abstract; use a subclass. - rtcp_packet.SetSenderSsrc(kSsrc); - rtc::Buffer raw_packet = rtcp_packet.Build(); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc(raw_packet); - EXPECT_EQ(ssrc, kSsrc); -} - -TEST(RtpRtcpDemuxerHelperTest, ParseRtcpPacketSenderSsrc_ReceiverReportPacket) { - webrtc::rtcp::ReceiverReport rtcp_packet; - rtcp_packet.SetSenderSsrc(kSsrc); - rtc::Buffer raw_packet = rtcp_packet.Build(); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc(raw_packet); - EXPECT_EQ(ssrc, kSsrc); -} - -TEST(RtpRtcpDemuxerHelperTest, ParseRtcpPacketSenderSsrc_RtpfbPacket) { - // Rtpfb is abstract; use a subclass. - webrtc::rtcp::RapidResyncRequest rtcp_packet; - rtcp_packet.SetSenderSsrc(kSsrc); - rtc::Buffer raw_packet = rtcp_packet.Build(); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc(raw_packet); - EXPECT_EQ(ssrc, kSsrc); -} - -TEST(RtpRtcpDemuxerHelperTest, ParseRtcpPacketSenderSsrc_SenderReportPacket) { - webrtc::rtcp::SenderReport rtcp_packet; - rtcp_packet.SetSenderSsrc(kSsrc); - rtc::Buffer raw_packet = rtcp_packet.Build(); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc(raw_packet); - EXPECT_EQ(ssrc, kSsrc); -} - -TEST(RtpRtcpDemuxerHelperTest, ParseRtcpPacketSenderSsrc_MalformedRtcpPacket) { - uint8_t garbage[100]; - memset(&garbage[0], 0, arraysize(garbage)); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc(garbage); - EXPECT_FALSE(ssrc); -} - -TEST(RtpRtcpDemuxerHelperTest, - ParseRtcpPacketSenderSsrc_RtcpMessageWithoutSenderSsrc) { - webrtc::rtcp::ExtendedJitterReport rtcp_packet; // Has no sender SSRC. - rtc::Buffer raw_packet = rtcp_packet.Build(); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc(raw_packet); - EXPECT_FALSE(ssrc); -} - -TEST(RtpRtcpDemuxerHelperTest, ParseRtcpPacketSenderSsrc_TruncatedRtcpMessage) { - webrtc::rtcp::Bye rtcp_packet; - rtcp_packet.SetSenderSsrc(kSsrc); - rtc::Buffer raw_packet = rtcp_packet.Build(); - - constexpr size_t rtcp_length_bytes = 8; - ASSERT_EQ(rtcp_length_bytes, raw_packet.size()); - - rtc::Optional ssrc = ParseRtcpPacketSenderSsrc( - rtc::ArrayView(raw_packet.data(), rtcp_length_bytes - 1)); - EXPECT_FALSE(ssrc); -} - -} // namespace webrtc