Skip to content

Commit

Permalink
Enable Simulcast RTP Headers by default
Browse files Browse the repository at this point in the history
Relates to #2557
  • Loading branch information
Sean-Der committed Sep 13, 2023
1 parent 1345033 commit 050b4d4
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 75 deletions.
29 changes: 1 addition & 28 deletions examples/simulcast/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"os"
"time"

"github.com/pion/interceptor"
"github.com/pion/rtcp"
"github.com/pion/webrtc/v4"
"github.com/pion/webrtc/v4/examples/internal/signal"
Expand All @@ -33,34 +32,8 @@ func main() {
},
}

// Enable Extension Headers needed for Simulcast
m := &webrtc.MediaEngine{}
if err := m.RegisterDefaultCodecs(); err != nil {
panic(err)
}
for _, extension := range []string{
"urn:ietf:params:rtp-hdrext:sdes:mid",
"urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id",
"urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id",
} {
if err := m.RegisterHeaderExtension(webrtc.RTPHeaderExtensionCapability{URI: extension}, webrtc.RTPCodecTypeVideo); err != nil {
panic(err)
}
}

// Create a InterceptorRegistry. This is the user configurable RTP/RTCP Pipeline.
// This provides NACKs, RTCP Reports and other features. If you use `webrtc.NewPeerConnection`
// this is enabled by default. If you are manually managing You MUST create a InterceptorRegistry
// for each PeerConnection.
i := &interceptor.Registry{}

// Use the default set of Interceptors
if err := webrtc.RegisterDefaultInterceptors(m, i); err != nil {
panic(err)
}

// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewAPI(webrtc.WithMediaEngine(m), webrtc.WithInterceptorRegistry(i)).NewPeerConnection(config)
peerConnection, err := webrtc.NewPeerConnection(config)
if err != nil {
panic(err)
}
Expand Down
17 changes: 17 additions & 0 deletions interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ func RegisterDefaultInterceptors(mediaEngine *MediaEngine, interceptorRegistry *
return err
}

if err := ConfigureSimulcastExtensionHeaders(mediaEngine); err != nil {
return err
}

Check warning on line 35 in interceptor.go

View check run for this annotation

Codecov / codecov/patch

interceptor.go#L34-L35

Added lines #L34 - L35 were not covered by tests

return ConfigureTWCCSender(mediaEngine, interceptorRegistry)
}

Expand Down Expand Up @@ -123,6 +127,19 @@ func ConfigureCongestionControlFeedback(mediaEngine *MediaEngine, interceptorReg
return nil
}

// ConfigureSimulcastExtensionHeaders enables the RTP Extenison Headers needed for Simulcast
func ConfigureSimulcastExtensionHeaders(mediaEngine *MediaEngine) error {
if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.SDESMidURI}, RTPCodecTypeVideo); err != nil {
return err
}

Check warning on line 134 in interceptor.go

View check run for this annotation

Codecov / codecov/patch

interceptor.go#L133-L134

Added lines #L133 - L134 were not covered by tests

if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.SDESRTPStreamIDURI}, RTPCodecTypeVideo); err != nil {
return err
}

Check warning on line 138 in interceptor.go

View check run for this annotation

Codecov / codecov/patch

interceptor.go#L137-L138

Added lines #L137 - L138 were not covered by tests

return mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdesRepairRTPStreamIDURI}, RTPCodecTypeVideo)
}

type interceptorToTrackLocalWriter struct{ interceptor atomic.Value } // interceptor.RTPWriter }

func (i *interceptorToTrackLocalWriter) WriteRTP(header *rtp.Header, payload []byte) (int, error) {
Expand Down
2 changes: 1 addition & 1 deletion mediaengine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ a=rtpmap:111 opus/48000/2

m := MediaEngine{}
assert.NoError(t, m.RegisterDefaultCodecs())
registerSimulcastHeaderExtensions(&m, RTPCodecTypeAudio)
assert.NoError(t, m.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.SDESMidURI}, RTPCodecTypeAudio))
assert.NoError(t, m.updateFromRemoteDescription(mustParse(headerExtensions)))

assert.False(t, m.negotiatedVideo)
Expand Down
4 changes: 2 additions & 2 deletions peerconnection.go
Original file line number Diff line number Diff line change
Expand Up @@ -1671,17 +1671,17 @@ func (pc *PeerConnection) undeclaredRTPMediaProcessor() {
continue
}

pc.dtlsTransport.storeSimulcastStream(stream)

if atomic.AddUint64(&simulcastRoutineCount, 1) >= simulcastMaxProbeRoutines {
atomic.AddUint64(&simulcastRoutineCount, ^uint64(0))
pc.log.Warn(ErrSimulcastProbeOverflow.Error())
pc.dtlsTransport.storeSimulcastStream(stream)
continue
}

go func(rtpStream io.Reader, ssrc SSRC) {
if err := pc.handleIncomingSSRC(rtpStream, ssrc); err != nil {
pc.log.Errorf(incomingUnhandledRTPSsrc, ssrc, err)
pc.dtlsTransport.storeSimulcastStream(stream)
}
atomic.AddUint64(&simulcastRoutineCount, ^uint64(0))
}(stream, SSRC(ssrc))
Expand Down
37 changes: 4 additions & 33 deletions peerconnection_media_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,6 @@ var (
errNoTransceiverwithMid = errors.New("no transceiver with mid")
)

func registerSimulcastHeaderExtensions(m *MediaEngine, codecType RTPCodecType) {
for _, extension := range []string{
sdp.SDESMidURI,
sdp.SDESRTPStreamIDURI,
sdesRepairRTPStreamIDURI,
} {
if err := m.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: extension}, codecType); err != nil {
panic(err)
}
}
}

/*
Integration test for bi-directional peers
Expand Down Expand Up @@ -1051,10 +1039,8 @@ func TestPeerConnection_Simulcast_Probe(t *testing.T) {
unhandledSimulcastError := make(chan struct{})

m := &MediaEngine{}
if err := m.RegisterDefaultCodecs(); err != nil {
panic(err)
}
registerSimulcastHeaderExtensions(m, RTPCodecTypeVideo)
assert.NoError(t, m.RegisterDefaultCodecs())
assert.NoError(t, ConfigureSimulcastExtensionHeaders(m))

pcOffer, pcAnswer, err := NewAPI(WithSettingEngine(SettingEngine{
LoggerFactory: &undeclaredSsrcLoggerFactory{unhandledSimulcastError},
Expand Down Expand Up @@ -1086,7 +1072,6 @@ func TestPeerConnection_Simulcast_Probe(t *testing.T) {
filtered += scanner.Text() + "\r\n"
}
}

return
}))

Expand Down Expand Up @@ -1228,13 +1213,6 @@ func TestPeerConnection_Simulcast(t *testing.T) {
var ridMapLock sync.RWMutex
ridMap := map[string]int{}

// Enable Extension Headers needed for Simulcast
m := &MediaEngine{}
if err := m.RegisterDefaultCodecs(); err != nil {
panic(err)
}
registerSimulcastHeaderExtensions(m, RTPCodecTypeVideo)

assertRidCorrect := func(t *testing.T) {
ridMapLock.Lock()
defer ridMapLock.Unlock()
Expand All @@ -1260,7 +1238,7 @@ func TestPeerConnection_Simulcast(t *testing.T) {
}

t.Run("RTP Extension Based", func(t *testing.T) {
pcOffer, pcAnswer, err := NewAPI(WithMediaEngine(m)).newPair(Configuration{})
pcOffer, pcAnswer, err := newPair()
assert.NoError(t, err)

vp8WriterA, err := NewTrackLocalStaticRTP(RTPCodecCapability{MimeType: MimeTypeVP8}, "video", "pion2", WithRTPStreamID("a"))
Expand Down Expand Up @@ -1360,14 +1338,7 @@ func TestPeerConnection_Simulcast_NoDataChannel(t *testing.T) {
report := test.CheckRoutines(t)
defer report()

// Enable Extension Headers needed for Simulcast
m := &MediaEngine{}
if err := m.RegisterDefaultCodecs(); err != nil {
panic(err)
}
registerSimulcastHeaderExtensions(m, RTPCodecTypeVideo)

pcSender, pcReceiver, err := NewAPI(WithMediaEngine(m)).newPair(Configuration{})
pcSender, pcReceiver, err := newPair()
assert.NoError(t, err)

var wg sync.WaitGroup
Expand Down
10 changes: 2 additions & 8 deletions peerconnection_renegotiation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1014,12 +1014,6 @@ func TestPeerConnection_Renegotiation_Simulcast(t *testing.T) {
report := test.CheckRoutines(t)
defer report()

m := &MediaEngine{}
if err := m.RegisterDefaultCodecs(); err != nil {
panic(err)
}
registerSimulcastHeaderExtensions(m, RTPCodecTypeVideo)

originalRids := []string{"a", "b", "c"}
signalWithRids := func(sessionDescription string, rids []string) string {
sessionDescription = strings.SplitAfter(sessionDescription, "a=end-of-candidates\r\n")[0]
Expand Down Expand Up @@ -1081,7 +1075,7 @@ func TestPeerConnection_Renegotiation_Simulcast(t *testing.T) {

t.Run("Disable Transceiver", func(t *testing.T) {
trackMap = map[string]*TrackRemote{}
pcOffer, pcAnswer, err := NewAPI(WithMediaEngine(m)).newPair(Configuration{})
pcOffer, pcAnswer, err := newPair()
assert.NoError(t, err)

vp8Writer, err := NewTrackLocalStaticRTP(RTPCodecCapability{MimeType: MimeTypeVP8}, "video", "pion2")
Expand Down Expand Up @@ -1114,7 +1108,7 @@ func TestPeerConnection_Renegotiation_Simulcast(t *testing.T) {

t.Run("Change RID", func(t *testing.T) {
trackMap = map[string]*TrackRemote{}
pcOffer, pcAnswer, err := NewAPI(WithMediaEngine(m)).newPair(Configuration{})
pcOffer, pcAnswer, err := newPair()
assert.NoError(t, err)

vp8Writer, err := NewTrackLocalStaticRTP(RTPCodecCapability{MimeType: MimeTypeVP8}, "video", "pion2")
Expand Down
7 changes: 4 additions & 3 deletions rtpreceiver_go_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing"
"time"

"github.com/pion/sdp/v3"
"github.com/pion/webrtc/v4/pkg/media"
"github.com/stretchr/testify/assert"
)
Expand All @@ -34,9 +35,9 @@ func TestSetRTPParameters(t *testing.T) {
},
},
HeaderExtensions: []RTPHeaderExtensionParameter{
{URI: "urn:ietf:params:rtp-hdrext:sdes:mid"},
{URI: "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"},
{URI: "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"},
{URI: sdp.SDESMidURI},
{URI: sdp.SDESRTPStreamIDURI},
{URI: sdesRepairRTPStreamIDURI},
},
}

Expand Down

0 comments on commit 050b4d4

Please sign in to comment.