Move SDP m= line matching from BaseChannel to WebRtcSession
This is part of the work towards implementing Unified Plan. The logic for correlating m= lines to channels is changing in Unified Plan. Moving this logic to WebRtcSession means that we do not need to add a flag to BaseChannel to indicate which logic it should use (i.e., Plan B vs. Unified Plan) and can keep those details in WebRtcSession. Bug: webrtc:8183 Change-Id: I729da73ece01fd20f45e82f8956a02c4cad2469e Reviewed-on: https://chromium-review.googlesource.com/653490 Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> Reviewed-by: Peter Thatcher <pthatcher@webrtc.org> Commit-Queue: Steve Anton <steveanton@webrtc.org> Cr-Commit-Position: refs/heads/master@{#19786}
This commit is contained in:
parent
3e1c1ff073
commit
18ee1d55b4
@ -111,13 +111,6 @@ static bool IsSendContentDirection(MediaContentDirection direction) {
|
||||
return direction == MD_SENDRECV || direction == MD_SENDONLY;
|
||||
}
|
||||
|
||||
static const MediaContentDescription* GetContentDescription(
|
||||
const ContentInfo* cinfo) {
|
||||
if (cinfo == NULL)
|
||||
return NULL;
|
||||
return static_cast<const MediaContentDescription*>(cinfo->description);
|
||||
}
|
||||
|
||||
template <class Codec>
|
||||
void RtpParametersFromMediaDescription(
|
||||
const MediaContentDescriptionImpl<Codec>* desc,
|
||||
@ -746,34 +739,6 @@ void BaseChannel::ProcessPacket(bool rtcp,
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseChannel::PushdownLocalDescription(
|
||||
const SessionDescription* local_desc, ContentAction action,
|
||||
std::string* error_desc) {
|
||||
const ContentInfo* content_info = GetFirstContent(local_desc);
|
||||
const MediaContentDescription* content_desc =
|
||||
GetContentDescription(content_info);
|
||||
if (content_desc && content_info && !content_info->rejected &&
|
||||
!SetLocalContent(content_desc, action, error_desc)) {
|
||||
LOG(LS_ERROR) << "Failure in SetLocalContent with action " << action;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseChannel::PushdownRemoteDescription(
|
||||
const SessionDescription* remote_desc, ContentAction action,
|
||||
std::string* error_desc) {
|
||||
const ContentInfo* content_info = GetFirstContent(remote_desc);
|
||||
const MediaContentDescription* content_desc =
|
||||
GetContentDescription(content_info);
|
||||
if (content_desc && content_info && !content_info->rejected &&
|
||||
!SetRemoteContent(content_desc, action, error_desc)) {
|
||||
LOG(LS_ERROR) << "Failure in SetRemoteContent with action " << action;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseChannel::EnableMedia_w() {
|
||||
RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
|
||||
if (enabled_)
|
||||
@ -1728,11 +1693,6 @@ void VoiceChannel::UpdateMediaSendRecvState_w() {
|
||||
LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
|
||||
}
|
||||
|
||||
const ContentInfo* VoiceChannel::GetFirstContent(
|
||||
const SessionDescription* sdesc) {
|
||||
return GetFirstAudioContent(sdesc);
|
||||
}
|
||||
|
||||
bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
|
||||
ContentAction action,
|
||||
std::string* error_desc) {
|
||||
@ -2015,11 +1975,6 @@ void VideoChannel::StopMediaMonitor() {
|
||||
}
|
||||
}
|
||||
|
||||
const ContentInfo* VideoChannel::GetFirstContent(
|
||||
const SessionDescription* sdesc) {
|
||||
return GetFirstVideoContent(sdesc);
|
||||
}
|
||||
|
||||
bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
|
||||
ContentAction action,
|
||||
std::string* error_desc) {
|
||||
@ -2201,11 +2156,6 @@ bool RtpDataChannel::SendData(const SendDataParams& params,
|
||||
payload, result));
|
||||
}
|
||||
|
||||
const ContentInfo* RtpDataChannel::GetFirstContent(
|
||||
const SessionDescription* sdesc) {
|
||||
return GetFirstDataContent(sdesc);
|
||||
}
|
||||
|
||||
bool RtpDataChannel::CheckDataChannelTypeFromContent(
|
||||
const DataContentDescription* content,
|
||||
std::string* error_desc) {
|
||||
|
||||
@ -121,12 +121,6 @@ class BaseChannel
|
||||
DtlsTransportInternal* rtcp_dtls_transport);
|
||||
void SetTransports(rtc::PacketTransportInternal* rtp_packet_transport,
|
||||
rtc::PacketTransportInternal* rtcp_packet_transport);
|
||||
bool PushdownLocalDescription(const SessionDescription* local_desc,
|
||||
ContentAction action,
|
||||
std::string* error_desc);
|
||||
bool PushdownRemoteDescription(const SessionDescription* remote_desc,
|
||||
ContentAction action,
|
||||
std::string* error_desc);
|
||||
// Channel control
|
||||
bool SetLocalContent(const MediaContentDescription* content,
|
||||
ContentAction action,
|
||||
@ -302,9 +296,6 @@ class BaseChannel
|
||||
void UpdateMediaSendRecvState();
|
||||
virtual void UpdateMediaSendRecvState_w() = 0;
|
||||
|
||||
// Gets the content info appropriate to the channel (audio or video).
|
||||
virtual const ContentInfo* GetFirstContent(
|
||||
const SessionDescription* sdesc) = 0;
|
||||
bool UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
|
||||
ContentAction action,
|
||||
std::string* error_desc);
|
||||
@ -509,7 +500,6 @@ class VoiceChannel : public BaseChannel {
|
||||
rtc::CopyOnWriteBuffer* packet,
|
||||
const rtc::PacketTime& packet_time) override;
|
||||
void UpdateMediaSendRecvState_w() override;
|
||||
const ContentInfo* GetFirstContent(const SessionDescription* sdesc) override;
|
||||
bool SetLocalContent_w(const MediaContentDescription* content,
|
||||
ContentAction action,
|
||||
std::string* error_desc) override;
|
||||
@ -589,7 +579,6 @@ class VideoChannel : public BaseChannel {
|
||||
private:
|
||||
// overrides from BaseChannel
|
||||
void UpdateMediaSendRecvState_w() override;
|
||||
const ContentInfo* GetFirstContent(const SessionDescription* sdesc) override;
|
||||
bool SetLocalContent_w(const MediaContentDescription* content,
|
||||
ContentAction action,
|
||||
std::string* error_desc) override;
|
||||
@ -699,7 +688,6 @@ class RtpDataChannel : public BaseChannel {
|
||||
typedef rtc::TypedMessageData<bool> DataChannelReadyToSendMessageData;
|
||||
|
||||
// overrides from BaseChannel
|
||||
const ContentInfo* GetFirstContent(const SessionDescription* sdesc) override;
|
||||
// Checks that data channel type is RTP.
|
||||
bool CheckDataChannelTypeFromContent(const DataContentDescription* content,
|
||||
std::string* error_desc);
|
||||
|
||||
@ -511,17 +511,13 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
// overridden in specialized classes
|
||||
}
|
||||
|
||||
// Creates a cricket::SessionDescription with one MediaContent and one stream.
|
||||
// Creates a MediaContent with one stream.
|
||||
// kPcmuCodec is used as audio codec and kH264Codec is used as video codec.
|
||||
cricket::SessionDescription* CreateSessionDescriptionWithStream(
|
||||
uint32_t ssrc) {
|
||||
typename T::Content content;
|
||||
cricket::SessionDescription* sdesc = new cricket::SessionDescription();
|
||||
CreateContent(SECURE, kPcmuCodec, kH264Codec, &content);
|
||||
AddLegacyStreamInContent(ssrc, 0, &content);
|
||||
sdesc->AddContent("DUMMY_CONTENT_NAME",
|
||||
cricket::NS_JINGLE_RTP, content.Copy());
|
||||
return sdesc;
|
||||
typename T::Content* CreateMediaContentWithStream(uint32_t ssrc) {
|
||||
typename T::Content* content = new typename T::Content();
|
||||
CreateContent(SECURE, kPcmuCodec, kH264Codec, content);
|
||||
AddLegacyStreamInContent(ssrc, 0, content);
|
||||
return content;
|
||||
}
|
||||
|
||||
// Will manage the lifetime of a CallThread, making sure it's
|
||||
@ -1829,41 +1825,39 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
void TestSetContentFailure() {
|
||||
CreateChannels(0, 0);
|
||||
|
||||
auto sdesc = cricket::SessionDescription();
|
||||
sdesc.AddContent(cricket::CN_AUDIO, cricket::NS_JINGLE_RTP,
|
||||
new cricket::AudioContentDescription());
|
||||
sdesc.AddContent(cricket::CN_VIDEO, cricket::NS_JINGLE_RTP,
|
||||
new cricket::VideoContentDescription());
|
||||
|
||||
std::string err;
|
||||
std::unique_ptr<typename T::Content> content(
|
||||
CreateMediaContentWithStream(1));
|
||||
|
||||
media_channel1_->set_fail_set_recv_codecs(true);
|
||||
EXPECT_FALSE(channel1_->PushdownLocalDescription(
|
||||
&sdesc, cricket::CA_OFFER, &err));
|
||||
EXPECT_FALSE(channel1_->PushdownLocalDescription(
|
||||
&sdesc, cricket::CA_ANSWER, &err));
|
||||
EXPECT_FALSE(
|
||||
channel1_->SetLocalContent(content.get(), cricket::CA_OFFER, &err));
|
||||
EXPECT_FALSE(
|
||||
channel1_->SetLocalContent(content.get(), cricket::CA_ANSWER, &err));
|
||||
|
||||
media_channel1_->set_fail_set_send_codecs(true);
|
||||
EXPECT_FALSE(channel1_->PushdownRemoteDescription(
|
||||
&sdesc, cricket::CA_OFFER, &err));
|
||||
EXPECT_FALSE(
|
||||
channel1_->SetRemoteContent(content.get(), cricket::CA_OFFER, &err));
|
||||
|
||||
media_channel1_->set_fail_set_send_codecs(true);
|
||||
EXPECT_FALSE(channel1_->PushdownRemoteDescription(
|
||||
&sdesc, cricket::CA_ANSWER, &err));
|
||||
EXPECT_FALSE(
|
||||
channel1_->SetRemoteContent(content.get(), cricket::CA_ANSWER, &err));
|
||||
}
|
||||
|
||||
void TestSendTwoOffers() {
|
||||
CreateChannels(0, 0);
|
||||
|
||||
std::string err;
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc1(
|
||||
CreateSessionDescriptionWithStream(1));
|
||||
EXPECT_TRUE(channel1_->PushdownLocalDescription(
|
||||
sdesc1.get(), cricket::CA_OFFER, &err));
|
||||
std::unique_ptr<typename T::Content> content1(
|
||||
CreateMediaContentWithStream(1));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetLocalContent(content1.get(), cricket::CA_OFFER, &err));
|
||||
EXPECT_TRUE(media_channel1_->HasSendStream(1));
|
||||
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc2(
|
||||
CreateSessionDescriptionWithStream(2));
|
||||
EXPECT_TRUE(channel1_->PushdownLocalDescription(
|
||||
sdesc2.get(), cricket::CA_OFFER, &err));
|
||||
std::unique_ptr<typename T::Content> content2(
|
||||
CreateMediaContentWithStream(2));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetLocalContent(content2.get(), cricket::CA_OFFER, &err));
|
||||
EXPECT_FALSE(media_channel1_->HasSendStream(1));
|
||||
EXPECT_TRUE(media_channel1_->HasSendStream(2));
|
||||
}
|
||||
@ -1872,16 +1866,16 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
CreateChannels(0, 0);
|
||||
|
||||
std::string err;
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc1(
|
||||
CreateSessionDescriptionWithStream(1));
|
||||
EXPECT_TRUE(channel1_->PushdownRemoteDescription(
|
||||
sdesc1.get(), cricket::CA_OFFER, &err));
|
||||
std::unique_ptr<typename T::Content> content1(
|
||||
CreateMediaContentWithStream(1));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetRemoteContent(content1.get(), cricket::CA_OFFER, &err));
|
||||
EXPECT_TRUE(media_channel1_->HasRecvStream(1));
|
||||
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc2(
|
||||
CreateSessionDescriptionWithStream(2));
|
||||
EXPECT_TRUE(channel1_->PushdownRemoteDescription(
|
||||
sdesc2.get(), cricket::CA_OFFER, &err));
|
||||
std::unique_ptr<typename T::Content> content2(
|
||||
CreateMediaContentWithStream(2));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetRemoteContent(content2.get(), cricket::CA_OFFER, &err));
|
||||
EXPECT_FALSE(media_channel1_->HasRecvStream(1));
|
||||
EXPECT_TRUE(media_channel1_->HasRecvStream(2));
|
||||
}
|
||||
@ -1891,25 +1885,25 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
|
||||
std::string err;
|
||||
// Receive offer
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc1(
|
||||
CreateSessionDescriptionWithStream(1));
|
||||
EXPECT_TRUE(channel1_->PushdownRemoteDescription(
|
||||
sdesc1.get(), cricket::CA_OFFER, &err));
|
||||
std::unique_ptr<typename T::Content> content1(
|
||||
CreateMediaContentWithStream(1));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetRemoteContent(content1.get(), cricket::CA_OFFER, &err));
|
||||
EXPECT_TRUE(media_channel1_->HasRecvStream(1));
|
||||
|
||||
// Send PR answer
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc2(
|
||||
CreateSessionDescriptionWithStream(2));
|
||||
EXPECT_TRUE(channel1_->PushdownLocalDescription(
|
||||
sdesc2.get(), cricket::CA_PRANSWER, &err));
|
||||
std::unique_ptr<typename T::Content> content2(
|
||||
CreateMediaContentWithStream(2));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetLocalContent(content2.get(), cricket::CA_PRANSWER, &err));
|
||||
EXPECT_TRUE(media_channel1_->HasRecvStream(1));
|
||||
EXPECT_TRUE(media_channel1_->HasSendStream(2));
|
||||
|
||||
// Send answer
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc3(
|
||||
CreateSessionDescriptionWithStream(3));
|
||||
EXPECT_TRUE(channel1_->PushdownLocalDescription(
|
||||
sdesc3.get(), cricket::CA_ANSWER, &err));
|
||||
std::unique_ptr<typename T::Content> content3(
|
||||
CreateMediaContentWithStream(3));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetLocalContent(content3.get(), cricket::CA_ANSWER, &err));
|
||||
EXPECT_TRUE(media_channel1_->HasRecvStream(1));
|
||||
EXPECT_FALSE(media_channel1_->HasSendStream(2));
|
||||
EXPECT_TRUE(media_channel1_->HasSendStream(3));
|
||||
@ -1920,25 +1914,25 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
|
||||
std::string err;
|
||||
// Send offer
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc1(
|
||||
CreateSessionDescriptionWithStream(1));
|
||||
EXPECT_TRUE(channel1_->PushdownLocalDescription(
|
||||
sdesc1.get(), cricket::CA_OFFER, &err));
|
||||
std::unique_ptr<typename T::Content> content1(
|
||||
CreateMediaContentWithStream(1));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetLocalContent(content1.get(), cricket::CA_OFFER, &err));
|
||||
EXPECT_TRUE(media_channel1_->HasSendStream(1));
|
||||
|
||||
// Receive PR answer
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc2(
|
||||
CreateSessionDescriptionWithStream(2));
|
||||
EXPECT_TRUE(channel1_->PushdownRemoteDescription(
|
||||
sdesc2.get(), cricket::CA_PRANSWER, &err));
|
||||
std::unique_ptr<typename T::Content> content2(
|
||||
CreateMediaContentWithStream(2));
|
||||
EXPECT_TRUE(channel1_->SetRemoteContent(content2.get(),
|
||||
cricket::CA_PRANSWER, &err));
|
||||
EXPECT_TRUE(media_channel1_->HasSendStream(1));
|
||||
EXPECT_TRUE(media_channel1_->HasRecvStream(2));
|
||||
|
||||
// Receive answer
|
||||
std::unique_ptr<cricket::SessionDescription> sdesc3(
|
||||
CreateSessionDescriptionWithStream(3));
|
||||
EXPECT_TRUE(channel1_->PushdownRemoteDescription(
|
||||
sdesc3.get(), cricket::CA_ANSWER, &err));
|
||||
std::unique_ptr<typename T::Content> content3(
|
||||
CreateMediaContentWithStream(3));
|
||||
EXPECT_TRUE(
|
||||
channel1_->SetRemoteContent(content3.get(), cricket::CA_ANSWER, &err));
|
||||
EXPECT_TRUE(media_channel1_->HasSendStream(1));
|
||||
EXPECT_FALSE(media_channel1_->HasRecvStream(2));
|
||||
EXPECT_TRUE(media_channel1_->HasRecvStream(3));
|
||||
|
||||
@ -847,6 +847,21 @@ bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO(steveanton): Eventually it'd be nice to store the channels as a single
|
||||
// vector of BaseChannel pointers instead of separate voice and video channel
|
||||
// vectors. At that point, this will become a simple getter.
|
||||
std::vector<cricket::BaseChannel*> WebRtcSession::Channels() const {
|
||||
std::vector<cricket::BaseChannel*> channels;
|
||||
channels.insert(channels.end(), voice_channels_.begin(),
|
||||
voice_channels_.end());
|
||||
channels.insert(channels.end(), video_channels_.begin(),
|
||||
video_channels_.end());
|
||||
if (rtp_data_channel_) {
|
||||
channels.push_back(rtp_data_channel_.get());
|
||||
}
|
||||
return channels;
|
||||
}
|
||||
|
||||
void WebRtcSession::LogState(State old_state, State new_state) {
|
||||
LOG(LS_INFO) << "Session:" << id()
|
||||
<< " Old state:" << GetStateString(old_state)
|
||||
@ -953,30 +968,40 @@ bool WebRtcSession::PushdownMediaDescription(
|
||||
cricket::ContentAction action,
|
||||
cricket::ContentSource source,
|
||||
std::string* err) {
|
||||
auto set_content = [this, action, source, err](cricket::BaseChannel* ch) {
|
||||
if (!ch) {
|
||||
return true;
|
||||
} else if (source == cricket::CS_LOCAL) {
|
||||
return ch->PushdownLocalDescription(local_description()->description(),
|
||||
action, err);
|
||||
} else {
|
||||
return ch->PushdownRemoteDescription(remote_description()->description(),
|
||||
action, err);
|
||||
const SessionDescription* sdesc =
|
||||
(source == cricket::CS_LOCAL ? local_description() : remote_description())
|
||||
->description();
|
||||
RTC_DCHECK(sdesc);
|
||||
bool all_success = true;
|
||||
for (auto* channel : Channels()) {
|
||||
// TODO(steveanton): Add support for multiple channels of the same type.
|
||||
const ContentInfo* content_info =
|
||||
cricket::GetFirstMediaContent(sdesc->contents(), channel->media_type());
|
||||
if (!content_info) {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
bool ret = (set_content(voice_channel()) && set_content(video_channel()) &&
|
||||
set_content(rtp_data_channel()));
|
||||
const MediaContentDescription* content_desc =
|
||||
static_cast<const MediaContentDescription*>(content_info->description);
|
||||
if (content_desc && !content_info->rejected) {
|
||||
bool success = (source == cricket::CS_LOCAL)
|
||||
? channel->SetLocalContent(content_desc, action, err)
|
||||
: channel->SetRemoteContent(content_desc, action, err);
|
||||
if (!success) {
|
||||
all_success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Need complete offer/answer with an SCTP m= section before starting SCTP,
|
||||
// according to https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-19
|
||||
if (sctp_transport_ && local_description() && remote_description() &&
|
||||
cricket::GetFirstDataContent(local_description()->description()) &&
|
||||
cricket::GetFirstDataContent(remote_description()->description())) {
|
||||
ret &= network_thread_->Invoke<bool>(
|
||||
all_success &= network_thread_->Invoke<bool>(
|
||||
RTC_FROM_HERE,
|
||||
rtc::Bind(&WebRtcSession::PushdownSctpParameters_n, this, source));
|
||||
}
|
||||
return ret;
|
||||
return all_success;
|
||||
}
|
||||
|
||||
bool WebRtcSession::PushdownSctpParameters_n(cricket::ContentSource source) {
|
||||
|
||||
@ -393,6 +393,9 @@ class WebRtcSession :
|
||||
kAnswer,
|
||||
};
|
||||
|
||||
// Return all managed, non-null channels.
|
||||
std::vector<cricket::BaseChannel*> Channels() const;
|
||||
|
||||
// Non-const versions of local_description()/remote_description(), for use
|
||||
// internally.
|
||||
SessionDescriptionInterface* mutable_local_description() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user