In MPEG2-TS, the data 'quantum' is the Packetised Elementary Stream (PES) packet, whose structure is described in ISO/IEC 13818-1.
The fields of interest in this application note are the PTS
and DTS
timestamps.
To support bidirectional inter-frame video coding, PES packets support both a Presentation Timestamp (PTS) and Decode Timestamp (DTS): the pts_dts_flags
field in the PES header indicates which are present in any given packet.
The ISO/IEC 13818-1 standard indicates that the system frequency shall be in the range
Both the PTS and DTS timestamps are represented by a 33-bit unsigned integer indicating a number of units of the sample time base, calculated as such:
where
An alternate way to envision this is to think of the timestamp fields storing only the lowest 33-bits of an absolute timestamp in MPEG-TS samples, e.g.:
Where
The obvious consequence of this is that the timestamp on its own can not be used to uniquely identify any given media unit: the timestamps will roll-over every ~26.5 hours.
In TAMS, we must be able to reconstruct the absolute timestamp of any given PES packet.
To facilitate this, each Flow Segment in a TAM store which carries MPEG2-TS media contains a ts_offset
field.
As stated in the above section, we can imagine that the PTS/DTS fields are simply the lower 33 bits of some absolute timestamp, so if we can carry the upper bits we can use those to generate the absolute timestamp.
This is initially done when generating the flow segments, where the absolute timestamp is known. For the earliest presentation timestamp in a segment, an 'absolute' PTS is generated, which can then be used to calculate a 'base' sample count for that segment:
Where
The .from_count
method provided in the public mediatimestamp
repository: effectively this represents
which is then processed into a sec:nanosec
timestamp.
This can be thought of as the last time the 33-bit counter 'rolled over'.
Working backwards, the absolute timestamp for any given PTS or DTS
It is possible that the counter will roll over mid-segment. As such, simply using the equations outlined above will result in incorrect timestamps. To account for this, a decoder could, for example:
TS_OFFSET = FLOW_SEG.ts_offset
FOR EACH PTS
IF (PTS < LAST_PTS) AND (LAST_PTS > 2^33-2^31) THEN
TS_OFFSET = TS_OFFSET + ((2^33-1)/90000) SECONDS
END IF
TIMESTAMP = GET_TIMESTAMP(PTS, TS_OFFSET)
LAST_PTS = PTS
END FOR