Skip to content

Commit

Permalink
Improvement of segment timeline $Time$ accuracy (#706)
Browse files Browse the repository at this point in the history
Fix incorrect timeReplacement when large timescale

The current code essentially does this

    timeReplacement =
	(startTime / timescale + presentationTimeOffset) * timescale

When timescale is large enough (e.g. 10 MHz in order to support MS
Smooth Streaming as well), "startTime / timescale * timescale" may not
always be exactly "startTime" because of floating point precision,
which could produce incorrect segment URLs.

Keep startTime and presentationTimeOffset unchanged in the timeline
just to avoid the multiply/divide dance.

Closes #690
  • Loading branch information
tobbee authored and TheModMaker committed Feb 22, 2017
1 parent cc3e345 commit 547a88c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Andy Hochhaus <[email protected]>
Chad Assareh <[email protected]>
Costel Madalin Grecu <[email protected]>
Donato Borrello <[email protected]>
Duc Pham <[email protected]>
Esteban Dosztal <[email protected]>
Itay Kinnrot <[email protected]>
Jacob Trimble <[email protected]>
Expand Down
15 changes: 13 additions & 2 deletions lib/dash/mpd_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ shaka.dash.MpdUtils.GAP_OVERLAP_TOLERANCE_SECONDS = 1 / 15;
/**
* @typedef {{
* start: number,
* unscaledStart: number,
* end: number
* }}
*
Expand All @@ -52,6 +53,8 @@ shaka.dash.MpdUtils.GAP_OVERLAP_TOLERANCE_SECONDS = 1 / 15;
*
* @property {number} start
* The start time of the range.
* @property {number} unscaledStart
* The start time of the range in representation timescale units.
* @property {number} end
* The end time (exclusive) of the range.
*/
Expand All @@ -64,6 +67,7 @@ shaka.dash.MpdUtils.TimeRange;
* segmentDuration: ?number,
* startNumber: number,
* presentationTimeOffset: number,
* unscaledPresentationTimeOffset: number,
* timeline: Array.<shaka.dash.MpdUtils.TimeRange>
* }}
*
Expand All @@ -78,6 +82,8 @@ shaka.dash.MpdUtils.TimeRange;
* The start number of the segments; 1 or greater.
* @property {number} presentationTimeOffset
* The presentationTimeOffset of the representation, in seconds.
* @property {number} unscaledPresentationTimeOffset
* The presentationTimeOffset of the representation, in timescale units.
* @property {Array.<shaka.dash.MpdUtils.TimeRange>} timeline
* The timeline of the representation, if given. Times in seconds.
*/
Expand Down Expand Up @@ -269,8 +275,12 @@ shaka.dash.MpdUtils.createTimeline = function(

for (var j = 0; j <= repeat; ++j) {
var endTime = startTime + d;
timeline.push(
{start: (startTime / timescale), end: (endTime / timescale)});
var item = {
start: startTime / timescale,
end: endTime / timescale,
unscaledStart: startTime
};
timeline.push(item);

startTime = endTime;
lastEndTime = endTime;
Expand Down Expand Up @@ -398,6 +408,7 @@ shaka.dash.MpdUtils.parseSegmentInfo = function(context, callback) {
segmentDuration: segmentDuration,
startNumber: startNumber,
presentationTimeOffset: pto,
unscaledPresentationTimeOffset: Number(presentationTimeOffset),
timeline: timeline
};
};
Expand Down
10 changes: 7 additions & 3 deletions lib/dash/segment_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ shaka.dash.SegmentTemplate.createStream = function(
* segmentDuration: ?number,
* startNumber: number,
* presentationTimeOffset: number,
* unscaledPresentationTimeOffset: number,
* timeline: Array.<shaka.dash.MpdUtils.TimeRange>,
* mediaTemplate: ?string,
* indexTemplate: ?string
Expand All @@ -131,6 +132,8 @@ shaka.dash.SegmentTemplate.createStream = function(
* The start number of the segments; 1 or greater.
* @property {number} presentationTimeOffset
* The presentationTimeOffset of the representation, in seconds.
* @property {number} unscaledPresentationTimeOffset
* The presentationTimeOffset of the representation, in timescale units.
* @property {Array.<shaka.dash.MpdUtils.TimeRange>} timeline
* The timeline of the representation, if given. Times in seconds.
* @property {?string} mediaTemplate
Expand Down Expand Up @@ -174,6 +177,7 @@ shaka.dash.SegmentTemplate.parseSegmentTemplateInfo_ = function(context) {
timescale: segmentInfo.timescale,
startNumber: segmentInfo.startNumber,
presentationTimeOffset: segmentInfo.presentationTimeOffset,
unscaledPresentationTimeOffset: segmentInfo.unscaledPresentationTimeOffset,
timeline: segmentInfo.timeline,
mediaTemplate: media,
indexTemplate: index
Expand Down Expand Up @@ -357,16 +361,16 @@ shaka.dash.SegmentTemplate.createFromTimeline_ = function(context, info) {
var references = [];
for (var i = 0; i < info.timeline.length; i++) {
var start = info.timeline[i].start;
var unscaledStart = info.timeline[i].unscaledStart;
var end = info.timeline[i].end;

// Note: i = k - 1, where k indicates the k'th segment listed in the MPD.
// (See section 5.3.9.5.3 of the DASH spec.)
var segmentReplacement = i + info.startNumber;

// Consider the presentation time offset in segment uri computation
var timeReplacement = (start + info.presentationTimeOffset) *
info.timescale;

var timeReplacement = unscaledStart +
info.unscaledPresentationTimeOffset;
var createUris = (function(
template, repId, bandwidth, baseUris, segmentId, time) {
var mediaUri = MpdUtils.fillUriTemplate(
Expand Down

0 comments on commit 547a88c

Please sign in to comment.