6ea1ad65 by jrivera

Guard against the xhr callback clearing segmentXr_ or pendingSegment_ when the c…

…allback is no longer valid
In XHR, aborts eventually cause timeouts which cause the callback to be issued again later. We would see that it was a timeout and clear two important state holding properties on the Hls object which could cause problems processing the current segment
1 parent bfd9b23a
...@@ -984,17 +984,25 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { ...@@ -984,17 +984,25 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) {
984 // decrease in network performance or a server issue. 984 // decrease in network performance or a server issue.
985 timeout: (segment.duration * 1.5) * 1000 985 timeout: (segment.duration * 1.5) * 1000
986 }, function(error, request) { 986 }, function(error, request) {
987 // the segment request is no longer outstanding 987 // This is a timeout of a previously aborted segment request
988 self.segmentXhr_ = null; 988 // so simply ignore it
989 if (!self.segmentXhr_ || request !== self.segmentXhr_) {
990 return;
991 }
989 992
990 // if a segment request times out, we may have better luck with another playlist 993 // if a segment request times out, we may have better luck with another playlist
991 if (request.timedout) { 994 if (request.timedout) {
995 // the segment request is no longer outstanding
996 self.segmentXhr_ = null;
992 self.bandwidth = 1; 997 self.bandwidth = 1;
993 return self.playlists.media(self.selectPlaylist()); 998 return self.playlists.media(self.selectPlaylist());
994 } 999 }
995 1000
996 // otherwise, trigger a network error 1001 // otherwise, trigger a network error
997 if (!request.aborted && error) { 1002 if (!request.aborted && error) {
1003 // the segment request is no longer outstanding
1004 self.segmentXhr_ = null;
1005
998 self.pendingSegment_ = null; 1006 self.pendingSegment_ = null;
999 return self.blacklistCurrentPlaylist_({ 1007 return self.blacklistCurrentPlaylist_({
1000 status: request.status, 1008 status: request.status,
...@@ -1005,6 +1013,8 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { ...@@ -1005,6 +1013,8 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) {
1005 1013
1006 // stop processing if the request was aborted 1014 // stop processing if the request was aborted
1007 if (!request.response) { 1015 if (!request.response) {
1016 // the segment request is no longer outstanding
1017 self.segmentXhr_ = null;
1008 return; 1018 return;
1009 } 1019 }
1010 1020
...@@ -1016,10 +1026,15 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { ...@@ -1016,10 +1026,15 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) {
1016 } else { 1026 } else {
1017 segmentInfo.bytes = new Uint8Array(request.response); 1027 segmentInfo.bytes = new Uint8Array(request.response);
1018 } 1028 }
1029
1019 self.pendingSegment_ = segmentInfo; 1030 self.pendingSegment_ = segmentInfo;
1031
1020 self.tech_.trigger('progress'); 1032 self.tech_.trigger('progress');
1021 self.drainBuffer(); 1033 self.drainBuffer();
1022 1034
1035 // the segment request is no longer outstanding
1036 self.segmentXhr_ = null;
1037
1023 // figure out what stream the next segment should be downloaded from 1038 // figure out what stream the next segment should be downloaded from
1024 // with the updated bandwidth information 1039 // with the updated bandwidth information
1025 self.playlists.media(self.selectPlaylist()); 1040 self.playlists.media(self.selectPlaylist());
......