blob: 2635069c1540a75235d9ee8cec5c623356dac716 [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"
19#include "media/base/mediaconstants.h"
20#include "media/base/rtputils.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"
23#include "rtc_base/byteorder.h"
24#include "rtc_base/checks.h"
25#include "rtc_base/copyonwritebuffer.h"
26#include "rtc_base/dscp.h"
27#include "rtc_base/logging.h"
28#include "rtc_base/networkroute.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.
33#include "media/engine/webrtcvoiceengine.h" // nogncheck
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "p2p/base/packettransportinternal.h"
35#include "pc/channelmanager.h"
Steve Anton4e70a722017-11-28 14:57:10 -080036#include "pc/rtpmediautils.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::AddRecvStream(const StreamParams& sp) {
Zhi Huang365381f2018-04-13 16:44:34 -0700260 demuxer_criteria_.ssrcs.insert(sp.first_ssrc());
261 if (!RegisterRtpDemuxerSink()) {
262 return false;
263 }
stefanf79ade12017-06-02 06:44:03 -0700264 return InvokeOnWorker<bool>(RTC_FROM_HERE,
265 Bind(&BaseChannel::AddRecvStream_w, this, sp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266}
267
Peter Boström0c4e06b2015-10-07 12:23:21 +0200268bool BaseChannel::RemoveRecvStream(uint32_t ssrc) {
Zhi Huang365381f2018-04-13 16:44:34 -0700269 demuxer_criteria_.ssrcs.erase(ssrc);
270 if (!RegisterRtpDemuxerSink()) {
271 return false;
272 }
stefanf79ade12017-06-02 06:44:03 -0700273 return InvokeOnWorker<bool>(
274 RTC_FROM_HERE, Bind(&BaseChannel::RemoveRecvStream_w, this, ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275}
276
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000277bool BaseChannel::AddSendStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700278 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700279 RTC_FROM_HERE, Bind(&MediaChannel::AddSendStream, media_channel(), sp));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000280}
281
Peter Boström0c4e06b2015-10-07 12:23:21 +0200282bool BaseChannel::RemoveSendStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700283 return InvokeOnWorker<bool>(
284 RTC_FROM_HERE,
285 Bind(&MediaChannel::RemoveSendStream, media_channel(), ssrc));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000286}
287
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800289 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000290 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100291 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700292 return InvokeOnWorker<bool>(
293 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800294 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000295}
296
297bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800298 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000299 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100300 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700301 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800302 RTC_FROM_HERE,
303 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304}
305
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700306bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000307 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800308 return enabled() &&
309 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310}
311
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700312bool BaseChannel::IsReadyToSendMedia_w() const {
313 // Need to access some state updated on the network thread.
314 return network_thread_->Invoke<bool>(
315 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
316}
317
318bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 // Send outgoing data if we are enabled, have local and remote content,
320 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800321 return enabled() &&
322 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
323 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 16:44:34 -0700324 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325}
326
jbaucheec21bd2016-03-20 06:15:43 -0700327bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700328 const rtc::PacketOptions& options) {
329 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330}
331
jbaucheec21bd2016-03-20 06:15:43 -0700332bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700333 const rtc::PacketOptions& options) {
334 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335}
336
Yves Gerey665174f2018-06-19 15:03:05 +0200337int BaseChannel::SetOption(SocketType type,
338 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200340 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700341 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200342}
343
344int BaseChannel::SetOption_n(SocketType type,
345 rtc::Socket::Option opt,
346 int value) {
347 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700348 RTC_DCHECK(rtp_transport_);
deadbeef5bd5ca32017-02-10 11:31:50 -0800349 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000351 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700352 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700353 socket_options_.push_back(
354 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000355 break;
356 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700357 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700358 rtcp_socket_options_.push_back(
359 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000360 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000361 }
deadbeeff5346592017-01-24 21:51:21 -0800362 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363}
364
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800365void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200366 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800367 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800368 ChannelWritable_n();
369 } else {
370 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800371 }
372}
373
Zhi Huang942bc2e2017-11-13 13:26:07 -0800374void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200375 absl::optional<rtc::NetworkRoute> network_route) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800376 RTC_LOG(LS_INFO) << "Network route was changed.";
377
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200378 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800379 rtc::NetworkRoute new_route;
380 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800381 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000382 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800383 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
384 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
385 // work correctly. Intentionally leave it broken to simplify the code and
386 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800387 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800388 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800389 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700390}
391
zstein56162b92017-04-24 16:54:35 -0700392void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800393 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
394 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395}
396
stefanc1aeaf02015-10-15 07:26:07 -0700397bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700398 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700399 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200400 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
401 // If the thread is not our network thread, we will post to our network
402 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000403 // synchronize access to all the pieces of the send path, including
404 // SRTP and the inner workings of the transport channels.
405 // The only downside is that we can't return a proper failure code if
406 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200407 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000408 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200409 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
410 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800411 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700412 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700413 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000414 return true;
415 }
Zhi Huange830e682018-03-30 10:48:35 -0700416
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200417 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000418
419 // Now that we are on the correct thread, ensure we have a place to send this
420 // packet before doing anything. (We might get RTCP packets that we don't
421 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
422 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700423 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000424 return false;
425 }
426
427 // Protect ourselves against crazy data.
428 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100429 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
430 << RtpRtcpStringLiteral(rtcp)
431 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000432 return false;
433 }
434
Zhi Huangcf990f52017-09-22 12:12:30 -0700435 if (!srtp_active()) {
436 if (srtp_required_) {
437 // The audio/video engines may attempt to send RTCP packets as soon as the
438 // streams are created, so don't treat this as an error for RTCP.
439 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
440 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000441 return false;
442 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700443 // However, there shouldn't be any RTP packets sent before SRTP is set up
444 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100445 RTC_LOG(LS_ERROR)
446 << "Can't send outgoing RTP packet when SRTP is inactive"
447 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700448 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800449 return false;
450 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800451
452 std::string packet_type = rtcp ? "RTCP" : "RTP";
453 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
454 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000455 }
Zhi Huange830e682018-03-30 10:48:35 -0700456
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000457 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800458 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
459 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000460}
461
Zhi Huang365381f2018-04-13 16:44:34 -0700462void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
463 // Reconstruct the PacketTime from the |parsed_packet|.
464 // RtpPacketReceived.arrival_time_ms = (PacketTime + 500) / 1000;
465 // Note: The |not_before| field is always 0 here. This field is not currently
466 // used, so it should be fine.
Niels Möllere6933812018-11-05 13:01:41 +0100467 int64_t timestamp_us = -1;
Zhi Huang365381f2018-04-13 16:44:34 -0700468 if (parsed_packet.arrival_time_ms() > 0) {
Niels Möllere6933812018-11-05 13:01:41 +0100469 timestamp_us = parsed_packet.arrival_time_ms() * 1000;
Zhi Huang365381f2018-04-13 16:44:34 -0700470 }
Zhi Huang365381f2018-04-13 16:44:34 -0700471
Niels Möllere6933812018-11-05 13:01:41 +0100472 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), timestamp_us);
Zhi Huang365381f2018-04-13 16:44:34 -0700473}
474
475void BaseChannel::UpdateRtpHeaderExtensionMap(
476 const RtpHeaderExtensions& header_extensions) {
477 RTC_DCHECK(rtp_transport_);
478 // Update the header extension map on network thread in case there is data
479 // race.
480 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
481 // be accessed from different threads.
482 //
483 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
484 // extension maps are not merged when BUNDLE is enabled. This is fine because
485 // the ID for MID should be consistent among all the RTP transports.
486 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
487 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
488 });
489}
490
491bool BaseChannel::RegisterRtpDemuxerSink() {
492 RTC_DCHECK(rtp_transport_);
493 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
494 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
495 });
496}
497
498void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
Niels Möllere6933812018-11-05 13:01:41 +0100499 int64_t packet_time_us) {
500 OnPacketReceived(/*rtcp=*/true, *packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000501}
502
zstein3dcf0e92017-06-01 13:22:42 -0700503void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang365381f2018-04-13 16:44:34 -0700504 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 13:01:41 +0100505 int64_t packet_time_us) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000506 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000507 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700508 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000509 }
510
Zhi Huangcf990f52017-09-22 12:12:30 -0700511 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000512 // Our session description indicates that SRTP is required, but we got a
513 // packet before our SRTP filter is active. This means either that
514 // a) we got SRTP packets before we received the SDES keys, in which case
515 // we can't decrypt it anyway, or
516 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800517 // transports, so we haven't yet extracted keys, even if DTLS did
518 // complete on the transport that the packets are being sent on. It's
519 // really good practice to wait for both RTP and RTCP to be good to go
520 // before sending media, to prevent weird failure modes, so it's fine
521 // for us to just eat packets here. This is all sidestepped if RTCP mux
522 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100523 RTC_LOG(LS_WARNING)
524 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
525 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526 return;
527 }
528
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200529 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700530 RTC_FROM_HERE, worker_thread_,
Niels Möllere6933812018-11-05 13:01:41 +0100531 Bind(&BaseChannel::ProcessPacket, this, rtcp, packet, packet_time_us));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200532}
533
zstein3dcf0e92017-06-01 13:22:42 -0700534void BaseChannel::ProcessPacket(bool rtcp,
535 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 13:01:41 +0100536 int64_t packet_time_us) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200537 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700538
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200539 // Need to copy variable because OnRtcpReceived/OnPacketReceived
540 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
541 rtc::CopyOnWriteBuffer data(packet);
542 if (rtcp) {
Niels Möllere6933812018-11-05 13:01:41 +0100543 media_channel_->OnRtcpReceived(&data, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544 } else {
Niels Möllere6933812018-11-05 13:01:41 +0100545 media_channel_->OnPacketReceived(&data, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000546 }
547}
548
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000549void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700550 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000551 if (enabled_)
552 return;
553
Mirko Bonadei675513b2017-11-09 11:09:25 +0100554 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700556 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000557}
558
559void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700560 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000561 if (!enabled_)
562 return;
563
Mirko Bonadei675513b2017-11-09 11:09:25 +0100564 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700566 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567}
568
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200569void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700570 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
571 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200572 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700573 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200574 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700575 }
576}
577
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200578void BaseChannel::ChannelWritable_n() {
579 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800580 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000581 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800582 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000583
Mirko Bonadei675513b2017-11-09 11:09:25 +0100584 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
585 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000586
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000587 was_ever_writable_ = true;
588 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700589 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000590}
591
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200592void BaseChannel::ChannelNotWritable_n() {
593 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000594 if (!writable_)
595 return;
596
Mirko Bonadei675513b2017-11-09 11:09:25 +0100597 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000598 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700599 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000600}
601
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000602bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700603 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800604 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000605}
606
Peter Boström0c4e06b2015-10-07 12:23:21 +0200607bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700608 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000609 return media_channel()->RemoveRecvStream(ssrc);
610}
611
612bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800613 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000614 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000615 // Check for streams that have been removed.
616 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800617 for (const StreamParams& old_stream : local_streams_) {
618 if (old_stream.has_ssrcs() &&
619 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
620 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200621 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800622 desc << "Failed to remove send stream with ssrc "
623 << old_stream.first_ssrc() << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000624 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000625 ret = false;
626 }
627 }
628 }
629 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800630 for (const StreamParams& new_stream : streams) {
631 if (new_stream.has_ssrcs() &&
632 !GetStreamBySsrc(local_streams_, new_stream.first_ssrc())) {
633 if (media_channel()->AddSendStream(new_stream)) {
634 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200636 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800637 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000638 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000639 ret = false;
640 }
641 }
642 }
643 local_streams_ = streams;
644 return ret;
645}
646
647bool BaseChannel::UpdateRemoteStreams_w(
648 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800649 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000650 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651 // Check for streams that have been removed.
652 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800653 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700654 // If we no longer have an unsignaled stream, we would like to remove
655 // the unsignaled stream params that are cached.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800656 if ((!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
657 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
658 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
659 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc();
Zhi Huang365381f2018-04-13 16:44:34 -0700660 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200661 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800662 desc << "Failed to remove remote stream with ssrc "
663 << old_stream.first_ssrc() << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000664 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000665 ret = false;
666 }
667 }
668 }
Zhi Huang365381f2018-04-13 16:44:34 -0700669 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800671 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700672 // We allow a StreamParams with an empty list of SSRCs, in which case the
673 // MediaChannel will cache the parameters and use them for any unsignaled
674 // stream received later.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800675 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
676 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
677 if (AddRecvStream_w(new_stream)) {
678 RTC_LOG(LS_INFO) << "Add remote ssrc: " << new_stream.first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000679 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200680 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800681 desc << "Failed to add remote stream ssrc: " << new_stream.first_ssrc();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000682 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000683 ret = false;
684 }
685 }
Zhi Huang365381f2018-04-13 16:44:34 -0700686 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800687 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
688 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000689 }
Zhi Huang365381f2018-04-13 16:44:34 -0700690 // Re-register the sink to update the receiving ssrcs.
691 RegisterRtpDemuxerSink();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692 remote_streams_ = streams;
693 return ret;
694}
695
jbauch5869f502017-06-29 12:31:36 -0700696RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
697 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700698 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700699 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700700 RtpHeaderExtensions filtered;
701 auto pred = [](const webrtc::RtpExtension& extension) {
Yves Gerey665174f2018-06-19 15:03:05 +0200702 return !extension.encrypt;
jbauch5869f502017-06-29 12:31:36 -0700703 };
704 std::copy_if(extensions.begin(), extensions.end(),
Yves Gerey665174f2018-06-19 15:03:05 +0200705 std::back_inserter(filtered), pred);
jbauch5869f502017-06-29 12:31:36 -0700706 return filtered;
707 }
708
709 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
710}
711
Yves Gerey665174f2018-06-19 15:03:05 +0200712void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100713 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200715 case MSG_SEND_RTP_PACKET:
716 case MSG_SEND_RTCP_PACKET: {
717 RTC_DCHECK(network_thread_->IsCurrent());
718 SendPacketMessageData* data =
719 static_cast<SendPacketMessageData*>(pmsg->pdata);
720 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
721 SendPacket(rtcp, &data->packet, data->options);
722 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723 break;
724 }
725 case MSG_FIRSTPACKETRECEIVED: {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800726 SignalFirstPacketReceived_(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 break;
728 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729 }
730}
731
zstein3dcf0e92017-06-01 13:22:42 -0700732void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 16:44:34 -0700733 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -0700734}
735
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200736void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737 // Flush all remaining RTCP messages. This should only be called in
738 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200739 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000740 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200741 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
742 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700743 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
744 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000745 }
746}
747
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800748void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200749 RTC_DCHECK(network_thread_->IsCurrent());
750 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700751 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200752 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
753}
754
755void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
756 RTC_DCHECK(worker_thread_->IsCurrent());
757 SignalSentPacket(sent_packet);
758}
759
760VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
761 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800762 rtc::Thread* signaling_thread,
Niels Möllerf120cba2018-01-30 09:33:03 +0100763 // TODO(nisse): Delete unused argument.
764 MediaEngineInterface* /* media_engine */,
Steve Anton8699a322017-11-06 15:53:33 -0800765 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700767 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700768 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200769 : BaseChannel(worker_thread,
770 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800771 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800772 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700773 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700774 srtp_required,
775 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776
777VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800778 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000779 // this can't be done in the base class, since it calls a virtual
780 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700781 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782}
783
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700784void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200785 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700786 invoker_.AsyncInvoke<void>(
787 RTC_FROM_HERE, worker_thread_,
788 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200789}
790
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800791void BaseChannel::OnNetworkRouteChanged(
792 const rtc::NetworkRoute& network_route) {
793 OnNetworkRouteChanged(absl::make_optional(network_route));
794}
795
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700796void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000797 // Render incoming data if we're the active call, and we have the local
798 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700799 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700800 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000801
802 // Send outgoing data if we're the active call, we have the remote content,
803 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700804 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800805 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806
Mirko Bonadei675513b2017-11-09 11:09:25 +0100807 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808}
809
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800811 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000812 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100813 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800814 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100815 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816
Steve Antonb1c1de12017-12-21 15:14:30 -0800817 RTC_DCHECK(content);
818 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000819 SafeSetError("Can't find audio content in local description.", error_desc);
820 return false;
821 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822
Steve Antonb1c1de12017-12-21 15:14:30 -0800823 const AudioContentDescription* audio = content->as_audio();
824
jbauch5869f502017-06-29 12:31:36 -0700825 RtpHeaderExtensions rtp_header_extensions =
826 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700827 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100828 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700829
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700830 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700831 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700832 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -0700833 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700834 error_desc);
835 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700837 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700838 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700839 }
Zhi Huang365381f2018-04-13 16:44:34 -0700840 // Need to re-register the sink to update the handled payload.
841 if (!RegisterRtpDemuxerSink()) {
842 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
843 return false;
844 }
845
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700846 last_recv_params_ = recv_params;
847
848 // TODO(pthatcher): Move local streams into AudioSendParameters, and
849 // only give it to the media channel once we have a remote
850 // description too (without a remote description, we won't be able
851 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800852 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700853 SafeSetError("Failed to set local audio description streams.", error_desc);
854 return false;
855 }
856
857 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700858 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700859 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860}
861
862bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800863 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000864 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100865 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800866 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100867 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868
Steve Antonb1c1de12017-12-21 15:14:30 -0800869 RTC_DCHECK(content);
870 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000871 SafeSetError("Can't find audio content in remote description.", error_desc);
872 return false;
873 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874
Steve Antonb1c1de12017-12-21 15:14:30 -0800875 const AudioContentDescription* audio = content->as_audio();
876
jbauch5869f502017-06-29 12:31:36 -0700877 RtpHeaderExtensions rtp_header_extensions =
878 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
879
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700880 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700881 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +0200882 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700883 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700884
885 bool parameters_applied = media_channel()->SetSendParameters(send_params);
886 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700887 SafeSetError("Failed to set remote audio description send parameters.",
888 error_desc);
889 return false;
890 }
891 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700893 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
894 // and only give it to the media channel once we have a local
895 // description too (without a local description, we won't be able to
896 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800897 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700898 SafeSetError("Failed to set remote audio description streams.", error_desc);
899 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900 }
901
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700902 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700903 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700904 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905}
906
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200907VideoChannel::VideoChannel(rtc::Thread* worker_thread,
908 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800909 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800910 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700912 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700913 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200914 : BaseChannel(worker_thread,
915 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800916 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800917 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700918 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700919 srtp_required,
920 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800923 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924 // this can't be done in the base class, since it calls a virtual
925 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700926 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927}
928
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700929void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930 // Send outgoing data if we're the active call, we have the remote content,
931 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700932 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100934 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935 // TODO(gangji): Report error back to server.
936 }
937
Mirko Bonadei675513b2017-11-09 11:09:25 +0100938 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939}
940
stefanf79ade12017-06-02 06:44:03 -0700941void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
942 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
943 media_channel(), bwe_info));
944}
945
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800947 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000948 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100949 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800950 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100951 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952
Steve Antonb1c1de12017-12-21 15:14:30 -0800953 RTC_DCHECK(content);
954 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000955 SafeSetError("Can't find video content in local description.", error_desc);
956 return false;
957 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
Steve Antonb1c1de12017-12-21 15:14:30 -0800959 const VideoContentDescription* video = content->as_video();
960
jbauch5869f502017-06-29 12:31:36 -0700961 RtpHeaderExtensions rtp_header_extensions =
962 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700963 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100964 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700965
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700966 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700967 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700968 if (!media_channel()->SetRecvParameters(recv_params)) {
969 SafeSetError("Failed to set local video description recv parameters.",
970 error_desc);
971 return false;
972 }
973 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700974 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700975 }
Zhi Huang365381f2018-04-13 16:44:34 -0700976 // Need to re-register the sink to update the handled payload.
977 if (!RegisterRtpDemuxerSink()) {
978 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
979 return false;
980 }
981
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700982 last_recv_params_ = recv_params;
983
984 // TODO(pthatcher): Move local streams into VideoSendParameters, and
985 // only give it to the media channel once we have a remote
986 // description too (without a remote description, we won't be able
987 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800988 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700989 SafeSetError("Failed to set local video description streams.", error_desc);
990 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991 }
992
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700993 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700994 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700995 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996}
997
998bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800999 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001000 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001001 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001002 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001003 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
Steve Antonb1c1de12017-12-21 15:14:30 -08001005 RTC_DCHECK(content);
1006 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001007 SafeSetError("Can't find video content in remote description.", error_desc);
1008 return false;
1009 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010
Steve Antonb1c1de12017-12-21 15:14:30 -08001011 const VideoContentDescription* video = content->as_video();
1012
jbauch5869f502017-06-29 12:31:36 -07001013 RtpHeaderExtensions rtp_header_extensions =
1014 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1015
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001016 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001017 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001018 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001019 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001020 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001021 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001022 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001023
1024 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1025
1026 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001027 SafeSetError("Failed to set remote video description send parameters.",
1028 error_desc);
1029 return false;
1030 }
1031 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001032
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001033 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1034 // and only give it to the media channel once we have a local
1035 // description too (without a local description, we won't be able to
1036 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001037 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001038 SafeSetError("Failed to set remote video description streams.", error_desc);
1039 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001040 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001041 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001042 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001043 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001044}
1045
deadbeef953c2ce2017-01-09 14:53:41 -08001046RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1047 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001048 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001049 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001050 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001051 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001052 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001053 : BaseChannel(worker_thread,
1054 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001055 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001056 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001057 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001058 srtp_required,
1059 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001060
deadbeef953c2ce2017-01-09 14:53:41 -08001061RtpDataChannel::~RtpDataChannel() {
1062 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001063 // this can't be done in the base class, since it calls a virtual
1064 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001065 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001066}
1067
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001068void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
Anton Sukhanov98a462c2018-10-17 13:15:42 -07001069 BaseChannel::Init_w(rtp_transport, /*media_transport=*/nullptr);
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001070 media_channel()->SignalDataReceived.connect(this,
1071 &RtpDataChannel::OnDataReceived);
1072 media_channel()->SignalReadyToSend.connect(
1073 this, &RtpDataChannel::OnDataChannelReadyToSend);
1074}
1075
deadbeef953c2ce2017-01-09 14:53:41 -08001076bool RtpDataChannel::SendData(const SendDataParams& params,
1077 const rtc::CopyOnWriteBuffer& payload,
1078 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001079 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001080 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1081 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001082}
1083
deadbeef953c2ce2017-01-09 14:53:41 -08001084bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001085 const DataContentDescription* content,
1086 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001087 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1088 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001089 // It's been set before, but doesn't match. That's bad.
1090 if (is_sctp) {
1091 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1092 error_desc);
1093 return false;
1094 }
1095 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001096}
1097
deadbeef953c2ce2017-01-09 14:53:41 -08001098bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001099 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001100 std::string* error_desc) {
1101 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001102 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001103 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001104
Steve Antonb1c1de12017-12-21 15:14:30 -08001105 RTC_DCHECK(content);
1106 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001107 SafeSetError("Can't find data content in local description.", error_desc);
1108 return false;
1109 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001110
Steve Antonb1c1de12017-12-21 15:14:30 -08001111 const DataContentDescription* data = content->as_data();
1112
deadbeef953c2ce2017-01-09 14:53:41 -08001113 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001114 return false;
1115 }
1116
jbauch5869f502017-06-29 12:31:36 -07001117 RtpHeaderExtensions rtp_header_extensions =
1118 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1119
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001120 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001121 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001122 if (!media_channel()->SetRecvParameters(recv_params)) {
1123 SafeSetError("Failed to set remote data description recv parameters.",
1124 error_desc);
1125 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001126 }
deadbeef953c2ce2017-01-09 14:53:41 -08001127 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001128 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001129 }
Zhi Huang365381f2018-04-13 16:44:34 -07001130 // Need to re-register the sink to update the handled payload.
1131 if (!RegisterRtpDemuxerSink()) {
1132 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1133 return false;
1134 }
1135
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001136 last_recv_params_ = recv_params;
1137
1138 // TODO(pthatcher): Move local streams into DataSendParameters, and
1139 // only give it to the media channel once we have a remote
1140 // description too (without a remote description, we won't be able
1141 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001142 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001143 SafeSetError("Failed to set local data description streams.", error_desc);
1144 return false;
1145 }
1146
1147 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001148 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001149 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001150}
1151
deadbeef953c2ce2017-01-09 14:53:41 -08001152bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001153 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001154 std::string* error_desc) {
1155 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001156 RTC_DCHECK_RUN_ON(worker_thread());
1157 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001158
Steve Antonb1c1de12017-12-21 15:14:30 -08001159 RTC_DCHECK(content);
1160 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001161 SafeSetError("Can't find data content in remote description.", error_desc);
1162 return false;
1163 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001164
Steve Antonb1c1de12017-12-21 15:14:30 -08001165 const DataContentDescription* data = content->as_data();
1166
Zhi Huang801b8682017-11-15 11:36:43 -08001167 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1168 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001169 return true;
1170 }
1171
deadbeef953c2ce2017-01-09 14:53:41 -08001172 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001173 return false;
1174 }
1175
jbauch5869f502017-06-29 12:31:36 -07001176 RtpHeaderExtensions rtp_header_extensions =
1177 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1178
Mirko Bonadei675513b2017-11-09 11:09:25 +01001179 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001180 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001181 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001182 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001183 if (!media_channel()->SetSendParameters(send_params)) {
1184 SafeSetError("Failed to set remote data description send parameters.",
1185 error_desc);
1186 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001187 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001188 last_send_params_ = send_params;
1189
1190 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1191 // and only give it to the media channel once we have a local
1192 // description too (without a local description, we won't be able to
1193 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001194 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yves Gerey665174f2018-06-19 15:03:05 +02001195 SafeSetError("Failed to set remote data description streams.", error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001196 return false;
1197 }
1198
1199 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001200 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001201 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001202}
1203
deadbeef953c2ce2017-01-09 14:53:41 -08001204void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001205 // Render incoming data if we're the active call, and we have the local
1206 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001207 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001208 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001209 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001210 }
1211
1212 // Send outgoing data if we're the active call, we have the remote content,
1213 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001214 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001215 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001216 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001217 }
1218
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001219 // Trigger SignalReadyToSendData asynchronously.
1220 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001221
Mirko Bonadei675513b2017-11-09 11:09:25 +01001222 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001223}
1224
deadbeef953c2ce2017-01-09 14:53:41 -08001225void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001226 switch (pmsg->message_id) {
1227 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001228 DataChannelReadyToSendMessageData* data =
1229 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001230 ready_to_send_data_ = data->data();
1231 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001232 delete data;
1233 break;
1234 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001235 case MSG_DATARECEIVED: {
1236 DataReceivedMessageData* data =
1237 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001238 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001239 delete data;
1240 break;
1241 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001242 default:
1243 BaseChannel::OnMessage(pmsg);
1244 break;
1245 }
1246}
1247
deadbeef953c2ce2017-01-09 14:53:41 -08001248void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1249 const char* data,
1250 size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +02001251 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001252 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001253}
1254
deadbeef953c2ce2017-01-09 14:53:41 -08001255void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001256 // This is usded for congestion control to indicate that the stream is ready
1257 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1258 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001259 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001260 new DataChannelReadyToSendMessageData(writable));
1261}
1262
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001263} // namespace cricket