diff --git a/webrtc/api/rtcstatscollector_unittest.cc b/webrtc/api/rtcstatscollector_unittest.cc index 72d00c49ac..4d17003269 100644 --- a/webrtc/api/rtcstatscollector_unittest.cc +++ b/webrtc/api/rtcstatscollector_unittest.cc @@ -596,14 +596,15 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsSingle) { TEST_F(RTCStatsCollectorTest, CollectRTCCodecStats) { MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel(); cricket::VoiceChannel voice_channel( - test_->worker_thread(), test_->network_thread(), test_->media_engine(), - voice_media_channel, nullptr, "VoiceContentName", kDefaultRtcpEnabled, - kDefaultSrtpRequired); + test_->worker_thread(), test_->network_thread(), nullptr, + test_->media_engine(), voice_media_channel, "VoiceContentName", + kDefaultRtcpEnabled, kDefaultSrtpRequired); MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - test_->worker_thread(), test_->network_thread(), video_media_channel, - nullptr, "VideoContentName", kDefaultRtcpEnabled, kDefaultSrtpRequired); + test_->worker_thread(), test_->network_thread(), nullptr, + video_media_channel, "VideoContentName", kDefaultRtcpEnabled, + kDefaultSrtpRequired); // Audio cricket::VoiceMediaInfo voice_media_info; @@ -1443,9 +1444,9 @@ TEST_F(RTCStatsCollectorTest, TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) { MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel(); cricket::VoiceChannel voice_channel( - test_->worker_thread(), test_->network_thread(), test_->media_engine(), - voice_media_channel, nullptr, "VoiceContentName", kDefaultRtcpEnabled, - kDefaultSrtpRequired); + test_->worker_thread(), test_->network_thread(), nullptr, + test_->media_engine(), voice_media_channel, "VoiceContentName", + kDefaultRtcpEnabled, kDefaultSrtpRequired); cricket::VoiceMediaInfo voice_media_info; @@ -1516,8 +1517,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) { TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) { MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - test_->worker_thread(), test_->network_thread(), video_media_channel, - nullptr, "VideoContentName", kDefaultRtcpEnabled, kDefaultSrtpRequired); + test_->worker_thread(), test_->network_thread(), nullptr, + video_media_channel, "VideoContentName", kDefaultRtcpEnabled, + kDefaultSrtpRequired); cricket::VideoMediaInfo video_media_info; @@ -1594,9 +1596,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) { TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) { MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel(); cricket::VoiceChannel voice_channel( - test_->worker_thread(), test_->network_thread(), test_->media_engine(), - voice_media_channel, nullptr, "VoiceContentName", kDefaultRtcpEnabled, - kDefaultSrtpRequired); + test_->worker_thread(), test_->network_thread(), nullptr, + test_->media_engine(), voice_media_channel, "VoiceContentName", + kDefaultRtcpEnabled, kDefaultSrtpRequired); cricket::VoiceMediaInfo voice_media_info; @@ -1662,8 +1664,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) { TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) { MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - test_->worker_thread(), test_->network_thread(), video_media_channel, - nullptr, "VideoContentName", kDefaultRtcpEnabled, kDefaultSrtpRequired); + test_->worker_thread(), test_->network_thread(), nullptr, + video_media_channel, "VideoContentName", kDefaultRtcpEnabled, + kDefaultSrtpRequired); cricket::VideoMediaInfo video_media_info; @@ -1739,13 +1742,14 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) { TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Default) { MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel(); cricket::VoiceChannel voice_channel( - test_->worker_thread(), test_->network_thread(), test_->media_engine(), - voice_media_channel, nullptr, "VoiceContentName", kDefaultRtcpEnabled, - kDefaultSrtpRequired); + test_->worker_thread(), test_->network_thread(), nullptr, + test_->media_engine(), voice_media_channel, "VoiceContentName", + kDefaultRtcpEnabled, kDefaultSrtpRequired); MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - test_->worker_thread(), test_->network_thread(), video_media_channel, - nullptr, "VideoContentName", kDefaultRtcpEnabled, kDefaultSrtpRequired); + test_->worker_thread(), test_->network_thread(), nullptr, + video_media_channel, "VideoContentName", kDefaultRtcpEnabled, + kDefaultSrtpRequired); cricket::VoiceMediaInfo voice_media_info; voice_media_info.senders.push_back(cricket::VoiceSenderInfo()); diff --git a/webrtc/api/rtpsenderreceiver_unittest.cc b/webrtc/api/rtpsenderreceiver_unittest.cc index a79b2976b6..b6c51841bd 100644 --- a/webrtc/api/rtpsenderreceiver_unittest.cc +++ b/webrtc/api/rtpsenderreceiver_unittest.cc @@ -64,12 +64,17 @@ class RtpSenderReceiverTest : public testing::Test { channel_manager_.Init(); bool rtcp_enabled = false; bool srtp_required = true; + cricket::TransportChannel* rtp_transport = + fake_transport_controller_.CreateTransportChannel( + cricket::CN_AUDIO, cricket::ICE_CANDIDATE_COMPONENT_RTP); voice_channel_ = channel_manager_.CreateVoiceChannel( - &fake_media_controller_, &fake_transport_controller_, cricket::CN_AUDIO, - nullptr, rtcp_enabled, srtp_required, cricket::AudioOptions()); + &fake_media_controller_, rtp_transport, nullptr, rtc::Thread::Current(), + cricket::CN_AUDIO, nullptr, rtcp_enabled, srtp_required, + cricket::AudioOptions()); video_channel_ = channel_manager_.CreateVideoChannel( - &fake_media_controller_, &fake_transport_controller_, cricket::CN_VIDEO, - nullptr, rtcp_enabled, srtp_required, cricket::VideoOptions()); + &fake_media_controller_, rtp_transport, nullptr, rtc::Thread::Current(), + cricket::CN_VIDEO, nullptr, rtcp_enabled, srtp_required, + cricket::VideoOptions()); voice_media_channel_ = media_engine_->GetVoiceChannel(0); video_media_channel_ = media_engine_->GetVideoChannel(0); RTC_CHECK(voice_channel_); diff --git a/webrtc/api/statscollector_unittest.cc b/webrtc/api/statscollector_unittest.cc index 50ae51d6b0..5cabaaf675 100644 --- a/webrtc/api/statscollector_unittest.cc +++ b/webrtc/api/statscollector_unittest.cc @@ -866,7 +866,7 @@ TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) { MockVideoMediaChannel* media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_channel, kVideoChannelName, kDefaultRtcpEnabled, kDefaultSrtpRequired); StatsReports reports; // returned values. cricket::VideoSenderInfo video_sender_info; @@ -915,7 +915,7 @@ TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) { MockVideoMediaChannel* media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_channel, kVideoChannelName, kDefaultRtcpEnabled, kDefaultSrtpRequired); StatsReports reports; // returned values. @@ -991,7 +991,7 @@ TEST_F(StatsCollectorTest, TrackObjectExistsWithoutUpdateStats) { MockVideoMediaChannel* media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, "video", + worker_thread_, network_thread_, nullptr, media_channel, "video", kDefaultRtcpEnabled, kDefaultSrtpRequired); AddOutgoingVideoTrackStats(); stats.AddStream(stream_); @@ -1030,7 +1030,7 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) { MockVideoMediaChannel* media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_channel, kVideoChannelName, kDefaultRtcpEnabled, kDefaultSrtpRequired); AddOutgoingVideoTrackStats(); stats.AddStream(stream_); @@ -1099,7 +1099,7 @@ TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) { // The transport_name known by the video channel. const std::string kVcName("vcname"); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, kVcName, + worker_thread_, network_thread_, nullptr, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); AddOutgoingVideoTrackStats(); stats.AddStream(stream_); @@ -1160,7 +1160,7 @@ TEST_F(StatsCollectorTest, RemoteSsrcInfoIsAbsent) { // The transport_name known by the video channel. const std::string kVcName("vcname"); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, kVcName, + worker_thread_, network_thread_, nullptr, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); AddOutgoingVideoTrackStats(); stats.AddStream(stream_); @@ -1187,7 +1187,7 @@ TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) { // The transport_name known by the video channel. const std::string kVcName("vcname"); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, kVcName, + worker_thread_, network_thread_, nullptr, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); AddOutgoingVideoTrackStats(); stats.AddStream(stream_); @@ -1247,7 +1247,7 @@ TEST_F(StatsCollectorTest, ReportsFromRemoteTrack) { MockVideoMediaChannel* media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_channel, kVideoChannelName, kDefaultRtcpEnabled, kDefaultSrtpRequired); AddIncomingVideoTrackStats(); stats.AddStream(stream_); @@ -1560,7 +1560,7 @@ TEST_F(StatsCollectorTest, FilterOutNegativeInitialValues) { // The transport_name known by the voice channel. const std::string kVcName("vcname"); cricket::VoiceChannel voice_channel( - worker_thread_, network_thread_, media_engine_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_engine_, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); // Create a local stream with a local audio track and adds it to the stats. @@ -1670,7 +1670,7 @@ TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) { // The transport_name known by the voice channel. const std::string kVcName("vcname"); cricket::VoiceChannel voice_channel( - worker_thread_, network_thread_, media_engine_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_engine_, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); AddOutgoingAudioTrackStats(); stats.AddStream(stream_); @@ -1706,7 +1706,7 @@ TEST_F(StatsCollectorTest, GetStatsFromRemoteStream) { // The transport_name known by the voice channel. const std::string kVcName("vcname"); cricket::VoiceChannel voice_channel( - worker_thread_, network_thread_, media_engine_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_engine_, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); AddIncomingAudioTrackStats(); stats.AddStream(stream_); @@ -1736,7 +1736,7 @@ TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) { // The transport_name known by the voice channel. const std::string kVcName("vcname"); cricket::VoiceChannel voice_channel( - worker_thread_, network_thread_, media_engine_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_engine_, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); AddOutgoingAudioTrackStats(); stats.AddStream(stream_); @@ -1800,7 +1800,7 @@ TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) { // The transport_name known by the voice channel. const std::string kVcName("vcname"); cricket::VoiceChannel voice_channel( - worker_thread_, network_thread_, media_engine_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_engine_, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); // Create a local stream with a local audio track and adds it to the stats. @@ -1890,7 +1890,7 @@ TEST_F(StatsCollectorTest, TwoLocalTracksWithSameSsrc) { // The transport_name known by the voice channel. const std::string kVcName("vcname"); cricket::VoiceChannel voice_channel( - worker_thread_, network_thread_, media_engine_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_engine_, media_channel, kVcName, kDefaultRtcpEnabled, kDefaultSrtpRequired); // Create a local stream with a local audio track and adds it to the stats. @@ -1950,7 +1950,7 @@ TEST_F(StatsCollectorTest, VerifyVideoSendSsrcStats) { MockVideoMediaChannel* media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_channel, kVideoChannelName, kDefaultRtcpEnabled, kDefaultSrtpRequired); StatsReports reports; // returned values. cricket::VideoSenderInfo video_sender_info; @@ -1998,7 +1998,7 @@ TEST_F(StatsCollectorTest, VerifyVideoReceiveSsrcStats) { MockVideoMediaChannel* media_channel = new MockVideoMediaChannel(); cricket::VideoChannel video_channel( - worker_thread_, network_thread_, media_channel, nullptr, + worker_thread_, network_thread_, nullptr, media_channel, kVideoChannelName, kDefaultRtcpEnabled, kDefaultSrtpRequired); StatsReports reports; // returned values. cricket::VideoReceiverInfo video_receiver_info; diff --git a/webrtc/api/webrtcsession.cc b/webrtc/api/webrtcsession.cc index 94ebc07f05..aa172cef37 100644 --- a/webrtc/api/webrtcsession.cc +++ b/webrtc/api/webrtcsession.cc @@ -506,16 +506,13 @@ WebRtcSession::~WebRtcSession() { // Destroy video_channel_ first since it may have a pointer to the // voice_channel_. if (video_channel_) { - SignalVideoChannelDestroyed(); - channel_manager_->DestroyVideoChannel(video_channel_.release()); + DestroyVideoChannel(); } if (voice_channel_) { - SignalVoiceChannelDestroyed(); - channel_manager_->DestroyVoiceChannel(voice_channel_.release()); + DestroyVoiceChannel(); } if (rtp_data_channel_) { - SignalDataChannelDestroyed(); - channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release()); + DestroyDataChannel(); } if (sctp_transport_) { SignalDataChannelDestroyed(); @@ -736,14 +733,12 @@ bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc, if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) { return false; } - if (remote_description()) { // Now that we have a local description, we can push down remote candidates. UseCandidatesInSessionDescription(remote_description()); } pending_ice_restarts_.clear(); - if (error() != ERROR_NONE) { return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); } @@ -1074,25 +1069,42 @@ bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) { << " on " << transport_name << "with QUIC."; } #endif - auto maybe_set_transport = [this, bundle, transport_name](cricket::BaseChannel* ch) { if (!ch || !bundle.HasContentName(ch->content_name())) { return true; } - if (ch->transport_name() == transport_name) { + std::string old_transport_name = ch->transport_name(); + if (old_transport_name == transport_name) { LOG(LS_INFO) << "BUNDLE already enabled for " << ch->content_name() << " on " << transport_name << "."; return true; } - if (!ch->SetTransport(transport_name)) { + cricket::TransportChannel* rtp_transport = + transport_controller_->CreateTransportChannel( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + bool need_rtcp = (ch->rtcp_transport() != nullptr); + cricket::TransportChannel* rtcp_transport = nullptr; + if (need_rtcp) { + rtcp_transport = transport_controller_->CreateTransportChannel_n( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + + if (!ch->SetTransport(rtp_transport, rtcp_transport)) { LOG(LS_WARNING) << "Failed to enable BUNDLE for " << ch->content_name(); return false; } LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on " << transport_name << "."; + DestroyTransport(old_transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + // If the channel needs rtcp, it means that the channel used to have a + // rtcp transport which needs to be deleted now. + if (need_rtcp) { + DestroyTransport(old_transport_name, + cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } return true; }; @@ -1680,23 +1692,20 @@ void WebRtcSession::RemoveUnusedChannels(const SessionDescription* desc) { const cricket::ContentInfo* video_info = cricket::GetFirstVideoContent(desc); if ((!video_info || video_info->rejected) && video_channel_) { - SignalVideoChannelDestroyed(); - channel_manager_->DestroyVideoChannel(video_channel_.release()); + DestroyVideoChannel(); } const cricket::ContentInfo* voice_info = cricket::GetFirstAudioContent(desc); if ((!voice_info || voice_info->rejected) && voice_channel_) { - SignalVoiceChannelDestroyed(); - channel_manager_->DestroyVoiceChannel(voice_channel_.release()); + DestroyVoiceChannel(); } const cricket::ContentInfo* data_info = cricket::GetFirstDataContent(desc); if (!data_info || data_info->rejected) { if (rtp_data_channel_) { - SignalDataChannelDestroyed(); - channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release()); + DestroyDataChannel(); } if (sctp_transport_) { SignalDataChannelDestroyed(); @@ -1779,13 +1788,30 @@ bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content, bool require_rtcp_mux = rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; bool create_rtcp_transport_channel = !require_rtcp_mux; + + std::string transport_name = + bundle_transport ? *bundle_transport : content->name; + + cricket::TransportChannel* rtp_transport = + transport_controller_->CreateTransportChannel( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + cricket::TransportChannel* rtcp_transport = nullptr; + if (create_rtcp_transport_channel) { + rtcp_transport = transport_controller_->CreateTransportChannel( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + voice_channel_.reset(channel_manager_->CreateVoiceChannel( - media_controller_, transport_controller_.get(), content->name, + media_controller_, rtp_transport, rtcp_transport, + transport_controller_->signaling_thread(), content->name, bundle_transport, create_rtcp_transport_channel, SrtpRequired(), audio_options_)); if (!voice_channel_) { return false; } + + voice_channel_->SignalDestroyRtcpTransport.connect( + this, &WebRtcSession::OnDestroyRtcpTransport_n); if (require_rtcp_mux) { voice_channel_->ActivateRtcpMux(); } @@ -1804,13 +1830,31 @@ bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content, bool require_rtcp_mux = rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; bool create_rtcp_transport_channel = !require_rtcp_mux; + + std::string transport_name = + bundle_transport ? *bundle_transport : content->name; + + cricket::TransportChannel* rtp_transport = + transport_controller_->CreateTransportChannel( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + cricket::TransportChannel* rtcp_transport = nullptr; + if (create_rtcp_transport_channel) { + rtcp_transport = transport_controller_->CreateTransportChannel( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + video_channel_.reset(channel_manager_->CreateVideoChannel( - media_controller_, transport_controller_.get(), content->name, + media_controller_, rtp_transport, rtcp_transport, + transport_controller_->signaling_thread(), content->name, bundle_transport, create_rtcp_transport_channel, SrtpRequired(), video_options_)); + if (!video_channel_) { return false; } + + video_channel_->SignalDestroyRtcpTransport.connect( + this, &WebRtcSession::OnDestroyRtcpTransport_n); if (require_rtcp_mux) { video_channel_->ActivateRtcpMux(); } @@ -1851,12 +1895,30 @@ bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content, bool require_rtcp_mux = rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; bool create_rtcp_transport_channel = !sctp && !require_rtcp_mux; + + std::string transport_name = + bundle_transport ? *bundle_transport : content->name; + cricket::TransportChannel* rtp_transport = + transport_controller_->CreateTransportChannel( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + cricket::TransportChannel* rtcp_transport = nullptr; + if (create_rtcp_transport_channel) { + rtcp_transport = transport_controller_->CreateTransportChannel( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + rtp_data_channel_.reset(channel_manager_->CreateRtpDataChannel( - media_controller_, transport_controller_.get(), content->name, + media_controller_, rtp_transport, rtcp_transport, + transport_controller_->signaling_thread(), content->name, bundle_transport, create_rtcp_transport_channel, SrtpRequired())); + if (!rtp_data_channel_) { return false; } + + rtp_data_channel_->SignalDestroyRtcpTransport.connect( + this, &WebRtcSession::OnDestroyRtcpTransport_n); + if (require_rtcp_mux) { rtp_data_channel_->ActivateRtcpMux(); } @@ -1867,6 +1929,7 @@ bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content, } SignalDataChannelCreated(); + return true; } @@ -2318,4 +2381,57 @@ const std::string WebRtcSession::GetTransportName( return channel->transport_name(); } +void WebRtcSession::DestroyTransport(const std::string& transport_name, + int component) { + network_thread_->Invoke( + RTC_FROM_HERE, + rtc::Bind(&cricket::TransportController::DestroyTransportChannel_n, + transport_controller_.get(), transport_name, component)); +} + +void WebRtcSession::OnDestroyRtcpTransport_n( + const std::string& transport_name) { + ASSERT(network_thread()->IsCurrent()); + transport_controller_->DestroyTransportChannel_n( + transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); +} + +void WebRtcSession::DestroyVideoChannel() { + SignalVideoChannelDestroyed(); + RTC_DCHECK(video_channel_->rtp_transport()); + std::string transport_name; + transport_name = video_channel_->rtp_transport()->transport_name(); + bool need_to_delete_rtcp = (video_channel_->rtcp_transport() != nullptr); + channel_manager_->DestroyVideoChannel(video_channel_.release()); + DestroyTransport(transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + if (need_to_delete_rtcp) { + DestroyTransport(transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } +} + +void WebRtcSession::DestroyVoiceChannel() { + SignalVoiceChannelDestroyed(); + RTC_DCHECK(voice_channel_->rtp_transport()); + std::string transport_name; + transport_name = voice_channel_->rtp_transport()->transport_name(); + bool need_to_delete_rtcp = (voice_channel_->rtcp_transport() != nullptr); + channel_manager_->DestroyVoiceChannel(voice_channel_.release()); + DestroyTransport(transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + if (need_to_delete_rtcp) { + DestroyTransport(transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } +} + +void WebRtcSession::DestroyDataChannel() { + SignalDataChannelDestroyed(); + RTC_DCHECK(rtp_data_channel_->rtp_transport()); + std::string transport_name; + transport_name = rtp_data_channel_->rtp_transport()->transport_name(); + bool need_to_delete_rtcp = (rtp_data_channel_->rtcp_transport() != nullptr); + channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release()); + DestroyTransport(transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + if (need_to_delete_rtcp) { + DestroyTransport(transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } +} } // namespace webrtc diff --git a/webrtc/api/webrtcsession.h b/webrtc/api/webrtcsession.h index e346112cba..42e0e4bc0d 100644 --- a/webrtc/api/webrtcsession.h +++ b/webrtc/api/webrtcsession.h @@ -553,6 +553,12 @@ class WebRtcSession : const std::string GetTransportName(const std::string& content_name); + void DestroyTransport(const std::string& transport_name, int component); + void OnDestroyRtcpTransport_n(const std::string& transport_name); + void DestroyVideoChannel(); + void DestroyVoiceChannel(); + void DestroyDataChannel(); + rtc::Thread* const network_thread_; rtc::Thread* const worker_thread_; rtc::Thread* const signaling_thread_; diff --git a/webrtc/api/webrtcsession_unittest.cc b/webrtc/api/webrtcsession_unittest.cc index f739c16abe..3e1a5833e5 100644 --- a/webrtc/api/webrtcsession_unittest.cc +++ b/webrtc/api/webrtcsession_unittest.cc @@ -306,7 +306,7 @@ class WebRtcSessionForTest : public webrtc::WebRtcSession { if (!ch) { return nullptr; } - return ch->transport_channel(); + return ch->rtp_transport(); } rtc::PacketTransportInterface* rtcp_transport_channel( @@ -314,7 +314,7 @@ class WebRtcSessionForTest : public webrtc::WebRtcSession { if (!ch) { return nullptr; } - return ch->rtcp_transport_channel(); + return ch->rtcp_transport(); } }; diff --git a/webrtc/p2p/base/faketransportcontroller.h b/webrtc/p2p/base/faketransportcontroller.h index 28eb86caca..a73d464ece 100644 --- a/webrtc/p2p/base/faketransportcontroller.h +++ b/webrtc/p2p/base/faketransportcontroller.h @@ -665,6 +665,11 @@ class FakeTransportController : public TransportController { return new FakeCandidatePair(local_candidate, remote_candidate); } + void DestroyRtcpTransport(const std::string& transport_name) { + DestroyTransportChannel_n(transport_name, + cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + protected: // The ICE channel is never actually used by TransportController directly, // since (currently) the DTLS channel pretends to be both ICE + DTLS. This diff --git a/webrtc/p2p/base/transportcontroller.cc b/webrtc/p2p/base/transportcontroller.cc index 2781b0ba21..810b96e8d1 100644 --- a/webrtc/p2p/base/transportcontroller.cc +++ b/webrtc/p2p/base/transportcontroller.cc @@ -227,6 +227,14 @@ void TransportController::SetMetricsObserver( metrics_observer)); } +TransportChannel* TransportController::CreateTransportChannel( + const std::string& transport_name, + int component) { + return network_thread_->Invoke( + RTC_FROM_HERE, rtc::Bind(&TransportController::CreateTransportChannel_n, + this, transport_name, component)); +} + TransportChannel* TransportController::CreateTransportChannel_n( const std::string& transport_name, int component) { @@ -292,7 +300,6 @@ void TransportController::DestroyTransportChannel_n( const std::string& transport_name, int component) { RTC_DCHECK(network_thread_->IsCurrent()); - auto it = GetChannelIterator_n(transport_name, component); if (it == channels_.end()) { LOG(LS_WARNING) << "Attempting to delete " << transport_name @@ -313,7 +320,6 @@ void TransportController::DestroyTransportChannel_n( if (!t->HasChannels()) { transports_.erase(transport_name); } - // Removing a channel could cause aggregate state to change. UpdateAggregateStates_n(); } diff --git a/webrtc/p2p/base/transportcontroller.h b/webrtc/p2p/base/transportcontroller.h index 7929cf0140..147d568a2e 100644 --- a/webrtc/p2p/base/transportcontroller.h +++ b/webrtc/p2p/base/transportcontroller.h @@ -113,6 +113,8 @@ class TransportController : public sigslot::has_slots<>, // Creates a channel if it doesn't exist. Otherwise, increments a reference // count and returns an existing channel. + TransportChannel* CreateTransportChannel(const std::string& transport_name, + int component); virtual TransportChannel* CreateTransportChannel_n( const std::string& transport_name, int component); diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc index 45141c8d0f..182d4cafcd 100644 --- a/webrtc/pc/channel.cc +++ b/webrtc/pc/channel.cc @@ -160,25 +160,20 @@ void RtpSendParametersFromMediaDescription( BaseChannel::BaseChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, + rtc::Thread* signaling_thread, MediaChannel* media_channel, - TransportController* transport_controller, const std::string& content_name, bool rtcp, bool srtp_required) : worker_thread_(worker_thread), network_thread_(network_thread), - + signaling_thread_(signaling_thread), content_name_(content_name), - - transport_controller_(transport_controller), rtcp_enabled_(rtcp), srtp_required_(srtp_required), media_channel_(media_channel), selected_candidate_pair_(nullptr) { RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); - if (transport_controller) { - RTC_DCHECK_EQ(network_thread, transport_controller->network_thread()); - } LOG(LS_INFO) << "Created channel for " << content_name; } @@ -194,11 +189,7 @@ BaseChannel::~BaseChannel() { // the media channel may try to send on the dead transport channel. NULLing // is not an effective strategy since the sends will come on another thread. delete media_channel_; - // Note that we don't just call SetTransportChannel_n(nullptr) because that - // would call a pure virtual method which we can't do from a destructor. - network_thread_->Invoke( - RTC_FROM_HERE, Bind(&BaseChannel::DestroyTransportChannels_n, this)); - LOG(LS_INFO) << "Destroyed channel"; + LOG(LS_INFO) << "Destroyed channel: " << content_name_; } void BaseChannel::DisconnectTransportChannels_n() { @@ -207,11 +198,11 @@ void BaseChannel::DisconnectTransportChannels_n() { // Stop signals from transport channels, but keep them alive because // media_channel may use them from a different thread. - if (transport_channel_) { - DisconnectFromTransportChannel(transport_channel_); + if (rtp_transport_) { + DisconnectFromTransportChannel(rtp_transport_); } - if (rtcp_transport_channel_) { - DisconnectFromTransportChannel(rtcp_transport_channel_); + if (rtcp_transport_) { + DisconnectFromTransportChannel(rtcp_transport_); } // Clear pending read packets/messages. @@ -219,24 +210,11 @@ void BaseChannel::DisconnectTransportChannels_n() { network_thread_->Clear(this); } -void BaseChannel::DestroyTransportChannels_n() { - if (transport_channel_) { - transport_controller_->DestroyTransportChannel_n( - transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP); - } - if (rtcp_transport_channel_) { - transport_controller_->DestroyTransportChannel_n( - transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); - } - // Clear pending send packets/messages. - network_thread_->Clear(&invoker_); - network_thread_->Clear(this); -} - -bool BaseChannel::Init_w(const std::string* bundle_transport_name) { +bool BaseChannel::Init_w(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport) { if (!network_thread_->Invoke( - RTC_FROM_HERE, - Bind(&BaseChannel::InitNetwork_n, this, bundle_transport_name))) { + RTC_FROM_HERE, Bind(&BaseChannel::InitNetwork_n, this, rtp_transport, + rtcp_transport))) { return false; } @@ -247,19 +225,19 @@ bool BaseChannel::Init_w(const std::string* bundle_transport_name) { return true; } -bool BaseChannel::InitNetwork_n(const std::string* bundle_transport_name) { +bool BaseChannel::InitNetwork_n(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport) { RTC_DCHECK(network_thread_->IsCurrent()); - const std::string& transport_name = - (bundle_transport_name ? *bundle_transport_name : content_name()); - if (!SetTransport_n(transport_name)) { + // const std::string& transport_name = + // (bundle_transport_name ? *bundle_transport_name : content_name()); + if (!SetTransport_n(rtp_transport, rtcp_transport)) { return false; } - if (!SetDtlsSrtpCryptoSuites_n(transport_channel_, false)) { + if (!SetDtlsSrtpCryptoSuites_n(rtp_transport_, false)) { return false; } - if (rtcp_transport_channel_ && - !SetDtlsSrtpCryptoSuites_n(rtcp_transport_channel_, true)) { + if (rtcp_transport_ && !SetDtlsSrtpCryptoSuites_n(rtcp_transport_, true)) { return false; } return true; @@ -275,19 +253,34 @@ void BaseChannel::Deinit() { RTC_FROM_HERE, Bind(&BaseChannel::DisconnectTransportChannels_n, this)); } -bool BaseChannel::SetTransport(const std::string& transport_name) { +bool BaseChannel::SetTransport(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport) { return network_thread_->Invoke( - RTC_FROM_HERE, Bind(&BaseChannel::SetTransport_n, this, transport_name)); + RTC_FROM_HERE, + Bind(&BaseChannel::SetTransport_n, this, rtp_transport, rtcp_transport)); } -bool BaseChannel::SetTransport_n(const std::string& transport_name) { +bool BaseChannel::SetTransport_n(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport) { RTC_DCHECK(network_thread_->IsCurrent()); + if (!rtp_transport && !rtcp_transport) { + LOG(LS_ERROR) << "Setting nullptr to RTP Transport and RTCP Transport."; + return false; + } - if (transport_name == transport_name_) { + if (rtcp_transport) { + RTC_DCHECK(rtp_transport->transport_name() == + rtcp_transport->transport_name()); + RTC_DCHECK(NeedsRtcpTransport()); + } + + if (rtp_transport->transport_name() == transport_name_) { // Nothing to do if transport name isn't changing. return true; } + transport_name_ = rtp_transport->transport_name(); + // When using DTLS-SRTP, we must reset the SrtpFilter every time the transport // changes and wait until the DTLS handshake is complete to set the newly // negotiated parameters. @@ -300,28 +293,22 @@ bool BaseChannel::SetTransport_n(const std::string& transport_name) { // If this BaseChannel uses RTCP and we haven't fully negotiated RTCP mux, // we need an RTCP channel. - if (rtcp_enabled_ && !rtcp_mux_filter_.IsFullyActive()) { - LOG(LS_INFO) << "Create RTCP TransportChannel for " << content_name() - << " on " << transport_name << " transport "; - SetTransportChannel_n( - true, transport_controller_->CreateTransportChannel_n( - transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP)); - if (!rtcp_transport_channel_) { + if (NeedsRtcpTransport()) { + LOG(LS_INFO) << "Setting RTCP Transport for " << content_name() << " on " + << transport_name() << " transport " << rtcp_transport; + SetTransportChannel_n(true, rtcp_transport); + if (!rtcp_transport_) { return false; } } - LOG(LS_INFO) << "Create non-RTCP TransportChannel for " << content_name() - << " on " << transport_name << " transport "; - SetTransportChannel_n( - false, transport_controller_->CreateTransportChannel_n( - transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP)); - if (!transport_channel_) { + LOG(LS_INFO) << "Setting non-RTCP Transport for " << content_name() << " on " + << transport_name() << " transport " << rtp_transport; + SetTransportChannel_n(false, rtp_transport); + if (!rtp_transport_) { return false; } - transport_name_ = transport_name; - // Update aggregate writable/ready-to-send state between RTP and RTCP upon // setting new transport channels. UpdateWritableState_n(); @@ -334,44 +321,38 @@ bool BaseChannel::SetTransport_n(const std::string& transport_name) { // This won't always be accurate (the last SendPacket call from another // 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_transport_ && rtp_transport_->writable()); SetTransportChannelReadyToSend( - false, transport_channel_ && transport_channel_->writable()); - SetTransportChannelReadyToSend( - true, rtcp_transport_channel_ && rtcp_transport_channel_->writable()); + true, rtcp_transport_ && rtcp_transport_->writable()); return true; } void BaseChannel::SetTransportChannel_n(bool rtcp, - TransportChannel* new_channel) { + TransportChannel* new_transport) { RTC_DCHECK(network_thread_->IsCurrent()); - TransportChannel*& old_channel = - rtcp ? rtcp_transport_channel_ : transport_channel_; - - if (!old_channel && !new_channel) { + TransportChannel*& old_transport = rtcp ? rtcp_transport_ : rtp_transport_; + if (!old_transport && !new_transport) { // Nothing to do. return; } - RTC_DCHECK(old_channel != new_channel); - - if (old_channel) { - DisconnectFromTransportChannel(old_channel); - transport_controller_->DestroyTransportChannel_n( - transport_name_, rtcp ? cricket::ICE_CANDIDATE_COMPONENT_RTCP - : cricket::ICE_CANDIDATE_COMPONENT_RTP); + RTC_DCHECK(old_transport != new_transport); + if (old_transport) { + DisconnectFromTransportChannel(old_transport); } - old_channel = new_channel; + old_transport = new_transport; - if (new_channel) { + if (new_transport) { if (rtcp) { RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_filter_.IsActive())) << "Setting RTCP for DTLS/SRTP after SrtpFilter is active " << "should never happen."; } - ConnectToTransportChannel(new_channel); + ConnectToTransportChannel(new_transport); auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_; for (const auto& pair : socket_options) { - new_channel->SetOption(pair.first, pair.second); + new_transport->SetOption(pair.first, pair.second); } } } @@ -445,8 +426,8 @@ bool BaseChannel::SetRemoteContent(const MediaContentDescription* content, } void BaseChannel::StartConnectionMonitor(int cms) { - // We pass in the BaseChannel instead of the transport_channel_ - // because if the transport_channel_ changes, the ConnectionMonitor + // We pass in the BaseChannel instead of the rtp_transport_ + // because if the rtp_transport_ changes, the ConnectionMonitor // would be pointing to the wrong TransportChannel. // We pass in the network thread because on that thread connection monitor // will call BaseChannel::GetConnectionStats which must be called on the @@ -467,7 +448,11 @@ void BaseChannel::StopConnectionMonitor() { bool BaseChannel::GetConnectionStats(ConnectionInfos* infos) { RTC_DCHECK(network_thread_->IsCurrent()); - return transport_channel_->GetStats(infos); + return rtp_transport_->GetStats(infos); +} + +bool BaseChannel::NeedsRtcpTransport() { + return rtcp_enabled_ && !rtcp_mux_filter_.IsFullyActive(); } bool BaseChannel::IsReadyToReceiveMedia_w() const { @@ -513,12 +498,12 @@ int BaseChannel::SetOption_n(SocketType type, TransportChannel* channel = nullptr; switch (type) { case ST_RTP: - channel = transport_channel_; + channel = rtp_transport_; socket_options_.push_back( std::pair(opt, value)); break; case ST_RTCP: - channel = rtcp_transport_channel_; + channel = rtcp_transport_; rtcp_socket_options_.push_back( std::pair(opt, value)); break; @@ -532,8 +517,7 @@ bool BaseChannel::SetCryptoOptions(const rtc::CryptoOptions& crypto_options) { } void BaseChannel::OnWritableState(rtc::PacketTransportInterface* transport) { - RTC_DCHECK(transport == transport_channel_ || - transport == rtcp_transport_channel_); + RTC_DCHECK(transport == rtp_transport_ || transport == rtcp_transport_); RTC_DCHECK(network_thread_->IsCurrent()); UpdateWritableState_n(); } @@ -555,9 +539,8 @@ void BaseChannel::OnPacketRead(rtc::PacketTransportInterface* transport, } void BaseChannel::OnReadyToSend(rtc::PacketTransportInterface* transport) { - RTC_DCHECK(transport == transport_channel_ || - transport == rtcp_transport_channel_); - SetTransportChannelReadyToSend(transport == rtcp_transport_channel_, true); + RTC_DCHECK(transport == rtp_transport_ || transport == rtcp_transport_); + SetTransportChannelReadyToSend(transport == rtcp_transport_, true); } void BaseChannel::OnDtlsState(TransportChannel* channel, @@ -581,8 +564,7 @@ void BaseChannel::OnSelectedCandidatePairChanged( CandidatePairInterface* selected_candidate_pair, int last_sent_packet_id, bool ready_to_send) { - RTC_DCHECK(channel == transport_channel_ || - channel == rtcp_transport_channel_); + RTC_DCHECK(channel == rtp_transport_ || channel == rtcp_transport_); RTC_DCHECK(network_thread_->IsCurrent()); selected_candidate_pair_ = selected_candidate_pair; std::string transport_name = channel->transport_name(); @@ -611,8 +593,8 @@ void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) { bool ready_to_send = (rtp_ready_to_send_ && - // In the case of rtcp mux |rtcp_transport_channel_| will be null. - (rtcp_ready_to_send_ || !rtcp_transport_channel_)); + // In the case of rtcp mux |rtcp_transport_| will be null. + (rtcp_ready_to_send_ || !rtcp_transport_)); invoker_.AsyncInvoke( RTC_FROM_HERE, worker_thread_, @@ -622,7 +604,7 @@ void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) { bool BaseChannel::PacketIsRtcp(const rtc::PacketTransportInterface* transport, const char* data, size_t len) { - return (transport == rtcp_transport_channel_ || + return (transport == rtcp_transport_ || rtcp_mux_filter_.DemuxRtcp(data, static_cast(len))); } @@ -651,8 +633,8 @@ bool BaseChannel::SendPacket(bool rtcp, // packet before doing anything. (We might get RTCP packets that we don't // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP // transport. - TransportChannel* channel = (!rtcp || rtcp_mux_filter_.IsActive()) ? - transport_channel_ : rtcp_transport_channel_; + TransportChannel* channel = + (!rtcp || rtcp_mux_filter_.IsActive()) ? rtp_transport_ : rtcp_transport_; if (!channel || !channel->writable()) { return false; } @@ -900,8 +882,8 @@ void BaseChannel::DisableMedia_w() { } void BaseChannel::UpdateWritableState_n() { - if (transport_channel_ && transport_channel_->writable() && - (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { + if (rtp_transport_ && rtp_transport_->writable() && + (!rtcp_transport_ || rtcp_transport_->writable())) { ChannelWritable_n(); } else { ChannelNotWritable_n(); @@ -956,7 +938,7 @@ bool BaseChannel::SetDtlsSrtpCryptoSuites_n(TransportChannel* tc, bool rtcp) { bool BaseChannel::ShouldSetupDtlsSrtp_n() const { // Since DTLS is applied to all channels, checking RTP should be enough. - return transport_channel_ && transport_channel_->IsDtlsActive(); + return rtp_transport_ && rtp_transport_->IsDtlsActive(); } // This function returns true if either DTLS-SRTP is not in use @@ -965,8 +947,7 @@ bool BaseChannel::SetupDtlsSrtp_n(bool rtcp_channel) { RTC_DCHECK(network_thread_->IsCurrent()); bool ret = false; - TransportChannel* channel = - rtcp_channel ? rtcp_transport_channel_ : transport_channel_; + TransportChannel* channel = rtcp_channel ? rtcp_transport_ : rtp_transport_; RTC_DCHECK(channel->IsDtlsActive()); @@ -1064,7 +1045,7 @@ void BaseChannel::MaybeSetupDtlsSrtp_n() { return; } - if (rtcp_transport_channel_) { + if (rtcp_transport_) { if (!SetupDtlsSrtp_n(true)) { SignalDtlsSrtpSetupFailure_n(true); return; @@ -1121,7 +1102,7 @@ bool BaseChannel::SetRtpTransportParameters_n( bool BaseChannel::CheckSrtpConfig_n(const std::vector& cryptos, bool* dtls, std::string* error_desc) { - *dtls = transport_channel_->IsDtlsActive(); + *dtls = rtp_transport_->IsDtlsActive(); if (*dtls && !cryptos.empty()) { SafeSetError("Cryptos must be empty when DTLS is active.", error_desc); return false; @@ -1184,7 +1165,11 @@ void BaseChannel::ActivateRtcpMux() { void BaseChannel::ActivateRtcpMux_n() { if (!rtcp_mux_filter_.IsActive()) { rtcp_mux_filter_.SetActive(); + bool need_to_delete_rtcp = (rtcp_transport() != nullptr); SetTransportChannel_n(true, nullptr); + if (need_to_delete_rtcp) { + SignalDestroyRtcpTransport(rtp_transport()->transport_name()); + } // Update aggregate writable/ready-to-send state between RTP and RTCP upon // removing channel. UpdateWritableState_n(); @@ -1213,7 +1198,11 @@ bool BaseChannel::SetRtcpMux_n(bool enable, LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name() << " by destroying RTCP transport channel for " << transport_name(); + bool need_to_delete_rtcp = (rtcp_transport() != nullptr); SetTransportChannel_n(true, nullptr); + if (need_to_delete_rtcp) { + SignalDestroyRtcpTransport(rtp_transport()->transport_name()); + } UpdateWritableState_n(); SetTransportChannelReadyToSend(true, false); } @@ -1234,7 +1223,7 @@ bool BaseChannel::SetRtcpMux_n(bool enable, // received a final answer. if (rtcp_mux_filter_.IsActive()) { // If the RTP transport is already writable, then so are we. - if (transport_channel_->writable()) { + if (rtp_transport_->writable()) { ChannelWritable_n(); } } @@ -1469,16 +1458,16 @@ void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) { VoiceChannel::VoiceChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, + rtc::Thread* signaling_thread, MediaEngineInterface* media_engine, VoiceMediaChannel* media_channel, - TransportController* transport_controller, const std::string& content_name, bool rtcp, bool srtp_required) : BaseChannel(worker_thread, network_thread, + signaling_thread, media_channel, - transport_controller, content_name, rtcp, srtp_required), @@ -1494,11 +1483,9 @@ VoiceChannel::~VoiceChannel() { Deinit(); } -bool VoiceChannel::Init_w(const std::string* bundle_transport_name) { - if (!BaseChannel::Init_w(bundle_transport_name)) { - return false; - } - return true; +bool VoiceChannel::Init_w(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport) { + return BaseChannel::Init_w(rtp_transport, rtcp_transport); } bool VoiceChannel::SetAudioSend(uint32_t ssrc, @@ -1885,24 +1872,22 @@ void VoiceChannel::GetSrtpCryptoSuites_n( VideoChannel::VideoChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, + rtc::Thread* signaling_thread, VideoMediaChannel* media_channel, - TransportController* transport_controller, const std::string& content_name, bool rtcp, bool srtp_required) : BaseChannel(worker_thread, network_thread, + signaling_thread, media_channel, - transport_controller, content_name, rtcp, srtp_required) {} -bool VideoChannel::Init_w(const std::string* bundle_transport_name) { - if (!BaseChannel::Init_w(bundle_transport_name)) { - return false; - } - return true; +bool VideoChannel::Init_w(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport) { + return BaseChannel::Init_w(rtp_transport, rtcp_transport); } VideoChannel::~VideoChannel() { @@ -2148,15 +2133,15 @@ void VideoChannel::GetSrtpCryptoSuites_n( RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, + rtc::Thread* signaling_thread, DataMediaChannel* media_channel, - TransportController* transport_controller, const std::string& content_name, bool rtcp, bool srtp_required) : BaseChannel(worker_thread, network_thread, + signaling_thread, media_channel, - transport_controller, content_name, rtcp, srtp_required) {} @@ -2170,8 +2155,9 @@ RtpDataChannel::~RtpDataChannel() { Deinit(); } -bool RtpDataChannel::Init_w(const std::string* bundle_transport_name) { - if (!BaseChannel::Init_w(bundle_transport_name)) { +bool RtpDataChannel::Init_w(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport) { + if (!BaseChannel::Init_w(rtp_transport, rtcp_transport)) { return false; } media_channel()->SignalDataReceived.connect(this, diff --git a/webrtc/pc/channel.h b/webrtc/pc/channel.h index ff98a2fb27..e5180ca26f 100644 --- a/webrtc/pc/channel.h +++ b/webrtc/pc/channel.h @@ -80,13 +80,14 @@ class BaseChannel // RTP/RTCP packets without using SRTP (either using SDES or DTLS-SRTP). BaseChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, + rtc::Thread* signaling_thread, MediaChannel* channel, - TransportController* transport_controller, const std::string& content_name, bool rtcp, bool srtp_required); virtual ~BaseChannel(); - bool Init_w(const std::string* bundle_transport_name); + bool Init_w(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport); // Deinit may be called multiple times and is simply ignored if it's already // done. void Deinit(); @@ -111,7 +112,8 @@ class BaseChannel // description doesn't support RTCP mux, setting the remote // description will fail. void ActivateRtcpMux(); - bool SetTransport(const std::string& transport_name); + bool SetTransport(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport); bool PushdownLocalDescription(const SessionDescription* local_desc, ContentAction action, std::string* error_desc); @@ -159,11 +161,14 @@ class BaseChannel // Forward TransportChannel SignalSentPacket to worker thread. sigslot::signal1 SignalSentPacket; - // Only public for unit tests. Otherwise, consider private. - TransportChannel* transport_channel() const { return transport_channel_; } - TransportChannel* rtcp_transport_channel() const { - return rtcp_transport_channel_; - } + // Emitted whenever the rtcp-mux is active and the rtcp-transport can be + // destroyed. + sigslot::signal1 SignalDestroyRtcpTransport; + + TransportChannel* rtp_transport() const { return rtp_transport_; } + TransportChannel* rtcp_transport() const { return rtcp_transport_; } + + bool NeedsRtcpTransport(); // Made public for easier testing. // @@ -193,15 +198,15 @@ class BaseChannel protected: virtual MediaChannel* media_channel() const { return media_channel_; } - // Sets the |transport_channel_| (and |rtcp_transport_channel_|, if - // |rtcp_enabled_| is true). Gets the transport channels from - // |transport_controller_|. + // Sets the |rtp_transport_| (and |rtcp_transport_|, if + // |rtcp_enabled_| is true). // This method also updates writability and "ready-to-send" state. - bool SetTransport_n(const std::string& transport_name); + bool SetTransport_n(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport); // This does not update writability or "ready-to-send" state; it just // disconnects from the old channel and connects to the new one. - void SetTransportChannel_n(bool rtcp, TransportChannel* new_channel); + void SetTransportChannel_n(bool rtcp, TransportChannel* new_transport); bool was_ever_writable() const { return was_ever_writable_; } void set_local_content_direction(MediaContentDirection direction) { @@ -222,9 +227,7 @@ class BaseChannel // called. bool IsReadyToReceiveMedia_w() const; bool IsReadyToSendMedia_w() const; - rtc::Thread* signaling_thread() { - return transport_controller_->signaling_thread(); - } + rtc::Thread* signaling_thread() { return signaling_thread_; } void ConnectToTransportChannel(TransportChannel* tc); void DisconnectFromTransportChannel(TransportChannel* tc); @@ -359,9 +362,9 @@ class BaseChannel } private: - bool InitNetwork_n(const std::string* bundle_transport_name); + bool InitNetwork_n(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport); void DisconnectTransportChannels_n(); - void DestroyTransportChannels_n(); void SignalSentPacket_n(rtc::PacketTransportInterface* transport, const rtc::SentPacket& sent_packet); void SignalSentPacket_w(const rtc::SentPacket& sent_packet); @@ -372,22 +375,21 @@ class BaseChannel rtc::Thread* const worker_thread_; rtc::Thread* const network_thread_; + rtc::Thread* const signaling_thread_; rtc::AsyncInvoker invoker_; const std::string content_name_; std::unique_ptr connection_monitor_; - // Transport related members that should be accessed from network thread. - TransportController* const transport_controller_; std::string transport_name_; // Is RTCP used at all by this type of channel? // Expected to be true (as of typing this) for everything except data // channels. const bool rtcp_enabled_; // TODO(johan): Replace TransportChannel* with rtc::PacketTransportInterface*. - TransportChannel* transport_channel_ = nullptr; + TransportChannel* rtp_transport_ = nullptr; std::vector > socket_options_; - TransportChannel* rtcp_transport_channel_ = nullptr; + TransportChannel* rtcp_transport_ = nullptr; std::vector > rtcp_socket_options_; SrtpFilter srtp_filter_; RtcpMuxFilter rtcp_mux_filter_; @@ -422,14 +424,15 @@ class VoiceChannel : public BaseChannel { public: VoiceChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, + rtc::Thread* signaling_thread, MediaEngineInterface* media_engine, VoiceMediaChannel* channel, - TransportController* transport_controller, const std::string& content_name, bool rtcp, bool srtp_required); ~VoiceChannel(); - bool Init_w(const std::string* bundle_transport_name); + bool Init_w(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport); // Configure sending media on the stream with SSRC |ssrc| // If there is only one sending stream SSRC 0 can be used. @@ -540,14 +543,15 @@ class VoiceChannel : public BaseChannel { class VideoChannel : public BaseChannel { public: VideoChannel(rtc::Thread* worker_thread, - rtc::Thread* netwokr_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, VideoMediaChannel* channel, - TransportController* transport_controller, const std::string& content_name, bool rtcp, bool srtp_required); ~VideoChannel(); - bool Init_w(const std::string* bundle_transport_name); + bool Init_w(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport); // downcasts a MediaChannel VideoMediaChannel* media_channel() const override { @@ -620,13 +624,14 @@ class RtpDataChannel : public BaseChannel { public: RtpDataChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, - DataMediaChannel* media_channel, - TransportController* transport_controller, + rtc::Thread* signaling_thread, + DataMediaChannel* channel, const std::string& content_name, bool rtcp, bool srtp_required); ~RtpDataChannel(); - bool Init_w(const std::string* bundle_transport_name); + bool Init_w(TransportChannel* rtp_transport, + TransportChannel* rtcp_transport); virtual bool SendData(const SendDataParams& params, const rtc::CopyOnWriteBuffer& payload, diff --git a/webrtc/pc/channel_unittest.cc b/webrtc/pc/channel_unittest.cc index 589ebd54d1..f8346c9a8e 100644 --- a/webrtc/pc/channel_unittest.cc +++ b/webrtc/pc/channel_unittest.cc @@ -145,6 +145,12 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { &ChannelTest::OnMediaMonitor1); channel2_->SignalMediaMonitor.connect(this, &ChannelTest::OnMediaMonitor2); + channel1_->SignalDestroyRtcpTransport.connect( + transport_controller1_.get(), + &cricket::FakeTransportController::DestroyRtcpTransport); + channel2_->SignalDestroyRtcpTransport.connect( + transport_controller2_.get(), + &cricket::FakeTransportController::DestroyRtcpTransport); if ((flags1 & DTLS) && (flags2 & DTLS)) { flags1 = (flags1 & ~SECURE); flags2 = (flags2 & ~SECURE); @@ -190,13 +196,24 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { typename T::MediaChannel* ch, cricket::TransportController* transport_controller, int flags) { + rtc::Thread* signaling_thread = + transport_controller ? transport_controller->signaling_thread() + : nullptr; typename T::Channel* channel = new typename T::Channel( - worker_thread, network_thread, engine, ch, transport_controller, + worker_thread, network_thread, signaling_thread, engine, ch, cricket::CN_AUDIO, (flags & RTCP) != 0, (flags & SECURE) != 0); rtc::CryptoOptions crypto_options; crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0; channel->SetCryptoOptions(crypto_options); - if (!channel->Init_w(nullptr)) { + cricket::TransportChannel* rtp_transport = + transport_controller->CreateTransportChannel( + channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP); + cricket::TransportChannel* rtcp_transport = nullptr; + if (channel->NeedsRtcpTransport()) { + rtcp_transport = transport_controller->CreateTransportChannel( + channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + if (!channel->Init_w(rtp_transport, rtcp_transport)) { delete channel; channel = NULL; } @@ -383,7 +400,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { // Returns true if so. bool CheckGcmCipher(typename T::Channel* channel, int flags) { int suite; - if (!channel->transport_channel()->GetSrtpCryptoSuite(&suite)) { + if (!channel->rtp_transport()->GetSrtpCryptoSuite(&suite)) { return false; } @@ -513,43 +530,43 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { // mux. void TestSetContentsRtcpMux() { CreateChannels(RTCP, RTCP); - EXPECT_TRUE(channel1_->rtcp_transport_channel() != NULL); - EXPECT_TRUE(channel2_->rtcp_transport_channel() != NULL); + EXPECT_TRUE(channel1_->rtcp_transport() != NULL); + EXPECT_TRUE(channel2_->rtcp_transport() != NULL); typename T::Content content; CreateContent(0, kPcmuCodec, kH264Codec, &content); // Both sides agree on mux. Should no longer be a separate RTCP channel. content.set_rtcp_mux(true); EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL)); EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL)); - EXPECT_TRUE(channel1_->rtcp_transport_channel() == NULL); + EXPECT_TRUE(channel1_->rtcp_transport() == NULL); // Only initiator supports mux. Should still have a separate RTCP channel. EXPECT_TRUE(channel2_->SetLocalContent(&content, CA_OFFER, NULL)); content.set_rtcp_mux(false); EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_ANSWER, NULL)); - EXPECT_TRUE(channel2_->rtcp_transport_channel() != NULL); + EXPECT_TRUE(channel2_->rtcp_transport() != NULL); } // Test that SetLocalContent and SetRemoteContent properly set RTCP // mux when a provisional answer is received. void TestSetContentsRtcpMuxWithPrAnswer() { CreateChannels(RTCP, RTCP); - EXPECT_TRUE(channel1_->rtcp_transport_channel() != NULL); - EXPECT_TRUE(channel2_->rtcp_transport_channel() != NULL); + EXPECT_TRUE(channel1_->rtcp_transport() != NULL); + EXPECT_TRUE(channel2_->rtcp_transport() != NULL); typename T::Content content; CreateContent(0, kPcmuCodec, kH264Codec, &content); content.set_rtcp_mux(true); EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL)); EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_PRANSWER, NULL)); - EXPECT_TRUE(channel1_->rtcp_transport_channel() != NULL); + EXPECT_TRUE(channel1_->rtcp_transport() != NULL); EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL)); // Both sides agree on mux. Should no longer be a separate RTCP channel. - EXPECT_TRUE(channel1_->rtcp_transport_channel() == NULL); + EXPECT_TRUE(channel1_->rtcp_transport() == NULL); // Only initiator supports mux. Should still have a separate RTCP channel. EXPECT_TRUE(channel2_->SetLocalContent(&content, CA_OFFER, NULL)); content.set_rtcp_mux(false); EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_PRANSWER, NULL)); EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_ANSWER, NULL)); - EXPECT_TRUE(channel2_->rtcp_transport_channel() != NULL); + EXPECT_TRUE(channel2_->rtcp_transport() != NULL); } // Test that SetRemoteContent properly deals with a content update. @@ -931,8 +948,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { CreateChannels(0, 0); - cricket::TransportChannel* transport_channel1 = - channel1_->transport_channel(); + cricket::TransportChannel* transport_channel1 = channel1_->rtp_transport(); ASSERT_TRUE(transport_channel1); typename T::MediaChannel* media_channel1 = static_cast(channel1_->media_channel()); @@ -1804,8 +1820,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { error_handler.mode_ = cricket::SrtpFilter::UNPROTECT; network_thread_->Invoke(RTC_FROM_HERE, [this] { - cricket::TransportChannel* transport_channel = - channel2_->transport_channel(); + cricket::TransportChannel* transport_channel = channel2_->rtp_transport(); transport_channel->SignalReadPacket( transport_channel, reinterpret_cast(kBadPacket), sizeof(kBadPacket), rtc::PacketTime(), 0); @@ -1818,8 +1833,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { void TestOnReadyToSend() { CreateChannels(RTCP, RTCP); - TransportChannel* rtp = channel1_->transport_channel(); - TransportChannel* rtcp = channel1_->rtcp_transport_channel(); + TransportChannel* rtp = channel1_->rtp_transport(); + TransportChannel* rtcp = channel1_->rtcp_transport(); EXPECT_FALSE(media_channel1_->ready_to_send()); network_thread_->Invoke(RTC_FROM_HERE, @@ -1869,8 +1884,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { content.set_rtcp_mux(true); EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL)); EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL)); - EXPECT_TRUE(channel1_->rtcp_transport_channel() == NULL); - TransportChannel* rtp = channel1_->transport_channel(); + EXPECT_TRUE(channel1_->rtcp_transport() == NULL); + TransportChannel* rtp = channel1_->rtp_transport(); EXPECT_FALSE(media_channel1_->ready_to_send()); // In the case of rtcp mux, the SignalReadyToSend() from rtp channel // should trigger the MediaChannel's OnReadyToSend. @@ -2041,13 +2056,23 @@ cricket::VideoChannel* ChannelTest::CreateChannel( cricket::FakeVideoMediaChannel* ch, cricket::TransportController* transport_controller, int flags) { + rtc::Thread* signaling_thread = + transport_controller ? transport_controller->signaling_thread() : nullptr; cricket::VideoChannel* channel = new cricket::VideoChannel( - worker_thread, network_thread, ch, transport_controller, - cricket::CN_VIDEO, (flags & RTCP) != 0, (flags & SECURE) != 0); + worker_thread, network_thread, signaling_thread, ch, cricket::CN_VIDEO, + (flags & RTCP) != 0, (flags & SECURE) != 0); rtc::CryptoOptions crypto_options; crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0; channel->SetCryptoOptions(crypto_options); - if (!channel->Init_w(nullptr)) { + cricket::TransportChannel* rtp_transport = + transport_controller->CreateTransportChannel( + channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP); + cricket::TransportChannel* rtcp_transport = nullptr; + if (channel->NeedsRtcpTransport()) { + rtcp_transport = transport_controller->CreateTransportChannel( + channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + if (!channel->Init_w(rtp_transport, rtcp_transport)) { delete channel; channel = NULL; } @@ -3313,13 +3338,23 @@ cricket::RtpDataChannel* ChannelTest::CreateChannel( cricket::FakeDataMediaChannel* ch, cricket::TransportController* transport_controller, int flags) { + rtc::Thread* signaling_thread = + transport_controller ? transport_controller->signaling_thread() : nullptr; cricket::RtpDataChannel* channel = new cricket::RtpDataChannel( - worker_thread, network_thread, ch, transport_controller, cricket::CN_DATA, + worker_thread, network_thread, signaling_thread, ch, cricket::CN_DATA, (flags & RTCP) != 0, (flags & SECURE) != 0); rtc::CryptoOptions crypto_options; crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0; channel->SetCryptoOptions(crypto_options); - if (!channel->Init_w(nullptr)) { + cricket::TransportChannel* rtp_transport = + transport_controller->CreateTransportChannel( + channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP); + cricket::TransportChannel* rtcp_transport = nullptr; + if (channel->NeedsRtcpTransport()) { + rtcp_transport = transport_controller->CreateTransportChannel( + channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + if (!channel->Init_w(rtp_transport, rtcp_transport)) { delete channel; channel = NULL; } diff --git a/webrtc/pc/channelmanager.cc b/webrtc/pc/channelmanager.cc index 4098d62729..f8ed7702d7 100644 --- a/webrtc/pc/channelmanager.cc +++ b/webrtc/pc/channelmanager.cc @@ -207,21 +207,26 @@ void ChannelManager::Terminate_w() { VoiceChannel* ChannelManager::CreateVoiceChannel( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, bool srtp_required, const AudioOptions& options) { return worker_thread_->Invoke( - RTC_FROM_HERE, Bind(&ChannelManager::CreateVoiceChannel_w, this, - media_controller, transport_controller, content_name, - bundle_transport_name, rtcp, srtp_required, options)); + RTC_FROM_HERE, + Bind(&ChannelManager::CreateVoiceChannel_w, this, media_controller, + rtp_transport, rtcp_transport, signaling_thread, content_name, + bundle_transport_name, rtcp, srtp_required, options)); } VoiceChannel* ChannelManager::CreateVoiceChannel_w( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, @@ -230,16 +235,18 @@ VoiceChannel* ChannelManager::CreateVoiceChannel_w( RTC_DCHECK(initialized_); RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); RTC_DCHECK(nullptr != media_controller); + VoiceMediaChannel* media_channel = media_engine_->CreateChannel( media_controller->call_w(), media_controller->config(), options); if (!media_channel) return nullptr; VoiceChannel* voice_channel = new VoiceChannel( - worker_thread_, network_thread_, media_engine_.get(), media_channel, - transport_controller, content_name, rtcp, srtp_required); + worker_thread_, network_thread_, signaling_thread, media_engine_.get(), + media_channel, content_name, rtcp, srtp_required); voice_channel->SetCryptoOptions(crypto_options_); - if (!voice_channel->Init_w(bundle_transport_name)) { + + if (!voice_channel->Init_w(rtp_transport, rtcp_transport)) { delete voice_channel; return nullptr; } @@ -272,21 +279,26 @@ void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) { VideoChannel* ChannelManager::CreateVideoChannel( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, bool srtp_required, const VideoOptions& options) { return worker_thread_->Invoke( - RTC_FROM_HERE, Bind(&ChannelManager::CreateVideoChannel_w, this, - media_controller, transport_controller, content_name, - bundle_transport_name, rtcp, srtp_required, options)); + RTC_FROM_HERE, + Bind(&ChannelManager::CreateVideoChannel_w, this, media_controller, + rtp_transport, rtcp_transport, signaling_thread, content_name, + bundle_transport_name, rtcp, srtp_required, options)); } VideoChannel* ChannelManager::CreateVideoChannel_w( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, @@ -302,10 +314,10 @@ VideoChannel* ChannelManager::CreateVideoChannel_w( } VideoChannel* video_channel = - new VideoChannel(worker_thread_, network_thread_, media_channel, - transport_controller, content_name, rtcp, srtp_required); + new VideoChannel(worker_thread_, network_thread_, signaling_thread, + media_channel, content_name, rtcp, srtp_required); video_channel->SetCryptoOptions(crypto_options_); - if (!video_channel->Init_w(bundle_transport_name)) { + if (!video_channel->Init_w(rtp_transport, rtcp_transport)) { delete video_channel; return NULL; } @@ -339,20 +351,25 @@ void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) { RtpDataChannel* ChannelManager::CreateRtpDataChannel( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, bool srtp_required) { return worker_thread_->Invoke( - RTC_FROM_HERE, Bind(&ChannelManager::CreateRtpDataChannel_w, this, - media_controller, transport_controller, content_name, - bundle_transport_name, rtcp, srtp_required)); + RTC_FROM_HERE, + Bind(&ChannelManager::CreateRtpDataChannel_w, this, media_controller, + rtp_transport, rtcp_transport, signaling_thread, content_name, + bundle_transport_name, rtcp, srtp_required)); } RtpDataChannel* ChannelManager::CreateRtpDataChannel_w( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, @@ -369,11 +386,11 @@ RtpDataChannel* ChannelManager::CreateRtpDataChannel_w( return nullptr; } - RtpDataChannel* data_channel = new RtpDataChannel( - worker_thread_, network_thread_, media_channel, transport_controller, - content_name, rtcp, srtp_required); + RtpDataChannel* data_channel = + new RtpDataChannel(worker_thread_, network_thread_, signaling_thread, + media_channel, content_name, rtcp, srtp_required); data_channel->SetCryptoOptions(crypto_options_); - if (!data_channel->Init_w(bundle_transport_name)) { + if (!data_channel->Init_w(rtp_transport, rtcp_transport)) { LOG(LS_WARNING) << "Failed to init data channel."; delete data_channel; return nullptr; diff --git a/webrtc/pc/channelmanager.h b/webrtc/pc/channelmanager.h index 3022eca8aa..89af44afee 100644 --- a/webrtc/pc/channelmanager.h +++ b/webrtc/pc/channelmanager.h @@ -90,7 +90,9 @@ class ChannelManager { // Creates a voice channel, to be associated with the specified session. VoiceChannel* CreateVoiceChannel( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, @@ -102,7 +104,9 @@ class ChannelManager { // associated with the specified session. VideoChannel* CreateVideoChannel( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, @@ -112,7 +116,9 @@ class ChannelManager { void DestroyVideoChannel(VideoChannel* video_channel); RtpDataChannel* CreateRtpDataChannel( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, @@ -161,7 +167,9 @@ class ChannelManager { bool SetCryptoOptions_w(const rtc::CryptoOptions& crypto_options); VoiceChannel* CreateVoiceChannel_w( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, @@ -170,7 +178,9 @@ class ChannelManager { void DestroyVoiceChannel_w(VoiceChannel* voice_channel); VideoChannel* CreateVideoChannel_w( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, @@ -179,7 +189,9 @@ class ChannelManager { void DestroyVideoChannel_w(VideoChannel* video_channel); RtpDataChannel* CreateRtpDataChannel_w( webrtc::MediaControllerInterface* media_controller, - TransportController* transport_controller, + TransportChannel* rtp_transport, + TransportChannel* rtcp_transport, + rtc::Thread* signaling_thread, const std::string& content_name, const std::string* bundle_transport_name, bool rtcp, diff --git a/webrtc/pc/channelmanager_unittest.cc b/webrtc/pc/channelmanager_unittest.cc index 30d2fe5879..34d9108cff 100644 --- a/webrtc/pc/channelmanager_unittest.cc +++ b/webrtc/pc/channelmanager_unittest.cc @@ -102,17 +102,23 @@ TEST_F(ChannelManagerTest, StartupShutdownOnThread) { // Test that we can create and destroy a voice and video channel. TEST_F(ChannelManagerTest, CreateDestroyChannels) { EXPECT_TRUE(cm_->Init()); + cricket::TransportChannel* rtp_transport = + transport_controller_->CreateTransportChannel( + cricket::CN_AUDIO, cricket::ICE_CANDIDATE_COMPONENT_RTP); cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel( - &fake_mc_, transport_controller_, cricket::CN_AUDIO, nullptr, - kDefaultRtcpEnabled, kDefaultSrtpRequired, AudioOptions()); + &fake_mc_, rtp_transport, nullptr /*rtcp_transport*/, + rtc::Thread::Current(), cricket::CN_AUDIO, nullptr, kDefaultRtcpEnabled, + kDefaultSrtpRequired, AudioOptions()); EXPECT_TRUE(voice_channel != nullptr); cricket::VideoChannel* video_channel = cm_->CreateVideoChannel( - &fake_mc_, transport_controller_, cricket::CN_VIDEO, nullptr, - kDefaultRtcpEnabled, kDefaultSrtpRequired, VideoOptions()); + &fake_mc_, rtp_transport, nullptr /*rtcp_transport*/, + rtc::Thread::Current(), cricket::CN_VIDEO, nullptr, kDefaultRtcpEnabled, + kDefaultSrtpRequired, VideoOptions()); EXPECT_TRUE(video_channel != nullptr); cricket::RtpDataChannel* rtp_data_channel = cm_->CreateRtpDataChannel( - &fake_mc_, transport_controller_, cricket::CN_DATA, nullptr, - kDefaultRtcpEnabled, kDefaultSrtpRequired); + &fake_mc_, rtp_transport, nullptr /*rtcp_transport*/, + rtc::Thread::Current(), cricket::CN_DATA, nullptr, kDefaultRtcpEnabled, + kDefaultSrtpRequired); EXPECT_TRUE(rtp_data_channel != nullptr); cm_->DestroyVideoChannel(video_channel); cm_->DestroyVoiceChannel(voice_channel); @@ -130,17 +136,23 @@ TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) { delete transport_controller_; transport_controller_ = new cricket::FakeTransportController(&network_, ICEROLE_CONTROLLING); + cricket::TransportChannel* rtp_transport = + transport_controller_->CreateTransportChannel( + cricket::CN_AUDIO, cricket::ICE_CANDIDATE_COMPONENT_RTP); cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel( - &fake_mc_, transport_controller_, cricket::CN_AUDIO, nullptr, - kDefaultRtcpEnabled, kDefaultSrtpRequired, AudioOptions()); + &fake_mc_, rtp_transport, nullptr /*rtcp_transport*/, + rtc::Thread::Current(), cricket::CN_AUDIO, nullptr, kDefaultRtcpEnabled, + kDefaultSrtpRequired, AudioOptions()); EXPECT_TRUE(voice_channel != nullptr); cricket::VideoChannel* video_channel = cm_->CreateVideoChannel( - &fake_mc_, transport_controller_, cricket::CN_VIDEO, nullptr, - kDefaultRtcpEnabled, kDefaultSrtpRequired, VideoOptions()); + &fake_mc_, rtp_transport, nullptr /*rtcp_transport*/, + rtc::Thread::Current(), cricket::CN_VIDEO, nullptr, kDefaultRtcpEnabled, + kDefaultSrtpRequired, VideoOptions()); EXPECT_TRUE(video_channel != nullptr); cricket::RtpDataChannel* rtp_data_channel = cm_->CreateRtpDataChannel( - &fake_mc_, transport_controller_, cricket::CN_DATA, nullptr, - kDefaultRtcpEnabled, kDefaultSrtpRequired); + &fake_mc_, rtp_transport, nullptr /*rtcp_transport*/, + rtc::Thread::Current(), cricket::CN_DATA, nullptr, kDefaultRtcpEnabled, + kDefaultSrtpRequired); EXPECT_TRUE(rtp_data_channel != nullptr); cm_->DestroyVideoChannel(video_channel); cm_->DestroyVoiceChannel(voice_channel);