Skip to content

Commit

Permalink
feat: add disableTwcc helper function (#19)
Browse files Browse the repository at this point in the history
* feat: add disableTwcc helper function

* chore: update typo and modifies disableRemb
  • Loading branch information
bxu2 authored Dec 20, 2023
1 parent cf5061c commit c9ec114
Show file tree
Hide file tree
Showing 4 changed files with 407 additions and 9 deletions.
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"trackingid",
"transcoding",
"transpiled",
"twcc",
"typedoc",
"ufrag",
"ulpfec",
Expand Down
106 changes: 105 additions & 1 deletion src/munge.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import * as fs from 'fs';
import { AvMediaDescription, CodecInfo, Sdp } from './model';
import { removeCodec, retainCandidates, retainCodecs } from './munge';
import {
removeCodec,
retainCandidates,
retainCodecs,
disableRtcpFbValue,
disableRemb,
disableTwcc,
} from './munge';
import { parse } from './parser';

/**
Expand Down Expand Up @@ -31,6 +38,25 @@ const validateOfferCodecs = (offer: Sdp): boolean => {
return true;
};

/**
* Check that the sdp offer contains rtcpFbValue or not.
*
* @param offer - The {@link Sdp} or {@link AvMediaDescription} to validate.
* @param rtcpFbValue - The rtcp-fb value to check.
* @returns True if the offer contains rtcp-fb value.
*/
const checkOfferContainsRtcpFeedback = (
offer: Sdp | AvMediaDescription,
rtcpFbValue: string
): boolean => {
const mediaDescriptions = offer instanceof Sdp ? offer.avMedia : [offer];
return mediaDescriptions.some((av: AvMediaDescription) => {
return [...av.codecs.values()].some((ci: CodecInfo) => {
return ci.feedback.includes(rtcpFbValue);
});
});
};

describe('munging', () => {
describe('removeCodec', () => {
it('should remove codecs correctly when passing in an SDP', () => {
Expand Down Expand Up @@ -119,4 +145,82 @@ describe('munging', () => {
});
});
});

describe('disableRtcpFbValue', () => {
it('should remove rtcp feedback correctly when passing in an SDP', () => {
expect.hasAssertions();
const offer = fs.readFileSync('./src/sdp-corpus/offer_with_rtcp_feedback.sdp', 'utf-8');
const parsed = parse(offer);

disableRtcpFbValue(parsed, 'transport-cc');
expect(checkOfferContainsRtcpFeedback(parsed, 'transport-cc')).toBe(false);
expect(checkOfferContainsRtcpFeedback(parsed, 'goog-remb')).toBe(true);
});
it('should remove rtcp feedback correctly when passing in an AvMediaDescription', () => {
expect.hasAssertions();
const offer = fs.readFileSync('./src/sdp-corpus/offer_with_rtcp_feedback.sdp', 'utf-8');
const parsed = parse(offer);

parsed.avMedia
.filter((av) => av.type === 'audio')
.forEach((av) => {
disableRtcpFbValue(av, 'transport-cc');
expect(checkOfferContainsRtcpFeedback(av, 'transport-cc')).toBe(false);
});
expect(checkOfferContainsRtcpFeedback(parsed, 'transport-cc')).toBe(true);
expect(checkOfferContainsRtcpFeedback(parsed, 'goog-remb')).toBe(true);
});
});

describe('disableTwcc', () => {
it('should disable twcc when passing in an SDP', () => {
expect.hasAssertions();
const offer = fs.readFileSync('./src/sdp-corpus/offer_with_rtcp_feedback.sdp', 'utf-8');
const parsed = parse(offer);

disableTwcc(parsed);
expect(checkOfferContainsRtcpFeedback(parsed, 'transport-cc')).toBe(false);
expect(checkOfferContainsRtcpFeedback(parsed, 'goog-remb')).toBe(true);
});
it('should disable twcc when passing in an AvMediaDescription', () => {
expect.hasAssertions();
const offer = fs.readFileSync('./src/sdp-corpus/offer_with_rtcp_feedback.sdp', 'utf-8');
const parsed = parse(offer);

parsed.avMedia
.filter((av) => av.type === 'audio')
.forEach((av) => {
disableTwcc(av);
expect(checkOfferContainsRtcpFeedback(av, 'transport-cc')).toBe(false);
});
expect(checkOfferContainsRtcpFeedback(parsed, 'transport-cc')).toBe(true);
expect(checkOfferContainsRtcpFeedback(parsed, 'goog-remb')).toBe(true);
});
});

describe('disableRemb', () => {
it('should disable remb when passing in an SDP', () => {
expect.hasAssertions();
const offer = fs.readFileSync('./src/sdp-corpus/offer_with_rtcp_feedback.sdp', 'utf-8');
const parsed = parse(offer);

disableRemb(parsed);
expect(checkOfferContainsRtcpFeedback(parsed, 'goog-remb')).toBe(false);
expect(checkOfferContainsRtcpFeedback(parsed, 'transport-cc')).toBe(true);
});
it('should disable remb when passing in an AvMediaDescription', () => {
expect.hasAssertions();
const offer = fs.readFileSync('./src/sdp-corpus/offer_with_rtcp_feedback.sdp', 'utf-8');
const parsed = parse(offer);

parsed.avMedia
.filter((av) => av.type === 'video')
.forEach((av) => {
disableRemb(av);
expect(checkOfferContainsRtcpFeedback(av, 'goog-remb')).toBe(false);
});
expect(checkOfferContainsRtcpFeedback(parsed, 'goog-remb')).toBe(false);
expect(checkOfferContainsRtcpFeedback(parsed, 'transport-cc')).toBe(true);
});
});
});
26 changes: 18 additions & 8 deletions src/munge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
import { AvMediaDescription, CodecInfo, MediaDescription, Sdp } from './model';

/**
* Disable an rtcp-fb value from all media blocks in the given SDP.
* Disable an rtcp-fb value from the media blocks in the given SDP or audio/video media description.
*
* @param sdp - The SDP from which to filter an rtcp-fb value.
* @param sdpOrAv - The {@link Sdp} or {@link AvMediaDescription} from which to filter an rtcp-fb value.
* @param rtcpFbValue - The rtcp-fb value to filter.
*/
export function disableRtcpFbValue(sdp: Sdp, rtcpFbValue: string) {
sdp.avMedia.forEach((media: AvMediaDescription) => {
export function disableRtcpFbValue(sdpOrAv: Sdp | AvMediaDescription, rtcpFbValue: string) {
const mediaDescriptions = sdpOrAv instanceof Sdp ? sdpOrAv.avMedia : [sdpOrAv];
mediaDescriptions.forEach((media: AvMediaDescription) => {
media.codecs.forEach((codec: CodecInfo) => {
// eslint-disable-next-line no-param-reassign
codec.feedback = codec.feedback.filter((fb) => fb !== rtcpFbValue);
Expand All @@ -32,12 +33,21 @@ export function disableRtcpFbValue(sdp: Sdp, rtcpFbValue: string) {
}

/**
* Disable REMB from all media blocks in the given SDP.
* Disable REMB from the media blocks in the given SDP or audio/video media description.
*
* @param sdpOrAv - The {@link Sdp} or {@link AvMediaDescription} from which to filter REMB.
*/
export function disableRemb(sdpOrAv: Sdp | AvMediaDescription) {
disableRtcpFbValue(sdpOrAv, 'goog-remb');
}

/**
* Disable TWCC from the media blocks in the given SDP or audio/video media description.
*
* @param sdp - The SDP from which to filter REMB.
* @param sdpOrAv - The {@link Sdp} or {@link AvMediaDescription} from which to filter TWCC.
*/
export function disableRemb(sdp: Sdp) {
disableRtcpFbValue(sdp, 'goog-remb');
export function disableTwcc(sdpOrAv: Sdp | AvMediaDescription) {
disableRtcpFbValue(sdpOrAv, 'transport-cc');
}

/**
Expand Down
Loading

0 comments on commit c9ec114

Please sign in to comment.