blob: 916c403a00f6f6c4777acc8934168d69c5b75984 [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
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070011#include "pc/channel.h"
12
jbauch5869f502017-06-29 12:31:36 -070013#include <iterator>
kwiberg0eb15ed2015-12-17 03:04:15 -080014#include <utility>
15
Steve Anton64b626b2019-01-28 17:25:26 -080016#include "absl/algorithm/container.h"
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"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070019#include "api/media_transport_config.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "media/base/media_constants.h"
21#include "media/base/rtp_utils.h"
Zhi Huang365381f2018-04-13 16:44:34 -070022#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070023#include "p2p/base/packet_transport_internal.h"
24#include "pc/channel_manager.h"
25#include "pc/rtp_media_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "rtc_base/bind.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/byte_order.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/copy_on_write_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "rtc_base/dscp.h"
31#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/network_route.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020033#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/trace_event.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035
36namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000037using rtc::Bind;
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080038using rtc::UniqueRandomIdGenerator;
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
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080048// Finds a stream based on target's Primary SSRC or RIDs.
49// This struct is used in BaseChannel::UpdateLocalStreams_w.
50struct StreamFinder {
51 explicit StreamFinder(const StreamParams* target) : target_(target) {
52 RTC_DCHECK(target);
53 }
54
55 bool operator()(const StreamParams& sp) const {
56 if (target_->has_ssrcs() && sp.has_ssrcs()) {
57 return sp.has_ssrc(target_->first_ssrc());
58 }
59
60 if (!target_->has_rids() && !sp.has_rids()) {
61 return false;
62 }
63
64 const std::vector<RidDescription>& target_rids = target_->rids();
65 const std::vector<RidDescription>& source_rids = sp.rids();
66 if (source_rids.size() != target_rids.size()) {
67 return false;
68 }
69
70 // Check that all RIDs match.
71 return std::equal(source_rids.begin(), source_rids.end(),
72 target_rids.begin(),
73 [](const RidDescription& lhs, const RidDescription& rhs) {
74 return lhs.rid == rhs.rid;
75 });
76 }
77
78 const StreamParams* target_;
79};
80
deadbeef2d110be2016-01-13 12:00:26 -080081} // namespace
82
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083enum {
Steve Anton0807d152018-03-05 11:23:09 -080084 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020085 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000087 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089};
90
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000091static void SafeSetError(const std::string& message, std::string* error_desc) {
92 if (error_desc) {
93 *error_desc = message;
94 }
95}
96
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070097template <class Codec>
Steve Antonadd7ef92019-07-30 18:04:40 -070098std::vector<Codec> SanitizeCodecList(const std::vector<Codec>& codecs) {
99 std::vector<Codec> sanitized;
100 for (const Codec& codec : codecs) {
101 if (absl::c_any_of(sanitized, [&](const Codec& other) {
102 return codec.Matches(other);
103 })) {
104 continue;
105 }
106 sanitized.push_back(codec);
107 }
108 return sanitized;
109}
110
111template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700112void RtpParametersFromMediaDescription(
113 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -0700114 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700115 RtpParameters<Codec>* params) {
116 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 11:36:43 -0800117 // a description without codecs. Currently the ORTC implementation is relying
118 // on this.
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700119 if (desc->has_codecs()) {
Steve Antonadd7ef92019-07-30 18:04:40 -0700120 params->codecs = SanitizeCodecList(desc->codecs());
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700121 }
122 // TODO(pthatcher): See if we really need
123 // rtp_header_extensions_set() and remove it if we don't.
124 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -0700125 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700126 }
deadbeef13871492015-12-09 12:37:51 -0800127 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Sebastian Janssone1795f42019-07-24 11:38:03 +0200128 params->rtcp.remote_estimate = desc->remote_estimate();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700129}
130
nisse05103312016-03-16 02:22:50 -0700131template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700132void RtpSendParametersFromMediaDescription(
133 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -0700134 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 02:22:50 -0700135 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 12:31:36 -0700136 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700137 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 11:22:05 +0100138 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700139}
140
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200141BaseChannel::BaseChannel(rtc::Thread* worker_thread,
142 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800143 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800144 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700145 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700146 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800147 webrtc::CryptoOptions crypto_options,
148 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200149 : worker_thread_(worker_thread),
150 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800151 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800153 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700154 crypto_options_(crypto_options),
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800155 media_channel_(std::move(media_channel)),
156 ssrc_generator_(ssrc_generator) {
Steve Anton8699a322017-11-06 15:53:33 -0800157 RTC_DCHECK_RUN_ON(worker_thread_);
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800158 RTC_DCHECK(ssrc_generator_);
Zhi Huang365381f2018-04-13 16:44:34 -0700159 demuxer_criteria_.mid = content_name;
Mirko Bonadei675513b2017-11-09 11:09:25 +0100160 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161}
162
163BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800164 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800165 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800166
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700167 if (media_transport_config_.media_transport) {
168 media_transport_config_.media_transport->RemoveNetworkChangeCallback(this);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800169 }
170
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200171 // Eats any outstanding messages or packets.
172 worker_thread_->Clear(&invoker_);
173 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 // We must destroy the media channel before the transport channel, otherwise
175 // the media channel may try to send on the dead transport channel. NULLing
176 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800177 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100178 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200179}
180
Zhi Huang365381f2018-04-13 16:44:34 -0700181bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800182 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700183 if (!RegisterRtpDemuxerSink()) {
184 return false;
185 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800186 rtp_transport_->SignalReadyToSend.connect(
187 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang365381f2018-04-13 16:44:34 -0700188 rtp_transport_->SignalRtcpPacketReceived.connect(
189 this, &BaseChannel::OnRtcpPacketReceived);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800190
191 // If media transport is used, it's responsible for providing network
192 // route changed callbacks.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700193 if (!media_transport_config_.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800194 rtp_transport_->SignalNetworkRouteChanged.connect(
195 this, &BaseChannel::OnNetworkRouteChanged);
196 }
197 // TODO(bugs.webrtc.org/9719): Media transport should also be used to provide
198 // 'writable' state here.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800199 rtp_transport_->SignalWritableState.connect(this,
200 &BaseChannel::OnWritableState);
201 rtp_transport_->SignalSentPacket.connect(this,
202 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 16:44:34 -0700203 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800204}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200205
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800206void BaseChannel::DisconnectFromRtpTransport() {
207 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700208 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800209 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang365381f2018-04-13 16:44:34 -0700210 rtp_transport_->SignalRtcpPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800211 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
212 rtp_transport_->SignalWritableState.disconnect(this);
213 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200214}
215
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700216void BaseChannel::Init_w(
217 webrtc::RtpTransportInternal* rtp_transport,
218 const webrtc::MediaTransportConfig& media_transport_config) {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800219 RTC_DCHECK_RUN_ON(worker_thread_);
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700220 media_transport_config_ = media_transport_config;
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800221
Zhi Huang365381f2018-04-13 16:44:34 -0700222 network_thread_->Invoke<void>(
223 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800224
225 // Both RTP and RTCP channels should be set, we can call SetInterface on
226 // the media channel and it can set network options.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700227 media_channel_->SetInterface(this, media_transport_config);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800228
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700229 RTC_LOG(LS_INFO) << "BaseChannel::Init_w, media_transport_config="
230 << media_transport_config.DebugString();
231 if (media_transport_config_.media_transport) {
232 media_transport_config_.media_transport->AddNetworkChangeCallback(this);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800233 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200234}
235
wu@webrtc.org78187522013-10-07 23:32:02 +0000236void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200237 RTC_DCHECK(worker_thread_->IsCurrent());
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700238 media_channel_->SetInterface(/*iface=*/nullptr,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700239 webrtc::MediaTransportConfig());
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200240 // Packets arrive on the network thread, processing packets calls virtual
241 // functions, so need to stop this process in Deinit that is called in
242 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800243 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000244 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700245
Zhi Huange830e682018-03-30 10:48:35 -0700246 if (rtp_transport_) {
247 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000248 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800249 // Clear pending read packets/messages.
250 network_thread_->Clear(&invoker_);
251 network_thread_->Clear(this);
252 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000253}
254
Zhi Huang365381f2018-04-13 16:44:34 -0700255bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
256 if (rtp_transport == rtp_transport_) {
257 return true;
258 }
259
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800260 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 16:44:34 -0700261 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
262 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800263 });
264 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000265
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800266 if (rtp_transport_) {
267 DisconnectFromRtpTransport();
268 }
Zhi Huange830e682018-03-30 10:48:35 -0700269
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800270 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700271 if (rtp_transport_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700272 transport_name_ = rtp_transport_->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800273
Zhi Huang365381f2018-04-13 16:44:34 -0700274 if (!ConnectToRtpTransport()) {
275 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport.";
276 return false;
277 }
Zhi Huange830e682018-03-30 10:48:35 -0700278 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
279 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800280
Zhi Huange830e682018-03-30 10:48:35 -0700281 // Set the cached socket options.
282 for (const auto& pair : socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700283 rtp_transport_->SetRtpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700284 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700285 if (!rtp_transport_->rtcp_mux_enabled()) {
Zhi Huange830e682018-03-30 10:48:35 -0700286 for (const auto& pair : rtcp_socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700287 rtp_transport_->SetRtcpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700288 }
289 }
guoweis46383312015-12-17 16:45:59 -0800290 }
Zhi Huang365381f2018-04-13 16:44:34 -0700291 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000292}
293
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000294bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700295 worker_thread_->Invoke<void>(
296 RTC_FROM_HERE,
297 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
298 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299 return true;
300}
301
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000302bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800303 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000304 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100305 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700306 return InvokeOnWorker<bool>(
307 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800308 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000309}
310
311bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800312 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000313 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100314 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700315 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800316 RTC_FROM_HERE,
317 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318}
319
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700320bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800322 return enabled() &&
323 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324}
325
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700326bool BaseChannel::IsReadyToSendMedia_w() const {
327 // Need to access some state updated on the network thread.
328 return network_thread_->Invoke<bool>(
329 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
330}
331
332bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 // Send outgoing data if we are enabled, have local and remote content,
334 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800335 return enabled() &&
336 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
337 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 16:44:34 -0700338 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339}
340
jbaucheec21bd2016-03-20 06:15:43 -0700341bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700342 const rtc::PacketOptions& options) {
343 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344}
345
jbaucheec21bd2016-03-20 06:15:43 -0700346bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700347 const rtc::PacketOptions& options) {
348 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349}
350
Yves Gerey665174f2018-06-19 15:03:05 +0200351int BaseChannel::SetOption(SocketType type,
352 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000353 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200354 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700355 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200356}
357
358int BaseChannel::SetOption_n(SocketType type,
359 rtc::Socket::Option opt,
360 int value) {
361 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700362 RTC_DCHECK(rtp_transport_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000364 case ST_RTP:
deadbeefcbecd352015-09-23 11:50:27 -0700365 socket_options_.push_back(
366 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700367 return rtp_transport_->SetRtpOption(opt, value);
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000368 case ST_RTCP:
deadbeefcbecd352015-09-23 11:50:27 -0700369 rtcp_socket_options_.push_back(
370 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700371 return rtp_transport_->SetRtcpOption(opt, value);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000372 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700373 return -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374}
375
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800376void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200377 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800378 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800379 ChannelWritable_n();
380 } else {
381 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800382 }
383}
384
Zhi Huang942bc2e2017-11-13 13:26:07 -0800385void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200386 absl::optional<rtc::NetworkRoute> network_route) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800387 RTC_LOG(LS_INFO) << "Network route was changed.";
388
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200389 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800390 rtc::NetworkRoute new_route;
391 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800392 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000393 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800394 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
395 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
396 // work correctly. Intentionally leave it broken to simplify the code and
397 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800398 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800399 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800400 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700401}
402
zstein56162b92017-04-24 16:54:35 -0700403void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800404 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
405 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000406}
407
stefanc1aeaf02015-10-15 07:26:07 -0700408bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700409 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700410 const rtc::PacketOptions& options) {
Amit Hilbuchedd20542019-03-18 12:33:43 -0700411 // Until all the code is migrated to use RtpPacketType instead of bool.
412 RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200413 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
414 // If the thread is not our network thread, we will post to our network
415 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000416 // synchronize access to all the pieces of the send path, including
417 // SRTP and the inner workings of the transport channels.
418 // The only downside is that we can't return a proper failure code if
419 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200420 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000421 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200422 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
423 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800424 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700425 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700426 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000427 return true;
428 }
Zhi Huange830e682018-03-30 10:48:35 -0700429
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200430 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431
432 // Now that we are on the correct thread, ensure we have a place to send this
433 // packet before doing anything. (We might get RTCP packets that we don't
434 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
435 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700436 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000437 return false;
438 }
439
440 // Protect ourselves against crazy data.
Amit Hilbuchedd20542019-03-18 12:33:43 -0700441 if (!IsValidRtpPacketSize(packet_type, packet->size())) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100442 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
Amit Hilbuchedd20542019-03-18 12:33:43 -0700443 << RtpPacketTypeToString(packet_type)
Mirko Bonadei675513b2017-11-09 11:09:25 +0100444 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000445 return false;
446 }
447
Zhi Huangcf990f52017-09-22 12:12:30 -0700448 if (!srtp_active()) {
449 if (srtp_required_) {
450 // The audio/video engines may attempt to send RTCP packets as soon as the
451 // streams are created, so don't treat this as an error for RTCP.
452 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
453 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000454 return false;
455 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700456 // However, there shouldn't be any RTP packets sent before SRTP is set up
457 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100458 RTC_LOG(LS_ERROR)
459 << "Can't send outgoing RTP packet when SRTP is inactive"
460 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700461 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800462 return false;
463 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800464
465 std::string packet_type = rtcp ? "RTCP" : "RTP";
466 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
467 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000468 }
Zhi Huange830e682018-03-30 10:48:35 -0700469
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000470 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800471 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
472 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000473}
474
Zhi Huang365381f2018-04-13 16:44:34 -0700475void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Niels Möller29e13fd2018-12-17 12:35:30 +0100476 // Take packet time from the |parsed_packet|.
477 // RtpPacketReceived.arrival_time_ms = (timestamp_us + 500) / 1000;
Niels Möllere6933812018-11-05 13:01:41 +0100478 int64_t timestamp_us = -1;
Zhi Huang365381f2018-04-13 16:44:34 -0700479 if (parsed_packet.arrival_time_ms() > 0) {
Niels Möllere6933812018-11-05 13:01:41 +0100480 timestamp_us = parsed_packet.arrival_time_ms() * 1000;
Zhi Huang365381f2018-04-13 16:44:34 -0700481 }
Zhi Huang365381f2018-04-13 16:44:34 -0700482
Niels Möllere6933812018-11-05 13:01:41 +0100483 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), timestamp_us);
Zhi Huang365381f2018-04-13 16:44:34 -0700484}
485
486void BaseChannel::UpdateRtpHeaderExtensionMap(
487 const RtpHeaderExtensions& header_extensions) {
488 RTC_DCHECK(rtp_transport_);
489 // Update the header extension map on network thread in case there is data
490 // race.
491 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
492 // be accessed from different threads.
493 //
494 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
495 // extension maps are not merged when BUNDLE is enabled. This is fine because
496 // the ID for MID should be consistent among all the RTP transports.
497 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
498 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
499 });
500}
501
502bool BaseChannel::RegisterRtpDemuxerSink() {
503 RTC_DCHECK(rtp_transport_);
504 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
505 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
506 });
507}
508
509void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
Niels Möllere6933812018-11-05 13:01:41 +0100510 int64_t packet_time_us) {
511 OnPacketReceived(/*rtcp=*/true, *packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000512}
513
zstein3dcf0e92017-06-01 13:22:42 -0700514void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang365381f2018-04-13 16:44:34 -0700515 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 13:01:41 +0100516 int64_t packet_time_us) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000517 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000518 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700519 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 }
521
Zhi Huangcf990f52017-09-22 12:12:30 -0700522 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000523 // Our session description indicates that SRTP is required, but we got a
524 // packet before our SRTP filter is active. This means either that
525 // a) we got SRTP packets before we received the SDES keys, in which case
526 // we can't decrypt it anyway, or
527 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800528 // transports, so we haven't yet extracted keys, even if DTLS did
529 // complete on the transport that the packets are being sent on. It's
530 // really good practice to wait for both RTP and RTCP to be good to go
531 // before sending media, to prevent weird failure modes, so it's fine
532 // for us to just eat packets here. This is all sidestepped if RTCP mux
533 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100534 RTC_LOG(LS_WARNING)
Amit Hilbuchedd20542019-03-18 12:33:43 -0700535 << "Can't process incoming "
536 << RtpPacketTypeToString(rtcp ? RtpPacketType::kRtcp
537 : RtpPacketType::kRtp)
Mirko Bonadei675513b2017-11-09 11:09:25 +0100538 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000539 return;
540 }
541
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200542 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700543 RTC_FROM_HERE, worker_thread_,
Niels Möllere6933812018-11-05 13:01:41 +0100544 Bind(&BaseChannel::ProcessPacket, this, rtcp, packet, packet_time_us));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200545}
546
zstein3dcf0e92017-06-01 13:22:42 -0700547void BaseChannel::ProcessPacket(bool rtcp,
548 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 13:01:41 +0100549 int64_t packet_time_us) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200550 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700551
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200552 if (rtcp) {
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700553 media_channel_->OnRtcpReceived(packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 } else {
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700555 media_channel_->OnPacketReceived(packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000556 }
557}
558
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700560 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000561 if (enabled_)
562 return;
563
Mirko Bonadei675513b2017-11-09 11:09:25 +0100564 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700566 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567}
568
569void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700570 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571 if (!enabled_)
572 return;
573
Mirko Bonadei675513b2017-11-09 11:09:25 +0100574 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000575 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700576 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577}
578
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200579void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700580 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
581 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200582 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700583 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200584 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700585 }
586}
587
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200588void BaseChannel::ChannelWritable_n() {
589 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800590 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000591 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800592 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000593
Mirko Bonadei675513b2017-11-09 11:09:25 +0100594 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
595 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000596
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000597 was_ever_writable_ = true;
598 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700599 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000600}
601
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200602void BaseChannel::ChannelNotWritable_n() {
603 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000604 if (!writable_)
605 return;
606
Mirko Bonadei675513b2017-11-09 11:09:25 +0100607 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000608 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700609 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000610}
611
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000612bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700613 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800614 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000615}
616
Peter Boström0c4e06b2015-10-07 12:23:21 +0200617bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700618 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000619 return media_channel()->RemoveRecvStream(ssrc);
620}
621
622bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800623 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000624 std::string* error_desc) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800625 // In the case of RIDs (where SSRCs are not negotiated), this method will
626 // generate an SSRC for each layer in StreamParams. That representation will
627 // be stored internally in |local_streams_|.
628 // In subsequent offers, the same stream can appear in |streams| again
629 // (without the SSRCs), so it should be looked up using RIDs (if available)
630 // and then by primary SSRC.
631 // In both scenarios, it is safe to assume that the media channel will be
632 // created with a StreamParams object with SSRCs. However, it is not safe to
633 // assume that |local_streams_| will always have SSRCs as there are scenarios
634 // in which niether SSRCs or RIDs are negotiated.
635
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000636 // Check for streams that have been removed.
637 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800638 for (const StreamParams& old_stream : local_streams_) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800639 if (!old_stream.has_ssrcs() ||
640 GetStream(streams, StreamFinder(&old_stream))) {
641 continue;
642 }
643 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
644 rtc::StringBuilder desc;
645 desc << "Failed to remove send stream with ssrc "
646 << old_stream.first_ssrc() << ".";
647 SafeSetError(desc.str(), error_desc);
648 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649 }
650 }
651 // Check for new streams.
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800652 std::vector<StreamParams> all_streams;
653 for (const StreamParams& stream : streams) {
654 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
655 if (existing) {
656 // Parameters cannot change for an existing stream.
657 all_streams.push_back(*existing);
658 continue;
659 }
660
661 all_streams.push_back(stream);
662 StreamParams& new_stream = all_streams.back();
663
664 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
665 continue;
666 }
667
668 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
669 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
670 rtc::StringBuilder desc;
671 desc << "Failed to add send stream: " << new_stream.first_ssrc()
672 << ". Stream has both SSRCs and RIDs.";
673 SafeSetError(desc.str(), error_desc);
674 ret = false;
675 continue;
676 }
677
678 // At this point we use the legacy simulcast group in StreamParams to
679 // indicate that we want multiple layers to the media channel.
680 if (!new_stream.has_ssrcs()) {
681 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
682 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
683 /* flex_fec = */ false, ssrc_generator_);
684 }
685
686 if (media_channel()->AddSendStream(new_stream)) {
687 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0];
688 } else {
689 rtc::StringBuilder desc;
690 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc();
691 SafeSetError(desc.str(), error_desc);
692 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000693 }
694 }
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800695 local_streams_ = all_streams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000696 return ret;
697}
698
699bool BaseChannel::UpdateRemoteStreams_w(
700 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800701 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000702 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703 // Check for streams that have been removed.
704 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800705 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700706 // If we no longer have an unsignaled stream, we would like to remove
707 // the unsignaled stream params that are cached.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800708 if ((!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
709 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
710 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
711 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc();
Zhi Huang365381f2018-04-13 16:44:34 -0700712 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200713 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800714 desc << "Failed to remove remote stream with ssrc "
715 << old_stream.first_ssrc() << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000716 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717 ret = false;
718 }
719 }
720 }
Zhi Huang365381f2018-04-13 16:44:34 -0700721 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800723 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700724 // We allow a StreamParams with an empty list of SSRCs, in which case the
725 // MediaChannel will cache the parameters and use them for any unsignaled
726 // stream received later.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800727 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
728 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
729 if (AddRecvStream_w(new_stream)) {
730 RTC_LOG(LS_INFO) << "Add remote ssrc: " << new_stream.first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200732 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800733 desc << "Failed to add remote stream ssrc: " << new_stream.first_ssrc();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000734 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000735 ret = false;
736 }
737 }
Zhi Huang365381f2018-04-13 16:44:34 -0700738 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800739 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
740 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741 }
Zhi Huang365381f2018-04-13 16:44:34 -0700742 // Re-register the sink to update the receiving ssrcs.
743 RegisterRtpDemuxerSink();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000744 remote_streams_ = streams;
745 return ret;
746}
747
jbauch5869f502017-06-29 12:31:36 -0700748RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
749 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700750 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700751 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700752 RtpHeaderExtensions filtered;
Steve Anton64b626b2019-01-28 17:25:26 -0800753 absl::c_copy_if(extensions, std::back_inserter(filtered),
754 [](const webrtc::RtpExtension& extension) {
755 return !extension.encrypt;
756 });
jbauch5869f502017-06-29 12:31:36 -0700757 return filtered;
758 }
759
760 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
761}
762
Yves Gerey665174f2018-06-19 15:03:05 +0200763void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100764 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200766 case MSG_SEND_RTP_PACKET:
767 case MSG_SEND_RTCP_PACKET: {
768 RTC_DCHECK(network_thread_->IsCurrent());
769 SendPacketMessageData* data =
770 static_cast<SendPacketMessageData*>(pmsg->pdata);
771 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
772 SendPacket(rtcp, &data->packet, data->options);
773 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000774 break;
775 }
776 case MSG_FIRSTPACKETRECEIVED: {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800777 SignalFirstPacketReceived_(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000778 break;
779 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780 }
781}
782
zstein3dcf0e92017-06-01 13:22:42 -0700783void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 16:44:34 -0700784 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -0700785}
786
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200787void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788 // Flush all remaining RTCP messages. This should only be called in
789 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200790 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000791 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200792 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
793 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700794 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
795 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796 }
797}
798
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800799void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200800 RTC_DCHECK(network_thread_->IsCurrent());
801 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700802 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200803 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
804}
805
806void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
807 RTC_DCHECK(worker_thread_->IsCurrent());
808 SignalSentPacket(sent_packet);
809}
810
811VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
812 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800813 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800814 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000815 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700816 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800817 webrtc::CryptoOptions crypto_options,
818 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200819 : BaseChannel(worker_thread,
820 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800821 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800822 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700823 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700824 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800825 crypto_options,
826 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827
828VoiceChannel::~VoiceChannel() {
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -0800829 if (media_transport()) {
830 media_transport()->SetFirstAudioPacketReceivedObserver(nullptr);
831 }
Peter Boströmca8b4042016-03-08 14:24:13 -0800832 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000833 // this can't be done in the base class, since it calls a virtual
834 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700835 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836}
837
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700838void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200839 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700840 invoker_.AsyncInvoke<void>(
841 RTC_FROM_HERE, worker_thread_,
842 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200843}
844
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800845void BaseChannel::OnNetworkRouteChanged(
846 const rtc::NetworkRoute& network_route) {
847 OnNetworkRouteChanged(absl::make_optional(network_route));
848}
849
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700850void VoiceChannel::Init_w(
851 webrtc::RtpTransportInternal* rtp_transport,
852 const webrtc::MediaTransportConfig& media_transport_config) {
853 BaseChannel::Init_w(rtp_transport, media_transport_config);
854 if (media_transport_config.media_transport) {
855 media_transport_config.media_transport->SetFirstAudioPacketReceivedObserver(
856 this);
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -0800857 }
858}
859
860void VoiceChannel::OnFirstAudioPacketReceived(int64_t channel_id) {
861 has_received_packet_ = true;
862 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
863}
864
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700865void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866 // Render incoming data if we're the active call, and we have the local
867 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700868 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700869 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000870
871 // Send outgoing data if we're the active call, we have the remote content,
872 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700873 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800874 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875
Mirko Bonadei675513b2017-11-09 11:09:25 +0100876 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877}
878
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000879bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800880 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000881 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100882 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800883 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100884 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885
Steve Antonb1c1de12017-12-21 15:14:30 -0800886 RTC_DCHECK(content);
887 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000888 SafeSetError("Can't find audio content in local description.", error_desc);
889 return false;
890 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891
Steve Antonb1c1de12017-12-21 15:14:30 -0800892 const AudioContentDescription* audio = content->as_audio();
893
jbauch5869f502017-06-29 12:31:36 -0700894 RtpHeaderExtensions rtp_header_extensions =
895 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700896 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100897 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700898
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700899 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700900 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700901 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -0700902 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700903 error_desc);
904 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700906 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700907 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700908 }
Zhi Huang365381f2018-04-13 16:44:34 -0700909 // Need to re-register the sink to update the handled payload.
910 if (!RegisterRtpDemuxerSink()) {
911 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
912 return false;
913 }
914
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700915 last_recv_params_ = recv_params;
916
917 // TODO(pthatcher): Move local streams into AudioSendParameters, and
918 // only give it to the media channel once we have a remote
919 // description too (without a remote description, we won't be able
920 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800921 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700922 SafeSetError("Failed to set local audio description streams.", error_desc);
923 return false;
924 }
925
926 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700927 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700928 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000929}
930
931bool VoiceChannel::SetRemoteContent_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", "VoiceChannel::SetRemoteContent_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 remote voice 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 audio content in remote 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 AudioContentDescription* audio = content->as_audio();
945
jbauch5869f502017-06-29 12:31:36 -0700946 RtpHeaderExtensions rtp_header_extensions =
947 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
948
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700949 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700950 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +0200951 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700952 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700953
954 bool parameters_applied = media_channel()->SetSendParameters(send_params);
955 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700956 SafeSetError("Failed to set remote audio description send parameters.",
957 error_desc);
958 return false;
959 }
960 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700962 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
963 // and only give it to the media channel once we have a local
964 // description too (without a local description, we won't be able to
965 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800966 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700967 SafeSetError("Failed to set remote audio description streams.", error_desc);
968 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969 }
970
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700971 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700972 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700973 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974}
975
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200976VideoChannel::VideoChannel(rtc::Thread* worker_thread,
977 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800978 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800979 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700981 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800982 webrtc::CryptoOptions crypto_options,
983 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200984 : BaseChannel(worker_thread,
985 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800986 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800987 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700988 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700989 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800990 crypto_options,
991 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000993VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800994 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995 // this can't be done in the base class, since it calls a virtual
996 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700997 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998}
999
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001000void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001 // Send outgoing data if we're the active call, we have the remote content,
1002 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001003 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001005 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001006 // TODO(gangji): Report error back to server.
1007 }
1008
Mirko Bonadei675513b2017-11-09 11:09:25 +01001009 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010}
1011
stefanf79ade12017-06-02 06:44:03 -07001012void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
1013 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
1014 media_channel(), bwe_info));
1015}
1016
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001018 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001019 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001020 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001021 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001022 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023
Steve Antonb1c1de12017-12-21 15:14:30 -08001024 RTC_DCHECK(content);
1025 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001026 SafeSetError("Can't find video content in local description.", error_desc);
1027 return false;
1028 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001029
Steve Antonb1c1de12017-12-21 15:14:30 -08001030 const VideoContentDescription* video = content->as_video();
1031
jbauch5869f502017-06-29 12:31:36 -07001032 RtpHeaderExtensions rtp_header_extensions =
1033 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -07001034 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +01001035 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -07001036
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001037 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001038 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001039
1040 VideoSendParameters send_params = last_send_params_;
1041 bool needs_send_params_update = false;
1042 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
1043 for (auto& send_codec : send_params.codecs) {
1044 auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
1045 if (recv_codec) {
1046 if (!recv_codec->packetization && send_codec.packetization) {
1047 send_codec.packetization.reset();
1048 needs_send_params_update = true;
1049 } else if (recv_codec->packetization != send_codec.packetization) {
1050 SafeSetError(
1051 "Failed to set local answer due to invalid codec packetization.",
1052 error_desc);
1053 return false;
1054 }
1055 }
1056 }
1057 }
1058
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001059 if (!media_channel()->SetRecvParameters(recv_params)) {
1060 SafeSetError("Failed to set local video description recv parameters.",
1061 error_desc);
1062 return false;
1063 }
1064 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001065 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001066 }
Zhi Huang365381f2018-04-13 16:44:34 -07001067 // Need to re-register the sink to update the handled payload.
1068 if (!RegisterRtpDemuxerSink()) {
1069 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
1070 return false;
1071 }
1072
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001073 last_recv_params_ = recv_params;
1074
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001075 if (needs_send_params_update) {
1076 if (!media_channel()->SetSendParameters(send_params)) {
1077 SafeSetError("Failed to set send parameters.", error_desc);
1078 return false;
1079 }
1080 last_send_params_ = send_params;
1081 }
1082
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001083 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1084 // only give it to the media channel once we have a remote
1085 // description too (without a remote description, we won't be able
1086 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001087 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001088 SafeSetError("Failed to set local video description streams.", error_desc);
1089 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001090 }
1091
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001092 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001093 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001094 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001095}
1096
1097bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001098 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001099 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001100 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001101 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001102 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001103
Steve Antonb1c1de12017-12-21 15:14:30 -08001104 RTC_DCHECK(content);
1105 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001106 SafeSetError("Can't find video content in remote description.", error_desc);
1107 return false;
1108 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001109
Steve Antonb1c1de12017-12-21 15:14:30 -08001110 const VideoContentDescription* video = content->as_video();
1111
jbauch5869f502017-06-29 12:31:36 -07001112 RtpHeaderExtensions rtp_header_extensions =
1113 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1114
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001115 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001116 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001117 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001118 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001119 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001120 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001121 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001122
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001123 VideoRecvParameters recv_params = last_recv_params_;
1124 bool needs_recv_params_update = false;
1125 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
1126 for (auto& recv_codec : recv_params.codecs) {
1127 auto* send_codec = FindMatchingCodec(send_params.codecs, recv_codec);
1128 if (send_codec) {
1129 if (!send_codec->packetization && recv_codec.packetization) {
1130 recv_codec.packetization.reset();
1131 needs_recv_params_update = true;
1132 } else if (send_codec->packetization != recv_codec.packetization) {
1133 SafeSetError(
1134 "Failed to set remote answer due to invalid codec packetization.",
1135 error_desc);
1136 return false;
1137 }
1138 }
1139 }
1140 }
skvladdc1c62c2016-03-16 19:07:43 -07001141
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001142 if (!media_channel()->SetSendParameters(send_params)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001143 SafeSetError("Failed to set remote video description send parameters.",
1144 error_desc);
1145 return false;
1146 }
1147 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001148
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001149 if (needs_recv_params_update) {
1150 if (!media_channel()->SetRecvParameters(recv_params)) {
1151 SafeSetError("Failed to set recv parameters.", error_desc);
1152 return false;
1153 }
1154 last_recv_params_ = recv_params;
1155 }
1156
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001157 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1158 // and only give it to the media channel once we have a local
1159 // description too (without a local description, we won't be able to
1160 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001161 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001162 SafeSetError("Failed to set remote video description streams.", error_desc);
1163 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001164 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001165 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001166 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001167 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001168}
1169
deadbeef953c2ce2017-01-09 14:53:41 -08001170RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1171 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001172 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001173 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001174 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001175 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001176 webrtc::CryptoOptions crypto_options,
1177 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001178 : BaseChannel(worker_thread,
1179 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001180 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001181 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001182 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001183 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001184 crypto_options,
1185 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001186
deadbeef953c2ce2017-01-09 14:53:41 -08001187RtpDataChannel::~RtpDataChannel() {
1188 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001189 // this can't be done in the base class, since it calls a virtual
1190 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001191 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001192}
1193
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001194void RtpDataChannel::Init_w(
1195 webrtc::RtpTransportInternal* rtp_transport,
1196 const webrtc::MediaTransportConfig& media_transport_config) {
1197 BaseChannel::Init_w(rtp_transport, media_transport_config);
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001198 media_channel()->SignalDataReceived.connect(this,
1199 &RtpDataChannel::OnDataReceived);
1200 media_channel()->SignalReadyToSend.connect(
1201 this, &RtpDataChannel::OnDataChannelReadyToSend);
1202}
1203
deadbeef953c2ce2017-01-09 14:53:41 -08001204bool RtpDataChannel::SendData(const SendDataParams& params,
1205 const rtc::CopyOnWriteBuffer& payload,
1206 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001207 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001208 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1209 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001210}
1211
deadbeef953c2ce2017-01-09 14:53:41 -08001212bool RtpDataChannel::CheckDataChannelTypeFromContent(
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02001213 const RtpDataContentDescription* content,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001214 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001215 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1216 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001217 // It's been set before, but doesn't match. That's bad.
1218 if (is_sctp) {
1219 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1220 error_desc);
1221 return false;
1222 }
1223 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001224}
1225
deadbeef953c2ce2017-01-09 14:53:41 -08001226bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001227 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001228 std::string* error_desc) {
1229 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001230 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001231 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001232
Steve Antonb1c1de12017-12-21 15:14:30 -08001233 RTC_DCHECK(content);
1234 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001235 SafeSetError("Can't find data content in local description.", error_desc);
1236 return false;
1237 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001238
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02001239 const RtpDataContentDescription* data = content->as_rtp_data();
Steve Antonb1c1de12017-12-21 15:14:30 -08001240
deadbeef953c2ce2017-01-09 14:53:41 -08001241 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001242 return false;
1243 }
1244
jbauch5869f502017-06-29 12:31:36 -07001245 RtpHeaderExtensions rtp_header_extensions =
1246 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1247
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001248 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001249 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001250 if (!media_channel()->SetRecvParameters(recv_params)) {
1251 SafeSetError("Failed to set remote data description recv parameters.",
1252 error_desc);
1253 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001254 }
deadbeef953c2ce2017-01-09 14:53:41 -08001255 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001256 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001257 }
Zhi Huang365381f2018-04-13 16:44:34 -07001258 // Need to re-register the sink to update the handled payload.
1259 if (!RegisterRtpDemuxerSink()) {
1260 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1261 return false;
1262 }
1263
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001264 last_recv_params_ = recv_params;
1265
1266 // TODO(pthatcher): Move local streams into DataSendParameters, and
1267 // only give it to the media channel once we have a remote
1268 // description too (without a remote description, we won't be able
1269 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001270 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001271 SafeSetError("Failed to set local data description streams.", error_desc);
1272 return false;
1273 }
1274
1275 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001276 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001277 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001278}
1279
deadbeef953c2ce2017-01-09 14:53:41 -08001280bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001281 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001282 std::string* error_desc) {
1283 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001284 RTC_DCHECK_RUN_ON(worker_thread());
1285 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001286
Steve Antonb1c1de12017-12-21 15:14:30 -08001287 RTC_DCHECK(content);
1288 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001289 SafeSetError("Can't find data content in remote description.", error_desc);
1290 return false;
1291 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001292
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02001293 const RtpDataContentDescription* data = content->as_rtp_data();
1294
1295 if (!data) {
1296 RTC_LOG(LS_INFO) << "Accepting and ignoring non-RTP content description";
1297 return true;
1298 }
Steve Antonb1c1de12017-12-21 15:14:30 -08001299
Zhi Huang801b8682017-11-15 11:36:43 -08001300 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1301 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001302 return true;
1303 }
1304
deadbeef953c2ce2017-01-09 14:53:41 -08001305 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001306 return false;
1307 }
1308
jbauch5869f502017-06-29 12:31:36 -07001309 RtpHeaderExtensions rtp_header_extensions =
1310 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1311
Mirko Bonadei675513b2017-11-09 11:09:25 +01001312 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001313 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001314 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001315 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001316 if (!media_channel()->SetSendParameters(send_params)) {
1317 SafeSetError("Failed to set remote data description send parameters.",
1318 error_desc);
1319 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001320 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001321 last_send_params_ = send_params;
1322
1323 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1324 // and only give it to the media channel once we have a local
1325 // description too (without a local description, we won't be able to
1326 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001327 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yves Gerey665174f2018-06-19 15:03:05 +02001328 SafeSetError("Failed to set remote data description streams.", error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001329 return false;
1330 }
1331
1332 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001333 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001334 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001335}
1336
deadbeef953c2ce2017-01-09 14:53:41 -08001337void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001338 // Render incoming data if we're the active call, and we have the local
1339 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001340 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001341 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001342 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343 }
1344
1345 // Send outgoing data if we're the active call, we have the remote content,
1346 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001347 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001349 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001350 }
1351
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001352 // Trigger SignalReadyToSendData asynchronously.
1353 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354
Mirko Bonadei675513b2017-11-09 11:09:25 +01001355 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356}
1357
deadbeef953c2ce2017-01-09 14:53:41 -08001358void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001359 switch (pmsg->message_id) {
1360 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001361 DataChannelReadyToSendMessageData* data =
1362 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001363 ready_to_send_data_ = data->data();
1364 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001365 delete data;
1366 break;
1367 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001368 case MSG_DATARECEIVED: {
1369 DataReceivedMessageData* data =
1370 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001371 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001372 delete data;
1373 break;
1374 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375 default:
1376 BaseChannel::OnMessage(pmsg);
1377 break;
1378 }
1379}
1380
deadbeef953c2ce2017-01-09 14:53:41 -08001381void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1382 const char* data,
1383 size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +02001384 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001385 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386}
1387
deadbeef953c2ce2017-01-09 14:53:41 -08001388void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001389 // This is usded for congestion control to indicate that the stream is ready
1390 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1391 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001392 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001393 new DataChannelReadyToSendMessageData(writable));
1394}
1395
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396} // namespace cricket