diff --git a/webrtc/pc/BUILD.gn b/webrtc/pc/BUILD.gn index 75a644c1ed..8aba758aa0 100644 --- a/webrtc/pc/BUILD.gn +++ b/webrtc/pc/BUILD.gn @@ -46,6 +46,8 @@ rtc_static_library("rtc_pc") { "mediasession.h", "rtcpmuxfilter.cc", "rtcpmuxfilter.h", + "rtptransport.cc", + "rtptransport.h", "srtpfilter.cc", "srtpfilter.h", "voicechannel.h", diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc index ecc1c9a633..5634648336 100644 --- a/webrtc/pc/channel.cc +++ b/webrtc/pc/channel.cc @@ -167,7 +167,7 @@ BaseChannel::BaseChannel(rtc::Thread* worker_thread, network_thread_(network_thread), signaling_thread_(signaling_thread), content_name_(content_name), - rtcp_mux_required_(rtcp_mux_required), + rtp_transport_(rtcp_mux_required), srtp_required_(srtp_required), media_channel_(media_channel), selected_candidate_pair_(nullptr) { @@ -201,13 +201,13 @@ void BaseChannel::DisconnectTransportChannels_n() { // media_channel may use them from a different thread. if (rtp_dtls_transport_) { DisconnectFromDtlsTransport(rtp_dtls_transport_); - } else if (rtp_packet_transport_) { - DisconnectFromPacketTransport(rtp_packet_transport_); + } else if (rtp_transport_.rtp_packet_transport()) { + DisconnectFromPacketTransport(rtp_transport_.rtp_packet_transport()); } if (rtcp_dtls_transport_) { DisconnectFromDtlsTransport(rtcp_dtls_transport_); - } else if (rtcp_packet_transport_) { - DisconnectFromPacketTransport(rtcp_packet_transport_); + } else if (rtp_transport_.rtcp_packet_transport()) { + DisconnectFromPacketTransport(rtp_transport_.rtcp_packet_transport()); } // Clear pending read packets/messages. @@ -249,7 +249,7 @@ bool BaseChannel::InitNetwork_n( !SetDtlsSrtpCryptoSuites_n(rtcp_dtls_transport_, true)) { return false; } - if (rtcp_mux_required_) { + if (rtp_transport_.rtcp_mux_required()) { rtcp_mux_filter_.SetActive(); } return true; @@ -295,7 +295,7 @@ void BaseChannel::SetTransports_n( RTC_DCHECK(rtp_dtls_transport == rtp_packet_transport); RTC_DCHECK(rtcp_dtls_transport == rtcp_packet_transport); // Can't go from non-DTLS to DTLS. - RTC_DCHECK(!rtp_packet_transport_ || rtp_dtls_transport_); + RTC_DCHECK(!rtp_transport_.rtp_packet_transport() || rtp_dtls_transport_); } else { // Can't go from DTLS to non-DTLS. RTC_DCHECK(!rtp_dtls_transport_); @@ -312,7 +312,7 @@ void BaseChannel::SetTransports_n( } else { debug_name = rtp_packet_transport->debug_name(); } - if (rtp_packet_transport == rtp_packet_transport_) { + if (rtp_packet_transport == rtp_transport_.rtp_packet_transport()) { // Nothing to do if transport isn't changing. return; } @@ -352,9 +352,9 @@ void BaseChannel::SetTransports_n( // BaseChannel could have resulted in an error), but even so, we'll just // encounter the error again and update "ready to send" accordingly. SetTransportChannelReadyToSend( - false, rtp_packet_transport_ && rtp_packet_transport_->writable()); + false, rtp_packet_transport && rtp_packet_transport->writable()); SetTransportChannelReadyToSend( - true, rtcp_packet_transport_ && rtcp_packet_transport_->writable()); + true, rtcp_packet_transport && rtcp_packet_transport->writable()); } void BaseChannel::SetTransport_n( @@ -364,8 +364,9 @@ void BaseChannel::SetTransport_n( RTC_DCHECK(network_thread_->IsCurrent()); DtlsTransportInternal*& old_dtls_transport = rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_; - rtc::PacketTransportInternal*& old_packet_transport = - rtcp ? rtcp_packet_transport_ : rtp_packet_transport_; + rtc::PacketTransportInternal* old_packet_transport = + rtcp ? rtp_transport_.rtcp_packet_transport() + : rtp_transport_.rtp_packet_transport(); if (!old_packet_transport && !new_packet_transport) { // Nothing to do. @@ -379,7 +380,11 @@ void BaseChannel::SetTransport_n( DisconnectFromPacketTransport(old_packet_transport); } - old_packet_transport = new_packet_transport; + if (rtcp) { + rtp_transport_.set_rtcp_packet_transport(new_packet_transport); + } else { + rtp_transport_.set_rtp_packet_transport(new_packet_transport); + } old_dtls_transport = new_dtls_transport; // If there's no new transport, we're done after disconnecting from old one. @@ -524,7 +529,8 @@ bool BaseChannel::GetConnectionStats(ConnectionInfos* infos) { bool BaseChannel::NeedsRtcpTransport() { // If this BaseChannel doesn't require RTCP mux and we haven't fully // negotiated RTCP mux, we need an RTCP transport. - return !rtcp_mux_required_ && !rtcp_mux_filter_.IsFullyActive(); + return !rtp_transport_.rtcp_mux_required() && + !rtcp_mux_filter_.IsFullyActive(); } bool BaseChannel::IsReadyToReceiveMedia_w() const { @@ -570,12 +576,12 @@ int BaseChannel::SetOption_n(SocketType type, rtc::PacketTransportInternal* transport = nullptr; switch (type) { case ST_RTP: - transport = rtp_packet_transport_; + transport = rtp_transport_.rtp_packet_transport(); socket_options_.push_back( std::pair(opt, value)); break; case ST_RTCP: - transport = rtcp_packet_transport_; + transport = rtp_transport_.rtcp_packet_transport(); rtcp_socket_options_.push_back( std::pair(opt, value)); break; @@ -589,8 +595,8 @@ bool BaseChannel::SetCryptoOptions(const rtc::CryptoOptions& crypto_options) { } void BaseChannel::OnWritableState(rtc::PacketTransportInternal* transport) { - RTC_DCHECK(transport == rtp_packet_transport_ || - transport == rtcp_packet_transport_); + RTC_DCHECK(transport == rtp_transport_.rtp_packet_transport() || + transport == rtp_transport_.rtcp_packet_transport()); RTC_DCHECK(network_thread_->IsCurrent()); UpdateWritableState_n(); } @@ -612,9 +618,10 @@ void BaseChannel::OnPacketRead(rtc::PacketTransportInternal* transport, } void BaseChannel::OnReadyToSend(rtc::PacketTransportInternal* transport) { - RTC_DCHECK(transport == rtp_packet_transport_ || - transport == rtcp_packet_transport_); - SetTransportChannelReadyToSend(transport == rtcp_packet_transport_, true); + RTC_DCHECK(transport == rtp_transport_.rtp_packet_transport() || + transport == rtp_transport_.rtcp_packet_transport()); + SetTransportChannelReadyToSend( + transport == rtp_transport_.rtcp_packet_transport(), true); } void BaseChannel::OnDtlsState(DtlsTransportInternal* transport, @@ -671,7 +678,7 @@ void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) { bool ready_to_send = (rtp_ready_to_send_ && // In the case of rtcp mux |rtcp_packet_transport_| will be null. - (rtcp_ready_to_send_ || !rtcp_packet_transport_)); + (rtcp_ready_to_send_ || !rtp_transport_.rtcp_packet_transport())); invoker_.AsyncInvoke( RTC_FROM_HERE, worker_thread_, @@ -681,7 +688,7 @@ void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) { bool BaseChannel::PacketIsRtcp(const rtc::PacketTransportInternal* transport, const char* data, size_t len) { - return (transport == rtcp_packet_transport_ || + return (transport == rtp_transport_.rtcp_packet_transport() || rtcp_mux_filter_.DemuxRtcp(data, static_cast(len))); } @@ -711,8 +718,9 @@ bool BaseChannel::SendPacket(bool rtcp, // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP // transport. rtc::PacketTransportInternal* transport = - (!rtcp || rtcp_mux_filter_.IsActive()) ? rtp_packet_transport_ - : rtcp_packet_transport_; + (!rtcp || rtcp_mux_filter_.IsActive()) + ? rtp_transport_.rtp_packet_transport() + : rtp_transport_.rtcp_packet_transport(); if (!transport || !transport->writable()) { return false; } @@ -966,8 +974,12 @@ void BaseChannel::DisableMedia_w() { } void BaseChannel::UpdateWritableState_n() { - if (rtp_packet_transport_ && rtp_packet_transport_->writable() && - (!rtcp_packet_transport_ || rtcp_packet_transport_->writable())) { + rtc::PacketTransportInternal* rtp_packet_transport = + rtp_transport_.rtp_packet_transport(); + rtc::PacketTransportInternal* rtcp_packet_transport = + rtp_transport_.rtcp_packet_transport(); + if (rtp_packet_transport && rtp_packet_transport->writable() && + (!rtcp_packet_transport || rtcp_packet_transport->writable())) { ChannelWritable_n(); } else { ChannelNotWritable_n(); @@ -1246,7 +1258,7 @@ bool BaseChannel::SetRtcpMux_n(bool enable, std::string* error_desc) { // Provide a more specific error message for the RTCP mux "require" policy // case. - if (rtcp_mux_required_ && !enable) { + if (rtp_transport_.rtcp_mux_required() && !enable) { SafeSetError( "rtcpMuxPolicy is 'require', but media description does not " "contain 'a=rtcp-mux'.", @@ -1268,13 +1280,14 @@ bool BaseChannel::SetRtcpMux_n(bool enable, if (ret && rtcp_mux_filter_.IsActive()) { // We permanently activated RTCP muxing; signal that we no longer need // the RTCP transport. - std::string debug_name = transport_name_.empty() - ? rtp_packet_transport_->debug_name() - : transport_name_; + std::string debug_name = + transport_name_.empty() + ? rtp_transport_.rtp_packet_transport()->debug_name() + : transport_name_; ; LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name() << "; no longer need RTCP transport for " << debug_name; - if (rtcp_packet_transport_) { + if (rtp_transport_.rtcp_packet_transport()) { SetTransport_n(true, nullptr, nullptr); SignalRtcpMuxFullyActive(transport_name_); } @@ -1298,7 +1311,7 @@ bool BaseChannel::SetRtcpMux_n(bool enable, // a final answer. if (rtcp_mux_filter_.IsActive()) { // If the RTP transport is already writable, then so are we. - if (rtp_packet_transport_->writable()) { + if (rtp_transport_.rtp_packet_transport()->writable()) { ChannelWritable_n(); } } diff --git a/webrtc/pc/channel.h b/webrtc/pc/channel.h index 6ff0556c97..bc98bc9fc8 100644 --- a/webrtc/pc/channel.h +++ b/webrtc/pc/channel.h @@ -39,6 +39,7 @@ #include "webrtc/pc/mediamonitor.h" #include "webrtc/pc/mediasession.h" #include "webrtc/pc/rtcpmuxfilter.h" +#include "webrtc/pc/rtptransport.h" #include "webrtc/pc/srtpfilter.h" namespace webrtc { @@ -398,17 +399,13 @@ class BaseChannel // Won't be set when using raw packet transports. SDP-specific thing. std::string transport_name_; - // True if RTCP-multiplexing is required. In other words, no standalone RTCP - // transport will ever be used for this channel. - const bool rtcp_mux_required_; // Separate DTLS/non-DTLS pointers to support using BaseChannel without DTLS. // Temporary measure until more refactoring is done. // If non-null, "X_dtls_transport_" will always equal "X_packet_transport_". DtlsTransportInternal* rtp_dtls_transport_ = nullptr; DtlsTransportInternal* rtcp_dtls_transport_ = nullptr; - rtc::PacketTransportInternal* rtp_packet_transport_ = nullptr; - rtc::PacketTransportInternal* rtcp_packet_transport_ = nullptr; + webrtc::RtpTransport rtp_transport_; std::vector > socket_options_; std::vector > rtcp_socket_options_; SrtpFilter srtp_filter_; diff --git a/webrtc/pc/rtptransport.cc b/webrtc/pc/rtptransport.cc new file mode 100644 index 0000000000..eb463db0bf --- /dev/null +++ b/webrtc/pc/rtptransport.cc @@ -0,0 +1,23 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/pc/rtptransport.h" + +#include "webrtc/base/checks.h" + +namespace webrtc { + +void RtpTransport::set_rtcp_packet_transport( + rtc::PacketTransportInternal* rtcp) { + RTC_DCHECK(!rtcp_mux_required_); + rtcp_packet_transport_ = rtcp; +} + +} // namespace webrtc diff --git a/webrtc/pc/rtptransport.h b/webrtc/pc/rtptransport.h new file mode 100644 index 0000000000..5dbebe6ed9 --- /dev/null +++ b/webrtc/pc/rtptransport.h @@ -0,0 +1,57 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_PC_RTPTRANSPORT_H_ +#define WEBRTC_PC_RTPTRANSPORT_H_ + +namespace rtc { + +class PacketTransportInternal; + +} // namespace rtc + +namespace webrtc { + +class RtpTransport { + public: + RtpTransport(const RtpTransport&) = delete; + RtpTransport& operator=(const RtpTransport&) = delete; + + explicit RtpTransport(bool rtcp_mux_required) + : rtcp_mux_required_(rtcp_mux_required) {} + + bool rtcp_mux_required() const { return rtcp_mux_required_; } + + rtc::PacketTransportInternal* rtp_packet_transport() const { + return rtp_packet_transport_; + } + void set_rtp_packet_transport(rtc::PacketTransportInternal* rtp) { + rtp_packet_transport_ = rtp; + } + + rtc::PacketTransportInternal* rtcp_packet_transport() const { + return rtcp_packet_transport_; + } + void set_rtcp_packet_transport(rtc::PacketTransportInternal* rtcp); + + private: + // True if RTCP-multiplexing is required. rtcp_packet_transport_ should + // always be null in this case. + const bool rtcp_mux_required_; + + // TODO(zstein): Revisit ownership here - transports are currently owned by + // TransportController + rtc::PacketTransportInternal* rtp_packet_transport_ = nullptr; + rtc::PacketTransportInternal* rtcp_packet_transport_ = nullptr; +}; + +} // namespace webrtc + +#endif // WEBRTC_PC_RTPTRANSPORT_H_