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