Skip to content

Commit 935e0e6

Browse files
committed
Automatically configure RTX codecs
1 parent 3e43ae9 commit 935e0e6

File tree

13 files changed

+392
-33
lines changed

13 files changed

+392
-33
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ jobs:
2121
release:
2222
uses: pion/.goassets/.github/workflows/release.reusable.yml@master
2323
with:
24-
go-version: "1.22" # auto-update/latest-go-version
24+
go-version: "1.24" # auto-update/latest-go-version

.github/workflows/test.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
uses: pion/.goassets/.github/workflows/test.reusable.yml@master
2424
strategy:
2525
matrix:
26-
go: ["1.23", "1.22"] # auto-update/supported-go-version-list
26+
go: ["1.24", "1.23"] # auto-update/supported-go-version-list
2727
fail-fast: false
2828
with:
2929
go-version: ${{ matrix.go }}
@@ -33,13 +33,13 @@ jobs:
3333
uses: pion/.goassets/.github/workflows/test-i386.reusable.yml@master
3434
strategy:
3535
matrix:
36-
go: ["1.23", "1.22"] # auto-update/supported-go-version-list
36+
go: ["1.24", "1.23"] # auto-update/supported-go-version-list
3737
fail-fast: false
3838
with:
3939
go-version: ${{ matrix.go }}
4040

4141
test-wasm:
4242
uses: pion/.goassets/.github/workflows/test-wasm.reusable.yml@master
4343
with:
44-
go-version: "1.23" # auto-update/latest-go-version
44+
go-version: "1.24" # auto-update/latest-go-version
4545
secrets: inherit

.github/workflows/tidy-check.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ jobs:
2222
tidy:
2323
uses: pion/.goassets/.github/workflows/tidy-check.reusable.yml@master
2424
with:
25-
go-version: "1.22" # auto-update/latest-go-version
25+
go-version: "1.24" # auto-update/latest-go-version

.reuse/dep5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ Files: README.md DESIGN.md **/README.md AUTHORS.txt renovate.json go.mod go.sum
66
Copyright: 2023 The Pion community <https://pion.ly>
77
License: MIT
88

9-
Files: testdata/fuzz/* **/testdata/fuzz/* api/*.txt
9+
Files: testdata/seed/* testdata/fuzz/* **/testdata/fuzz/* api/*.txt
1010
Copyright: 2023 The Pion community <https://pion.ly>
1111
License: CC0-1.0

certificate_test.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -104,24 +104,6 @@ func TestGenerateCertificateExpires(t *testing.T) {
104104
assert.Contains(t, x509Cert.statsID, "certificate")
105105
}
106106

107-
func TestBadCertificate(t *testing.T) {
108-
var nokey interface{}
109-
badcert, err := NewCertificate(nokey, x509.Certificate{})
110-
assert.Nil(t, badcert)
111-
assert.Error(t, err)
112-
113-
sk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
114-
assert.Nil(t, err)
115-
116-
badcert, err = NewCertificate(sk, x509.Certificate{})
117-
assert.Nil(t, badcert)
118-
assert.Error(t, err)
119-
120-
c0 := Certificate{}
121-
c1 := Certificate{}
122-
assert.False(t, c0.Equals(c1))
123-
}
124-
125107
func TestPEM(t *testing.T) {
126108
sk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
127109
assert.Nil(t, err)

examples/save-to-disk-av1/main.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ func main() {
5353
// Create a MediaEngine object to configure the supported codec
5454
mediaEngine := &webrtc.MediaEngine{}
5555

56-
// Setup the codecs you want to use.
57-
// We'll use a VP8 and Opus but you can also define your own
5856
if err := mediaEngine.RegisterCodec(webrtc.RTPCodecParameters{
5957
RTPCodecCapability: webrtc.RTPCodecCapability{
6058
MimeType: webrtc.MimeTypeAV1,

mediaengine.go

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type mediaEngineHeaderExtension struct {
3333
type MediaEngine struct {
3434
// If we have attempted to negotiate a codec type yet.
3535
negotiatedVideo, negotiatedAudio bool
36+
negotiateMultiCodecs bool
3637

3738
videoCodecs, audioCodecs []RTPCodecParameters
3839
negotiatedVideoCodecs, negotiatedAudioCodecs []RTPCodecParameters
@@ -43,6 +44,22 @@ type MediaEngine struct {
4344
mu sync.RWMutex
4445
}
4546

47+
// setMultiCodecNegotiation enables or disables the negotiation of multiple codecs.
48+
func (m *MediaEngine) setMultiCodecNegotiation(negotiateMultiCodecs bool) {
49+
m.mu.Lock()
50+
defer m.mu.Unlock()
51+
52+
m.negotiateMultiCodecs = negotiateMultiCodecs
53+
}
54+
55+
// multiCodecNegotiation returns the current state of the negotiation of multiple codecs.
56+
func (m *MediaEngine) multiCodecNegotiation() bool {
57+
m.mu.RLock()
58+
defer m.mu.RUnlock()
59+
60+
return m.negotiateMultiCodecs
61+
}
62+
4663
// RegisterDefaultCodecs registers the default codecs supported by Pion WebRTC.
4764
// RegisterDefaultCodecs is not safe for concurrent use.
4865
func (m *MediaEngine) RegisterDefaultCodecs() error {
@@ -159,7 +176,18 @@ func (m *MediaEngine) RegisterDefaultCodecs() error {
159176
RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=39", nil},
160177
PayloadType: 40,
161178
},
162-
179+
{
180+
RTPCodecCapability: RTPCodecCapability{
181+
MimeType: MimeTypeH265,
182+
ClockRate: 90000,
183+
RTCPFeedback: videoRTCPFeedback,
184+
},
185+
PayloadType: 116,
186+
},
187+
{
188+
RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=116", nil},
189+
PayloadType: 117,
190+
},
163191
{
164192
RTPCodecCapability: RTPCodecCapability{MimeTypeAV1, 90000, 0, "", videoRTCPFeedback},
165193
PayloadType: 45,
@@ -245,6 +273,44 @@ func (m *MediaEngine) RegisterCodec(codec RTPCodecParameters, typ RTPCodecType)
245273
return err
246274
}
247275

276+
func (m *MediaEngine) autoConfigRTXCodecs() error {
277+
additionalRTXCodecs := []RTPCodecParameters{}
278+
for _, codec := range m.videoCodecs {
279+
// ignore FEC & RTX
280+
if strings.Contains(codec.MimeType, MimeTypeFlexFEC) || codec.MimeType == MimeTypeRTX {
281+
continue
282+
}
283+
haveNACK := false
284+
for _, fb := range codec.RTCPFeedback {
285+
if fb.Type == "nack" {
286+
haveNACK = true
287+
288+
break
289+
}
290+
}
291+
if haveNACK {
292+
additionalRTXCodecs = append(additionalRTXCodecs, RTPCodecParameters{
293+
RTPCodecCapability: RTPCodecCapability{
294+
MimeType: MimeTypeRTX,
295+
ClockRate: 90000,
296+
Channels: 0,
297+
SDPFmtpLine: fmt.Sprintf("apt=%d", codec.PayloadType),
298+
RTCPFeedback: nil,
299+
},
300+
PayloadType: codec.PayloadType + 1,
301+
})
302+
}
303+
}
304+
for i := range additionalRTXCodecs {
305+
err := m.RegisterCodec(additionalRTXCodecs[i], RTPCodecTypeVideo)
306+
if err != nil {
307+
return err
308+
}
309+
}
310+
311+
return nil
312+
}
313+
248314
// RegisterHeaderExtension adds a header extension to the MediaEngine
249315
// To determine the negotiated value use `GetHeaderExtensionID` after signaling is complete.
250316
//
@@ -564,7 +630,7 @@ func (m *MediaEngine) pushCodecs(codecs []RTPCodecParameters, typ RTPCodecType)
564630
}
565631

566632
// Update the MediaEngine from a remote description.
567-
func (m *MediaEngine) updateFromRemoteDescription(desc sdp.SessionDescription) error { //nolint:cyclop
633+
func (m *MediaEngine) updateFromRemoteDescription(desc sdp.SessionDescription) error { //nolint:cyclop,gocognit
568634
m.mu.Lock()
569635
defer m.mu.Unlock()
570636

@@ -592,7 +658,9 @@ func (m *MediaEngine) updateFromRemoteDescription(desc sdp.SessionDescription) e
592658
return err
593659
}
594660

595-
continue
661+
if !m.negotiateMultiCodecs || (typ != RTPCodecTypeAudio && typ != RTPCodecTypeVideo) {
662+
continue
663+
}
596664
}
597665

598666
codecs, err := codecsFromMediaDescription(media)

0 commit comments

Comments
 (0)