1 /*
2 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
3 *
4 * 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.
9 */
10
11 #include "pc/channel.h"
12
13 #include <algorithm>
14 #include <cstdint>
15 #include <string>
16 #include <type_traits>
17 #include <utility>
18
19 #include "absl/strings/string_view.h"
20 #include "api/rtp_parameters.h"
21 #include "api/sequence_checker.h"
22 #include "api/task_queue/pending_task_safety_flag.h"
23 #include "api/units/timestamp.h"
24 #include "media/base/codec.h"
25 #include "media/base/rid_description.h"
26 #include "media/base/rtp_utils.h"
27 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
28 #include "p2p/base/dtls_transport_internal.h"
29 #include "pc/rtp_media_utils.h"
30 #include "rtc_base/checks.h"
31 #include "rtc_base/copy_on_write_buffer.h"
32 #include "rtc_base/logging.h"
33 #include "rtc_base/network_route.h"
34 #include "rtc_base/strings/string_format.h"
35 #include "rtc_base/trace_event.h"
36
37 namespace cricket {
38 namespace {
39
40 using ::rtc::StringFormat;
41 using ::rtc::UniqueRandomIdGenerator;
42 using ::webrtc::PendingTaskSafetyFlag;
43 using ::webrtc::SdpType;
44
45 // Finds a stream based on target's Primary SSRC or RIDs.
46 // This struct is used in BaseChannel::UpdateLocalStreams_w.
47 struct StreamFinder {
StreamFindercricket::__anon18d5a84c0111::StreamFinder48 explicit StreamFinder(const StreamParams* target) : target_(target) {
49 RTC_DCHECK(target);
50 }
51
operator ()cricket::__anon18d5a84c0111::StreamFinder52 bool operator()(const StreamParams& sp) const {
53 if (target_->has_ssrcs() && sp.has_ssrcs()) {
54 return sp.has_ssrc(target_->first_ssrc());
55 }
56
57 if (!target_->has_rids() && !sp.has_rids()) {
58 return false;
59 }
60
61 const std::vector<RidDescription>& target_rids = target_->rids();
62 const std::vector<RidDescription>& source_rids = sp.rids();
63 if (source_rids.size() != target_rids.size()) {
64 return false;
65 }
66
67 // Check that all RIDs match.
68 return std::equal(source_rids.begin(), source_rids.end(),
69 target_rids.begin(),
70 [](const RidDescription& lhs, const RidDescription& rhs) {
71 return lhs.rid == rhs.rid;
72 });
73 }
74
75 const StreamParams* target_;
76 };
77
78 } // namespace
79
80 template <class Codec>
RtpParametersFromMediaDescription(const MediaContentDescriptionImpl<Codec> * desc,const RtpHeaderExtensions & extensions,bool is_stream_active,RtpParameters<Codec> * params)81 void RtpParametersFromMediaDescription(
82 const MediaContentDescriptionImpl<Codec>* desc,
83 const RtpHeaderExtensions& extensions,
84 bool is_stream_active,
85 RtpParameters<Codec>* params) {
86 params->is_stream_active = is_stream_active;
87 params->codecs = desc->codecs();
88 // TODO(bugs.webrtc.org/11513): See if we really need
89 // rtp_header_extensions_set() and remove it if we don't.
90 if (desc->rtp_header_extensions_set()) {
91 params->extensions = extensions;
92 }
93 params->rtcp.reduced_size = desc->rtcp_reduced_size();
94 params->rtcp.remote_estimate = desc->remote_estimate();
95 }
96
97 template <class Codec>
RtpSendParametersFromMediaDescription(const MediaContentDescriptionImpl<Codec> * desc,webrtc::RtpExtension::Filter extensions_filter,RtpSendParameters<Codec> * send_params)98 void RtpSendParametersFromMediaDescription(
99 const MediaContentDescriptionImpl<Codec>* desc,
100 webrtc::RtpExtension::Filter extensions_filter,
101 RtpSendParameters<Codec>* send_params) {
102 RtpHeaderExtensions extensions =
103 webrtc::RtpExtension::DeduplicateHeaderExtensions(
104 desc->rtp_header_extensions(), extensions_filter);
105 const bool is_stream_active =
106 webrtc::RtpTransceiverDirectionHasRecv(desc->direction());
107 RtpParametersFromMediaDescription(desc, extensions, is_stream_active,
108 send_params);
109 send_params->max_bandwidth_bps = desc->bandwidth();
110 send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
111 }
112
BaseChannel(rtc::Thread * worker_thread,rtc::Thread * network_thread,rtc::Thread * signaling_thread,std::unique_ptr<MediaChannel> media_channel,absl::string_view mid,bool srtp_required,webrtc::CryptoOptions crypto_options,UniqueRandomIdGenerator * ssrc_generator)113 BaseChannel::BaseChannel(rtc::Thread* worker_thread,
114 rtc::Thread* network_thread,
115 rtc::Thread* signaling_thread,
116 std::unique_ptr<MediaChannel> media_channel,
117 absl::string_view mid,
118 bool srtp_required,
119 webrtc::CryptoOptions crypto_options,
120 UniqueRandomIdGenerator* ssrc_generator)
121 : worker_thread_(worker_thread),
122 network_thread_(network_thread),
123 signaling_thread_(signaling_thread),
124 alive_(PendingTaskSafetyFlag::Create()),
125 srtp_required_(srtp_required),
126 extensions_filter_(
127 crypto_options.srtp.enable_encrypted_rtp_header_extensions
128 ? webrtc::RtpExtension::kPreferEncryptedExtension
129 : webrtc::RtpExtension::kDiscardEncryptedExtension),
130 media_channel_(std::move(media_channel)),
131 demuxer_criteria_(mid),
132 ssrc_generator_(ssrc_generator) {
133 RTC_DCHECK_RUN_ON(worker_thread_);
134 RTC_DCHECK(media_channel_);
135 RTC_DCHECK(ssrc_generator_);
136 RTC_DLOG(LS_INFO) << "Created channel: " << ToString();
137 }
138
~BaseChannel()139 BaseChannel::~BaseChannel() {
140 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
141 RTC_DCHECK_RUN_ON(worker_thread_);
142
143 // Eats any outstanding messages or packets.
144 alive_->SetNotAlive();
145 // The media channel is destroyed at the end of the destructor, since it
146 // is a std::unique_ptr. The transport channel (rtp_transport) must outlive
147 // the media channel.
148 }
149
ToString() const150 std::string BaseChannel::ToString() const {
151 return StringFormat("{mid: %s, media_type: %s}", mid().c_str(),
152 MediaTypeToString(media_channel_->media_type()).c_str());
153 }
154
ConnectToRtpTransport_n()155 bool BaseChannel::ConnectToRtpTransport_n() {
156 RTC_DCHECK(rtp_transport_);
157 RTC_DCHECK(media_channel());
158
159 // We don't need to call OnDemuxerCriteriaUpdatePending/Complete because
160 // there's no previous criteria to worry about.
161 if (!rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this)) {
162 return false;
163 }
164 rtp_transport_->SignalReadyToSend.connect(
165 this, &BaseChannel::OnTransportReadyToSend);
166 rtp_transport_->SignalNetworkRouteChanged.connect(
167 this, &BaseChannel::OnNetworkRouteChanged);
168 rtp_transport_->SignalWritableState.connect(this,
169 &BaseChannel::OnWritableState);
170 rtp_transport_->SignalSentPacket.connect(this,
171 &BaseChannel::SignalSentPacket_n);
172 return true;
173 }
174
DisconnectFromRtpTransport_n()175 void BaseChannel::DisconnectFromRtpTransport_n() {
176 RTC_DCHECK(rtp_transport_);
177 RTC_DCHECK(media_channel());
178 rtp_transport_->UnregisterRtpDemuxerSink(this);
179 rtp_transport_->SignalReadyToSend.disconnect(this);
180 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
181 rtp_transport_->SignalWritableState.disconnect(this);
182 rtp_transport_->SignalSentPacket.disconnect(this);
183 rtp_transport_ = nullptr;
184 media_channel_->SetInterface(nullptr);
185 }
186
SetRtpTransport(webrtc::RtpTransportInternal * rtp_transport)187 bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
188 TRACE_EVENT0("webrtc", "BaseChannel::SetRtpTransport");
189 RTC_DCHECK_RUN_ON(network_thread());
190 if (rtp_transport == rtp_transport_) {
191 return true;
192 }
193
194 if (rtp_transport_) {
195 DisconnectFromRtpTransport_n();
196 // Clear the cached header extensions on the worker.
197 worker_thread_->PostTask(SafeTask(alive_, [this] {
198 RTC_DCHECK_RUN_ON(worker_thread());
199 rtp_header_extensions_.clear();
200 }));
201 }
202
203 rtp_transport_ = rtp_transport;
204 if (rtp_transport_) {
205 if (!ConnectToRtpTransport_n()) {
206 return false;
207 }
208
209 RTC_DCHECK(!media_channel_->HasNetworkInterface());
210 media_channel_->SetInterface(this);
211
212 media_channel_->OnReadyToSend(rtp_transport_->IsReadyToSend());
213 UpdateWritableState_n();
214
215 // Set the cached socket options.
216 for (const auto& pair : socket_options_) {
217 rtp_transport_->SetRtpOption(pair.first, pair.second);
218 }
219 if (!rtp_transport_->rtcp_mux_enabled()) {
220 for (const auto& pair : rtcp_socket_options_) {
221 rtp_transport_->SetRtcpOption(pair.first, pair.second);
222 }
223 }
224 }
225
226 return true;
227 }
228
Enable(bool enable)229 void BaseChannel::Enable(bool enable) {
230 RTC_DCHECK_RUN_ON(signaling_thread());
231
232 if (enable == enabled_s_)
233 return;
234
235 enabled_s_ = enable;
236
237 worker_thread_->PostTask(SafeTask(alive_, [this, enable] {
238 RTC_DCHECK_RUN_ON(worker_thread());
239 // Sanity check to make sure that enabled_ and enabled_s_
240 // stay in sync.
241 RTC_DCHECK_NE(enabled_, enable);
242 if (enable) {
243 EnableMedia_w();
244 } else {
245 DisableMedia_w();
246 }
247 }));
248 }
249
SetLocalContent(const MediaContentDescription * content,SdpType type,std::string & error_desc)250 bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
251 SdpType type,
252 std::string& error_desc) {
253 RTC_DCHECK_RUN_ON(worker_thread());
254 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
255 return SetLocalContent_w(content, type, error_desc);
256 }
257
SetRemoteContent(const MediaContentDescription * content,SdpType type,std::string & error_desc)258 bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
259 SdpType type,
260 std::string& error_desc) {
261 RTC_DCHECK_RUN_ON(worker_thread());
262 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
263 return SetRemoteContent_w(content, type, error_desc);
264 }
265
SetPayloadTypeDemuxingEnabled(bool enabled)266 bool BaseChannel::SetPayloadTypeDemuxingEnabled(bool enabled) {
267 // TODO(bugs.webrtc.org/11993): The demuxer state needs to be managed on the
268 // network thread. At the moment there's a workaround for inconsistent state
269 // between the worker and network thread because of this (see
270 // OnDemuxerCriteriaUpdatePending elsewhere in this file) and
271 // SetPayloadTypeDemuxingEnabled_w has a BlockingCall over to the network
272 // thread to apply state updates.
273 RTC_DCHECK_RUN_ON(worker_thread());
274 TRACE_EVENT0("webrtc", "BaseChannel::SetPayloadTypeDemuxingEnabled");
275 return SetPayloadTypeDemuxingEnabled_w(enabled);
276 }
277
IsReadyToSendMedia_w() const278 bool BaseChannel::IsReadyToSendMedia_w() const {
279 // Send outgoing data if we are enabled, have local and remote content,
280 // and we have had some form of connectivity.
281 return enabled_ &&
282 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
283 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
284 was_ever_writable_;
285 }
286
SendPacket(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)287 bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
288 const rtc::PacketOptions& options) {
289 return SendPacket(false, packet, options);
290 }
291
SendRtcp(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)292 bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
293 const rtc::PacketOptions& options) {
294 return SendPacket(true, packet, options);
295 }
296
SetOption(SocketType type,rtc::Socket::Option opt,int value)297 int BaseChannel::SetOption(SocketType type,
298 rtc::Socket::Option opt,
299 int value) {
300 RTC_DCHECK_RUN_ON(network_thread());
301 RTC_DCHECK(network_initialized());
302 RTC_DCHECK(rtp_transport_);
303 switch (type) {
304 case ST_RTP:
305 socket_options_.push_back(
306 std::pair<rtc::Socket::Option, int>(opt, value));
307 return rtp_transport_->SetRtpOption(opt, value);
308 case ST_RTCP:
309 rtcp_socket_options_.push_back(
310 std::pair<rtc::Socket::Option, int>(opt, value));
311 return rtp_transport_->SetRtcpOption(opt, value);
312 }
313 return -1;
314 }
315
OnWritableState(bool writable)316 void BaseChannel::OnWritableState(bool writable) {
317 RTC_DCHECK_RUN_ON(network_thread());
318 RTC_DCHECK(network_initialized());
319 if (writable) {
320 ChannelWritable_n();
321 } else {
322 ChannelNotWritable_n();
323 }
324 }
325
OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route)326 void BaseChannel::OnNetworkRouteChanged(
327 absl::optional<rtc::NetworkRoute> network_route) {
328 RTC_DCHECK_RUN_ON(network_thread());
329 RTC_DCHECK(network_initialized());
330
331 RTC_LOG(LS_INFO) << "Network route changed for " << ToString();
332
333 rtc::NetworkRoute new_route;
334 if (network_route) {
335 new_route = *(network_route);
336 }
337 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
338 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
339 // work correctly. Intentionally leave it broken to simplify the code and
340 // encourage the users to stop using non-muxing RTCP.
341 media_channel_->OnNetworkRouteChanged(transport_name(), new_route);
342 }
343
SetFirstPacketReceivedCallback(std::function<void ()> callback)344 void BaseChannel::SetFirstPacketReceivedCallback(
345 std::function<void()> callback) {
346 RTC_DCHECK_RUN_ON(network_thread());
347 RTC_DCHECK(!on_first_packet_received_ || !callback);
348
349 // TODO(bugs.webrtc.org/11992): Rename SetFirstPacketReceivedCallback to
350 // something that indicates network thread initialization/uninitialization and
351 // call Init_n() / Deinit_n() respectively.
352 // if (!callback)
353 // Deinit_n();
354
355 on_first_packet_received_ = std::move(callback);
356 }
357
OnTransportReadyToSend(bool ready)358 void BaseChannel::OnTransportReadyToSend(bool ready) {
359 RTC_DCHECK_RUN_ON(network_thread());
360 RTC_DCHECK(network_initialized());
361 media_channel_->OnReadyToSend(ready);
362 }
363
SendPacket(bool rtcp,rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)364 bool BaseChannel::SendPacket(bool rtcp,
365 rtc::CopyOnWriteBuffer* packet,
366 const rtc::PacketOptions& options) {
367 RTC_DCHECK_RUN_ON(network_thread());
368 RTC_DCHECK(network_initialized());
369 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
370
371 // Until all the code is migrated to use RtpPacketType instead of bool.
372 RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
373
374 // Ensure we have a place to send this packet before doing anything. We might
375 // get RTCP packets that we don't intend to send. If we've negotiated RTCP
376 // mux, send RTCP over the RTP transport.
377 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
378 return false;
379 }
380
381 // Protect ourselves against crazy data.
382 if (!IsValidRtpPacketSize(packet_type, packet->size())) {
383 RTC_LOG(LS_ERROR) << "Dropping outgoing " << ToString() << " "
384 << RtpPacketTypeToString(packet_type)
385 << " packet: wrong size=" << packet->size();
386 return false;
387 }
388
389 if (!srtp_active()) {
390 if (srtp_required_) {
391 // The audio/video engines may attempt to send RTCP packets as soon as the
392 // streams are created, so don't treat this as an error for RTCP.
393 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
394 // However, there shouldn't be any RTP packets sent before SRTP is set
395 // up (and SetSend(true) is called).
396 RTC_DCHECK(rtcp) << "Can't send outgoing RTP packet for " << ToString()
397 << " when SRTP is inactive and crypto is required";
398 return false;
399 }
400
401 RTC_DLOG(LS_WARNING) << "Sending an " << (rtcp ? "RTCP" : "RTP")
402 << " packet without encryption for " << ToString()
403 << ".";
404 }
405
406 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
407 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
408 }
409
OnRtpPacket(const webrtc::RtpPacketReceived & parsed_packet)410 void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
411 RTC_DCHECK_RUN_ON(network_thread());
412 RTC_DCHECK(network_initialized());
413
414 if (on_first_packet_received_) {
415 on_first_packet_received_();
416 on_first_packet_received_ = nullptr;
417 }
418
419 if (!srtp_active() && srtp_required_) {
420 // Our session description indicates that SRTP is required, but we got a
421 // packet before our SRTP filter is active. This means either that
422 // a) we got SRTP packets before we received the SDES keys, in which case
423 // we can't decrypt it anyway, or
424 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
425 // transports, so we haven't yet extracted keys, even if DTLS did
426 // complete on the transport that the packets are being sent on. It's
427 // really good practice to wait for both RTP and RTCP to be good to go
428 // before sending media, to prevent weird failure modes, so it's fine
429 // for us to just eat packets here. This is all sidestepped if RTCP mux
430 // is used anyway.
431 RTC_LOG(LS_WARNING) << "Can't process incoming RTP packet when "
432 "SRTP is inactive and crypto is required "
433 << ToString();
434 return;
435 }
436
437 webrtc::Timestamp packet_time = parsed_packet.arrival_time();
438 media_channel_->OnPacketReceived(
439 parsed_packet.Buffer(),
440 packet_time.IsMinusInfinity() ? -1 : packet_time.us());
441 }
442
MaybeUpdateDemuxerAndRtpExtensions_w(bool update_demuxer,absl::optional<RtpHeaderExtensions> extensions,std::string & error_desc)443 bool BaseChannel::MaybeUpdateDemuxerAndRtpExtensions_w(
444 bool update_demuxer,
445 absl::optional<RtpHeaderExtensions> extensions,
446 std::string& error_desc) {
447 if (extensions) {
448 if (rtp_header_extensions_ == extensions) {
449 extensions.reset(); // No need to update header extensions.
450 } else {
451 rtp_header_extensions_ = *extensions;
452 }
453 }
454
455 if (!update_demuxer && !extensions)
456 return true; // No update needed.
457
458 // TODO(bugs.webrtc.org/13536): See if we can do this asynchronously.
459
460 if (update_demuxer)
461 media_channel()->OnDemuxerCriteriaUpdatePending();
462
463 bool success = network_thread()->BlockingCall([&]() mutable {
464 RTC_DCHECK_RUN_ON(network_thread());
465 // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
466 // extension maps are not merged when BUNDLE is enabled. This is fine
467 // because the ID for MID should be consistent among all the RTP transports.
468 if (extensions)
469 rtp_transport_->UpdateRtpHeaderExtensionMap(*extensions);
470
471 if (!update_demuxer)
472 return true;
473
474 if (!rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this)) {
475 error_desc =
476 StringFormat("Failed to apply demuxer criteria for '%s': '%s'.",
477 mid().c_str(), demuxer_criteria_.ToString().c_str());
478 return false;
479 }
480 return true;
481 });
482
483 if (update_demuxer)
484 media_channel()->OnDemuxerCriteriaUpdateComplete();
485
486 return success;
487 }
488
RegisterRtpDemuxerSink_w()489 bool BaseChannel::RegisterRtpDemuxerSink_w() {
490 media_channel_->OnDemuxerCriteriaUpdatePending();
491 // Copy demuxer criteria, since they're a worker-thread variable
492 // and we want to pass them to the network thread
493 bool ret = network_thread_->BlockingCall(
494 [this, demuxer_criteria = demuxer_criteria_] {
495 RTC_DCHECK_RUN_ON(network_thread());
496 if (!rtp_transport_) {
497 // Transport was disconnected before attempting to update the
498 // criteria. This can happen while setting the remote description.
499 // See chromium:1295469 for an example.
500 return false;
501 }
502 // Note that RegisterRtpDemuxerSink first unregisters the sink if
503 // already registered. So this will change the state of the class
504 // whether the call succeeds or not.
505 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria, this);
506 });
507
508 media_channel_->OnDemuxerCriteriaUpdateComplete();
509
510 return ret;
511 }
512
EnableMedia_w()513 void BaseChannel::EnableMedia_w() {
514 if (enabled_)
515 return;
516
517 RTC_LOG(LS_INFO) << "Channel enabled: " << ToString();
518 enabled_ = true;
519 UpdateMediaSendRecvState_w();
520 }
521
DisableMedia_w()522 void BaseChannel::DisableMedia_w() {
523 if (!enabled_)
524 return;
525
526 RTC_LOG(LS_INFO) << "Channel disabled: " << ToString();
527 enabled_ = false;
528 UpdateMediaSendRecvState_w();
529 }
530
UpdateWritableState_n()531 void BaseChannel::UpdateWritableState_n() {
532 TRACE_EVENT0("webrtc", "BaseChannel::UpdateWritableState_n");
533 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
534 rtp_transport_->IsWritable(/*rtcp=*/false)) {
535 ChannelWritable_n();
536 } else {
537 ChannelNotWritable_n();
538 }
539 }
540
ChannelWritable_n()541 void BaseChannel::ChannelWritable_n() {
542 TRACE_EVENT0("webrtc", "BaseChannel::ChannelWritable_n");
543 if (writable_) {
544 return;
545 }
546 writable_ = true;
547 RTC_LOG(LS_INFO) << "Channel writable (" << ToString() << ")"
548 << (was_ever_writable_n_ ? "" : " for the first time");
549 // We only have to do this PostTask once, when first transitioning to
550 // writable.
551 if (!was_ever_writable_n_) {
552 worker_thread_->PostTask(SafeTask(alive_, [this] {
553 RTC_DCHECK_RUN_ON(worker_thread());
554 was_ever_writable_ = true;
555 UpdateMediaSendRecvState_w();
556 }));
557 }
558 was_ever_writable_n_ = true;
559 }
560
ChannelNotWritable_n()561 void BaseChannel::ChannelNotWritable_n() {
562 TRACE_EVENT0("webrtc", "BaseChannel::ChannelNotWritable_n");
563 if (!writable_) {
564 return;
565 }
566 writable_ = false;
567 RTC_LOG(LS_INFO) << "Channel not writable (" << ToString() << ")";
568 }
569
SetPayloadTypeDemuxingEnabled_w(bool enabled)570 bool BaseChannel::SetPayloadTypeDemuxingEnabled_w(bool enabled) {
571 RTC_LOG_THREAD_BLOCK_COUNT();
572
573 if (enabled == payload_type_demuxing_enabled_) {
574 return true;
575 }
576
577 payload_type_demuxing_enabled_ = enabled;
578
579 bool config_changed = false;
580
581 if (!enabled) {
582 // TODO(crbug.com/11477): This will remove *all* unsignaled streams (those
583 // without an explicitly signaled SSRC), which may include streams that
584 // were matched to this channel by MID or RID. Ideally we'd remove only the
585 // streams that were matched based on payload type alone, but currently
586 // there is no straightforward way to identify those streams.
587 media_channel()->ResetUnsignaledRecvStream();
588 if (!demuxer_criteria_.payload_types().empty()) {
589 config_changed = true;
590 demuxer_criteria_.payload_types().clear();
591 }
592 } else if (!payload_types_.empty()) {
593 for (const auto& type : payload_types_) {
594 if (demuxer_criteria_.payload_types().insert(type).second) {
595 config_changed = true;
596 }
597 }
598 } else {
599 RTC_DCHECK(demuxer_criteria_.payload_types().empty());
600 }
601
602 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
603
604 if (!config_changed)
605 return true;
606
607 // Note: This synchronously hops to the network thread.
608 return RegisterRtpDemuxerSink_w();
609 }
610
UpdateLocalStreams_w(const std::vector<StreamParams> & streams,SdpType type,std::string & error_desc)611 bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
612 SdpType type,
613 std::string& error_desc) {
614 // In the case of RIDs (where SSRCs are not negotiated), this method will
615 // generate an SSRC for each layer in StreamParams. That representation will
616 // be stored internally in `local_streams_`.
617 // In subsequent offers, the same stream can appear in `streams` again
618 // (without the SSRCs), so it should be looked up using RIDs (if available)
619 // and then by primary SSRC.
620 // In both scenarios, it is safe to assume that the media channel will be
621 // created with a StreamParams object with SSRCs. However, it is not safe to
622 // assume that `local_streams_` will always have SSRCs as there are scenarios
623 // in which niether SSRCs or RIDs are negotiated.
624
625 // Check for streams that have been removed.
626 bool ret = true;
627 for (const StreamParams& old_stream : local_streams_) {
628 if (!old_stream.has_ssrcs() ||
629 GetStream(streams, StreamFinder(&old_stream))) {
630 continue;
631 }
632 if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
633 error_desc = StringFormat(
634 "Failed to remove send stream with ssrc %u from m-section with "
635 "mid='%s'.",
636 old_stream.first_ssrc(), mid().c_str());
637 ret = false;
638 }
639 }
640 // Check for new streams.
641 std::vector<StreamParams> all_streams;
642 for (const StreamParams& stream : streams) {
643 StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
644 if (existing) {
645 // Parameters cannot change for an existing stream.
646 all_streams.push_back(*existing);
647 continue;
648 }
649
650 all_streams.push_back(stream);
651 StreamParams& new_stream = all_streams.back();
652
653 if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
654 continue;
655 }
656
657 RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
658 if (new_stream.has_ssrcs() && new_stream.has_rids()) {
659 error_desc = StringFormat(
660 "Failed to add send stream: %u into m-section with mid='%s'. Stream "
661 "has both SSRCs and RIDs.",
662 new_stream.first_ssrc(), mid().c_str());
663 ret = false;
664 continue;
665 }
666
667 // At this point we use the legacy simulcast group in StreamParams to
668 // indicate that we want multiple layers to the media channel.
669 if (!new_stream.has_ssrcs()) {
670 // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
671 new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
672 /* flex_fec = */ false, ssrc_generator_);
673 }
674
675 if (media_channel()->AddSendStream(new_stream)) {
676 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0]
677 << " into " << ToString();
678 } else {
679 error_desc = StringFormat(
680 "Failed to add send stream ssrc: %u into m-section with mid='%s'",
681 new_stream.first_ssrc(), mid().c_str());
682 ret = false;
683 }
684 }
685 local_streams_ = all_streams;
686 return ret;
687 }
688
UpdateRemoteStreams_w(const MediaContentDescription * content,SdpType type,std::string & error_desc)689 bool BaseChannel::UpdateRemoteStreams_w(const MediaContentDescription* content,
690 SdpType type,
691 std::string& error_desc) {
692 RTC_LOG_THREAD_BLOCK_COUNT();
693 bool needs_re_registration = false;
694 if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
695 RTC_DLOG(LS_VERBOSE) << "UpdateRemoteStreams_w: remote side will not send "
696 "- disable payload type demuxing for "
697 << ToString();
698 if (ClearHandledPayloadTypes()) {
699 needs_re_registration = payload_type_demuxing_enabled_;
700 }
701 }
702
703 const std::vector<StreamParams>& streams = content->streams();
704 const bool new_has_unsignaled_ssrcs = HasStreamWithNoSsrcs(streams);
705 const bool old_has_unsignaled_ssrcs = HasStreamWithNoSsrcs(remote_streams_);
706
707 // Check for streams that have been removed.
708 for (const StreamParams& old_stream : remote_streams_) {
709 // If we no longer have an unsignaled stream, we would like to remove
710 // the unsignaled stream params that are cached.
711 if (!old_stream.has_ssrcs() && !new_has_unsignaled_ssrcs) {
712 media_channel()->ResetUnsignaledRecvStream();
713 RTC_LOG(LS_INFO) << "Reset unsignaled remote stream for " << ToString()
714 << ".";
715 } else if (old_stream.has_ssrcs() &&
716 !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
717 if (media_channel()->RemoveRecvStream(old_stream.first_ssrc())) {
718 RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc()
719 << " from " << ToString() << ".";
720 } else {
721 error_desc = StringFormat(
722 "Failed to remove remote stream with ssrc %u from m-section with "
723 "mid='%s'.",
724 old_stream.first_ssrc(), mid().c_str());
725 return false;
726 }
727 }
728 }
729
730 // Check for new streams.
731 webrtc::flat_set<uint32_t> ssrcs;
732 for (const StreamParams& new_stream : streams) {
733 // We allow a StreamParams with an empty list of SSRCs, in which case the
734 // MediaChannel will cache the parameters and use them for any unsignaled
735 // stream received later.
736 if ((!new_stream.has_ssrcs() && !old_has_unsignaled_ssrcs) ||
737 !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
738 if (media_channel()->AddRecvStream(new_stream)) {
739 RTC_LOG(LS_INFO) << "Add remote ssrc: "
740 << (new_stream.has_ssrcs()
741 ? std::to_string(new_stream.first_ssrc())
742 : "unsignaled")
743 << " to " << ToString();
744 } else {
745 error_desc =
746 StringFormat("Failed to add remote stream ssrc: %s to %s",
747 new_stream.has_ssrcs()
748 ? std::to_string(new_stream.first_ssrc()).c_str()
749 : "unsignaled",
750 ToString().c_str());
751 return false;
752 }
753 }
754 // Update the receiving SSRCs.
755 ssrcs.insert(new_stream.ssrcs.begin(), new_stream.ssrcs.end());
756 }
757
758 if (demuxer_criteria_.ssrcs() != ssrcs) {
759 demuxer_criteria_.ssrcs() = std::move(ssrcs);
760 needs_re_registration = true;
761 }
762
763 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
764
765 // Re-register the sink to update after changing the demuxer criteria.
766 if (needs_re_registration && !RegisterRtpDemuxerSink_w()) {
767 error_desc = StringFormat("Failed to set up audio demuxing for mid='%s'.",
768 mid().c_str());
769 return false;
770 }
771
772 remote_streams_ = streams;
773
774 set_remote_content_direction(content->direction());
775 UpdateMediaSendRecvState_w();
776
777 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1);
778
779 return true;
780 }
781
GetDeduplicatedRtpHeaderExtensions(const RtpHeaderExtensions & extensions)782 RtpHeaderExtensions BaseChannel::GetDeduplicatedRtpHeaderExtensions(
783 const RtpHeaderExtensions& extensions) {
784 return webrtc::RtpExtension::DeduplicateHeaderExtensions(extensions,
785 extensions_filter_);
786 }
787
MaybeAddHandledPayloadType(int payload_type)788 bool BaseChannel::MaybeAddHandledPayloadType(int payload_type) {
789 bool demuxer_criteria_modified = false;
790 if (payload_type_demuxing_enabled_) {
791 demuxer_criteria_modified = demuxer_criteria_.payload_types()
792 .insert(static_cast<uint8_t>(payload_type))
793 .second;
794 }
795 // Even if payload type demuxing is currently disabled, we need to remember
796 // the payload types in case it's re-enabled later.
797 payload_types_.insert(static_cast<uint8_t>(payload_type));
798 return demuxer_criteria_modified;
799 }
800
ClearHandledPayloadTypes()801 bool BaseChannel::ClearHandledPayloadTypes() {
802 const bool was_empty = demuxer_criteria_.payload_types().empty();
803 demuxer_criteria_.payload_types().clear();
804 payload_types_.clear();
805 return !was_empty;
806 }
807
SignalSentPacket_n(const rtc::SentPacket & sent_packet)808 void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
809 RTC_DCHECK_RUN_ON(network_thread());
810 RTC_DCHECK(network_initialized());
811 media_channel()->OnPacketSent(sent_packet);
812 }
813
VoiceChannel(rtc::Thread * worker_thread,rtc::Thread * network_thread,rtc::Thread * signaling_thread,std::unique_ptr<VoiceMediaChannel> media_channel,absl::string_view mid,bool srtp_required,webrtc::CryptoOptions crypto_options,UniqueRandomIdGenerator * ssrc_generator)814 VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
815 rtc::Thread* network_thread,
816 rtc::Thread* signaling_thread,
817 std::unique_ptr<VoiceMediaChannel> media_channel,
818 absl::string_view mid,
819 bool srtp_required,
820 webrtc::CryptoOptions crypto_options,
821 UniqueRandomIdGenerator* ssrc_generator)
822 : BaseChannel(worker_thread,
823 network_thread,
824 signaling_thread,
825 std::move(media_channel),
826 mid,
827 srtp_required,
828 crypto_options,
829 ssrc_generator) {}
830
~VoiceChannel()831 VoiceChannel::~VoiceChannel() {
832 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
833 // this can't be done in the base class, since it calls a virtual
834 DisableMedia_w();
835 }
836
UpdateMediaSendRecvState_w()837 void VoiceChannel::UpdateMediaSendRecvState_w() {
838 // Render incoming data if we're the active call, and we have the local
839 // content. We receive data on the default channel and multiplexed streams.
840 bool ready_to_receive = enabled() && webrtc::RtpTransceiverDirectionHasRecv(
841 local_content_direction());
842 media_channel()->SetPlayout(ready_to_receive);
843
844 // Send outgoing data if we're the active call, we have the remote content,
845 // and we have had some form of connectivity.
846 bool send = IsReadyToSendMedia_w();
847 media_channel()->SetSend(send);
848
849 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << ready_to_receive
850 << " send=" << send << " for " << ToString();
851 }
852
SetLocalContent_w(const MediaContentDescription * content,SdpType type,std::string & error_desc)853 bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
854 SdpType type,
855 std::string& error_desc) {
856 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
857 RTC_DLOG(LS_INFO) << "Setting local voice description for " << ToString();
858
859 RTC_LOG_THREAD_BLOCK_COUNT();
860
861 RtpHeaderExtensions header_extensions =
862 GetDeduplicatedRtpHeaderExtensions(content->rtp_header_extensions());
863 bool update_header_extensions = true;
864 media_channel()->SetExtmapAllowMixed(content->extmap_allow_mixed());
865
866 AudioRecvParameters recv_params = last_recv_params_;
867 RtpParametersFromMediaDescription(
868 content->as_audio(), header_extensions,
869 webrtc::RtpTransceiverDirectionHasRecv(content->direction()),
870 &recv_params);
871
872 if (!media_channel()->SetRecvParameters(recv_params)) {
873 error_desc = StringFormat(
874 "Failed to set local audio description recv parameters for m-section "
875 "with mid='%s'.",
876 mid().c_str());
877 return false;
878 }
879
880 bool criteria_modified = false;
881 if (webrtc::RtpTransceiverDirectionHasRecv(content->direction())) {
882 for (const AudioCodec& codec : content->as_audio()->codecs()) {
883 if (MaybeAddHandledPayloadType(codec.id)) {
884 criteria_modified = true;
885 }
886 }
887 }
888
889 last_recv_params_ = recv_params;
890
891 if (!UpdateLocalStreams_w(content->as_audio()->streams(), type, error_desc)) {
892 RTC_DCHECK(!error_desc.empty());
893 return false;
894 }
895
896 set_local_content_direction(content->direction());
897 UpdateMediaSendRecvState_w();
898
899 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
900
901 bool success = MaybeUpdateDemuxerAndRtpExtensions_w(
902 criteria_modified,
903 update_header_extensions
904 ? absl::optional<RtpHeaderExtensions>(std::move(header_extensions))
905 : absl::nullopt,
906 error_desc);
907
908 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1);
909
910 return success;
911 }
912
SetRemoteContent_w(const MediaContentDescription * content,SdpType type,std::string & error_desc)913 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
914 SdpType type,
915 std::string& error_desc) {
916 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
917 RTC_LOG(LS_INFO) << "Setting remote voice description for " << ToString();
918
919 AudioSendParameters send_params = last_send_params_;
920 RtpSendParametersFromMediaDescription(content->as_audio(),
921 extensions_filter(), &send_params);
922 send_params.mid = mid();
923
924 bool parameters_applied = media_channel()->SetSendParameters(send_params);
925 if (!parameters_applied) {
926 error_desc = StringFormat(
927 "Failed to set remote audio description send parameters for m-section "
928 "with mid='%s'.",
929 mid().c_str());
930 return false;
931 }
932 last_send_params_ = send_params;
933
934 return UpdateRemoteStreams_w(content, type, error_desc);
935 }
936
VideoChannel(rtc::Thread * worker_thread,rtc::Thread * network_thread,rtc::Thread * signaling_thread,std::unique_ptr<VideoMediaChannel> media_channel,absl::string_view mid,bool srtp_required,webrtc::CryptoOptions crypto_options,UniqueRandomIdGenerator * ssrc_generator)937 VideoChannel::VideoChannel(rtc::Thread* worker_thread,
938 rtc::Thread* network_thread,
939 rtc::Thread* signaling_thread,
940 std::unique_ptr<VideoMediaChannel> media_channel,
941 absl::string_view mid,
942 bool srtp_required,
943 webrtc::CryptoOptions crypto_options,
944 UniqueRandomIdGenerator* ssrc_generator)
945 : BaseChannel(worker_thread,
946 network_thread,
947 signaling_thread,
948 std::move(media_channel),
949 mid,
950 srtp_required,
951 crypto_options,
952 ssrc_generator) {}
953
~VideoChannel()954 VideoChannel::~VideoChannel() {
955 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
956 // this can't be done in the base class, since it calls a virtual
957 DisableMedia_w();
958 }
959
UpdateMediaSendRecvState_w()960 void VideoChannel::UpdateMediaSendRecvState_w() {
961 // Send outgoing data if we're the active call, we have the remote content,
962 // and we have had some form of connectivity.
963 bool send = IsReadyToSendMedia_w();
964 media_channel()->SetSend(send);
965 RTC_LOG(LS_INFO) << "Changing video state, send=" << send << " for "
966 << ToString();
967 }
968
SetLocalContent_w(const MediaContentDescription * content,SdpType type,std::string & error_desc)969 bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
970 SdpType type,
971 std::string& error_desc) {
972 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
973 RTC_DLOG(LS_INFO) << "Setting local video description for " << ToString();
974
975 RTC_LOG_THREAD_BLOCK_COUNT();
976
977 RtpHeaderExtensions header_extensions =
978 GetDeduplicatedRtpHeaderExtensions(content->rtp_header_extensions());
979 bool update_header_extensions = true;
980 media_channel()->SetExtmapAllowMixed(content->extmap_allow_mixed());
981
982 VideoRecvParameters recv_params = last_recv_params_;
983
984 RtpParametersFromMediaDescription(
985 content->as_video(), header_extensions,
986 webrtc::RtpTransceiverDirectionHasRecv(content->direction()),
987 &recv_params);
988
989 VideoSendParameters send_params = last_send_params_;
990
991 bool needs_send_params_update = false;
992 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
993 for (auto& send_codec : send_params.codecs) {
994 auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
995 if (recv_codec) {
996 if (!recv_codec->packetization && send_codec.packetization) {
997 send_codec.packetization.reset();
998 needs_send_params_update = true;
999 } else if (recv_codec->packetization != send_codec.packetization) {
1000 error_desc = StringFormat(
1001 "Failed to set local answer due to invalid codec packetization "
1002 "specified in m-section with mid='%s'.",
1003 mid().c_str());
1004 return false;
1005 }
1006 }
1007 }
1008 }
1009
1010 if (!media_channel()->SetRecvParameters(recv_params)) {
1011 error_desc = StringFormat(
1012 "Failed to set local video description recv parameters for m-section "
1013 "with mid='%s'.",
1014 mid().c_str());
1015 return false;
1016 }
1017
1018 bool criteria_modified = false;
1019 if (webrtc::RtpTransceiverDirectionHasRecv(content->direction())) {
1020 for (const VideoCodec& codec : content->as_video()->codecs()) {
1021 if (MaybeAddHandledPayloadType(codec.id))
1022 criteria_modified = true;
1023 }
1024 }
1025
1026 last_recv_params_ = recv_params;
1027
1028 if (needs_send_params_update) {
1029 if (!media_channel()->SetSendParameters(send_params)) {
1030 error_desc = StringFormat(
1031 "Failed to set send parameters for m-section with mid='%s'.",
1032 mid().c_str());
1033 return false;
1034 }
1035 last_send_params_ = send_params;
1036 }
1037
1038 if (!UpdateLocalStreams_w(content->as_video()->streams(), type, error_desc)) {
1039 RTC_DCHECK(!error_desc.empty());
1040 return false;
1041 }
1042
1043 set_local_content_direction(content->direction());
1044 UpdateMediaSendRecvState_w();
1045
1046 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
1047
1048 bool success = MaybeUpdateDemuxerAndRtpExtensions_w(
1049 criteria_modified,
1050 update_header_extensions
1051 ? absl::optional<RtpHeaderExtensions>(std::move(header_extensions))
1052 : absl::nullopt,
1053 error_desc);
1054
1055 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1);
1056
1057 return success;
1058 }
1059
SetRemoteContent_w(const MediaContentDescription * content,SdpType type,std::string & error_desc)1060 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
1061 SdpType type,
1062 std::string& error_desc) {
1063 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
1064 RTC_LOG(LS_INFO) << "Setting remote video description for " << ToString();
1065
1066 const VideoContentDescription* video = content->as_video();
1067
1068 VideoSendParameters send_params = last_send_params_;
1069 RtpSendParametersFromMediaDescription(video, extensions_filter(),
1070 &send_params);
1071 send_params.mid = mid();
1072 send_params.conference_mode = video->conference_mode();
1073
1074 VideoRecvParameters recv_params = last_recv_params_;
1075
1076 bool needs_recv_params_update = false;
1077 if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
1078 for (auto& recv_codec : recv_params.codecs) {
1079 auto* send_codec = FindMatchingCodec(send_params.codecs, recv_codec);
1080 if (send_codec) {
1081 if (!send_codec->packetization && recv_codec.packetization) {
1082 recv_codec.packetization.reset();
1083 needs_recv_params_update = true;
1084 } else if (send_codec->packetization != recv_codec.packetization) {
1085 error_desc = StringFormat(
1086 "Failed to set remote answer due to invalid codec packetization "
1087 "specifid in m-section with mid='%s'.",
1088 mid().c_str());
1089 return false;
1090 }
1091 }
1092 }
1093 }
1094
1095 if (!media_channel()->SetSendParameters(send_params)) {
1096 error_desc = StringFormat(
1097 "Failed to set remote video description send parameters for m-section "
1098 "with mid='%s'.",
1099 mid().c_str());
1100 return false;
1101 }
1102 last_send_params_ = send_params;
1103
1104 if (needs_recv_params_update) {
1105 if (!media_channel()->SetRecvParameters(recv_params)) {
1106 error_desc = StringFormat(
1107 "Failed to set recv parameters for m-section with mid='%s'.",
1108 mid().c_str());
1109 return false;
1110 }
1111 last_recv_params_ = recv_params;
1112 }
1113
1114 return UpdateRemoteStreams_w(content, type, error_desc);
1115 }
1116
1117 } // namespace cricket
1118