From 3615fe000556d61977262397d59c6af927e80e2a Mon Sep 17 00:00:00 2001 From: Ellen Hui Date: Thu, 30 Mar 2023 16:25:28 -0700 Subject: [PATCH 1/3] match heaader extensions to offer --- mediaengine.go | 24 ++++++++++++++++++++---- peerconnection.go | 4 +++- sdp.go | 13 +++++++++---- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/mediaengine.go b/mediaengine.go index cfe4e47124..9293962d62 100644 --- a/mediaengine.go +++ b/mediaengine.go @@ -475,14 +475,30 @@ func (m *MediaEngine) updateFromRemoteDescription(desc sdp.SessionDescription) e for _, media := range desc.MediaDescriptions { var typ RTPCodecType + + // Determine the type switch { - case !m.negotiatedAudio && strings.EqualFold(media.MediaName.Media, "audio"): - m.negotiatedAudio = true + case strings.EqualFold(media.MediaName.Media, "audio"): typ = RTPCodecTypeAudio - case !m.negotiatedVideo && strings.EqualFold(media.MediaName.Media, "video"): - m.negotiatedVideo = true + case strings.EqualFold(media.MediaName.Media, "video"): typ = RTPCodecTypeVideo + } + + switch { + case !m.negotiatedAudio && typ == RTPCodecTypeAudio: + m.negotiatedAudio = true + case !m.negotiatedVideo && typ == RTPCodecTypeVideo: + m.negotiatedVideo = true default: + extensions, err := rtpExtensionsFromMediaDescription(media) + if err != nil { + return err + } + for extension, id := range extensions { + if err = m.updateHeaderExtension(id, extension, typ); err != nil { + return err + } + } continue } diff --git a/peerconnection.go b/peerconnection.go index 5cfaf85bae..6fa0c85cc8 100644 --- a/peerconnection.go +++ b/peerconnection.go @@ -2435,7 +2435,9 @@ func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, use sender.setNegotiated() } mediaTransceivers := []*RTPTransceiver{t} - mediaSections = append(mediaSections, mediaSection{id: midValue, transceivers: mediaTransceivers, ridMap: getRids(media)}) + + extensions, _ := rtpExtensionsFromMediaDescription(media) + mediaSections = append(mediaSections, mediaSection{id: midValue, transceivers: mediaTransceivers, extensions: extensions, ridMap: getRids(media)}) } } diff --git a/sdp.go b/sdp.go index f0123d2bdd..94ecbca599 100644 --- a/sdp.go +++ b/sdp.go @@ -456,11 +456,15 @@ func addTransceiverSDP( parameters := mediaEngine.getRTPParametersByKind(t.kind, directions) for _, rtpExtension := range parameters.HeaderExtensions { - extURL, err := url.Parse(rtpExtension.URI) - if err != nil { - return false, err + if mediaSection.extensions != nil { + if _, enabled := mediaSection.extensions[rtpExtension.URI]; enabled { + extURL, err := url.Parse(rtpExtension.URI) + if err != nil { + return false, err + } + media.WithExtMap(sdp.ExtMap{Value: rtpExtension.ID, URI: extURL}) + } } - media.WithExtMap(sdp.ExtMap{Value: rtpExtension.ID, URI: extURL}) } if len(mediaSection.ridMap) > 0 { @@ -498,6 +502,7 @@ type mediaSection struct { transceivers []*RTPTransceiver data bool ridMap map[string]string + extensions map[string]int } // populateSDP serializes a PeerConnections state into an SDP From c5b639b3b0f2f12ed14e3b8594d3c8fed404e087 Mon Sep 17 00:00:00 2001 From: Ellen Hui Date: Thu, 6 Apr 2023 17:17:03 +0000 Subject: [PATCH 2/3] Add a test case that triggers the error --- mediaengine_test.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/mediaengine_test.go b/mediaengine_test.go index a92cd7da93..2f5bb61650 100644 --- a/mediaengine_test.go +++ b/mediaengine_test.go @@ -209,6 +209,38 @@ a=rtpmap:111 opus/48000/2 assert.False(t, midVideoEnabled) }) + t.Run("Different Header Extensions on same codec", func(t *testing.T) { + const headerExtensions = `v=0 +o=- 4596489990601351948 2 IN IP4 127.0.0.1 +s=- +t=0 0 +m=audio 9 UDP/TLS/RTP/SAVPF 111 +a=rtpmap:111 opus/48000/2 +m=audio 9 UDP/TLS/RTP/SAVPF 111 +a=extmap:7 urn:ietf:params:rtp-hdrext:sdes:mid +a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id +a=rtpmap:111 opus/48000/2 +` + + m := MediaEngine{} + assert.NoError(t, m.RegisterDefaultCodecs()) + registerSimulcastHeaderExtensions(&m, RTPCodecTypeAudio) + assert.NoError(t, m.updateFromRemoteDescription(mustParse(headerExtensions))) + + assert.False(t, m.negotiatedVideo) + assert.True(t, m.negotiatedAudio) + + absID, absAudioEnabled, absVideoEnabled := m.getHeaderExtensionID(RTPHeaderExtensionCapability{sdp.ABSSendTimeURI}) + assert.Equal(t, absID, 0) + assert.False(t, absAudioEnabled) + assert.False(t, absVideoEnabled) + + midID, midAudioEnabled, midVideoEnabled := m.getHeaderExtensionID(RTPHeaderExtensionCapability{sdp.SDESMidURI}) + assert.Equal(t, midID, 7) + assert.True(t, midAudioEnabled) + assert.False(t, midVideoEnabled) + }) + t.Run("Prefers exact codec matches", func(t *testing.T) { const profileLevels = `v=0 o=- 4596489990601351948 2 IN IP4 127.0.0.1 From 63d2ca383fa9bbeb6c68c1193b5b86ac5d4efde3 Mon Sep 17 00:00:00 2001 From: Ellen Hui Date: Thu, 6 Apr 2023 17:33:24 +0000 Subject: [PATCH 3/3] add a multi-codec test --- mediaengine_test.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/mediaengine_test.go b/mediaengine_test.go index 2f5bb61650..39196b77d4 100644 --- a/mediaengine_test.go +++ b/mediaengine_test.go @@ -397,6 +397,40 @@ a=fmtp:97 apt=96 _, _, err := m.getCodecByPayload(97) assert.ErrorIs(t, err, ErrCodecNotFound) }) + + t.Run("Multiple codecs same kind", func(t *testing.T) { + const mixedCodecs = `v=0 +o=- 4596489990601351948 2 IN IP4 127.0.0.1 +s=- +t=0 0 +m=video 60323 UDP/TLS/RTP/SAVPF 96 +a=rtpmap:96 VP9/90000 +m=video 60323 UDP/TLS/RTP/SAVPF 94 +a=rtpmap:94 VP8/90000 +` + m := MediaEngine{} + assert.NoError(t, m.RegisterCodec(RTPCodecParameters{ + RTPCodecCapability: RTPCodecCapability{MimeTypeVP8, 90000, 0, "", nil}, + PayloadType: 94, + }, RTPCodecTypeVideo)) + assert.NoError(t, m.RegisterCodec(RTPCodecParameters{ + RTPCodecCapability: RTPCodecCapability{MimeTypeVP9, 90000, 0, "", nil}, + PayloadType: 96, + }, RTPCodecTypeVideo)) + + assert.NoError(t, m.updateFromRemoteDescription(mustParse(mixedCodecs))) + assert.True(t, m.negotiatedVideo) + + vp8Codec, _, err := m.getCodecByPayload(94) + assert.NoError(t, err) + assert.Equal(t, vp8Codec.MimeType, MimeTypeVP8) + + vp9Codec, _, err := m.getCodecByPayload(96) + assert.NoError(t, err) + assert.Equal(t, vp9Codec.MimeType, MimeTypeVP9) + + }) + } func TestMediaEngineHeaderExtensionDirection(t *testing.T) {