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) { ...@@ -584,6 +584,11 @@ videojs.Hls.prototype.fillBuffer = function(offset) {
584 return; 584 return;
585 } 585 }
586 586
587 // if a playlist switch is in progress, wait for it to finish
588 if (this.playlists.state === 'SWITCHING_MEDIA') {
589 return;
590 }
591
587 // if the video has finished downloading, stop trying to buffer 592 // if the video has finished downloading, stop trying to buffer
588 segment = this.playlists.media().segments[this.mediaIndex]; 593 segment = this.playlists.media().segments[this.mediaIndex];
589 if (!segment) { 594 if (!segment) {
......
...@@ -976,6 +976,35 @@ test('only appends one segment at a time', function() { ...@@ -976,6 +976,35 @@ test('only appends one segment at a time', function() {
976 equal(appends, 0, 'did not append while updating'); 976 equal(appends, 0, 'did not append while updating');
977 }); 977 });
978 978
979 test('waits to download new segments until the media playlist is stable', function() {
980 var media;
981 player.src({
982 src: 'manifest/master.m3u8',
983 type: 'application/vnd.apple.mpegurl'
984 });
985 openMediaSource(player);
986 standardXHRResponse(requests.shift()); // master
987 player.hls.bandwidth = 1; // make sure we stay on the lowest variant
988 standardXHRResponse(requests.shift()); // media
989
990 // mock a playlist switch
991 media = player.hls.playlists.media();
992 player.hls.playlists.media = function() {
993 return media;
994 };
995 player.hls.playlists.state = 'SWITCHING_MEDIA';
996
997 standardXHRResponse(requests.shift()); // segment 0
998
999 equal(requests.length, 0, 'no requests outstanding');
1000 player.hls.checkBuffer_();
1001 equal(requests.length, 0, 'delays segment fetching');
1002
1003 player.hls.playlists.state = 'LOADED_METADATA';
1004 player.hls.checkBuffer_();
1005 equal(requests.length, 1, 'resumes segment fetching');
1006 });
1007
979 test('cancels outstanding XHRs when seeking', function() { 1008 test('cancels outstanding XHRs when seeking', function() {
980 player.src({ 1009 player.src({
981 src: 'manifest/media.m3u8', 1010 src: 'manifest/media.m3u8',
......