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 <iterator>
14 #include <utility>
15 
16 #include "absl/algorithm/container.h"
17 #include "absl/memory/memory.h"
18 #include "api/call/audio_sink.h"
19 #include "media/base/media_constants.h"
20 #include "media/base/rtp_utils.h"
21 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
22 #include "p2p/base/packet_transport_internal.h"
23 #include "pc/channel_manager.h"
24 #include "pc/rtp_media_utils.h"
25 #include "rtc_base/bind.h"
26 #include "rtc_base/byte_order.h"
27 #include "rtc_base/checks.h"
28 #include "rtc_base/copy_on_write_buffer.h"
29 #include "rtc_base/dscp.h"
30 #include "rtc_base/logging.h"
31 #include "rtc_base/network_route.h"
32 #include "rtc_base/strings/string_builder.h"
33 #include "rtc_base/synchronization/sequence_checker.h"
34 #include "rtc_base/trace_event.h"
35 
36 namespace cricket {
37 using rtc::Bind;
38 using rtc::UniqueRandomIdGenerator;
39 using webrtc::SdpType;
40 
41 namespace {
42 
43 struct SendPacketMessageData : public rtc::MessageData {
44   rtc::CopyOnWriteBuffer packet;
45   rtc::PacketOptions options;
46 };
47 
48 // Finds a stream based on target's Primary SSRC or RIDs.
49 // This struct is used in BaseChannel::UpdateLocalStreams_w.
50 struct StreamFinder {
StreamFindercricket::__anon5c1716e30111::StreamFinder51   explicit StreamFinder(const StreamParams* target) : target_(target) {
52     RTC_DCHECK(target);
53   }
54 
operator ()cricket::__anon5c1716e30111::StreamFinder55   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 
81 }  // namespace
82 
83 enum {
84   MSG_SEND_RTP_PACKET = 1,
85   MSG_SEND_RTCP_PACKET,
86   MSG_READYTOSENDDATA,
87   MSG_DATARECEIVED,
88   MSG_FIRSTPACKETRECEIVED,
89 };
90 
SafeSetError(const std::string & message,std::string * error_desc)91 static void SafeSetError(const std::string& message, std::string* error_desc) {
92   if (error_desc) {
93     *error_desc = message;
94   }
95 }
96 
97 template <class Codec>
RtpParametersFromMediaDescription(const MediaContentDescriptionImpl<Codec> * desc,const RtpHeaderExtensions & extensions,bool is_stream_active,RtpParameters<Codec> * params)98 void RtpParametersFromMediaDescription(
99     const MediaContentDescriptionImpl<Codec>* desc,
100     const RtpHeaderExtensions& extensions,
101     bool is_stream_active,
102     RtpParameters<Codec>* params) {
103   params->is_stream_active = is_stream_active;
104   params->codecs = desc->codecs();
105   // TODO(bugs.webrtc.org/11513): See if we really need
106   // rtp_header_extensions_set() and remove it if we don't.
107   if (desc->rtp_header_extensions_set()) {
108     params->extensions = extensions;
109   }
110   params->rtcp.reduced_size = desc->rtcp_reduced_size();
111   params->rtcp.remote_estimate = desc->remote_estimate();
112 }
113 
114 template <class Codec>
RtpSendParametersFromMediaDescription(const MediaContentDescriptionImpl<Codec> * desc,const RtpHeaderExtensions & extensions,bool is_stream_active,RtpSendParameters<Codec> * send_params)115 void RtpSendParametersFromMediaDescription(
116     const MediaContentDescriptionImpl<Codec>* desc,
117     const RtpHeaderExtensions& extensions,
118     bool is_stream_active,
119     RtpSendParameters<Codec>* send_params) {
120   RtpParametersFromMediaDescription(desc, extensions, is_stream_active,
121                                     send_params);
122   send_params->max_bandwidth_bps = desc->bandwidth();
123   send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
124 }
125 
BaseChannel(rtc::Thread * worker_thread,rtc::Thread * network_thread,rtc::Thread * signaling_thread,std::unique_ptr<MediaChannel> media_channel,const std::string & content_name,bool srtp_required,webrtc::CryptoOptions crypto_options,UniqueRandomIdGenerator * ssrc_generator)126 BaseChannel::BaseChannel(rtc::Thread* worker_thread,
127                          rtc::Thread* network_thread,
128                          rtc::Thread* signaling_thread,
129                          std::unique_ptr<MediaChannel> media_channel,
130                          const std::string& content_name,
131                          bool srtp_required,
132                          webrtc::CryptoOptions crypto_options,
133                          UniqueRandomIdGenerator* ssrc_generator)
134     : worker_thread_(worker_thread),
135       network_thread_(network_thread),
136       signaling_thread_(signaling_thread),
137       content_name_(content_name),
138       srtp_required_(srtp_required),
139       crypto_options_(crypto_options),
140       media_channel_(std::move(media_channel)),
141       ssrc_generator_(ssrc_generator) {
142   RTC_DCHECK_RUN_ON(worker_thread_);
143   RTC_DCHECK(ssrc_generator_);
144   demuxer_criteria_.mid = content_name;
145   RTC_LOG(LS_INFO) << "Created channel: " << ToString();
146 }
147 
~BaseChannel()148 BaseChannel::~BaseChannel() {
149   TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
150   RTC_DCHECK_RUN_ON(worker_thread_);
151 
152   // Eats any outstanding messages or packets.
153   worker_thread_->Clear(&invoker_);
154   worker_thread_->Clear(this);
155   // We must destroy the media channel before the transport channel, otherwise
156   // the media channel may try to send on the dead transport channel. NULLing
157   // is not an effective strategy since the sends will come on another thread.
158   media_channel_.reset();
159   RTC_LOG(LS_INFO) << "Destroyed channel: " << ToString();
160 }
161 
ToString() const162 std::string BaseChannel::ToString() const {
163   rtc::StringBuilder sb;
164   sb << "{mid: " << content_name_;
165   if (media_channel_) {
166     sb << ", media_type: " << MediaTypeToString(media_channel_->media_type());
167   }
168   sb << "}";
169   return sb.Release();
170 }
171 
ConnectToRtpTransport()172 bool BaseChannel::ConnectToRtpTransport() {
173   RTC_DCHECK(rtp_transport_);
174   if (!RegisterRtpDemuxerSink()) {
175     RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString();
176     return false;
177   }
178   rtp_transport_->SignalReadyToSend.connect(
179       this, &BaseChannel::OnTransportReadyToSend);
180   rtp_transport_->SignalNetworkRouteChanged.connect(
181       this, &BaseChannel::OnNetworkRouteChanged);
182   rtp_transport_->SignalWritableState.connect(this,
183                                               &BaseChannel::OnWritableState);
184   rtp_transport_->SignalSentPacket.connect(this,
185                                            &BaseChannel::SignalSentPacket_n);
186   return true;
187 }
188 
DisconnectFromRtpTransport()189 void BaseChannel::DisconnectFromRtpTransport() {
190   RTC_DCHECK(rtp_transport_);
191   rtp_transport_->UnregisterRtpDemuxerSink(this);
192   rtp_transport_->SignalReadyToSend.disconnect(this);
193   rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
194   rtp_transport_->SignalWritableState.disconnect(this);
195   rtp_transport_->SignalSentPacket.disconnect(this);
196 }
197 
Init_w(webrtc::RtpTransportInternal * rtp_transport)198 void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
199   RTC_DCHECK_RUN_ON(worker_thread_);
200 
201   network_thread_->Invoke<void>(
202       RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
203 
204   // Both RTP and RTCP channels should be set, we can call SetInterface on
205   // the media channel and it can set network options.
206   media_channel_->SetInterface(this);
207 }
208 
Deinit()209 void BaseChannel::Deinit() {
210   RTC_DCHECK_RUN_ON(worker_thread());
211   media_channel_->SetInterface(/*iface=*/nullptr);
212   // Packets arrive on the network thread, processing packets calls virtual
213   // functions, so need to stop this process in Deinit that is called in
214   // derived classes destructor.
215   network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
216     FlushRtcpMessages_n();
217 
218     if (rtp_transport_) {
219       DisconnectFromRtpTransport();
220     }
221     // Clear pending read packets/messages.
222     network_thread_->Clear(&invoker_);
223     network_thread_->Clear(this);
224   });
225 }
226 
SetRtpTransport(webrtc::RtpTransportInternal * rtp_transport)227 bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
228   if (rtp_transport == rtp_transport_) {
229     return true;
230   }
231 
232   if (!network_thread_->IsCurrent()) {
233     return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this, rtp_transport] {
234       return SetRtpTransport(rtp_transport);
235     });
236   }
237 
238   if (rtp_transport_) {
239     DisconnectFromRtpTransport();
240   }
241 
242   rtp_transport_ = rtp_transport;
243   if (rtp_transport_) {
244     transport_name_ = rtp_transport_->transport_name();
245 
246     if (!ConnectToRtpTransport()) {
247       RTC_LOG(LS_ERROR) << "Failed to connect to the new RtpTransport for "
248                         << ToString() << ".";
249       return false;
250     }
251     OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
252     UpdateWritableState_n();
253 
254     // Set the cached socket options.
255     for (const auto& pair : socket_options_) {
256       rtp_transport_->SetRtpOption(pair.first, pair.second);
257     }
258     if (!rtp_transport_->rtcp_mux_enabled()) {
259       for (const auto& pair : rtcp_socket_options_) {
260         rtp_transport_->SetRtcpOption(pair.first, pair.second);
261       }
262     }
263   }
264   return true;
265 }
266 
Enable(bool enable)267 bool BaseChannel::Enable(bool enable) {
268   worker_thread_->Invoke<void>(
269       RTC_FROM_HERE,
270       Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
271            this));
272   return true;
273 }
274 
SetLocalContent(const MediaContentDescription * content,SdpType type,std::string * error_desc)275 bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
276                                   SdpType type,
277                                   std::string* error_desc) {
278   TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
279   return InvokeOnWorker<bool>(
280       RTC_FROM_HERE,
281       Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
282 }
283 
SetRemoteContent(const MediaContentDescription * content,SdpType type,std::string * error_desc)284 bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
285                                    SdpType type,
286                                    std::string* error_desc) {
287   TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
288   return InvokeOnWorker<bool>(
289       RTC_FROM_HERE,
290       Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
291 }
292 
SetPayloadTypeDemuxingEnabled(bool enabled)293 bool BaseChannel::SetPayloadTypeDemuxingEnabled(bool enabled) {
294   TRACE_EVENT0("webrtc", "BaseChannel::SetPayloadTypeDemuxingEnabled");
295   return InvokeOnWorker<bool>(
296       RTC_FROM_HERE,
297       Bind(&BaseChannel::SetPayloadTypeDemuxingEnabled_w, this, enabled));
298 }
299 
IsReadyToReceiveMedia_w() const300 bool BaseChannel::IsReadyToReceiveMedia_w() const {
301   // Receive data if we are enabled and have local content,
302   return enabled() &&
303          webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
304 }
305 
IsReadyToSendMedia_w() const306 bool BaseChannel::IsReadyToSendMedia_w() const {
307   // Need to access some state updated on the network thread.
308   return network_thread_->Invoke<bool>(
309       RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
310 }
311 
IsReadyToSendMedia_n() const312 bool BaseChannel::IsReadyToSendMedia_n() const {
313   // Send outgoing data if we are enabled, have local and remote content,
314   // and we have had some form of connectivity.
315   return enabled() &&
316          webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
317          webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
318          was_ever_writable();
319 }
320 
SendPacket(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)321 bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
322                              const rtc::PacketOptions& options) {
323   return SendPacket(false, packet, options);
324 }
325 
SendRtcp(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)326 bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
327                            const rtc::PacketOptions& options) {
328   return SendPacket(true, packet, options);
329 }
330 
SetOption(SocketType type,rtc::Socket::Option opt,int value)331 int BaseChannel::SetOption(SocketType type,
332                            rtc::Socket::Option opt,
333                            int value) {
334   return network_thread_->Invoke<int>(
335       RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
336 }
337 
SetOption_n(SocketType type,rtc::Socket::Option opt,int value)338 int BaseChannel::SetOption_n(SocketType type,
339                              rtc::Socket::Option opt,
340                              int value) {
341   RTC_DCHECK_RUN_ON(network_thread());
342   RTC_DCHECK(rtp_transport_);
343   switch (type) {
344     case ST_RTP:
345       socket_options_.push_back(
346           std::pair<rtc::Socket::Option, int>(opt, value));
347       return rtp_transport_->SetRtpOption(opt, value);
348     case ST_RTCP:
349       rtcp_socket_options_.push_back(
350           std::pair<rtc::Socket::Option, int>(opt, value));
351       return rtp_transport_->SetRtcpOption(opt, value);
352   }
353   return -1;
354 }
355 
OnWritableState(bool writable)356 void BaseChannel::OnWritableState(bool writable) {
357   RTC_DCHECK_RUN_ON(network_thread());
358   if (writable) {
359     ChannelWritable_n();
360   } else {
361     ChannelNotWritable_n();
362   }
363 }
364 
OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route)365 void BaseChannel::OnNetworkRouteChanged(
366     absl::optional<rtc::NetworkRoute> network_route) {
367   RTC_LOG(LS_INFO) << "Network route for " << ToString() << " was changed.";
368 
369   RTC_DCHECK_RUN_ON(network_thread());
370   rtc::NetworkRoute new_route;
371   if (network_route) {
372     new_route = *(network_route);
373   }
374   // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
375   // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
376   // work correctly. Intentionally leave it broken to simplify the code and
377   // encourage the users to stop using non-muxing RTCP.
378   invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
379     media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
380   });
381 }
382 
SignalFirstPacketReceived()383 sigslot::signal1<ChannelInterface*>& BaseChannel::SignalFirstPacketReceived() {
384   RTC_DCHECK_RUN_ON(signaling_thread_);
385   return SignalFirstPacketReceived_;
386 }
387 
SignalSentPacket()388 sigslot::signal1<const rtc::SentPacket&>& BaseChannel::SignalSentPacket() {
389   // TODO(bugs.webrtc.org/11994): Uncomment this check once callers have been
390   // fixed to access this variable from the correct thread.
391   // RTC_DCHECK_RUN_ON(worker_thread_);
392   return SignalSentPacket_;
393 }
394 
OnTransportReadyToSend(bool ready)395 void BaseChannel::OnTransportReadyToSend(bool ready) {
396   invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
397                              [=] { media_channel_->OnReadyToSend(ready); });
398 }
399 
SendPacket(bool rtcp,rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)400 bool BaseChannel::SendPacket(bool rtcp,
401                              rtc::CopyOnWriteBuffer* packet,
402                              const rtc::PacketOptions& options) {
403   // Until all the code is migrated to use RtpPacketType instead of bool.
404   RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
405   // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
406   // If the thread is not our network thread, we will post to our network
407   // so that the real work happens on our network. This avoids us having to
408   // synchronize access to all the pieces of the send path, including
409   // SRTP and the inner workings of the transport channels.
410   // The only downside is that we can't return a proper failure code if
411   // needed. Since UDP is unreliable anyway, this should be a non-issue.
412   if (!network_thread_->IsCurrent()) {
413     // Avoid a copy by transferring the ownership of the packet data.
414     int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
415     SendPacketMessageData* data = new SendPacketMessageData;
416     data->packet = std::move(*packet);
417     data->options = options;
418     network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
419     return true;
420   }
421 
422   TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
423 
424   // Now that we are on the correct thread, ensure we have a place to send this
425   // packet before doing anything. (We might get RTCP packets that we don't
426   // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
427   // transport.
428   if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
429     return false;
430   }
431 
432   // Protect ourselves against crazy data.
433   if (!IsValidRtpPacketSize(packet_type, packet->size())) {
434     RTC_LOG(LS_ERROR) << "Dropping outgoing " << ToString() << " "
435                       << RtpPacketTypeToString(packet_type)
436                       << " packet: wrong size=" << packet->size();
437     return false;
438   }
439 
440   if (!srtp_active()) {
441     if (srtp_required_) {
442       // The audio/video engines may attempt to send RTCP packets as soon as the
443       // streams are created, so don't treat this as an error for RTCP.
444       // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
445       if (rtcp) {
446         return false;
447       }
448       // However, there shouldn't be any RTP packets sent before SRTP is set up
449       // (and SetSend(true) is called).
450       RTC_LOG(LS_ERROR) << "Can't send outgoing RTP packet for " << ToString()
451                         << " when SRTP is inactive and crypto is required";
452       RTC_NOTREACHED();
453       return false;
454     }
455 
456     std::string packet_type = rtcp ? "RTCP" : "RTP";
457     RTC_DLOG(LS_WARNING) << "Sending an " << packet_type
458                          << " packet without encryption for " << ToString()
459                          << ".";
460   }
461 
462   // Bon voyage.
463   return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
464               : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
465 }
466 
OnRtpPacket(const webrtc::RtpPacketReceived & parsed_packet)467 void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
468   // Take packet time from the |parsed_packet|.
469   // RtpPacketReceived.arrival_time_ms = (timestamp_us + 500) / 1000;
470   int64_t packet_time_us = -1;
471   if (parsed_packet.arrival_time_ms() > 0) {
472     packet_time_us = parsed_packet.arrival_time_ms() * 1000;
473   }
474 
475   if (!has_received_packet_) {
476     has_received_packet_ = true;
477     signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
478   }
479 
480   if (!srtp_active() && srtp_required_) {
481     // Our session description indicates that SRTP is required, but we got a
482     // packet before our SRTP filter is active. This means either that
483     // a) we got SRTP packets before we received the SDES keys, in which case
484     //    we can't decrypt it anyway, or
485     // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
486     //    transports, so we haven't yet extracted keys, even if DTLS did
487     //    complete on the transport that the packets are being sent on. It's
488     //    really good practice to wait for both RTP and RTCP to be good to go
489     //    before sending  media, to prevent weird failure modes, so it's fine
490     //    for us to just eat packets here. This is all sidestepped if RTCP mux
491     //    is used anyway.
492     RTC_LOG(LS_WARNING) << "Can't process incoming RTP packet when "
493                            "SRTP is inactive and crypto is required "
494                         << ToString();
495     return;
496   }
497 
498   auto packet_buffer = parsed_packet.Buffer();
499 
500   invoker_.AsyncInvoke<void>(
501       RTC_FROM_HERE, worker_thread_, [this, packet_buffer, packet_time_us] {
502         RTC_DCHECK_RUN_ON(worker_thread());
503         media_channel_->OnPacketReceived(packet_buffer, packet_time_us);
504       });
505 }
506 
UpdateRtpHeaderExtensionMap(const RtpHeaderExtensions & header_extensions)507 void BaseChannel::UpdateRtpHeaderExtensionMap(
508     const RtpHeaderExtensions& header_extensions) {
509   RTC_DCHECK(rtp_transport_);
510   // Update the header extension map on network thread in case there is data
511   // race.
512   // TODO(zhihuang): Add an rtc::ThreadChecker make sure to RtpTransport won't
513   // be accessed from different threads.
514   //
515   // NOTE: This doesn't take the BUNDLE case in account meaning the RTP header
516   // extension maps are not merged when BUNDLE is enabled. This is fine because
517   // the ID for MID should be consistent among all the RTP transports.
518   network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &header_extensions] {
519     rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
520   });
521 }
522 
RegisterRtpDemuxerSink()523 bool BaseChannel::RegisterRtpDemuxerSink() {
524   RTC_DCHECK(rtp_transport_);
525   return network_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
526     return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
527   });
528 }
529 
EnableMedia_w()530 void BaseChannel::EnableMedia_w() {
531   RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
532   if (enabled_)
533     return;
534 
535   RTC_LOG(LS_INFO) << "Channel enabled: " << ToString();
536   enabled_ = true;
537   UpdateMediaSendRecvState_w();
538 }
539 
DisableMedia_w()540 void BaseChannel::DisableMedia_w() {
541   RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
542   if (!enabled_)
543     return;
544 
545   RTC_LOG(LS_INFO) << "Channel disabled: " << ToString();
546   enabled_ = false;
547   UpdateMediaSendRecvState_w();
548 }
549 
UpdateWritableState_n()550 void BaseChannel::UpdateWritableState_n() {
551   if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
552       rtp_transport_->IsWritable(/*rtcp=*/false)) {
553     ChannelWritable_n();
554   } else {
555     ChannelNotWritable_n();
556   }
557 }
558 
ChannelWritable_n()559 void BaseChannel::ChannelWritable_n() {
560   RTC_DCHECK_RUN_ON(network_thread());
561   if (writable_) {
562     return;
563   }
564 
565   RTC_LOG(LS_INFO) << "Channel writable (" << ToString() << ")"
566                    << (was_ever_writable_ ? "" : " for the first time");
567 
568   was_ever_writable_ = true;
569   writable_ = true;
570   UpdateMediaSendRecvState();
571 }
572 
ChannelNotWritable_n()573 void BaseChannel::ChannelNotWritable_n() {
574   RTC_DCHECK_RUN_ON(network_thread());
575   if (!writable_)
576     return;
577 
578   RTC_LOG(LS_INFO) << "Channel not writable (" << ToString() << ")";
579   writable_ = false;
580   UpdateMediaSendRecvState();
581 }
582 
AddRecvStream_w(const StreamParams & sp)583 bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
584   RTC_DCHECK(worker_thread() == rtc::Thread::Current());
585   return media_channel()->AddRecvStream(sp);
586 }
587 
RemoveRecvStream_w(uint32_t ssrc)588 bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
589   RTC_DCHECK(worker_thread() == rtc::Thread::Current());
590   return media_channel()->RemoveRecvStream(ssrc);
591 }
592 
ResetUnsignaledRecvStream_w()593 void BaseChannel::ResetUnsignaledRecvStream_w() {
594   RTC_DCHECK(worker_thread() == rtc::Thread::Current());
595   media_channel()->ResetUnsignaledRecvStream();
596 }
597 
SetPayloadTypeDemuxingEnabled_w(bool enabled)598 bool BaseChannel::SetPayloadTypeDemuxingEnabled_w(bool enabled) {
599   RTC_DCHECK_RUN_ON(worker_thread());
600   if (enabled == payload_type_demuxing_enabled_) {
601     return true;
602   }
603   payload_type_demuxing_enabled_ = enabled;
604   if (!enabled) {
605     // TODO(crbug.com/11477): This will remove *all* unsignaled streams (those
606     // without an explicitly signaled SSRC), which may include streams that
607     // were matched to this channel by MID or RID. Ideally we'd remove only the
608     // streams that were matched based on payload type alone, but currently
609     // there is no straightforward way to identify those streams.
610     media_channel()->ResetUnsignaledRecvStream();
611     demuxer_criteria_.payload_types.clear();
612     if (!RegisterRtpDemuxerSink()) {
613       RTC_LOG(LS_ERROR) << "Failed to disable payload type demuxing for "
614                         << ToString();
615       return false;
616     }
617   } else if (!payload_types_.empty()) {
618     demuxer_criteria_.payload_types.insert(payload_types_.begin(),
619                                            payload_types_.end());
620     if (!RegisterRtpDemuxerSink()) {
621       RTC_LOG(LS_ERROR) << "Failed to enable payload type demuxing for "
622                         << ToString();
623       return false;
624     }
625   }
626   return true;
627 }
628 
UpdateLocalStreams_w(const std::vector<StreamParams> & streams,SdpType type,std::string * error_desc)629 bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
630                                        SdpType type,
631                                        std::string* error_desc) {
632   // In the case of RIDs (where SSRCs are not negotiated), this method will
633   // generate an SSRC for each layer in StreamParams. That representation will
634   // be stored internally in |local_streams_|.
635   // In subsequent offers, the same stream can appear in |streams| again
636   // (without the SSRCs), so it should be looked up using RIDs (if available)
637   // and then by primary SSRC.
638   // In both scenarios, it is safe to assume that the media channel will be
639   // created with a StreamParams object with SSRCs. However, it is not safe to
640   // assume that |local_streams_| will always have SSRCs as there are scenarios
641   // in which niether SSRCs or RIDs are negotiated.
642 
643   // Check for streams that have been removed.
644   bool ret = true;
645   for (const StreamParams& old_stream : local_streams_) {
646     if (!old_stream.has_ssrcs() ||
647         GetStream(streams, StreamFinder(&old_stream))) {
648       continue;
649     }
650     if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
651       rtc::StringBuilder desc;
652       desc << "Failed to remove send stream with ssrc "
653            << old_stream.first_ssrc() << " from m-section with mid='"
654            << content_name() << "'.";
655       SafeSetError(desc.str(), error_desc);
656       ret = false;
657     }
658   }
659   // Check for new streams.
660   std::vector<StreamParams> all_streams;
661   for (const StreamParams& stream : streams) {
662     StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
663     if (existing) {
664       // Parameters cannot change for an existing stream.
665       all_streams.push_back(*existing);
666       continue;
667     }
668 
669     all_streams.push_back(stream);
670     StreamParams& new_stream = all_streams.back();
671 
672     if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
673       continue;
674     }
675 
676     RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
677     if (new_stream.has_ssrcs() && new_stream.has_rids()) {
678       rtc::StringBuilder desc;
679       desc << "Failed to add send stream: " << new_stream.first_ssrc()
680            << " into m-section with mid='" << content_name()
681            << "'. Stream has both SSRCs and RIDs.";
682       SafeSetError(desc.str(), error_desc);
683       ret = false;
684       continue;
685     }
686 
687     // At this point we use the legacy simulcast group in StreamParams to
688     // indicate that we want multiple layers to the media channel.
689     if (!new_stream.has_ssrcs()) {
690       // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
691       new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
692                                /* flex_fec = */ false, ssrc_generator_);
693     }
694 
695     if (media_channel()->AddSendStream(new_stream)) {
696       RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0]
697                        << " into " << ToString();
698     } else {
699       rtc::StringBuilder desc;
700       desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc()
701            << " into m-section with mid='" << content_name() << "'";
702       SafeSetError(desc.str(), error_desc);
703       ret = false;
704     }
705   }
706   local_streams_ = all_streams;
707   return ret;
708 }
709 
UpdateRemoteStreams_w(const std::vector<StreamParams> & streams,SdpType type,std::string * error_desc)710 bool BaseChannel::UpdateRemoteStreams_w(
711     const std::vector<StreamParams>& streams,
712     SdpType type,
713     std::string* error_desc) {
714   // Check for streams that have been removed.
715   bool ret = true;
716   for (const StreamParams& old_stream : remote_streams_) {
717     // If we no longer have an unsignaled stream, we would like to remove
718     // the unsignaled stream params that are cached.
719     if (!old_stream.has_ssrcs() && !HasStreamWithNoSsrcs(streams)) {
720       ResetUnsignaledRecvStream_w();
721       RTC_LOG(LS_INFO) << "Reset unsignaled remote stream for " << ToString()
722                        << ".";
723     } else if (old_stream.has_ssrcs() &&
724                !GetStreamBySsrc(streams, old_stream.first_ssrc())) {
725       if (RemoveRecvStream_w(old_stream.first_ssrc())) {
726         RTC_LOG(LS_INFO) << "Remove remote ssrc: " << old_stream.first_ssrc()
727                          << " from " << ToString() << ".";
728       } else {
729         rtc::StringBuilder desc;
730         desc << "Failed to remove remote stream with ssrc "
731              << old_stream.first_ssrc() << " from m-section with mid='"
732              << content_name() << "'.";
733         SafeSetError(desc.str(), error_desc);
734         ret = false;
735       }
736     }
737   }
738   demuxer_criteria_.ssrcs.clear();
739   // Check for new streams.
740   for (const StreamParams& new_stream : streams) {
741     // We allow a StreamParams with an empty list of SSRCs, in which case the
742     // MediaChannel will cache the parameters and use them for any unsignaled
743     // stream received later.
744     if ((!new_stream.has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
745         !GetStreamBySsrc(remote_streams_, new_stream.first_ssrc())) {
746       if (AddRecvStream_w(new_stream)) {
747         RTC_LOG(LS_INFO) << "Add remote ssrc: "
748                          << (new_stream.has_ssrcs()
749                                  ? std::to_string(new_stream.first_ssrc())
750                                  : "unsignaled")
751                          << " to " << ToString();
752       } else {
753         rtc::StringBuilder desc;
754         desc << "Failed to add remote stream ssrc: "
755              << (new_stream.has_ssrcs()
756                      ? std::to_string(new_stream.first_ssrc())
757                      : "unsignaled")
758              << " to " << ToString();
759         SafeSetError(desc.str(), error_desc);
760         ret = false;
761       }
762     }
763     // Update the receiving SSRCs.
764     demuxer_criteria_.ssrcs.insert(new_stream.ssrcs.begin(),
765                                    new_stream.ssrcs.end());
766   }
767   // Re-register the sink to update the receiving ssrcs.
768   if (!RegisterRtpDemuxerSink()) {
769     RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString();
770     ret = false;
771   }
772   remote_streams_ = streams;
773   return ret;
774 }
775 
GetFilteredRtpHeaderExtensions(const RtpHeaderExtensions & extensions)776 RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
777     const RtpHeaderExtensions& extensions) {
778   RTC_DCHECK(rtp_transport_);
779   if (crypto_options_.srtp.enable_encrypted_rtp_header_extensions) {
780     RtpHeaderExtensions filtered;
781     absl::c_copy_if(extensions, std::back_inserter(filtered),
782                     [](const webrtc::RtpExtension& extension) {
783                       return !extension.encrypt;
784                     });
785     return filtered;
786   }
787 
788   return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
789 }
790 
OnMessage(rtc::Message * pmsg)791 void BaseChannel::OnMessage(rtc::Message* pmsg) {
792   TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
793   switch (pmsg->message_id) {
794     case MSG_SEND_RTP_PACKET:
795     case MSG_SEND_RTCP_PACKET: {
796       RTC_DCHECK_RUN_ON(network_thread());
797       SendPacketMessageData* data =
798           static_cast<SendPacketMessageData*>(pmsg->pdata);
799       bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
800       SendPacket(rtcp, &data->packet, data->options);
801       delete data;
802       break;
803     }
804     case MSG_FIRSTPACKETRECEIVED: {
805       RTC_DCHECK_RUN_ON(signaling_thread_);
806       SignalFirstPacketReceived_(this);
807       break;
808     }
809   }
810 }
811 
MaybeAddHandledPayloadType(int payload_type)812 void BaseChannel::MaybeAddHandledPayloadType(int payload_type) {
813   if (payload_type_demuxing_enabled_) {
814     demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
815   }
816   // Even if payload type demuxing is currently disabled, we need to remember
817   // the payload types in case it's re-enabled later.
818   payload_types_.insert(static_cast<uint8_t>(payload_type));
819 }
820 
ClearHandledPayloadTypes()821 void BaseChannel::ClearHandledPayloadTypes() {
822   demuxer_criteria_.payload_types.clear();
823   payload_types_.clear();
824 }
825 
FlushRtcpMessages_n()826 void BaseChannel::FlushRtcpMessages_n() {
827   // Flush all remaining RTCP messages. This should only be called in
828   // destructor.
829   RTC_DCHECK_RUN_ON(network_thread());
830   rtc::MessageList rtcp_messages;
831   network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
832   for (const auto& message : rtcp_messages) {
833     network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
834                           message.pdata);
835   }
836 }
837 
SignalSentPacket_n(const rtc::SentPacket & sent_packet)838 void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
839   RTC_DCHECK_RUN_ON(network_thread());
840   invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
841                              [this, sent_packet] {
842                                RTC_DCHECK_RUN_ON(worker_thread());
843                                SignalSentPacket()(sent_packet);
844                              });
845 }
846 
VoiceChannel(rtc::Thread * worker_thread,rtc::Thread * network_thread,rtc::Thread * signaling_thread,std::unique_ptr<VoiceMediaChannel> media_channel,const std::string & content_name,bool srtp_required,webrtc::CryptoOptions crypto_options,UniqueRandomIdGenerator * ssrc_generator)847 VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
848                            rtc::Thread* network_thread,
849                            rtc::Thread* signaling_thread,
850                            std::unique_ptr<VoiceMediaChannel> media_channel,
851                            const std::string& content_name,
852                            bool srtp_required,
853                            webrtc::CryptoOptions crypto_options,
854                            UniqueRandomIdGenerator* ssrc_generator)
855     : BaseChannel(worker_thread,
856                   network_thread,
857                   signaling_thread,
858                   std::move(media_channel),
859                   content_name,
860                   srtp_required,
861                   crypto_options,
862                   ssrc_generator) {}
863 
~VoiceChannel()864 VoiceChannel::~VoiceChannel() {
865   TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
866   // this can't be done in the base class, since it calls a virtual
867   DisableMedia_w();
868   Deinit();
869 }
870 
UpdateMediaSendRecvState()871 void BaseChannel::UpdateMediaSendRecvState() {
872   RTC_DCHECK_RUN_ON(network_thread());
873   invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
874                              [this] { UpdateMediaSendRecvState_w(); });
875 }
876 
Init_w(webrtc::RtpTransportInternal * rtp_transport)877 void VoiceChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
878   BaseChannel::Init_w(rtp_transport);
879 }
880 
UpdateMediaSendRecvState_w()881 void VoiceChannel::UpdateMediaSendRecvState_w() {
882   // Render incoming data if we're the active call, and we have the local
883   // content. We receive data on the default channel and multiplexed streams.
884   bool recv = IsReadyToReceiveMedia_w();
885   media_channel()->SetPlayout(recv);
886 
887   // Send outgoing data if we're the active call, we have the remote content,
888   // and we have had some form of connectivity.
889   bool send = IsReadyToSendMedia_w();
890   media_channel()->SetSend(send);
891 
892   RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send
893                    << " for " << ToString();
894 }
895 
SetLocalContent_w(const MediaContentDescription * content,SdpType type,std::string * error_desc)896 bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
897                                      SdpType type,
898                                      std::string* error_desc) {
899   TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
900   RTC_DCHECK_RUN_ON(worker_thread());
901   RTC_LOG(LS_INFO) << "Setting local voice description for " << ToString();
902 
903   RTC_DCHECK(content);
904   if (!content) {
905     SafeSetError("Can't find audio content in local description.", error_desc);
906     return false;
907   }
908 
909   const AudioContentDescription* audio = content->as_audio();
910 
911   RtpHeaderExtensions rtp_header_extensions =
912       GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
913   UpdateRtpHeaderExtensionMap(rtp_header_extensions);
914   media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
915 
916   AudioRecvParameters recv_params = last_recv_params_;
917   RtpParametersFromMediaDescription(
918       audio, rtp_header_extensions,
919       webrtc::RtpTransceiverDirectionHasRecv(audio->direction()), &recv_params);
920   if (!media_channel()->SetRecvParameters(recv_params)) {
921     SafeSetError(
922         "Failed to set local audio description recv parameters for m-section "
923         "with mid='" +
924             content_name() + "'.",
925         error_desc);
926     return false;
927   }
928 
929   if (webrtc::RtpTransceiverDirectionHasRecv(audio->direction())) {
930     for (const AudioCodec& codec : audio->codecs()) {
931       MaybeAddHandledPayloadType(codec.id);
932     }
933     // Need to re-register the sink to update the handled payload.
934     if (!RegisterRtpDemuxerSink()) {
935       RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing for " << ToString();
936       return false;
937     }
938   }
939 
940   last_recv_params_ = recv_params;
941 
942   // TODO(pthatcher): Move local streams into AudioSendParameters, and
943   // only give it to the media channel once we have a remote
944   // description too (without a remote description, we won't be able
945   // to send them anyway).
946   if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
947     SafeSetError(
948         "Failed to set local audio description streams for m-section with "
949         "mid='" +
950             content_name() + "'.",
951         error_desc);
952     return false;
953   }
954 
955   set_local_content_direction(content->direction());
956   UpdateMediaSendRecvState_w();
957   return true;
958 }
959 
SetRemoteContent_w(const MediaContentDescription * content,SdpType type,std::string * error_desc)960 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
961                                       SdpType type,
962                                       std::string* error_desc) {
963   TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
964   RTC_DCHECK_RUN_ON(worker_thread());
965   RTC_LOG(LS_INFO) << "Setting remote voice description for " << ToString();
966 
967   RTC_DCHECK(content);
968   if (!content) {
969     SafeSetError("Can't find audio content in remote description.", error_desc);
970     return false;
971   }
972 
973   const AudioContentDescription* audio = content->as_audio();
974 
975   RtpHeaderExtensions rtp_header_extensions =
976       GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
977 
978   AudioSendParameters send_params = last_send_params_;
979   RtpSendParametersFromMediaDescription(
980       audio, rtp_header_extensions,
981       webrtc::RtpTransceiverDirectionHasRecv(audio->direction()), &send_params);
982   send_params.mid = content_name();
983 
984   bool parameters_applied = media_channel()->SetSendParameters(send_params);
985   if (!parameters_applied) {
986     SafeSetError(
987         "Failed to set remote audio description send parameters for m-section "
988         "with mid='" +
989             content_name() + "'.",
990         error_desc);
991     return false;
992   }
993   last_send_params_ = send_params;
994 
995   if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
996     RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
997                             "disable payload type demuxing for "
998                          << ToString();
999     ClearHandledPayloadTypes();
1000     if (!RegisterRtpDemuxerSink()) {
1001       RTC_LOG(LS_ERROR) << "Failed to update audio demuxing for " << ToString();
1002       return false;
1003     }
1004   }
1005 
1006   // TODO(pthatcher): Move remote streams into AudioRecvParameters,
1007   // and only give it to the media channel once we have a local
1008   // description too (without a local description, we won't be able to
1009   // recv them anyway).
1010   if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
1011     SafeSetError(
1012         "Failed to set remote audio description streams for m-section with "
1013         "mid='" +
1014             content_name() + "'.",
1015         error_desc);
1016     return false;
1017   }
1018 
1019   set_remote_content_direction(content->direction());
1020   UpdateMediaSendRecvState_w();
1021   return true;
1022 }
1023 
VideoChannel(rtc::Thread * worker_thread,rtc::Thread * network_thread,rtc::Thread * signaling_thread,std::unique_ptr<VideoMediaChannel> media_channel,const std::string & content_name,bool srtp_required,webrtc::CryptoOptions crypto_options,UniqueRandomIdGenerator * ssrc_generator)1024 VideoChannel::VideoChannel(rtc::Thread* worker_thread,
1025                            rtc::Thread* network_thread,
1026                            rtc::Thread* signaling_thread,
1027                            std::unique_ptr<VideoMediaChannel> media_channel,
1028                            const std::string& content_name,
1029                            bool srtp_required,
1030                            webrtc::CryptoOptions crypto_options,
1031                            UniqueRandomIdGenerator* ssrc_generator)
1032     : BaseChannel(worker_thread,
1033                   network_thread,
1034                   signaling_thread,
1035                   std::move(media_channel),
1036                   content_name,
1037                   srtp_required,
1038                   crypto_options,
1039                   ssrc_generator) {}
1040 
~VideoChannel()1041 VideoChannel::~VideoChannel() {
1042   TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
1043   // this can't be done in the base class, since it calls a virtual
1044   DisableMedia_w();
1045   Deinit();
1046 }
1047 
UpdateMediaSendRecvState_w()1048 void VideoChannel::UpdateMediaSendRecvState_w() {
1049   // Send outgoing data if we're the active call, we have the remote content,
1050   // and we have had some form of connectivity.
1051   bool send = IsReadyToSendMedia_w();
1052   if (!media_channel()->SetSend(send)) {
1053     RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel: " + ToString();
1054     // TODO(gangji): Report error back to server.
1055   }
1056 
1057   RTC_LOG(LS_INFO) << "Changing video state, send=" << send << " for "
1058                    << ToString();
1059 }
1060 
FillBitrateInfo(BandwidthEstimationInfo * bwe_info)1061 void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
1062   InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
1063                                            media_channel(), bwe_info));
1064 }
1065 
SetLocalContent_w(const MediaContentDescription * content,SdpType type,std::string * error_desc)1066 bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
1067                                      SdpType type,
1068                                      std::string* error_desc) {
1069   TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
1070   RTC_DCHECK_RUN_ON(worker_thread());
1071   RTC_LOG(LS_INFO) << "Setting local video description for " << ToString();
1072 
1073   RTC_DCHECK(content);
1074   if (!content) {
1075     SafeSetError("Can't find video content in local description.", error_desc);
1076     return false;
1077   }
1078 
1079   const VideoContentDescription* video = content->as_video();
1080 
1081   RtpHeaderExtensions rtp_header_extensions =
1082       GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1083   UpdateRtpHeaderExtensionMap(rtp_header_extensions);
1084   media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
1085 
1086   VideoRecvParameters recv_params = last_recv_params_;
1087   RtpParametersFromMediaDescription(
1088       video, rtp_header_extensions,
1089       webrtc::RtpTransceiverDirectionHasRecv(video->direction()), &recv_params);
1090 
1091   VideoSendParameters send_params = last_send_params_;
1092 
1093   bool needs_send_params_update = false;
1094   if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
1095     for (auto& send_codec : send_params.codecs) {
1096       auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
1097       if (recv_codec) {
1098         if (!recv_codec->packetization && send_codec.packetization) {
1099           send_codec.packetization.reset();
1100           needs_send_params_update = true;
1101         } else if (recv_codec->packetization != send_codec.packetization) {
1102           SafeSetError(
1103               "Failed to set local answer due to invalid codec packetization "
1104               "specified in m-section with mid='" +
1105                   content_name() + "'.",
1106               error_desc);
1107           return false;
1108         }
1109       }
1110     }
1111   }
1112 
1113   if (!media_channel()->SetRecvParameters(recv_params)) {
1114     SafeSetError(
1115         "Failed to set local video description recv parameters for m-section "
1116         "with mid='" +
1117             content_name() + "'.",
1118         error_desc);
1119     return false;
1120   }
1121 
1122   if (webrtc::RtpTransceiverDirectionHasRecv(video->direction())) {
1123     for (const VideoCodec& codec : video->codecs()) {
1124       MaybeAddHandledPayloadType(codec.id);
1125     }
1126     // Need to re-register the sink to update the handled payload.
1127     if (!RegisterRtpDemuxerSink()) {
1128       RTC_LOG(LS_ERROR) << "Failed to set up video demuxing for " << ToString();
1129       return false;
1130     }
1131   }
1132 
1133   last_recv_params_ = recv_params;
1134 
1135   if (needs_send_params_update) {
1136     if (!media_channel()->SetSendParameters(send_params)) {
1137       SafeSetError("Failed to set send parameters for m-section with mid='" +
1138                        content_name() + "'.",
1139                    error_desc);
1140       return false;
1141     }
1142     last_send_params_ = send_params;
1143   }
1144 
1145   // TODO(pthatcher): Move local streams into VideoSendParameters, and
1146   // only give it to the media channel once we have a remote
1147   // description too (without a remote description, we won't be able
1148   // to send them anyway).
1149   if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
1150     SafeSetError(
1151         "Failed to set local video description streams for m-section with "
1152         "mid='" +
1153             content_name() + "'.",
1154         error_desc);
1155     return false;
1156   }
1157 
1158   set_local_content_direction(content->direction());
1159   UpdateMediaSendRecvState_w();
1160   return true;
1161 }
1162 
SetRemoteContent_w(const MediaContentDescription * content,SdpType type,std::string * error_desc)1163 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
1164                                       SdpType type,
1165                                       std::string* error_desc) {
1166   TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
1167   RTC_DCHECK_RUN_ON(worker_thread());
1168   RTC_LOG(LS_INFO) << "Setting remote video description for " << ToString();
1169 
1170   RTC_DCHECK(content);
1171   if (!content) {
1172     SafeSetError("Can't find video content in remote description.", error_desc);
1173     return false;
1174   }
1175 
1176   const VideoContentDescription* video = content->as_video();
1177 
1178   RtpHeaderExtensions rtp_header_extensions =
1179       GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1180 
1181   VideoSendParameters send_params = last_send_params_;
1182   RtpSendParametersFromMediaDescription(
1183       video, rtp_header_extensions,
1184       webrtc::RtpTransceiverDirectionHasRecv(video->direction()), &send_params);
1185   if (video->conference_mode()) {
1186     send_params.conference_mode = true;
1187   }
1188   send_params.mid = content_name();
1189 
1190   VideoRecvParameters recv_params = last_recv_params_;
1191 
1192   bool needs_recv_params_update = false;
1193   if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
1194     for (auto& recv_codec : recv_params.codecs) {
1195       auto* send_codec = FindMatchingCodec(send_params.codecs, recv_codec);
1196       if (send_codec) {
1197         if (!send_codec->packetization && recv_codec.packetization) {
1198           recv_codec.packetization.reset();
1199           needs_recv_params_update = true;
1200         } else if (send_codec->packetization != recv_codec.packetization) {
1201           SafeSetError(
1202               "Failed to set remote answer due to invalid codec packetization "
1203               "specifid in m-section with mid='" +
1204                   content_name() + "'.",
1205               error_desc);
1206           return false;
1207         }
1208       }
1209     }
1210   }
1211 
1212   if (!media_channel()->SetSendParameters(send_params)) {
1213     SafeSetError(
1214         "Failed to set remote video description send parameters for m-section "
1215         "with mid='" +
1216             content_name() + "'.",
1217         error_desc);
1218     return false;
1219   }
1220   last_send_params_ = send_params;
1221 
1222   if (needs_recv_params_update) {
1223     if (!media_channel()->SetRecvParameters(recv_params)) {
1224       SafeSetError("Failed to set recv parameters for m-section with mid='" +
1225                        content_name() + "'.",
1226                    error_desc);
1227       return false;
1228     }
1229     last_recv_params_ = recv_params;
1230   }
1231 
1232   if (!webrtc::RtpTransceiverDirectionHasSend(content->direction())) {
1233     RTC_DLOG(LS_VERBOSE) << "SetRemoteContent_w: remote side will not send - "
1234                             "disable payload type demuxing for "
1235                          << ToString();
1236     ClearHandledPayloadTypes();
1237     if (!RegisterRtpDemuxerSink()) {
1238       RTC_LOG(LS_ERROR) << "Failed to update video demuxing for " << ToString();
1239       return false;
1240     }
1241   }
1242 
1243   // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1244   // and only give it to the media channel once we have a local
1245   // description too (without a local description, we won't be able to
1246   // recv them anyway).
1247   if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
1248     SafeSetError(
1249         "Failed to set remote video description streams for m-section with "
1250         "mid='" +
1251             content_name() + "'.",
1252         error_desc);
1253     return false;
1254   }
1255   set_remote_content_direction(content->direction());
1256   UpdateMediaSendRecvState_w();
1257   return true;
1258 }
1259 
RtpDataChannel(rtc::Thread * worker_thread,rtc::Thread * network_thread,rtc::Thread * signaling_thread,std::unique_ptr<DataMediaChannel> media_channel,const std::string & content_name,bool srtp_required,webrtc::CryptoOptions crypto_options,UniqueRandomIdGenerator * ssrc_generator)1260 RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1261                                rtc::Thread* network_thread,
1262                                rtc::Thread* signaling_thread,
1263                                std::unique_ptr<DataMediaChannel> media_channel,
1264                                const std::string& content_name,
1265                                bool srtp_required,
1266                                webrtc::CryptoOptions crypto_options,
1267                                UniqueRandomIdGenerator* ssrc_generator)
1268     : BaseChannel(worker_thread,
1269                   network_thread,
1270                   signaling_thread,
1271                   std::move(media_channel),
1272                   content_name,
1273                   srtp_required,
1274                   crypto_options,
1275                   ssrc_generator) {}
1276 
~RtpDataChannel()1277 RtpDataChannel::~RtpDataChannel() {
1278   TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
1279   // this can't be done in the base class, since it calls a virtual
1280   DisableMedia_w();
1281   Deinit();
1282 }
1283 
Init_w(webrtc::RtpTransportInternal * rtp_transport)1284 void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
1285   BaseChannel::Init_w(rtp_transport);
1286   media_channel()->SignalDataReceived.connect(this,
1287                                               &RtpDataChannel::OnDataReceived);
1288   media_channel()->SignalReadyToSend.connect(
1289       this, &RtpDataChannel::OnDataChannelReadyToSend);
1290 }
1291 
SendData(const SendDataParams & params,const rtc::CopyOnWriteBuffer & payload,SendDataResult * result)1292 bool RtpDataChannel::SendData(const SendDataParams& params,
1293                               const rtc::CopyOnWriteBuffer& payload,
1294                               SendDataResult* result) {
1295   return InvokeOnWorker<bool>(
1296       RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1297                           payload, result));
1298 }
1299 
CheckDataChannelTypeFromContent(const MediaContentDescription * content,std::string * error_desc)1300 bool RtpDataChannel::CheckDataChannelTypeFromContent(
1301     const MediaContentDescription* content,
1302     std::string* error_desc) {
1303   if (!content->as_rtp_data()) {
1304     if (content->as_sctp()) {
1305       SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1306                    error_desc);
1307     } else {
1308       SafeSetError("Data channel is not RTP or SCTP.", error_desc);
1309     }
1310     return false;
1311   }
1312   return true;
1313 }
1314 
SetLocalContent_w(const MediaContentDescription * content,SdpType type,std::string * error_desc)1315 bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
1316                                        SdpType type,
1317                                        std::string* error_desc) {
1318   TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
1319   RTC_DCHECK_RUN_ON(worker_thread());
1320   RTC_LOG(LS_INFO) << "Setting local data description for " << ToString();
1321 
1322   RTC_DCHECK(content);
1323   if (!content) {
1324     SafeSetError("Can't find data content in local description.", error_desc);
1325     return false;
1326   }
1327 
1328   if (!CheckDataChannelTypeFromContent(content, error_desc)) {
1329     return false;
1330   }
1331   const RtpDataContentDescription* data = content->as_rtp_data();
1332 
1333   RtpHeaderExtensions rtp_header_extensions =
1334       GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1335 
1336   DataRecvParameters recv_params = last_recv_params_;
1337   RtpParametersFromMediaDescription(
1338       data, rtp_header_extensions,
1339       webrtc::RtpTransceiverDirectionHasRecv(data->direction()), &recv_params);
1340   if (!media_channel()->SetRecvParameters(recv_params)) {
1341     SafeSetError(
1342         "Failed to set remote data description recv parameters for m-section "
1343         "with mid='" +
1344             content_name() + "'.",
1345         error_desc);
1346     return false;
1347   }
1348   for (const DataCodec& codec : data->codecs()) {
1349     MaybeAddHandledPayloadType(codec.id);
1350   }
1351   // Need to re-register the sink to update the handled payload.
1352   if (!RegisterRtpDemuxerSink()) {
1353     RTC_LOG(LS_ERROR) << "Failed to set up data demuxing for " << ToString();
1354     return false;
1355   }
1356 
1357   last_recv_params_ = recv_params;
1358 
1359   // TODO(pthatcher): Move local streams into DataSendParameters, and
1360   // only give it to the media channel once we have a remote
1361   // description too (without a remote description, we won't be able
1362   // to send them anyway).
1363   if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
1364     SafeSetError(
1365         "Failed to set local data description streams for m-section with "
1366         "mid='" +
1367             content_name() + "'.",
1368         error_desc);
1369     return false;
1370   }
1371 
1372   set_local_content_direction(content->direction());
1373   UpdateMediaSendRecvState_w();
1374   return true;
1375 }
1376 
SetRemoteContent_w(const MediaContentDescription * content,SdpType type,std::string * error_desc)1377 bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
1378                                         SdpType type,
1379                                         std::string* error_desc) {
1380   TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
1381   RTC_DCHECK_RUN_ON(worker_thread());
1382   RTC_LOG(LS_INFO) << "Setting remote data description for " << ToString();
1383 
1384   RTC_DCHECK(content);
1385   if (!content) {
1386     SafeSetError("Can't find data content in remote description.", error_desc);
1387     return false;
1388   }
1389 
1390   if (!CheckDataChannelTypeFromContent(content, error_desc)) {
1391     return false;
1392   }
1393 
1394   const RtpDataContentDescription* data = content->as_rtp_data();
1395 
1396   // If the remote data doesn't have codecs, it must be empty, so ignore it.
1397   if (!data->has_codecs()) {
1398     return true;
1399   }
1400 
1401   RtpHeaderExtensions rtp_header_extensions =
1402       GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1403 
1404   RTC_LOG(LS_INFO) << "Setting remote data description for " << ToString();
1405   DataSendParameters send_params = last_send_params_;
1406   RtpSendParametersFromMediaDescription<DataCodec>(
1407       data, rtp_header_extensions,
1408       webrtc::RtpTransceiverDirectionHasRecv(data->direction()), &send_params);
1409   if (!media_channel()->SetSendParameters(send_params)) {
1410     SafeSetError(
1411         "Failed to set remote data description send parameters for m-section "
1412         "with mid='" +
1413             content_name() + "'.",
1414         error_desc);
1415     return false;
1416   }
1417   last_send_params_ = send_params;
1418 
1419   // TODO(pthatcher): Move remote streams into DataRecvParameters,
1420   // and only give it to the media channel once we have a local
1421   // description too (without a local description, we won't be able to
1422   // recv them anyway).
1423   if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
1424     SafeSetError(
1425         "Failed to set remote data description streams for m-section with "
1426         "mid='" +
1427             content_name() + "'.",
1428         error_desc);
1429     return false;
1430   }
1431 
1432   set_remote_content_direction(content->direction());
1433   UpdateMediaSendRecvState_w();
1434   return true;
1435 }
1436 
UpdateMediaSendRecvState_w()1437 void RtpDataChannel::UpdateMediaSendRecvState_w() {
1438   // Render incoming data if we're the active call, and we have the local
1439   // content. We receive data on the default channel and multiplexed streams.
1440   bool recv = IsReadyToReceiveMedia_w();
1441   if (!media_channel()->SetReceive(recv)) {
1442     RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel: " << ToString();
1443   }
1444 
1445   // Send outgoing data if we're the active call, we have the remote content,
1446   // and we have had some form of connectivity.
1447   bool send = IsReadyToSendMedia_w();
1448   if (!media_channel()->SetSend(send)) {
1449     RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel: " << ToString();
1450   }
1451 
1452   // Trigger SignalReadyToSendData asynchronously.
1453   OnDataChannelReadyToSend(send);
1454 
1455   RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send
1456                    << " for " << ToString();
1457 }
1458 
OnMessage(rtc::Message * pmsg)1459 void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
1460   switch (pmsg->message_id) {
1461     case MSG_READYTOSENDDATA: {
1462       DataChannelReadyToSendMessageData* data =
1463           static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
1464       ready_to_send_data_ = data->data();
1465       SignalReadyToSendData(ready_to_send_data_);
1466       delete data;
1467       break;
1468     }
1469     case MSG_DATARECEIVED: {
1470       DataReceivedMessageData* data =
1471           static_cast<DataReceivedMessageData*>(pmsg->pdata);
1472       SignalDataReceived(data->params, data->payload);
1473       delete data;
1474       break;
1475     }
1476     default:
1477       BaseChannel::OnMessage(pmsg);
1478       break;
1479   }
1480 }
1481 
OnDataReceived(const ReceiveDataParams & params,const char * data,size_t len)1482 void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1483                                     const char* data,
1484                                     size_t len) {
1485   DataReceivedMessageData* msg = new DataReceivedMessageData(params, data, len);
1486   signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
1487 }
1488 
OnDataChannelReadyToSend(bool writable)1489 void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
1490   // This is usded for congestion control to indicate that the stream is ready
1491   // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1492   // that the transport channel is ready.
1493   signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
1494                            new DataChannelReadyToSendMessageData(writable));
1495 }
1496 
1497 }  // namespace cricket
1498