<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-ramadan-moq-mmt-00" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true">

<front>
<title abbrev="MMT for MoQ">MPEG Media Transport (MMT) Packaging for Media over QUIC</title><seriesInfo value="draft-ramadan-moq-mmt-00" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="O." surname="Ramadan" fullname="Omar Ramadan"><organization>Blockcast</organization><address><postal><street></street>
</postal><email>omar@blockcast.net</email>
</address></author><date year="2026" month="October" day="14"></date>
<area>wit</area>
<workgroup>moq</workgroup>
<keyword>MMT</keyword>
<keyword>MMTP</keyword>
<keyword>MoQ</keyword>
<keyword>ATSC 3.0</keyword>
<keyword>FEC</keyword>

<abstract>
<t>This document specifies the use of MPEG Media Transport (MMT) as a
container format for Media over QUIC (MoQ).  MMT provides a unified
framework for streaming media over heterogeneous networks including
broadcast (ATSC 3.0, ARIB STD-B60), multicast (SSM), and unicast
(QUIC/WebTransport).  This specification defines the mapping of MMT
packets to MoQ objects, interaction with Application-Layer FEC,
bidirectional conversion between S-TSID and MoQ catalogs, and
compatibility considerations for both ATSC 3.0 and ARIB STD-B60
systems.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>MPEG Media Transport (MMT) <xref target="ISO.23008-1"></xref> is a transport protocol
designed for delivery of multimedia content over heterogeneous
networks.  MMT is supported as an alternative transport in ATSC 3.0
broadcast television (Americas, South Korea) alongside the primary
ROUTE/DASH transport, and is the basis for ARIB STD-B60 (Japan).
MMT provides native support for:</t>

<ul spacing="compact">
<li>Media Processing Units (MPU, branded &quot;mpuf&quot; in ISOBMFF) as the
media container, with structural similarities to fMP4</li>
<li>Application-Layer FEC (AL-FEC) supporting multiple schemes
including RaptorQ and Reed-Solomon</li>
<li>Cross-layer signaling for adaptive streaming</li>
<li>Hybrid delivery combining broadcast and broadband</li>
</ul>
<t>This document defines how MMT-encapsulated media can be transported
over MoQ <xref target="I-D.ietf-moq-transport"></xref>, enabling:</t>

<ol spacing="compact">
<li><strong>Broadcast-to-Unicast bridging</strong>: Content from ATSC 3.0 or ARIB STD-B60
broadcasts can be relayed to MoQ subscribers without transcoding</li>
<li><strong>Unified FEC</strong>: MMT's AL-FEC integrates with MoQ FEC repair tracks
per <xref target="MOQ-FEC"></xref></li>
<li><strong>Multicast promotion</strong>: MoQ clients can receive SSM multicast
directly when available, per <xref target="MOQ-MULTICAST"></xref></li>
<li><strong>Bidirectional signaling</strong>: Convert between S-TSID (ATSC) and MoQ
catalogs for seamless interoperability</li>
</ol>

<section anchor="relationship-to-other-moq-media-formats"><name>Relationship to Other MoQ Media Formats</name>
<t>This specification complements existing MoQ packaging formats:</t>
<table>
<thead>
<tr>
<th>Format</th>
<th>Container</th>
<th>Primary Use Case</th>
<th>FEC Support</th>
</tr>
</thead>

<tbody>
<tr>
<td>MSF (LOC)</td>
<td>WebCodecs chunks</td>
<td>Low-latency unicast</td>
<td>No</td>
</tr>

<tr>
<td>CMSF</td>
<td>CMAF fMP4</td>
<td>Adaptive streaming</td>
<td>No</td>
</tr>

<tr>
<td>CARP</td>
<td>CMAF fMP4</td>
<td>ABR delivery</td>
<td>No</td>
</tr>

<tr>
<td>This spec (MMT)</td>
<td>MMTP + MPU (ISOBMFF)</td>
<td>Broadcast bridge</td>
<td>Yes</td>
</tr>
</tbody>
</table><t>MMT packaging is RECOMMENDED when:</t>

<ul spacing="compact">
<li>Ingesting ATSC 3.0 or ARIB STD-B60 broadcasts</li>
<li>FEC protection is required for multicast delivery</li>
<li>Hybrid broadcast/unicast architectures are deployed</li>
<li>Interoperability with broadcast receivers is needed</li>
</ul>
<t>CMAF packaging (CMSF/CARP) is RECOMMENDED when:</t>

<ul spacing="compact">
<li>Content originates as DASH/HLS</li>
<li>No multicast delivery is planned</li>
<li>Interoperability with existing CDN infrastructure is needed</li>
</ul>
</section>
</section>

<section anchor="terminology"><name>Terminology</name>
<t>The key words &quot;<bcp14>MUST</bcp14>&quot;, &quot;<bcp14>MUST NOT</bcp14>&quot;, &quot;<bcp14>REQUIRED</bcp14>&quot;, &quot;<bcp14>SHALL</bcp14>&quot;,
&quot;<bcp14>SHALL NOT</bcp14>&quot;, &quot;<bcp14>SHOULD</bcp14>&quot;, &quot;<bcp14>SHOULD NOT</bcp14>&quot;, &quot;<bcp14>RECOMMENDED</bcp14>&quot;,
&quot;<bcp14>NOT RECOMMENDED</bcp14>&quot;, &quot;<bcp14>MAY</bcp14>&quot;, and &quot;<bcp14>OPTIONAL</bcp14>&quot; in this document
are to be interpreted as described in BCP 14 <xref target="RFC2119"></xref> <xref target="RFC8174"></xref> when,
and only when, they appear in all capitals, as shown here.</t>
<t><strong>MMTP</strong>: MMT Protocol - the packet layer of MMT (ISO 23008-1 Clause 9)</t>
<t><strong>MPU</strong>: Media Processing Unit - a generic container for independently
decodable timed or non-timed data (<xref target="ISO.23008-1"></xref> Clause 3.1.14)</t>
<t><strong>MFU</strong>: Media Fragment Unit - a sample or subsample of timed media
data, or an item of non-timed media data, within an MPU
(<xref target="ISO.23008-1"></xref> Clause 9.3.1)</t>
<t><strong>AL-FEC</strong>: Application-Layer Forward Error Correction</t>
<t><strong>S-TSID</strong>: Service-based Transport Session Instance Description -
ATSC 3.0 signaling table containing transport and FEC parameters</t>
<t><strong>SLT</strong>: Service Layer Table - ATSC 3.0 bootstrap signaling</t>
<t><strong>MPT</strong>: MMT Package Table - signaling table containing MMT asset info</t>
<t><strong>PA</strong>: Package Access - the signaling message that carries the
tables a receiver needs to consume a Package, among them the MPT
(<xref target="ISO.23008-1"></xref> Clause 10.3.2)</t>
<t><strong>MPI</strong>: Media Presentation Information - signalling table carrying
the presentation information document (<xref target="ISO.23008-1"></xref> Clause 10.3.8)</t>
</section>

<section anchor="mmt-overview"><name>MMT Overview</name>
<t>MMT uses a layered architecture:</t>

<artwork><![CDATA[+---------------------------------------------+
|              Application Layer              |
+---------------------------------------------+
|  MPU (Media Processing Unit)                |
|  +---------+---------+---------+---------+  |
|  |  MFU 0  |  MFU 1  |  MFU 2  |   ...   |  |
|  | (IDR)   | (P)     | (P)     |         |  |
|  +---------+---------+---------+---------+  |
+---------------------------------------------+
|  MMTP (MMT Protocol)                        |
|  +-----------------------------------------+|
|  | MMTP Header | Payload (MPU fragment)    ||
|  | 12 bytes    | Variable                  ||
|  +-----------------------------------------+|
+---------------------------------------------+
|  Transport: UDP/IP (broadcast/multicast)    |
|             QUIC/WebTransport (unicast)     |
+---------------------------------------------+
]]></artwork>

<section anchor="mmtp-header-format"><name>MMTP Header Format</name>

<artwork><![CDATA[MMTP Header (12 bytes minimum) {
  Version (2),
  Packet Counter Flag (C) (1),
  FEC_type (FEC) (2),
  Reserved (1),
  Extension Flag (X) (1),
  RAP Flag (R) (1),
  Reserved (2),
  type (6),
  Packet ID (16),
  Timestamp (32),
  Packet Sequence Number (32),
  [Packet Counter (32)],       // Present if C=1 (never: C=0)
  [Header Extension (..)]      // Present if X=1
}
]]></artwork>
<t>The fixed fields sum to 96 bits (three 32-bit words).  Byte 0 is
version(2) | packet_counter_flag(1) | FEC_type(2) | reserved(1) |
extension_flag(1) | RAP_flag(1); byte 1 is reserved(2) |
type(6), i.e. the packet type occupies the LOW six bits of
the second byte (<xref target="ISO.23008-1"></xref> Clause 9.2).</t>
<t>Senders MUST set all reserved bits in the MMTP packet header to zero.
Receivers MUST ignore their values after validating the header; they
MUST NOT assign private semantics to reserved bits.</t>
<t>Every packet of an MMTP packet flow -- media, repair, and signaling
packets alike, on every delivery path -- MUST set the packet counter
flag C to 0, so no packet carries the Packet Counter field.
<xref target="ISO.23008-1"></xref> Clause 9.2.3 requires all packets of an MMTP flow to
share one setting of C; this profile fixes that setting at 0.  The
MMTP packet header is therefore 12 bytes unless X = 1 adds a header
extension.</t>
<t>This document profiles MMTP version 0 (<tt>V = 00</tt>) of
ISO/IEC 23008-1:2023 as amended by Amd 1:2025.  A packet whose version
is not <tt>00</tt> MUST be rejected before its <tt>type</tt> field is parsed: version
1 uses a different type-field layout and is not defined by this
profile.  The <tt>C = 0</tt> requirement above is also a conformance gate;
packets with <tt>C = 1</tt> MUST be rejected.  An <tt>X = 1</tt> header extension is
parsed according to its declared length, but this document defines no
additional version or packet-counter semantics.</t>
<t>Key fields for MoQ mapping:</t>

<ul spacing="compact">
<li><strong>Packet ID</strong>: Maps to MoQ track within namespace.  This document
reserves packet_id 0 for the MMTP signaling flow: MMTP packets of
packet type 0x02 carrying signaling messages, such as the PA message
of a multicast endpoint flow (<xref target="MOQ-MULTICAST"></xref> Section 5) and the
AL-FEC message of Section 8.3.  No MoQ track is advertised for
the signaling flow, but an mmtp source track MAY carry its AL-FEC
message as an object (Section 8).  An MMTP packet carrying media
(packet type 0x00) or a repair symbol (packet type 0x03) MUST NOT use
packet_id 0; a
track's packet_id is in the range 1..65535, and on multicast
delivery it is the <tt>packetId</tt> the endpoint advertises for the
track (<xref target="MOQ-MULTICAST"></xref> Section 4.1).  On every delivery path, a
receiver MUST NOT deliver an MMTP packet on packet_id 0 to a media
or repair decoder, including one received as the payload of an
object of a media or repair track: a receiver that processes MMTP
signaling reads it as a signaling message, and any other receiver
discards it (<xref target="MOQ-MULTICAST"></xref> Section 5 states the same rule for
every unlisted packet_id on multicast)</li>
<li><strong>Timestamp</strong>: UTC wallclock send time in NTP short format (32
bits: 16-bit seconds and 16-bit fraction, relative to the NTP
epoch), carried inside the object payload.  MoQ Transport defines
no per-object timestamp field; receivers needing the send time read
it from the preserved MMTP packet header.  Because the seconds part
is 16 bits, the value wraps every 65 536 seconds (about 18.2
hours): it identifies the send time modulo that period and MUST NOT
be interpreted as an absolute wallclock time without an out-of-band
era reference.  It is used for packet delivery and jitter
measurement and is never media time: not a DTS, PTS, duration,
media-clock epoch, or movie-fragment identifier</li>
<li><strong>Packet Sequence Number</strong>: per-<tt>packet_id</tt>, incremented by one modulo
2^32 across the flow (<xref target="ISO.23008-1"></xref> Clause 9.2.3); carried inside
the object payload for wrap-aware MMTP-layer loss/ordering detection.
It is NOT the MoQ Object ID --
Object IDs are the per-data-unit packet index within a subgroup
(Section 4.1), which resets per subgroup.</li>
<li><strong>FEC Type</strong>: 0=no AL-FEC, 1=AL-FEC source packet (exactly one
4-byte Source FEC Payload ID trails the packet, <xref target="MOQ-FEC"></xref>
Section 8.5), 2=AL-FEC repair packet for FEC payload ID mode 0,
3=AL-FEC repair packet for FEC payload ID mode 1 (not used by this
mapping) (<xref target="ISO.23008-1"></xref> Clause 9.2.3)</li>
<li><strong>RAP Flag</strong>: 1 indicates Random Access Point.  On a track that the
catalog protects with a keyframe overlay, a packet with RAP_flag 1
also carries the overlay's SS_ID in a header extension of type
0x8B01 (<xref target="MOQ-FEC"></xref> Section 8.5.1)</li>
</ul>
<t>A signaling packet (packet type 0x02, on packet_id 0) MUST carry its
messages in the signaling message mode of <xref target="ISO.23008-1"></xref>
Clause 9.3.4: its MMTP payload begins with the 2-byte payload header
of Clause 9.3.4.2:</t>

<artwork><![CDATA[Signaling Message Payload Header {
  f_i (2),                    // fragmentation indicator
  RES (4),                    // reserved, set to 0
  H (1),                      // 1: each MSG_length is 32 bits
  A (1),                      // aggregation_flag
  frag_count (8),             // fragmentation counter
}
]]></artwork>
<t>When A = 1, a MSG_length field of 16 bits, or 32 bits when H = 1,
precedes each aggregated message; when A = 0 no MSG_length field is
present.  The signaling message follows (<xref target="ISO.23008-1"></xref>
Clause 10.2), beginning with its message_id.  A packet that carries
one complete signaling message without aggregation has f_i = 00,
A = 0, and frag_count = 0, and its sender sets H = 0 (H has no
effect when A = 0), so its payload header is the two bytes 0x00 0x00
and the message_id immediately follows them.  A receiver ignores H
when A = 0 and parses the header field by field, never by matching
those two bytes.</t>
</section>
</section>

<section anchor="moq-object-mapping"><name>MoQ Object Mapping</name>

<section anchor="track-structure"><name>Track Structure</name>
<t>An MMT stream maps to MoQ tracks as follows:</t>
<table>
<thead>
<tr>
<th>MMT Component</th>
<th>MoQ Mapping</th>
</tr>
</thead>

<tbody>
<tr>
<td>Package</td>
<td>Namespace</td>
</tr>

<tr>
<td>Asset, by Packet ID (video)</td>
<td>Track &quot;video&quot;</td>
</tr>

<tr>
<td>Asset, by Packet ID (audio)</td>
<td>Track &quot;audio&quot;</td>
</tr>

<tr>
<td>MPU (one MPU per group)</td>
<td>Group; number derived from media time (Section 4.4.1)</td>
</tr>

<tr>
<td>MPU data unit (FT=0, FT=1, or FT=2)</td>
<td>Subgroup ID</td>
</tr>

<tr>
<td>MMTP packet (fragment) within a data unit</td>
<td>Object ID</td>
</tr>

<tr>
<td>AL-FEC signaling message (OPTIONAL, packet_id 0)</td>
<td>Object in Subgroup 0 immediately before FT=0 (Section 8)</td>
</tr>

<tr>
<td>AL-FEC repair</td>
<td>Track &quot;video/repair&quot;</td>
</tr>
</tbody>
</table></section>

<section anchor="object-payload"><name>Object Payload</name>
<t>Each MoQ object carries one complete MMTP packet:</t>

<artwork><![CDATA[MoQ Object Payload {
  MMTP Packet Header (12+ bytes),
  MMTP Payload (MPU-mode payload header,
                then an FT=0, FT=1, or FT=2 data-unit fragment),
  [Source FEC Payload ID (32)],   // trails FEC Type=1 packets
}
]]></artwork>
<t>The object payload begins at byte zero of the preserved MMTP packet
header.  It has no MoQ-private envelope, length prefix, harness prefix,
or other undocumented bytes before that header.  For an FEC Type 1
packet, the Source FEC Payload ID and any profile-defined MMTP header
extensions remain in their specified wire locations.  No object-layer
prefix, suffix, or private replacement for those fields is permitted.
When <xref target="MOQ-FEC"></xref> requires the FEC Source Info Object Property (type
<tt>0x11</tt>), its value remains the four-byte, network-byte-order <tt>SS_ID</tt>
defined by that document; the property is object metadata and is not
inserted into this payload.</t>
<t>The one exception is the OPTIONAL AL-FEC signaling object of
Section 8: its payload is a complete MMTP signaling packet (packet
type 0x02) on packet_id 0 with FEC Type 0.  Its MMTP payload is the
signaling message payload header of Section 3.1 followed by one
complete AL-FEC message (f_i = 00, A = 0), rather than an MPU-mode
payload header and data-unit fragment, and it carries no Source FEC
Payload ID.  No other object on an mmtp source track uses packet
type 0x02 or packet_id 0.</t>
<t>Throughout this document, &quot;MMTP packet&quot; means the header-included
wire unit and &quot;MMTP payload&quot; means the bytes that follow the packet
header, per <xref target="ISO.23008-1"></xref>.  Both MMTP header layers are always
preserved: the packet header carries the FEC Type, RAP Flag, and
timestamp, and the MPU-mode payload header (the first bytes of the
MMTP payload) carries the Fragmentation Indicator and MPU sequence
number that receivers and the FEC layer depend on.  A publisher that
wishes to deliver raw ISOBMFF fragments without MMTP encapsulation
publishes the track with CMAF packaging <xref target="I-D.ietf-moq-cmsf"></xref>
instead.  In this profile an MPU can contain one or more ISOBMFF movie
fragments: FT=1 carries one movie fragment's metadata and each FT=2
data unit carries one whole sample or one producer-authored subsample
of a sample (Section 5.2.1).</t>
</section>

<section anchor="group-boundaries"><name>Group Boundaries</name>
<t>This section defines the object layout of mfu mode
(<tt>mmtpMode: &quot;mfu&quot;</tt>, Section 12.1).</t>
<t>Group boundaries align with MPU boundaries, and subgroup boundaries
align with MPU data-unit boundaries:</t>

<ul spacing="compact">
<li>Each group contains all objects of exactly one MPU: a change of MPU
sequence number starts a new group, numbered per Section 4.4.1.</li>
<li>Subgroup 0 of each group carries exactly one complete FT=0 MPU
metadata packet.  Its data unit contains the authored initialization
boxes, including <tt>ftyp</tt>, <tt>mmpu</tt>, and <tt>moov</tt>, and uses FI=0.  When the
publisher carries the OPTIONAL AL-FEC signaling object of Section 8,
that object is in Subgroup 0 of the same group and is the object
immediately before the FT=0 object; Subgroup 0 then carries exactly
these two objects.  No other object precedes FT=0, and a group
carries at most one signaling object.</li>
<li>Subgroups 1..M each carry exactly one subsequent MPU data unit in
authored order.  An FT=1 movie-fragment-metadata data unit is one
complete FI=0 object.  An FT=2 timed sample is either one FI=0 object
or an FI=1, zero-or-more FI=2, FI=3 object chain.  A timed sample
whose media exceeds one data unit's capacity is carried as a
contiguous run of producer-authored subsample data units
(Section 5.2.1), one subgroup per subsample data unit, in ascending
<tt>offset</tt> order.  Section 5.2 defines the only permitted
fragmentation state machine.</li>
<li>A timed MPU MUST publish its single FT=0 metadata data unit before
any FT=1 or FT=2 data unit; only the OPTIONAL signaling object of
Section 8 may precede FT=0.  It then MUST publish each FT=1
data unit before every FT=2 sample or subsample that references that movie
fragment.  If an MPU contains multiple movie fragments, the sequence
repeats as FT=1 followed by its FT=2 samples.  A receiver MUST
validate and process subgroups in ascending Subgroup ID, not network
arrival order, and MUST NOT admit an FT=2 sample before its FT=1
metadata: concurrently delivered subgroups MAY arrive in any order
and are buffered until their turn.  A missing or duplicate FT=0 invalidates the group; a gap,
duplicate data-unit identity, or invalid FT=1/FT=2 sequence in that
logical order invalidates the affected movie fragment.  A receiver
MUST NOT infer the missing structure.  The signaling object is not a
data unit: its presence or absence does not affect this validation,
and a signaling object anywhere other than immediately before FT=0
in Subgroup 0, or a second one in a group, invalidates the group.</li>
<li>The FI=0 or FI=1 object that begins the first FT=2 sample of each
timed group -- for a subsample-partitioned sample, the object that
begins its offset-0 data unit -- MUST have RAP Flag = 1.</li>
</ul>
<t>The MPU sequence number remains present in-band (in the MMTP payload
header of every MPU fragment) and delimits which packets belong to the
same group, but it is NOT the MoQ Group number.  Publishers MUST NOT
copy the MPU sequence number into the Group number, and subscribers
MUST NOT derive media time or switching decisions from it.  (The MPU
sequence number is a per-Asset counter.  It starts at zero for the first
MPU in an Asset and increments by one for every following MPU
(<xref target="ISO.23008-1"></xref> Clause 7.3.3), but it is
Asset-local: independently packetized renditions need not assign the
same MPU number to the same media instant.  Counter-based group
numbering therefore cannot satisfy the switching-set alignment
requirements of Section 4.4.)</t>
<t>For an ISOBMFF source, the publisher MUST preserve initialization in
FT=0, MUST copy the authored <tt>moof</tt> and the original <tt>mdat</tt> prefix
through the byte before the first media sample byte-for-byte into FT=1,
and MUST copy the referenced sample bytes byte-for-byte and without
transformation into FT=2.  A receiver can therefore reconstruct the
authored movie fragment without synthesizing box fields, sample timing,
or media bytes (Section 5.1).</t>
<t>Mapping each data unit to its own subgroup makes a complete metadata
unit or sample the unit of in-order delivery, loss, and FEC.  Relays MAY
deliver subgroups concurrently.  Under unrecoverable congestion a relay
MAY drop a subgroup;
the resulting gap invalidates the affected movie fragment rather than
authorizing inferred metadata, timing, or cadence.</t>
</section>

<section anchor="switching-sets"><name>Switching Sets</name>
<t>When multiple tracks represent alternative renditions of the same
media (e.g., an ABR ladder), they form a switching set: a set of
alternate tracks that MUST be time-aligned per
<xref target="I-D.ietf-moq-msf"></xref> Section 4.2 (the same construct that
<xref target="I-D.ietf-moq-cmsf"></xref> Section 3.2 applies to CMAF tracks).  MoQ
Group numbers MUST be media-time-aligned across all tracks of a
switching set so that subscribers can switch at group boundaries;
the switch is without discontinuity when the MPUs are closed GOPs.  On
a join or switch at a Group boundary, leading pictures (Section 4.4.1)
that reference the preceding Group are not decodable, and presentation
of the new track begins at its RAP.  If the old track's next MPU has
leading pictures, neither track has decodable pictures for their
presentation interval, and the receiver conceals that gap.</t>
<t>Switching-set membership is declared in the catalog via the
per-track field:</t>

<artwork><![CDATA[altGroup (OPTIONAL, unsigned integer)
]]></artwork>
<t>defined by <xref target="I-D.ietf-moq-msf"></xref> Section 5.2.12: an integer
identifying a group of tracks that are alternate versions of one
another.  Two tracks are members of the same switching set if and only if both
carry the <tt>altGroup</tt> field and the values are equal.  A track that
omits <tt>altGroup</tt> is a member of no switching set, and the
switching-set requirements of this section do not bind it.  A repair
track (Section 8.2) protecting a member track
carries the same <tt>altGroup</tt> value as the track it protects.</t>

<section anchor="group-number-formula"><name>Group Number Formula</name>
<t>The Group number of every mmtp-packaged track MUST be computed from
media time by the formula in this section.  This single definition is
what makes group boundaries align across the renditions of a
switching set.  FEC interleave timing is independent of this grouping;
Section 7.1 does not derive FEC block boundaries or a number of Groups
per FEC block from this formula:</t>

<artwork><![CDATA[relative_ticks = ticks - presentationAnchorTicks
group_number = floor(relative_ticks / groupDurationTicks)
]]></artwork>
<t>where:</t>

<ul spacing="compact">
<li><tt>ticks</tt> is the presentation timestamp (PTS) of the MPU's first AU in
decode order, expressed in the track's <tt>timescale</tt> (Hz, Section
4.4.2) as a signed integer.  That AU is first in the MPU payload, as
ISO/IEC 23008-1 requires, and is the MPU's RAP (Section 4.3).
Leading pictures, which follow the RAP in decode order but present
before it, do not select <tt>ticks</tt>, even when they present within the
preceding MPU's Group interval.</li>
<li><tt>groupDurationTicks</tt> is the per-track group duration expressed
in the same <tt>timescale</tt>, as a positive integer.  The catalog
signals it either directly or through an exact millisecond
conversion as specified in Section 4.4.2.</li>
<li><tt>presentationAnchorTicks</tt> is the signed timestamp in this track's
<tt>timescale</tt> that corresponds to presentation time zero.  It includes
the publisher's edit-list, encoder-priming, and composition-time
decisions, and MUST be applied before the formula.  A track that is
intended to be rendered with another audio or video track MUST signal
this field; a track that is not part of a synchronized presentation
MAY omit it and use zero as its local origin.</li>
</ul>
<t>The publisher MUST choose <tt>presentationAnchorTicks</tt> no later than the
smallest <tt>ticks</tt> value of the MPUs it admits for the track.  If an
MPU's <tt>ticks</tt> is earlier than the anchor, the publisher MUST reject
that MPU.  Before the first group is published, the publisher MAY
instead revise the catalog anchor and validate the complete initial
input again; after publication, the anchor is immutable for that track
instance.  It MUST NOT clamp the Group number to zero.  The <tt>floor</tt> in
the formula is mathematical floor (floor division), not truncation
towards zero.  With the anchor requirement, every admitted MPU has a
non-negative <tt>relative_ticks</tt> value.  The requirement binds <tt>ticks</tt>
only; a leading picture of an admitted MPU can present before the
anchor.</t>
<t>Timeline origin: <tt>ticks</tt> is measured on the track's media
presentation timeline; <tt>presentationAnchorTicks</tt> maps that track to
the shared presentation timeline.  For every set of audio and video
tracks intended to be rendered together, the publisher MUST choose one
presentation origin and MUST signal an anchor for each track such that</t>

<artwork><![CDATA[presentation_time = (ticks - presentationAnchorTicks) / timescale
]]></artwork>
<t>has the same rational value for samples representing the same media
instant.  This is a media-time relation, not an NTP or wall-clock
relation, and it is not the <tt>Timestamp</tt> field of the MMTP packet header
(Section 3.1).  For
ISOBMFF-derived MPU content, the anchor is applied to the composition
timeline after edit-list and priming adjustments.  All tracks of a
switching set MUST use the same presentation origin as well.  A
publisher that resets the timeline (a timeline discontinuity) MUST
reset it identically, at the same media instant, across every affected
audio, video, and switching-set track.  A discontinuity on an existing
track does not reset its Group number sequence.</t>
<t>This Group anchor is a MoQ scheduling and switching key only.  ISO/IEC
23008-1 presentation timing remains authoritative: the presentation time
of an MPU is signaled by the presentation information (or the
<tt>mpu_timestamp_descriptor</tt> when no presentation information is present),
with any applicable <tt>elst</tt> offset, and is not rewritten by this Group
number calculation.</t>
<t>For each track, when the MPU changes, the computed Group number MUST be
strictly greater than the Group number of the preceding admitted MPU.
The publisher MUST NOT put two different MPUs in one Group, reuse a
Group number, or alter authored timestamps to satisfy this rule.  A
publisher that restarts or declares a discontinuity MUST retain the last
Group number for the existing track instance and resume with a greater
number; numeric gaps are allowed.  If it cannot do that while preserving
the formula and authored timing, it MUST close that track instance and
start a new track with a distinct (namespace, track name) pair before
emitting the reset MPU.  That new identity is the Group-number
scope for the restarted stream; it MUST NOT be presented as a
continuation of the old track.  Group-number state is transport state;
this document defines no new catalog field for it.</t>
<t>For two tracks A and B, a receiver can verify that timestamps describe
the same presentation instant without floating-point conversion:</t>

<artwork><![CDATA[(ticksA - presentationAnchorTicksA) * timescaleB ==
    (ticksB - presentationAnchorTicksB) * timescaleA
]]></artwork>
<t>The group-duration agreement rule in this section applies after the
same anchor conversion.  Consequently, equal rational values of
<tt>groupDurationTicks / timescale</tt> and correctly paired
<tt>presentationAnchorTicks</tt> values are what align 30-fps video with
audio; per-track <tt>timescale</tt> and <tt>groupDurationTicks</tt> values alone do
not establish synchronization.</t>
<t>All arithmetic is in integers: <tt>relative_ticks</tt> and <tt>groupDurationTicks</tt>
are integers, <tt>floor(relative_ticks / groupDurationTicks)</tt> is integer division,
and implementations MUST NOT compute the group number in floating
point or apply any tolerance.  An input held in another unit
(seconds, milliseconds, a different timescale) MUST be converted to
an exact integer tick count before the formula is applied; if that
conversion is not exact, the publisher's timescale or group-duration
choice is wrong (Section 4.4.2) -- implementations MUST NOT round to
compensate.</t>
<t>For ISOBMFF content, authored composition timestamps use the media
track's <tt>mdhd</tt> timescale.  If that differs from the catalog <tt>timescale</tt>,
the publisher MUST convert the adjusted composition timestamps by the
exact ratio <tt>timescale / mdhd.timescale</tt> before applying this formula.
It MUST reject a timestamp that is not an integer in the selected
catalog clock; it MUST NOT relabel media ticks as asset-clock ticks.</t>
<t>Worked example.  A switching set of two video renditions of the same
content: rendition A with <tt>timescale: 90000</tt>, rendition B with
<tt>timescale: 44100</tt>, both with <tt>presentationAnchorTicks: 0</tt> and
<tt>groupDurationMs: 2000</tt> in the catalog (Section 4.4.2).  The sample
that is 10.5 seconds into the shared presentation timeline has an
integer timestamp in both timescales:</t>

<artwork><![CDATA[A: groupDurationTicks = 2000 * 90000 / 1000 = 180000
B: groupDurationTicks = 2000 * 44100 / 1000 =  88200

Same media instant, t = 10.5 s on the shared timeline:
A: relative_ticks = 945000 -> floor(945000 / 180000) = 5
B: relative_ticks = 463050 -> floor(463050 /  88200) = 5
]]></artwork>
<t>Both renditions place the instant in group 5.  No intermediate value
is shared between the two computations -- only the integer results
agree -- which is exactly the property group-boundary switching
requires.</t>
<t>Negative authored timestamps use the same rule and are not clamped.  For
one 90 kHz track with <tt>groupDurationTicks: 180000</tt>, choose the shared
presentation anchor <tt>presentationAnchorTicks: -180000</tt>, which is earlier
than the <tt>ticks</tt> of the first admitted MPU:</t>

<artwork><![CDATA[MPU 0 ticks = -90000: relative_ticks =  90000 -> group 0
MPU 1 ticks =  90000: relative_ticks = 270000 -> group 1
]]></artwork>
<t>The negative authored PTS therefore maps to group 0 through the shared
earlier anchor.  A catalog with the same samples and
<tt>presentationAnchorTicks: 0</tt> is invalid for this profile; the publisher
rejects MPU 0 instead of mapping it to group 0.</t>
<t>With reordered samples, the first AU in decode order selects the
Group number.  This example lists the authored PTS values of the first
three AUs of two consecutive MPUs in decode order.  MPU 0 is a closed
GOP.  MPU 1 is an open GOP: its RAP presents at 180000, and its two
leading pictures present before it, inside Group 0's interval:</t>

<sourcecode type="json"><![CDATA[{
  "timescale": 90000,
  "presentationAnchorTicks": 0,
  "groupDurationTicks": 180000,
  "mpuSamplePtsInDecodeOrder": [
    [0, 6000, 3000],
    [180000, 174000, 177000]
  ],
  "ticks": [0, 180000],
  "groupNumbers": [0, 1]
}
]]></sourcecode>
<t><tt>ticks</tt> is the first entry of each MPU's list.  Selecting the minimum
presented PTS instead would give <tt>ticks</tt> 0 and 174000, both in Group 0,
which violates the strictly-greater rule above.</t>
</section>

<section anchor="catalog-signaling-of-group-duration"><name>Catalog Signaling of Group Duration</name>
<t>For a subscriber to apply the formula in Section 4.4.1, the catalog
MUST publish the group duration for every mmtp-packaged track.
The catalog publishes either the millisecond form or the exact tick
form defined here:</t>

<artwork><![CDATA[groupDurationMs (REQUIRED unless groupDurationTicks is present,
                positive unsigned integer, milliseconds)
]]></artwork>
<t>The timescale is the MSF <tt>timescale</tt> field (<xref target="I-D.ietf-moq-msf"></xref>
Section 5.2.21), resolved per the track's <tt>packaging</tt> value
(<xref target="I-D.ietf-moq-msf"></xref> Section 5.2.4; this document adds <tt>mmtp</tt>,
Section 12.1):</t>
<table>
<thead>
<tr>
<th><tt>packaging</tt></th>
<th>Timescale source</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>mmtp</tt></td>
<td>The <tt>timescale</tt> field, REQUIRED for mmtp tracks (Section 12.1); absence is a catalog error, and the 90 000 <tt>asset_timescale</tt> default of <xref target="ISO.23008-1"></xref> Clause 10.3.9.3 does not apply.</td>
</tr>

<tr>
<td><tt>cmaf</tt></td>
<td>The <tt>timescale</tt> field.  <xref target="I-D.ietf-moq-cmsf"></xref> leaves it OPTIONAL, so this document makes it REQUIRED for any cmaf track to which this section applies (a member of a switching set governed by Section 4.4.1); leaving it unset on such a track is a catalog error.</td>
</tr>

<tr>
<td><tt>loc</tt></td>
<td>The <tt>timescale</tt> field; when absent, 1 000 000 -- LOC timestamps are expressed in microseconds <xref target="I-D.ietf-moq-loc"></xref>.</td>
</tr>

<tr>
<td>(absent or unrecognized <tt>packaging</tt>)</td>
<td>1 000 000 (microseconds).  This row covers track entries whose <tt>packaging</tt> value is missing or unrecognized; the convention is fixed by this document and does NOT derive from <xref target="I-D.ietf-moq-transport"></xref>.</td>
</tr>
</tbody>
</table><t>When <tt>groupDurationTicks</tt> is absent, conversion is
<tt>groupDurationTicks = groupDurationMs * timescale / 1000</tt>.  The
catalog publisher MUST choose a <tt>groupDurationMs</tt> such that the
resulting tick count is a positive integer and the conversion is exact
(i.e. <tt>(groupDurationMs * timescale) % 1000 == 0</tt>).  If this cannot be
satisfied, or if the intended cadence is not an integer number of
milliseconds, the catalog MUST publish ticks directly via the exact
tick field:</t>

<artwork><![CDATA[groupDurationTicks (OPTIONAL, positive unsigned integer)
]]></artwork>
<t>If both <tt>groupDurationMs</tt> and <tt>groupDurationTicks</tt> are present,
<tt>groupDurationTicks</tt> wins and <tt>groupDurationMs</tt> is informational; it is
not used in the conversion and need not have an exact millisecond
conversion.  Cases where the override is required include:</t>

<ul spacing="compact">
<li>An MPU group duration at a 30-per-second cadence
(<tt>1/30 s = 33.333... ms</tt>): expressing this in integer ms is
impossible.  If the track <tt>timescale</tt> is divisible by 30, publishers
set <tt>groupDurationTicks: timescale / 30</tt> directly (e.g. <tt>3000</tt> at
90 000 Hz, <tt>1500</tt> at 45 000 Hz).  A timescale not divisible by 30
cannot represent this cadence as an integer tick count and MUST be
changed or rejected for this profile; it MUST NOT be rounded.</li>
<li>Audio sample-rate timescales not divisible by 1000 Hz, such as
44 100 Hz: a 333 ms field would imply
<tt>333 x 44 100 / 1000 = 14 685.3</tt> ticks.  A publisher whose authored
cadence is the exact integral cadence of 14 685 ticks MUST publish
<tt>groupDurationTicks: 14685</tt> (about 332.993 ms); it MUST NOT claim
that this preserves an exact 333 ms duration.  A publisher that
requires exactly 333 ms MUST choose a compatible timescale or reject
that cadence.</li>
</ul>
<t>For example, this catalog uses the exact 30-per-second cadence on a
44 100 Hz track.  It omits <tt>groupDurationMs</tt> because 33.333... ms is
not an integer millisecond value:</t>

<sourcecode type="json"><![CDATA[{
  "version": "draft-01",
  "tracks": [{
    "name": "video-30fps",
    "packaging": "mmtp",
    "mmtpMode": "mfu",
    "timescale": 44100,
    "presentationAnchorTicks": 0,
    "groupDurationTicks": 1470,
    "codec": "avc1.64001f",
    "framerate": 30
  }]
}
]]></sourcecode>
<t>Switching-set agreement: every track in the same switching set MUST
publish the same effective group duration as a rational number of
seconds.  Raw <tt>groupDurationTicks</tt> values need not be equal when track
timescales differ.  For tracks A and B, subscribers validate exact
equality with integer arithmetic:</t>

<artwork><![CDATA[A.groupDurationTicks * B.timescale ==
    B.groupDurationTicks * A.timescale
]]></artwork>
<t>Subscribers SHOULD validate this at catalog load and, on disagreement,
SHOULD reject the catalog and signal a catalog-validation error to the
application.  Subscribers that proceed despite disagreement are
non-conformant for switching across the affected tracks; ABR transitions
on such tracks will produce group-boundary discontinuities.</t>
</section>

<section anchor="catalog-signaling-of-keyframe-interval"><name>Catalog Signaling of Keyframe Interval</name>
<t>The group duration above describes the cadence of MMTP media groups
(one MPU per group, Section 4.3).  It does NOT describe whether an MPU
contains additional keyframes after its required group-start random
access point.  This document defines an OPTIONAL per-track field for
the cadence of all keyframes, which the repair policy of <xref target="MOQ-FEC"></xref>
Section 11.4.1 uses to classify FEC blocks:</t>

<artwork><![CDATA[keyframeIntervalMs (OPTIONAL, unsigned integer, milliseconds)
]]></artwork>
<t><tt>keyframeIntervalMs</tt> is the interval between consecutive video
keyframes, in integer milliseconds.  It is distinct from
<tt>groupDurationMs</tt>: <tt>groupDurationMs</tt> is the duration of
one MPU/group, whereas <tt>keyframeIntervalMs</tt> describes every keyframe,
including any additional keyframes inside an MPU.  When the only
keyframes are the required group-start RAPs and group duration is
constant, the two values are equal; additional RAPs can make the
keyframe interval shorter.  The field applies to video tracks only; a
publisher that cannot determine the cadence simply omits it.</t>
<t>Its absence is not a catalog error:
subscribers MUST NOT reject a catalog solely because it is missing,
and a receiver MUST NOT substitute a locally chosen or observed
cadence for it.  When present, <tt>keyframeIntervalMs</tt> MUST be a
positive integer; a zero value is a catalog error.</t>
<t>The repair policy of <xref target="MOQ-FEC"></xref> Section 11.4.1 relies on a published
keyframe interval to exclude keyframes from part of a group, so when
the field is present it binds every keyframe of the track: the publisher MUST NOT emit a
keyframe other than at a group start or a whole number of intervals
after one.  A publisher whose encoder can place keyframes off that
cadence, for example at scene cuts, omits the field.</t>
<t>As with the group duration, the integer-millisecond form cannot
express a keyframe cadence whose tick count is non-integer on the
track's timescale.  A publisher MAY publish an exact override:</t>

<artwork><![CDATA[keyframeIntervalTicks (OPTIONAL, unsigned integer)
]]></artwork>
<t>expressed in the same timescale as <tt>groupDurationTicks</tt> (Section 4.4.2,
selected by the track's <tt>packaging</tt>).  If both
<tt>keyframeIntervalMs</tt> and <tt>keyframeIntervalTicks</tt> are present,
<tt>keyframeIntervalTicks</tt> wins.  Unlike
<tt>groupDurationTicks</tt>, this document places NO switching-set agreement
requirement on the keyframe interval: it is a per-track hint,
and tracks in a switching set MAY carry different keyframe cadences.</t>
</section>
</section>

<section anchor="init-segment-signaling"><name>Init Segment Signaling</name>
<t>Publishers signal MPU metadata inline as the complete FT=0 object in
Subgroup 0 of every group (Section 4.3), preceded in that subgroup only
by the OPTIONAL AL-FEC signaling object of Section 8.  Its data unit contains the
authored initialization boxes, including <tt>ftyp</tt>, <tt>mmpu</tt>, and <tt>moov</tt>.</t>
<t>In addition, publishers SHOULD carry decoder initialization data
directly in the catalog via the per-track field:</t>

<artwork><![CDATA[initData (OPTIONAL, string)
]]></artwork>
<t><tt>initData</tt> is the base64 encoding of an ISOBMFF initialization
segment (<tt>ftyp</tt> + <tt>moov</tt>) sufficient to initialize the decoder for
the track (including the codec configuration record, e.g. avcC or
hvcC).  The field name and carriage -- a base64 string in the
track's catalog entry -- are those of the <tt>initData</tt> field defined
by <xref target="I-D.ietf-moq-cmsf"></xref> Section 3.1 for CMAF headers; this
document applies the same field to mmtp-packaged tracks and
constrains its decoded content as below.  (The base catalog
<xref target="I-D.ietf-moq-msf"></xref> Sections 5.1.7 and 5.2.13 additionally define
an indirected <tt>initDataList</tt>/<tt>initRef</tt> mechanism; this document
does not use the indirection -- mmtp tracks carry <tt>initData</tt>
inline.)  It lets a subscriber initialize its decoder at
catalog load,
before the first FT=0 MPU metadata object arrives,
removing one delivery round trip from the join path (Section 6.1).</t>
<t><tt>initData</tt> is a join optimization, not a replacement for in-band
metadata: the per-group FT=0 MPU metadata remains
authoritative, and a receiver MUST adopt in-band metadata when it
differs from <tt>initData</tt>.  Catalog content is untrusted input; a
receiver MUST validate that decoded <tt>initData</tt> is a well-formed
<tt>ftyp</tt> + <tt>moov</tt> sequence before passing it to a decoder, and MUST
discard it otherwise.</t>
</section>

<section anchor="object-identifier-reconstruction"><name>Object Identifier Reconstruction</name>
<t>Within a subgroup, MoQ Object IDs increase monotonically, but the
increment between successive objects is not guaranteed to be one;
depending on the transport encoding an object's ID may be carried as a
delta from the previous object rather than as an explicit absolute
value.  A receiver MUST reconstruct each object's absolute Object ID by
maintaining a running value per subgroup; it MUST NOT assume successive
objects differ by a fixed nonzero step, nor that an absolute Object ID
is carried explicitly.</t>
<t>Object IDs identify preserved source objects
within a subgroup; they do not replace the MMTP packet sequence, FI
countdown, or active-data-unit association required by Sections 5.2
and 5.3.</t>
</section>
</section>

<section anchor="media-fragment-unit-mfu-mode"><name>Media Fragment Unit (MFU) Mode</name>
<t>This timed-media profile transports each authored MPU data unit without
rewriting it:</t>

<artwork><![CDATA[MFU Mode (one subgroup per MPU data unit):
  Group N:
   [SG 0 / Obj 0: [MMTP type=0x02 id=0][SH][AL-FEC msg]] (Section 8)
    SG 0 / next:  [MMTP][PH FT=0 FI=0][ftyp+mmpu+moov]
    SG 1 / Obj 0: [MMTP][PH FT=1 FI=0][moof+mdat prefix]
    SG 2 / Obj 0: [MMTP][PH FT=2 FI=0][DU][sample 1]
    SG 3 / Obj 0: [MMTP][PH FT=2 FI=0][DU][sample 2]
  ...

Fragmented FT=2 sample (Section 5.2):
  Group N, SG 2:
    Obj 0: [MMTP][PH FT=2 FI=1][DU][sample part 1]
    Obj 1: [MMTP][PH FT=2 FI=2][sample part 2]
    Obj 2: [MMTP][PH FT=2 FI=3][sample part 3]

Subsample-partitioned FT=2 sample (Section 5.2.1) -- one sample,
two producer-authored subsample data units:
  Group N:
    SG 4 / Obj 0..j: [MMTP][PH FT=2 FI=1][DU offset=0]  ... FI=3
    SG 5 / Obj 0..k: [MMTP][PH FT=2 FI=1][DU offset=L0] ... FI=3

[MMTP] = MMTP packet header (Section 3.1): 12 bytes, since C = 0,
         plus a header extension when X = 1.
[PH]   = MPU-mode payload header, which carries the Fragmentation
         Indicator (FI); the FI is NOT in the MMTP packet header.
[SH]   = signaling message payload header (Section 3.1).
[...]  = OPTIONAL signaling object.  When present it is the first
         object of SG 0 and FT=0 is the object after it; when absent,
         FT=0 is the first object of SG 0 (Obj 0).
]]></artwork>
<t>For conformance, an <tt>mmtp</tt> track in this document carries timed media
only.  ISO/IEC 23008-1 Clause 9.3.2.3 defines the Timed Flag as
indicating whether the MPU is timed or non-timed, independently of the
FT value.  Every MPU-mode packet with FT=0, FT=1, or FT=2 in this
profile MUST carry <tt>T = 1</tt>; a packet with <tt>T = 0</tt> MUST be rejected.
Checking only FT=2 would leave metadata packets unchecked.  The ISO
non-timed DU identity and four-byte header remain outside this profile;
no <tt>Item_ID</tt>-based mapping is defined here.</t>
<t>FT=0 initializes the track, FT=1 supplies the authoritative movie
fragment structure and sample table, and FT=2 supplies the exact bytes
of each sample.  That order is a decoder contract, not a hint.</t>

<section anchor="authored-movie-fragment-timing"><name>Authored Movie-Fragment Timing</name>
<t>For timed media, receivers MUST derive sample timing and layout only
from the authored ISOBMFF metadata carried by FT=0 and FT=1:</t>

<ol spacing="compact">
<li>FT=0 supplies the one media track's <tt>mdhd</tt> timescale and <tt>trex</tt>
defaults.  It MUST contain a usable <tt>mvex</tt>/<tt>trex</tt> for that track.</li>
<li>FT=1 begins with a byte-for-byte copy of the authored <tt>moof</tt> and
carries a byte-for-byte copy of the original <tt>mdat</tt> prefix through
the byte before the first media sample.  This includes the original
<tt>mdat</tt> header and any auxiliary sample information.  The
<tt>mfhd.sequence_number</tt> identifies the movie fragment referenced by
subsequent timed-MFU DU headers.</li>
<li>For the <tt>traf</tt> whose <tt>tfhd.track_ID</tt> matches the independent media
track's <tt>tkhd.track_ID</tt>, <tt>tfdt</tt> supplies the first decode time.
Each sample duration and size is resolved using the ISOBMFF
precedence rules across <tt>trun</tt>, <tt>tfhd</tt>, and <tt>trex</tt>; composition time
is decode time plus the authored <tt>trun</tt> composition-time offset.
Signed offsets MUST remain signed.  Sample byte positions are
resolved from the authored base-data-offset and <tt>trun.data_offset</tt>
rules, not from a fixed <tt>mdat</tt>-header guess.</li>
<li>Each FT=2 timed DU identifies one sample -- or one producer-authored
subsample of it -- by <tt>(MPU_sequence_number,
movie_fragment_sequence_number, sample_number, offset)</tt>.  A
whole-sample data unit carries <tt>offset</tt> zero; a subsample data unit
(Section 5.2.1) carries the authored byte position of its first
media byte within the sample.  Section 5.3.3 defines sample
completion.</li>
</ol>
<t>A receiver MUST reject a missing or ambiguous media track, timescale,
movie-fragment sequence, <tt>tfdt</tt>, or sample identity.  It MUST also
reject any sample duration, sample size, byte position, or composition
offset that remains unresolved or invalid after applying all authored
<tt>trun</tt>, <tt>tfhd</tt>, <tt>trex</tt>, and implicit ISOBMFF rules.  An absent
per-sample <tt>trun</tt> composition-time-offset resolves to zero, and an
absent <tt>trun.data_offset</tt> is not by itself an error when the ISOBMFF
base-data-offset and run-continuation rules resolve the byte position.
The receiver MUST reject overlapping sample byte ranges, undeclared
bytes, duplicate samples, duplicate or overlapping subsample data
units (Section 5.2.1), and FT=2 media for which the governing FT=0
or FT=1 has not been accepted.  It MUST NOT synthesize timing from the
MMTP Timestamp, packet or MPU counters, MoQ Object IDs, arrival time,
catalog cadence, codec frame-rate guesses, or previously observed
samples.</t>
<t>The MMTP Timestamp is a send time, not media time (Section 3.1).
Any absolute MMT presentation anchor and edit-list offset are applied
as specified by PI/MPU presentation signalling and ISOBMFF; a receiver
without the required anchor MUST reject that timeline rather than
silently omit the authored adjustment.</t>
</section>

<section anchor="fragmentation-and-strict-active-du-reassembly"><name>Fragmentation and Strict Active-DU Reassembly</name>
<t>A single MFU can exceed the path MTU, but the ISO MPU-mode payload
header does not permit an unbounded number of fragments.  The 8-bit
<tt>fragment_counter</tt> is the number of MMTP payloads containing fragments
of the same data unit that succeed the current payload; it is not a
modulo sequence number.  A complete FI=0 data unit MUST carry zero.
For a fragmented data unit carried in N payloads, where 2 &lt;= N &lt;= 256,
the FI=1 payload MUST carry N - 1, every succeeding payload MUST
decrement the value by one, and the FI=3 payload MUST carry zero.  The
counter MUST NOT wrap or repeat within a data unit.</t>
<t>The mfu mapping defined here carries exactly one data unit per MMTP
payload, so <tt>aggregation_flag</tt> MUST be zero.  The upstream MMTP
packetizer produces conformant data units, and an input MMTP flow used
by this mapping MUST already satisfy the 256-payload bound for every
data unit.  In this profile an FT=2 timed data unit carries one whole
sample, or exactly one producer-authored subsample of it
(Section 5.2.1).  A sample whose media exceeds one data unit's
capacity MUST be partitioned into subsample data units by the origin
packetizer per Section 5.2.1, before this mapping applies -- never by
a relay and never by this mapping, which does not repacketize or
subdivide an input data unit.  Such a sample MUST NOT be carried by
wrapping or extending the counter, silently truncated, or split into a
second MPU, and an access unit MUST NOT be split across multiple MPUs
(<xref target="ISO.23008-1"></xref> Section 6.4).  A publisher MUST reject a purported
data unit that exceeds the bound, has an invalid countdown, or uses
aggregation.  It MUST NOT wrap or extend the counter, divide one data
unit's overflow between subgroups, or synthesize MoQ Object IDs to
make a non-conformant MMTP data unit appear valid.</t>
<t>Each MMTP packet maps to exactly one MoQ object, and the publisher
MUST NOT reassemble MFU fragments:</t>

<ol spacing="compact">
<li>The publisher MUST publish each MMTP packet of a data unit as a
separate object within that data unit's subgroup (Section 4.3), preserving the
MMTP packet header and the MPU-mode payload header.  Those headers
carry the Fragmentation Indicator
and MPU sequence number.  Object IDs identify the preserved source
packets within the subgroup but are not MFU identities or media
timestamps.</li>
<li>The publisher MUST NOT reassemble or reorder fragments based on
the Fragmentation Indicator.  It routes each packet to (track,
group, subgroup) by packet_id, MPU boundary, data-unit type, and the
strict active-DU state of Section 5.3: a change of MPU sequence
number starts the next group (Section 4.3), and each distinct data
unit within the group maps to its own subgroup as defined in
Section 5.3.</li>
<li><t>The receiver MUST reassemble each data unit from the objects of its
subgroup before media processing.  After restoring serial packet
order (Section 5.3.3), it applies the FI/counter state machine of
Section 5.3:</t>

<ul spacing="compact">
<li>A single object with FI=0 is a complete, unfragmented data unit;
for FT=2 that data unit is one MFU.</li>
<li>FT=2 objects with FI=1 (first), FI=2 (zero or more middle), and FI=3
(last) reassemble, in that restored MMTP order, into one MFU by
concatenating each fragment's media bytes, delimited as defined
below.</li>
<li>The receiver MUST validate the <tt>fragment_counter</tt> countdown with
the state machine of Section 5.3.2.  Any missing, repeated,
wrapped, or non-decrementing count invalidates the entire MFU.</li>
<li>The reassembled MFU's RAP flag is taken from its FI=1 (or FI=0)
object.</li>
</ul></li>
</ol>
<t>The bytes concatenated are each fragment's media (data unit)
   bytes only -- NOT everything after the MMTP packet header.  Every
   fragment begins with a 12-or-more-byte MMTP packet header.  The
   receiver MUST parse the C and X flags, packet-counter presence, and
   header-extension length to locate the following 8-byte MPU-mode
   payload header; it MUST NOT assume a fixed offset of 12 bytes.  The
   MPU-mode payload header contains, by <xref target="ISO.23008-1"></xref>
   Clause 9.3.2.3 name with this document's alias in parentheses,
   length (<tt>payload_length</tt>, 16), FT (<tt>fragment_type</tt>, 4), T
   (<tt>timed_flag</tt>, 1), f_i (<tt>fragmentation_indicator</tt>, 2),
   aggregation_flag (1), fragment_counter (8), and
   MPU_sequence_number (32); both headers are stripped from every
   fragment.</t>
<t>The 16-bit <tt>payload_length</tt> field MUST be encoded and interpreted
   as the number of bytes following that field within the MPU payload,
   as defined by <xref target="ISO.23008-1"></xref>.  It therefore includes the remaining
   six bytes of the 8-byte MPU-mode payload header.  For FT=2 packets,
   the declared lengths are:</t>

<artwork><![CDATA[   FI=0 or FI=1: payload_length = 6 + DU_header_octets + media_octets
   FI=2 or FI=3: payload_length = 6 + media_octets
]]></artwork>
<t><tt>DU_header_octets</tt> is 14 for timed media and 4 for non-timed media,
   and the right-hand side MUST NOT exceed the 16-bit maximum of 65535.
   A trailing Source FEC Payload ID is outside the declared MPU payload
   and MUST NOT be counted.  A publisher MUST NOT encode a media-only or
   DU-plus-media length convention.  A receiver MUST require the
   declared MPU payload to end exactly at the protected MPU boundary
   before the Source FEC Payload ID, when present.  It MUST reject a
   declaration that is too short, cannot contain the required header
   bytes, extends beyond the available MPU payload bytes, leaves
   undeclared bytes before the outer trailer, or consumes that trailer.</t>
<t>The DU header (<xref target="ISO.23008-1"></xref> Figures 12 and 13: 14 bytes for
   timed media -- movie_fragment_sequence_number (32),
   sample_number (32), offset (32), priority (8),
   dep_counter (8) -- or 4 bytes for non-timed media) follows the
   payload header on an FI=0 object and on the FI=1 first fragment;
   it is likewise stripped rather than concatenated into the media
   stream.  When the packet's FEC Type is 1, the trailing 4-byte
   Source FEC Payload ID (<xref target="MOQ-FEC"></xref> Section 8.5) is excluded as
   well.
4. FT=0 and FT=1 MUST each be unaggregated, complete FI=0 data units
   with <tt>fragment_counter</tt> zero.  Their payload length is six plus the
   metadata octets; they have no DU header.  Fragmented or empty
   metadata is rejected by this profile.
5. The receiver MUST bound both in-flight data-unit memory and pending
   FT=1 sample records.  At either bound it MUST reclaim a slot by
   evicting the least recently admitted incomplete record — an open
   data unit or a parked continuation run alike — and admit the new
   one; it rejects only when no such record exists.  A record that has
   already completed is never a candidate.  An incomplete data
   unit is discarded on declared discontinuity or unrecoverable loss
   and is never emitted.</t>
<t>For very large frames where FEC cannot recover the loss, receivers
SHOULD support resolution-tier fallback (subscribe to a lower-resolution
track of the switching set and upscale) rather than stalling.</t>

<section anchor="subsample-data-units"><name>Subsample Data Units</name>
<t>At a given packet size, one data unit carries at most 256 MMTP
payloads of media.  A single intra-coded 4K or 8K sample routinely
exceeds that capacity.  This section defines the only conformant way
to carry such a sample: the origin packetizer partitions it into
subsample data units, using the <tt>offset</tt> field that <xref target="ISO.23008-1"></xref>
Section 9.3.2.3 already defines in the timed-MFU DU header.  The
partition is producer-authored and wire-stated; nothing about it is
inferred.</t>
<t>A subsample data unit is an ordinary FT=2 timed data unit: it has its
own DU header, its own FI chain, and its own <tt>fragment_counter</tt>
countdown bounded by 256 payloads (Section 5.2).  Its identity is
<tt>(packet_id, MPU_sequence_number, movie_fragment_sequence_number,
sample_number, offset)</tt>, where <tt>offset</tt> is the authored byte position
of the data unit's first media byte within the sample.</t>
<t>Origin packetizer requirements:</t>

<ol spacing="compact">
<li>A packetizer MUST emit a sample as a single whole-sample data unit
(<tt>offset</tt> zero) whenever the sample fits within one data unit's
capacity.  Subsample partitioning of a sample that fits is not
conformant.</li>
<li>When partitioning, the first subsample data unit MUST carry
<tt>offset</tt> zero and each subsequent one MUST carry an <tt>offset</tt> equal
to the sum of the media lengths of all preceding subsample data
units of that sample: offsets are strictly increasing, with no gap
and no overlap.</li>
<li>Each subsample data unit of one sample MUST be published as its
own subgroup per Section 5.3.2, contiguously per Section 5.2.2.</li>
<li><tt>priority</tt> and <tt>dep_counter</tt> describe the sample and SHOULD be
identical across its subsample data units.</li>
</ol>
<t>Relays and this mapping MUST NOT create, merge, or re-partition
subsample data units.</t>
<t>Receiver sample assembly: a subsample-partitioned sample completes
only when every one of its subsample data units has completed under
the state machine of Section 5.3.2 and, ordered by <tt>offset</tt>, the data
units begin at zero, are byte-adjacent (each <tt>offset</tt> equals the
preceding <tt>offset</tt> plus the preceding data unit's media length), and
their total media length equals the sample's authored size from the
FT=1 record.  A gap, overlap, duplicate <tt>offset</tt>, or length mismatch
invalidates the sample; the receiver MUST NOT emit a partial sample or
synthesize missing bytes.  Completion is a protocol event -- every
constituent subgroup complete -- and on reliable transport a receiver
MUST NOT substitute timers, cadence, buffer occupancy, or successor
arrival for it.  On lossy datagram paths the existing per-data-unit
deadline derivation applies to each subsample data unit unchanged; no
additional sample-level timer is defined or permitted.</t>
<t>The sample's RAP flag is the RAP flag of the FI=0 or FI=1 object of
its offset-0 data unit.  FEC is unaffected by the partition: source
symbols are MMTP packets (<xref target="MOQ-FEC"></xref>), and the packet stream's block
and interleave structure does not depend on data-unit boundaries.</t>
</section>

<section anchor="source-contiguity"><name>Source Contiguity</name>
<t><xref target="ISO.23008-1"></xref> does not prohibit a packetizer from emitting an
unrelated payload of the same <tt>packet_id</tt> between two fragments of one
data unit.  This profile does prohibit it.</t>
<t>An origin packetizer MUST emit every multi-packet unit on consecutive
<tt>packet_sequence_number</tt> values of its <tt>packet_id</tt>, in authored order,
with no other payload of that <tt>packet_id</tt> between its packets: the
fragments of a data unit in FI order, and the subsample data units of
one sample (Section 5.2.1) in ascending <tt>offset</tt> order.  The sequence
numbers of the FI=1 fragment, of each FI=2 fragment, and of the FI=3
fragment MUST be successive values under
modulo-2^32 arithmetic.  A data unit of a different <tt>packet_id</tt> MAY be
emitted at any point, and a further data unit of the same <tt>packet_id</tt>
MAY be emitted once that data unit's FI=3 fragment has been emitted,
subject to the sample-level contiguity above.</t>
<t>The requirement constrains the packetizer's emission order only.  Loss
or reordering on the path does not violate it: the receiver restores
serial packet order before reassembly (Section 5.3.3).  Repair
carried on its own flow bears a different <tt>packet_id</tt> and therefore
cannot interleave.</t>
<t>A violating data unit never completes at the receiver, which
associates continuations only through active data-unit state
(Section 5.3) and evicts the stranded records without a protocol
error (Section 5.2, item 5).  A receiver MUST NOT relax association to
tolerate such a producer: a continuation admitted into the wrong data
unit corrupts media that would otherwise have been discarded.</t>
</section>
</section>

<section anchor="active-data-unit-association-and-subgroup-derivation"><name>Active Data-Unit Association and Subgroup Derivation</name>
<t>Object IDs are transport coordinates, not an MMTP continuation key.
A fragment recovered below the MoQ object layer has no Object ID, and
Object IDs from two delivery paths are not comparable.  The MMTP DU
header is also not a per-fragment coordinate: this profile carries it
only in the FI=0 or FI=1 payload (<xref target="ISO.23008-1"></xref> Clause 9.3.2 does
not specify whether FI=2 and FI=3 fragments repeat it).  FI=2 and FI=3
continuations carry media bytes but no movie-fragment sequence, sample
number, or sample offset.</t>
<t>Consequently a receiver MUST associate continuations through the
ordered, bounded active-data-unit state defined here.  It MUST NOT use
an MMTP Timestamp, MoQ Object ID, signaling identifier, packet arrival
time or order, inferred byte offset, recently completed identity, or a
(stream, MPU sequence number) pair or fragment counter alone as a
fallback association.</t>

<section anchor="first-fragment-identity"><name>First-Fragment Identity</name>
<t>For an FT=2 first or complete fragment, <xref target="ISO.23008-1"></xref> defines a
transport-independent data-unit identity in the DU header:</t>
<table>
<thead>
<tr>
<th>Object class</th>
<th>Data-unit identity</th>
<th><xref target="ISO.23008-1"></xref></th>
</tr>
</thead>

<tbody>
<tr>
<td>Timed-media MFU</td>
<td>packet_id, MPU_sequence_number, movie_fragment_sequence_number, sample_number, offset</td>
<td>Section 9.3.2.3</td>
</tr>

<tr>
<td>Non-timed media MFU</td>
<td>packet_id, MPU_sequence_number, Item_ID</td>
<td>Section 9.3.2.3</td>
</tr>
</tbody>
</table><t>For this timed-media profile, <tt>offset</tt> MUST be zero for a whole-sample
data unit and MUST equal the authored subsample byte position for a
subsample data unit (Section 5.2.1);
<tt>movie_fragment_sequence_number</tt> and <tt>sample_number</tt> MUST be non-zero,
and <tt>MPU_sequence_number</tt> MAY be zero (indeed, ISO/IEC 23008-1 requires
zero for the first MPU in an Asset).  The <tt>packet_id</tt> MUST be
non-zero: packet_id 0 is the MMTP signaling flow (Section 3.1) and
carries no media data unit, so a receiver MUST reject an MPU-mode
packet (packet type 0x00) on packet_id 0 rather than admit it to
active state.  A non-zero <tt>packet_id</tt> is validated in the scope of its
MMTP session; on multicast delivery it is validated against the
<tt>packetId</tt> values the endpoint advertises (<xref target="MOQ-MULTICAST"></xref>
Section 5).  A continuation inherits the accepted first-fragment
identity from active state; it does not reconstruct or guess another
copy of the DU header.</t>
</section>

<section anchor="subgroup-derivation"><name>Subgroup Derivation</name>
<t>Section 4.3 assigns Subgroup 0 to FT=0.  The publisher assigns every
following FT=1 or FT=2 data unit the next unused Subgroup ID in source
order.  All packets from one FI=1 through FI=3 chain share that ID.
An FI=2 or FI=3 packet therefore remains in the subgroup opened by the
immediately preceding FI=1 packet on the same <tt>packet_id</tt>; a new data
unit MUST NOT interleave before the chain closes (Section 5.2.2).</t>
<t>The publisher and receiver each maintain at most one active fragmented
data unit per <tt>(packet_id, MPU_sequence_number)</tt> while processing
subgroups in order:</t>

<ol spacing="compact">
<li>FI=0 requires <tt>fragment_counter == 0</tt> and no active data unit.  For
FT=2 it requires a valid DU header and represents the complete
sample.  FT=0 and FT=1 are permitted only in this form.</li>
<li>FI=1 requires no active data unit, a counter <tt>c</tt> in 1..255, and, for
FT=2, a valid DU header.  It creates active state containing the
data-unit type, timed flag, full first-fragment identity, destination
subgroup, and <tt>next_expected_counter = c - 1</tt>.</li>
<li>FI=2 requires exactly one matching active state and a non-zero
counter equal to the next expected counter.  It appends only the
declared media bytes and decrements the expected counter.</li>
<li>FI=3 requires exactly one matching active state,
<tt>next_expected_counter == 0</tt>, and a wire counter of zero.  It appends
the declared media bytes, closes the state, and emits the complete
data unit only after all size and authored-timing checks succeed.</li>
</ol>
<t>An FI=0 or FI=1 while state is active is an overlap.  An FI=2 or FI=3
without it is an orphan.  A changed packet ID, MPU sequence, FT, timed
flag, subgroup, skipped/repeated counter, FI=2 at zero, or FI=3 before
the expected counter reaches zero is a mismatch or gap.  The receiver
MUST reject all of these and MUST NOT advance, replace, or consume valid state or pending sample
timing on rejection.  A new MPU arriving while the prior MPU has an
incomplete data unit declares loss and discontinuity; the incomplete
unit is discarded and never emitted.</t>
</section>

<section anchor="receiver-admission-and-completion"><name>Receiver Admission and Completion</name>
<t>A receiver admits a fragment only after its declared MPU payload
boundary, outer FEC trailer, stream scope, subgroup order, and active-DU
transition all validate.  Duplicate packets may be dropped by exact
MMTP packet identity before admission, but a duplicate MUST NOT create
or advance active state.  Multi-path combining and FEC recovery MUST
restore the same per-<tt>packet_id</tt> serial packet order before this state
machine, using modulo-2^32 serial-number arithmetic across
<tt>packet_sequence_number</tt> wrap within a bounded replay window.  The
MMTP-session and MoQ-track scope are part of that ordering state;
neither mechanism may fabricate a missing transition.</t>
<t>Completion is transactional.  For a whole-sample data unit the
receiver first validates the full FI chain and the matching unconsumed
FT=1 sample record; the reassembled FT=2 media length MUST equal that
sample's authored size.  For a subsample-partitioned sample it
additionally requires every constituent subsample data unit to have
completed, with the byte-adjacency and total-length checks of
Section 5.2.1.  Only then may it emit the sample and consume that
record.  Every <tt>(sample, offset)</tt> data unit is admitted at most once,
and every described sample is emitted at most once.  A failed check leaves every pre-existing valid state and timing record
unchanged, except that an explicitly declared discontinuity discards
the incomplete prior unit.</t>
</section>

<section anchor="random-access-and-priority"><name>Random Access and Priority</name>
<t>An MPU begins at a Stream Access Point: the first access unit of an
MPU is a random access point (RAP) (<xref target="ISO.23008-1"></xref> Section 6.4;
Section 4.3).  Accordingly a receiver:</t>

<ul spacing="compact">
<li>SHOULD gate the start of media decoding on the availability of a
complete RAP MFU, including a RAP MFU completed by FEC recovery;
and</li>
<li>SHOULD prioritize FEC recovery and retention of fragments whose
DU header carries a higher priority or dep_counter value
(Section 5.2; the subsample_priority and dependency_counter of
<xref target="ISO.23008-1"></xref> Section 9.3.2.3), since these are decode-order
roots upon which other access units depend.</li>
</ul>
<t>On a multicast or AMT leg, <xref target="MOQ-FEC"></xref> Section 11.4 specifies the
receiver repair policy this implies.</t>
</section>
</section>
</section>

<section anchor="subscriber-join-and-relay-behavior"><name>Subscriber Join and Relay Behavior</name>
<t>This section defines the join procedure for subscribers and the
retention behavior relays apply so that late joiners reach first
frame without waiting for the next group boundary.  The retention
rules in
Section 6.2 are purely positional (group, subgroup, and object
identifiers plus the Subgroup 0 convention of Section 4.3), so relays
remain container-blind and never parse MMTP.</t>

<section anchor="subscriber-join-procedure"><name>Subscriber Join Procedure</name>
<t>A subscriber joins a live mmtp-packaged track as follows:</t>

<ol>
<li><t><strong>Catalog.</strong> Fetch and validate the catalog (the track named
<tt>catalog</tt>, Section 12).  Validation includes
the per-track REQUIRED fields of Section 12.1 and the
switching-set agreement check of Section 4.4.2.  A subscriber
MUST NOT issue SUBSCRIBE for a track whose catalog entry fails
validation.</t>
</li>
<li><t><strong>Decoder initialization.</strong> If the track carries <tt>initData</tt>
(Section 4.5) and it validates, initialize the decoder from it
immediately.  In all cases the subscriber MUST accept the
authoritative FT=0 object in Subgroup 0 before admitting this
group's FT=1 or FT=2 data units.  An AL-FEC signaling object that
precedes FT=0 in Subgroup 0 (Section 8) is not decoder
initialization and does not satisfy this step.</t>
</li>
<li><t><strong>Subscribe at a group boundary.</strong> Issue SUBSCRIBE requesting
delivery from the start of the newest available group, not from
the latest object.  The group start carries FT=0 initialization
(Subgroup 0), the FT=1 metadata governing the first samples, and
the RAP-bearing first FT=2 subgroup
(Section 4.3); a mid-group start position yields objects that
cannot be decoded until the next group.  Where the relay retains
the current group (Section 6.2), starting at the newest group
boundary gives immediate decodability; otherwise the subscriber
waits for the next group boundary.</t>
</li>
<li><t><strong>Repair track.</strong> If the subscriber wants FEC protection and the
catalog signals FEC for the track, it SHOULD subscribe to the
repair track (Section 8.2) at the same time as the source track,
so that the first FEC block spanning the join point is
repairable.  Repair-track subscription is selective and optional
(<xref target="MOQ-FEC"></xref> Section 6.2).</t>
</li>
<li><t><strong>Presentation gate.</strong> A subscriber MUST NOT submit media to the
decoder until it has (a) accepted the authoritative FT=0 and FT=1
data units and (b) a completely reassembled FT=2 sample whose RAP
flag is set (Section 5.2).  Objects received before that point are buffered
or discarded according to the receiver's reassembly bounds.</t>
</li>
<li><t><strong>Loss and discontinuity.</strong> If a RAP MFU is discarded under
unrepairable loss (Section 5.2), the subscriber MUST
treat the track as discontinuous and MUST NOT resume presentation
before the next completely reassembled RAP MFU (normally the
start of the next group).  The same holds when the group's FT=0
data unit, or the FT=1 data unit governing its RAP, is lost, since
the RAP then cannot be admitted (Section 4.3).  On a multicast or
AMT leg, loss that spares those three data units does not make the
track discontinuous; <xref target="MOQ-FEC"></xref> Section 11.4 specifies its
handling.</t>
</li>
</ol>
</section>

<section anchor="relay-retention-for-late-joiners"><name>Relay Retention for Late Joiners</name>
<t>A relay that admits subscribers mid-stream SHOULD retain, for each
track it serves, all objects of the current (most recent) group.</t>
<t>When a subscription joins mid-group, the relay SHOULD deliver the
retained objects of the current group from the group start --
including objects of subgroups that were already complete or still
open at join time -- in subgroup and object order, ahead of or
interleaved with newly arriving objects.  A relay that holds earlier
objects of the current group MUST NOT deliver only objects published
after the join; doing so strands the subscriber until the next group
boundary and defeats retention.</t>
<t>Two completeness rules apply to replayed subgroups:</t>

<ol spacing="compact">
<li>The relay MUST track which retained subgroups are finalized
(closed by the publisher) and, when replaying a finalized
subgroup, MUST deliver it completely; replaying a partial prefix
of a finalized subgroup and silently omitting the remainder
produces an MFU the receiver can never reassemble and is
indistinguishable from network loss.</li>
<li>The relay SHOULD deliver retained subgroups in ascending Subgroup ID
and objects in their source order.  Under the positional mapping of
Section 4.3, this delivers Subgroup 0 and every lower-numbered
governing metadata subgroup before its FT=2 subgroup without parsing
MMTP.  Receivers still enforce Subgroup-ID order (Section 4.3).</li>
</ol>
<t>Retention of groups older than the current group (for example to
serve FETCH-based catch-up) is permitted but out of scope for this
document.  Under cache pressure a relay MAY evict retained objects;
eviction converts a late join into a wait for the next group
boundary, which is the same behavior as a relay that retains nothing.</t>
</section>
</section>

<section anchor="fec-integration"><name>FEC Integration</name>
<t>MMT's AL-FEC framework supports multiple FEC schemes, with the MMT
FEC codes specified in <xref target="ISO.23008-10"></xref> and parameters signaled via
MMTP signaling messages or, in ATSC 3.0, via S-TSID (which is part of
the ROUTE transport layer).  For MoQ, RaptorQ <xref target="RFC6330"></xref> is the
mandatory-to-implement and only fully
specified scheme (<xref target="MOQ-FEC"></xref> Section 4.3), and FEC repair uses the
model defined in <xref target="MOQ-FEC"></xref>:</t>

<artwork><![CDATA[Source Track: video
  +-- Objects: MMTP packets with FEC Type=0 or 1 (source)

Repair Track: video/repair
  +-- Objects: MMTP packets with FEC Type=2 (repair)
]]></artwork>

<section anchor="interleaving"><name>Interleaving</name>
<t>Interleaving and typical interleave windows (<tt>interleaveDepthMs</tt>)
follow <xref target="MOQ-FEC"></xref> Section 9.  A positive <tt>interleaveDepthMs</tt> is the
elapsed source/repair send-span bound for each actual FEC block; it does not
select FEC block boundaries, derive a number of groups per block, or
require a fixed relationship between an FEC block and a media Group.
Absent and zero values follow <xref target="MOQ-FEC"></xref> Section 5.1 and do not supply
an elapsed-time deadline.  A typical window for ARIB STD-B60 content is
2000 ms.</t>
</section>

<section anchor="oti-signaling"><name>OTI Signaling</name>
<t>The S-TSID carries the RaptorQ OTI of <xref target="RFC6330"></xref> Section 3.3 in its
<tt>fecOTI</tt> attribute.  MoQ carries no OTI in-session: receivers derive
it per block from the catalog <tt>fec</tt> fields and the block's SSB_length
per <xref target="MOQ-FEC"></xref> Section 4.2, and Section 12.2 converts an ingested
<tt>fecOTI</tt> to catalog fields.</t>
</section>
</section>

<section anchor="fec-parameter-signaling"><name>FEC Parameter Signaling</name>
<t>FEC parameters for mmtp-packaged tracks are signaled in the catalog
<tt>fec</tt> object, defined normatively in <xref target="MOQ-FEC"></xref> Section 5, which is
authoritative for MoQ receivers (<xref target="MOQ-FEC"></xref> Section 5.2).  A MoQ
receiver requires no in-session FEC signaling: the catalog carries
every FEC parameter it needs.
This document does not redefine the catalog fields but specifies
MMT-specific considerations for their use.</t>
<t>A publisher MAY also carry the MMTP AL-FEC signaling message of
Section 8.3 on a MoQ mmtp source track, as an object whose payload
is an MMTP signaling packet on packet_id 0 (Section 3.1).  When
present, it is published in Subgroup 0 of an MPU group as the object
immediately before, and in the same subgroup as, that group's FT=0
object, and a group carries at most one such object (Sections 4.2
and 4.3).  On a MoQ
track such an object is a redundant in-band copy of catalog state:
the message MUST NOT signal FEC parameters that contradict the
track's catalog <tt>fec</tt> object, and where the two disagree the catalog
governs.  The object carries no media data
unit and no repair symbol, so a MoQ receiver MUST NOT deliver it to
a media or repair decoder (Section 3.1); a receiver that does not
process MMTP signaling discards it.</t>
<t>The signaling object is not an FEC source symbol.  Its MMTP packet
has FEC Type 0 and no Source FEC Payload ID; it is not protected by
any repair symbol, is not counted in any FEC block or in
<tt>sourceSymbols</tt> (K), and has no SS_ID and no Encoding Symbol ID.
Because it occupies an Object ID in Subgroup 0, Object IDs on an mmtp
source track are not positions in the FEC block: a receiver MUST take
each source symbol's SS_ID from the Source FEC Payload ID that trails
its FEC Type 1 packet (<xref target="MOQ-FEC"></xref> Section 8.5), never from its
Object ID, and places the symbol in its block by that SS_ID
(<xref target="MOQ-FEC"></xref> Section 8.3).</t>
<t>A MoQ track carries only the
signaling packets its publisher chose to place on that track, so
the packet_sequence_number values it exhibits on packet_id 0 need
not be contiguous.  A receiver MUST NOT infer loss from a
packet_sequence_number gap on packet_id 0 of a MoQ track, and MUST
NOT defer any packet, including a later packet on packet_id 0,
behind such a gap.</t>

<section anchor="mmt-specific-fec-parameters"><name>MMT-Specific FEC Parameters</name>
<t>When used with MMT packaging, the catalog <tt>fec</tt> fields map as
follows:</t>

<ul spacing="compact">
<li><strong>algorithm</strong>: Typically &quot;raptorq&quot; for ATSC 3.0 ingest,
or as specified in MMTP AL-FEC signaling</li>
<li><strong>blockProfile</strong>: &quot;iso-ssbg1-v1&quot; (<xref target="MOQ-FEC"></xref> Section 5.1), the
ISO 23008-1 Annex C block profile, for which an AL-FEC message
carries the coding byte 0x14 (Section 8.3); REQUIRED when
<tt>algorithm</tt> is not &quot;none&quot;</li>
<li><strong>sourceSymbols</strong>: The largest number of MMTP packets (source
symbols) that an FEC block may hold; each block holds SSB_length of
them (<xref target="MOQ-FEC"></xref> Section 7.4).  On the MMT path the canonical FEC
source symbol is one whole MMTP packet, before its Source FEC
Payload ID, framed with its length (<xref target="MOQ-FEC"></xref> Section 7.3)</li>
<li><strong>interleaveDepthMs</strong>: When positive, the elapsed source/repair send
span bound of each actual FEC block, as defined by <xref target="MOQ-FEC"></xref>
Section 5.1; that section also defines absent and zero values.  It is
independent of <tt>groupDurationMs</tt> and does not imply a block count or
block boundary from MoQ Groups.  When ingesting broadcast content,
use the ISO protection-window signaling or a known source/repair
send-span bound.  A source-frame count alone does not bound the
actual packet send span (Section 12.2).</li>
</ul>
<t>See <xref target="MOQ-FEC"></xref> for the complete catalog field definitions, the
algorithm registry, and the OTI derivation.</t>
</section>

<section anchor="repair-tracks"><name>Repair Tracks</name>
<t>A source track's repair tracks are the track its <tt>fec.repairTrack</tt>
names and the tracks that name it in <tt>depends</tt> (<xref target="MOQ-FEC"></xref>
Section 5.1.1); <xref target="MOQ-FEC"></xref> Section 6.1 gives their conventional
names.  Subscription to them follows <xref target="MOQ-FEC"></xref> Section 6.2, and
their priorities <xref target="MOQ-FEC"></xref> Section 10.</t>
</section>

<section anchor="fec-signaling-for-multicast-delivery"><name>FEC Signaling for Multicast Delivery</name>
<t>For multicast (SSM/ASM) delivery there is no bidirectional
signaling channel.  FEC parameters reach multicast receivers via:</t>

<ol>
<li><t><strong>MoQ Catalog Extension</strong> (authoritative for MoQ receivers,
<xref target="MOQ-FEC"></xref> Section 5.2): out-of-band delivery in the catalog
<tt>fec</tt> object (see the worked catalog of <xref target="MOQ-FEC"></xref>
Section 5.1.2).</t>
</li>
<li><t><strong>MMTP AL-FEC Signaling (message_id=0x0203)</strong>: in-band delivery
of the AL-FEC message of <xref target="ISO.23008-1"></xref> Clause C.6, with
Table C.3 as replaced by <xref target="ISO.23008-1.AMD1"></xref>,
for ISO/IEC 23008-1 receivers that consume the flow without the
catalog, such as native broadcast (ATSC 3.0, ARIB STD-B60)
receivers.  A publisher that sends this message MUST carry it in
an MMTP signaling packet (packet type 0x02) on packet_id 0, the
MMTP signaling flow, after the signaling message payload header of
<xref target="ISO.23008-1"></xref> Clause 9.3.4.2 (Section 3.1); on
multicast delivery it shares the multicast group of the media it
describes, and on MoQ delivery it MAY be carried as an object of an
mmtp source track under the rules of Section 8.  No track is
advertised on packet_id 0
(<xref target="MOQ-MULTICAST"></xref> Section 4.1), and a receiver does not deliver
these packets to a media or repair decoder (Section 3.1;
<xref target="MOQ-MULTICAST"></xref> Section 5)</t>
</li>
</ol>
<t>Each FEC source flow has one FEC encoded flow (<xref target="ISO.23008-1"></xref>
Clause C.6.3), so the message describes a source track's flow as one
entry of the message's <tt>fec_flow_descriptor</tt> naming exactly one repair
flow,
the track's layer-0 repair track (<xref target="MOQ-FEC"></xref> Section 6.3).  For a
track whose <tt>fec.blockProfile</tt> is &quot;iso-ssbg1-v1&quot;, that entry carries:</t>

<ul spacing="compact">
<li>the coding byte 0x14, that is <tt>fec_coding_structure</tt> 0001
(one-stage), <tt>ssbg_mode</tt> 01, <tt>ffsrpts_flag</tt> 0 and
<tt>fec_payload_id_mode</tt> 0 (<xref target="MOQ-FEC"></xref> Section 7.3);</li>
<li>as its <tt>repair_flow_id</tt>, the packet_id of the layer-0 repair
packets.  <xref target="ISO.23008-1.AMD1"></xref> makes this field 16 bits in the
one-stage branch, where the 2023 edition of Table C.3 gives it 8
bits and so cannot name a repair packet_id above 255; and</li>
<li>as its <tt>maximum_k_for_repair_flow</tt>, the track's <tt>fec.sourceSymbols</tt>:
like that field, it bounds each block's SSB_length and is not the
size of any particular block (<xref target="MOQ-FEC"></xref> Section 7.4).</li>
</ul>
<t>A publisher MUST NOT describe a repair layer above layer 0, or a
keyframe overlay, in the message, whether in that entry or in an
entry of its own: the one-stage coding structure names one repair
flow per FEC encoded flow, the overlay protects a RAP subset that no
<tt>packet_id</tt> identifies, and only the catalog declares either
(<xref target="MOQ-FEC"></xref> Sections 6.3, 6.4 and 8.5.1).</t>
</section>
</section>

<section anchor="multicast-integration"><name>Multicast Integration</name>
<t>MMT content can be delivered via IP multicast (SSM, AMT) and TreeDN
for scalable distribution.  Platform-specific delivery paths, the
multicast endpoint catalog extension, and TreeDN/AMT integration are
defined in <xref target="MOQ-MULTICAST"></xref>, and the multicast packet format in its
Section 5.</t>
</section>

<section anchor="arib-std-b60-compatibility"><name>ARIB STD-B60 Compatibility</name>
<t>ARIB STD-B60 <xref target="ARIB-B60"></xref> (Japan's MMT-based broadcasting standard)
uses the same ISO 23008-1 foundation as ATSC 3.0.  Publishers SHOULD
preserve the original FEC parameters when ingesting ARIB STD-B60
content.</t>

<section anchor="clock-reference"><name>Clock Reference</name>
<t>ARIB STD-B60 uses the MMTP Timestamp of Section 3.1: the UTC send
time of the packet in NTP short format.</t>
</section>
</section>

<section anchor="transport-hierarchy"><name>Transport Hierarchy</name>
<t>Clients SHOULD attempt transports in the preference order that
<xref target="MOQ-MULTICAST"></xref> Section 3 defines for native and browser clients.
AL-FEC (Section 7) is the loss recovery on SSM/AMT paths, which have
no retransmission.</t>
</section>

<section anchor="catalog-signaling"><name>Catalog Signaling</name>
<t>The MoQ catalog indicates MMT packaging and multicast endpoints.</t>
<t>The catalog of this suite is an MSF catalog: the root object and
its fields (<tt>version</tt>, <tt>generatedAt</tt>, <tt>tracks</tt>, ...), the
requirement that parsers ignore fields they do not understand, and
the base per-track fields are those of <xref target="I-D.ietf-moq-msf"></xref>
Section 5.  The catalog is delivered as a MoQ track whose
case-sensitive Track Name is <tt>catalog</tt> (<xref target="I-D.ietf-moq-msf"></xref>
Section 5).  The documents of this suite extend the base in the
same manner as
<xref target="I-D.ietf-moq-cmsf"></xref> extends it: this document adds the packaging
value <tt>mmtp</tt> and the mmtp track fields (Section 12.1), <xref target="MOQ-FEC"></xref>
adds the per-track <tt>fec</tt> object and the <tt>fec-repair</tt> packaging
value, and <xref target="MOQ-MULTICAST"></xref> adds the root-level <tt>multicast</tt>
member.  Every catalog field this suite uses is defined either by
<xref target="I-D.ietf-moq-msf"></xref> or locally by a document of this suite (with
<tt>cmaf</tt> tracks and <tt>initData</tt> per <xref target="I-D.ietf-moq-cmsf"></xref>); no field
is defined by any other catalog specification.</t>

<section anchor="packaging-value-and-track-fields"><name>Packaging Value and Track Fields</name>
<t>This document defines a single packaging value:</t>

<artwork><![CDATA[packaging: "mmtp"
]]></artwork>
<t>carried in the per-track <tt>packaging</tt> field of the catalog
(<xref target="I-D.ietf-moq-msf"></xref> Section 5.2.4).  The value extends the
allowed packaging values of that specification in the same manner
as the <tt>cmaf</tt> value of <xref target="I-D.ietf-moq-cmsf"></xref> Section 3.5.1; see
Section 14 for the registry request.  Object payloads of an
mmtp-packaged track are whole MMTP packets per Section 4.2.</t>
<t>Per-track catalog fields for mmtp packaging:</t>
<table>
<thead>
<tr>
<th>Field</th>
<th>Status</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>packaging</tt></td>
<td>REQUIRED</td>
<td>String</td>
<td>MUST be &quot;mmtp&quot;</td>
</tr>

<tr>
<td><tt>mmtpMode</tt></td>
<td>REQUIRED</td>
<td>String</td>
<td>MUST be &quot;mfu&quot; (Section 5); defined by this document</td>
</tr>

<tr>
<td><tt>timescale</tt></td>
<td>REQUIRED</td>
<td>Number</td>
<td>Media timescale in Hz (<xref target="I-D.ietf-moq-msf"></xref> Section 5.2.21, profiled REQUIRED here; Section 4.4.2)</td>
</tr>

<tr>
<td><tt>presentationAnchorTicks</tt></td>
<td>REQUIRED for synchronized audio/video tracks</td>
<td>Signed integer</td>
<td>Track timestamp corresponding to shared presentation time zero (Section 4.4.1); defined by this document</td>
</tr>

<tr>
<td><tt>groupDurationMs</tt></td>
<td>Conditional</td>
<td>Number</td>
<td>REQUIRED without the tick form; positive integer ms (Section 4.4.2); informational when ticks are present</td>
</tr>

<tr>
<td><tt>groupDurationTicks</tt></td>
<td>OPTIONAL</td>
<td>Number</td>
<td>Positive exact group duration in track ticks; authoritative when present (Section 4.4.2); defined by this document</td>
</tr>

<tr>
<td><tt>altGroup</tt></td>
<td>OPTIONAL</td>
<td>Number</td>
<td>Switching-set membership key (<xref target="I-D.ietf-moq-msf"></xref> Section 5.2.12, profiled in Section 4.4)</td>
</tr>

<tr>
<td><tt>keyframeIntervalMs</tt></td>
<td>OPTIONAL</td>
<td>Number</td>
<td>Keyframe/GOP cadence, integer ms; video only (Section 4.4.3); defined by this document</td>
</tr>

<tr>
<td><tt>keyframeIntervalTicks</tt></td>
<td>OPTIONAL</td>
<td>Number</td>
<td>Integer-tick override for the keyframe interval (Section 4.4.3); defined by this document</td>
</tr>

<tr>
<td><tt>initData</tt></td>
<td>OPTIONAL</td>
<td>String</td>
<td>Base64 ftyp+moov init segment (<xref target="I-D.ietf-moq-cmsf"></xref> Section 3.1, profiled in Section 4.5)</td>
</tr>

<tr>
<td><tt>fec</tt></td>
<td>OPTIONAL</td>
<td>Object</td>
<td>AL-FEC parameters, defined in <xref target="MOQ-FEC"></xref> Section 5 (Section 8)</td>
</tr>
</tbody>
</table><t>All other base track fields of <xref target="I-D.ietf-moq-msf"></xref> Section 5.2
apply unchanged.  In particular <tt>name</tt> and the rendition
parameters -- <tt>codec</tt> (<xref target="I-D.ietf-moq-msf"></xref> Section 5.2.18; required
for media tracks per that section), <tt>framerate</tt>, <tt>width</tt>, <tt>height</tt>,
<tt>samplerate</tt>, <tt>channelConfig</tt>, <tt>bitrate</tt>, and <tt>lang</tt> -- are flat,
top-level fields of the track object.</t>
<t><tt>mmtpMode</tt> selects the object layout and MUST be &quot;mfu&quot;.  It delivers
one subgroup per FT=0, FT=1, or FT=2 data unit as defined in Sections
4.3 and 5.  A subscriber MUST reject a track whose
<tt>mmtpMode</tt> is absent or has any other value; the object layout cannot
be inferred safely from received objects.</t>
<t>Example:</t>

<sourcecode type="json"><![CDATA[{
  "tracks": [{
    "name": "video",
    "packaging": "mmtp",
    "mmtpMode": "mfu",
    "timescale": 90000,
    "presentationAnchorTicks": 0,
    "groupDurationMs": 1000,
    "codec": "avc1.64001f",
    "width": 1920,
    "height": 1080,
    "framerate": 30
  }]
}
]]></sourcecode>
</section>

<section anchor="s-tsid-to-moq-catalog-conversion"><name>S-TSID to MoQ Catalog Conversion</name>
<t>This section and its inverse (Section 12.3) are informative: they
document a mapping for ingesting ATSC 3.0 broadcast signaling into
MoQ catalogs and exporting it back, and impose no interoperability
requirements on MoQ publishers or subscribers.  A converter's
output catalog is
subject to the normative catalog requirements of Section 12.1 like
any other catalog.</t>
<t>When ingesting ATSC 3.0 content delivered via ROUTE, generate MoQ
catalog from the S-TSID signaling table (defined in ATSC A/331
<xref target="ATSC-A331"></xref> for the ROUTE transport layer).  For MMT-delivered
content, equivalent parameters are obtained from the MP table (asset
locations, <xref target="ISO.23008-1"></xref> Clause 10.3.9) and the AL-FEC message (FEC
parameters, <xref target="ISO.23008-1"></xref> Annex C.6).  A complete worked example is given in
Appendix A.</t>
<t>Overhead arithmetic.  <tt>FECParameters@overhead</tt> is an integer
percentage.  Below, a div b is the integer quotient floor(a / b) of a
non-negative integer a and a positive integer b.  Export
(Section 12.3) rounds up, computing ceil(100 x P / K) as
(100 x P + K - 1) div K; ingest (this section) rounds down, computing
P = floor(K x overhead / 100) as (K x overhead) div 100.  The two are
matching inverses: ceil(100 x P / K) &lt;= overhead if and only if
P &lt;= (K x overhead) div 100, so ingest yields the largest P whose
exported <tt>@overhead</tt> does not exceed the ingested one.</t>
<t>The <tt>multicast</tt> field in the output uses the multicast endpoint format
defined in <xref target="MOQ-MULTICAST"></xref> Section 4.1.  Conversion rules:</t>

<ul spacing="compact">
<li><tt>RS@sIpAddr</tt> -&gt; <tt>multicast.endpoints[].sourceAddress</tt></li>
<li><tt>RS@dIpAddr</tt> -&gt; <tt>multicast.endpoints[].groupAddress</tt></li>
<li><tt>RS@dPort</tt> -&gt; <tt>multicast.endpoints[].port</tt></li>
<li>each <tt>LS</tt> SrcFlow and RepairFlow -&gt; a distinct
<tt>multicast.endpoints[].tracks[]</tt> entry, with <tt>packetId</tt> assigned per
the rule below</li>
<li><tt>LS@bw</tt> -&gt; <tt>bitrate</tt> (<xref target="I-D.ietf-moq-msf"></xref> Section 5.2.22)</li>
<li>the source composition/edit-list origin for each synchronized media
track -&gt; <tt>presentationAnchorTicks</tt>; a converter MUST preserve one
common presentation origin across audio and video and MUST NOT emit
zero merely because the source offset was unavailable</li>
<li><tt>FECParameters@overhead</tt> -&gt; <tt>fec.repairSymbols</tt>, computed as
P = (K x overhead) div 100 (overhead arithmetic above)</li>
<li><tt>fecOTI</tt> F,T -&gt; <tt>fec.sourceSymbols</tt> (K = ceil(F / T)),
<tt>fec.symbolSize</tt> (T)</li>
<li><tt>FECParameters@maximumDelay</tt> has no direct catalog mapping.  A/331
defines it as the maximum delivery delay between a source packet and
its associated repair packet, whereas <tt>fec.interleaveDepthMs</tt> is the
ISO protection-window send span from the first source or repair
packet to the last.  The converter MUST NOT copy this attribute into
<tt>interleaveDepthMs</tt>.  It sets <tt>interleaveDepthMs</tt> only when an ISO
AL-FEC <tt>protection_window_time</tt> value or an independently known
source/repair send schedule supplies that first-to-last span, using
a positive integer millisecond upper bound that covers the complete
span.  It MUST NOT round a fractional span down.  If the span is
unknown, or ISO signals zero (the size-based case), the converter
omits <tt>interleaveDepthMs</tt>.  The RFC 6330 Z parameter -- the number of
source blocks -- is likewise unrelated to interleaving and does not
map to any catalog FEC field.</li>
</ul>
<t>An ingested <tt>@overhead</tt> with K x overhead &lt; 100 yields P = 0, less
than one repair symbol per block.  A catalog cannot express that for
a flow that has a RepairFlow (<tt>repairSymbols</tt> is at least 1 when a
repair track is published, <xref target="MOQ-FEC"></xref> Section 5.1), so the
conversion of such an S-TSID fails: the converter neither rounds P
up nor emits the source flow without its RepairFlow.  The
round-trip properties of Section 12.3 assume that the ingested
<tt>@overhead</tt> was rounded up as that section specifies; an
<tt>@overhead</tt> that its producer rounded down or to nearest can ingest
to a P below the one it was computed from.</t>
<t>No OTI is carried in the output catalog.  The MoQ-side decoder
configuration is re-derived per block from the catalog fields and the
block's SSB_length (Section 7.2), and the ingested F does not survive
conversion: it yields only K = ceil(F / T), the upper bound on a
block's source symbol count (<xref target="MOQ-FEC"></xref> Section 7.4).  The transfer
length of a full MoQ-side block, K x T, exceeds the ingested F when F
is not a multiple of T.</t>
<t><tt>packetId</tt> is assigned per flow, not per <tt>tsi</tt>.  An <tt>LS</tt> (ROUTE
transport session) carrying both a SrcFlow and its RepairFlow yields
two <tt>tracks[]</tt> entries, and Section 4.1 of <xref target="MOQ-MULTICAST"></xref>
requires each <tt>packetId</tt> value to denote exactly one sub-flow across
all endpoints of the MMT sending entity (<xref target="MOQ-MULTICAST"></xref>
Section 2); reusing <tt>tsi</tt> directly would collide for a repair flow
that shares its source's <tt>tsi</tt>, and for <tt>LS</tt> elements of different
<tt>RS</tt> elements that reuse a <tt>tsi</tt>.  The converter assigns <tt>packetId</tt>
sequentially from 1, in <tt>RS</tt> document order and in <tt>tsi</tt> order
within each <tt>RS</tt>, without restarting at a new <tt>RS</tt>, and emits each
source flow immediately before its repair flow (so <tt>tsi</tt> 1
source -&gt; packetId 1, its repair -&gt; packetId 2, <tt>tsi</tt> 2
source -&gt; packetId 3); it never assigns 0, which is reserved for the
MMTP signaling flow (<xref target="MOQ-MULTICAST"></xref> Section 4.1).  The numbering
scope is the MMT sending entity, which serves exactly one MoQ
namespace (<xref target="MOQ-MULTICAST"></xref> Section 4.1) but is not limited to one
S-TSID: when the converter publishes the flows of several S-TSIDs
under one namespace, it continues the sequence from one S-TSID to
the next, in ingestion order, rather than restarting at 1, so that no
two flows of that sending entity share a value.  S-TSIDs published
under different namespaces belong to different sending entities, and
each is numbered from 1.  Flows sharing one
(sourceAddress, groupAddress, port) tuple collapse into a single
endpoint whose <tt>tracks[]</tt> array lists them all.</t>
<t><tt>timescale</tt>, the group-duration field, and <tt>mmtpMode</tt> are not carried in
S-TSID, yet they are REQUIRED fields (Section 12.1).  The converter
takes <tt>timescale</tt> from <tt>asset_timescale</tt> in the MP table when
<tt>asset_timescale_flag</tt> is 1, and uses 90 000 Hz when that flag is 0,
as specified by <xref target="ISO.23008-1"></xref> Clause 10.3.9.3.  For each timed
Asset, it obtains the presentation time of each MPU's first AU in
presentation order from the PI document when PI is present;
ISO/IEC 23008-1 Clause 10.5.2.1 says that the MPU timestamp
descriptor is ignored in that case.  Otherwise it decodes each
descriptor's 64-bit NTP <tt>mpu_presentation_time</tt> value
(<xref target="ISO.23008-1"></xref> Clause 10.5.2) and MUST NOT treat the encoded NTP
integer as a media tick count.  It converts those presentation
instants through the selected asset/media clock, retaining the
authored media timing when NTP fractional quantization does not land
on an integer media tick.  That instant is not <tt>ticks</tt>
(Section 4.4.1) when the MPU has leading pictures: <tt>ticks</tt> is that
instant plus the difference between the authored composition times
(Section 5.1) of the MPU's first AU in decode order and its
earliest-presented AU, converted to the selected timescale as
Section 4.4.1 requires.</t>
<t>The converter derives the group duration from the authored MPU/media
cadence and validates it against those <tt>ticks</tt> values.  It may emit
<tt>groupDurationMs</tt> only when the conversion to the selected timescale
is an exact positive integer tick count; when the cadence is exact
only in ticks it emits <tt>groupDurationTicks</tt>.
The fixed-cadence profile cannot represent a source whose MPU cadence
is not one constant positive duration, so conversion MUST fail rather
than round or invent a cadence.  It sets <tt>mmtpMode</tt> itself.  Nor does
S-TSID carry <tt>fec.blockProfile</tt>, which is REQUIRED for a
track whose <tt>fec.algorithm</tt> is not &quot;none&quot; (<xref target="MOQ-FEC"></xref> Section 5.1);
for such a track the converter sets it to the profile under
which the MoQ-side publisher protects the track, &quot;iso-ssbg1-v1&quot;.</t>
</section>

<section anchor="moq-catalog-to-s-tsid-conversion"><name>MoQ Catalog to S-TSID Conversion</name>
<t>When generating ATSC-compatible output, convert the MoQ catalog to
S-TSID by inverting the mapping of Section 12.2.  Conversion rules:</t>

<ul spacing="compact">
<li><tt>multicast.endpoints[].sourceAddress</tt> -&gt; <tt>RS@sIpAddr</tt></li>
<li><tt>fec.repairSymbols</tt> (P) and <tt>fec.sourceSymbols</tt> (K) -&gt;
<tt>FECParameters@overhead</tt>, computed as (100 x P + K - 1) div K
(Section 12.2)</li>
<li><tt>fec.interleaveDepthMs</tt> has no direct inverse to
<tt>FECParameters@maximumDelay</tt>: the former is the ISO protection-window
source/repair send span, while the latter is the maximum delay from a
source packet to its associated repair packet.  Emit
<tt>@maximumDelay</tt> only when the target converter separately computes
that A/331 delivery delay; otherwise omit it rather than copying
<tt>interleaveDepthMs</tt> (and document that the field was not preserved).</li>
<li><tt>fec.sourceSymbols</tt> and <tt>fec.symbolSize</tt> -&gt; <tt>fecOTI</tt>, exactly the
OTI of a full block (SSB_length = K) derived from them
(Section 7.2)</li>
</ul>
<t>Because export rounds up, for a catalog whose only FEC instance is
the source track's own, the exported overhead never understates the
catalog's repair rate.  That guarantee does not extend to a catalog
that declares layered repair tracks (<xref target="MOQ-FEC"></xref> Section 6.3) or a
keyframe overlay (<xref target="MOQ-FEC"></xref> Section 6.4).  There <tt>fec.repairSymbols</tt>
is P_0, the base layer only; layers i &gt;= 1 and the overlay carry
repair symbols of their own, and a single <tt>FECParameters@overhead</tt>
cannot represent them.  Converting such a catalog with this rule
therefore understates its repair rate, and the exported
<tt>FECParameters</tt> describes the base layer alone, not the catalog's
full repair capacity.</t>
<t>Like the rest of this section, the round-trip properties that follow
from the overhead arithmetic of Section 12.2 are informative:</t>

<ul spacing="compact">
<li>catalog -&gt; S-TSID -&gt; catalog always reproduces <tt>repairSymbols</tt> when
K &lt;= 100.  For larger K, several values of P can share one
whole-percent <tt>@overhead</tt>, and the round trip yields the largest of
them.</li>
<li>S-TSID -&gt; catalog -&gt; S-TSID always reproduces <tt>@overhead</tt> when
K &gt;= 100.  For smaller K it reproduces <tt>@overhead</tt> if and only if
the ingested value equals ceil(100 x P / K) for some P; otherwise
it yields the largest such value below the ingested one.</li>
<li>Either round trip is stable: converting its output again changes
nothing.</li>
</ul>
</section>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>
<t>MMT content protection uses Common Encryption (CENC) which is
preserved through MoQ transport.  The MMTP packet and payload
headers are not encrypted by CENC, allowing relays and receivers to
inspect packet type, sequence, and fragmentation metadata without
accessing media sample content.</t>

<section anchor="multicast-security"><name>Multicast Security</name>
<t>Multicast-specific security considerations (source authentication,
replay protection, AMT relay trust) are defined in
<xref target="MOQ-MULTICAST"></xref> Section 7.</t>
</section>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>
<t>This document defines the catalog <tt>packaging</tt> value &quot;mmtp&quot;
(Section 12.1), extending the allowed packaging values of the MoQ
Streaming Format <xref target="I-D.ietf-moq-msf"></xref> Section 5.2.4 in the same
manner as <xref target="I-D.ietf-moq-cmsf"></xref>.  If a registry of packaging
values is established for that format, this document requests
registration of:</t>
<table>
<thead>
<tr>
<th>Value</th>
<th>Description</th>
<th>Reference</th>
</tr>
</thead>

<tbody>
<tr>
<td>&quot;mmtp&quot;</td>
<td>MMTP packets carrying MPU/MFU payloads</td>
<td>This document</td>
</tr>
</tbody>
</table><t>This document requests no MoQ message type registrations.  FEC
signaling uses no MoQ control message (<xref target="MOQ-FEC"></xref> Section 5.2); no
document in this suite requests a control-message codepoint.</t>
</section>

</middle>

<back>
<references><name>References</name>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-moq-msf.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-moq-transport.xml"/>
<reference anchor="ISO.23008-1" target="">
  <front>
    <title>Information technology - High efficiency coding and media delivery in heterogeneous environments - Part 1: MPEG media transport (MMT)</title>
    <author>
      <organization>ISO/IEC</organization>
    </author>
    <date year="2023"></date>
  </front>
  <seriesInfo name="ISO/IEC" value="23008-1:2023"></seriesInfo>
</reference>
<reference anchor="ISO.23008-1.AMD1" target="">
  <front>
    <title>Information technology - High efficiency coding and media delivery in heterogeneous environments - Part 1: MPEG media transport (MMT) - Amendment 1: Signalling of adaptive FEC scheme</title>
    <author>
      <organization>ISO/IEC</organization>
    </author>
    <date year="2025" month="May"></date>
  </front>
  <seriesInfo name="ISO/IEC" value="23008-1:2023/Amd 1:2025"></seriesInfo>
</reference>
<reference anchor="MOQ-FEC" target="">
  <front>
    <title>Forward Error Correction for Media over QUIC</title>
    <author fullname="Omar Ramadan" initials="O." surname="Ramadan">
      <organization>Blockcast</organization>
    </author>
    <date year="2026"></date>
  </front>
  <seriesInfo name="Internet-Draft" value="draft-ramadan-moq-fec-00"></seriesInfo>
</reference>
<reference anchor="MOQ-MULTICAST" target="">
  <front>
    <title>Multicast Delivery and Endpoint Discovery for Media over QUIC</title>
    <author fullname="Omar Ramadan" initials="O." surname="Ramadan">
      <organization>Blockcast</organization>
    </author>
    <date year="2026"></date>
  </front>
  <seriesInfo name="Internet-Draft" value="draft-ramadan-moq-multicast-00"></seriesInfo>
</reference>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6330.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
</references>
<references><name>Informative References</name>
<reference anchor="ARIB-B60" target="">
  <front>
    <title>MMT-Based Media Transport Scheme in Digital Broadcasting Systems</title>
    <author>
      <organization>ARIB</organization>
    </author>
    <date></date>
  </front>
  <seriesInfo name="ARIB STD-B60" value="Version 1.14"></seriesInfo>
</reference>
<reference anchor="ATSC-A331" target="https://www.atsc.org/atsc-documents/3312017-signaling-delivery-synchronization-error-protection/">
  <front>
    <title>Signaling, Delivery, Synchronization, and Error Protection</title>
    <author>
      <organization>ATSC</organization>
    </author>
    <date year="2026" month="February"></date>
  </front>
  <seriesInfo name="ATSC" value="A/331:2026-02"></seriesInfo>
</reference>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-moq-cmsf.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-moq-loc.xml"/>
<reference anchor="ISO.23008-10" target="">
  <front>
    <title>Information technology - High efficiency coding and media delivery in heterogeneous environments - Part 10: MPEG media transport forward error correction (FEC) codes</title>
    <author>
      <organization>ISO/IEC</organization>
    </author>
    <date></date>
  </front>
  <seriesInfo name="ISO/IEC" value="23008-10"></seriesInfo>
</reference>
</references>
</references>

<section anchor="s-tsid-conversion-example"><name>S-TSID Conversion Example</name>
<t>This appendix is informative, like the conversion mapping it
illustrates (Section 12.2).</t>
<t>Complete example showing bidirectional conversion between
ATSC S-TSID and MoQ catalog for a multi-track service.</t>

<section anchor="original-atsc-s-tsid"><name>Original ATSC S-TSID</name>

<sourcecode type="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<S-TSID
    xmlns="tag:atsc.org,2016:XMLSchemas/ATSC3/Delivery/S-TSID/1.0/">
  <RS sIpAddr="10.0.0.1" dIpAddr="232.1.1.10" dPort="5000">
    <!-- Video 1080p -->
    <LS tsi="1" bw="7984000">
      <SrcFlow rt="true" minBuffSize="8000000">
        <ContentInfo>
          <MediaInfo contentType="video" repId="1080p" lang="en"/>
        </ContentInfo>
        <EFDT>
          <FDT-Instance Expires="4294967295">
            <File Content-Location="video/1080p/init.mp4" TOI="1"/>
          </FDT-Instance>
        </EFDT>
        <Payload codePoint="128" formatId="2" srcFecPayloadId="6"/>
      </SrcFlow>
      <RepairFlow>
        <FECParameters maximumDelay="1000" overhead="25"
                       fecOTI="F=1000000;T=1000;Z=1;N=1;Al=8">
          <ProtectedObject tsi="1">
            <SourceTOI x="0" y="65535"/>
          </ProtectedObject>
        </FECParameters>
      </RepairFlow>
    </LS>
    <!-- Audio Stereo -->
    <LS tsi="2" bw="128000">
      <SrcFlow rt="true">
        <ContentInfo>
          <MediaInfo contentType="audio" repId="stereo" lang="en"/>
        </ContentInfo>
        <Payload codePoint="128" formatId="2"/>
      </SrcFlow>
    </LS>
  </RS>
</S-TSID>
]]></sourcecode>
</section>

<section anchor="converted-moq-catalog"><name>Converted MoQ Catalog</name>

<sourcecode type="json"><![CDATA[{
  "version": "draft-01",
  "tracks": [
    {
      "name": "video/1080p",
      "packaging": "mmtp",
      "mmtpMode": "mfu",
      "timescale": 90000,
      "presentationAnchorTicks": 0,
      "groupDurationMs": 1000,
      "codec": "avc1.64001f",
      "width": 1920,
      "height": 1080,
      "framerate": 30,
      "bitrate": 7984000,
      "lang": "en",
      "fec": {
        "algorithm": "raptorq",
        "blockProfile": "iso-ssbg1-v1",
        "sourceSymbols": 1000,
        "repairSymbols": 250,
        "symbolSize": 1000,
        "reorderToleranceMs": 40,
        "repairTrack": "video/1080p/repair"
      }
    },
    {
      "name": "video/1080p/repair",
      "packaging": "fec-repair",
      "priority": 240
    },
    {
      "name": "audio/stereo",
      "packaging": "mmtp",
      "mmtpMode": "mfu",
      "timescale": 48000,
      "presentationAnchorTicks": 0,
      "groupDurationMs": 1000,
      "codec": "mp4a.40.2",
      "samplerate": 48000,
      "channelConfig": "2",
      "bitrate": 128000,
      "lang": "en"
    }
  ],
  "multicast": {
    "endpoints": [{
      "protocol": "ssm",
      "sourceAddress": "10.0.0.1",
      "groupAddress": "232.1.1.10",
      "port": 5000,
      "tracks": [
        { "name": "video/1080p",        "packetId": 1 },
        { "name": "video/1080p/repair", "packetId": 2 },
        { "name": "audio/stereo",        "packetId": 3 }
      ]
    }],
    "networkSource": [{
      "type": "amt",
      "discovery": "driad"
    }]
  }
}
]]></sourcecode>
<t>The catalog envelope is the MSF root (<xref target="I-D.ietf-moq-msf"></xref>
Section 5.1); the <tt>version</tt> value names the MSF revision the
catalog conforms to.  The converter publishes the catalog under the
namespace derived from the ingested service, and the track entries
inherit that namespace from the catalog track
(<xref target="I-D.ietf-moq-msf"></xref> Section 5.2.2).  Rendition parameters
(<tt>codec</tt>, <tt>width</tt>, <tt>bitrate</tt>, <tt>lang</tt>, ...) are the flat base track
fields of <xref target="I-D.ietf-moq-msf"></xref> Section 5.2 (Section 12.1).</t>
<t>The FEC fields recompute from the S-TSID as follows:</t>

<ul spacing="compact">
<li><tt>sourceSymbols</tt>: K = ceil(F / T) = ceil(1,000,000 / 1,000) = 1000</li>
<li><tt>repairSymbols</tt>: P = (K x overhead) div 100 = (1000 x 25) div 100
= 250 (Section 12.2); re-exporting gives <tt>@overhead</tt> =
(100 x 250 + 1000 - 1) div 1000 = 25, the ingested value
(Section 12.3)</li>
<li><tt>interleaveDepthMs</tt>: omitted.  The source S-TSID value
<tt>maximumDelay=&quot;1000&quot;</tt> describes the maximum delivery delay from a
source packet to its associated repair packet; it does not provide
the ISO protection-window send span required by this catalog field.</li>
<li><tt>blockProfile</tt>: set by the converter (Section 12.2), since S-TSID
carries none and the track's <tt>algorithm</tt> is not &quot;none&quot;</li>
<li>Derived MoQ OTI of a full block (SSB_length = K, Section 7.2):
F = K x T = 1000 x 1000 = 1,000,000 bytes, identical to the
ingested <tt>fecOTI</tt>, so the round trip is lossless</li>
</ul>
<t>This S-TSID example supplies no ISO protection-window send span, so the
converted catalog does not signal <tt>interleaveDepthMs</tt>.  If a publisher
has that span independently, it may add the field; it still does not
imply that one MoQ Group is one FEC block or that a block contains a
fixed number of Groups.  The publisher signals each block's <tt>SS_Start</tt>
and <tt>SSB_length</tt> in its repair packets (<xref target="MOQ-FEC"></xref> Sections 7.1 and
7.4).  The full-block OTI calculation above is therefore a catalog
bound and does not replace that per-block signaling.</t>
</section>
</section>

</back>

</rfc>
