Skip to content

Commit

Permalink
fix(DASH): Fix precision issue on some platforms (#6258)
Browse files Browse the repository at this point in the history
When recalculations of period end are made, it is possible that we will not be able to find last segment from period on low precision platforms. To mitigate it, try to use cached value of `periodEnd_` whenever possible.

Issue observed on Xbox One & Xbox Series.
  • Loading branch information
tykus160 authored Feb 20, 2024
1 parent 0de7af9 commit 4a0d1ca
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 14 deletions.
31 changes: 18 additions & 13 deletions lib/dash/segment_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -755,16 +755,10 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {

this.evict(this.periodStart_);

if (timeline.length === 0) {
return;
}

if (this.periodEnd_ !== Infinity) {
// Adjust the last timeline entry to match the period end
const lastTimePeriod = timeline[timeline.length - 1];
// NOTE: end should be relative to period start
lastTimePeriod.end = this.periodEnd_ - this.periodStart_;
}
// Do NOT adjust last range to match period end! With high precision
// timestamps several recalculations may give wrong results on less precise
// platforms. To mitigate that, we're using cached |periodEnd_| value in
// find/get() methods whenever possible.
}

/**
Expand All @@ -784,7 +778,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
const timeline = this.templateInfo_.timeline;

// Early exit if the time isn't within this period
if (time < this.periodStart_ || time > this.periodEnd_) {
if (time < this.periodStart_ || time >= this.periodEnd_) {
return null;
}

Expand All @@ -797,10 +791,14 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
// the references by a fraction of a second. To account for this, we use
// the start of the next segment as /end/, unless this is the last
// reference, in which case we use the period end as the /end/
let end = range.end + this.periodStart_;
let end;

if (i < lastIndex) {
end = timeline[i + 1].start + this.periodStart_;
} else if (this.periodEnd_ === Infinity) {
end = range.end + this.periodStart_;
} else {
end = this.periodEnd_;
}

if ((time >= start) && (time < end)) {
Expand Down Expand Up @@ -831,6 +829,12 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
.unscaledPresentationTimeOffset + range.unscaledStart;
const timestampOffset = this.periodStart_ -
this.templateInfo_.scaledPresentationTimeOffset;
const trueSegmentEnd = this.periodStart_ + range.end;
let segmentEnd = trueSegmentEnd;
if (correctedPosition === this.getNumReferences() - 1 &&
this.periodEnd_ !== Infinity) {
segmentEnd = this.periodEnd_;
}

const partialSegmentRefs = [];

Expand Down Expand Up @@ -901,7 +905,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {

ref = new shaka.media.SegmentReference(
this.periodStart_ + range.start,
this.periodStart_ + range.end,
segmentEnd,
createUrisCb,
/* startByte= */ 0,
/* endByte= */ null,
Expand All @@ -916,6 +920,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
shaka.media.SegmentReference.Status.AVAILABLE,
this.aesKey_,
/* allPartialSegments= */ range.partialSegments > 0);
ref.trueEndTime = trueSegmentEnd;
this.references[correctedPosition] = ref;
}

Expand Down
2 changes: 1 addition & 1 deletion test/dash/dash_parser_segment_template_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ describe('DashParser SegmentTemplate', () => {
const newTemplateInfo = makeTemplateInfo(newRanges);

const newEnd = newRanges[newRanges.length - 1].end;
index.appendTemplateInfo(newTemplateInfo, newEnd);
index.appendTemplateInfo(newTemplateInfo, /* periodStart= */ 0, newEnd);
expect(index.find(newStart)).toBe(10);
expect(index.find(newEnd - 1.0)).toBe(19);
});
Expand Down

0 comments on commit 4a0d1ca

Please sign in to comment.