| Internet-Draft | Opus In-Band FEC with ULPFEC | October 2026 |
| Oancea | Expires 28 April 2027 | [Page] |
The Opus codec can carry low-bitrate redundancy for the preceding frame inside each packet ("in-band FEC"). The RTP payload format for generic Forward Error Correction (RFC 5109, commonly called ULPFEC) protects groups of RTP packets with XOR parity packets. The two mechanisms recover different loss patterns, have different delay and overhead characteristics, and interact in ways that are not described in either specification.¶
This document gives informational guidance on when the combination is worthwhile, how a sender should configure each mechanism, how a receiver should order recovery, how to signal the combination in SDP, how middleboxes affect it, and how to keep the combined redundancy consistent with congestion control. It complements, and does not change, the WebRTC FEC requirements in RFC 8854. It defines no new protocol elements.¶
This note is to be removed before publishing as an RFC.¶
Discussion of this document is expected to take place on the AVTCORE Working Group mailing list (avt@ietf.org). This is an individual submission and has not been adopted by any working group.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 28 April 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Packet loss on the path between an audio sender and receiver can be repaired in several ways: retransmission [RFC4588], redundant encoding [RFC2198], codec-internal redundancy, and separate parity-based FEC streams such as [RFC5109] and [RFC8627]. For Opus [RFC6716], the codec-internal mechanism is the Low-Bit-Rate Redundancy (LBRR) of the SILK layer, which RTP usage [RFC7587] refers to as "in-band FEC".¶
In-band FEC and ULPFEC are complementary. In-band FEC adds at most one packet of delay and can be decoded from a single received packet, but it can only repair the frame immediately preceding a received packet, it is not available in every Opus mode, and it yields a lower-fidelity reconstruction. ULPFEC reconstructs lost RTP packets bit-exactly, independent of the codec and mode, and can be arranged to cover bursts, but it adds delay proportional to the size of the protected group, and its overhead does not shrink with the codec's own bitrate decisions.¶
Neither [RFC7587] nor [RFC5109] discusses using the two together, and [RFC8854] (which targets WebRTC) recommends Opus in-band FEC for audio and does not recommend a separate FEC stream for audio because of its overhead. That recommendation remains appropriate for typical interactive WebRTC calls. There are, however, deployments where the assumptions behind it do not hold: music or other content coded in Opus modes without LBRR, links with frequent burst loss, one-way or latency-tolerant distribution, multicast without a feedback path, and systems that must recover RTP header extensions or contributing-source lists along with the payload. This document describes how to combine the mechanisms well in those deployments.¶
This document is informational. It does not update [RFC5109], [RFC7587], or [RFC8854], and it defines no new RTP payload formats, SDP attributes, or media type parameters. Where this document uses requirement language, it describes good practice for implementations that choose to combine the two mechanisms; it does not impose requirements on implementations that do not.¶
Flexible FEC [RFC8627] provides a superset of ULPFEC's capabilities and most of the guidance here applies to it equally. This document concentrates on ULPFEC because it is widely implemented and because [RFC5109] is the format named in many existing deployments. The Opus Deep Redundancy (DRED) extension under development in the MLCODEC Working Group [I-D.ietf-mlcodec-opus-dred] is discussed in Section 11.¶
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 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
Opus operates in SILK-only, Hybrid, and CELT-only modes [RFC6716]. LBRR frames are a SILK-layer feature, so in-band FEC is only available in SILK-only and Hybrid modes. Audio coded in CELT-only mode, which encoders commonly select for music and for high bitrates, carries no in-band redundancy.¶
When enabled, an Opus packet can carry an LBRR re-encoding of the SILK frames of the previous packet. A decoder that has lost packet N but received packet N+1 can decode the LBRR data in packet N+1 instead of concealing the loss. The decision to include LBRR data is made entirely by the encoder [RFC7587]; in the reference implementation it depends on the application enabling in-band FEC and on the expected packet loss rate configured by the application. A receiver indicates that it can make use of in-band FEC with "useinbandfec=1" [RFC7587]; the default is 0, and [RFC8854] requires WebRTC receivers that can use incoming FEC to signal it.¶
Two properties matter for the combination:¶
An ULPFEC packet carries a 10-octet FEC header and one or more level headers, each with a protection length and a 16- or 48-bit mask selecting the protected media packets relative to a base sequence number [RFC5109]. The FEC data is the XOR of the protected packets' RTP header fields and of the octets following the fixed 12-octet RTP header, which include any CSRC list, header extension, and payload. If exactly one packet of a protection group is missing, it can be reconstructed exactly, including its marker bit, timestamp, CSRCs, and header extensions. RED-based redundancy [RFC2198] cannot recover these header elements [RFC8854].¶
[RFC5109] allows FEC to be sent either as a separate stream with the same SSRC as the protected stream, in which case it recommends a separate RTP session, or as a secondary encoding inside RED. The registered media type audio/ulpfec has a required "rate" parameter; matching the protected media's clock rate, 48000 for Opus [RFC7587], is recommended.¶
| Property | Opus in-band FEC | ULPFEC |
|---|---|---|
| Losses repaired | Single loss followed by a received packet | One loss per protection group per level; bursts if interleaved |
| Added receiver delay | One packet duration | Up to the time span of the protection group |
| Fidelity of repair | Lower-bitrate approximation | Bit-exact packet, including header extensions |
| Opus modes | SILK-only and Hybrid | All |
| Overhead | Chosen per packet by the encoder | About 1/k of the largest protected packet, plus headers |
| Survives payload-preserving forwarding | Yes | Only if sequence numbers and headers are preserved (Section 8) |
| Signalling | "useinbandfec" parameter | Separate payload type, and session or RED configuration |
For interactive, unicast calls with isolated losses, Opus in-band FEC alone (optionally supplemented with RED as recommended by [RFC8854]) is usually the better trade-off, and senders SHOULD NOT add ULPFEC for audio in that case. The combination is worth considering when one or more of the following holds:¶
If none of these holds, the added overhead and delay of ULPFEC are unlikely to be justified for Opus audio.¶
As [RFC8854] recommends, FEC should only be activated when network conditions warrant it. A sender combining the mechanisms SHOULD adapt them independently:¶
A sender SHOULD NOT send ULPFEC to a receiver that has not accepted the ULPFEC payload type in the offer/answer exchange [RFC3264], and SHOULD NOT include in-band FEC data for a receiver that signalled "useinbandfec=0" unless it has other reasons to do so. Any compliant Opus decoder ignores in-band FEC data it does not need [RFC7587], so this is an efficiency concern, not an interoperability one.¶
The following considerations apply when choosing ULPFEC parameters for an Opus stream:¶
The sender MUST keep the total of primary Opus bitrate, in-band FEC, ULPFEC, and packet headers within the rate allowed by its congestion controller (Section 9). When FEC is enabled or increased, the primary Opus bitrate should be reduced to make room for it, rather than adding FEC on top of a rate that already fills the allowed budget. The worked example in Appendix A shows that ULPFEC with k=4 adds about 27% to the on-the-wire rate of a 32 kbit/s Opus stream with in-band FEC, under the stated assumptions.¶
When media packet N is missing at its playout deadline, a receiver supporting both mechanisms SHOULD attempt recovery in the following order:¶
ULPFEC recovery comes first because it produces the original packet and restores its header information. Receivers SHOULD run ULPFEC recovery iteratively: a packet recovered from one FEC packet can complete another protection group or provide the N+1 packet needed for in-band FEC.¶
ULPFEC only helps if the jitter buffer holds missing packets' slots long enough for the FEC packet to arrive. An adaptive jitter buffer that targets a delay shorter than the protection group's span will rarely benefit from ULPFEC and still pays its overhead. Receivers SHOULD take the signalled or observed protection span into account when choosing a target delay, or report to the application that ULPFEC is ineffective at the current delay so that the sender can be asked to reduce k. In-band FEC needs only one packet duration of additional delay.¶
A packet that is reconstructed by ULPFEC and later arrives late from the network is a duplicate. Receivers MUST discard such duplicates and MUST NOT decode the same audio twice from LBRR data and from a recovered or late packet.¶
Receivers should keep separate counts of packets lost before repair, packets recovered by ULPFEC, losses covered by in-band FEC, and losses concealed. Pre-repair counts are the input to congestion control (Section 9); post-repair counts are the input to FEC adaptation (Section 5.1). RTCP receiver reports [RFC3550] are conventionally computed from packets received from the network, before repair.¶
The combination needs no new signalling. Opus in-band FEC is indicated with "useinbandfec" [RFC7587]; ULPFEC is negotiated as its own payload type [RFC5109]. Two configurations are possible.¶
When media is multiplexed with BUNDLE [RFC9143], a separate RTP session for FEC is not available. ULPFEC can instead be carried as a secondary encoding inside RED [RFC2198], as allowed by [RFC5109]. The RED encapsulation then carries the Opus primary block in every packet and an ULPFEC block in the packets the sender chooses. The following SDP fragment offers this configuration:¶
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 100 c=IN IP4 0.0.0.0 a=mid:a0 a=rtpmap:111 opus/48000/2 a=fmtp:111 useinbandfec=1 a=rtpmap:63 red/48000/2 a=fmtp:63 111/100 a=rtpmap:100 ulpfec/48000¶
In this configuration, implementers should be aware that RED adds a per-block header, and that peers which support RED for audio do not necessarily support ULPFEC as a RED secondary encoding for audio. An answerer that does not support it removes payload type 100 from its answer, and the sender then uses in-band FEC (and RED redundancy, if negotiated) alone.¶
Outside WebRTC, ULPFEC can be sent in its own RTP session, as recommended by [RFC5109], and associated with the media session using the FEC-FR grouping semantics of [RFC5956]. The FEC stream uses the same SSRC as the media stream. [RFC8854] advises against offering FEC-only "m=" lines in WebRTC; the example below is intended for other environments such as SIP-based or broadcast systems.¶
v=0 o=- 4858251974351650128 1 IN IP4 192.0.2.10 s=- c=IN IP4 192.0.2.10 t=0 0 a=group:FEC-FR m1 m2 m=audio 49170 RTP/AVP 111 a=mid:m1 a=rtpmap:111 opus/48000/2 a=fmtp:111 useinbandfec=1;maxaveragebitrate=32000 m=audio 49172 RTP/AVP 100 a=mid:m2 a=rtpmap:100 ulpfec/48000¶
The "maxaveragebitrate" parameter limits the average bitrate of the Opus stream [RFC7587]. It does not cover the separate FEC stream, so the sender must still account for ULPFEC in its overall budget (Section 5.3).¶
RTP topologies [RFC7667] affect the two mechanisms differently:¶
FEC must not hide congestion. [RFC9265] recommends that, from a congestion control standpoint, a packet recovered by FEC be treated as lost. [RFC5109] requires that implementations not substantially increase total bandwidth as losses increase, and [RFC8854] notes that redundancy sent during congestion reduces the bandwidth available for the primary encoding and can make losses worse. For the combination, this means:¶
Using [RFC9265]'s classification, both mechanisms as described here operate above the transport, within the rate given to the application by its congestion controller.¶
Adapting the combination requires both pre-repair and post-repair loss information. Standard RTCP receiver reports provide the former. The latter can be conveyed with the RTCP Extended Report blocks for post-repair loss run-length encoding [RFC5725] or for post-repair loss counts [RFC7509]. A sender that receives these can tell whether ULPFEC is effective at the receiver's jitter buffer depth (Section 6.2) and can set the Opus encoder's expected loss rate from the residual loss (Section 5.1). Without post-repair feedback, the sender has to rely on models such as the one in Appendix B, which can be substantially wrong for real loss patterns.¶
The MLCODEC Working Group is specifying a Deep Redundancy (DRED) extension for Opus [I-D.ietf-mlcodec-opus-dred]. DRED carries very low bitrate redundancy, covering up to a second or more of past audio, inside the Opus padding. When both peers support it, DRED addresses much of the burst-loss case for which this document suggests ULPFEC, at lower overhead. ULPFEC would remain relevant where bit-exact recovery, recovery of RTP header information, codec independence, or support for peers without DRED is needed. Guidance on combining DRED with ULPFEC, and with in-band FEC, is left for a future revision once the DRED specification is stable.¶
This document has no IANA actions.¶
Neither in-band FEC nor ULPFEC provides any security. The security considerations of [RFC6716], [RFC7587], and [RFC5109] apply. In particular:¶
This example illustrates the bitrate cost of each mechanism for a single stream. Assumptions: Opus at 32 kbit/s with 20 ms packets (80 octets of payload per packet, 50 packets per second); in-band FEC adding 25% to the payload when active (20 octets), the midpoint of the range reported in [RFC8854]; IPv4 and UDP headers (28 octets), RTP fixed header (12 octets), and a 10-octet SRTP authentication tag; ULPFEC sent as a separate stream with one FEC packet per four media packets (k=4), one 4-octet level header, and a protection length equal to the 100-octet media payload.¶
| Configuration | Packet size (octets) | Packets/s | Rate (kbit/s) |
|---|---|---|---|
| Opus only | 130 | 50 | 52.0 |
| Opus with in-band FEC | 150 | 50 | 60.0 |
| ULPFEC stream, k=4 | 164 | 12.5 | 16.4 |
| Opus with in-band FEC and ULPFEC, k=4 | - | 62.5 | 76.4 |
With k=2 the ULPFEC stream would cost 32.8 kbit/s, bringing the total to 92.8 kbit/s. Real overhead depends on Opus packet-size variation (Section 5.2), on IPv6 (20 additional octets per packet), and on RED encapsulation if used.¶
The following table gives residual loss from a simple simulation, to show the qualitative behaviour of each mechanism. It is not a performance claim. Assumptions: 20 ms packets; in-band FEC present in every media packet and able to repair packet N whenever packet N+1 is available; ULPFEC with one FEC packet per four media packets, either consecutive (k=4) or interleaved (two FEC packets per eight media packets, each covering every second packet); FEC packets subject to the same loss process as media packets; losses generated by a two-state Gilbert model with the stated average loss and mean burst length, where a mean burst length of 1 means independent losses; 400,000 media packets per run. Receivers apply ULPFEC first and then in-band FEC, as in Section 6.1. Values are residual loss in percent.¶
| Mean burst | Network loss | None | In-band FEC | ULPFEC k=4 | Both, k=4 | ULPFEC interleaved | Both, interleaved |
|---|---|---|---|---|---|---|---|
| 1 | 2% | 1.99 | 0.04 | 0.15 | 0.03 | 0.15 | 0.00 |
| 1 | 5% | 4.97 | 0.24 | 0.92 | 0.18 | 0.93 | 0.01 |
| 1 | 10% | 9.98 | 0.99 | 3.39 | 0.77 | 3.43 | 0.12 |
| 1 | 20% | 20.04 | 4.02 | 11.81 | 3.35 | 11.90 | 1.38 |
| 2 | 2% | 1.96 | 0.97 | 1.35 | 0.78 | 0.81 | 0.33 |
| 2 | 5% | 5.02 | 2.49 | 3.53 | 2.03 | 2.27 | 0.89 |
| 2 | 10% | 9.92 | 4.93 | 7.22 | 4.07 | 5.16 | 1.99 |
| 2 | 20% | 19.91 | 9.92 | 15.33 | 8.37 | 12.96 | 5.08 |
Under these assumptions, in-band FEC alone is very effective against independent losses, and adding consecutive ULPFEC improves on it only modestly; interleaving helps even here, because two adjacent losses then fall into different protection groups. With bursts, in-band FEC alone halves the loss at best, while interleaved ULPFEC combined with in-band FEC reduces it several-fold, because ULPFEC breaks up bursts and the packets it recovers then supply LBRR data for their predecessors. The interleaved arrangement doubles the recovery delay (Section 5.2). Real in-band FEC is not present in every packet, is absent in CELT-only mode, and repairs at lower fidelity, so measurements with real encoders and loss traces are needed before drawing quantitative conclusions.¶
This document builds on the analysis of FEC for WebRTC in [RFC8854] and on the FEC and congestion control guidance of [RFC9265].¶