|
|
@@ -69,7 +69,7 @@ function getRtxSsrc (videoMLine, primarySsrc) {
|
|
69
|
69
|
* @param {number} rtxSsrc the rtx ssrc to associate with the primary ssrc
|
|
70
|
70
|
*/
|
|
71
|
71
|
function updateAssociatedRtxStream (videoMLine, primarySsrcInfo, rtxSsrc) {
|
|
72
|
|
- logger.info("Updating mline to associate " + rtxSsrc +
|
|
|
72
|
+ logger.debug("Updating mline to associate " + rtxSsrc +
|
|
73
|
73
|
" rtx ssrc with primary stream ", primarySsrcInfo.id);
|
|
74
|
74
|
let primarySsrc = primarySsrcInfo.id;
|
|
75
|
75
|
let primarySsrcMsid = primarySsrcInfo.msid;
|
|
|
@@ -78,20 +78,20 @@ function updateAssociatedRtxStream (videoMLine, primarySsrcInfo, rtxSsrc) {
|
|
78
|
78
|
let previousAssociatedRtxStream =
|
|
79
|
79
|
getRtxSsrc (videoMLine, primarySsrc);
|
|
80
|
80
|
if (previousAssociatedRtxStream === rtxSsrc) {
|
|
81
|
|
- logger.info(rtxSsrc + " was already associated with " +
|
|
|
81
|
+ logger.debug(rtxSsrc + " was already associated with " +
|
|
82
|
82
|
primarySsrc);
|
|
83
|
83
|
return;
|
|
84
|
84
|
}
|
|
85
|
85
|
if (previousAssociatedRtxStream) {
|
|
86
|
|
- logger.info(primarySsrc + " was previously assocaited with rtx " +
|
|
|
86
|
+ logger.debug(primarySsrc + " was previously assocaited with rtx " +
|
|
87
|
87
|
previousAssociatedRtxStream + ", removing all references to it");
|
|
88
|
88
|
// Stream already had an rtx ssrc that is different than the one given,
|
|
89
|
89
|
// remove all trace of the old one
|
|
90
|
90
|
videoMLine.ssrcs = videoMLine.ssrcs
|
|
91
|
91
|
.filter(ssrcInfo => ssrcInfo.id !== previousAssociatedRtxStream);
|
|
92
|
|
- logger.info("groups before filtering for " +
|
|
|
92
|
+ logger.debug("groups before filtering for " +
|
|
93
|
93
|
previousAssociatedRtxStream);
|
|
94
|
|
- logger.info(JSON.stringify(videoMLine.ssrcGroups));
|
|
|
94
|
+ logger.debug(JSON.stringify(videoMLine.ssrcGroups));
|
|
95
|
95
|
videoMLine.ssrcGroups = videoMLine.ssrcGroups
|
|
96
|
96
|
.filter(groupInfo => {
|
|
97
|
97
|
return groupInfo
|
|
|
@@ -151,7 +151,7 @@ export default class RtxModifier {
|
|
151
|
151
|
* ssrcs to their corresponding rtx ssrcs
|
|
152
|
152
|
*/
|
|
153
|
153
|
setSsrcCache (ssrcMapping) {
|
|
154
|
|
- logger.info("Setting ssrc cache to ", ssrcMapping);
|
|
|
154
|
+ logger.debug("Setting ssrc cache to ", ssrcMapping);
|
|
155
|
155
|
this.correspondingRtxSsrcs = ssrcMapping;
|
|
156
|
156
|
}
|
|
157
|
157
|
|
|
|
@@ -168,44 +168,44 @@ export default class RtxModifier {
|
|
168
|
168
|
parsedSdp.media.find(mLine => mLine.type === "video");
|
|
169
|
169
|
if (videoMLine.direction === "inactive" ||
|
|
170
|
170
|
videoMLine.direction === "recvonly") {
|
|
171
|
|
- logger.info("RtxModifier doing nothing, video " +
|
|
|
171
|
+ logger.debug("RtxModifier doing nothing, video " +
|
|
172
|
172
|
"m line is inactive or recvonly");
|
|
173
|
173
|
return sdpStr;
|
|
174
|
174
|
}
|
|
175
|
175
|
if (!videoMLine.ssrcs) {
|
|
176
|
|
- logger.info("RtxModifier doing nothing, no video ssrcs present");
|
|
|
176
|
+ logger.debug("RtxModifier doing nothing, no video ssrcs present");
|
|
177
|
177
|
return sdpStr;
|
|
178
|
178
|
}
|
|
179
|
|
- logger.info("Current ssrc mapping: ", this.correspondingRtxSsrcs);
|
|
|
179
|
+ logger.debug("Current ssrc mapping: ", this.correspondingRtxSsrcs);
|
|
180
|
180
|
let primaryVideoSsrcs = getPrimaryVideoSsrcs(videoMLine);
|
|
181
|
|
- logger.info("Parsed primary video ssrcs ", primaryVideoSsrcs, " " +
|
|
|
181
|
+ logger.debug("Parsed primary video ssrcs ", primaryVideoSsrcs, " " +
|
|
182
|
182
|
"making sure all have rtx streams");
|
|
183
|
183
|
primaryVideoSsrcs.forEach(ssrc => {
|
|
184
|
184
|
let msid = SDPUtil.getSsrcAttribute(videoMLine, ssrc, "msid");
|
|
185
|
185
|
let cname = SDPUtil.getSsrcAttribute(videoMLine, ssrc, "cname");
|
|
186
|
186
|
let correspondingRtxSsrc = this.correspondingRtxSsrcs.get(ssrc);
|
|
187
|
187
|
if (correspondingRtxSsrc) {
|
|
188
|
|
- logger.info("Already have an associated rtx ssrc for " +
|
|
|
188
|
+ logger.debug("Already have an associated rtx ssrc for " +
|
|
189
|
189
|
" video ssrc " + ssrc + ": " +
|
|
190
|
190
|
correspondingRtxSsrc);
|
|
191
|
191
|
} else {
|
|
192
|
|
- logger.info("No previously associated rtx ssrc for " +
|
|
|
192
|
+ logger.debug("No previously associated rtx ssrc for " +
|
|
193
|
193
|
" video ssrc " + ssrc);
|
|
194
|
194
|
// If there's one in the sdp already for it, we'll just set
|
|
195
|
195
|
// that as the corresponding one
|
|
196
|
196
|
let previousAssociatedRtxStream =
|
|
197
|
197
|
getRtxSsrc (videoMLine, ssrc);
|
|
198
|
198
|
if (previousAssociatedRtxStream) {
|
|
199
|
|
- logger.info("Rtx stream " + previousAssociatedRtxStream +
|
|
|
199
|
+ logger.debug("Rtx stream " + previousAssociatedRtxStream +
|
|
200
|
200
|
" already existed in the sdp as an rtx stream for " +
|
|
201
|
201
|
ssrc);
|
|
202
|
202
|
correspondingRtxSsrc = previousAssociatedRtxStream;
|
|
203
|
203
|
} else {
|
|
204
|
204
|
correspondingRtxSsrc = SDPUtil.generateSsrc();
|
|
205
|
|
- logger.info("Generated rtx ssrc " + correspondingRtxSsrc +
|
|
|
205
|
+ logger.debug("Generated rtx ssrc " + correspondingRtxSsrc +
|
|
206
|
206
|
" for ssrc " + ssrc);
|
|
207
|
207
|
}
|
|
208
|
|
- logger.info("Caching rtx ssrc " + correspondingRtxSsrc +
|
|
|
208
|
+ logger.debug("Caching rtx ssrc " + correspondingRtxSsrc +
|
|
209
|
209
|
" for video ssrc " + ssrc);
|
|
210
|
210
|
this.correspondingRtxSsrcs.set(ssrc, correspondingRtxSsrc);
|
|
211
|
211
|
}
|
|
|
@@ -222,55 +222,44 @@ export default class RtxModifier {
|
|
222
|
222
|
}
|
|
223
|
223
|
|
|
224
|
224
|
/**
|
|
225
|
|
- * Remove all reference to any rtx ssrcs that
|
|
226
|
|
- * don't correspond to the primary stream.
|
|
227
|
|
- * Must be called *after* any simulcast streams
|
|
228
|
|
- * have been imploded
|
|
|
225
|
+ * Strip all rtx streams from the given sdp
|
|
229
|
226
|
* @param {string} sdpStr sdp in raw string format
|
|
|
227
|
+ * @returns {string} sdp string with all rtx streams stripped
|
|
230
|
228
|
*/
|
|
231
|
|
- implodeRemoteRtxSsrcs (sdpStr) {
|
|
232
|
|
- let parsedSdp = transform.parse(sdpStr);
|
|
233
|
|
- let videoMLine =
|
|
|
229
|
+ stripRtx (sdpStr) {
|
|
|
230
|
+ const parsedSdp = transform.parse(sdpStr);
|
|
|
231
|
+ const videoMLine =
|
|
234
|
232
|
parsedSdp.media.find(mLine => mLine.type === "video");
|
|
235
|
233
|
if (videoMLine.direction === "inactive" ||
|
|
236
|
234
|
videoMLine.direction === "recvonly") {
|
|
237
|
|
- logger.info("RtxModifier doing nothing, video " +
|
|
|
235
|
+ logger.debug("RtxModifier doing nothing, video " +
|
|
238
|
236
|
"m line is inactive or recvonly");
|
|
239
|
237
|
return sdpStr;
|
|
240
|
238
|
}
|
|
|
239
|
+ if (!videoMLine.ssrcs) {
|
|
|
240
|
+ logger.debug("RtxModifier doing nothing, no video ssrcs present");
|
|
|
241
|
+ return sdpStr;
|
|
|
242
|
+ }
|
|
241
|
243
|
if (!videoMLine.ssrcGroups) {
|
|
242
|
|
- // Nothing to do
|
|
243
|
|
- return sdpStr;
|
|
|
244
|
+ logger.debug("RtxModifier doing nothing, " +
|
|
|
245
|
+ "no video ssrcGroups present");
|
|
|
246
|
+ return sdpStr;
|
|
244
|
247
|
}
|
|
245
|
|
-
|
|
246
|
|
- // Returns true if the given ssrc is present
|
|
247
|
|
- // in the mLine's ssrc list
|
|
248
|
|
- let ssrcExists = (ssrcToFind) => {
|
|
249
|
|
- return videoMLine.ssrcs.
|
|
250
|
|
- find((ssrc) => ssrc.id + "" === ssrcToFind);
|
|
251
|
|
- };
|
|
252
|
|
- let ssrcsToRemove = [];
|
|
253
|
|
- videoMLine.ssrcGroups.forEach(group => {
|
|
254
|
|
- if (group.semantics === "FID") {
|
|
255
|
|
- let primarySsrc = group.ssrcs.split(" ")[0];
|
|
256
|
|
- let rtxSsrc = group.ssrcs.split(" ")[1];
|
|
257
|
|
- if (!ssrcExists(primarySsrc)) {
|
|
258
|
|
- ssrcsToRemove.push(rtxSsrc);
|
|
259
|
|
- }
|
|
260
|
|
- }
|
|
|
248
|
+ const fidGroups = videoMLine.ssrcGroups
|
|
|
249
|
+ .filter(group => group.semantics === "FID");
|
|
|
250
|
+ // Remove the fid groups from the mline
|
|
|
251
|
+ videoMLine.ssrcGroups = videoMLine.ssrcGroups
|
|
|
252
|
+ .filter(group => group.semantics !== "FID");
|
|
|
253
|
+ // Get the rtx ssrcs and remove them from the mline
|
|
|
254
|
+ const ssrcsToRemove = [];
|
|
|
255
|
+ fidGroups.forEach(fidGroup => {
|
|
|
256
|
+ const groupSsrcs = SDPUtil.parseGroupSsrcs(fidGroup);
|
|
|
257
|
+ const rtxSsrc = groupSsrcs[1];
|
|
|
258
|
+ ssrcsToRemove.push(rtxSsrc);
|
|
261
|
259
|
});
|
|
262
|
260
|
videoMLine.ssrcs = videoMLine.ssrcs
|
|
263
|
|
- .filter(ssrc => ssrcsToRemove.indexOf(ssrc.id + "") === -1);
|
|
264
|
|
- videoMLine.ssrcGroups = videoMLine.ssrcGroups
|
|
265
|
|
- .filter(group => {
|
|
266
|
|
- let ssrcs = group.ssrcs.split(" ");
|
|
267
|
|
- for (let i = 0; i < ssrcs.length; ++i) {
|
|
268
|
|
- if (ssrcsToRemove.indexOf(ssrcs[i]) !== -1) {
|
|
269
|
|
- return false;
|
|
270
|
|
- }
|
|
271
|
|
- }
|
|
272
|
|
- return true;
|
|
273
|
|
- });
|
|
|
261
|
+ .filter(line => ssrcsToRemove.indexOf(line.id) === -1);
|
|
|
262
|
+
|
|
274
|
263
|
return transform.write(parsedSdp);
|
|
275
|
264
|
}
|
|
276
|
265
|
}
|