From 478f6937c38624cffb971668af0a2e76639feb62 Mon Sep 17 00:00:00 2001 From: David Chen Date: Sun, 30 Aug 2026 17:43:57 -0700 Subject: [PATCH] Fix FlexFEC negotiation with libwebrtc publishers --- pkg/rtc/mediaengine.go | 5 +++-- pkg/rtc/transport_fec_test.go | 6 +++--- pkg/sfu/buffer/buffer_fec_test.go | 2 +- test/flexfec_upstream_test.go | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pkg/rtc/mediaengine.go b/pkg/rtc/mediaengine.go index 57016344c..2f5156643 100644 --- a/pkg/rtc/mediaengine.go +++ b/pkg/rtc/mediaengine.go @@ -26,8 +26,9 @@ import ( ) // flexFECRepairWindow is the flexfec-03 "repair-window" fmtp value in -// microseconds (2 s). -const flexFECRepairWindow = 2_000_000 +// microseconds (10 s), matching libwebrtc and pion's fixed advertised value. +// A different value prevents those publishers from negotiating FlexFEC. +const flexFECRepairWindow = 10_000_000 // flexFECCodecParameters returns the flexfec-03 codec registered/offered when // FlexFEC is enabled for a direction. Mirrors pion's ConfigureFlexFEC03 codec diff --git a/pkg/rtc/transport_fec_test.go b/pkg/rtc/transport_fec_test.go index fb33b66f0..4c0e9a194 100644 --- a/pkg/rtc/transport_fec_test.go +++ b/pkg/rtc/transport_fec_test.go @@ -40,7 +40,7 @@ a=rtpmap:96 VP8/90000 a=rtpmap:97 rtx/90000 a=fmtp:97 apt=96 a=rtpmap:115 flexfec-03/90000 -a=fmtp:115 repair-window=2000000 +a=fmtp:115 repair-window=10000000 a=ssrc-group:FID 1111 2222 a=ssrc-group:FEC-FR 1111 3333 a=ssrc:1111 cname:test @@ -156,7 +156,7 @@ func TestMediaEngineRegistersFlexFEC(t *testing.T) { require.NoError(t, err) flexFECParams := flexFECCodecParameters(115) - assert.Equal(t, "repair-window=2000000", flexFECParams.SDPFmtpLine) + assert.Equal(t, "repair-window=10000000", flexFECParams.SDPFmtpLine) filtered := filterCodecs( []webrtc.RTPCodecParameters{flexFECParams}, enabledCodecs, @@ -168,7 +168,7 @@ func TestMediaEngineRegistersFlexFEC(t *testing.T) { require.Len(t, filtered, 1) assert.Equal(t, webrtc.MimeTypeFlexFEC03, filtered[0].MimeType) assert.Contains(t, offer.SDP, "a=rtpmap:115 flexfec-03/90000") - assert.Contains(t, offer.SDP, "a=fmtp:115 repair-window=2000000") + assert.Contains(t, offer.SDP, "a=fmtp:115 repair-window=10000000") } else { assert.Empty(t, filtered) assert.NotContains(t, offer.SDP, "flexfec-03") diff --git a/pkg/sfu/buffer/buffer_fec_test.go b/pkg/sfu/buffer/buffer_fec_test.go index da20c38b3..876e58dbb 100644 --- a/pkg/sfu/buffer/buffer_fec_test.go +++ b/pkg/sfu/buffer/buffer_fec_test.go @@ -42,7 +42,7 @@ var flexFECCodec = webrtc.RTPCodecParameters{ RTPCodecCapability: webrtc.RTPCodecCapability{ MimeType: webrtc.MimeTypeFlexFEC03, ClockRate: 90000, - SDPFmtpLine: "repair-window=2000000", + SDPFmtpLine: "repair-window=10000000", }, PayloadType: webrtc.PayloadType(fecTestFECPT), } diff --git a/test/flexfec_upstream_test.go b/test/flexfec_upstream_test.go index a5f8f4b1c..95e39f923 100644 --- a/test/flexfec_upstream_test.go +++ b/test/flexfec_upstream_test.go @@ -78,7 +78,7 @@ func TestFlexFECUpstreamNegotiation(t *testing.T) { if !strings.Contains(sd.SDP, "flexfec-03") { return "SFU answer does not contain flexfec-03" } - if !strings.Contains(sd.SDP, "repair-window=2000000") { + if !strings.Contains(sd.SDP, "repair-window=10000000") { return "SFU answer does not contain the configured FlexFEC repair window" } return ""