Skip to content

fix!: correctly support wildcard payload types in feedback lines#27

Open
bbaldino wants to merge 4 commits intomainfrom
bbaldino/wildcard-fb
Open

fix!: correctly support wildcard payload types in feedback lines#27
bbaldino wants to merge 4 commits intomainfrom
bbaldino/wildcard-fb

Conversation

@bbaldino
Copy link
Collaborator

@bbaldino bbaldino commented Mar 9, 2026

Description

This change adds support for wildcard payload types in feedback lines, e.g.:

a=rtcp-fb:* nack pli
a=rtcp-fb:* ccm msync
a=rtcp-fb:* ccm fir
a=rtcp-fb:* nack

Chrome is starting to use in v147. Currently, these would fail to parse but would fallback to UnknownLine which is fine as long as no manipulation around them is needed.

The design of this fix introduces a new PayloadTypeRef type that models the payload type as a number or *. There are still places, though, where we want a "resolved" payload type (number only), so the naming of this type was chosen to try and distinguish an SDP-syntax "reference" to a payload type, not an actual payload type (for which number is still used).

This change implements...

  • A new feature
  • A bug fix
  • Other (please specify):

Is this a breaking change?

  • Yes - The type of the payload type member on some types as changed, as well as some constructor argument types
  • No

I certify that...

  • All relevant unit and integration tests have passed and/or have been updated according to this change.

Generative AI (GAI) Usage Disclosure

Reference: Cisco GAI Coding Guidelines

  • Cisco approved GAI tool/IDE was used for coding - eg: VSCode, Cursor, Windsurf, Codex, Claude code
  • No GAI - Code was written entirely manually without GAI assistance

If a GAI tool/IDE was used then select the category that best describes GAI usage in this PR:

  • Manual Draft with GAI Refinement - I/we created a draft manually that was non-substantively modified by GAI (e.g., refactoring was performed by GAI on manually written code) (Default)
  • [] GAI Draft with Manual Customization - GAI tool was used to create a draft that I/we subsequently customized or modified.
  • GAI Generated Code - Code was generated entirely by GAI

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds proper support for wildcard payload type (*) in SDP rtcp-fb lines (e.g., a=rtcp-fb:* nack pli), which Chrome v147+ is starting to emit. Previously these lines would fail to parse and fall back to UnknownLine. The change introduces a PayloadTypeRef type wrapping number | '*' and a new CodecStore class to separate per-codec from wildcard feedback storage.

Changes:

  • New PayloadTypeRef class and CodecStore class; RtcpFbLine regex updated to match *; RtpMapLine, FmtpLine, RtcpFbLine constructors updated to accept PayloadTypeRef instead of number.
  • AvMediaDescription.codecs changed from Map<number, CodecInfo> to CodecStore; codec-related line routing refactored to use CodecStore.addLine.
  • disableRtcpFbValue in munge.ts simplified to delegate to CodecStore.removeFeedback, correctly handling wildcard feedback.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/lines/payload-type-ref.ts New class modeling a payload type reference as number or '*'
src/lines/payload-type-ref.spec.ts Tests for the new PayloadTypeRef class
src/lines/rtcpfb-line.ts Updated regex and parsing to support wildcard *; payloadType field changed to PayloadTypeRef
src/lines/rtcpfb-line.spec.ts New tests for wildcard and numeric parsing/serialization of RtcpFbLine
src/lines/rtpmap-line.ts payloadType field changed to PayloadTypeRef; constructor updated
src/lines/fmtp-line.ts payloadType field changed to PayloadTypeRef; constructor updated
src/lines/index.ts Exports PayloadTypeRef
src/model/codec-store.ts New CodecStore class handling per-codec and wildcard feedback
src/model/codec-store.spec.ts Tests for CodecStore
src/model/codec-info.ts Uses PayloadTypeRef in toLines()
src/model/av-media-description.ts Uses CodecStore instead of raw Map<number, CodecInfo>
src/model/index.ts Exports CodecStore
src/munge.ts Delegates feedback removal to CodecStore.removeFeedback
src/utils.spec.ts Uses PayloadTypeRef when constructing RtpMapLine
src/parser.spec.ts New test for parsing an SDP with wildcard rtcp-fb lines

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +142 to +149
toLines(): Line[] {
const lines: Line[] = [];
this.codecs.forEach((codec) => lines.push(...codec.toLines()));
this.wildcardFeedback.forEach((fb) => {
lines.push(new RtcpFbLine(new PayloadTypeRef('*'), fb));
});
return lines;
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toLines() method always emits all per-codec lines first, then wildcard feedback lines at the end. However, in the wildcard_rtcpfb.sdp corpus file (and in real-world Chrome SDPs), wildcard rtcp-fb lines appear before per-codec feedback lines. After a round-trip parse-and-serialize, the ordering changes: a=rtcp-fb:96 ccm fir will appear before a=rtcp-fb:* goog-remb, a=rtcp-fb:* nack, etc.

While the compareSdps test helper ignores ordering so the round-trip test passes, and RFC 4585 doesn't mandate a specific ordering of rtcp-fb lines, this reordering could be a concern for interoperability with SDP consumers that are sensitive to ordering. Consider whether preserving the original relative order of wildcard and per-codec lines is desirable. Note that this is consistent with the codebase's existing behavior of reordering lines during serialization (as documented in src/sdp-corpus/ordering.ts).

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is probably fine as-is.

store.set(97, new CodecInfo(97));
});

describe('basic map operations', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I noticed the basic map operations tests verify just get/set/has/delete/forEach/values/entries behavior. Since these are thin wrappers over Map, I'm wondering what do we gain from testing these separately? If we ever swapped the internal Map for a different structure, would these tests make that harder? It seems like the addLine/getFeedback/toLines tests already checks these methods indirectly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is more about ensuring map operations work correctly, as opposed to enforcing it works like a map. I worry a bit that addLine/getFeedback/toLines may not verify those operations enough (no deletion there, for example). What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually good point about delete not being covered elsewhere. I agree that we shouldn't lose that coverage. But what if we reframe those tests as domain scenarios instead of map operations? Something like:

  • 'after deleting a codec, addLine should throw for that payload type'
  • 'after deleting a codec, toLines should not include it'

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well I just double checked and noticed the get/set/delete/etc. methods do get used directly as well, so I guess it's worth testing them directly? they're not just internal helpers.

Copy link
Contributor

@antsukanova antsukanova Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. If they’re part of the public contract, it makes sense to keep the tests for sure. Would renaming the describe block from 'basic map operations' to something like 'codec storage operations' better reflect what we’re actually testing then?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants