54977aa4 by David LaPalomento

Don't download segments while switching playlists

If bandwidth drops off precipitously, it's not a good idea to fetch a higher quality segment while waiting for the new media playlist to load. Delay segment loading instead. Less fetching will be done in parallel after this change but:
 - the player will adjust to dramatic bandwidth drops more quickly
 - the player will upshift more quickly when bandwidth returns
1 parent d0183164
......@@ -584,6 +584,11 @@ videojs.Hls.prototype.fillBuffer = function(offset) {
return;
}
// if a playlist switch is in progress, wait for it to finish
if (this.playlists.state === 'SWITCHING_MEDIA') {
return;
}
// if the video has finished downloading, stop trying to buffer
segment = this.playlists.media().segments[this.mediaIndex];
if (!segment) {
......
......@@ -976,6 +976,35 @@ test('only appends one segment at a time', function() {
equal(appends, 0, 'did not append while updating');
});
test('waits to download new segments until the media playlist is stable', function() {
var media;
player.src({
src: 'manifest/master.m3u8',
type: 'application/vnd.apple.mpegurl'
});
openMediaSource(player);
standardXHRResponse(requests.shift()); // master
player.hls.bandwidth = 1; // make sure we stay on the lowest variant
standardXHRResponse(requests.shift()); // media
// mock a playlist switch
media = player.hls.playlists.media();
player.hls.playlists.media = function() {
return media;
};
player.hls.playlists.state = 'SWITCHING_MEDIA';
standardXHRResponse(requests.shift()); // segment 0
equal(requests.length, 0, 'no requests outstanding');
player.hls.checkBuffer_();
equal(requests.length, 0, 'delays segment fetching');
player.hls.playlists.state = 'LOADED_METADATA';
player.hls.checkBuffer_();
equal(requests.length, 1, 'resumes segment fetching');
});
test('cancels outstanding XHRs when seeking', function() {
player.src({
src: 'manifest/media.m3u8',
......