diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js index 59c978ca43e9..dd02fe597ba1 100644 --- a/dom/media/tests/mochitest/pc.js +++ b/dom/media/tests/mochitest/pc.js @@ -926,9 +926,17 @@ PeerConnectionWrapper.prototype = { var type = ''; if (constraints.audio) { type = 'audio'; + stream.getAudioTracks().map(track => { + info(this + " gUM local stream " + stream.id + + " with audio track " + track.id); + }); } if (constraints.video) { type += 'video'; + stream.getVideoTracks().map(track => { + info(this + " gUM local stream " + stream.id + + " with video track " + track.id); + }); } this.attachMedia(stream, type, 'local'); }); @@ -1119,9 +1127,17 @@ PeerConnectionWrapper.prototype = { var type = ''; if (event.stream.getAudioTracks().length > 0) { type = 'audio'; + event.stream.getAudioTracks().map(track => { + info(this + " remote stream " + event.stream.id + " with audio track " + + track.id); + }); } if (event.stream.getVideoTracks().length > 0) { type += 'video'; + event.stream.getVideoTracks().map(track => { + info(this + " remote stream " + event.stream.id + " with video track " + + track.id); + }); } this.attachMedia(event.stream, type, 'remote'); }); @@ -1395,11 +1411,9 @@ PeerConnectionWrapper.prototype = { var checkSdpForMsids = (desc, streams, side) => { streams.forEach(stream => { stream.getTracks().forEach(track => { - // TODO(bug 1089798): Once DOMMediaStream has an id field, we - // should be verifying that the SDP contains - // a=msid: - ok(desc.sdp.match(new RegExp("a=msid:[^ ]+ " + track.id)), - side + " SDP contains track id " + track.id ); + ok(desc.sdp.match(new RegExp("a=msid:" + stream.id + " " + track.id)), + this + ": " + side + " SDP contains stream " + stream.id + + " and track " + track.id ); }); }); }; diff --git a/dom/media/tests/mochitest/templates.js b/dom/media/tests/mochitest/templates.js index 688cbbfe3567..29f8dac43673 100644 --- a/dom/media/tests/mochitest/templates.js +++ b/dom/media/tests/mochitest/templates.js @@ -486,14 +486,6 @@ var commandsPeerConnectionOfferAnswer = [ function PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT(test) { return test.pcRemote.checkMediaFlowPresent(); }, -/* TODO: re-enable when Bug 1095218 lands - function PC_LOCAL_CHECK_MSID(test) { - test.pcLocal.checkMsids(); - }, - function PC_REMOTE_CHECK_MSID(test) { - test.pcRemote.checkMsids(); - }, -*/ function PC_LOCAL_CHECK_STATS(test) { return test.pcLocal.getStats(null).then(stats => { test.pcLocal.checkStats(stats, test.steeplechase); diff --git a/media/webrtc/signaling/test/jsep_session_unittest.cpp b/media/webrtc/signaling/test/jsep_session_unittest.cpp index e5101b6ee1c5..5c595d2f72d2 100644 --- a/media/webrtc/signaling/test/jsep_session_unittest.cpp +++ b/media/webrtc/signaling/test/jsep_session_unittest.cpp @@ -127,7 +127,7 @@ protected: } void - AddTracks(JsepSessionImpl* side) + AddTracks(JsepSessionImpl& side) { // Add tracks. if (types.empty()) { @@ -142,7 +142,7 @@ protected: } void - AddTracks(JsepSessionImpl* side, const std::string& mediatypes) + AddTracks(JsepSessionImpl& side, const std::string& mediatypes) { AddTracks(side, BuildTypes(mediatypes)); } @@ -178,7 +178,7 @@ protected: } void - AddTracks(JsepSessionImpl* side, + AddTracks(JsepSessionImpl& side, const std::vector& mediatypes) { FakeUuidGenerator uuid_gen; @@ -187,14 +187,89 @@ protected: ASSERT_TRUE(uuid_gen.Generate(&stream_id)); + AddTracksToStream(side, stream_id, mediatypes); + } + + void + AddTracksToStream(JsepSessionImpl& side, + const std::string stream_id, + const std::string& mediatypes) + { + AddTracksToStream(side, stream_id, BuildTypes(mediatypes)); + } + + void + AddTracksToStream(JsepSessionImpl& side, + const std::string stream_id, + const std::vector& mediatypes) + + { + FakeUuidGenerator uuid_gen; + std::string track_id; + for (auto track = mediatypes.begin(); track != mediatypes.end(); ++track) { ASSERT_TRUE(uuid_gen.Generate(&track_id)); RefPtr mst(new JsepTrack(*track, stream_id, track_id)); - side->AddTrack(mst); + side.AddTrack(mst); } } + bool HasMediaStream(std::vector> tracks) const { + for (auto i = tracks.begin(); i != tracks.end(); ++i) { + if ((*i)->GetMediaType() != SdpMediaSection::kApplication) { + return 1; + } + } + return 0; + } + + const std::string GetFirstLocalStreamId(JsepSessionImpl& side) const { + auto tracks = side.GetLocalTracks(); + return (*tracks.begin())->GetStreamId(); + } + + std::vector + GetMediaStreamIds(std::vector> tracks) const { + std::vector ids; + for (auto i = tracks.begin(); i != tracks.end(); ++i) { + // data channels don't have msid's + if ((*i)->GetMediaType() == SdpMediaSection::kApplication) { + continue; + } + ids.push_back((*i)->GetStreamId()); + } + return ids; + } + + std::vector + GetLocalMediaStreamIds(JsepSessionImpl& side) const { + return GetMediaStreamIds(side.GetLocalTracks()); + } + + std::vector + GetRemoteMediaStreamIds(JsepSessionImpl& side) const { + return GetMediaStreamIds(side.GetRemoteTracks()); + } + + std::vector + sortUniqueStrVector(std::vector in) const { + std::sort(in.begin(), in.end()); + auto it = std::unique(in.begin(), in.end()); + in.resize( std::distance(in.begin(), it)); + return in; + } + + std::vector + GetLocalUniqueStreamIds(JsepSessionImpl& side) const { + return sortUniqueStrVector(GetLocalMediaStreamIds(side)); + } + + std::vector + GetRemoteUniqueStreamIds(JsepSessionImpl& side) const { + return sortUniqueStrVector(GetRemoteMediaStreamIds(side)); + } + RefPtr GetTrack(JsepSessionImpl& side, SdpMediaSection::MediaType type, size_t index) const { @@ -746,20 +821,20 @@ TEST_F(JsepSessionTestBase, CreateDestroy) {} TEST_P(JsepSessionTest, CreateOffer) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); CreateOffer(); } TEST_P(JsepSessionTest, CreateOfferSetLocal) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); } TEST_P(JsepSessionTest, CreateOfferSetLocalSetRemote) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); @@ -767,32 +842,32 @@ TEST_P(JsepSessionTest, CreateOfferSetLocalSetRemote) TEST_P(JsepSessionTest, CreateOfferSetLocalSetRemoteCreateAnswer) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); std::string answer = CreateAnswer(); } TEST_P(JsepSessionTest, CreateOfferSetLocalSetRemoteCreateAnswerSetLocal) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); std::string answer = CreateAnswer(); SetLocalAnswer(answer); } TEST_P(JsepSessionTest, FullCall) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); std::string answer = CreateAnswer(); SetLocalAnswer(answer); SetRemoteAnswer(answer); @@ -800,7 +875,7 @@ TEST_P(JsepSessionTest, FullCall) TEST_P(JsepSessionTest, RenegotiationNoChange) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); @@ -810,7 +885,7 @@ TEST_P(JsepSessionTest, RenegotiationNoChange) ASSERT_EQ(types.size(), added.size()); ASSERT_EQ(0U, removed.size()); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); std::string answer = CreateAnswer(); SetLocalAnswer(answer); SetRemoteAnswer(answer); @@ -857,8 +932,8 @@ TEST_P(JsepSessionTest, RenegotiationNoChange) TEST_P(JsepSessionTest, RenegotiationOffererAddsTrack) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); OfferAnswer(); @@ -868,7 +943,7 @@ TEST_P(JsepSessionTest, RenegotiationOffererAddsTrack) std::vector extraTypes; extraTypes.push_back(SdpMediaSection::kAudio); extraTypes.push_back(SdpMediaSection::kVideo); - AddTracks(&mSessionOff, extraTypes); + AddTracks(mSessionOff, extraTypes); types.insert(types.end(), extraTypes.begin(), extraTypes.end()); OfferAnswer(CHECK_SUCCESS); @@ -901,8 +976,8 @@ TEST_P(JsepSessionTest, RenegotiationOffererAddsTrack) TEST_P(JsepSessionTest, RenegotiationAnswererAddsTrack) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); OfferAnswer(); @@ -912,7 +987,7 @@ TEST_P(JsepSessionTest, RenegotiationAnswererAddsTrack) std::vector extraTypes; extraTypes.push_back(SdpMediaSection::kAudio); extraTypes.push_back(SdpMediaSection::kVideo); - AddTracks(&mSessionAns, extraTypes); + AddTracks(mSessionAns, extraTypes); types.insert(types.end(), extraTypes.begin(), extraTypes.end()); // We need to add a recvonly m-section to the offer for this to work @@ -958,8 +1033,8 @@ TEST_P(JsepSessionTest, RenegotiationAnswererAddsTrack) TEST_P(JsepSessionTest, RenegotiationBothAddTrack) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); OfferAnswer(); @@ -969,8 +1044,8 @@ TEST_P(JsepSessionTest, RenegotiationBothAddTrack) std::vector extraTypes; extraTypes.push_back(SdpMediaSection::kAudio); extraTypes.push_back(SdpMediaSection::kVideo); - AddTracks(&mSessionAns, extraTypes); - AddTracks(&mSessionOff, extraTypes); + AddTracks(mSessionAns, extraTypes); + AddTracks(mSessionOff, extraTypes); types.insert(types.end(), extraTypes.begin(), extraTypes.end()); OfferAnswer(CHECK_SUCCESS); @@ -1003,10 +1078,59 @@ TEST_P(JsepSessionTest, RenegotiationBothAddTrack) } } +TEST_P(JsepSessionTest, RenegotiationBothAddTracksToExistingStream) +{ + AddTracks(mSessionOff); + AddTracks(mSessionAns); + if (GetParam() == "datachannel") { + return; + } + + OfferAnswer(); + + auto oHasStream = HasMediaStream(mSessionOff.GetLocalTracks()); + auto aHasStream = HasMediaStream(mSessionAns.GetLocalTracks()); + ASSERT_EQ(oHasStream, GetLocalUniqueStreamIds(mSessionOff).size()); + ASSERT_EQ(aHasStream, GetLocalUniqueStreamIds(mSessionAns).size()); + ASSERT_EQ(aHasStream, GetRemoteUniqueStreamIds(mSessionOff).size()); + ASSERT_EQ(oHasStream, GetRemoteUniqueStreamIds(mSessionAns).size()); + + auto firstOffId = GetFirstLocalStreamId(mSessionOff); + auto firstAnsId = GetFirstLocalStreamId(mSessionAns); + + auto offererPairs = GetTrackPairsByLevel(mSessionOff); + auto answererPairs = GetTrackPairsByLevel(mSessionAns); + + std::vector extraTypes; + extraTypes.push_back(SdpMediaSection::kAudio); + extraTypes.push_back(SdpMediaSection::kVideo); + AddTracksToStream(mSessionOff, firstOffId, extraTypes); + AddTracksToStream(mSessionAns, firstAnsId, extraTypes); + types.insert(types.end(), extraTypes.begin(), extraTypes.end()); + + OfferAnswer(CHECK_SUCCESS); + + oHasStream = HasMediaStream(mSessionOff.GetLocalTracks()); + aHasStream = HasMediaStream(mSessionAns.GetLocalTracks()); + + ASSERT_EQ(oHasStream, GetLocalUniqueStreamIds(mSessionOff).size()); + ASSERT_EQ(aHasStream, GetLocalUniqueStreamIds(mSessionAns).size()); + ASSERT_EQ(aHasStream, GetRemoteUniqueStreamIds(mSessionOff).size()); + ASSERT_EQ(oHasStream, GetRemoteUniqueStreamIds(mSessionAns).size()); + if (oHasStream) { + ASSERT_STREQ(firstOffId.c_str(), + GetFirstLocalStreamId(mSessionOff).c_str()); + } + if (aHasStream) { + ASSERT_STREQ(firstAnsId.c_str(), + GetFirstLocalStreamId(mSessionAns).c_str()); + } +} + TEST_P(JsepSessionTest, RenegotiationOffererRemovesTrack) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); if (types.front() == SdpMediaSection::kApplication) { return; } @@ -1083,8 +1207,8 @@ TEST_P(JsepSessionTest, RenegotiationOffererRemovesTrack) TEST_P(JsepSessionTest, RenegotiationAnswererRemovesTrack) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); if (types.front() == SdpMediaSection::kApplication) { return; } @@ -1161,8 +1285,8 @@ TEST_P(JsepSessionTest, RenegotiationAnswererRemovesTrack) TEST_P(JsepSessionTest, RenegotiationBothRemoveTrack) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); if (types.front() == SdpMediaSection::kApplication) { return; } @@ -1234,8 +1358,8 @@ TEST_P(JsepSessionTest, RenegotiationBothRemoveTrack) TEST_P(JsepSessionTest, RenegotiationBothRemoveTrackDifferentMsection) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); if (types.front() == SdpMediaSection::kApplication) { return; } @@ -1341,8 +1465,8 @@ TEST_P(JsepSessionTest, RenegotiationBothRemoveTrackDifferentMsection) TEST_P(JsepSessionTest, RenegotiationOffererReplacesTrack) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); if (types.front() == SdpMediaSection::kApplication) { return; @@ -1427,11 +1551,11 @@ TEST_P(JsepSessionTest, RenegotiationOffererReplacesTrack) // side doesn't use msid attributes) are stable across renegotiation. TEST_P(JsepSessionTest, RenegotiationAutoAssignedMsidIsStable) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); std::string answer = CreateAnswer(); SetLocalAnswer(answer); @@ -1457,7 +1581,7 @@ TEST_P(JsepSessionTest, RenegotiationAutoAssignedMsidIsStable) offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); answer = CreateAnswer(); SetLocalAnswer(answer); @@ -1477,11 +1601,11 @@ TEST_P(JsepSessionTest, RenegotiationAutoAssignedMsidIsStable) // but does on renegotiation. TEST_P(JsepSessionTest, RenegotiationAnswererEnablesMsid) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); std::string answer = CreateAnswer(); SetLocalAnswer(answer); @@ -1494,7 +1618,7 @@ TEST_P(JsepSessionTest, RenegotiationAnswererEnablesMsid) offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); answer = CreateAnswer(); SetLocalAnswer(answer); SetRemoteAnswer(answer, CHECK_SUCCESS); @@ -1522,11 +1646,11 @@ TEST_P(JsepSessionTest, RenegotiationAnswererEnablesMsid) TEST_P(JsepSessionTest, RenegotiationAnswererDisablesMsid) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); std::string answer = CreateAnswer(); SetLocalAnswer(answer); SetRemoteAnswer(answer, CHECK_SUCCESS); @@ -1536,7 +1660,7 @@ TEST_P(JsepSessionTest, RenegotiationAnswererDisablesMsid) offer = CreateOffer(); SetLocalOffer(offer); SetRemoteOffer(offer); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); answer = CreateAnswer(); SetLocalAnswer(answer); @@ -1569,8 +1693,8 @@ TEST_P(JsepSessionTest, RenegotiationAnswererDisablesMsid) // but does on renegotiation. TEST_P(JsepSessionTest, RenegotiationOffererEnablesBundle) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); std::string offer = CreateOffer(); DisableBundle(&offer); @@ -1628,8 +1752,8 @@ TEST_P(JsepSessionTest, RenegotiationOffererEnablesBundle) TEST_P(JsepSessionTest, RenegotiationOffererDisablesBundleTransport) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); if (types.size() < 2) { return; @@ -1680,8 +1804,8 @@ TEST_P(JsepSessionTest, RenegotiationOffererDisablesBundleTransport) TEST_P(JsepSessionTest, RenegotiationAnswererDisablesBundleTransport) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); if (types.size() < 2) { return; @@ -1732,7 +1856,7 @@ TEST_P(JsepSessionTest, RenegotiationAnswererDisablesBundleTransport) TEST_P(JsepSessionTest, FullCallWithCandidates) { - AddTracks(&mSessionOff); + AddTracks(mSessionOff); std::string offer = CreateOffer(); SetLocalOffer(offer); GatherOffererCandidates(); @@ -1740,7 +1864,7 @@ TEST_P(JsepSessionTest, FullCallWithCandidates) SetRemoteOffer(offer); TrickleOffererCandidates(); ValidateAnswererCandidates(); - AddTracks(&mSessionAns); + AddTracks(mSessionAns); std::string answer = CreateAnswer(); SetLocalAnswer(answer); SetRemoteAnswer(answer); @@ -1809,7 +1933,7 @@ TEST_F(JsepSessionTest, OfferAnswerRecvOnlyLines) SetLocalOffer(offer, CHECK_SUCCESS); - AddTracks(&mSessionAns, "audio,video"); + AddTracks(mSessionAns, "audio,video"); SetRemoteOffer(offer, CHECK_SUCCESS); std::string answer = CreateAnswer(); @@ -1832,7 +1956,7 @@ TEST_F(JsepSessionTest, OfferAnswerRecvOnlyLines) TEST_F(JsepSessionTest, OfferAnswerSendOnlyLines) { - AddTracks(&mSessionOff, "audio,video,video"); + AddTracks(mSessionOff, "audio,video,video"); JsepOfferOptions options; options.mOfferToReceiveAudio = Some(static_cast(0U)); @@ -1868,7 +1992,7 @@ TEST_F(JsepSessionTest, OfferAnswerSendOnlyLines) SetLocalOffer(offer, CHECK_SUCCESS); - AddTracks(&mSessionAns, "audio,video"); + AddTracks(mSessionAns, "audio,video"); SetRemoteOffer(offer, CHECK_SUCCESS); std::string answer = CreateAnswer(); @@ -2174,8 +2298,8 @@ TEST_F(JsepSessionTest, ValidateAnsweredCodecParams) TEST_P(JsepSessionTest, TestRejectMline) { - AddTracks(&mSessionOff); - AddTracks(&mSessionAns); + AddTracks(mSessionOff); + AddTracks(mSessionAns); switch (types.front()) { case SdpMediaSection::kAudio: @@ -2248,8 +2372,8 @@ TEST_F(JsepSessionTest, CreateOfferNoMlines) TEST_F(JsepSessionTest, TestIceLite) { - AddTracks(&mSessionOff, "audio"); - AddTracks(&mSessionAns, "audio"); + AddTracks(mSessionOff, "audio"); + AddTracks(mSessionAns, "audio"); std::string offer = CreateOffer(); SetLocalOffer(offer, CHECK_SUCCESS); @@ -2268,8 +2392,8 @@ TEST_F(JsepSessionTest, TestIceLite) TEST_F(JsepSessionTest, TestIceOptions) { - AddTracks(&mSessionOff, "audio"); - AddTracks(&mSessionAns, "audio"); + AddTracks(mSessionOff, "audio"); + AddTracks(mSessionAns, "audio"); std::string offer = CreateOffer(); SetLocalOffer(offer, CHECK_SUCCESS); SetRemoteOffer(offer, CHECK_SUCCESS); @@ -2286,8 +2410,8 @@ TEST_F(JsepSessionTest, TestIceOptions) TEST_F(JsepSessionTest, TestExtmap) { - AddTracks(&mSessionOff, "audio"); - AddTracks(&mSessionAns, "audio"); + AddTracks(mSessionOff, "audio"); + AddTracks(mSessionAns, "audio"); // ssrc-audio-level will be extmap 1 for both mSessionOff.AddAudioRtpExtension("foo"); // Default mapping of 2 mSessionOff.AddAudioRtpExtension("bar"); // Default mapping of 3 @@ -2332,8 +2456,8 @@ TEST_F(JsepSessionTest, TestExtmap) TEST_F(JsepSessionTest, TestRtcpFbStar) { - AddTracks(&mSessionOff, "video"); - AddTracks(&mSessionAns, "video"); + AddTracks(mSessionOff, "video"); + AddTracks(mSessionAns, "video"); std::string offer = CreateOffer(); @@ -2368,8 +2492,8 @@ TEST_F(JsepSessionTest, TestUniquePayloadTypes) { // The audio payload types will all appear more than once, but the video // payload types will be unique. - AddTracks(&mSessionOff, "audio,audio,video"); - AddTracks(&mSessionAns, "audio,audio,video"); + AddTracks(mSessionOff, "audio,audio,video"); + AddTracks(mSessionAns, "audio,audio,video"); std::string offer = CreateOffer(); SetLocalOffer(offer, CHECK_SUCCESS);