0

Limit the amount the latency compensates at once with a ramp up

This commit is contained in:
Gabe Kangas 2022-04-04 13:46:52 -07:00
parent af64e88678
commit 823f952b9c
No known key found for this signature in database
GPG Key ID: 9A56337728BC81EA

View File

@ -7,6 +7,7 @@ possible, without causing any buffering events.
It will: It will:
- Determine the start (max) and end (min) latency values. - Determine the start (max) and end (min) latency values.
- Keep an eye on download speed and stop compensating if it drops too low. - Keep an eye on download speed and stop compensating if it drops too low.
- Limit the playback speedup so it doesn't sound weird by jumping rates.
- Dynamically calculate the speedup rate based on network speed. - Dynamically calculate the speedup rate based on network speed.
- Pause the compensation if buffering events occur. - Pause the compensation if buffering events occur.
- Completely give up on all compensation if too many buffering events occur. - Completely give up on all compensation if too many buffering events occur.
@ -14,12 +15,13 @@ It will:
const REBUFFER_EVENT_LIMIT = 5; // Max number of buffering events before we stop compensating for latency. const REBUFFER_EVENT_LIMIT = 5; // Max number of buffering events before we stop compensating for latency.
const MIN_BUFFER_DURATION = 500; // Min duration a buffer event must last to be counted. const MIN_BUFFER_DURATION = 500; // Min duration a buffer event must last to be counted.
const MAX_SPEEDUP_RATE = 1.08; // The playback rate when compensating for latency. const MAX_SPEEDUP_RATE = 1.07; // The playback rate when compensating for latency.
const MAX_SPEEDUP_RAMP = 0.005; // The max amount we will increase the playback rate at once.
const TIMEOUT_DURATION = 30 * 1000; // The amount of time we stop handling latency after certain events. const TIMEOUT_DURATION = 30 * 1000; // The amount of time we stop handling latency after certain events.
const CHECK_TIMER_INTERVAL = 5_000; // How often we check if we should be compensating for latency. const CHECK_TIMER_INTERVAL = 5_000; // How often we check if we should be compensating for latency.
const BUFFERING_AMNESTY_DURATION = 3 * 1000 * 60; // How often until a buffering event expires. const BUFFERING_AMNESTY_DURATION = 3 * 1000 * 60; // How often until a buffering event expires.
const REQUIRED_BANDWIDTH_RATIO = 2.0; // The player:bitrate ratio required to enable compensating for latency. const REQUIRED_BANDWIDTH_RATIO = 2.0; // The player:bitrate ratio required to enable compensating for latency.
const HIGHEST_LATENCY_SEGMENT_LENGTH_MULTIPLIER = 2.4; // Segment length * this value is when we start compensating. const HIGHEST_LATENCY_SEGMENT_LENGTH_MULTIPLIER = 2.5; // Segment length * this value is when we start compensating.
const LOWEST_LATENCY_SEGMENT_LENGTH_MULTIPLIER = 1.7; // Segment length * this value is when we stop compensating. const LOWEST_LATENCY_SEGMENT_LENGTH_MULTIPLIER = 1.7; // Segment length * this value is when we stop compensating.
const MIN_LATENCY = 4 * 1000; // The lowest we'll continue compensation to be running at. const MIN_LATENCY = 4 * 1000; // The lowest we'll continue compensation to be running at.
const MAX_LATENCY = 8 * 1000; // The highest we'll allow a target latency to be before we start compensating. const MAX_LATENCY = 8 * 1000; // The highest we'll allow a target latency to be before we start compensating.
@ -94,19 +96,31 @@ class LatencyCompensator {
const playerBandwidth = tech.vhs.systemBandwidth; const playerBandwidth = tech.vhs.systemBandwidth;
const bandwidthRatio = playerBandwidth / currentPlaylistBandwidth; const bandwidthRatio = playerBandwidth / currentPlaylistBandwidth;
// If we don't think we have the bandwidth to play faster, then don't do it.
if (bandwidthRatio < REQUIRED_BANDWIDTH_RATIO) { if (bandwidthRatio < REQUIRED_BANDWIDTH_RATIO) {
this.timeout(); this.timeout();
return; return;
} }
let proposedPlaybackRate = bandwidthRatio * 0.34; // Using our bandwidth ratio determine a wide guess at how fast we can play.
let proposedPlaybackRate = bandwidthRatio * 0.33;
console.log('proposed rate', proposedPlaybackRate); console.log('proposed rate', proposedPlaybackRate);
// But limit the playback rate to a max value.
proposedPlaybackRate = Math.max( proposedPlaybackRate = Math.max(
Math.min(proposedPlaybackRate, MAX_SPEEDUP_RATE), Math.min(proposedPlaybackRate, MAX_SPEEDUP_RATE),
1.0 1.0
); );
// If this proposed speed is substantially faster than the current rate,
// then allow us to ramp up by using a slower value for now.
if (proposedPlaybackRate > this.playbackRate + MAX_SPEEDUP_RAMP) {
proposedPlaybackRate = this.playbackRate + MAX_SPEEDUP_RAMP;
}
proposedPlaybackRate =
Math.round(proposedPlaybackRate * Math.pow(10, 3)) / Math.pow(10, 3);
try { try {
const segment = getCurrentlyPlayingSegment(tech); const segment = getCurrentlyPlayingSegment(tech);
if (!segment) { if (!segment) {