Skip to content

Confusion around $Time$ value to use in SegmentTemplate. #419

@stevemayhew

Description

@stevemayhew

Please give more examples and suggestions how to implement SampleTemplate/SampleTimeline that allows for clean period splits.

The ISO standard is very unclear as to the source of the value for $Time$.

5.3.9.6 Segment timeline

5.3.9.6.1 General

The SegmentTimeline element ...

The value of S@t minus @presentationTimeOffset specifies the MPD start time, in @timescale units, of the first Segment in the series.

...

5.3.9.6.2 Semantics

Table 21 — Semantics of SegmentTimeline element

Element or Attribute Name Use Description
@t O this value of this attribute minus the value of the @presentationTimeOffset specifies the MPD start time, in @timescale units, of the first Segment in the series. The MPD start time is relative to the beginning of the Period.

That second key bolded sentence probably belongs in the General section as well

Here we see ExoPlayer treats @t correct according to the table description:

DashSegmentIndex uses the SegmentBase.getSegmentTimeUs()

    @Override
    public long getTimeUs(long segmentNum) {
      return segmentBase.getSegmentTimeUs(segmentNum);
    }
    /** See {@link DashSegmentIndex#getTimeUs(long)}. */
    public final long getSegmentTimeUs(long sequenceNumber) {
      long unscaledSegmentTime;
      if (segmentTimeline != null) {
        unscaledSegmentTime =
            segmentTimeline.get((int) (sequenceNumber - startNumber)).startTime
                - presentationTimeOffset;
      } else {
        unscaledSegmentTime = (sequenceNumber - startNumber) * duration;
      }
      return Util.scaleLargeTimestamp(unscaledSegmentTime, C.MICROS_PER_SECOND, timescale);
    }

So, here @t is converted to period relative MPD time.

Then, this value is added to the Period@start:

      long firstAvailableSegmentNum =
          index.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs);
      long lastAvailableSegmentNum = firstAvailableSegmentNum + availableSegmentCount - 1;
      long adaptationSetAvailableEndTimeInManifestUs =
          periodStartTimeInManifestUs
              + index.getTimeUs(lastAvailableSegmentNum)
              + index.getDurationUs(lastAvailableSegmentNum, periodDurationUs);

Where ExoPlayer's Time In Manifest is MPD Time, or time relative to the AST.

This matches the calculation from the DASH-IOP:

Note: To transform a sample timeline position SampleTime to an MPD timeline position, use the formula

MpdTime = Period@start + (SampleTime - @presentationTimeOffset) / @timescale.

Where SampleTime is == SegmentTimeline.startTime

Here's where things get confusing, and IMO, the IOP could help clear this up. From the ISO standard

5.3.9.4.4 Template-based Segment URL construction

...

$<Identifier>% Substitution parameter Format
$Time$ This identifier is substituted with the value of the MPD start time of the Segment being accessed. For the Segment Timeline, this means that this identifier is substituted with the value of the SegmentTimeline@t attribute for the Segment being accessed. The format tag may be present.

If no format tag is present, a default format tag with width=1 shall be used.

These two sentences seem to conflict each other, is it MPD start time of the Segment? or the @t attribute (which is Sample timeline time)

This is not what ExoPlayer does:

    @Override
    public RangedUri getSegmentUrl(Representation representation, long sequenceNumber) {
      long time;
      if (segmentTimeline != null) {
        time = segmentTimeline.get((int) (sequenceNumber - startNumber)).startTime;
      } else {
        time = (sequenceNumber - startNumber) * duration;
      }
      String uriString =
          mediaTemplate.buildUri(
              representation.format.id, sequenceNumber, representation.format.bitrate, time);
      return new RangedUri(uriString, 0, C.LENGTH_UNSET);
    }

For SegmentTemplate/SegmentTimeline, startTime is simply the value of @t, so if this is SampleTime then it is not MPD time?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions