Fixes layout/simulcast related problems.
This commit is contained in:
parent
e0dbb1a47a
commit
ca3c59f244
124
simulcast.js
124
simulcast.js
|
@ -37,11 +37,11 @@ function Simulcast() {
|
||||||
};
|
};
|
||||||
}());
|
}());
|
||||||
|
|
||||||
Simulcast.prototype._cacheVideoSources = function (lines) {
|
Simulcast.prototype._cacheLocalVideoSources = function (lines) {
|
||||||
localVideoSourceCache = this._getVideoSources(lines);
|
localVideoSourceCache = this._getVideoSources(lines);
|
||||||
};
|
};
|
||||||
|
|
||||||
Simulcast.prototype._restoreVideoSources = function (lines) {
|
Simulcast.prototype._restoreLocalVideoSources = function (lines) {
|
||||||
this._replaceVideoSources(lines, localVideoSourceCache);
|
this._replaceVideoSources(lines, localVideoSourceCache);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ function Simulcast() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a random integer between min (included) and max (excluded)
|
// Returns a random integer between min (included) and max (excluded)
|
||||||
// Using Math.round() will give you a non-uniform distribution!
|
// Using Math.round() gives a non-uniform distribution!
|
||||||
Simulcast.prototype._generateRandomSSRC = function () {
|
Simulcast.prototype._generateRandomSSRC = function () {
|
||||||
var min = 0, max = 0xffffffff;
|
var min = 0, max = 0xffffffff;
|
||||||
return Math.floor(Math.random() * (max - min)) + min;
|
return Math.floor(Math.random() * (max - min)) + min;
|
||||||
|
@ -198,6 +198,23 @@ function Simulcast() {
|
||||||
|
|
||||||
emptyCompoundIndex = new CompoundIndex();
|
emptyCompoundIndex = new CompoundIndex();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The _indexOfArray() method returns the first a CompoundIndex at which a
|
||||||
|
* given element can be found in the array, or emptyCompoundIndex if it is
|
||||||
|
* not present.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* _indexOfArray('3', [ 'this is line 1', 'this is line 2', 'this is line 3' ])
|
||||||
|
*
|
||||||
|
* returns {row: 2, column: 14}
|
||||||
|
*
|
||||||
|
* @param needle
|
||||||
|
* @param haystack
|
||||||
|
* @param start
|
||||||
|
* @returns {CompoundIndex}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
Simulcast.prototype._indexOfArray = function (needle, haystack, start) {
|
Simulcast.prototype._indexOfArray = function (needle, haystack, start) {
|
||||||
var length = haystack.length, idx, i;
|
var length = haystack.length, idx, i;
|
||||||
|
|
||||||
|
@ -360,11 +377,11 @@ function Simulcast() {
|
||||||
|
|
||||||
if (this._indexOfArray('a=ssrc-group:SIM', lines) === emptyCompoundIndex) {
|
if (this._indexOfArray('a=ssrc-group:SIM', lines) === emptyCompoundIndex) {
|
||||||
this._appendSimulcastGroup(lines);
|
this._appendSimulcastGroup(lines);
|
||||||
this._cacheVideoSources(lines);
|
this._cacheLocalVideoSources(lines);
|
||||||
} else {
|
} else {
|
||||||
// verify that the ssrcs participating in the SIM group are present
|
// verify that the ssrcs participating in the SIM group are present
|
||||||
// in the SDP (needed for presence).
|
// in the SDP (needed for presence).
|
||||||
this._restoreVideoSources(lines);
|
this._restoreLocalVideoSources(lines);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -550,14 +567,12 @@ function Simulcast() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Simulcast.prototype._updateRemoteMaps = function (lines) {
|
Simulcast.prototype._updateRemoteMaps = function (lines) {
|
||||||
var remoteVideoSources = this._parseMedia(lines, ['video'])[0], videoSource, quality;
|
var remoteVideoSources = this._parseMedia(lines, ['video'])[0],
|
||||||
|
videoSource, quality;
|
||||||
|
|
||||||
// (re) initialize the remote maps.
|
// (re) initialize the remote maps.
|
||||||
remoteMaps = {
|
remoteMaps.msid2Quality = {};
|
||||||
msid2Quality: {},
|
remoteMaps.ssrc2Msid = {};
|
||||||
ssrc2Msid: {},
|
|
||||||
receivingVideoStreams: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (remoteVideoSources.groups && remoteVideoSources.groups.length !== 0) {
|
if (remoteVideoSources.groups && remoteVideoSources.groups.length !== 0) {
|
||||||
remoteVideoSources.groups.forEach(function (group) {
|
remoteVideoSources.groups.forEach(function (group) {
|
||||||
|
@ -637,11 +652,8 @@ function Simulcast() {
|
||||||
return desc;
|
return desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
Simulcast.prototype._setReceivingVideoStream = function (ssrc) {
|
Simulcast.prototype._setReceivingVideoStream = function (endpoint, ssrc) {
|
||||||
var receivingTrack = remoteMaps.ssrc2Msid[ssrc],
|
remoteMaps.receivingVideoStreams[endpoint] = ssrc;
|
||||||
msidParts = receivingTrack.split(' ');
|
|
||||||
|
|
||||||
remoteMaps.receivingVideoStreams[msidParts[0]] = msidParts[1];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -652,22 +664,20 @@ function Simulcast() {
|
||||||
* @returns {webkitMediaStream}
|
* @returns {webkitMediaStream}
|
||||||
*/
|
*/
|
||||||
Simulcast.prototype.getReceivingVideoStream = function (stream) {
|
Simulcast.prototype.getReceivingVideoStream = function (stream) {
|
||||||
var tracks, i, electedTrack, msid, quality = 1, receivingTrackId;
|
var tracks, i, electedTrack, msid, quality = 0, receivingTrackId;
|
||||||
|
|
||||||
if (config.enableSimulcast) {
|
if (config.enableSimulcast) {
|
||||||
|
|
||||||
if (remoteMaps.receivingVideoStreams[stream.id])
|
stream.getVideoTracks().some(function(track) {
|
||||||
{
|
return Object.keys(remoteMaps.receivingVideoStreams).some(function(endpoint) {
|
||||||
// the bridge has signaled us to receive a specific track.
|
var ssrc = remoteMaps.receivingVideoStreams[endpoint];
|
||||||
receivingTrackId = remoteMaps.receivingVideoStreams[stream.id];
|
var msid = remoteMaps.ssrc2Msid[ssrc];
|
||||||
tracks = stream.getVideoTracks();
|
if (msid == [stream.id, track.id].join(' ')) {
|
||||||
for (i = 0; i < tracks.length; i++) {
|
electedTrack = track;
|
||||||
if (receivingTrackId === tracks[i].id) {
|
return true;
|
||||||
electedTrack = tracks[i];
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
if (!electedTrack) {
|
if (!electedTrack) {
|
||||||
// we don't have an elected track, choose by initial quality.
|
// we don't have an elected track, choose by initial quality.
|
||||||
|
@ -708,11 +718,15 @@ function Simulcast() {
|
||||||
video: {
|
video: {
|
||||||
mandatory: {
|
mandatory: {
|
||||||
maxWidth: 320,
|
maxWidth: 320,
|
||||||
maxHeight: 180
|
maxHeight: 180,
|
||||||
|
maxFrameRate: 15
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('HQ constraints: ', constraints);
|
||||||
|
console.log('LQ constraints: ', lqConstraints);
|
||||||
|
|
||||||
if (config.enableSimulcast && !config.useNativeSimulcast) {
|
if (config.enableSimulcast && !config.useNativeSimulcast) {
|
||||||
|
|
||||||
// NOTE(gp) if we request the lq stream first webkitGetUserMedia
|
// NOTE(gp) if we request the lq stream first webkitGetUserMedia
|
||||||
|
@ -777,42 +791,30 @@ function Simulcast() {
|
||||||
return this._parseMedia(lines, mediatypes);
|
return this._parseMedia(lines, mediatypes);
|
||||||
};
|
};
|
||||||
|
|
||||||
Simulcast.prototype._startLocalVideoStream = function (ssrc) {
|
Simulcast.prototype._setLocalVideoStreamEnabled = function (ssrc, enabled) {
|
||||||
var trackid;
|
var trackid;
|
||||||
|
|
||||||
Object.keys(localMaps.msid2ssrc).some(function (tid) {
|
console.log(['Requested to', enabled ? 'enable' : 'disable', ssrc].join(' '));
|
||||||
if (localMaps.msid2ssrc[tid] == ssrc)
|
if (Object.keys(localMaps.msid2ssrc).some(function (tid) {
|
||||||
{
|
// Search for the track id that corresponds to the ssrc
|
||||||
|
if (localMaps.msid2ssrc[tid] == ssrc) {
|
||||||
trackid = tid;
|
trackid = tid;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
}) && stream.getVideoTracks().some(function(track) {
|
||||||
|
// Start/stop the track that corresponds to the track id
|
||||||
stream.getVideoTracks().some(function(track) {
|
|
||||||
if (track.id === trackid) {
|
if (track.id === trackid) {
|
||||||
track.enabled = true;
|
track.enabled = enabled;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
})) {
|
||||||
};
|
console.log([trackid, enabled ? 'enabled' : 'disabled'].join(' '));
|
||||||
|
$(document).trigger(enabled
|
||||||
Simulcast.prototype._stopLocalVideoStream = function (ssrc) {
|
? 'simulcastlayerstarted'
|
||||||
var trackid;
|
: 'simulcastlayerstopped');
|
||||||
|
} else {
|
||||||
Object.keys(localMaps.msid2ssrc).some(function (tid) {
|
console.error("I don't have a local stream with SSRC " + ssrc);
|
||||||
if (localMaps.msid2ssrc[tid] == ssrc)
|
}
|
||||||
{
|
|
||||||
trackid = tid;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
stream.getVideoTracks().some(function(track) {
|
|
||||||
if (track.id === trackid) {
|
|
||||||
track.enabled = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Simulcast.prototype.getLocalVideoStream = function() {
|
Simulcast.prototype.getLocalVideoStream = function() {
|
||||||
|
@ -831,21 +833,19 @@ function Simulcast() {
|
||||||
endpointSimulcastLayers.forEach(function (esl) {
|
endpointSimulcastLayers.forEach(function (esl) {
|
||||||
var ssrc = esl.simulcastLayer.primarySSRC;
|
var ssrc = esl.simulcastLayer.primarySSRC;
|
||||||
var simulcast = new Simulcast();
|
var simulcast = new Simulcast();
|
||||||
simulcast._setReceivingVideoStream(ssrc);
|
simulcast._setReceivingVideoStream(esl.endpoint, ssrc);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).bind('startsimulcastlayer', function(event, simulcastLayer) {
|
$(document).bind('startsimulcastlayer', function(event, simulcastLayer) {
|
||||||
var ssrc = simulcastLayer.primarySSRC;
|
var ssrc = simulcastLayer.primarySSRC;
|
||||||
var simulcast = new Simulcast();
|
var simulcast = new Simulcast();
|
||||||
simulcast._startLocalVideoStream(ssrc);
|
simulcast._setLocalVideoStreamEnabled(ssrc, true);
|
||||||
$(document).trigger('simulcastlayerstarted');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).bind('stopsimulcastlayer', function(event, simulcastLayer) {
|
$(document).bind('stopsimulcastlayer', function(event, simulcastLayer) {
|
||||||
var ssrc = simulcastLayer.primarySSRC;
|
var ssrc = simulcastLayer.primarySSRC;
|
||||||
var simulcast = new Simulcast();
|
var simulcast = new Simulcast();
|
||||||
simulcast._stopLocalVideoStream(ssrc);
|
simulcast._setLocalVideoStreamEnabled(ssrc, false);
|
||||||
$(document).trigger('simulcastlayerstopped');
|
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -1320,26 +1320,27 @@ var VideoLayout = (function (my) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).bind('simulcastlayerstarted', function(event) {
|
$(document).bind('simulcastlayerstarted simulcastlayerstopped', function(event) {
|
||||||
var localVideoSelector = $('#' + 'localVideo_' + connection.jingle.localVideo.id);
|
var localVideoSelector = $('#' + 'localVideo_' + connection.jingle.localVideo.id);
|
||||||
var simulcast = new Simulcast();
|
var simulcast = new Simulcast();
|
||||||
var stream = simulcast.getLocalVideoStream();
|
var stream = simulcast.getLocalVideoStream();
|
||||||
|
|
||||||
|
var updateLargeVideo = (connection.emuc.myroomjid
|
||||||
|
== getJidFromVideoSrc(largeVideoNewSrc));
|
||||||
|
var updateFocusedVideoSrc = (localVideoSrc == focusedVideoSrc);
|
||||||
|
|
||||||
// Attach WebRTC stream
|
// Attach WebRTC stream
|
||||||
RTC.attachMediaStream(localVideoSelector, stream);
|
RTC.attachMediaStream(localVideoSelector, stream);
|
||||||
|
|
||||||
localVideoSrc = $(localVideoSelector).attr('src');
|
localVideoSrc = $(localVideoSelector).attr('src');
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('simulcastlayerstopped', function(event) {
|
if (updateLargeVideo) {
|
||||||
var localVideoSelector = $('#' + 'localVideo_' + connection.jingle.localVideo.id);
|
VideoLayout.updateLargeVideo(localVideoSrc);
|
||||||
var simulcast = new Simulcast();
|
}
|
||||||
var stream = simulcast.getLocalVideoStream();
|
|
||||||
|
|
||||||
// Attach WebRTC stream
|
if (updateFocusedVideoSrc) {
|
||||||
RTC.attachMediaStream(localVideoSelector, stream);
|
focusedVideoSrc = localVideoSrc;
|
||||||
|
}
|
||||||
localVideoSrc = $(localVideoSelector).attr('src');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1415,7 +1416,7 @@ var VideoLayout = (function (my) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.error('Could not find a stream or a session.');
|
console.error('Could not find a stream or a session.', session, electedStream);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue