Skip to content

Commit

Permalink
Replace simulcast with a proper encodings array of RTCRtpCodingParame…
Browse files Browse the repository at this point in the history
…ters
  • Loading branch information
ibc committed Jan 28, 2019
1 parent 727bb5d commit dd203e8
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 111 deletions.
43 changes: 17 additions & 26 deletions lib/Transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@ const ortc = require('./ortc');
const Producer = require('./Producer');
const Consumer = require('./Consumer');

const SIMULCAST_DEFAULT =
[
{ maxBitrate: 100000 },
{ maxBitrate: 500000 },
{ maxBitrate: 1500000 }
];

const logger = new Logger('Transport');

class Transport extends EnhancedEventEmitter
Expand Down Expand Up @@ -267,7 +260,7 @@ class Transport extends EnhancedEventEmitter
* Produce a track.
*
* @param {MediaStreamTrack} track - Track to sent.
* @param {Object|Boolean} [simulcast=true] - Simulcast options.
* @param {Array<RTCRtpCodingParameters>} [encodings] - Encodings.
* @param {Number} [maxSpatialLayer] - Video max spatial layer to send.
* @param {Object} [appData={}] - Custom app data.
*
Expand All @@ -278,7 +271,7 @@ class Transport extends EnhancedEventEmitter
* @throws {UnsupportedError} if Transport direction is incompatible or
* cannot produce the given media kind.
*/
async produce({ track, simulcast = false, maxSpatialLayer, appData = {} } = {})
async produce({ track, encodings, maxSpatialLayer, appData = {} } = {})
{
logger.debug('produce() [track:%o]', track);

Expand All @@ -301,34 +294,32 @@ class Transport extends EnhancedEventEmitter
return this._awaitQueue.push(
async () =>
{
let normalizedSimulcast;
let normalizedEncodings;

if (!simulcast || track.kind !== 'video')
if (encodings && !Array.isArray(encodings))
{
normalizedSimulcast = false;
throw TypeError('encodings must be an array');
}
else if (simulcast === true)
else if (encodings && encodings.length === 0)
{
normalizedSimulcast = SIMULCAST_DEFAULT;
normalizedEncodings = undefined;
}
else if (Array.isArray(simulcast) && simulcast.length > 1)
else if (encodings)
{
normalizedSimulcast = simulcast
.map((entry) =>
normalizedEncodings = encodings
.map((encoding) =>
{
if (!entry || entry.maxBitrate !== 'number')
throw TypeError('invalid simulcast entry');

return { maxBitrate: entry.maxBitrate };
return {
active : true,
maxBitrate : encoding.maxBitrate,
maxFramerate : encoding.maxFramerate,
scaleResolutionDownBy : encoding.scaleResolutionDownBy
};
});
}
else
{
throw new TypeError('invalid simulcast');
}

const rtpParameters =
await this._handler.send({ track, simulcast: normalizedSimulcast });
await this._handler.send({ track, encodings: normalizedEncodings });

if (typeof maxSpatialLayer === 'number')
{
Expand Down
7 changes: 3 additions & 4 deletions lib/handlers/Chrome55.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class SendHandler extends Handler
this._stream = new MediaStream();
}

async send({ track, simulcast })
async send({ track, encodings })
{
logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);

Expand All @@ -156,8 +156,7 @@ class SendHandler extends Handler

let offer = await this._pc.createOffer();

// If simulcast is set, mangle the offer.
if (simulcast)
if (encodings && encodings.length > 1)
{
logger.debug('send() | enabling simulcast');

Expand All @@ -166,7 +165,7 @@ class SendHandler extends Handler
sdpPlanBUtils.addSimulcastForTrack(
sdpObject,
track,
{ numStreams: simulcast.length });
{ numStreams: encodings.length });

const offerSdp = sdpTransform.write(sdpObject);

Expand Down
7 changes: 3 additions & 4 deletions lib/handlers/Chrome67.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class SendHandler extends Handler
this._stream = new MediaStream();
}

async send({ track, simulcast })
async send({ track, encodings })
{
logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);

Expand All @@ -158,8 +158,7 @@ class SendHandler extends Handler

let offer = this._pc.createOffer();

// If simulcast is set, mangle the offer.
if (simulcast)
if (encodings && encodings.length > 1)
{
logger.debug('send() | enabling simulcast');

Expand All @@ -168,7 +167,7 @@ class SendHandler extends Handler
sdpPlanBUtils.addSimulcastForTrack(
sdpObject,
track,
{ numStreams: simulcast.length });
{ numStreams: encodings.length });

const offerSdp = sdpTransform.write(sdpObject);

Expand Down
16 changes: 10 additions & 6 deletions lib/handlers/Chrome70.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class SendHandler extends Handler
this._tracks = new Set();
}

async send({ track, simulcast })
async send({ track, encodings })
{
logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);

Expand Down Expand Up @@ -163,18 +163,22 @@ class SendHandler extends Handler
// Must reset encodings in the RtpSender.
const parameters = rtpSender.getParameters();

await rtpSender.setParameters({ ...parameters, encodings: [] });
await rtpSender.setParameters({ ...parameters, encodings });
await rtpSender.replaceTrack(track);
}
else
{
transceiver = this._pc.addTransceiver(track, { direction: 'sendonly' });
transceiver = this._pc.addTransceiver(
track,
{
direction : 'sendonly',
sendEncodings : encodings
});
}

let offer = await this._pc.createOffer();

// If simulcast is set, mangle the offer.
if (simulcast)
if (encodings && encodings.length > 1)
{
logger.debug('send() | enabling simulcast');

Expand All @@ -184,7 +188,7 @@ class SendHandler extends Handler
sdpObject,
track,
{
numStreams : simulcast.length,
numStreams : encodings.length,
mid : transceiver.mid
});

Expand Down
22 changes: 10 additions & 12 deletions lib/handlers/Edge11.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class Edge11 extends EnhancedEventEmitter
return this._iceTransport.getStats();
}

async send({ track, simulcast }) // eslint-disable-line no-unused-vars
async send({ track, encodings })
{
logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);

Expand All @@ -126,22 +126,20 @@ class Edge11 extends EnhancedEventEmitter
const rtpSender = new RTCRtpSender(track, this._dtlsTransport);
const rtpParameters =
utils.clone(this._sendingRtpParametersByKind[track.kind]);
const useRtx = rtpParameters.codecs.some((codec) => codec.name === 'rtx');

// Fill RTCRtpParameters.encodings.
const encoding =
{
ssrc : utils.generateRandomNumber()
};
if (!encodings)
encodings = [ {} ];

if (rtpParameters.codecs.some((codec) => codec.name === 'rtx'))
for (const encoding of encodings)
{
encoding.rtx =
{
ssrc : utils.generateRandomNumber()
};
encoding.ssrc = utils.generateRandomNumber();

if (useRtx)
encoding.rtx = { ssrc: utils.generateRandomNumber() };
}

rtpParameters.encodings.push(encoding);
rtpParameters.encodings = encodings;

// Fill RTCRtpParameters.rtcp.
rtpParameters.rtcp =
Expand Down
52 changes: 20 additions & 32 deletions lib/handlers/Firefox60.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,24 @@ class SendHandler extends Handler
this._nextRid = 1;
}

async send({ track, simulcast })
async send({ track, encodings })
{
logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);

if (this._tracks.has(track))
throw new DuplicatedError('track already handled');

if (encodings && encodings.length > 1)
{
encodings.forEach((encoding, idx) =>
{
encoding.rid = `rid-${this._nextRid}-${idx}`;

// Update RID counter for future ones.
this._nextRid++;
});
}

let transceiver;

try
Expand All @@ -163,38 +174,17 @@ class SendHandler extends Handler
// Must reset encodings in the RtpSender.
const parameters = rtpSender.getParameters();

await rtpSender.setParameters({ ...parameters, encodings: [] });
await rtpSender.setParameters({ ...parameters, encodings });
await rtpSender.replaceTrack(track);
}
else
{
transceiver = this._pc.addTransceiver(track, { direction: 'sendonly' });
}

let encodings;

if (simulcast)
{
logger.debug('send() | enabling simulcast');

const { sender } = transceiver;

encodings = simulcast
.map((entry, idx) => (
{
rid : `rid-${this._nextRid}-${idx}`,
active : true,
maxBitrate : entry.maxBitrate
}
));

// Update RID counter for future ones.
this._nextRid++;

const parameters = sender.getParameters();
const newParameters = Object.assign(parameters, { encodings });

await sender.setParameters(newParameters);
transceiver = this._pc.addTransceiver(
track,
{
direction : 'sendonly',
sendEncodings : encodings
});
}

const offer = await this._pc.createOffer();
Expand Down Expand Up @@ -223,9 +213,7 @@ class SendHandler extends Handler
const rtpParameters =
utils.clone(this._sendingRtpParametersByKind[track.kind]);

// If simulcast is given, automatically set the encodings.
if (simulcast)
rtpParameters.encodings = encodings;
rtpParameters.encodings = encodings;

sdpUnifiedPlanUtils.fillRtpParametersForTrack(
rtpParameters,
Expand Down
7 changes: 3 additions & 4 deletions lib/handlers/ReactNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class SendHandler extends Handler
this._tracks = new Set();
}

async send({ track, simulcast })
async send({ track, encodings })
{
logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);

Expand All @@ -163,8 +163,7 @@ class SendHandler extends Handler

let offer = await this._pc.createOffer();

// If simulcast is set, mangle the offer.
if (simulcast)
if (encodings && encodings.length > 1)
{
logger.debug('send() | enabling simulcast');

Expand All @@ -173,7 +172,7 @@ class SendHandler extends Handler
sdpPlanBUtils.addSimulcastForTrack(
sdpObject,
track,
{ numStreams: simulcast.length });
{ numStreams: encodings.length });

const offerSdp = sdpTransform.write(sdpObject);

Expand Down
2 changes: 1 addition & 1 deletion lib/handlers/Safari11.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class SendHandler extends Handler
this._stream = new MediaStream();
}

async send({ track, simulcast }) // eslint-disable-line no-unused-vars
async send({ track, encodings }) // eslint-disable-line no-unused-vars
{
logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);

Expand Down
16 changes: 10 additions & 6 deletions lib/handlers/Safari12.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class SendHandler extends Handler
this._tracks = new Set();
}

async send({ track, simulcast })
async send({ track, encodings })
{
logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);

Expand Down Expand Up @@ -163,18 +163,22 @@ class SendHandler extends Handler
// Must reset encodings in the RtpSender.
const parameters = rtpSender.getParameters();

await rtpSender.setParameters({ ...parameters, encodings: [] });
await rtpSender.setParameters({ ...parameters, encodings });
await rtpSender.replaceTrack(track);
}
else
{
transceiver = this._pc.addTransceiver(track, { direction: 'sendonly' });
transceiver = this._pc.addTransceiver(
track,
{
direction : 'sendonly',
sendEncodings : encodings
});
}

let offer = await this._pc.createOffer();

// If simulcast is set, mangle the offer.
if (simulcast)
if (encodings && encodings.length > 1)
{
logger.debug('send() | enabling simulcast');

Expand All @@ -184,7 +188,7 @@ class SendHandler extends Handler
sdpObject,
track,
{
numStreams : simulcast.length,
numStreams : encodings.length,
mid : transceiver.mid
});

Expand Down
3 changes: 2 additions & 1 deletion lib/handlers/sdp/unifiedPlanUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ exports.fillRtpParametersForTrack = function(
// Standard simylcast based on a=simulcast and RID.
if (!legacySimulcast)
{
// If encodings are already given (so RID usage), just use them.
// If encodings are already given (so RID usage) and there are more than just
// one, just use them.
if (Array.isArray(encodings) && encodings.length > 1)
{
rtpParameters.encodings = encodings;
Expand Down
Loading

0 comments on commit dd203e8

Please sign in to comment.