Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
stevemayhew opened this issue May 1, 2023 · 1 comment
Open

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

stevemayhew opened this issue May 1, 2023 · 1 comment

Comments

@stevemayhew
Copy link

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?

@dsilhavy
Copy link

dsilhavy commented May 2, 2023

@stevemayhew Probably related to what we raised for the previous MPEG meeting: Dash-Industry-Forum/MPEG#36 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants