blob: 8e1d5ff015fa02109c5eccba0a7e27fe642b8678 [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_);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200121 // Eats any outstanding messages or packets.
122 worker_thread_->Clear(&invoker_);
123 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000124 // We must destroy the media channel before the transport channel, otherwise
125 // the media channel may try to send on the dead transport channel. NULLing
126 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800127 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100128 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200129}
130
Zhi Huang365381f2018-04-13 16:44:34 -0700131bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800132 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700133 if (!RegisterRtpDemuxerSink()) {
134 return false;
135 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800136 rtp_transport_->SignalReadyToSend.connect(
137 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang365381f2018-04-13 16:44:34 -0700138 rtp_transport_->SignalRtcpPacketReceived.connect(
139 this, &BaseChannel::OnRtcpPacketReceived);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800140 rtp_transport_->SignalNetworkRouteChanged.connect(
141 this, &BaseChannel::OnNetworkRouteChanged);
142 rtp_transport_->SignalWritableState.connect(this,
143 &BaseChannel::OnWritableState);
144 rtp_transport_->SignalSentPacket.connect(this,
145 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 16:44:34 -0700146 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800147}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200148
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800149void BaseChannel::DisconnectFromRtpTransport() {
150 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700151 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800152 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang365381f2018-04-13 16:44:34 -0700153 rtp_transport_->SignalRtcpPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800154 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
155 rtp_transport_->SignalWritableState.disconnect(this);
156 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200157}
158
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700159void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport,
160 webrtc::MediaTransportInterface* media_transport) {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800161 RTC_DCHECK_RUN_ON(worker_thread_);
Zhi Huang365381f2018-04-13 16:44:34 -0700162 network_thread_->Invoke<void>(
163 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800164
165 // Both RTP and RTCP channels should be set, we can call SetInterface on
166 // the media channel and it can set network options.
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700167 media_channel_->SetInterface(this, media_transport);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200168}
169
wu@webrtc.org78187522013-10-07 23:32:02 +0000170void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200171 RTC_DCHECK(worker_thread_->IsCurrent());
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700172 media_channel_->SetInterface(/*iface=*/nullptr,
173 /*media_transport=*/nullptr);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200174 // Packets arrive on the network thread, processing packets calls virtual
175 // functions, so need to stop this process in Deinit that is called in
176 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800177 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000178 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700179
Zhi Huange830e682018-03-30 10:48:35 -0700180 if (rtp_transport_) {
181 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000182 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800183 // Clear pending read packets/messages.
184 network_thread_->Clear(&invoker_);
185 network_thread_->Clear(this);
186 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000187}
188
Zhi Huang365381f2018-04-13 16:44:34 -0700189bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
190 if (rtp_transport == rtp_transport_) {
191 return true;
192 }
193
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800194 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 16:44:34 -0700195 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
196 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800197 });
198 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000199
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800200 if (rtp_transport_) {
201 DisconnectFromRtpTransport();
202 }
Zhi Huange830e682018-03-30 10:48:35 -0700203
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800204 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700205 if (rtp_transport_) {
206 RTC_DCHECK(rtp_transport_->rtp_packet_transport());
207 transport_name_ = rtp_transport_->rtp_packet_transport()->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800208
Zhi Huang365381f2018-04-13 16:44:34 -0700209 if (!ConnectToRtpTransport()) {
210 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport.";
211 return false;
212 }
Zhi Huange830e682018-03-30 10:48:35 -0700213 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
214 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800215
Zhi Huange830e682018-03-30 10:48:35 -0700216 // Set the cached socket options.
217 for (const auto& pair : socket_options_) {
218 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
219 pair.second);
220 }
221 if (rtp_transport_->rtcp_packet_transport()) {
222 for (const auto& pair : rtcp_socket_options_) {
223 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
224 pair.second);
225 }
226 }
guoweis46383312015-12-17 16:45:59 -0800227 }
Zhi Huang365381f2018-04-13 16:44:34 -0700228 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000229}
230
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000231bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700232 worker_thread_->Invoke<void>(
233 RTC_FROM_HERE,
234 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
235 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 return true;
237}
238
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239bool BaseChannel::AddRecvStream(const StreamParams& sp) {
Zhi Huang365381f2018-04-13 16:44:34 -0700240 demuxer_criteria_.ssrcs.insert(sp.first_ssrc());
241 if (!RegisterRtpDemuxerSink()) {
242 return false;
243 }
stefanf79ade12017-06-02 06:44:03 -0700244 return InvokeOnWorker<bool>(RTC_FROM_HERE,
245 Bind(&BaseChannel::AddRecvStream_w, this, sp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246}
247
Peter Boström0c4e06b2015-10-07 12:23:21 +0200248bool BaseChannel::RemoveRecvStream(uint32_t ssrc) {
Zhi Huang365381f2018-04-13 16:44:34 -0700249 demuxer_criteria_.ssrcs.erase(ssrc);
250 if (!RegisterRtpDemuxerSink()) {
251 return false;
252 }
stefanf79ade12017-06-02 06:44:03 -0700253 return InvokeOnWorker<bool>(
254 RTC_FROM_HERE, Bind(&BaseChannel::RemoveRecvStream_w, this, ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255}
256
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000257bool BaseChannel::AddSendStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700258 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700259 RTC_FROM_HERE, Bind(&MediaChannel::AddSendStream, media_channel(), sp));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000260}
261
Peter Boström0c4e06b2015-10-07 12:23:21 +0200262bool BaseChannel::RemoveSendStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700263 return InvokeOnWorker<bool>(
264 RTC_FROM_HERE,
265 Bind(&MediaChannel::RemoveSendStream, media_channel(), ssrc));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000266}
267
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268bool BaseChannel::SetLocalContent(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::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700272 return InvokeOnWorker<bool>(
273 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800274 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275}
276
277bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800278 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000279 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100280 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700281 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800282 RTC_FROM_HERE,
283 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284}
285
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700286bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000287 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800288 return enabled() &&
289 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000290}
291
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700292bool BaseChannel::IsReadyToSendMedia_w() const {
293 // Need to access some state updated on the network thread.
294 return network_thread_->Invoke<bool>(
295 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
296}
297
298bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299 // Send outgoing data if we are enabled, have local and remote content,
300 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800301 return enabled() &&
302 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
303 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 16:44:34 -0700304 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000305}
306
jbaucheec21bd2016-03-20 06:15:43 -0700307bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700308 const rtc::PacketOptions& options) {
309 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310}
311
jbaucheec21bd2016-03-20 06:15:43 -0700312bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700313 const rtc::PacketOptions& options) {
314 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315}
316
Yves Gerey665174f2018-06-19 15:03:05 +0200317int BaseChannel::SetOption(SocketType type,
318 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200320 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700321 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200322}
323
324int BaseChannel::SetOption_n(SocketType type,
325 rtc::Socket::Option opt,
326 int value) {
327 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700328 RTC_DCHECK(rtp_transport_);
deadbeef5bd5ca32017-02-10 11:31:50 -0800329 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000331 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700332 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700333 socket_options_.push_back(
334 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000335 break;
336 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700337 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700338 rtcp_socket_options_.push_back(
339 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000340 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341 }
deadbeeff5346592017-01-24 21:51:21 -0800342 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343}
344
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800345void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200346 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800347 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800348 ChannelWritable_n();
349 } else {
350 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800351 }
352}
353
Zhi Huang942bc2e2017-11-13 13:26:07 -0800354void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200355 absl::optional<rtc::NetworkRoute> network_route) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200356 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800357 rtc::NetworkRoute new_route;
358 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800359 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000360 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800361 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
362 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
363 // work correctly. Intentionally leave it broken to simplify the code and
364 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800365 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800366 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800367 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700368}
369
zstein56162b92017-04-24 16:54:35 -0700370void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800371 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
372 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373}
374
stefanc1aeaf02015-10-15 07:26:07 -0700375bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700376 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700377 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200378 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
379 // If the thread is not our network thread, we will post to our network
380 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000381 // synchronize access to all the pieces of the send path, including
382 // SRTP and the inner workings of the transport channels.
383 // The only downside is that we can't return a proper failure code if
384 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200385 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000386 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200387 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
388 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800389 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700390 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700391 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000392 return true;
393 }
Zhi Huange830e682018-03-30 10:48:35 -0700394
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200395 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000396
397 // Now that we are on the correct thread, ensure we have a place to send this
398 // packet before doing anything. (We might get RTCP packets that we don't
399 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
400 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700401 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000402 return false;
403 }
404
405 // Protect ourselves against crazy data.
406 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100407 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
408 << RtpRtcpStringLiteral(rtcp)
409 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000410 return false;
411 }
412
Zhi Huangcf990f52017-09-22 12:12:30 -0700413 if (!srtp_active()) {
414 if (srtp_required_) {
415 // The audio/video engines may attempt to send RTCP packets as soon as the
416 // streams are created, so don't treat this as an error for RTCP.
417 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
418 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000419 return false;
420 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700421 // However, there shouldn't be any RTP packets sent before SRTP is set up
422 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100423 RTC_LOG(LS_ERROR)
424 << "Can't send outgoing RTP packet when SRTP is inactive"
425 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700426 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800427 return false;
428 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800429
430 std::string packet_type = rtcp ? "RTCP" : "RTP";
431 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
432 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000433 }
Zhi Huange830e682018-03-30 10:48:35 -0700434
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000435 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800436 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
437 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000438}
439
Zhi Huang365381f2018-04-13 16:44:34 -0700440void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
441 // Reconstruct the PacketTime from the |parsed_packet|.
442 // RtpPacketReceived.arrival_time_ms = (PacketTime + 500) / 1000;
443 // Note: The |not_before| field is always 0 here. This field is not currently
444 // used, so it should be fine.
445 int64_t timestamp = -1;
446 if (parsed_packet.arrival_time_ms() > 0) {
447 timestamp = parsed_packet.arrival_time_ms() * 1000;
448 }
449 rtc::PacketTime packet_time(timestamp, /*not_before=*/0);
450
451 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), packet_time);
452}
453
454void BaseChannel::UpdateRtpHeaderExtensionMap(
455 const RtpHeaderExtensions& header_extensions) {
456 RTC_DCHECK(rtp_transport_);
457 // Update the header extension map on network thread in case there is data
458 // race.
459 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
460 // be accessed from different threads.
461 //
462 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
463 // extension maps are not merged when BUNDLE is enabled. This is fine because
464 // the ID for MID should be consistent among all the RTP transports.
465 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
466 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
467 });
468}
469
470bool BaseChannel::RegisterRtpDemuxerSink() {
471 RTC_DCHECK(rtp_transport_);
472 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
473 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
474 });
475}
476
477void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
478 const rtc::PacketTime& packet_time) {
479 OnPacketReceived(/*rtcp=*/true, *packet, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000480}
481
zstein3dcf0e92017-06-01 13:22:42 -0700482void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang365381f2018-04-13 16:44:34 -0700483 const rtc::CopyOnWriteBuffer& packet,
zstein3dcf0e92017-06-01 13:22:42 -0700484 const rtc::PacketTime& packet_time) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000485 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000486 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700487 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000488 }
489
Zhi Huangcf990f52017-09-22 12:12:30 -0700490 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000491 // Our session description indicates that SRTP is required, but we got a
492 // packet before our SRTP filter is active. This means either that
493 // a) we got SRTP packets before we received the SDES keys, in which case
494 // we can't decrypt it anyway, or
495 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800496 // transports, so we haven't yet extracted keys, even if DTLS did
497 // complete on the transport that the packets are being sent on. It's
498 // really good practice to wait for both RTP and RTCP to be good to go
499 // before sending media, to prevent weird failure modes, so it's fine
500 // for us to just eat packets here. This is all sidestepped if RTCP mux
501 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100502 RTC_LOG(LS_WARNING)
503 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
504 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000505 return;
506 }
507
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200508 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700509 RTC_FROM_HERE, worker_thread_,
Zhi Huang365381f2018-04-13 16:44:34 -0700510 Bind(&BaseChannel::ProcessPacket, this, rtcp, packet, packet_time));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200511}
512
zstein3dcf0e92017-06-01 13:22:42 -0700513void BaseChannel::ProcessPacket(bool rtcp,
514 const rtc::CopyOnWriteBuffer& packet,
515 const rtc::PacketTime& packet_time) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200516 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700517
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200518 // Need to copy variable because OnRtcpReceived/OnPacketReceived
519 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
520 rtc::CopyOnWriteBuffer data(packet);
521 if (rtcp) {
522 media_channel_->OnRtcpReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000523 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200524 media_channel_->OnPacketReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000525 }
526}
527
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000528void BaseChannel::EnableMedia_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 enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000534 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700535 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536}
537
538void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700539 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000540 if (!enabled_)
541 return;
542
Mirko Bonadei675513b2017-11-09 11:09:25 +0100543 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700545 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000546}
547
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200548void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700549 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
550 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200551 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700552 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200553 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700554 }
555}
556
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200557void BaseChannel::ChannelWritable_n() {
558 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800559 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000560 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800561 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000562
Mirko Bonadei675513b2017-11-09 11:09:25 +0100563 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
564 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000566 was_ever_writable_ = true;
567 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700568 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569}
570
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200571void BaseChannel::ChannelNotWritable_n() {
572 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000573 if (!writable_)
574 return;
575
Mirko Bonadei675513b2017-11-09 11:09:25 +0100576 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700578 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579}
580
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000581bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700582 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800583 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000584}
585
Peter Boström0c4e06b2015-10-07 12:23:21 +0200586bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700587 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000588 return media_channel()->RemoveRecvStream(ssrc);
589}
590
591bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800592 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000593 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000594 // Check for streams that have been removed.
595 bool ret = true;
596 for (StreamParamsVec::const_iterator it = local_streams_.begin();
597 it != local_streams_.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700598 if (it->has_ssrcs() && !GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200600 rtc::StringBuilder desc;
Yves Gerey665174f2018-06-19 15:03:05 +0200601 desc << "Failed to remove send stream with ssrc " << it->first_ssrc()
602 << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000603 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000604 ret = false;
605 }
606 }
607 }
608 // Check for new streams.
609 for (StreamParamsVec::const_iterator it = streams.begin();
610 it != streams.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700611 if (it->has_ssrcs() && !GetStreamBySsrc(local_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000612 if (media_channel()->AddSendStream(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100613 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000614 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200615 rtc::StringBuilder desc;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000616 desc << "Failed to add send stream ssrc: " << it->first_ssrc();
617 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000618 ret = false;
619 }
620 }
621 }
622 local_streams_ = streams;
623 return ret;
624}
625
626bool BaseChannel::UpdateRemoteStreams_w(
627 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800628 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000629 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000630 // Check for streams that have been removed.
631 bool ret = true;
632 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
633 it != remote_streams_.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700634 // If we no longer have an unsignaled stream, we would like to remove
635 // the unsignaled stream params that are cached.
636 if ((!it->has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
637 !GetStreamBySsrc(streams, it->first_ssrc())) {
Zhi Huang365381f2018-04-13 16:44:34 -0700638 if (RemoveRecvStream_w(it->first_ssrc())) {
639 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << it->first_ssrc();
640 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200641 rtc::StringBuilder desc;
Yves Gerey665174f2018-06-19 15:03:05 +0200642 desc << "Failed to remove remote stream with ssrc " << it->first_ssrc()
643 << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000644 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645 ret = false;
646 }
647 }
648 }
Zhi Huang365381f2018-04-13 16:44:34 -0700649 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000650 // Check for new streams.
651 for (StreamParamsVec::const_iterator it = streams.begin();
Yves Gerey665174f2018-06-19 15:03:05 +0200652 it != streams.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700653 // We allow a StreamParams with an empty list of SSRCs, in which case the
654 // MediaChannel will cache the parameters and use them for any unsignaled
655 // stream received later.
656 if ((!it->has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
657 !GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658 if (AddRecvStream_w(*it)) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700659 RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000660 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200661 rtc::StringBuilder desc;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000662 desc << "Failed to add remote stream ssrc: " << it->first_ssrc();
663 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000664 ret = false;
665 }
666 }
Zhi Huang365381f2018-04-13 16:44:34 -0700667 // Update the receiving SSRCs.
668 demuxer_criteria_.ssrcs.insert(it->ssrcs.begin(), it->ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 }
Zhi Huang365381f2018-04-13 16:44:34 -0700670 // Re-register the sink to update the receiving ssrcs.
671 RegisterRtpDemuxerSink();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000672 remote_streams_ = streams;
673 return ret;
674}
675
jbauch5869f502017-06-29 12:31:36 -0700676RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
677 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700678 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700679 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700680 RtpHeaderExtensions filtered;
681 auto pred = [](const webrtc::RtpExtension& extension) {
Yves Gerey665174f2018-06-19 15:03:05 +0200682 return !extension.encrypt;
jbauch5869f502017-06-29 12:31:36 -0700683 };
684 std::copy_if(extensions.begin(), extensions.end(),
Yves Gerey665174f2018-06-19 15:03:05 +0200685 std::back_inserter(filtered), pred);
jbauch5869f502017-06-29 12:31:36 -0700686 return filtered;
687 }
688
689 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
690}
691
Yves Gerey665174f2018-06-19 15:03:05 +0200692void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100693 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200695 case MSG_SEND_RTP_PACKET:
696 case MSG_SEND_RTCP_PACKET: {
697 RTC_DCHECK(network_thread_->IsCurrent());
698 SendPacketMessageData* data =
699 static_cast<SendPacketMessageData*>(pmsg->pdata);
700 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
701 SendPacket(rtcp, &data->packet, data->options);
702 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703 break;
704 }
705 case MSG_FIRSTPACKETRECEIVED: {
706 SignalFirstPacketReceived(this);
707 break;
708 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709 }
710}
711
zstein3dcf0e92017-06-01 13:22:42 -0700712void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 16:44:34 -0700713 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -0700714}
715
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200716void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717 // Flush all remaining RTCP messages. This should only be called in
718 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200719 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000720 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200721 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
722 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700723 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
724 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 }
726}
727
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800728void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200729 RTC_DCHECK(network_thread_->IsCurrent());
730 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700731 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200732 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
733}
734
735void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
736 RTC_DCHECK(worker_thread_->IsCurrent());
737 SignalSentPacket(sent_packet);
738}
739
740VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
741 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800742 rtc::Thread* signaling_thread,
Niels Möllerf120cba2018-01-30 09:33:03 +0100743 // TODO(nisse): Delete unused argument.
744 MediaEngineInterface* /* media_engine */,
Steve Anton8699a322017-11-06 15:53:33 -0800745 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700747 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700748 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200749 : BaseChannel(worker_thread,
750 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800751 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800752 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700753 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700754 srtp_required,
755 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000756
757VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800758 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000759 // this can't be done in the base class, since it calls a virtual
760 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700761 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000762}
763
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700764void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200765 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700766 invoker_.AsyncInvoke<void>(
767 RTC_FROM_HERE, worker_thread_,
768 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200769}
770
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700771void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772 // Render incoming data if we're the active call, and we have the local
773 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700774 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700775 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776
777 // Send outgoing data if we're the active call, we have the remote content,
778 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700779 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800780 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781
Mirko Bonadei675513b2017-11-09 11:09:25 +0100782 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783}
784
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800786 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000787 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100788 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800789 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100790 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791
Steve Antonb1c1de12017-12-21 15:14:30 -0800792 RTC_DCHECK(content);
793 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000794 SafeSetError("Can't find audio content in local description.", error_desc);
795 return false;
796 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000797
Steve Antonb1c1de12017-12-21 15:14:30 -0800798 const AudioContentDescription* audio = content->as_audio();
799
jbauch5869f502017-06-29 12:31:36 -0700800 RtpHeaderExtensions rtp_header_extensions =
801 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700802 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100803 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700804
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700805 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700806 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700807 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -0700808 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700809 error_desc);
810 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000811 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700812 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700813 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700814 }
Zhi Huang365381f2018-04-13 16:44:34 -0700815 // Need to re-register the sink to update the handled payload.
816 if (!RegisterRtpDemuxerSink()) {
817 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
818 return false;
819 }
820
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700821 last_recv_params_ = recv_params;
822
823 // TODO(pthatcher): Move local streams into AudioSendParameters, and
824 // only give it to the media channel once we have a remote
825 // description too (without a remote description, we won't be able
826 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800827 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700828 SafeSetError("Failed to set local audio description streams.", error_desc);
829 return false;
830 }
831
832 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700833 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700834 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835}
836
837bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800838 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000839 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100840 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800841 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100842 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843
Steve Antonb1c1de12017-12-21 15:14:30 -0800844 RTC_DCHECK(content);
845 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000846 SafeSetError("Can't find audio content in remote description.", error_desc);
847 return false;
848 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849
Steve Antonb1c1de12017-12-21 15:14:30 -0800850 const AudioContentDescription* audio = content->as_audio();
851
jbauch5869f502017-06-29 12:31:36 -0700852 RtpHeaderExtensions rtp_header_extensions =
853 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
854
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700855 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700856 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +0200857 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700858 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700859
860 bool parameters_applied = media_channel()->SetSendParameters(send_params);
861 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700862 SafeSetError("Failed to set remote audio description send parameters.",
863 error_desc);
864 return false;
865 }
866 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000867
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700868 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
869 // and only give it to the media channel once we have a local
870 // description too (without a local description, we won't be able to
871 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800872 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700873 SafeSetError("Failed to set remote audio description streams.", error_desc);
874 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875 }
876
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700877 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700878 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700879 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200882VideoChannel::VideoChannel(rtc::Thread* worker_thread,
883 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800884 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800885 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000886 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700887 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700888 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200889 : BaseChannel(worker_thread,
890 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800891 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800892 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700893 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700894 srtp_required,
895 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800898 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899 // this can't be done in the base class, since it calls a virtual
900 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700901 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902}
903
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700904void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 // Send outgoing data if we're the active call, we have the remote content,
906 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700907 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100909 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910 // TODO(gangji): Report error back to server.
911 }
912
Mirko Bonadei675513b2017-11-09 11:09:25 +0100913 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914}
915
stefanf79ade12017-06-02 06:44:03 -0700916void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
917 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
918 media_channel(), bwe_info));
919}
920
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800922 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000923 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100924 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800925 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100926 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927
Steve Antonb1c1de12017-12-21 15:14:30 -0800928 RTC_DCHECK(content);
929 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000930 SafeSetError("Can't find video content in local description.", error_desc);
931 return false;
932 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933
Steve Antonb1c1de12017-12-21 15:14:30 -0800934 const VideoContentDescription* video = content->as_video();
935
jbauch5869f502017-06-29 12:31:36 -0700936 RtpHeaderExtensions rtp_header_extensions =
937 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700938 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100939 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700940
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700941 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700942 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700943 if (!media_channel()->SetRecvParameters(recv_params)) {
944 SafeSetError("Failed to set local video description recv parameters.",
945 error_desc);
946 return false;
947 }
948 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700949 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700950 }
Zhi Huang365381f2018-04-13 16:44:34 -0700951 // Need to re-register the sink to update the handled payload.
952 if (!RegisterRtpDemuxerSink()) {
953 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
954 return false;
955 }
956
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700957 last_recv_params_ = recv_params;
958
959 // TODO(pthatcher): Move local streams into VideoSendParameters, and
960 // only give it to the media channel once we have a remote
961 // description too (without a remote description, we won't be able
962 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800963 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700964 SafeSetError("Failed to set local video description streams.", error_desc);
965 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000966 }
967
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700968 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700969 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700970 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971}
972
973bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800974 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000975 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100976 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800977 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100978 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000979
Steve Antonb1c1de12017-12-21 15:14:30 -0800980 RTC_DCHECK(content);
981 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000982 SafeSetError("Can't find video content in remote description.", error_desc);
983 return false;
984 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985
Steve Antonb1c1de12017-12-21 15:14:30 -0800986 const VideoContentDescription* video = content->as_video();
987
jbauch5869f502017-06-29 12:31:36 -0700988 RtpHeaderExtensions rtp_header_extensions =
989 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
990
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700991 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700992 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +0200993 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700994 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -0800995 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700996 }
Steve Antonbb50ce52018-03-26 10:24:32 -0700997 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700998
999 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1000
1001 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001002 SafeSetError("Failed to set remote video description send parameters.",
1003 error_desc);
1004 return false;
1005 }
1006 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001008 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1009 // and only give it to the media channel once we have a local
1010 // description too (without a local description, we won't be able to
1011 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001012 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001013 SafeSetError("Failed to set remote video description streams.", error_desc);
1014 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001016 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001017 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001018 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019}
1020
deadbeef953c2ce2017-01-09 14:53:41 -08001021RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1022 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001023 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001024 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001025 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001026 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001027 webrtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001028 : BaseChannel(worker_thread,
1029 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001030 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001031 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001032 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001033 srtp_required,
1034 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001035
deadbeef953c2ce2017-01-09 14:53:41 -08001036RtpDataChannel::~RtpDataChannel() {
1037 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001038 // this can't be done in the base class, since it calls a virtual
1039 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001040 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001041}
1042
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001043void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
Anton Sukhanov98a462c2018-10-17 13:15:42 -07001044 BaseChannel::Init_w(rtp_transport, /*media_transport=*/nullptr);
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001045 media_channel()->SignalDataReceived.connect(this,
1046 &RtpDataChannel::OnDataReceived);
1047 media_channel()->SignalReadyToSend.connect(
1048 this, &RtpDataChannel::OnDataChannelReadyToSend);
1049}
1050
deadbeef953c2ce2017-01-09 14:53:41 -08001051bool RtpDataChannel::SendData(const SendDataParams& params,
1052 const rtc::CopyOnWriteBuffer& payload,
1053 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001054 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001055 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1056 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057}
1058
deadbeef953c2ce2017-01-09 14:53:41 -08001059bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001060 const DataContentDescription* content,
1061 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001062 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1063 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001064 // It's been set before, but doesn't match. That's bad.
1065 if (is_sctp) {
1066 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1067 error_desc);
1068 return false;
1069 }
1070 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001071}
1072
deadbeef953c2ce2017-01-09 14:53:41 -08001073bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001074 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001075 std::string* error_desc) {
1076 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001077 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001078 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001079
Steve Antonb1c1de12017-12-21 15:14:30 -08001080 RTC_DCHECK(content);
1081 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001082 SafeSetError("Can't find data content in local description.", error_desc);
1083 return false;
1084 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001085
Steve Antonb1c1de12017-12-21 15:14:30 -08001086 const DataContentDescription* data = content->as_data();
1087
deadbeef953c2ce2017-01-09 14:53:41 -08001088 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001089 return false;
1090 }
1091
jbauch5869f502017-06-29 12:31:36 -07001092 RtpHeaderExtensions rtp_header_extensions =
1093 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1094
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001095 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001096 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001097 if (!media_channel()->SetRecvParameters(recv_params)) {
1098 SafeSetError("Failed to set remote data description recv parameters.",
1099 error_desc);
1100 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001101 }
deadbeef953c2ce2017-01-09 14:53:41 -08001102 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001103 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001104 }
Zhi Huang365381f2018-04-13 16:44:34 -07001105 // Need to re-register the sink to update the handled payload.
1106 if (!RegisterRtpDemuxerSink()) {
1107 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1108 return false;
1109 }
1110
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001111 last_recv_params_ = recv_params;
1112
1113 // TODO(pthatcher): Move local streams into DataSendParameters, and
1114 // only give it to the media channel once we have a remote
1115 // description too (without a remote description, we won't be able
1116 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001117 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001118 SafeSetError("Failed to set local data description streams.", error_desc);
1119 return false;
1120 }
1121
1122 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001123 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001124 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001125}
1126
deadbeef953c2ce2017-01-09 14:53:41 -08001127bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001128 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001129 std::string* error_desc) {
1130 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001131 RTC_DCHECK_RUN_ON(worker_thread());
1132 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001133
Steve Antonb1c1de12017-12-21 15:14:30 -08001134 RTC_DCHECK(content);
1135 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001136 SafeSetError("Can't find data content in remote description.", error_desc);
1137 return false;
1138 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001139
Steve Antonb1c1de12017-12-21 15:14:30 -08001140 const DataContentDescription* data = content->as_data();
1141
Zhi Huang801b8682017-11-15 11:36:43 -08001142 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1143 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001144 return true;
1145 }
1146
deadbeef953c2ce2017-01-09 14:53:41 -08001147 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001148 return false;
1149 }
1150
jbauch5869f502017-06-29 12:31:36 -07001151 RtpHeaderExtensions rtp_header_extensions =
1152 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1153
Mirko Bonadei675513b2017-11-09 11:09:25 +01001154 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001155 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001156 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001157 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001158 if (!media_channel()->SetSendParameters(send_params)) {
1159 SafeSetError("Failed to set remote data description send parameters.",
1160 error_desc);
1161 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001162 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001163 last_send_params_ = send_params;
1164
1165 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1166 // and only give it to the media channel once we have a local
1167 // description too (without a local description, we won't be able to
1168 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001169 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yves Gerey665174f2018-06-19 15:03:05 +02001170 SafeSetError("Failed to set remote data description streams.", error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001171 return false;
1172 }
1173
1174 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001175 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001176 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001177}
1178
deadbeef953c2ce2017-01-09 14:53:41 -08001179void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001180 // Render incoming data if we're the active call, and we have the local
1181 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001182 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001183 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001184 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001185 }
1186
1187 // Send outgoing data if we're the active call, we have the remote content,
1188 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001189 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001190 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001191 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001192 }
1193
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001194 // Trigger SignalReadyToSendData asynchronously.
1195 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001196
Mirko Bonadei675513b2017-11-09 11:09:25 +01001197 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001198}
1199
deadbeef953c2ce2017-01-09 14:53:41 -08001200void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001201 switch (pmsg->message_id) {
1202 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001203 DataChannelReadyToSendMessageData* data =
1204 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001205 ready_to_send_data_ = data->data();
1206 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001207 delete data;
1208 break;
1209 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001210 case MSG_DATARECEIVED: {
1211 DataReceivedMessageData* data =
1212 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001213 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001214 delete data;
1215 break;
1216 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001217 default:
1218 BaseChannel::OnMessage(pmsg);
1219 break;
1220 }
1221}
1222
deadbeef953c2ce2017-01-09 14:53:41 -08001223void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1224 const char* data,
1225 size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +02001226 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001227 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001228}
1229
deadbeef953c2ce2017-01-09 14:53:41 -08001230void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001231 // This is usded for congestion control to indicate that the stream is ready
1232 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1233 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001234 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001235 new DataChannelReadyToSendMessageData(writable));
1236}
1237
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001238} // namespace cricket