Title: [214960] trunk
Revision
214960
Author
[email protected]
Date
2017-04-05 12:14:36 -0700 (Wed, 05 Apr 2017)

Log Message

[WebRTC][OpenWebRTC] Add support for SDP BUNDLE ("a:group:BUNDLE" and "a=bundle-only" lines)
https://bugs.webkit.org/show_bug.cgi?id=170157

Reviewed by Alejandro G. Castro.

Source/WebCore:

This implements support on the SDPProcessor for generating an "a=group:BUNDLE"
attribute with the MID identifiers specified in the bundle group in the most
recent answer.
It also implements support for generating "a=bundle-only" attributes on the
"m=" sections of the SDP according to the bundlePolicy defined.

Test: fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html

* Modules/mediastream/MediaEndpointPeerConnection.cpp:
(WebCore::MediaEndpointPeerConnection::createOfferTask):
(WebCore::MediaEndpointPeerConnection::createAnswerTask):
* Modules/mediastream/SDPProcessor.cpp:
(WebCore::getBundlePolicyName):
(WebCore::configurationToJSON):
* Modules/mediastream/sdp.js:
(SDP.generate):
* platform/mediastream/MediaEndpointSessionConfiguration.h:
(WebCore::MediaEndpointSessionConfiguration::bundlePolicy):
(WebCore::MediaEndpointSessionConfiguration::setBundlePolicy):
(WebCore::MediaEndpointSessionConfiguration::clone):

LayoutTests:

The test fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html
is used to check that we generate the "a=bundle-only" lines on the "m=" sections
according to the bundlePolicy. The 3 possible values of bundlePolicy are tested.
To properly test bundlePolicy:"balanced" we generate 5 extra tracks (6 in total)
for each one of the audio media type and video media type.

* TestExpectations: Set RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html
as failing in the general TestExpectations, because the libwebrtc backend currently
doesn't generate the expected a=bundle-only lines.
On the GTK+ port TestExpectations file this is overriden, and the test is marked to pass.
The whole fast/mediastream directory is already overriden to pass.
* fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only-expected.txt: Added.
* fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html: Added.
* fast/mediastream/resources/sdp-utils.js:
(printComparableSessionDescription): Validate the a=group:BUNDLE line to contain the required MID identifiers.
* platform/gtk/fast/mediastream/RTCPeerConnection-inspect-answer-expected.txt: Added. Rebaseline with the expected a=group:BUNDLE line.
* platform/gtk/fast/mediastream/RTCPeerConnection-inspect-offer-expected.txt: Added. Rebaseline with the expected a=group:BUNDLE line.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (214959 => 214960)


--- trunk/LayoutTests/ChangeLog	2017-04-05 19:09:28 UTC (rev 214959)
+++ trunk/LayoutTests/ChangeLog	2017-04-05 19:14:36 UTC (rev 214960)
@@ -1,3 +1,28 @@
+2017-04-05  Carlos Alberto Lopez Perez  <[email protected]>
+
+        [WebRTC][OpenWebRTC] Add support for SDP BUNDLE ("a:group:BUNDLE" and "a=bundle-only" lines)
+        https://bugs.webkit.org/show_bug.cgi?id=170157
+
+        Reviewed by Alejandro G. Castro.
+
+        The test fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html
+        is used to check that we generate the "a=bundle-only" lines on the "m=" sections
+        according to the bundlePolicy. The 3 possible values of bundlePolicy are tested.
+        To properly test bundlePolicy:"balanced" we generate 5 extra tracks (6 in total)
+        for each one of the audio media type and video media type.
+
+        * TestExpectations: Set RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html
+        as failing in the general TestExpectations, because the libwebrtc backend currently
+        doesn't generate the expected a=bundle-only lines.
+        On the GTK+ port TestExpectations file this is overriden, and the test is marked to pass.
+        The whole fast/mediastream directory is already overriden to pass.
+        * fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only-expected.txt: Added.
+        * fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html: Added.
+        * fast/mediastream/resources/sdp-utils.js:
+        (printComparableSessionDescription): Validate the a=group:BUNDLE line to contain the required MID identifiers.
+        * platform/gtk/fast/mediastream/RTCPeerConnection-inspect-answer-expected.txt: Added. Rebaseline with the expected a=group:BUNDLE line.
+        * platform/gtk/fast/mediastream/RTCPeerConnection-inspect-offer-expected.txt: Added. Rebaseline with the expected a=group:BUNDLE line.
+
 2017-04-05  Jer Noble  <[email protected]>
 
         [MSE] Seeks to currentTime=0 will fail if currentTime is already 0.

Modified: trunk/LayoutTests/TestExpectations (214959 => 214960)


--- trunk/LayoutTests/TestExpectations	2017-04-05 19:09:28 UTC (rev 214959)
+++ trunk/LayoutTests/TestExpectations	2017-04-05 19:14:36 UTC (rev 214960)
@@ -724,6 +724,8 @@
 fast/mediastream/RTCRtpSender-replaceTrack.html [ Skip ]
 fast/mediastream/RTCPeerConnection-icecandidate-event.html [ Pass Failure ]
 fast/mediastream/RTCPeerConnection-dtmf.html [ Failure ]
+# libwebrtc backend doesn't generate a=bundle-only lines
+fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html [ Failure ]
 
 # Need updating wptserve
 imported/w3c/web-platform-tests/XMLHttpRequest/setrequestheader-content-type.htm [ Skip ]

Added: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only-expected.txt (0 => 214960)


--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only-expected.txt	2017-04-05 19:14:36 UTC (rev 214960)
@@ -0,0 +1,700 @@
+Inspect that the SDP offer contains the correct number of a=bundle-only lines according to the bundlePolicy value.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Start promise chain for bundlePolicy: max-compat
+PASS Generated SDP offer for bundlePolicy: max-compat
+=== RTCSessionDescription ===
+type: offer, sdp:
+v=0
+o=- {session-id:OK} 0 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=group:BUNDLE {bundle:OK}
+a=msid-semantic:WMS {media-stream-id:OK}
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+===
+
+PASS Generated SDP offer for bundlePolicy: max-compat. Got the expected number of a=bundle-only lines: 0
+PASS Start promise chain for bundlePolicy: balanced
+PASS Generated SDP offer for bundlePolicy: balanced
+=== RTCSessionDescription ===
+type: offer, sdp:
+v=0
+o=- {session-id:OK} 0 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=group:BUNDLE {bundle:OK}
+a=msid-semantic:WMS {media-stream-id:OK}
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+===
+
+PASS Generated SDP offer for bundlePolicy: balanced. Got the expected number of a=bundle-only lines: 10
+PASS Start promise chain for bundlePolicy: max-bundle
+PASS Generated SDP offer for bundlePolicy: max-bundle
+=== RTCSessionDescription ===
+type: offer, sdp:
+v=0
+o=- {session-id:OK} 0 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=group:BUNDLE {bundle:OK}
+a=msid-semantic:WMS {media-stream-id:OK}
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=bundle-only
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+===
+
+PASS Generated SDP offer for bundlePolicy: max-bundle. Got the expected number of a=bundle-only lines: 11
+PASS Tested the following bundlePolicy values: max-compat balanced max-bundle
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html (0 => 214960)


--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html	2017-04-05 19:14:36 UTC (rev 214960)
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+    <head>
+        <script src=""
+        <script src=""
+    </head>
+    <body>
+        <script>
+
+            description("Inspect that the SDP offer contains the correct number of a=bundle-only lines according to the bundlePolicy value.");
+
+            if (window.testRunner)
+                testRunner.setUserMediaPermission(true);
+            else {
+                debug("This test can not be run without the testRunner");
+                finishJSTest();
+            }
+
+            function testBundlePolicySDP(bundlePolicy) {
+                var mediaDescriptionVariables = [];
+                var numberOfExtraTracksPerType = 5;
+                var stream;
+                var numberOfGeneratedBundleOnlyLines = 0;
+                var numberOfExpectedBundleOnlyLines = 0;
+                var numberOfDifferentTypeTracks = 2; // audio and video
+
+                switch (bundlePolicy) {
+                    case "max-compat":
+                        // None of the m= sections should have a=bundle-only.
+                        numberOfExpectedBundleOnlyLines = 0;
+                        break;
+                    case "max-bundle":
+                        // All the m= sections (except the first one) should have a=bundle-only.
+                        numberOfExpectedBundleOnlyLines = numberOfDifferentTypeTracks * (numberOfExtraTracksPerType + 1 ) - 1;
+                        break;
+                     default: // balanced
+                        // All the m= sections (except the first one of each type) should have a=bundle-only.
+                        numberOfExpectedBundleOnlyLines = numberOfDifferentTypeTracks * numberOfExtraTracksPerType;
+                        break;
+                    }
+                if (numberOfExpectedBundleOnlyLines < 0)
+                    numberOfExpectedBundleOnlyLines = 0;
+
+                var connectionConfig = { iceServers:[{urls:'stun:foo.com'}],
+                                         bundlePolicy: bundlePolicy };
+                var pc = new RTCPeerConnection(connectionConfig);
+
+                navigator.mediaDevices.getUserMedia({ "audio": true, "video": true})
+                .then(function (stream) {
+                    testPassed("Start promise chain for bundlePolicy: " + bundlePolicy);
+                    var audioTrack = stream.getAudioTracks()[0];
+                    var videoTrack = stream.getVideoTracks()[0];
+                    pc.addTrack(audioTrack, stream);
+                    pc.addTrack(videoTrack, stream);
+                    mediaDescriptionVariables.push({ "trackId": audioTrack.id, "streamId": stream.id });
+                    mediaDescriptionVariables.push({ "trackId": videoTrack.id, "streamId": stream.id });
+                    for(var i=0; i < numberOfExtraTracksPerType; i++){
+                        var audioTrackCloned = audioTrack.clone();
+                        var videoTrackCloned = videoTrack.clone();
+                        pc.addTrack(audioTrackCloned, stream);
+                        pc.addTrack(videoTrackCloned, stream);
+                        mediaDescriptionVariables.push({ "trackId": audioTrackCloned.id, "streamId": stream.id });
+                        mediaDescriptionVariables.push({ "trackId": videoTrackCloned.id, "streamId": stream.id });
+                    }
+                    return pc.createOffer();
+                })
+                .then(function (offer) {
+                    testPassed("Generated SDP offer for bundlePolicy: " + bundlePolicy);
+                    printComparableSessionDescription(offer, mediaDescriptionVariables);
+                    offer.sdp.split("\r\n").forEach(function (line) {
+                        if (line == "a=bundle-only") {
+                            numberOfGeneratedBundleOnlyLines++;
+                        };
+                    });
+                    if (numberOfExpectedBundleOnlyLines == numberOfGeneratedBundleOnlyLines) {
+                        testPassed("Generated SDP offer for bundlePolicy: " + bundlePolicy + ". Got the expected number of a=bundle-only lines: " + numberOfGeneratedBundleOnlyLines);
+                    } else {
+                        testFailed("Generated SDP offer for bundlePolicy: " + bundlePolicy + ". Expected " + numberOfExpectedBundleOnlyLines + " a=bundle-only lines, but got " + numberOfGeneratedBundleOnlyLines + " lines instead.");
+                    }
+                    runNextSubTestIfNotFinished();
+
+                })
+                .catch(function (error) {
+                    testFailed("Error caught in promise chain: " + error);
+                    finishJSTest();
+                });
+
+            };
+
+
+            function runNextSubTestIfNotFinished() {
+                if (subTestsCompleted == bundlePolicies.length) {
+                    testPassed("Tested the following bundlePolicy values: " + bundlePolicies.join(" "));
+                    finishJSTest();
+                } else {
+                    testBundlePolicySDP(bundlePolicies[subTestsCompleted]);
+                    subTestsCompleted++;
+                };
+            };
+
+
+            var subTestsCompleted = 0;
+            var bundlePolicies = ["max-compat", "balanced", "max-bundle"];
+
+            runNextSubTestIfNotFinished();
+
+            window.jsTestIsAsync = true;
+            window.successfullyParsed = true;
+
+        </script>
+        <script src=""
+    </body>
+</html>

Modified: trunk/LayoutTests/fast/mediastream/resources/sdp-utils.js (214959 => 214960)


--- trunk/LayoutTests/fast/mediastream/resources/sdp-utils.js	2017-04-05 19:09:28 UTC (rev 214959)
+++ trunk/LayoutTests/fast/mediastream/resources/sdp-utils.js	2017-04-05 19:14:36 UTC (rev 214960)
@@ -16,10 +16,19 @@
             "msid": "^a=(ssrc:\\d+ )?msid:([\\w+/\\-=]+) +([\\w+/\\-=]+).*$",
             "iceufrag": "^a=ice-ufrag:([\\w+/]*).*$",
             "icepwd": "^a=ice-pwd:([\\w+/]*).*$",
+            "bundle": "^a=group:BUNDLE .*$",
         };
 
         var mdescIndex = -1;
+
+        var mid;
+        var mids = [];
         sdp.split("\r\n").forEach(function (line) {
+           if (mid = match(line, regexp.mid))
+                mids.push(mid[1]);
+        });
+
+        sdp.split("\r\n").forEach(function (line) {
             if (match(line, regexp.mline)) {
                 // Media block ("header" line)
                 mdescIndex++;
@@ -32,6 +41,9 @@
                     // The session-id should be a number between 0 and LLONG_MAX (2^63-1).
                     if (sessid >= 0 && sessid <= 9223372036854775807)
                         line = line.replace(oline[2], verified("session-id"));
+                } else if (match(line, regexp.bundle)) {
+                    if (mids.length > 0)
+                        line = line.replace("a=group:BUNDLE " + mids.join(" "), "a=group:BUNDLE " + verified("bundle"));
                 } else if (match(line, regexp.msidsemantic)) {
                     mdescVariables.forEach(function (variables) {
                         line = line.replace(variables.streamId, verified("media-stream-id"));
@@ -40,7 +52,6 @@
             } else {
                 // Media block (content lines)
                 var cname;
-                var mid;
                 var msid;
                 var iceufrag;
                 var icepwd;
@@ -49,7 +60,7 @@
                     line = line.replace(cname[1], verified("ssrc"));
                     line = line.replace(cname[2], verified("cname"));
                 } else if (mid = match(line, regexp.mid))
-                    line = line.replace(mid[1], verified("mid"))
+                    line = line.replace(mid[1], verified("mid"));
                 else if (msid = match(line, regexp.msid)) {
                     if (msid[1])
                         line = line.replace(msid[1], verified("ssrc"));

Added: trunk/LayoutTests/platform/gtk/fast/mediastream/RTCPeerConnection-inspect-answer-expected.txt (0 => 214960)


--- trunk/LayoutTests/platform/gtk/fast/mediastream/RTCPeerConnection-inspect-answer-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/gtk/fast/mediastream/RTCPeerConnection-inspect-answer-expected.txt	2017-04-05 19:14:36 UTC (rev 214960)
@@ -0,0 +1,75 @@
+Test RTCPeerConnection.setRemoteDescription called with an RTCSessionDescription of type 'offer'
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Answer with audio created
+=== RTCSessionDescription ===
+type: answer, sdp:
+v=0
+o=- {session-id:OK} 0 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=group:BUNDLE {bundle:OK}
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=recvonly
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:active
+===
+
+PASS Answer with audio and video created
+=== RTCSessionDescription ===
+type: answer, sdp:
+v=0
+o=- {session-id:OK} 1 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=group:BUNDLE {bundle:OK}
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=recvonly
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:active
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=recvonly
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:active
+===
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/platform/gtk/fast/mediastream/RTCPeerConnection-inspect-offer-expected.txt (0 => 214960)


--- trunk/LayoutTests/platform/gtk/fast/mediastream/RTCPeerConnection-inspect-offer-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/gtk/fast/mediastream/RTCPeerConnection-inspect-offer-expected.txt	2017-04-05 19:14:36 UTC (rev 214960)
@@ -0,0 +1,81 @@
+Inspect the result of RTCPeerConnection.createOffer()
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Got offer
+=== RTCSessionDescription ===
+type: offer, sdp:
+v=0
+o=- {session-id:OK} 0 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=group:BUNDLE {bundle:OK}
+a=msid-semantic:WMS {media-stream-id:OK}
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+===
+
+PASS Got offer
+=== RTCSessionDescription ===
+type: offer, sdp:
+v=0
+o=- {session-id:OK} 1 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=group:BUNDLE {bundle:OK}
+a=msid-semantic:WMS {media-stream-id:OK}
+m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:111 OPUS/48000/2
+a=rtpmap:8 PCMA/8000
+a=rtpmap:0 PCMU/8000
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+m=video 9 UDP/TLS/RTP/SAVPF 103 100 120
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendrecv
+a=mid:{mid:OK}
+a=rtpmap:103 H264/90000
+a=rtpmap:100 VP8/90000
+a=rtpmap:120 RTX/90000
+a=fmtp:103 packetization-mode=1
+a=fmtp:120 apt=100;rtx-time=200
+a=rtcp-fb:100 nack
+a=rtcp-fb:103 nack pli
+a=rtcp-fb:100 nack pli
+a=rtcp-fb:103 ccm fir
+a=rtcp-fb:100 ccm fir
+a=ssrc:{ssrc:OK} cname:{cname:OK}
+a=msid:{media-stream-id:OK} {media-stream-track-id:OK}
+a=ice-ufrag:{ice-ufrag:OK}
+a=ice-pwd:{ice-password:OK}
+a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B
+a=setup:actpass
+===
+
+PASS End of promise chain
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Modified: trunk/Source/WebCore/ChangeLog (214959 => 214960)


--- trunk/Source/WebCore/ChangeLog	2017-04-05 19:09:28 UTC (rev 214959)
+++ trunk/Source/WebCore/ChangeLog	2017-04-05 19:14:36 UTC (rev 214960)
@@ -1,3 +1,31 @@
+2017-04-05  Carlos Alberto Lopez Perez  <[email protected]>
+
+        [WebRTC][OpenWebRTC] Add support for SDP BUNDLE ("a:group:BUNDLE" and "a=bundle-only" lines)
+        https://bugs.webkit.org/show_bug.cgi?id=170157
+
+        Reviewed by Alejandro G. Castro.
+
+        This implements support on the SDPProcessor for generating an "a=group:BUNDLE"
+        attribute with the MID identifiers specified in the bundle group in the most
+        recent answer.
+        It also implements support for generating "a=bundle-only" attributes on the
+        "m=" sections of the SDP according to the bundlePolicy defined.
+
+        Test: fast/mediastream/RTCPeerConnection-inspect-offer-bundlePolicy-bundle-only.html
+
+        * Modules/mediastream/MediaEndpointPeerConnection.cpp:
+        (WebCore::MediaEndpointPeerConnection::createOfferTask):
+        (WebCore::MediaEndpointPeerConnection::createAnswerTask):
+        * Modules/mediastream/SDPProcessor.cpp:
+        (WebCore::getBundlePolicyName):
+        (WebCore::configurationToJSON):
+        * Modules/mediastream/sdp.js:
+        (SDP.generate):
+        * platform/mediastream/MediaEndpointSessionConfiguration.h:
+        (WebCore::MediaEndpointSessionConfiguration::bundlePolicy):
+        (WebCore::MediaEndpointSessionConfiguration::setBundlePolicy):
+        (WebCore::MediaEndpointSessionConfiguration::clone):
+
 2017-04-05  Jer Noble  <[email protected]>
 
         [MSE] Seeks to currentTime=0 will fail if currentTime is already 0.

Modified: trunk/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp (214959 => 214960)


--- trunk/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp	2017-04-05 19:09:28 UTC (rev 214959)
+++ trunk/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp	2017-04-05 19:14:36 UTC (rev 214960)
@@ -159,6 +159,7 @@
     RefPtr<MediaEndpointSessionConfiguration> configurationSnapshot = localDescription ?
         localDescription->configuration()->clone() : MediaEndpointSessionConfiguration::create();
 
+    configurationSnapshot->setBundlePolicy(m_peerConnection.getConfiguration().bundlePolicy);
     configurationSnapshot->setSessionVersion(m_sdpOfferSessionVersion++);
 
     auto transceivers = RtpTransceiverVector(m_peerConnection.getTransceivers());
@@ -237,6 +238,7 @@
     RefPtr<MediaEndpointSessionConfiguration> configurationSnapshot = localDescription ?
         localDescription->configuration()->clone() : MediaEndpointSessionConfiguration::create();
 
+    configurationSnapshot->setBundlePolicy(m_peerConnection.getConfiguration().bundlePolicy);
     configurationSnapshot->setSessionVersion(m_sdpAnswerSessionVersion++);
 
     auto transceivers = RtpTransceiverVector(m_peerConnection.getTransceivers());

Modified: trunk/Source/WebCore/Modules/mediastream/SDPProcessor.cpp (214959 => 214960)


--- trunk/Source/WebCore/Modules/mediastream/SDPProcessor.cpp	2017-04-05 19:09:28 UTC (rev 214959)
+++ trunk/Source/WebCore/Modules/mediastream/SDPProcessor.cpp	2017-04-05 19:14:36 UTC (rev 214960)
@@ -57,6 +57,7 @@
 
 STRING_FUNCTION(address)
 STRING_FUNCTION(apt)
+STRING_FUNCTION(bundlePolicy)
 STRING_FUNCTION(candidates)
 STRING_FUNCTION(ccmfir)
 STRING_FUNCTION(channels)
@@ -340,9 +341,23 @@
     return createCandidate(*candidateObject);
 }
 
+static String getBundlePolicyName(const PeerConnectionStates::BundlePolicy bundlePolicy)
+{
+    switch (bundlePolicy) {
+    case PeerConnectionStates::BundlePolicy::MaxCompat:
+        return "max-compat";
+    case PeerConnectionStates::BundlePolicy::MaxBundle:
+        return "max-bundle";
+    case PeerConnectionStates::BundlePolicy::Balanced:
+    default:
+        return "balanced";
+    };
+}
+
 static String configurationToJSON(const MediaEndpointSessionConfiguration& configuration)
 {
     RefPtr<InspectorObject> object = InspectorObject::create();
+    object->setString(bundlePolicyString(), getBundlePolicyName(configuration.bundlePolicy()));
 
     RefPtr<InspectorObject> originatorObject = InspectorObject::create();
     originatorObject->setString(sessionIdString(), String::number(configuration.sessionId()));

Modified: trunk/Source/WebCore/Modules/mediastream/sdp.js (214959 => 214960)


--- trunk/Source/WebCore/Modules/mediastream/sdp.js	2017-04-05 19:09:28 UTC (rev 214959)
+++ trunk/Source/WebCore/Modules/mediastream/sdp.js	2017-04-05 19:14:36 UTC (rev 214960)
@@ -68,6 +68,7 @@
             "o=${username} ${sessionId} ${sessionVersion} ${netType} ${addressType} ${address}\r\n" +
             "s=${sessionName}\r\n" +
             "t=${startTime} ${stopTime}\r\n" +
+            "${bundleLine}" +
             "${msidsemanticLine}",
 
         "msidsemantic": "a=msid-semantic:WMS ${mediaStreamIds}\r\n",
@@ -77,6 +78,7 @@
             "c=${netType} ${addressType} ${address}\r\n" +
             "${rtcpLine}" +
             "${rtcpMuxLine}" +
+            "${bundleOnlyLine}" +
             "a=${mode}\r\n" +
             "${midLine}" +
             "${rtpMapLines}" +
@@ -96,6 +98,7 @@
         "rtcp": "a=rtcp:${port}${[ ]netType}${[ ]addressType}${[ ]address}\r\n",
         "rtcpMux": "a=rtcp-mux\r\n",
         "mid": "a=mid:${mid}\r\n",
+        "bundle": "a=group:BUNDLE ${midsBundle}\r\n",
 
         "rtpMap": "a=rtpmap:${type} ${encodingName}/${clockRate}${[/]channels}\r\n",
         "fmtp": "a=fmtp:${type} ${parameters}\r\n",
@@ -373,6 +376,7 @@
             "sessionName": "-",
             "startTime": 0,
             "stopTime": 0,
+            "bundlePolicy": "balanced",
             "mediaDescriptions": []
         });
         addDefaults(sdpObj.originator, {
@@ -386,6 +390,8 @@
         var sdpText = fillTemplate(templates.sdp, sdpObj);
         sdpText = fillTemplate(sdpText, sdpObj.originator);
 
+        var midsBundle = [];
+        var mediatypesBundle = [];
         var msidsemanticLine = "";
         var mediaStreamIds = [];
         sdpObj.mediaDescriptions.forEach(function (mdesc) {
@@ -412,10 +418,16 @@
             });
             var mblock = fillTemplate(templates.mblock, mediaDescription);
 
-            var midInfo = {"midLine": ""};
-            if (mediaDescription.mid)
-                midInfo.midLine = fillTemplate(templates.mid, mediaDescription);
-            mblock = fillTemplate(mblock, midInfo);
+            var midBundleInfo = {"midLine": "", "bundleOnlyLine": ""};
+            if (mediaDescription.mid) {
+                midBundleInfo.midLine = fillTemplate(templates.mid, mediaDescription);
+                if ((sdpObj.bundlePolicy == "balanced"   && mediatypesBundle.includes(mediaDescription.type)) ||
+                    (sdpObj.bundlePolicy == "max-bundle" && mediatypesBundle.length > 0))
+                    midBundleInfo.bundleOnlyLine = "a=bundle-only\r\n";
+                mediatypesBundle.push(mediaDescription.type)
+                midsBundle.push(mediaDescription.mid);
+            }
+            mblock = fillTemplate(mblock, midBundleInfo);
 
             var payloadInfo = {"rtpMapLines": "", "fmtpLines": "", "nackLines": "",
                 "nackpliLines": "", "ccmfirLines": "", "ericScreamLines": ""};
@@ -523,6 +535,11 @@
             sdpText += mblock;
         });
 
+        var bundleLine = "";
+        if (midsBundle.length > 0)
+            bundleLine = fillTemplate(templates.bundle, { "midsBundle": midsBundle.join(" ") });
+        sdpText = fillTemplate(sdpText, { "bundleLine": bundleLine });
+
         return sdpText;
     };
 

Modified: trunk/Source/WebCore/platform/mediastream/MediaEndpointSessionConfiguration.h (214959 => 214960)


--- trunk/Source/WebCore/platform/mediastream/MediaEndpointSessionConfiguration.h	2017-04-05 19:09:28 UTC (rev 214959)
+++ trunk/Source/WebCore/platform/mediastream/MediaEndpointSessionConfiguration.h	2017-04-05 19:14:36 UTC (rev 214960)
@@ -33,6 +33,7 @@
 
 #if ENABLE(WEB_RTC)
 
+#include "PeerConnectionStates.h"
 #include "PeerMediaDescription.h"
 #include <wtf/CryptographicallyRandomNumber.h>
 
@@ -56,6 +57,9 @@
     const Vector<PeerMediaDescription>& mediaDescriptions() const { return m_mediaDescriptions; }
     void addMediaDescription(PeerMediaDescription&& description) { m_mediaDescriptions.append(WTFMove(description)); }
 
+    PeerConnectionStates::BundlePolicy bundlePolicy() const { return m_bundlePolicy; }
+    void setBundlePolicy(PeerConnectionStates::BundlePolicy bundlePolicy) { m_bundlePolicy = bundlePolicy; }
+
     RefPtr<MediaEndpointSessionConfiguration> clone() const
     {
         RefPtr<MediaEndpointSessionConfiguration> copy = create();
@@ -62,6 +66,7 @@
         copy->m_sessionId = m_sessionId;
         copy->m_sessionVersion = m_sessionVersion;
         copy->m_mediaDescriptions = m_mediaDescriptions;
+        copy->m_bundlePolicy = m_bundlePolicy;
 
         return copy;
     }
@@ -77,6 +82,8 @@
     unsigned m_sessionVersion { 0 };
 
     Vector<PeerMediaDescription> m_mediaDescriptions;
+
+    PeerConnectionStates::BundlePolicy m_bundlePolicy { PeerConnectionStates::BundlePolicy::Balanced };
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to