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

Enable Simulcast RTP Headers by default #2576

Merged
merged 1 commit into from
Sep 13, 2023
Merged
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
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 @@
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 @@
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
Loading