|
@@ -1,7 +1,6 @@
|
1
|
1
|
/* eslint-disable max-len*/
|
2
|
|
-/* eslint-disable no-invalid-this */
|
3
|
2
|
import RtxModifier from './RtxModifier.js';
|
4
|
|
-import * as SampleSdpStrings from './SampleSdpStrings.js';
|
|
3
|
+import { default as SampleSdpStrings } from './SampleSdpStrings.js';
|
5
|
4
|
import * as transform from 'sdp-transform';
|
6
|
5
|
import SDPUtil from './SDPUtil';
|
7
|
6
|
|
|
@@ -76,26 +75,28 @@ function getVideoGroups(parsedSdp, groupSemantics) {
|
76
|
75
|
}
|
77
|
76
|
|
78
|
77
|
describe('RtxModifier', () => {
|
79
|
|
- beforeEach(function() {
|
80
|
|
- this.rtxModifier = new RtxModifier();
|
81
|
|
- this.transform = transform;
|
82
|
|
- this.SDPUtil = SDPUtil;
|
|
78
|
+ let rtxModifier;
|
|
79
|
+
|
|
80
|
+ beforeEach(() => {
|
|
81
|
+ rtxModifier = new RtxModifier();
|
83
|
82
|
});
|
84
|
83
|
|
85
|
84
|
describe('modifyRtxSsrcs', () => {
|
86
|
85
|
describe('when given an sdp with a single video ssrc', () => {
|
87
|
|
- beforeEach(function() {
|
88
|
|
- this.singleVideoSdp = SampleSdpStrings.plainVideoSdp;
|
89
|
|
- this.primaryVideoSsrc = getPrimaryVideoSsrc(this.singleVideoSdp);
|
|
86
|
+ let primaryVideoSsrc, singleVideoSdp;
|
|
87
|
+
|
|
88
|
+ beforeEach(() => {
|
|
89
|
+ singleVideoSdp = SampleSdpStrings.plainVideoSdp;
|
|
90
|
+ primaryVideoSsrc = getPrimaryVideoSsrc(singleVideoSdp);
|
90
|
91
|
});
|
91
|
|
- it('should add a single rtx ssrc', function() {
|
|
92
|
+ it('should add a single rtx ssrc', () => {
|
92
|
93
|
// Call rtxModifier.modifyRtxSsrcs with an sdp that contains a single video
|
93
|
94
|
// ssrc. The returned sdp should have an rtx ssrc and an fid group.
|
94
|
|
- const newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.singleVideoSdp));
|
|
95
|
+ const newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(singleVideoSdp));
|
95
|
96
|
const newSdp = transform.parse(newSdpStr);
|
96
|
97
|
const newPrimaryVideoSsrc = getPrimaryVideoSsrc(newSdp);
|
97
|
98
|
|
98
|
|
- expect(newPrimaryVideoSsrc).toEqual(this.primaryVideoSsrc);
|
|
99
|
+ expect(newPrimaryVideoSsrc).toEqual(primaryVideoSsrc);
|
99
|
100
|
|
100
|
101
|
// Should now have an rtx ssrc as well
|
101
|
102
|
expect(numVideoSsrcs(newSdp)).toEqual(2);
|
|
@@ -108,21 +109,21 @@ describe('RtxModifier', () => {
|
108
|
109
|
const fidGroup = fidGroups[0];
|
109
|
110
|
const fidGroupPrimarySsrc = SDPUtil.parseGroupSsrcs(fidGroup)[0];
|
110
|
111
|
|
111
|
|
- expect(fidGroupPrimarySsrc).toEqual(this.primaryVideoSsrc);
|
|
112
|
+ expect(fidGroupPrimarySsrc).toEqual(primaryVideoSsrc);
|
112
|
113
|
});
|
113
|
114
|
|
114
|
|
- it('should re-use the same rtx ssrc for a primary ssrc it\'s seen before', function() {
|
|
115
|
+ it('should re-use the same rtx ssrc for a primary ssrc it\'s seen before', () => {
|
115
|
116
|
// Have rtxModifier generate an rtx ssrc via modifyRtxSsrcs. Then call it again
|
116
|
117
|
// with the same primary ssrc in the sdp (but no rtx ssrc). It should use
|
117
|
118
|
// the same rtx ssrc as before.
|
118
|
|
- let newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.singleVideoSdp));
|
|
119
|
+ let newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(singleVideoSdp));
|
119
|
120
|
let newSdp = transform.parse(newSdpStr);
|
120
|
121
|
|
121
|
122
|
let fidGroup = getVideoGroups(newSdp, 'FID')[0];
|
122
|
123
|
const fidGroupRtxSsrc = SDPUtil.parseGroupSsrcs(fidGroup)[1];
|
123
|
124
|
|
124
|
125
|
// Now pass the original sdp through again
|
125
|
|
- newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.singleVideoSdp));
|
|
126
|
+ newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(singleVideoSdp));
|
126
|
127
|
newSdp = transform.parse(newSdpStr);
|
127
|
128
|
fidGroup = getVideoGroups(newSdp, 'FID')[0];
|
128
|
129
|
const newFidGroupRtxSsrc = SDPUtil.parseGroupSsrcs(fidGroup)[1];
|
|
@@ -130,21 +131,21 @@ describe('RtxModifier', () => {
|
130
|
131
|
expect(newFidGroupRtxSsrc).toEqual(fidGroupRtxSsrc);
|
131
|
132
|
});
|
132
|
133
|
|
133
|
|
- it('should NOT re-use the same rtx ssrc for a primary ssrc it\'s seen before if the cache has been cleared', function() {
|
|
134
|
+ it('should NOT re-use the same rtx ssrc for a primary ssrc it\'s seen before if the cache has been cleared', () => {
|
134
|
135
|
// Call modifyRtxSsrcs to generate an rtx ssrc
|
135
|
136
|
// Clear the rtxModifier cache
|
136
|
137
|
// Call modifyRtxSsrcs to generate an rtx ssrc again with the same primary ssrc
|
137
|
138
|
// --> We should get a different rtx ssrc
|
138
|
|
- let newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.singleVideoSdp));
|
|
139
|
+ let newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(singleVideoSdp));
|
139
|
140
|
let newSdp = transform.parse(newSdpStr);
|
140
|
141
|
|
141
|
142
|
let fidGroup = getVideoGroups(newSdp, 'FID')[0];
|
142
|
143
|
const fidGroupRtxSsrc = SDPUtil.parseGroupSsrcs(fidGroup)[1];
|
143
|
144
|
|
144
|
|
- this.rtxModifier.clearSsrcCache();
|
|
145
|
+ rtxModifier.clearSsrcCache();
|
145
|
146
|
|
146
|
147
|
// Now pass the original sdp through again
|
147
|
|
- newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.singleVideoSdp));
|
|
148
|
+ newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(singleVideoSdp));
|
148
|
149
|
newSdp = transform.parse(newSdpStr);
|
149
|
150
|
fidGroup = getVideoGroups(newSdp, 'FID')[0];
|
150
|
151
|
const newFidGroupRtxSsrc = SDPUtil.parseGroupSsrcs(fidGroup)[1];
|
|
@@ -152,16 +153,16 @@ describe('RtxModifier', () => {
|
152
|
153
|
expect(newFidGroupRtxSsrc).not.toEqual(fidGroupRtxSsrc);
|
153
|
154
|
});
|
154
|
155
|
|
155
|
|
- it('should use the rtx ssrc from the cache when the cache has been manually set', function() {
|
|
156
|
+ it('should use the rtx ssrc from the cache when the cache has been manually set', () => {
|
156
|
157
|
// Manually set an rtx ssrc mapping in the cache
|
157
|
158
|
// Call modifyRtxSsrcs
|
158
|
159
|
// -->The rtx ssrc used should be the one we set
|
159
|
160
|
const forcedRtxSsrc = 123456;
|
160
|
161
|
const ssrcCache = new Map();
|
161
|
162
|
|
162
|
|
- ssrcCache.set(this.primaryVideoSsrc, forcedRtxSsrc);
|
163
|
|
- this.rtxModifier.setSsrcCache(ssrcCache);
|
164
|
|
- const newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.singleVideoSdp));
|
|
163
|
+ ssrcCache.set(primaryVideoSsrc, forcedRtxSsrc);
|
|
164
|
+ rtxModifier.setSsrcCache(ssrcCache);
|
|
165
|
+ const newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(singleVideoSdp));
|
165
|
166
|
const newSdp = transform.parse(newSdpStr);
|
166
|
167
|
|
167
|
168
|
const fidGroup = getVideoGroups(newSdp, 'FID')[0];
|
|
@@ -172,39 +173,41 @@ describe('RtxModifier', () => {
|
172
|
173
|
});
|
173
|
174
|
|
174
|
175
|
describe('when given an sdp with multiple video ssrcs', () => {
|
175
|
|
- beforeEach(function() {
|
176
|
|
- this.multipleVideoSdp = SampleSdpStrings.simulcastSdp;
|
177
|
|
- this.primaryVideoSsrcs = getPrimaryVideoSsrcs(this.multipleVideoSdp);
|
|
176
|
+ let multipleVideoSdp, primaryVideoSsrcs;
|
|
177
|
+
|
|
178
|
+ beforeEach(() => {
|
|
179
|
+ multipleVideoSdp = SampleSdpStrings.simulcastSdp;
|
|
180
|
+ primaryVideoSsrcs = getPrimaryVideoSsrcs(multipleVideoSdp);
|
178
|
181
|
});
|
179
|
182
|
|
180
|
|
- it('should add rtx ssrcs for all of them', function() {
|
|
183
|
+ it('should add rtx ssrcs for all of them', () => {
|
181
|
184
|
// Call rtxModifier.modifyRtxSsrcs with an sdp that contains multiple video
|
182
|
185
|
// ssrcs. The returned sdp should have an rtx ssrc and an fid group for all of them.
|
183
|
|
- const newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.multipleVideoSdp));
|
|
186
|
+ const newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(multipleVideoSdp));
|
184
|
187
|
const newSdp = transform.parse(newSdpStr);
|
185
|
188
|
const newPrimaryVideoSsrcs = getPrimaryVideoSsrcs(newSdp);
|
186
|
189
|
|
187
|
|
- expect(newPrimaryVideoSsrcs).toEqual(this.primaryVideoSsrcs);
|
|
190
|
+ expect(newPrimaryVideoSsrcs).toEqual(primaryVideoSsrcs);
|
188
|
191
|
|
189
|
192
|
// Should now have rtx ssrcs as well
|
190
|
|
- expect(numVideoSsrcs(newSdp)).toEqual(this.primaryVideoSsrcs.length * 2);
|
|
193
|
+ expect(numVideoSsrcs(newSdp)).toEqual(primaryVideoSsrcs.length * 2);
|
191
|
194
|
|
192
|
195
|
// Should now have FID groups
|
193
|
196
|
const fidGroups = getVideoGroups(newSdp, 'FID');
|
194
|
197
|
|
195
|
|
- expect(fidGroups.length).toEqual(this.primaryVideoSsrcs.length);
|
|
198
|
+ expect(fidGroups.length).toEqual(primaryVideoSsrcs.length);
|
196
|
199
|
fidGroups.forEach(fidGroup => {
|
197
|
200
|
const fidGroupPrimarySsrc = SDPUtil.parseGroupSsrcs(fidGroup)[0];
|
198
|
201
|
|
199
|
|
- expect(this.primaryVideoSsrcs.indexOf(fidGroupPrimarySsrc)).not.toEqual(-1);
|
|
202
|
+ expect(primaryVideoSsrcs.indexOf(fidGroupPrimarySsrc)).not.toEqual(-1);
|
200
|
203
|
});
|
201
|
204
|
});
|
202
|
205
|
|
203
|
|
- it('should re-use the same rtx ssrcs for any primary ssrc it\'s seen before', function() {
|
|
206
|
+ it('should re-use the same rtx ssrcs for any primary ssrc it\'s seen before', () => {
|
204
|
207
|
// Have rtxModifier generate an rtx ssrc via modifyRtxSsrcs. Then call it again
|
205
|
208
|
// with the same primary ssrc in the sdp (but no rtx ssrc). It should use
|
206
|
209
|
// the same rtx ssrc as before.
|
207
|
|
- let newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.multipleVideoSdp));
|
|
210
|
+ let newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(multipleVideoSdp));
|
208
|
211
|
let newSdp = transform.parse(newSdpStr);
|
209
|
212
|
|
210
|
213
|
const rtxMapping = new Map();
|
|
@@ -221,7 +224,7 @@ describe('RtxModifier', () => {
|
221
|
224
|
});
|
222
|
225
|
|
223
|
226
|
// Now pass the original sdp through again and make sure we get the same mapping
|
224
|
|
- newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.multipleVideoSdp));
|
|
227
|
+ newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(multipleVideoSdp));
|
225
|
228
|
newSdp = transform.parse(newSdpStr);
|
226
|
229
|
fidGroups = getVideoGroups(newSdp, 'FID');
|
227
|
230
|
fidGroups.forEach(fidGroup => {
|
|
@@ -234,12 +237,12 @@ describe('RtxModifier', () => {
|
234
|
237
|
});
|
235
|
238
|
});
|
236
|
239
|
|
237
|
|
- it('should NOT re-use the same rtx ssrcs for any primary ssrc it\'s seen before if the cache has been cleared', function() {
|
|
240
|
+ it('should NOT re-use the same rtx ssrcs for any primary ssrc it\'s seen before if the cache has been cleared', () => {
|
238
|
241
|
// Call modifyRtxSsrcs to generate an rtx ssrc
|
239
|
242
|
// Clear the rtxModifier cache
|
240
|
243
|
// Call modifyRtxSsrcs to generate rtx ssrcs again with the same primary ssrcs
|
241
|
244
|
// --> We should get different rtx ssrcs
|
242
|
|
- let newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.multipleVideoSdp));
|
|
245
|
+ let newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(multipleVideoSdp));
|
243
|
246
|
let newSdp = transform.parse(newSdpStr);
|
244
|
247
|
|
245
|
248
|
const rtxMapping = new Map();
|
|
@@ -255,10 +258,10 @@ describe('RtxModifier', () => {
|
255
|
258
|
rtxMapping.set(fidGroupPrimarySsrc, fidGroupRtxSsrc);
|
256
|
259
|
});
|
257
|
260
|
|
258
|
|
- this.rtxModifier.clearSsrcCache();
|
|
261
|
+ rtxModifier.clearSsrcCache();
|
259
|
262
|
|
260
|
263
|
// Now pass the original sdp through again and make sure we get the same mapping
|
261
|
|
- newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.multipleVideoSdp));
|
|
264
|
+ newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(multipleVideoSdp));
|
262
|
265
|
newSdp = transform.parse(newSdpStr);
|
263
|
266
|
fidGroups = getVideoGroups(newSdp, 'FID');
|
264
|
267
|
fidGroups.forEach(fidGroup => {
|
|
@@ -271,18 +274,18 @@ describe('RtxModifier', () => {
|
271
|
274
|
});
|
272
|
275
|
});
|
273
|
276
|
|
274
|
|
- it('should use the rtx ssrcs from the cache when the cache has been manually set', function() {
|
|
277
|
+ it('should use the rtx ssrcs from the cache when the cache has been manually set', () => {
|
275
|
278
|
// Manually set an rtx ssrc mapping in the cache
|
276
|
279
|
// Call modifyRtxSsrcs
|
277
|
280
|
// -->The rtx ssrc used should be the one we set
|
278
|
281
|
const rtxMapping = new Map();
|
279
|
282
|
|
280
|
|
- this.primaryVideoSsrcs.forEach(ssrc => {
|
|
283
|
+ primaryVideoSsrcs.forEach(ssrc => {
|
281
|
284
|
rtxMapping.set(ssrc, SDPUtil.generateSsrc());
|
282
|
285
|
});
|
283
|
|
- this.rtxModifier.setSsrcCache(rtxMapping);
|
|
286
|
+ rtxModifier.setSsrcCache(rtxMapping);
|
284
|
287
|
|
285
|
|
- const newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(this.multipleVideoSdp));
|
|
288
|
+ const newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(multipleVideoSdp));
|
286
|
289
|
const newSdp = transform.parse(newSdpStr);
|
287
|
290
|
|
288
|
291
|
const fidGroups = getVideoGroups(newSdp, 'FID');
|
|
@@ -299,9 +302,9 @@ describe('RtxModifier', () => {
|
299
|
302
|
});
|
300
|
303
|
|
301
|
304
|
describe('when given an sdp with a flexfec stream', () => {
|
302
|
|
- it('should not add rtx for the flexfec ssrc', function() {
|
|
305
|
+ it('should not add rtx for the flexfec ssrc', () => {
|
303
|
306
|
const flexFecSdp = SampleSdpStrings.flexFecSdp;
|
304
|
|
- const newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(flexFecSdp));
|
|
307
|
+ const newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(flexFecSdp));
|
305
|
308
|
const newSdp = transform.parse(newSdpStr);
|
306
|
309
|
const fidGroups = getVideoGroups(newSdp, 'FID');
|
307
|
310
|
|
|
@@ -310,47 +313,46 @@ describe('RtxModifier', () => {
|
310
|
313
|
});
|
311
|
314
|
|
312
|
315
|
describe('(corner cases)', () => {
|
313
|
|
- it('should handle a recvonly video mline', function() {
|
|
316
|
+ it('should handle a recvonly video mline', () => {
|
314
|
317
|
const sdp = SampleSdpStrings.plainVideoSdp;
|
315
|
318
|
const videoMLine = sdp.media.find(m => m.type === 'video');
|
316
|
319
|
|
317
|
320
|
videoMLine.direction = 'recvonly';
|
318
|
|
- const newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(sdp));
|
|
321
|
+ const newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(sdp));
|
319
|
322
|
|
320
|
|
- expect(newSdpStr).toEqual(this.transform.write(sdp));
|
|
323
|
+ expect(newSdpStr).toEqual(transform.write(sdp));
|
321
|
324
|
});
|
322
|
325
|
|
323
|
|
- it('should handle a video mline with no video ssrcs', function() {
|
|
326
|
+ it('should handle a video mline with no video ssrcs', () => {
|
324
|
327
|
const sdp = SampleSdpStrings.plainVideoSdp;
|
325
|
328
|
const videoMLine = sdp.media.find(m => m.type === 'video');
|
326
|
329
|
|
327
|
330
|
videoMLine.ssrcs = [];
|
328
|
|
- const newSdpStr = this.rtxModifier.modifyRtxSsrcs(this.transform.write(sdp));
|
|
331
|
+ const newSdpStr = rtxModifier.modifyRtxSsrcs(transform.write(sdp));
|
329
|
332
|
|
330
|
|
- expect(newSdpStr).toEqual(this.transform.write(sdp));
|
|
333
|
+ expect(newSdpStr).toEqual(transform.write(sdp));
|
331
|
334
|
});
|
332
|
335
|
});
|
333
|
336
|
});
|
334
|
337
|
|
335
|
338
|
describe('stripRtx', () => {
|
336
|
339
|
beforeEach(() => { }); // eslint-disable-line no-empty-function
|
337
|
|
- it('should strip all rtx streams from an sdp with rtx', function() {
|
|
340
|
+ it('should strip all rtx streams from an sdp with rtx', () => {
|
338
|
341
|
const sdpStr = transform.write(SampleSdpStrings.rtxVideoSdp);
|
339
|
|
- const newSdpStr = this.rtxModifier.stripRtx(sdpStr);
|
|
342
|
+ const newSdpStr = rtxModifier.stripRtx(sdpStr);
|
340
|
343
|
const newSdp = transform.parse(newSdpStr);
|
341
|
344
|
const fidGroups = getVideoGroups(newSdp, 'FID');
|
342
|
345
|
|
343
|
346
|
expect(fidGroups.length).toEqual(0);
|
344
|
347
|
expect(numVideoSsrcs(newSdp)).toEqual(1);
|
345
|
348
|
});
|
346
|
|
- it('should do nothing to an sdp with no rtx', function() {
|
|
349
|
+ it('should do nothing to an sdp with no rtx', () => {
|
347
|
350
|
const sdpStr = transform.write(SampleSdpStrings.plainVideoSdp);
|
348
|
|
- const newSdpStr = this.rtxModifier.stripRtx(sdpStr);
|
|
351
|
+ const newSdpStr = rtxModifier.stripRtx(sdpStr);
|
349
|
352
|
|
350
|
353
|
expect(newSdpStr).toEqual(sdpStr);
|
351
|
354
|
});
|
352
|
355
|
});
|
353
|
356
|
});
|
354
|
357
|
|
355
|
|
-/* eslint-enable no-invalid-this */
|
356
|
358
|
/* eslint-enable max-len*/
|