<?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 customise 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-03"
  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-03"/>

    <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 subbmission:
         * 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 an extension is 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 an extension will simply
          discard the extension and proceed as if none was present.</t>

      <t>An extension starts with a byte that signals a 7-bit ID, as well as a binary flag L for length signaling.
         For extension IDs 1 and 3 through 31, L=0 means that no data follows
          the extension, whereas L=1 means that exactly one byte of extension
          data follows.
         These are collectively called "short extensions".
         For IDs 32 to 127, L=0 signals that the extension data takes up the
          rest of the padding, and L=1 signals that a length indicator
          follows.
         These are collectively called "long extensions".
         For ID 0, L=0 has the same meaning as for long extensions, but L=1
          signals a length of zero (no length indicator follows).
         In any given packet containing padding, the "rest of the padding"
          cannot appear more than once.
         For ID 2, the extension itself has no payload (for either L=0 or
          L=1), but it is used to signal that previously coded extensions are
          repeated in subsequent Opus frames.
         Their payloads follow immediately after (see <xref
          target="ID2"/>).</t>
      <t>When a long extension signals that it requires a length indicator, the
          following byte contains a length value from 0 to 254.
         If the length byte is 255, then the length is 255 plus the length
          signaled from the next byte, with the 255 case being allowed to
          repeat as long as the size of the padding is not exceeded.
         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>

      <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 content...       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
   |                                                               |
   :                                                               :
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            ]]>
          </artwork>
        </artset>
      </figure>

      <t>A decoder MUST ignore any extension it does not know, 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 extension ID
          ordering within each Opus frame is significant (see, e.g., <xref
          target="ID1"/>).
         A particular extension ID definition MAY place further restrictions on
          count and ordering of these extensions (see
          <xref target="IANA"/>).
         Reordering of extensions 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 content of the extension
           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 0x01 header byte is
           simply skipped and extension decoding continues from the next byte. This can be useful as a way
           to insert padding one byte at a time, since appending zeros at the end may cause an increase in size
           from having to signal a multi-byte length indicator for the last extension.</t>
      </section>

      <section anchor="ID1">
        <name>ID 1: Separator</name>
        <t>In the case where multiple Opus frames are packed inside the same packet, there may be a need to
            specify which extension(s) apply to which frame.
           By default, all extensions apply to the first Opus frame in the
            packet.
           An extension with ID=1 acts as a separator between extensions from
            different Opus frames.
           When parsing extensions sequentially, any time a separator with L=0
            is encountered, the associated frame is increased by one.
           If L=1 is used, the following data byte indicates the increment
            applied for the new associated frame.
           The associated frame value MUST NOT exceed the bound equal to the
            number of frames in the packet, minus one (indexing starts at
            zero).
           Similarly, L=0 separators MUST NOT cause the associated frame to
            exceed the above bound.
           The decoder MUST ignore all extensions associated with an
            out-of-bound 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 overhead of coding the extension IDs and frame
            separators can be reduced by using the Repeat These Extensions
            (RTE) extension.
           An extension with ID=2 acts as a signal that all of the non-padding
            extensions seen so far in the current frame, starting after the
            last RTE extension (if any), are to be repeated in all subsequent
            frames.
           The extension itself has no payload, but it is immediately followed
            by the extension data for 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 for each payload is not coded: only the length
            (if needed) and the extension data.
           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 it.
           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 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 and all remaining extensions MUST be
            ignored by the decoder.</t>
        <t>If the RTE extension uses L=1, then extension coding continues
            afterwards for the same frame as the RTE extension appeared in.
           This allows a frame to contain both repeated and non-repeated
            extensions.
           This also means that the complete list of extensions for a given
            frame might not all be contiguous in the packet.
           If the RTE extension uses L=0, but the repeated extension data did
            not contain a long extension, then extension coding continues
            afterwards for the frame following 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,
            while 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 know about.
            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: I-D Experimental</name>
        <t>We reserve these 7 IDs for experimental extensions, such that extensions defined in Internet-Drafts
            can be tested before they become 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 know about.
           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 definition</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 Internet-Draft implementations</td><td>Defined in <xref target="ID-experimental"/>, following the "Experimental Use" policy <xref target="RFC8126"/></td></tr>
          <tr><td>127</td><td>Reserved for future 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>Extension 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>
