Skip to content

Commit

Permalink
Align live playlist updates to end of last when there is no media-seq…
Browse files Browse the repository at this point in the history
…uence/disconitinuity overlap and no PDT

Resolves #6685
(duplicate of #5282)
  • Loading branch information
robwalch committed Sep 11, 2024
1 parent 7e7cf60 commit c998dbb
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/utils/discontinuities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function alignStream(
// Try to align on sn so that we pick a better start fragment.
// Do not perform this on playlists with delta updates as this is only to align levels on switch
// and adjustSliding only adjusts fragments after skippedSegments.
adjustSliding(switchDetails, details);
adjustSliding(switchDetails, details, false);
}
}

Expand Down
18 changes: 16 additions & 2 deletions src/utils/level-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,28 @@ export function mapFragmentIntersection(
export function adjustSliding(
oldDetails: LevelDetails,
newDetails: LevelDetails,
matchingStableVariantOrRendition: boolean = true,
): void {
const delta =
newDetails.startSN + newDetails.skippedSegments - oldDetails.startSN;
const oldFragments = oldDetails.fragments;
if (delta < 0 || delta >= oldFragments.length) {
if (delta < 0) {
return;
}
addSliding(newDetails, oldFragments[delta].start);
let sliding = 0;
if (delta < oldFragments.length) {
sliding = oldFragments[delta].start;
} else if (matchingStableVariantOrRendition) {
// align new start with old end (updated playlist start sequence is past end sequence of last update)
sliding = oldDetails.edge;
} else if (newDetails.fragments[0].start === 0) {
// align new start with old (playlist switch has a sequence with no overlap and should not be used for alignment)
sliding = oldDetails.fragments[0].start;
} else {
// new details already has a sliding offset
return;
}
addSliding(newDetails, sliding);
}

export function addSliding(details: LevelDetails, start: number) {
Expand Down
12 changes: 6 additions & 6 deletions tests/unit/controller/level-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,20 @@ describe('LevelHelper Tests', function () {
expect(actual).to.deep.equal([10, 15, 20]);
});

it('does not apply sliding if no common segments exist', function () {
it('applies minimal sliding when no common segments exist', function () {
const oldPlaylist = generatePlaylist([1, 2, 3]);
const newPlaylist = generatePlaylist([5, 6, 7]);
adjustSliding(oldPlaylist, newPlaylist);
const actual = newPlaylist.fragments.map((f) => f.start);
expect(actual).to.deep.equal([0, 5, 10]);
expect(actual).to.deep.equal([15, 20, 25]);
});

it('does not apply sliding when segments meet but do not overlap', function () {
it('applies minimal sliding when segments meet but do not overlap', function () {
const oldPlaylist = generatePlaylist([1, 2, 3]);
const newPlaylist = generatePlaylist([4, 5, 6]);
adjustSliding(oldPlaylist, newPlaylist);
const actual = newPlaylist.fragments.map((f) => f.start);
expect(actual).to.deep.equal([0, 5, 10]);
expect(actual).to.deep.equal([15, 20, 25]);
});
});

Expand All @@ -164,12 +164,12 @@ describe('LevelHelper Tests', function () {
expect(actual).to.deep.equal([5, 10, 15, 20]);
});

it('does not change start times when there is no segment overlap', function () {
it('applies minimal sliding when there is no segment overlap', function () {
const oldPlaylist = generatePlaylist([1, 2, 3]);
const newPlaylist = generatePlaylist([5, 6, 7]);
mergeDetails(oldPlaylist, newPlaylist);
const actual = newPlaylist.fragments.map((f) => f.start);
expect(actual).to.deep.equal([0, 5, 10]);
expect(actual).to.deep.equal([15, 20, 25]);
});

it('does not extrapolate if the new playlist starts before the old', function () {
Expand Down

0 comments on commit c998dbb

Please sign in to comment.