blob: d26a5113d41abb44300d9477f4ceec76852249e6 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellander65c7f672016-02-12 00:05:01 -08002 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellander65c7f672016-02-12 00:05:01 -08004 * 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:36 +00009 */
10
jbauch5869f502017-06-29 12:31:36 -070011#include <algorithm>
12#include <iterator>
kwiberg0eb15ed2015-12-17 03:04:15 -080013#include <utility>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "pc/channel.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000016
Karl Wiberg918f50c2018-07-05 11:40:33 +020017#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/call/audio_sink.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "media/base/media_constants.h"
20#include "media/base/rtp_utils.h"
Zhi Huang365381f2018-04-13 16:44:34 -070021#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/bind.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/byte_order.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/copy_on_write_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "rtc_base/dscp.h"
27#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/network_route.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020029#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "rtc_base/trace_event.h"
Patrik Höglund42805f32018-01-18 19:15:38 +000031// Adding 'nogncheck' to disable the gn include headers check to support modular
32// WebRTC build targets.
Steve Anton10542f22019-01-11 09:11:00 -080033#include "media/engine/webrtc_voice_engine.h" // nogncheck
34#include "p2p/base/packet_transport_internal.h"
35#include "pc/channel_manager.h"
36#include "pc/rtp_media_utils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
38namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000039using rtc::Bind;
Steve Anton3828c062017-12-06 10:34:51 -080040using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000041
deadbeef2d110be2016-01-13 12:00:26 -080042namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020043
44struct SendPacketMessageData : public rtc::MessageData {
45 rtc::CopyOnWriteBuffer packet;
46 rtc::PacketOptions options;
47};
48
deadbeef2d110be2016-01-13 12:00:26 -080049} // namespace
50
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051enum {
Steve Anton0807d152018-03-05 11:23:09 -080052 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020053 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057};
58
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000059static void SafeSetError(const std::string& message, std::string* error_desc) {
60 if (error_desc) {
61 *error_desc = message;
62 }
63}
64
jbaucheec21bd2016-03-20 06:15:43 -070065static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066 // Check the packet size. We could check the header too if needed.
zstein3dcf0e92017-06-01 13:22:42 -070067 return packet && IsValidRtpRtcpPacketSize(rtcp, packet->size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068}
69
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070070template <class Codec>
71void RtpParametersFromMediaDescription(
72 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070073 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070074 RtpParameters<Codec>* params) {
75 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 11:36:43 -080076 // a description without codecs. Currently the ORTC implementation is relying
77 // on this.
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070078 if (desc->has_codecs()) {
79 params->codecs = desc->codecs();
80 }
81 // TODO(pthatcher): See if we really need
82 // rtp_header_extensions_set() and remove it if we don't.
83 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -070084 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070085 }
deadbeef13871492015-12-09 12:37:51 -080086 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070087}
88
nisse05103312016-03-16 02:22:50 -070089template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070090void RtpSendParametersFromMediaDescription(
91 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070092 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 02:22:50 -070093 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 12:31:36 -070094 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070095 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 11:22:05 +010096 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070097}
98
Danil Chapovalov33b01f22016-05-11 19:55:27 +020099BaseChannel::BaseChannel(rtc::Thread* worker_thread,
100 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800101 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800102 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700103 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700104 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700105 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200106 : worker_thread_(worker_thread),
107 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800108 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000109 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800110 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700111 crypto_options_(crypto_options),
Zhi Huang1d88d742017-11-15 15:58:49 -0800112 media_channel_(std::move(media_channel)) {
Steve Anton8699a322017-11-06 15:53:33 -0800113 RTC_DCHECK_RUN_ON(worker_thread_);
Zhi Huang365381f2018-04-13 16:44:34 -0700114 demuxer_criteria_.mid = content_name;
Mirko Bonadei675513b2017-11-09 11:09:25 +0100115 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116}
117
118BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800119 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800120 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800121
122 if (media_transport_) {
123 media_transport_->SetNetworkChangeCallback(nullptr);
124 }
125
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200126 // Eats any outstanding messages or packets.
127 worker_thread_->Clear(&invoker_);
128 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129 // We must destroy the media channel before the transport channel, otherwise
130 // the media channel may try to send on the dead transport channel. NULLing
131 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800132 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100133 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200134}
135
Zhi Huang365381f2018-04-13 16:44:34 -0700136bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800137 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700138 if (!RegisterRtpDemuxerSink()) {
139 return false;
140 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800141 rtp_transport_->SignalReadyToSend.connect(
142 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang365381f2018-04-13 16:44:34 -0700143 rtp_transport_->SignalRtcpPacketReceived.connect(
144 this, &BaseChannel::OnRtcpPacketReceived);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800145
146 // If media transport is used, it's responsible for providing network
147 // route changed callbacks.
148 if (!media_transport_) {
149 rtp_transport_->SignalNetworkRouteChanged.connect(
150 this, &BaseChannel::OnNetworkRouteChanged);
151 }
152 // TODO(bugs.webrtc.org/9719): Media transport should also be used to provide
153 // 'writable' state here.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800154 rtp_transport_->SignalWritableState.connect(this,
155 &BaseChannel::OnWritableState);
156 rtp_transport_->SignalSentPacket.connect(this,
157 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 16:44:34 -0700158 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800159}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200160
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800161void BaseChannel::DisconnectFromRtpTransport() {
162 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700163 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800164 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang365381f2018-04-13 16:44:34 -0700165 rtp_transport_->SignalRtcpPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800166 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
167 rtp_transport_->SignalWritableState.disconnect(this);
168 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200169}
170
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700171void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport,
172 webrtc::MediaTransportInterface* media_transport) {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800173 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800174 media_transport_ = media_transport;
175
Zhi Huang365381f2018-04-13 16:44:34 -0700176 network_thread_->Invoke<void>(
177 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800178
179 // Both RTP and RTCP channels should be set, we can call SetInterface on
180 // the media channel and it can set network options.
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700181 media_channel_->SetInterface(this, media_transport);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800182
183 RTC_LOG(LS_INFO) << "BaseChannel::Init_w, media_transport="
184 << (media_transport_ != nullptr);
185 if (media_transport_) {
186 media_transport_->SetNetworkChangeCallback(this);
187 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200188}
189
wu@webrtc.org78187522013-10-07 23:32:02 +0000190void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200191 RTC_DCHECK(worker_thread_->IsCurrent());
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700192 media_channel_->SetInterface(/*iface=*/nullptr,
193 /*media_transport=*/nullptr);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200194 // Packets arrive on the network thread, processing packets calls virtual
195 // functions, so need to stop this process in Deinit that is called in
196 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800197 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000198 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700199
Zhi Huange830e682018-03-30 10:48:35 -0700200 if (rtp_transport_) {
201 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000202 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800203 // Clear pending read packets/messages.
204 network_thread_->Clear(&invoker_);
205 network_thread_->Clear(this);
206 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000207}
208
Zhi Huang365381f2018-04-13 16:44:34 -0700209bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
210 if (rtp_transport == rtp_transport_) {
211 return true;
212 }
213
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800214 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 16:44:34 -0700215 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
216 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800217 });
218 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000219
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800220 if (rtp_transport_) {
221 DisconnectFromRtpTransport();
222 }
Zhi Huange830e682018-03-30 10:48:35 -0700223
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800224 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700225 if (rtp_transport_) {
226 RTC_DCHECK(rtp_transport_->rtp_packet_transport());
227 transport_name_ = rtp_transport_->rtp_packet_transport()->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800228
Zhi Huang365381f2018-04-13 16:44:34 -0700229 if (!ConnectToRtpTransport()) {
230 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport.";
231 return false;
232 }
Zhi Huange830e682018-03-30 10:48:35 -0700233 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
234 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800235
Zhi Huange830e682018-03-30 10:48:35 -0700236 // Set the cached socket options.
237 for (const auto& pair : socket_options_) {
238 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
239 pair.second);
240 }
241 if (rtp_transport_->rtcp_packet_transport()) {
242 for (const auto& pair : rtcp_socket_options_) {
243 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
244 pair.second);
245 }
246 }
guoweis46383312015-12-17 16:45:59 -0800247 }
Zhi Huang365381f2018-04-13 16:44:34 -0700248 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000249}
250
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700252 worker_thread_->Invoke<void>(
253 RTC_FROM_HERE,
254 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
255 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 return true;
257}
258
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800260 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000261 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100262 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700263 return InvokeOnWorker<bool>(
264 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800265 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266}
267
268bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800269 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000270 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100271 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700272 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800273 RTC_FROM_HERE,
274 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275}
276
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700277bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800279 return enabled() &&
280 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281}
282
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700283bool BaseChannel::IsReadyToSendMedia_w() const {
284 // Need to access some state updated on the network thread.
285 return network_thread_->Invoke<bool>(
286 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
287}
288
289bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000290 // Send outgoing data if we are enabled, have local and remote content,
291 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800292 return enabled() &&
293 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
294 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 16:44:34 -0700295 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000296}
297
jbaucheec21bd2016-03-20 06:15:43 -0700298bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700299 const rtc::PacketOptions& options) {
300 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301}
302
jbaucheec21bd2016-03-20 06:15:43 -0700303bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700304 const rtc::PacketOptions& options) {
305 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000306}
307
Yves Gerey665174f2018-06-19 15:03:05 +0200308int BaseChannel::SetOption(SocketType type,
309 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200311 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700312 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200313}
314
315int BaseChannel::SetOption_n(SocketType type,
316 rtc::Socket::Option opt,
317 int value) {
318 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700319 RTC_DCHECK(rtp_transport_);
deadbeef5bd5ca32017-02-10 11:31:50 -0800320 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000322 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700323 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700324 socket_options_.push_back(
325 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000326 break;
327 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700328 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700329 rtcp_socket_options_.push_back(
330 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000331 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 }
deadbeeff5346592017-01-24 21:51:21 -0800333 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334}
335
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800336void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200337 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800338 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800339 ChannelWritable_n();
340 } else {
341 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800342 }
343}
344
Zhi Huang942bc2e2017-11-13 13:26:07 -0800345void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200346 absl::optional<rtc::NetworkRoute> network_route) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800347 RTC_LOG(LS_INFO) << "Network route was changed.";
348
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200349 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800350 rtc::NetworkRoute new_route;
351 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800352 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000353 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800354 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
355 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
356 // work correctly. Intentionally leave it broken to simplify the code and
357 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800358 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800359 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800360 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700361}
362
zstein56162b92017-04-24 16:54:35 -0700363void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800364 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
365 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366}
367
stefanc1aeaf02015-10-15 07:26:07 -0700368bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700369 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700370 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200371 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
372 // If the thread is not our network thread, we will post to our network
373 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374 // synchronize access to all the pieces of the send path, including
375 // SRTP and the inner workings of the transport channels.
376 // The only downside is that we can't return a proper failure code if
377 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200378 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000379 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200380 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
381 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800382 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700383 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700384 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000385 return true;
386 }
Zhi Huange830e682018-03-30 10:48:35 -0700387
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200388 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389
390 // Now that we are on the correct thread, ensure we have a place to send this
391 // packet before doing anything. (We might get RTCP packets that we don't
392 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
393 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700394 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395 return false;
396 }
397
398 // Protect ourselves against crazy data.
399 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100400 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
401 << RtpRtcpStringLiteral(rtcp)
402 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000403 return false;
404 }
405
Zhi Huangcf990f52017-09-22 12:12:30 -0700406 if (!srtp_active()) {
407 if (srtp_required_) {
408 // The audio/video engines may attempt to send RTCP packets as soon as the
409 // streams are created, so don't treat this as an error for RTCP.
410 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
411 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000412 return false;
413 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700414 // However, there shouldn't be any RTP packets sent before SRTP is set up
415 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100416 RTC_LOG(LS_ERROR)
417 << "Can't send outgoing RTP packet when SRTP is inactive"
418 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700419 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800420 return false;
421 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800422
423 std::string packet_type = rtcp ? "RTCP" : "RTP";
424 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
425 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000426 }
Zhi Huange830e682018-03-30 10:48:35 -0700427
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000428 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800429 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
430 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431}
432
Zhi Huang365381f2018-04-13 16:44:34 -0700433void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Niels Möller29e13fd2018-12-17 12:35:30 +0100434 // Take packet time from the |parsed_packet|.
435 // RtpPacketReceived.arrival_time_ms = (timestamp_us + 500) / 1000;
Niels Möllere6933812018-11-05 13:01:41 +0100436 int64_t timestamp_us = -1;
Zhi Huang365381f2018-04-13 16:44:34 -0700437 if (parsed_packet.arrival_time_ms() > 0) {
Niels Möllere6933812018-11-05 13:01:41 +0100438 timestamp_us = parsed_packet.arrival_time_ms() * 1000;
Zhi Huang365381f2018-04-13 16:44:34 -0700439 }
Zhi Huang365381f2018-04-13 16:44:34 -0700440
Niels Möllere6933812018-11-05 13:01:41 +0100441 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), timestamp_us);
Zhi Huang365381f2018-04-13 16:44:34 -0700442}
443
444void BaseChannel::UpdateRtpHeaderExtensionMap(
445 const RtpHeaderExtensions& header_extensions) {
446 RTC_DCHECK(rtp_transport_);
447 // Update the header extension map on network thread in case there is data
448 // race.
449 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
450 // be accessed from different threads.
451 //
452 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
453 // extension maps are not merged when BUNDLE is enabled. This is fine because
454 // the ID for MID should be consistent among all the RTP transports.
455 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
456 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
457 });
458}
459
460bool BaseChannel::RegisterRtpDemuxerSink() {
461 RTC_DCHECK(rtp_transport_);
462 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
463 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
464 });
465}
466
467void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
Niels Möllere6933812018-11-05 13:01:41 +0100468 int64_t packet_time_us) {
469 OnPacketReceived(/*rtcp=*/true, *packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000470}
471
zstein3dcf0e92017-06-01 13:22:42 -0700472void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang365381f2018-04-13 16:44:34 -0700473 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 13:01:41 +0100474 int64_t packet_time_us) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000475 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000476 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700477 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000478 }
479
Zhi Huangcf990f52017-09-22 12:12:30 -0700480 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000481 // Our session description indicates that SRTP is required, but we got a
482 // packet before our SRTP filter is active. This means either that
483 // a) we got SRTP packets before we received the SDES keys, in which case
484 // we can't decrypt it anyway, or
485 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800486 // transports, so we haven't yet extracted keys, even if DTLS did
487 // complete on the transport that the packets are being sent on. It's
488 // really good practice to wait for both RTP and RTCP to be good to go
489 // before sending media, to prevent weird failure modes, so it's fine
490 // for us to just eat packets here. This is all sidestepped if RTCP mux
491 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100492 RTC_LOG(LS_WARNING)
493 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
494 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000495 return;
496 }
497
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200498 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700499 RTC_FROM_HERE, worker_thread_,
Niels Möllere6933812018-11-05 13:01:41 +0100500 Bind(&BaseChannel::ProcessPacket, this, rtcp, packet, packet_time_us));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200501}
502
zstein3dcf0e92017-06-01 13:22:42 -0700503void BaseChannel::ProcessPacket(bool rtcp,
504 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 13:01:41 +0100505 int64_t packet_time_us) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200506 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700507
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200508 // Need to copy variable because OnRtcpReceived/OnPacketReceived
509 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
510 rtc::CopyOnWriteBuffer data(packet);
511 if (rtcp) {
Niels Möllere6933812018-11-05 13:01:41 +0100512 media_channel_->OnRtcpReceived(&data, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000513 } else {
Niels Möllere6933812018-11-05 13:01:41 +0100514 media_channel_->OnPacketReceived(&data, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000515 }
516}
517
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000518void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700519 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 if (enabled_)
521 return;
522
Mirko Bonadei675513b2017-11-09 11:09:25 +0100523 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000524 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700525 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526}
527
528void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700529 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000530 if (!enabled_)
531 return;
532
Mirko Bonadei675513b2017-11-09 11:09:25 +0100533 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000534 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700535 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536}
537
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200538void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700539 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
540 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200541 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700542 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200543 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700544 }
545}
546
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200547void BaseChannel::ChannelWritable_n() {
548 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800549 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000550 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800551 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000552
Mirko Bonadei675513b2017-11-09 11:09:25 +0100553 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
554 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000556 was_ever_writable_ = true;
557 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700558 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559}
560
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200561void BaseChannel::ChannelNotWritable_n() {
562 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000563 if (!writable_)
564 return;
565
Mirko Bonadei675513b2017-11-09 11:09:25 +0100566 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700568 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569}
570
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700572 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800573 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000574}
575
Peter Boström0c4e06b2015-10-07 12:23:21 +0200576bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700577 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 return media_channel()->RemoveRecvStream(ssrc);
579}
580
581bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800582 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000583 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000584 // Check for streams that have been removed.
585 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800586 for (const StreamParams& old_stream : local_streams_) {
587 if (old_stream.has_ssrcs() &&
588 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
589 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200590 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800591 desc << "Failed to remove send stream with ssrc "
592 << old_stream.first_ssrc() << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000593 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000594 ret = false;
595 }
596 }
597 }
598 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800599 for (const StreamParams& new_stream : streams) {
600 if (new_stream.has_ssrcs() &&
601 !GetStreamBySsrc(local_streams_, new_stream.first_ssrc())) {
602 if (media_channel()->AddSendStream(new_stream)) {
603 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000604 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200605 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800606 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000607 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000608 ret = false;
609 }
610 }
611 }
612 local_streams_ = streams;
613 return ret;
614}
615
616bool BaseChannel::UpdateRemoteStreams_w(
617 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800618 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000619 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000620 // Check for streams that have been removed.
621 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800622 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700623 // If we no longer have an unsignaled stream, we would like to remove
624 // the unsignaled stream params that are cached.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800625 if ((!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
626 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
627 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
628 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc();
Zhi Huang365381f2018-04-13 16:44:34 -0700629 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200630 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800631 desc << "Failed to remove remote stream with ssrc "
632 << old_stream.first_ssrc() << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000633 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000634 ret = false;
635 }
636 }
637 }
Zhi Huang365381f2018-04-13 16:44:34 -0700638 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000639 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800640 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700641 // We allow a StreamParams with an empty list of SSRCs, in which case the
642 // MediaChannel will cache the parameters and use them for any unsignaled
643 // stream received later.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800644 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
645 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
646 if (AddRecvStream_w(new_stream)) {
647 RTC_LOG(LS_INFO) << "Add remote ssrc: " << new_stream.first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200649 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800650 desc << "Failed to add remote stream ssrc: " << new_stream.first_ssrc();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000651 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000652 ret = false;
653 }
654 }
Zhi Huang365381f2018-04-13 16:44:34 -0700655 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800656 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
657 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658 }
Zhi Huang365381f2018-04-13 16:44:34 -0700659 // Re-register the sink to update the receiving ssrcs.
660 RegisterRtpDemuxerSink();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000661 remote_streams_ = streams;
662 return ret;
663}
664
jbauch5869f502017-06-29 12:31:36 -0700665RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
666 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700667 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700668 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700669 RtpHeaderExtensions filtered;
670 auto pred = [](const webrtc::RtpExtension& extension) {
Yves Gerey665174f2018-06-19 15:03:05 +0200671 return !extension.encrypt;
jbauch5869f502017-06-29 12:31:36 -0700672 };
673 std::copy_if(extensions.begin(), extensions.end(),
Yves Gerey665174f2018-06-19 15:03:05 +0200674 std::back_inserter(filtered), pred);
jbauch5869f502017-06-29 12:31:36 -0700675 return filtered;
676 }
677
678 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
679}
680
Yves Gerey665174f2018-06-19 15:03:05 +0200681void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100682 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000683 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200684 case MSG_SEND_RTP_PACKET:
685 case MSG_SEND_RTCP_PACKET: {
686 RTC_DCHECK(network_thread_->IsCurrent());
687 SendPacketMessageData* data =
688 static_cast<SendPacketMessageData*>(pmsg->pdata);
689 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
690 SendPacket(rtcp, &data->packet, data->options);
691 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692 break;
693 }
694 case MSG_FIRSTPACKETRECEIVED: {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800695 SignalFirstPacketReceived_(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000696 break;
697 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698 }
699}
700
zstein3dcf0e92017-06-01 13:22:42 -0700701void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 16:44:34 -0700702 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -0700703}
704
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200705void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000706 // Flush all remaining RTCP messages. This should only be called in
707 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200708 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000709 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200710 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
711 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700712 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
713 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 }
715}
716
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800717void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200718 RTC_DCHECK(network_thread_->IsCurrent());
719 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700720 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200721 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
722}
723
724void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
725 RTC_DCHECK(worker_thread_->IsCurrent());
726 SignalSentPacket(sent_packet);
727}
728
729VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
730 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800731 rtc::Thread* signaling_thread,
Niels Möllerf120cba2018-01-30 09:33:03 +0100732 // TODO(nisse): Delete unused argument.
733 MediaEngineInterface* /* media_engine */,
Steve Anton8699a322017-11-06 15:53:33 -0800734 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000735 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700736 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700737 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200738 : BaseChannel(worker_thread,
739 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800740 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800741 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700742 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700743 srtp_required,
744 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000745
746VoiceChannel::~VoiceChannel() {
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -0800747 if (media_transport()) {
748 media_transport()->SetFirstAudioPacketReceivedObserver(nullptr);
749 }
Peter Boströmca8b4042016-03-08 14:24:13 -0800750 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751 // this can't be done in the base class, since it calls a virtual
752 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700753 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000754}
755
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700756void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200757 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700758 invoker_.AsyncInvoke<void>(
759 RTC_FROM_HERE, worker_thread_,
760 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200761}
762
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800763void BaseChannel::OnNetworkRouteChanged(
764 const rtc::NetworkRoute& network_route) {
765 OnNetworkRouteChanged(absl::make_optional(network_route));
766}
767
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -0800768void VoiceChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport,
769 webrtc::MediaTransportInterface* media_transport) {
770 BaseChannel::Init_w(rtp_transport, media_transport);
771 if (BaseChannel::media_transport()) {
772 this->media_transport()->SetFirstAudioPacketReceivedObserver(this);
773 }
774}
775
776void VoiceChannel::OnFirstAudioPacketReceived(int64_t channel_id) {
777 has_received_packet_ = true;
778 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
779}
780
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700781void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782 // Render incoming data if we're the active call, and we have the local
783 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700784 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700785 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786
787 // Send outgoing data if we're the active call, we have the remote content,
788 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700789 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800790 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791
Mirko Bonadei675513b2017-11-09 11:09:25 +0100792 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000793}
794
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800796 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000797 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100798 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800799 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100800 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000801
Steve Antonb1c1de12017-12-21 15:14:30 -0800802 RTC_DCHECK(content);
803 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000804 SafeSetError("Can't find audio content in local description.", error_desc);
805 return false;
806 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807
Steve Antonb1c1de12017-12-21 15:14:30 -0800808 const AudioContentDescription* audio = content->as_audio();
809
jbauch5869f502017-06-29 12:31:36 -0700810 RtpHeaderExtensions rtp_header_extensions =
811 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700812 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100813 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700814
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700815 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700816 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700817 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -0700818 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700819 error_desc);
820 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700822 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700823 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700824 }
Zhi Huang365381f2018-04-13 16:44:34 -0700825 // Need to re-register the sink to update the handled payload.
826 if (!RegisterRtpDemuxerSink()) {
827 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
828 return false;
829 }
830
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700831 last_recv_params_ = recv_params;
832
833 // TODO(pthatcher): Move local streams into AudioSendParameters, and
834 // only give it to the media channel once we have a remote
835 // description too (without a remote description, we won't be able
836 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800837 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700838 SafeSetError("Failed to set local audio description streams.", error_desc);
839 return false;
840 }
841
842 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700843 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700844 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845}
846
847bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800848 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000849 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100850 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800851 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100852 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853
Steve Antonb1c1de12017-12-21 15:14:30 -0800854 RTC_DCHECK(content);
855 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000856 SafeSetError("Can't find audio content in remote description.", error_desc);
857 return false;
858 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859
Steve Antonb1c1de12017-12-21 15:14:30 -0800860 const AudioContentDescription* audio = content->as_audio();
861
jbauch5869f502017-06-29 12:31:36 -0700862 RtpHeaderExtensions rtp_header_extensions =
863 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
864
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700865 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700866 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +0200867 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700868 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700869
870 bool parameters_applied = media_channel()->SetSendParameters(send_params);
871 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700872 SafeSetError("Failed to set remote audio description send parameters.",
873 error_desc);
874 return false;
875 }
876 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700878 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
879 // and only give it to the media channel once we have a local
880 // description too (without a local description, we won't be able to
881 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800882 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700883 SafeSetError("Failed to set remote audio description streams.", error_desc);
884 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 }
886
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700887 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700888 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700889 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890}
891
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200892VideoChannel::VideoChannel(rtc::Thread* worker_thread,
893 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800894 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800895 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700897 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700898 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200899 : BaseChannel(worker_thread,
900 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800901 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800902 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700903 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700904 srtp_required,
905 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800908 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909 // this can't be done in the base class, since it calls a virtual
910 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700911 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912}
913
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700914void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915 // Send outgoing data if we're the active call, we have the remote content,
916 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700917 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100919 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920 // TODO(gangji): Report error back to server.
921 }
922
Mirko Bonadei675513b2017-11-09 11:09:25 +0100923 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924}
925
stefanf79ade12017-06-02 06:44:03 -0700926void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
927 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
928 media_channel(), bwe_info));
929}
930
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800932 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000933 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100934 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800935 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100936 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937
Steve Antonb1c1de12017-12-21 15:14:30 -0800938 RTC_DCHECK(content);
939 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000940 SafeSetError("Can't find video content in local description.", error_desc);
941 return false;
942 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
Steve Antonb1c1de12017-12-21 15:14:30 -0800944 const VideoContentDescription* video = content->as_video();
945
jbauch5869f502017-06-29 12:31:36 -0700946 RtpHeaderExtensions rtp_header_extensions =
947 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700948 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100949 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700950
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700951 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700952 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700953 if (!media_channel()->SetRecvParameters(recv_params)) {
954 SafeSetError("Failed to set local video description recv parameters.",
955 error_desc);
956 return false;
957 }
958 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700959 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700960 }
Zhi Huang365381f2018-04-13 16:44:34 -0700961 // Need to re-register the sink to update the handled payload.
962 if (!RegisterRtpDemuxerSink()) {
963 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
964 return false;
965 }
966
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700967 last_recv_params_ = recv_params;
968
969 // TODO(pthatcher): Move local streams into VideoSendParameters, and
970 // only give it to the media channel once we have a remote
971 // description too (without a remote description, we won't be able
972 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800973 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700974 SafeSetError("Failed to set local video description streams.", error_desc);
975 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976 }
977
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700978 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700979 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700980 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981}
982
983bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800984 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000985 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100986 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800987 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100988 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000989
Steve Antonb1c1de12017-12-21 15:14:30 -0800990 RTC_DCHECK(content);
991 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000992 SafeSetError("Can't find video content in remote description.", error_desc);
993 return false;
994 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995
Steve Antonb1c1de12017-12-21 15:14:30 -0800996 const VideoContentDescription* video = content->as_video();
997
jbauch5869f502017-06-29 12:31:36 -0700998 RtpHeaderExtensions rtp_header_extensions =
999 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1000
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001001 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001002 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001003 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001004 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001005 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001006 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001007 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001008
1009 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1010
1011 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001012 SafeSetError("Failed to set remote video description send parameters.",
1013 error_desc);
1014 return false;
1015 }
1016 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001018 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1019 // and only give it to the media channel once we have a local
1020 // description too (without a local description, we won't be able to
1021 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001022 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001023 SafeSetError("Failed to set remote video description streams.", error_desc);
1024 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001026 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001027 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001028 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001029}
1030
deadbeef953c2ce2017-01-09 14:53:41 -08001031RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1032 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001033 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001034 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001035 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001036 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001037 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001038 : BaseChannel(worker_thread,
1039 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001040 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001041 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001042 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001043 srtp_required,
1044 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001045
deadbeef953c2ce2017-01-09 14:53:41 -08001046RtpDataChannel::~RtpDataChannel() {
1047 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001048 // this can't be done in the base class, since it calls a virtual
1049 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001050 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001051}
1052
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -08001053void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport,
1054 webrtc::MediaTransportInterface* media_transport) {
Anton Sukhanov98a462c2018-10-17 13:15:42 -07001055 BaseChannel::Init_w(rtp_transport, /*media_transport=*/nullptr);
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001056 media_channel()->SignalDataReceived.connect(this,
1057 &RtpDataChannel::OnDataReceived);
1058 media_channel()->SignalReadyToSend.connect(
1059 this, &RtpDataChannel::OnDataChannelReadyToSend);
1060}
1061
deadbeef953c2ce2017-01-09 14:53:41 -08001062bool RtpDataChannel::SendData(const SendDataParams& params,
1063 const rtc::CopyOnWriteBuffer& payload,
1064 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001065 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001066 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1067 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001068}
1069
deadbeef953c2ce2017-01-09 14:53:41 -08001070bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001071 const DataContentDescription* content,
1072 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001073 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1074 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001075 // It's been set before, but doesn't match. That's bad.
1076 if (is_sctp) {
1077 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1078 error_desc);
1079 return false;
1080 }
1081 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001082}
1083
deadbeef953c2ce2017-01-09 14:53:41 -08001084bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001085 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001086 std::string* error_desc) {
1087 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001088 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001089 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001090
Steve Antonb1c1de12017-12-21 15:14:30 -08001091 RTC_DCHECK(content);
1092 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001093 SafeSetError("Can't find data content in local description.", error_desc);
1094 return false;
1095 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001096
Steve Antonb1c1de12017-12-21 15:14:30 -08001097 const DataContentDescription* data = content->as_data();
1098
deadbeef953c2ce2017-01-09 14:53:41 -08001099 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001100 return false;
1101 }
1102
jbauch5869f502017-06-29 12:31:36 -07001103 RtpHeaderExtensions rtp_header_extensions =
1104 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1105
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001106 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001107 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001108 if (!media_channel()->SetRecvParameters(recv_params)) {
1109 SafeSetError("Failed to set remote data description recv parameters.",
1110 error_desc);
1111 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001112 }
deadbeef953c2ce2017-01-09 14:53:41 -08001113 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001114 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001115 }
Zhi Huang365381f2018-04-13 16:44:34 -07001116 // Need to re-register the sink to update the handled payload.
1117 if (!RegisterRtpDemuxerSink()) {
1118 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1119 return false;
1120 }
1121
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001122 last_recv_params_ = recv_params;
1123
1124 // TODO(pthatcher): Move local streams into DataSendParameters, and
1125 // only give it to the media channel once we have a remote
1126 // description too (without a remote description, we won't be able
1127 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001128 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001129 SafeSetError("Failed to set local data description streams.", error_desc);
1130 return false;
1131 }
1132
1133 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001134 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001135 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001136}
1137
deadbeef953c2ce2017-01-09 14:53:41 -08001138bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001139 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001140 std::string* error_desc) {
1141 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001142 RTC_DCHECK_RUN_ON(worker_thread());
1143 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001144
Steve Antonb1c1de12017-12-21 15:14:30 -08001145 RTC_DCHECK(content);
1146 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001147 SafeSetError("Can't find data content in remote description.", error_desc);
1148 return false;
1149 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001150
Steve Antonb1c1de12017-12-21 15:14:30 -08001151 const DataContentDescription* data = content->as_data();
1152
Zhi Huang801b8682017-11-15 11:36:43 -08001153 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1154 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001155 return true;
1156 }
1157
deadbeef953c2ce2017-01-09 14:53:41 -08001158 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001159 return false;
1160 }
1161
jbauch5869f502017-06-29 12:31:36 -07001162 RtpHeaderExtensions rtp_header_extensions =
1163 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1164
Mirko Bonadei675513b2017-11-09 11:09:25 +01001165 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001166 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001167 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001168 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001169 if (!media_channel()->SetSendParameters(send_params)) {
1170 SafeSetError("Failed to set remote data description send parameters.",
1171 error_desc);
1172 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001173 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001174 last_send_params_ = send_params;
1175
1176 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1177 // and only give it to the media channel once we have a local
1178 // description too (without a local description, we won't be able to
1179 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001180 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yves Gerey665174f2018-06-19 15:03:05 +02001181 SafeSetError("Failed to set remote data description streams.", error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001182 return false;
1183 }
1184
1185 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001186 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001187 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001188}
1189
deadbeef953c2ce2017-01-09 14:53:41 -08001190void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001191 // Render incoming data if we're the active call, and we have the local
1192 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001193 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001194 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001195 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001196 }
1197
1198 // Send outgoing data if we're the active call, we have the remote content,
1199 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001200 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001201 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001202 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001203 }
1204
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001205 // Trigger SignalReadyToSendData asynchronously.
1206 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001207
Mirko Bonadei675513b2017-11-09 11:09:25 +01001208 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001209}
1210
deadbeef953c2ce2017-01-09 14:53:41 -08001211void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001212 switch (pmsg->message_id) {
1213 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001214 DataChannelReadyToSendMessageData* data =
1215 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001216 ready_to_send_data_ = data->data();
1217 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001218 delete data;
1219 break;
1220 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001221 case MSG_DATARECEIVED: {
1222 DataReceivedMessageData* data =
1223 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001224 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001225 delete data;
1226 break;
1227 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001228 default:
1229 BaseChannel::OnMessage(pmsg);
1230 break;
1231 }
1232}
1233
deadbeef953c2ce2017-01-09 14:53:41 -08001234void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1235 const char* data,
1236 size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +02001237 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001238 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001239}
1240
deadbeef953c2ce2017-01-09 14:53:41 -08001241void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001242 // This is usded for congestion control to indicate that the stream is ready
1243 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1244 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001245 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001246 new DataChannelReadyToSendMessageData(writable));
1247}
1248
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001249} // namespace cricket