<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.19 (Ruby 3.3.3) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-lcurley-moq-transfork-02" category="info" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.23.2 -->
  <front>
    <title abbrev="moqtf">Media over QUIC - Transfork</title>
    <seriesInfo name="Internet-Draft" value="draft-lcurley-moq-transfork-02"/>
    <author fullname="Luke Curley">
      <organization>Discord</organization>
      <address>
        <email>kixelated@gmail.com</email>
      </address>
    </author>
    <date year="2024" month="October" day="15"/>
    <area>wit</area>
    <workgroup>moq</workgroup>
    <abstract>
      <?line 25?>

<t>MoqTransfork is designed to serve a broadcast to an unbounded number of viewers with different latency and quality targets: the entire spectrum between real-time and VOD.
MoqTransfork itself is a media agnostic transport, allowing relays and CDNs to forward the most important content under degraded networks without knowledge of codecs, containers, or even if the content is fully encrypted.
Higher level protocols specify how to use MoqTransfork to encode and deliver video, audio, messages, or any form of live content.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Discussion of this document takes place on the
    Media Over QUIC Working Group mailing list (moq@ietf.org),
    which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/moq/"/>.</t>
      <t>Source for this draft and an issue tracker can be found at
    <eref target="https://github.com/kixelated/moq-transfork"/>.</t>
    </note>
  </front>
  <middle>
    <?line 31?>

<section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="fork">
      <name>Fork</name>
      <t>This draft is based on moq-transport-03 <xref target="moqt"/>.
The concepts, motivations, and terminology are very similar on purpose.
When in doubt, refer to the upstream draft.</t>
      <t>I absolutely believe in the motivation and potential of Media over QUIC.
The layering is phenomenal and addresses many of the problems with current live media protocols.
I fully support the goals of the working group and the IETF process.</t>
      <t>But there are practical and conceptual flaws with MoqTransport that need to be addressed.
However it's been difficult to design such an experimental protocol via committee.
Despite years of arguments in person and on GitHub, we've yet to align on even the most critical property of the transport... how to utilize QUIC.
The result is inevitably an unwieldy "compromise", consisting of a modes for each party that make everything more difficult to support or explain.</t>
      <t>In our RUSH to standardize a protocol, the QUICR solutions have led to WARP in ideals.</t>
      <t>This fork is meant to be a constructive, alternative vision.
I would like to lead by example, demonstrating that you can support real media use-cases while simplifying the protocol.
The working group will keep making progress and hopefully many of these ideas will be incorporated.</t>
      <t>The appendix contains a list of high level differences between MoqTransport and MoqTransfork.</t>
    </section>
    <section anchor="concepts">
      <name>Concepts</name>
      <t>MoqTransfork consists of:</t>
      <ul spacing="normal">
        <li>
          <t><strong>Session</strong>: An established connection between a client and server used to transmit any number of Broadcasts.</t>
        </li>
        <li>
          <t><strong>Broadcast</strong>: A collection of Tracks from a single producer (client). This is primarily used for routing, but Tracks within a Broadcast may be correlated.</t>
        </li>
        <li>
          <t><strong>Track</strong>: An append-only series of Groups, each of which can be delivered and decoded independently.</t>
        </li>
        <li>
          <t><strong>Group</strong>: An append-only series of Frames, each of which are delivered and decoded in order</t>
        </li>
        <li>
          <t><strong>Frame</strong>: A sized payload of bytes, intended to represent a single moment in time.</t>
        </li>
      </ul>
      <t>The application determines how to split data into broadcasts, tracks, groups, and frames.
MoqTransfork only is responsible for the networking and deduplication by utilizing rules encoded in headers.
This provides robust and generic one-to-many transmission, even for latency sensitive applications.</t>
      <section anchor="session">
        <name>Session</name>
        <t>A Session consists of a connection between a QUIC client and server.</t>
        <t>A session is established after the necessary QUIC, WebTransport, and MoqTransfork handshakes.
The MoqTransfork handshake consists of version and extension negotiation.</t>
        <t>The intent is that sessions are chained together via relays.
A broadcaster could establish a session with an CDN ingest edge while the viewers establish separate sessions to CDN distribution edges.
A MoqTransfork session is hop-by-hop, but the application should be designed end-to-end.</t>
      </section>
      <section anchor="broadcast">
        <name>Broadcast</name>
        <t>A Broadcast is a collection of tracks from a single producer identified by a unique path within the session.
A MoqTransfork session may be used to publish and subscribe to multiple, potentially unrelated, broadcasts.</t>
        <t>A broadcast path is an a UTF-8 string which may be discovered using a prefix.
Correlated broadcasts should utilize this and share a path, for example: <tt>meeting.1234.alice</tt> and <tt>meeting.1234.bob</tt>
A subscriber could then discover all broadcasts starting with <tt>meeting.1234.</tt></t>
        <t>The application determines if tracks within a broadcast are correlated.
For example, a "video" track and "audio" track could share timestamp domains.
This is possible as a broadcast is created by a single publisher, avoiding the need for clock synchronization.</t>
        <t>A publisher can advertise available broadcasts via an ANNOUNCE message.
This allows a subscriber to dynamically discover available broadcasts.
Alternatively, the application can discover broadcasts via an out-of-band mechanism.</t>
      </section>
      <section anchor="track">
        <name>Track</name>
        <t>A Track is a series of Groups within a Broadcast, identified by a unique name within the Broadcast.</t>
        <t>Each subscription is scoped to a single Track.
A subscription will always start at a Group boundary, either the latest group or a specified sequence number.
A subscriber chooses the ordering and priority of each subscription, hinting to the publisher which Track should arrive first during congestion.
This is critical for a decent user experience during network degradation and the core reason why QUIC can offer real-time latency.</t>
        <t>There is currently no way to discover tracks within a broadcast; it must be negotiated out-of-band.
This is often done with a named "catalog" track that lists all available tracks and their properties.
An application may choose to use static and/or dynamic track names.</t>
      </section>
      <section anchor="group">
        <name>Group</name>
        <t>A Group is an ordered stream of Frames within a Track.</t>
        <t>A group is served by a dedicated QUIC stream which may be closed on completion, reset by the publisher, or cancelled by the subscriber.
An active subscription involves delivering multiple potential concurrent groups.
The Frames within a Group will arrive reliably and in order thanks to the QUIC stream.
However, Groups within a Track can arrive in any order or not at all, and which the application should be prepared to handle.</t>
        <t>A subscriber may FETCH a specific group starting at a given byte offset.
This is similar to a HTTP request and may be used to recover from partial failures among other things.</t>
      </section>
      <section anchor="frame">
        <name>Frame</name>
        <t>A Frame is a payload of bytes within a Group.</t>
        <t>A frame is used to represent a chunk of data with a known size.
A frame should represent a single moment in time and avoid any buffering that would increase latency.</t>
      </section>
      <section anchor="liveliness">
        <name>Liveliness</name>
        <t>A media protocol can only be considered "live" if it can handle degraded network congestion.
MoqTransfork handles this by prioritizing the most important media while the remainder is starved.</t>
        <t>The importance of each broadcast/track/group/frame is signaled by the subscriber and the publisher will attempt to obey it.
This is done via the Track Priority and the Group Order.
Any data that is excessively starved may be dropped (by either endpoint) rather than block the live stream.</t>
        <t>A publisher that serves multiple sessions, commonly a relay, should prioritize on a per-session basis.
Alice may want real-time latency with a preference for audio, while Bob may want reliable playback while audio is muted.
A relay <bcp14>MAY</bcp14> forward subscriber preferences upstream, but when there is a conflict (like the above example), the publisher's preference should be used as a tiebreaker.</t>
      </section>
    </section>
    <section anchor="workflow">
      <name>Workflow</name>
      <t>This section outlines the flow of messages within a MoqTransfork session.
See the section for Messages section for the specific encoding.</t>
      <section anchor="connection">
        <name>Connection</name>
        <t>MoqTransfork runs on top of WebTransport.
WebTransport is a layer on top of QUIC and HTTP/3, required for web support.
The API is nearly identical to QUIC, however notably lacks stream IDs and has fewer available error codes.</t>
        <t>How the WebTransport connection is established is out-of-scope for this draft.
For example, a service <bcp14>MAY</bcp14> use the WebTransport handshake to perform authentication via the URL.</t>
      </section>
      <section anchor="termination">
        <name>Termination</name>
        <t>QUIC bidirectional streams have an independent send and receive direction.
Rather than deal with half-open states, MoqTransfork combines both sides.
If an endpoint closes the send direction of a stream, the peer <bcp14>MUST</bcp14> also close the send direction.</t>
        <t>MoqTransfork contains many long-lived transactions, such as subscriptions and announcements.
These are terminated when the underlying QUIC stream is terminated.</t>
        <t>To terminate a stream, an endpoint may:
- close the send direction (STREAM with FIN) to gracefully terminate (all messages are flushed).
- reset the send direction (RESET_STREAM) to immediately terminate.</t>
        <t>After resetting the send direction, an endpoint <bcp14>MAY</bcp14> close the recv direction (STOP_SENDING).
However, it is ultimately the other peer's responsibility to close their send direction.</t>
      </section>
      <section anchor="handshake">
        <name>Handshake</name>
        <t>After a connection is established, the client opens a Session Stream and sends a SESSION_CLIENT message, to which the server replies with a SESSION_SERVER message.
The session is active until either endpoint closes or resets the Session Stream.</t>
        <t>This session handshake is used to negotiate the MoqTransfork version and any extensions.
See the Extension section for more information.</t>
      </section>
      <section anchor="bidirectional-streams">
        <name>Bidirectional Streams</name>
        <t>Bidirectional streams are primarily used for control streams.
The first byte of each stream indicates the Stream Type.</t>
        <t>The second column in this table indicates which endpoint or role will create a stream.</t>
        <table>
          <thead>
            <tr>
              <th align="right">ID</th>
              <th align="left">Type</th>
              <th align="left">Role</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="right">0x0</td>
              <td align="left">Session</td>
              <td align="left">Client</td>
            </tr>
            <tr>
              <td align="right">0x1</td>
              <td align="left">Announced</td>
              <td align="left">Subscriber</td>
            </tr>
            <tr>
              <td align="right">0x2</td>
              <td align="left">Subscribe</td>
              <td align="left">Subscriber</td>
            </tr>
            <tr>
              <td align="right">0x3</td>
              <td align="left">Fetch</td>
              <td align="left">Subscriber</td>
            </tr>
            <tr>
              <td align="right">0x4</td>
              <td align="left">Info</td>
              <td align="left">Subscriber</td>
            </tr>
          </tbody>
        </table>
        <section anchor="session-1">
          <name>Session</name>
          <t>The Session stream contains all messages that are session level.</t>
          <t>The client <bcp14>MUST</bcp14> open a single Session Stream immediately after establishing the QUIC/WebTransport session.
The client sends a SESSION_CLIENT message and the server replies with a SESSION_SERVER message.</t>
          <t>Afterwards, both endpoints <bcp14>SHOULD</bcp14> send SESSION_UPDATE messages, such as after a significant change in the session bitrate.</t>
          <t>The session remains active until the Session Stream is closed or reset by either endpoint.</t>
          <section anchor="versions">
            <name>Versions</name>
            <t>The SESSION_CLIENT and SESSION_SERVER messages are used to negotiate versions.
This draft's version is combined with the constant <tt>0xff0bad00</tt>.</t>
            <t>For example, moq-transfork-draft-03 is identified as <tt>0xff0bad03</tt>.</t>
            <t>A client may advertise support for multiple versions.
The server chooses one of the supported versions, or errors if none of the listing versions are supported.</t>
          </section>
        </section>
        <section anchor="announce">
          <name>Announce</name>
          <t>A subscriber can open a Announce Stream to discover broadcasts matching a prefix.
This is <bcp14>OPTIONAL</bcp14> and the application can determine broadcast paths out-of-band.</t>
          <t>The subscriber <bcp14>MUST</bcp14> start the stream with a ANNOUNCE_INTEREST message.
The publisher <bcp14>MAY</bcp14> reply with any number of ANNOUNCE message to indicate when a broadcast has started or stopped.
Both sides may close/reset the stream at any point.</t>
          <t>The publisher <bcp14>SHOULD</bcp14> send an ANNOUNCE message for each broadcast path that matches the prefix.
There <bcp14>MAY</bcp14> be multiple Announce Streams, potentially containing overlapping prefixes, that get their own copy of each ANNOUNCE.
The publisher <bcp14>MAY</bcp14> choose to not ANNOUNCE matching streams, such as when they are private or the prefix is too expansive.
The publisher <bcp14>SHOULD</bcp14> close the stream with an error code when this happens.</t>
          <t>When a broadcast has ended, the publisher sends an ANNOUNCE message with an identical name.
This will toggle the availability of the broadcast and avoids the need for a dedicated UNANNOUNCE message.</t>
        </section>
        <section anchor="subscribe">
          <name>Subscribe</name>
          <t>A subscriber can open a Subscribe Stream to request a named track within a broadcast.</t>
          <t>The subscriber <bcp14>MUST</bcp14> start a Info Stream with a SUBSCRIBE message followed by any number SUBSCRIBE_UPDATE messages.
The publisher <bcp14>MUST</bcp14> reply with an INFO message followed by any number of GROUP_DROPPED messages.
A publisher <bcp14>MAY</bcp14> reset the stream at any point if it is unable to serve the subscription.</t>
          <t>The publisher <bcp14>MUST</bcp14> transmit a complete Group Stream or a GROUP_DROPPED message for each Group within the subscription range.
This means the publisher <bcp14>MUST</bcp14> transmit a GROUP_DROPPED if a Group Stream is reset.
The subscriber <bcp14>SHOULD</bcp14> close the subscription when all GROUP and GROUP_DROP messages have been received, and the publisher <bcp14>MAY</bcp14> close the subscription after all messages have been acknowledged.</t>
        </section>
        <section anchor="fetch">
          <name>Fetch</name>
          <t>A subscriber can open a Fetch Stream to receive a single Group at a specified offset.
This is primarily used to recover from an abrupt stream termination, causing the truncation of a Group.</t>
          <t>The subscriber <bcp14>MUST</bcp14> start a Fetch Stream with a FETCH message followed by any number of FETCH_UPDATE messages.
The publisher <bcp14>MUST</bcp14> reply with the contents of a Group Stream, except starting at the specified offset <em>after</em> the GROUP message.
Note that this includes any FRAME messages.</t>
          <t>The fetch is active until both endpoints close the stream, or either endpoint resets the stream.</t>
        </section>
        <section anchor="info">
          <name>Info</name>
          <t>A subscriber can open an Info Stream to request information about a track.
This is not often necessary as SUBSCRIBE will trigger an INFO reply.</t>
          <t>The subscriber <bcp14>MUST</bcp14> start the stream with a INFO_REQUEST message.
The publisher <bcp14>MUST</bcp14> reply with an INFO message or reset the stream.
Both endpoints <bcp14>MUST</bcp14> close the stream afterwards.</t>
        </section>
      </section>
      <section anchor="unidirectional">
        <name>Unidirectional</name>
        <t>Unidirectional streams are used for subscription data.</t>
        <table>
          <thead>
            <tr>
              <th align="right">ID</th>
              <th align="left">Stream</th>
              <th align="left">Role</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="right">0x0</td>
              <td align="left">Group</td>
              <td align="left">Publisher</td>
            </tr>
          </tbody>
        </table>
        <section anchor="group-1">
          <name>Group</name>
          <t>A publisher creates Group Streams in response to a Subscribe Stream.</t>
          <t>A Group Stream <bcp14>MUST</bcp14> start with a GROUP message and <bcp14>MAY</bcp14> be followed by any number of FRAME messages.
An application <bcp14>MAY</bcp14> use an empty GROUP and/or FRAME to signal gaps.</t>
          <t>Both the publisher and subscriber <bcp14>MAY</bcp14> reset the stream at any time.
When a Group stream is reset, the publisher <bcp14>MUST</bcp14> send a GROUP_DROP message on the corresponding Subscribe stream.
A future version of this draft may utilize reliable reset instead.</t>
        </section>
      </section>
    </section>
    <section anchor="encoding">
      <name>Encoding</name>
      <t>This section covers the encoding of each message.</t>
      <t>Note that these message do not currently contain a type identifier.
The message type is determined by the stream type and the current state.</t>
      <section anchor="types">
        <name>Types</name>
        <t>Unless otherwise indicated, all types are big-endian (network order).</t>
        <t><tt>(i)</tt>:
A QUIC VarInt with a maximum size of 62-bits.
The highest two bits in the first byte indicate the total size; 1 bytes, 2 bytes, 4 bytes or 8 bytes.
This value is unsigned unless otherwise indicated.</t>
        <t><tt>(b)</tt>:
VarInt size followed by that many indicated bytes.</t>
        <t><tt>(s)</tt>:
A VarInt size followed by that many indicated bytes.
The bytes <bcp14>MUST</bcp14> be a valid UTF-8 string.</t>
      </section>
      <section anchor="sessionclient">
        <name>SESSION_CLIENT</name>
        <t>The client advertises supported versions and any extensions.</t>
        <artwork><![CDATA[
SESSION_CLIENT Message {
  Supported Versions Count (i)
  Supported Version (i)
  Extension Count (i)
  [
    Extension ID (i)
    Extension Payload (b)
  ]...
}
]]></artwork>
      </section>
      <section anchor="sessionserver">
        <name>SESSION_SERVER</name>
        <t>The server responds with the selected version and any extensions.</t>
        <artwork><![CDATA[
SESSION_SERVER Message {
  Selected Version (i)
  Extension Count (i)
  [
    Extension ID (i)
    Extension Payload (b)
  ]...
}
]]></artwork>
      </section>
      <section anchor="sessionupdate">
        <name>SESSION_UPDATE</name>
        <artwork><![CDATA[
SESSION_UPDATE Message {
  Session Bitrate (i)
}
]]></artwork>
        <t><strong>Session Bitrate</strong>:
The estimated bitrate of the QUIC connection in bits per second.
This <bcp14>SHOULD</bcp14> be sourced directly from the QUIC congestion controller.
A value of 0 indicates that this information is not available.</t>
      </section>
      <section anchor="announceinterest">
        <name>ANNOUNCE_INTEREST</name>
        <t>A subscriber sends an ANNOUNCE_INTEREST message to indicate it wants any cooresponding ANNOUNCE messages.</t>
        <artwork><![CDATA[
ANNOUNCE_INTEREST Message {
  Broadcast Prefix (s),
}
]]></artwork>
        <t><strong>Broadcast Prefix</strong>:
Indicate interest for any broadcasts that start with this prefix.
The publisher <bcp14>SHOULD</bcp14> reply with an ANNOUNCE message for any matching broadcasts.</t>
      </section>
      <section anchor="announce-1">
        <name>ANNOUNCE</name>
        <t>A publisher sends an ANNOUNCE message to advertise a broadcast.</t>
        <artwork><![CDATA[
ANNOUNCE Message {
  Broadcast Path (s),
}
]]></artwork>
        <t><strong>Broadcast Path</strong>
The broadcast path.
This <bcp14>MUST</bcp14> start with the requested prefix.</t>
      </section>
      <section anchor="subscribe-1">
        <name>SUBSCRIBE</name>
        <t>SUBSCRIBE is sent by a subscriber to start a subscription.</t>
        <artwork><![CDATA[
SUBSCRIBE Message {
  Subscribe ID (i)
  Broadcast Name (b)
  Track Name (b)
  Track Priority (i)
  Group Order (i)
  Group Expires (i)
  Group Min (i)
  Group Max (i)
}
]]></artwork>
        <t><strong>Subscribe ID</strong>:
A unique idenfier chosen by the subscriber.
A Subscribe ID <bcp14>MUST NOT</bcp14> be reused within the same session, even if the prior subscription has been closed.</t>
        <t><strong>Broadcast Name</strong>:
The name of the broadcast.
A zero-sized name is valid but not recommended.</t>
        <t><strong>Track Name</strong>:
The name of the track.
A zero-sized name is valid but not recommended.</t>
        <t><strong>Track Priority</strong>:
The transmission priority of the subscription relative to all other active subscriptions within the session.
The publisher <bcp14>SHOULD</bcp14> transmit <em>higher</em> values first during congestion.</t>
        <t><strong>Group Order</strong>:
The transmission order of the Groups within the subscription.
The publisher <bcp14>SHOULD</bcp14> transmit groups based on their sequence number in default (0), ascending (1), or descending (2) order.</t>
        <t><strong>Group Expires</strong>:
A duration in milliseconds that applies to all Groups within the subscription.
The group <bcp14>SHOULD</bcp14> be dropped if this duration has elapsed after group has finished, including any time spent cached.
The publisher's Group Expires value (via INFO) <bcp14>SHOULD</bcp14> be used instead when smaller.</t>
        <t><strong>Group Min</strong>:
The minimum group sequence number plus 1.
A value of 0 indicates the latest Group Sequence as determined by the publisher.</t>
        <t><strong>Group Max</strong>:
The maximum group sequence number plus 1.
A value of 0 indicates there is no maximum and the subscription continues indefinitely.</t>
      </section>
      <section anchor="subscribeupdate">
        <name>SUBSCRIBE_UPDATE</name>
        <t>A subscriber can modify a subscription with a SUBSCRIBE_UPDATE message.</t>
        <artwork><![CDATA[
SUBSCRIBE_UPDATE Message {
  Track Priority (i)
  Group Order (i)
  Group Expires (i)
  Group Min (i)
  Group Max (i)
}
]]></artwork>
        <t><strong>Track Priority</strong>:
The new track priority; see SUBSCRIBE.
The publisher <bcp14>SHOULD</bcp14> use the new priority for any blocked streams.</t>
        <t><strong>Group Order</strong>:
The new group order; see SUBSCRIBE.
The publisher <bcp14>SHOULD</bcp14> use the new order for any blocked streams.</t>
        <t><strong>Group Min</strong>:
The new minimum group sequence, or 0 if there is no update.
This value <bcp14>MUST NOT</bcp14> be smaller than prior SUBSCRIBE and SUBSCRIBE_UPDATE messages.</t>
        <t><strong>Group Max</strong>:
The new maximum group sequence, or 0 if there is no update.
This value <bcp14>MUST NOT</bcp14> be larger than prior SUBSCRIBE or SUBSCRIBE_UPDATE messages.</t>
        <t>If the Min and Max are updated, the publisher <bcp14>SHOULD</bcp14> reset any blocked streams that are outside the new range.</t>
      </section>
      <section anchor="info-1">
        <name>INFO</name>
        <t>The INFO message contains the current information about a track.</t>
        <artwork><![CDATA[
INFO Message {
  Track Priority (i)
  Group Latest (i)
  Group Order (i)
  Group Expires (i)
}
]]></artwork>
        <t><strong>Track Priority</strong>:
The priority of this track within the <em>broadcast</em>.
Note that this is slightly different than SUBSCRIBE, which is scoped to a session not broadcast.
The publisher <bcp14>SHOULD</bcp14> transmit subscriptions with <em>higher</em> values first during congestion.</t>
        <t><strong>Group Latest</strong>:
The latest group as currently known by the publisher.
A relay without an active subscription <bcp14>SHOULD</bcp14> forward this request upstream</t>
        <t><strong>Group Order</strong>:
The publisher's intended order of the groups within the subscription: none (0), ascending (1), or descending (2).</t>
        <t><strong>Group Expires</strong>:
A duration in milliseconds.
The group <bcp14>SHOULD</bcp14> be dropped if this duration has elapsed after group has finished, including any time spent cached.
The Subscriber's Group Expires value <bcp14>SHOULD</bcp14> be used instead when smaller.</t>
      </section>
      <section anchor="inforequest">
        <name>INFO_REQUEST</name>
        <t>The INFO_REQUEST message is used to request an INFO response.</t>
        <artwork><![CDATA[
INFO_REQUEST Message {
  Broadcast Name (b)
  Track Name (b)
}
]]></artwork>
      </section>
      <section anchor="fetch-1">
        <name>FETCH</name>
        <t>A subscriber can request a byte offset within a Group with a FETCH message.</t>
        <artwork><![CDATA[
FETCH Message {
  Broadcast Name (b)
  Track Name (b)
  Track Priority (i)
  Group Sequence (i)
  Group Offset (i)
}
]]></artwork>
        <t><strong>Track Priority</strong>:
The priority of the group relative to all other FETCH and SUBSCRIBE requests within the session.
The publisher should transmit <em>higher</em> values first during congestion.</t>
        <t><strong>Group Offset</strong>:
The requested offset in bytes <em>after</em> the GROUP message.</t>
      </section>
      <section anchor="fetchupdate">
        <name>FETCH_UPDATE</name>
        <t>A subscriber can modify a FETCH request with a FETCH_UPDATE message.</t>
        <artwork><![CDATA[
FETCH_UPDATE Message {
  Track Priority (i)
}
]]></artwork>
        <t><strong>Track Priority</strong>:
The priority of the group relative to all other FETCH and SUBSCRIBE requests within the session.
The publisher should transmit <em>higher</em> values first during congestion.</t>
      </section>
      <section anchor="group-2">
        <name>GROUP</name>
        <t>The GROUP message contains information about a Group, as well as a reference to the subscription being served.</t>
        <artwork><![CDATA[
GROUP Message {
  Subscribe ID (i)
  Group Sequence (i)
}
]]></artwork>
        <t><strong>Subscribe ID</strong>:
The corresponding Subscribe ID.
This ID is used to distinguish between multiple subscriptions for the same track.</t>
        <t><strong>Group Sequence</strong>:
The sequence number of the group.</t>
      </section>
      <section anchor="groupdrop">
        <name>GROUP_DROP</name>
        <t>A publisher transmits a GROUP_DROP message when it is unable to serve a group for a SUBSCRIBE.</t>
        <artwork><![CDATA[
GROUP_DROP {
  Group Start (i)
  Group Count (i)
  Group Error Code (i)
}
]]></artwork>
        <t><strong>Group Start</strong>:
The sequence number for the first group within the dropped range.</t>
        <t><strong>Group Count</strong>:
The number of additional groups after the first.
This value is 0 when only one group is dropped.</t>
        <t><strong>Error Code</strong>:
An error code indicated by the application.</t>
      </section>
      <section anchor="frame-1">
        <name>FRAME</name>
        <t>The FRAME message is a payload at a specific point of time.</t>
        <artwork><![CDATA[
FRAME Message {
  Payload (b)
}
]]></artwork>
        <t><strong>Payload</strong>:
An application specific payload.
A generic library or relay <bcp14>MUST NOT</bcp14> inspect or modify the contents unless otherwise negotiated.</t>
      </section>
    </section>
    <section anchor="appendix-changelog">
      <name>Appendix: Changelog</name>
      <t>Notable changes between versions of this draft.</t>
      <section anchor="moq-transfork-02">
        <name>moq-transfork-02</name>
        <ul spacing="normal">
          <li>
            <t>Document version numbers.</t>
          </li>
          <li>
            <t>Added ANNOUNCE_INTEREST to opt-into ANNOUNCE messages.</t>
          </li>
          <li>
            <t>Remove ROLE extension.</t>
          </li>
        </ul>
      </section>
      <section anchor="moq-transfork-01">
        <name>moq-transfork-01</name>
        <ul spacing="normal">
          <li>
            <t>Removed datagram support</t>
          </li>
          <li>
            <t>Removed native QUIC support</t>
          </li>
          <li>
            <t>Moved Expires from GROUP to SUBSCRIBE</t>
          </li>
          <li>
            <t>Added FETCH_UPDATE</t>
          </li>
          <li>
            <t>Added ROLE=Any</t>
          </li>
          <li>
            <t>Track Priority is now descending.</t>
          </li>
        </ul>
        <t>Datagram and native QUIC support may be re-added in a future draft.</t>
      </section>
      <section anchor="moq-transfork-00">
        <name>moq-transfork-00</name>
        <t>Based on moq-transport-03.
The significant changes have been broken into sections.</t>
        <section anchor="bikeshedding">
          <name>Bikeshedding</name>
          <ul spacing="normal">
            <li>
              <t>Renamed Track Namespace to Broadcast</t>
            </li>
            <li>
              <t>Renamed Object to Frame</t>
            </li>
          </ul>
        </section>
        <section anchor="stream-per-group">
          <name>Stream per Group</name>
          <t>The MoQ WG couldn't agree on how to utilize QUIC streams, so the compromise was to support multiple modes and let the application choose.
This is a headache for too many reasons to list.
MoqTransfork only "supports" a stream per group.</t>
        </section>
        <section anchor="subscribers-choice">
          <name>Subscriber's Choice</name>
          <t>MoqTransfork moves most decision making to the subscriber, so a single publisher can support multiple diverse subscribers.
The publisher provides a default value to resolve conflicts when deduplicating.</t>
        </section>
        <section anchor="control-streams">
          <name>Control Streams</name>
          <t>Transactions like Announce and Subscribe use their own control stream, inheriting the stream state machine for error handling.</t>
          <t>This replaces excessive message types in MoqTransport:
- Removed ANNOUNCE_ERROR
- Removed ANNOUNCE_DONE
- Removed UNANNOUNCE
- Removed SUBSCRIBE_OK
- Removed SUBSCRIBE_ERROR
- Removed SUBSCRIBE_DONE
- Removed UNSUBSCRIBE</t>
        </section>
        <section anchor="unambiguous-delivery">
          <name>Unambiguous Delivery</name>
          <t>With MoqTransfork, the subscriber knows if a group/frame will be delivered or was dropped.</t>
          <ul spacing="normal">
            <li>
              <t>Group Sequences are sequential</t>
            </li>
            <li>
              <t>All sequences within the SUBSCRIBE range are delivered or dropped.</t>
            </li>
            <li>
              <t>GROUP_DROP when a group is dropped.</t>
            </li>
          </ul>
        </section>
        <section anchor="fetch-via-offset">
          <name>Fetch via Offset</name>
          <t>A reconnecting subscriber can request the retransmission of a group/stream at a given byte offset.
Resumption in MoqTransport is more complicated and can only occur at object/group boundaries.</t>
        </section>
        <section anchor="track-info">
          <name>Track INFO</name>
          <t>Added a mechanism to request information about the current track state.</t>
          <ul spacing="normal">
            <li>
              <t>Added INFO_REQUEST and INFO</t>
            </li>
            <li>
              <t>Replaced SUBSCRIBE_OK with INFO</t>
            </li>
          </ul>
        </section>
      </section>
    </section>
    <section anchor="appendix-media-use-cases">
      <name>Appendix: Media Use-Cases</name>
      <t>These are some recommended ways to use MoqTransfork for media delivery.</t>
      <section anchor="video">
        <name>Video</name>
        <t>Video encoding involves complex dependencies between frames/slices.
The terminology in this section stems from H.264 but is applicable to most modern codecs.</t>
        <t>Each frame of video is encoded as one or more slices but to simplify the discussion, we'll refer to a slice as a frame.
There are three types of frames:</t>
        <ul spacing="normal">
          <li>
            <t><strong>I-Frame</strong>: A frame that can be decoded independently.</t>
          </li>
          <li>
            <t><strong>P-Frame</strong>: A frame that depends on previous frames.</t>
          </li>
          <li>
            <t><strong>B-Frame</strong>: A frame that depends on previous or future frames.</t>
          </li>
        </ul>
        <section anchor="group-of-pictures">
          <name>Group of Pictures</name>
          <t>A simple application can ignore the complexity of P/B frames and focus on I-Frames.
This is the optimal approach for many encoding configurations.</t>
          <t>Each I-Frame begins a Group of Pictures (GoP).
A GoP is a set of frames that <bcp14>MAY</bcp14> depend on each other and <bcp14>MUST NOT</bcp14> depend on other GoPs.
Each frame has a decode order (DTS) and a frame <bcp14>MUST NOT</bcp14> depend on frames with a higher DTS.</t>
          <t>This perfectly maps to a QUIC stream, as they too are independent and ordered.
The easiest way to use MoqTransfork is to send each GoP as a GROUP with each frame as a FRAME, hence the names.</t>
          <t>Each SUBSCRIBE starts at a Group to ensure that it starts with an I-Frame.
Each Group is delivered in decode order ensuring that all frames are decodable (no artifacts).</t>
          <t>A subscriber can choose the Group Order based on the desired user experience:</t>
          <ul spacing="normal">
            <li>
              <t><tt>SUBSCRIBE order=DESC</tt>: Transmits new Groups first to allow skipping, intended for low-latency live streams.</t>
            </li>
            <li>
              <t><tt>SUBSCRIBE order=ASC</tt>: Transmits old Groups first to avoid skipping, intended for VOD and reliable live streams.</t>
            </li>
          </ul>
          <t>A publisher or subscriber can skip the remainder of a Group by resetting a Group Stream or by issuing a SUBSCRIBE_UPDATE.
A FETCH can be used to recover any partial groups.</t>
        </section>
        <section anchor="layers">
          <name>Layers</name>
          <t>An advanced application can subdivide a GoP into layers.</t>
          <t>The most comprehensive way to do this is with Scalable Video Coding (SVC).
There is a base layer and one or more enhancement layers that depend on lower layers.
For example, a 4K stream could be broken into 4K, 1080p, and 360p (base) layers.
However, SVC has limited support and is complex to encode.</t>
          <t>Another approach is to use temporal scalability via something like B-pyramids.
The frames within a GoP are sub-divided based on their dependencies, intentionally creating a hierarchy.
For example, even frames could be prevented from referencing odd frames, creating a base 30fps layer and an enhancement 60fps layer.
This is effectively a custom SVC scheme however it's limited to time and doesn't require special decoder support.</t>
          <t>The purpose of these layers is to support degrading the quality of the broadcast.
A subscriber could limit bandwidth usage by choose to only receive the base layer or a subset of the enhancements layers.
During congestion, the base layer can be prioritized while the enhancement layers can be deprioritized or dropped.
However, the cost is a small increase in bitrate (10%) as limiting potential references can only hurt the compression ratio.</t>
          <t>When using MoqTransfork, each layer is delivered as a separate Track.
This allows the subscriber to choose which layers to receive and how to prioritize them in SUBSCRIBE.
It also enables layers to be prioritized within the layer application, for example Alice's base layer is more important than Bob's enhancement layer.</t>
          <t>The application is responsible for determining the relationship between layers, since they're unrelated tracks as MoqTransport is concerned.
The application could use a catalog to advertise the layers and how to synchronize them, for example based on the Group Sequence.</t>
        </section>
        <section anchor="non-reference-frames">
          <name>Non-Reference Frames</name>
          <t>While not explicitly stated, I believe the complexity in MoqTransport stems almost entirely from a single use-case: the ability to drop individual non-reference frames in the middle of a group.</t>
          <t>In theory, transmitting enhancement layers as tracks like mentioned above could introduce head-of-line blocking depending on the encoding.
This would occur when enhancement layers are not self-referential, a rare configuration which also hurts the compression ratio.
And in practice, there's no discernable user impact given the disproportionate size difference between base and enhancement layers.</t>
          <t>The ability to drop individual non-reference frames in the middle of a group is an explicit non-goal for MoqTransfork.</t>
        </section>
      </section>
      <section anchor="audio">
        <name>Audio</name>
        <t>Unlike video, audio is simple and yet has perhaps more potential for optimization.</t>
        <section anchor="frames">
          <name>Frames</name>
          <t>Audio samples are very small and for the sake of compression, are grouped into a frame.
This depends on the codec and the sample rate but each frame is typically 10-50ms of audio.</t>
          <t>Audio frames are independent, which means they map nicely to MoqTransfork Groups.
Each audio frame can be transmitted as a GROUP with a single FRAME.</t>
        </section>
        <section anchor="groups">
          <name>Groups</name>
          <t>Audio FRAMEs can also be combined into periodic GROUPs to reduce overhead at the cost of some introducing head-of-line blocking.
This won't increase latency except under significant congestion as each FRAME is still streamed.</t>
          <t>For example, an application could then subscribe to video and audio starting at group X for both tracks, instead of trying to maintain a mapping between the two based on timestamp.
This is quite common in HLS/DASH as there's no reason to subdivide audio segments at frame boundaries.</t>
        </section>
        <section anchor="fec">
          <name>FEC</name>
          <t>Real-time audio applications often use Forward Error Correction (FEC) to conceal packet loss.
Audio frames are a good candidate for FEC given that they are small and independent.</t>
          <t>In an ideal world, FEC would be performed by QUIC based on the properties of the hop.
However this is not currently not supported and FEC is left to the application.</t>
          <t>In MoqTransfork, each FEC packet is transmitted as a separate GROUP with a single FRAME.
A real-time subscriber issues a <tt>SUBSCRIBE</tt> with an aggressive <tt>Group Expires</tt> value in the milliseconds range.
The publisher will drop any Groups that have not been transmitted or acknowledged within this time frame, potentially causing them to be lost.</t>
          <t>Normally, FEC is performed by transmitting individual packets once as datagrams.
However, QUIC streams are useful as they allow retransmissions when <tt>Group Expires</tt> is smaller than the RTT.
If the RTT is too high, then the RESET_STREAM frame adds some overhead but it's inconsequential (~10 more bytes).
This enables retransmitting lost packets on short hops and otherwise relying on FEC for long hops.</t>
        </section>
      </section>
      <section anchor="metadata">
        <name>Metadata</name>
        <t>There's a number of non-media use cases that can be served by MoqTransfork.</t>
        <section anchor="catalog">
          <name>Catalog</name>
          <t>Originally part of the transport itself, the catalog is a list of all tracks within a broadcast.
It's since been delegated to the application and is now just another track with a well-known name.</t>
          <t>The proposed MoQ catalog format supports live updates.
It does this by encoding a base JSON blob and then applying JSON patches over time.
If the number of deltas becomes too large, the producer can start over with a new base JSON blob.</t>
          <t>In MoqTransfork, the base and all deltas are a single GROUP.
The base is the first FRAME and all deltas are subsequent FRAMEs.
The producer can create a new GROUP to start over, repeating the process.</t>
        </section>
        <section anchor="timeline">
          <name>Timeline</name>
          <t>Another track that is commonly pitched is a timeline track.
This records the presentation timestamp of each Group, giving a VOD viewer to seek to a specific time.</t>
          <t>The <tt>timeline</tt> track is a single Group containing a Frame for each timestamp.
The live nature of the timeline track is great for DVR applications while being concise enough for VOD.
Timed metadata would use a similar approach or perhaps leverage this track.</t>
        </section>
        <section anchor="interaction">
          <name>Interaction</name>
          <t>Another common use-case is to transmit user interactions, such as controller inputs or chat messages.
It's up to the application to determine the format and encoding of these messages.</t>
          <t>Let's take controller input as an example.
The application needs to determine its loss vs latency tolerance, as reordering or dropping inputs will lead to a poor user experience.</t>
          <ul spacing="normal">
            <li>
              <t>If you don't want loss, then use a single GROUP with a FRAME per input.</t>
            </li>
            <li>
              <t>If you don't want latency, then use a GROUP per input with a single FRAME.</t>
            </li>
            <li>
              <t>If you want a hybrid, then use form of clustering inputs into GROUPs and FRAMEs based on time.</t>
            </li>
          </ul>
          <t>A publisher could monitor the session RTT or stream acknowledgements to get a sense of the latency and create Groups accordingly.
However, this only applies to the first hop and won't be applicable when relays are involved.</t>
        </section>
      </section>
      <section anchor="latency">
        <name>Latency</name>
        <t>One explicit goal of MoqTransfork is to support multiple latency targets.</t>
        <t>This is accomplished by using the same Tracks and Group for all viewers, but slightly changing the behavior based on the subscription.
This is driven by the subscriber, allowing them to choose the trade-off between latency and reliability.
This may be done on the fly via SUBSCRIBE_UPDATE, for example if a high-latency viewer wishes to join the stage and suddenly needs real-time latency.</t>
        <t>The below examples assume one audio and one video track.
See the next section for more complicated broadcasts.</t>
        <section anchor="real-time">
          <name>Real-Time</name>
          <t>Real-time latency is accomplished by prioritizing the most important media during congestion and skipping the rest.</t>
          <t>This is slightly different from other media protocols which instead opt to drop packets.
The end result is similar, but prioritization means utilizing all available bandwidth as determined by the congestion controller.
A subscriber or publisher can reset groups to avoid wasting bandwidth on old data.</t>
          <t>A real-time viewer could issue:</t>
          <artwork><![CDATA[
SUBSCRIBE track=audio priority=1 order=DESC group_expires=100ms
SUBSCRIBE track=video priority=0 order=DESC group_expires=100ms
]]></artwork>
          <t>In this example, audio is higher priority than video, and newer groups are higher priority than older groups.
Suppose a viewer fell behind after a burst of congestion and has to decide which groups to deliver next.
This configuration would result in the transmission order:</t>
          <artwork><![CDATA[
GROUP track=audio sequence=102
GROUP track=audio sequence=101
GROUP track=audio sequence=100
GROUP track=video sequence=5
GROUP track=video sequence=4
]]></artwork>
          <t>The user experience depends on the amount of congestion:</t>
          <ul spacing="normal">
            <li>
              <t>If there's no congestion, all audio and video is delivered.</t>
            </li>
            <li>
              <t>If there's moderate congestion, the tail of the old video group is dropped.</t>
            </li>
            <li>
              <t>If there's severe congestion, all video will be late/dropped and some audio groups/frames will be dropped.</t>
            </li>
          </ul>
          <t>The value of <tt>group_expires</tt> is optional.
In this example it means that the publisher automatically resets each group 100ms after they are no longer the latest.
It's recommended to use the maximum jitter buffer size.</t>
        </section>
        <section anchor="unreliable-live">
          <name>Unreliable Live</name>
          <t>Unreliable live is a term I made up.
Basically we want low latency, but we don't need it at all costs and we're willing to skip some video to achieve it.
This is useful for broadcasts where latency is important but so is picture quality.</t>
          <t>An unreliable live viewer could issue:</t>
          <artwork><![CDATA[
SUBSCRIBE track=audio priority=1 order=ASC
SUBSCRIBE track=video priority=0 order=DESC group_expires=3s
]]></artwork>
          <t>This example is different from the real-time one in that audio is fully reliable and delivered in order.
Of course this is optional and up to the application, as it will result in buffering during significant congestion.
If the viewer goes through a tunnel and then comes back online, they won't miss any audio.</t>
          <t>A key difference is that our jitter buffer is much larger for video, 3s in this example.
The player will tolerate up to 3s of latency before it starts skipping past video frames.
Note that the <tt>group_expires</tt> value can be increased during buffering by issuing a SUBSCRIBE_UPDATE.</t>
        </section>
        <section anchor="reliable-live">
          <name>Reliable Live</name>
          <t>Reliable live is another term I made up.
This is when we have a live stream but primarily care about picture quality.
A good example is a sports game where you want to see every frame.</t>
          <t>A reliable live viewer could issue:</t>
          <artwork><![CDATA[
SUBSCRIBE track=audio priority=0 order=ASC
SUBSCRIBE track=video priority=0 order=ASC
]]></artwork>
          <t>This will deliver both audio and video in order, and with the same priority.
The viewer won't miss any content unless the publisher resets a group.
However, this can result in buffering during congestion and provides a similar user experience to HLS/DASH.</t>
        </section>
        <section anchor="vod-dvr">
          <name>VOD / DVR</name>
          <t>Video on Demand (VOD) and Digital Video Recorder (DVR) both involve seeking backwards in a live stream.
MoqTransfork can serve this use-case too, don't worry.</t>
          <t>A VOD viewer could issue:</t>
          <artwork><![CDATA[
SUBSCRIBE track=audio priority=0 order=ASC start=345 end=396
SUBSCRIBE track=video priority=0 order=ASC start=123 end=134
]]></artwork>
          <t>The application is responsible for determining the group sequence numbers based on the desired timestamp.
This could be done via a <tt>timeline</tt> track or out-of-band.</t>
          <t>A subscriber will need a specific <tt>end</tt> or else it will download too much data at once, as old media is transmitted at network speed and not encode speed.
It will need to issue an updated SUBSCRIBE to expand the range as playback continues and the buffer depletes.
A subscriber could use SUBSCRIBE_UPDATE, however there are race conditions involved.</t>
          <t>A DVR player does the same thing but can automatically support joining the live stream.
It's perfectly valid to specify a <tt>end</tt> in the future and it will behave like reliable live viewer once it reaches the live playhead.</t>
          <t>Alternatively, a DVR player could prefetch the live playhead by issuing a parallel SUBSCRIBE at a lower priority.
This would allow playback to immediately continue after clicking the "Go Live" button, canceling or deprioritizing the VOD subscription.</t>
          <artwork><![CDATA[
SUBSCRIBE track=video priority=1 order=ASC start=123 end=134
SUBSCRIBE track=video priority=0 order=DESC
]]></artwork>
        </section>
        <section anchor="upstream">
          <name>Upstream</name>
          <t>All of these separate viewers could be watching the same broadcast.
How is a relay supposed to fetch the content from upstream?</t>
          <t>MoqTransfork addresses this by providing the publisher's Track Priority and Group Order in the INFO message.
This is the intended behavior for the first hop and dictates which viewers are preferred.</t>
          <t>For example, suppose the producer chooses:</t>
          <artwork><![CDATA[
INFO track=audio priority=1 order=DESC
INFO track=video priority=0 order=DESC
]]></artwork>
          <t>If Alice is watching a VOD and issues:</t>
          <artwork><![CDATA[
SUBSCRIBE track=audio priority=0 order=ASC
SUBSCRIBE track=video priority=0 order=ASC
]]></artwork>
          <t>If Bob is watching real-time and issues:</t>
          <artwork><![CDATA[
SUBSCRIBE track=audio priority=1 order=DESC
SUBSCRIBE track=video priority=0 order=DESC
]]></artwork>
          <t>For any congestion on the first mile, then the relay will improve Bob's experience by following the producer's preference.
However any congestion on the last mile will always use the viewer's preference.</t>
          <t>A relay should use the publisher's priority/order only when there's a conflict.
If viewers have the same priority/order, then the relay should use the viewer's preference and it can always issue a SUBSCRIBE_UPDATE when this changes.</t>
        </section>
      </section>
      <section anchor="broadcast-1">
        <name>Broadcast</name>
        <t>A broadcast is a collection of tracks from a single producer.
This usually includes an audio track and/or a video track, but there are reasons to have more than that.</t>
        <section anchor="abr">
          <name>ABR</name>
          <t>Virtually all mass fan-out use-cases rely on Adaptive Bitrate (ABR) streaming.
The idea is to encode the same content at multiple bitrates and resolutions, allowing the viewer to choose based on their unique situation.</t>
          <t>MoqTransfork unsurprisingly supports this via multiple Tracks, but relies on the application to determine the relationship between them.
This is often done via a <tt>catalog</tt> track that details each track's name, bitrate, resolution, and codec.
This includes how a group in one track corresponds to a group in another track.
A common approach is to use the same Group Sequence number for all tracks, or perhaps utilize a <tt>timeline</tt> track to map between Group Sequences and presentation timestamps.</t>
          <t>The viewer may limit the available tracks based on capabilities or preferences.
For example, the device may not support the 4K track since it uses AV1, or the screen size may be too small to justify the bandwidth.
This is easy enough to support; just ignore these tracks in the catalog.</t>
          <t>The primary reason to use ABR is to adapt to changing network conditions.
The viewer learns about the estimated bandwidth via the SESSION_UPDATE message, or by measuring network traffic and can then choose the appropriate track based on bitrate.</t>
          <t>Transitioning between tracks can be done seamlessly by utilizing prioritization.
For example, suppose a viewer is watching the 360p track and wants to switch to 1080p at group 69.</t>
          <t>A real-time or unreliable live viewer could issue:</t>
          <artwork><![CDATA[
SUBSCRIBE_UPDATE track=360p  priority=0 order=DESC end=69
SUBSCRIBE        track=1080p priority=1 order=DESC start=69
]]></artwork>
          <t>A reliable live or VOD viewer could issue:</t>
          <artwork><![CDATA[
SUBSCRIBE_UPDATE track=360p  priority=1 order=ASC end=69
SUBSCRIBE        track=1080p priority=0 order=ASC start=69
]]></artwork>
          <t>The difference between them is whether to prioritize the old track or the new track.
In both scenarios, the subscription will seamlessly switch at group 69 even if it's seconds in the future.
The same behavior can be used to switch down.</t>
        </section>
        <section anchor="svc">
          <name>SVC</name>
          <t>We touched on SVC before, but it's worth mentioning as an alternative to ABR.
I want to see it used more often but I doubt it will be.</t>
          <t>Instead of choosing the track based on the bitrate, the viewer subscribes to them all:</t>
          <artwork><![CDATA[
SUBSCRIBE track=360p  priority=2 order=DESC
SUBSCRIBE track=1080p priority=1 order=DESC
SUBSCRIBE track=4k    priority=0 order=DESC
]]></artwork>
          <t>During congestion, the 4k enhancement layer will be deprioritized followed by the 1080p enhancement layer.
This is a more efficient use of bandwidth than ABR, but it requires more complex encoding.</t>
        </section>
      </section>
      <section anchor="conferences">
        <name>Conferences</name>
        <t>Some applications involve multiple producers, such as a conference calls or a live events.
Even though these are separate broadcasts from potentially separate origins, MoqTransfork can still serve them over the same session.</t>
        <section anchor="discovery">
          <name>Discovery</name>
          <t>The first step to joining a conference is to discover the available broadcasts.</t>
          <t>There is currently no discovery mechanism in MoqTransfork.
However, an application can build one on top of a MoqTransfork track (of course!).</t>
          <t>For example, suppose we have a conference room called <tt>room.12345</tt>.
An index service could produce a <tt>room.12345</tt> track that lists all broadcasts within the room.
When Alice joins and ANNOUNCES <tt>room.12345.alice</tt>, the index service could update the <tt>room.12345</tt> track to add a new FRAME <tt>+alice</tt>.
The same can be done to remove her when she leaves.</t>
        </section>
        <section anchor="participants">
          <name>Participants</name>
          <t>Extending the idea that audio is more important than video, we can prioritize tracks regardless of the source.
This works because <tt>SUBSCRIBE priority</tt> is scoped to the session and not the broadcast.</t>
          <artwork><![CDATA[
SUBSCRIBE broadcast=alice track=audio priority=3
SUBSCRIBE broadcast=frank track=audio priority=3
SUBSCRIBE broadcast=alice track=video priority=1
SUBSCRIBE broadcast=frank track=video priority=1
]]></artwork>
          <t>When Alice starts talking or is focused, we can actually issue a SUBSCRIBE_UPDATE to increase her priority:</t>
          <artwork><![CDATA[
SUBSCRIBE_UPDATE broadcast=alice track=audio priority=2
SUBSCRIBE_UPDATE broadcast=frank track=video priority=0
]]></artwork>
          <t>Note that audio is still more important than video, but Alice is now more important than Frank. (poor Frank)</t>
          <t>This concept can further be extended to work with SVC or ABR:</t>
          <artwork><![CDATA[
SUBSCRIBE broadcast=alice track=360p priority=4
SUBSCRIBE broadcast=frank track=360p priority=3
SUBSCRIBE broadcast=alice track=720p priority=2
SUBSCRIBE broadcast=frank track=720p priority=1
]]></artwork>
        </section>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>TODO Security</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <reference anchor="moqt">
        <front>
          <title>Media over QUIC Transport</title>
          <author fullname="Luke Curley" initials="L." surname="Curley">
            <organization>Discord</organization>
          </author>
          <author fullname="Kirill Pugin" initials="K." surname="Pugin">
            <organization>Meta</organization>
          </author>
          <author fullname="Suhas Nandakumar" initials="S." surname="Nandakumar">
            <organization>Cisco</organization>
          </author>
          <author fullname="Victor Vasiliev" initials="V." surname="Vasiliev">
            <organization>Google</organization>
          </author>
          <author fullname="Ian Swett" initials="I." surname="Swett">
            <organization>Google</organization>
          </author>
          <date day="19" month="September" year="2024"/>
          <abstract>
            <t>   This document defines the core behavior for Media over QUIC Transport
   (MOQT), a media transport protocol designed to operate over QUIC and
   WebTransport, which have similar functionality.  MOQT allows a
   producer of media to publish data and have it consumed via
   subscription by a multiplicity of endpoints.  It supports
   intermediate content distribution networks and is designed for high
   scale and low latency distribution.

            </t>
          </abstract>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-moq-transport-06"/>
      </reference>
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S." surname="Bradner"/>
          <date month="March" year="1997"/>
          <abstract>
            <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>
      <reference anchor="RFC8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B." surname="Leiba"/>
          <date month="May" year="2017"/>
          <abstract>
            <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>
    </references>
    <?line 1077?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA9196XLc2JXm/3wKtComtAyTIiW52qa7upsiqRLHkqgmKdU4
HI4iMvMmEyYSSANIUWmX/SzzLPNkc76z3AUJUqVy90zE+IdLTAB3Offs2x2P
x6Ou6Ep3kD1462ZFntWfXJP9x4fTo2ycXTZ51c7r5ubBKJ9MGveJ3lrWf+7m
D0bTvHPXdbM5yIpqXo9Gs3pa5UsaZtbk825cTtdN6TZjenvc2SjjvWejdj1Z
Fm1b1FW3WdHrpyeXr7Lsmywv25pGL6qZWzn6v6p7sJM9oBV1dVPkJf44PXxJ
/6kb+tf55asHo2q9nLjmYDSjpRyMaG3PR3nj8oPstuhGtzTfdVOvVwcZrWE0
ytfdoqaXs/Eoo//N12Up632zvnHZEa+Wn9TNdV4Vf8k7WuJBdly007qZ8RO3
zIvyILspPruSppz9+zV+2J3Wy9GoqpslffKJFpJhwo52Nj7eLVw3DzBY1U03
GgFe/uXReDzO8klLz6f07G39Zw/zrGizmWuL68rNsq7OWtd8clmeTZo6n03z
tsOPeZWtq0m9JojNMgFIVs+zT4W7dU0LSCyyWTGfu4YgmmHZ1XRDX82yP6/z
sug2WZc3165rD7Ju4TJ6qWhc1q7ctGvWy2ziulvnqozAWo67Yun4049nx7u9
pXatK+dYcZ4tGY3y66puu2Ka+Z3v0BmX9W1RXdNwZb5peayj43ctNkLD3ObN
jFexpC+zYomPclr1lHAFq8cmGwLJdZPzbmltNLdssl532U1V35Zudu0AgWk9
c9N2hz/Oi4qAwajjPtFuijlPY+PSqoEOG9r9tNms6GR3R6+L6wVNVtL7ZbZq
6q6e1mXLgCnmm2xR32LR69ZlCRzoNxqEpua9zVxZgJo+FTNX0/bXs4L+s3Rt
m187WU9ebbD1JZaMl21Ru4IZy2I2K91o9E12VFefcDp1JXA7dvOiKvjv0SVt
5sZtMgLHrCU6/nBxCXrBf7N3Z/zv8xMi6fOTY/z74vXhmzf+HyN94+L12Yc3
x+Ff4cujs7dvT94dy8f0a5b8NHrw9vD39ASLenD2/vL07N3hmwfEFQjGwOB6
ul4CykSaAM/E0aPONavGEaCzvB0Rjk+bYkJ/0Dcvj97/7/+1/yL761//6fzV
0bP9/d/87W/6x6/3//kF/XG7cJXMVld0ZvInHedmlK9WLm8wCiFaNs1XRUdc
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
5oYq4YC/DY+DhHRzMH9pF5aTVtl2NCEOoyUzGVInvl3BDgfWqvWNm9WuhWmv
HZnEFUaQF67ZhMZMapDyZRmh271iXZHY99IKzqxBu8ZnKFFtq9cuLzFDYfVt
MSMiWbMZOIkbTLKSbkVsPGIgEGlMSoOKGO8WCY20Hm+P+x79nf5IyjxCu7NZ
1IFugO681hZ/EVtMnlREIbLezxwSDO35Ct/pIHu0v/ffHmdGU1zR7JtGRp3M
vN2yWGtFlHAfbZAA3mUlwVKEl9qdLKxly4ngzEUb0u7Zl1E9l/bf7RmsaMUj
RySBdmNHUb0hX5rAfqOoiRwNgyYtsc/9tJP+T46d9G00VP9AguWqVBPYddIC
OuOWdA/b+IDNDgx9Bjlj4GU9edhuH/BAJ/yBbvWWw2WoLzEremNB0s7sH9nO
DnxDog9tHiJNxFpq+9ar7ZbdyhetNJXpaolwkqbYnGisPV7T/GMPpDY+iNCq
WU4ihVqizKReBRWZ7+pqfO6DV6K+E66BTpBSgbtGimnRSS9DzoI59bfl9AyD
vp0udl9eskCVW78sq9771ex2D7kaLA9doUB1HIEgno97aSpaZ9RtUPi1XdfD
N1hFzoVdvhqFHtXogWxBJabAAcLPWzsxFklLkR+gIO4YONX2m500cGcXJnpH
8NVHnPODcUUKsYCokiIqK7jnUcQzwd6WoYU0AnTcc2abBbOApG+kn3hkJtnF
EiA0cI72LtZxKN1l9coftyPpVA85mwp2MTppT+QsGhATvaYeGbWc0TmYDhRC
FX34gWrhbhNPFUyZfMXA1s6M9v6Tjlf7DBtu8se4EEkaJvYvVPkmO0SXSdSI
4Xjji9K0By3bvrRw3B0EFYjU/AUsMeYugWVjdLZlQ1v0b6zDLCmdPGDLdNdG
91SxdBAr2UKoN3p7nD+pHX6f98YWD5uA3hXBXN3b93LIJNxDtqfQOrN5+D4i
6w1SfbPSnur7e+Nf7S2lGhqLhQbHi44MqMi0tIQrX6/P9mlWEQqVfIaJWfm9
6uFsxuVhWBOrnghNMkXmpucGbGfGfgoDKz8QScn4zg1ttecOgwuWGZHbVIZV
qcXkCosBJGsV3iy4CQTsQTOqBt0O0rWnXmhY/Ra8VkQulwYmsaBQLITEJcBE
Qpzc7xYuYFHb2cWa6vTVgFToOPUovtVBXGGsYwreRXXsQiP/kxGOi8vtDhfL
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
++7BPC9b9+BvI5k8SifeHf0fGYqrriusAAA=

-->

</rfc>
