blob: 13341e3e1b4b6e1b822773909d349bb6e7adec27 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:361/*
kjellander65c7f672016-02-12 08:05:012 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:363 *
kjellander65c7f672016-02-12 08:05:014 * 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:369 */
10
Anton Sukhanov4f08faa2019-05-21 18:12:5711#include "pc/channel.h"
12
jbauch5869f502017-06-29 19:31:3613#include <iterator>
kwiberg0eb15ed2015-12-17 11:04:1514#include <utility>
15
Steve Anton64b626b2019-01-29 01:25:2616#include "absl/algorithm/container.h"
Karl Wiberg918f50c2018-07-05 09:40:3317#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3118#include "api/call/audio_sink.h"
Anton Sukhanov4f08faa2019-05-21 18:12:5719#include "api/media_transport_config.h"
Steve Anton10542f22019-01-11 17:11:0020#include "media/base/media_constants.h"
21#include "media/base/rtp_utils.h"
Zhi Huang365381f2018-04-13 23:44:3422#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Anton Sukhanov4f08faa2019-05-21 18:12:5723#include "p2p/base/packet_transport_internal.h"
24#include "pc/channel_manager.h"
25#include "pc/rtp_media_utils.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3126#include "rtc_base/bind.h"
Steve Anton10542f22019-01-11 17:11:0027#include "rtc_base/byte_order.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3128#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 17:11:0029#include "rtc_base/copy_on_write_buffer.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3130#include "rtc_base/dscp.h"
31#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 17:11:0032#include "rtc_base/network_route.h"
Jonas Olsson366a50c2018-09-06 11:41:3033#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3134#include "rtc_base/trace_event.h"
henrike@webrtc.org28e20752013-07-10 00:45:3635
36namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5237using rtc::Bind;
Amit Hilbuchbcd39d42019-01-26 01:13:5638using rtc::UniqueRandomIdGenerator;
Steve Anton3828c062017-12-06 18:34:5139using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:2640
deadbeef2d110be2016-01-13 20:00:2641namespace {
Danil Chapovalov33b01f22016-05-11 17:55:2742
43struct SendPacketMessageData : public rtc::MessageData {
44 rtc::CopyOnWriteBuffer packet;
45 rtc::PacketOptions options;
46};
47
Amit Hilbuchbcd39d42019-01-26 01:13:5648// 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 20:00:2681} // namespace
82
henrike@webrtc.org28e20752013-07-10 00:45:3683enum {
Steve Anton0807d152018-03-05 19:23:0984 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 17:55:2785 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:3686 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:3687 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:3688 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:3689};
90
sergeyu@chromium.org4b26e2e2014-01-15 23:15:5491static 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 23:05:3497template <class Codec>
98void RtpParametersFromMediaDescription(
99 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 19:31:36100 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 23:05:34101 RtpParameters<Codec>* params) {
102 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 19:36:43103 // a description without codecs. Currently the ORTC implementation is relying
104 // on this.
Peter Thatcherc2ee2c82015-08-07 23:05:34105 if (desc->has_codecs()) {
106 params->codecs = desc->codecs();
107 }
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 19:31:36111 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 23:05:34112 }
deadbeef13871492015-12-09 20:37:51113 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Peter Thatcherc2ee2c82015-08-07 23:05:34114}
115
nisse05103312016-03-16 09:22:50116template <class Codec>
Peter Thatcherc2ee2c82015-08-07 23:05:34117void RtpSendParametersFromMediaDescription(
118 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 19:31:36119 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 09:22:50120 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 19:31:36121 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 23:05:34122 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 10:22:05123 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 23:05:34124}
125
Danil Chapovalov33b01f22016-05-11 17:55:27126BaseChannel::BaseChannel(rtc::Thread* worker_thread,
127 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-13 03:37:48128 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 23:53:33129 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 18:50:27130 const std::string& content_name,
Zhi Huange830e682018-03-30 17:48:35131 bool srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56132 webrtc::CryptoOptions crypto_options,
133 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 17:55:27134 : worker_thread_(worker_thread),
135 network_thread_(network_thread),
zhihuangf5b251b2017-01-13 03:37:48136 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36137 content_name_(content_name),
deadbeef7af91dd2016-12-13 19:29:11138 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 17:48:35139 crypto_options_(crypto_options),
Amit Hilbuchbcd39d42019-01-26 01:13:56140 media_channel_(std::move(media_channel)),
141 ssrc_generator_(ssrc_generator) {
Steve Anton8699a322017-11-06 23:53:33142 RTC_DCHECK_RUN_ON(worker_thread_);
Amit Hilbuchbcd39d42019-01-26 01:13:56143 RTC_DCHECK(ssrc_generator_);
Zhi Huang365381f2018-04-13 23:44:34144 demuxer_criteria_.mid = content_name;
Mirko Bonadei675513b2017-11-09 10:09:25145 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36146}
147
148BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 22:24:13149 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 23:53:33150 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58151
Anton Sukhanov4f08faa2019-05-21 18:12:57152 if (media_transport_config_.media_transport) {
153 media_transport_config_.media_transport->RemoveNetworkChangeCallback(this);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58154 }
155
Danil Chapovalov33b01f22016-05-11 17:55:27156 // Eats any outstanding messages or packets.
157 worker_thread_->Clear(&invoker_);
158 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36159 // We must destroy the media channel before the transport channel, otherwise
160 // the media channel may try to send on the dead transport channel. NULLing
161 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 23:53:33162 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 10:09:25163 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 17:55:27164}
165
Zhi Huang365381f2018-04-13 23:44:34166bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 18:41:57167 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 23:44:34168 if (!RegisterRtpDemuxerSink()) {
169 return false;
170 }
Zhi Huangcd3fc5d2017-11-29 18:41:57171 rtp_transport_->SignalReadyToSend.connect(
172 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang365381f2018-04-13 23:44:34173 rtp_transport_->SignalRtcpPacketReceived.connect(
174 this, &BaseChannel::OnRtcpPacketReceived);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58175
176 // If media transport is used, it's responsible for providing network
177 // route changed callbacks.
Anton Sukhanov4f08faa2019-05-21 18:12:57178 if (!media_transport_config_.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 17:57:58179 rtp_transport_->SignalNetworkRouteChanged.connect(
180 this, &BaseChannel::OnNetworkRouteChanged);
181 }
182 // TODO(bugs.webrtc.org/9719): Media transport should also be used to provide
183 // 'writable' state here.
Zhi Huangcd3fc5d2017-11-29 18:41:57184 rtp_transport_->SignalWritableState.connect(this,
185 &BaseChannel::OnWritableState);
186 rtp_transport_->SignalSentPacket.connect(this,
187 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 23:44:34188 return true;
Zhi Huangcd3fc5d2017-11-29 18:41:57189}
Danil Chapovalovdae07ba2016-05-13 23:43:50190
Zhi Huangcd3fc5d2017-11-29 18:41:57191void BaseChannel::DisconnectFromRtpTransport() {
192 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 23:44:34193 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 18:41:57194 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang365381f2018-04-13 23:44:34195 rtp_transport_->SignalRtcpPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 18:41:57196 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
197 rtp_transport_->SignalWritableState.disconnect(this);
198 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-13 23:43:50199}
200
Anton Sukhanov4f08faa2019-05-21 18:12:57201void BaseChannel::Init_w(
202 webrtc::RtpTransportInternal* rtp_transport,
203 const webrtc::MediaTransportConfig& media_transport_config) {
Zhi Huang2dfc42d2017-12-04 21:38:48204 RTC_DCHECK_RUN_ON(worker_thread_);
Anton Sukhanov4f08faa2019-05-21 18:12:57205 media_transport_config_ = media_transport_config;
Piotr (Peter) Slatala179a3922018-11-16 17:57:58206
Zhi Huang365381f2018-04-13 23:44:34207 network_thread_->Invoke<void>(
208 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 21:38:48209
210 // Both RTP and RTCP channels should be set, we can call SetInterface on
211 // the media channel and it can set network options.
Anton Sukhanov4f08faa2019-05-21 18:12:57212 media_channel_->SetInterface(this, media_transport_config);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58213
Anton Sukhanov4f08faa2019-05-21 18:12:57214 RTC_LOG(LS_INFO) << "BaseChannel::Init_w, media_transport_config="
215 << media_transport_config.DebugString();
216 if (media_transport_config_.media_transport) {
217 media_transport_config_.media_transport->AddNetworkChangeCallback(this);
Piotr (Peter) Slatala179a3922018-11-16 17:57:58218 }
Danil Chapovalov33b01f22016-05-11 17:55:27219}
220
wu@webrtc.org78187522013-10-07 23:32:02221void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 17:55:27222 RTC_DCHECK(worker_thread_->IsCurrent());
Anton Sukhanov98a462c2018-10-17 20:15:42223 media_channel_->SetInterface(/*iface=*/nullptr,
Anton Sukhanov4f08faa2019-05-21 18:12:57224 webrtc::MediaTransportConfig());
Danil Chapovalovdae07ba2016-05-13 23:43:50225 // Packets arrive on the network thread, processing packets calls virtual
226 // functions, so need to stop this process in Deinit that is called in
227 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 18:41:57228 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03229 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-27 04:37:23230
Zhi Huange830e682018-03-30 17:48:35231 if (rtp_transport_) {
232 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03233 }
Zhi Huangcd3fc5d2017-11-29 18:41:57234 // Clear pending read packets/messages.
235 network_thread_->Clear(&invoker_);
236 network_thread_->Clear(this);
237 });
wu@webrtc.org78187522013-10-07 23:32:02238}
239
Zhi Huang365381f2018-04-13 23:44:34240bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
241 if (rtp_transport == rtp_transport_) {
242 return true;
243 }
244
Zhi Huang2dfc42d2017-12-04 21:38:48245 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 23:44:34246 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
247 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 21:38:48248 });
249 }
Zhi Huang95e7dbb2018-03-29 00:08:03250
Zhi Huang2dfc42d2017-12-04 21:38:48251 if (rtp_transport_) {
252 DisconnectFromRtpTransport();
253 }
Zhi Huange830e682018-03-30 17:48:35254
Zhi Huang2dfc42d2017-12-04 21:38:48255 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 17:48:35256 if (rtp_transport_) {
Bjorn A Mellem3a1b9272019-05-24 23:13:08257 transport_name_ = rtp_transport_->transport_name();
Zhi Huang2dfc42d2017-12-04 21:38:48258
Zhi Huang365381f2018-04-13 23:44:34259 if (!ConnectToRtpTransport()) {
260 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport.";
261 return false;
262 }
Zhi Huange830e682018-03-30 17:48:35263 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
264 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 21:38:48265
Zhi Huange830e682018-03-30 17:48:35266 // Set the cached socket options.
267 for (const auto& pair : socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 23:13:08268 rtp_transport_->SetRtpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 17:48:35269 }
Bjorn A Mellem3a1b9272019-05-24 23:13:08270 if (!rtp_transport_->rtcp_mux_enabled()) {
Zhi Huange830e682018-03-30 17:48:35271 for (const auto& pair : rtcp_socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 23:13:08272 rtp_transport_->SetRtcpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 17:48:35273 }
274 }
guoweis46383312015-12-18 00:45:59275 }
Zhi Huang365381f2018-04-13 23:44:34276 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12277}
278
henrike@webrtc.org28e20752013-07-10 00:45:36279bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 21:17:27280 worker_thread_->Invoke<void>(
281 RTC_FROM_HERE,
282 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
283 this));
henrike@webrtc.org28e20752013-07-10 00:45:36284 return true;
285}
286
henrike@webrtc.org28e20752013-07-10 00:45:36287bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:51288 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54289 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:57290 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 13:44:03291 return InvokeOnWorker<bool>(
292 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 18:34:51293 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36294}
295
296bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:51297 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54298 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:57299 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 13:44:03300 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 18:34:51301 RTC_FROM_HERE,
302 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36303}
304
Taylor Brandstetterbad33bf2016-08-25 20:31:14305bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36306 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 22:57:10307 return enabled() &&
308 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36309}
310
Taylor Brandstetterbad33bf2016-08-25 20:31:14311bool BaseChannel::IsReadyToSendMedia_w() const {
312 // Need to access some state updated on the network thread.
313 return network_thread_->Invoke<bool>(
314 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
315}
316
317bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36318 // Send outgoing data if we are enabled, have local and remote content,
319 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 22:57:10320 return enabled() &&
321 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
322 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 23:44:34323 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36324}
325
jbaucheec21bd2016-03-20 13:15:43326bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 14:26:07327 const rtc::PacketOptions& options) {
328 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36329}
330
jbaucheec21bd2016-03-20 13:15:43331bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 14:26:07332 const rtc::PacketOptions& options) {
333 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36334}
335
Yves Gerey665174f2018-06-19 13:03:05336int BaseChannel::SetOption(SocketType type,
337 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36338 int value) {
Danil Chapovalov33b01f22016-05-11 17:55:27339 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:27340 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 17:55:27341}
342
343int BaseChannel::SetOption_n(SocketType type,
344 rtc::Socket::Option opt,
345 int value) {
346 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 17:48:35347 RTC_DCHECK(rtp_transport_);
henrike@webrtc.org28e20752013-07-10 00:45:36348 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07349 case ST_RTP:
deadbeefcbecd352015-09-23 18:50:27350 socket_options_.push_back(
351 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 23:13:08352 return rtp_transport_->SetRtpOption(opt, value);
wu@webrtc.org9caf2762013-12-11 18:25:07353 case ST_RTCP:
deadbeefcbecd352015-09-23 18:50:27354 rtcp_socket_options_.push_back(
355 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 23:13:08356 return rtp_transport_->SetRtcpOption(opt, value);
henrike@webrtc.org28e20752013-07-10 00:45:36357 }
Bjorn A Mellem3a1b9272019-05-24 23:13:08358 return -1;
henrike@webrtc.org28e20752013-07-10 00:45:36359}
360
Zhi Huangcd3fc5d2017-11-29 18:41:57361void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 17:55:27362 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 18:41:57363 if (writable) {
Zhi Huangcd3fc5d2017-11-29 18:41:57364 ChannelWritable_n();
365 } else {
366 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 17:59:56367 }
368}
369
Zhi Huang942bc2e2017-11-13 21:26:07370void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 14:47:43371 absl::optional<rtc::NetworkRoute> network_route) {
Piotr (Peter) Slatala179a3922018-11-16 17:57:58372 RTC_LOG(LS_INFO) << "Network route was changed.";
373
Danil Chapovalov33b01f22016-05-11 17:55:27374 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 21:26:07375 rtc::NetworkRoute new_route;
376 if (network_route) {
Zhi Huang942bc2e2017-11-13 21:26:07377 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45378 }
Zhi Huang942bc2e2017-11-13 21:26:07379 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
380 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
381 // work correctly. Intentionally leave it broken to simplify the code and
382 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 23:53:33383 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 21:26:07384 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 23:53:33385 });
Honghai Zhangcc411c02016-03-30 00:27:21386}
387
zstein56162b92017-04-24 23:54:35388void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 23:53:33389 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
390 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36391}
392
stefanc1aeaf02015-10-15 14:26:07393bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 13:15:43394 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 14:26:07395 const rtc::PacketOptions& options) {
Amit Hilbuchedd20542019-03-18 19:33:43396 // Until all the code is migrated to use RtpPacketType instead of bool.
397 RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
Danil Chapovalov33b01f22016-05-11 17:55:27398 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
399 // If the thread is not our network thread, we will post to our network
400 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36401 // synchronize access to all the pieces of the send path, including
402 // SRTP and the inner workings of the transport channels.
403 // The only downside is that we can't return a proper failure code if
404 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 17:55:27405 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36406 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 17:55:27407 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
408 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 11:04:15409 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 14:26:07410 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 21:17:27411 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36412 return true;
413 }
Zhi Huange830e682018-03-30 17:48:35414
Danil Chapovalov33b01f22016-05-11 17:55:27415 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36416
417 // Now that we are on the correct thread, ensure we have a place to send this
418 // packet before doing anything. (We might get RTCP packets that we don't
419 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
420 // transport.
Zhi Huange830e682018-03-30 17:48:35421 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36422 return false;
423 }
424
425 // Protect ourselves against crazy data.
Amit Hilbuchedd20542019-03-18 19:33:43426 if (!IsValidRtpPacketSize(packet_type, packet->size())) {
Mirko Bonadei675513b2017-11-09 10:09:25427 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
Amit Hilbuchedd20542019-03-18 19:33:43428 << RtpPacketTypeToString(packet_type)
Mirko Bonadei675513b2017-11-09 10:09:25429 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36430 return false;
431 }
432
Zhi Huangcf990f52017-09-22 19:12:30433 if (!srtp_active()) {
434 if (srtp_required_) {
435 // The audio/video engines may attempt to send RTCP packets as soon as the
436 // streams are created, so don't treat this as an error for RTCP.
437 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
438 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36439 return false;
440 }
Zhi Huangcf990f52017-09-22 19:12:30441 // However, there shouldn't be any RTP packets sent before SRTP is set up
442 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 10:09:25443 RTC_LOG(LS_ERROR)
444 << "Can't send outgoing RTP packet when SRTP is inactive"
445 << " and crypto is required";
Zhi Huangcf990f52017-09-22 19:12:30446 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 20:26:27447 return false;
448 }
Zhi Huangcd3fc5d2017-11-29 18:41:57449
450 std::string packet_type = rtcp ? "RTCP" : "RTP";
451 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
452 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36453 }
Zhi Huange830e682018-03-30 17:48:35454
henrike@webrtc.org28e20752013-07-10 00:45:36455 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 18:41:57456 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
457 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36458}
459
Zhi Huang365381f2018-04-13 23:44:34460void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Niels Möller29e13fd2018-12-17 11:35:30461 // Take packet time from the |parsed_packet|.
462 // RtpPacketReceived.arrival_time_ms = (timestamp_us + 500) / 1000;
Niels Möllere6933812018-11-05 12:01:41463 int64_t timestamp_us = -1;
Zhi Huang365381f2018-04-13 23:44:34464 if (parsed_packet.arrival_time_ms() > 0) {
Niels Möllere6933812018-11-05 12:01:41465 timestamp_us = parsed_packet.arrival_time_ms() * 1000;
Zhi Huang365381f2018-04-13 23:44:34466 }
Zhi Huang365381f2018-04-13 23:44:34467
Niels Möllere6933812018-11-05 12:01:41468 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), timestamp_us);
Zhi Huang365381f2018-04-13 23:44:34469}
470
471void BaseChannel::UpdateRtpHeaderExtensionMap(
472 const RtpHeaderExtensions& header_extensions) {
473 RTC_DCHECK(rtp_transport_);
474 // Update the header extension map on network thread in case there is data
475 // race.
476 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
477 // be accessed from different threads.
478 //
479 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
480 // extension maps are not merged when BUNDLE is enabled. This is fine because
481 // the ID for MID should be consistent among all the RTP transports.
482 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
483 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
484 });
485}
486
487bool BaseChannel::RegisterRtpDemuxerSink() {
488 RTC_DCHECK(rtp_transport_);
489 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
490 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
491 });
492}
493
494void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
Niels Möllere6933812018-11-05 12:01:41495 int64_t packet_time_us) {
496 OnPacketReceived(/*rtcp=*/true, *packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36497}
498
zstein3dcf0e92017-06-01 20:22:42499void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang365381f2018-04-13 23:44:34500 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 12:01:41501 int64_t packet_time_us) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33502 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36503 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 21:17:27504 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36505 }
506
Zhi Huangcf990f52017-09-22 19:12:30507 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36508 // Our session description indicates that SRTP is required, but we got a
509 // packet before our SRTP filter is active. This means either that
510 // a) we got SRTP packets before we received the SDES keys, in which case
511 // we can't decrypt it anyway, or
512 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-20 00:54:25513 // transports, so we haven't yet extracted keys, even if DTLS did
514 // complete on the transport that the packets are being sent on. It's
515 // really good practice to wait for both RTP and RTCP to be good to go
516 // before sending media, to prevent weird failure modes, so it's fine
517 // for us to just eat packets here. This is all sidestepped if RTCP mux
518 // is used anyway.
Mirko Bonadei675513b2017-11-09 10:09:25519 RTC_LOG(LS_WARNING)
Amit Hilbuchedd20542019-03-18 19:33:43520 << "Can't process incoming "
521 << RtpPacketTypeToString(rtcp ? RtpPacketType::kRtcp
522 : RtpPacketType::kRtp)
Mirko Bonadei675513b2017-11-09 10:09:25523 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36524 return;
525 }
526
Danil Chapovalov33b01f22016-05-11 17:55:27527 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:27528 RTC_FROM_HERE, worker_thread_,
Niels Möllere6933812018-11-05 12:01:41529 Bind(&BaseChannel::ProcessPacket, this, rtcp, packet, packet_time_us));
Danil Chapovalov33b01f22016-05-11 17:55:27530}
531
zstein3dcf0e92017-06-01 20:22:42532void BaseChannel::ProcessPacket(bool rtcp,
533 const rtc::CopyOnWriteBuffer& packet,
Niels Möllere6933812018-11-05 12:01:41534 int64_t packet_time_us) {
Danil Chapovalov33b01f22016-05-11 17:55:27535 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 20:22:42536
Danil Chapovalov33b01f22016-05-11 17:55:27537 if (rtcp) {
Amit Hilbuche7a5f7b2019-03-12 18:10:27538 media_channel_->OnRtcpReceived(packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36539 } else {
Amit Hilbuche7a5f7b2019-03-12 18:10:27540 media_channel_->OnPacketReceived(packet, packet_time_us);
henrike@webrtc.org28e20752013-07-10 00:45:36541 }
542}
543
henrike@webrtc.org28e20752013-07-10 00:45:36544void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 20:31:14545 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36546 if (enabled_)
547 return;
548
Mirko Bonadei675513b2017-11-09 10:09:25549 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36550 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 20:31:14551 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36552}
553
554void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 20:31:14555 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36556 if (!enabled_)
557 return;
558
Mirko Bonadei675513b2017-11-09 10:09:25559 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36560 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 20:31:14561 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36562}
563
Danil Chapovalov33b01f22016-05-11 17:55:27564void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 17:48:35565 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
566 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 17:55:27567 ChannelWritable_n();
deadbeefcbecd352015-09-23 18:50:27568 } else {
Danil Chapovalov33b01f22016-05-11 17:55:27569 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 18:50:27570 }
571}
572
Danil Chapovalov33b01f22016-05-11 17:55:27573void BaseChannel::ChannelWritable_n() {
574 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 17:59:56575 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36576 return;
Guo-wei Shieh1218d7a2015-12-05 17:59:56577 }
henrike@webrtc.org28e20752013-07-10 00:45:36578
Mirko Bonadei675513b2017-11-09 10:09:25579 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
580 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36581
henrike@webrtc.org28e20752013-07-10 00:45:36582 was_ever_writable_ = true;
583 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 20:31:14584 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36585}
586
Danil Chapovalov33b01f22016-05-11 17:55:27587void BaseChannel::ChannelNotWritable_n() {
588 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36589 if (!writable_)
590 return;
591
Mirko Bonadei675513b2017-11-09 10:09:25592 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36593 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 20:31:14594 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36595}
596
henrike@webrtc.org28e20752013-07-10 00:45:36597bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 20:31:14598 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 18:19:58599 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36600}
601
Peter Boström0c4e06b2015-10-07 10:23:21602bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 20:31:14603 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36604 return media_channel()->RemoveRecvStream(ssrc);
605}
606
607bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 18:34:51608 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54609 std::string* error_desc) {
Amit Hilbuchbcd39d42019-01-26 01:13:56610 // In the case of RIDs (where SSRCs are not negotiated), this method will
611 // generate an SSRC for each layer in StreamParams. That representation will
612 // be stored internally in |local_streams_|.
613 // In subsequent offers, the same stream can appear in |streams| again
614 // (without the SSRCs), so it should be looked up using RIDs (if available)
615 // and then by primary SSRC.
616 // In both scenarios, it is safe to assume that the media channel will be
617 // created with a StreamParams object with SSRCs. However, it is not safe to
618 // assume that |local_streams_| will always have SSRCs as there are scenarios
619 // in which niether SSRCs or RIDs are negotiated.
620
henrike@webrtc.org28e20752013-07-10 00:45:36621 // Check for streams that have been removed.
622 bool ret = true;
Steve Anton5f8b5fd2018-12-28 00:58:10623 for (const StreamParams& old_stream : local_streams_) {
Amit Hilbuchbcd39d42019-01-26 01:13:56624 if (!old_stream.has_ssrcs() ||
625 GetStream(streams, StreamFinder(&old_stream))) {
626 continue;
627 }
628 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
629 rtc::StringBuilder desc;
630 desc << "Failed to remove send stream with ssrc "
631 << old_stream.first_ssrc() << ".";
632 SafeSetError(desc.str(), error_desc);
633 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36634 }
635 }
636 // Check for new streams.
Amit Hilbuchbcd39d42019-01-26 01:13:56637 std::vector<StreamParams> all_streams;
638 for (const StreamParams& stream : streams) {
639 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
640 if (existing) {
641 // Parameters cannot change for an existing stream.
642 all_streams.push_back(*existing);
643 continue;
644 }
645
646 all_streams.push_back(stream);
647 StreamParams& new_stream = all_streams.back();
648
649 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
650 continue;
651 }
652
653 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
654 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
655 rtc::StringBuilder desc;
656 desc << "Failed to add send stream: " << new_stream.first_ssrc()
657 << ". Stream has both SSRCs and RIDs.";
658 SafeSetError(desc.str(), error_desc);
659 ret = false;
660 continue;
661 }
662
663 // At this point we use the legacy simulcast group in StreamParams to
664 // indicate that we want multiple layers to the media channel.
665 if (!new_stream.has_ssrcs()) {
666 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
667 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
668 /* flex_fec = */ false, ssrc_generator_);
669 }
670
671 if (media_channel()->AddSendStream(new_stream)) {
672 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0];
673 } else {
674 rtc::StringBuilder desc;
675 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc();
676 SafeSetError(desc.str(), error_desc);
677 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36678 }
679 }
Amit Hilbuchbcd39d42019-01-26 01:13:56680 local_streams_ = all_streams;
henrike@webrtc.org28e20752013-07-10 00:45:36681 return ret;
682}
683
684bool BaseChannel::UpdateRemoteStreams_w(
685 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 18:34:51686 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54687 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36688 // Check for streams that have been removed.
689 bool ret = true;
Steve Anton5f8b5fd2018-12-28 00:58:10690 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 18:16:33691 // If we no longer have an unsignaled stream, we would like to remove
692 // the unsignaled stream params that are cached.
Steve Anton5f8b5fd2018-12-28 00:58:10693 if ((!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
694 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
695 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
696 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc();
Zhi Huang365381f2018-04-13 23:44:34697 } else {
Jonas Olsson366a50c2018-09-06 11:41:30698 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-28 00:58:10699 desc << "Failed to remove remote stream with ssrc "
700 << old_stream.first_ssrc() << ".";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54701 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36702 ret = false;
703 }
704 }
705 }
Zhi Huang365381f2018-04-13 23:44:34706 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36707 // Check for new streams.
Steve Anton5f8b5fd2018-12-28 00:58:10708 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 18:16:33709 // We allow a StreamParams with an empty list of SSRCs, in which case the
710 // MediaChannel will cache the parameters and use them for any unsignaled
711 // stream received later.
Steve Anton5f8b5fd2018-12-28 00:58:10712 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
713 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
714 if (AddRecvStream_w(new_stream)) {
715 RTC_LOG(LS_INFO) << "Add remote ssrc: " << new_stream.first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36716 } else {
Jonas Olsson366a50c2018-09-06 11:41:30717 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-28 00:58:10718 desc << "Failed to add remote stream ssrc: " << new_stream.first_ssrc();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54719 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36720 ret = false;
721 }
722 }
Zhi Huang365381f2018-04-13 23:44:34723 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-28 00:58:10724 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
725 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36726 }
Zhi Huang365381f2018-04-13 23:44:34727 // Re-register the sink to update the receiving ssrcs.
728 RegisterRtpDemuxerSink();
henrike@webrtc.org28e20752013-07-10 00:45:36729 remote_streams_ = streams;
730 return ret;
731}
732
jbauch5869f502017-06-29 19:31:36733RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
734 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 17:48:35735 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 22:33:17736 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 19:31:36737 RtpHeaderExtensions filtered;
Steve Anton64b626b2019-01-29 01:25:26738 absl::c_copy_if(extensions, std::back_inserter(filtered),
739 [](const webrtc::RtpExtension& extension) {
740 return !extension.encrypt;
741 });
jbauch5869f502017-06-29 19:31:36742 return filtered;
743 }
744
745 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
746}
747
Yves Gerey665174f2018-06-19 13:03:05748void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 22:17:15749 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36750 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 17:55:27751 case MSG_SEND_RTP_PACKET:
752 case MSG_SEND_RTCP_PACKET: {
753 RTC_DCHECK(network_thread_->IsCurrent());
754 SendPacketMessageData* data =
755 static_cast<SendPacketMessageData*>(pmsg->pdata);
756 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
757 SendPacket(rtcp, &data->packet, data->options);
758 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36759 break;
760 }
761 case MSG_FIRSTPACKETRECEIVED: {
Amit Hilbuchdd9390c2018-11-14 00:26:05762 SignalFirstPacketReceived_(this);
henrike@webrtc.org28e20752013-07-10 00:45:36763 break;
764 }
henrike@webrtc.org28e20752013-07-10 00:45:36765 }
766}
767
zstein3dcf0e92017-06-01 20:22:42768void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 23:44:34769 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 20:22:42770}
771
Danil Chapovalov33b01f22016-05-11 17:55:27772void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36773 // Flush all remaining RTCP messages. This should only be called in
774 // destructor.
Danil Chapovalov33b01f22016-05-11 17:55:27775 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52776 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 17:55:27777 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
778 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 21:17:27779 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
780 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36781 }
782}
783
Zhi Huangcd3fc5d2017-11-29 18:41:57784void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 17:55:27785 RTC_DCHECK(network_thread_->IsCurrent());
786 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:27787 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 17:55:27788 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
789}
790
791void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
792 RTC_DCHECK(worker_thread_->IsCurrent());
793 SignalSentPacket(sent_packet);
794}
795
796VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
797 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-13 03:37:48798 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 23:53:33799 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36800 const std::string& content_name,
Zhi Huange830e682018-03-30 17:48:35801 bool srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56802 webrtc::CryptoOptions crypto_options,
803 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 17:55:27804 : BaseChannel(worker_thread,
805 network_thread,
zhihuangf5b251b2017-01-13 03:37:48806 signaling_thread,
Steve Anton8699a322017-11-06 23:53:33807 std::move(media_channel),
deadbeefcbecd352015-09-23 18:50:27808 content_name,
Zhi Huange830e682018-03-30 17:48:35809 srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56810 crypto_options,
811 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36812
813VoiceChannel::~VoiceChannel() {
Piotr (Peter) Slatala309aafe2019-01-15 22:24:34814 if (media_transport()) {
815 media_transport()->SetFirstAudioPacketReceivedObserver(nullptr);
816 }
Peter Boströmca8b4042016-03-08 22:24:13817 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36818 // this can't be done in the base class, since it calls a virtual
819 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 20:17:42820 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36821}
822
Taylor Brandstetterbad33bf2016-08-25 20:31:14823void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 17:55:27824 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 20:31:14825 invoker_.AsyncInvoke<void>(
826 RTC_FROM_HERE, worker_thread_,
827 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 17:55:27828}
829
Piotr (Peter) Slatala179a3922018-11-16 17:57:58830void BaseChannel::OnNetworkRouteChanged(
831 const rtc::NetworkRoute& network_route) {
832 OnNetworkRouteChanged(absl::make_optional(network_route));
833}
834
Anton Sukhanov4f08faa2019-05-21 18:12:57835void VoiceChannel::Init_w(
836 webrtc::RtpTransportInternal* rtp_transport,
837 const webrtc::MediaTransportConfig& media_transport_config) {
838 BaseChannel::Init_w(rtp_transport, media_transport_config);
839 if (media_transport_config.media_transport) {
840 media_transport_config.media_transport->SetFirstAudioPacketReceivedObserver(
841 this);
Piotr (Peter) Slatala309aafe2019-01-15 22:24:34842 }
843}
844
845void VoiceChannel::OnFirstAudioPacketReceived(int64_t channel_id) {
846 has_received_packet_ = true;
847 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
848}
849
Taylor Brandstetterbad33bf2016-08-25 20:31:14850void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36851 // Render incoming data if we're the active call, and we have the local
852 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 20:31:14853 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 11:10:31854 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36855
856 // Send outgoing data if we're the active call, we have the remote content,
857 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 20:31:14858 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 20:37:39859 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36860
Mirko Bonadei675513b2017-11-09 10:09:25861 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36862}
863
henrike@webrtc.org28e20752013-07-10 00:45:36864bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:51865 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54866 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:57867 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 23:14:30868 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:25869 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36870
Steve Antonb1c1de12017-12-21 23:14:30871 RTC_DCHECK(content);
872 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54873 SafeSetError("Can't find audio content in local description.", error_desc);
874 return false;
875 }
henrike@webrtc.org28e20752013-07-10 00:45:36876
Steve Antonb1c1de12017-12-21 23:14:30877 const AudioContentDescription* audio = content->as_audio();
878
jbauch5869f502017-06-29 19:31:36879 RtpHeaderExtensions rtp_header_extensions =
880 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 23:44:34881 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 10:22:05882 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 19:31:36883
Peter Thatcherc2ee2c82015-08-07 23:05:34884 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 19:31:36885 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 23:05:34886 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-21 00:40:24887 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 23:05:34888 error_desc);
889 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36890 }
Peter Thatcherc2ee2c82015-08-07 23:05:34891 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 20:22:42892 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 23:05:34893 }
Zhi Huang365381f2018-04-13 23:44:34894 // Need to re-register the sink to update the handled payload.
895 if (!RegisterRtpDemuxerSink()) {
896 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
897 return false;
898 }
899
Peter Thatcherc2ee2c82015-08-07 23:05:34900 last_recv_params_ = recv_params;
901
902 // TODO(pthatcher): Move local streams into AudioSendParameters, and
903 // only give it to the media channel once we have a remote
904 // description too (without a remote description, we won't be able
905 // to send them anyway).
Steve Anton3828c062017-12-06 18:34:51906 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:34907 SafeSetError("Failed to set local audio description streams.", error_desc);
908 return false;
909 }
910
911 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:14912 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:34913 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36914}
915
916bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:51917 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54918 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:57919 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 23:14:30920 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:25921 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36922
Steve Antonb1c1de12017-12-21 23:14:30923 RTC_DCHECK(content);
924 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54925 SafeSetError("Can't find audio content in remote description.", error_desc);
926 return false;
927 }
henrike@webrtc.org28e20752013-07-10 00:45:36928
Steve Antonb1c1de12017-12-21 23:14:30929 const AudioContentDescription* audio = content->as_audio();
930
jbauch5869f502017-06-29 19:31:36931 RtpHeaderExtensions rtp_header_extensions =
932 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
933
Peter Thatcherc2ee2c82015-08-07 23:05:34934 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 19:31:36935 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
Yves Gerey665174f2018-06-19 13:03:05936 &send_params);
Steve Antonbb50ce52018-03-26 17:24:32937 send_params.mid = content_name();
skvladdc1c62c2016-03-17 02:07:43938
939 bool parameters_applied = media_channel()->SetSendParameters(send_params);
940 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 23:05:34941 SafeSetError("Failed to set remote audio description send parameters.",
942 error_desc);
943 return false;
944 }
945 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36946
Peter Thatcherc2ee2c82015-08-07 23:05:34947 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
948 // and only give it to the media channel once we have a local
949 // description too (without a local description, we won't be able to
950 // recv them anyway).
Steve Anton3828c062017-12-06 18:34:51951 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:34952 SafeSetError("Failed to set remote audio description streams.", error_desc);
953 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36954 }
955
Peter Thatcherc2ee2c82015-08-07 23:05:34956 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:14957 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:34958 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36959}
960
Danil Chapovalov33b01f22016-05-11 17:55:27961VideoChannel::VideoChannel(rtc::Thread* worker_thread,
962 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-13 03:37:48963 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 23:53:33964 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36965 const std::string& content_name,
Zhi Huange830e682018-03-30 17:48:35966 bool srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56967 webrtc::CryptoOptions crypto_options,
968 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 17:55:27969 : BaseChannel(worker_thread,
970 network_thread,
zhihuangf5b251b2017-01-13 03:37:48971 signaling_thread,
Steve Anton8699a322017-11-06 23:53:33972 std::move(media_channel),
deadbeefcbecd352015-09-23 18:50:27973 content_name,
Zhi Huange830e682018-03-30 17:48:35974 srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:56975 crypto_options,
976 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36977
henrike@webrtc.org28e20752013-07-10 00:45:36978VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 22:24:13979 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36980 // this can't be done in the base class, since it calls a virtual
981 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 20:17:42982 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36983}
984
Taylor Brandstetterbad33bf2016-08-25 20:31:14985void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36986 // Send outgoing data if we're the active call, we have the remote content,
987 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 20:31:14988 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36989 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 10:09:25990 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36991 // TODO(gangji): Report error back to server.
992 }
993
Mirko Bonadei675513b2017-11-09 10:09:25994 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36995}
996
stefanf79ade12017-06-02 13:44:03997void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
998 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
999 media_channel(), bwe_info));
1000}
1001
henrike@webrtc.org28e20752013-07-10 00:45:361002bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:511003 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541004 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:571005 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 23:14:301006 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:251007 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:361008
Steve Antonb1c1de12017-12-21 23:14:301009 RTC_DCHECK(content);
1010 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541011 SafeSetError("Can't find video content in local description.", error_desc);
1012 return false;
1013 }
henrike@webrtc.org28e20752013-07-10 00:45:361014
Steve Antonb1c1de12017-12-21 23:14:301015 const VideoContentDescription* video = content->as_video();
1016
jbauch5869f502017-06-29 19:31:361017 RtpHeaderExtensions rtp_header_extensions =
1018 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 23:44:341019 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 10:22:051020 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 19:31:361021
Peter Thatcherc2ee2c82015-08-07 23:05:341022 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 19:31:361023 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 23:05:341024 if (!media_channel()->SetRecvParameters(recv_params)) {
1025 SafeSetError("Failed to set local video description recv parameters.",
1026 error_desc);
1027 return false;
1028 }
1029 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 20:22:421030 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 23:05:341031 }
Zhi Huang365381f2018-04-13 23:44:341032 // Need to re-register the sink to update the handled payload.
1033 if (!RegisterRtpDemuxerSink()) {
1034 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
1035 return false;
1036 }
1037
Peter Thatcherc2ee2c82015-08-07 23:05:341038 last_recv_params_ = recv_params;
1039
1040 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1041 // only give it to the media channel once we have a remote
1042 // description too (without a remote description, we won't be able
1043 // to send them anyway).
Steve Anton3828c062017-12-06 18:34:511044 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:341045 SafeSetError("Failed to set local video description streams.", error_desc);
1046 return false;
henrike@webrtc.org28e20752013-07-10 00:45:361047 }
1048
Peter Thatcherc2ee2c82015-08-07 23:05:341049 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:141050 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:341051 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361052}
1053
1054bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:511055 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541056 std::string* error_desc) {
Peter Boström9f45a452015-12-08 12:25:571057 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 23:14:301058 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:251059 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:361060
Steve Antonb1c1de12017-12-21 23:14:301061 RTC_DCHECK(content);
1062 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541063 SafeSetError("Can't find video content in remote description.", error_desc);
1064 return false;
1065 }
henrike@webrtc.org28e20752013-07-10 00:45:361066
Steve Antonb1c1de12017-12-21 23:14:301067 const VideoContentDescription* video = content->as_video();
1068
jbauch5869f502017-06-29 19:31:361069 RtpHeaderExtensions rtp_header_extensions =
1070 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1071
Peter Thatcherc2ee2c82015-08-07 23:05:341072 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 19:31:361073 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
Yves Gerey665174f2018-06-19 13:03:051074 &send_params);
Peter Thatcherc2ee2c82015-08-07 23:05:341075 if (video->conference_mode()) {
nisse4b4dc862016-02-17 13:25:361076 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 23:05:341077 }
Steve Antonbb50ce52018-03-26 17:24:321078 send_params.mid = content_name();
skvladdc1c62c2016-03-17 02:07:431079
1080 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1081
1082 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 23:05:341083 SafeSetError("Failed to set remote video description send parameters.",
1084 error_desc);
1085 return false;
1086 }
1087 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:361088
Peter Thatcherc2ee2c82015-08-07 23:05:341089 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1090 // and only give it to the media channel once we have a local
1091 // description too (without a local description, we won't be able to
1092 // recv them anyway).
Steve Anton3828c062017-12-06 18:34:511093 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:341094 SafeSetError("Failed to set remote video description streams.", error_desc);
1095 return false;
henrike@webrtc.org28e20752013-07-10 00:45:361096 }
Peter Thatcherc2ee2c82015-08-07 23:05:341097 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:141098 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:341099 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361100}
1101
deadbeef953c2ce2017-01-09 22:53:411102RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1103 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-13 03:37:481104 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 23:53:331105 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 22:53:411106 const std::string& content_name,
Zhi Huange830e682018-03-30 17:48:351107 bool srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:561108 webrtc::CryptoOptions crypto_options,
1109 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 17:55:271110 : BaseChannel(worker_thread,
1111 network_thread,
zhihuangf5b251b2017-01-13 03:37:481112 signaling_thread,
Steve Anton8699a322017-11-06 23:53:331113 std::move(media_channel),
deadbeefcbecd352015-09-23 18:50:271114 content_name,
Zhi Huange830e682018-03-30 17:48:351115 srtp_required,
Amit Hilbuchbcd39d42019-01-26 01:13:561116 crypto_options,
1117 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:361118
deadbeef953c2ce2017-01-09 22:53:411119RtpDataChannel::~RtpDataChannel() {
1120 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:361121 // this can't be done in the base class, since it calls a virtual
1122 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 20:17:421123 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:361124}
1125
Anton Sukhanov4f08faa2019-05-21 18:12:571126void RtpDataChannel::Init_w(
1127 webrtc::RtpTransportInternal* rtp_transport,
1128 const webrtc::MediaTransportConfig& media_transport_config) {
1129 BaseChannel::Init_w(rtp_transport, media_transport_config);
Zhi Huang2dfc42d2017-12-04 21:38:481130 media_channel()->SignalDataReceived.connect(this,
1131 &RtpDataChannel::OnDataReceived);
1132 media_channel()->SignalReadyToSend.connect(
1133 this, &RtpDataChannel::OnDataChannelReadyToSend);
1134}
1135
deadbeef953c2ce2017-01-09 22:53:411136bool RtpDataChannel::SendData(const SendDataParams& params,
1137 const rtc::CopyOnWriteBuffer& payload,
1138 SendDataResult* result) {
stefanf79ade12017-06-02 13:44:031139 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:271140 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1141 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:361142}
1143
deadbeef953c2ce2017-01-09 22:53:411144bool RtpDataChannel::CheckDataChannelTypeFromContent(
Harald Alvestrand5fc28b12019-05-13 11:36:161145 const RtpDataContentDescription* content,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541146 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:361147 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1148 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 22:53:411149 // It's been set before, but doesn't match. That's bad.
1150 if (is_sctp) {
1151 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1152 error_desc);
1153 return false;
1154 }
1155 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361156}
1157
deadbeef953c2ce2017-01-09 22:53:411158bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:511159 SdpType type,
deadbeef953c2ce2017-01-09 22:53:411160 std::string* error_desc) {
1161 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 23:14:301162 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 10:09:251163 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:361164
Steve Antonb1c1de12017-12-21 23:14:301165 RTC_DCHECK(content);
1166 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541167 SafeSetError("Can't find data content in local description.", error_desc);
1168 return false;
1169 }
henrike@webrtc.org28e20752013-07-10 00:45:361170
Harald Alvestrand5fc28b12019-05-13 11:36:161171 const RtpDataContentDescription* data = content->as_rtp_data();
Steve Antonb1c1de12017-12-21 23:14:301172
deadbeef953c2ce2017-01-09 22:53:411173 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:361174 return false;
1175 }
1176
jbauch5869f502017-06-29 19:31:361177 RtpHeaderExtensions rtp_header_extensions =
1178 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1179
Peter Thatcherc2ee2c82015-08-07 23:05:341180 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 19:31:361181 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 23:05:341182 if (!media_channel()->SetRecvParameters(recv_params)) {
1183 SafeSetError("Failed to set remote data description recv parameters.",
1184 error_desc);
1185 return false;
henrike@webrtc.org28e20752013-07-10 00:45:361186 }
deadbeef953c2ce2017-01-09 22:53:411187 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 20:22:421188 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 23:05:341189 }
Zhi Huang365381f2018-04-13 23:44:341190 // Need to re-register the sink to update the handled payload.
1191 if (!RegisterRtpDemuxerSink()) {
1192 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1193 return false;
1194 }
1195
Peter Thatcherc2ee2c82015-08-07 23:05:341196 last_recv_params_ = recv_params;
1197
1198 // TODO(pthatcher): Move local streams into DataSendParameters, and
1199 // only give it to the media channel once we have a remote
1200 // description too (without a remote description, we won't be able
1201 // to send them anyway).
Steve Anton3828c062017-12-06 18:34:511202 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 23:05:341203 SafeSetError("Failed to set local data description streams.", error_desc);
1204 return false;
1205 }
1206
1207 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:141208 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:341209 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361210}
1211
deadbeef953c2ce2017-01-09 22:53:411212bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 18:34:511213 SdpType type,
deadbeef953c2ce2017-01-09 22:53:411214 std::string* error_desc) {
1215 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 23:14:301216 RTC_DCHECK_RUN_ON(worker_thread());
1217 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:361218
Steve Antonb1c1de12017-12-21 23:14:301219 RTC_DCHECK(content);
1220 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:541221 SafeSetError("Can't find data content in remote description.", error_desc);
1222 return false;
1223 }
henrike@webrtc.org28e20752013-07-10 00:45:361224
Harald Alvestrand5fc28b12019-05-13 11:36:161225 const RtpDataContentDescription* data = content->as_rtp_data();
1226
1227 if (!data) {
1228 RTC_LOG(LS_INFO) << "Accepting and ignoring non-RTP content description";
1229 return true;
1230 }
Steve Antonb1c1de12017-12-21 23:14:301231
Zhi Huang801b8682017-11-15 19:36:431232 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1233 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 23:05:341234 return true;
1235 }
1236
deadbeef953c2ce2017-01-09 22:53:411237 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:361238 return false;
1239 }
1240
jbauch5869f502017-06-29 19:31:361241 RtpHeaderExtensions rtp_header_extensions =
1242 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1243
Mirko Bonadei675513b2017-11-09 10:09:251244 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 23:05:341245 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 19:31:361246 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
Yves Gerey665174f2018-06-19 13:03:051247 &send_params);
Peter Thatcherc2ee2c82015-08-07 23:05:341248 if (!media_channel()->SetSendParameters(send_params)) {
1249 SafeSetError("Failed to set remote data description send parameters.",
1250 error_desc);
1251 return false;
henrike@webrtc.org28e20752013-07-10 00:45:361252 }
Peter Thatcherc2ee2c82015-08-07 23:05:341253 last_send_params_ = send_params;
1254
1255 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1256 // and only give it to the media channel once we have a local
1257 // description too (without a local description, we won't be able to
1258 // recv them anyway).
Steve Anton3828c062017-12-06 18:34:511259 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yves Gerey665174f2018-06-19 13:03:051260 SafeSetError("Failed to set remote data description streams.", error_desc);
Peter Thatcherc2ee2c82015-08-07 23:05:341261 return false;
1262 }
1263
1264 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 20:31:141265 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 23:05:341266 return true;
henrike@webrtc.org28e20752013-07-10 00:45:361267}
1268
deadbeef953c2ce2017-01-09 22:53:411269void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:361270 // Render incoming data if we're the active call, and we have the local
1271 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 20:31:141272 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:361273 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 10:09:251274 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:361275 }
1276
1277 // Send outgoing data if we're the active call, we have the remote content,
1278 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 20:31:141279 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:361280 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 10:09:251281 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:361282 }
1283
sergeyu@chromium.org9cf037b2014-02-07 19:03:261284 // Trigger SignalReadyToSendData asynchronously.
1285 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:361286
Mirko Bonadei675513b2017-11-09 10:09:251287 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:361288}
1289
deadbeef953c2ce2017-01-09 22:53:411290void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:361291 switch (pmsg->message_id) {
1292 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:071293 DataChannelReadyToSendMessageData* data =
1294 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:341295 ready_to_send_data_ = data->data();
1296 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:361297 delete data;
1298 break;
1299 }
henrike@webrtc.org28e20752013-07-10 00:45:361300 case MSG_DATARECEIVED: {
1301 DataReceivedMessageData* data =
1302 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 22:53:411303 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:361304 delete data;
1305 break;
1306 }
henrike@webrtc.org28e20752013-07-10 00:45:361307 default:
1308 BaseChannel::OnMessage(pmsg);
1309 break;
1310 }
1311}
1312
deadbeef953c2ce2017-01-09 22:53:411313void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1314 const char* data,
1315 size_t len) {
Yves Gerey665174f2018-06-19 13:03:051316 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 21:17:271317 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:361318}
1319
deadbeef953c2ce2017-01-09 22:53:411320void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:071321 // This is usded for congestion control to indicate that the stream is ready
1322 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1323 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 21:17:271324 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:071325 new DataChannelReadyToSendMessageData(writable));
1326}
1327
henrike@webrtc.org28e20752013-07-10 00:45:361328} // namespace cricket