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

Add support for rtcp-fb:* (Chrome PSA) #152

Merged
merged 1 commit into from
Mar 29, 2024
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
52 changes: 39 additions & 13 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@
return fmt.Sprintf("%d %s/%d/%s (%s) [%s]", c.PayloadType, c.Name, c.ClockRate, c.EncodingParameters, c.Fmtp, strings.Join(c.RTCPFeedback, ", "))
}

func (c *Codec) appendRTCPFeedback(rtcpFeedback string) {
for _, existingRTCPFeedback := range c.RTCPFeedback {
if existingRTCPFeedback == rtcpFeedback {
return
}
}

c.RTCPFeedback = append(c.RTCPFeedback, rtcpFeedback)
}

func parseRtpmap(rtpmap string) (Codec, error) {
var codec Codec
parsingFailed := errExtractCodecRtpmap
Expand Down Expand Up @@ -153,30 +163,33 @@
return codec, nil
}

func parseRtcpFb(rtcpFb string) (Codec, error) {
var codec Codec
parsingFailed := errExtractCodecRtcpFb
func parseRtcpFb(rtcpFb string) (codec Codec, isWildcard bool, err error) {
var ptInt uint64
err = errExtractCodecRtcpFb

// a=ftcp-fb:<payload type> <RTCP feedback type> [<RTCP feedback parameter>]
split := strings.SplitN(rtcpFb, " ", 2)
if len(split) != 2 {
return codec, parsingFailed
return

Check warning on line 173 in util.go

View check run for this annotation

Codecov / codecov/patch

util.go#L173

Added line #L173 was not covered by tests
}

ptSplit := strings.Split(split[0], ":")
if len(ptSplit) != 2 {
return codec, parsingFailed
return

Check warning on line 178 in util.go

View check run for this annotation

Codecov / codecov/patch

util.go#L178

Added line #L178 was not covered by tests
}

ptInt, err := strconv.ParseUint(ptSplit[1], 10, 8)
if err != nil {
return codec, parsingFailed
isWildcard = ptSplit[1] == "*"
if !isWildcard {
ptInt, err = strconv.ParseUint(ptSplit[1], 10, 8)
if err != nil {
return
}

Check warning on line 186 in util.go

View check run for this annotation

Codecov / codecov/patch

util.go#L185-L186

Added lines #L185 - L186 were not covered by tests

codec.PayloadType = uint8(ptInt)
}

codec.PayloadType = uint8(ptInt)
codec.RTCPFeedback = append(codec.RTCPFeedback, split[1])

return codec, nil
return codec, isWildcard, nil
}

func mergeCodecs(codec Codec, codecs map[uint8]Codec) {
Expand Down Expand Up @@ -217,6 +230,7 @@
},
}

wildcardRTCPFeedback := []string{}
for _, m := range s.MediaDescriptions {
for _, a := range m.Attributes {
attr := a.String()
Expand All @@ -232,14 +246,26 @@
mergeCodecs(codec, codecs)
}
case strings.HasPrefix(attr, "rtcp-fb:"):
codec, err := parseRtcpFb(attr)
if err == nil {
codec, isWildcard, err := parseRtcpFb(attr)
switch {
case err != nil:

Check warning on line 251 in util.go

View check run for this annotation

Codecov / codecov/patch

util.go#L251

Added line #L251 was not covered by tests
case isWildcard:
wildcardRTCPFeedback = append(wildcardRTCPFeedback, codec.RTCPFeedback...)
default:
mergeCodecs(codec, codecs)
}
}
}
}

for i, codec := range codecs {
for _, newRTCPFeedback := range wildcardRTCPFeedback {
codec.appendRTCPFeedback(newRTCPFeedback)
}

codecs[i] = codec
}

return codecs
}

Expand Down
31 changes: 18 additions & 13 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ func getTestSessionDescription() SessionDescription {
NewAttribute("rtcp-fb:97 ccm fir", ""),
NewAttribute("rtcp-fb:97 nack", ""),
NewAttribute("rtcp-fb:97 nack pli", ""),
NewAttribute("rtcp-fb:* transport-cc", ""),
NewAttribute("rtcp-fb:* nack", ""),
},
},
},
Expand Down Expand Up @@ -103,32 +105,35 @@ func TestGetCodecForPayloadType(t *testing.T) {
getTestSessionDescription(),
120,
Codec{
PayloadType: 120,
Name: "VP8",
ClockRate: 90000,
Fmtp: "max-fs=12288;max-fr=60",
PayloadType: 120,
Name: "VP8",
ClockRate: 90000,
Fmtp: "max-fs=12288;max-fr=60",
RTCPFeedback: []string{"transport-cc", "nack"},
},
},
{
"vp9",
getTestSessionDescription(),
121,
Codec{
PayloadType: 121,
Name: "VP9",
ClockRate: 90000,
Fmtp: "max-fs=12288;max-fr=60",
PayloadType: 121,
Name: "VP9",
ClockRate: 90000,
Fmtp: "max-fs=12288;max-fr=60",
RTCPFeedback: []string{"transport-cc", "nack"},
},
},
{
"h264 126",
getTestSessionDescription(),
126,
Codec{
PayloadType: 126,
Name: "H264",
ClockRate: 90000,
Fmtp: "profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1",
PayloadType: 126,
Name: "H264",
ClockRate: 90000,
Fmtp: "profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1",
RTCPFeedback: []string{"transport-cc", "nack"},
},
},
{
Expand All @@ -140,7 +145,7 @@ func TestGetCodecForPayloadType(t *testing.T) {
Name: "H264",
ClockRate: 90000,
Fmtp: "profile-level-id=42e01f;level-asymmetry-allowed=1",
RTCPFeedback: []string{"ccm fir", "nack", "nack pli"},
RTCPFeedback: []string{"ccm fir", "nack", "nack pli", "transport-cc"},
},
},
{
Expand Down
Loading