Fixes SSRC=1 issue. Renames VideoSSRCHack to LocalSSRCReplacement.
This commit is contained in:
parent
ab4c29eddc
commit
fb875423a9
|
@ -7,7 +7,7 @@ var async = require("async");
|
|||
var transform = require("sdp-transform");
|
||||
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
|
||||
var RTCBrowserType = require("../RTC/RTCBrowserType");
|
||||
var VideoSSRCHack = require("./VideoSSRCHack");
|
||||
var SSRCReplacement = require("./LocalSSRCReplacement");
|
||||
|
||||
// Jingle stuff
|
||||
function JingleSession(me, sid, connection, service, eventEmitter) {
|
||||
|
@ -254,7 +254,7 @@ JingleSession.prototype.accept = function () {
|
|||
//console.log('setLocalDescription success');
|
||||
self.setLocalDescription();
|
||||
|
||||
VideoSSRCHack.processSessionInit(accept);
|
||||
SSRCReplacement.processSessionInit(accept);
|
||||
|
||||
self.connection.sendIQ(accept,
|
||||
function () {
|
||||
|
@ -348,7 +348,7 @@ JingleSession.prototype.sendIceCandidate = function (candidate) {
|
|||
self.initiator == self.me ? 'initiator' : 'responder',
|
||||
ssrc);
|
||||
|
||||
VideoSSRCHack.processSessionInit(init);
|
||||
SSRCReplacement.processSessionInit(init);
|
||||
|
||||
self.connection.sendIQ(init,
|
||||
function () {
|
||||
|
@ -467,7 +467,7 @@ JingleSession.prototype.createdOffer = function (sdp) {
|
|||
this.initiator == this.me ? 'initiator' : 'responder',
|
||||
this.localStreamsSSRC);
|
||||
|
||||
VideoSSRCHack.processSessionInit(init);
|
||||
SSRCReplacement.processSessionInit(init);
|
||||
|
||||
self.connection.sendIQ(init,
|
||||
function () {
|
||||
|
@ -733,7 +733,7 @@ JingleSession.prototype.createdAnswer = function (sdp, provisional) {
|
|||
self.initiator == self.me ? 'initiator' : 'responder',
|
||||
ssrcs);
|
||||
|
||||
VideoSSRCHack.processSessionInit(accept);
|
||||
SSRCReplacement.processSessionInit(accept);
|
||||
|
||||
self.connection.sendIQ(accept,
|
||||
function () {
|
||||
|
@ -1135,7 +1135,7 @@ JingleSession.prototype.notifyMySSRCUpdate = function (old_sdp, new_sdp) {
|
|||
// Let 'source-remove' IQ through the hack and see if we're allowed to send
|
||||
// it in the current form
|
||||
if (removed)
|
||||
remove = VideoSSRCHack.processSourceRemove(remove);
|
||||
remove = SSRCReplacement.processSourceRemove(remove);
|
||||
|
||||
if (removed && remove) {
|
||||
console.info("Sending source-remove", remove);
|
||||
|
@ -1166,7 +1166,7 @@ JingleSession.prototype.notifyMySSRCUpdate = function (old_sdp, new_sdp) {
|
|||
// Let 'source-add' IQ through the hack and see if we're allowed to send
|
||||
// it in the current form
|
||||
if (added)
|
||||
add = VideoSSRCHack.processSourceAdd(add);
|
||||
add = SSRCReplacement.processSourceAdd(add);
|
||||
|
||||
if (added && add) {
|
||||
console.info("Sending source-add", add);
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
/* global $ */
|
||||
|
||||
/*
|
||||
The purpose of this hack is to re-use SSRC of first video stream ever created
|
||||
for any video streams created later on. In order to do that this hack:
|
||||
Here we do modifications of local video SSRCs. There are 2 situations we have
|
||||
to handle:
|
||||
|
||||
1. We generate SSRC for local recvonly video stream. This is the case when we
|
||||
have no local camera and it is not generated automatically, but SSRC=1 is
|
||||
used implicitly. If that happens RTCP packets will be dropped by the JVB
|
||||
and we won't be able to request video key frames correctly.
|
||||
|
||||
2. A hack to re-use SSRC of the first video stream for any new stream created
|
||||
in future. It turned out that Chrome may keep on using the SSRC of removed
|
||||
video stream in RTCP even though a new one has been created. So we just
|
||||
want to avoid that by re-using it. Jingle 'source-remove'/'source-add'
|
||||
notifications are blocked once first video SSRC is advertised to the focus.
|
||||
|
||||
What this hack does:
|
||||
|
||||
1. Stores the SSRC of the first video stream created by
|
||||
a) scanning Jingle session-accept/session-invite for existing video SSRC
|
||||
|
@ -33,6 +46,18 @@ var isEnabled = !RTCBrowserType.isFirefox();
|
|||
*/
|
||||
var localVideoSSRC;
|
||||
|
||||
/**
|
||||
* SSRC used for recvonly video stream when we have no local camera.
|
||||
* This is in order to tell Chrome what SSRC should be used in RTCP requests
|
||||
* instead of 1.
|
||||
*/
|
||||
var localRecvOnlySSRC;
|
||||
|
||||
/**
|
||||
* cname for <tt>localRecvOnlySSRC</tt>
|
||||
*/
|
||||
var localRecvOnlyCName;
|
||||
|
||||
/**
|
||||
* Method removes <source> element which describes <tt>localVideoSSRC</tt>
|
||||
* from given Jingle IQ.
|
||||
|
@ -79,21 +104,41 @@ var storeLocalVideoSSRC = function (jingleIq) {
|
|||
$(jingleIq.tree())
|
||||
.find('>jingle>content[name="video"]>description>source');
|
||||
|
||||
console.info('Video desc: ', videoSSRCs);
|
||||
if (!videoSSRCs.length)
|
||||
videoSSRCs.each(function (idx, ssrcElem) {
|
||||
if (localVideoSSRC)
|
||||
return;
|
||||
|
||||
var ssrc = videoSSRCs.attr('ssrc');
|
||||
if (ssrc) {
|
||||
localVideoSSRC = ssrc;
|
||||
console.info(
|
||||
'Stored local video SSRC for future re-use: ' + localVideoSSRC);
|
||||
} else {
|
||||
console.error('No "ssrc" attribute present in <source> element');
|
||||
// We consider SSRC real only if it has msid attribute
|
||||
// recvonly streams in FF do not have it as well as local SSRCs
|
||||
// we generate for recvonly streams in Chrome
|
||||
var ssrSel = $(ssrcElem);
|
||||
var msid = ssrSel.find('>parameter[name="msid"]');
|
||||
if (msid.length) {
|
||||
var ssrcVal = ssrSel.attr('ssrc');
|
||||
if (ssrcVal) {
|
||||
localVideoSSRC = ssrcVal;
|
||||
console.info('Stored local video SSRC' +
|
||||
' for future re-use: ' + localVideoSSRC);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var LocalVideoSSRCHack = {
|
||||
/**
|
||||
* Generates new SSRC for local video recvonly stream.
|
||||
* FIXME what about eventual SSRC collision ?
|
||||
*/
|
||||
function generateRecvonlySSRC() {
|
||||
//
|
||||
localRecvOnlySSRC =
|
||||
Math.random().toString(10).substring(2, 11);
|
||||
localRecvOnlyCName =
|
||||
Math.random().toString(36).substring(2);
|
||||
console.info(
|
||||
"Generated local recvonly SSRC: " + localRecvOnlySSRC +
|
||||
", cname: " + localRecvOnlyCName);
|
||||
}
|
||||
|
||||
var LocalSSRCReplacement = {
|
||||
/**
|
||||
* Method must be called before 'session-initiate' or 'session-invite' is
|
||||
* sent. Scans the IQ for local video SSRC and stores it if detected.
|
||||
|
@ -144,6 +189,25 @@ var LocalVideoSSRCHack = {
|
|||
new RegExp('a=ssrc:' + newSSRC, 'g'),
|
||||
'a=ssrc:' + localVideoSSRC);
|
||||
}
|
||||
} else {
|
||||
// Make sure we have any SSRC for recvonly video stream
|
||||
var sdp = new SDP(localDescription.sdp);
|
||||
|
||||
if (sdp.media[1] && sdp.media[1].indexOf('a=ssrc:') === -1 &&
|
||||
sdp.media[1].indexOf('a=recvonly') !== -1) {
|
||||
|
||||
if (!localRecvOnlySSRC) {
|
||||
generateRecvonlySSRC();
|
||||
}
|
||||
|
||||
console.info('No SSRC in video recvonly stream' +
|
||||
' - adding SSRC: ' + localRecvOnlySSRC);
|
||||
|
||||
sdp.media[1] += 'a=ssrc:' + localRecvOnlySSRC +
|
||||
' cname:' + localRecvOnlyCName + '\r\n';
|
||||
|
||||
localDescription.sdp = sdp.session + sdp.media.join('');
|
||||
}
|
||||
}
|
||||
return localDescription;
|
||||
},
|
||||
|
@ -196,4 +260,4 @@ var LocalVideoSSRCHack = {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports = LocalVideoSSRCHack;
|
||||
module.exports = LocalSSRCReplacement;
|
|
@ -1,7 +1,7 @@
|
|||
var RTC = require('../RTC/RTC');
|
||||
var RTCBrowserType = require("../RTC/RTCBrowserType.js");
|
||||
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
|
||||
var VideoSSRCHack = require("./VideoSSRCHack");
|
||||
var SSRCReplacement = require("./LocalSSRCReplacement");
|
||||
|
||||
function TraceablePeerConnection(ice_config, constraints, session) {
|
||||
var self = this;
|
||||
|
@ -213,7 +213,7 @@ if (TraceablePeerConnection.prototype.__defineGetter__ !== undefined) {
|
|||
function() {
|
||||
var desc = this.peerconnection.localDescription;
|
||||
|
||||
desc = VideoSSRCHack.mungeLocalVideoSSRC(desc);
|
||||
desc = SSRCReplacement.mungeLocalVideoSSRC(desc);
|
||||
|
||||
this.trace('getLocalDescription::preTransform', dumpSDP(desc));
|
||||
|
||||
|
@ -372,7 +372,7 @@ TraceablePeerConnection.prototype.createOffer
|
|||
self.trace('createOfferOnSuccess::postTransform (Plan B)', dumpSDP(offer));
|
||||
}
|
||||
|
||||
offer = VideoSSRCHack.mungeLocalVideoSSRC(offer);
|
||||
offer = SSRCReplacement.mungeLocalVideoSSRC(offer);
|
||||
|
||||
if (config.enableSimulcast && self.simulcast.isSupported()) {
|
||||
offer = self.simulcast.mungeLocalDescription(offer);
|
||||
|
@ -402,7 +402,7 @@ TraceablePeerConnection.prototype.createAnswer
|
|||
}
|
||||
|
||||
// munge local video SSRC
|
||||
answer = VideoSSRCHack.mungeLocalVideoSSRC(answer);
|
||||
answer = SSRCReplacement.mungeLocalVideoSSRC(answer);
|
||||
|
||||
if (config.enableSimulcast && self.simulcast.isSupported()) {
|
||||
answer = self.simulcast.mungeLocalDescription(answer);
|
||||
|
|
Loading…
Reference in New Issue