blob: a1869c43ca1a1a26341572a9c3a76b9c5501ed74 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/call/audio_sink.h"
18#include "media/base/mediaconstants.h"
19#include "media/base/rtputils.h"
20#include "rtc_base/bind.h"
21#include "rtc_base/byteorder.h"
22#include "rtc_base/checks.h"
23#include "rtc_base/copyonwritebuffer.h"
24#include "rtc_base/dscp.h"
25#include "rtc_base/logging.h"
26#include "rtc_base/networkroute.h"
27#include "rtc_base/ptr_util.h"
28#include "rtc_base/trace_event.h"
Patrik Höglund42805f32018-01-18 19:15:38 +000029// Adding 'nogncheck' to disable the gn include headers check to support modular
30// WebRTC build targets.
31#include "media/engine/webrtcvoiceengine.h" // nogncheck
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "p2p/base/packettransportinternal.h"
33#include "pc/channelmanager.h"
Steve Anton4e70a722017-11-28 14:57:10 -080034#include "pc/rtpmediautils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035
36namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000037using rtc::Bind;
Steve Anton3828c062017-12-06 10:34:51 -080038using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000039
deadbeef2d110be2016-01-13 12:00:26 -080040namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020041
42struct SendPacketMessageData : public rtc::MessageData {
43 rtc::CopyOnWriteBuffer packet;
44 rtc::PacketOptions options;
45};
46
deadbeef2d110be2016-01-13 12:00:26 -080047} // namespace
48
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049enum {
Steve Anton0807d152018-03-05 11:23:09 -080050 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020051 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055};
56
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000057static void SafeSetError(const std::string& message, std::string* error_desc) {
58 if (error_desc) {
59 *error_desc = message;
60 }
61}
62
jbaucheec21bd2016-03-20 06:15:43 -070063static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 // Check the packet size. We could check the header too if needed.
zstein3dcf0e92017-06-01 13:22:42 -070065 return packet && IsValidRtpRtcpPacketSize(rtcp, packet->size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066}
67
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070068template <class Codec>
69void RtpParametersFromMediaDescription(
70 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070071 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070072 RtpParameters<Codec>* params) {
73 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 11:36:43 -080074 // a description without codecs. Currently the ORTC implementation is relying
75 // on this.
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070076 if (desc->has_codecs()) {
77 params->codecs = desc->codecs();
78 }
79 // TODO(pthatcher): See if we really need
80 // rtp_header_extensions_set() and remove it if we don't.
81 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -070082 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070083 }
deadbeef13871492015-12-09 12:37:51 -080084 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070085}
86
nisse05103312016-03-16 02:22:50 -070087template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070088void RtpSendParametersFromMediaDescription(
89 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070090 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 02:22:50 -070091 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 12:31:36 -070092 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070093 send_params->max_bandwidth_bps = desc->bandwidth();
94}
95
Danil Chapovalov33b01f22016-05-11 19:55:27 +020096BaseChannel::BaseChannel(rtc::Thread* worker_thread,
97 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -080098 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -080099 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700100 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700101 bool srtp_required,
102 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200103 : worker_thread_(worker_thread),
104 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800105 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000106 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800107 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700108 crypto_options_(crypto_options),
Zhi Huang1d88d742017-11-15 15:58:49 -0800109 media_channel_(std::move(media_channel)) {
Steve Anton8699a322017-11-06 15:53:33 -0800110 RTC_DCHECK_RUN_ON(worker_thread_);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100111 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000112}
113
114BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800115 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800116 RTC_DCHECK_RUN_ON(worker_thread_);
wu@webrtc.org78187522013-10-07 23:32:02 +0000117 Deinit();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200118 // Eats any outstanding messages or packets.
119 worker_thread_->Clear(&invoker_);
120 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121 // We must destroy the media channel before the transport channel, otherwise
122 // the media channel may try to send on the dead transport channel. NULLing
123 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800124 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100125 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200126}
127
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800128void BaseChannel::ConnectToRtpTransport() {
129 RTC_DCHECK(rtp_transport_);
130 rtp_transport_->SignalReadyToSend.connect(
131 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000132 // TODO(zstein): RtpTransport::SignalPacketReceived will probably be replaced
133 // with a callback interface later so that the demuxer can select which
134 // channel to signal.
135 rtp_transport_->SignalPacketReceived.connect(this,
136 &BaseChannel::OnPacketReceived);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800137 rtp_transport_->SignalNetworkRouteChanged.connect(
138 this, &BaseChannel::OnNetworkRouteChanged);
139 rtp_transport_->SignalWritableState.connect(this,
140 &BaseChannel::OnWritableState);
141 rtp_transport_->SignalSentPacket.connect(this,
142 &BaseChannel::SignalSentPacket_n);
Steve Antondb67ba12018-03-19 17:41:42 -0700143 // TODO(bugs.webrtc.org/8587): Set the metrics observer through
144 // JsepTransportController once it takes responsibility for creating
145 // RtpTransports.
146 if (metrics_observer_) {
147 rtp_transport_->SetMetricsObserver(metrics_observer_);
148 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800149}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200150
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800151void BaseChannel::DisconnectFromRtpTransport() {
152 RTC_DCHECK(rtp_transport_);
153 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000154 rtp_transport_->SignalPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800155 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
156 rtp_transport_->SignalWritableState.disconnect(this);
157 rtp_transport_->SignalSentPacket.disconnect(this);
Steve Antondb67ba12018-03-19 17:41:42 -0700158 rtp_transport_->SetMetricsObserver(nullptr);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200159}
160
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800161void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
162 RTC_DCHECK_RUN_ON(worker_thread_);
163 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
164 SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800165 });
166
167 // Both RTP and RTCP channels should be set, we can call SetInterface on
168 // the media channel and it can set network options.
169 media_channel_->SetInterface(this);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200170}
171
wu@webrtc.org78187522013-10-07 23:32:02 +0000172void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200173 RTC_DCHECK(worker_thread_->IsCurrent());
wu@webrtc.org78187522013-10-07 23:32:02 +0000174 media_channel_->SetInterface(NULL);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200175 // Packets arrive on the network thread, processing packets calls virtual
176 // functions, so need to stop this process in Deinit that is called in
177 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800178 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000179 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700180
Zhi Huange830e682018-03-30 10:48:35 -0700181 if (rtp_transport_) {
182 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000183 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800184 // Clear pending read packets/messages.
185 network_thread_->Clear(&invoker_);
186 network_thread_->Clear(this);
187 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000188}
189
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800190void BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
191 if (!network_thread_->IsCurrent()) {
192 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
193 SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800194 });
Zhi Huange830e682018-03-30 10:48:35 -0700195 return;
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800196 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000197
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800198 if (rtp_transport_) {
199 DisconnectFromRtpTransport();
200 }
Zhi Huange830e682018-03-30 10:48:35 -0700201
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800202 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700203 if (rtp_transport_) {
204 RTC_DCHECK(rtp_transport_->rtp_packet_transport());
205 transport_name_ = rtp_transport_->rtp_packet_transport()->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800206
Zhi Huange830e682018-03-30 10:48:35 -0700207 ConnectToRtpTransport();
208 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
209 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800210
Zhi Huange830e682018-03-30 10:48:35 -0700211 // Set the cached socket options.
212 for (const auto& pair : socket_options_) {
213 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
214 pair.second);
215 }
216 if (rtp_transport_->rtcp_packet_transport()) {
217 for (const auto& pair : rtcp_socket_options_) {
218 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
219 pair.second);
220 }
221 }
guoweis46383312015-12-17 16:45:59 -0800222 }
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000223}
224
Steve Antondb67ba12018-03-19 17:41:42 -0700225void BaseChannel::SetMetricsObserver(
226 rtc::scoped_refptr<webrtc::MetricsObserverInterface> metrics_observer) {
227 metrics_observer_ = metrics_observer;
228 if (rtp_transport_) {
229 rtp_transport_->SetMetricsObserver(metrics_observer);
230 }
231}
232
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700234 worker_thread_->Invoke<void>(
235 RTC_FROM_HERE,
236 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
237 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 return true;
239}
240
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241bool BaseChannel::AddRecvStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700242 return InvokeOnWorker<bool>(RTC_FROM_HERE,
243 Bind(&BaseChannel::AddRecvStream_w, this, sp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244}
245
Peter Boström0c4e06b2015-10-07 12:23:21 +0200246bool BaseChannel::RemoveRecvStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700247 return InvokeOnWorker<bool>(
248 RTC_FROM_HERE, Bind(&BaseChannel::RemoveRecvStream_w, this, ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249}
250
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000251bool BaseChannel::AddSendStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700252 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700253 RTC_FROM_HERE, Bind(&MediaChannel::AddSendStream, media_channel(), sp));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000254}
255
Peter Boström0c4e06b2015-10-07 12:23:21 +0200256bool BaseChannel::RemoveSendStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700257 return InvokeOnWorker<bool>(
258 RTC_FROM_HERE,
259 Bind(&MediaChannel::RemoveSendStream, media_channel(), ssrc));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000260}
261
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800263 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000264 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100265 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700266 return InvokeOnWorker<bool>(
267 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800268 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269}
270
271bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800272 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000273 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100274 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700275 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800276 RTC_FROM_HERE,
277 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278}
279
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700280bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800282 return enabled() &&
283 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284}
285
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700286bool BaseChannel::IsReadyToSendMedia_w() const {
287 // Need to access some state updated on the network thread.
288 return network_thread_->Invoke<bool>(
289 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
290}
291
292bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000293 // Send outgoing data if we are enabled, have local and remote content,
294 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800295 return enabled() &&
296 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
297 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huange830e682018-03-30 10:48:35 -0700298 was_ever_writable() && (srtp_active() || encryption_disabled_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299}
300
jbaucheec21bd2016-03-20 06:15:43 -0700301bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700302 const rtc::PacketOptions& options) {
303 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304}
305
jbaucheec21bd2016-03-20 06:15:43 -0700306bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700307 const rtc::PacketOptions& options) {
308 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000309}
310
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000311int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000312 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200313 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700314 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200315}
316
317int BaseChannel::SetOption_n(SocketType type,
318 rtc::Socket::Option opt,
319 int value) {
320 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700321 RTC_DCHECK(rtp_transport_);
deadbeef5bd5ca32017-02-10 11:31:50 -0800322 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000324 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700325 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700326 socket_options_.push_back(
327 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000328 break;
329 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700330 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700331 rtcp_socket_options_.push_back(
332 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000333 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 }
deadbeeff5346592017-01-24 21:51:21 -0800335 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336}
337
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800338void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200339 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800340 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800341 ChannelWritable_n();
342 } else {
343 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800344 }
345}
346
Zhi Huang942bc2e2017-11-13 13:26:07 -0800347void BaseChannel::OnNetworkRouteChanged(
348 rtc::Optional<rtc::NetworkRoute> network_route) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200349 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800350 rtc::NetworkRoute new_route;
351 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800352 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000353 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800354 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
355 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
356 // work correctly. Intentionally leave it broken to simplify the code and
357 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800358 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800359 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800360 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700361}
362
zstein56162b92017-04-24 16:54:35 -0700363void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800364 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
365 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366}
367
stefanc1aeaf02015-10-15 07:26:07 -0700368bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700369 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700370 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200371 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
372 // If the thread is not our network thread, we will post to our network
373 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374 // synchronize access to all the pieces of the send path, including
375 // SRTP and the inner workings of the transport channels.
376 // The only downside is that we can't return a proper failure code if
377 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200378 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000379 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200380 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
381 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800382 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700383 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700384 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000385 return true;
386 }
Zhi Huange830e682018-03-30 10:48:35 -0700387
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200388 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389
390 // Now that we are on the correct thread, ensure we have a place to send this
391 // packet before doing anything. (We might get RTCP packets that we don't
392 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
393 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700394 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395 return false;
396 }
397
398 // Protect ourselves against crazy data.
399 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100400 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
401 << RtpRtcpStringLiteral(rtcp)
402 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000403 return false;
404 }
405
Zhi Huangcf990f52017-09-22 12:12:30 -0700406 if (!srtp_active()) {
407 if (srtp_required_) {
408 // The audio/video engines may attempt to send RTCP packets as soon as the
409 // streams are created, so don't treat this as an error for RTCP.
410 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
411 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000412 return false;
413 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700414 // However, there shouldn't be any RTP packets sent before SRTP is set up
415 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100416 RTC_LOG(LS_ERROR)
417 << "Can't send outgoing RTP packet when SRTP is inactive"
418 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700419 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800420 return false;
421 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800422
423 std::string packet_type = rtcp ? "RTCP" : "RTP";
424 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
425 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000426 }
Zhi Huange830e682018-03-30 10:48:35 -0700427
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000428 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800429 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
430 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431}
432
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000433bool BaseChannel::HandlesPayloadType(int packet_type) const {
Zhi Huange830e682018-03-30 10:48:35 -0700434 return bundle_filter_.FindPayloadType(packet_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000435}
436
zstein3dcf0e92017-06-01 13:22:42 -0700437void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000438 rtc::CopyOnWriteBuffer* packet,
zstein3dcf0e92017-06-01 13:22:42 -0700439 const rtc::PacketTime& packet_time) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000440 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000441 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700442 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000443 }
444
Zhi Huange830e682018-03-30 10:48:35 -0700445 // Filter out the packet this channel cannot handle.
446 if (!rtcp && !bundle_filter_.DemuxPacket(packet->data(), packet->size())) {
447 return;
448 }
449
Zhi Huangcf990f52017-09-22 12:12:30 -0700450 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000451 // Our session description indicates that SRTP is required, but we got a
452 // packet before our SRTP filter is active. This means either that
453 // a) we got SRTP packets before we received the SDES keys, in which case
454 // we can't decrypt it anyway, or
455 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800456 // transports, so we haven't yet extracted keys, even if DTLS did
457 // complete on the transport that the packets are being sent on. It's
458 // really good practice to wait for both RTP and RTCP to be good to go
459 // before sending media, to prevent weird failure modes, so it's fine
460 // for us to just eat packets here. This is all sidestepped if RTCP mux
461 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100462 RTC_LOG(LS_WARNING)
463 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
464 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000465 return;
466 }
467
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200468 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700469 RTC_FROM_HERE, worker_thread_,
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000470 Bind(&BaseChannel::ProcessPacket, this, rtcp, *packet, packet_time));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200471}
472
zstein3dcf0e92017-06-01 13:22:42 -0700473void BaseChannel::ProcessPacket(bool rtcp,
474 const rtc::CopyOnWriteBuffer& packet,
475 const rtc::PacketTime& packet_time) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200476 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700477
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200478 // Need to copy variable because OnRtcpReceived/OnPacketReceived
479 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
480 rtc::CopyOnWriteBuffer data(packet);
481 if (rtcp) {
482 media_channel_->OnRtcpReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000483 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200484 media_channel_->OnPacketReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000485 }
486}
487
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000488void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700489 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000490 if (enabled_)
491 return;
492
Mirko Bonadei675513b2017-11-09 11:09:25 +0100493 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000494 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700495 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000496}
497
498void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700499 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000500 if (!enabled_)
501 return;
502
Mirko Bonadei675513b2017-11-09 11:09:25 +0100503 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000504 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700505 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000506}
507
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200508void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700509 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
510 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200511 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700512 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200513 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700514 }
515}
516
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200517void BaseChannel::ChannelWritable_n() {
518 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800519 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800521 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000522
Mirko Bonadei675513b2017-11-09 11:09:25 +0100523 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
524 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000525
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526 was_ever_writable_ = true;
527 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700528 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000529}
530
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200531void BaseChannel::ChannelNotWritable_n() {
532 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000533 if (!writable_)
534 return;
535
Mirko Bonadei675513b2017-11-09 11:09:25 +0100536 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000537 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700538 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000539}
540
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000541bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700542 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800543 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544}
545
Peter Boström0c4e06b2015-10-07 12:23:21 +0200546bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700547 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000548 return media_channel()->RemoveRecvStream(ssrc);
549}
550
551bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800552 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000553 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 // Check for streams that have been removed.
555 bool ret = true;
556 for (StreamParamsVec::const_iterator it = local_streams_.begin();
557 it != local_streams_.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700558 if (it->has_ssrcs() && !GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000560 std::ostringstream desc;
561 desc << "Failed to remove send stream with ssrc "
562 << it->first_ssrc() << ".";
563 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000564 ret = false;
565 }
566 }
567 }
568 // Check for new streams.
569 for (StreamParamsVec::const_iterator it = streams.begin();
570 it != streams.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700571 if (it->has_ssrcs() && !GetStreamBySsrc(local_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000572 if (media_channel()->AddSendStream(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100573 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000574 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000575 std::ostringstream desc;
576 desc << "Failed to add send stream ssrc: " << it->first_ssrc();
577 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 ret = false;
579 }
580 }
581 }
582 local_streams_ = streams;
583 return ret;
584}
585
586bool BaseChannel::UpdateRemoteStreams_w(
587 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800588 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000589 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000590 // Check for streams that have been removed.
591 bool ret = true;
592 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
593 it != remote_streams_.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700594 // If we no longer have an unsignaled stream, we would like to remove
595 // the unsignaled stream params that are cached.
596 if ((!it->has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
597 !GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000598 if (!RemoveRecvStream_w(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000599 std::ostringstream desc;
600 desc << "Failed to remove remote stream with ssrc "
601 << it->first_ssrc() << ".";
602 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000603 ret = false;
604 }
605 }
606 }
607 // Check for new streams.
608 for (StreamParamsVec::const_iterator it = streams.begin();
609 it != streams.end(); ++it) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700610 // We allow a StreamParams with an empty list of SSRCs, in which case the
611 // MediaChannel will cache the parameters and use them for any unsignaled
612 // stream received later.
613 if ((!it->has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
614 !GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000615 if (AddRecvStream_w(*it)) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700616 RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000617 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000618 std::ostringstream desc;
619 desc << "Failed to add remote stream ssrc: " << it->first_ssrc();
620 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000621 ret = false;
622 }
623 }
624 }
625 remote_streams_ = streams;
626 return ret;
627}
628
jbauch5869f502017-06-29 12:31:36 -0700629RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
630 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700631 RTC_DCHECK(rtp_transport_);
632 if (crypto_options_.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700633 RtpHeaderExtensions filtered;
634 auto pred = [](const webrtc::RtpExtension& extension) {
635 return !extension.encrypt;
636 };
637 std::copy_if(extensions.begin(), extensions.end(),
638 std::back_inserter(filtered), pred);
639 return filtered;
640 }
641
642 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
643}
644
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000645void BaseChannel::OnMessage(rtc::Message *pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100646 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000647 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200648 case MSG_SEND_RTP_PACKET:
649 case MSG_SEND_RTCP_PACKET: {
650 RTC_DCHECK(network_thread_->IsCurrent());
651 SendPacketMessageData* data =
652 static_cast<SendPacketMessageData*>(pmsg->pdata);
653 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
654 SendPacket(rtcp, &data->packet, data->options);
655 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000656 break;
657 }
658 case MSG_FIRSTPACKETRECEIVED: {
659 SignalFirstPacketReceived(this);
660 break;
661 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662 }
663}
664
zstein3dcf0e92017-06-01 13:22:42 -0700665void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huange830e682018-03-30 10:48:35 -0700666 bundle_filter_.AddPayloadType(payload_type);
zstein3dcf0e92017-06-01 13:22:42 -0700667}
668
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200669void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670 // Flush all remaining RTCP messages. This should only be called in
671 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200672 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000673 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200674 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
675 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700676 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
677 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678 }
679}
680
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800681void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200682 RTC_DCHECK(network_thread_->IsCurrent());
683 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700684 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200685 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
686}
687
688void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
689 RTC_DCHECK(worker_thread_->IsCurrent());
690 SignalSentPacket(sent_packet);
691}
692
693VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
694 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800695 rtc::Thread* signaling_thread,
Niels Möllerf120cba2018-01-30 09:33:03 +0100696 // TODO(nisse): Delete unused argument.
697 MediaEngineInterface* /* media_engine */,
Steve Anton8699a322017-11-06 15:53:33 -0800698 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700700 bool srtp_required,
701 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200702 : BaseChannel(worker_thread,
703 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800704 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800705 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700706 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700707 srtp_required,
708 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709
710VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800711 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000712 // this can't be done in the base class, since it calls a virtual
713 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700714 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715}
716
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700717void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200718 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700719 invoker_.AsyncInvoke<void>(
720 RTC_FROM_HERE, worker_thread_,
721 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200722}
723
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700724void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 // Render incoming data if we're the active call, and we have the local
726 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700727 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700728 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729
730 // Send outgoing data if we're the active call, we have the remote content,
731 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700732 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800733 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000734
Mirko Bonadei675513b2017-11-09 11:09:25 +0100735 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000736}
737
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800739 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000740 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100741 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800742 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100743 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000744
Steve Antonb1c1de12017-12-21 15:14:30 -0800745 RTC_DCHECK(content);
746 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000747 SafeSetError("Can't find audio content in local description.", error_desc);
748 return false;
749 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000750
Steve Antonb1c1de12017-12-21 15:14:30 -0800751 const AudioContentDescription* audio = content->as_audio();
752
jbauch5869f502017-06-29 12:31:36 -0700753 RtpHeaderExtensions rtp_header_extensions =
754 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
755
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700756 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700757 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700758 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -0700759 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700760 error_desc);
761 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000762 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700763 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700764 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700765 }
766 last_recv_params_ = recv_params;
767
768 // TODO(pthatcher): Move local streams into AudioSendParameters, and
769 // only give it to the media channel once we have a remote
770 // description too (without a remote description, we won't be able
771 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800772 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700773 SafeSetError("Failed to set local audio description streams.", error_desc);
774 return false;
775 }
776
777 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700778 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700779 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780}
781
782bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800783 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000784 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100785 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800786 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100787 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788
Steve Antonb1c1de12017-12-21 15:14:30 -0800789 RTC_DCHECK(content);
790 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000791 SafeSetError("Can't find audio content in remote description.", error_desc);
792 return false;
793 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794
Steve Antonb1c1de12017-12-21 15:14:30 -0800795 const AudioContentDescription* audio = content->as_audio();
796
jbauch5869f502017-06-29 12:31:36 -0700797 RtpHeaderExtensions rtp_header_extensions =
798 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
799
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700800 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700801 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
802 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700803 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700804
805 bool parameters_applied = media_channel()->SetSendParameters(send_params);
806 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700807 SafeSetError("Failed to set remote audio description send parameters.",
808 error_desc);
809 return false;
810 }
811 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700813 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
814 // and only give it to the media channel once we have a local
815 // description too (without a local description, we won't be able to
816 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800817 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700818 SafeSetError("Failed to set remote audio description streams.", error_desc);
819 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820 }
821
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700822 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700823 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700824 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825}
826
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200827VideoChannel::VideoChannel(rtc::Thread* worker_thread,
828 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800829 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800830 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000831 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700832 bool srtp_required,
833 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200834 : BaseChannel(worker_thread,
835 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800836 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800837 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700838 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700839 srtp_required,
840 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000842VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800843 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000844 // this can't be done in the base class, since it calls a virtual
845 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700846 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000847}
848
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700849void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000850 // Send outgoing data if we're the active call, we have the remote content,
851 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700852 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100854 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855 // TODO(gangji): Report error back to server.
856 }
857
Mirko Bonadei675513b2017-11-09 11:09:25 +0100858 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859}
860
stefanf79ade12017-06-02 06:44:03 -0700861void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
862 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
863 media_channel(), bwe_info));
864}
865
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800867 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000868 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100869 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800870 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100871 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872
Steve Antonb1c1de12017-12-21 15:14:30 -0800873 RTC_DCHECK(content);
874 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000875 SafeSetError("Can't find video content in local description.", error_desc);
876 return false;
877 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000878
Steve Antonb1c1de12017-12-21 15:14:30 -0800879 const VideoContentDescription* video = content->as_video();
880
jbauch5869f502017-06-29 12:31:36 -0700881 RtpHeaderExtensions rtp_header_extensions =
882 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
883
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700884 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700885 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700886 if (!media_channel()->SetRecvParameters(recv_params)) {
887 SafeSetError("Failed to set local video description recv parameters.",
888 error_desc);
889 return false;
890 }
891 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700892 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700893 }
894 last_recv_params_ = recv_params;
895
896 // TODO(pthatcher): Move local streams into VideoSendParameters, and
897 // only give it to the media channel once we have a remote
898 // description too (without a remote description, we won't be able
899 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800900 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700901 SafeSetError("Failed to set local video description streams.", error_desc);
902 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903 }
904
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700905 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700906 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700907 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908}
909
910bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800911 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000912 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100913 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800914 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100915 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916
Steve Antonb1c1de12017-12-21 15:14:30 -0800917 RTC_DCHECK(content);
918 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000919 SafeSetError("Can't find video content in remote description.", error_desc);
920 return false;
921 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922
Steve Antonb1c1de12017-12-21 15:14:30 -0800923 const VideoContentDescription* video = content->as_video();
924
jbauch5869f502017-06-29 12:31:36 -0700925 RtpHeaderExtensions rtp_header_extensions =
926 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
927
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700928 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700929 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
930 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700931 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -0800932 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700933 }
Steve Antonbb50ce52018-03-26 10:24:32 -0700934 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700935
936 bool parameters_applied = media_channel()->SetSendParameters(send_params);
937
938 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700939 SafeSetError("Failed to set remote video description send parameters.",
940 error_desc);
941 return false;
942 }
943 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700945 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
946 // and only give it to the media channel once we have a local
947 // description too (without a local description, we won't be able to
948 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800949 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700950 SafeSetError("Failed to set remote video description streams.", error_desc);
951 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700953 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700954 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700955 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956}
957
deadbeef953c2ce2017-01-09 14:53:41 -0800958RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
959 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800960 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800961 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -0800962 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700963 bool srtp_required,
964 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200965 : BaseChannel(worker_thread,
966 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800967 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800968 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700969 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700970 srtp_required,
971 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972
deadbeef953c2ce2017-01-09 14:53:41 -0800973RtpDataChannel::~RtpDataChannel() {
974 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000975 // this can't be done in the base class, since it calls a virtual
976 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700977 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978}
979
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800980void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
981 BaseChannel::Init_w(rtp_transport);
982 media_channel()->SignalDataReceived.connect(this,
983 &RtpDataChannel::OnDataReceived);
984 media_channel()->SignalReadyToSend.connect(
985 this, &RtpDataChannel::OnDataChannelReadyToSend);
986}
987
deadbeef953c2ce2017-01-09 14:53:41 -0800988bool RtpDataChannel::SendData(const SendDataParams& params,
989 const rtc::CopyOnWriteBuffer& payload,
990 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -0700991 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700992 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
993 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994}
995
deadbeef953c2ce2017-01-09 14:53:41 -0800996bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000997 const DataContentDescription* content,
998 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1000 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001001 // It's been set before, but doesn't match. That's bad.
1002 if (is_sctp) {
1003 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1004 error_desc);
1005 return false;
1006 }
1007 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001008}
1009
deadbeef953c2ce2017-01-09 14:53:41 -08001010bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001011 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001012 std::string* error_desc) {
1013 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001014 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001015 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016
Steve Antonb1c1de12017-12-21 15:14:30 -08001017 RTC_DCHECK(content);
1018 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001019 SafeSetError("Can't find data content in local description.", error_desc);
1020 return false;
1021 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022
Steve Antonb1c1de12017-12-21 15:14:30 -08001023 const DataContentDescription* data = content->as_data();
1024
deadbeef953c2ce2017-01-09 14:53:41 -08001025 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001026 return false;
1027 }
1028
jbauch5869f502017-06-29 12:31:36 -07001029 RtpHeaderExtensions rtp_header_extensions =
1030 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1031
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001032 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001033 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001034 if (!media_channel()->SetRecvParameters(recv_params)) {
1035 SafeSetError("Failed to set remote data description recv parameters.",
1036 error_desc);
1037 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001038 }
deadbeef953c2ce2017-01-09 14:53:41 -08001039 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001040 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001041 }
1042 last_recv_params_ = recv_params;
1043
1044 // TODO(pthatcher): Move local streams into DataSendParameters, and
1045 // only give it to the media channel once we have a remote
1046 // description too (without a remote description, we won't be able
1047 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001048 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001049 SafeSetError("Failed to set local data description streams.", error_desc);
1050 return false;
1051 }
1052
1053 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001054 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001055 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001056}
1057
deadbeef953c2ce2017-01-09 14:53:41 -08001058bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001059 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001060 std::string* error_desc) {
1061 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001062 RTC_DCHECK_RUN_ON(worker_thread());
1063 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001064
Steve Antonb1c1de12017-12-21 15:14:30 -08001065 RTC_DCHECK(content);
1066 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001067 SafeSetError("Can't find data content in remote description.", error_desc);
1068 return false;
1069 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001070
Steve Antonb1c1de12017-12-21 15:14:30 -08001071 const DataContentDescription* data = content->as_data();
1072
Zhi Huang801b8682017-11-15 11:36:43 -08001073 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1074 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001075 return true;
1076 }
1077
deadbeef953c2ce2017-01-09 14:53:41 -08001078 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001079 return false;
1080 }
1081
jbauch5869f502017-06-29 12:31:36 -07001082 RtpHeaderExtensions rtp_header_extensions =
1083 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1084
Mirko Bonadei675513b2017-11-09 11:09:25 +01001085 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001086 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001087 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
1088 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001089 if (!media_channel()->SetSendParameters(send_params)) {
1090 SafeSetError("Failed to set remote data description send parameters.",
1091 error_desc);
1092 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001093 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001094 last_send_params_ = send_params;
1095
1096 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1097 // and only give it to the media channel once we have a local
1098 // description too (without a local description, we won't be able to
1099 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001100 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001101 SafeSetError("Failed to set remote data description streams.",
1102 error_desc);
1103 return false;
1104 }
1105
1106 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001107 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001108 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001109}
1110
deadbeef953c2ce2017-01-09 14:53:41 -08001111void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001112 // Render incoming data if we're the active call, and we have the local
1113 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001114 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001115 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001116 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001117 }
1118
1119 // Send outgoing data if we're the active call, we have the remote content,
1120 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001121 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001122 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001123 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001124 }
1125
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001126 // Trigger SignalReadyToSendData asynchronously.
1127 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001128
Mirko Bonadei675513b2017-11-09 11:09:25 +01001129 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001130}
1131
deadbeef953c2ce2017-01-09 14:53:41 -08001132void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001133 switch (pmsg->message_id) {
1134 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001135 DataChannelReadyToSendMessageData* data =
1136 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001137 ready_to_send_data_ = data->data();
1138 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001139 delete data;
1140 break;
1141 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001142 case MSG_DATARECEIVED: {
1143 DataReceivedMessageData* data =
1144 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001145 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001146 delete data;
1147 break;
1148 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001149 default:
1150 BaseChannel::OnMessage(pmsg);
1151 break;
1152 }
1153}
1154
deadbeef953c2ce2017-01-09 14:53:41 -08001155void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1156 const char* data,
1157 size_t len) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001158 DataReceivedMessageData* msg = new DataReceivedMessageData(
1159 params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001160 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001161}
1162
deadbeef953c2ce2017-01-09 14:53:41 -08001163void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001164 // This is usded for congestion control to indicate that the stream is ready
1165 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1166 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001167 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001168 new DataChannelReadyToSendMessageData(writable));
1169}
1170
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001171} // namespace cricket