blob: eeba19b2c1c7bc9637de89be5042e3ecc37ee2d1 [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "rtc_base/trace_event.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034
35namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000036using rtc::Bind;
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080037using rtc::UniqueRandomIdGenerator;
Steve Anton3828c062017-12-06 10:34:51 -080038using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000039
deadbeef2d110be2016-01-13 12:00:26 -080040namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020041
42struct SendPacketMessageData : public rtc::MessageData {
43 rtc::CopyOnWriteBuffer packet;
44 rtc::PacketOptions options;
45};
46
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080047// Finds a stream based on target's Primary SSRC or RIDs.
48// This struct is used in BaseChannel::UpdateLocalStreams_w.
49struct StreamFinder {
50 explicit StreamFinder(const StreamParams* target) : target_(target) {
51 RTC_DCHECK(target);
52 }
53
54 bool operator()(const StreamParams& sp) const {
55 if (target_->has_ssrcs() && sp.has_ssrcs()) {
56 return sp.has_ssrc(target_->first_ssrc());
57 }
58
59 if (!target_->has_rids() && !sp.has_rids()) {
60 return false;
61 }
62
63 const std::vector<RidDescription>& target_rids = target_->rids();
64 const std::vector<RidDescription>& source_rids = sp.rids();
65 if (source_rids.size() != target_rids.size()) {
66 return false;
67 }
68
69 // Check that all RIDs match.
70 return std::equal(source_rids.begin(), source_rids.end(),
71 target_rids.begin(),
72 [](const RidDescription& lhs, const RidDescription& rhs) {
73 return lhs.rid == rhs.rid;
74 });
75 }
76
77 const StreamParams* target_;
78};
79
deadbeef2d110be2016-01-13 12:00:26 -080080} // namespace
81
henrike@webrtc.org28e20752013-07-10 00:45:36 +000082enum {
Steve Anton0807d152018-03-05 11:23:09 -080083 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020084 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000087 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088};
89
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000090static void SafeSetError(const std::string& message, std::string* error_desc) {
91 if (error_desc) {
92 *error_desc = message;
93 }
94}
95
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070096template <class Codec>
97void RtpParametersFromMediaDescription(
98 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070099 const RtpHeaderExtensions& extensions,
Johannes Kron3e983682020-03-29 22:17:00 +0200100 bool is_stream_active,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700101 RtpParameters<Codec>* params) {
Johannes Kron3e983682020-03-29 22:17:00 +0200102 params->is_stream_active = is_stream_active;
Mirko Bonadei1f0677d2020-04-17 14:15:47 +0200103 params->codecs = desc->codecs();
104 // TODO(bugs.webrtc.org/11513): See if we really need
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700105 // rtp_header_extensions_set() and remove it if we don't.
106 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -0700107 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700108 }
deadbeef13871492015-12-09 12:37:51 -0800109 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Sebastian Janssone1795f42019-07-24 11:38:03 +0200110 params->rtcp.remote_estimate = desc->remote_estimate();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700111}
112
nisse05103312016-03-16 02:22:50 -0700113template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700114void RtpSendParametersFromMediaDescription(
115 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -0700116 const RtpHeaderExtensions& extensions,
Johannes Kron3e983682020-03-29 22:17:00 +0200117 bool is_stream_active,
nisse05103312016-03-16 02:22:50 -0700118 RtpSendParameters<Codec>* send_params) {
Johannes Kron3e983682020-03-29 22:17:00 +0200119 RtpParametersFromMediaDescription(desc, extensions, is_stream_active,
120 send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700121 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 11:22:05 +0100122 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700123}
124
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200125BaseChannel::BaseChannel(rtc::Thread* worker_thread,
126 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800127 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800128 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700129 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700130 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800131 webrtc::CryptoOptions crypto_options,
132 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200133 : worker_thread_(worker_thread),
134 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800135 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800137 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700138 crypto_options_(crypto_options),
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800139 media_channel_(std::move(media_channel)),
140 ssrc_generator_(ssrc_generator) {
Steve Anton8699a322017-11-06 15:53:33 -0800141 RTC_DCHECK_RUN_ON(worker_thread_);
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800142 RTC_DCHECK(ssrc_generator_);
Zhi Huang365381f2018-04-13 16:44:34 -0700143 demuxer_criteria_.mid = content_name;
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300144 RTC_LOG(LS_INFO) << "Created channel: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145}
146
147BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800148 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800149 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800150
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200151 // Eats any outstanding messages or packets.
152 worker_thread_->Clear(&invoker_);
153 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154 // We must destroy the media channel before the transport channel, otherwise
155 // the media channel may try to send on the dead transport channel. NULLing
156 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800157 media_channel_.reset();
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300158 RTC_LOG(LS_INFO) << "Destroyed channel: " << ToString();
159}
160
161std::string BaseChannel::ToString() const {
162 rtc::StringBuilder sb;
163 sb << "{mid: " << content_name_;
164 if (media_channel_) {
165 sb << ", media_type: " << MediaTypeToString(media_channel_->media_type());
166 }
167 sb << "}";
168 return sb.Release();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200169}
170
Zhi Huang365381f2018-04-13 16:44:34 -0700171bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800172 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700173 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300174 RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString();
Zhi Huang365381f2018-04-13 16:44:34 -0700175 return false;
176 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800177 rtp_transport_->SignalReadyToSend.connect(
178 this, &BaseChannel::OnTransportReadyToSend);
Bjorn A Mellem7a9a0922019-11-26 09:19:40 -0800179 rtp_transport_->SignalNetworkRouteChanged.connect(
180 this, &BaseChannel::OnNetworkRouteChanged);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800181 rtp_transport_->SignalWritableState.connect(this,
182 &BaseChannel::OnWritableState);
183 rtp_transport_->SignalSentPacket.connect(this,
184 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 16:44:34 -0700185 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800186}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200187
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800188void BaseChannel::DisconnectFromRtpTransport() {
189 RTC_DCHECK(rtp_transport_);
Zhi Huang365381f2018-04-13 16:44:34 -0700190 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800191 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800192 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
193 rtp_transport_->SignalWritableState.disconnect(this);
194 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200195}
196
Niels Möller2a707032020-06-16 16:39:13 +0200197void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800198 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800199
Zhi Huang365381f2018-04-13 16:44:34 -0700200 network_thread_->Invoke<void>(
201 RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800202
203 // Both RTP and RTCP channels should be set, we can call SetInterface on
204 // the media channel and it can set network options.
Niels Möller2a707032020-06-16 16:39:13 +0200205 media_channel_->SetInterface(this);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200206}
207
wu@webrtc.org78187522013-10-07 23:32:02 +0000208void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200209 RTC_DCHECK(worker_thread_->IsCurrent());
Niels Möller2a707032020-06-16 16:39:13 +0200210 media_channel_->SetInterface(/*iface=*/nullptr);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200211 // Packets arrive on the network thread, processing packets calls virtual
212 // functions, so need to stop this process in Deinit that is called in
213 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800214 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000215 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700216
Zhi Huange830e682018-03-30 10:48:35 -0700217 if (rtp_transport_) {
218 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000219 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800220 // Clear pending read packets/messages.
221 network_thread_->Clear(&invoker_);
222 network_thread_->Clear(this);
223 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000224}
225
Zhi Huang365381f2018-04-13 16:44:34 -0700226bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
227 if (rtp_transport == rtp_transport_) {
228 return true;
229 }
230
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800231 if (!network_thread_->IsCurrent()) {
Zhi Huang365381f2018-04-13 16:44:34 -0700232 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
233 return SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800234 });
235 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000236
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800237 if (rtp_transport_) {
238 DisconnectFromRtpTransport();
239 }
Zhi Huange830e682018-03-30 10:48:35 -0700240
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800241 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700242 if (rtp_transport_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700243 transport_name_ = rtp_transport_->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800244
Zhi Huang365381f2018-04-13 16:44:34 -0700245 if (!ConnectToRtpTransport()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300246 RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport for "
247 << ToString() << ".";
Zhi Huang365381f2018-04-13 16:44:34 -0700248 return false;
249 }
Zhi Huange830e682018-03-30 10:48:35 -0700250 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
251 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800252
Zhi Huange830e682018-03-30 10:48:35 -0700253 // Set the cached socket options.
254 for (const auto& pair : socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700255 rtp_transport_->SetRtpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700256 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700257 if (!rtp_transport_->rtcp_mux_enabled()) {
Zhi Huange830e682018-03-30 10:48:35 -0700258 for (const auto& pair : rtcp_socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700259 rtp_transport_->SetRtcpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700260 }
261 }
guoweis46383312015-12-17 16:45:59 -0800262 }
Zhi Huang365381f2018-04-13 16:44:34 -0700263 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000264}
265
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700267 worker_thread_->Invoke<void>(
268 RTC_FROM_HERE,
269 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
270 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000271 return true;
272}
273
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800275 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000276 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100277 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700278 return InvokeOnWorker<bool>(
279 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800280 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281}
282
283bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800284 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000285 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100286 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700287 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800288 RTC_FROM_HERE,
289 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000290}
291
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700292bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000293 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800294 return enabled() &&
295 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000296}
297
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700298bool BaseChannel::IsReadyToSendMedia_w() const {
299 // Need to access some state updated on the network thread.
300 return network_thread_->Invoke<bool>(
301 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
302}
303
304bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000305 // Send outgoing data if we are enabled, have local and remote content,
306 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800307 return enabled() &&
308 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
309 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huang365381f2018-04-13 16:44:34 -0700310 was_ever_writable();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000311}
312
jbaucheec21bd2016-03-20 06:15:43 -0700313bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700314 const rtc::PacketOptions& options) {
315 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316}
317
jbaucheec21bd2016-03-20 06:15:43 -0700318bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700319 const rtc::PacketOptions& options) {
320 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321}
322
Yves Gerey665174f2018-06-19 15:03:05 +0200323int BaseChannel::SetOption(SocketType type,
324 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200326 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700327 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200328}
329
330int BaseChannel::SetOption_n(SocketType type,
331 rtc::Socket::Option opt,
332 int value) {
333 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700334 RTC_DCHECK(rtp_transport_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000336 case ST_RTP:
deadbeefcbecd352015-09-23 11:50:27 -0700337 socket_options_.push_back(
338 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700339 return rtp_transport_->SetRtpOption(opt, value);
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000340 case ST_RTCP:
deadbeefcbecd352015-09-23 11:50:27 -0700341 rtcp_socket_options_.push_back(
342 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700343 return rtp_transport_->SetRtcpOption(opt, value);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700345 return -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346}
347
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800348void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200349 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800350 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800351 ChannelWritable_n();
352 } else {
353 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800354 }
355}
356
Zhi Huang942bc2e2017-11-13 13:26:07 -0800357void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200358 absl::optional<rtc::NetworkRoute> network_route) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300359 RTC_LOG(LS_INFO) << "Network route for " << ToString() << " was changed.";
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800360
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200361 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800362 rtc::NetworkRoute new_route;
363 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800364 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000365 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800366 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
367 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
368 // work correctly. Intentionally leave it broken to simplify the code and
369 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800370 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800371 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800372 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700373}
374
zstein56162b92017-04-24 16:54:35 -0700375void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800376 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
377 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378}
379
stefanc1aeaf02015-10-15 07:26:07 -0700380bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700381 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700382 const rtc::PacketOptions& options) {
Amit Hilbuchedd20542019-03-18 12:33:43 -0700383 // Until all the code is migrated to use RtpPacketType instead of bool.
384 RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200385 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
386 // If the thread is not our network thread, we will post to our network
387 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000388 // synchronize access to all the pieces of the send path, including
389 // SRTP and the inner workings of the transport channels.
390 // The only downside is that we can't return a proper failure code if
391 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200392 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000393 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200394 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
395 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800396 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700397 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700398 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000399 return true;
400 }
Zhi Huange830e682018-03-30 10:48:35 -0700401
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200402 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000403
404 // Now that we are on the correct thread, ensure we have a place to send this
405 // packet before doing anything. (We might get RTCP packets that we don't
406 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
407 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700408 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000409 return false;
410 }
411
412 // Protect ourselves against crazy data.
Amit Hilbuchedd20542019-03-18 12:33:43 -0700413 if (!IsValidRtpPacketSize(packet_type, packet->size())) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300414 RTC_LOG(LS_ERROR) << "Dropping outgoing " << ToString() << " "
Amit Hilbuchedd20542019-03-18 12:33:43 -0700415 << RtpPacketTypeToString(packet_type)
Mirko Bonadei675513b2017-11-09 11:09:25 +0100416 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000417 return false;
418 }
419
Zhi Huangcf990f52017-09-22 12:12:30 -0700420 if (!srtp_active()) {
421 if (srtp_required_) {
422 // The audio/video engines may attempt to send RTCP packets as soon as the
423 // streams are created, so don't treat this as an error for RTCP.
424 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
425 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000426 return false;
427 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700428 // However, there shouldn't be any RTP packets sent before SRTP is set up
429 // (and SetSend(true) is called).
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300430 RTC_LOG(LS_ERROR) << "Can't send outgoing RTP packet for " << ToString()
431 << " when SRTP is inactive and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700432 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800433 return false;
434 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800435
436 std::string packet_type = rtcp ? "RTCP" : "RTP";
Marina Ciocea38728732020-07-29 10:15:46 +0200437 RTC_DLOG(LS_WARNING) << "Sending an " << packet_type
438 << " packet without encryption for " << ToString()
439 << ".";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000440 }
Zhi Huange830e682018-03-30 10:48:35 -0700441
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000442 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800443 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
444 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000445}
446
Zhi Huang365381f2018-04-13 16:44:34 -0700447void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Niels Möller29e13fd2018-12-17 12:35:30 +0100448 // Take packet time from the |parsed_packet|.
449 // RtpPacketReceived.arrival_time_ms = (timestamp_us + 500) / 1000;
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200450 int64_t packet_time_us = -1;
Zhi Huang365381f2018-04-13 16:44:34 -0700451 if (parsed_packet.arrival_time_ms() > 0) {
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200452 packet_time_us = parsed_packet.arrival_time_ms() * 1000;
Zhi Huang365381f2018-04-13 16:44:34 -0700453 }
Zhi Huang365381f2018-04-13 16:44:34 -0700454
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200455 if (!has_received_packet_) {
456 has_received_packet_ = true;
457 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
458 }
459
460 if (!srtp_active() && srtp_required_) {
461 // Our session description indicates that SRTP is required, but we got a
462 // packet before our SRTP filter is active. This means either that
463 // a) we got SRTP packets before we received the SDES keys, in which case
464 // we can't decrypt it anyway, or
465 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
466 // transports, so we haven't yet extracted keys, even if DTLS did
467 // complete on the transport that the packets are being sent on. It's
468 // really good practice to wait for both RTP and RTCP to be good to go
469 // before sending media, to prevent weird failure modes, so it's fine
470 // for us to just eat packets here. This is all sidestepped if RTCP mux
471 // is used anyway.
472 RTC_LOG(LS_WARNING) << "Can't process incoming RTP packet when "
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300473 "SRTP is inactive and crypto is required "
474 << ToString();
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200475 return;
476 }
477
478 auto packet_buffer = parsed_packet.Buffer();
479
480 invoker_.AsyncInvoke<void>(
481 RTC_FROM_HERE, worker_thread_, [this, packet_buffer, packet_time_us] {
482 RTC_DCHECK(worker_thread_->IsCurrent());
483 media_channel_->OnPacketReceived(packet_buffer, packet_time_us);
484 });
Zhi Huang365381f2018-04-13 16:44:34 -0700485}
486
487void BaseChannel::UpdateRtpHeaderExtensionMap(
488 const RtpHeaderExtensions& header_extensions) {
489 RTC_DCHECK(rtp_transport_);
490 // Update the header extension map on network thread in case there is data
491 // race.
492 // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
493 // be accessed from different threads.
494 //
495 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
496 // extension maps are not merged when BUNDLE is enabled. This is fine because
497 // the ID for MID should be consistent among all the RTP transports.
498 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
499 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
500 });
501}
502
503bool BaseChannel::RegisterRtpDemuxerSink() {
504 RTC_DCHECK(rtp_transport_);
505 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
506 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
507 });
508}
509
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000510void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700511 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000512 if (enabled_)
513 return;
514
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300515 RTC_LOG(LS_INFO) << "Channel enabled: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000516 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700517 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000518}
519
520void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700521 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000522 if (!enabled_)
523 return;
524
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300525 RTC_LOG(LS_INFO) << "Channel disabled: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700527 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000528}
529
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200530void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700531 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
532 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200533 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700534 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200535 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700536 }
537}
538
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200539void BaseChannel::ChannelWritable_n() {
540 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800541 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000542 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800543 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300545 RTC_LOG(LS_INFO) << "Channel writable (" << ToString() << ")"
Mirko Bonadei675513b2017-11-09 11:09:25 +0100546 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000547
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000548 was_ever_writable_ = true;
549 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700550 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000551}
552
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200553void BaseChannel::ChannelNotWritable_n() {
554 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555 if (!writable_)
556 return;
557
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300558 RTC_LOG(LS_INFO) << "Channel not writable (" << ToString() << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700560 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000561}
562
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000563bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700564 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800565 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000566}
567
Peter Boström0c4e06b2015-10-07 12:23:21 +0200568bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700569 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000570 return media_channel()->RemoveRecvStream(ssrc);
571}
572
Saurav Dasff27da52019-09-20 11:05:30 -0700573void BaseChannel::ResetUnsignaledRecvStream_w() {
574 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
575 media_channel()->ResetUnsignaledRecvStream();
576}
577
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800579 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000580 std::string* error_desc) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800581 // In the case of RIDs (where SSRCs are not negotiated), this method will
582 // generate an SSRC for each layer in StreamParams. That representation will
583 // be stored internally in |local_streams_|.
584 // In subsequent offers, the same stream can appear in |streams| again
585 // (without the SSRCs), so it should be looked up using RIDs (if available)
586 // and then by primary SSRC.
587 // In both scenarios, it is safe to assume that the media channel will be
588 // created with a StreamParams object with SSRCs. However, it is not safe to
589 // assume that |local_streams_| will always have SSRCs as there are scenarios
590 // in which niether SSRCs or RIDs are negotiated.
591
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000592 // Check for streams that have been removed.
593 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800594 for (const StreamParams& old_stream : local_streams_) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800595 if (!old_stream.has_ssrcs() ||
596 GetStream(streams, StreamFinder(&old_stream))) {
597 continue;
598 }
599 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
600 rtc::StringBuilder desc;
601 desc << "Failed to remove send stream with ssrc "
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000602 << old_stream.first_ssrc() << " from m-section with mid='"
603 << content_name() << "'.";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800604 SafeSetError(desc.str(), error_desc);
605 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000606 }
607 }
608 // Check for new streams.
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800609 std::vector<StreamParams> all_streams;
610 for (const StreamParams& stream : streams) {
611 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
612 if (existing) {
613 // Parameters cannot change for an existing stream.
614 all_streams.push_back(*existing);
615 continue;
616 }
617
618 all_streams.push_back(stream);
619 StreamParams& new_stream = all_streams.back();
620
621 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
622 continue;
623 }
624
625 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
626 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
627 rtc::StringBuilder desc;
628 desc << "Failed to add send stream: " << new_stream.first_ssrc()
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000629 << " into m-section with mid='" << content_name()
630 << "'. Stream has both SSRCs and RIDs.";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800631 SafeSetError(desc.str(), error_desc);
632 ret = false;
633 continue;
634 }
635
636 // At this point we use the legacy simulcast group in StreamParams to
637 // indicate that we want multiple layers to the media channel.
638 if (!new_stream.has_ssrcs()) {
639 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
640 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
641 /* flex_fec = */ false, ssrc_generator_);
642 }
643
644 if (media_channel()->AddSendStream(new_stream)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300645 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0]
646 << " into " << ToString();
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800647 } else {
648 rtc::StringBuilder desc;
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000649 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc()
650 << " into m-section with mid='" << content_name() << "'";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800651 SafeSetError(desc.str(), error_desc);
652 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000653 }
654 }
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800655 local_streams_ = all_streams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000656 return ret;
657}
658
659bool BaseChannel::UpdateRemoteStreams_w(
660 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800661 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000662 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000663 // Check for streams that have been removed.
664 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800665 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700666 // If we no longer have an unsignaled stream, we would like to remove
667 // the unsignaled stream params that are cached.
Saurav Dasff27da52019-09-20 11:05:30 -0700668 if (!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) {
669 ResetUnsignaledRecvStream_w();
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300670 RTC_LOG(LS_INFO) << "Reset unsignaled remote stream for " << ToString()
671 << ".";
Saurav Dasff27da52019-09-20 11:05:30 -0700672 } else if (old_stream.has_ssrcs() &&
673 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800674 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300675 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc()
676 << " from " << ToString() << ".";
Zhi Huang365381f2018-04-13 16:44:34 -0700677 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200678 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800679 desc << "Failed to remove remote stream with ssrc "
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000680 << old_stream.first_ssrc() << " from m-section with mid='"
681 << content_name() << "'.";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000682 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000683 ret = false;
684 }
685 }
686 }
Zhi Huang365381f2018-04-13 16:44:34 -0700687 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800689 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700690 // We allow a StreamParams with an empty list of SSRCs, in which case the
691 // MediaChannel will cache the parameters and use them for any unsignaled
692 // stream received later.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800693 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
694 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
695 if (AddRecvStream_w(new_stream)) {
Saurav Dasff27da52019-09-20 11:05:30 -0700696 RTC_LOG(LS_INFO) << "Add remote ssrc: "
697 << (new_stream.has_ssrcs()
698 ? std::to_string(new_stream.first_ssrc())
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300699 : "unsignaled")
700 << " to " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000701 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200702 rtc::StringBuilder desc;
Saurav Dasff27da52019-09-20 11:05:30 -0700703 desc << "Failed to add remote stream ssrc: "
704 << (new_stream.has_ssrcs()
705 ? std::to_string(new_stream.first_ssrc())
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300706 : "unsignaled")
707 << " to " << ToString();
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 }
Zhi Huang365381f2018-04-13 16:44:34 -0700712 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800713 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
714 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 }
Zhi Huang365381f2018-04-13 16:44:34 -0700716 // Re-register the sink to update the receiving ssrcs.
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300717 if (!RegisterRtpDemuxerSink()) {
718 RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString();
719 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 remote_streams_ = streams;
721 return ret;
722}
723
jbauch5869f502017-06-29 12:31:36 -0700724RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
725 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700726 RTC_DCHECK(rtp_transport_);
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700727 if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700728 RtpHeaderExtensions filtered;
Steve Anton64b626b2019-01-28 17:25:26 -0800729 absl::c_copy_if(extensions, std::back_inserter(filtered),
730 [](const webrtc::RtpExtension& extension) {
731 return !extension.encrypt;
732 });
jbauch5869f502017-06-29 12:31:36 -0700733 return filtered;
734 }
735
736 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
737}
738
Yves Gerey665174f2018-06-19 15:03:05 +0200739void BaseChannel::OnMessage(rtc::Message* pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100740 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200742 case MSG_SEND_RTP_PACKET:
743 case MSG_SEND_RTCP_PACKET: {
744 RTC_DCHECK(network_thread_->IsCurrent());
745 SendPacketMessageData* data =
746 static_cast<SendPacketMessageData*>(pmsg->pdata);
747 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
748 SendPacket(rtcp, &data->packet, data->options);
749 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000750 break;
751 }
752 case MSG_FIRSTPACKETRECEIVED: {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800753 SignalFirstPacketReceived_(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000754 break;
755 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000756 }
757}
758
zstein3dcf0e92017-06-01 13:22:42 -0700759void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang365381f2018-04-13 16:44:34 -0700760 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -0700761}
762
Steve Antonbe2e5f72019-09-06 16:26:02 -0700763void BaseChannel::ClearHandledPayloadTypes() {
764 demuxer_criteria_.payload_types.clear();
765}
766
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200767void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768 // Flush all remaining RTCP messages. This should only be called in
769 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200770 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000771 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200772 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
773 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700774 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
775 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 }
777}
778
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800779void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200780 RTC_DCHECK(network_thread_->IsCurrent());
Sebastian Jansson01be33b2019-09-12 17:39:18 +0200781 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
782 [this, sent_packet] {
783 RTC_DCHECK(worker_thread_->IsCurrent());
784 SignalSentPacket(sent_packet);
785 });
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200786}
787
788VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
789 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800790 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800791 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000792 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700793 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800794 webrtc::CryptoOptions crypto_options,
795 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200796 : BaseChannel(worker_thread,
797 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800798 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800799 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700800 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700801 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800802 crypto_options,
803 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804
805VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800806 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807 // this can't be done in the base class, since it calls a virtual
808 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700809 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810}
811
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700812void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200813 RTC_DCHECK(network_thread_->IsCurrent());
Sebastian Jansson01be33b2019-09-12 17:39:18 +0200814 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
815 [this] { UpdateMediaSendRecvState_w(); });
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200816}
817
Niels Möller2a707032020-06-16 16:39:13 +0200818void VoiceChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
819 BaseChannel::Init_w(rtp_transport);
Piotr (Peter) Slatala309aafe2019-01-15 14:24:34 -0800820}
821
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700822void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823 // Render incoming data if we're the active call, and we have the local
824 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700825 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700826 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827
828 // Send outgoing data if we're the active call, we have the remote content,
829 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700830 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800831 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300833 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send
834 << " for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835}
836
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800838 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000839 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100840 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800841 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300842 RTC_LOG(LS_INFO) << "Setting local voice description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843
Steve Antonb1c1de12017-12-21 15:14:30 -0800844 RTC_DCHECK(content);
845 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000846 SafeSetError("Can't find audio content in local description.", error_desc);
847 return false;
848 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849
Steve Antonb1c1de12017-12-21 15:14:30 -0800850 const AudioContentDescription* audio = content->as_audio();
851
jbauch5869f502017-06-29 12:31:36 -0700852 RtpHeaderExtensions rtp_header_extensions =
853 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -0700854 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +0100855 media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700856
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700857 AudioRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +0200858 RtpParametersFromMediaDescription(
859 audio, rtp_header_extensions,
860 webrtc::RtpTransceiverDirectionHasRecv(audio->direction()), &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700861 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000862 SafeSetError(
863 "Failed to set local audio description recv parameters for m-section "
864 "with mid='" +
865 content_name() + "'.",
866 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700867 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868 }
Steve Antonbe2e5f72019-09-06 16:26:02 -0700869
870 if (webrtc::RtpTransceiverDirectionHasRecv(audio->direction())) {
871 for (const AudioCodec& codec : audio->codecs()) {
872 AddHandledPayloadType(codec.id);
873 }
874 // Need to re-register the sink to update the handled payload.
875 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300876 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing for " << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -0700877 return false;
878 }
Zhi Huang365381f2018-04-13 16:44:34 -0700879 }
880
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700881 last_recv_params_ = recv_params;
882
883 // TODO(pthatcher): Move local streams into AudioSendParameters, and
884 // only give it to the media channel once we have a remote
885 // description too (without a remote description, we won't be able
886 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800887 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000888 SafeSetError(
889 "Failed to set local audio description streams for m-section with "
890 "mid='" +
891 content_name() + "'.",
892 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700893 return false;
894 }
895
896 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700897 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700898 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899}
900
901bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800902 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000903 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100904 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800905 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300906 RTC_LOG(LS_INFO) << "Setting remote voice description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907
Steve Antonb1c1de12017-12-21 15:14:30 -0800908 RTC_DCHECK(content);
909 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000910 SafeSetError("Can't find audio content in remote description.", error_desc);
911 return false;
912 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000913
Steve Antonb1c1de12017-12-21 15:14:30 -0800914 const AudioContentDescription* audio = content->as_audio();
915
jbauch5869f502017-06-29 12:31:36 -0700916 RtpHeaderExtensions rtp_header_extensions =
917 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
918
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700919 AudioSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +0200920 RtpSendParametersFromMediaDescription(
921 audio, rtp_header_extensions,
922 webrtc::RtpTransceiverDirectionHasRecv(audio->direction()), &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700923 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700924
925 bool parameters_applied = media_channel()->SetSendParameters(send_params);
926 if (!parameters_applied) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000927 SafeSetError(
928 "Failed to set remote audio description send parameters for m-section "
929 "with mid='" +
930 content_name() + "'.",
931 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700932 return false;
933 }
934 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935
Steve Antonbe2e5f72019-09-06 16:26:02 -0700936 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
937 RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300938 "disable payload type demuxing for "
939 << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -0700940 ClearHandledPayloadTypes();
941 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300942 RTC_LOG(LS_ERROR) << "Failed to update audio demuxing for " << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -0700943 return false;
944 }
945 }
946
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700947 // 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 10:34:51 -0800951 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000952 SafeSetError(
953 "Failed to set remote audio description streams for m-section with "
954 "mid='" +
955 content_name() + "'.",
956 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700957 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958 }
959
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700960 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700961 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700962 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963}
964
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200965VideoChannel::VideoChannel(rtc::Thread* worker_thread,
966 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800967 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800968 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700970 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800971 webrtc::CryptoOptions crypto_options,
972 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200973 : BaseChannel(worker_thread,
974 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800975 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800976 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700977 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700978 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800979 crypto_options,
980 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800983 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000984 // this can't be done in the base class, since it calls a virtual
985 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700986 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987}
988
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700989void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000990 // Send outgoing data if we're the active call, we have the remote content,
991 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700992 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000993 if (!media_channel()->SetSend(send)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300994 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel: " + ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995 // TODO(gangji): Report error back to server.
996 }
997
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300998 RTC_LOG(LS_INFO) << "Changing video state, send=" << send << " for "
999 << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000}
1001
stefanf79ade12017-06-02 06:44:03 -07001002void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
1003 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
1004 media_channel(), bwe_info));
1005}
1006
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001008 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001009 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001010 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001011 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001012 RTC_LOG(LS_INFO) << "Setting local video description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001013
Steve Antonb1c1de12017-12-21 15:14:30 -08001014 RTC_DCHECK(content);
1015 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001016 SafeSetError("Can't find video content in local description.", error_desc);
1017 return false;
1018 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019
Steve Antonb1c1de12017-12-21 15:14:30 -08001020 const VideoContentDescription* video = content->as_video();
1021
jbauch5869f502017-06-29 12:31:36 -07001022 RtpHeaderExtensions rtp_header_extensions =
1023 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang365381f2018-04-13 16:44:34 -07001024 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Johannes Kron9190b822018-10-29 11:22:05 +01001025 media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -07001026
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001027 VideoRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001028 RtpParametersFromMediaDescription(
1029 video, rtp_header_extensions,
1030 webrtc::RtpTransceiverDirectionHasRecv(video->direction()), &recv_params);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001031
1032 VideoSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001033
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001034 bool needs_send_params_update = false;
Johannes Krona104ceb2020-01-24 16:04:04 +00001035 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001036 for (auto& send_codec : send_params.codecs) {
1037 auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
1038 if (recv_codec) {
1039 if (!recv_codec->packetization && send_codec.packetization) {
1040 send_codec.packetization.reset();
1041 needs_send_params_update = true;
1042 } else if (recv_codec->packetization != send_codec.packetization) {
1043 SafeSetError(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001044 "Failed to set local answer due to invalid codec packetization "
1045 "specified in m-section with mid='" +
1046 content_name() + "'.",
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001047 error_desc);
1048 return false;
1049 }
1050 }
1051 }
1052 }
1053
Johannes Krona104ceb2020-01-24 16:04:04 +00001054 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001055 SafeSetError(
1056 "Failed to set local video description recv parameters for m-section "
1057 "with mid='" +
1058 content_name() + "'.",
1059 error_desc);
Johannes Krona104ceb2020-01-24 16:04:04 +00001060 return false;
1061 }
Johannes Kron9bac68c2020-01-23 13:12:25 +00001062
Johannes Krona104ceb2020-01-24 16:04:04 +00001063 if (webrtc::RtpTransceiverDirectionHasRecv(video->direction())) {
Steve Antonbe2e5f72019-09-06 16:26:02 -07001064 for (const VideoCodec& codec : video->codecs()) {
1065 AddHandledPayloadType(codec.id);
1066 }
1067 // Need to re-register the sink to update the handled payload.
1068 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001069 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing for " << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -07001070 return false;
1071 }
Zhi Huang365381f2018-04-13 16:44:34 -07001072 }
1073
Johannes Krona104ceb2020-01-24 16:04:04 +00001074 last_recv_params_ = recv_params;
1075
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001076 if (needs_send_params_update) {
1077 if (!media_channel()->SetSendParameters(send_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001078 SafeSetError("Failed to set send parameters for m-section with mid='" +
1079 content_name() + "'.",
1080 error_desc);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001081 return false;
1082 }
1083 last_send_params_ = send_params;
1084 }
1085
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001086 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1087 // only give it to the media channel once we have a remote
1088 // description too (without a remote description, we won't be able
1089 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001090 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001091 SafeSetError(
1092 "Failed to set local video description streams for m-section with "
1093 "mid='" +
1094 content_name() + "'.",
1095 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001096 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001097 }
1098
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001099 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001100 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001101 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001102}
1103
1104bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001105 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001106 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001107 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001108 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001109 RTC_LOG(LS_INFO) << "Setting remote video description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001110
Steve Antonb1c1de12017-12-21 15:14:30 -08001111 RTC_DCHECK(content);
1112 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001113 SafeSetError("Can't find video content in remote description.", error_desc);
1114 return false;
1115 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001116
Steve Antonb1c1de12017-12-21 15:14:30 -08001117 const VideoContentDescription* video = content->as_video();
1118
jbauch5869f502017-06-29 12:31:36 -07001119 RtpHeaderExtensions rtp_header_extensions =
1120 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1121
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001122 VideoSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001123 RtpSendParametersFromMediaDescription(
1124 video, rtp_header_extensions,
1125 webrtc::RtpTransceiverDirectionHasRecv(video->direction()), &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001126 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001127 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001128 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001129 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001130
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001131 VideoRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001132
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001133 bool needs_recv_params_update = false;
Johannes Krona104ceb2020-01-24 16:04:04 +00001134 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001135 for (auto& recv_codec : recv_params.codecs) {
1136 auto* send_codec = FindMatchingCodec(send_params.codecs, recv_codec);
1137 if (send_codec) {
1138 if (!send_codec->packetization && recv_codec.packetization) {
1139 recv_codec.packetization.reset();
1140 needs_recv_params_update = true;
1141 } else if (send_codec->packetization != recv_codec.packetization) {
1142 SafeSetError(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001143 "Failed to set remote answer due to invalid codec packetization "
1144 "specifid in m-section with mid='" +
1145 content_name() + "'.",
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001146 error_desc);
1147 return false;
1148 }
1149 }
1150 }
1151 }
skvladdc1c62c2016-03-16 19:07:43 -07001152
Johannes Krona104ceb2020-01-24 16:04:04 +00001153 if (!media_channel()->SetSendParameters(send_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001154 SafeSetError(
1155 "Failed to set remote video description send parameters for m-section "
1156 "with mid='" +
1157 content_name() + "'.",
1158 error_desc);
Johannes Krona104ceb2020-01-24 16:04:04 +00001159 return false;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001160 }
Johannes Krona104ceb2020-01-24 16:04:04 +00001161 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001162
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001163 if (needs_recv_params_update) {
1164 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001165 SafeSetError("Failed to set recv parameters for m-section with mid='" +
1166 content_name() + "'.",
1167 error_desc);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001168 return false;
1169 }
1170 last_recv_params_ = recv_params;
1171 }
1172
Steve Antonbe2e5f72019-09-06 16:26:02 -07001173 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
1174 RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001175 "disable payload type demuxing for "
1176 << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -07001177 ClearHandledPayloadTypes();
1178 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001179 RTC_LOG(LS_ERROR) << "Failed to update video demuxing for " << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -07001180 return false;
1181 }
1182 }
1183
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001184 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1185 // and only give it to the media channel once we have a local
1186 // description too (without a local description, we won't be able to
1187 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001188 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001189 SafeSetError(
1190 "Failed to set remote video description streams for m-section with "
1191 "mid='" +
1192 content_name() + "'.",
1193 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001194 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001195 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001196 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001197 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001198 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001199}
1200
deadbeef953c2ce2017-01-09 14:53:41 -08001201RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1202 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001203 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001204 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001205 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001206 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001207 webrtc::CryptoOptions crypto_options,
1208 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001209 : BaseChannel(worker_thread,
1210 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001211 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001212 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001213 content_name,
Zhi Huange830e682018-03-30 10:48:35 -07001214 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001215 crypto_options,
1216 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001217
deadbeef953c2ce2017-01-09 14:53:41 -08001218RtpDataChannel::~RtpDataChannel() {
1219 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001220 // this can't be done in the base class, since it calls a virtual
1221 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -07001222 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001223}
1224
Niels Möller2a707032020-06-16 16:39:13 +02001225void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
1226 BaseChannel::Init_w(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001227 media_channel()->SignalDataReceived.connect(this,
1228 &RtpDataChannel::OnDataReceived);
1229 media_channel()->SignalReadyToSend.connect(
1230 this, &RtpDataChannel::OnDataChannelReadyToSend);
1231}
1232
deadbeef953c2ce2017-01-09 14:53:41 -08001233bool RtpDataChannel::SendData(const SendDataParams& params,
1234 const rtc::CopyOnWriteBuffer& payload,
1235 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001236 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001237 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1238 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001239}
1240
deadbeef953c2ce2017-01-09 14:53:41 -08001241bool RtpDataChannel::CheckDataChannelTypeFromContent(
Harald Alvestrand755187f2019-12-05 13:43:34 +01001242 const MediaContentDescription* content,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001243 std::string* error_desc) {
Harald Alvestrand755187f2019-12-05 13:43:34 +01001244 if (!content->as_rtp_data()) {
1245 if (content->as_sctp()) {
1246 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1247 error_desc);
1248 } else {
1249 SafeSetError("Data channel is not RTP or SCTP.", error_desc);
1250 }
deadbeef953c2ce2017-01-09 14:53:41 -08001251 return false;
1252 }
1253 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001254}
1255
deadbeef953c2ce2017-01-09 14:53:41 -08001256bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001257 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001258 std::string* error_desc) {
1259 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001260 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001261 RTC_LOG(LS_INFO) << "Setting local data description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001262
Steve Antonb1c1de12017-12-21 15:14:30 -08001263 RTC_DCHECK(content);
1264 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001265 SafeSetError("Can't find data content in local description.", error_desc);
1266 return false;
1267 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001268
Harald Alvestrand755187f2019-12-05 13:43:34 +01001269 if (!CheckDataChannelTypeFromContent(content, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001270 return false;
1271 }
Harald Alvestrand755187f2019-12-05 13:43:34 +01001272 const RtpDataContentDescription* data = content->as_rtp_data();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001273
jbauch5869f502017-06-29 12:31:36 -07001274 RtpHeaderExtensions rtp_header_extensions =
1275 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1276
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001277 DataRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001278 RtpParametersFromMediaDescription(
1279 data, rtp_header_extensions,
1280 webrtc::RtpTransceiverDirectionHasRecv(data->direction()), &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001281 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001282 SafeSetError(
1283 "Failed to set remote data description recv parameters for m-section "
1284 "with mid='" +
1285 content_name() + "'.",
1286 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001287 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001288 }
deadbeef953c2ce2017-01-09 14:53:41 -08001289 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001290 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001291 }
Zhi Huang365381f2018-04-13 16:44:34 -07001292 // Need to re-register the sink to update the handled payload.
1293 if (!RegisterRtpDemuxerSink()) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001294 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing for " << ToString();
Zhi Huang365381f2018-04-13 16:44:34 -07001295 return false;
1296 }
1297
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001298 last_recv_params_ = recv_params;
1299
1300 // TODO(pthatcher): Move local streams into DataSendParameters, and
1301 // only give it to the media channel once we have a remote
1302 // description too (without a remote description, we won't be able
1303 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001304 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001305 SafeSetError(
1306 "Failed to set local data description streams for m-section with "
1307 "mid='" +
1308 content_name() + "'.",
1309 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001310 return false;
1311 }
1312
1313 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001314 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001315 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316}
1317
deadbeef953c2ce2017-01-09 14:53:41 -08001318bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001319 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001320 std::string* error_desc) {
1321 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001322 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001323 RTC_LOG(LS_INFO) << "Setting remote data description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001324
Steve Antonb1c1de12017-12-21 15:14:30 -08001325 RTC_DCHECK(content);
1326 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001327 SafeSetError("Can't find data content in remote description.", error_desc);
1328 return false;
1329 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001330
Harald Alvestrand755187f2019-12-05 13:43:34 +01001331 if (!CheckDataChannelTypeFromContent(content, error_desc)) {
1332 return false;
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02001333 }
Steve Antonb1c1de12017-12-21 15:14:30 -08001334
Harald Alvestrand755187f2019-12-05 13:43:34 +01001335 const RtpDataContentDescription* data = content->as_rtp_data();
1336
Zhi Huang801b8682017-11-15 11:36:43 -08001337 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1338 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001339 return true;
1340 }
1341
jbauch5869f502017-06-29 12:31:36 -07001342 RtpHeaderExtensions rtp_header_extensions =
1343 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1344
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001345 RTC_LOG(LS_INFO) << "Setting remote data description for " << ToString();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001346 DataSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001347 RtpSendParametersFromMediaDescription<DataCodec>(
1348 data, rtp_header_extensions,
1349 webrtc::RtpTransceiverDirectionHasRecv(data->direction()), &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001350 if (!media_channel()->SetSendParameters(send_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001351 SafeSetError(
1352 "Failed to set remote data description send parameters for m-section "
1353 "with mid='" +
1354 content_name() + "'.",
1355 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001356 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001357 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001358 last_send_params_ = send_params;
1359
1360 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1361 // and only give it to the media channel once we have a local
1362 // description too (without a local description, we won't be able to
1363 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001364 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001365 SafeSetError(
1366 "Failed to set remote data description streams for m-section with "
1367 "mid='" +
1368 content_name() + "'.",
1369 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001370 return false;
1371 }
1372
1373 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001374 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001375 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001376}
1377
deadbeef953c2ce2017-01-09 14:53:41 -08001378void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001379 // Render incoming data if we're the active call, and we have the local
1380 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001381 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382 if (!media_channel()->SetReceive(recv)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001383 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384 }
1385
1386 // Send outgoing data if we're the active call, we have the remote content,
1387 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001388 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001389 if (!media_channel()->SetSend(send)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001390 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001391 }
1392
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001393 // Trigger SignalReadyToSendData asynchronously.
1394 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001396 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send
1397 << " for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398}
1399
deadbeef953c2ce2017-01-09 14:53:41 -08001400void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001401 switch (pmsg->message_id) {
1402 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001403 DataChannelReadyToSendMessageData* data =
1404 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001405 ready_to_send_data_ = data->data();
1406 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407 delete data;
1408 break;
1409 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001410 case MSG_DATARECEIVED: {
1411 DataReceivedMessageData* data =
1412 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001413 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414 delete data;
1415 break;
1416 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001417 default:
1418 BaseChannel::OnMessage(pmsg);
1419 break;
1420 }
1421}
1422
deadbeef953c2ce2017-01-09 14:53:41 -08001423void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1424 const char* data,
1425 size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +02001426 DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001427 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001428}
1429
deadbeef953c2ce2017-01-09 14:53:41 -08001430void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001431 // This is usded for congestion control to indicate that the stream is ready
1432 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1433 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001434 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001435 new DataChannelReadyToSendMessageData(writable));
1436}
1437
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438} // namespace cricket