blob: cb3672a9530ea814ddc2bccf41ee8588eec97bc7 [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/trace_event.h"
Patrik Höglund42805f32018-01-18 19:15:38 +000030// Adding 'nogncheck' to disable the gn include headers check to support modular
31// WebRTC build targets.
32#include "media/engine/webrtcvoiceengine.h" // nogncheck
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "p2p/base/packettransportinternal.h"
34#include "pc/channelmanager.h"
Steve Anton4e70a722017-11-28 14:57:10 -080035#include "pc/rtpmediautils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
37namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000038using rtc::Bind;
Steve Anton3828c062017-12-06 10:34:51 -080039using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000040
deadbeef2d110be2016-01-13 12:00:26 -080041namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020042
43struct SendPacketMessageData : public rtc::MessageData {
44 rtc::CopyOnWriteBuffer packet;
45 rtc::PacketOptions options;
46};
47
deadbeef2d110be2016-01-13 12:00:26 -080048} // namespace
49
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050enum {
Steve Anton0807d152018-03-05 11:23:09 -080051 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020052 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056};
57
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000058static void SafeSetError(const std::string& message, std::string* error_desc) {
59 if (error_desc) {
60 *error_desc = message;
61 }
62}
63
jbaucheec21bd2016-03-20 06:15:43 -070064static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 // Check the packet size. We could check the header too if needed.
zstein3dcf0e92017-06-01 13:22:42 -070066 return packet && IsValidRtpRtcpPacketSize(rtcp, packet->size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067}
68
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070069template <class Codec>
70void RtpParametersFromMediaDescription(
71 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070072 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070073 RtpParameters<Codec>* params) {
74 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 11:36:43 -080075 // a description without codecs. Currently the ORTC implementation is relying
76 // on this.
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070077 if (desc->has_codecs()) {
78 params->codecs = desc->codecs();
79 }
80 // TODO(pthatcher): See if we really need
81 // rtp_header_extensions_set() and remove it if we don't.
82 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -070083 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070084 }
deadbeef13871492015-12-09 12:37:51 -080085 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070086}
87
nisse05103312016-03-16 02:22:50 -070088template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070089void RtpSendParametersFromMediaDescription(
90 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070091 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 02:22:50 -070092 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 12:31:36 -070093 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070094 send_params->max_bandwidth_bps = desc->bandwidth();
95}
96
Danil Chapovalov33b01f22016-05-11 19:55:27 +020097BaseChannel::BaseChannel(rtc::Thread* worker_thread,
98 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -080099 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800100 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700101 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700102 bool srtp_required,
103 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200104 : worker_thread_(worker_thread),
105 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800106 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000107 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800108 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700109 crypto_options_(crypto_options),
Zhi Huang1d88d742017-11-15 15:58:49 -0800110 media_channel_(std::move(media_channel)) {
Steve Anton8699a322017-11-06 15:53:33 -0800111 RTC_DCHECK_RUN_ON(worker_thread_);
Zhi Huang365381f2018-04-13 16:44:34 -0700112 demuxer_criteria_.mid = content_name;
Mirko Bonadei675513b2017-11-09 11:09:25 +0100113 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114}
115
116BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800117 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800118 RTC_DCHECK_RUN_ON(worker_thread_);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200119 // Eats any outstanding messages or packets.
120 worker_thread_->Clear(&invoker_);
121 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122 // We must destroy the media channel before the transport channel, otherwise
123 // the media channel may try to send on the dead transport channel. NULLing
124 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800125 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100126 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200127}
128
Zhi Huang365381f2018-04-13 16:44:34 -0700129bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800130 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700131 if (!RegisterRtpDemuxerSink()) {
132 return false;
133 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800134 rtp_transport_->SignalReadyToSend.connect(
135 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang365381f2018-04-13 16:44:34 -0700136 rtp_transport_->SignalRtcpPacketReceived.connect(
137 this, &BaseChannel::OnRtcpPacketReceived);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800138 rtp_transport_->SignalNetworkRouteChanged.connect(
139 this, &BaseChannel::OnNetworkRouteChanged);
140 rtp_transport_->SignalWritableState.connect(this,
141 &BaseChannel::OnWritableState);
142 rtp_transport_->SignalSentPacket.connect(this,
143 &BaseChannel::SignalSentPacket_n);
Steve Antondb67ba12018-03-19 17:41:42 -0700144 // TODO(bugs.webrtc.org/8587): Set the metrics observer through
145 // JsepTransportController once it takes responsibility for creating
146 // RtpTransports.
147 if (metrics_observer_) {
148 rtp_transport_->SetMetricsObserver(metrics_observer_);
149 }
Zhi Huang365381f2018-04-13 16:44:34 -0700150 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800151}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200152
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800153void BaseChannel::DisconnectFromRtpTransport() {
154 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700155 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800156 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang365381f2018-04-13 16:44:34 -0700157 rtp_transport_->SignalRtcpPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800158 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
159 rtp_transport_->SignalWritableState.disconnect(this);
160 rtp_transport_->SignalSentPacket.disconnect(this);
Steve Antondb67ba12018-03-19 17:41:42 -0700161 rtp_transport_->SetMetricsObserver(nullptr);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200162}
163
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800164void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
165 RTC_DCHECK_RUN_ON(worker_thread_);
Zhi Huang365381f2018-04-13 16:44:34 -0700166 network_thread_->Invoke<void>(
167 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800168
169 // Both RTP and RTCP channels should be set, we can call SetInterface on
170 // the media channel and it can set network options.
171 media_channel_->SetInterface(this);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200172}
173
wu@webrtc.org78187522013-10-07 23:32:02 +0000174void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200175 RTC_DCHECK(worker_thread_->IsCurrent());
wu@webrtc.org78187522013-10-07 23:32:02 +0000176 media_channel_->SetInterface(NULL);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200177 // Packets arrive on the network thread, processing packets calls virtual
178 // functions, so need to stop this process in Deinit that is called in
179 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800180 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000181 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700182
Zhi Huange830e682018-03-30 10:48:35 -0700183 if (rtp_transport_) {
184 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000185 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800186 // Clear pending read packets/messages.
187 network_thread_->Clear(&invoker_);
188 network_thread_->Clear(this);
189 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000190}
191
Zhi Huang365381f2018-04-13 16:44:34 -0700192bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
193 if (rtp_transport == rtp_transport_) {
194 return true;
195 }
196
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800197 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 16:44:34 -0700198 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
199 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800200 });
201 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000202
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800203 if (rtp_transport_) {
204 DisconnectFromRtpTransport();
205 }
Zhi Huange830e682018-03-30 10:48:35 -0700206
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800207 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700208 if (rtp_transport_) {
209 RTC_DCHECK(rtp_transport_->rtp_packet_transport());
210 transport_name_ = rtp_transport_->rtp_packet_transport()->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800211
Zhi Huang365381f2018-04-13 16:44:34 -0700212 if (!ConnectToRtpTransport()) {
213 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport.";
214 return false;
215 }
Zhi Huange830e682018-03-30 10:48:35 -0700216 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
217 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800218
Zhi Huange830e682018-03-30 10:48:35 -0700219 // Set the cached socket options.
220 for (const auto& pair : socket_options_) {
221 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
222 pair.second);
223 }
224 if (rtp_transport_->rtcp_packet_transport()) {
225 for (const auto& pair : rtcp_socket_options_) {
226 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
227 pair.second);
228 }
229 }
guoweis46383312015-12-17 16:45:59 -0800230 }
Zhi Huang365381f2018-04-13 16:44:34 -0700231 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000232}
233
Steve Antondb67ba12018-03-19 17:41:42 -0700234void BaseChannel::SetMetricsObserver(
235 rtc::scoped_refptr<webrtc::MetricsObserverInterface> metrics_observer) {
236 metrics_observer_ = metrics_observer;
237 if (rtp_transport_) {
238 rtp_transport_->SetMetricsObserver(metrics_observer);
239 }
240}
241
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700243 worker_thread_->Invoke<void>(
244 RTC_FROM_HERE,
245 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
246 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247 return true;
248}
249
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250bool BaseChannel::AddRecvStream(const StreamParams& sp) {
Zhi Huang365381f2018-04-13 16:44:34 -0700251 demuxer_criteria_.ssrcs.insert(sp.first_ssrc());
252 if (!RegisterRtpDemuxerSink()) {
253 return false;
254 }
stefanf79ade12017-06-02 06:44:03 -0700255 return InvokeOnWorker<bool>(RTC_FROM_HERE,
256 Bind(&BaseChannel::AddRecvStream_w, this, sp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257}
258
Peter Boström0c4e06b2015-10-07 12:23:21 +0200259bool BaseChannel::RemoveRecvStream(uint32_t ssrc) {
Zhi Huang365381f2018-04-13 16:44:34 -0700260 demuxer_criteria_.ssrcs.erase(ssrc);
261 if (!RegisterRtpDemuxerSink()) {
262 return false;
263 }
stefanf79ade12017-06-02 06:44:03 -0700264 return InvokeOnWorker<bool>(
265 RTC_FROM_HERE, Bind(&BaseChannel::RemoveRecvStream_w, this, ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266}
267
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000268bool BaseChannel::AddSendStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700269 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700270 RTC_FROM_HERE, Bind(&MediaChannel::AddSendStream, media_channel(), sp));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000271}
272
Peter Boström0c4e06b2015-10-07 12:23:21 +0200273bool BaseChannel::RemoveSendStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700274 return InvokeOnWorker<bool>(
275 RTC_FROM_HERE,
276 Bind(&MediaChannel::RemoveSendStream, media_channel(), ssrc));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000277}
278
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000279bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800280 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000281 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100282 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700283 return InvokeOnWorker<bool>(
284 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800285 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286}
287
288bool BaseChannel::SetRemoteContent(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::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700292 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800293 RTC_FROM_HERE,
294 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000295}
296
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700297bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800299 return enabled() &&
300 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301}
302
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700303bool BaseChannel::IsReadyToSendMedia_w() const {
304 // Need to access some state updated on the network thread.
305 return network_thread_->Invoke<bool>(
306 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
307}
308
309bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 // Send outgoing data if we are enabled, have local and remote content,
311 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800312 return enabled() &&
313 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
314 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 16:44:34 -0700315 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316}
317
jbaucheec21bd2016-03-20 06:15:43 -0700318bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700319 const rtc::PacketOptions& options) {
320 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321}
322
jbaucheec21bd2016-03-20 06:15:43 -0700323bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700324 const rtc::PacketOptions& options) {
325 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326}
327
Yves Gerey665174f2018-06-19 15:03:05 +0200328int BaseChannel::SetOption(SocketType type,
329 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200331 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700332 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200333}
334
335int BaseChannel::SetOption_n(SocketType type,
336 rtc::Socket::Option opt,
337 int value) {
338 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700339 RTC_DCHECK(rtp_transport_);
deadbeef5bd5ca32017-02-10 11:31:50 -0800340 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000342 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700343 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700344 socket_options_.push_back(
345 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000346 break;
347 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700348 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700349 rtcp_socket_options_.push_back(
350 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000351 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352 }
deadbeeff5346592017-01-24 21:51:21 -0800353 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354}
355
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800356void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200357 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800358 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800359 ChannelWritable_n();
360 } else {
361 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800362 }
363}
364
Zhi Huang942bc2e2017-11-13 13:26:07 -0800365void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200366 absl::optional<rtc::NetworkRoute> network_route) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200367 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800368 rtc::NetworkRoute new_route;
369 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800370 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000371 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800372 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
373 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
374 // work correctly. Intentionally leave it broken to simplify the code and
375 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800376 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800377 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800378 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700379}
380
zstein56162b92017-04-24 16:54:35 -0700381void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800382 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
383 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384}
385
stefanc1aeaf02015-10-15 07:26:07 -0700386bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700387 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700388 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200389 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
390 // If the thread is not our network thread, we will post to our network
391 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000392 // synchronize access to all the pieces of the send path, including
393 // SRTP and the inner workings of the transport channels.
394 // The only downside is that we can't return a proper failure code if
395 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200396 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000397 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200398 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
399 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800400 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700401 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700402 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000403 return true;
404 }
Zhi Huange830e682018-03-30 10:48:35 -0700405
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200406 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407
408 // Now that we are on the correct thread, ensure we have a place to send this
409 // packet before doing anything. (We might get RTCP packets that we don't
410 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
411 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700412 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000413 return false;
414 }
415
416 // Protect ourselves against crazy data.
417 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100418 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
419 << RtpRtcpStringLiteral(rtcp)
420 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000421 return false;
422 }
423
Zhi Huangcf990f52017-09-22 12:12:30 -0700424 if (!srtp_active()) {
425 if (srtp_required_) {
426 // The audio/video engines may attempt to send RTCP packets as soon as the
427 // streams are created, so don't treat this as an error for RTCP.
428 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
429 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000430 return false;
431 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700432 // However, there shouldn't be any RTP packets sent before SRTP is set up
433 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100434 RTC_LOG(LS_ERROR)
435 << "Can't send outgoing RTP packet when SRTP is inactive"
436 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700437 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800438 return false;
439 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800440
441 std::string packet_type = rtcp ? "RTCP" : "RTP";
442 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
443 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000444 }
Zhi Huange830e682018-03-30 10:48:35 -0700445
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000446 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800447 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
448 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000449}
450
Zhi Huang365381f2018-04-13 16:44:34 -0700451void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
452 // Reconstruct the PacketTime from the |parsed_packet|.
453 // RtpPacketReceived.arrival_time_ms = (PacketTime + 500) / 1000;
454 // Note: The |not_before| field is always 0 here. This field is not currently
455 // used, so it should be fine.
456 int64_t timestamp = -1;
457 if (parsed_packet.arrival_time_ms() > 0) {
458 timestamp = parsed_packet.arrival_time_ms() * 1000;
459 }
460 rtc::PacketTime packet_time(timestamp, /*not_before=*/0);
461
462 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), packet_time);
463}
464
465void BaseChannel::UpdateRtpHeaderExtensionMap(
466 const RtpHeaderExtensions& header_extensions) {
467 RTC_DCHECK(rtp_transport_);
468 // Update the header extension map on network thread in case there is data
469 // race.
470 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
471 // be accessed from different threads.
472 //
473 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
474 // extension maps are not merged when BUNDLE is enabled. This is fine because
475 // the ID for MID should be consistent among all the RTP transports.
476 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
477 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
478 });
479}
480
481bool BaseChannel::RegisterRtpDemuxerSink() {
482 RTC_DCHECK(rtp_transport_);
483 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
484 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
485 });
486}
487
488void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
489 const rtc::PacketTime& packet_time) {
490 OnPacketReceived(/*rtcp=*/true, *packet, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000491}
492
zstein3dcf0e92017-06-01 13:22:42 -0700493void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang365381f2018-04-13 16:44:34 -0700494 const rtc::CopyOnWriteBuffer& packet,
zstein3dcf0e92017-06-01 13:22:42 -0700495 const rtc::PacketTime& packet_time) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000496 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000497 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700498 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000499 }
500
Zhi Huangcf990f52017-09-22 12:12:30 -0700501 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000502 // Our session description indicates that SRTP is required, but we got a
503 // packet before our SRTP filter is active. This means either that
504 // a) we got SRTP packets before we received the SDES keys, in which case
505 // we can't decrypt it anyway, or
506 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800507 // transports, so we haven't yet extracted keys, even if DTLS did
508 // complete on the transport that the packets are being sent on. It's
509 // really good practice to wait for both RTP and RTCP to be good to go
510 // before sending media, to prevent weird failure modes, so it's fine
511 // for us to just eat packets here. This is all sidestepped if RTCP mux
512 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100513 RTC_LOG(LS_WARNING)
514 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
515 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000516 return;
517 }
518
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200519 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700520 RTC_FROM_HERE, worker_thread_,
Zhi Huang365381f2018-04-13 16:44:34 -0700521 Bind(&BaseChannel::ProcessPacket, this, rtcp, packet, packet_time));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200522}
523
zstein3dcf0e92017-06-01 13:22:42 -0700524void BaseChannel::ProcessPacket(bool rtcp,
525 const rtc::CopyOnWriteBuffer& packet,
526 const rtc::PacketTime& packet_time) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200527 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700528
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200529 // Need to copy variable because OnRtcpReceived/OnPacketReceived
530 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
531 rtc::CopyOnWriteBuffer data(packet);
532 if (rtcp) {
533 media_channel_->OnRtcpReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000534 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200535 media_channel_->OnPacketReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536 }
537}
538
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000539void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700540 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000541 if (enabled_)
542 return;
543
Mirko Bonadei675513b2017-11-09 11:09:25 +0100544 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000545 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700546 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000547}
548
549void BaseChannel::DisableMedia_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 disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700556 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000557}
558
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200559void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700560 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
561 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200562 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700563 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200564 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700565 }
566}
567
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200568void BaseChannel::ChannelWritable_n() {
569 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800570 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800572 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000573
Mirko Bonadei675513b2017-11-09 11:09:25 +0100574 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
575 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000576
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 was_ever_writable_ = true;
578 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700579 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580}
581
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200582void BaseChannel::ChannelNotWritable_n() {
583 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000584 if (!writable_)
585 return;
586
Mirko Bonadei675513b2017-11-09 11:09:25 +0100587 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000588 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700589 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000590}
591
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000592bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700593 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800594 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595}
596
Peter Boström0c4e06b2015-10-07 12:23:21 +0200597bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700598 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599 return media_channel()->RemoveRecvStream(ssrc);
600}
601
602bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800603 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000604 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000605 // Check for streams that have been removed.
606 bool ret = true;
607 for (StreamParamsVec::const_iterator it = local_streams_.begin();
608 it != local_streams_.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700609 if (it->has_ssrcs() && !GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000610 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000611 std::ostringstream desc;
Yves Gerey665174f2018-06-19 15:03:05 +0200612 desc << "Failed to remove send stream with ssrc " << it->first_ssrc()
613 << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000614 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000615 ret = false;
616 }
617 }
618 }
619 // Check for new streams.
620 for (StreamParamsVec::const_iterator it = streams.begin();
621 it != streams.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700622 if (it->has_ssrcs() && !GetStreamBySsrc(local_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000623 if (media_channel()->AddSendStream(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100624 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000625 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000626 std::ostringstream desc;
627 desc << "Failed to add send stream ssrc: " << it->first_ssrc();
628 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629 ret = false;
630 }
631 }
632 }
633 local_streams_ = streams;
634 return ret;
635}
636
637bool BaseChannel::UpdateRemoteStreams_w(
638 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800639 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000640 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000641 // Check for streams that have been removed.
642 bool ret = true;
643 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
644 it != remote_streams_.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700645 // If we no longer have an unsignaled stream, we would like to remove
646 // the unsignaled stream params that are cached.
647 if ((!it->has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
648 !GetStreamBySsrc(streams, it->first_ssrc())) {
Zhi Huang365381f2018-04-13 16:44:34 -0700649 if (RemoveRecvStream_w(it->first_ssrc())) {
650 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << it->first_ssrc();
651 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000652 std::ostringstream desc;
Yves Gerey665174f2018-06-19 15:03:05 +0200653 desc << "Failed to remove remote stream with ssrc " << it->first_ssrc()
654 << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000655 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000656 ret = false;
657 }
658 }
659 }
Zhi Huang365381f2018-04-13 16:44:34 -0700660 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000661 // Check for new streams.
662 for (StreamParamsVec::const_iterator it = streams.begin();
Yves Gerey665174f2018-06-19 15:03:05 +0200663 it != streams.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700664 // We allow a StreamParams with an empty list of SSRCs, in which case the
665 // MediaChannel will cache the parameters and use them for any unsignaled
666 // stream received later.
667 if ((!it->has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
668 !GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 if (AddRecvStream_w(*it)) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700670 RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000671 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000672 std::ostringstream desc;
673 desc << "Failed to add remote stream ssrc: " << it->first_ssrc();
674 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675 ret = false;
676 }
677 }
Zhi Huang365381f2018-04-13 16:44:34 -0700678 // Update the receiving SSRCs.
679 demuxer_criteria_.ssrcs.insert(it->ssrcs.begin(), it->ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000680 }
Zhi Huang365381f2018-04-13 16:44:34 -0700681 // Re-register the sink to update the receiving ssrcs.
682 RegisterRtpDemuxerSink();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000683 remote_streams_ = streams;
684 return ret;
685}
686
jbauch5869f502017-06-29 12:31:36 -0700687RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
688 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700689 RTC_DCHECK(rtp_transport_);
690 if (crypto_options_.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700691 RtpHeaderExtensions filtered;
692 auto pred = [](const webrtc::RtpExtension& extension) {
Yves Gerey665174f2018-06-19 15:03:05 +0200693 return !extension.encrypt;
jbauch5869f502017-06-29 12:31:36 -0700694 };
695 std::copy_if(extensions.begin(), extensions.end(),
Yves Gerey665174f2018-06-19 15:03:05 +0200696 std::back_inserter(filtered), pred);
jbauch5869f502017-06-29 12:31:36 -0700697 return filtered;
698 }
699
700 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
701}
702
Yves Gerey665174f2018-06-19 15:03:05 +0200703void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100704 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200706 case MSG_SEND_RTP_PACKET:
707 case MSG_SEND_RTCP_PACKET: {
708 RTC_DCHECK(network_thread_->IsCurrent());
709 SendPacketMessageData* data =
710 static_cast<SendPacketMessageData*>(pmsg->pdata);
711 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
712 SendPacket(rtcp, &data->packet, data->options);
713 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 break;
715 }
716 case MSG_FIRSTPACKETRECEIVED: {
717 SignalFirstPacketReceived(this);
718 break;
719 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 }
721}
722
zstein3dcf0e92017-06-01 13:22:42 -0700723void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 16:44:34 -0700724 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -0700725}
726
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200727void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000728 // Flush all remaining RTCP messages. This should only be called in
729 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200730 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000731 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200732 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
733 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700734 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
735 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000736 }
737}
738
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800739void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200740 RTC_DCHECK(network_thread_->IsCurrent());
741 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700742 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200743 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
744}
745
746void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
747 RTC_DCHECK(worker_thread_->IsCurrent());
748 SignalSentPacket(sent_packet);
749}
750
751VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
752 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800753 rtc::Thread* signaling_thread,
Niels Möllerf120cba2018-01-30 09:33:03 +0100754 // TODO(nisse): Delete unused argument.
755 MediaEngineInterface* /* media_engine */,
Steve Anton8699a322017-11-06 15:53:33 -0800756 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000757 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700758 bool srtp_required,
759 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200760 : BaseChannel(worker_thread,
761 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800762 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800763 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700764 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700765 srtp_required,
766 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767
768VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800769 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770 // this can't be done in the base class, since it calls a virtual
771 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700772 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773}
774
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700775void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200776 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700777 invoker_.AsyncInvoke<void>(
778 RTC_FROM_HERE, worker_thread_,
779 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200780}
781
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700782void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783 // Render incoming data if we're the active call, and we have the local
784 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700785 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700786 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787
788 // Send outgoing data if we're the active call, we have the remote content,
789 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700790 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800791 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000792
Mirko Bonadei675513b2017-11-09 11:09:25 +0100793 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794}
795
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800797 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000798 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100799 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800800 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100801 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802
Steve Antonb1c1de12017-12-21 15:14:30 -0800803 RTC_DCHECK(content);
804 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000805 SafeSetError("Can't find audio content in local description.", error_desc);
806 return false;
807 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808
Steve Antonb1c1de12017-12-21 15:14:30 -0800809 const AudioContentDescription* audio = content->as_audio();
810
jbauch5869f502017-06-29 12:31:36 -0700811 RtpHeaderExtensions rtp_header_extensions =
812 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700813 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
jbauch5869f502017-06-29 12:31:36 -0700814
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700815 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700816 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700817 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -0700818 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700819 error_desc);
820 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700822 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700823 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700824 }
Zhi Huang365381f2018-04-13 16:44:34 -0700825 // Need to re-register the sink to update the handled payload.
826 if (!RegisterRtpDemuxerSink()) {
827 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
828 return false;
829 }
830
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700831 last_recv_params_ = recv_params;
832
833 // TODO(pthatcher): Move local streams into AudioSendParameters, and
834 // only give it to the media channel once we have a remote
835 // description too (without a remote description, we won't be able
836 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800837 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700838 SafeSetError("Failed to set local audio description streams.", error_desc);
839 return false;
840 }
841
842 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700843 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700844 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845}
846
847bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800848 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000849 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100850 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800851 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100852 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853
Steve Antonb1c1de12017-12-21 15:14:30 -0800854 RTC_DCHECK(content);
855 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000856 SafeSetError("Can't find audio content in remote description.", error_desc);
857 return false;
858 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859
Steve Antonb1c1de12017-12-21 15:14:30 -0800860 const AudioContentDescription* audio = content->as_audio();
861
jbauch5869f502017-06-29 12:31:36 -0700862 RtpHeaderExtensions rtp_header_extensions =
863 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
864
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700865 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700866 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +0200867 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700868 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700869
870 bool parameters_applied = media_channel()->SetSendParameters(send_params);
871 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700872 SafeSetError("Failed to set remote audio description send parameters.",
873 error_desc);
874 return false;
875 }
876 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700878 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
879 // and only give it to the media channel once we have a local
880 // description too (without a local description, we won't be able to
881 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800882 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700883 SafeSetError("Failed to set remote audio description streams.", error_desc);
884 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 }
886
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700887 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700888 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700889 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890}
891
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200892VideoChannel::VideoChannel(rtc::Thread* worker_thread,
893 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800894 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800895 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700897 bool srtp_required,
898 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200899 : BaseChannel(worker_thread,
900 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800901 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800902 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700903 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700904 srtp_required,
905 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800908 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909 // this can't be done in the base class, since it calls a virtual
910 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700911 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912}
913
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700914void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915 // Send outgoing data if we're the active call, we have the remote content,
916 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700917 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100919 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920 // TODO(gangji): Report error back to server.
921 }
922
Mirko Bonadei675513b2017-11-09 11:09:25 +0100923 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924}
925
stefanf79ade12017-06-02 06:44:03 -0700926void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
927 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
928 media_channel(), bwe_info));
929}
930
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800932 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000933 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100934 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800935 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100936 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937
Steve Antonb1c1de12017-12-21 15:14:30 -0800938 RTC_DCHECK(content);
939 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000940 SafeSetError("Can't find video content in local description.", error_desc);
941 return false;
942 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
Steve Antonb1c1de12017-12-21 15:14:30 -0800944 const VideoContentDescription* video = content->as_video();
945
jbauch5869f502017-06-29 12:31:36 -0700946 RtpHeaderExtensions rtp_header_extensions =
947 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700948 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
jbauch5869f502017-06-29 12:31:36 -0700949
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700950 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700951 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700952 if (!media_channel()->SetRecvParameters(recv_params)) {
953 SafeSetError("Failed to set local video description recv parameters.",
954 error_desc);
955 return false;
956 }
957 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700958 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700959 }
Zhi Huang365381f2018-04-13 16:44:34 -0700960 // Need to re-register the sink to update the handled payload.
961 if (!RegisterRtpDemuxerSink()) {
962 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
963 return false;
964 }
965
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700966 last_recv_params_ = recv_params;
967
968 // TODO(pthatcher): Move local streams into VideoSendParameters, and
969 // only give it to the media channel once we have a remote
970 // description too (without a remote description, we won't be able
971 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800972 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700973 SafeSetError("Failed to set local video description streams.", error_desc);
974 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000975 }
976
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700977 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700978 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700979 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980}
981
982bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800983 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100985 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800986 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100987 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988
Steve Antonb1c1de12017-12-21 15:14:30 -0800989 RTC_DCHECK(content);
990 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000991 SafeSetError("Can't find video content in remote description.", error_desc);
992 return false;
993 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994
Steve Antonb1c1de12017-12-21 15:14:30 -0800995 const VideoContentDescription* video = content->as_video();
996
jbauch5869f502017-06-29 12:31:36 -0700997 RtpHeaderExtensions rtp_header_extensions =
998 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
999
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001000 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001001 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001002 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001003 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001004 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001005 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001006 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001007
1008 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1009
1010 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001011 SafeSetError("Failed to set remote video description send parameters.",
1012 error_desc);
1013 return false;
1014 }
1015 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001017 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1018 // and only give it to the media channel once we have a local
1019 // description too (without a local description, we won't be able to
1020 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001021 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001022 SafeSetError("Failed to set remote video description streams.", error_desc);
1023 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001025 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001026 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001027 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001028}
1029
deadbeef953c2ce2017-01-09 14:53:41 -08001030RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1031 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001032 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001033 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001034 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001035 bool srtp_required,
1036 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001037 : BaseChannel(worker_thread,
1038 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001039 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001040 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001041 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001042 srtp_required,
1043 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001044
deadbeef953c2ce2017-01-09 14:53:41 -08001045RtpDataChannel::~RtpDataChannel() {
1046 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001047 // this can't be done in the base class, since it calls a virtual
1048 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001049 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001050}
1051
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001052void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
1053 BaseChannel::Init_w(rtp_transport);
1054 media_channel()->SignalDataReceived.connect(this,
1055 &RtpDataChannel::OnDataReceived);
1056 media_channel()->SignalReadyToSend.connect(
1057 this, &RtpDataChannel::OnDataChannelReadyToSend);
1058}
1059
deadbeef953c2ce2017-01-09 14:53:41 -08001060bool RtpDataChannel::SendData(const SendDataParams& params,
1061 const rtc::CopyOnWriteBuffer& payload,
1062 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001063 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001064 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1065 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001066}
1067
deadbeef953c2ce2017-01-09 14:53:41 -08001068bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001069 const DataContentDescription* content,
1070 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001071 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1072 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001073 // It's been set before, but doesn't match. That's bad.
1074 if (is_sctp) {
1075 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1076 error_desc);
1077 return false;
1078 }
1079 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001080}
1081
deadbeef953c2ce2017-01-09 14:53:41 -08001082bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001083 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001084 std::string* error_desc) {
1085 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001086 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001087 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001088
Steve Antonb1c1de12017-12-21 15:14:30 -08001089 RTC_DCHECK(content);
1090 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001091 SafeSetError("Can't find data content in local description.", error_desc);
1092 return false;
1093 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001094
Steve Antonb1c1de12017-12-21 15:14:30 -08001095 const DataContentDescription* data = content->as_data();
1096
deadbeef953c2ce2017-01-09 14:53:41 -08001097 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001098 return false;
1099 }
1100
jbauch5869f502017-06-29 12:31:36 -07001101 RtpHeaderExtensions rtp_header_extensions =
1102 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1103
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001104 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001105 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001106 if (!media_channel()->SetRecvParameters(recv_params)) {
1107 SafeSetError("Failed to set remote data description recv parameters.",
1108 error_desc);
1109 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001110 }
deadbeef953c2ce2017-01-09 14:53:41 -08001111 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001112 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001113 }
Zhi Huang365381f2018-04-13 16:44:34 -07001114 // Need to re-register the sink to update the handled payload.
1115 if (!RegisterRtpDemuxerSink()) {
1116 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1117 return false;
1118 }
1119
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001120 last_recv_params_ = recv_params;
1121
1122 // TODO(pthatcher): Move local streams into DataSendParameters, and
1123 // only give it to the media channel once we have a remote
1124 // description too (without a remote description, we won't be able
1125 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001126 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001127 SafeSetError("Failed to set local data description streams.", error_desc);
1128 return false;
1129 }
1130
1131 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001132 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001133 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001134}
1135
deadbeef953c2ce2017-01-09 14:53:41 -08001136bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001137 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001138 std::string* error_desc) {
1139 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001140 RTC_DCHECK_RUN_ON(worker_thread());
1141 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001142
Steve Antonb1c1de12017-12-21 15:14:30 -08001143 RTC_DCHECK(content);
1144 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001145 SafeSetError("Can't find data content in remote description.", error_desc);
1146 return false;
1147 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001148
Steve Antonb1c1de12017-12-21 15:14:30 -08001149 const DataContentDescription* data = content->as_data();
1150
Zhi Huang801b8682017-11-15 11:36:43 -08001151 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1152 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001153 return true;
1154 }
1155
deadbeef953c2ce2017-01-09 14:53:41 -08001156 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001157 return false;
1158 }
1159
jbauch5869f502017-06-29 12:31:36 -07001160 RtpHeaderExtensions rtp_header_extensions =
1161 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1162
Mirko Bonadei675513b2017-11-09 11:09:25 +01001163 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001164 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001165 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001166 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001167 if (!media_channel()->SetSendParameters(send_params)) {
1168 SafeSetError("Failed to set remote data description send parameters.",
1169 error_desc);
1170 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001171 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001172 last_send_params_ = send_params;
1173
1174 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1175 // and only give it to the media channel once we have a local
1176 // description too (without a local description, we won't be able to
1177 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001178 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yves Gerey665174f2018-06-19 15:03:05 +02001179 SafeSetError("Failed to set remote data description streams.", error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001180 return false;
1181 }
1182
1183 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001184 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001185 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001186}
1187
deadbeef953c2ce2017-01-09 14:53:41 -08001188void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001189 // Render incoming data if we're the active call, and we have the local
1190 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001191 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001192 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001193 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001194 }
1195
1196 // Send outgoing data if we're the active call, we have the remote content,
1197 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001198 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001199 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001200 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001201 }
1202
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001203 // Trigger SignalReadyToSendData asynchronously.
1204 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001205
Mirko Bonadei675513b2017-11-09 11:09:25 +01001206 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001207}
1208
deadbeef953c2ce2017-01-09 14:53:41 -08001209void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001210 switch (pmsg->message_id) {
1211 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001212 DataChannelReadyToSendMessageData* data =
1213 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001214 ready_to_send_data_ = data->data();
1215 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001216 delete data;
1217 break;
1218 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001219 case MSG_DATARECEIVED: {
1220 DataReceivedMessageData* data =
1221 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001222 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001223 delete data;
1224 break;
1225 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001226 default:
1227 BaseChannel::OnMessage(pmsg);
1228 break;
1229 }
1230}
1231
deadbeef953c2ce2017-01-09 14:53:41 -08001232void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1233 const char* data,
1234 size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +02001235 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001236 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001237}
1238
deadbeef953c2ce2017-01-09 14:53:41 -08001239void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001240 // This is usded for congestion control to indicate that the stream is ready
1241 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1242 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001243 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001244 new DataChannelReadyToSendMessageData(writable));
1245}
1246
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001247} // namespace cricket