Skip to content

Commit

Permalink
Bugfix live edge calculation (#3201)
Browse files Browse the repository at this point in the history
* Improve live delay calculation

* Update settings

* Add fragment duration as delay fallback

* Update reference client config

* r parameter takes precedence over suggestedPresentationDelay

* Update unit tests for live delay fragment count and suggested presentation delay

* Use four times the minbuffertime instead of two times ofr live edge calculation

* Set liveDelayFragmentCount to NaN by default
  • Loading branch information
dsilhavy authored Mar 23, 2020
1 parent 2ea3e92 commit 12fafca
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 19 deletions.
4 changes: 2 additions & 2 deletions samples/dash-if-reference-player/dashjs_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"streaming": {
"metricsMaxListDepth": 50,
"abandonLoadTimeout": 10000,
"liveDelayFragmentCount": 4,
"liveDelayFragmentCount": null,
"liveDelay": null,
"scheduleWhilePaused": true,
"fastSwitchEnabled": true,
Expand All @@ -22,7 +22,7 @@
"lowLatencyEnabled": false,
"keepProtectionMediaKeys": false,
"useManifestDateHeaderTimeSource": true,
"useSuggestedPresentationDelay": false,
"useSuggestedPresentationDelay": true,
"manifestUpdateRetryInterval": 100,
"liveCatchUpMinDrift": 0.02,
"liveCatchUpMaxDrift": 0,
Expand Down
8 changes: 4 additions & 4 deletions src/core/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest';
* streaming: {
* metricsMaxListDepth: 1000,
* abandonLoadTimeout: 10000,
* liveDelayFragmentCount: 4,
* liveDelayFragmentCount: NaN,
* liveDelay: null,
* scheduleWhilePaused: true,
* fastSwitchEnabled: false,
Expand Down Expand Up @@ -203,7 +203,7 @@ import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest';
* @property {number} [abandonLoadTimeout=10000]
* A timeout value in seconds, which during the ABRController will block switch-up events.
* This will only take effect after an abandoned fragment event occurs.
* @property {number} [liveDelayFragmentCount=4]
* @property {number} [liveDelayFragmentCount=NaN]
* Changing this value will lower or increase live stream latency. The detected segment duration will be multiplied by this value
* to define a time in seconds to delay a live stream from the live edge. Lowering this value will lower latency but may decrease
* the player's ability to build a stable buffer.
Expand Down Expand Up @@ -373,7 +373,7 @@ function Settings() {
streaming: {
metricsMaxListDepth: 1000,
abandonLoadTimeout: 10000,
liveDelayFragmentCount: 4,
liveDelayFragmentCount: NaN,
liveDelay: null,
scheduleWhilePaused: true,
fastSwitchEnabled: false,
Expand All @@ -390,7 +390,7 @@ function Settings() {
lowLatencyEnabled: false,
keepProtectionMediaKeys: false,
useManifestDateHeaderTimeSource: true,
useSuggestedPresentationDelay: false,
useSuggestedPresentationDelay: true,
useAppendWindowEnd: true,
manifestUpdateRetryInterval: 100,
liveCatchUpMinDrift: 0.02,
Expand Down
3 changes: 2 additions & 1 deletion src/mss/parser/MssParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,8 @@ function MssParser(config) {
if (manifest.type === 'dynamic') {
let targetLiveDelay = mediaPlayerModel.getLiveDelay();
if (!targetLiveDelay) {
targetLiveDelay = segmentDuration * settings.get().streaming.liveDelayFragmentCount;
const liveDelayFragmentCount = settings.get().streaming.liveDelayFragmentCount !== null && !isNaN(settings.get().streaming.liveDelayFragmentCount) ? settings.get().streaming.liveDelayFragmentCount : 4;
targetLiveDelay = segmentDuration * liveDelayFragmentCount;
}
let targetDelayCapping = Math.max(manifest.timeShiftBufferDepth - 10/*END_OF_PLAYLIST_PADDING*/, manifest.timeShiftBufferDepth / 2);
let liveDelay = Math.min(targetDelayCapping, targetLiveDelay);
Expand Down
17 changes: 9 additions & 8 deletions src/streaming/controllers/PlaybackController.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,19 +240,20 @@ function PlaybackController() {

let suggestedPresentationDelay = adapter.getSuggestedPresentationDelay();

if (settings.get().streaming.useSuggestedPresentationDelay && suggestedPresentationDelay !== null) {
delay = suggestedPresentationDelay;
} else if (settings.get().streaming.lowLatencyEnabled) {
if (settings.get().streaming.lowLatencyEnabled) {
delay = 0;
} else if (mediaPlayerModel.getLiveDelay()) {
delay = mediaPlayerModel.getLiveDelay(); // If set by user, this value takes precedence
} else if (settings.get().streaming.liveDelayFragmentCount !== null && !isNaN(settings.get().streaming.liveDelayFragmentCount) && !isNaN(fragmentDuration)) {
delay = fragmentDuration * settings.get().streaming.liveDelayFragmentCount;
} else if (r) {
delay = r;
}
else if (!isNaN(fragmentDuration)) {
delay = fragmentDuration * settings.get().streaming.liveDelayFragmentCount;
} else if (settings.get().streaming.useSuggestedPresentationDelay === true && suggestedPresentationDelay !== null && !isNaN(suggestedPresentationDelay) && suggestedPresentationDelay > 0) {
delay = suggestedPresentationDelay;
} else if (!isNaN(fragmentDuration)) {
delay = fragmentDuration * 4;
} else {
delay = streamInfo.manifestInfo.minBufferTime * 2;
delay = streamInfo.manifestInfo.minBufferTime * 4;
}

startTime = adapter.getAvailabilityStartTime();
Expand Down Expand Up @@ -758,7 +759,7 @@ function PlaybackController() {
const minDelay = 1.2 * e.request.duration;
if (minDelay > mediaPlayerModel.getLiveDelay()) {
logger.warn('Browser does not support fetch API with StreamReader. Increasing live delay to be 20% higher than segment duration:', minDelay.toFixed(2));
const s = { streaming: { liveDelay: minDelay } };
const s = {streaming: {liveDelay: minDelay}};
settings.update(s);
}
}
Expand Down
8 changes: 4 additions & 4 deletions test/unit/streaming.MediaPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ describe('MediaPlayer', function () {

it('should configure LiveDelayFragmentCount', function () {
let liveDelayFragmentCount = player.getSettings().streaming.liveDelayFragmentCount;
expect(liveDelayFragmentCount).to.equal(4);
expect(liveDelayFragmentCount).to.be.NaN; // jshint ignore:line

player.updateSettings({'streaming': { 'liveDelayFragmentCount': 5 }});

Expand All @@ -612,12 +612,12 @@ describe('MediaPlayer', function () {

it('should configure useSuggestedPresentationDelay', function () {
let useSuggestedPresentationDelay = player.getSettings().streaming.useSuggestedPresentationDelay;
expect(useSuggestedPresentationDelay).to.be.false; // jshint ignore:line
expect(useSuggestedPresentationDelay).to.be.true; // jshint ignore:line

player.updateSettings({'streaming': { 'useSuggestedPresentationDelay': true }});
player.updateSettings({'streaming': { 'useSuggestedPresentationDelay': false }});

useSuggestedPresentationDelay = player.getSettings().streaming.useSuggestedPresentationDelay;
expect(useSuggestedPresentationDelay).to.be.true; // jshint ignore:line
expect(useSuggestedPresentationDelay).to.be.false; // jshint ignore:line
});

it('should configure scheduleWhilePaused', function () {
Expand Down

0 comments on commit 12fafca

Please sign in to comment.