Refactor BaseChannel creation in PeerConnection

This changes the CreateVoiceChannel/CreateVideoChannel helper
methods in PeerConnection to return the created channel instead of
setting it directly. That allows the Unified Plan version of
SetLocalDescription to use the same factory methods without the
assumption that there is at most one voice and one video channel.

Also simplifies and deduplicates the logic for determining the
transport name for a given channel in the presence of BUNDLE.

Bug: webrtc:8587
Change-Id: I1f156f45309ce2d08d6d5d5ed3c6e01fbf094b36
Reviewed-on: https://webrtc-review.googlesource.com/26821
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Peter Thatcher <pthatcher@webrtc.org>
Reviewed-by: Zhi Huang <zhihuang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21050}
This commit is contained in:
Steve Anton
2017-12-04 10:21:55 -08:00
committed by Commit Bot
parent 6cea2b0f4b
commit eda6ccd0c2
2 changed files with 73 additions and 84 deletions

View File

@ -4294,62 +4294,71 @@ void PeerConnection::RemoveUnusedChannels(const SessionDescription* desc) {
} }
} }
// Returns the name of the transport channel when BUNDLE is enabled, or nullptr std::string PeerConnection::GetTransportNameForMediaSection(
// if the channel is not part of any bundle. const std::string& mid,
const std::string* PeerConnection::GetBundleTransportName( const cricket::ContentGroup* bundle_group) const {
const cricket::ContentInfo* content, if (!bundle_group) {
const cricket::ContentGroup* bundle) { return mid;
if (!bundle) {
return nullptr;
} }
const std::string* first_content_name = bundle->FirstContentName(); const std::string* first_content_name = bundle_group->FirstContentName();
if (!first_content_name) { if (!first_content_name) {
RTC_LOG(LS_WARNING) << "Tried to BUNDLE with no contents."; RTC_LOG(LS_WARNING) << "Tried to BUNDLE with no contents.";
return nullptr; return mid;
} }
if (!bundle->HasContentName(content->name)) { if (!bundle_group->HasContentName(mid)) {
RTC_LOG(LS_WARNING) << content->name << " is not part of any bundle group"; RTC_LOG(LS_WARNING) << mid << " is not part of any bundle group";
return nullptr; return mid;
} }
RTC_LOG(LS_INFO) << "Bundling " << content->name << " on " RTC_LOG(LS_INFO) << "Bundling " << mid << " on " << *first_content_name;
<< *first_content_name; return *first_content_name;
return first_content_name;
} }
bool PeerConnection::CreateChannels(const SessionDescription* desc) { bool PeerConnection::CreateChannels(const SessionDescription* desc) {
// TODO(steveanton): Add support for multiple audio/video channels. RTC_DCHECK(desc);
const cricket::ContentGroup* bundle_group = nullptr; const cricket::ContentGroup* bundle_group = nullptr;
if (configuration_.bundle_policy == if (configuration_.bundle_policy ==
PeerConnectionInterface::kBundlePolicyMaxBundle) { PeerConnectionInterface::kBundlePolicyMaxBundle) {
bundle_group = desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); bundle_group = desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
if (!bundle_group) { if (!bundle_group) {
RTC_LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified"; RTC_LOG(LS_WARNING) << "max-bundle configured but session description "
return false; "has no BUNDLE group";
}
}
// Creating the media channels and transport proxies.
const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc);
if (voice && !voice->rejected && !voice_channel()) {
if (!CreateVoiceChannel(voice,
GetBundleTransportName(voice, bundle_group))) {
RTC_LOG(LS_ERROR) << "Failed to create voice channel.";
return false; return false;
} }
} }
// Creating the media channels and transport proxies.
const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc);
if (voice && !voice->rejected &&
!GetAudioTransceiver()->internal()->channel()) {
cricket::VoiceChannel* voice_channel = CreateVoiceChannel(
voice->name,
GetTransportNameForMediaSection(voice->name, bundle_group));
if (!voice_channel) {
RTC_LOG(LS_ERROR) << "Failed to create voice channel.";
return false;
}
GetAudioTransceiver()->internal()->SetChannel(voice_channel);
}
const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc); const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
if (video && !video->rejected && !video_channel()) { if (video && !video->rejected &&
if (!CreateVideoChannel(video, !GetVideoTransceiver()->internal()->channel()) {
GetBundleTransportName(video, bundle_group))) { cricket::VideoChannel* video_channel = CreateVideoChannel(
video->name,
GetTransportNameForMediaSection(video->name, bundle_group));
if (!video_channel) {
RTC_LOG(LS_ERROR) << "Failed to create video channel."; RTC_LOG(LS_ERROR) << "Failed to create video channel.";
return false; return false;
} }
GetVideoTransceiver()->internal()->SetChannel(video_channel);
} }
const cricket::ContentInfo* data = cricket::GetFirstDataContent(desc); const cricket::ContentInfo* data = cricket::GetFirstDataContent(desc);
if (data_channel_type_ != cricket::DCT_NONE && data && !data->rejected && if (data_channel_type_ != cricket::DCT_NONE && data && !data->rejected &&
!rtp_data_channel_ && !sctp_transport_) { !rtp_data_channel_ && !sctp_transport_) {
if (!CreateDataChannel(data, GetBundleTransportName(data, bundle_group))) { if (!CreateDataChannel(data->name, GetTransportNameForMediaSection(
data->name, bundle_group))) {
RTC_LOG(LS_ERROR) << "Failed to create data channel."; RTC_LOG(LS_ERROR) << "Failed to create data channel.";
return false; return false;
} }
@ -4359,15 +4368,9 @@ bool PeerConnection::CreateChannels(const SessionDescription* desc) {
} }
// TODO(steveanton): Perhaps this should be managed by the RtpTransceiver. // TODO(steveanton): Perhaps this should be managed by the RtpTransceiver.
bool PeerConnection::CreateVoiceChannel(const cricket::ContentInfo* content, cricket::VoiceChannel* PeerConnection::CreateVoiceChannel(
const std::string* bundle_transport) { const std::string& mid,
// TODO(steveanton): Check to see if it's safe to create multiple voice const std::string& transport_name) {
// channels.
RTC_DCHECK(!voice_channel());
std::string transport_name =
bundle_transport ? *bundle_transport : content->name;
cricket::DtlsTransportInternal* rtp_dtls_transport = cricket::DtlsTransportInternal* rtp_dtls_transport =
transport_controller_->CreateDtlsTransport( transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
@ -4380,8 +4383,8 @@ bool PeerConnection::CreateVoiceChannel(const cricket::ContentInfo* content,
cricket::VoiceChannel* voice_channel = channel_manager()->CreateVoiceChannel( cricket::VoiceChannel* voice_channel = channel_manager()->CreateVoiceChannel(
call_.get(), configuration_.media_config, rtp_dtls_transport, call_.get(), configuration_.media_config, rtp_dtls_transport,
rtcp_dtls_transport, transport_controller_->signaling_thread(), rtcp_dtls_transport, signaling_thread(), mid, SrtpRequired(),
content->name, SrtpRequired(), audio_options_); audio_options_);
if (!voice_channel) { if (!voice_channel) {
transport_controller_->DestroyDtlsTransport( transport_controller_->DestroyDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
@ -4389,7 +4392,7 @@ bool PeerConnection::CreateVoiceChannel(const cricket::ContentInfo* content,
transport_controller_->DestroyDtlsTransport( transport_controller_->DestroyDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
} }
return false; return nullptr;
} }
voice_channel->SignalRtcpMuxFullyActive.connect( voice_channel->SignalRtcpMuxFullyActive.connect(
this, &PeerConnection::DestroyRtcpTransport_n); this, &PeerConnection::DestroyRtcpTransport_n);
@ -4398,21 +4401,13 @@ bool PeerConnection::CreateVoiceChannel(const cricket::ContentInfo* content,
voice_channel->SignalSentPacket.connect(this, voice_channel->SignalSentPacket.connect(this,
&PeerConnection::OnSentPacket_w); &PeerConnection::OnSentPacket_w);
GetAudioTransceiver()->internal()->SetChannel(voice_channel); return voice_channel;
return true;
} }
// TODO(steveanton): Perhaps this should be managed by the RtpTransceiver. // TODO(steveanton): Perhaps this should be managed by the RtpTransceiver.
bool PeerConnection::CreateVideoChannel(const cricket::ContentInfo* content, cricket::VideoChannel* PeerConnection::CreateVideoChannel(
const std::string* bundle_transport) { const std::string& mid,
// TODO(steveanton): Check to see if it's safe to create multiple video const std::string& transport_name) {
// channels.
RTC_DCHECK(!video_channel());
std::string transport_name =
bundle_transport ? *bundle_transport : content->name;
cricket::DtlsTransportInternal* rtp_dtls_transport = cricket::DtlsTransportInternal* rtp_dtls_transport =
transport_controller_->CreateDtlsTransport( transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
@ -4425,8 +4420,8 @@ bool PeerConnection::CreateVideoChannel(const cricket::ContentInfo* content,
cricket::VideoChannel* video_channel = channel_manager()->CreateVideoChannel( cricket::VideoChannel* video_channel = channel_manager()->CreateVideoChannel(
call_.get(), configuration_.media_config, rtp_dtls_transport, call_.get(), configuration_.media_config, rtp_dtls_transport,
rtcp_dtls_transport, transport_controller_->signaling_thread(), rtcp_dtls_transport, signaling_thread(), mid, SrtpRequired(),
content->name, SrtpRequired(), video_options_); video_options_);
if (!video_channel) { if (!video_channel) {
transport_controller_->DestroyDtlsTransport( transport_controller_->DestroyDtlsTransport(
@ -4435,7 +4430,7 @@ bool PeerConnection::CreateVideoChannel(const cricket::ContentInfo* content,
transport_controller_->DestroyDtlsTransport( transport_controller_->DestroyDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
} }
return false; return nullptr;
} }
video_channel->SignalRtcpMuxFullyActive.connect( video_channel->SignalRtcpMuxFullyActive.connect(
this, &PeerConnection::DestroyRtcpTransport_n); this, &PeerConnection::DestroyRtcpTransport_n);
@ -4444,15 +4439,11 @@ bool PeerConnection::CreateVideoChannel(const cricket::ContentInfo* content,
video_channel->SignalSentPacket.connect(this, video_channel->SignalSentPacket.connect(this,
&PeerConnection::OnSentPacket_w); &PeerConnection::OnSentPacket_w);
GetVideoTransceiver()->internal()->SetChannel(video_channel); return video_channel;
return true;
} }
bool PeerConnection::CreateDataChannel(const cricket::ContentInfo* content, bool PeerConnection::CreateDataChannel(const std::string& mid,
const std::string* bundle_transport) { const std::string& transport_name) {
const std::string transport_name =
bundle_transport ? *bundle_transport : content->name;
bool sctp = (data_channel_type_ == cricket::DCT_SCTP); bool sctp = (data_channel_type_ == cricket::DCT_SCTP);
if (sctp) { if (sctp) {
if (!sctp_factory_) { if (!sctp_factory_) {
@ -4463,12 +4454,13 @@ bool PeerConnection::CreateDataChannel(const cricket::ContentInfo* content,
} }
if (!network_thread()->Invoke<bool>( if (!network_thread()->Invoke<bool>(
RTC_FROM_HERE, rtc::Bind(&PeerConnection::CreateSctpTransport_n, RTC_FROM_HERE, rtc::Bind(&PeerConnection::CreateSctpTransport_n,
this, content->name, transport_name))) { this, mid, transport_name))) {
return false; return false;
} }
for (const auto& channel : sctp_data_channels_) {
channel->OnTransportChannelCreated();
}
} else { } else {
std::string transport_name =
bundle_transport ? *bundle_transport : content->name;
cricket::DtlsTransportInternal* rtp_dtls_transport = cricket::DtlsTransportInternal* rtp_dtls_transport =
transport_controller_->CreateDtlsTransport( transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
@ -4481,8 +4473,7 @@ bool PeerConnection::CreateDataChannel(const cricket::ContentInfo* content,
rtp_data_channel_ = channel_manager()->CreateRtpDataChannel( rtp_data_channel_ = channel_manager()->CreateRtpDataChannel(
configuration_.media_config, rtp_dtls_transport, rtcp_dtls_transport, configuration_.media_config, rtp_dtls_transport, rtcp_dtls_transport,
transport_controller_->signaling_thread(), content->name, signaling_thread(), mid, SrtpRequired());
SrtpRequired());
if (!rtp_data_channel_) { if (!rtp_data_channel_) {
transport_controller_->DestroyDtlsTransport( transport_controller_->DestroyDtlsTransport(
@ -4502,10 +4493,6 @@ bool PeerConnection::CreateDataChannel(const cricket::ContentInfo* content,
this, &PeerConnection::OnSentPacket_w); this, &PeerConnection::OnSentPacket_w);
} }
for (const auto& channel : sctp_data_channels_) {
channel->OnTransportChannelCreated();
}
return true; return true;
} }

View File

@ -650,11 +650,13 @@ class PeerConnection : public PeerConnectionInterface,
const std::string& content_name, const std::string& content_name,
cricket::TransportDescription* info); cricket::TransportDescription* info);
// Returns the name of the transport channel when BUNDLE is enabled, or // Returns the transport name for the given media section identified by |mid|.
// nullptr if the channel is not part of any bundle. // If BUNDLE is enabled and the media section is part of the bundle group,
const std::string* GetBundleTransportName( // the transport name will be the first mid in the bundle group. Otherwise,
const cricket::ContentInfo* content, // the transport name will be the mid of the media section.
const cricket::ContentGroup* bundle); std::string GetTransportNameForMediaSection(
const std::string& mid,
const cricket::ContentGroup* bundle_group) const;
// Cause all the BaseChannels in the bundle group to have the same // Cause all the BaseChannels in the bundle group to have the same
// transport channel. // transport channel.
@ -682,12 +684,12 @@ class PeerConnection : public PeerConnectionInterface,
bool CreateChannels(const cricket::SessionDescription* desc); bool CreateChannels(const cricket::SessionDescription* desc);
// Helper methods to create media channels. // Helper methods to create media channels.
bool CreateVoiceChannel(const cricket::ContentInfo* content, cricket::VoiceChannel* CreateVoiceChannel(const std::string& mid,
const std::string* bundle_transport); const std::string& transport_name);
bool CreateVideoChannel(const cricket::ContentInfo* content, cricket::VideoChannel* CreateVideoChannel(const std::string& mid,
const std::string* bundle_transport); const std::string& transport_name);
bool CreateDataChannel(const cricket::ContentInfo* content, bool CreateDataChannel(const std::string& mid,
const std::string* bundle_transport); const std::string& transport_name);
std::unique_ptr<SessionStats> GetSessionStats_n( std::unique_ptr<SessionStats> GetSessionStats_n(
const ChannelNamePairs& channel_name_pairs); const ChannelNamePairs& channel_name_pairs);