blob: 9b8e8f8c3938bc693d0d4922adc673cedd25793b [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>
Harald Alvestrandc24a2182022-02-23 13:44:59 +000015#include <string>
16#include <type_traits>
kwiberg0eb15ed2015-12-17 03:04:15 -080017#include <utility>
18
Harald Alvestrand5761e7b2021-01-29 14:45:08 +000019#include "absl/strings/string_view.h"
20#include "api/rtp_parameters.h"
Artem Titovd15a5752021-02-10 14:31:24 +010021#include "api/sequence_checker.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000022#include "api/units/timestamp.h"
Harald Alvestrand5761e7b2021-01-29 14:45:08 +000023#include "media/base/codec.h"
24#include "media/base/rid_description.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "media/base/rtp_utils.h"
Zhi Huang365381f2018-04-13 16:44:34 -070026#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000027#include "p2p/base/dtls_transport_internal.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"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000031#include "rtc_base/location.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "rtc_base/network_route.h"
Tomas Gunnarssond908d742022-01-05 10:44:26 +000034#include "rtc_base/strings/string_format.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
Tomas Gunnarssond908d742022-01-05 10:44:26 +000042using ::rtc::StringFormat;
Danil Chapovalovfd9500e2021-01-15 17:29:53 +010043using ::rtc::UniqueRandomIdGenerator;
44using ::webrtc::PendingTaskSafetyFlag;
45using ::webrtc::SdpType;
46using ::webrtc::ToQueuedTask;
47
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080048// Finds a stream based on target's Primary SSRC or RIDs.
49// This struct is used in BaseChannel::UpdateLocalStreams_w.
50struct StreamFinder {
51 explicit StreamFinder(const StreamParams* target) : target_(target) {
52 RTC_DCHECK(target);
53 }
54
55 bool operator()(const StreamParams& sp) const {
56 if (target_->has_ssrcs() && sp.has_ssrcs()) {
57 return sp.has_ssrc(target_->first_ssrc());
58 }
59
60 if (!target_->has_rids() && !sp.has_rids()) {
61 return false;
62 }
63
64 const std::vector<RidDescription>& target_rids = target_->rids();
65 const std::vector<RidDescription>& source_rids = sp.rids();
66 if (source_rids.size() != target_rids.size()) {
67 return false;
68 }
69
70 // Check that all RIDs match.
71 return std::equal(source_rids.begin(), source_rids.end(),
72 target_rids.begin(),
73 [](const RidDescription& lhs, const RidDescription& rhs) {
74 return lhs.rid == rhs.rid;
75 });
76 }
77
78 const StreamParams* target_;
79};
80
deadbeef2d110be2016-01-13 12:00:26 -080081} // namespace
82
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070083template <class Codec>
84void RtpParametersFromMediaDescription(
85 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070086 const RtpHeaderExtensions& extensions,
Johannes Kron3e983682020-03-29 22:17:00 +020087 bool is_stream_active,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070088 RtpParameters<Codec>* params) {
Johannes Kron3e983682020-03-29 22:17:00 +020089 params->is_stream_active = is_stream_active;
Mirko Bonadei1f0677d2020-04-17 14:15:47 +020090 params->codecs = desc->codecs();
91 // TODO(bugs.webrtc.org/11513): See if we really need
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070092 // rtp_header_extensions_set() and remove it if we don't.
93 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -070094 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070095 }
deadbeef13871492015-12-09 12:37:51 -080096 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Sebastian Janssone1795f42019-07-24 11:38:03 +020097 params->rtcp.remote_estimate = desc->remote_estimate();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070098}
99
nisse05103312016-03-16 02:22:50 -0700100template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700101void RtpSendParametersFromMediaDescription(
102 const MediaContentDescriptionImpl<Codec>* desc,
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000103 webrtc::RtpExtension::Filter extensions_filter,
nisse05103312016-03-16 02:22:50 -0700104 RtpSendParameters<Codec>* send_params) {
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000105 RtpHeaderExtensions extensions =
106 webrtc::RtpExtension::DeduplicateHeaderExtensions(
107 desc->rtp_header_extensions(), extensions_filter);
108 const bool is_stream_active =
109 webrtc::RtpTransceiverDirectionHasRecv(desc->direction());
Johannes Kron3e983682020-03-29 22:17:00 +0200110 RtpParametersFromMediaDescription(desc, extensions, is_stream_active,
111 send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700112 send_params->max_bandwidth_bps = desc->bandwidth();
Johannes Kron9190b822018-10-29 11:22:05 +0100113 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700114}
115
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200116BaseChannel::BaseChannel(rtc::Thread* worker_thread,
117 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800118 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800119 std::unique_ptr<MediaChannel> media_channel,
Harald Alvestrand8f429922022-05-04 10:32:30 +0000120 absl::string_view mid,
Zhi Huange830e682018-03-30 10:48:35 -0700121 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800122 webrtc::CryptoOptions crypto_options,
123 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200124 : worker_thread_(worker_thread),
125 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800126 signaling_thread_(signaling_thread),
Danil Chapovalovfd9500e2021-01-15 17:29:53 +0100127 alive_(PendingTaskSafetyFlag::Create()),
deadbeef7af91dd2016-12-13 11:29:11 -0800128 srtp_required_(srtp_required),
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000129 extensions_filter_(
130 crypto_options.srtp.enable_encrypted_rtp_header_extensions
131 ? webrtc::RtpExtension::kPreferEncryptedExtension
132 : webrtc::RtpExtension::kDiscardEncryptedExtension),
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800133 media_channel_(std::move(media_channel)),
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100134 demuxer_criteria_(mid),
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800135 ssrc_generator_(ssrc_generator) {
Steve Anton8699a322017-11-06 15:53:33 -0800136 RTC_DCHECK_RUN_ON(worker_thread_);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000137 RTC_DCHECK(media_channel_);
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800138 RTC_DCHECK(ssrc_generator_);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000139 RTC_DLOG(LS_INFO) << "Created channel: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140}
141
142BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800143 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800144 RTC_DCHECK_RUN_ON(worker_thread_);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800145
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200146 // Eats any outstanding messages or packets.
Danil Chapovalovfd9500e2021-01-15 17:29:53 +0100147 alive_->SetNotAlive();
Harald Alvestrand0f0bcb32020-12-07 11:45:55 +0000148 // The media channel is destroyed at the end of the destructor, since it
149 // is a std::unique_ptr. The transport channel (rtp_transport) must outlive
150 // the media channel.
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300151}
152
153std::string BaseChannel::ToString() const {
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100154 return StringFormat("{mid: %s, media_type: %s}", mid().c_str(),
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000155 MediaTypeToString(media_channel_->media_type()).c_str());
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200156}
157
Tomas Gunnarssonb496c322022-01-05 10:26:36 +0000158bool BaseChannel::ConnectToRtpTransport_n() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800159 RTC_DCHECK(rtp_transport_);
Tomas Gunnarssoneb9c3f22021-04-19 12:53:09 +0200160 RTC_DCHECK(media_channel());
161
Henrik Boström15e078c2021-04-16 09:54:18 +0200162 // We don't need to call OnDemuxerCriteriaUpdatePending/Complete because
163 // there's no previous criteria to worry about.
Tomas Gunnarsson9abd74d2022-01-04 17:21:54 +0000164 if (!rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this)) {
Zhi Huang365381f2018-04-13 16:44:34 -0700165 return false;
166 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800167 rtp_transport_->SignalReadyToSend.connect(
168 this, &BaseChannel::OnTransportReadyToSend);
Bjorn A Mellem7a9a0922019-11-26 09:19:40 -0800169 rtp_transport_->SignalNetworkRouteChanged.connect(
170 this, &BaseChannel::OnNetworkRouteChanged);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800171 rtp_transport_->SignalWritableState.connect(this,
172 &BaseChannel::OnWritableState);
173 rtp_transport_->SignalSentPacket.connect(this,
174 &BaseChannel::SignalSentPacket_n);
Zhi Huang365381f2018-04-13 16:44:34 -0700175 return true;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800176}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200177
Tomas Gunnarssonb496c322022-01-05 10:26:36 +0000178void BaseChannel::DisconnectFromRtpTransport_n() {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800179 RTC_DCHECK(rtp_transport_);
Tomas Gunnarssoneb9c3f22021-04-19 12:53:09 +0200180 RTC_DCHECK(media_channel());
Zhi Huang365381f2018-04-13 16:44:34 -0700181 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800182 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800183 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
184 rtp_transport_->SignalWritableState.disconnect(this);
185 rtp_transport_->SignalSentPacket.disconnect(this);
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100186 rtp_transport_ = nullptr;
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +0100187 media_channel_->SetInterface(nullptr);
wu@webrtc.org78187522013-10-07 23:32:02 +0000188}
189
Zhi Huang365381f2018-04-13 16:44:34 -0700190bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
Markus Handell518669d2021-06-07 13:30:46 +0200191 TRACE_EVENT0("webrtc", "BaseChannel::SetRtpTransport");
Harald Alvestrand27883a22020-11-26 07:24:32 +0000192 RTC_DCHECK_RUN_ON(network_thread());
193 if (rtp_transport == rtp_transport_) {
194 return true;
195 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000196
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800197 if (rtp_transport_) {
Tomas Gunnarssonb496c322022-01-05 10:26:36 +0000198 DisconnectFromRtpTransport_n();
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000199 // Clear the cached header extensions on the worker.
200 worker_thread_->PostTask(ToQueuedTask(alive_, [this] {
201 RTC_DCHECK_RUN_ON(worker_thread());
202 rtp_header_extensions_.clear();
203 }));
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800204 }
Zhi Huange830e682018-03-30 10:48:35 -0700205
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800206 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700207 if (rtp_transport_) {
Tomas Gunnarssonb496c322022-01-05 10:26:36 +0000208 if (!ConnectToRtpTransport_n()) {
Zhi Huang365381f2018-04-13 16:44:34 -0700209 return false;
210 }
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +0100211
212 RTC_DCHECK(!media_channel_->HasNetworkInterface());
213 media_channel_->SetInterface(this);
214
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100215 media_channel_->OnReadyToSend(rtp_transport_->IsReadyToSend());
Zhi Huange830e682018-03-30 10:48:35 -0700216 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800217
Zhi Huange830e682018-03-30 10:48:35 -0700218 // Set the cached socket options.
219 for (const auto& pair : socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700220 rtp_transport_->SetRtpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700221 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700222 if (!rtp_transport_->rtcp_mux_enabled()) {
Zhi Huange830e682018-03-30 10:48:35 -0700223 for (const auto& pair : rtcp_socket_options_) {
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700224 rtp_transport_->SetRtcpOption(pair.first, pair.second);
Zhi Huange830e682018-03-30 10:48:35 -0700225 }
226 }
guoweis46383312015-12-17 16:45:59 -0800227 }
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +0100228
Zhi Huang365381f2018-04-13 16:44:34 -0700229 return true;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000230}
231
Tommi1959f8f2021-04-26 10:20:19 +0200232void BaseChannel::Enable(bool enable) {
233 RTC_DCHECK_RUN_ON(signaling_thread());
234
235 if (enable == enabled_s_)
236 return;
237
238 enabled_s_ = enable;
239
240 worker_thread_->PostTask(ToQueuedTask(alive_, [this, enable] {
Niels Möller4bab23f2021-01-18 09:24:33 +0100241 RTC_DCHECK_RUN_ON(worker_thread());
Tommi1959f8f2021-04-26 10:20:19 +0200242 // Sanity check to make sure that enabled_ and enabled_s_
243 // stay in sync.
244 RTC_DCHECK_NE(enabled_, enable);
Niels Möller4bab23f2021-01-18 09:24:33 +0100245 if (enable) {
246 EnableMedia_w();
247 } else {
248 DisableMedia_w();
249 }
Tommi1959f8f2021-04-26 10:20:19 +0200250 }));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251}
252
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800254 SdpType type,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000255 std::string& error_desc) {
Tommicc7a3682021-05-04 14:59:38 +0200256 RTC_DCHECK_RUN_ON(worker_thread());
Peter Boström9f45a452015-12-08 13:25:57 +0100257 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
Tommicc7a3682021-05-04 14:59:38 +0200258 return SetLocalContent_w(content, type, error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259}
260
261bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800262 SdpType type,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000263 std::string& error_desc) {
Tommicc7a3682021-05-04 14:59:38 +0200264 RTC_DCHECK_RUN_ON(worker_thread());
Peter Boström9f45a452015-12-08 13:25:57 +0100265 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
Tommicc7a3682021-05-04 14:59:38 +0200266 return SetRemoteContent_w(content, type, error_desc);
Tommia63bee52021-04-26 20:11:18 +0200267}
268
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800269bool BaseChannel::SetPayloadTypeDemuxingEnabled(bool enabled) {
Tomas Gunnarsson92f9b742022-01-02 20:40:22 +0000270 // TODO(bugs.webrtc.org/11993): The demuxer state needs to be managed on the
271 // network thread. At the moment there's a workaround for inconsistent state
272 // between the worker and network thread because of this (see
273 // OnDemuxerCriteriaUpdatePending elsewhere in this file) and
274 // SetPayloadTypeDemuxingEnabled_w has an Invoke over to the network thread
275 // to apply state updates.
Tommi15f41ff2021-05-03 12:37:43 +0200276 RTC_DCHECK_RUN_ON(worker_thread());
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700277 TRACE_EVENT0("webrtc", "BaseChannel::SetPayloadTypeDemuxingEnabled");
Tommi15f41ff2021-05-03 12:37:43 +0200278 return SetPayloadTypeDemuxingEnabled_w(enabled);
Taylor Brandstetterc1ad1ff2020-12-10 15:31:14 -0800279}
280
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700281bool BaseChannel::IsReadyToSendMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000282 // Send outgoing data if we are enabled, have local and remote content,
283 // and we have had some form of connectivity.
Tommi1959f8f2021-04-26 10:20:19 +0200284 return enabled_ &&
Steve Anton4e70a722017-11-28 14:57:10 -0800285 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
286 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Tomas Gunnarssonf1ea4172022-01-02 15:15:08 +0000287 was_ever_writable_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288}
289
jbaucheec21bd2016-03-20 06:15:43 -0700290bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700291 const rtc::PacketOptions& options) {
292 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000293}
294
jbaucheec21bd2016-03-20 06:15:43 -0700295bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700296 const rtc::PacketOptions& options) {
297 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298}
299
Yves Gerey665174f2018-06-19 15:03:05 +0200300int BaseChannel::SetOption(SocketType type,
301 rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000302 int value) {
Tommicf2aeff2021-05-07 18:02:53 +0200303 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100304 RTC_DCHECK(network_initialized());
Zhi Huange830e682018-03-30 10:48:35 -0700305 RTC_DCHECK(rtp_transport_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000306 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000307 case ST_RTP:
deadbeefcbecd352015-09-23 11:50:27 -0700308 socket_options_.push_back(
309 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700310 return rtp_transport_->SetRtpOption(opt, value);
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000311 case ST_RTCP:
deadbeefcbecd352015-09-23 11:50:27 -0700312 rtcp_socket_options_.push_back(
313 std::pair<rtc::Socket::Option, int>(opt, value));
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700314 return rtp_transport_->SetRtcpOption(opt, value);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315 }
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -0700316 return -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317}
318
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800319void BaseChannel::OnWritableState(bool writable) {
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700320 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100321 RTC_DCHECK(network_initialized());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800322 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800323 ChannelWritable_n();
324 } else {
325 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800326 }
327}
328
Zhi Huang942bc2e2017-11-13 13:26:07 -0800329void BaseChannel::OnNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200330 absl::optional<rtc::NetworkRoute> network_route) {
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100331 RTC_DCHECK_RUN_ON(network_thread());
332 RTC_DCHECK(network_initialized());
333
Tomas Gunnarssonad325862021-02-03 16:23:40 +0100334 RTC_LOG(LS_INFO) << "Network route changed for " << ToString();
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800335
Zhi Huang942bc2e2017-11-13 13:26:07 -0800336 rtc::NetworkRoute new_route;
337 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800338 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000339 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800340 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
341 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
342 // work correctly. Intentionally leave it broken to simplify the code and
343 // encourage the users to stop using non-muxing RTCP.
Tomas Gunnarsson94f01942022-01-03 14:59:12 +0000344 media_channel_->OnNetworkRouteChanged(transport_name(), new_route);
Honghai Zhangcc411c02016-03-29 17:27:21 -0700345}
346
Tommi99c8a802021-04-27 15:00:00 +0200347void BaseChannel::SetFirstPacketReceivedCallback(
348 std::function<void()> callback) {
349 RTC_DCHECK_RUN_ON(network_thread());
350 RTC_DCHECK(!on_first_packet_received_ || !callback);
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100351
352 // TODO(bugs.webrtc.org/11992): Rename SetFirstPacketReceivedCallback to
353 // something that indicates network thread initialization/uninitialization and
354 // call Init_n() / Deinit_n() respectively.
355 // if (!callback)
356 // Deinit_n();
357
Tommi99c8a802021-04-27 15:00:00 +0200358 on_first_packet_received_ = std::move(callback);
Tomas Gunnarssonb2995a12020-09-28 14:05:35 +0200359}
360
zstein56162b92017-04-24 16:54:35 -0700361void BaseChannel::OnTransportReadyToSend(bool ready) {
Tomas Gunnarssonad325862021-02-03 16:23:40 +0100362 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100363 RTC_DCHECK(network_initialized());
Tomas Gunnarssonad325862021-02-03 16:23:40 +0100364 media_channel_->OnReadyToSend(ready);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000365}
366
stefanc1aeaf02015-10-15 07:26:07 -0700367bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700368 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700369 const rtc::PacketOptions& options) {
Tommicf2aeff2021-05-07 18:02:53 +0200370 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100371 RTC_DCHECK(network_initialized());
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200372 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373
Tomas Gunnarssona49942a2022-01-17 09:03:06 +0100374 // Until all the code is migrated to use RtpPacketType instead of bool.
375 RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
376
377 // Ensure we have a place to send this packet before doing anything. We might
378 // get RTCP packets that we don't intend to send. If we've negotiated RTCP
379 // mux, send RTCP over the RTP transport.
Zhi Huange830e682018-03-30 10:48:35 -0700380 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000381 return false;
382 }
383
384 // Protect ourselves against crazy data.
Amit Hilbuchedd20542019-03-18 12:33:43 -0700385 if (!IsValidRtpPacketSize(packet_type, packet->size())) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300386 RTC_LOG(LS_ERROR) << "Dropping outgoing " << ToString() << " "
Amit Hilbuchedd20542019-03-18 12:33:43 -0700387 << RtpPacketTypeToString(packet_type)
Mirko Bonadei675513b2017-11-09 11:09:25 +0100388 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389 return false;
390 }
391
Zhi Huangcf990f52017-09-22 12:12:30 -0700392 if (!srtp_active()) {
393 if (srtp_required_) {
394 // The audio/video engines may attempt to send RTCP packets as soon as the
395 // streams are created, so don't treat this as an error for RTCP.
396 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
Tomas Gunnarssona49942a2022-01-17 09:03:06 +0100397 // However, there shouldn't be any RTP packets sent before SRTP is set
398 // up (and SetSend(true) is called).
399 RTC_DCHECK(rtcp) << "Can't send outgoing RTP packet for " << ToString()
400 << " when SRTP is inactive and crypto is required";
deadbeef8f425f92016-12-01 12:26:27 -0800401 return false;
402 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800403
Tomas Gunnarssona49942a2022-01-17 09:03:06 +0100404 RTC_DLOG(LS_WARNING) << "Sending an " << (rtcp ? "RTCP" : "RTP")
Marina Ciocea38728732020-07-29 10:15:46 +0200405 << " packet without encryption for " << ToString()
406 << ".";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407 }
Zhi Huange830e682018-03-30 10:48:35 -0700408
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800409 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
410 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000411}
412
Zhi Huang365381f2018-04-13 16:44:34 -0700413void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
Tommi99c8a802021-04-27 15:00:00 +0200414 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100415 RTC_DCHECK(network_initialized());
Tommi99c8a802021-04-27 15:00:00 +0200416
Tommi99c8a802021-04-27 15:00:00 +0200417 if (on_first_packet_received_) {
418 on_first_packet_received_();
419 on_first_packet_received_ = nullptr;
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200420 }
421
422 if (!srtp_active() && srtp_required_) {
423 // Our session description indicates that SRTP is required, but we got a
424 // packet before our SRTP filter is active. This means either that
425 // a) we got SRTP packets before we received the SDES keys, in which case
426 // we can't decrypt it anyway, or
427 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
428 // transports, so we haven't yet extracted keys, even if DTLS did
429 // complete on the transport that the packets are being sent on. It's
430 // really good practice to wait for both RTP and RTCP to be good to go
431 // before sending media, to prevent weird failure modes, so it's fine
432 // for us to just eat packets here. This is all sidestepped if RTCP mux
433 // is used anyway.
434 RTC_LOG(LS_WARNING) << "Can't process incoming RTP packet when "
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300435 "SRTP is inactive and crypto is required "
436 << ToString();
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200437 return;
438 }
439
Tommi2497a272021-05-05 12:33:00 +0200440 webrtc::Timestamp packet_time = parsed_packet.arrival_time();
441 media_channel_->OnPacketReceived(
442 parsed_packet.Buffer(),
443 packet_time.IsMinusInfinity() ? -1 : packet_time.us());
Zhi Huang365381f2018-04-13 16:44:34 -0700444}
445
Tommi2195d542022-01-31 20:58:11 +0100446bool BaseChannel::MaybeUpdateDemuxerAndRtpExtensions_w(
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000447 bool update_demuxer,
Tommi2195d542022-01-31 20:58:11 +0100448 absl::optional<RtpHeaderExtensions> extensions,
449 std::string& error_desc) {
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000450 if (extensions) {
451 if (rtp_header_extensions_ == extensions) {
452 extensions.reset(); // No need to update header extensions.
453 } else {
454 rtp_header_extensions_ = *extensions;
455 }
456 }
457
458 if (!update_demuxer && !extensions)
Tommi2195d542022-01-31 20:58:11 +0100459 return true; // No update needed.
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000460
461 // TODO(bugs.webrtc.org/13536): See if we can do this asynchronously.
462
463 if (update_demuxer)
464 media_channel()->OnDemuxerCriteriaUpdatePending();
465
Tommi2195d542022-01-31 20:58:11 +0100466 bool success = network_thread()->Invoke<bool>(RTC_FROM_HERE, [&]() mutable {
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800467 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000468 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
469 // extension maps are not merged when BUNDLE is enabled. This is fine
470 // because the ID for MID should be consistent among all the RTP transports.
471 if (extensions)
472 rtp_transport_->UpdateRtpHeaderExtensionMap(*extensions);
Tommi2195d542022-01-31 20:58:11 +0100473
474 if (!update_demuxer)
475 return true;
476
477 if (!rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this)) {
478 error_desc =
479 StringFormat("Failed to apply demuxer criteria for '%s': '%s'.",
480 mid().c_str(), demuxer_criteria_.ToString().c_str());
481 return false;
482 }
483 return true;
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800484 });
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000485
486 if (update_demuxer)
487 media_channel()->OnDemuxerCriteriaUpdateComplete();
Tommi2195d542022-01-31 20:58:11 +0100488
489 return success;
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800490}
491
492bool BaseChannel::RegisterRtpDemuxerSink_w() {
Henrik Boström15e078c2021-04-16 09:54:18 +0200493 media_channel_->OnDemuxerCriteriaUpdatePending();
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800494 // Copy demuxer criteria, since they're a worker-thread variable
495 // and we want to pass them to the network thread
Tomas Gunnarssonf643aea2022-01-02 15:57:28 +0000496 bool ret = network_thread_->Invoke<bool>(
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800497 RTC_FROM_HERE, [this, demuxer_criteria = demuxer_criteria_] {
498 RTC_DCHECK_RUN_ON(network_thread());
Tommi075db392022-02-11 18:09:31 +0100499 if (!rtp_transport_) {
500 // Transport was disconnected before attempting to update the
501 // criteria. This can happen while setting the remote description.
502 // See chromium:1295469 for an example.
503 return false;
504 }
Tomas Gunnarsson9abd74d2022-01-04 17:21:54 +0000505 // Note that RegisterRtpDemuxerSink first unregisters the sink if
506 // already registered. So this will change the state of the class
507 // whether the call succeeds or not.
508 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria, this);
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800509 });
Tomas Gunnarssonf643aea2022-01-02 15:57:28 +0000510
511 media_channel_->OnDemuxerCriteriaUpdateComplete();
512
513 return ret;
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800514}
515
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000516void BaseChannel::EnableMedia_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000517 if (enabled_)
518 return;
519
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300520 RTC_LOG(LS_INFO) << "Channel enabled: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000521 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700522 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000523}
524
525void BaseChannel::DisableMedia_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526 if (!enabled_)
527 return;
528
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300529 RTC_LOG(LS_INFO) << "Channel disabled: " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000530 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700531 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000532}
533
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200534void BaseChannel::UpdateWritableState_n() {
Markus Handell518669d2021-06-07 13:30:46 +0200535 TRACE_EVENT0("webrtc", "BaseChannel::UpdateWritableState_n");
Zhi Huange830e682018-03-30 10:48:35 -0700536 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
537 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200538 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700539 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200540 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700541 }
542}
543
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200544void BaseChannel::ChannelWritable_n() {
Markus Handell518669d2021-06-07 13:30:46 +0200545 TRACE_EVENT0("webrtc", "BaseChannel::ChannelWritable_n");
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800546 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000547 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800548 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800549 writable_ = true;
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800550 RTC_LOG(LS_INFO) << "Channel writable (" << ToString() << ")"
551 << (was_ever_writable_n_ ? "" : " for the first time");
552 // We only have to do this PostTask once, when first transitioning to
553 // writable.
554 if (!was_ever_writable_n_) {
555 worker_thread_->PostTask(ToQueuedTask(alive_, [this] {
556 RTC_DCHECK_RUN_ON(worker_thread());
557 was_ever_writable_ = true;
558 UpdateMediaSendRecvState_w();
559 }));
560 }
561 was_ever_writable_n_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000562}
563
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200564void BaseChannel::ChannelNotWritable_n() {
Markus Handell518669d2021-06-07 13:30:46 +0200565 TRACE_EVENT0("webrtc", "BaseChannel::ChannelNotWritable_n");
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800566 if (!writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567 return;
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800568 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800569 writable_ = false;
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800570 RTC_LOG(LS_INFO) << "Channel not writable (" << ToString() << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571}
572
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800573bool BaseChannel::SetPayloadTypeDemuxingEnabled_w(bool enabled) {
Tomas Gunnarssone68d8742022-01-06 14:47:12 +0000574 RTC_LOG_THREAD_BLOCK_COUNT();
575
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700576 if (enabled == payload_type_demuxing_enabled_) {
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800577 return true;
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700578 }
Tomas Gunnarssone68d8742022-01-06 14:47:12 +0000579
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700580 payload_type_demuxing_enabled_ = enabled;
Tomas Gunnarssone68d8742022-01-06 14:47:12 +0000581
582 bool config_changed = false;
583
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700584 if (!enabled) {
585 // TODO(crbug.com/11477): This will remove *all* unsignaled streams (those
586 // without an explicitly signaled SSRC), which may include streams that
587 // were matched to this channel by MID or RID. Ideally we'd remove only the
588 // streams that were matched based on payload type alone, but currently
589 // there is no straightforward way to identify those streams.
590 media_channel()->ResetUnsignaledRecvStream();
Tomas Gunnarssone68d8742022-01-06 14:47:12 +0000591 if (!demuxer_criteria_.payload_types().empty()) {
592 config_changed = true;
593 demuxer_criteria_.payload_types().clear();
594 }
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700595 } else if (!payload_types_.empty()) {
Tomas Gunnarssone68d8742022-01-06 14:47:12 +0000596 for (const auto& type : payload_types_) {
597 if (demuxer_criteria_.payload_types().insert(type).second) {
598 config_changed = true;
599 }
600 }
601 } else {
602 RTC_DCHECK(demuxer_criteria_.payload_types().empty());
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700603 }
Tomas Gunnarssonde6e1b42022-01-03 22:43:54 +0000604
Tomas Gunnarssone68d8742022-01-06 14:47:12 +0000605 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
606
607 if (!config_changed)
608 return true;
609
Tomas Gunnarssonde6e1b42022-01-03 22:43:54 +0000610 // Note: This synchronously hops to the network thread.
611 return RegisterRtpDemuxerSink_w();
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700612}
613
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000614bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800615 SdpType type,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000616 std::string& error_desc) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800617 // In the case of RIDs (where SSRCs are not negotiated), this method will
618 // generate an SSRC for each layer in StreamParams. That representation will
Artem Titov880fa812021-07-30 22:30:23 +0200619 // be stored internally in `local_streams_`.
620 // In subsequent offers, the same stream can appear in `streams` again
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800621 // (without the SSRCs), so it should be looked up using RIDs (if available)
622 // and then by primary SSRC.
623 // In both scenarios, it is safe to assume that the media channel will be
624 // created with a StreamParams object with SSRCs. However, it is not safe to
Artem Titov880fa812021-07-30 22:30:23 +0200625 // assume that `local_streams_` will always have SSRCs as there are scenarios
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800626 // in which niether SSRCs or RIDs are negotiated.
627
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000628 // Check for streams that have been removed.
629 bool ret = true;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800630 for (const StreamParams& old_stream : local_streams_) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800631 if (!old_stream.has_ssrcs() ||
632 GetStream(streams, StreamFinder(&old_stream))) {
633 continue;
634 }
635 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000636 error_desc = StringFormat(
637 "Failed to remove send stream with ssrc %u from m-section with "
638 "mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100639 old_stream.first_ssrc(), mid().c_str());
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800640 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000641 }
642 }
643 // Check for new streams.
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800644 std::vector<StreamParams> all_streams;
645 for (const StreamParams& stream : streams) {
646 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
647 if (existing) {
648 // Parameters cannot change for an existing stream.
649 all_streams.push_back(*existing);
650 continue;
651 }
652
653 all_streams.push_back(stream);
654 StreamParams& new_stream = all_streams.back();
655
656 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
657 continue;
658 }
659
660 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
661 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000662 error_desc = StringFormat(
663 "Failed to add send stream: %u into m-section with mid='%s'. Stream "
664 "has both SSRCs and RIDs.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100665 new_stream.first_ssrc(), mid().c_str());
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800666 ret = false;
667 continue;
668 }
669
670 // At this point we use the legacy simulcast group in StreamParams to
671 // indicate that we want multiple layers to the media channel.
672 if (!new_stream.has_ssrcs()) {
673 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
674 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
675 /* flex_fec = */ false, ssrc_generator_);
676 }
677
678 if (media_channel()->AddSendStream(new_stream)) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300679 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0]
680 << " into " << ToString();
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800681 } else {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000682 error_desc = StringFormat(
683 "Failed to add send stream ssrc: %u into m-section with mid='%s'",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100684 new_stream.first_ssrc(), mid().c_str());
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800685 ret = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000686 }
687 }
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800688 local_streams_ = all_streams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000689 return ret;
690}
691
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000692bool BaseChannel::UpdateRemoteStreams_w(const MediaContentDescription* content,
693 SdpType type,
694 std::string& error_desc) {
695 RTC_LOG_THREAD_BLOCK_COUNT();
696 bool needs_re_registration = false;
697 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
698 RTC_DLOG(LS_VERBOSE) << "UpdateRemoteStreams_w: remote side will not send "
699 "- disable payload type demuxing for "
700 << ToString();
701 if (ClearHandledPayloadTypes()) {
702 needs_re_registration = payload_type_demuxing_enabled_;
703 }
704 }
705
706 const std::vector<StreamParams>& streams = content->streams();
707 const bool new_has_unsignaled_ssrcs = HasStreamWithNoSsrcs(streams);
708 const bool old_has_unsignaled_ssrcs = HasStreamWithNoSsrcs(remote_streams_);
709
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000710 // Check for streams that have been removed.
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800711 for (const StreamParams& old_stream : remote_streams_) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700712 // If we no longer have an unsignaled stream, we would like to remove
713 // the unsignaled stream params that are cached.
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000714 if (!old_stream.has_ssrcs() && !new_has_unsignaled_ssrcs) {
715 media_channel()->ResetUnsignaledRecvStream();
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300716 RTC_LOG(LS_INFO) << "Reset unsignaled remote stream for " << ToString()
717 << ".";
Saurav Dasff27da52019-09-20 11:05:30 -0700718 } else if (old_stream.has_ssrcs() &&
719 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000720 if (media_channel()->RemoveRecvStream(old_stream.first_ssrc())) {
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300721 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc()
722 << " from " << ToString() << ".";
Zhi Huang365381f2018-04-13 16:44:34 -0700723 } else {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000724 error_desc = StringFormat(
725 "Failed to remove remote stream with ssrc %u from m-section with "
726 "mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100727 old_stream.first_ssrc(), mid().c_str());
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000728 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729 }
730 }
731 }
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000732
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000733 // Check for new streams.
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000734 webrtc::flat_set<uint32_t> ssrcs;
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800735 for (const StreamParams& new_stream : streams) {
Seth Hampson5897a6e2018-04-03 11:16:33 -0700736 // We allow a StreamParams with an empty list of SSRCs, in which case the
737 // MediaChannel will cache the parameters and use them for any unsignaled
738 // stream received later.
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000739 if ((!new_stream.has_ssrcs() && !old_has_unsignaled_ssrcs) ||
Steve Anton5f8b5fd2018-12-27 16:58:10 -0800740 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000741 if (media_channel()->AddRecvStream(new_stream)) {
Saurav Dasff27da52019-09-20 11:05:30 -0700742 RTC_LOG(LS_INFO) << "Add remote ssrc: "
743 << (new_stream.has_ssrcs()
744 ? std::to_string(new_stream.first_ssrc())
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300745 : "unsignaled")
746 << " to " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000747 } else {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000748 error_desc =
749 StringFormat("Failed to add remote stream ssrc: %s to %s",
750 new_stream.has_ssrcs()
751 ? std::to_string(new_stream.first_ssrc()).c_str()
752 : "unsignaled",
753 ToString().c_str());
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000754 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 }
756 }
Zhi Huang365381f2018-04-13 16:44:34 -0700757 // Update the receiving SSRCs.
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000758 ssrcs.insert(new_stream.ssrcs.begin(), new_stream.ssrcs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000759 }
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000760
761 if (demuxer_criteria_.ssrcs() != ssrcs) {
762 demuxer_criteria_.ssrcs() = std::move(ssrcs);
763 needs_re_registration = true;
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800764 }
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000765
766 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
767
768 // Re-register the sink to update after changing the demuxer criteria.
769 if (needs_re_registration && !RegisterRtpDemuxerSink_w()) {
770 error_desc = StringFormat("Failed to set up audio demuxing for mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100771 mid().c_str());
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000772 return false;
773 }
774
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000775 remote_streams_ = streams;
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000776
777 set_remote_content_direction(content->direction());
778 UpdateMediaSendRecvState_w();
779
780 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1);
781
782 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783}
784
Lennart Grahl0d0ed762021-05-17 16:06:37 +0200785RtpHeaderExtensions BaseChannel::GetDeduplicatedRtpHeaderExtensions(
jbauch5869f502017-06-29 12:31:36 -0700786 const RtpHeaderExtensions& extensions) {
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000787 return webrtc::RtpExtension::DeduplicateHeaderExtensions(extensions,
788 extensions_filter_);
jbauch5869f502017-06-29 12:31:36 -0700789}
790
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000791bool BaseChannel::MaybeAddHandledPayloadType(int payload_type) {
792 bool demuxer_criteria_modified = false;
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700793 if (payload_type_demuxing_enabled_) {
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000794 demuxer_criteria_modified = demuxer_criteria_.payload_types()
795 .insert(static_cast<uint8_t>(payload_type))
796 .second;
Taylor Brandstetterc03a1872020-09-02 13:25:31 -0700797 }
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700798 // Even if payload type demuxing is currently disabled, we need to remember
799 // the payload types in case it's re-enabled later.
800 payload_types_.insert(static_cast<uint8_t>(payload_type));
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000801 return demuxer_criteria_modified;
zstein3dcf0e92017-06-01 13:22:42 -0700802}
803
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000804bool BaseChannel::ClearHandledPayloadTypes() {
805 const bool was_empty = demuxer_criteria_.payload_types().empty();
Tomas Gunnarsson8a5ac162022-01-03 14:16:46 +0000806 demuxer_criteria_.payload_types().clear();
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -0700807 payload_types_.clear();
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000808 return !was_empty;
Steve Antonbe2e5f72019-09-06 16:26:02 -0700809}
810
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800811void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Tomas Gunnarssoneb9c3f22021-04-19 12:53:09 +0200812 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarssoncc9b7ec2022-01-16 20:44:25 +0100813 RTC_DCHECK(network_initialized());
Tomas Gunnarssoneb9c3f22021-04-19 12:53:09 +0200814 media_channel()->OnPacketSent(sent_packet);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200815}
816
817VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
818 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800819 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800820 std::unique_ptr<VoiceMediaChannel> media_channel,
Harald Alvestrand8f429922022-05-04 10:32:30 +0000821 absl::string_view mid,
Zhi Huange830e682018-03-30 10:48:35 -0700822 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800823 webrtc::CryptoOptions crypto_options,
824 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200825 : BaseChannel(worker_thread,
826 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800827 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800828 std::move(media_channel),
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100829 mid,
Zhi Huange830e682018-03-30 10:48:35 -0700830 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800831 crypto_options,
832 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000833
834VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800835 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836 // this can't be done in the base class, since it calls a virtual
837 DisableMedia_w();
838}
839
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700840void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841 // Render incoming data if we're the active call, and we have the local
842 // content. We receive data on the default channel and multiplexed streams.
Tomas Gunnarssonb496c322022-01-05 10:26:36 +0000843 bool ready_to_receive = enabled() && webrtc::RtpTransceiverDirectionHasRecv(
844 local_content_direction());
845 media_channel()->SetPlayout(ready_to_receive);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846
847 // Send outgoing data if we're the active call, we have the remote content,
848 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700849 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800850 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851
Tomas Gunnarssonb496c322022-01-05 10:26:36 +0000852 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << ready_to_receive
853 << " send=" << send << " for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000854}
855
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800857 SdpType type,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000858 std::string& error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100859 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000860 RTC_DLOG(LS_INFO) << "Setting local voice description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000861
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000862 RTC_LOG_THREAD_BLOCK_COUNT();
863
864 RtpHeaderExtensions header_extensions =
Lennart Grahl0d0ed762021-05-17 16:06:37 +0200865 GetDeduplicatedRtpHeaderExtensions(content->rtp_header_extensions());
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000866 bool update_header_extensions = true;
Tommia63bee52021-04-26 20:11:18 +0200867 media_channel()->SetExtmapAllowMixed(content->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700868
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700869 AudioRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +0200870 RtpParametersFromMediaDescription(
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000871 content->as_audio(), header_extensions,
Tommia63bee52021-04-26 20:11:18 +0200872 webrtc::RtpTransceiverDirectionHasRecv(content->direction()),
873 &recv_params);
874
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700875 if (!media_channel()->SetRecvParameters(recv_params)) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000876 error_desc = StringFormat(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000877 "Failed to set local audio description recv parameters for m-section "
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000878 "with mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100879 mid().c_str());
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700880 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881 }
Steve Antonbe2e5f72019-09-06 16:26:02 -0700882
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000883 bool criteria_modified = false;
Tommia63bee52021-04-26 20:11:18 +0200884 if (webrtc::RtpTransceiverDirectionHasRecv(content->direction())) {
885 for (const AudioCodec& codec : content->as_audio()->codecs()) {
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000886 if (MaybeAddHandledPayloadType(codec.id)) {
887 criteria_modified = true;
888 }
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -0800889 }
Zhi Huang365381f2018-04-13 16:44:34 -0700890 }
891
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700892 last_recv_params_ = recv_params;
893
Tommia63bee52021-04-26 20:11:18 +0200894 if (!UpdateLocalStreams_w(content->as_audio()->streams(), type, error_desc)) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000895 RTC_DCHECK(!error_desc.empty());
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700896 return false;
897 }
898
899 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700900 UpdateMediaSendRecvState_w();
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000901
902 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
903
Tommi2195d542022-01-31 20:58:11 +0100904 bool success = MaybeUpdateDemuxerAndRtpExtensions_w(
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000905 criteria_modified,
906 update_header_extensions
907 ? absl::optional<RtpHeaderExtensions>(std::move(header_extensions))
Tommi2195d542022-01-31 20:58:11 +0100908 : absl::nullopt,
909 error_desc);
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000910
911 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1);
912
Tommi2195d542022-01-31 20:58:11 +0100913 return success;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914}
915
916bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800917 SdpType type,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000918 std::string& error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100919 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300920 RTC_LOG(LS_INFO) << "Setting remote voice description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700922 AudioSendParameters send_params = last_send_params_;
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000923 RtpSendParametersFromMediaDescription(content->as_audio(),
924 extensions_filter(), &send_params);
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100925 send_params.mid = mid();
skvladdc1c62c2016-03-16 19:07:43 -0700926
927 bool parameters_applied = media_channel()->SetSendParameters(send_params);
928 if (!parameters_applied) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000929 error_desc = StringFormat(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +0000930 "Failed to set remote audio description send parameters for m-section "
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000931 "with mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100932 mid().c_str());
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700933 return false;
934 }
935 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000937 return UpdateRemoteStreams_w(content, type, error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938}
939
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200940VideoChannel::VideoChannel(rtc::Thread* worker_thread,
941 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800942 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800943 std::unique_ptr<VideoMediaChannel> media_channel,
Harald Alvestrand8f429922022-05-04 10:32:30 +0000944 absl::string_view mid,
Zhi Huange830e682018-03-30 10:48:35 -0700945 bool srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800946 webrtc::CryptoOptions crypto_options,
947 UniqueRandomIdGenerator* ssrc_generator)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200948 : BaseChannel(worker_thread,
949 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800950 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800951 std::move(media_channel),
Tomas Gunnarsson5411b172022-01-24 08:45:26 +0100952 mid,
Zhi Huange830e682018-03-30 10:48:35 -0700953 srtp_required,
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800954 crypto_options,
955 ssrc_generator) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800958 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959 // this can't be done in the base class, since it calls a virtual
960 DisableMedia_w();
961}
962
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700963void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964 // Send outgoing data if we're the active call, we have the remote content,
965 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700966 bool send = IsReadyToSendMedia_w();
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +0000967 media_channel()->SetSend(send);
Yura Yaroshevichc3252462020-05-18 13:26:14 +0300968 RTC_LOG(LS_INFO) << "Changing video state, send=" << send << " for "
969 << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970}
971
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800973 SdpType type,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000974 std::string& error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100975 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000976 RTC_DLOG(LS_INFO) << "Setting local video description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000978 RTC_LOG_THREAD_BLOCK_COUNT();
979
980 RtpHeaderExtensions header_extensions =
Lennart Grahl0d0ed762021-05-17 16:06:37 +0200981 GetDeduplicatedRtpHeaderExtensions(content->rtp_header_extensions());
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000982 bool update_header_extensions = true;
Tommia63bee52021-04-26 20:11:18 +0200983 media_channel()->SetExtmapAllowMixed(content->extmap_allow_mixed());
jbauch5869f502017-06-29 12:31:36 -0700984
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700985 VideoRecvParameters recv_params = last_recv_params_;
Tommia63bee52021-04-26 20:11:18 +0200986
Johannes Kron3e983682020-03-29 22:17:00 +0200987 RtpParametersFromMediaDescription(
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +0000988 content->as_video(), header_extensions,
Tommia63bee52021-04-26 20:11:18 +0200989 webrtc::RtpTransceiverDirectionHasRecv(content->direction()),
990 &recv_params);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +0200991
992 VideoSendParameters send_params = last_send_params_;
Johannes Kron3e983682020-03-29 22:17:00 +0200993
Mirta Dvornicic479a3c02019-06-04 15:38:50 +0200994 bool needs_send_params_update = false;
Johannes Krona104ceb2020-01-24 16:04:04 +0000995 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
Mirta Dvornicic479a3c02019-06-04 15:38:50 +0200996 for (auto& send_codec : send_params.codecs) {
997 auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
998 if (recv_codec) {
999 if (!recv_codec->packetization && send_codec.packetization) {
1000 send_codec.packetization.reset();
1001 needs_send_params_update = true;
1002 } else if (recv_codec->packetization != send_codec.packetization) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001003 error_desc = StringFormat(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001004 "Failed to set local answer due to invalid codec packetization "
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001005 "specified in m-section with mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +01001006 mid().c_str());
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001007 return false;
1008 }
1009 }
1010 }
1011 }
1012
Johannes Krona104ceb2020-01-24 16:04:04 +00001013 if (!media_channel()->SetRecvParameters(recv_params)) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001014 error_desc = StringFormat(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001015 "Failed to set local video description recv parameters for m-section "
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001016 "with mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +01001017 mid().c_str());
Johannes Krona104ceb2020-01-24 16:04:04 +00001018 return false;
1019 }
Johannes Kron9bac68c2020-01-23 13:12:25 +00001020
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +00001021 bool criteria_modified = false;
Tommia63bee52021-04-26 20:11:18 +02001022 if (webrtc::RtpTransceiverDirectionHasRecv(content->direction())) {
1023 for (const VideoCodec& codec : content->as_video()->codecs()) {
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +00001024 if (MaybeAddHandledPayloadType(codec.id))
1025 criteria_modified = true;
Taylor Brandstetterd0acbd82021-01-25 13:44:55 -08001026 }
Zhi Huang365381f2018-04-13 16:44:34 -07001027 }
1028
Johannes Krona104ceb2020-01-24 16:04:04 +00001029 last_recv_params_ = recv_params;
1030
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001031 if (needs_send_params_update) {
1032 if (!media_channel()->SetSendParameters(send_params)) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001033 error_desc = StringFormat(
1034 "Failed to set send parameters for m-section with mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +01001035 mid().c_str());
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001036 return false;
1037 }
1038 last_send_params_ = send_params;
1039 }
1040
Tommia63bee52021-04-26 20:11:18 +02001041 if (!UpdateLocalStreams_w(content->as_video()->streams(), type, error_desc)) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001042 RTC_DCHECK(!error_desc.empty());
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001043 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001044 }
1045
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001046 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001047 UpdateMediaSendRecvState_w();
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +00001048
1049 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
1050
Tommi2195d542022-01-31 20:58:11 +01001051 bool success = MaybeUpdateDemuxerAndRtpExtensions_w(
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +00001052 criteria_modified,
1053 update_header_extensions
1054 ? absl::optional<RtpHeaderExtensions>(std::move(header_extensions))
Tommi2195d542022-01-31 20:58:11 +01001055 : absl::nullopt,
1056 error_desc);
Tomas Gunnarssonc69453d2022-01-06 12:36:04 +00001057
1058 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1);
1059
Tommi2195d542022-01-31 20:58:11 +01001060 return success;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001061}
1062
1063bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001064 SdpType type,
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001065 std::string& error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001066 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Yura Yaroshevichc3252462020-05-18 13:26:14 +03001067 RTC_LOG(LS_INFO) << "Setting remote video description for " << ToString();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001068
Steve Antonb1c1de12017-12-21 15:14:30 -08001069 const VideoContentDescription* video = content->as_video();
1070
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001071 VideoSendParameters send_params = last_send_params_;
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +00001072 RtpSendParametersFromMediaDescription(video, extensions_filter(),
1073 &send_params);
Tomas Gunnarsson5411b172022-01-24 08:45:26 +01001074 send_params.mid = mid();
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +00001075 send_params.conference_mode = video->conference_mode();
skvladdc1c62c2016-03-16 19:07:43 -07001076
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001077 VideoRecvParameters recv_params = last_recv_params_;
Johannes Kron3e983682020-03-29 22:17:00 +02001078
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001079 bool needs_recv_params_update = false;
Johannes Krona104ceb2020-01-24 16:04:04 +00001080 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001081 for (auto& recv_codec : recv_params.codecs) {
1082 auto* send_codec = FindMatchingCodec(send_params.codecs, recv_codec);
1083 if (send_codec) {
1084 if (!send_codec->packetization && recv_codec.packetization) {
1085 recv_codec.packetization.reset();
1086 needs_recv_params_update = true;
1087 } else if (send_codec->packetization != recv_codec.packetization) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001088 error_desc = StringFormat(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001089 "Failed to set remote answer due to invalid codec packetization "
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001090 "specifid in m-section with mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +01001091 mid().c_str());
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001092 return false;
1093 }
1094 }
1095 }
1096 }
skvladdc1c62c2016-03-16 19:07:43 -07001097
Johannes Krona104ceb2020-01-24 16:04:04 +00001098 if (!media_channel()->SetSendParameters(send_params)) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001099 error_desc = StringFormat(
Yura Yaroshevichbc1f9102020-06-03 21:15:22 +00001100 "Failed to set remote video description send parameters for m-section "
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001101 "with mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +01001102 mid().c_str());
Johannes Krona104ceb2020-01-24 16:04:04 +00001103 return false;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001104 }
Johannes Krona104ceb2020-01-24 16:04:04 +00001105 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001106
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001107 if (needs_recv_params_update) {
1108 if (!media_channel()->SetRecvParameters(recv_params)) {
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001109 error_desc = StringFormat(
1110 "Failed to set recv parameters for m-section with mid='%s'.",
Tomas Gunnarsson5411b172022-01-24 08:45:26 +01001111 mid().c_str());
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02001112 return false;
1113 }
1114 last_recv_params_ = recv_params;
1115 }
1116
Tomas Gunnarssonac72dda2022-01-06 10:16:42 +00001117 return UpdateRemoteStreams_w(content, type, error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001118}
1119
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001120} // namespace cricket