Skip to content

Commit

Permalink
Reduce max buffer length in response to buffer full errors
Browse files Browse the repository at this point in the history
Fixes #6529
  • Loading branch information
robwalch committed Jul 1, 2024
1 parent 61dd3f5 commit 7d2a971
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
2 changes: 1 addition & 1 deletion api-extractor/report/hls.js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ export class BaseStreamController extends TaskLoop implements NetworkComponentAP
// (undocumented)
protected reduceLengthAndFlushBuffer(data: ErrorData): boolean;
// (undocumented)
protected reduceMaxBufferLength(threshold: number): boolean;
protected reduceMaxBufferLength(threshold: number, fragDuration: number): boolean;
// (undocumented)
protected removeUnbufferedFrags(start?: number): void;
// (undocumented)
Expand Down
23 changes: 15 additions & 8 deletions src/controller/base-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ export default class BaseStreamController
: 0;
if (
backtracked === 1 ||
this.reduceMaxBufferLength(minForwardBufferLength)
this.reduceMaxBufferLength(minForwardBufferLength, frag.duration)
) {
fragmentTracker.removeFragment(frag);
}
Expand Down Expand Up @@ -1026,10 +1026,16 @@ export default class BaseStreamController
return Math.min(maxBufLen, config.maxMaxBufferLength);
}

protected reduceMaxBufferLength(threshold: number) {
protected reduceMaxBufferLength(threshold: number, fragDuration: number) {
const config = this.config;
const minLength = threshold || config.maxBufferLength;
const reducedLength = config.maxMaxBufferLength / 2;
const minLength = Math.max(
Math.min(threshold, config.maxBufferLength),
fragDuration,
);
const reducedLength = Math.max(
threshold - fragDuration * 3,
config.maxMaxBufferLength / 2,
);
if (reducedLength >= minLength) {
// reduce max buffer length as it might be too high. we do this to avoid loop flushing ...
config.maxMaxBufferLength = reducedLength;
Expand Down Expand Up @@ -1581,6 +1587,7 @@ export default class BaseStreamController
protected reduceLengthAndFlushBuffer(data: ErrorData): boolean {
// if in appending state
if (this.state === State.PARSING || this.state === State.PARSED) {
const frag = data.frag;
const playlistType = data.parent as PlaylistLevelType;
const bufferedInfo = this.getFwdBufferInfo(
this.mediaBuffer,
Expand All @@ -1590,7 +1597,7 @@ export default class BaseStreamController
// reduce max buf len if current position is buffered
const buffered = bufferedInfo && bufferedInfo.len > 0.5;
if (buffered) {
this.reduceMaxBufferLength(bufferedInfo.len);
this.reduceMaxBufferLength(bufferedInfo.len, frag?.duration || 10);
}
const flushBuffer = !buffered;
if (flushBuffer) {
Expand All @@ -1601,9 +1608,9 @@ export default class BaseStreamController
`Buffer full error while media.currentTime is not buffered, flush ${playlistType} buffer`,
);
}
if (data.frag) {
this.fragmentTracker.removeFragment(data.frag);
this.nextLoadPosition = data.frag.start;
if (frag) {
this.fragmentTracker.removeFragment(frag);
this.nextLoadPosition = frag.start;
}
this.resetLoadingState();
return flushBuffer;
Expand Down

0 comments on commit 7d2a971

Please sign in to comment.