Skip to content

Commit

Permalink
feat(DASH): Add support for minimum values in service descriptions (#…
Browse files Browse the repository at this point in the history
…5844)

Closes #5780
  • Loading branch information
avelad committed Nov 2, 2023
1 parent 8d2b657 commit 5f94a62
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 7 deletions.
8 changes: 8 additions & 0 deletions demo/config.js
Expand Up @@ -407,6 +407,14 @@ shakaDemo.Config = class {
.addNumberInput_('Playback rate for live sync',
'streaming.liveSyncPlaybackRate',
/* canBeDecimal= */ true,
/* canBeZero= */ false)
.addNumberInput_('Min latency for live sync',
'streaming.liveSyncMinLatency',
/* canBeDecimal= */ true,
/* canBeZero= */ true)
.addNumberInput_('Min playback rate for live sync',
'streaming.liveSyncMinPlaybackRate',
/* canBeDecimal= */ true,
/* canBeZero= */ false);

if (!shakaDemoMain.getNativeControlsEnabled()) {
Expand Down
14 changes: 11 additions & 3 deletions externs/shaka/manifest.js
Expand Up @@ -152,18 +152,26 @@ shaka.extern.InitDataOverride;
/**
* @typedef {{
* maxLatency: ?number,
* maxPlaybackRate: ?number
* maxPlaybackRate: ?number,
* minLatency: ?number,
* minPlaybackRate: ?number
* }}
*
* @description
* Maximum latency and playback rate for a manifest. When max latency is reached
* playbackrate is updated to maxPlaybackRate to decrease latency.
* Maximum and minimun latency and playback rate for a manifest. When max
* latency is reached playbackrate is updated to maxPlaybackRate to decrease
* latency. When min latency is reached playbackrate is updated to
* minPlaybackRate to increase latency.
* More information {@link https://dashif.org/docs/CR-Low-Latency-Live-r8.pdf here}.
*
* @property {?number} maxLatency
* Maximum latency in seconds.
* @property {?number} maxPlaybackRate
* Maximum playback rate.
* @property {?number} minLatency
* Minimun latency in seconds.
* @property {?number} minPlaybackRate
* Minimun playback rate.
*
* @exportDoc
*/
Expand Down
11 changes: 10 additions & 1 deletion externs/shaka/player.js
Expand Up @@ -1105,7 +1105,9 @@ shaka.extern.ManifestConfiguration;
* segmentPrefetchLimit: number,
* liveSync: boolean,
* liveSyncMaxLatency: number,
* liveSyncPlaybackRate: number
* liveSyncPlaybackRate: number,
* liveSyncMinLatency: number,
* liveSyncMinPlaybackRate: number
* }}
*
* @description
Expand Down Expand Up @@ -1234,6 +1236,13 @@ shaka.extern.ManifestConfiguration;
* Playback rate used for latency chasing. It is recommended to use a value
* between 1 and 2. Effective only if liveSync is true. Defaults to
* <code>1.1</code>.
* @property {number} liveSyncMinLatency
* Minimun acceptable latency, in seconds. Effective only if liveSync is
* true. Defaults to <code>0</code>.
* @property {number} liveSyncMinPlaybackRate
* Minimun playback rate used for latency chasing. It is recommended to use a
* value between 0 and 1. Effective only if liveSync is true. Defaults to
* <code>1</code>.
* @exportDoc
*/
shaka.extern.StreamingConfiguration;
Expand Down
13 changes: 12 additions & 1 deletion lib/dash/dash_parser.js
Expand Up @@ -603,8 +603,19 @@ shaka.dash.DashParser = class {
const maxPlaybackRate = playbackRateNode ?
parseFloat(playbackRateNode.getAttribute('max')) :
null;
const minLatency = latencyNode && latencyNode.getAttribute('min') ?
parseInt(latencyNode.getAttribute('min'), 10) / 1000 :
null;
const minPlaybackRate = playbackRateNode ?
parseFloat(playbackRateNode.getAttribute('min')) :
null;

return {maxLatency, maxPlaybackRate};
return {
maxLatency,
maxPlaybackRate,
minLatency,
minPlaybackRate,
};
}

return null;
Expand Down
25 changes: 25 additions & 0 deletions lib/player.js
Expand Up @@ -5471,6 +5471,23 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
}
}

let liveSyncMinLatency;
let liveSyncMinPlaybackRate;
if (this.config_.streaming.liveSync) {
liveSyncMinLatency = this.config_.streaming.liveSyncMinLatency;
liveSyncMinPlaybackRate = this.config_.streaming.liveSyncMinPlaybackRate;
} else {
// serviceDescription must override if it is defined in the MPD and
// liveSync configuration is not set.
if (this.manifest_ && this.manifest_.serviceDescription) {
liveSyncMinLatency = this.manifest_.serviceDescription.minLatency ||
this.config_.streaming.liveSyncMinLatency;
liveSyncMinPlaybackRate =
this.manifest_.serviceDescription.minPlaybackRate ||
this.config_.streaming.liveSyncMinPlaybackRate;
}
}

const playbackRate = this.video_.playbackRate;
const latency = seekRange.end - this.video_.currentTime;
let offset = 0;
Expand All @@ -5494,6 +5511,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
'Updating playbackRate to ' + liveSyncPlaybackRate);
this.trickPlay(liveSyncPlaybackRate);
}
} else if (liveSyncMinLatency && liveSyncMinPlaybackRate &&
(latency - offset) < liveSyncMinLatency) {
if (playbackRate != liveSyncMinPlaybackRate) {
shaka.log.debug('Latency (' + latency + 's) ' +
'is smaller than liveSyncMinLatency (' + liveSyncMinLatency + 's). ' +
'Updating playbackRate to ' + liveSyncMinPlaybackRate);
this.trickPlay(liveSyncMinPlaybackRate);
}
} else if (playbackRate !== this.playRateController_.getDefaultRate()) {
this.cancelTrickPlay();
}
Expand Down
2 changes: 2 additions & 0 deletions lib/util/player_configuration.js
Expand Up @@ -216,6 +216,8 @@ shaka.util.PlayerConfiguration = class {
liveSync: false,
liveSyncMaxLatency: 1,
liveSyncPlaybackRate: 1.1,
liveSyncMinLatency: 0,
liveSyncMinPlaybackRate: 1,
};

// WebOS, Tizen, Chromecast and Hisense have long hardware pipelines
Expand Down
6 changes: 4 additions & 2 deletions test/dash/dash_parser_manifest_unit.js
Expand Up @@ -2611,8 +2611,8 @@ describe('DashParser Manifest', () => {
'<MPD minBufferTime="PT75S" type="dynamic"',
' availabilityStartTime="1970-01-01T00:00:00Z">',
' <ServiceDescription id="0">',
' <Latency max="2000" min="2000" referenceId="0" target="4000" />',
' <PlaybackRate max="1.10" min="0.96" />',
' <Latency max="2000" min="1000" referenceId="0" target="4000" />',
' <PlaybackRate max="1.10" min="0.95" />',
' </ServiceDescription>',
'</MPD>',
].join('\n');
Expand All @@ -2624,6 +2624,8 @@ describe('DashParser Manifest', () => {

expect(manifest.serviceDescription.maxLatency).toBe(2);
expect(manifest.serviceDescription.maxPlaybackRate).toBe(1.1);
expect(manifest.serviceDescription.minLatency).toBe(1);
expect(manifest.serviceDescription.minPlaybackRate).toBe(0.95);
});
});
});

0 comments on commit 5f94a62

Please sign in to comment.