<?xml version="1.0" encoding="utf-8"?>
<!--
     draft-rfcxml-general-template-standard-00

     This template includes examples of the most commonly used features of RFCXML with comments
     explaining how to customize them. This template can be quickly turned into an I-D by editing
     the examples provided. Look for [REPLACE], [REPLACE/DELETE], [CHECK] and edit accordingly.
     Note - 'DELETE' means delete the element or attribute, not just the contents.

     Documentation is at https://authors.ietf.org/en/templates-and-schemas
-->
<?xml-model href="rfc7991bis.rnc"?>  <!-- Required for schema validation and schema-aware editing -->
<!-- <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> -->
<!-- This third-party XSLT can be enabled for direct transformations in XML processors, including most browsers -->


<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<!-- If further character entities are required then they should be added to the DOCTYPE above.
     Use of an external entity file is not recommended. -->

<rfc
  xmlns:xi="http://www.w3.org/2001/XInclude"
  category="std"
  consensus="true"
  docName="draft-ietf-mlcodec-opus-extension-04"
  ipr="trust200902"
  obsoletes=""
  updates="6716"
  submissionType="IETF"
  xml:lang="en"
  version="3">
<!-- [REPLACE]
       * docName with name of your draft
     [CHECK]
       * category should be one of std, bcp, info, exp, historic
       * ipr should be one of trust200902, noModificationTrust200902, noDerivativesTrust200902, pre5378Trust200902
       * updates can be an RFC number as NNNN
       * obsoletes can be an RFC number as NNNN
-->

  <front>
    <title abbrev="Opus Extension">Extension Formatting for the Opus Codec</title>

    <seriesInfo name="Internet-Draft" value="draft-ietf-mlcodec-opus-extension-04"/>

    <author fullname="Timothy B. Terriberry" initials="T" surname="Terriberry">
      <!-- [CHECK]
             * initials should not include an initial for the surname
             * role="editor" is optional -->
    <!-- Can have more than one author -->

    <!-- all of the following elements are optional -->
      <organization>Xiph.Org</organization>
      <address>
        <postal>
          <country>US</country>
          <!-- Uses two letter country code -->
        </postal>
        <email>tterribe@xiph.org</email>
      </address>
    </author>

    <author fullname="Jean-Marc Valin" initials="JM" surname="Valin">
      <organization>Google</organization>
      <address>
        <postal>
          <country>CA</country>
          <!-- Uses two letter country code -->
        </postal>
        <email>jeanmarcv@google.com</email>
      </address>
    </author>

    <!--date year="2025"/-->
    <!-- On draft submission:
         * If only the current year is specified, the current day and month will be used.
         * If the month and year are both specified and are the current ones, the current day will
           be used
         * If the year is not the current one, it is necessary to specify at least a month and day="1" will be used.
    -->

    <area>Applications and Real-Time</area>
    <workgroup>mlcodec</workgroup>
    <!-- "Internet Engineering Task Force" is fine for individual submissions.  If this element is
          not present, the default is "Network Working Group", which is used by the RFC Editor as
          a nod to the history of the RFC Series. -->

    <keyword>Opus, RFC6716</keyword>

    <abstract>
      <t>This document updates RFC6716 to extend the Opus codec (RFC6716) in a
          way that maintains interoperability, while adding optional
          functionality. </t>
    </abstract>

  </front>

  <middle>

    <section>
      <name>Introduction</name>
      <t>This document updates RFC6716 to extend the Opus codec (RFC6716) in a
          way that maintains interoperability, while adding optional
          functionality. </t>

      <section>
        <name>Requirements Language</name>
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
          "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT
          RECOMMENDED", "MAY", and "OPTIONAL" 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>
      </section>

    </section>

    <section anchor="format">
      <name>Extension Format</name>
      <t>The Opus padding mechanism provides a safe way to extend the Opus codec
          while preserving interoperability and without having to transmit any extra packets.
          <xref target="RFC6716"/> specifies that all padding bytes "MUST be set to zero" by the encoder,
          while the decoder "MUST accept any value for the padding bytes". In that way, any non-zero padding will
          indicate to an extended decoder that extensions are present and can be processed. On the other hand, for
          any all-zero padding, the decoder will just discard the padding like any non-extended decoder. A
          non-extended decoder receiving a packet with extensions will simply
          discard the extensions and proceed as if none were present.</t>

      <t>An instance of an extension is composed of an "extension ID byte" and
          an optional payload, which may be prefixed by an optional length
          indicator, followed by 0 or more bytes of extension data.
         Although there is only one padding region per Opus packet, each
          extension instance is tied to an underlying Opus frame, of which
          there may be more than one per packet.
         Extension instances are grouped by the corresponding Opus frame they
          are extending, starting from the first frame, with frame separator
          extensions (<xref target="ID1"/>) delineating the boundaries between
          the extensions for each frame.</t>

      <t>There are three types of extensions:</t>
         <ul>
            <li>Structural extensions (IDs 0, 1, and 2), which control extension
             parsing, but do not inherently change the behavior of a decoder
             themselves.</li>
            <li>Short extensions (IDs 3 through 31), which have either 0 or 1
             bytes of extension data.</li>
            <li>Long extensions (IDs 32 through 127), which can have an
             arbitrary number of extension data bytes.</li>
         </ul>

      <t>An extension instance starts with an "extension ID byte" that contains
          a 7-bit ID, as well as a binary flag L for length signaling.
         For short extensions, L=0 means that no data follows the extension ID
          byte, whereas L=1 means that exactly one byte of extension data
          follows.
         For long extensions, L=0 signals that the extension data takes up the
          rest of the padding.
         In any given packet, this signal cannot appear more than once.
         Conversely, L=1 in a long extension signals that a length indicator
          follows.
         The following byte contains a length value from 0 to 254, or the
          special value 255, indicating that the length is 255 plus the length
          signaled from the next byte.
         The 255 case MAY repeat as long as the size of the padding is not
          exceeded.
         Also, any extension signaled with a length that would cause the
          decoder to read beyond the bounds of the packet MUST be ignored by
          the decoder.</t>
      <t>For ID 0 (Original Padding), L=0 has the same meaning as for long
          extensions, but L=1 signals a length of zero (no length indicator
          or extension data follows).
         For ID 1 (Frame Separator), the L flag has the same meaning as for
          short extensions.
         For ID 2 (Repeat These Extensions), the extension itself has no
          payload (for either L=0 or L=1), but is used to signal that
          previously coded extensions are to be repeated for subsequent Opus
          frames.
         The payloads of the repeated extensions follow immediately after.
         See <xref target="ID2"/> for the details of this process and for how
          the L flag is to be interpreted.</t>
      <figure>
        <name>Extension framing</name>
        <artset>
        <!-- This <artset> includes two <artwork> elements, each of a different type -->
          <artwork type="ascii-art" name="extension-framing.txt">
            <![CDATA[
    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      ID     |L| Length (opt.) |    extension data...          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
   |                                                               |
   :                                                               :
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            ]]>
          </artwork>
        </artset>
      </figure>

      <t>A decoder MUST ignore any extension it does not support, decoding the
          rest of the packet as if the extension was not present.
         Additionally, a decoder MAY ignore any other extension even if it
          technically supports it. An encoder MUST NOT alter the way it encodes the non-extension
          part of an Opus packet in such a way as to noticeably reduce its quality when decoded with a non-extended
          decoder. </t>

      <t>A given extension ID MAY appear multiple times and the ordering of
          extension instances within each Opus frame is significant (see
          <xref target="ID1"/>).
         A particular extension ID definition MAY place further restrictions on
          count and ordering of these extensions instances (see
          <xref target="IANA"/>).
         Reordering of extension instances between Opus frames caused by the
          repeat mechanism is not significant and an extended decoder MUST
          treat repeated extensions as equivalent to the same extensions coded
          individually (see <xref target="ID2"/>).</t>

      <section anchor="ID0">
        <name>ID 0: Original Padding</name>
        <t>For compatibility reasons, an ID of 0 means that the remaining
            content of the padding is actual padding, as originally defined in
            <xref target="RFC6716"/>.
           As in its original definition, the padding bytes MUST be set to zero
            by the encoder, while the decoder MUST ignore any non-zero padding.
           In the case where the L flag is set, the extension ID byte (0x01) is
            simply skipped and extension decoding continues from the next byte.
           This allows inserting padding one byte at a time in a way that would
            not be possible if an explicit padding length were coded instead
            (that would make L=1 padding require at least two bytes, and
            appending a L=0 padding might require signaling a multi-byte length
            indicator for a preceding long extension that would not otherwise
            be necessary, both causing the packet size to increase by more than
            one byte).</t>
      </section>

      <section anchor="ID1">
        <name>ID 1: Separator</name>
        <t>In the case where multiple Opus frames are packed inside the same
            packet, frame separators specify which extension instance(s) are
            associated with which frames.
           An extension instance with ID=1 acts as a separator between
            extension instances from different Opus frames.</t>
        <t>By default, extension instances are associated with the first Opus
            frame in the packet (frame 0).
           When parsing sequentially, any time a separator with L=0 is
            encountered, the associated frame index is incremented by one.
           If L=1 is used, the following payload byte indicates the amount by
            which to increment the frame index.
           The frame index MUST NOT exceed the number of frames in the packet
            minus one (i.e., indexing starts at zero), regardless of how it is
            incremented.
           The decoder MUST ignore all extension instances associated with an
            out-of-bounds frame index.</t>
      </section>

      <section anchor="ID2">
        <name>ID 2: Repeat These Extensions (RTE)</name>
        <t>In the case where multiple Opus frames are packed inside the same
            packet, the Repeat These Extensions (RTE) extension can reduce the
            overhead of coding extension IDs and frame separators when the
            extensions in the current frame also appear in every subsequent
            frame (albeit, possibly with different payloads).
           An extension with ID=2 acts as a signal to repeat all of the
            non-padding (ID=0) extensions following the most recent of</t>
            <ul>
               <li>The start of the packet, or</li>
               <li>A frame separator (ID=1) with a non-zero increment, or</li>
               <li>A preceding RTE extension (ID=2), if any.</li>
            </ul>
        <t>Padding extensions are not repeated, nor is any frame separator with
            an increment of 0 (which acts as another form of padding).
           Extensions preceding a frame separator with an increment of zero do
            get repeated, as they still belong to the current frame.
           An RTE extension MAY appear multiple times in the same frame.
           Only the extensions which follow the most recent RTE (if any) are
            repeated by a subsequent RTE.</t>
        <t>The RTE extension itself has no payload, but it is immediately
            followed by the payloads of new instances of the repeated
            extensions.
           The payloads for all of the repeated extensions for the next frame
            come first, followed by those of the frame after, etc.
           The extension ID byte corresponding to each payload is implicit and
            not coded: only the length (if needed) and the subsequent extension
            data are coded.
           An RTE extension MAY appear in the last frame.
           In this case, no extensions are repeated.</t>
        <t>For short extensions, the repeated extension payloads use the same L
            flag as the instance of the extension being repeated.
           If the length of a short extension needs to change between frames,
            this repeat mechanism cannot be used to signal that.
           All repeated long extension payloads except the final instance of
            the last repeated long extension in the last frame are coded as if
            with L=1 (using an explicit length indicator).
           The final repeated long extension payload is coded with the L flag
            specified by the RTE extension.
           In the case that the RTE extension specifies L=0, and the last
            repeated long extension is followed by one or more repeated short
            extensions with a payload, then the final long extension does not
            consume the rest of the padding as normal, but leaves enough room
            for the payloads of the repeated short extensions that follow.
           If there is not enough room for the repeated short extensions that
            follow, even if the length of the final long extension were set to
            zero, then that extension instance and all remaining padding data
            MUST be ignored by the decoder.</t>
        <t>If the RTE extension uses L=1, then extension coding continues
            afterwards with the same frame index as the RTE extension.
           This allows a frame to contain both repeated and non-repeated
            extensions.
           This also means that the complete collection of extension instances
            for a given frame might not all be contiguous in the packet.
           If the RTE extension uses L=0, but the repeated extensions did not
            contain a long extension, then extension coding continues
            afterwards with the frame index following that of the RTE extension
            (as if an L=0 separator had been coded).
           If an RTE extension with L=0 appears in the last frame, then the
            rest of the padding (if any) MUST be set to zero by the encoder,
            and the decoder MUST ignore any additional non-zero padding.</t>
      </section>

      <section>
        <name>IDs 3-119: Unassigned</name>
        <t>These extensions are to be defined in their own respective documents
            and the IDs are to be assigned by IANA.
           The meaning of the L flag is already defined for all of these
            unassigned IDs because a decoder must know how to skip extensions
            it does not support.
           Due to potential for interaction between extensions, new extensions
            are to be assigned with the "Standards Action" policy defined by
            <xref target="RFC8126"/>.</t>
      </section>

      <section anchor="ID-experimental">
        <name>IDs 120-126: Experimental</name>
        <t>We reserve these 7 IDs for experimental extensions, such that
            extensions defined in Internet-Drafts can be tested before
            publication as an RFC without causing possible interoperability
            issues should their bitstream definitions change.
           When using an experimental ID, it is RECOMMENDED to use a two-byte
            prefix that attempts to encode an experiment number (first byte)
            and a version number (second byte).
           Experimental extension documents SHOULD attempt to choose an
            experiment number that does not collide with other ongoing
            experiments.</t>
      </section>

      <section anchor="ID-extended-extensions">
        <name>ID 127: Extended Extensions</name>
        <t>The last ID is reserved for future extensions to the extension
            mechanism.
           As with all other long extensions, the meaning of the L
            flag is pre-defined to ensure decoders can skip extended extensions
            they do not support.
           The contents of the payload for this extension will be defined by a
            future specification.</t>
      </section>

    </section>

    <section anchor="IANA">
    <!-- All drafts are required to have an IANA considerations section. See RFC 8126 for a guide.-->
      <name>IANA Considerations</name>
      <t>This document defines a new registry "Opus Extension IDs" in a new "Opus" group, that allocates individual IDs
          to individual extensions to be defined in the future. The existing "Opus Channel Mapping Families" registry will also be
          moved to the newly created "Opus" group. Moreover, this document already defines
          the following IDs:</t>

      <table>
        <thead>
          <tr><th>Extension ID</th><th>Description</th><th>Reference</th></tr>
        </thead>
        <tbody>
          <tr><td>0</td><td>Original Padding</td><td>Defined in <xref target="ID0"/></td></tr>
          <tr><td>1</td><td>Frame Separator</td><td>Defined in <xref target="ID1"/>.</td></tr>
          <tr><td>2</td><td>Repeat These Extensions</td><td>Defined in <xref target="ID2"/>.</td></tr>
          <tr><td>3-119</td><td>Unassigned</td><td>To be assigned with the "Standards Action" policy <xref target="RFC8126"/></td></tr>
          <tr><td>120-126</td><td>Experimental</td><td>Defined in <xref target="ID-experimental"/>, following the "Experimental Use" policy <xref target="RFC8126"/></td></tr>
          <tr><td>127</td><td>Extended Extensions</td><td>Reserved in <xref target="ID-extended-extensions"/></td></tr>
        </tbody>
      </table>

      <t>For forward compatibility, any extension MUST use the definition of
          the L flag dictated by its ID value (see <xref target="format"/>).
         Extension definitions MUST specify whether or not it is permitted for
          the extension to appear multiple times for a given Opus frame within
          the packet.</t>

      <section anchor="media">
        <name>Opus Media Type Update</name>
        <t>This document updates the audio/opus media type registration
            <xref target="RFC7587"/> to add the following two optional parameters:</t>
        <t>extensions: specifies a comma-separated list of supported extension IDs on the
            receiver side.</t>
        <t>sprop-extensions: specifies a comma-separated list of supported extension IDs on the
            sender side.</t>
        <t>extN-*: To facilitate parameter forwarding, extension document that
            require receiver extension parameters
            SHOULD name them "ext", followed by the extension ID, a hyphen, and the
            parameter name. </t>
        <t>sprop-extN-*: Extension-specific sender-side parameters defined similarly as above.</t>
        <t>All names starting with "ext" and "sprop-ext" are reserved for use by Opus extensions.</t>
        <t>Structural extensions (IDs 0, 1, and 2) MUST be supported by any
            receiver that recognizes Opus extensions, and do not need to be
            included in the extensions or sprop-extensions lists.</t>

      </section>
      <section anchor="SDP">
        <name>Mapping to SDP Parameters</name>
        <t>The media type parameters described above map to declarative SDP and
            SDP offer-answer in the same way as other optional parameters in <xref target="RFC7587"/>.
           As per <xref target="RFC5576"/> Section 6.3, media-level format
            parameters MUST be explicitly specified and MUST NOT be carried
            over blindly from another offer or answer.
           Regardless of any a=fmtp SDP attribute specified, the receiver MUST
            be capable of receiving any signal.</t>
      </section>
    </section>

    <section anchor="Security">
      <!-- All drafts are required to have a security considerations section. See RFC 3552 for a guide. -->
      <name>Security Considerations</name>
      <t>This document does not add security considerations beyond those already documented in <xref target="RFC6716"/>.
         Future Opus extensions may have their own security implications.</t>
    </section>

  </middle>

  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>

        <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.8174.xml"/>
        <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.6716.xml"/>
        <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.8126.xml"/>
        <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.7587.xml"/>
        <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.5576.xml"/>
        <!-- The recommended and simplest way to include a well known reference -->

      </references>

      <!--
      <references>
        <name>Informative References</name>

        <reference anchor="exampleRefMin">
          <front>
            <title>Title [REPLACE]</title>
            <author initials="Initials [REPLACE]" surname="Surname [REPLACE]">
              <organization/>
            </author>
            <date year="2006"/>
          </front>
        </reference>

      </references>
      -->
    </references>

    <!--
    <section>
      <name>Appendix 1 [REPLACE/DELETE]</name>
      <t>This becomes an Appendix [REPLACE]</t>
    </section>

    <section anchor="Acknowledgments" numbered="false">
      <name>Acknowledgments</name>
      <t>We would like to thank...</t>
    </section>

    <section anchor="Contributors" numbered="false">
      <name>Contributors</name>
      <t>Thanks to all of the contributors. [REPLACE]</t>
    </section>
      -->

 </back>
</rfc>
