bfd9b23a by jrivera

Only update segment.end if we find a single changed end-point in buffered

We can simplify this code since we no longer try to store segment start information
We also try to be more conservative in what data we save. If the last append somehow resulted in more than one change we can't be sure which end-point is the one that belongs to the segment so save nothing.
1 parent dc9c10aa
...@@ -242,11 +242,11 @@ videojs.HlsHandler.prototype.handleSourceOpen = function() { ...@@ -242,11 +242,11 @@ videojs.HlsHandler.prototype.handleSourceOpen = function() {
242 } 242 }
243 }; 243 };
244 244
245 // Returns the array of time range edge objects that were additively 245 // Search for any end-points in `update` that do not also exist
246 // modified between two TimeRanges. 246 // in `original`.
247 videojs.Hls.bufferedAdditions_ = function(original, update) { 247 // If we found only one such uncommon end-point return it.
248 var result = [], edges = [], 248 videojs.Hls.findSoleUncommonTimeRangesEnd_ = function(original, update) {
249 i, inOriginalRanges; 249 var result = [], originalEnds = [];
250 250
251 // if original or update are falsey, return an empty list of 251 // if original or update are falsey, return an empty list of
252 // additions 252 // additions
...@@ -254,49 +254,25 @@ videojs.Hls.bufferedAdditions_ = function(original, update) { ...@@ -254,49 +254,25 @@ videojs.Hls.bufferedAdditions_ = function(original, update) {
254 return result; 254 return result;
255 } 255 }
256 256
257 // create a sorted array of time range start and end times 257 // Save all the end-points in the `original` TimeRanges object
258 for (i = 0; i < original.length; i++) { 258 for (i = 0; i < original.length; i++) {
259 edges.push({ original: true, start: original.start(i) }); 259 originalEnds.push(original.end(i));
260 edges.push({ original: true, end: original.end(i) });
261 } 260 }
262 for (i = 0; i < update.length; i++) {
263 edges.push({ start: update.start(i) });
264 edges.push({ end: update.end(i) });
265 }
266 edges.sort(function(left, right) {
267 var leftTime, rightTime;
268 leftTime = left.start !== undefined ? left.start : left.end;
269 rightTime = right.start !== undefined ? right.start : right.end;
270 261
271 // when two times are equal, ensure the original edge covers the 262 // Save any end-points in `update` that are not in the `original`
272 // update 263 // TimeRanges object
273 if (leftTime === rightTime) { 264 for (i = 0; i < update.length; i++) {
274 if (left.original) { 265 if (originalEnds.indexOf(update.end(i)) === -1) {
275 return left.start !== undefined ? -1 : 1; 266 result.push(update.end(i));
276 } 267 }
277 return right.start !== undefined ? -1 : 1;
278 } 268 }
279 return leftTime - rightTime;
280 });
281 269
282 // filter out all time range edges that occur during a period that 270 // Return null if didn't find exactly one differing end-point
283 // was already covered by `original` 271 if (result.length !== 1) {
284 inOriginalRanges = false; 272 return null;
285 for (i = 0; i < edges.length; i++) { 273 } else {
286 // if this is a transition point for `original`, track whether 274 return result[0];
287 // subsequent edges are additions
288 if (edges[i].original) {
289 inOriginalRanges = edges[i].start !== undefined;
290 continue;
291 }
292 // if we're in a time range that was in `original`, ignore this edge
293 if (inOriginalRanges) {
294 continue;
295 }
296 // this edge occurred outside the range of `original`
297 result.push(edges[i]);
298 } 275 }
299 return result;
300 }; 276 };
301 277
302 var parseCodecs = function(codecs) { 278 var parseCodecs = function(codecs) {
...@@ -1170,12 +1146,12 @@ videojs.HlsHandler.prototype.updateEndHandler_ = function () { ...@@ -1170,12 +1146,12 @@ videojs.HlsHandler.prototype.updateEndHandler_ = function () {
1170 currentMediaIndex, 1146 currentMediaIndex,
1171 currentBuffered, 1147 currentBuffered,
1172 seekable, 1148 seekable,
1173 timelineUpdates; 1149 timelineUpdate;
1174 1150
1175 this.pendingSegment_ = null;
1176 1151
1177 // stop here if the update errored or was aborted 1152 // stop here if the update errored or was aborted
1178 if (!segmentInfo) { 1153 if (!segmentInfo) {
1154 this.pendingSegment_ = null;
1179 return; 1155 return;
1180 } 1156 }
1181 1157
...@@ -1187,6 +1163,7 @@ videojs.HlsHandler.prototype.updateEndHandler_ = function () { ...@@ -1187,6 +1163,7 @@ videojs.HlsHandler.prototype.updateEndHandler_ = function () {
1187 // if we switched renditions don't try to add segment timeline 1163 // if we switched renditions don't try to add segment timeline
1188 // information to the playlist 1164 // information to the playlist
1189 if (segmentInfo.playlist.uri !== this.playlists.media().uri) { 1165 if (segmentInfo.playlist.uri !== this.playlists.media().uri) {
1166 this.pendingSegment_ = null;
1190 return this.fillBuffer(); 1167 return this.fillBuffer();
1191 } 1168 }
1192 1169
...@@ -1211,15 +1188,13 @@ videojs.HlsHandler.prototype.updateEndHandler_ = function () { ...@@ -1211,15 +1188,13 @@ videojs.HlsHandler.prototype.updateEndHandler_ = function () {
1211 } 1188 }
1212 } 1189 }
1213 1190
1214 timelineUpdates = videojs.Hls.bufferedAdditions_(segmentInfo.buffered, 1191
1192 timelineUpdate = videojs.Hls.findSoleUncommonTimeRangesEnd_(segmentInfo.buffered,
1215 this.tech_.buffered()); 1193 this.tech_.buffered());
1216 timelineUpdates.forEach(function (update) { 1194
1217 if (segment) { 1195 if (timelineUpdate && segment) {
1218 if (update.end !== undefined) { 1196 segment.end = timelineUpdate;
1219 segment.end = update.end;
1220 }
1221 } 1197 }
1222 });
1223 1198
1224 // if we've buffered to the end of the video, let the MediaSource know 1199 // if we've buffered to the end of the video, let the MediaSource know
1225 if (this.playlists.media().endList && 1200 if (this.playlists.media().endList &&
...@@ -1227,17 +1202,21 @@ videojs.HlsHandler.prototype.updateEndHandler_ = function () { ...@@ -1227,17 +1202,21 @@ videojs.HlsHandler.prototype.updateEndHandler_ = function () {
1227 segments[segments.length - 1].end <= currentBuffered.end(0) && 1202 segments[segments.length - 1].end <= currentBuffered.end(0) &&
1228 this.mediaSource.readyState === 'open') { 1203 this.mediaSource.readyState === 'open') {
1229 this.mediaSource.endOfStream(); 1204 this.mediaSource.endOfStream();
1205 this.pendingSegment_ = null;
1230 return; 1206 return;
1231 } 1207 }
1232 1208
1233 if (timelineUpdates.length || 1209 if (timelineUpdate !== null ||
1234 segmentInfo.buffered.length !== this.tech_.buffered().length) { 1210 segmentInfo.buffered.length !== this.tech_.buffered().length) {
1235 this.updateDuration(playlist); 1211 this.updateDuration(playlist);
1212 this.pendingSegment_ = null;
1236 // check if it's time to download the next segment 1213 // check if it's time to download the next segment
1237 this.fillBuffer(); 1214 this.fillBuffer();
1238 return; 1215 return;
1239 } 1216 }
1240 1217
1218 this.pendingSegment_ = null;
1219
1241 // the last segment append must have been entirely in the 1220 // the last segment append must have been entirely in the
1242 // already buffered time ranges. just buffer forward until we 1221 // already buffered time ranges. just buffer forward until we
1243 // find a segment that adds to the buffered time ranges and 1222 // find a segment that adds to the buffered time ranges and
......