Browse Source

fix: Missed SSRCs in Unified Plan with several "ssrc-group:FID" groups. (#1658)

* fix: Missed SSRCs in Unified Plan with several "ssrc-group:FID" groups.

`TpcUtils.ensureCorrectOrderOfSsrcs()` takes into account only the first `ssrs-group`, and it causes missed `ssrs` attributes. It results in an error during `peerconnection.setRemoteDescription()`.

For fixing `ensureCorrectOrderOfSsrcs()`, all `ssrs-group` are traversed and all distinct `ssrs` are preserved with keeping their order.

* test: Added extra tests for `TpcUtils.ensureCorrectOrderOfSsrcs()`
tags/v0.0.2
Mikhail Nasyrov 4 years ago
parent
commit
39448f9a9c
No account linked to committer's email address
2 changed files with 221 additions and 1 deletions
  1. 10
    1
      modules/RTC/TPCUtils.js
  2. 211
    0
      modules/RTC/TPCUtils.spec.js

+ 10
- 1
modules/RTC/TPCUtils.js View File

@@ -129,7 +129,16 @@ export class TPCUtils {
129 129
             }
130 130
             let reorderedSsrcs = [];
131 131
 
132
-            mLine.ssrcGroups[0].ssrcs.split(' ').forEach(ssrc => {
132
+            const ssrcs = new Set();
133
+
134
+            mLine.ssrcGroups.map(group =>
135
+                group.ssrcs
136
+                    .split(' ')
137
+                    .filter(Boolean)
138
+                    .forEach(ssrc => ssrcs.add(ssrc)),
139
+            );
140
+
141
+            ssrcs.forEach(ssrc => {
133 142
                 const sources = mLine.ssrcs.filter(source => source.id.toString() === ssrc);
134 143
 
135 144
                 reorderedSsrcs = reorderedSsrcs.concat(sources);

+ 211
- 0
modules/RTC/TPCUtils.spec.js View File

@@ -0,0 +1,211 @@
1
+/* eslint-disable max-len */
2
+import { MockPeerConnection } from './MockClasses';
3
+import { TPCUtils } from './TPCUtils';
4
+
5
+const TEST_VIDEO_BITRATES = {
6
+    low: 200000,
7
+    standard: 700000,
8
+    high: 2500000
9
+};
10
+
11
+describe('TPCUtils', () => {
12
+    describe('ensureCorrectOrderOfSsrcs()', () => {
13
+        const commonSdpLines = [
14
+            'v=0',
15
+            'o=- 814997227879783433 5 IN IP4 127.0.0.1',
16
+            's=-',
17
+            't=0 0',
18
+            'a=msid-semantic: WMS 0836cc8e-a7bb-47e9-affb-0599414bc56d',
19
+            'a=group:BUNDLE video',
20
+            'm=video 9 RTP/SAVPF 100 96',
21
+            'c=IN IP4 0.0.0.0',
22
+            'a=rtpmap:100 VP8/90000',
23
+            'a=fmtp:96 apt=100',
24
+            'a=rtcp:9 IN IP4 0.0.0.0',
25
+            'a=rtcp-fb:100 ccm fir',
26
+            'a=rtcp-fb:100 nack',
27
+            'a=rtcp-fb:100 nack pli',
28
+            'a=rtcp-fb:100 goog-remb',
29
+            'a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time',
30
+            'a=setup:passive',
31
+            'a=mid:video',
32
+            'a=sendrecv',
33
+            'a=ice-ufrag:adPg',
34
+            'a=ice-pwd:Xsr05Mq8S7CR44DAnusZE26F',
35
+            'a=fingerprint:sha-256 6A:39:DE:11:24:AD:2E:4E:63:D6:69:D3:85:05:53:C7:3C:38:A4:B7:91:74:C0:91:44:FC:94:63:7F:01:AB:A9'
36
+        ];
37
+
38
+        it('sort ssrcs associated with all FID ssrc-groups', () => {
39
+            const pc = new MockPeerConnection();
40
+            const tpcUtils = new TPCUtils(pc, TEST_VIDEO_BITRATES);
41
+
42
+            const source = new RTCSessionDescription({
43
+                type: 'offer',
44
+                sdp: getSourceSdp()
45
+            });
46
+            const result = tpcUtils.ensureCorrectOrderOfSsrcs(source);
47
+
48
+            expect(result.sdp).toBe(getExpectedSdp());
49
+
50
+            /**
51
+             * Test SDP with multiple FID groups
52
+             */
53
+            function getSourceSdp() {
54
+                return `${[
55
+                    ...commonSdpLines,
56
+                    'a=ssrc:1757014965 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
57
+                    'a=ssrc:1757014965 cname:peDGrDD6WsxUOki/',
58
+                    'a=ssrc:1479742055 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
59
+                    'a=ssrc:1479742055 cname:peDGrDD6WsxUOki/',
60
+                    'a=ssrc:1089111804 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
61
+                    'a=ssrc:1089111804 cname:peDGrDD6WsxUOki/',
62
+                    'a=ssrc:855213044 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
63
+                    'a=ssrc:855213044 cname:peDGrDD6WsxUOki/',
64
+                    'a=ssrc:984899560 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
65
+                    'a=ssrc:984899560 cname:peDGrDD6WsxUOki/',
66
+                    'a=ssrc:2963867077 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
67
+                    'a=ssrc:2963867077 cname:peDGrDD6WsxUOki/',
68
+                    'a=ssrc-group:FID 1757014965 984899560',
69
+                    'a=ssrc-group:FID 1479742055 855213044',
70
+                    'a=ssrc-group:FID 1089111804 2963867077',
71
+                    'a=ssrc-group:SIM 1757014965 1479742055 1089111804',
72
+                    'a=rtcp-mux'
73
+                ].join('\r\n')}\r\n`;
74
+            }
75
+
76
+            /**
77
+             * Expected SDP: all ssrc must be present and ordered
78
+             */
79
+            function getExpectedSdp() {
80
+                return `${[
81
+                    ...commonSdpLines,
82
+                    'a=ssrc:1757014965 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
83
+                    'a=ssrc:1757014965 cname:peDGrDD6WsxUOki/',
84
+                    'a=ssrc:984899560 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
85
+                    'a=ssrc:984899560 cname:peDGrDD6WsxUOki/',
86
+                    'a=ssrc:1479742055 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
87
+                    'a=ssrc:1479742055 cname:peDGrDD6WsxUOki/',
88
+                    'a=ssrc:855213044 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
89
+                    'a=ssrc:855213044 cname:peDGrDD6WsxUOki/',
90
+                    'a=ssrc:1089111804 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
91
+                    'a=ssrc:1089111804 cname:peDGrDD6WsxUOki/',
92
+                    'a=ssrc:2963867077 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
93
+                    'a=ssrc:2963867077 cname:peDGrDD6WsxUOki/',
94
+                    'a=ssrc-group:FID 1757014965 984899560',
95
+                    'a=ssrc-group:FID 1479742055 855213044',
96
+                    'a=ssrc-group:FID 1089111804 2963867077',
97
+                    'a=ssrc-group:SIM 1757014965 1479742055 1089111804',
98
+                    'a=rtcp-mux'
99
+                ].join('\r\n')}\r\n`;
100
+            }
101
+        });
102
+
103
+        it('sort ssrcs in case the first ssrc in the SIM group is not present at the top', () => {
104
+            const pc = new MockPeerConnection();
105
+            const tpcUtils = new TPCUtils(pc, TEST_VIDEO_BITRATES);
106
+
107
+            const source = new RTCSessionDescription({
108
+                type: 'offer',
109
+                sdp: getSourceSdp()
110
+            });
111
+            const result = tpcUtils.ensureCorrectOrderOfSsrcs(source);
112
+
113
+            expect(result.sdp).toBe(getExpectedSdp());
114
+
115
+            /**
116
+             * Test SDP with multiple FID groups where the first ssrc in the SIM group is not present at the top
117
+             */
118
+            function getSourceSdp() {
119
+                return `${[
120
+                    ...commonSdpLines,
121
+                    'a=ssrc:1479742055 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
122
+                    'a=ssrc:1479742055 cname:peDGrDD6WsxUOki/',
123
+                    'a=ssrc:1757014965 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
124
+                    'a=ssrc:1757014965 cname:peDGrDD6WsxUOki/',
125
+                    'a=ssrc:1089111804 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
126
+                    'a=ssrc:1089111804 cname:peDGrDD6WsxUOki/',
127
+                    'a=ssrc:855213044 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
128
+                    'a=ssrc:855213044 cname:peDGrDD6WsxUOki/',
129
+                    'a=ssrc:984899560 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
130
+                    'a=ssrc:984899560 cname:peDGrDD6WsxUOki/',
131
+                    'a=ssrc:2963867077 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
132
+                    'a=ssrc:2963867077 cname:peDGrDD6WsxUOki/',
133
+                    'a=ssrc-group:FID 1757014965 984899560',
134
+                    'a=ssrc-group:FID 1479742055 855213044',
135
+                    'a=ssrc-group:FID 1089111804 2963867077',
136
+                    'a=ssrc-group:SIM 1757014965 1479742055 1089111804',
137
+                    'a=rtcp-mux'
138
+                ].join('\r\n')}\r\n`;
139
+            }
140
+
141
+            /**
142
+             * Expected SDP: all ssrc must be present and ordered
143
+             */
144
+            function getExpectedSdp() {
145
+                return `${[
146
+                    ...commonSdpLines,
147
+                    'a=ssrc:1757014965 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
148
+                    'a=ssrc:1757014965 cname:peDGrDD6WsxUOki/',
149
+                    'a=ssrc:984899560 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
150
+                    'a=ssrc:984899560 cname:peDGrDD6WsxUOki/',
151
+                    'a=ssrc:1479742055 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
152
+                    'a=ssrc:1479742055 cname:peDGrDD6WsxUOki/',
153
+                    'a=ssrc:855213044 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
154
+                    'a=ssrc:855213044 cname:peDGrDD6WsxUOki/',
155
+                    'a=ssrc:1089111804 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
156
+                    'a=ssrc:1089111804 cname:peDGrDD6WsxUOki/',
157
+                    'a=ssrc:2963867077 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
158
+                    'a=ssrc:2963867077 cname:peDGrDD6WsxUOki/',
159
+                    'a=ssrc-group:FID 1757014965 984899560',
160
+                    'a=ssrc-group:FID 1479742055 855213044',
161
+                    'a=ssrc-group:FID 1089111804 2963867077',
162
+                    'a=ssrc-group:SIM 1757014965 1479742055 1089111804',
163
+                    'a=rtcp-mux'
164
+                ].join('\r\n')}\r\n`;
165
+            }
166
+        });
167
+
168
+        it('sort ssrcs in case there is a single FID group', () => {
169
+            const pc = new MockPeerConnection();
170
+            const tpcUtils = new TPCUtils(pc, TEST_VIDEO_BITRATES);
171
+
172
+            const source = new RTCSessionDescription({
173
+                type: 'offer',
174
+                sdp: getSourceSdp()
175
+            });
176
+            const result = tpcUtils.ensureCorrectOrderOfSsrcs(source);
177
+
178
+            expect(result.sdp).toBe(getExpectedSdp());
179
+
180
+            /**
181
+             * Test SDP with the single FID group
182
+             */
183
+            function getSourceSdp() {
184
+                return `${[
185
+                    ...commonSdpLines,
186
+                    'a=ssrc:984899560 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
187
+                    'a=ssrc:984899560 cname:peDGrDD6WsxUOki/',
188
+                    'a=ssrc:1757014965 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
189
+                    'a=ssrc:1757014965 cname:peDGrDD6WsxUOki/',
190
+                    'a=ssrc-group:FID 1757014965 984899560',
191
+                    'a=rtcp-mux'
192
+                ].join('\r\n')}\r\n`;
193
+            }
194
+
195
+            /**
196
+             * Expected SDP: all ssrc must be present and ordered
197
+             */
198
+            function getExpectedSdp() {
199
+                return `${[
200
+                    ...commonSdpLines,
201
+                    'a=ssrc:1757014965 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
202
+                    'a=ssrc:1757014965 cname:peDGrDD6WsxUOki/',
203
+                    'a=ssrc:984899560 msid:0836cc8e-a7bb-47e9-affb-0599414bc56d bdbd2c0a-7959-4578-8db5-9a6a1aec4ecf',
204
+                    'a=ssrc:984899560 cname:peDGrDD6WsxUOki/',
205
+                    'a=ssrc-group:FID 1757014965 984899560',
206
+                    'a=rtcp-mux'
207
+                ].join('\r\n')}\r\n`;
208
+            }
209
+        });
210
+    });
211
+});

Loading…
Cancel
Save