Bug 1585009: Support playout-delay RTP header extension r=bwc
authorAndreas Schuler <andreas.schuler@phenixrts.com>
Tue, 08 Oct 2019 12:49:52 +0000
changeset 496805 258c68e013454a876c4c65a2556a43d4739a26c4
parent 496804 70cd4ff8583c68f28ce609a617b34f7dda9ec75b
child 496806 b44da78c9070d87870a6fb5ce924b273dcae8369
push id36668
push useraiakab@mozilla.com
push dateWed, 09 Oct 2019 04:06:09 +0000
treeherdermozilla-central@26ebfec08834 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc
bugs1585009
milestone71.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1585009: Support playout-delay RTP header extension r=bwc Added playout-delay RTP header extension for video to JsepSessionImpl::SetupDefaultRtpExtensions. This ensures that this extension will be preserved when generating an answer to an offer (by a sending peer) containing it. Also updated JsepSessionTest to include a test verifying that the expected default audio and video extensions are set. Differential Revision: https://phabricator.services.mozilla.com/D47689
dom/media/tests/mochitest/test_peerConnection_basicAudioVideoVerifyExtmap.html
dom/media/tests/mochitest/test_peerConnection_basicAudioVideoVerifyExtmapSendonly.html
media/webrtc/signaling/gtest/jsep_session_unittest.cpp
media/webrtc/signaling/gtest/sdp_unittests.cpp
media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoVerifyExtmap.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoVerifyExtmap.html
@@ -38,16 +38,17 @@
         const video = sdputils.findExtmapIdsUrnsDirections(
             sdputils.getVideoMSections(test.originalOffer.sdp));
         const expected_video = [
           /* Please modify this list when you add or remove RTP header
           extensions. */
           ["3", "urn:ietf:params:rtp-hdrext:sdes:mid", ""],
           ["4", "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", ""],
           ["5", "urn:ietf:params:rtp-hdrext:toffset", ""],
+          ["6", "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay", "recvonly"],
         ];
         // *Ugh* ...
         ok(JSON.stringify(video) ===
            JSON.stringify(expected_video),
            "List of offer video URNs meets expected values");
       }
     ]);
 
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoVerifyExtmapSendonly.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoVerifyExtmapSendonly.html
@@ -38,16 +38,17 @@
         const video = sdputils.findExtmapIdsUrnsDirections(
             sdputils.getVideoMSections(test.originalOffer.sdp));
         const expected_video = [
           /* Please modify this list when you add or remove RTP header
           extensions. */
           ["3", "urn:ietf:params:rtp-hdrext:sdes:mid", ""],
           ["4", "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", ""],
           ["5", "urn:ietf:params:rtp-hdrext:toffset", ""],
+          ["6", "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay", "recvonly"],
         ];
         // *Ugh* ...
         ok(JSON.stringify(video) ===
            JSON.stringify(expected_video),
            "List of offer video URNs meets expected values");
       }
     ]);
 
--- a/media/webrtc/signaling/gtest/jsep_session_unittest.cpp
+++ b/media/webrtc/signaling/gtest/jsep_session_unittest.cpp
@@ -4191,19 +4191,19 @@ TEST_F(JsepSessionTest, TestAnswererIndi
 
 TEST_F(JsepSessionTest, TestExtmap) {
   AddTracks(*mSessionOff, "audio");
   AddTracks(*mSessionAns, "audio");
   // ssrc-audio-level will be extmap 1 for both
   // csrc-audio-level will be 2 for both
   // mid will be 3 for both
   // video related extensions take 4 and 5
-  mSessionOff->AddAudioRtpExtension("foo");  // Default mapping of 6
-  mSessionOff->AddAudioRtpExtension("bar");  // Default mapping of 7
-  mSessionAns->AddAudioRtpExtension("bar");  // Default mapping of 6
+  mSessionOff->AddAudioRtpExtension("foo");  // Default mapping of 7
+  mSessionOff->AddAudioRtpExtension("bar");  // Default mapping of 8
+  mSessionAns->AddAudioRtpExtension("bar");  // Default mapping of 7
   std::string offer = CreateOffer();
   SetLocalOffer(offer, CHECK_SUCCESS);
   SetRemoteOffer(offer, CHECK_SUCCESS);
   std::string answer = CreateAnswer();
   SetLocalAnswer(answer, CHECK_SUCCESS);
   SetRemoteAnswer(answer, CHECK_SUCCESS);
 
   UniquePtr<Sdp> parsedOffer(Parse(offer));
@@ -4218,50 +4218,137 @@ TEST_F(JsepSessionTest, TestExtmap) {
   ASSERT_EQ(1U, offerExtmap[0].entry);
   ASSERT_EQ("urn:ietf:params:rtp-hdrext:csrc-audio-level",
             offerExtmap[1].extensionname);
   ASSERT_EQ(2U, offerExtmap[1].entry);
   ASSERT_EQ("urn:ietf:params:rtp-hdrext:sdes:mid",
             offerExtmap[2].extensionname);
   ASSERT_EQ(3U, offerExtmap[2].entry);
   ASSERT_EQ("foo", offerExtmap[3].extensionname);
-  ASSERT_EQ(6U, offerExtmap[3].entry);
+  ASSERT_EQ(7U, offerExtmap[3].entry);
   ASSERT_EQ("bar", offerExtmap[4].extensionname);
-  ASSERT_EQ(7U, offerExtmap[4].entry);
+  ASSERT_EQ(8U, offerExtmap[4].entry);
 
   UniquePtr<Sdp> parsedAnswer(Parse(answer));
   ASSERT_EQ(1U, parsedAnswer->GetMediaSectionCount());
 
   auto& answerMediaAttrs = parsedAnswer->GetMediaSection(0).GetAttributeList();
   ASSERT_TRUE(answerMediaAttrs.HasAttribute(SdpAttribute::kExtmapAttribute));
   auto& answerExtmap = answerMediaAttrs.GetExtmap().mExtmaps;
   ASSERT_EQ(3U, answerExtmap.size());
   ASSERT_EQ("urn:ietf:params:rtp-hdrext:ssrc-audio-level",
             answerExtmap[0].extensionname);
   ASSERT_EQ(1U, answerExtmap[0].entry);
   ASSERT_EQ("urn:ietf:params:rtp-hdrext:sdes:mid",
             answerExtmap[1].extensionname);
   ASSERT_EQ(3U, answerExtmap[1].entry);
   // We ensure that the entry for "bar" matches what was in the offer
   ASSERT_EQ("bar", answerExtmap[2].extensionname);
-  ASSERT_EQ(7U, answerExtmap[2].entry);
+  ASSERT_EQ(8U, answerExtmap[2].entry);
+}
+
+TEST_F(JsepSessionTest, TestExtmapDefaults) {
+  types.push_back(SdpMediaSection::kAudio);
+  types.push_back(SdpMediaSection::kVideo);
+  AddTracks(*mSessionOff, "audio,video");
+
+  std::string offer = CreateOffer();
+  SetLocalOffer(offer, CHECK_SUCCESS);
+  SetRemoteOffer(offer, CHECK_SUCCESS);
+
+  std::string answer = CreateAnswer();
+  SetLocalAnswer(answer, CHECK_SUCCESS);
+  SetRemoteAnswer(answer, CHECK_SUCCESS);
+
+  UniquePtr<Sdp> parsedOffer(Parse(offer));
+  ASSERT_EQ(2U, parsedOffer->GetMediaSectionCount());
+
+  auto& offerAudioMediaAttrs =
+      parsedOffer->GetMediaSection(0).GetAttributeList();
+  ASSERT_TRUE(
+      offerAudioMediaAttrs.HasAttribute(SdpAttribute::kExtmapAttribute));
+  auto& offerAudioExtmap = offerAudioMediaAttrs.GetExtmap().mExtmaps;
+  ASSERT_EQ(3U, offerAudioExtmap.size());
+
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:ssrc-audio-level",
+            offerAudioExtmap[0].extensionname);
+  ASSERT_EQ(1U, offerAudioExtmap[0].entry);
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:csrc-audio-level",
+            offerAudioExtmap[1].extensionname);
+  ASSERT_EQ(2U, offerAudioExtmap[1].entry);
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:sdes:mid",
+            offerAudioExtmap[2].extensionname);
+
+  auto& offerVideoMediaAttrs =
+      parsedOffer->GetMediaSection(1).GetAttributeList();
+  ASSERT_TRUE(
+      offerVideoMediaAttrs.HasAttribute(SdpAttribute::kExtmapAttribute));
+  auto& offerVideoExtmap = offerVideoMediaAttrs.GetExtmap().mExtmaps;
+  ASSERT_EQ(4U, offerVideoExtmap.size());
+
+  ASSERT_EQ(3U, offerVideoExtmap[0].entry);
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:sdes:mid",
+            offerVideoExtmap[0].extensionname);
+  ASSERT_EQ("http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",
+            offerVideoExtmap[1].extensionname);
+  ASSERT_EQ(4U, offerVideoExtmap[1].entry);
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:toffset",
+            offerVideoExtmap[2].extensionname);
+  ASSERT_EQ(5U, offerVideoExtmap[2].entry);
+  ASSERT_EQ("http://www.webrtc.org/experiments/rtp-hdrext/playout-delay",
+            offerVideoExtmap[3].extensionname);
+  ASSERT_EQ(6U, offerVideoExtmap[3].entry);
+
+  UniquePtr<Sdp> parsedAnswer(Parse(answer));
+  ASSERT_EQ(2U, parsedAnswer->GetMediaSectionCount());
+
+  auto& answerAudioMediaAttrs =
+      parsedAnswer->GetMediaSection(0).GetAttributeList();
+  ASSERT_TRUE(
+      answerAudioMediaAttrs.HasAttribute(SdpAttribute::kExtmapAttribute));
+  auto& answerAudioExtmap = answerAudioMediaAttrs.GetExtmap().mExtmaps;
+  ASSERT_EQ(2U, answerAudioExtmap.size());
+
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:ssrc-audio-level",
+            answerAudioExtmap[0].extensionname);
+  ASSERT_EQ(1U, answerAudioExtmap[0].entry);
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:sdes:mid",
+            answerAudioExtmap[1].extensionname);
+  ASSERT_EQ(3U, answerAudioExtmap[1].entry);
+
+  auto& answerVideoMediaAttrs =
+      parsedAnswer->GetMediaSection(1).GetAttributeList();
+  ASSERT_TRUE(
+      answerVideoMediaAttrs.HasAttribute(SdpAttribute::kExtmapAttribute));
+  auto& answerVideoExtmap = answerVideoMediaAttrs.GetExtmap().mExtmaps;
+  ASSERT_EQ(3U, answerVideoExtmap.size());
+
+  ASSERT_EQ(3U, answerVideoExtmap[0].entry);
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:sdes:mid",
+            answerVideoExtmap[0].extensionname);
+  ASSERT_EQ("http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",
+            answerVideoExtmap[1].extensionname);
+  ASSERT_EQ(4U, answerVideoExtmap[1].entry);
+  ASSERT_EQ("urn:ietf:params:rtp-hdrext:toffset",
+            answerVideoExtmap[2].extensionname);
+  ASSERT_EQ(5U, answerVideoExtmap[2].entry);
 }
 
 TEST_F(JsepSessionTest, TestExtmapWithDuplicates) {
   AddTracks(*mSessionOff, "audio");
   AddTracks(*mSessionAns, "audio");
   // ssrc-audio-level will be extmap 1 for both
   // csrc-audio-level will be 2 for both
   // mid will be 3 for both
   // video related extensions take 4 and 5
-  mSessionOff->AddAudioRtpExtension("foo");  // Default mapping of 6
-  mSessionOff->AddAudioRtpExtension("bar");  // Default mapping of 7
+  mSessionOff->AddAudioRtpExtension("foo");  // Default mapping of 7
+  mSessionOff->AddAudioRtpExtension("bar");  // Default mapping of 8
   mSessionOff->AddAudioRtpExtension("bar");  // Should be ignored
   mSessionOff->AddAudioRtpExtension("bar");  // Should be ignored
-  mSessionOff->AddAudioRtpExtension("baz");  // Default mapping of 8
+  mSessionOff->AddAudioRtpExtension("baz");  // Default mapping of 9
   mSessionOff->AddAudioRtpExtension("bar");  // Should be ignored
 
   std::string offer = CreateOffer();
   UniquePtr<Sdp> parsedOffer(Parse(offer));
   ASSERT_EQ(1U, parsedOffer->GetMediaSectionCount());
 
   auto& offerMediaAttrs = parsedOffer->GetMediaSection(0).GetAttributeList();
   ASSERT_TRUE(offerMediaAttrs.HasAttribute(SdpAttribute::kExtmapAttribute));
@@ -4272,21 +4359,21 @@ TEST_F(JsepSessionTest, TestExtmapWithDu
   ASSERT_EQ(1U, offerExtmap[0].entry);
   ASSERT_EQ("urn:ietf:params:rtp-hdrext:csrc-audio-level",
             offerExtmap[1].extensionname);
   ASSERT_EQ(2U, offerExtmap[1].entry);
   ASSERT_EQ("urn:ietf:params:rtp-hdrext:sdes:mid",
             offerExtmap[2].extensionname);
   ASSERT_EQ(3U, offerExtmap[2].entry);
   ASSERT_EQ("foo", offerExtmap[3].extensionname);
-  ASSERT_EQ(6U, offerExtmap[3].entry);
+  ASSERT_EQ(7U, offerExtmap[3].entry);
   ASSERT_EQ("bar", offerExtmap[4].extensionname);
-  ASSERT_EQ(7U, offerExtmap[4].entry);
+  ASSERT_EQ(8U, offerExtmap[4].entry);
   ASSERT_EQ("baz", offerExtmap[5].extensionname);
-  ASSERT_EQ(8U, offerExtmap[5].entry);
+  ASSERT_EQ(9U, offerExtmap[5].entry);
 }
 
 TEST_F(JsepSessionTest, TestRtcpFbStar) {
   AddTracks(*mSessionOff, "video");
   AddTracks(*mSessionAns, "video");
 
   std::string offer = CreateOffer();
 
--- a/media/webrtc/signaling/gtest/sdp_unittests.cpp
+++ b/media/webrtc/signaling/gtest/sdp_unittests.cpp
@@ -5634,16 +5634,18 @@ TEST_F(SdpTest, hugeSdp) {
       "a=ice-options:google-ice\r\n"
       "a=fingerprint:sha-256 "
       "59:4A:8B:73:A7:73:53:71:88:D7:4D:58:28:0C:79:72:31:29:9B:05:37:DD:58:43:"
       "C2:D4:85:A2:B3:66:38:7A\r\n"
       "a=setup:active\r\n"
       "a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n"
       "a=extmap:3 "
       "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n"
+      "a=extmap:6 "
+      "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n"
       "a=sendrecv\r\n"
       "a=mid:video\r\n"
       "a=rtcp-mux\r\n"
       "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
       "inline:/U44g3ULdtapeiSg+T3n6dDLBKIjpOhb/NXAL/2b\r\n"
       "a=rtpmap:100 VP8/90000\r\n"
       "a=rtcp-fb:100 ccm fir\r\n"
       "a=rtcp-fb:100 nack\r\n"
--- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
+++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
@@ -1986,16 +1986,18 @@ void JsepSessionImpl::SetupDefaultRtpExt
   AddAudioRtpExtension(webrtc::RtpExtension::kCsrcAudioLevelUri,
                        SdpDirectionAttribute::Direction::kRecvonly);
   AddAudioVideoRtpExtension(webrtc::RtpExtension::kMIdUri,
                             SdpDirectionAttribute::Direction::kSendrecv);
   AddVideoRtpExtension(webrtc::RtpExtension::kAbsSendTimeUri,
                        SdpDirectionAttribute::Direction::kSendrecv);
   AddVideoRtpExtension(webrtc::RtpExtension::kTimestampOffsetUri,
                        SdpDirectionAttribute::Direction::kSendrecv);
+  AddVideoRtpExtension(webrtc::RtpExtension::kPlayoutDelayUri,
+                       SdpDirectionAttribute::Direction::kRecvonly);
 }
 
 void JsepSessionImpl::SetState(JsepSignalingState state) {
   if (state == mState) return;
 
   MOZ_MTLOG(ML_NOTICE, "[" << mName << "]: " << GetStateStr(mState) << " -> "
                            << GetStateStr(state));
   mState = state;