diff options
Diffstat (limited to 'third_party/libwebrtc/webrtc/call/rtcp_demuxer.cc')
-rw-r--r-- | third_party/libwebrtc/webrtc/call/rtcp_demuxer.cc | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/third_party/libwebrtc/webrtc/call/rtcp_demuxer.cc b/third_party/libwebrtc/webrtc/call/rtcp_demuxer.cc new file mode 100644 index 0000000000..0adbdf3133 --- /dev/null +++ b/third_party/libwebrtc/webrtc/call/rtcp_demuxer.cc @@ -0,0 +1,100 @@ +/* + * 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 "call/rtcp_demuxer.h" + +#include "call/rtcp_packet_sink_interface.h" +#include "call/rtp_rtcp_demuxer_helper.h" +#include "common_types.h" // NOLINT(build/include) +#include "rtc_base/checks.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<const uint8_t> packet) { + // Perform sender-SSRC-based demuxing for packets with a sender-SSRC. + rtc::Optional<uint32_t> 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::OnSsrcBoundToRsid(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 |