RFC 6262

RTP Payload Format for IP-MR Speech Codec

πŸ“… published August 2011, from ietf

RFC 6262: RTP Payload Format for IP-MR Speech Codec πŸŽ€

Request for Comments: 6262 πŸ’– Written by S. Ikonin from SPIRIT DSP, dated August 2011. Category: Standards Track πŸ¦‹ ISSN: 2070-1721. So this is an official Internet Standards Track doc, not just someone's vibes.

Abstract

okay so this spec explains how to pack SPIRIT IP-MR speech into RTP packets 🎢 It lets one packet hold multiple frames and adds redundancy so calls survive packet loss and bit errors. literally built for robustness πŸ’ͺ✨

Status of This Memo

This is an Internet Standards Track document 🌸

It's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check Section 2 of RFC 5741 🫢

Info about the current status, errata, and how to send feedback lives at http://www.rfc-editor.org/info/rfc6262 πŸ”₯

Copyright (c) 2011 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 (http://trustee.ietf.org/license-info) as in effect on the date of publication. Please actually read those, bestie, because they spell out your rights and restrictions for this doc πŸ“œ Code Components pulled out of this document must include the Simplified BSD License text described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Simplified BSD License πŸ’œ

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The people controlling the copyright in some of that material may not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. So unless you get an adequate license from those copyright holders, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process. The exceptions are formatting it for publication as an RFC or translating it into languages other than English 🌈

Table of Contents

   1. Introduction ....................................................2
   2. IP-MR Codec Description .........................................3
   3. Payload Format ..................................................4
      3.1. RTP Header Usage ...........................................4
      3.2. RTP Payload Structure ......................................4
      3.3. Speech Payload Header ......................................5
      3.4. Speech Payload Table of Contents ...........................6
      3.5. Speech Payload Data ........................................6
      3.6. Redundancy Payload Header ..................................7
      3.7. Redundancy Payload Table of Contents .......................8
      3.8. Redundancy Payload Data ....................................8
   4. Payload Examples ................................................9
      4.1. Payload Carrying a Single Frame ............................9
      4.2. Payload Carrying Multiple Frames with Redundancy ..........10
   5. Congestion Control .............................................11
   6. Security Considerations ........................................12
   7. Payload Format Parameters ......................................13
      7.1. Media Type Registration ...................................13
      7.2. Mapping Media Type Parameters into SDP ....................14
   8. IANA Considerations ............................................14
   9. Normative References ...........................................15
   Appendix A. Retrieving Frame Information ..........................16
      A.1. get_frame_info.c ..........................................16

1. Introduction ✨

So this doc is the recipe for chopping SPIRIT IP-MR encoded speech into the Real-time Transport Protocol (RTP) πŸŽ€ The format lets you stuff multiple frames in one packet and bakes in redundancy so you can handle packet loss and bit errors like a pro πŸ’…

Quick key-word note: the words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be read as described in RFC 2119 [RFC2119]. These are the capital-letter requirement words, and they're doing serious work 🧚

2. IP-MR Codec Description

IP-MR is a wideband speech codec SPIRIT designed for conferencing over packet-switched networks, like the Internet 🌸

It's scalable too, which is so iconic. The source can change its transmission rate on the fly, and the gateway can drop bandwidth at any time without any performance overhead πŸ“‰ There are 6 coding rates available, from 7.7 to 34.2 kbps πŸ’œ

It works frame by frame. Each frame is 20 ms, sampled at 16 kHz, with a total end-to-end delay of 25 ms ⏱️ Each compressed frame is a stack of layers. The first (base) layer is mandatory, but the enhancement layers can be safely discarded. Info about the frame structure lives in the payload header πŸ“¦ If a gateway wants to adjust outgoing bandwidth, it MUST read the frame(s) structure from the payload header, decide which enhancement layers to discard, and build a new RTP packet following this specification πŸ”₯

Here's the tea 🍡 not all bits in a frame are equally tolerant of distortion. IP-MR defines 6 sensitivity classes for bit errors, labelled 'A' through 'F'. Damage to class 'A' bits causes big reconstruction artifacts, while losing class 'F' bits might not even be noticed by the listener πŸ‘‚ Only the base layer gets represented as a set of classes.

IP-MR's payload format lets you duplicate frames across packets to boost packet-loss robustness (see Section 3.6) πŸ¦‹ The base layer can be retransmitted completely or in several sensitive classes. Enhancement layers are not retransmittable πŸ™ˆ

The fine-grained redundancy plus bitrate scalability means apps can tune the trade-off between overhead and packet-loss robustness 🎚️ And it's all supported natively within a packet, so no out-of-band signals or session-initialization procedures needed. Not a single extra handshake, periodt πŸ’…

Main IP-MR features, the highlight reel 🎬

  • High-quality wideband speech codec 🎀
  • Bitrate scalable with 6 average rates from 7.7 to 34.2 kbps πŸ“Š
  • Built-in discontinuous transmission (DTX) and comfort noise generation (CNG) support πŸŒ™
  • Flexible in-band redundancy control scheme for packet-loss protection πŸ›‘οΈ

3. Payload Format

The payload format is the RTP header plus the IP-MR payload πŸŽ€

3.1. RTP Header Usage

The RTP header format is specified in [RFC3550], and this payload format uses the header fields in a way that matches that spec πŸ’–

The RTP timestamp corresponds to the sampling instant of the first sample encoded for the first frame-block in the packet. The timestamp clock frequency SHALL be 16 kHz ⏰ Each frame is 20 ms, which works out to 320 samples per frame, so the timestamp goes up by 320 for each consecutive frame. The timestamp also helps the receiver recover the correct decoding order of the frame-blocks 🧩

The RTP header marker bit (M) SHALL be set to 1 whenever the first frame-block in the packet is the first frame-block in a talkspurt (see the talkspurt definition in Section 4.1 of [RFC3551]) πŸ—£οΈ For all other packets, the marker bit SHALL be set to zero (M=0) ✨

Assigning an RTP payload type for this format is outside this document's scope πŸ™…β€β™€οΈ The RTP profiles in use right now mandate binding the payload type dynamically for this format. That's basically necessary, because the payload type expresses how the payload itself is configured, like basic or interleaved mode, and how many channels it carries πŸŽ›οΈ

The remaining RTP header fields are used as specified in [RFC3550] πŸ’œ

3.2. RTP Payload Structure

The IP-MR payload is made of two payloads: one for current speech and one for redundancy. Both use the same shape: Header, Table of Contents (TOC), and Data. The redundancy payload carries data for the preceding and pre-preceding packets 🌈

  +--------+-----+----------------------+- - - - +- -  +- - - - - +
  | Header | TOC | Data                 | Header | TOC | Data     |
  +--------+-----+----------------------+- - - - +- -  +- - - - - +
  |<- Speech -------------------------->|<- Redundancy (opt) ---->|

3.3. Speech Payload Header

This header carries the parameters that are common to all frames in the packet 🧁

                     0                   1
                     0 1 2 3 4 5 6 7 8 9 0 1
                    +-+-+-+-+-+-+-+-+-+-+-+-+
                    |T| CR  | BR  |D|A|GR |R|
                    +-+-+-+-+-+-+-+-+-+-+-+-+
  • T (1 bit): Reserved. It MUST always be set to 0. A receiver MAY discard the packet if the 'T' bit is not equal to 0 🚫
  • CR (3 bits): Coding rate index, which is the top enhancement layer available. The CR value 7 (NO_DATA) means there's no speech data (and therefore no speech TOC) in the payload. This MAY be used to transmit redundancy data only πŸ“‘
  • BR (3 bits): Base rate index, which is the base layer bitrate. The speech payload can be scaled to any rate index between BR and CR. Packets with BR = 6 or BR > CR MUST be discarded. Redundancy data is also considered to have a base rate of BR πŸ”»
  • D (1 bit): Reserved. It MUST always be set to 1. A receiver MAY discard the packet if the 'D' bit is zero 🫧
  • A (1 bit): Byte alignment. A value of 1 means padding bits were added so each compressed frame (3.5) starts on a byte (8-bit) boundary. A value of 0 means the frames are unaligned. The speech payload is always padded to the byte boundary no matter what the 'A' bit says 🧡
  • GR (2 bits): Number of frames in the packet, aka the grouping size. The actual grouping size is GR + 1, so the max grouping supported is 4 πŸ“¦
  • R (1 bit): Redundancy presence. A value of 1 means a redundancy payload is present πŸ”
Heads up, bestie: the 'T' and 'D' bits are fixed, and any other values aren't allowed by the spec 🚨 Padding bits (the 'P' bits) MUST always be set to zero.

Here's the rate index to rate value mapping πŸ“Š

                  +------------+--------------+
                  | rate index | avg. bitrate |
                  +------------+--------------+
                  |      0     |   7.7 kbps   |
                  |      1     |   9.8 kbps   |
                  |      2     |  14.3 kbps   |
                  |      3     |  20.8 kbps   |
                  |      4     |  27.9 kbps   |
                  |      5     |  34.2 kbps   |
                  |      6     |  (reserved)  |
                  |      7     |   NO_DATA    |
                  +------------+--------------+

The value 6 is reserved. If a receiver gets this value, the packet MUST be discarded πŸ™…β€β™€οΈ

(Part 1 of 4, more coming next! πŸ’–)

3.4. Speech Payload Table of Contents πŸ’…

Okay so the speech TOC is basically a bitmask that tells you which frames are actually in the packet 🧚 It only shows up if the 'CR' value is not equal to 7 (NO_DATA), so no CR, no TOC, no drama.

                              0 1 2 3
                             +-+-+-+-+
                             |E|E|E|E|
                             +-+-+-+-+
                             |<----->| <-- #(GR+1)
  • E (1 bit): Frame existence indicator πŸ‘€ A 0 means there's no speech data for that frame. The IP-MR encoder flips 'E' to 0 during the silent gaps in DTX mode. Applications MUST set this bit to 0 if the frame is known to be damaged, because nobody wants to play back garbage πŸ’€

3.5. Speech Payload Data πŸŽ€

Speech data holds (GR+1) compressed IP-MR frames, which is 20 ms of audio each. If the TOC flag for a frame is zero, that compressed frame has a length of zero. Iconic, zero effort.

Now the alignment part πŸ¦‹ Each compressed frame starts on an aligned boundary if the 'A' bit is nonzero, but the end of the speech payload is ALWAYS lined up to a byte (8-bit) boundary:

+- - -+------------+------------+------------+------------+
| TOC | Frame1     | Frame2     | Frame3     | Frame4     |
+- - -+------------+------------+------------+------------+   ALWAYS
      |<- aligned  |<- aligned  |<- aligned  |<- aligned  |<- ALIGNED

Marked regions MUST be padded only if the 'A' bit is set to '1'. Not vibes-based padding, rule-based padding πŸ™ˆ

The compressed frame structure looks like this:

|<---- sensitive classes ------>|<----- enchantment layers -------->|
+-------------------------------+----+-----+------+- - - - - +------+
| L1 (Base Layer)               | L2 | L3  | L4   |          | LN   |
+-------------------------------+----+-----+------+- - - - - +------+
|<- A --->|<- B ->| ... |<- F ->|                                   |
|<- BR rate ------------------->|                                   |
|<- CR rate ------------------------------------------------------->|

Appendix A of this document has a helper routine written in "C" that MUST be used to pull out the sensitivity classes and the bounds for the enchantment layers from the compressed frame data. Use the helper, bestie 🫢

3.6. Redundancy Payload Header 🌸

The redundancy payload shows up when the 'R' bit of the speech payload header is set. The redundancy header is two fields of 3 bits each, so it's tiny but mighty ✨

                              0 1 2 3 4 5
                             +-+-+-+-+-+-+
                             | CL1 | CL2 |
                             +-+-+-+-+-+-+

'CL1' and 'CL2' tell you which sensitivity classes are available for the preceding and pre-preceding packets respectively. Here's the full lookup table:

                  +-------+--------------------+
                  |  CL   | Redundancy classes |
                  |       |      available     |
                  +-------+--------------------+
                  |   0   |       NONE         |
                  |   1   |        A           |
                  |   2   |        A-B         |
                  |   3   |        A-C         |
                  |   4   |        A-D         |
                  |   5   |        A-E         |
                  |   6   |        A-F         |
                  |   7   |    (reserved)      |
                  +-------+--------------------+

A receiver can rebuild the base layer of preceding packets completely (CL=6) or partially (0<CL< 6), depending on which sensitivity classes made it through πŸ”₯ A decoder MUST discard the redundancy payload if 'CL' is equal to 0 or 7.

Also, the base rate and grouping parameter index isn't sent in the redundancy payload. So applications MUST assume that 'BR' and 'GR' match the current packet. No guessing, just copying the vibes from the current packet πŸ’œ

3.7. Redundancy Payload Table of Contents ✨

The redundancy TOC is another bitmask, this time for which frames are in the redundancy payload. It's only around if 'CL' is not 0 or 7.

              0 1 ...
             +-+-+-+-+-+-+-+-+
             |E|E|E|E|E|E|E|E|
             +-+-+-+-+-+-+-+-+
             |       |<----->| pre-preceding payload #(GR+1)
             |<----->| preceding payload #(GR+1)
  • E (1 bit): Redundancy frame existence indicator πŸ¦‹ A 0 means there's no redundancy data for that frame.

3.8. Redundancy Payload Data 🌈

IP-MR defines 6 classes ('A'-'F') of sensitivity to bit errors. Damage to class 'A' bits causes big reconstruction artifacts, but losing class 'F' might not even be noticeable to the listener πŸ‘‚ Only the base layer of a bitstream gets represented as a set of classes. Put the sensitivity classes together with redundancy and IP-MR can send duplicate frames through the packets, which makes it way more robust against packet loss. Genius, honestly πŸ‘‘

The redundancy data carries some sensitivity classes for the preceding and pre-preceding packets, as indicated by 'CL1' and 'CL2' in the redundancy header. Each frame's sensitivity class data is only there if the matching 'E' bit in the redundancy TOC is nonzero:

+---+---+----+----|-----+-----+-----+-----+-----+-----+-----+
|A-C|A-B|1000|1001|cl_A1|cl_B1|cl_C1|cl_A1|cl_B1|cl_A4|cl_B4|
+---+---+----+----|-----+-----+-----+-----+-----+-----+-----+
|<- CL >|<- TOC ->|<- preceding --->|<- pre-preceding ----->|

Redundancy data is ONLY available if the base rates (BRs) and coding rates (CRs) of the preceding and pre-preceding packets match the current packet's. So keep those rates consistent, bestie πŸ’–

A receiver MAY use redundancy data to make up for packet loss. If it does, the 'CL' field MUST also be passed to the decoder. And the helper routine in Appendix A MUST be used to work out the sensitivity classes' length for each frame. Here's the pseudocode for the sequence of operations:

   int sensitivityBits[numOfRedundancyFrames][6];
   int redundancyBits [numOfRedundancyFrames];
   for(i = 0 ; i < numOfRedundancyFrames; i++) {
       GetFrameInfo(CR, BR, pRedundancyPayloadData, dummy,
                    sensitivityBits[i], dummy);
       redundancyBits[i] = 0;
       for(j = 0; j < CL[i]; j++ ) {
            redundancyBits[i] += sensitivityBits[i][j];
       }
       flushBits(pRedundancyPayloadData, redundancyBits[i]);
   }

4. Payload Examples ✨

Time for the fun part πŸ“ This section gives you detailed examples of the IP-MR payload format, so you can actually see the bits lining up.

4.1. Payload Carrying a Single Frame 🧚

This diagram shows a typical IP-MR payload carrying one (GR=0) non-aligned (A=0) speech frame with no redundancy (R=0). The base layer is coded at 7.8 kbps (BR=0), while the coding rate is 9.7 kbps (CR=1). The 'E' bit value of 1 signals that compressed frame bits s(0) - s(193) are present. There's a padding bit 'P' to keep the speech payload size aligned, because yes, it matters πŸ’…

    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|CR=1 |BR=0 |1|0|0 0|0|1|s(0)                                 |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       s(193)|P|
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

4.2. Payload Carrying Multiple Frames with Redundancy πŸ‘‘

Okay this one's giving main character energy πŸ¦‹ The diagram shows a payload with 3 (GR=2) aligned (A=1) speech frames and redundancy (R=1). The TOC value of '101' says there's speech for the first frame (bits sp1(0)-sp1(92)) and the third frame (bits sp3(0)-sp3(171)). There are no enchantment layers, because the base and coding rates are equal (BR=CR=0). The padding bit 'P' is inserted to keep everything aligned 🫢

The redundancy payload is present for both the preceding and pre-preceding payloads (CL1 = A-B, CL2=A). But redundancy data is only available for 5 (TOC='111011') of the 6 (2*(GR+1)) frames 😭 You get 20, 39, and 35 bits of redundancy data for each of the three frames in the preceding packet, and 15 and 19 bits for the two frames in the pre-preceding packet. Bit counting is a whole sport, ngl πŸ†

    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|CR=0 |BR=0 |1|1|1 0|1|1 0 1|P|sp1(0)                         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                  sp1(92)|P|P|P|sp3(0)                         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                               sp3(171)|P|P|P|P|
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |CL1=2|CL2=1|1 1 1|0 1 1|red1_1_AB(0)              red1_1_AB(19)|
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |red1_2_AB(0)                                                   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |red1_2_AB(38)|red1_3_AB(0)                                     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      red1_3_AB(34)|red2_2_A(0)      red2_2_A(14)|red2_3_A(0)  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           red2_3_A(18)|P|P|P|P|
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

5. Congestion Control πŸ¦‹

okay so bestie, congestion control is a whole vibe 🌊 The general congestion control stuff for RTP data totally applies to IP-MR speech over RTP (go check RTP [RFC3550] and any RTP profile that applies, like the Audio-Visual Profile (AVP) [RFC3551]) πŸ“š But here's the lowkey iconic part: IP-MR's multi-rate capability can help keep congestion in check, because you can change the bandwidth demand just by picking a different encoding mode πŸ’…

The number of frames packed into each RTP payload has a HUGE effect on the total bandwidth of the RTP stream, because of header overhead 😭 Stuffing more frames into each payload means fewer packets get sent, so you save on the IP/UDP/RTP header overhead. The tradeoff? More delay πŸ•°οΈ it's always a trade, bestie.

Because IP_MR is scalable, the transmission rate can be dropped at any transport stage to fit the channel bandwidth 🌈 The minimal rate is set by the BR field of the payload header and can go as low as 7.7 kbps. It's up to the application to balance coding quality (high BR) against bitstream scalability (low BR) βš–οΈ Now, coding quality depends on the coding rate (CR) and NOT the base rate (BR), so it is NOT RECOMMENDED to use high BR values for real-time communications. Not me saying "no" to high BR for real-time calls πŸ™ˆ

Applications MAY use bitstream redundancy to fight packet loss πŸ›‘οΈ However, the gateway is free to choose any option for lowering the transmission rate, and the coding layer or the redundancy bits can get dropped πŸ’€ Because of this, it is NOT RECOMMENDED for applications to increase the total bitrate when they add redundancy in response to packet loss. Don't panic-boost your bitrate, babe 🫢


6. Security Considerations πŸ”

Okay, security time, and it's giving serious 😀 RTP packets that use the payload format in this spec are subject to the security considerations in the RTP spec [RFC3550] and in any RTP profile that applies. The main security concerns for the RTP packets carrying this payload format are confidentiality, integrity, and source authenticity πŸ”’ Confidentiality comes from encrypting the RTP payload. Integrity of the RTP packets comes from a suitable cryptographic integrity-protection mechanism, and that same cryptographic system may also let you authenticate where the payload came from πŸ•΅οΈβ€β™€οΈ A good security mechanism for this payload format should give you confidentiality, integrity protection, and source authentication, at least enough to tell whether an RTP packet is from a member of the RTP session.

Note that the right mechanisms for securing RTP and payloads that follow this memo can vary πŸ¦‹ They depend on the application, the transport, and the signaling protocol being used. So a single mechanism is not sufficient πŸ™…β€β™€οΈ Still, if it's suitable, using the Secure Real-time Transport Protocol (SRTP) [RFC3711] is recommended. Other mechanisms that may be used are IPsec [RFC4301] and Transport Layer Security (TLS) [RFC5246] (RTP over TCP), and other alternatives may exist ✨

This payload format doesn't show any significant non-uniformity in receiver-side computational complexity for packet processing. That means it's unlikely to be a denial-of-service threat from pathological data received πŸ›‘ Phew, safe bestie πŸ’œ


7. Payload Format Parameters πŸŽ€

This section covers the media types and names tied to this payload format πŸ“

The IP-MR media subtype is defined as ip-mr_v2.5. This subtype was registered to specify an internal codec version πŸ§ͺ Later on, that version was accepted as final, the bitstream was frozen, and IP-MR v2.5 got published under the name IP-MR πŸŽ‰ Right now, 'IP-MR' and 'IP-MR v2.5' are synonyms, and the subtype name ip-mr_v2.5 is what implementations are actually using πŸ’…

7.1. Media Type Registration πŸ“

Here's the registration, all laid out:

   Media Type name:     audio

   Media Subtype name:  ip-mr_v2.5

   Required parameters: none

   Optional parameters:
      These parameters apply to RTP transfer only.

      ptime: The media packet length in milliseconds.  Allowed values
      are: 20, 40, 60, and 80.

   Encoding considerations:
      This media type is framed and binary (see RFC 4288, Section 4.8).

   Security considerations:
      See Section 6 of RFC 6262.

   Interoperability considerations:
      none

   Published specification:
      RFC 6262

   Applications that use this media type:
      Real-time audio applications like voice over IP,
      teleconference, and multimedia streaming.

   Additional information:
      none

   Person & email address to contact for further information:
      V. Sviridenko <vladimirs@spiritdsp.com>

   Intended usage:
      COMMON

   Restrictions on usage:
      This media type depends on RTP framing and thus is only defined
      for transfer via RTP [RFC3550].

   Authors:
      Sergey Ikonin <info@spiritdsp.com>
      Dmitry Yudin <info@spiritdsp.com>

   Change controller:
      IETF Audio/Video Transport working group delegated from the IESG.

7.2. Mapping Media Type Parameters into SDP πŸ—ΊοΈ

The info in the media type spec has a specific mapping to fields in the Session Description Protocol (SDP) [RFC4566], which is what people commonly use to describe RTP sessions πŸ“‘ When you use SDP to describe sessions that use the IP-MR codec, the mapping goes like this:

  • The media type (audio) goes in SDP m= as the media name.
  • The media subtype (payload format name) goes in SDP a=rtpmap as the encoding name. The RTP clock rate in a=rtpmap MUST be 16000. 🎡
  • The parameter ptime goes in the SDP a=ptime attribute.

Any leftover parameters go in the SDP a=fmtp attribute. You copy them straight from the media type parameter string as a semicolon-separated list of parameter=value pairs πŸ§ƒ

Quick note: payload format (encoding) names are usually written in uppercase, and media subtypes are usually written in lowercase πŸ”€ Both are case-insensitive in both places, so no drama either way πŸ’–


8. IANA Considerations πŸ“š

One media type, ip-mr_v2.5, has been defined and registered in the media types registry. Officially on the books now 🌸


9. Normative References πŸ“–

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119, March 1997.

   [RFC3550]  Schulzrinne, H., Casner, S., Frederick, R., and V.
              Jacobson, "RTP: A Transport Protocol for Real-Time
              Applications", STD 64, RFC 3550, July 2003.

   [RFC3551]  Schulzrinne, H. and S. Casner, "RTP Profile for Audio and
              Video Conferences with Minimal Control", STD 65, RFC 3551,
              July 2003.

   [RFC3711]  Baugher, M., McGrew, D., Naslund, M., Carrara, E., and K.
              Norrman, "The Secure Real-time Transport Protocol (SRTP)",
              RFC 3711, March 2004.

   [RFC4301]  Kent, S. and K. Seo, "Security Architecture for the
              Internet Protocol", RFC 4301, December 2005.

   [RFC4566]  Handley, M., Jacobson, V., and C. Perkins, "SDP: Session
              Description Protocol", RFC 4566, July 2006.

   [RFC5246]  Dierks, T. and E. Rescorla, "The Transport Layer Security
              (TLS) Protocol Version 1.2", RFC 5246, August 2008.

Appendix A. Retrieving Frame Information 🧚

This appendix is where the C code for the frame-parsing function lives πŸ’» That function pulls out info about a coded frame, including the frame size, the number of layers, the size of each layer, and the size of the perceptual sensitive classes. Main character function energy πŸ‘‘

A.1. get_frame_info.c ✨

okay bestie, this is the appendix where the spec gets a real C file, and it's giving very "here's the actual code, no vibes-only hand-waving" πŸ’»πŸŽ€ Below is the full file exactly as it appears in the RFC, license and all, so nothing gets lost 🫢

/*

Copyright (c) 2011 IETF Trust and the persons identified as
authors of the code.  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

- Redistributions of source code must retain the above copyright
  notice, this list of conditions and
  the following disclaimer.

- Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the
  distribution.

- Neither the name of Internet Society, IETF or IETF Trust, nor the
  names of specific contributors, may be used to endorse or promote
  products derived from this software without specific prior written
  permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/******************************************************************

  get_frame_info.c

  Retrieving frame information for IP-MR Speech Codec

******************************************************************/

#define RATES_NUM       6   // number of codec rates
#define SENSE_CLASSES   6   // number of sensitivity classes (A..F)

// frame types
#define FT_SPEECH       0   // active speech
#define FT_DTX_SID      1   // silence insertion descriptor

// get specified bit from coded data
int GetBit(const unsigned char *buf, int curBit)
{
    return (buf[curBit>>3]>>(curBit%8))&1;
}

// retrieve frame information
int GetFrameInfo(               // o: frame size in bits
    short rate,                 // i: encoding rate (0..5)
    short base_rate,            // i: base (core) layer rate,
    const unsigned char buf[2], // i: coded bit frame
    int size,                   // i: coded bit frame size in bytes
    short pLayerBits[RATES_NUM],     // o: number of bits in layers
    short pSenseBits[SENSE_CLASSES], // o: number of bits in
                                     //    sensitivity classes
    short *nLayers                   // o: number of layers
)
{
    static const short Bits_1[4]    = {  0, 9, 9,15};
    static const short Bits_2[16]   = { 43,50,36,31,46,48,40,44,
                                        47,43,44,45,43,44,47,36};
    static const short Bits_3[2][6] = {{13,11,23,33,36,31},
                                       {25, 0,23,32,36,31},};
    int FrType;
    int i, nBits = 0;

    if (rate < 0 || rate > 5) {
        return 0; // incorrect stream
    }

    // extract frame type bit if required
    FrType = GetBit(buf, nBits++) ? FT_SPEECH : FT_DTX_SID;

    if((FrType != FT_DTX_SID && size < 2) || size < 1) {
        return 0; // not enough input data

    }

    for(i = 0; i < SENSE_CLASSES; i++) {
        pSenseBits[i] = 0;

    }

    {
        int cw_0;
        int b[14];

        // extract meaning bits
        for(i = 0 ; i < 14; i++) {
            b[i] = GetBit(buf, nBits++);
        }

        // parse
        if(FrType == FT_DTX_SID) {
            cw_0 = (b[0]<<0)|(b[1]<<1)|(b[2]<<2)|(b[3]<<3);
            rate = 0;
            pSenseBits[0] = 10 + Bits_2[cw_0];
        } else {

            int i, idx;
            int nFlag_1, nFlag_2, cw_1, cw_2;

            nFlag_1 = b[0] + b[2] + b[4] + b[6];
            cw_1 = (cw_1 << 1) | b[0];
            cw_1 = (cw_1 << 1) | b[2];
            cw_1 = (cw_1 << 1) | b[4];
            cw_1 = (cw_1 << 1) | b[6];

            nFlag_2 = b[1] + b[3] + b[5] + b[7];
            cw_2 = (cw_2 << 1) | b[1];
            cw_2 = (cw_2 << 1) | b[3];
            cw_2 = (cw_2 << 1) | b[5];
            cw_2 = (cw_2 << 1) | b[7];

            cw_0 = (b[10]<<0)|(b[11]<<1)|(b[12]<<2)|(b[13]<<3);
            if (base_rate < 0)    base_rate = 0;
            if (base_rate > rate) base_rate = rate;
            idx = base_rate == 0 ? 0 : 1;

            pSenseBits[0] = 15+Bits_2[cw_0];
            pSenseBits[1] = Bits_1[(cw_1>>0)&0x3] +
                            Bits_1[(cw_1>>2)&0x3];
            pSenseBits[2] = nFlag_1*5;
            pSenseBits[3] = nFlag_2*30;
            pSenseBits[5] = (4 - nFlag_2)*(Bits_3[idx][0]);

            for (i = 1; i < rate+1; i++) {
                pLayerBits[i] = 4*Bits_3[idx][i];
            }

        }

        pLayerBits[0] = 0;
        for (i = 0; i < SENSE_CLASSES; i++) {
            pLayerBits[0] += pSenseBits[i];
        }

        *nLayers = rate+1;
    }

    {
        // count total frame size
        int payloadBitCount = 0;
        for (i = 0; i < *nLayers; i++) {
            payloadBitCount += pLayerBits[i];
        }
        return payloadBitCount;
    }
}

That's the whole helper, the bit-twiddling and all πŸ’œ The function takes a coded frame and works out how many bits it holds, per layer and per sensitivity class, so you can tell exactly how big each slice of the payload is 🌸


Author's Address

Sergey Ikonin, the author of this code, is based at SPIRIT DSP 🧚 Here are the contact details exactly as the RFC lists them:

Sergey Ikonin
SPIRIT DSP
Building 27, A. Solzhenitsyna Street
109004, Moscow
Russia

Tel: +7 495 661-2178
Fax: +7 495 912-6786
EMail: s.ikonin@gmail.com
πŸ“¦ where this page comes from