Skip to content

Commit

Permalink
Make low latency specific reduction and multiplication factor for ret…
Browse files Browse the repository at this point in the history
…ry attempts and retry interval configurable. (#3279)
  • Loading branch information
dsilhavy committed Jun 8, 2020
1 parent 54244b6 commit b6af24f
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 26 deletions.
16 changes: 10 additions & 6 deletions src/core/Settings.js
Expand Up @@ -87,7 +87,8 @@ import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest';
* IndexSegment: 1000,
* MediaSegment: 1000,
* BitstreamSwitchingSegment: 1000,
* other: 1000
* other: 1000,
* lowLatencyReductionFactor: 10
* },
* retryAttempts: {
* MPD: 3,
Expand All @@ -96,7 +97,8 @@ import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest';
* IndexSegment: 3,
* MediaSegment: 3,
* BitstreamSwitchingSegment: 3,
* other: 3
* other: 3,
* lowLatencyMultiplyFactor: 5
* },
* abr: {
* movingAverageMethod: Constants.MOVING_AVERAGE_SLIDING_WINDOW,
Expand Down Expand Up @@ -316,8 +318,8 @@ import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest';
* @property {module:Settings~AudioVideoSettings} [cacheLoadThresholds={video: 50, audio: 5}]
* For a given media type, the threshold which defines if the response to a fragment
* request is coming from browser cache or not.
* @property {module:Settings~RequestTypeSettings} [retryIntervals] Time in milliseconds of which to reload a failed file load attempt.
* @property {module:Settings~RequestTypeSettings} [retryAttempts] Total number of retry attempts that will occur on a file load before it fails.
* @property {module:Settings~RequestTypeSettings} [retryIntervals] Time in milliseconds of which to reload a failed file load attempt. For low latency mode these values are divided by lowLatencyReductionFactor.
* @property {module:Settings~RequestTypeSettings} [retryAttempts] Total number of retry attempts that will occur on a file load before it fails. For low latency mode these values are multiplied by lowLatencyMultiplyFactor.
* @property {module:Settings~AbrSettings} abr Adaptive Bitrate algorithm related settings.
* @property {module:Settings~CmcdSettings} cmcd Settings related to Common Media Client Data reporting.
*/
Expand Down Expand Up @@ -406,7 +408,8 @@ function Settings() {
[HTTPRequest.INIT_SEGMENT_TYPE]: 1000,
[HTTPRequest.BITSTREAM_SWITCHING_SEGMENT_TYPE]: 1000,
[HTTPRequest.INDEX_SEGMENT_TYPE]: 1000,
[HTTPRequest.OTHER_TYPE]: 1000
[HTTPRequest.OTHER_TYPE]: 1000,
lowLatencyReductionFactor: 10
},
retryAttempts: {
[HTTPRequest.MPD_TYPE]: 3,
Expand All @@ -415,7 +418,8 @@ function Settings() {
[HTTPRequest.INIT_SEGMENT_TYPE]: 3,
[HTTPRequest.BITSTREAM_SWITCHING_SEGMENT_TYPE]: 3,
[HTTPRequest.INDEX_SEGMENT_TYPE]: 3,
[HTTPRequest.OTHER_TYPE]: 3
[HTTPRequest.OTHER_TYPE]: 3,
lowLatencyMultiplyFactor: 5
},
abr: {
movingAverageMethod: Constants.MOVING_AVERAGE_SLIDING_WINDOW,
Expand Down
10 changes: 7 additions & 3 deletions src/streaming/models/MediaPlayerModel.js
Expand Up @@ -126,11 +126,15 @@ function MediaPlayerModel() {
}

function getRetryAttemptsForType(type) {
return settings.get().streaming.lowLatencyEnabled ? settings.get().streaming.retryAttempts[type] * LOW_LATENCY_MULTIPLY_FACTOR : settings.get().streaming.retryAttempts[type];
const lowLatencyMultiplyFactor = !isNaN(settings.get().streaming.retryAttempts.lowLatencyMultiplyFactor) ? settings.get().streaming.retryAttempts.lowLatencyMultiplyFactor : LOW_LATENCY_MULTIPLY_FACTOR;

return settings.get().streaming.lowLatencyEnabled ? settings.get().streaming.retryAttempts[type] * lowLatencyMultiplyFactor : settings.get().streaming.retryAttempts[type];
}

function getRetryIntervalsForType(type) {
return settings.get().streaming.lowLatencyEnabled ? settings.get().streaming.retryIntervals[type] / LOW_LATENCY_REDUCTION_FACTOR : settings.get().streaming.retryIntervals[type];
const lowLatencyReductionFactor = !isNaN(settings.get().streaming.retryIntervals.lowLatencyReductionFactor) ? settings.get().streaming.retryIntervals.lowLatencyReductionFactor : LOW_LATENCY_REDUCTION_FACTOR;

return settings.get().streaming.lowLatencyEnabled ? settings.get().streaming.retryIntervals[type] / lowLatencyReductionFactor : settings.get().streaming.retryIntervals[type];
}

function getLiveDelay() {
Expand Down Expand Up @@ -221,4 +225,4 @@ function MediaPlayerModel() {

//TODO see if you can move this and not export and just getter to get default value.
MediaPlayerModel.__dashjs_factory_name = 'MediaPlayerModel';
export default FactoryMaker.getSingletonFactory(MediaPlayerModel);
export default FactoryMaker.getSingletonFactory(MediaPlayerModel);
77 changes: 60 additions & 17 deletions test/unit/streaming.models.MediaPlayerModel.js
Expand Up @@ -12,7 +12,11 @@ const expect = chai.expect;
describe('MediaPlayerModel', function () {
const context = {};
const mediaPlayerModel = MediaPlayerModel(context).getInstance();
const settings = Settings(context).getInstance();
let settings = Settings(context).getInstance();

beforeEach(() => {
settings.reset();
});

it('Method removeUTCTimingSource should throw an exception', function () {
expect(mediaPlayerModel.removeUTCTimingSource.bind(mediaPlayerModel, true, 'string')).to.throw(Constants.BAD_ARGUMENT_ERROR);
Expand Down Expand Up @@ -44,7 +48,7 @@ describe('MediaPlayerModel', function () {
let FragmentLoaderRetryAttempts = mediaPlayerModel.getRetryAttemptsForType(HTTPRequest.MEDIA_SEGMENT_TYPE);
expect(FragmentLoaderRetryAttempts).to.equal(3);

const s = { streaming: { retryAttempts: {}}};
const s = {streaming: {retryAttempts: {}}};
s.streaming.retryAttempts[HTTPRequest.MEDIA_SEGMENT_TYPE] = 50;
settings.update(s);

Expand All @@ -53,46 +57,85 @@ describe('MediaPlayerModel', function () {
});

it('should configure FragmentLoaderRetryInterval', function () {
let FragmentLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MEDIA_SEGMENT_TYPE);
let FragmentLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MEDIA_SEGMENT_TYPE);
expect(FragmentLoaderRetryInterval).to.equal(1000);

const s = { streaming: { retryIntervals: {}}};
const s = {streaming: {retryIntervals: {}}};
s.streaming.retryIntervals[HTTPRequest.MEDIA_SEGMENT_TYPE] = 50;
settings.update(s);

FragmentLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MEDIA_SEGMENT_TYPE);
FragmentLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MEDIA_SEGMENT_TYPE);
expect(FragmentLoaderRetryInterval).to.equal(50);
});

it('should configure ManifestLoaderRetryAttempts', function () {
let ManifestLoaderRetryAttempts = mediaPlayerModel.getRetryAttemptsForType(HTTPRequest.MPD_TYPE);
expect(ManifestLoaderRetryAttempts).to.equal(3);
let manifestLoaderRetryAttempts = mediaPlayerModel.getRetryAttemptsForType(HTTPRequest.MPD_TYPE);
expect(manifestLoaderRetryAttempts).to.equal(3);

const s = { streaming: { retryAttempts: {}}};
const s = {streaming: {retryAttempts: {}}};
s.streaming.retryAttempts[HTTPRequest.MPD_TYPE] = 50;
settings.update(s);

ManifestLoaderRetryAttempts = mediaPlayerModel.getRetryAttemptsForType(HTTPRequest.MPD_TYPE);
expect(ManifestLoaderRetryAttempts).to.equal(50);
manifestLoaderRetryAttempts = mediaPlayerModel.getRetryAttemptsForType(HTTPRequest.MPD_TYPE);
expect(manifestLoaderRetryAttempts).to.equal(50);
});

it('should configure low latency retry attempt multiplication factor', function () {
let manifestLoaderRetryAttempts = mediaPlayerModel.getRetryAttemptsForType(HTTPRequest.MPD_TYPE);
expect(manifestLoaderRetryAttempts).to.equal(3);

const s = {
streaming:
{
lowLatencyEnabled: true,
retryAttempts: {
lowLatencyMultiplyFactor: 10
}
}
};
settings.update(s);

manifestLoaderRetryAttempts = mediaPlayerModel.getRetryAttemptsForType(HTTPRequest.MPD_TYPE);
expect(manifestLoaderRetryAttempts).to.equal(30);
});

it('should configure ManifestLoaderRetryInterval', function () {
let ManifestLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MPD_TYPE);
expect(ManifestLoaderRetryInterval).to.equal(500);
let manifestLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MPD_TYPE);
expect(manifestLoaderRetryInterval).to.equal(500);

const s = { streaming: { retryIntervals: {}}};
const s = {streaming: {retryIntervals: {}}};
s.streaming.retryIntervals[HTTPRequest.MPD_TYPE] = 50;
settings.update(s);

ManifestLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MPD_TYPE);
expect(ManifestLoaderRetryInterval).to.equal(50);
manifestLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MPD_TYPE);
expect(manifestLoaderRetryInterval).to.equal(50);
});

it('should configure low latency retry interval reduction factor', function () {
let manifestLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MPD_TYPE);
expect(manifestLoaderRetryInterval).to.equal(500);

const s = {
streaming:
{
lowLatencyEnabled: true,
retryIntervals: {
lowLatencyReductionFactor: 5
}
}
};
settings.update(s);

manifestLoaderRetryInterval = mediaPlayerModel.getRetryIntervalsForType(HTTPRequest.MPD_TYPE);
expect(manifestLoaderRetryInterval).to.equal(100);
});

it('should configure StableBufferTime', function () {
const s = { streaming: { stableBufferTime: 50 } };
const s = {streaming: {stableBufferTime: 50}};
settings.update(s);

let StableBufferTime = mediaPlayerModel.getStableBufferTime();
expect(StableBufferTime).to.equal(50);
});
});

});

0 comments on commit b6af24f

Please sign in to comment.