blob: accc233aa11675d0a7f4ccadea6679d99d322735 [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"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "media/base/media_constants.h"
20#include "media/base/rtp_utils.h"
Zhi Huang365381f2018-04-13 16:44:34 -070021#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070022#include "p2p/base/packet_transport_internal.h"
23#include "pc/channel_manager.h"
24#include "pc/rtp_media_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "rtc_base/bind.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "rtc_base/byte_order.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/copy_on_write_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/dscp.h"
30#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "rtc_base/network_route.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020032#include "rtc_base/strings/string_builder.h"
Taylor Brandstetterc03a1872020-09-02 13:25:31 -070033#include "rtc_base/synchronization/sequence_checker.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,
Johannes Kron3e983682020-03-29 22:17:00 +0200101 bool is_stream_active,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700102 RtpParameters<Codec>* params) {
Johannes Kron3e983682020-03-29 22:17:00 +0200103 params->is_stream_active = is_stream_active;
Mirko Bonadei1f0677d2020-04-17 14:15:47 +0200104 params->codecs = desc->codecs();
105 // TODO(bugs.webrtc.org/11513): See if we really need
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700106 // rtp_header_extensions_set() and remove it if we don't.
107 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -0700108 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700109 }
deadbeef13871492015-12-09 12:37:51 -0800110 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Sebastian Janssone1795f42019-07-24 11:38:03 +0200111 params->rtcp.remote_estimate = desc->remote_estimate();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700112}
113
nisse05103312016-03-16 02:22:50 -0700114template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700115void RtpSendParametersFromMediaDescription(
116 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -0700117 const RtpHeaderExtensions& extensions,
Johannes Kron3e983682020-03-29 22:17:00 +0200118 bool is_stream_active,
nisse05103312016-03-16 02:22:50 -0700119 RtpSendParameters<Codec>* send_params) {
Johannes Kron3e983682020-03-29 22:17:00 +0200120 RtpParametersFromMediaDescription(desc, extensions, is_stream_active,
121 send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700122 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 11:22:05 +0100123 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700124}
125
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200126BaseChannel::BaseChannel(rtc::Thread* worker_thread,
127 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800128 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800129 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700130 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700131 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800132 webrtc::CryptoOptions crypto_options,
133 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200134 : worker_thread_(worker_thread),
135 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800136 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800138 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700139 crypto_options_(crypto_options),
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800140 media_channel_(std::move(media_channel)),
141 ssrc_generator_(ssrc_generator) {
Steve Anton8699a322017-11-06 15:53:33 -0800142 RTC_DCHECK_RUN_ON(worker_thread_);
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800143 RTC_DCHECK(ssrc_generator_);
Zhi Huang365381f2018-04-13 16:44:34 -0700144 demuxer_criteria_.mid = content_name;
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300145 RTC_LOG(LS_INFO) << "Created channel: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000146}
147
148BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800149 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800150 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800151
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200152 // Eats any outstanding messages or packets.
153 worker_thread_->Clear(&invoker_);
154 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000155 // We must destroy the media channel before the transport channel, otherwise
156 // the media channel may try to send on the dead transport channel. NULLing
157 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800158 media_channel_.reset();
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300159 RTC_LOG(LS_INFO) << "Destroyed channel: " << ToString();
160}
161
162std::string BaseChannel::ToString() const {
163 rtc::StringBuilder sb;
164 sb << "{mid: " << content_name_;
165 if (media_channel_) {
166 sb << ", media_type: " << MediaTypeToString(media_channel_->media_type());
167 }
168 sb << "}";
169 return sb.Release();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200170}
171
Zhi Huang365381f2018-04-13 16:44:34 -0700172bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800173 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700174 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300175 RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString();
Zhi Huang365381f2018-04-13 16:44:34 -0700176 return false;
177 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800178 rtp_transport_->SignalReadyToSend.connect(
179 this, &BaseChannel::OnTransportReadyToSend);
Bjorn A Mellem7a9a0922019-11-26 09:19:40 -0800180 rtp_transport_->SignalNetworkRouteChanged.connect(
181 this, &BaseChannel::OnNetworkRouteChanged);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800182 rtp_transport_->SignalWritableState.connect(this,
183 &BaseChannel::OnWritableState);
184 rtp_transport_->SignalSentPacket.connect(this,
185 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 16:44:34 -0700186 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800187}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200188
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800189void BaseChannel::DisconnectFromRtpTransport() {
190 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700191 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800192 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800193 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
194 rtp_transport_->SignalWritableState.disconnect(this);
195 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200196}
197
Niels Möller2a707032020-06-16 16:39:13 +0200198void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800199 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800200
Zhi Huang365381f2018-04-13 16:44:34 -0700201 network_thread_->Invoke<void>(
202 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800203
204 // Both RTP and RTCP channels should be set, we can call SetInterface on
205 // the media channel and it can set network options.
Niels Möller2a707032020-06-16 16:39:13 +0200206 media_channel_->SetInterface(this);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200207}
208
wu@webrtc.org78187522013-10-07 23:32:02 +0000209void BaseChannel::Deinit() {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700210 RTC_DCHECK_RUN_ON(worker_thread());
Niels Möller2a707032020-06-16 16:39:13 +0200211 media_channel_->SetInterface(/*iface=*/nullptr);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200212 // Packets arrive on the network thread, processing packets calls virtual
213 // functions, so need to stop this process in Deinit that is called in
214 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800215 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000216 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700217
Zhi Huange830e682018-03-30 10:48:35 -0700218 if (rtp_transport_) {
219 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000220 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800221 // Clear pending read packets/messages.
222 network_thread_->Clear(&invoker_);
223 network_thread_->Clear(this);
224 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000225}
226
Zhi Huang365381f2018-04-13 16:44:34 -0700227bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
228 if (rtp_transport == rtp_transport_) {
229 return true;
230 }
231
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800232 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 16:44:34 -0700233 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
234 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800235 });
236 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000237
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800238 if (rtp_transport_) {
239 DisconnectFromRtpTransport();
240 }
Zhi Huange830e682018-03-30 10:48:35 -0700241
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800242 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700243 if (rtp_transport_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700244 transport_name_ = rtp_transport_->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800245
Zhi Huang365381f2018-04-13 16:44:34 -0700246 if (!ConnectToRtpTransport()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300247 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport for "
248 << ToString() << ".";
Zhi Huang365381f2018-04-13 16:44:34 -0700249 return false;
250 }
Zhi Huange830e682018-03-30 10:48:35 -0700251 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
252 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800253
Zhi Huange830e682018-03-30 10:48:35 -0700254 // Set the cached socket options.
255 for (const auto& pair : socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700256 rtp_transport_->SetRtpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700257 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700258 if (!rtp_transport_->rtcp_mux_enabled()) {
Zhi Huange830e682018-03-30 10:48:35 -0700259 for (const auto& pair : rtcp_socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700260 rtp_transport_->SetRtcpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700261 }
262 }
guoweis46383312015-12-17 16:45:59 -0800263 }
Zhi Huang365381f2018-04-13 16:44:34 -0700264 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000265}
266
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000267bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700268 worker_thread_->Invoke<void>(
269 RTC_FROM_HERE,
270 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
271 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 return true;
273}
274
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800276 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000277 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100278 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700279 return InvokeOnWorker<bool>(
280 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800281 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000282}
283
284bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800285 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000286 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100287 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700288 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800289 RTC_FROM_HERE,
290 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000291}
292
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700293void BaseChannel::SetPayloadTypeDemuxingEnabled(bool enabled) {
294 TRACE_EVENT0("webrtc", "BaseChannel::SetPayloadTypeDemuxingEnabled");
295 InvokeOnWorker<void>(
296 RTC_FROM_HERE,
297 Bind(&BaseChannel::SetPayloadTypeDemuxingEnabled_w, this, enabled));
298}
299
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700300bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800302 return enabled() &&
303 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304}
305
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700306bool BaseChannel::IsReadyToSendMedia_w() const {
307 // Need to access some state updated on the network thread.
308 return network_thread_->Invoke<bool>(
309 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
310}
311
312bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000313 // Send outgoing data if we are enabled, have local and remote content,
314 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800315 return enabled() &&
316 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
317 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 16:44:34 -0700318 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319}
320
jbaucheec21bd2016-03-20 06:15:43 -0700321bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700322 const rtc::PacketOptions& options) {
323 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324}
325
jbaucheec21bd2016-03-20 06:15:43 -0700326bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700327 const rtc::PacketOptions& options) {
328 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329}
330
Yves Gerey665174f2018-06-19 15:03:05 +0200331int BaseChannel::SetOption(SocketType type,
332 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200334 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700335 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200336}
337
338int BaseChannel::SetOption_n(SocketType type,
339 rtc::Socket::Option opt,
340 int value) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700341 RTC_DCHECK_RUN_ON(network_thread());
Zhi Huange830e682018-03-30 10:48:35 -0700342 RTC_DCHECK(rtp_transport_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000344 case ST_RTP:
deadbeefcbecd352015-09-23 11:50:27 -0700345 socket_options_.push_back(
346 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700347 return rtp_transport_->SetRtpOption(opt, value);
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000348 case ST_RTCP:
deadbeefcbecd352015-09-23 11:50:27 -0700349 rtcp_socket_options_.push_back(
350 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700351 return rtp_transport_->SetRtcpOption(opt, value);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700353 return -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354}
355
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800356void BaseChannel::OnWritableState(bool writable) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700357 RTC_DCHECK_RUN_ON(network_thread());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800358 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800359 ChannelWritable_n();
360 } else {
361 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800362 }
363}
364
Zhi Huang942bc2e2017-11-13 13:26:07 -0800365void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200366 absl::optional<rtc::NetworkRoute> network_route) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300367 RTC_LOG(LS_INFO) << "Network route for " << ToString() << " was changed.";
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800368
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700369 RTC_DCHECK_RUN_ON(network_thread());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800370 rtc::NetworkRoute new_route;
371 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800372 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000373 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800374 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
375 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
376 // work correctly. Intentionally leave it broken to simplify the code and
377 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800378 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800379 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800380 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700381}
382
zstein56162b92017-04-24 16:54:35 -0700383void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800384 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
385 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000386}
387
stefanc1aeaf02015-10-15 07:26:07 -0700388bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700389 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700390 const rtc::PacketOptions& options) {
Amit Hilbuchedd20542019-03-18 12:33:43 -0700391 // Until all the code is migrated to use RtpPacketType instead of bool.
392 RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200393 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
394 // If the thread is not our network thread, we will post to our network
395 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000396 // synchronize access to all the pieces of the send path, including
397 // SRTP and the inner workings of the transport channels.
398 // The only downside is that we can't return a proper failure code if
399 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200400 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000401 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200402 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
403 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800404 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700405 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700406 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407 return true;
408 }
Zhi Huange830e682018-03-30 10:48:35 -0700409
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200410 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000411
412 // Now that we are on the correct thread, ensure we have a place to send this
413 // packet before doing anything. (We might get RTCP packets that we don't
414 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
415 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700416 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000417 return false;
418 }
419
420 // Protect ourselves against crazy data.
Amit Hilbuchedd20542019-03-18 12:33:43 -0700421 if (!IsValidRtpPacketSize(packet_type, packet->size())) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300422 RTC_LOG(LS_ERROR) << "Dropping outgoing " << ToString() << " "
Amit Hilbuchedd20542019-03-18 12:33:43 -0700423 << RtpPacketTypeToString(packet_type)
Mirko Bonadei675513b2017-11-09 11:09:25 +0100424 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000425 return false;
426 }
427
Zhi Huangcf990f52017-09-22 12:12:30 -0700428 if (!srtp_active()) {
429 if (srtp_required_) {
430 // The audio/video engines may attempt to send RTCP packets as soon as the
431 // streams are created, so don't treat this as an error for RTCP.
432 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
433 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000434 return false;
435 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700436 // However, there shouldn't be any RTP packets sent before SRTP is set up
437 // (and SetSend(true) is called).
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300438 RTC_LOG(LS_ERROR) << "Can't send outgoing RTP packet for " << ToString()
439 << " when SRTP is inactive and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700440 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800441 return false;
442 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800443
444 std::string packet_type = rtcp ? "RTCP" : "RTP";
Marina Ciocea38728732020-07-29 10:15:46 +0200445 RTC_DLOG(LS_WARNING) << "Sending an " << packet_type
446 << " packet without encryption for " << ToString()
447 << ".";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000448 }
Zhi Huange830e682018-03-30 10:48:35 -0700449
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800451 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
452 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000453}
454
Zhi Huang365381f2018-04-13 16:44:34 -0700455void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Niels Möller29e13fd2018-12-17 12:35:30 +0100456 // Take packet time from the |parsed_packet|.
457 // RtpPacketReceived.arrival_time_ms = (timestamp_us + 500) / 1000;
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200458 int64_t packet_time_us = -1;
Zhi Huang365381f2018-04-13 16:44:34 -0700459 if (parsed_packet.arrival_time_ms() > 0) {
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200460 packet_time_us = parsed_packet.arrival_time_ms() * 1000;
Zhi Huang365381f2018-04-13 16:44:34 -0700461 }
Zhi Huang365381f2018-04-13 16:44:34 -0700462
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200463 if (!has_received_packet_) {
464 has_received_packet_ = true;
465 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
466 }
467
468 if (!srtp_active() && srtp_required_) {
469 // Our session description indicates that SRTP is required, but we got a
470 // packet before our SRTP filter is active. This means either that
471 // a) we got SRTP packets before we received the SDES keys, in which case
472 // we can't decrypt it anyway, or
473 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
474 // transports, so we haven't yet extracted keys, even if DTLS did
475 // complete on the transport that the packets are being sent on. It's
476 // really good practice to wait for both RTP and RTCP to be good to go
477 // before sending media, to prevent weird failure modes, so it's fine
478 // for us to just eat packets here. This is all sidestepped if RTCP mux
479 // is used anyway.
480 RTC_LOG(LS_WARNING) << "Can't process incoming RTP packet when "
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300481 "SRTP is inactive and crypto is required "
482 << ToString();
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200483 return;
484 }
485
486 auto packet_buffer = parsed_packet.Buffer();
487
488 invoker_.AsyncInvoke<void>(
489 RTC_FROM_HERE, worker_thread_, [this, packet_buffer, packet_time_us] {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700490 RTC_DCHECK_RUN_ON(worker_thread());
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200491 media_channel_->OnPacketReceived(packet_buffer, packet_time_us);
492 });
Zhi Huang365381f2018-04-13 16:44:34 -0700493}
494
495void BaseChannel::UpdateRtpHeaderExtensionMap(
496 const RtpHeaderExtensions& header_extensions) {
497 RTC_DCHECK(rtp_transport_);
498 // Update the header extension map on network thread in case there is data
499 // race.
500 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
501 // be accessed from different threads.
502 //
503 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
504 // extension maps are not merged when BUNDLE is enabled. This is fine because
505 // the ID for MID should be consistent among all the RTP transports.
506 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
507 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
508 });
509}
510
511bool BaseChannel::RegisterRtpDemuxerSink() {
512 RTC_DCHECK(rtp_transport_);
513 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
514 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
515 });
516}
517
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000518void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700519 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 if (enabled_)
521 return;
522
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300523 RTC_LOG(LS_INFO) << "Channel enabled: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000524 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700525 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526}
527
528void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700529 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000530 if (!enabled_)
531 return;
532
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300533 RTC_LOG(LS_INFO) << "Channel disabled: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000534 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700535 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536}
537
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200538void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700539 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
540 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200541 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700542 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200543 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700544 }
545}
546
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200547void BaseChannel::ChannelWritable_n() {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700548 RTC_DCHECK_RUN_ON(network_thread());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800549 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000550 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800551 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000552
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300553 RTC_LOG(LS_INFO) << "Channel writable (" << ToString() << ")"
Mirko Bonadei675513b2017-11-09 11:09:25 +0100554 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000556 was_ever_writable_ = true;
557 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700558 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559}
560
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200561void BaseChannel::ChannelNotWritable_n() {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700562 RTC_DCHECK_RUN_ON(network_thread());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000563 if (!writable_)
564 return;
565
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300566 RTC_LOG(LS_INFO) << "Channel not writable (" << ToString() << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700568 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569}
570
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700572 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800573 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000574}
575
Peter Boström0c4e06b2015-10-07 12:23:21 +0200576bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700577 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 return media_channel()->RemoveRecvStream(ssrc);
579}
580
Saurav Dasff27da52019-09-20 11:05:30 -0700581void BaseChannel::ResetUnsignaledRecvStream_w() {
582 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
583 media_channel()->ResetUnsignaledRecvStream();
584}
585
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700586void BaseChannel::SetPayloadTypeDemuxingEnabled_w(bool enabled) {
587 RTC_DCHECK_RUN_ON(worker_thread());
588 if (enabled == payload_type_demuxing_enabled_) {
589 return;
590 }
591 if (!enabled) {
592 // TODO(crbug.com/11477): This will remove *all* unsignaled streams (those
593 // without an explicitly signaled SSRC), which may include streams that
594 // were matched to this channel by MID or RID. Ideally we'd remove only the
595 // streams that were matched based on payload type alone, but currently
596 // there is no straightforward way to identify those streams.
597 media_channel()->ResetUnsignaledRecvStream();
598 ClearHandledPayloadTypes();
599 RegisterRtpDemuxerSink();
600 }
601 payload_type_demuxing_enabled_ = enabled;
602}
603
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000604bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800605 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000606 std::string* error_desc) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800607 // In the case of RIDs (where SSRCs are not negotiated), this method will
608 // generate an SSRC for each layer in StreamParams. That representation will
609 // be stored internally in |local_streams_|.
610 // In subsequent offers, the same stream can appear in |streams| again
611 // (without the SSRCs), so it should be looked up using RIDs (if available)
612 // and then by primary SSRC.
613 // In both scenarios, it is safe to assume that the media channel will be
614 // created with a StreamParams object with SSRCs. However, it is not safe to
615 // assume that |local_streams_| will always have SSRCs as there are scenarios
616 // in which niether SSRCs or RIDs are negotiated.
617
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000618 // Check for streams that have been removed.
619 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800620 for (const StreamParams& old_stream : local_streams_) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800621 if (!old_stream.has_ssrcs() ||
622 GetStream(streams, StreamFinder(&old_stream))) {
623 continue;
624 }
625 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
626 rtc::StringBuilder desc;
627 desc << "Failed to remove send stream with ssrc "
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000628 << old_stream.first_ssrc() << " from m-section with mid='"
629 << content_name() << "'.";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800630 SafeSetError(desc.str(), error_desc);
631 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632 }
633 }
634 // Check for new streams.
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800635 std::vector<StreamParams> all_streams;
636 for (const StreamParams& stream : streams) {
637 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
638 if (existing) {
639 // Parameters cannot change for an existing stream.
640 all_streams.push_back(*existing);
641 continue;
642 }
643
644 all_streams.push_back(stream);
645 StreamParams& new_stream = all_streams.back();
646
647 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
648 continue;
649 }
650
651 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
652 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
653 rtc::StringBuilder desc;
654 desc << "Failed to add send stream: " << new_stream.first_ssrc()
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000655 << " into m-section with mid='" << content_name()
656 << "'. Stream has both SSRCs and RIDs.";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800657 SafeSetError(desc.str(), error_desc);
658 ret = false;
659 continue;
660 }
661
662 // At this point we use the legacy simulcast group in StreamParams to
663 // indicate that we want multiple layers to the media channel.
664 if (!new_stream.has_ssrcs()) {
665 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
666 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
667 /* flex_fec = */ false, ssrc_generator_);
668 }
669
670 if (media_channel()->AddSendStream(new_stream)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300671 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0]
672 << " into " << ToString();
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800673 } else {
674 rtc::StringBuilder desc;
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000675 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc()
676 << " into m-section with mid='" << content_name() << "'";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800677 SafeSetError(desc.str(), error_desc);
678 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000679 }
680 }
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800681 local_streams_ = all_streams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000682 return ret;
683}
684
685bool BaseChannel::UpdateRemoteStreams_w(
686 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800687 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000688 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000689 // Check for streams that have been removed.
690 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800691 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700692 // If we no longer have an unsignaled stream, we would like to remove
693 // the unsignaled stream params that are cached.
Saurav Dasff27da52019-09-20 11:05:30 -0700694 if (!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) {
695 ResetUnsignaledRecvStream_w();
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300696 RTC_LOG(LS_INFO) << "Reset unsignaled remote stream for " << ToString()
697 << ".";
Saurav Dasff27da52019-09-20 11:05:30 -0700698 } else if (old_stream.has_ssrcs() &&
699 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800700 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300701 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc()
702 << " from " << ToString() << ".";
Zhi Huang365381f2018-04-13 16:44:34 -0700703 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200704 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800705 desc << "Failed to remove remote stream with ssrc "
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000706 << old_stream.first_ssrc() << " from m-section with mid='"
707 << content_name() << "'.";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000708 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709 ret = false;
710 }
711 }
712 }
Zhi Huang365381f2018-04-13 16:44:34 -0700713 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800715 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700716 // We allow a StreamParams with an empty list of SSRCs, in which case the
717 // MediaChannel will cache the parameters and use them for any unsignaled
718 // stream received later.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800719 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
720 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
721 if (AddRecvStream_w(new_stream)) {
Saurav Dasff27da52019-09-20 11:05:30 -0700722 RTC_LOG(LS_INFO) << "Add remote ssrc: "
723 << (new_stream.has_ssrcs()
724 ? std::to_string(new_stream.first_ssrc())
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300725 : "unsignaled")
726 << " to " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200728 rtc::StringBuilder desc;
Saurav Dasff27da52019-09-20 11:05:30 -0700729 desc << "Failed to add remote stream ssrc: "
730 << (new_stream.has_ssrcs()
731 ? std::to_string(new_stream.first_ssrc())
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300732 : "unsignaled")
733 << " to " << ToString();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000734 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000735 ret = false;
736 }
737 }
Zhi Huang365381f2018-04-13 16:44:34 -0700738 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800739 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
740 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741 }
Zhi Huang365381f2018-04-13 16:44:34 -0700742 // Re-register the sink to update the receiving ssrcs.
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300743 if (!RegisterRtpDemuxerSink()) {
744 RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString();
745 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746 remote_streams_ = streams;
747 return ret;
748}
749
jbauch5869f502017-06-29 12:31:36 -0700750RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
751 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700752 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700753 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700754 RtpHeaderExtensions filtered;
Steve Anton64b626b2019-01-28 17:25:26 -0800755 absl::c_copy_if(extensions, std::back_inserter(filtered),
756 [](const webrtc::RtpExtension& extension) {
757 return !extension.encrypt;
758 });
jbauch5869f502017-06-29 12:31:36 -0700759 return filtered;
760 }
761
762 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
763}
764
Yves Gerey665174f2018-06-19 15:03:05 +0200765void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100766 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200768 case MSG_SEND_RTP_PACKET:
769 case MSG_SEND_RTCP_PACKET: {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700770 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200771 SendPacketMessageData* data =
772 static_cast<SendPacketMessageData*>(pmsg->pdata);
773 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
774 SendPacket(rtcp, &data->packet, data->options);
775 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 break;
777 }
778 case MSG_FIRSTPACKETRECEIVED: {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800779 SignalFirstPacketReceived_(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780 break;
781 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782 }
783}
784
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700785void BaseChannel::MaybeAddHandledPayloadType(int payload_type) {
786 if (payload_type_demuxing_enabled_) {
787 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
788 }
zstein3dcf0e92017-06-01 13:22:42 -0700789}
790
Steve Antonbe2e5f72019-09-06 16:26:02 -0700791void BaseChannel::ClearHandledPayloadTypes() {
792 demuxer_criteria_.payload_types.clear();
793}
794
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200795void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796 // Flush all remaining RTCP messages. This should only be called in
797 // destructor.
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700798 RTC_DCHECK_RUN_ON(network_thread());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000799 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200800 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
801 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700802 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
803 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804 }
805}
806
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800807void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700808 RTC_DCHECK_RUN_ON(network_thread());
Sebastian Jansson01be33b2019-09-12 17:39:18 +0200809 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
810 [this, sent_packet] {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700811 RTC_DCHECK_RUN_ON(worker_thread());
Sebastian Jansson01be33b2019-09-12 17:39:18 +0200812 SignalSentPacket(sent_packet);
813 });
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200814}
815
816VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
817 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800818 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800819 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700821 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800822 webrtc::CryptoOptions crypto_options,
823 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200824 : BaseChannel(worker_thread,
825 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800826 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800827 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700828 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700829 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800830 crypto_options,
831 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832
833VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800834 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835 // this can't be done in the base class, since it calls a virtual
836 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700837 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838}
839
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700840void BaseChannel::UpdateMediaSendRecvState() {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700841 RTC_DCHECK_RUN_ON(network_thread());
Sebastian Jansson01be33b2019-09-12 17:39:18 +0200842 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
843 [this] { UpdateMediaSendRecvState_w(); });
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200844}
845
Niels Möller2a707032020-06-16 16:39:13 +0200846void VoiceChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
847 BaseChannel::Init_w(rtp_transport);
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -0800848}
849
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700850void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851 // 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 13:31:14 -0700853 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700854 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855
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 13:31:14 -0700858 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800859 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300861 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send
862 << " for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863}
864
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000865bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800866 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000867 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100868 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800869 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300870 RTC_LOG(LS_INFO) << "Setting local voice description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000871
Steve Antonb1c1de12017-12-21 15:14:30 -0800872 RTC_DCHECK(content);
873 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000874 SafeSetError("Can't find audio content in local description.", error_desc);
875 return false;
876 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877
Steve Antonb1c1de12017-12-21 15:14:30 -0800878 const AudioContentDescription* audio = content->as_audio();
879
jbauch5869f502017-06-29 12:31:36 -0700880 RtpHeaderExtensions rtp_header_extensions =
881 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700882 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100883 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700884
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700885 AudioRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +0200886 RtpParametersFromMediaDescription(
887 audio, rtp_header_extensions,
888 webrtc::RtpTransceiverDirectionHasRecv(audio->direction()), &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700889 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000890 SafeSetError(
891 "Failed to set local audio description recv parameters for m-section "
892 "with mid='" +
893 content_name() + "'.",
894 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700895 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896 }
Steve Antonbe2e5f72019-09-06 16:26:02 -0700897
898 if (webrtc::RtpTransceiverDirectionHasRecv(audio->direction())) {
899 for (const AudioCodec& codec : audio->codecs()) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700900 MaybeAddHandledPayloadType(codec.id);
Steve Antonbe2e5f72019-09-06 16:26:02 -0700901 }
902 // Need to re-register the sink to update the handled payload.
903 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300904 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing for " << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -0700905 return false;
906 }
Zhi Huang365381f2018-04-13 16:44:34 -0700907 }
908
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700909 last_recv_params_ = recv_params;
910
911 // TODO(pthatcher): Move local streams into AudioSendParameters, and
912 // only give it to the media channel once we have a remote
913 // description too (without a remote description, we won't be able
914 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800915 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000916 SafeSetError(
917 "Failed to set local audio description streams for m-section with "
918 "mid='" +
919 content_name() + "'.",
920 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700921 return false;
922 }
923
924 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700925 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700926 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927}
928
929bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800930 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000931 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100932 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800933 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300934 RTC_LOG(LS_INFO) << "Setting remote voice description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935
Steve Antonb1c1de12017-12-21 15:14:30 -0800936 RTC_DCHECK(content);
937 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000938 SafeSetError("Can't find audio content in remote description.", error_desc);
939 return false;
940 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000941
Steve Antonb1c1de12017-12-21 15:14:30 -0800942 const AudioContentDescription* audio = content->as_audio();
943
jbauch5869f502017-06-29 12:31:36 -0700944 RtpHeaderExtensions rtp_header_extensions =
945 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
946
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700947 AudioSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +0200948 RtpSendParametersFromMediaDescription(
949 audio, rtp_header_extensions,
950 webrtc::RtpTransceiverDirectionHasRecv(audio->direction()), &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700951 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700952
953 bool parameters_applied = media_channel()->SetSendParameters(send_params);
954 if (!parameters_applied) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000955 SafeSetError(
956 "Failed to set remote audio description send parameters for m-section "
957 "with mid='" +
958 content_name() + "'.",
959 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700960 return false;
961 }
962 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963
Steve Antonbe2e5f72019-09-06 16:26:02 -0700964 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
965 RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300966 "disable payload type demuxing for "
967 << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -0700968 ClearHandledPayloadTypes();
969 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300970 RTC_LOG(LS_ERROR) << "Failed to update audio demuxing for " << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -0700971 return false;
972 }
973 }
974
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700975 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
976 // and only give it to the media channel once we have a local
977 // description too (without a local description, we won't be able to
978 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800979 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000980 SafeSetError(
981 "Failed to set remote audio description streams for m-section with "
982 "mid='" +
983 content_name() + "'.",
984 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700985 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986 }
987
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700988 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700989 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700990 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991}
992
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200993VideoChannel::VideoChannel(rtc::Thread* worker_thread,
994 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800995 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800996 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700998 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800999 webrtc::CryptoOptions crypto_options,
1000 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001001 : BaseChannel(worker_thread,
1002 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001003 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001004 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001005 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001006 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001007 crypto_options,
1008 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001009
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -08001011 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012 // this can't be done in the base class, since it calls a virtual
1013 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001014 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015}
1016
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001017void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001018 // Send outgoing data if we're the active call, we have the remote content,
1019 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001020 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001021 if (!media_channel()->SetSend(send)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001022 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel: " + ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023 // TODO(gangji): Report error back to server.
1024 }
1025
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001026 RTC_LOG(LS_INFO) << "Changing video state, send=" << send << " for "
1027 << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001028}
1029
stefanf79ade12017-06-02 06:44:03 -07001030void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
1031 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
1032 media_channel(), bwe_info));
1033}
1034
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001035bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001036 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001037 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001038 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001039 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001040 RTC_LOG(LS_INFO) << "Setting local video description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001041
Steve Antonb1c1de12017-12-21 15:14:30 -08001042 RTC_DCHECK(content);
1043 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001044 SafeSetError("Can't find video content in local description.", error_desc);
1045 return false;
1046 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001047
Steve Antonb1c1de12017-12-21 15:14:30 -08001048 const VideoContentDescription* video = content->as_video();
1049
jbauch5869f502017-06-29 12:31:36 -07001050 RtpHeaderExtensions rtp_header_extensions =
1051 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -07001052 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +01001053 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -07001054
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001055 VideoRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001056 RtpParametersFromMediaDescription(
1057 video, rtp_header_extensions,
1058 webrtc::RtpTransceiverDirectionHasRecv(video->direction()), &recv_params);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001059
1060 VideoSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001061
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001062 bool needs_send_params_update = false;
Johannes Krona104ceb2020-01-24 16:04:04 +00001063 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001064 for (auto& send_codec : send_params.codecs) {
1065 auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
1066 if (recv_codec) {
1067 if (!recv_codec->packetization && send_codec.packetization) {
1068 send_codec.packetization.reset();
1069 needs_send_params_update = true;
1070 } else if (recv_codec->packetization != send_codec.packetization) {
1071 SafeSetError(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001072 "Failed to set local answer due to invalid codec packetization "
1073 "specified in m-section with mid='" +
1074 content_name() + "'.",
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001075 error_desc);
1076 return false;
1077 }
1078 }
1079 }
1080 }
1081
Johannes Krona104ceb2020-01-24 16:04:04 +00001082 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001083 SafeSetError(
1084 "Failed to set local video description recv parameters for m-section "
1085 "with mid='" +
1086 content_name() + "'.",
1087 error_desc);
Johannes Krona104ceb2020-01-24 16:04:04 +00001088 return false;
1089 }
Johannes Kron9bac68c2020-01-23 13:12:25 +00001090
Johannes Krona104ceb2020-01-24 16:04:04 +00001091 if (webrtc::RtpTransceiverDirectionHasRecv(video->direction())) {
Steve Antonbe2e5f72019-09-06 16:26:02 -07001092 for (const VideoCodec& codec : video->codecs()) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -07001093 MaybeAddHandledPayloadType(codec.id);
Steve Antonbe2e5f72019-09-06 16:26:02 -07001094 }
1095 // Need to re-register the sink to update the handled payload.
1096 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001097 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing for " << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -07001098 return false;
1099 }
Zhi Huang365381f2018-04-13 16:44:34 -07001100 }
1101
Johannes Krona104ceb2020-01-24 16:04:04 +00001102 last_recv_params_ = recv_params;
1103
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001104 if (needs_send_params_update) {
1105 if (!media_channel()->SetSendParameters(send_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001106 SafeSetError("Failed to set send parameters for m-section with mid='" +
1107 content_name() + "'.",
1108 error_desc);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001109 return false;
1110 }
1111 last_send_params_ = send_params;
1112 }
1113
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001114 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1115 // only give it to the media channel once we have a remote
1116 // description too (without a remote description, we won't be able
1117 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001118 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001119 SafeSetError(
1120 "Failed to set local video description streams for m-section with "
1121 "mid='" +
1122 content_name() + "'.",
1123 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001124 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001125 }
1126
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001127 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001128 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001129 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001130}
1131
1132bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001133 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001134 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001135 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001136 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001137 RTC_LOG(LS_INFO) << "Setting remote video description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001138
Steve Antonb1c1de12017-12-21 15:14:30 -08001139 RTC_DCHECK(content);
1140 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001141 SafeSetError("Can't find video content in remote description.", error_desc);
1142 return false;
1143 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001144
Steve Antonb1c1de12017-12-21 15:14:30 -08001145 const VideoContentDescription* video = content->as_video();
1146
jbauch5869f502017-06-29 12:31:36 -07001147 RtpHeaderExtensions rtp_header_extensions =
1148 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1149
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001150 VideoSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001151 RtpSendParametersFromMediaDescription(
1152 video, rtp_header_extensions,
1153 webrtc::RtpTransceiverDirectionHasRecv(video->direction()), &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001154 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001155 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001156 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001157 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001158
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001159 VideoRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001160
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001161 bool needs_recv_params_update = false;
Johannes Krona104ceb2020-01-24 16:04:04 +00001162 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001163 for (auto& recv_codec : recv_params.codecs) {
1164 auto* send_codec = FindMatchingCodec(send_params.codecs, recv_codec);
1165 if (send_codec) {
1166 if (!send_codec->packetization && recv_codec.packetization) {
1167 recv_codec.packetization.reset();
1168 needs_recv_params_update = true;
1169 } else if (send_codec->packetization != recv_codec.packetization) {
1170 SafeSetError(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001171 "Failed to set remote answer due to invalid codec packetization "
1172 "specifid in m-section with mid='" +
1173 content_name() + "'.",
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001174 error_desc);
1175 return false;
1176 }
1177 }
1178 }
1179 }
skvladdc1c62c2016-03-16 19:07:43 -07001180
Johannes Krona104ceb2020-01-24 16:04:04 +00001181 if (!media_channel()->SetSendParameters(send_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001182 SafeSetError(
1183 "Failed to set remote video description send parameters for m-section "
1184 "with mid='" +
1185 content_name() + "'.",
1186 error_desc);
Johannes Krona104ceb2020-01-24 16:04:04 +00001187 return false;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001188 }
Johannes Krona104ceb2020-01-24 16:04:04 +00001189 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001190
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001191 if (needs_recv_params_update) {
1192 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001193 SafeSetError("Failed to set recv parameters for m-section with mid='" +
1194 content_name() + "'.",
1195 error_desc);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001196 return false;
1197 }
1198 last_recv_params_ = recv_params;
1199 }
1200
Steve Antonbe2e5f72019-09-06 16:26:02 -07001201 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
1202 RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001203 "disable payload type demuxing for "
1204 << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -07001205 ClearHandledPayloadTypes();
1206 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001207 RTC_LOG(LS_ERROR) << "Failed to update video demuxing for " << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -07001208 return false;
1209 }
1210 }
1211
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001212 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1213 // and only give it to the media channel once we have a local
1214 // description too (without a local description, we won't be able to
1215 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001216 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001217 SafeSetError(
1218 "Failed to set remote video description streams for m-section with "
1219 "mid='" +
1220 content_name() + "'.",
1221 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001222 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001223 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001224 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001225 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001226 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001227}
1228
deadbeef953c2ce2017-01-09 14:53:41 -08001229RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1230 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001231 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001232 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001233 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001234 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001235 webrtc::CryptoOptions crypto_options,
1236 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001237 : BaseChannel(worker_thread,
1238 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001239 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001240 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001241 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001242 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001243 crypto_options,
1244 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001245
deadbeef953c2ce2017-01-09 14:53:41 -08001246RtpDataChannel::~RtpDataChannel() {
1247 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001248 // this can't be done in the base class, since it calls a virtual
1249 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001250 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001251}
1252
Niels Möller2a707032020-06-16 16:39:13 +02001253void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
1254 BaseChannel::Init_w(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001255 media_channel()->SignalDataReceived.connect(this,
1256 &RtpDataChannel::OnDataReceived);
1257 media_channel()->SignalReadyToSend.connect(
1258 this, &RtpDataChannel::OnDataChannelReadyToSend);
1259}
1260
deadbeef953c2ce2017-01-09 14:53:41 -08001261bool RtpDataChannel::SendData(const SendDataParams& params,
1262 const rtc::CopyOnWriteBuffer& payload,
1263 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001264 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001265 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1266 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001267}
1268
deadbeef953c2ce2017-01-09 14:53:41 -08001269bool RtpDataChannel::CheckDataChannelTypeFromContent(
Harald Alvestrand755187f2019-12-05 13:43:34 +01001270 const MediaContentDescription* content,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001271 std::string* error_desc) {
Harald Alvestrand755187f2019-12-05 13:43:34 +01001272 if (!content->as_rtp_data()) {
1273 if (content->as_sctp()) {
1274 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1275 error_desc);
1276 } else {
1277 SafeSetError("Data channel is not RTP or SCTP.", error_desc);
1278 }
deadbeef953c2ce2017-01-09 14:53:41 -08001279 return false;
1280 }
1281 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001282}
1283
deadbeef953c2ce2017-01-09 14:53:41 -08001284bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001285 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001286 std::string* error_desc) {
1287 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001288 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001289 RTC_LOG(LS_INFO) << "Setting local data description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001290
Steve Antonb1c1de12017-12-21 15:14:30 -08001291 RTC_DCHECK(content);
1292 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001293 SafeSetError("Can't find data content in local description.", error_desc);
1294 return false;
1295 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001296
Harald Alvestrand755187f2019-12-05 13:43:34 +01001297 if (!CheckDataChannelTypeFromContent(content, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001298 return false;
1299 }
Harald Alvestrand755187f2019-12-05 13:43:34 +01001300 const RtpDataContentDescription* data = content->as_rtp_data();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301
jbauch5869f502017-06-29 12:31:36 -07001302 RtpHeaderExtensions rtp_header_extensions =
1303 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1304
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001305 DataRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001306 RtpParametersFromMediaDescription(
1307 data, rtp_header_extensions,
1308 webrtc::RtpTransceiverDirectionHasRecv(data->direction()), &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001309 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001310 SafeSetError(
1311 "Failed to set remote data description recv parameters for m-section "
1312 "with mid='" +
1313 content_name() + "'.",
1314 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001315 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316 }
deadbeef953c2ce2017-01-09 14:53:41 -08001317 for (const DataCodec& codec : data->codecs()) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -07001318 MaybeAddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001319 }
Zhi Huang365381f2018-04-13 16:44:34 -07001320 // Need to re-register the sink to update the handled payload.
1321 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001322 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing for " << ToString();
Zhi Huang365381f2018-04-13 16:44:34 -07001323 return false;
1324 }
1325
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001326 last_recv_params_ = recv_params;
1327
1328 // TODO(pthatcher): Move local streams into DataSendParameters, and
1329 // only give it to the media channel once we have a remote
1330 // description too (without a remote description, we won't be able
1331 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001332 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001333 SafeSetError(
1334 "Failed to set local data description streams for m-section with "
1335 "mid='" +
1336 content_name() + "'.",
1337 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001338 return false;
1339 }
1340
1341 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001342 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001343 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344}
1345
deadbeef953c2ce2017-01-09 14:53:41 -08001346bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001347 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001348 std::string* error_desc) {
1349 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001350 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001351 RTC_LOG(LS_INFO) << "Setting remote data description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001352
Steve Antonb1c1de12017-12-21 15:14:30 -08001353 RTC_DCHECK(content);
1354 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001355 SafeSetError("Can't find data content in remote description.", error_desc);
1356 return false;
1357 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358
Harald Alvestrand755187f2019-12-05 13:43:34 +01001359 if (!CheckDataChannelTypeFromContent(content, error_desc)) {
1360 return false;
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02001361 }
Steve Antonb1c1de12017-12-21 15:14:30 -08001362
Harald Alvestrand755187f2019-12-05 13:43:34 +01001363 const RtpDataContentDescription* data = content->as_rtp_data();
1364
Zhi Huang801b8682017-11-15 11:36:43 -08001365 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1366 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001367 return true;
1368 }
1369
jbauch5869f502017-06-29 12:31:36 -07001370 RtpHeaderExtensions rtp_header_extensions =
1371 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1372
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001373 RTC_LOG(LS_INFO) << "Setting remote data description for " << ToString();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001374 DataSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001375 RtpSendParametersFromMediaDescription<DataCodec>(
1376 data, rtp_header_extensions,
1377 webrtc::RtpTransceiverDirectionHasRecv(data->direction()), &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001378 if (!media_channel()->SetSendParameters(send_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001379 SafeSetError(
1380 "Failed to set remote data description send parameters for m-section "
1381 "with mid='" +
1382 content_name() + "'.",
1383 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001384 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001386 last_send_params_ = send_params;
1387
1388 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1389 // and only give it to the media channel once we have a local
1390 // description too (without a local description, we won't be able to
1391 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001392 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001393 SafeSetError(
1394 "Failed to set remote data description streams for m-section with "
1395 "mid='" +
1396 content_name() + "'.",
1397 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001398 return false;
1399 }
1400
1401 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001402 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001403 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404}
1405
deadbeef953c2ce2017-01-09 14:53:41 -08001406void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407 // Render incoming data if we're the active call, and we have the local
1408 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001409 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001410 if (!media_channel()->SetReceive(recv)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001411 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412 }
1413
1414 // Send outgoing data if we're the active call, we have the remote content,
1415 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001416 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001417 if (!media_channel()->SetSend(send)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001418 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001419 }
1420
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001421 // Trigger SignalReadyToSendData asynchronously.
1422 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001424 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send
1425 << " for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426}
1427
deadbeef953c2ce2017-01-09 14:53:41 -08001428void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001429 switch (pmsg->message_id) {
1430 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001431 DataChannelReadyToSendMessageData* data =
1432 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001433 ready_to_send_data_ = data->data();
1434 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435 delete data;
1436 break;
1437 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438 case MSG_DATARECEIVED: {
1439 DataReceivedMessageData* data =
1440 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001441 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001442 delete data;
1443 break;
1444 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445 default:
1446 BaseChannel::OnMessage(pmsg);
1447 break;
1448 }
1449}
1450
deadbeef953c2ce2017-01-09 14:53:41 -08001451void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1452 const char* data,
1453 size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +02001454 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001455 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456}
1457
deadbeef953c2ce2017-01-09 14:53:41 -08001458void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001459 // This is usded for congestion control to indicate that the stream is ready
1460 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1461 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001462 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001463 new DataChannelReadyToSendMessageData(writable));
1464}
1465
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466} // namespace cricket