blob: 991e9e338c70a82841e2decada1257697108096e [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:361/*
kjellander65c7f672016-02-12 08:05:012 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:363 *
kjellander65c7f672016-02-12 08:05:014 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:369 */
10
jbauch5869f502017-06-29 19:31:3611#include <iterator>
kwiberg0eb15ed2015-12-17 11:04:1512#include <utility>
13
Mirko Bonadei92ea95e2017-09-15 04:47:3114#include "pc/channel.h"
henrike@webrtc.org28e20752013-07-10 00:45:3615
Steve Anton64b626b2019-01-29 01:25:2616#include "absl/algorithm/container.h"
Karl Wiberg918f50c2018-07-05 09:40:3317#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3118#include "api/call/audio_sink.h"
Steve Anton10542f22019-01-11 17:11:0019#include "media/base/media_constants.h"
20#include "media/base/rtp_utils.h"
Zhi Huang365381f2018-04-13 23:44:3421#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3122#include "rtc_base/bind.h"
Steve Anton10542f22019-01-11 17:11:0023#include "rtc_base/byte_order.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3124#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 17:11:0025#include "rtc_base/copy_on_write_buffer.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3126#include "rtc_base/dscp.h"
27#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 17:11:0028#include "rtc_base/network_route.h"
Jonas Olsson366a50c2018-09-06 11:41:3029#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3130#include "rtc_base/trace_event.h"
Steve Anton10542f22019-01-11 17:11:0031#include "p2p/base/packet_transport_internal.h"
32#include "pc/channel_manager.h"
33#include "pc/rtp_media_utils.h"
henrike@webrtc.org28e20752013-07-10 00:45:3634
35namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5236using rtc::Bind;
Amit Hilbuchbcd39d42019-01-26 01:13:5637using rtc::UniqueRandomIdGenerator;
Steve Anton3828c062017-12-06 18:34:5138using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:2639
deadbeef2d110be2016-01-13 20:00:2640namespace {
Danil Chapovalov33b01f22016-05-11 17:55:2741
42struct SendPacketMessageData : public rtc::MessageData {
43 rtc::CopyOnWriteBuffer packet;
44 rtc::PacketOptions options;
45};
46
Amit Hilbuchbcd39d42019-01-26 01:13:5647// Finds a stream based on target's Primary SSRC or RIDs.
48// This struct is used in BaseChannel::UpdateLocalStreams_w.
49struct StreamFinder {
50 explicit StreamFinder(const StreamParams* target) : target_(target) {
51 RTC_DCHECK(target);
52 }
53
54 bool operator()(const StreamParams& sp) const {
55 if (target_->has_ssrcs() && sp.has_ssrcs()) {
56 return sp.has_ssrc(target_->first_ssrc());
57 }
58
59 if (!target_->has_rids() && !sp.has_rids()) {
60 return false;
61 }
62
63 const std::vector<RidDescription>& target_rids = target_->rids();
64 const std::vector<RidDescription>& source_rids = sp.rids();
65 if (source_rids.size() != target_rids.size()) {
66 return false;
67 }
68
69 // Check that all RIDs match.
70 return std::equal(source_rids.begin(), source_rids.end(),
71 target_rids.begin(),
72 [](const RidDescription& lhs, const RidDescription& rhs) {
73 return lhs.rid == rhs.rid;
74 });
75 }
76
77 const StreamParams* target_;
78};
79
deadbeef2d110be2016-01-13 20:00:2680} // namespace
81
henrike@webrtc.org28e20752013-07-10 00:45:3682enum {
Steve Anton0807d152018-03-05 19:23:0983 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 17:55:2784 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:3685 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:3686 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:3687 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:3688};
89
sergeyu@chromium.org4b26e2e2014-01-15 23:15:5490static void SafeSetError(const std::string& message, std::string* error_desc) {
91 if (error_desc) {
92 *error_desc = message;
93 }
94}
95
jbaucheec21bd2016-03-20 13:15:4396static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) {
henrike@webrtc.org28e20752013-07-10 00:45:3697 // Check the packet size. We could check the header too if needed.
zstein3dcf0e92017-06-01 20:22:4298 return packet && IsValidRtpRtcpPacketSize(rtcp, packet->size());
henrike@webrtc.org28e20752013-07-10 00:45:3699}
100
Peter Thatcherc2ee2c82015-08-07 23:05:34101template <class Codec>
102void RtpParametersFromMediaDescription(
103 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 19:31:36104 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 23:05:34105 RtpParameters<Codec>* params) {
106 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 19:36:43107 // a description without codecs. Currently the ORTC implementation is relying
108 // on this.
Peter Thatcherc2ee2c82015-08-07 23:05:34109 if (desc->has_codecs()) {
110 params->codecs = desc->codecs();
111 }
112 // TODO(pthatcher): See if we really need
113 // rtp_header_extensions_set() and remove it if we don't.
114 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 19:31:36115 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 23:05:34116 }
deadbeef13871492015-12-09 20:37:51117 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Peter Thatcherc2ee2c82015-08-07 23:05:34118}
119
nisse05103312016-03-16 09:22:50120template <class Codec>
Peter Thatcherc2ee2c82015-08-07 23:05:34121void RtpSendParametersFromMediaDescription(
122 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 19:31:36123 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 09:22:50124 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 19:31:36125 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 23:05:34126 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 10:22:05127 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 23:05:34128}
129
Danil Chapovalov33b01f22016-05-11 17:55:27130BaseChannel::BaseChannel(rtc::Thread* worker_thread,
131 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-13 03:37:48132 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 23:53:33133 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 18:50:27134 const std::string& content_name,
Zhi Huange830e682018-03-30 17:48:35135 bool srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56136 webrtc::CryptoOptions crypto_options,
137 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 17:55:27138 : worker_thread_(worker_thread),
139 network_thread_(network_thread),
zhihuangf5b251b2017-01-13 03:37:48140 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36141 content_name_(content_name),
deadbeef7af91dd2016-12-13 19:29:11142 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 17:48:35143 crypto_options_(crypto_options),
Amit Hilbuchbcd39d42019-01-26 01:13:56144 media_channel_(std::move(media_channel)),
145 ssrc_generator_(ssrc_generator) {
Steve Anton8699a322017-11-06 23:53:33146 RTC_DCHECK_RUN_ON(worker_thread_);
Amit Hilbuchbcd39d42019-01-26 01:13:56147 RTC_DCHECK(ssrc_generator_);
Zhi Huang365381f2018-04-13 23:44:34148 demuxer_criteria_.mid = content_name;
Mirko Bonadei675513b2017-11-09 10:09:25149 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36150}
151
152BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 22:24:13153 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 23:53:33154 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58155
156 if (media_transport_) {
Niels Möllerfe6e50f2019-02-05 16:32:57157 media_transport_->RemoveNetworkChangeCallback(this);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58158 }
159
Danil Chapovalov33b01f22016-05-11 17:55:27160 // Eats any outstanding messages or packets.
161 worker_thread_->Clear(&invoker_);
162 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36163 // We must destroy the media channel before the transport channel, otherwise
164 // the media channel may try to send on the dead transport channel. NULLing
165 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 23:53:33166 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 10:09:25167 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 17:55:27168}
169
Zhi Huang365381f2018-04-13 23:44:34170bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 18:41:57171 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 23:44:34172 if (!RegisterRtpDemuxerSink()) {
173 return false;
174 }
Zhi Huangcd3fc5d2017-11-29 18:41:57175 rtp_transport_->SignalReadyToSend.connect(
176 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang365381f2018-04-13 23:44:34177 rtp_transport_->SignalRtcpPacketReceived.connect(
178 this, &BaseChannel::OnRtcpPacketReceived);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58179
180 // If media transport is used, it's responsible for providing network
181 // route changed callbacks.
182 if (!media_transport_) {
183 rtp_transport_->SignalNetworkRouteChanged.connect(
184 this, &BaseChannel::OnNetworkRouteChanged);
185 }
186 // TODO(bugs.webrtc.org/9719): Media transport should also be used to provide
187 // 'writable' state here.
Zhi Huangcd3fc5d2017-11-29 18:41:57188 rtp_transport_->SignalWritableState.connect(this,
189 &BaseChannel::OnWritableState);
190 rtp_transport_->SignalSentPacket.connect(this,
191 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 23:44:34192 return true;
Zhi Huangcd3fc5d2017-11-29 18:41:57193}
Danil Chapovalovdae07ba2016-05-13 23:43:50194
Zhi Huangcd3fc5d2017-11-29 18:41:57195void BaseChannel::DisconnectFromRtpTransport() {
196 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 23:44:34197 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 18:41:57198 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang365381f2018-04-13 23:44:34199 rtp_transport_->SignalRtcpPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 18:41:57200 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
201 rtp_transport_->SignalWritableState.disconnect(this);
202 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-13 23:43:50203}
204
Anton Sukhanov98a462c2018-10-17 20:15:42205void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport,
206 webrtc::MediaTransportInterface* media_transport) {
Zhi Huang2dfc42d2017-12-04 21:38:48207 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58208 media_transport_ = media_transport;
209
Zhi Huang365381f2018-04-13 23:44:34210 network_thread_->Invoke<void>(
211 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 21:38:48212
213 // Both RTP and RTCP channels should be set, we can call SetInterface on
214 // the media channel and it can set network options.
Anton Sukhanov98a462c2018-10-17 20:15:42215 media_channel_->SetInterface(this, media_transport);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58216
217 RTC_LOG(LS_INFO) << "BaseChannel::Init_w, media_transport="
218 << (media_transport_ != nullptr);
219 if (media_transport_) {
Niels Möllerfe6e50f2019-02-05 16:32:57220 media_transport_->AddNetworkChangeCallback(this);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58221 }
Danil Chapovalov33b01f22016-05-11 17:55:27222}
223
wu@webrtc.org78187522013-10-07 23:32:02224void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 17:55:27225 RTC_DCHECK(worker_thread_->IsCurrent());
Anton Sukhanov98a462c2018-10-17 20:15:42226 media_channel_->SetInterface(/*iface=*/nullptr,
227 /*media_transport=*/nullptr);
Danil Chapovalovdae07ba2016-05-13 23:43:50228 // Packets arrive on the network thread, processing packets calls virtual
229 // functions, so need to stop this process in Deinit that is called in
230 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 18:41:57231 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03232 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-27 04:37:23233
Zhi Huange830e682018-03-30 17:48:35234 if (rtp_transport_) {
235 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03236 }
Zhi Huangcd3fc5d2017-11-29 18:41:57237 // Clear pending read packets/messages.
238 network_thread_->Clear(&invoker_);
239 network_thread_->Clear(this);
240 });
wu@webrtc.org78187522013-10-07 23:32:02241}
242
Zhi Huang365381f2018-04-13 23:44:34243bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
244 if (rtp_transport == rtp_transport_) {
245 return true;
246 }
247
Zhi Huang2dfc42d2017-12-04 21:38:48248 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 23:44:34249 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
250 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 21:38:48251 });
252 }
Zhi Huang95e7dbb2018-03-29 00:08:03253
Zhi Huang2dfc42d2017-12-04 21:38:48254 if (rtp_transport_) {
255 DisconnectFromRtpTransport();
256 }
Zhi Huange830e682018-03-30 17:48:35257
Zhi Huang2dfc42d2017-12-04 21:38:48258 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 17:48:35259 if (rtp_transport_) {
260 RTC_DCHECK(rtp_transport_->rtp_packet_transport());
261 transport_name_ = rtp_transport_->rtp_packet_transport()->transport_name();
Zhi Huang2dfc42d2017-12-04 21:38:48262
Zhi Huang365381f2018-04-13 23:44:34263 if (!ConnectToRtpTransport()) {
264 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport.";
265 return false;
266 }
Zhi Huange830e682018-03-30 17:48:35267 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
268 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 21:38:48269
Zhi Huange830e682018-03-30 17:48:35270 // Set the cached socket options.
271 for (const auto& pair : socket_options_) {
272 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
273 pair.second);
274 }
275 if (rtp_transport_->rtcp_packet_transport()) {
276 for (const auto& pair : rtcp_socket_options_) {
277 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
278 pair.second);
279 }
280 }
guoweis46383312015-12-18 00:45:59281 }
Zhi Huang365381f2018-04-13 23:44:34282 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12283}
284
henrike@webrtc.org28e20752013-07-10 00:45:36285bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 21:17:27286 worker_thread_->Invoke<void>(
287 RTC_FROM_HERE,
288 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
289 this));
henrike@webrtc.org28e20752013-07-10 00:45:36290 return true;
291}
292
henrike@webrtc.org28e20752013-07-10 00:45:36293bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:51294 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54295 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:57296 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 13:44:03297 return InvokeOnWorker<bool>(
298 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 18:34:51299 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36300}
301
302bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:51303 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54304 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:57305 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 13:44:03306 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 18:34:51307 RTC_FROM_HERE,
308 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36309}
310
Taylor Brandstetterbad33bf2016-08-25 20:31:14311bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36312 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 22:57:10313 return enabled() &&
314 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36315}
316
Taylor Brandstetterbad33bf2016-08-25 20:31:14317bool BaseChannel::IsReadyToSendMedia_w() const {
318 // Need to access some state updated on the network thread.
319 return network_thread_->Invoke<bool>(
320 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
321}
322
323bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36324 // Send outgoing data if we are enabled, have local and remote content,
325 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 22:57:10326 return enabled() &&
327 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
328 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 23:44:34329 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36330}
331
jbaucheec21bd2016-03-20 13:15:43332bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 14:26:07333 const rtc::PacketOptions& options) {
334 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36335}
336
jbaucheec21bd2016-03-20 13:15:43337bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 14:26:07338 const rtc::PacketOptions& options) {
339 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36340}
341
Yves Gerey665174f2018-06-19 13:03:05342int BaseChannel::SetOption(SocketType type,
343 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36344 int value) {
Danil Chapovalov33b01f22016-05-11 17:55:27345 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:27346 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 17:55:27347}
348
349int BaseChannel::SetOption_n(SocketType type,
350 rtc::Socket::Option opt,
351 int value) {
352 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 17:48:35353 RTC_DCHECK(rtp_transport_);
deadbeef5bd5ca32017-02-10 19:31:50354 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36355 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07356 case ST_RTP:
zsteine8ab5432017-07-12 18:48:11357 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 18:50:27358 socket_options_.push_back(
359 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07360 break;
361 case ST_RTCP:
zsteine8ab5432017-07-12 18:48:11362 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 18:50:27363 rtcp_socket_options_.push_back(
364 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07365 break;
henrike@webrtc.org28e20752013-07-10 00:45:36366 }
deadbeeff5346592017-01-25 05:51:21367 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36368}
369
Zhi Huangcd3fc5d2017-11-29 18:41:57370void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 17:55:27371 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 18:41:57372 if (writable) {
Zhi Huangcd3fc5d2017-11-29 18:41:57373 ChannelWritable_n();
374 } else {
375 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 17:59:56376 }
377}
378
Zhi Huang942bc2e2017-11-13 21:26:07379void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 14:47:43380 absl::optional<rtc::NetworkRoute> network_route) {
Piotr (Peter) Slatala179a3922018-11-16 17:57:58381 RTC_LOG(LS_INFO) << "Network route was changed.";
382
Danil Chapovalov33b01f22016-05-11 17:55:27383 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 21:26:07384 rtc::NetworkRoute new_route;
385 if (network_route) {
Zhi Huang942bc2e2017-11-13 21:26:07386 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45387 }
Zhi Huang942bc2e2017-11-13 21:26:07388 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
389 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
390 // work correctly. Intentionally leave it broken to simplify the code and
391 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 23:53:33392 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 21:26:07393 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 23:53:33394 });
Honghai Zhangcc411c02016-03-30 00:27:21395}
396
zstein56162b92017-04-24 23:54:35397void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 23:53:33398 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
399 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36400}
401
stefanc1aeaf02015-10-15 14:26:07402bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 13:15:43403 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 14:26:07404 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 17:55:27405 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
406 // If the thread is not our network thread, we will post to our network
407 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36408 // synchronize access to all the pieces of the send path, including
409 // SRTP and the inner workings of the transport channels.
410 // The only downside is that we can't return a proper failure code if
411 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 17:55:27412 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36413 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 17:55:27414 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
415 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 11:04:15416 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 14:26:07417 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 21:17:27418 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36419 return true;
420 }
Zhi Huange830e682018-03-30 17:48:35421
Danil Chapovalov33b01f22016-05-11 17:55:27422 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36423
424 // Now that we are on the correct thread, ensure we have a place to send this
425 // packet before doing anything. (We might get RTCP packets that we don't
426 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
427 // transport.
Zhi Huange830e682018-03-30 17:48:35428 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36429 return false;
430 }
431
432 // Protect ourselves against crazy data.
433 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 10:09:25434 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
435 << RtpRtcpStringLiteral(rtcp)
436 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36437 return false;
438 }
439
Zhi Huangcf990f52017-09-22 19:12:30440 if (!srtp_active()) {
441 if (srtp_required_) {
442 // The audio/video engines may attempt to send RTCP packets as soon as the
443 // streams are created, so don't treat this as an error for RTCP.
444 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
445 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36446 return false;
447 }
Zhi Huangcf990f52017-09-22 19:12:30448 // However, there shouldn't be any RTP packets sent before SRTP is set up
449 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 10:09:25450 RTC_LOG(LS_ERROR)
451 << "Can't send outgoing RTP packet when SRTP is inactive"
452 << " and crypto is required";
Zhi Huangcf990f52017-09-22 19:12:30453 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 20:26:27454 return false;
455 }
Zhi Huangcd3fc5d2017-11-29 18:41:57456
457 std::string packet_type = rtcp ? "RTCP" : "RTP";
458 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
459 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36460 }
Zhi Huange830e682018-03-30 17:48:35461
henrike@webrtc.org28e20752013-07-10 00:45:36462 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 18:41:57463 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
464 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36465}
466
Zhi Huang365381f2018-04-13 23:44:34467void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Niels Möller29e13fd2018-12-17 11:35:30468 // Take packet time from the |parsed_packet|.
469 // RtpPacketReceived.arrival_time_ms = (timestamp_us + 500) / 1000;
Niels Möllere6933812018-11-05 12:01:41470 int64_t timestamp_us = -1;
Zhi Huang365381f2018-04-13 23:44:34471 if (parsed_packet.arrival_time_ms() > 0) {
Niels Möllere6933812018-11-05 12:01:41472 timestamp_us = parsed_packet.arrival_time_ms() * 1000;
Zhi Huang365381f2018-04-13 23:44:34473 }
Zhi Huang365381f2018-04-13 23:44:34474
Niels Möllere6933812018-11-05 12:01:41475 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), timestamp_us);
Zhi Huang365381f2018-04-13 23:44:34476}
477
478void BaseChannel::UpdateRtpHeaderExtensionMap(
479 const RtpHeaderExtensions& header_extensions) {
480 RTC_DCHECK(rtp_transport_);
481 // Update the header extension map on network thread in case there is data
482 // race.
483 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
484 // be accessed from different threads.
485 //
486 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
487 // extension maps are not merged when BUNDLE is enabled. This is fine because
488 // the ID for MID should be consistent among all the RTP transports.
489 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
490 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
491 });
492}
493
494bool BaseChannel::RegisterRtpDemuxerSink() {
495 RTC_DCHECK(rtp_transport_);
496 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
497 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
498 });
499}
500
501void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
Niels Möllere6933812018-11-05 12:01:41502 int64_t packet_time_us) {
503 OnPacketReceived(/*rtcp=*/true, *packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36504}
505
zstein3dcf0e92017-06-01 20:22:42506void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang365381f2018-04-13 23:44:34507 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 12:01:41508 int64_t packet_time_us) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33509 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36510 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 21:17:27511 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36512 }
513
Zhi Huangcf990f52017-09-22 19:12:30514 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36515 // Our session description indicates that SRTP is required, but we got a
516 // packet before our SRTP filter is active. This means either that
517 // a) we got SRTP packets before we received the SDES keys, in which case
518 // we can't decrypt it anyway, or
519 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-20 00:54:25520 // transports, so we haven't yet extracted keys, even if DTLS did
521 // complete on the transport that the packets are being sent on. It's
522 // really good practice to wait for both RTP and RTCP to be good to go
523 // before sending media, to prevent weird failure modes, so it's fine
524 // for us to just eat packets here. This is all sidestepped if RTCP mux
525 // is used anyway.
Mirko Bonadei675513b2017-11-09 10:09:25526 RTC_LOG(LS_WARNING)
527 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
528 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36529 return;
530 }
531
Danil Chapovalov33b01f22016-05-11 17:55:27532 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:27533 RTC_FROM_HERE, worker_thread_,
Niels Möllere6933812018-11-05 12:01:41534 Bind(&BaseChannel::ProcessPacket, this, rtcp, packet, packet_time_us));
Danil Chapovalov33b01f22016-05-11 17:55:27535}
536
zstein3dcf0e92017-06-01 20:22:42537void BaseChannel::ProcessPacket(bool rtcp,
538 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 12:01:41539 int64_t packet_time_us) {
Danil Chapovalov33b01f22016-05-11 17:55:27540 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 20:22:42541
Danil Chapovalov33b01f22016-05-11 17:55:27542 if (rtcp) {
Amit Hilbuche7a5f7b2019-03-12 18:10:27543 media_channel_->OnRtcpReceived(packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36544 } else {
Amit Hilbuche7a5f7b2019-03-12 18:10:27545 media_channel_->OnPacketReceived(packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36546 }
547}
548
henrike@webrtc.org28e20752013-07-10 00:45:36549void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 20:31:14550 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36551 if (enabled_)
552 return;
553
Mirko Bonadei675513b2017-11-09 10:09:25554 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36555 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 20:31:14556 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36557}
558
559void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 20:31:14560 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36561 if (!enabled_)
562 return;
563
Mirko Bonadei675513b2017-11-09 10:09:25564 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36565 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 20:31:14566 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36567}
568
Danil Chapovalov33b01f22016-05-11 17:55:27569void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 17:48:35570 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
571 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 17:55:27572 ChannelWritable_n();
deadbeefcbecd352015-09-23 18:50:27573 } else {
Danil Chapovalov33b01f22016-05-11 17:55:27574 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 18:50:27575 }
576}
577
Danil Chapovalov33b01f22016-05-11 17:55:27578void BaseChannel::ChannelWritable_n() {
579 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 17:59:56580 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36581 return;
Guo-wei Shieh1218d7a2015-12-05 17:59:56582 }
henrike@webrtc.org28e20752013-07-10 00:45:36583
Mirko Bonadei675513b2017-11-09 10:09:25584 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
585 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36586
henrike@webrtc.org28e20752013-07-10 00:45:36587 was_ever_writable_ = true;
588 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 20:31:14589 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36590}
591
Danil Chapovalov33b01f22016-05-11 17:55:27592void BaseChannel::ChannelNotWritable_n() {
593 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36594 if (!writable_)
595 return;
596
Mirko Bonadei675513b2017-11-09 10:09:25597 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36598 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 20:31:14599 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36600}
601
henrike@webrtc.org28e20752013-07-10 00:45:36602bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 20:31:14603 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 18:19:58604 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36605}
606
Peter Boström0c4e06b2015-10-07 10:23:21607bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 20:31:14608 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36609 return media_channel()->RemoveRecvStream(ssrc);
610}
611
612bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 18:34:51613 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54614 std::string* error_desc) {
Amit Hilbuchbcd39d42019-01-26 01:13:56615 // In the case of RIDs (where SSRCs are not negotiated), this method will
616 // generate an SSRC for each layer in StreamParams. That representation will
617 // be stored internally in |local_streams_|.
618 // In subsequent offers, the same stream can appear in |streams| again
619 // (without the SSRCs), so it should be looked up using RIDs (if available)
620 // and then by primary SSRC.
621 // In both scenarios, it is safe to assume that the media channel will be
622 // created with a StreamParams object with SSRCs. However, it is not safe to
623 // assume that |local_streams_| will always have SSRCs as there are scenarios
624 // in which niether SSRCs or RIDs are negotiated.
625
henrike@webrtc.org28e20752013-07-10 00:45:36626 // Check for streams that have been removed.
627 bool ret = true;
Steve Anton5f8b5fd2018-12-28 00:58:10628 for (const StreamParams& old_stream : local_streams_) {
Amit Hilbuchbcd39d42019-01-26 01:13:56629 if (!old_stream.has_ssrcs() ||
630 GetStream(streams, StreamFinder(&old_stream))) {
631 continue;
632 }
633 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
634 rtc::StringBuilder desc;
635 desc << "Failed to remove send stream with ssrc "
636 << old_stream.first_ssrc() << ".";
637 SafeSetError(desc.str(), error_desc);
638 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36639 }
640 }
641 // Check for new streams.
Amit Hilbuchbcd39d42019-01-26 01:13:56642 std::vector<StreamParams> all_streams;
643 for (const StreamParams& stream : streams) {
644 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
645 if (existing) {
646 // Parameters cannot change for an existing stream.
647 all_streams.push_back(*existing);
648 continue;
649 }
650
651 all_streams.push_back(stream);
652 StreamParams& new_stream = all_streams.back();
653
654 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
655 continue;
656 }
657
658 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
659 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
660 rtc::StringBuilder desc;
661 desc << "Failed to add send stream: " << new_stream.first_ssrc()
662 << ". Stream has both SSRCs and RIDs.";
663 SafeSetError(desc.str(), error_desc);
664 ret = false;
665 continue;
666 }
667
668 // At this point we use the legacy simulcast group in StreamParams to
669 // indicate that we want multiple layers to the media channel.
670 if (!new_stream.has_ssrcs()) {
671 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
672 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
673 /* flex_fec = */ false, ssrc_generator_);
674 }
675
676 if (media_channel()->AddSendStream(new_stream)) {
677 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0];
678 } else {
679 rtc::StringBuilder desc;
680 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc();
681 SafeSetError(desc.str(), error_desc);
682 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36683 }
684 }
Amit Hilbuchbcd39d42019-01-26 01:13:56685 local_streams_ = all_streams;
henrike@webrtc.org28e20752013-07-10 00:45:36686 return ret;
687}
688
689bool BaseChannel::UpdateRemoteStreams_w(
690 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 18:34:51691 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54692 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36693 // Check for streams that have been removed.
694 bool ret = true;
Steve Anton5f8b5fd2018-12-28 00:58:10695 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 18:16:33696 // If we no longer have an unsignaled stream, we would like to remove
697 // the unsignaled stream params that are cached.
Steve Anton5f8b5fd2018-12-28 00:58:10698 if ((!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
699 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
700 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
701 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc();
Zhi Huang365381f2018-04-13 23:44:34702 } else {
Jonas Olsson366a50c2018-09-06 11:41:30703 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-28 00:58:10704 desc << "Failed to remove remote stream with ssrc "
705 << old_stream.first_ssrc() << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54706 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36707 ret = false;
708 }
709 }
710 }
Zhi Huang365381f2018-04-13 23:44:34711 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36712 // Check for new streams.
Steve Anton5f8b5fd2018-12-28 00:58:10713 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 18:16:33714 // We allow a StreamParams with an empty list of SSRCs, in which case the
715 // MediaChannel will cache the parameters and use them for any unsignaled
716 // stream received later.
Steve Anton5f8b5fd2018-12-28 00:58:10717 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
718 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
719 if (AddRecvStream_w(new_stream)) {
720 RTC_LOG(LS_INFO) << "Add remote ssrc: " << new_stream.first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36721 } else {
Jonas Olsson366a50c2018-09-06 11:41:30722 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-28 00:58:10723 desc << "Failed to add remote stream ssrc: " << new_stream.first_ssrc();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54724 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36725 ret = false;
726 }
727 }
Zhi Huang365381f2018-04-13 23:44:34728 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-28 00:58:10729 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
730 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36731 }
Zhi Huang365381f2018-04-13 23:44:34732 // Re-register the sink to update the receiving ssrcs.
733 RegisterRtpDemuxerSink();
henrike@webrtc.org28e20752013-07-10 00:45:36734 remote_streams_ = streams;
735 return ret;
736}
737
jbauch5869f502017-06-29 19:31:36738RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
739 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 17:48:35740 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 22:33:17741 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 19:31:36742 RtpHeaderExtensions filtered;
Steve Anton64b626b2019-01-29 01:25:26743 absl::c_copy_if(extensions, std::back_inserter(filtered),
744 [](const webrtc::RtpExtension& extension) {
745 return !extension.encrypt;
746 });
jbauch5869f502017-06-29 19:31:36747 return filtered;
748 }
749
750 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
751}
752
Yves Gerey665174f2018-06-19 13:03:05753void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 22:17:15754 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36755 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 17:55:27756 case MSG_SEND_RTP_PACKET:
757 case MSG_SEND_RTCP_PACKET: {
758 RTC_DCHECK(network_thread_->IsCurrent());
759 SendPacketMessageData* data =
760 static_cast<SendPacketMessageData*>(pmsg->pdata);
761 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
762 SendPacket(rtcp, &data->packet, data->options);
763 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36764 break;
765 }
766 case MSG_FIRSTPACKETRECEIVED: {
Amit Hilbuchdd9390c2018-11-14 00:26:05767 SignalFirstPacketReceived_(this);
henrike@webrtc.org28e20752013-07-10 00:45:36768 break;
769 }
henrike@webrtc.org28e20752013-07-10 00:45:36770 }
771}
772
zstein3dcf0e92017-06-01 20:22:42773void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 23:44:34774 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 20:22:42775}
776
Danil Chapovalov33b01f22016-05-11 17:55:27777void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36778 // Flush all remaining RTCP messages. This should only be called in
779 // destructor.
Danil Chapovalov33b01f22016-05-11 17:55:27780 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52781 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 17:55:27782 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
783 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 21:17:27784 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
785 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36786 }
787}
788
Zhi Huangcd3fc5d2017-11-29 18:41:57789void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 17:55:27790 RTC_DCHECK(network_thread_->IsCurrent());
791 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:27792 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 17:55:27793 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
794}
795
796void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
797 RTC_DCHECK(worker_thread_->IsCurrent());
798 SignalSentPacket(sent_packet);
799}
800
801VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
802 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-13 03:37:48803 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 23:53:33804 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36805 const std::string& content_name,
Zhi Huange830e682018-03-30 17:48:35806 bool srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56807 webrtc::CryptoOptions crypto_options,
808 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 17:55:27809 : BaseChannel(worker_thread,
810 network_thread,
zhihuangf5b251b2017-01-13 03:37:48811 signaling_thread,
Steve Anton8699a322017-11-06 23:53:33812 std::move(media_channel),
deadbeefcbecd352015-09-23 18:50:27813 content_name,
Zhi Huange830e682018-03-30 17:48:35814 srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56815 crypto_options,
816 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36817
818VoiceChannel::~VoiceChannel() {
Piotr (Peter) Slatala309aafe2019-01-15 22:24:34819 if (media_transport()) {
820 media_transport()->SetFirstAudioPacketReceivedObserver(nullptr);
821 }
Peter Boströmca8b4042016-03-08 22:24:13822 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36823 // this can't be done in the base class, since it calls a virtual
824 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 20:17:42825 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36826}
827
Taylor Brandstetterbad33bf2016-08-25 20:31:14828void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 17:55:27829 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 20:31:14830 invoker_.AsyncInvoke<void>(
831 RTC_FROM_HERE, worker_thread_,
832 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 17:55:27833}
834
Piotr (Peter) Slatala179a3922018-11-16 17:57:58835void BaseChannel::OnNetworkRouteChanged(
836 const rtc::NetworkRoute& network_route) {
837 OnNetworkRouteChanged(absl::make_optional(network_route));
838}
839
Piotr (Peter) Slatala309aafe2019-01-15 22:24:34840void VoiceChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport,
841 webrtc::MediaTransportInterface* media_transport) {
842 BaseChannel::Init_w(rtp_transport, media_transport);
843 if (BaseChannel::media_transport()) {
844 this->media_transport()->SetFirstAudioPacketReceivedObserver(this);
845 }
846}
847
848void VoiceChannel::OnFirstAudioPacketReceived(int64_t channel_id) {
849 has_received_packet_ = true;
850 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
851}
852
Taylor Brandstetterbad33bf2016-08-25 20:31:14853void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36854 // Render incoming data if we're the active call, and we have the local
855 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 20:31:14856 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 11:10:31857 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36858
859 // Send outgoing data if we're the active call, we have the remote content,
860 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 20:31:14861 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 20:37:39862 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36863
Mirko Bonadei675513b2017-11-09 10:09:25864 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36865}
866
henrike@webrtc.org28e20752013-07-10 00:45:36867bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:51868 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54869 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:57870 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 23:14:30871 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:25872 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36873
Steve Antonb1c1de12017-12-21 23:14:30874 RTC_DCHECK(content);
875 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54876 SafeSetError("Can't find audio content in local description.", error_desc);
877 return false;
878 }
henrike@webrtc.org28e20752013-07-10 00:45:36879
Steve Antonb1c1de12017-12-21 23:14:30880 const AudioContentDescription* audio = content->as_audio();
881
jbauch5869f502017-06-29 19:31:36882 RtpHeaderExtensions rtp_header_extensions =
883 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 23:44:34884 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 10:22:05885 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 19:31:36886
Peter Thatcherc2ee2c82015-08-07 23:05:34887 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 19:31:36888 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 23:05:34889 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-21 00:40:24890 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 23:05:34891 error_desc);
892 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36893 }
Peter Thatcherc2ee2c82015-08-07 23:05:34894 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 20:22:42895 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 23:05:34896 }
Zhi Huang365381f2018-04-13 23:44:34897 // Need to re-register the sink to update the handled payload.
898 if (!RegisterRtpDemuxerSink()) {
899 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
900 return false;
901 }
902
Peter Thatcherc2ee2c82015-08-07 23:05:34903 last_recv_params_ = recv_params;
904
905 // TODO(pthatcher): Move local streams into AudioSendParameters, and
906 // only give it to the media channel once we have a remote
907 // description too (without a remote description, we won't be able
908 // to send them anyway).
Steve Anton3828c062017-12-06 18:34:51909 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:34910 SafeSetError("Failed to set local audio description streams.", error_desc);
911 return false;
912 }
913
914 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:14915 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:34916 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36917}
918
919bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:51920 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54921 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:57922 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 23:14:30923 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:25924 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36925
Steve Antonb1c1de12017-12-21 23:14:30926 RTC_DCHECK(content);
927 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54928 SafeSetError("Can't find audio content in remote description.", error_desc);
929 return false;
930 }
henrike@webrtc.org28e20752013-07-10 00:45:36931
Steve Antonb1c1de12017-12-21 23:14:30932 const AudioContentDescription* audio = content->as_audio();
933
jbauch5869f502017-06-29 19:31:36934 RtpHeaderExtensions rtp_header_extensions =
935 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
936
Peter Thatcherc2ee2c82015-08-07 23:05:34937 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 19:31:36938 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
Yves Gerey665174f2018-06-19 13:03:05939 &send_params);
Steve Antonbb50ce52018-03-26 17:24:32940 send_params.mid = content_name();
skvladdc1c62c2016-03-17 02:07:43941
942 bool parameters_applied = media_channel()->SetSendParameters(send_params);
943 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 23:05:34944 SafeSetError("Failed to set remote audio description send parameters.",
945 error_desc);
946 return false;
947 }
948 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36949
Peter Thatcherc2ee2c82015-08-07 23:05:34950 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
951 // and only give it to the media channel once we have a local
952 // description too (without a local description, we won't be able to
953 // recv them anyway).
Steve Anton3828c062017-12-06 18:34:51954 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:34955 SafeSetError("Failed to set remote audio description streams.", error_desc);
956 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36957 }
958
Peter Thatcherc2ee2c82015-08-07 23:05:34959 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:14960 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:34961 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36962}
963
Danil Chapovalov33b01f22016-05-11 17:55:27964VideoChannel::VideoChannel(rtc::Thread* worker_thread,
965 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-13 03:37:48966 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 23:53:33967 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36968 const std::string& content_name,
Zhi Huange830e682018-03-30 17:48:35969 bool srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56970 webrtc::CryptoOptions crypto_options,
971 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 17:55:27972 : BaseChannel(worker_thread,
973 network_thread,
zhihuangf5b251b2017-01-13 03:37:48974 signaling_thread,
Steve Anton8699a322017-11-06 23:53:33975 std::move(media_channel),
deadbeefcbecd352015-09-23 18:50:27976 content_name,
Zhi Huange830e682018-03-30 17:48:35977 srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56978 crypto_options,
979 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36980
henrike@webrtc.org28e20752013-07-10 00:45:36981VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 22:24:13982 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36983 // this can't be done in the base class, since it calls a virtual
984 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 20:17:42985 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36986}
987
Taylor Brandstetterbad33bf2016-08-25 20:31:14988void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36989 // Send outgoing data if we're the active call, we have the remote content,
990 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 20:31:14991 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36992 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 10:09:25993 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36994 // TODO(gangji): Report error back to server.
995 }
996
Mirko Bonadei675513b2017-11-09 10:09:25997 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36998}
999
stefanf79ade12017-06-02 13:44:031000void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
1001 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
1002 media_channel(), bwe_info));
1003}
1004
henrike@webrtc.org28e20752013-07-10 00:45:361005bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:511006 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541007 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:571008 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 23:14:301009 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:251010 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:361011
Steve Antonb1c1de12017-12-21 23:14:301012 RTC_DCHECK(content);
1013 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541014 SafeSetError("Can't find video content in local description.", error_desc);
1015 return false;
1016 }
henrike@webrtc.org28e20752013-07-10 00:45:361017
Steve Antonb1c1de12017-12-21 23:14:301018 const VideoContentDescription* video = content->as_video();
1019
jbauch5869f502017-06-29 19:31:361020 RtpHeaderExtensions rtp_header_extensions =
1021 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 23:44:341022 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 10:22:051023 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 19:31:361024
Peter Thatcherc2ee2c82015-08-07 23:05:341025 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 19:31:361026 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 23:05:341027 if (!media_channel()->SetRecvParameters(recv_params)) {
1028 SafeSetError("Failed to set local video description recv parameters.",
1029 error_desc);
1030 return false;
1031 }
1032 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 20:22:421033 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 23:05:341034 }
Zhi Huang365381f2018-04-13 23:44:341035 // Need to re-register the sink to update the handled payload.
1036 if (!RegisterRtpDemuxerSink()) {
1037 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
1038 return false;
1039 }
1040
Peter Thatcherc2ee2c82015-08-07 23:05:341041 last_recv_params_ = recv_params;
1042
1043 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1044 // only give it to the media channel once we have a remote
1045 // description too (without a remote description, we won't be able
1046 // to send them anyway).
Steve Anton3828c062017-12-06 18:34:511047 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:341048 SafeSetError("Failed to set local video description streams.", error_desc);
1049 return false;
henrike@webrtc.org28e20752013-07-10 00:45:361050 }
1051
Peter Thatcherc2ee2c82015-08-07 23:05:341052 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:141053 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:341054 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361055}
1056
1057bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:511058 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541059 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:571060 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 23:14:301061 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:251062 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:361063
Steve Antonb1c1de12017-12-21 23:14:301064 RTC_DCHECK(content);
1065 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541066 SafeSetError("Can't find video content in remote description.", error_desc);
1067 return false;
1068 }
henrike@webrtc.org28e20752013-07-10 00:45:361069
Steve Antonb1c1de12017-12-21 23:14:301070 const VideoContentDescription* video = content->as_video();
1071
jbauch5869f502017-06-29 19:31:361072 RtpHeaderExtensions rtp_header_extensions =
1073 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1074
Peter Thatcherc2ee2c82015-08-07 23:05:341075 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 19:31:361076 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
Yves Gerey665174f2018-06-19 13:03:051077 &send_params);
Peter Thatcherc2ee2c82015-08-07 23:05:341078 if (video->conference_mode()) {
nisse4b4dc862016-02-17 13:25:361079 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 23:05:341080 }
Steve Antonbb50ce52018-03-26 17:24:321081 send_params.mid = content_name();
skvladdc1c62c2016-03-17 02:07:431082
1083 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1084
1085 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 23:05:341086 SafeSetError("Failed to set remote video description send parameters.",
1087 error_desc);
1088 return false;
1089 }
1090 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:361091
Peter Thatcherc2ee2c82015-08-07 23:05:341092 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1093 // and only give it to the media channel once we have a local
1094 // description too (without a local description, we won't be able to
1095 // recv them anyway).
Steve Anton3828c062017-12-06 18:34:511096 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:341097 SafeSetError("Failed to set remote video description streams.", error_desc);
1098 return false;
henrike@webrtc.org28e20752013-07-10 00:45:361099 }
Peter Thatcherc2ee2c82015-08-07 23:05:341100 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:141101 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:341102 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361103}
1104
deadbeef953c2ce2017-01-09 22:53:411105RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1106 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-13 03:37:481107 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 23:53:331108 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 22:53:411109 const std::string& content_name,
Zhi Huange830e682018-03-30 17:48:351110 bool srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:561111 webrtc::CryptoOptions crypto_options,
1112 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 17:55:271113 : BaseChannel(worker_thread,
1114 network_thread,
zhihuangf5b251b2017-01-13 03:37:481115 signaling_thread,
Steve Anton8699a322017-11-06 23:53:331116 std::move(media_channel),
deadbeefcbecd352015-09-23 18:50:271117 content_name,
Zhi Huange830e682018-03-30 17:48:351118 srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:561119 crypto_options,
1120 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:361121
deadbeef953c2ce2017-01-09 22:53:411122RtpDataChannel::~RtpDataChannel() {
1123 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:361124 // this can't be done in the base class, since it calls a virtual
1125 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 20:17:421126 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:361127}
1128
Piotr (Peter) Slatala309aafe2019-01-15 22:24:341129void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport,
1130 webrtc::MediaTransportInterface* media_transport) {
Anton Sukhanov98a462c2018-10-17 20:15:421131 BaseChannel::Init_w(rtp_transport, /*media_transport=*/nullptr);
Zhi Huang2dfc42d2017-12-04 21:38:481132 media_channel()->SignalDataReceived.connect(this,
1133 &RtpDataChannel::OnDataReceived);
1134 media_channel()->SignalReadyToSend.connect(
1135 this, &RtpDataChannel::OnDataChannelReadyToSend);
1136}
1137
deadbeef953c2ce2017-01-09 22:53:411138bool RtpDataChannel::SendData(const SendDataParams& params,
1139 const rtc::CopyOnWriteBuffer& payload,
1140 SendDataResult* result) {
stefanf79ade12017-06-02 13:44:031141 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:271142 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1143 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:361144}
1145
deadbeef953c2ce2017-01-09 22:53:411146bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541147 const DataContentDescription* content,
1148 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:361149 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1150 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 22:53:411151 // It's been set before, but doesn't match. That's bad.
1152 if (is_sctp) {
1153 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1154 error_desc);
1155 return false;
1156 }
1157 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361158}
1159
deadbeef953c2ce2017-01-09 22:53:411160bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:511161 SdpType type,
deadbeef953c2ce2017-01-09 22:53:411162 std::string* error_desc) {
1163 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 23:14:301164 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:251165 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:361166
Steve Antonb1c1de12017-12-21 23:14:301167 RTC_DCHECK(content);
1168 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541169 SafeSetError("Can't find data content in local description.", error_desc);
1170 return false;
1171 }
henrike@webrtc.org28e20752013-07-10 00:45:361172
Steve Antonb1c1de12017-12-21 23:14:301173 const DataContentDescription* data = content->as_data();
1174
deadbeef953c2ce2017-01-09 22:53:411175 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:361176 return false;
1177 }
1178
jbauch5869f502017-06-29 19:31:361179 RtpHeaderExtensions rtp_header_extensions =
1180 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1181
Peter Thatcherc2ee2c82015-08-07 23:05:341182 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 19:31:361183 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 23:05:341184 if (!media_channel()->SetRecvParameters(recv_params)) {
1185 SafeSetError("Failed to set remote data description recv parameters.",
1186 error_desc);
1187 return false;
henrike@webrtc.org28e20752013-07-10 00:45:361188 }
deadbeef953c2ce2017-01-09 22:53:411189 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 20:22:421190 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 23:05:341191 }
Zhi Huang365381f2018-04-13 23:44:341192 // Need to re-register the sink to update the handled payload.
1193 if (!RegisterRtpDemuxerSink()) {
1194 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1195 return false;
1196 }
1197
Peter Thatcherc2ee2c82015-08-07 23:05:341198 last_recv_params_ = recv_params;
1199
1200 // TODO(pthatcher): Move local streams into DataSendParameters, and
1201 // only give it to the media channel once we have a remote
1202 // description too (without a remote description, we won't be able
1203 // to send them anyway).
Steve Anton3828c062017-12-06 18:34:511204 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:341205 SafeSetError("Failed to set local data description streams.", error_desc);
1206 return false;
1207 }
1208
1209 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:141210 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:341211 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361212}
1213
deadbeef953c2ce2017-01-09 22:53:411214bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:511215 SdpType type,
deadbeef953c2ce2017-01-09 22:53:411216 std::string* error_desc) {
1217 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 23:14:301218 RTC_DCHECK_RUN_ON(worker_thread());
1219 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:361220
Steve Antonb1c1de12017-12-21 23:14:301221 RTC_DCHECK(content);
1222 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541223 SafeSetError("Can't find data content in remote description.", error_desc);
1224 return false;
1225 }
henrike@webrtc.org28e20752013-07-10 00:45:361226
Steve Antonb1c1de12017-12-21 23:14:301227 const DataContentDescription* data = content->as_data();
1228
Zhi Huang801b8682017-11-15 19:36:431229 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1230 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 23:05:341231 return true;
1232 }
1233
deadbeef953c2ce2017-01-09 22:53:411234 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:361235 return false;
1236 }
1237
jbauch5869f502017-06-29 19:31:361238 RtpHeaderExtensions rtp_header_extensions =
1239 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1240
Mirko Bonadei675513b2017-11-09 10:09:251241 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 23:05:341242 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 19:31:361243 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
Yves Gerey665174f2018-06-19 13:03:051244 &send_params);
Peter Thatcherc2ee2c82015-08-07 23:05:341245 if (!media_channel()->SetSendParameters(send_params)) {
1246 SafeSetError("Failed to set remote data description send parameters.",
1247 error_desc);
1248 return false;
henrike@webrtc.org28e20752013-07-10 00:45:361249 }
Peter Thatcherc2ee2c82015-08-07 23:05:341250 last_send_params_ = send_params;
1251
1252 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1253 // and only give it to the media channel once we have a local
1254 // description too (without a local description, we won't be able to
1255 // recv them anyway).
Steve Anton3828c062017-12-06 18:34:511256 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yves Gerey665174f2018-06-19 13:03:051257 SafeSetError("Failed to set remote data description streams.", error_desc);
Peter Thatcherc2ee2c82015-08-07 23:05:341258 return false;
1259 }
1260
1261 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:141262 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:341263 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361264}
1265
deadbeef953c2ce2017-01-09 22:53:411266void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:361267 // Render incoming data if we're the active call, and we have the local
1268 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 20:31:141269 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:361270 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 10:09:251271 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:361272 }
1273
1274 // Send outgoing data if we're the active call, we have the remote content,
1275 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 20:31:141276 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:361277 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 10:09:251278 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:361279 }
1280
sergeyu@chromium.org9cf037b2014-02-07 19:03:261281 // Trigger SignalReadyToSendData asynchronously.
1282 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:361283
Mirko Bonadei675513b2017-11-09 10:09:251284 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:361285}
1286
deadbeef953c2ce2017-01-09 22:53:411287void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:361288 switch (pmsg->message_id) {
1289 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:071290 DataChannelReadyToSendMessageData* data =
1291 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:341292 ready_to_send_data_ = data->data();
1293 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:361294 delete data;
1295 break;
1296 }
henrike@webrtc.org28e20752013-07-10 00:45:361297 case MSG_DATARECEIVED: {
1298 DataReceivedMessageData* data =
1299 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 22:53:411300 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:361301 delete data;
1302 break;
1303 }
henrike@webrtc.org28e20752013-07-10 00:45:361304 default:
1305 BaseChannel::OnMessage(pmsg);
1306 break;
1307 }
1308}
1309
deadbeef953c2ce2017-01-09 22:53:411310void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1311 const char* data,
1312 size_t len) {
Yves Gerey665174f2018-06-19 13:03:051313 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 21:17:271314 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:361315}
1316
deadbeef953c2ce2017-01-09 22:53:411317void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:071318 // This is usded for congestion control to indicate that the stream is ready
1319 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1320 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 21:17:271321 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:071322 new DataChannelReadyToSendMessageData(writable));
1323}
1324
henrike@webrtc.org28e20752013-07-10 00:45:361325} // namespace cricket