RFC 8627

RTP Payload Format for Flexible Forward Error Correction (FEC)

๐Ÿ“… published July 2019, from ietf

RFC 8627 ๐Ÿ“š๐Ÿ’– RTP Payload Format for Flexible Forward Error Correction (FEC)

okay bestie, let's get into it โœจ this is the RFC that defines the RTP payload formats for FEC packets generated by the non-interleaved and interleaved parity codes, and it's giving main character energy for streaming media ๐ŸŽ€

Title block (the important bits, no columns ๐Ÿ’…):

  • Number: RFC 8627, on the Internet Standards Track ๐ŸŒธ
  • Date: July 2019 ๐Ÿ—“๏ธ
  • Authors: M. Zanaty (Cisco), V. Singh (callstats.io), A. Begen (Networked Media), and G. Mandyam (Qualcomm Inc.) ๐Ÿ‘‘
  • Obsoletes and updates: nothing is listed in this part of the title block, so none is noted here ๐Ÿ™ˆ
  • ISSN: 2070-1721 ๐Ÿฆ‹

Abstract

okay so the abstract says this document defines new RTP payload formats for the Forward Error Correction (FEC) packets made by the non-interleaved and interleaved parity codes ๐Ÿงš these are systematic codes (called Flexible FEC, or "FLEX FEC") where a bunch of FEC repair packets are generated from a set of source packets, which can come from one or more source RTP streams ๐Ÿ’…

the repair packets get sent in a separate redundancy RTP stream, apart from the source RTP stream(s) carrying the source packets ๐ŸŒˆ if source packets get lost in transit, they can be rebuilt using the source and repair packets that did arrive ๐Ÿซถ

the non-interleaved and interleaved parity codes are good at handling random and bursty packet loss, respectively, but they cost more in complexity โœจ the payload formats here fix scalability problems from earlier specs and add several improvements ๐Ÿ”ฅ

because of those changes, the new payload formats are NOT backward compatible with earlier specs ๐Ÿ’€ BUT endpoints that don't implement this spec can still function fine, they just ignore the FEC repair packets ๐Ÿ“


Status of This Memo

this one's the official paperwork ๐Ÿ“œ it's an Internet Standards Track document โœจ it's a product of the IETF and represents the consensus of the IETF community ๐Ÿ’œ it got public review and was approved for publication by the IESG ๐Ÿ‘‘ more info on Internet Standards is in Section 2 of RFC 7841 ๐ŸŒธ

you can find the current status, any errata, and how to give feedback at https://www.rfc-editor.org/info/rfc8627 ๐Ÿฆ‹


okay the legal bit ๐Ÿ™ˆ copyright (c) 2019 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) as in effect on the publication date ๐ŸŽ€ please read these carefully because they spell out your rights and restrictions ๐Ÿ’…

code components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Simplified BSD License ๐Ÿซถ


Table of Contents

the TOC is a map of the whole doc ๐Ÿ—บ๏ธ I'm keeping every section and subsection number exactly as written, so the cross-references still line up ๐Ÿ’…

1.  Introduction
  1.1.  Parity Codes
    1.1.1.  One-Dimensional (1-D) Non-interleaved (Row) FEC
            Protection
    1.1.2.  1-D Interleaved (Column) FEC Protection
    1.1.3.  Use Cases for 1-D FEC Protection
    1.1.4.  Two-Dimensional (2-D) (Row and Column) FEC Protection
    1.1.5.  FEC Protection with Flexible Mask
    1.1.6.  FEC Overhead Considerations
    1.1.7.  FEC Protection with Retransmission
    1.1.8.  Repair Window Considerations
2.  Requirements Notation
3.  Definitions and Notations
  3.1.  Definitions
  3.2.  Notations
4.  Packet Formats
  4.1.  Source Packets
  4.2.  FEC Repair Packets
    4.2.1.  RTP Header of FEC Repair Packets
    4.2.2.  FEC Header of FEC Repair Packets
5.  Payload Format Parameters
  5.1.  Media Type Registration -- Parity Codes
    5.1.1.  Registration of audio/flexfec
    5.1.2.  Registration of video/flexfec
    5.1.3.  Registration of text/flexfec
    5.1.4.  Registration of application/flexfec
  5.2.  Mapping to SDP Parameters
    5.2.1.  Offer/Answer Model Considerations
    5.2.2.  Declarative Considerations
6.  Protection and Recovery Procedures -- Parity Codes
  6.1.  Overview
  6.2.  Repair Packet Construction
  6.3.  Source Packet Reconstruction
    6.3.1.  Associating the Source and Repair Packets
    6.3.2.  Recovering the RTP Header
    6.3.3.  Recovering the RTP Payload
    6.3.4.  Iterative Decoding Algorithm for the 2-D Parity FEC
            Protection
7.  Signaling Requirements
  7.1.  SDP Examples
    7.1.1.  Example SDP for Flexible FEC Protection with In-Band
            SSRC Mapping
    7.1.2.  Example SDP for Flexible FEC Protection with Explicit
            Signaling in the SDP
  7.2.  On the Use of the RTP Stream Identifier Source
        Description
8.  Congestion Control Considerations
9.  Security Considerations
10. IANA Considerations
11. References
  11.1.  Normative References
  11.2.  Informative References
Acknowledgments
Authors' Addresses

1. Introduction โœจ

okay this is where the good stuff starts ๐ŸŽ€ the doc defines new RTP payload formats for the FEC generated by the non-interleaved and interleaved parity codes from source media encapsulated in RTP [RFC3550] ๐ŸŒธ the source media can be audio, video, text, or application ๐Ÿ’–

the FEC data gets generated from the media type parameters, which are communicated out of band (for example, in the Session Description Protocol (SDP)) ๐Ÿฆ‹ the links between source and repair RTP streams can be communicated in-band or out-of-band ๐Ÿซถ in-band works best when the endpoint is adapting the FEC parameters, and out-of-band may be the better pick when the FEC parameters are fixed ๐Ÿงš

the doc fully defines how FEC protects RTP streams, and it also borrows several definitions and the basic source/repair header description from [RFC6363] and applies them to the parity codes defined here ๐Ÿ’…

the Redundancy RTP Stream [RFC7656] repair packets proposed here protect the Source RTP Stream packets that belong to the same RTP session ๐ŸŒˆ

the new payload formats fix the scalability issues seen in the earlier specs, including [RFC2733], [RFC5109], and [SMPTE2022-1] ๐Ÿ”ฅ

1.1. Parity Codes ๐Ÿงฎ

both the non-interleaved and interleaved parity codes use the eXclusive OR (XOR) operation to generate the repair packets ๐Ÿ’œ here's what happens, step by step:

  1. the sender picks a set of source packets to protect with FEC, based on the media type parameters ๐Ÿ“
  2. the sender applies the XOR operation to the source packets to make the required number of repair packets โœจ
  3. the sender sends the repair packet(s) alongside the source packets, in different RTP streams, to the receivers ๐Ÿฆ‹ repair packets can go out proactively or on demand, based on RTCP feedback messages such as NACK [RFC4585] ๐Ÿ‘‘

on the receiver side, if every source packet arrived, there's no need for FEC recovery and the repair packets get discarded ๐Ÿ™ˆ but if source packets are missing, the repair packets can be used to recover the missing info ๐Ÿซถ

Figures 1 and 2 show example block diagrams for the systematic parity FEC encoder and decoder, respectively ๐ŸŽ€

                              +------------+
   +--+  +--+  +--+  +--+ --> | Systematic | --> +--+  +--+  +--+  +--+
   +--+  +--+  +--+  +--+     | Parity FEC |     +--+  +--+  +--+  +--+
                              |  Encoder   |
                              |  (Sender)  | --> +==+  +==+
                              +------------+     +==+  +==+

   Source Packet: +--+    Repair Packet: +==+
                  +--+                   +==+

         Figure 1: Block Diagram for Systematic Parity FEC Encoder
                              +------------+
   +--+    X    X    +--+ --> | Systematic | --> +--+  +--+  +--+  +--+
   +--+              +--+     | Parity FEC |     +--+  +--+  +--+  +--+
                              |  Decoder   |
               +==+  +==+ --> | (Receiver) |
               +==+  +==+     +------------+

   Source Packet: +--+    Repair Packet: +==+    Lost Packet: X
                  +--+                   +==+

         Figure 2: Block Diagram for Systematic Parity FEC Decoder

in Figure 2 it's clear that FEC repair packets have to reach the endpoint within a certain amount of time for FEC recovery to be useful โฐ the repair window is the time that spans one FEC block, which is made of the source packets and their matching repair packets ๐ŸŒธ

at the receiver, the FEC decoder SHOULD buffer source and repair packets for at least the duration of the repair window so all the repair packets have time to arrive ๐Ÿ’– the decoder can start decoding packets it already has sooner ๐Ÿฆ‹ but it should not register a FEC decoding failure until it has waited at least the full repair window โณ

ngl this is the part to screenshot for your group chat ๐Ÿ“ธ wait for the whole repair window before you call a decode a failure ๐Ÿ’…

Part 1 of 8. More parts coming, bestie ๐Ÿซถ๐Ÿ’–

1.1.1. One-Dimensional (1-D) Non-interleaved (Row) FEC Protection ๐ŸŒธ

okay so picture a group of D x L source packets, numbered from 1 all the way up to D x L (D and L mean the same things they do in Section 3.2 ๐Ÿซถ). now you XOR every L consecutive packets together to make a repair packet. this is called "1-D non-interleaved FEC protection" ๐Ÿ’… you end up with D repair packets, which are called non-interleaved (or row) FEC repair packets. basically D and L tell you how the packets are grouped by depth and length when you interleave all D x L of them โœจ

   +--------------------------------------------------+    ---    +===+
   | S_1          S_2          S3          ...  S_L   | + |XOR| = |R_1|
   +--------------------------------------------------+    ---    +===+
   +--------------------------------------------------+    ---    +===+
   | S_L+1        S_L+2        S_L+3       ...  S_2xL | + |XOR| = |R_2|
   +--------------------------------------------------+    ---    +===+
     .            .            .                .           .       .
     .            .            .                .           .       .
     .            .            .                .           .       .
   +--------------------------------------------------+    ---    +===+
   | S_(D-1)xL+1  S_(D-1)xL+2  S_(D-1)xL+3 ...  S_DxL | + |XOR| = |R_D|
   +--------------------------------------------------+    ---    +===+

       Figure 3: Generating Non-interleaved (Row) FEC Repair Packets

1.1.2. 1-D Interleaved (Column) FEC Protection ๐Ÿฆ‹

this one is a little different, bestie. now the XOR gets applied to source packets whose Sequence Numbers are L apart from each other ๐Ÿ‘€ (see Figure 4). in this case the endpoint makes L repair packets. this is the "1-D interleaved FEC protection" vibe, and those L repair packets are called "interleaved (or column) FEC repair packets" ๐Ÿงš

       +-------------+ +-------------+ +-------------+     +-------+
       | S_1         | | S_2         | | S3          | ... | S_L   |
       | S_L+1       | | S_L+2       | | S_L+3       | ... | S_2xL |
       | .           | | .           | |             |     |       |
       | .           | | .           | |             |     |       |
       | .           | | .           | |             |     |       |
       | S_(D-1)xL+1 | | S_(D-1)xL+2 | | S_(D-1)xL+3 | ... | S_DxL |
       +-------------+ +-------------+ +-------------+     +-------+
              +               +               +                +
        -------------   -------------   -------------       -------
       |     XOR     | |     XOR     | |     XOR     | ... |  XOR  |
        -------------   -------------   -------------       -------
              =               =               =                =
            +===+           +===+           +===+            +===+
            |C_1|           |C_2|           |C_3|      ...   |C_L|
            +===+           +===+           +===+            +===+

       Figure 4: Generating Interleaved (Column) FEC Repair Packets

1.1.3. Use Cases for 1-D FEC Protection ๐Ÿ“

so a sender can make one non-interleaved repair packet out of L consecutive source packets, OR one interleaved repair packet out of D nonconsecutive source packets ๐Ÿคญ either way, the repair packet can fully recover the missing info as long as only ONE packet is missing from the matching source packets. that means 1-D non-interleaved protection does better when the source packets get randomly lost ๐ŸŽ€ but if the losses come in bursts, 1-D interleaved protection wins, as long as L is picked big enough that the L-packet duration isn't shorter than the burst duration we actually see ๐Ÿ˜ญ if the sender uses non-interleaved repair packets and a burst loss hits the source packets, the repair fails. check out Figure 5 for the tea โ˜•

                     +---+                +---+  +===+
                     | 1 |    X      X    | 4 |  |R_1|
                     +---+                +---+  +===+

                     +---+  +---+  +---+  +---+  +===+
                     | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                     +---+  +---+  +---+  +---+  +===+

                     +---+  +---+  +---+  +---+  +===+
                     | 9 |  | 10|  | 11|  | 12|  |R_3|
                     +---+  +---+  +---+  +---+  +===+

                        Figure 5: Example Scenario:
   1-D Non-interleaved FEC Protection Fails Error Recovery (Burst Loss)

the sender can make interleaved FEC repair packets to fight the bursty losses ๐Ÿ’ช BUT two or more random losses might land in the same column, and then the repair fails too ๐Ÿ’€ see Figure 6. also, two burst losses can happen back-to-back, and in that case interleaved repair packets can still fail to recover the lost data ๐Ÿ™ˆ

                        +---+         +---+  +---+
                        | 1 |    X    | 3 |  | 4 |
                        +---+         +---+  +---+

                        +---+         +---+  +---+
                        | 5 |    X    | 7 |  | 8 |
                        +---+         +---+  +---+

                        +---+  +---+  +---+  +---+
                        | 9 |  | 10|  | 11|  | 12|
                        +---+  +---+  +---+  +---+

                        +===+  +===+  +===+  +===+
                        |C_1|  |C_2|  |C_3|  |C_4|
                        +===+  +===+  +===+  +===+

                        Figure 6: Example Scenario:
    1-D Interleaved FEC Protection Fails Error Recovery (Periodic Loss)

1.1.4. Two-Dimensional (2-D) (Row and Column) FEC Protection ๐Ÿ‘‘

when source packets get lost both randomly AND in bursts, the sender ought to make both non-interleaved and interleaved FEC repair packets ๐Ÿซถ this combo is known as "2-D parity FEC protection". yes it means more repair packets and more FEC overhead, but 2-D FEC gives you way better protection against mixed loss patterns ๐Ÿ”ฅ still, it's possible for 2-D parity protection to fail and not recover every lost source packet if a certain loss pattern happens. Figure 7 shows one example scenario ๐Ÿ‘€

                     +---+                +---+  +===+
                     | 1 |    X      X    | 4 |  |R_1|
                     +---+                +---+  +===+

                     +---+  +---+  +---+  +---+  +===+
                     | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                     +---+  +---+  +---+  +---+  +===+

                     +---+                +---+  +===+
                     | 9 |    X      X    | 12|  |R_3|
                     +---+                +---+  +===+

                     +===+  +===+  +===+  +===+
                     |C_1|  |C_2|  |C_3|  |C_4|
                     +===+  +===+  +===+  +===+

                      Figure 7: Example Scenario #1:
              2-D Parity FEC Protection Fails Error Recovery

2-D parity protection also fails when at least two rows are each missing a source packet, and the FEC packet plus the missing source packets (in at least two rows) line up in the same column ๐Ÿ˜ญ there's an example loss pattern in Figure 8. similarly, 2-D parity protection can't repair all the missing source packets when at least two columns are each missing a source packet, and the FEC packet plus the missing source packets (in at least two columns) line up in the same row ๐Ÿ’€

                     +---+  +---+         +---+
                     | 1 |  | 2 |    X    | 4 |    X
                     +---+  +---+         +---+

                     +---+  +---+  +---+  +---+  +===+
                     | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                     +---+  +---+  +---+  +---+  +===+

                     +---+  +---+         +---+
                     | 9 |  | 10|    X    | 12|    X
                     +---+  +---+         +---+

                     +===+  +===+  +===+  +===+
                     |C_1|  |C_2|  |C_3|  |C_4|
                     +===+  +===+  +===+  +===+

                      Figure 8: Example Scenario #2:
              2-D Parity FEC Protection Fails Error Recovery

1.1.5. FEC Protection with Flexible Mask ๐ŸŒˆ

you can define FEC protection for only selected packets in the source stream โœจ this gives you differential protection, which means applying FEC only to the packets that need a higher level of reliability than the rest of the stream ๐ŸŽ€ the sender has to send a bitmap that marks which packets get protected, aka a "mask", over to the receiver. and since the mask can change during an RTP session ("flexible mask"), this kind of FEC can switch on dynamically too, like adapting to different kinds of traffic mid-session ๐Ÿฆ‹

1.1.6. FEC Overhead Considerations ๐Ÿ’œ

overhead is defined as the ratio of the bytes belonging to the repair packets to the bytes belonging to the protected source packets ๐Ÿงฎ

repair packets are usually bigger than source packets, and not all source packets are the same size either ๐Ÿ™ˆ but if we assume each repair packet carries the same number of bytes as a source packet, the overhead for each FEC protection method works out like this:

   1-D Non-interleaved FEC Protection: Overhead = 1/L

   1-D Interleaved FEC Protection: Overhead = 1/D

   2-D Parity FEC Protection: Overhead = 1/L + 1/D

where L and D are the number of columns and rows in the source block, respectively ๐Ÿ“

1.1.7. FEC Protection with Retransmission ๐Ÿ”

this spec supports both forward error correction (so before any loss is reported) AND retransmission of source packets after a loss is reported ๐Ÿ’– the retransmission includes the RTP header of the source packet as well as the payload. now, if a peer supports both FLEX FEC and other RTP retransmission methods (see [RFC4588]) and gets an Offer with both FLEX FEC and another RTP retransmission method, it MUST respond with an Answer containing only FLEX FEC ๐Ÿซถ

โš ๏ธ bestie, that MUST is not a suggestion. the Answer has to be FLEX FEC only.

1.1.8. Repair Window Considerations โณ

the repair window duration is tied to the maximum L and D values you expect during a FLEX FEC session, so you can't just pick it randomly ๐Ÿ™…โ€โ™€๏ธ repair packets that carry L and D values bigger than the repair window MUST NOT be sent ๐Ÿšซ the rate of the source streams matters too. the repair window duration should ideally span several packetization intervals so the parity code can actually do its error correction job ๐Ÿ’…

because the FEC configuration can change with every repair packet (see Section 4.2.2), a FLEX FEC receiver MUST support every possible L and D combination (both 1-D and 2-D interleaved over all source flows) and every flexible mask configuration (over all source flows) inside the repair window it agreed to, whether that got set up through SDP or out-of-band signaling for a FLEX FEC RTP session ๐Ÿงš on top of that, the FLEX FEC receiver MUST support receiving a retransmission of any source flow packet within the agreed repair window ๐ŸŒธ

2. Requirements Notation โœจ

okay so first, the BCP 14 key words. when they show up in ALL CAPS like this, they're the official "do this / don't do this" words: "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL". they follow [RFC2119] [RFC8174], and they only count when they're capitalised like that ๐Ÿ’…

3. Definitions and Notations ๐ŸŽ€

3.1. Definitions

bestie, this doc borrows a bunch of definitions from [RFC6363]. it also makes up its own, and updates some of the [RFC6363] ones too ๐Ÿงš

1-D Non-interleaved Row FEC: a protection scheme that works on consecutive source packets in the source block. it can recover one lost source packet per row of the source block ๐ŸŒธ

1-D Interleaved Column FEC: a protection scheme that works on interleaved source packets in the source block. it can recover one lost source packet per column of the source block ๐Ÿฆ‹

2-D FEC: a protection scheme that combines row FEC and column FEC ๐Ÿ’œ

Source Block: a set of source packets that get protected by a set of 1-D or 2-D FEC repair packets ๐Ÿ“

FEC Block: a source block plus its matching FEC repair packets ๐Ÿซถ

Repair Window: the time that spans a FEC block, which is made up of the source packets and their FEC repair packets โญ

XOR Parity Codes: a FEC code that uses the eXclusive OR (XOR) parity operation to encode a set of source packets into one FEC repair packet ๐Ÿ”ฅ

3.2. Notations

here's the shorthand you'll see everywhere ๐Ÿ‘‘

L: the number of columns in the source block, which is the length of each row.

D: the number of rows in the source block, which is the depth of each column.

bitmask: a 15-bit, 46-bit, or 110-bit mask that tells you which source packets a FEC repair packet protects. if bit i in the mask is set to 1, then source packet number N + i is protected by this FEC repair packet, where N is the Sequence Number base carried in the FEC repair packet. the most significant bit of the mask is i=0. the least significant bit is i=14 in the 15-bit mask, i=45 in the 46-bit mask, or i=109 in the 110-bit mask ๐Ÿง 

4. Packet Formats ๐Ÿ’–

this section explains what the source packets look like, and defines what the FEC repair packets look like too โœจ

4.1. Source Packets

so the source packets already carry the info that says which source block they belong to, and where they sit inside it. the RTP streams already have unique Sequence Numbers in their RTP headers [RFC3550], so the source packets can be identified straightforwardly. no need to tack on any extra fields ๐Ÿ™Œ

the big perk of leaving the source packets totally alone is backward compatibility for receivers that don't support FEC at all. in multicast, that's a huge deal. non-FEC-capable and FEC-capable receivers can both receive and interpret the same source packets sent in the same multicast session ๐Ÿซถ

the source packets get sent as usual, with no changes. they're used together with the FEC repair packets to recover any missing source packets, which makes this scheme a systematic code ๐ŸŽ€

the source packets are full RTP packets, with an optional contributing source (CSRC) list, an RTP header extension, and padding. if any of those optional bits are in the source RTP packet and that packet gets lost, the FEC repair operation recovers them too. it rebuilds the whole source RTP packet, optional elements and all ๐Ÿฆ‹

4.2. FEC Repair Packets

the FEC repair packets carry info that identifies the source block they belong to, plus the relationship between the repair packets and the original source block. they use the RTP header of the repair packets, plus another header inside the RTP payload called the "FEC header", as shown in Figure 9 ๐Ÿงš

note that all the source stream packets protected by a particular FEC packet need to be in the same RTP session ๐Ÿ’…

          +------------------------------+
          |          IP Header           |
          +------------------------------+
          |       Transport Header       |
          +------------------------------+
          |          RTP Header          |
          +------------------------------+ ---+
          |          FEC Header          |    |
          +------------------------------+    | RTP Payload
          |         Repair Payload       |    |
          +------------------------------+ ---+

               Figure 9: Format of FEC Repair Packets

the Repair Payload comes after the FEC header and covers everything that follows the fixed 12-byte RTP header of each source packet. that includes any CSRC identifier list and header extensions, if they're there ๐ŸŒˆ

4.2.1. RTP Header of FEC Repair Packets

the RTP header follows [RFC3550], with a few extra clarifications listed below ๐Ÿ’œ

Version (V) 2 bits: this MUST be set to 2 (binary 10). this spec requires all source RTP packets and all FEC repair packets to use RTP version 2 ๐Ÿ‘‘

Padding (P) bit: source packets can have optional RTP padding, which can be recovered. FEC repair packets can have optional RTP padding too, and it's independent of the source packets' padding ๐ŸŒธ

Extension (X) bit: source packets can have optional RTP header extensions, which can be recovered. FEC repair packets can have optional RTP header extensions as well, and those are independent of the source packets' extensions โœจ

CSRC Count (CC) 4 bits, and CSRC List (CSRC_i) 32 bits each: source packets can have an optional CSRC list and count, which can be recovered. FEC repair packets MUST use the CSRC list and count to specify the synchronization sources (SSRCs) of the source RTP stream(s) protected by this FEC repair packet ๐Ÿ”ฅ

Marker (M) bit: this bit isn't used for this payload type. it SHALL be set to 0 by senders, and it SHALL be ignored by receivers ๐Ÿ™ˆ

Payload Type: the (dynamic) payload type for the FEC repair packets is figured out through out-of-band means (e.g., SDP). this document registers new payload formats for the repair packets (refer to Section 5 for details). according to [RFC3550], an RTP receiver that can't recognize a payload type must discard it. that's where the backward compatibility comes from. if a non-FEC-capable receiver gets a repair packet, it won't recognize the payload type, so it discards the repair packet ๐Ÿ’€

Sequence Number (SN): the Sequence Number follows the standard definition in [RFC3550]. so it must be one higher than the Sequence Number in the previously transmitted repair packet, and the initial value of the Sequence Number should be random (i.e., unpredictable) ๐ŸŽ€

Timestamp (TS): the timestamp SHALL be set to a time that matches the repair packet's transmission time. the timestamp value has no role in the actual FEC protection process, and it's usually handy for jitter calculations ๐Ÿฆ‹

Synchronization Source (SSRC): the SSRC value for each repair stream SHALL be randomly assigned, following the guidelines in Section 8 of [RFC3550]. this lets the sender multiplex the source and repair RTP streams in the same RTP session, or multiplex multiple repair streams in one RTP session. the repair stream's SSRC's CNAME SHOULD be identical to the CNAME of the source RTP stream(s) that this repair stream protects. a FEC stream protecting multiple source RTP streams with different CNAME's uses the CNAME tied to the entity generating the FEC stream, or the CNAME of the entity it's protecting on behalf of. when the repair stream covers packets from multiple source RTP streams with different CNAME values, and none of those CNAME values can be tied to the entity generating the FEC stream, any of them MAY be used ๐ŸŒŸ

in some networks, the RTP Source (the one producing the source packets) and the FEC Source (the one generating the repair packets from them) aren't the same host. in that case, using the same CNAME for the source and repair RTP streams means the RTP Source and FEC Source share one CNAME (for this specific source-repair stream association). a common CNAME can be produced from an algorithm that both the RTP and FEC Source know [RFC7022]. this usage is compliant with [RFC3550] ๐Ÿงš

because the SSRC assignments are random, an SSRC collision is possible. when that happens, the collisions must be resolved the way [RFC3550] describes ๐Ÿ’–

4.2.2. FEC Header of FEC Repair Packets โœจ

okay so the FEC header comes in three variants, and which one you get depends on the first two bits, R and F ๐ŸŽ€ (see Figure 10). R stands for "retransmit" and F stands for "fixed block" ๐Ÿ’… The first two variants are two different ways of pulling the source data out of a source packet for a repair packet. That lets the FEC method get tougher against different levels of burst errors and random packet loss ๐Ÿ”ฅ The third variant is just a straight retransmission of the source packet, no cap.

  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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |R|F|P|X|  CC   |M| PT recovery | ...varies depending on R/F... |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 |                 ...varies depending on R/F...                 |
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 :                Repair Payload follows FEC header              :
 :                                                               :

                       Figure 10: FEC header

The Repair Payload comes right after the FEC header, and it covers everything after the fixed 12-byte RTP header of each source packet ๐Ÿงš That includes the CSRC identifier list and any header extensions, if they're there. Section 6 has an overview of how the Repair Payload gets used to recover source packets, so go check that out bestie ๐Ÿฆ‹

+---+---+-----------------------------------------------------+
| R | F | FEC header variant                                  |
+---+---+-----------------------------------------------------+
| 0 | 0 | Flexible FEC Mask fields indicate source packets    |
| 0 | 1 | Fixed FEC L/D (cols/rows) indicate source packets   |
| 1 | 0 | Retransmission of a single source packet            |
| 1 | 1 | Reserved for future use, MUST NOT send, MUST ignore |
+---+---+-----------------------------------------------------+

     Figure 11: R and F Bit Values for FEC Header Variants

When R=0 and F=0, you get the first variant, which has a mask that signals the protected source packets (see Figure 12) ๐ŸŒธ When R=0 and F=1, you get the second one, with a number of columns (L) and rows (D) that signal the protected source packets (see Figure 13) ๐Ÿ’œ And when R=1 and F=0, it's the retransmission format, which you can see in Figure 15 ๐ŸŽ€

R=1 and F=1 is a no-go for now, since it's reserved for future use ๐Ÿ™ˆ Current FLEX FEC implementations MUST NOT send packets with this variant, and receivers MUST ignore these packets. Future FLEX FEC implementations might use it, but only by updating the media type registration ๐Ÿ’…

The FEC header for every variant has these common fields:

  • The R bit MUST be set to 1 to indicate a retransmission packet, and MUST be set to 0 for FEC repair packets.
  • The F bit tells you what kind of FEC repair packet you're looking at, as shown in Figure 11, when the R bit is 0. The F bit MUST be set to 0 when the R bit is 1 for retransmission packets.
  • The P, X, CC, M, and PT recovery fields are used to figure out the matching fields of the recovered packets (see also Section 6.3.2) ๐Ÿซถ

4.2.2.1. FEC Header with Flexible Mask

When R=0 and F=0, the FEC header has flexible Mask fields ๐ŸŒˆ

  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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |0|0|P|X|  CC   |M| PT recovery |        length recovery        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                          TS recovery                          |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |           SN base_i           |k|          Mask [0-14]        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |k|                   Mask [15-45] (optional)                   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                     Mask [46-109] (optional)                  |
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |   ... next SN base and Mask for CSRC_i in CSRC list ...       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 :                Repair Payload follows FEC header              :
 :                                                               :

                   Figure 12: FEC Header for F=0

Here's the breakdown for this variant, bestie ๐Ÿง

  • The Length recovery (16 bits) field helps figure out the length of the recovered packets. This length counts every octet after the fixed 12-byte RTP header of the source packets, including the CSRC list and any optional header extension(s) if they're present. It leaves out the fixed 12-byte RTP header of the source packets ๐ŸŽ€
  • The TS recovery (32 bits) field helps figure out the timestamp of the recovered packets โฐ
  • The CSRC_i (32 bits) field in the RTP header (not the FEC header) describes the SSRC of the source packets protected by this particular FEC packet. If one FEC packet protects multiple SSRCs (you can tell because the CSRC Count is > 1 in the RTP header), there will be multiple blocks of data, each with their own SN base and Mask fields ๐Ÿ‘‘
  • The SN base_i (16 bits) field gives the lowest sequence number, taking wrap around into account, of the source packets for a particular SSRC (the one in CSRC_i) that this repair packet protects ๐Ÿฆ‹
  • The Mask fields are a bitmask of which source packets this FEC repair packet protects. If bit j of the mask is set to 1, then the source packet with Sequence Number (SN base_i + j) is protected by this FEC repair packet. j=0 is the most significant bit in the mask ๐Ÿ’–
  • The k-bit in the bitmasks tells you whether the mask is 15, 46, or 110 bits. k=1 means another mask follows, and k=0 means this is the last block of mask ๐ŸŒธ
  • The Repair Payload, which follows the FEC header, covers everything after the fixed 12-byte RTP header of each source packet, including any CSRC identifier list and header extensions if they're there ๐Ÿซถ

4.2.2.2. FEC Header with Fixed L Columns and D Rows

When R=0 and F=1, the FEC header has L and D fields for fixed columns and rows. Everything else works the same as the last section ๐Ÿ“ Like before, the CSRC_i (32 bits) field in the RTP header (not the FEC Header) describes the SSRC of the source packets protected by this particular FEC packet. If there are multiple SSRCs protected by the FEC packet, there will be multiple blocks of data, each with an SN base along with L and D fields โœจ

  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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |0|1|P|X|  CC   |M| PT recovery |         length recovery       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                          TS recovery                          |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |           SN base_i           |  L (columns)  |    D (rows)   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |    ... next SN base and L/D for CSRC_i in CSRC list ...       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 :                Repair Payload follows FEC header              :
 :                                                               :

                   Figure 13: FEC Header for F=1

So here's how L and D work, no cap ๐Ÿ’…

If L=0, D=0, reserved for future use,
             MUST NOT send, MUST ignore if received.

If L>0, D=0, indicates row FEC, and no column FEC will follow (1D).
             Source packets for each row: SN, SN+1, ..., SN+(L-1)

If L>0, D=1, indicates row FEC, and column FEC will follow (2D).
             Source packets for each row: SN, SN+1, ..., SN+(L-1)
             Source packets for each col: SN, SN+L, ..., SN+(D-1)*L
             After all row FEC packets have been sent,
             the column FEC packets will be sent.

If L>0, D>1, indicates column FEC of every L packet, D times.
             Source packets for each col: SN, SN+L, ..., SN+(D-1)*L

          Figure 14: Interpreting the L and D Field Values

Since L and D are 8-bit fields (see Figure 13), the biggest either one can be is 255 ๐Ÿ”ฅ If L=0 and D=0 show up in a packet, the repair packet MUST be ignored by the receiver ๐Ÿ™ˆ Also, when L=1 and D=0, the repair packet turns into a retransmission of the matching source packet ๐Ÿ’œ

The L and D values for a block of recovery data match the type of recovery being used for that block ๐ŸŒท For 2-D repair especially, the (L,D) values might not stay the same across every packet for a given SSRC being repaired ๐Ÿฆ‹ L and D can also be different across the different blocks of repair data in one packet, since each block repairs a different SSRC. And if the L and D values end up making a repair packet that goes past the repair window of the FLEX FEC session, the repair packet MUST be ignored ๐Ÿซ 

It's worth noting that the flexible mask approach may be inefficient for protecting a large number of source packets, or impossible to signal if it's bigger than the largest mask size. In those cases, the fixed columns and rows variant may be more useful ๐ŸŒˆ

4.2.2.3. FEC Header for Retransmissions ๐Ÿฆ‹

okay so when R=1 and F=0, the FEC packet is a retransmission of a single source packet ๐Ÿ”. ngl this layout is different from every other FEC repair packet, so pay attention bestie ๐Ÿ‘€. The Sequence Number (SN base_i) takes over the spot where length recovery normally lives in the FEC header, because the length is already known for one packet ๐Ÿ’…. There are no L, D, or Mask fields ๐Ÿ™ˆ, since only one packet gets retransmitted and the Sequence Number in the FEC header is how it gets identified. The source packet's SSRC lives in the FEC header for retransmissions, not in the RTP header CSRC list like the R=0 variants do ๐ŸŒธ. When performing retransmissions, a single repair packet stream (SSRC) MAY be used for retransmitting packets from multiple source packet streams (SSRCs), as well as transmitting FEC repair packets that protect multiple source packet streams (SSRCs) โœจ.

This FEC header layout is identical to the source RTP (version 2) packet, starting with its RTP header. The retransmission "payload" is everything following the fixed 12-byte RTP header of the source packet, including the CSRC list and extensions if present. So the only operation needed for sending retransmissions is to prepend a new RTP header to the source packet ๐Ÿงš.

    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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |1|0|P|X|  CC   |M| Payload Type|        Sequence Number        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           Timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                              SSRC                             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   :           Retransmission Payload follows FEC header           :
   :                                                               :
                 Figure 15: FEC Header for Retransmission

5. Payload Format Parameters ๐ŸŽ€

this section is where the media subtype registrations for the non-interleaved and interleaved parity FEC live ๐Ÿ“. It also defines the parameters that are required to configure the FEC encoding and decoding operations. And if no specific FEC code is specified in the subtype, the FEC code defaults to the parity code defined in this specification ๐Ÿ’œ.

5.1. Media Type Registration -- Parity Codes

this registration is done using the template defined in [RFC6838] and following the guidance provided in [RFC4855] along with [RFC4856] ๐ŸŒˆ.

5.1.1. Registration of audio/flexfec

Type name: audio

Subtype name: flexfec

Required parameters:

  • rate: The RTP timestamp (clock) rate. The rate SHALL be larger than 1000 Hz to provide sufficient resolution to RTCP operations. However, it is RECOMMENDED to select the rate that matches the rate of the protected source RTP stream.
  • repair-window: The time that spans the source packets and the corresponding repair packets. The size of the repair window is specified in microseconds.

Encoding considerations: This media type is framed (see Section 4.8 in the template document [RFC6838]) and contains binary data.

Security considerations: See Section 9 of [RFC8627].

Interoperability considerations: None.

Published specification: [RFC8627].

Applications that use this media type: Multimedia applications that want to improve resiliency against packet loss by sending redundant data in addition to the source media.

Fragment identifier considerations: None.

Additional information: None.

Person & email address to contact for further information: IESG <iesg@ietf.org> and IETF Audio/Video Transport Payloads Working Group (or its successor as delegated by the IESG).

Intended usage: COMMON.

Restrictions on usage: This media type depends on RTP framing; hence, it is only defined for transport via RTP [RFC3550].

Author: Varun Singh <varun@callstats.io>.

Change controller: IETF Audio/Video Transport Payloads Working Group delegated from the IESG (or its successor as delegated by the IESG).

5.1.2. Registration of video/flexfec

Type name: video

Subtype name: flexfec

Required parameters:

  • rate: The RTP timestamp (clock) rate. The rate SHALL be larger than 1000 Hz to provide sufficient resolution to RTCP operations. However, it is RECOMMENDED to select the rate that matches the rate of the protected source RTP stream.
  • repair-window: The time that spans the source packets and the corresponding repair packets. The size of the repair window is specified in microseconds.

Encoding considerations: This media type is framed (see Section 4.8 in the template document [RFC6838]) and contains binary data.

Security considerations: See Section 9 of [RFC8627].

Interoperability considerations: None.

Published specification: [RFC8627].

Applications that use this media type: Multimedia applications that want to improve resiliency against packet loss by sending redundant data in addition to the source media.

Fragment identifier considerations: None.

Additional information: None.

Person & email address to contact for further information: IESG <iesg@ietf.org> and IETF Audio/Video Transport Payloads Working Group (or its successor as delegated by the IESG).

Intended usage: COMMON.

Restrictions on usage: This media type depends on RTP framing; hence, it is only defined for transport via RTP [RFC3550].

Author: Varun Singh <varun@callstats.io>.

Change controller: IETF Audio/Video Transport Payloads Working Group delegated from the IESG (or its successor as delegated by the IESG).

5.1.3. Registration of text/flexfec

Type name: text

Subtype name: flexfec

Required parameters:

  • rate: The RTP timestamp (clock) rate. The rate SHALL be larger than 1000 Hz to provide sufficient resolution to RTCP operations. However, it is RECOMMENDED to select the rate that matches the rate of the protected source RTP stream.
  • repair-window: The time that spans the source packets and the corresponding repair packets. The size of the repair window is specified in microseconds.

Encoding considerations: This media type is framed (see Section 4.8 in the template document [RFC6838]) and contains binary data.

Security considerations: See Section 9 of [RFC8627].

Interoperability considerations: None.

Published specification: [RFC8627].

Applications that use this media type: Multimedia applications that want to improve resiliency against packet loss by sending redundant data in addition to the source media.

Fragment identifier considerations: None.

Additional information: None.

Person & email address to contact for further information: IESG <iesg@ietf.org> and IETF Audio/Video Transport Payloads Working Group (or its successor as delegated by the IESG).

Intended usage: COMMON.

Restrictions on usage: This media type depends on RTP framing; hence, it is only defined for transport via RTP [RFC3550].

Author: Varun Singh <varun@callstats.io>.

Change controller: IETF Audio/Video Transport Payloads Working Group delegated from the IESG (or its successor as delegated by the IESG).

5.1.4. Registration of application/flexfec

Type name: application

Subtype name: flexfec

Required parameters:

  • rate: The RTP timestamp (clock) rate. The rate SHALL be larger than 1000 Hz to provide sufficient resolution to RTCP operations. However, it is RECOMMENDED to select the rate that matches the rate of the protected source RTP stream.
  • repair-window: The time that spans the source packets and the corresponding repair packets. The size of the repair window is specified in microseconds.

Encoding considerations: This media type is framed (see Section 4.8 in the template document [RFC6838]) and contains binary data.

Security considerations: See Section 9 of [RFC8627].

Interoperability considerations: None.

Published specification: [RFC8627].

Applications that use this media type: Multimedia applications that want to improve resiliency against packet loss by sending redundant data in addition to the source media.

Fragment identifier considerations: None.

Additional information: None.

Person & email address to contact for further information: IESG <iesg@ietf.org> and IETF Audio/Video Transport Payloads Working Group (or its successor as delegated by the IESG).

Intended usage: COMMON.

Restrictions on usage: This media type depends on RTP framing; hence, it is only defined for transport via RTP [RFC3550].

Author: Varun Singh <varun@callstats.io>.

Change controller: IETF Audio/Video Transport Payloads Working Group delegated from the IESG (or its successor as delegated by the IESG).

5.2. Mapping to SDP Parameters ๐Ÿฆ‹

applications that use the RTP transport commonly use the Session Description Protocol (SDP) [RFC4566] to describe their RTP sessions. The information used to specify the media types in an RTP session maps to specific fields in an SDP description, and this section provides those mappings for the media subtypes registered by this document ๐Ÿ—บ๏ธ. Note that if an application does not use SDP to describe the RTP sessions, an appropriate mapping must be defined and used to specify the media types and their parameters for the control/description protocol employed by the application.

the mapping of the media type specification for "flexfec" and its associated parameters in SDP goes like this:

  • The media type (e.g., "application") goes into the m= line as the media name.
  • The media subtype goes into the a=rtpmap line as the encoding name. The RTP clock rate parameter ("rate") also goes into the a=rtpmap line as the clock rate.
  • The remaining required payload-format-specific parameters go into the a=fmtp line by copying them directly from the media type string as a semicolon-separated list of parameter=value pairs.

SDP examples are provided in Section 7.1 โœจ.

5.2.1. Offer/Answer Model Considerations ๐Ÿ’…

when offering parity FEC over RTP using SDP in an Offer/Answer model [RFC3264], the following considerations apply:

  • A sender application will indicate a repair window consistent with the desired amount of protection. Since the sender can change the FEC configuration on a packet-by-packet basis, note that the receiver must support any valid FLEX FEC configuration within the repair window associated with the offer (see Section 4.2.2). If the receiver cannot support the offered repair window it MUST reject the offer.
  • The size of the repair-window is related to the maximum delay between the transmission of a source packet and the associated repair packet. This directly impacts the buffering requirement on the receiver side, and the receiver must consider this when choosing an offer.
  • Any unknown option in the offer must be ignored and deleted from the answer (see Section 6 of [RFC3264]). If FEC is not desired by the receiver, it can be deleted from the answer.

5.2.2. Declarative Considerations โœจ

okay so in declarative usage, like SDP in the Real-time Streaming Protocol (RTSP, for RTSP 1.0 see [RFC2326] and for RTSP 2.0 see [RFC7826]) or the Session Announcement Protocol (SAP) [RFC2974], these considerations apply ๐Ÿ’…

  • The payload format configuration parameters are all declarative, and a participant MUST use the configuration that is provided for the session. ๐ŸŽ€
  • More than one configuration may be provided (if desired) by declaring multiple RTP payload types. In that case, the receivers should choose the repair stream that is best for them. ๐Ÿฆ‹

6. Protection and Recovery Procedures -- Parity Codes ๐ŸŒธ

This section is the full, complete spec for the 1-D and 2-D parity codes and their RTP payload formats. It does not apply to the single packet retransmission format (R=1 in the FEC header) ๐Ÿ™ˆ

6.1. Overview

The next sections walk through the steps for making the repair packets and rebuilding the missing source packets from them. Let's gooo ๐Ÿงš

6.2. Repair Packet Construction

The RTP header of a repair packet is formed based on the guidelines given in Section 4.2. โœจ

The FEC header and Repair Payload of a repair packet are made by XORing bit strings. Each bit string comes from one of the source packets protected by that repair packet. To figure out which source packets belong to a given repair packet, use the formula in Section 6.3.1 ๐Ÿ’–

Each source packet gets its own bit string, built by concatenating these fields together in this exact order:

  • The first 16 bits of the RTP header (16 bits), though the first two (version) bits will be ignored by the recovery procedure.
  • Unsigned network-ordered 16-bit representation of the source packet length in bytes minus 12 (for the fixed RTP header), i.e., the sum of the lengths of all the following if present: the CSRC list, extension header, RTP payload, and RTP padding (16 bits).
  • The timestamp of the RTP header (32 bits).
  • All octets after the fixed 12-byte RTP header. (Note the SSRC field is skipped.)

The FEC bit string comes from applying the parity operation to the bit strings of the source packets. Then the FEC header is built from the FEC bit string like this:

  • The first (most significant) 2 bits in the FEC bit string, which contain the RTP version field, are skipped. The R and F bits in the FEC header are set to the appropriate value, i.e., it depends on the chosen format variant. As a consequence of overwriting the RTP version field with the R and F bits, this payload format only supports RTP version 2. ๐Ÿ“
  • The next bit in the FEC bit string is written into the P recovery bit in the FEC header.
  • The next bit in the FEC bit string is written into the X recovery bit in the FEC header.
  • The next 4 bits of the FEC bit string are written into the CC recovery field in the FEC header.
  • The next bit is written into the M recovery bit in the FEC header.
  • The next 7 bits of the FEC bit string are written into the PT recovery field in the FEC header.
  • The next 16 bits are written into the length recovery field in the FEC header.
  • The next 32 bits of the FEC bit string are written into the TS recovery field in the FEC header.
  • The lowest Sequence Number of the source packets protected by this repair packet is written into the Sequence Number Base field in the FEC header. This needs to be repeated for each SSRC that has packets included in the source block.
  • Depending on the chosen FEC header variant, the mask(s) is set when F=0 or the L and D values are set when F=1. This needs to be repeated for each SSRC that has packets included in the source block.
  • The rest of the FEC bit string, which contains everything after the fixed 12-byte RTP header of the source packet, is written into the Repair Payload following the FEC header. Here "Payload" means everything after the fixed 12-byte RTP header, including extensions, CSRC list, true payloads, and padding. ๐Ÿ‘‘

If the lengths of the source packets are not equal, each shorter packet MUST be padded to the length of the longest packet by adding octet zeros at the end. ๐Ÿซถ

Because of this possible padding and the mandatory FEC header, a repair packet ends up bigger than the source packets it protects. ๐Ÿ˜ญ That can cause problems if the resulting repair packet size goes over the Maximum Transmission Unit (MTU) size of the path the repair stream is sent over.

6.3. Source Packet Reconstruction

This section describes the recovery procedures needed to rebuild the missing source packets. The recovery process has two steps. In the first step, the FEC decoder figures out which source and repair packets to use to recover a missing packet. In the second step, the decoder rebuilds the missing packet, which is made of an RTP header and an RTP payload. ๐Ÿ”ฅ

The following describes the RECOMMENDED algorithms for the first and second steps. Depending on the implementation, different algorithms MAY be adopted. However, the end result MUST be identical to the one produced by the algorithms described below. ๐Ÿ’…

Note that the same algorithms are used by the 1-D parity codes, whether the FEC protection is applied over a column or a row. The 2-D parity codes, on the other hand, usually need multiple iterations of the procedures described here. That iterative decoding algorithm gets its own explanation in Section 6.3.4. ๐ŸŒˆ

6.3.1. Associating the Source and Repair Packets

Before associating source and repair packets, the receiver must know which RTP sessions the source and the repair are each being sent in. Once the receiver has that sorted, step one is associating the source and repair packets. This association can use flexible bitmasks or fixed L and D offsets. The offsets can live in the FEC header, or be signaled in SDP through optional payload format parameters when L=D=0 in the FEC header. โœจ

6.3.1.1. Using Bitmasks

To use flexible bitmasks, the first two FEC header bits MUST have R=0 and F=0. A 15-bit, 46-bit, or 110-bit mask shows which source packets are protected by a FEC repair packet. If bit i in the mask is set to 1, then source packet number N + i is protected by this FEC repair packet, where N is the Sequence Number base indicated in the FEC header. The most significant bit of the mask corresponds to i=0. The least significant bit corresponds to i=14 in the 15-bit mask, i=45 in the 46-bit mask, or i=109 in the 110-bit mask. ๐Ÿฆ‹

The bitmasks can represent arbitrary protection patterns, for example 1-D interleaved, 1-D non-interleaved, and 2-D. Honestly so flexible ๐Ÿคฉ

6.3.1.2. Using L and D Offsets

Let's call the set of source packets associated with repair packet p* by the name set T(p*). In a source block whose size is L columns by D rows, set T includes D source packets plus one repair packet for the FEC protection applied over a column, and it includes L source packets plus one repair packet for the FEC protection applied over a row. Remember that 1-D interleaved and non-interleaved FEC protection can fully recover the missing information if there is only one source packet missing per column or row in set T. If more than one source packet is missing per column or row in set T, 1-D FEC protection may fail to recover all the missing information. ๐Ÿ˜ญ

When the value of L is non-zero, the 8-bit fields indicate the offset of packets protected by an interleaved (D>0) or non-interleaved (D=0) FEC packet. Combining interleaved and non-interleaved FEC repair packets can form 2-D protection patterns. ๐Ÿ’œ

Mathematically, for any received repair packet p*, the sequence numbers of the source packets it protects are determined as follows, where SN is the Sequence Number base in the FEC header:

 For each SSRC (in CSRC list):
 When D <= 1: Source packets for each row: SN, SN+1, ..., SN+(L-1)
 When D >  1: Source packets for each col: SN, SN+L, ..., SN+(D-1)*L

6.3.2. Recovering the RTP Header

For a given set T, the procedure for recovering the RTP header of the missing packet, whose Sequence Number is denoted by SEQNUM, goes like this ๐ŸŽ€

  1. For each of the source packets that are successfully received in T, compute the 80-bit string by concatenating the first 64 bits of their RTP header and the unsigned network-ordered 16-bit representation of their length in bytes minus 12.
  2. For the repair packet in T, extract the FEC bit string as the first 80 bits of the FEC header.
  3. Calculate the recovered bit string as the XOR of the bit strings generated from all source packets in T and the FEC bit string generated from the repair packet in T.
  4. Create a new packet with the standard 12-byte RTP header and no payload.
  5. Set the version of the new packet to 2. Skip the first 2 bits in the recovered bit string.
  6. Set the Padding bit in the new packet to the next bit in the recovered bit string.
  7. Set the Extension bit in the new packet to the next bit in the recovered bit string.
  8. Set the CC field to the next 4 bits in the recovered bit string.
  9. Set the Marker bit in the new packet to the next bit in the recovered bit string.
  10. Set the Payload type in the new packet to the next 7 bits in the recovered bit string.
  11. Set the SN field in the new packet to SEQNUM.
  12. Take the next 16 bits of the recovered bit string and set the new variable Y to whatever unsigned integer this represents (assuming network order). Convert Y to host order. Y represents the length of the new packet in bytes minus 12 (for the fixed RTP header), i.e., the sum of the lengths of all the following if present: the CSRC list, header extension, RTP payload, and RTP padding.
  13. Set the TS field in the new packet to the next 32 bits in the recovered bit string.
  14. Set the SSRC of the new packet to the SSRC of the missing source RTP stream.

This procedure recovers the header of an RTP packet up to (and including) the SSRC field. ๐Ÿงš

6.3.3. Recovering the RTP Payload โœจ

okay bestie, once the RTP header is back, it's time for the RTP "payload" ๐Ÿ’–. Here "payload" means literally everything after the fixed 12-byte RTP header: extensions, CSRC list, true payload, and padding. The steps go like this:

  1. Allocate Y additional bytes for the new packet generated in Section 6.3.2.
  2. For each of the source packets that are successfully received in T, compute the bit string from the Y octets of data starting with the 13th octet of the packet. If any of the bit strings generated from the source packets has a length shorter than Y, pad them to that length. The zero-padding octets MUST be added at the end of the bit string. Note that the information of the first 8 octets are protected by the FEC header. ๐Ÿซถ
  3. For the repair packet in T, compute the FEC bit string from the repair packet payload, i.e., the Y octets of data following the FEC header. Note that the FEC header may be different sizes depending on the variant and bitmask size.
  4. Calculate the recovered bit string as the XOR of the bit strings generated from all source packets in T and the FEC bit string generated from the repair packet in T.
  5. Set the last Y octets in the new packet to the recovered bit string.

6.3.4. Iterative Decoding Algorithm for the 2-D Parity FEC Protection ๐ŸŒˆ

in 2-D parity FEC protection, the sender makes both non-interleaved and interleaved FEC repair packets ๐Ÿ”ฅ. That's the move for handling mixed loss patterns, the random ones and the bursty ones. On the receiver side, these FEC packets get used iteratively to fix the shortcomings of 1-D non-interleaved or interleaved FEC, which boosts the chances of full error recovery. iconic. ๐Ÿ‘‘

The iterative decoding algorithm runs like this:

  1. Set num_recovered_until_this_iteration to zero
  2. Set num_recovered_so_far to zero
  3. Recover as many source packets as possible by using the non-interleaved FEC repair packets as outlined in Sections 6.3.2 and 6.3.3 and increase the value of num_recovered_so_far by the number of recovered source packets.
  4. Recover as many source packets as possible by using the interleaved FEC repair packets as outlined in Sections 6.3.2 and 6.3.3 and increase the value of num_recovered_so_far by the number of recovered source packets.
  5. Check the condition below. If it holds, set num_recovered_until_this_iteration to the value of num_recovered_so_far and go back to step 3. Otherwise, terminate.
If num_recovered_so_far > num_recovered_until_this_iteration
---num_recovered_until_this_iteration = num_recovered_so_far
---Go to step 3
Else
---Terminate

The algorithm terminates either when all missing source packets are fully recovered, or when there are still missing source packets but the FEC repair packets can't recover any more of them. For the example scenarios where 2-D parity FEC protection fails to fully recover, refer to Section 1.1.4. Once it terminates, num_recovered_so_far holds the total number of recovered source packets. ๐Ÿ’…

Example:

Suppose the receiver experienced the loss pattern sketched in Figure 16.

                                   +---+  +---+  +===+
                       X      X    | 3 |  | 4 |  |R_1|
                                   +---+  +---+  +===+

                     +---+  +---+  +---+  +---+  +===+
                     | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                     +---+  +---+  +---+  +---+  +===+

                     +---+                +---+  +===+
                     | 9 |    X      X    | 12|  |R_3|
                     +---+                +---+  +===+

                     +===+  +===+  +===+  +===+
                     |C_1|  |C_2|  |C_3|  |C_4|
                     +===+  +===+  +===+  +===+

Figure 16: Example: Loss Pattern for the Iterative Decoding Algorithm

The receiver runs the iterative decoding algorithm and recovers source packets #1 and #11 in the first iteration. The resulting pattern is sketched in Figure 17. ๐Ÿฆ‹

                     +---+         +---+  +---+  +===+
                     | 1 |    X    | 3 |  | 4 |  |R_1|
                     +---+         +---+  +---+  +===+

                     +---+  +---+  +---+  +---+  +===+
                     | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                     +---+  +---+  +---+  +---+  +===+

                     +---+         +---+  +---+  +===+
                     | 9 |    X    | 11|  | 12|  |R_3|
                     +---+         +---+  +---+  +===+

                     +===+  +===+  +===+  +===+
                     |C_1|  |C_2|  |C_3|  |C_4|
                     +===+  +===+  +===+  +===+

Figure 17: The Resulting Pattern after the First Iteration

Since the if condition holds true, the receiver runs a new iteration. In the second iteration, source packets #2 and #10 are recovered, resulting in a full recovery as sketched in Figure 18. ๐ŸŽ€

                     +---+  +---+  +---+  +---+  +===+
                     | 1 |  | 2 |  | 3 |  | 4 |  |R_1|
                     +---+  +---+  +---+  +---+  +===+

                     +---+  +---+  +---+  +---+  +===+
                     | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                     +---+  +---+  +---+  +---+  +===+

                     +---+  +---+  +---+  +---+  +===+
                     | 9 |  | 10|  | 11|  | 12|  |R_3|
                     +---+  +---+  +---+  +---+  +===+

                     +===+  +===+  +===+  +===+
                     |C_1|  |C_2|  |C_3|  |C_4|
                     +===+  +===+  +===+  +===+

Figure 18: The Resulting Pattern after the Second Iteration


7. Signaling Requirements ๐Ÿ“ก

out-of-band signaling should be designed so the receiver can identify the RTP streams associated with source packets and repair packets, respectively. At a minimum, the signaling must be designed to allow the receiver to:

  • Determine whether one or more source RTP streams will be sent.
  • Determine whether one or more repair RTP streams will be sent.
  • Associate the appropriate SSRC's to both source and repair streams.
  • Clearly identify which SSRC's are associated with each source block.
  • Clearly identify which repair packets correspond to which source blocks.
  • Make use of repair packets to recover source data associated with specific SSRC's.

This section gives several Session Description Protocol (SDP) examples showing how these requirements can be met. ๐Ÿงš

7.1. SDP Examples ๐Ÿ“

This section gives two SDP [RFC4566] examples. The examples use the FEC grouping semantics defined in [RFC5956]. โœจ

7.1.1. Example SDP for Flexible FEC Protection with In-Band SSRC Mapping ๐ŸŽ€

in this example, we have one source video stream and one FEC repair stream. The source and repair streams are multiplexed on different SSRCs. The repair window is set to 200 ms.

v=0
o=mo 1122334455 1122334466 IN IP4 fec.example.com
s=FlexFEC minimal SDP signaling Example
t=0 0
m=video 30000 RTP/AVP 96 98
c=IN IP4 233.252.0.1/127
a=rtpmap:96 VP8/90000
a=rtpmap:98 flexfec/90000
a=fmtp:98; repair-window=200000

7.1.2. Example SDP for Flexible FEC Protection with Explicit Signaling in the SDP ๐Ÿ’œ

this example shows one source video stream (ssrc:1234) and one FEC repair streams (ssrc:2345). One FEC group is formed with the "a=ssrc-group:FEC-FR 1234 2345" line. The source and repair streams are multiplexed on different SSRCs. The repair window is set to 200 ms.

v=0
o=ali 1122334455 1122334466 IN IP4 fec.example.com
s=2-D Parity FEC with no in band signaling Example
t=0 0
m=video 30000 RTP/AVP 100 110
c=IN IP4 192.0.2.0/24
a=rtpmap:100 MP2T/90000
a=rtpmap:110 flexfec/90000
a=fmtp:110; repair-window:200000
a=ssrc:1234
a=ssrc:2345
a=ssrc-group:FEC-FR 1234 2345

7.2. On the Use of the RTP Stream Identifier Source Description ๐Ÿ™ˆ

the RTP Stream Identifier Source Description [RTP-SDES] is a format that can identify a single RTP source stream along with an associated repair stream. However, this specification already defines a way to identify source and repair streams that lets one repair stream protect multiple source streams. Therefore, the RTP Stream Identifier Source Description SHOULD NOT be used for the Flexible FEC payload format. > this one's a big no for RTP-SDES, bestie ๐Ÿ’€


8. Congestion Control Considerations ๐ŸŒธ

FEC is an effective way to give applications resiliency against packet losses. However, in networks where congestion is a major contributor to packet loss, the potential impacts of using FEC should be considered carefully before injecting repair streams into the network. In particular, in bandwidth-limited networks, FEC repair streams may consume a significant part of the available bandwidth and, as a result, may congest the network. In such cases, applications MUST NOT arbitrarily increase the amount of FEC protection, since doing so may lead to a congestion collapse. If desired, stronger FEC protection MAY be applied only after the source rate has been reduced. ๐Ÿšจ

In a network-friendly implementation, an application should avoid sending or receiving FEC repair streams if it knows that doing so would not help at all in recovering the missing packets. Examples of where FEC would not be beneficial are (1) if the successful recovery rate, as determined by RTCP feedback, is low (see [RFC5725] and [RFC7509] and (2) the application has a smaller latency requirement than the repair window adopted by the FEC configuration, based on the expected burst loss duration and the target FEC overhead. It is RECOMMENDED that the amount and type (row, column, or both) of FEC protection is adjusted dynamically based on the packet loss rate and burst loss length observed by the applications. smart and responsive, no notes ๐Ÿƒ

In multicast scenarios, it may be difficult to optimize FEC protection per receiver. If there is a large variation among the levels of FEC protection needed by different receivers, it is RECOMMENDED that the sender offer multiple repair streams with different levels of FEC protection, and that the receivers join the corresponding multicast sessions to receive the repair stream(s) that is best for them. this is the most considerate networking energy ever ๐ŸŒˆ๐Ÿ’–

9. Security Considerations โœจ

okay bestie, this section is a lot, but it's SO important, so let's go ๐Ÿซถ

RTP packets that use the payload format in this spec are subject to the security considerations in the RTP spec [RFC3550] and in any applicable RTP profile ๐Ÿ”. The big three things to care about for the RTP packet carrying this payload format are confidentiality, integrity, and source authenticity ๐Ÿ’œ. Confidentiality can be handled by encrypting the RTP payload. Integrity of the RTP packets comes from a suitable cryptographic integrity protection mechanism, and that same kind of crypto system might also let you authenticate where the payload came from โœจ. A good security mechanism for this payload format should give you confidentiality, integrity protection, and at least source authentication that can tell whether an RTP packet is from a member of the RTP session ๐Ÿฆ‹.

Here's the tea: no single mechanism is enough on its own, because the right security depends on the application, the transport, and the signaling protocol you're using ๐Ÿ™ˆ. If it fits, using the Secure Real-time Transport Protocol (SRTP) [RFC3711] is recommended ๐Ÿ’…. Other options include IPsec [RFC4301], and Datagram Transport Layer Security (DTLS, see [RFC6347]) when you're running RTP over UDP ๐ŸŒˆ. Other alternatives may exist too ๐ŸŒธ.

Now the spicy part ๐ŸŒถ๏ธ. FLEX FEC can protect multiple source streams, so it's possible for multiple source buffers to get created that never actually get used ๐Ÿ˜ญ. An attacker could abuse those unused source buffers to hog memory on a FLEX FEC endpoint ๐Ÿ’€. An attack on the FEC parameters themselves, like the repair window or the D or L values, could make a receiver allocate source buffer space it doesn't need, and that can lead to excessive resource consumption ๐Ÿ”ฅ. A network attacker could also tamper with the recovery fields that describe packet lengths (if there are no message integrity mechanisms), and that could force unnecessarily large memory allocations at the receiver ๐Ÿงš. And here's another one: the application's source data might not line up perfectly with FLEX FEC source partitioning ๐Ÿฅบ. If that happens, some source data could end up unprotected, for example if the FLEX FEC implementation throws away data that doesn't fit neatly into its source processing requirements ๐Ÿ˜ฑ.


10. IANA Considerations ๐ŸŒท

New media subtypes are subject to IANA registration ๐Ÿ“‹. For the registration of the payload formats and their parameters introduced in this document, check out Section 5.1 ๐ŸŽ€.

11. References ๐Ÿ“š

11.1. Normative References ๐Ÿ’–

11.2. Informative References ๐Ÿฆ‹

Acknowledgments ๐Ÿซถ

Some parts of this document are borrowed from [RFC5109]. So the author wants to thank the editor of [RFC5109] and everyone who contributed to it ๐Ÿ’–.

Thanks to Stephen Botzko, Bernard Aboba, Rasmus Brandt, Brian Baldino, Roni Even, Stefan Holmer, Jonathan Lennox, and Magnus Westerlund for giving valuable feedback on earlier draft versions of this document ๐ŸŒธโœจ.

Authors' Addresses ๐Ÿ’Œ

  • Mo Zanaty Cisco Raleigh, NC United States of America Email: mzanaty@cisco.com
  • Varun Singh CALLSTATS I/O Oy Annankatu 31-33 C 42 Helsinki 00101 Finland Email: varun.singh@iki.fi URI: http://www.callstats.io/
  • Ali Begen Networked Media Konya Turkey Email: ali.begen@networked.media
  • Giridhar Mandyam Qualcomm Inc. 5775 Morehouse Drive San Diego, CA 92121 United States of America Phone: +1 858 651 7200 Email: mandyam@qti.qualcomm.com
๐Ÿ“ฆ where this page comes from