blob: 9ff47d5401e5abb89617183ab4f04d5b5f1e06bd [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"
Niels Möller65f17ca2019-09-12 13:59:36 +020019#include "api/transport/media/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>
98void RtpParametersFromMediaDescription(
99 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -0700100 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700101 RtpParameters<Codec>* params) {
102 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 11:36:43 -0800103 // a description without codecs. Currently the ORTC implementation is relying
104 // on this.
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700105 if (desc->has_codecs()) {
Artem Titov65639342019-08-02 08:27:51 +0000106 params->codecs = desc->codecs();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700107 }
108 // TODO(pthatcher): See if we really need
109 // rtp_header_extensions_set() and remove it if we don't.
110 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -0700111 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700112 }
deadbeef13871492015-12-09 12:37:51 -0800113 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Sebastian Janssone1795f42019-07-24 11:38:03 +0200114 params->rtcp.remote_estimate = desc->remote_estimate();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700115}
116
nisse05103312016-03-16 02:22:50 -0700117template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700118void RtpSendParametersFromMediaDescription(
119 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -0700120 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 02:22:50 -0700121 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 12:31:36 -0700122 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700123 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 11:22:05 +0100124 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700125}
126
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200127BaseChannel::BaseChannel(rtc::Thread* worker_thread,
128 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800129 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800130 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700131 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700132 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800133 webrtc::CryptoOptions crypto_options,
134 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200135 : worker_thread_(worker_thread),
136 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800137 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000138 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800139 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700140 crypto_options_(crypto_options),
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800141 media_channel_(std::move(media_channel)),
142 ssrc_generator_(ssrc_generator) {
Steve Anton8699a322017-11-06 15:53:33 -0800143 RTC_DCHECK_RUN_ON(worker_thread_);
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800144 RTC_DCHECK(ssrc_generator_);
Zhi Huang365381f2018-04-13 16:44:34 -0700145 demuxer_criteria_.mid = content_name;
Mirko Bonadei675513b2017-11-09 11:09:25 +0100146 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000147}
148
149BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800150 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800151 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800152
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700153 if (media_transport_config_.media_transport) {
154 media_transport_config_.media_transport->RemoveNetworkChangeCallback(this);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800155 }
156
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200157 // Eats any outstanding messages or packets.
158 worker_thread_->Clear(&invoker_);
159 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160 // We must destroy the media channel before the transport channel, otherwise
161 // the media channel may try to send on the dead transport channel. NULLing
162 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800163 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100164 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200165}
166
Zhi Huang365381f2018-04-13 16:44:34 -0700167bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800168 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700169 if (!RegisterRtpDemuxerSink()) {
170 return false;
171 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800172 rtp_transport_->SignalReadyToSend.connect(
173 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang365381f2018-04-13 16:44:34 -0700174 rtp_transport_->SignalRtcpPacketReceived.connect(
175 this, &BaseChannel::OnRtcpPacketReceived);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800176
177 // If media transport is used, it's responsible for providing network
178 // route changed callbacks.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700179 if (!media_transport_config_.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800180 rtp_transport_->SignalNetworkRouteChanged.connect(
181 this, &BaseChannel::OnNetworkRouteChanged);
182 }
183 // TODO(bugs.webrtc.org/9719): Media transport should also be used to provide
184 // 'writable' state here.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800185 rtp_transport_->SignalWritableState.connect(this,
186 &BaseChannel::OnWritableState);
187 rtp_transport_->SignalSentPacket.connect(this,
188 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 16:44:34 -0700189 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800190}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200191
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800192void BaseChannel::DisconnectFromRtpTransport() {
193 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700194 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800195 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang365381f2018-04-13 16:44:34 -0700196 rtp_transport_->SignalRtcpPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800197 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
198 rtp_transport_->SignalWritableState.disconnect(this);
199 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200200}
201
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700202void BaseChannel::Init_w(
203 webrtc::RtpTransportInternal* rtp_transport,
204 const webrtc::MediaTransportConfig& media_transport_config) {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800205 RTC_DCHECK_RUN_ON(worker_thread_);
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700206 media_transport_config_ = media_transport_config;
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800207
Zhi Huang365381f2018-04-13 16:44:34 -0700208 network_thread_->Invoke<void>(
209 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800210
211 // Both RTP and RTCP channels should be set, we can call SetInterface on
212 // the media channel and it can set network options.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700213 media_channel_->SetInterface(this, media_transport_config);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800214
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700215 RTC_LOG(LS_INFO) << "BaseChannel::Init_w, media_transport_config="
216 << media_transport_config.DebugString();
217 if (media_transport_config_.media_transport) {
218 media_transport_config_.media_transport->AddNetworkChangeCallback(this);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800219 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200220}
221
wu@webrtc.org78187522013-10-07 23:32:02 +0000222void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200223 RTC_DCHECK(worker_thread_->IsCurrent());
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700224 media_channel_->SetInterface(/*iface=*/nullptr,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700225 webrtc::MediaTransportConfig());
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200226 // Packets arrive on the network thread, processing packets calls virtual
227 // functions, so need to stop this process in Deinit that is called in
228 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800229 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000230 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700231
Zhi Huange830e682018-03-30 10:48:35 -0700232 if (rtp_transport_) {
233 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000234 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800235 // Clear pending read packets/messages.
236 network_thread_->Clear(&invoker_);
237 network_thread_->Clear(this);
238 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000239}
240
Zhi Huang365381f2018-04-13 16:44:34 -0700241bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
242 if (rtp_transport == rtp_transport_) {
243 return true;
244 }
245
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800246 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 16:44:34 -0700247 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
248 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800249 });
250 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000251
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800252 if (rtp_transport_) {
253 DisconnectFromRtpTransport();
254 }
Zhi Huange830e682018-03-30 10:48:35 -0700255
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800256 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700257 if (rtp_transport_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700258 transport_name_ = rtp_transport_->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800259
Zhi Huang365381f2018-04-13 16:44:34 -0700260 if (!ConnectToRtpTransport()) {
261 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport.";
262 return false;
263 }
Zhi Huange830e682018-03-30 10:48:35 -0700264 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
265 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800266
Zhi Huange830e682018-03-30 10:48:35 -0700267 // Set the cached socket options.
268 for (const auto& pair : socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700269 rtp_transport_->SetRtpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700270 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700271 if (!rtp_transport_->rtcp_mux_enabled()) {
Zhi Huange830e682018-03-30 10:48:35 -0700272 for (const auto& pair : rtcp_socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700273 rtp_transport_->SetRtcpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700274 }
275 }
guoweis46383312015-12-17 16:45:59 -0800276 }
Zhi Huang365381f2018-04-13 16:44:34 -0700277 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000278}
279
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000280bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700281 worker_thread_->Invoke<void>(
282 RTC_FROM_HERE,
283 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
284 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285 return true;
286}
287
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800289 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000290 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100291 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700292 return InvokeOnWorker<bool>(
293 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800294 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000295}
296
297bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800298 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000299 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100300 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700301 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800302 RTC_FROM_HERE,
303 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304}
305
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700306bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000307 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800308 return enabled() &&
309 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310}
311
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700312bool BaseChannel::IsReadyToSendMedia_w() const {
313 // Need to access some state updated on the network thread.
314 return network_thread_->Invoke<bool>(
315 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
316}
317
318bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 // Send outgoing data if we are enabled, have local and remote content,
320 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800321 return enabled() &&
322 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
323 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 16:44:34 -0700324 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325}
326
jbaucheec21bd2016-03-20 06:15:43 -0700327bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700328 const rtc::PacketOptions& options) {
329 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330}
331
jbaucheec21bd2016-03-20 06:15:43 -0700332bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700333 const rtc::PacketOptions& options) {
334 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335}
336
Yves Gerey665174f2018-06-19 15:03:05 +0200337int BaseChannel::SetOption(SocketType type,
338 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200340 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700341 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200342}
343
344int BaseChannel::SetOption_n(SocketType type,
345 rtc::Socket::Option opt,
346 int value) {
347 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700348 RTC_DCHECK(rtp_transport_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000350 case ST_RTP:
deadbeefcbecd352015-09-23 11:50:27 -0700351 socket_options_.push_back(
352 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700353 return rtp_transport_->SetRtpOption(opt, value);
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000354 case ST_RTCP:
deadbeefcbecd352015-09-23 11:50:27 -0700355 rtcp_socket_options_.push_back(
356 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700357 return rtp_transport_->SetRtcpOption(opt, value);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000358 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700359 return -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000360}
361
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800362void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200363 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800364 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800365 ChannelWritable_n();
366 } else {
367 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800368 }
369}
370
Zhi Huang942bc2e2017-11-13 13:26:07 -0800371void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200372 absl::optional<rtc::NetworkRoute> network_route) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800373 RTC_LOG(LS_INFO) << "Network route was changed.";
374
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200375 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800376 rtc::NetworkRoute new_route;
377 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800378 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000379 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800380 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
381 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
382 // work correctly. Intentionally leave it broken to simplify the code and
383 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800384 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800385 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800386 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700387}
388
zstein56162b92017-04-24 16:54:35 -0700389void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800390 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
391 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000392}
393
stefanc1aeaf02015-10-15 07:26:07 -0700394bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700395 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700396 const rtc::PacketOptions& options) {
Amit Hilbuchedd20542019-03-18 12:33:43 -0700397 // Until all the code is migrated to use RtpPacketType instead of bool.
398 RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200399 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
400 // If the thread is not our network thread, we will post to our network
401 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000402 // synchronize access to all the pieces of the send path, including
403 // SRTP and the inner workings of the transport channels.
404 // The only downside is that we can't return a proper failure code if
405 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200406 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200408 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
409 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800410 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700411 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700412 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000413 return true;
414 }
Zhi Huange830e682018-03-30 10:48:35 -0700415
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200416 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000417
418 // Now that we are on the correct thread, ensure we have a place to send this
419 // packet before doing anything. (We might get RTCP packets that we don't
420 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
421 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700422 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000423 return false;
424 }
425
426 // Protect ourselves against crazy data.
Amit Hilbuchedd20542019-03-18 12:33:43 -0700427 if (!IsValidRtpPacketSize(packet_type, packet->size())) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100428 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
Amit Hilbuchedd20542019-03-18 12:33:43 -0700429 << RtpPacketTypeToString(packet_type)
Mirko Bonadei675513b2017-11-09 11:09:25 +0100430 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431 return false;
432 }
433
Zhi Huangcf990f52017-09-22 12:12:30 -0700434 if (!srtp_active()) {
435 if (srtp_required_) {
436 // The audio/video engines may attempt to send RTCP packets as soon as the
437 // streams are created, so don't treat this as an error for RTCP.
438 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
439 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000440 return false;
441 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700442 // However, there shouldn't be any RTP packets sent before SRTP is set up
443 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100444 RTC_LOG(LS_ERROR)
445 << "Can't send outgoing RTP packet when SRTP is inactive"
446 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700447 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800448 return false;
449 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800450
451 std::string packet_type = rtcp ? "RTCP" : "RTP";
452 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
453 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000454 }
Zhi Huange830e682018-03-30 10:48:35 -0700455
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000456 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800457 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
458 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000459}
460
Zhi Huang365381f2018-04-13 16:44:34 -0700461void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Niels Möller29e13fd2018-12-17 12:35:30 +0100462 // Take packet time from the |parsed_packet|.
463 // RtpPacketReceived.arrival_time_ms = (timestamp_us + 500) / 1000;
Niels Möllere6933812018-11-05 13:01:41 +0100464 int64_t timestamp_us = -1;
Zhi Huang365381f2018-04-13 16:44:34 -0700465 if (parsed_packet.arrival_time_ms() > 0) {
Niels Möllere6933812018-11-05 13:01:41 +0100466 timestamp_us = parsed_packet.arrival_time_ms() * 1000;
Zhi Huang365381f2018-04-13 16:44:34 -0700467 }
Zhi Huang365381f2018-04-13 16:44:34 -0700468
Niels Möllere6933812018-11-05 13:01:41 +0100469 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), timestamp_us);
Zhi Huang365381f2018-04-13 16:44:34 -0700470}
471
472void BaseChannel::UpdateRtpHeaderExtensionMap(
473 const RtpHeaderExtensions& header_extensions) {
474 RTC_DCHECK(rtp_transport_);
475 // Update the header extension map on network thread in case there is data
476 // race.
477 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
478 // be accessed from different threads.
479 //
480 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
481 // extension maps are not merged when BUNDLE is enabled. This is fine because
482 // the ID for MID should be consistent among all the RTP transports.
483 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
484 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
485 });
486}
487
488bool BaseChannel::RegisterRtpDemuxerSink() {
489 RTC_DCHECK(rtp_transport_);
490 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
491 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
492 });
493}
494
495void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
Niels Möllere6933812018-11-05 13:01:41 +0100496 int64_t packet_time_us) {
497 OnPacketReceived(/*rtcp=*/true, *packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000498}
499
zstein3dcf0e92017-06-01 13:22:42 -0700500void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang365381f2018-04-13 16:44:34 -0700501 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 13:01:41 +0100502 int64_t packet_time_us) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000503 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000504 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700505 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000506 }
507
Zhi Huangcf990f52017-09-22 12:12:30 -0700508 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000509 // Our session description indicates that SRTP is required, but we got a
510 // packet before our SRTP filter is active. This means either that
511 // a) we got SRTP packets before we received the SDES keys, in which case
512 // we can't decrypt it anyway, or
513 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800514 // transports, so we haven't yet extracted keys, even if DTLS did
515 // complete on the transport that the packets are being sent on. It's
516 // really good practice to wait for both RTP and RTCP to be good to go
517 // before sending media, to prevent weird failure modes, so it's fine
518 // for us to just eat packets here. This is all sidestepped if RTCP mux
519 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100520 RTC_LOG(LS_WARNING)
Amit Hilbuchedd20542019-03-18 12:33:43 -0700521 << "Can't process incoming "
522 << RtpPacketTypeToString(rtcp ? RtpPacketType::kRtcp
523 : RtpPacketType::kRtp)
Mirko Bonadei675513b2017-11-09 11:09:25 +0100524 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000525 return;
526 }
527
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200528 invoker_.AsyncInvoke<void>(
Sebastian Jansson01be33b2019-09-12 17:39:18 +0200529 RTC_FROM_HERE, worker_thread_, [this, rtcp, packet, packet_time_us] {
530 RTC_DCHECK(worker_thread_->IsCurrent());
531 if (rtcp) {
532 media_channel_->OnRtcpReceived(packet, packet_time_us);
533 } else {
534 media_channel_->OnPacketReceived(packet, packet_time_us);
535 }
536 });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000537}
538
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000539void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700540 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000541 if (enabled_)
542 return;
543
Mirko Bonadei675513b2017-11-09 11:09:25 +0100544 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000545 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700546 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000547}
548
549void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700550 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000551 if (!enabled_)
552 return;
553
Mirko Bonadei675513b2017-11-09 11:09:25 +0100554 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700556 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000557}
558
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200559void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700560 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
561 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200562 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700563 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200564 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700565 }
566}
567
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200568void BaseChannel::ChannelWritable_n() {
569 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800570 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800572 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000573
Mirko Bonadei675513b2017-11-09 11:09:25 +0100574 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
575 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000576
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 was_ever_writable_ = true;
578 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700579 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580}
581
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200582void BaseChannel::ChannelNotWritable_n() {
583 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000584 if (!writable_)
585 return;
586
Mirko Bonadei675513b2017-11-09 11:09:25 +0100587 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000588 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700589 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000590}
591
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000592bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700593 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800594 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595}
596
Peter Boström0c4e06b2015-10-07 12:23:21 +0200597bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700598 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599 return media_channel()->RemoveRecvStream(ssrc);
600}
601
602bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800603 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000604 std::string* error_desc) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800605 // In the case of RIDs (where SSRCs are not negotiated), this method will
606 // generate an SSRC for each layer in StreamParams. That representation will
607 // be stored internally in |local_streams_|.
608 // In subsequent offers, the same stream can appear in |streams| again
609 // (without the SSRCs), so it should be looked up using RIDs (if available)
610 // and then by primary SSRC.
611 // In both scenarios, it is safe to assume that the media channel will be
612 // created with a StreamParams object with SSRCs. However, it is not safe to
613 // assume that |local_streams_| will always have SSRCs as there are scenarios
614 // in which niether SSRCs or RIDs are negotiated.
615
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000616 // Check for streams that have been removed.
617 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800618 for (const StreamParams& old_stream : local_streams_) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800619 if (!old_stream.has_ssrcs() ||
620 GetStream(streams, StreamFinder(&old_stream))) {
621 continue;
622 }
623 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
624 rtc::StringBuilder desc;
625 desc << "Failed to remove send stream with ssrc "
626 << old_stream.first_ssrc() << ".";
627 SafeSetError(desc.str(), error_desc);
628 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629 }
630 }
631 // Check for new streams.
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800632 std::vector<StreamParams> all_streams;
633 for (const StreamParams& stream : streams) {
634 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
635 if (existing) {
636 // Parameters cannot change for an existing stream.
637 all_streams.push_back(*existing);
638 continue;
639 }
640
641 all_streams.push_back(stream);
642 StreamParams& new_stream = all_streams.back();
643
644 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
645 continue;
646 }
647
648 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
649 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
650 rtc::StringBuilder desc;
651 desc << "Failed to add send stream: " << new_stream.first_ssrc()
652 << ". Stream has both SSRCs and RIDs.";
653 SafeSetError(desc.str(), error_desc);
654 ret = false;
655 continue;
656 }
657
658 // At this point we use the legacy simulcast group in StreamParams to
659 // indicate that we want multiple layers to the media channel.
660 if (!new_stream.has_ssrcs()) {
661 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
662 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
663 /* flex_fec = */ false, ssrc_generator_);
664 }
665
666 if (media_channel()->AddSendStream(new_stream)) {
667 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0];
668 } else {
669 rtc::StringBuilder desc;
670 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc();
671 SafeSetError(desc.str(), error_desc);
672 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673 }
674 }
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800675 local_streams_ = all_streams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000676 return ret;
677}
678
679bool BaseChannel::UpdateRemoteStreams_w(
680 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800681 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000682 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000683 // Check for streams that have been removed.
684 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800685 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700686 // If we no longer have an unsignaled stream, we would like to remove
687 // the unsignaled stream params that are cached.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800688 if ((!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
689 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
690 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
691 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc();
Zhi Huang365381f2018-04-13 16:44:34 -0700692 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200693 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800694 desc << "Failed to remove remote stream with ssrc "
695 << old_stream.first_ssrc() << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000696 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000697 ret = false;
698 }
699 }
700 }
Zhi Huang365381f2018-04-13 16:44:34 -0700701 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800703 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700704 // We allow a StreamParams with an empty list of SSRCs, in which case the
705 // MediaChannel will cache the parameters and use them for any unsignaled
706 // stream received later.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800707 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
708 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
709 if (AddRecvStream_w(new_stream)) {
710 RTC_LOG(LS_INFO) << "Add remote ssrc: " << new_stream.first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200712 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800713 desc << "Failed to add remote stream ssrc: " << new_stream.first_ssrc();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000714 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 ret = false;
716 }
717 }
Zhi Huang365381f2018-04-13 16:44:34 -0700718 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800719 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
720 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721 }
Zhi Huang365381f2018-04-13 16:44:34 -0700722 // Re-register the sink to update the receiving ssrcs.
723 RegisterRtpDemuxerSink();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724 remote_streams_ = streams;
725 return ret;
726}
727
jbauch5869f502017-06-29 12:31:36 -0700728RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
729 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700730 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700731 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700732 RtpHeaderExtensions filtered;
Steve Anton64b626b2019-01-28 17:25:26 -0800733 absl::c_copy_if(extensions, std::back_inserter(filtered),
734 [](const webrtc::RtpExtension& extension) {
735 return !extension.encrypt;
736 });
jbauch5869f502017-06-29 12:31:36 -0700737 return filtered;
738 }
739
740 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
741}
742
Yves Gerey665174f2018-06-19 15:03:05 +0200743void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100744 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000745 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200746 case MSG_SEND_RTP_PACKET:
747 case MSG_SEND_RTCP_PACKET: {
748 RTC_DCHECK(network_thread_->IsCurrent());
749 SendPacketMessageData* data =
750 static_cast<SendPacketMessageData*>(pmsg->pdata);
751 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
752 SendPacket(rtcp, &data->packet, data->options);
753 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000754 break;
755 }
756 case MSG_FIRSTPACKETRECEIVED: {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800757 SignalFirstPacketReceived_(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000758 break;
759 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000760 }
761}
762
zstein3dcf0e92017-06-01 13:22:42 -0700763void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 16:44:34 -0700764 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -0700765}
766
Steve Antonbe2e5f72019-09-06 16:26:02 -0700767void BaseChannel::ClearHandledPayloadTypes() {
768 demuxer_criteria_.payload_types.clear();
769}
770
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200771void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772 // Flush all remaining RTCP messages. This should only be called in
773 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200774 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000775 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200776 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
777 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700778 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
779 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780 }
781}
782
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800783void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200784 RTC_DCHECK(network_thread_->IsCurrent());
Sebastian Jansson01be33b2019-09-12 17:39:18 +0200785 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
786 [this, sent_packet] {
787 RTC_DCHECK(worker_thread_->IsCurrent());
788 SignalSentPacket(sent_packet);
789 });
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200790}
791
792VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
793 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800794 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800795 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700797 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800798 webrtc::CryptoOptions crypto_options,
799 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200800 : BaseChannel(worker_thread,
801 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800802 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800803 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700804 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700805 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800806 crypto_options,
807 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808
809VoiceChannel::~VoiceChannel() {
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -0800810 if (media_transport()) {
811 media_transport()->SetFirstAudioPacketReceivedObserver(nullptr);
812 }
Peter Boströmca8b4042016-03-08 14:24:13 -0800813 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000814 // this can't be done in the base class, since it calls a virtual
815 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700816 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000817}
818
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700819void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200820 RTC_DCHECK(network_thread_->IsCurrent());
Sebastian Jansson01be33b2019-09-12 17:39:18 +0200821 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
822 [this] { UpdateMediaSendRecvState_w(); });
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200823}
824
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800825void BaseChannel::OnNetworkRouteChanged(
826 const rtc::NetworkRoute& network_route) {
827 OnNetworkRouteChanged(absl::make_optional(network_route));
828}
829
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700830void VoiceChannel::Init_w(
831 webrtc::RtpTransportInternal* rtp_transport,
832 const webrtc::MediaTransportConfig& media_transport_config) {
833 BaseChannel::Init_w(rtp_transport, media_transport_config);
834 if (media_transport_config.media_transport) {
835 media_transport_config.media_transport->SetFirstAudioPacketReceivedObserver(
836 this);
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -0800837 }
838}
839
840void VoiceChannel::OnFirstAudioPacketReceived(int64_t channel_id) {
841 has_received_packet_ = true;
842 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
843}
844
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700845void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846 // Render incoming data if we're the active call, and we have the local
847 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700848 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700849 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000850
851 // Send outgoing data if we're the active call, we have the remote content,
852 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700853 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800854 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855
Mirko Bonadei675513b2017-11-09 11:09:25 +0100856 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000857}
858
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800860 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000861 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100862 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800863 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100864 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000865
Steve Antonb1c1de12017-12-21 15:14:30 -0800866 RTC_DCHECK(content);
867 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000868 SafeSetError("Can't find audio content in local description.", error_desc);
869 return false;
870 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000871
Steve Antonb1c1de12017-12-21 15:14:30 -0800872 const AudioContentDescription* audio = content->as_audio();
873
jbauch5869f502017-06-29 12:31:36 -0700874 RtpHeaderExtensions rtp_header_extensions =
875 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700876 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100877 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700878
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700879 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700880 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700881 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -0700882 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700883 error_desc);
884 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 }
Steve Antonbe2e5f72019-09-06 16:26:02 -0700886
887 if (webrtc::RtpTransceiverDirectionHasRecv(audio->direction())) {
888 for (const AudioCodec& codec : audio->codecs()) {
889 AddHandledPayloadType(codec.id);
890 }
891 // Need to re-register the sink to update the handled payload.
892 if (!RegisterRtpDemuxerSink()) {
893 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
894 return false;
895 }
Zhi Huang365381f2018-04-13 16:44:34 -0700896 }
897
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700898 last_recv_params_ = recv_params;
899
900 // TODO(pthatcher): Move local streams into AudioSendParameters, and
901 // only give it to the media channel once we have a remote
902 // description too (without a remote description, we won't be able
903 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800904 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700905 SafeSetError("Failed to set local audio description streams.", error_desc);
906 return false;
907 }
908
909 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700910 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700911 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912}
913
914bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800915 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000916 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100917 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800918 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100919 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920
Steve Antonb1c1de12017-12-21 15:14:30 -0800921 RTC_DCHECK(content);
922 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000923 SafeSetError("Can't find audio content in remote description.", error_desc);
924 return false;
925 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926
Steve Antonb1c1de12017-12-21 15:14:30 -0800927 const AudioContentDescription* audio = content->as_audio();
928
jbauch5869f502017-06-29 12:31:36 -0700929 RtpHeaderExtensions rtp_header_extensions =
930 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
931
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700932 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700933 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +0200934 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700935 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700936
937 bool parameters_applied = media_channel()->SetSendParameters(send_params);
938 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700939 SafeSetError("Failed to set remote audio 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
Steve Antonbe2e5f72019-09-06 16:26:02 -0700945 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
946 RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
947 "disable payload type demuxing";
948 ClearHandledPayloadTypes();
949 if (!RegisterRtpDemuxerSink()) {
950 RTC_LOG(LS_ERROR) << "Failed to update audio demuxing.";
951 return false;
952 }
953 }
954
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700955 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
956 // and only give it to the media channel once we have a local
957 // description too (without a local description, we won't be able to
958 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800959 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700960 SafeSetError("Failed to set remote audio description streams.", error_desc);
961 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962 }
963
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700964 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700965 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700966 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200969VideoChannel::VideoChannel(rtc::Thread* worker_thread,
970 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800971 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800972 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700974 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800975 webrtc::CryptoOptions crypto_options,
976 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200977 : BaseChannel(worker_thread,
978 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800979 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800980 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700981 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700982 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800983 crypto_options,
984 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800987 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988 // this can't be done in the base class, since it calls a virtual
989 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700990 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991}
992
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700993void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994 // Send outgoing data if we're the active call, we have the remote content,
995 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700996 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100998 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999 // TODO(gangji): Report error back to server.
1000 }
1001
Mirko Bonadei675513b2017-11-09 11:09:25 +01001002 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001003}
1004
stefanf79ade12017-06-02 06:44:03 -07001005void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
1006 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
1007 media_channel(), bwe_info));
1008}
1009
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001011 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001012 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001013 TRACE_EVENT0("webrtc", "VideoChannel::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 video 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 video 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 VideoContentDescription* video = content->as_video();
1024
jbauch5869f502017-06-29 12:31:36 -07001025 RtpHeaderExtensions rtp_header_extensions =
1026 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -07001027 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +01001028 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -07001029
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001030 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001031 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001032
1033 VideoSendParameters send_params = last_send_params_;
1034 bool needs_send_params_update = false;
1035 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
1036 for (auto& send_codec : send_params.codecs) {
1037 auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
1038 if (recv_codec) {
1039 if (!recv_codec->packetization && send_codec.packetization) {
1040 send_codec.packetization.reset();
1041 needs_send_params_update = true;
1042 } else if (recv_codec->packetization != send_codec.packetization) {
1043 SafeSetError(
1044 "Failed to set local answer due to invalid codec packetization.",
1045 error_desc);
1046 return false;
1047 }
1048 }
1049 }
1050 }
1051
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001052 if (!media_channel()->SetRecvParameters(recv_params)) {
1053 SafeSetError("Failed to set local video description recv parameters.",
1054 error_desc);
1055 return false;
1056 }
Steve Antonbe2e5f72019-09-06 16:26:02 -07001057
1058 if (webrtc::RtpTransceiverDirectionHasRecv(video->direction())) {
1059 for (const VideoCodec& codec : video->codecs()) {
1060 AddHandledPayloadType(codec.id);
1061 }
1062 // Need to re-register the sink to update the handled payload.
1063 if (!RegisterRtpDemuxerSink()) {
1064 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
1065 return false;
1066 }
Zhi Huang365381f2018-04-13 16:44:34 -07001067 }
1068
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001069 last_recv_params_ = recv_params;
1070
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001071 if (needs_send_params_update) {
1072 if (!media_channel()->SetSendParameters(send_params)) {
1073 SafeSetError("Failed to set send parameters.", error_desc);
1074 return false;
1075 }
1076 last_send_params_ = send_params;
1077 }
1078
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001079 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1080 // only give it to the media channel once we have a remote
1081 // description too (without a remote description, we won't be able
1082 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001083 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001084 SafeSetError("Failed to set local video description streams.", error_desc);
1085 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001086 }
1087
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001088 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001089 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001090 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001091}
1092
1093bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001094 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001095 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001096 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001097 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001098 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001099
Steve Antonb1c1de12017-12-21 15:14:30 -08001100 RTC_DCHECK(content);
1101 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001102 SafeSetError("Can't find video content in remote description.", error_desc);
1103 return false;
1104 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001105
Steve Antonb1c1de12017-12-21 15:14:30 -08001106 const VideoContentDescription* video = content->as_video();
1107
jbauch5869f502017-06-29 12:31:36 -07001108 RtpHeaderExtensions rtp_header_extensions =
1109 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1110
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001111 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001112 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001113 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001114 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001115 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001116 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001117 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001118
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001119 VideoRecvParameters recv_params = last_recv_params_;
1120 bool needs_recv_params_update = false;
1121 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
1122 for (auto& recv_codec : recv_params.codecs) {
1123 auto* send_codec = FindMatchingCodec(send_params.codecs, recv_codec);
1124 if (send_codec) {
1125 if (!send_codec->packetization && recv_codec.packetization) {
1126 recv_codec.packetization.reset();
1127 needs_recv_params_update = true;
1128 } else if (send_codec->packetization != recv_codec.packetization) {
1129 SafeSetError(
1130 "Failed to set remote answer due to invalid codec packetization.",
1131 error_desc);
1132 return false;
1133 }
1134 }
1135 }
1136 }
skvladdc1c62c2016-03-16 19:07:43 -07001137
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001138 if (!media_channel()->SetSendParameters(send_params)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001139 SafeSetError("Failed to set remote video description send parameters.",
1140 error_desc);
1141 return false;
1142 }
1143 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001144
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001145 if (needs_recv_params_update) {
1146 if (!media_channel()->SetRecvParameters(recv_params)) {
1147 SafeSetError("Failed to set recv parameters.", error_desc);
1148 return false;
1149 }
1150 last_recv_params_ = recv_params;
1151 }
1152
Steve Antonbe2e5f72019-09-06 16:26:02 -07001153 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
1154 RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
1155 "disable payload type demuxing";
1156 ClearHandledPayloadTypes();
1157 if (!RegisterRtpDemuxerSink()) {
1158 RTC_LOG(LS_ERROR) << "Failed to update video demuxing.";
1159 return false;
1160 }
1161 }
1162
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001163 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1164 // and only give it to the media channel once we have a local
1165 // description too (without a local description, we won't be able to
1166 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001167 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001168 SafeSetError("Failed to set remote video description streams.", error_desc);
1169 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001170 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001171 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001172 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001173 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001174}
1175
deadbeef953c2ce2017-01-09 14:53:41 -08001176RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1177 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001178 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001179 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001180 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001181 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001182 webrtc::CryptoOptions crypto_options,
1183 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001184 : BaseChannel(worker_thread,
1185 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001186 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001187 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001188 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001189 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001190 crypto_options,
1191 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001192
deadbeef953c2ce2017-01-09 14:53:41 -08001193RtpDataChannel::~RtpDataChannel() {
1194 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001195 // this can't be done in the base class, since it calls a virtual
1196 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001197 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001198}
1199
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001200void RtpDataChannel::Init_w(
1201 webrtc::RtpTransportInternal* rtp_transport,
1202 const webrtc::MediaTransportConfig& media_transport_config) {
1203 BaseChannel::Init_w(rtp_transport, media_transport_config);
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001204 media_channel()->SignalDataReceived.connect(this,
1205 &RtpDataChannel::OnDataReceived);
1206 media_channel()->SignalReadyToSend.connect(
1207 this, &RtpDataChannel::OnDataChannelReadyToSend);
1208}
1209
deadbeef953c2ce2017-01-09 14:53:41 -08001210bool RtpDataChannel::SendData(const SendDataParams& params,
1211 const rtc::CopyOnWriteBuffer& payload,
1212 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001213 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001214 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1215 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001216}
1217
deadbeef953c2ce2017-01-09 14:53:41 -08001218bool RtpDataChannel::CheckDataChannelTypeFromContent(
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02001219 const RtpDataContentDescription* content,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001220 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001221 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1222 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001223 // It's been set before, but doesn't match. That's bad.
1224 if (is_sctp) {
1225 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1226 error_desc);
1227 return false;
1228 }
1229 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001230}
1231
deadbeef953c2ce2017-01-09 14:53:41 -08001232bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001233 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001234 std::string* error_desc) {
1235 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001236 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001237 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001238
Steve Antonb1c1de12017-12-21 15:14:30 -08001239 RTC_DCHECK(content);
1240 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001241 SafeSetError("Can't find data content in local description.", error_desc);
1242 return false;
1243 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001244
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02001245 const RtpDataContentDescription* data = content->as_rtp_data();
Steve Antonb1c1de12017-12-21 15:14:30 -08001246
deadbeef953c2ce2017-01-09 14:53:41 -08001247 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001248 return false;
1249 }
1250
jbauch5869f502017-06-29 12:31:36 -07001251 RtpHeaderExtensions rtp_header_extensions =
1252 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1253
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001254 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001255 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001256 if (!media_channel()->SetRecvParameters(recv_params)) {
1257 SafeSetError("Failed to set remote data description recv parameters.",
1258 error_desc);
1259 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001260 }
deadbeef953c2ce2017-01-09 14:53:41 -08001261 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001262 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001263 }
Zhi Huang365381f2018-04-13 16:44:34 -07001264 // Need to re-register the sink to update the handled payload.
1265 if (!RegisterRtpDemuxerSink()) {
1266 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1267 return false;
1268 }
1269
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001270 last_recv_params_ = recv_params;
1271
1272 // TODO(pthatcher): Move local streams into DataSendParameters, and
1273 // only give it to the media channel once we have a remote
1274 // description too (without a remote description, we won't be able
1275 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001276 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001277 SafeSetError("Failed to set local data description streams.", error_desc);
1278 return false;
1279 }
1280
1281 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001282 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001283 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284}
1285
deadbeef953c2ce2017-01-09 14:53:41 -08001286bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001287 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001288 std::string* error_desc) {
1289 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001290 RTC_DCHECK_RUN_ON(worker_thread());
1291 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001292
Steve Antonb1c1de12017-12-21 15:14:30 -08001293 RTC_DCHECK(content);
1294 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001295 SafeSetError("Can't find data content in remote description.", error_desc);
1296 return false;
1297 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001298
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02001299 const RtpDataContentDescription* data = content->as_rtp_data();
1300
1301 if (!data) {
1302 RTC_LOG(LS_INFO) << "Accepting and ignoring non-RTP content description";
1303 return true;
1304 }
Steve Antonb1c1de12017-12-21 15:14:30 -08001305
Zhi Huang801b8682017-11-15 11:36:43 -08001306 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1307 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001308 return true;
1309 }
1310
deadbeef953c2ce2017-01-09 14:53:41 -08001311 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312 return false;
1313 }
1314
jbauch5869f502017-06-29 12:31:36 -07001315 RtpHeaderExtensions rtp_header_extensions =
1316 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1317
Mirko Bonadei675513b2017-11-09 11:09:25 +01001318 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001319 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001320 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
Yves Gerey665174f2018-06-19 15:03:05 +02001321 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001322 if (!media_channel()->SetSendParameters(send_params)) {
1323 SafeSetError("Failed to set remote data description send parameters.",
1324 error_desc);
1325 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001326 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001327 last_send_params_ = send_params;
1328
1329 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1330 // and only give it to the media channel once we have a local
1331 // description too (without a local description, we won't be able to
1332 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001333 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yves Gerey665174f2018-06-19 15:03:05 +02001334 SafeSetError("Failed to set remote data description streams.", error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001335 return false;
1336 }
1337
1338 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001339 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001340 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001341}
1342
deadbeef953c2ce2017-01-09 14:53:41 -08001343void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344 // Render incoming data if we're the active call, and we have the local
1345 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001346 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001347 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001348 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001349 }
1350
1351 // Send outgoing data if we're the active call, we have the remote content,
1352 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001353 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001355 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356 }
1357
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001358 // Trigger SignalReadyToSendData asynchronously.
1359 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001360
Mirko Bonadei675513b2017-11-09 11:09:25 +01001361 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362}
1363
deadbeef953c2ce2017-01-09 14:53:41 -08001364void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001365 switch (pmsg->message_id) {
1366 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001367 DataChannelReadyToSendMessageData* data =
1368 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001369 ready_to_send_data_ = data->data();
1370 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001371 delete data;
1372 break;
1373 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001374 case MSG_DATARECEIVED: {
1375 DataReceivedMessageData* data =
1376 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001377 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001378 delete data;
1379 break;
1380 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001381 default:
1382 BaseChannel::OnMessage(pmsg);
1383 break;
1384 }
1385}
1386
deadbeef953c2ce2017-01-09 14:53:41 -08001387void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1388 const char* data,
1389 size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +02001390 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001391 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001392}
1393
deadbeef953c2ce2017-01-09 14:53:41 -08001394void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001395 // This is usded for congestion control to indicate that the stream is ready
1396 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1397 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001398 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001399 new DataChannelReadyToSendMessageData(writable));
1400}
1401
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001402} // namespace cricket