xref: /aosp_15_r20/external/webrtc/pc/channel.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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