[Unified Plan] If "a=msid" is missing, create default stream.

Prior to this CL, if the "a=msid" attribute was missing it was treated
the same as if "no streams" were explicitly signaled (a=msid:-); the
receivers would not be associated with any streams.

In order to support legacy endpoints that don't recognize "a=msid" that
assume the Plan B behavior of a stream being created anyway, this CL
creates a stream with a random ID in such cases. For background, see
https://github.com/web-platform-tests/wpt/pull/14054.

Bug: chromium:907508
Change-Id: I9d9dd0e4ba8f9941f8652f4d7873adc560777cd9
Reviewed-on: https://webrtc-review.googlesource.com/c/112900
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25901}
This commit is contained in:
Henrik Boström 2018-12-04 11:25:05 +01:00 committed by Commit Bot
parent e5e36ddc40
commit 5b1477839d
5 changed files with 55 additions and 0 deletions

View File

@ -146,6 +146,7 @@ class RtpReceiverInterface : public rtc::RefCountInterface {
BEGIN_SIGNALING_PROXY_MAP(RtpReceiver)
PROXY_SIGNALING_THREAD_DESTRUCTOR()
PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, track)
PROXY_CONSTMETHOD0(std::vector<std::string>, stream_ids)
PROXY_CONSTMETHOD0(std::vector<rtc::scoped_refptr<MediaStreamInterface>>,
streams)
PROXY_CONSTMETHOD0(cricket::MediaType, media_type)

View File

@ -2468,6 +2468,18 @@ RTCError PeerConnection::ApplyRemoteDescription(
}
media_streams.push_back(stream);
}
// Special case: "a=msid" missing, use random stream ID.
if (media_streams.empty() &&
!(remote_description()->description()->msid_signaling() &
cricket::kMsidSignalingMediaSection)) {
if (!missing_msid_default_stream_) {
missing_msid_default_stream_ = MediaStreamProxy::Create(
rtc::Thread::Current(),
MediaStream::Create(rtc::CreateRandomUuid()));
added_streams.push_back(missing_msid_default_stream_);
}
media_streams.push_back(missing_msid_default_stream_);
}
// This will add the remote track to the streams.
// TODO(hbos): When we remove remote_streams(), use set_stream_ids()
// instead. https://crbug.com/webrtc/9480

View File

@ -1033,6 +1033,11 @@ class PeerConnection : public PeerConnectionInternal,
std::vector<
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
transceivers_;
// In Unified Plan, if we encounter remote SDP that does not contain an a=msid
// line we create and use a stream with a random ID for our receivers. This is
// to support legacy endpoints that do not support the a=msid attribute (as
// opposed to streamless tracks with "a=msid:-").
rtc::scoped_refptr<MediaStreamInterface> missing_msid_default_stream_;
// MIDs that have been seen either by SetLocalDescription or
// SetRemoteDescription over the life of the PeerConnection.
std::set<std::string> seen_mids_;

View File

@ -151,6 +151,7 @@ void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
content.media_description()->mutable_streams().clear();
}
desc->set_msid_supported(false);
desc->set_msid_signaling(0);
}
// Removes all stream information besides the stream ids, simulating an
@ -2451,6 +2452,37 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
EXPECT_TRUE(ExpectNewFrames(media_expectations));
}
TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
ASSERT_TRUE(CreatePeerConnectionWrappers());
ConnectFakeSignaling();
caller()->AddAudioTrack();
caller()->AddVideoTrack();
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
auto callee_receivers = callee()->pc()->GetReceivers();
ASSERT_EQ(2u, callee_receivers.size());
EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
}
TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
ASSERT_TRUE(CreatePeerConnectionWrappers());
ConnectFakeSignaling();
caller()->AddAudioTrack();
caller()->AddVideoTrack();
callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
auto callee_receivers = callee()->pc()->GetReceivers();
ASSERT_EQ(2u, callee_receivers.size());
ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
callee_receivers[1]->stream_ids()[0]);
EXPECT_EQ(callee_receivers[0]->streams()[0],
callee_receivers[1]->streams()[0]);
}
// Test that if two video tracks are sent (from caller to callee, in this test),
// they're transmitted correctly end-to-end.
TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {

View File

@ -2501,6 +2501,8 @@ TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutMsid) {
EXPECT_TRUE(SdpDeserialize(sdp_without_msid, &jdesc));
// Verify
EXPECT_TRUE(CompareSessionDescription(jdesc_, jdesc));
EXPECT_FALSE(jdesc.description()->msid_signaling() &
~cricket::kMsidSignalingSsrcAttribute);
}
TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithExtmapAllowMixed) {
@ -3497,6 +3499,9 @@ TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionSpecialMsid) {
&deserialized_description));
EXPECT_TRUE(CompareSessionDescription(jdesc_, deserialized_description));
EXPECT_EQ(cricket::kMsidSignalingMediaSection |
cricket::kMsidSignalingSsrcAttribute,
deserialized_description.description()->msid_signaling());
}
// Tests the serialization of a Unified Plan SDP that is compatible for both