Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multi codec negotiation feature #3018

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions mediaengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type mediaEngineHeaderExtension struct {
type MediaEngine struct {
// If we have attempted to negotiate a codec type yet.
negotiatedVideo, negotiatedAudio bool
negotiateMultiCodecs bool

videoCodecs, audioCodecs []RTPCodecParameters
negotiatedVideoCodecs, negotiatedAudioCodecs []RTPCodecParameters
Expand All @@ -78,6 +79,22 @@ type MediaEngine struct {
mu sync.RWMutex
}

// SetMultiCodecNegotiation enables or disables the negotiation of multiple codecs.
func (m *MediaEngine) SetMultiCodecNegotiation(negotiateMultiCodecs bool) {
m.mu.Lock()
defer m.mu.Unlock()

m.negotiateMultiCodecs = negotiateMultiCodecs
}

// MultiCodecNegotiation returns the current state of the negotiation of multiple codecs.
func (m *MediaEngine) MultiCodecNegotiation() bool {
m.mu.RLock()
defer m.mu.RUnlock()

return m.negotiateMultiCodecs
}

// RegisterDefaultCodecs registers the default codecs supported by Pion WebRTC.
// RegisterDefaultCodecs is not safe for concurrent use.
func (m *MediaEngine) RegisterDefaultCodecs() error {
Expand Down Expand Up @@ -596,9 +613,9 @@ func (m *MediaEngine) updateFromRemoteDescription(desc sdp.SessionDescription) e
}

switch {
case !m.negotiatedAudio && typ == RTPCodecTypeAudio:
case (!m.negotiatedAudio || m.negotiateMultiCodecs) && typ == RTPCodecTypeAudio:
m.negotiatedAudio = true
case !m.negotiatedVideo && typ == RTPCodecTypeVideo:
case (!m.negotiatedVideo || m.negotiateMultiCodecs) && typ == RTPCodecTypeVideo:
m.negotiatedVideo = true
default:
// update header extesions from remote sdp if codec is negotiated, Firefox
Expand Down
65 changes: 65 additions & 0 deletions mediaengine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -876,3 +876,68 @@ a=rtcp-fb:96 nack
runTest(t, true)
})
}

func TestMultiCodecNegotiation(t *testing.T) {
const offerSdp = `v=0
o=- 781500112831855234 6 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1 2 3
a=extmap-allow-mixed
a=msid-semantic: WMS be0216be-f3d8-40ca-a624-379edf70f1c9
m=application 53555 UDP/DTLS/SCTP webrtc-datachannel
a=mid:0
a=sctp-port:5000
a=max-message-size:262144
m=video 9 UDP/TLS/RTP/SAVPF 98
a=mid:1
a=sendonly
a=msid:be0216be-f3d8-40ca-a624-379edf70f1c9 3d032b3b-ffe5-48ec-b783-21375668d1c3
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 profile-id=0
a=rid:q send
a=rid:h send
a=simulcast:send q;h
m=video 9 UDP/TLS/RTP/SAVPF 96
a=mid:2
a=sendonly
a=msid:6ff05509-be96-4ef1-a74f-425e14720983 16d5d7fe-d076-4718-9ca9-ec62b4543727
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=ssrc:4281768245 cname:JDM9GNMEg+9To6K7
a=ssrc:4281768245 msid:6ff05509-be96-4ef1-a74f-425e14720983 16d5d7fe-d076-4718-9ca9-ec62b4543727
`
mustParse := func(raw string) sdp.SessionDescription {
s := sdp.SessionDescription{}
assert.NoError(t, s.Unmarshal([]byte(raw)))

return s
}
t.Run("Multi codec negotiation disabled", func(t *testing.T) {
mediaEngine := MediaEngine{}
assert.NoError(t, mediaEngine.RegisterDefaultCodecs())
assert.NoError(t, mediaEngine.updateFromRemoteDescription(mustParse(offerSdp)))
assert.Len(t, mediaEngine.negotiatedVideoCodecs, 1)
})
t.Run("Multi codec negotiation enabled", func(t *testing.T) {
mediaEngine := MediaEngine{}
mediaEngine.SetMultiCodecNegotiation(true)
assert.True(t, mediaEngine.MultiCodecNegotiation())
assert.NoError(t, mediaEngine.RegisterDefaultCodecs())
assert.NoError(t, mediaEngine.updateFromRemoteDescription(mustParse(offerSdp)))
assert.Len(t, mediaEngine.negotiatedVideoCodecs, 2)
})
}
Loading