From 210eb2459ac056ab4077d544fc9d111eb888879c Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Mon, 19 Apr 2021 13:20:02 -0400 Subject: [PATCH] Evict unbuffered audio and main fragments from the tracker on BUFFER_FLUSHED Resolves #3770 --- src/controller/audio-stream-controller.ts | 2 +- src/controller/base-stream-controller.ts | 12 ++++++++++-- src/controller/fragment-tracker.ts | 11 +++++++++-- src/controller/stream-controller.ts | 2 +- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/controller/audio-stream-controller.ts b/src/controller/audio-stream-controller.ts index 936caf010d5..c63423e3c3b 100644 --- a/src/controller/audio-stream-controller.ts +++ b/src/controller/audio-stream-controller.ts @@ -659,7 +659,7 @@ class AudioStreamController ) { if (type === ElementaryStreamTypes.AUDIO) { const media = this.mediaBuffer ? this.mediaBuffer : this.media; - this.afterBufferFlushed(media, type); + this.afterBufferFlushed(media, type, PlaylistLevelType.AUDIO); } } diff --git a/src/controller/base-stream-controller.ts b/src/controller/base-stream-controller.ts index b2a7dce316a..1fdc62e73a6 100644 --- a/src/controller/base-stream-controller.ts +++ b/src/controller/base-stream-controller.ts @@ -1184,14 +1184,22 @@ export default class BaseStreamController } } - protected afterBufferFlushed(media: Bufferable, type: SourceBufferName) { + protected afterBufferFlushed( + media: Bufferable, + bufferType: SourceBufferName, + playlistType: PlaylistLevelType + ) { if (!media) { return; } // After successful buffer flushing, filter flushed fragments from bufferedFrags use mediaBuffered instead of media // (so that we will check against video.buffered ranges in case of alt audio track) const bufferedTimeRanges = BufferHelper.getBuffered(media); - this.fragmentTracker.detectEvictedFragments(type, bufferedTimeRanges); + this.fragmentTracker.detectEvictedFragments( + bufferType, + bufferedTimeRanges, + playlistType + ); if (this.state === State.ENDED) { this.resetLoadingState(); } diff --git a/src/controller/fragment-tracker.ts b/src/controller/fragment-tracker.ts index 3957cd6ae55..1ed47bed90a 100644 --- a/src/controller/fragment-tracker.ts +++ b/src/controller/fragment-tracker.ts @@ -136,12 +136,19 @@ export class FragmentTracker implements ComponentAPI { */ public detectEvictedFragments( elementaryStream: SourceBufferName, - timeRange: TimeRanges + timeRange: TimeRanges, + playlistType?: PlaylistLevelType ) { // Check if any flagged fragments have been unloaded Object.keys(this.fragments).forEach((key) => { const fragmentEntity = this.fragments[key]; - if (!fragmentEntity || !fragmentEntity.buffered) { + if (!fragmentEntity) { + return; + } + if (!fragmentEntity.buffered) { + if (fragmentEntity.body.type === playlistType) { + this.removeFragment(fragmentEntity.body); + } return; } const esData = fragmentEntity.range[elementaryStream]; diff --git a/src/controller/stream-controller.ts b/src/controller/stream-controller.ts index b0543fa4262..2cf0b6db48c 100644 --- a/src/controller/stream-controller.ts +++ b/src/controller/stream-controller.ts @@ -938,7 +938,7 @@ export default class StreamController (type === ElementaryStreamTypes.VIDEO ? this.videoBuffer : this.mediaBuffer) || this.media; - this.afterBufferFlushed(media, type); + this.afterBufferFlushed(media, type, PlaylistLevelType.MAIN); } }