blob: 7b6c0c870474a00ade146f8cc25e18b2e16a3dbe [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
Harald Alvestrand5761e7b2021-01-29 14:45:08 +000013#include <algorithm>
14#include <cstdint>
jbauch5869f502017-06-29 12:31:36 -070015#include <iterator>
Harald Alvestrand5761e7b2021-01-29 14:45:08 +000016#include <map>
kwiberg0eb15ed2015-12-17 03:04:15 -080017#include <utility>
18
Steve Anton64b626b2019-01-28 17:25:26 -080019#include "absl/algorithm/container.h"
Harald Alvestrand5761e7b2021-01-29 14:45:08 +000020#include "absl/strings/string_view.h"
21#include "api/rtp_parameters.h"
Artem Titovd15a5752021-02-10 14:31:24 +010022#include "api/sequence_checker.h"
Harald Alvestrand5761e7b2021-01-29 14:45:08 +000023#include "api/task_queue/queued_task.h"
24#include "media/base/codec.h"
25#include "media/base/rid_description.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "media/base/rtp_utils.h"
Zhi Huang365381f2018-04-13 16:44:34 -070027#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070028#include "pc/rtp_media_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "rtc_base/copy_on_write_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/network_route.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020033#include "rtc_base/strings/string_builder.h"
Markus Handell19217082021-01-14 14:00:40 +010034#include "rtc_base/synchronization/mutex.h"
Danil Chapovalovfd9500e2021-01-15 17:29:53 +010035#include "rtc_base/task_utils/pending_task_safety_flag.h"
36#include "rtc_base/task_utils/to_queued_task.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "rtc_base/trace_event.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038
39namespace cricket {
deadbeef2d110be2016-01-13 12:00:26 -080040namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020041
Danil Chapovalovfd9500e2021-01-15 17:29:53 +010042using ::rtc::UniqueRandomIdGenerator;
43using ::webrtc::PendingTaskSafetyFlag;
44using ::webrtc::SdpType;
45using ::webrtc::ToQueuedTask;
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
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000082static void SafeSetError(const std::string& message, std::string* error_desc) {
83 if (error_desc) {
84 *error_desc = message;
85 }
86}
87
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070088template <class Codec>
89void RtpParametersFromMediaDescription(
90 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070091 const RtpHeaderExtensions& extensions,
Johannes Kron3e983682020-03-29 22:17:00 +020092 bool is_stream_active,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070093 RtpParameters<Codec>* params) {
Johannes Kron3e983682020-03-29 22:17:00 +020094 params->is_stream_active = is_stream_active;
Mirko Bonadei1f0677d2020-04-17 14:15:47 +020095 params->codecs = desc->codecs();
96 // TODO(bugs.webrtc.org/11513): See if we really need
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070097 // rtp_header_extensions_set() and remove it if we don't.
98 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -070099 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700100 }
deadbeef13871492015-12-09 12:37:51 -0800101 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Sebastian Janssone1795f42019-07-24 11:38:03 +0200102 params->rtcp.remote_estimate = desc->remote_estimate();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700103}
104
nisse05103312016-03-16 02:22:50 -0700105template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700106void RtpSendParametersFromMediaDescription(
107 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -0700108 const RtpHeaderExtensions& extensions,
Johannes Kron3e983682020-03-29 22:17:00 +0200109 bool is_stream_active,
nisse05103312016-03-16 02:22:50 -0700110 RtpSendParameters<Codec>* send_params) {
Johannes Kron3e983682020-03-29 22:17:00 +0200111 RtpParametersFromMediaDescription(desc, extensions, is_stream_active,
112 send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700113 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 11:22:05 +0100114 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700115}
116
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200117BaseChannel::BaseChannel(rtc::Thread* worker_thread,
118 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800119 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800120 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700121 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700122 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800123 webrtc::CryptoOptions crypto_options,
124 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200125 : worker_thread_(worker_thread),
126 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800127 signaling_thread_(signaling_thread),
Danil Chapovalovfd9500e2021-01-15 17:29:53 +0100128 alive_(PendingTaskSafetyFlag::Create()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800130 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700131 crypto_options_(crypto_options),
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800132 media_channel_(std::move(media_channel)),
133 ssrc_generator_(ssrc_generator) {
Steve Anton8699a322017-11-06 15:53:33 -0800134 RTC_DCHECK_RUN_ON(worker_thread_);
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800135 RTC_DCHECK(ssrc_generator_);
Harald Alvestrand117e95f2021-12-09 16:40:12 +0000136 // Temp fix: MID in SDP is allowed to be slightly longer than what's allowed
137 // in the RTP demuxer. Truncate if needed; this won't match, but it only
138 // makes sense in places that wouldn't use this for matching anyway.
139 // TODO(bugs.webrtc.org/12517): remove when length 16 is policed by parser.
140 if (content_name.size() > 16) {
141 RTC_LOG(LS_ERROR) << "Overlong mid attribute, truncating for matching";
142 demuxer_criteria_.mid = content_name.substr(0, 16);
143 } else {
144 demuxer_criteria_.mid = content_name;
145 }
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300146 RTC_LOG(LS_INFO) << "Created channel: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000147}
148
149BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800150 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800151 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800152
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200153 // Eats any outstanding messages or packets.
Danil Chapovalovfd9500e2021-01-15 17:29:53 +0100154 alive_->SetNotAlive();
Harald Alvestrand0f0bcb32020-12-07 11:45:55 +0000155 // The media channel is destroyed at the end of the destructor, since it
156 // is a std::unique_ptr. The transport channel (rtp_transport) must outlive
157 // the media channel.
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300158}
159
160std::string BaseChannel::ToString() const {
161 rtc::StringBuilder sb;
162 sb << "{mid: " << content_name_;
163 if (media_channel_) {
164 sb << ", media_type: " << MediaTypeToString(media_channel_->media_type());
165 }
166 sb << "}";
167 return sb.Release();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200168}
169
Zhi Huang365381f2018-04-13 16:44:34 -0700170bool BaseChannel::ConnectToRtpTransport() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800171 RTC_DCHECK(rtp_transport_);
Tomas Gunnarssoneb9c3f22021-04-19 12:53:09 +0200172 RTC_DCHECK(media_channel());
173
Henrik Boström15e078c2021-04-16 09:54:18 +0200174 // We don't need to call OnDemuxerCriteriaUpdatePending/Complete because
175 // there's no previous criteria to worry about.
176 bool result = rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
177 if (result) {
178 previous_demuxer_criteria_ = demuxer_criteria_;
179 } else {
180 previous_demuxer_criteria_ = {};
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300181 RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString();
Zhi Huang365381f2018-04-13 16:44:34 -0700182 return false;
183 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800184 rtp_transport_->SignalReadyToSend.connect(
185 this, &BaseChannel::OnTransportReadyToSend);
Bjorn A Mellem7a9a0922019-11-26 09:19:40 -0800186 rtp_transport_->SignalNetworkRouteChanged.connect(
187 this, &BaseChannel::OnNetworkRouteChanged);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800188 rtp_transport_->SignalWritableState.connect(this,
189 &BaseChannel::OnWritableState);
190 rtp_transport_->SignalSentPacket.connect(this,
191 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 16:44:34 -0700192 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800193}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200194
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800195void BaseChannel::DisconnectFromRtpTransport() {
196 RTC_DCHECK(rtp_transport_);
Tomas Gunnarssoneb9c3f22021-04-19 12:53:09 +0200197 RTC_DCHECK(media_channel());
Zhi Huang365381f2018-04-13 16:44:34 -0700198 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800199 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800200 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
201 rtp_transport_->SignalWritableState.disconnect(this);
202 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200203}
204
Niels Möller2a707032020-06-16 16:39:13 +0200205void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
Harald Alvestrand27883a22020-11-26 07:24:32 +0000206 RTC_DCHECK_RUN_ON(worker_thread());
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800207
Tommic9625f02021-05-06 22:03:19 +0200208 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, rtp_transport] {
209 SetRtpTransport(rtp_transport);
210 // Both RTP and RTCP channels should be set, we can call SetInterface on
211 // the media channel and it can set network options.
212 media_channel_->SetInterface(this);
213 });
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200214}
215
wu@webrtc.org78187522013-10-07 23:32:02 +0000216void BaseChannel::Deinit() {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700217 RTC_DCHECK_RUN_ON(worker_thread());
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200218 // Packets arrive on the network thread, processing packets calls virtual
219 // functions, so need to stop this process in Deinit that is called in
220 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800221 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Harald Alvestrand27883a22020-11-26 07:24:32 +0000222 RTC_DCHECK_RUN_ON(network_thread());
Tommic9625f02021-05-06 22:03:19 +0200223 media_channel_->SetInterface(/*iface=*/nullptr);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700224
Zhi Huange830e682018-03-30 10:48:35 -0700225 if (rtp_transport_) {
226 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000227 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800228 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000229}
230
Zhi Huang365381f2018-04-13 16:44:34 -0700231bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
Markus Handell518669d2021-06-07 13:30:46 +0200232 TRACE_EVENT0("webrtc", "BaseChannel::SetRtpTransport");
Harald Alvestrand27883a22020-11-26 07:24:32 +0000233 RTC_DCHECK_RUN_ON(network_thread());
234 if (rtp_transport == rtp_transport_) {
235 return true;
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
Tommi1959f8f2021-04-26 10:20:19 +0200267void BaseChannel::Enable(bool enable) {
268 RTC_DCHECK_RUN_ON(signaling_thread());
269
270 if (enable == enabled_s_)
271 return;
272
273 enabled_s_ = enable;
274
275 worker_thread_->PostTask(ToQueuedTask(alive_, [this, enable] {
Niels Möller4bab23f2021-01-18 09:24:33 +0100276 RTC_DCHECK_RUN_ON(worker_thread());
Tommi1959f8f2021-04-26 10:20:19 +0200277 // Sanity check to make sure that enabled_ and enabled_s_
278 // stay in sync.
279 RTC_DCHECK_NE(enabled_, enable);
Niels Möller4bab23f2021-01-18 09:24:33 +0100280 if (enable) {
281 EnableMedia_w();
282 } else {
283 DisableMedia_w();
284 }
Tommi1959f8f2021-04-26 10:20:19 +0200285 }));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286}
287
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800289 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000290 std::string* error_desc) {
Tommicc7a3682021-05-04 14:59:38 +0200291 RTC_DCHECK_RUN_ON(worker_thread());
Peter Boström9f45a452015-12-08 13:25:57 +0100292 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
Tommicc7a3682021-05-04 14:59:38 +0200293 return SetLocalContent_w(content, type, error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000294}
295
296bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800297 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000298 std::string* error_desc) {
Tommicc7a3682021-05-04 14:59:38 +0200299 RTC_DCHECK_RUN_ON(worker_thread());
Peter Boström9f45a452015-12-08 13:25:57 +0100300 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
Tommicc7a3682021-05-04 14:59:38 +0200301 return SetRemoteContent_w(content, type, error_desc);
Tommia63bee52021-04-26 20:11:18 +0200302}
303
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800304bool BaseChannel::SetPayloadTypeDemuxingEnabled(bool enabled) {
Tommi15f41ff2021-05-03 12:37:43 +0200305 RTC_DCHECK_RUN_ON(worker_thread());
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700306 TRACE_EVENT0("webrtc", "BaseChannel::SetPayloadTypeDemuxingEnabled");
Tommi15f41ff2021-05-03 12:37:43 +0200307 return SetPayloadTypeDemuxingEnabled_w(enabled);
Taylor Brandstetterc1ad1ff2020-12-10 15:31:14 -0800308}
309
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700310bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000311 // Receive data if we are enabled and have local content,
Tommi1959f8f2021-04-26 10:20:19 +0200312 return enabled_ &&
Steve Anton4e70a722017-11-28 14:57:10 -0800313 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314}
315
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700316bool BaseChannel::IsReadyToSendMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 // Send outgoing data if we are enabled, have local and remote content,
318 // and we have had some form of connectivity.
Tommi1959f8f2021-04-26 10:20:19 +0200319 return enabled_ &&
Steve Anton4e70a722017-11-28 14:57:10 -0800320 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
321 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Tomas Gunnarssonf1ea4172022-01-02 15:15:08 +0000322 was_ever_writable_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323}
324
jbaucheec21bd2016-03-20 06:15:43 -0700325bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700326 const rtc::PacketOptions& options) {
327 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328}
329
jbaucheec21bd2016-03-20 06:15:43 -0700330bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700331 const rtc::PacketOptions& options) {
332 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333}
334
Yves Gerey665174f2018-06-19 15:03:05 +0200335int BaseChannel::SetOption(SocketType type,
336 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 int value) {
Tommicf2aeff2021-05-07 18:02:53 +0200338 RTC_DCHECK_RUN_ON(network_thread());
Zhi Huange830e682018-03-30 10:48:35 -0700339 RTC_DCHECK(rtp_transport_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000341 case ST_RTP:
deadbeefcbecd352015-09-23 11:50:27 -0700342 socket_options_.push_back(
343 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700344 return rtp_transport_->SetRtpOption(opt, value);
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000345 case ST_RTCP:
deadbeefcbecd352015-09-23 11:50:27 -0700346 rtcp_socket_options_.push_back(
347 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700348 return rtp_transport_->SetRtcpOption(opt, value);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700350 return -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351}
352
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800353void BaseChannel::OnWritableState(bool writable) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700354 RTC_DCHECK_RUN_ON(network_thread());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800355 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800356 ChannelWritable_n();
357 } else {
358 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800359 }
360}
361
Zhi Huang942bc2e2017-11-13 13:26:07 -0800362void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200363 absl::optional<rtc::NetworkRoute> network_route) {
Tomas Gunnarssonad325862021-02-03 16:23:40 +0100364 RTC_LOG(LS_INFO) << "Network route changed for " << ToString();
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800365
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700366 RTC_DCHECK_RUN_ON(network_thread());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800367 rtc::NetworkRoute new_route;
368 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800369 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000370 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800371 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
372 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
373 // work correctly. Intentionally leave it broken to simplify the code and
374 // encourage the users to stop using non-muxing RTCP.
Tomas Gunnarssonad325862021-02-03 16:23:40 +0100375 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Honghai Zhangcc411c02016-03-29 17:27:21 -0700376}
377
Tommi99c8a802021-04-27 15:00:00 +0200378void BaseChannel::SetFirstPacketReceivedCallback(
379 std::function<void()> callback) {
380 RTC_DCHECK_RUN_ON(network_thread());
381 RTC_DCHECK(!on_first_packet_received_ || !callback);
382 on_first_packet_received_ = std::move(callback);
Tomas Gunnarssonb2995a12020-09-28 14:05:35 +0200383}
384
zstein56162b92017-04-24 16:54:35 -0700385void BaseChannel::OnTransportReadyToSend(bool ready) {
Tomas Gunnarssonad325862021-02-03 16:23:40 +0100386 RTC_DCHECK_RUN_ON(network_thread());
387 media_channel_->OnReadyToSend(ready);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000388}
389
stefanc1aeaf02015-10-15 07:26:07 -0700390bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700391 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700392 const rtc::PacketOptions& options) {
Tommicf2aeff2021-05-07 18:02:53 +0200393 RTC_DCHECK_RUN_ON(network_thread());
Amit Hilbuchedd20542019-03-18 12:33:43 -0700394 // Until all the code is migrated to use RtpPacketType instead of bool.
395 RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200396 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
397 // If the thread is not our network thread, we will post to our network
398 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000399 // synchronize access to all the pieces of the send path, including
400 // SRTP and the inner workings of the transport channels.
401 // The only downside is that we can't return a proper failure code if
402 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Zhi Huange830e682018-03-30 10:48:35 -0700403
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200404 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000405
406 // Now that we are on the correct thread, ensure we have a place to send this
407 // packet before doing anything. (We might get RTCP packets that we don't
408 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
409 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700410 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000411 return false;
412 }
413
414 // Protect ourselves against crazy data.
Amit Hilbuchedd20542019-03-18 12:33:43 -0700415 if (!IsValidRtpPacketSize(packet_type, packet->size())) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300416 RTC_LOG(LS_ERROR) << "Dropping outgoing " << ToString() << " "
Amit Hilbuchedd20542019-03-18 12:33:43 -0700417 << RtpPacketTypeToString(packet_type)
Mirko Bonadei675513b2017-11-09 11:09:25 +0100418 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000419 return false;
420 }
421
Zhi Huangcf990f52017-09-22 12:12:30 -0700422 if (!srtp_active()) {
423 if (srtp_required_) {
424 // The audio/video engines may attempt to send RTCP packets as soon as the
425 // streams are created, so don't treat this as an error for RTCP.
426 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
427 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000428 return false;
429 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700430 // However, there shouldn't be any RTP packets sent before SRTP is set up
431 // (and SetSend(true) is called).
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300432 RTC_LOG(LS_ERROR) << "Can't send outgoing RTP packet for " << ToString()
433 << " when SRTP is inactive and crypto is required";
Artem Titovd3251962021-11-15 16:57:07 +0100434 RTC_DCHECK_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800435 return false;
436 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800437
438 std::string packet_type = rtcp ? "RTCP" : "RTP";
Marina Ciocea38728732020-07-29 10:15:46 +0200439 RTC_DLOG(LS_WARNING) << "Sending an " << packet_type
440 << " packet without encryption for " << ToString()
441 << ".";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000442 }
Zhi Huange830e682018-03-30 10:48:35 -0700443
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000444 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800445 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
446 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000447}
448
Zhi Huang365381f2018-04-13 16:44:34 -0700449void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Tommi99c8a802021-04-27 15:00:00 +0200450 RTC_DCHECK_RUN_ON(network_thread());
451
Tommi99c8a802021-04-27 15:00:00 +0200452 if (on_first_packet_received_) {
453 on_first_packet_received_();
454 on_first_packet_received_ = nullptr;
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200455 }
456
457 if (!srtp_active() && srtp_required_) {
458 // Our session description indicates that SRTP is required, but we got a
459 // packet before our SRTP filter is active. This means either that
460 // a) we got SRTP packets before we received the SDES keys, in which case
461 // we can't decrypt it anyway, or
462 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
463 // transports, so we haven't yet extracted keys, even if DTLS did
464 // complete on the transport that the packets are being sent on. It's
465 // really good practice to wait for both RTP and RTCP to be good to go
466 // before sending media, to prevent weird failure modes, so it's fine
467 // for us to just eat packets here. This is all sidestepped if RTCP mux
468 // is used anyway.
469 RTC_LOG(LS_WARNING) << "Can't process incoming RTP packet when "
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300470 "SRTP is inactive and crypto is required "
471 << ToString();
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200472 return;
473 }
474
Tommi2497a272021-05-05 12:33:00 +0200475 webrtc::Timestamp packet_time = parsed_packet.arrival_time();
476 media_channel_->OnPacketReceived(
477 parsed_packet.Buffer(),
478 packet_time.IsMinusInfinity() ? -1 : packet_time.us());
Zhi Huang365381f2018-04-13 16:44:34 -0700479}
480
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800481void BaseChannel::UpdateRtpHeaderExtensionMap(
482 const RtpHeaderExtensions& header_extensions) {
483 // Update the header extension map on network thread in case there is data
484 // race.
485 //
486 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
487 // extension maps are not merged when BUNDLE is enabled. This is fine because
488 // the ID for MID should be consistent among all the RTP transports.
489 network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
490 RTC_DCHECK_RUN_ON(network_thread());
491 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
492 });
493}
494
495bool BaseChannel::RegisterRtpDemuxerSink_w() {
Henrik Boström15e078c2021-04-16 09:54:18 +0200496 if (demuxer_criteria_ == previous_demuxer_criteria_) {
497 return true;
498 }
499 media_channel_->OnDemuxerCriteriaUpdatePending();
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800500 // Copy demuxer criteria, since they're a worker-thread variable
501 // and we want to pass them to the network thread
Tomas Gunnarssonf643aea2022-01-02 15:57:28 +0000502 bool ret = network_thread_->Invoke<bool>(
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800503 RTC_FROM_HERE, [this, demuxer_criteria = demuxer_criteria_] {
504 RTC_DCHECK_RUN_ON(network_thread());
505 RTC_DCHECK(rtp_transport_);
Henrik Boström15e078c2021-04-16 09:54:18 +0200506 bool result =
507 rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria, this);
508 if (result) {
509 previous_demuxer_criteria_ = demuxer_criteria;
510 } else {
511 previous_demuxer_criteria_ = {};
512 }
Henrik Boström15e078c2021-04-16 09:54:18 +0200513 return result;
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800514 });
Tomas Gunnarssonf643aea2022-01-02 15:57:28 +0000515
516 media_channel_->OnDemuxerCriteriaUpdateComplete();
517
518 return ret;
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800519}
520
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000521void BaseChannel::EnableMedia_w() {
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 enabled: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700527 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000528}
529
530void BaseChannel::DisableMedia_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000531 if (!enabled_)
532 return;
533
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300534 RTC_LOG(LS_INFO) << "Channel disabled: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000535 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700536 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000537}
538
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200539void BaseChannel::UpdateWritableState_n() {
Markus Handell518669d2021-06-07 13:30:46 +0200540 TRACE_EVENT0("webrtc", "BaseChannel::UpdateWritableState_n");
Zhi Huange830e682018-03-30 10:48:35 -0700541 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
542 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200543 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700544 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200545 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700546 }
547}
548
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200549void BaseChannel::ChannelWritable_n() {
Markus Handell518669d2021-06-07 13:30:46 +0200550 TRACE_EVENT0("webrtc", "BaseChannel::ChannelWritable_n");
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800551 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000552 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800553 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800554 writable_ = true;
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800555 RTC_LOG(LS_INFO) << "Channel writable (" << ToString() << ")"
556 << (was_ever_writable_n_ ? "" : " for the first time");
557 // We only have to do this PostTask once, when first transitioning to
558 // writable.
559 if (!was_ever_writable_n_) {
560 worker_thread_->PostTask(ToQueuedTask(alive_, [this] {
561 RTC_DCHECK_RUN_ON(worker_thread());
562 was_ever_writable_ = true;
563 UpdateMediaSendRecvState_w();
564 }));
565 }
566 was_ever_writable_n_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567}
568
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200569void BaseChannel::ChannelNotWritable_n() {
Markus Handell518669d2021-06-07 13:30:46 +0200570 TRACE_EVENT0("webrtc", "BaseChannel::ChannelNotWritable_n");
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800571 if (!writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000572 return;
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800573 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800574 writable_ = false;
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800575 RTC_LOG(LS_INFO) << "Channel not writable (" << ToString() << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000576}
577
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
pbos482b12e2015-11-16 10:19:58 -0800579 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580}
581
Peter Boström0c4e06b2015-10-07 12:23:21 +0200582bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000583 return media_channel()->RemoveRecvStream(ssrc);
584}
585
Saurav Dasff27da52019-09-20 11:05:30 -0700586void BaseChannel::ResetUnsignaledRecvStream_w() {
Saurav Dasff27da52019-09-20 11:05:30 -0700587 media_channel()->ResetUnsignaledRecvStream();
588}
589
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800590bool BaseChannel::SetPayloadTypeDemuxingEnabled_w(bool enabled) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700591 if (enabled == payload_type_demuxing_enabled_) {
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800592 return true;
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700593 }
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700594 payload_type_demuxing_enabled_ = enabled;
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700595 if (!enabled) {
596 // TODO(crbug.com/11477): This will remove *all* unsignaled streams (those
597 // without an explicitly signaled SSRC), which may include streams that
598 // were matched to this channel by MID or RID. Ideally we'd remove only the
599 // streams that were matched based on payload type alone, but currently
600 // there is no straightforward way to identify those streams.
601 media_channel()->ResetUnsignaledRecvStream();
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700602 demuxer_criteria_.payload_types.clear();
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800603 if (!RegisterRtpDemuxerSink_w()) {
604 RTC_LOG(LS_ERROR) << "Failed to disable payload type demuxing for "
605 << ToString();
606 return false;
607 }
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700608 } else if (!payload_types_.empty()) {
609 demuxer_criteria_.payload_types.insert(payload_types_.begin(),
610 payload_types_.end());
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800611 if (!RegisterRtpDemuxerSink_w()) {
612 RTC_LOG(LS_ERROR) << "Failed to enable payload type demuxing for "
613 << ToString();
614 return false;
615 }
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700616 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800617 return true;
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700618}
619
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000620bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800621 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000622 std::string* error_desc) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800623 // In the case of RIDs (where SSRCs are not negotiated), this method will
624 // generate an SSRC for each layer in StreamParams. That representation will
Artem Titov880fa812021-07-30 22:30:23 +0200625 // be stored internally in `local_streams_`.
626 // In subsequent offers, the same stream can appear in `streams` again
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800627 // (without the SSRCs), so it should be looked up using RIDs (if available)
628 // and then by primary SSRC.
629 // In both scenarios, it is safe to assume that the media channel will be
630 // created with a StreamParams object with SSRCs. However, it is not safe to
Artem Titov880fa812021-07-30 22:30:23 +0200631 // assume that `local_streams_` will always have SSRCs as there are scenarios
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800632 // in which niether SSRCs or RIDs are negotiated.
633
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000634 // Check for streams that have been removed.
635 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800636 for (const StreamParams& old_stream : local_streams_) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800637 if (!old_stream.has_ssrcs() ||
638 GetStream(streams, StreamFinder(&old_stream))) {
639 continue;
640 }
641 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
642 rtc::StringBuilder desc;
643 desc << "Failed to remove send stream with ssrc "
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000644 << old_stream.first_ssrc() << " from m-section with mid='"
645 << content_name() << "'.";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800646 SafeSetError(desc.str(), error_desc);
647 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648 }
649 }
650 // Check for new streams.
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800651 std::vector<StreamParams> all_streams;
652 for (const StreamParams& stream : streams) {
653 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
654 if (existing) {
655 // Parameters cannot change for an existing stream.
656 all_streams.push_back(*existing);
657 continue;
658 }
659
660 all_streams.push_back(stream);
661 StreamParams& new_stream = all_streams.back();
662
663 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
664 continue;
665 }
666
667 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
668 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
669 rtc::StringBuilder desc;
670 desc << "Failed to add send stream: " << new_stream.first_ssrc()
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000671 << " into m-section with mid='" << content_name()
672 << "'. Stream has both SSRCs and RIDs.";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800673 SafeSetError(desc.str(), error_desc);
674 ret = false;
675 continue;
676 }
677
678 // At this point we use the legacy simulcast group in StreamParams to
679 // indicate that we want multiple layers to the media channel.
680 if (!new_stream.has_ssrcs()) {
681 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
682 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
683 /* flex_fec = */ false, ssrc_generator_);
684 }
685
686 if (media_channel()->AddSendStream(new_stream)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300687 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0]
688 << " into " << ToString();
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800689 } else {
690 rtc::StringBuilder desc;
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000691 desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc()
692 << " into m-section with mid='" << content_name() << "'";
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800693 SafeSetError(desc.str(), error_desc);
694 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695 }
696 }
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800697 local_streams_ = all_streams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698 return ret;
699}
700
701bool BaseChannel::UpdateRemoteStreams_w(
702 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800703 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000704 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705 // Check for streams that have been removed.
706 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800707 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700708 // If we no longer have an unsignaled stream, we would like to remove
709 // the unsignaled stream params that are cached.
Saurav Dasff27da52019-09-20 11:05:30 -0700710 if (!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) {
711 ResetUnsignaledRecvStream_w();
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300712 RTC_LOG(LS_INFO) << "Reset unsignaled remote stream for " << ToString()
713 << ".";
Saurav Dasff27da52019-09-20 11:05:30 -0700714 } else if (old_stream.has_ssrcs() &&
715 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800716 if (RemoveRecvStream_w(old_stream.first_ssrc())) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300717 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc()
718 << " from " << ToString() << ".";
Zhi Huang365381f2018-04-13 16:44:34 -0700719 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200720 rtc::StringBuilder desc;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800721 desc << "Failed to remove remote stream with ssrc "
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000722 << old_stream.first_ssrc() << " from m-section with mid='"
723 << content_name() << "'.";
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000724 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 ret = false;
726 }
727 }
728 }
Zhi Huang365381f2018-04-13 16:44:34 -0700729 demuxer_criteria_.ssrcs.clear();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730 // Check for new streams.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800731 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700732 // We allow a StreamParams with an empty list of SSRCs, in which case the
733 // MediaChannel will cache the parameters and use them for any unsignaled
734 // stream received later.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800735 if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
736 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
737 if (AddRecvStream_w(new_stream)) {
Saurav Dasff27da52019-09-20 11:05:30 -0700738 RTC_LOG(LS_INFO) << "Add remote ssrc: "
739 << (new_stream.has_ssrcs()
740 ? std::to_string(new_stream.first_ssrc())
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300741 : "unsignaled")
742 << " to " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743 } else {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200744 rtc::StringBuilder desc;
Saurav Dasff27da52019-09-20 11:05:30 -0700745 desc << "Failed to add remote stream ssrc: "
746 << (new_stream.has_ssrcs()
747 ? std::to_string(new_stream.first_ssrc())
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300748 : "unsignaled")
749 << " to " << ToString();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000750 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751 ret = false;
752 }
753 }
Zhi Huang365381f2018-04-13 16:44:34 -0700754 // Update the receiving SSRCs.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800755 demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
756 new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000757 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800758 // Re-register the sink to update the receiving ssrcs.
759 if (!RegisterRtpDemuxerSink_w()) {
760 RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString();
761 ret = false;
762 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763 remote_streams_ = streams;
764 return ret;
765}
766
Lennart Grahl0d0ed762021-05-17 16:06:37 +0200767RtpHeaderExtensions BaseChannel::GetDeduplicatedRtpHeaderExtensions(
jbauch5869f502017-06-29 12:31:36 -0700768 const RtpHeaderExtensions& extensions) {
Lennart Grahl0d0ed762021-05-17 16:06:37 +0200769 return webrtc::RtpExtension::DeduplicateHeaderExtensions(
770 extensions, crypto_options_.srtp.enable_encrypted_rtp_header_extensions
771 ? webrtc::RtpExtension::kPreferEncryptedExtension
772 : webrtc::RtpExtension::kDiscardEncryptedExtension);
jbauch5869f502017-06-29 12:31:36 -0700773}
774
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700775void BaseChannel::MaybeAddHandledPayloadType(int payload_type) {
776 if (payload_type_demuxing_enabled_) {
777 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
778 }
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700779 // Even if payload type demuxing is currently disabled, we need to remember
780 // the payload types in case it's re-enabled later.
781 payload_types_.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -0700782}
783
Steve Antonbe2e5f72019-09-06 16:26:02 -0700784void BaseChannel::ClearHandledPayloadTypes() {
785 demuxer_criteria_.payload_types.clear();
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700786 payload_types_.clear();
Steve Antonbe2e5f72019-09-06 16:26:02 -0700787}
788
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800789void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Tomas Gunnarssoneb9c3f22021-04-19 12:53:09 +0200790 RTC_DCHECK_RUN_ON(network_thread());
791 media_channel()->OnPacketSent(sent_packet);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200792}
793
794VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
795 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800796 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800797 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700799 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800800 webrtc::CryptoOptions crypto_options,
801 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200802 : BaseChannel(worker_thread,
803 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800804 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800805 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700806 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700807 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800808 crypto_options,
809 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810
811VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800812 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813 // this can't be done in the base class, since it calls a virtual
814 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700815 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816}
817
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700818void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819 // Render incoming data if we're the active call, and we have the local
820 // content. We receive data on the default channel and multiplexed streams.
Harald Alvestrand27883a22020-11-26 07:24:32 +0000821 RTC_DCHECK_RUN_ON(worker_thread());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700822 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700823 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824
825 // Send outgoing data if we're the active call, we have the remote content,
826 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700827 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800828 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300830 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send
831 << " for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832}
833
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000834bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800835 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000836 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100837 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800838 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300839 RTC_LOG(LS_INFO) << "Setting local voice description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840
jbauch5869f502017-06-29 12:31:36 -0700841 RtpHeaderExtensions rtp_header_extensions =
Lennart Grahl0d0ed762021-05-17 16:06:37 +0200842 GetDeduplicatedRtpHeaderExtensions(content->rtp_header_extensions());
Tommia63bee52021-04-26 20:11:18 +0200843 // TODO(tommi): There's a hop to the network thread here.
844 // some of the below is also network thread related.
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800845 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Tommia63bee52021-04-26 20:11:18 +0200846 media_channel()->SetExtmapAllowMixed(content->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700847
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700848 AudioRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +0200849 RtpParametersFromMediaDescription(
Tommia63bee52021-04-26 20:11:18 +0200850 content->as_audio(), rtp_header_extensions,
851 webrtc::RtpTransceiverDirectionHasRecv(content->direction()),
852 &recv_params);
853
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700854 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000855 SafeSetError(
856 "Failed to set local audio description recv parameters for m-section "
857 "with mid='" +
858 content_name() + "'.",
859 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700860 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000861 }
Steve Antonbe2e5f72019-09-06 16:26:02 -0700862
Tommia63bee52021-04-26 20:11:18 +0200863 if (webrtc::RtpTransceiverDirectionHasRecv(content->direction())) {
864 for (const AudioCodec& codec : content->as_audio()->codecs()) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700865 MaybeAddHandledPayloadType(codec.id);
Steve Antonbe2e5f72019-09-06 16:26:02 -0700866 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800867 // Need to re-register the sink to update the handled payload.
868 if (!RegisterRtpDemuxerSink_w()) {
869 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing for " << ToString();
870 return false;
871 }
Zhi Huang365381f2018-04-13 16:44:34 -0700872 }
873
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700874 last_recv_params_ = recv_params;
875
876 // TODO(pthatcher): Move local streams into AudioSendParameters, and
877 // only give it to the media channel once we have a remote
878 // description too (without a remote description, we won't be able
879 // to send them anyway).
Tommia63bee52021-04-26 20:11:18 +0200880 if (!UpdateLocalStreams_w(content->as_audio()->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000881 SafeSetError(
882 "Failed to set local audio description streams for m-section with "
883 "mid='" +
884 content_name() + "'.",
885 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700886 return false;
887 }
888
889 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700890 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700891 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892}
893
894bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800895 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000896 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100897 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800898 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300899 RTC_LOG(LS_INFO) << "Setting remote voice description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900
Steve Antonb1c1de12017-12-21 15:14:30 -0800901 const AudioContentDescription* audio = content->as_audio();
902
jbauch5869f502017-06-29 12:31:36 -0700903 RtpHeaderExtensions rtp_header_extensions =
Lennart Grahl0d0ed762021-05-17 16:06:37 +0200904 GetDeduplicatedRtpHeaderExtensions(audio->rtp_header_extensions());
jbauch5869f502017-06-29 12:31:36 -0700905
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700906 AudioSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +0200907 RtpSendParametersFromMediaDescription(
908 audio, rtp_header_extensions,
909 webrtc::RtpTransceiverDirectionHasRecv(audio->direction()), &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700910 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700911
912 bool parameters_applied = media_channel()->SetSendParameters(send_params);
913 if (!parameters_applied) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000914 SafeSetError(
915 "Failed to set remote audio description send parameters for m-section "
916 "with mid='" +
917 content_name() + "'.",
918 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700919 return false;
920 }
921 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922
Steve Antonbe2e5f72019-09-06 16:26:02 -0700923 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
924 RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300925 "disable payload type demuxing for "
926 << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -0700927 ClearHandledPayloadTypes();
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800928 if (!RegisterRtpDemuxerSink_w()) {
929 RTC_LOG(LS_ERROR) << "Failed to update audio demuxing for " << ToString();
930 return false;
931 }
Steve Antonbe2e5f72019-09-06 16:26:02 -0700932 }
933
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700934 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
935 // and only give it to the media channel once we have a local
936 // description too (without a local description, we won't be able to
937 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800938 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000939 SafeSetError(
940 "Failed to set remote audio description streams for m-section with "
941 "mid='" +
942 content_name() + "'.",
943 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700944 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 }
946
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700947 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700948 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700949 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950}
951
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200952VideoChannel::VideoChannel(rtc::Thread* worker_thread,
953 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800954 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800955 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700957 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800958 webrtc::CryptoOptions crypto_options,
959 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200960 : BaseChannel(worker_thread,
961 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800962 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800963 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700964 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700965 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800966 crypto_options,
967 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800970 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971 // this can't be done in the base class, since it calls a virtual
972 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700973 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974}
975
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700976void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977 // Send outgoing data if we're the active call, we have the remote content,
978 // and we have had some form of connectivity.
Harald Alvestrand27883a22020-11-26 07:24:32 +0000979 RTC_DCHECK_RUN_ON(worker_thread());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700980 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981 if (!media_channel()->SetSend(send)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300982 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel: " + ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983 // TODO(gangji): Report error back to server.
984 }
985
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300986 RTC_LOG(LS_INFO) << "Changing video state, send=" << send << " for "
987 << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988}
989
stefanf79ade12017-06-02 06:44:03 -0700990void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
Tomas Gunnarsson788d8052021-05-03 16:23:08 +0200991 RTC_DCHECK_RUN_ON(worker_thread());
Niels Möller4bab23f2021-01-18 09:24:33 +0100992 VideoMediaChannel* mc = media_channel();
Tomas Gunnarsson788d8052021-05-03 16:23:08 +0200993 mc->FillBitrateInfo(bwe_info);
stefanf79ade12017-06-02 06:44:03 -0700994}
995
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800997 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000998 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100999 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001000 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001001 RTC_LOG(LS_INFO) << "Setting local video description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002
jbauch5869f502017-06-29 12:31:36 -07001003 RtpHeaderExtensions rtp_header_extensions =
Lennart Grahl0d0ed762021-05-17 16:06:37 +02001004 GetDeduplicatedRtpHeaderExtensions(content->rtp_header_extensions());
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -08001005 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Tommia63bee52021-04-26 20:11:18 +02001006 media_channel()->SetExtmapAllowMixed(content->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -07001007
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001008 VideoRecvParameters recv_params = last_recv_params_;
Tommia63bee52021-04-26 20:11:18 +02001009
Johannes Kron3e983682020-03-29 22:17:00 +02001010 RtpParametersFromMediaDescription(
Tommia63bee52021-04-26 20:11:18 +02001011 content->as_video(), rtp_header_extensions,
1012 webrtc::RtpTransceiverDirectionHasRecv(content->direction()),
1013 &recv_params);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001014
1015 VideoSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001016
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001017 bool needs_send_params_update = false;
Johannes Krona104ceb2020-01-24 16:04:04 +00001018 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001019 for (auto& send_codec : send_params.codecs) {
1020 auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
1021 if (recv_codec) {
1022 if (!recv_codec->packetization && send_codec.packetization) {
1023 send_codec.packetization.reset();
1024 needs_send_params_update = true;
1025 } else if (recv_codec->packetization != send_codec.packetization) {
1026 SafeSetError(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001027 "Failed to set local answer due to invalid codec packetization "
1028 "specified in m-section with mid='" +
1029 content_name() + "'.",
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001030 error_desc);
1031 return false;
1032 }
1033 }
1034 }
1035 }
1036
Johannes Krona104ceb2020-01-24 16:04:04 +00001037 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001038 SafeSetError(
1039 "Failed to set local video description recv parameters for m-section "
1040 "with mid='" +
1041 content_name() + "'.",
1042 error_desc);
Johannes Krona104ceb2020-01-24 16:04:04 +00001043 return false;
1044 }
Johannes Kron9bac68c2020-01-23 13:12:25 +00001045
Tommia63bee52021-04-26 20:11:18 +02001046 if (webrtc::RtpTransceiverDirectionHasRecv(content->direction())) {
1047 for (const VideoCodec& codec : content->as_video()->codecs()) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -07001048 MaybeAddHandledPayloadType(codec.id);
Steve Antonbe2e5f72019-09-06 16:26:02 -07001049 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -08001050 // Need to re-register the sink to update the handled payload.
1051 if (!RegisterRtpDemuxerSink_w()) {
1052 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing for " << ToString();
1053 return false;
1054 }
Zhi Huang365381f2018-04-13 16:44:34 -07001055 }
1056
Johannes Krona104ceb2020-01-24 16:04:04 +00001057 last_recv_params_ = recv_params;
1058
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001059 if (needs_send_params_update) {
1060 if (!media_channel()->SetSendParameters(send_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001061 SafeSetError("Failed to set send parameters for m-section with mid='" +
1062 content_name() + "'.",
1063 error_desc);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001064 return false;
1065 }
1066 last_send_params_ = send_params;
1067 }
1068
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001069 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1070 // only give it to the media channel once we have a remote
1071 // description too (without a remote description, we won't be able
1072 // to send them anyway).
Tommia63bee52021-04-26 20:11:18 +02001073 if (!UpdateLocalStreams_w(content->as_video()->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001074 SafeSetError(
1075 "Failed to set local video description streams for m-section with "
1076 "mid='" +
1077 content_name() + "'.",
1078 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001079 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001080 }
1081
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001082 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001083 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001084 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001085}
1086
1087bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001088 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001089 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001090 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001091 RTC_DCHECK_RUN_ON(worker_thread());
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001092 RTC_LOG(LS_INFO) << "Setting remote video description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001093
Steve Antonb1c1de12017-12-21 15:14:30 -08001094 const VideoContentDescription* video = content->as_video();
1095
jbauch5869f502017-06-29 12:31:36 -07001096 RtpHeaderExtensions rtp_header_extensions =
Lennart Grahl0d0ed762021-05-17 16:06:37 +02001097 GetDeduplicatedRtpHeaderExtensions(video->rtp_header_extensions());
jbauch5869f502017-06-29 12:31:36 -07001098
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001099 VideoSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001100 RtpSendParametersFromMediaDescription(
1101 video, rtp_header_extensions,
1102 webrtc::RtpTransceiverDirectionHasRecv(video->direction()), &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001103 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001104 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001105 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001106 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001107
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001108 VideoRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001109
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001110 bool needs_recv_params_update = false;
Johannes Krona104ceb2020-01-24 16:04:04 +00001111 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001112 for (auto& recv_codec : recv_params.codecs) {
1113 auto* send_codec = FindMatchingCodec(send_params.codecs, recv_codec);
1114 if (send_codec) {
1115 if (!send_codec->packetization && recv_codec.packetization) {
1116 recv_codec.packetization.reset();
1117 needs_recv_params_update = true;
1118 } else if (send_codec->packetization != recv_codec.packetization) {
1119 SafeSetError(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001120 "Failed to set remote answer due to invalid codec packetization "
1121 "specifid in m-section with mid='" +
1122 content_name() + "'.",
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001123 error_desc);
1124 return false;
1125 }
1126 }
1127 }
1128 }
skvladdc1c62c2016-03-16 19:07:43 -07001129
Johannes Krona104ceb2020-01-24 16:04:04 +00001130 if (!media_channel()->SetSendParameters(send_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001131 SafeSetError(
1132 "Failed to set remote video description send parameters for m-section "
1133 "with mid='" +
1134 content_name() + "'.",
1135 error_desc);
Johannes Krona104ceb2020-01-24 16:04:04 +00001136 return false;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001137 }
Johannes Krona104ceb2020-01-24 16:04:04 +00001138 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001139
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001140 if (needs_recv_params_update) {
1141 if (!media_channel()->SetRecvParameters(recv_params)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001142 SafeSetError("Failed to set recv parameters for m-section with mid='" +
1143 content_name() + "'.",
1144 error_desc);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001145 return false;
1146 }
1147 last_recv_params_ = recv_params;
1148 }
1149
Steve Antonbe2e5f72019-09-06 16:26:02 -07001150 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
1151 RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001152 "disable payload type demuxing for "
1153 << ToString();
Steve Antonbe2e5f72019-09-06 16:26:02 -07001154 ClearHandledPayloadTypes();
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -08001155 if (!RegisterRtpDemuxerSink_w()) {
1156 RTC_LOG(LS_ERROR) << "Failed to update video demuxing for " << ToString();
1157 return false;
1158 }
Steve Antonbe2e5f72019-09-06 16:26:02 -07001159 }
1160
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001161 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1162 // and only give it to the media channel once we have a local
1163 // description too (without a local description, we won't be able to
1164 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001165 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001166 SafeSetError(
1167 "Failed to set remote video description streams for m-section with "
1168 "mid='" +
1169 content_name() + "'.",
1170 error_desc);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001171 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001172 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001173 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001174 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001175 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001176}
1177
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001178} // namespace cricket