From 53876edbdcfcc39e18ed061bd51c949a38ee035d Mon Sep 17 00:00:00 2001 From: davidkim9 Date: Tue, 9 Jan 2018 10:18:53 -0500 Subject: [PATCH] revert maxSeekHole refactor mediaChannels to elementaryStreams --- src/config.js | 1 + src/controller/audio-stream-controller.js | 6 +----- src/controller/stream-controller.js | 21 +++++++++++++-------- src/helper/fragment-tracker.js | 18 +++++++++--------- src/loader/fragment.js | 3 +++ tests/unit/helper/fragment-tracker.js | 10 +++++----- 6 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/config.js b/src/config.js index 754107f9a50..721dbc74226 100644 --- a/src/config.js +++ b/src/config.js @@ -31,6 +31,7 @@ export var hlsDefaultConfig = { maxBufferLength: 30, // used by stream-controller maxBufferSize: 60 * 1000 * 1000, // used by stream-controller maxBufferHole: 0.5, // used by stream-controller + maxSeekHole: 2, // used by stream-controller lowBufferWatchdogPeriod: 0.5, // used by stream-controller highBufferWatchdogPeriod: 3, // used by stream-controller nudgeOffset: 0.1, // used by stream-controller diff --git a/src/controller/audio-stream-controller.js b/src/controller/audio-stream-controller.js index 3aba05de956..a4c2141aa02 100644 --- a/src/controller/audio-stream-controller.js +++ b/src/controller/audio-stream-controller.js @@ -645,11 +645,7 @@ class AudioStreamController extends TaskLoop { data.endDTS = data.startDTS + fragCurrent.duration; } - if(!fragCurrent.mediaChannels) { - // Set is used because the elements do not repeat - fragCurrent.mediaChannels = new Set(); - } - fragCurrent.mediaChannels.add(data.type); + fragCurrent.elementaryStreams.add(data.type); logger.log(`parsed ${data.type},PTS:[${data.startPTS.toFixed(3)},${data.endPTS.toFixed(3)}],DTS:[${data.startDTS.toFixed(3)}/${data.endDTS.toFixed(3)}],nb:${data.nb}`); LevelHelper.updateFragPTSDTS(track.details,fragCurrent,data.startPTS,data.endPTS); diff --git a/src/controller/stream-controller.js b/src/controller/stream-controller.js index 407309e8bc3..b101dafc9af 100644 --- a/src/controller/stream-controller.js +++ b/src/controller/stream-controller.js @@ -1085,11 +1085,7 @@ class StreamController extends TaskLoop { data.endDTS = data.startDTS + fragCurrent.duration; } - if(!frag.mediaChannels) { - // Set is used because the elements do not repeat - frag.mediaChannels = new Set(); - } - frag.mediaChannels.add(data.type); + frag.elementaryStreams.add(data.type); logger.log(`Parsed ${data.type},PTS:[${data.startPTS.toFixed(3)},${data.endPTS.toFixed(3)}],DTS:[${data.startDTS.toFixed(3)}/${data.endDTS.toFixed(3)}],nb:${data.nb},dropped:${data.dropped || 0}`); @@ -1365,10 +1361,19 @@ _checkBuffer() { this.loadedmetadata = true; // only adjust currentTime if different from startPosition or if startPosition not buffered // at that stage, there should be only one buffered range, as we reach that code after first fragment has been buffered - let startPosition = media.seeking ? currentTime : this.startPosition; - // if currentTime not matching with expected startPosition - if (currentTime !== startPosition) { + let startPosition = media.seeking ? currentTime : this.startPosition, + startPositionBuffered = BufferHelper.isBuffered(mediaBuffer,startPosition), + firstbufferedPosition = buffered.start(0), + startNotBufferedButClose = !startPositionBuffered && (Math.abs(startPosition-firstbufferedPosition) < config.maxSeekHole); + // if currentTime not matching with expected startPosition or startPosition not buffered but close to first buffered + if (currentTime !== startPosition || startNotBufferedButClose) { logger.log(`target start position:${startPosition}`); + + // if startPosition not buffered, let's seek to buffered.start(0) + if(startNotBufferedButClose) { + startPosition = firstbufferedPosition; + logger.log(`target start position not buffered, seek to buffered.start(0) ${startPosition}`); + } logger.log(`adjust currentTime from ${currentTime} to ${startPosition}`); media.currentTime = startPosition; } diff --git a/src/helper/fragment-tracker.js b/src/helper/fragment-tracker.js index 48bb2113cbc..8a4ae7673e1 100644 --- a/src/helper/fragment-tracker.js +++ b/src/helper/fragment-tracker.js @@ -37,15 +37,15 @@ export class FragmentTracker extends EventHandler { * Partial fragments effected by coded frame eviction will be removed * The browser will unload parts of the buffer to free up memory for new buffer data * Fragments will need to be reloaded when the buffer is freed up, removing partial fragments will allow them to reload(since there might be parts that are still playable) - * @param {String} channel The channel of media this is (eg. video/audio) + * @param {String} elementaryStream The elementaryStream of media this is (eg. video/audio) * @param {Object} timeRange TimeRange object from a sourceBuffer */ - detectEvictedFragments(channel, timeRange) { + detectEvictedFragments(elementaryStream, timeRange) { let fragmentTimes, time; // Check if any flagged fragments have been unloaded for (let fragmentEntity of this.fragments.values()) { if(fragmentEntity.buffered === true) { - fragmentTimes = fragmentEntity.range[channel].time; + fragmentTimes = fragmentEntity.range[elementaryStream].time; for (let i = 0; i < fragmentTimes.length; i++) { time = fragmentTimes[i]; @@ -68,11 +68,11 @@ export class FragmentTracker extends EventHandler { let fragKey = this.getFragmentKey(fragment); let fragmentEntity = this.fragments.get(fragKey); fragmentEntity.buffered = true; - for (let [channel, timeRange] of this.timeRanges) { - if(fragment.mediaChannels.has(channel) === true) { + for (let [elementaryStream, timeRange] of this.timeRanges) { + if(fragment.elementaryStreams.has(elementaryStream) === true) { // Check for malformed fragments - // Gaps need to be calculated for each channel - fragmentEntity.range[channel] = this.getBufferedTimes(fragment.startPTS, fragment.endPTS, timeRange); + // Gaps need to be calculated for each elementaryStream + fragmentEntity.range[elementaryStream] = this.getBufferedTimes(fragment.startPTS, fragment.endPTS, timeRange); } } } @@ -207,8 +207,8 @@ export class FragmentTracker extends EventHandler { onBufferAppended(e) { // Store the latest timeRanges loaded in the buffer this.timeRanges = e.timeRanges; - for (let [channel, timeRange] of this.timeRanges) { - this.detectEvictedFragments(channel, timeRange); + for (let [elementaryStream, timeRange] of this.timeRanges) { + this.detectEvictedFragments(elementaryStream, timeRange); } } diff --git a/src/loader/fragment.js b/src/loader/fragment.js index 1f1a08d489c..a8e7fcc3e84 100644 --- a/src/loader/fragment.js +++ b/src/loader/fragment.js @@ -10,6 +10,9 @@ export default class Fragment { this._byteRange = null; this._decryptdata = null; this.tagList = []; + + // Set is used because the elements do not repeat + this.elementaryStreams = new Set(); } get url() { diff --git a/tests/unit/helper/fragment-tracker.js b/tests/unit/helper/fragment-tracker.js index 14318326b05..eae2ddb199c 100644 --- a/tests/unit/helper/fragment-tracker.js +++ b/tests/unit/helper/fragment-tracker.js @@ -25,7 +25,7 @@ describe('FragmentTracker', () => { endPTS: 1, sn: 1, level: 1, - mediaChannels: new Set(['audio', 'video']), + elementaryStreams: new Set(['audio', 'video']), type: 'main' }; hls.trigger(Event.FRAG_LOADED, { frag: fragment }); @@ -72,7 +72,7 @@ describe('FragmentTracker', () => { endPTS: 1, sn: 1, level: 0, - mediaChannels: new Set(['audio', 'video']), + elementaryStreams: new Set(['audio', 'video']), type: 'main' }; hls.trigger(Event.FRAG_LOADED, { frag: fragment }); @@ -165,7 +165,7 @@ describe('FragmentTracker', () => { endPTS: 1, sn: 1, level: 1, - mediaChannels: new Set(['audio', 'video']), + elementaryStreams: new Set(['audio', 'video']), type: 'main' }; hls.trigger(Event.FRAG_LOADED, { frag: fragment }); @@ -196,7 +196,7 @@ describe('FragmentTracker', () => { endPTS: 1, sn: 1, level: 1, - mediaChannels: new Set(['audio', 'video']), + elementaryStreams: new Set(['audio', 'video']), type: 'main' }; hls.trigger(Event.FRAG_LOADED, { frag: fragment }); @@ -227,7 +227,7 @@ describe('FragmentTracker', () => { endPTS: 1, sn: 1, level: 1, - mediaChannels: new Set(['audio']), + elementaryStreams: new Set(['audio']), type: 'audio' }; hls.trigger(Event.FRAG_LOADED, { frag: fragment });