blob: 641d1d0fabe6dae1091712b7811c1398fc6b97b7 [file] [log] [blame]
Bjorn A Mellem44bd71c2019-05-28 15:25:38 -07001/*
2 * Copyright 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "pc/composite_rtp_transport.h"
12
Bjorn A Mellem44bd71c2019-05-28 15:25:38 -070013#include <string>
14#include <utility>
15
Bjorn A Mellem44bd71c2019-05-28 15:25:38 -070016#include "absl/memory/memory.h"
17#include "p2p/base/packet_transport_internal.h"
18
19namespace webrtc {
20
21CompositeRtpTransport::CompositeRtpTransport(
22 std::vector<RtpTransportInternal*> transports)
23 : transports_(std::move(transports)) {
24 RTC_DCHECK(!transports_.empty()) << "Cannot have an empty composite";
25 std::vector<rtc::PacketTransportInternal*> rtp_transports;
26 std::vector<rtc::PacketTransportInternal*> rtcp_transports;
27 for (RtpTransportInternal* transport : transports_) {
28 RTC_DCHECK_EQ(transport->rtcp_mux_enabled(), rtcp_mux_enabled())
29 << "Either all or none of the transports in a composite must enable "
30 "rtcp mux";
31 RTC_DCHECK_EQ(transport->transport_name(), transport_name())
32 << "All transports in a composite must have the same transport name";
33
34 transport->SignalNetworkRouteChanged.connect(
35 this, &CompositeRtpTransport::OnNetworkRouteChanged);
36 transport->SignalRtcpPacketReceived.connect(
37 this, &CompositeRtpTransport::OnRtcpPacketReceived);
38 }
39}
40
41void CompositeRtpTransport::SetSendTransport(
42 RtpTransportInternal* send_transport) {
43 if (send_transport_ == send_transport) {
44 return;
45 }
46
47 RTC_DCHECK(absl::c_linear_search(transports_, send_transport))
48 << "Cannot set a send transport that isn't part of the composite";
49
50 if (send_transport_) {
51 send_transport_->SignalReadyToSend.disconnect(this);
52 send_transport_->SignalWritableState.disconnect(this);
53 send_transport_->SignalSentPacket.disconnect(this);
54 }
55
56 send_transport_ = send_transport;
57 send_transport_->SignalReadyToSend.connect(
58 this, &CompositeRtpTransport::OnReadyToSend);
59 send_transport_->SignalWritableState.connect(
60 this, &CompositeRtpTransport::OnWritableState);
61 send_transport_->SignalSentPacket.connect(
62 this, &CompositeRtpTransport::OnSentPacket);
63
64 SignalWritableState(send_transport_->IsWritable(/*rtcp=*/true) &&
65 send_transport_->IsWritable(/*rtcp=*/false));
66 if (send_transport_->IsReadyToSend()) {
67 SignalReadyToSend(true);
68 }
69}
70
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -070071void CompositeRtpTransport::RemoveTransport(RtpTransportInternal* transport) {
72 RTC_DCHECK(transport != send_transport_) << "Cannot remove send transport";
73
74 auto it = absl::c_find(transports_, transport);
75 if (it == transports_.end()) {
76 return;
77 }
78
79 transport->SignalNetworkRouteChanged.disconnect(this);
80 transport->SignalRtcpPacketReceived.disconnect(this);
81 for (auto sink : rtp_demuxer_sinks_) {
82 transport->UnregisterRtpDemuxerSink(sink);
83 }
84
85 transports_.erase(it);
86}
87
Bjorn A Mellem44bd71c2019-05-28 15:25:38 -070088const std::string& CompositeRtpTransport::transport_name() const {
89 return transports_.front()->transport_name();
90}
91
92int CompositeRtpTransport::SetRtpOption(rtc::Socket::Option opt, int value) {
93 int result = 0;
94 for (auto transport : transports_) {
95 result |= transport->SetRtpOption(opt, value);
96 }
97 return result;
98}
99
100int CompositeRtpTransport::SetRtcpOption(rtc::Socket::Option opt, int value) {
101 int result = 0;
102 for (auto transport : transports_) {
103 result |= transport->SetRtcpOption(opt, value);
104 }
105 return result;
106}
107
108bool CompositeRtpTransport::rtcp_mux_enabled() const {
109 return transports_.front()->rtcp_mux_enabled();
110}
111
112void CompositeRtpTransport::SetRtcpMuxEnabled(bool enabled) {
113 for (auto transport : transports_) {
114 transport->SetRtcpMuxEnabled(enabled);
115 }
116}
117
118bool CompositeRtpTransport::IsReadyToSend() const {
119 return send_transport_ && send_transport_->IsReadyToSend();
120}
121
122bool CompositeRtpTransport::IsWritable(bool rtcp) const {
123 return send_transport_ && send_transport_->IsWritable(rtcp);
124}
125
126bool CompositeRtpTransport::SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
127 const rtc::PacketOptions& options,
128 int flags) {
129 if (!send_transport_) {
130 return false;
131 }
132 return send_transport_->SendRtpPacket(packet, options, flags);
133}
134
135bool CompositeRtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
136 const rtc::PacketOptions& options,
137 int flags) {
138 if (!send_transport_) {
139 return false;
140 }
141 return send_transport_->SendRtcpPacket(packet, options, flags);
142}
143
144void CompositeRtpTransport::UpdateRtpHeaderExtensionMap(
145 const cricket::RtpHeaderExtensions& header_extensions) {
146 for (RtpTransportInternal* transport : transports_) {
147 transport->UpdateRtpHeaderExtensionMap(header_extensions);
148 }
149}
150
151bool CompositeRtpTransport::IsSrtpActive() const {
152 bool active = true;
153 for (RtpTransportInternal* transport : transports_) {
154 active &= transport->IsSrtpActive();
155 }
156 return active;
157}
158
159bool CompositeRtpTransport::RegisterRtpDemuxerSink(
160 const RtpDemuxerCriteria& criteria,
161 RtpPacketSinkInterface* sink) {
162 for (RtpTransportInternal* transport : transports_) {
163 transport->RegisterRtpDemuxerSink(criteria, sink);
164 }
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700165 rtp_demuxer_sinks_.insert(sink);
Bjorn A Mellem44bd71c2019-05-28 15:25:38 -0700166 return true;
167}
168
169bool CompositeRtpTransport::UnregisterRtpDemuxerSink(
170 RtpPacketSinkInterface* sink) {
171 for (RtpTransportInternal* transport : transports_) {
172 transport->UnregisterRtpDemuxerSink(sink);
173 }
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700174 rtp_demuxer_sinks_.erase(sink);
Bjorn A Mellem44bd71c2019-05-28 15:25:38 -0700175 return true;
176}
177
178void CompositeRtpTransport::OnNetworkRouteChanged(
179 absl::optional<rtc::NetworkRoute> route) {
180 SignalNetworkRouteChanged(route);
181}
182
183void CompositeRtpTransport::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
184 int64_t packet_time_us) {
185 SignalRtcpPacketReceived(packet, packet_time_us);
186}
187
188void CompositeRtpTransport::OnWritableState(bool writable) {
189 SignalWritableState(writable);
190}
191
192void CompositeRtpTransport::OnReadyToSend(bool ready_to_send) {
193 SignalReadyToSend(ready_to_send);
194}
195
196void CompositeRtpTransport::OnSentPacket(const rtc::SentPacket& packet) {
197 SignalSentPacket(packet);
198}
199
200} // namespace webrtc