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 24, 2017
1 parent c751509 commit aa17226
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 <ahochhaus@samegoal.com>
Chad Assareh <assareh@google.com>
Costel Madalin Grecu <madalin.grecu@adswizz.com>
Donato Borrello <donato@jwplayer.com>
Duc Pham <duc.pham@edgeware.tv>
Esteban Dosztal <edosztal@gmail.com>
Itay Kinnrot <itay.kinnrot@kaltura.com>
Jacob Trimble <modmaker@google.com>
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 @@ -45,6 +45,7 @@ shaka.dash.MpdUtils.GAP_OVERLAP_TOLERANCE_SECONDS = 1 / 15;
/**
* @typedef {{
* start: number,
* unscaledStart: number,
* end: number
* }}
*
Expand All @@ -53,6 +54,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 @@ -65,6 +68,7 @@ shaka.dash.MpdUtils.TimeRange;
* segmentDuration: ?number,
* startNumber: number,
* presentationTimeOffset: number,
* unscaledPresentationTimeOffset: number,
* timeline: Array.<shaka.dash.MpdUtils.TimeRange>
* }}
*
Expand All @@ -79,6 +83,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 @@ -270,8 +276,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 @@ -423,6 +433,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 @@ -113,6 +113,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 @@ -130,6 +131,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 @@ -173,6 +176,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 @@ -352,16 +356,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 aa17226

Please sign in to comment.