mirror of
https://github.com/pion/webrtc.git
synced 2025-09-27 03:25:58 +08:00
Increase requirements for Plan-B detection
Before a SessionDescription was assumed to be Plan-B if it contained a MediaName of `audio` or `video`. This PR Changes that behavior. If SDPSemantics is UnifiedPlan the SessionDescription must contain a MediaDescription with two SSRCes to be considered a Plan-B. Before if the MediaDescription had name of `audio` or `video` it was assumed to be Plan-B. If SDPSemantics is PlanB or UnifiedPlanWithFallback it maintains the existing behavior. Resolves #2193
This commit is contained in:
@@ -635,8 +635,8 @@ func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription
|
|||||||
// in-parallel steps to create an offer
|
// in-parallel steps to create an offer
|
||||||
// https://w3c.github.io/webrtc-pc/#dfn-in-parallel-steps-to-create-an-offer
|
// https://w3c.github.io/webrtc-pc/#dfn-in-parallel-steps-to-create-an-offer
|
||||||
isPlanB := pc.configuration.SDPSemantics == SDPSemanticsPlanB
|
isPlanB := pc.configuration.SDPSemantics == SDPSemanticsPlanB
|
||||||
if pc.currentRemoteDescription != nil {
|
if pc.currentRemoteDescription != nil && isPlanB {
|
||||||
isPlanB = descriptionIsPlanB(pc.currentRemoteDescription)
|
isPlanB = descriptionPossiblyPlanB(pc.currentRemoteDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
// include unmatched local transceivers
|
// include unmatched local transceivers
|
||||||
@@ -1032,7 +1032,11 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error {
|
|||||||
|
|
||||||
var t *RTPTransceiver
|
var t *RTPTransceiver
|
||||||
localTransceivers := append([]*RTPTransceiver{}, pc.GetTransceivers()...)
|
localTransceivers := append([]*RTPTransceiver{}, pc.GetTransceivers()...)
|
||||||
detectedPlanB := descriptionIsPlanB(pc.RemoteDescription())
|
detectedPlanB := descriptionIsPlanB(pc.RemoteDescription(), pc.log)
|
||||||
|
if pc.configuration.SDPSemantics != SDPSemanticsUnifiedPlan {
|
||||||
|
detectedPlanB = descriptionPossiblyPlanB(pc.RemoteDescription())
|
||||||
|
}
|
||||||
|
|
||||||
weOffer := desc.Type == SDPTypeAnswer
|
weOffer := desc.Type == SDPTypeAnswer
|
||||||
|
|
||||||
if !weOffer && !detectedPlanB {
|
if !weOffer && !detectedPlanB {
|
||||||
@@ -1355,7 +1359,7 @@ func (pc *PeerConnection) startRTPReceivers(remoteDesc *SessionDescription, curr
|
|||||||
case SDPSemanticsPlanB:
|
case SDPSemanticsPlanB:
|
||||||
remoteIsPlanB = true
|
remoteIsPlanB = true
|
||||||
case SDPSemanticsUnifiedPlanWithFallback:
|
case SDPSemanticsUnifiedPlanWithFallback:
|
||||||
remoteIsPlanB = descriptionIsPlanB(pc.RemoteDescription())
|
remoteIsPlanB = descriptionPossiblyPlanB(pc.RemoteDescription())
|
||||||
default:
|
default:
|
||||||
// none
|
// none
|
||||||
}
|
}
|
||||||
@@ -2281,7 +2285,12 @@ func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, use
|
|||||||
}
|
}
|
||||||
isExtmapAllowMixed := isExtMapAllowMixedSet(remoteDescription.parsed)
|
isExtmapAllowMixed := isExtMapAllowMixedSet(remoteDescription.parsed)
|
||||||
localTransceivers := append([]*RTPTransceiver{}, transceivers...)
|
localTransceivers := append([]*RTPTransceiver{}, transceivers...)
|
||||||
detectedPlanB := descriptionIsPlanB(remoteDescription)
|
|
||||||
|
detectedPlanB := descriptionIsPlanB(remoteDescription, pc.log)
|
||||||
|
if pc.configuration.SDPSemantics != SDPSemanticsUnifiedPlan {
|
||||||
|
detectedPlanB = descriptionPossiblyPlanB(remoteDescription)
|
||||||
|
}
|
||||||
|
|
||||||
mediaSections := []mediaSection{}
|
mediaSections := []mediaSection{}
|
||||||
alreadyHaveApplicationMediaSection := false
|
alreadyHaveApplicationMediaSection := false
|
||||||
for _, media := range remoteDescription.parsed.MediaDescriptions {
|
for _, media := range remoteDescription.parsed.MediaDescriptions {
|
||||||
|
@@ -486,6 +486,7 @@ t=0 0
|
|||||||
a=group:BUNDLE audio
|
a=group:BUNDLE audio
|
||||||
a=msid-semantic: WMS 2867270241552712
|
a=msid-semantic: WMS 2867270241552712
|
||||||
m=video 0 UDP/TLS/RTP/SAVPF 0
|
m=video 0 UDP/TLS/RTP/SAVPF 0
|
||||||
|
a=mid:video
|
||||||
c=IN IP4 192.168.84.254
|
c=IN IP4 192.168.84.254
|
||||||
a=inactive
|
a=inactive
|
||||||
m=audio 9 UDP/TLS/RTP/SAVPF 111
|
m=audio 9 UDP/TLS/RTP/SAVPF 111
|
||||||
|
24
sdp.go
24
sdp.go
@@ -568,7 +568,29 @@ func getMidValue(media *sdp.MediaDescription) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func descriptionIsPlanB(desc *SessionDescription) bool {
|
// SessionDescription contains a MediaSection with Multiple SSRCs, it is Plan-B
|
||||||
|
func descriptionIsPlanB(desc *SessionDescription, log logging.LeveledLogger) bool {
|
||||||
|
if desc == nil || desc.parsed == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store all MIDs that already contain a track
|
||||||
|
midWithTrack := map[string]bool{}
|
||||||
|
|
||||||
|
for _, trackDetail := range trackDetailsFromSDP(log, desc.parsed) {
|
||||||
|
if _, ok := midWithTrack[trackDetail.mid]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
midWithTrack[trackDetail.mid] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionDescription contains a MediaSection with name `audio`, `video` or `data`
|
||||||
|
// If only one SSRC is set we can't know if it is Plan-B or Unified. If users have
|
||||||
|
// set fallback mode assume it is Plan-B
|
||||||
|
func descriptionPossiblyPlanB(desc *SessionDescription) bool {
|
||||||
if desc == nil || desc.parsed == nil {
|
if desc == nil || desc.parsed == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@@ -325,7 +325,7 @@ func TestSDPSemantics_UnifiedPlanWithFallback(t *testing.T) {
|
|||||||
|
|
||||||
// Assert that we can catch Remote SessionDescription that don't match our Semantics
|
// Assert that we can catch Remote SessionDescription that don't match our Semantics
|
||||||
func TestSDPSemantics_SetRemoteDescription_Mismatch(t *testing.T) {
|
func TestSDPSemantics_SetRemoteDescription_Mismatch(t *testing.T) {
|
||||||
planBOffer := "v=0\r\no=- 4648475892259889561 3 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE video audio\r\na=ice-ufrag:1hhfzwf0ijpzm\r\na=ice-pwd:jm5puo2ab1op3vs59ca53bdk7s\r\na=fingerprint:sha-256 40:42:FB:47:87:52:BF:CB:EC:3A:DF:EB:06:DA:2D:B7:2F:59:42:10:23:7B:9D:4C:C9:58:DD:FF:A2:8F:17:67\r\nm=video 9 UDP/TLS/RTP/SAVPF 96\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=setup:passive\r\na=mid:video\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:96 H264/90000\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 goog-remb\r\na=fmtp:96 packetization-mode=1;profile-level-id=42e01f\r\na=ssrc:1505338584 cname:10000000b5810aac\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=setup:passive\r\na=mid:audio\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=ssrc:697641945 cname:10000000b5810aac\r\n"
|
planBOffer := "v=0\r\no=- 4648475892259889561 3 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE video audio\r\na=ice-ufrag:1hhfzwf0ijpzm\r\na=ice-pwd:jm5puo2ab1op3vs59ca53bdk7s\r\na=fingerprint:sha-256 40:42:FB:47:87:52:BF:CB:EC:3A:DF:EB:06:DA:2D:B7:2F:59:42:10:23:7B:9D:4C:C9:58:DD:FF:A2:8F:17:67\r\nm=video 9 UDP/TLS/RTP/SAVPF 96\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=setup:passive\r\na=mid:video\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:96 H264/90000\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 goog-remb\r\na=fmtp:96 packetization-mode=1;profile-level-id=42e01f\r\na=ssrc:1505338584 cname:10000000b5810aac\r\na=ssrc:1 cname:trackB\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=setup:passive\r\na=mid:audio\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=ssrc:697641945 cname:10000000b5810aac\r\n"
|
||||||
unifiedPlanOffer := "v=0\r\no=- 4648475892259889561 3 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=ice-ufrag:1hhfzwf0ijpzm\r\na=ice-pwd:jm5puo2ab1op3vs59ca53bdk7s\r\na=fingerprint:sha-256 40:42:FB:47:87:52:BF:CB:EC:3A:DF:EB:06:DA:2D:B7:2F:59:42:10:23:7B:9D:4C:C9:58:DD:FF:A2:8F:17:67\r\nm=video 9 UDP/TLS/RTP/SAVPF 96\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=setup:passive\r\na=mid:0\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:96 H264/90000\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 goog-remb\r\na=fmtp:96 packetization-mode=1;profile-level-id=42e01f\r\na=ssrc:1505338584 cname:10000000b5810aac\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=setup:passive\r\na=mid:1\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=ssrc:697641945 cname:10000000b5810aac\r\n"
|
unifiedPlanOffer := "v=0\r\no=- 4648475892259889561 3 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=ice-ufrag:1hhfzwf0ijpzm\r\na=ice-pwd:jm5puo2ab1op3vs59ca53bdk7s\r\na=fingerprint:sha-256 40:42:FB:47:87:52:BF:CB:EC:3A:DF:EB:06:DA:2D:B7:2F:59:42:10:23:7B:9D:4C:C9:58:DD:FF:A2:8F:17:67\r\nm=video 9 UDP/TLS/RTP/SAVPF 96\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=setup:passive\r\na=mid:0\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:96 H264/90000\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 goog-remb\r\na=fmtp:96 packetization-mode=1;profile-level-id=42e01f\r\na=ssrc:1505338584 cname:10000000b5810aac\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=setup:passive\r\na=mid:1\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=ssrc:697641945 cname:10000000b5810aac\r\n"
|
||||||
|
|
||||||
report := test.CheckRoutines(t)
|
report := test.CheckRoutines(t)
|
||||||
|
Reference in New Issue
Block a user