Add findFECPayloadType (#3084)

#### Description

Before this, any interceptor that tries to read FEC payload type from
`info *interceptor.StreamInfo`, always gets 0. This PR implements the
logic to find FEC payload type.

Also, MimeType consts are moved from mediaengine.go to mimetype.go,
since mediaengine.go is not included in the WASM build.
This commit is contained in:
Jingyang Kang
2025-04-07 20:29:51 +08:00
committed by GitHub
parent 0b5e438a3f
commit 334692b122
5 changed files with 143 additions and 43 deletions

View File

@@ -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

46
mimetype.go Normal file
View File

@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2025 The Pion community <https://pion.ly>
// 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"
)

View File

@@ -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 {

85
rtpcodec_test.go Normal file
View File

@@ -0,0 +1,85 @@
// SPDX-FileCopyrightText: 2025 The Pion community <https://pion.ly>
// 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))
}
}

View File

@@ -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,
)