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