Skip to content

Commit

Permalink
Use strict tolerance when picking fragments when paused and seeking b…
Browse files Browse the repository at this point in the history
…ackward

Resolves #6511 #6331 #4905
Closes #4884
  • Loading branch information
robwalch committed Jun 28, 2024
1 parent 7d9ee80 commit 268edac
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
2 changes: 0 additions & 2 deletions api-extractor/report/hls.js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,6 @@ export class BaseStreamController extends TaskLoop implements NetworkComponentAP
// (undocumented)
protected getFwdBufferInfo(bufferable: Bufferable | null, type: PlaylistLevelType): BufferInfo | null;
// (undocumented)
protected getFwdBufferInfoAtPos(bufferable: Bufferable | null, pos: number, type: PlaylistLevelType): BufferInfo | null;
// (undocumented)
protected getInitialLiveFragment(levelDetails: LevelDetails, fragments: MediaFragment[]): MediaFragment | null;
// (undocumented)
protected getLevelDetails(): LevelDetails | undefined;
Expand Down
26 changes: 19 additions & 7 deletions src/controller/base-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,12 @@ export default class BaseStreamController
true,
);

this.lastCurrentTime = currentTime;
// Don't set lastCurrentTime with backward seeks (allows for frag selection with strict tolerances)
const lastCurrentTime = this.lastCurrentTime;
if (currentTime > lastCurrentTime) {
this.lastCurrentTime = currentTime;
}

if (!this.loadingParts) {
const bufferEnd = Math.max(bufferInfo.end, currentTime);
const shouldLoadParts = this.shouldLoadParts(
Expand Down Expand Up @@ -1109,17 +1114,18 @@ export default class BaseStreamController
if (!Number.isFinite(pos)) {
return null;
}
return this.getFwdBufferInfoAtPos(bufferable, pos, type);
const backwardSeek = this.lastCurrentTime > pos;
const maxBufferHole =
backwardSeek || this.media?.paused ? 0 : this.config.maxBufferHole;
return this.getFwdBufferInfoAtPos(bufferable, pos, type, maxBufferHole);
}

protected getFwdBufferInfoAtPos(
private getFwdBufferInfoAtPos(
bufferable: Bufferable | null,
pos: number,
type: PlaylistLevelType,
maxBufferHole: number,
): BufferInfo | null {
const {
config: { maxBufferHole },
} = this;
const bufferInfo = BufferHelper.bufferInfo(bufferable, pos, maxBufferHole);
// Workaround flaw in getting forward buffer when maxBufferHole is smaller than gap at current pos
if (bufferInfo.len === 0 && bufferInfo.nextStart !== undefined) {
Expand Down Expand Up @@ -1264,6 +1270,7 @@ export default class BaseStreamController
this.mediaBuffer ? this.mediaBuffer : this.media,
bufferInfo.nextStart,
playlistType,
0,
);
if (
nextbufferInfo !== null &&
Expand Down Expand Up @@ -1425,8 +1432,13 @@ export default class BaseStreamController

let frag: MediaFragment | null;
if (bufferEnd < end) {
const backwardSeek = bufferEnd < this.lastCurrentTime;
const lookupTolerance =
bufferEnd > end - maxFragLookUpTolerance ? 0 : maxFragLookUpTolerance;
backwardSeek ||
bufferEnd > end - maxFragLookUpTolerance ||
this.media?.paused
? 0
: maxFragLookUpTolerance;
// Remove the tolerance if it would put the bufferEnd past the actual end of stream
// Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE)
frag = findFragmentByPTS(
Expand Down

0 comments on commit 268edac

Please sign in to comment.