diff --git a/mediaengine.go b/mediaengine.go index 1e7e03b3..170a7299 100644 --- a/mediaengine.go +++ b/mediaengine.go @@ -20,48 +20,6 @@ import ( "github.com/pion/webrtc/v4/internal/fmtp" ) -const ( - // MimeTypeH264 H264 MIME type. - // Note: Matching should be case insensitive. - MimeTypeH264 = "video/H264" - // MimeTypeH265 H265 MIME type - // Note: Matching should be case insensitive. - MimeTypeH265 = "video/H265" - // MimeTypeOpus Opus MIME type - // Note: Matching should be case insensitive. - MimeTypeOpus = "audio/opus" - // MimeTypeVP8 VP8 MIME type - // Note: Matching should be case insensitive. - MimeTypeVP8 = "video/VP8" - // MimeTypeVP9 VP9 MIME type - // Note: Matching should be case insensitive. - MimeTypeVP9 = "video/VP9" - // MimeTypeAV1 AV1 MIME type - // Note: Matching should be case insensitive. - MimeTypeAV1 = "video/AV1" - // MimeTypeG722 G722 MIME type - // Note: Matching should be case insensitive. - MimeTypeG722 = "audio/G722" - // MimeTypePCMU PCMU MIME type - // Note: Matching should be case insensitive. - MimeTypePCMU = "audio/PCMU" - // MimeTypePCMA PCMA MIME type - // Note: Matching should be case insensitive. - MimeTypePCMA = "audio/PCMA" - // MimeTypeRTX RTX MIME type - // Note: Matching should be case insensitive. - MimeTypeRTX = "video/rtx" - // MimeTypeFlexFEC FEC MIME Type - // Note: Matching should be case insensitive. - MimeTypeFlexFEC = "video/flexfec" - // MimeTypeFlexFEC03 FlexFEC03 MIME Type - // Note: Matching should be case insensitive. - MimeTypeFlexFEC03 = "video/flexfec-03" - // MimeTypeUlpFEC UlpFEC MIME Type - // Note: Matching should be case insensitive. - MimeTypeUlpFEC = "video/ulpfec" -) - type mediaEngineHeaderExtension struct { uri string isAudio, isVideo bool diff --git a/mimetype.go b/mimetype.go new file mode 100644 index 00000000..9575f9eb --- /dev/null +++ b/mimetype.go @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2025 The Pion community +// SPDX-License-Identifier: MIT + +package webrtc + +const ( + // MimeTypeH264 H264 MIME type. + // Note: Matching should be case insensitive. + MimeTypeH264 = "video/H264" + // MimeTypeH265 H265 MIME type + // Note: Matching should be case insensitive. + MimeTypeH265 = "video/H265" + // MimeTypeOpus Opus MIME type + // Note: Matching should be case insensitive. + MimeTypeOpus = "audio/opus" + // MimeTypeVP8 VP8 MIME type + // Note: Matching should be case insensitive. + MimeTypeVP8 = "video/VP8" + // MimeTypeVP9 VP9 MIME type + // Note: Matching should be case insensitive. + MimeTypeVP9 = "video/VP9" + // MimeTypeAV1 AV1 MIME type + // Note: Matching should be case insensitive. + MimeTypeAV1 = "video/AV1" + // MimeTypeG722 G722 MIME type + // Note: Matching should be case insensitive. + MimeTypeG722 = "audio/G722" + // MimeTypePCMU PCMU MIME type + // Note: Matching should be case insensitive. + MimeTypePCMU = "audio/PCMU" + // MimeTypePCMA PCMA MIME type + // Note: Matching should be case insensitive. + MimeTypePCMA = "audio/PCMA" + // MimeTypeRTX RTX MIME type + // Note: Matching should be case insensitive. + MimeTypeRTX = "video/rtx" + // MimeTypeFlexFEC FEC MIME Type + // Note: Matching should be case insensitive. + MimeTypeFlexFEC = "video/flexfec" + // MimeTypeFlexFEC03 FlexFEC03 MIME Type + // Note: Matching should be case insensitive. + MimeTypeFlexFEC03 = "video/flexfec-03" + // MimeTypeUlpFEC UlpFEC MIME Type + // Note: Matching should be case insensitive. + MimeTypeUlpFEC = "video/ulpfec" +) diff --git a/rtpcodec.go b/rtpcodec.go index 798d3093..d4733dbd 100644 --- a/rtpcodec.go +++ b/rtpcodec.go @@ -155,6 +155,17 @@ func findRTXPayloadType(needle PayloadType, haystack []RTPCodecParameters) Paylo return PayloadType(0) } +// For now, only FlexFEC is supported. +func findFECPayloadType(haystack []RTPCodecParameters) PayloadType { + for _, c := range haystack { + if strings.Contains(c.RTPCodecCapability.MimeType, MimeTypeFlexFEC) { + return c.PayloadType + } + } + + return PayloadType(0) +} + func rtcpFeedbackIntersection(a, b []RTCPFeedback) (out []RTCPFeedback) { for _, aFeedback := range a { for _, bFeeback := range b { diff --git a/rtpcodec_test.go b/rtpcodec_test.go new file mode 100644 index 00000000..0328f36f --- /dev/null +++ b/rtpcodec_test.go @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: 2025 The Pion community +// SPDX-License-Identifier: MIT + +package webrtc + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFindFECPayloadType(t *testing.T) { + for _, test := range []struct { + Haystack []RTPCodecParameters + ResultPayloadType PayloadType + }{ + { + Haystack: []RTPCodecParameters{ + { + PayloadType: 1, + RTPCodecCapability: RTPCodecCapability{ + MimeType: MimeTypeFlexFEC03, + ClockRate: 90000, + Channels: 0, + SDPFmtpLine: "repair-window=10000000", + RTCPFeedback: nil, + }, + }, + }, + ResultPayloadType: 1, + }, + { + Haystack: []RTPCodecParameters{ + { + PayloadType: 2, + RTPCodecCapability: RTPCodecCapability{ + MimeType: MimeTypeFlexFEC, + ClockRate: 90000, + Channels: 0, + SDPFmtpLine: "repair-window=10000000", + RTCPFeedback: nil, + }, + }, + { + PayloadType: 1, + RTPCodecCapability: RTPCodecCapability{ + MimeType: MimeTypeFlexFEC03, + ClockRate: 90000, + Channels: 0, + SDPFmtpLine: "repair-window=10000000", + RTCPFeedback: nil, + }, + }, + }, + ResultPayloadType: 2, + }, + { + Haystack: []RTPCodecParameters{ + { + PayloadType: 100, + RTPCodecCapability: RTPCodecCapability{ + MimeType: MimeTypeH265, + ClockRate: 90000, + Channels: 0, + SDPFmtpLine: "", + RTCPFeedback: nil, + }, + }, + { + PayloadType: 101, + RTPCodecCapability: RTPCodecCapability{ + MimeType: MimeTypeRTX, + ClockRate: 90000, + Channels: 0, + SDPFmtpLine: "apt=100", + RTCPFeedback: nil, + }, + }, + }, + ResultPayloadType: 0, + }, + } { + assert.Equal(t, test.ResultPayloadType, findFECPayloadType(test.Haystack)) + } +} diff --git a/rtpsender.go b/rtpsender.go index 20522741..27d27ab8 100644 --- a/rtpsender.go +++ b/rtpsender.go @@ -355,7 +355,7 @@ func (r *RTPSender) Send(parameters RTPSendParameters) error { parameters.Encodings[idx].FEC.SSRC, codec.PayloadType, findRTXPayloadType(codec.PayloadType, rtpParameters.Codecs), - 0, + findFECPayloadType(rtpParameters.Codecs), codec.RTPCodecCapability, parameters.HeaderExtensions, )