summaryrefslogtreecommitdiff
path: root/doc/rfc/rfc3119.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/rfc/rfc3119.txt')
-rw-r--r--doc/rfc/rfc3119.txt1067
1 files changed, 1067 insertions, 0 deletions
diff --git a/doc/rfc/rfc3119.txt b/doc/rfc/rfc3119.txt
new file mode 100644
index 0000000..8eb695c
--- /dev/null
+++ b/doc/rfc/rfc3119.txt
@@ -0,0 +1,1067 @@
+
+
+
+
+
+
+Network Working Group R. Finlayson
+Request for Comments: 3119 LIVE.COM
+Category: Standards Track June 2001
+
+
+ A More Loss-Tolerant RTP Payload Format for MP3 Audio
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Abstract
+
+ This document describes a RTP (Real-Time Protocol) payload format for
+ transporting MPEG (Moving Picture Experts Group) 1 or 2, layer III
+ audio (commonly known as "MP3"). This format is an alternative to
+ that described in RFC 2250, and performs better if there is packet
+ loss.
+
+1. Introduction
+
+ While the RTP payload format defined in RFC 2250 [2] is generally
+ applicable to all forms of MPEG audio or video, it is sub-optimal for
+ MPEG 1 or 2, layer III audio (commonly known as "MP3"). The reason
+ for this is that an MP3 frame is not a true "Application Data Unit" -
+ it contains a back-pointer to data in earlier frames, and so cannot
+ be decoded independently of these earlier frames. Because RFC 2250
+ defines that packet boundaries coincide with frame boundaries, it
+ handles packet loss inefficiently when carrying MP3 data. The loss
+ of an MP3 frame will render some data in previous (or future) frames
+ useless, even if they are received without loss.
+
+ In this document we define an alternative RTP payload format for MP3
+ audio. This format uses a data-preserving rearrangement of the
+ original MPEG frames, so that packet boundaries now coincide with
+ true MP3 "Application Data Units", which can also (optionally) be
+ rearranged in an interleaving pattern. This new format is therefore
+ more data-efficient than RFC 2250 in the face of packet loss.
+
+
+
+
+
+Finlayson Standards Track [Page 1]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+2. The Structure of MP3 Frames
+
+ In this section we give a brief overview of the structure of a MP3
+ frame. (For more detailed description, see the MPEG 1 audio [3] and
+ MPEG 2 audio [4] specifications.)
+
+ Each MPEG audio frame begins with a 4-byte header. Information
+ defined by this header includes:
+
+ - Whether the audio is MPEG 1 or MPEG 2.
+ - Whether the audio is layer I, II, or III.
+ (The remainder of this document assumes layer III, i.e., "MP3"
+ frames)
+ - Whether the audio is mono or stereo.
+ - Whether or not there is a 2-byte CRC field following the header.
+ - (indirectly) The size of the frame.
+
+ The following structures appear after the header:
+
+ - (optionally) A 2-byte CRC field
+ - A "side info" structure. This has the following length:
+ - 32 bytes for MPEG 1 stereo
+ - 17 bytes for MPEG 1 mono, or for MPEG 2 stereo
+ - 9 bytes for MPEG 2 mono
+ - Encoded audio data, plus optional ancillary data (filling out the
+ rest of the frame)
+
+ For the purpose of this document, the "side info" structure is the
+ most important, because it defines the location and size of the
+ "Application Data Unit" (ADU) that an MP3 decoder will process. In
+ particular, the "side info" structure defines:
+
+ - "main_data_begin": This is a back-pointer (in bytes) to the start
+ of the ADU. The back-pointer is counted from the beginning of the
+ frame, and counts only encoded audio data and any ancillary data
+ (i.e., ignoring any header, CRC, or "side info" fields).
+
+ An MP3 decoder processes each ADU independently. The ADUs will
+ generally vary in length, but their average length will, of course,
+ be that of the of the MP3 frames (minus the length of the header,
+ CRC, and "side info" fields). (In MPEG literature, this ADU is
+ sometimes referred to as a "bit reservoir".)
+
+
+
+
+
+
+
+
+
+Finlayson Standards Track [Page 2]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+3. A New Payload Format
+
+ As noted in [5], a payload format should be designed so that packet
+ boundaries coincide with "codec frame boundaries" - i.e., with ADUs.
+ In the RFC 2250 payload format for MPEG audio [2], each RTP packet
+ payload contains MP3 frames. In this new payload format for MP3
+ audio, however, each RTP packet payload contains "ADU frames", each
+ preceded by an "ADU descriptor".
+
+3.1 ADU frames
+
+ An "ADU frame" is defined as:
+
+ - The 4-byte MPEG header
+ (the same as the original MP3 frame, except that the first 11
+ bits are (optionally) replaced by an "Interleaving Sequence
+ Number", as described in section 6 below)
+ - The optional 2-byte CRC field
+ (the same as the original MP3 frame)
+ - The "side info" structure
+ (the same as the original MP3 frame)
+ - The complete sequence of encoded audio data (and any ancillary
+ data) for the ADU (i.e., running from the start of this MP3
+ frame's "main_data_begin" back-pointer, up to the start of the
+ next MP3 frame's back-pointer)
+
+3.2 ADU descriptors
+
+ Within each RTP packet payload, each "ADU frame" is preceded by a 1
+ or 2-byte "ADU descriptor", which gives the size of the ADU, and
+ indicates whether or not this packet's data is a continuation of the
+ previous packet's data. (This occurs only when a single "ADU
+ descriptor"+"ADU frame" is too large to fit within a RTP packet.)
+
+ An ADU descriptor consists of the following fields
+
+ - "C": Continuation flag (1 bit): 1 if the data following the ADU
+ descriptor is a continuation of an ADU frame that was too
+ large to fit within a single RTP packet; 0 otherwise.
+ - "T": Descriptor Type flag (1 bit):
+ 0 if this is a 1-byte ADU descriptor;
+ 1 if this is a 2-byte ADU descriptor.
+ - "ADU size" (6 or 14 bits):
+ The size (in bytes) of the ADU frame that will follow this
+ ADU descriptor (i.e., NOT including the size of the
+ descriptor itself). A 2-byte ADU descriptor (with a 14-bit
+ "ADU size" field) is used for ADU frames sizes of 64 bytes or
+ more. For smaller ADU frame sizes, senders MAY alternatively
+
+
+
+Finlayson Standards Track [Page 3]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ use a 1-byte ADU descriptor (with a 6-bit "ADU size" field).
+ Receivers MUST be able to accept an ADU descriptor of either
+ size.
+
+ Thus, a 1-byte ADU descriptor is formatted as follows:
+
+ 0 1 2 3 4 5 6 7
+ +-+-+-+-+-+-+-+-+
+ |C|0| ADU size |
+ +-+-+-+-+-+-+-+-+
+
+ and a 2-byte ADU descriptor is formatted as follows:
+
+ 0 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |C|1| ADU size (14 bits) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+3.3 Packing rules
+
+ Each RTP packet payload begins with a "ADU descriptor", followed by
+ "ADU frame" data. Normally, this "ADU descriptor"+"ADU frame" will
+ fit completely within the RTP packet. In this case, more than one
+ successive "ADU descriptor"+"ADU frame" MAY be packed into a single
+ RTP packet, provided that they all fit completely.
+
+ If, however, a single "ADU descriptor"+"ADU frame" is too large to
+ fit within an RTP packet, then the "ADU frame" is split across two or
+ more successive RTP packets. Each such packet begins with an ADU
+ descriptor. The first packet's descriptor has a "C" (continuation)
+ flag of 0; the following packets' descriptors each have a "C" flag of
+ 1. Each descriptor, in this case, has the same "ADU size" value: the
+ size of the entire "ADU frame" (not just the portion that will fit
+ within a single RTP packet). Each such packet (even the last one)
+ contains only one "ADU descriptor".
+
+3.4 RTP header fields
+
+ Payload Type: The (static) payload type 14 that was defined for
+ MPEG audio [6] MUST NOT be used. Instead, a different, dynamic
+ payload type MUST be used - i.e., one in the range [96,127].
+
+ M bit: This payload format defines no use for this bit. Senders
+ SHOULD set this bit to zero in each outgoing packet.
+
+ Timestamp: This is a 32-bit 90 kHz timestamp, representing the
+ presentation time of the first ADU packed within the packet.
+
+
+
+Finlayson Standards Track [Page 4]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+3.5 Handling received data
+
+ Note that no information is lost by converting a sequence of MP3
+ frames to a corresponding sequence of "ADU frames", so a receiving
+ RTP implementation can either feed the ADU frames directly to an
+ appropriately modified MP3 decoder, or convert them back into a
+ sequence of MP3 frames, as described in appendix A.2 below.
+
+4. Handling Multiple MPEG Audio Layers
+
+ The RTP payload format described here is intended only for MPEG 1 or
+ 2, layer III audio ("MP3"). In contrast, layer I and layer II frames
+ are self-contained, without a back-pointer to earlier frames.
+ However, it is possible (although unusual) for a sequence of audio
+ frames to consist of a mixture of layer III frames and layer I or II
+ frames. When such a sequence is transmitted, only layer III frames
+ are converted to ADUs; layer I or II frames are sent 'as is' (except
+ for the prepending of an "ADU descriptor"). Similarly, the receiver
+ of a sequence of frames - using this payload format - leaves layer I
+ and II frames untouched (after removing the prepended "ADU
+ descriptor), but converts layer III frames from "ADU frames" to
+ regular MP3 frames. (Recall that each frame's layer is identified
+ from its 4-byte MPEG header.)
+
+ If you are transmitting a stream consists *only* of layer I or layer
+ II frames (i.e., without any MP3 data), then there is no benefit to
+ using this payload format, *unless* you are using the interleaving
+ mechanism.
+
+5. Frame Packetizing and Depacketizing
+
+ The transmission of a sequence of MP3 frames takes the following
+ steps:
+
+ MP3 frames
+ -1-> ADU frames
+ -2-> interleaved ADU frames
+ -3-> RTP packets
+
+ Step 1, the conversion of a sequence of MP3 frames to a corresponding
+ sequence of ADU frames, takes place as described in sections 2 and
+ 3.1 above. (Note also the pseudo-code in appendix A.1.)
+
+ Step 2 is the reordering of the sequence of ADU frames in an
+ (optional) interleaving pattern, prior to packetization, as described
+ in section 6 below. (Note also the pseudo-code in appendix B.1.)
+ Interleaving helps reduce the effect of packet loss, by distributing
+ consecutive ADU frames over non-consecutive packets. (Note that
+
+
+
+Finlayson Standards Track [Page 5]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ because of the back-pointer in MP3 frames, interleaving can be
+ applied - in general - only to ADU frames. Thus, interleaving was
+ not possible for RFC 2250.)
+
+ Step 3 is the packetizing of a sequence of (interleaved) ADU frames
+ into RTP packets - as described in section 3.3 above. Each packet's
+ RTP timestamp is the presentation time of the first ADU that is
+ packed within it. Note that, if interleaving was done in step 2, the
+ RTP timestamps on outgoing packets will not necessarily be
+ monotonically nondecreasing.
+
+ Similarly, a sequence of received RTP packets is handled as follows:
+
+ RTP packets
+ -4-> RTP packets ordered by RTP sequence number
+ -5-> interleaved ADU frames
+ -6-> ADU frames
+ -7-> MP3 frames
+
+ Step 4 is the usual sorting of incoming RTP packets using the RTP
+ sequence number.
+
+ Step 5 is the depacketizing of ADU frames from RTP packets - i.e.,
+ the reverse of step 3. As part of this process, a receiver uses the
+ "C" (continuation) flag in the ADU descriptor to notice when an ADU
+ frame is split over more than one packet (and to discard the ADU
+ frame entirely if one of these packets is lost).
+
+ Step 6 is the rearranging of the sequence of ADU frames back to its
+ original order (except for ADU frames missing due to packet loss), as
+ described in section 6 below. (Note also the pseudo-code in appendix
+ B.2.)
+
+ Step 7 is the conversion of the sequence of ADU frames into a
+ corresponding sequence of MP3 frames - i.e., the reverse of step 1.
+ (Note also the pseudo-code in appendix A.2.) With an appropriately
+ modified MP3 decoder, an implementation may omit this step; instead,
+ it could feed ADU frames directly to the (modified) MP3 decoder.
+
+6. ADU Frame Interleaving
+
+ In MPEG audio frames (MPEG 1 or 2; all layers) the high-order 11 bits
+ of the 4-byte MPEG header ('syncword') are always all-one (i.e.,
+ 0xFFE). When reordering a sequence of ADU frames for transmission,
+ we reuse these 11 bits as an "Interleaving Sequence Number" (ISN).
+ (Upon reception, they are replaced with 0xFFE once again.)
+
+
+
+
+
+Finlayson Standards Track [Page 6]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ The structure of the ISN is (a,b), where:
+
+ - a == bits 0-7: 8-bit Interleave Index (within Cycle)
+ - b == bits 8-10: 3-bit Interleave Cycle Count
+
+ I.e., the 4-byte MPEG header is reused as follows:
+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |Interleave Idx |CycCt| The rest of the original MPEG header |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Example: Consider the following interleave cycle (of size 8):
+ 1,3,5,7,0,2,4,6
+ (This particular pattern has the property that any loss of up to four
+ consecutive ADUs in the interleaved stream will lead to a
+ deinterleaved stream with no gaps greater than one [7].) This
+ produces the following sequence of ISNs:
+
+ (1,0) (3,0) (5,0) (7,0) (0,0) (2,0) (4,0) (6,0) (1,1) (3,1)
+ (5,1) etc.
+
+ So, in this example, a sequence of ADU frames
+
+ f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 (etc.)
+
+ would get reordered, in step 2, into:
+
+ (1,0)f1 (3,0)f3 (5,0)f5 (7,0)f7 (0,0)f0 (2,0)f2 (4,0)f4 (6,0)f6
+ (1,1)f9 (3,1)f11 (5,1)f13 (etc.)
+
+ and the reverse reordering (along with replacement of the 0xFFE)
+ would occur upon reception.
+
+ The reason for breaking the ISN into "Interleave Cycle Count" and
+ "Interleave Index" (rather than just treating it as a single 11-bit
+ counter) is to give receivers a way of knowing when an ADU frame
+ should be 'released' to the ADU->MP3 conversion process (step 7
+ above), rather than waiting for more interleaved ADU frames to
+ arrive. E.g., in the example above, when the receiver sees a frame
+ with ISN (<something>,1), it knows that it can release all
+ previously-seen frames with ISN (<something>,0), even if some other
+ (<something>,0) frames remain missing due to packet loss. A 8-bit
+ Interleave Index allows interleave cycles of size up to 256.
+
+
+
+
+
+
+Finlayson Standards Track [Page 7]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ The choice of an interleaving order can be made independently of RTP
+ packetization. Thus, a simple implementation could choose an
+ interleaving order first, reorder the ADU frames accordingly (step
+ 2), then simply pack them sequentially into RTP packets (step 3).
+ However, the size of ADU frames - and thus the number of ADU frames
+ that will fit in each RTP packet - will typically vary in size, so a
+ more optimal implementation would combine steps 2 and 3, by choosing
+ an interleaving order that better reflected the number of ADU frames
+ packed within each RTP packet.
+
+ Each receiving implementation of this payload format MUST recognize
+ the ISN and be able to perform deinterleaving of incoming ADU frames
+ (step 6). However, a sending implementation of this payload format
+ MAY choose not to perform interleaving - i.e., by omitting step 2.
+ In this case, the high-order 11 bits in each 4-byte MPEG header would
+ remain at 0xFFE. Receiving implementations would thus see a sequence
+ of identical ISNs (all 0xFFE). They would handle this in the same
+ way as if the Interleave Cycle Count changed with each ADU frame, by
+ simply releasing the sequence of incoming ADU frames sequentially to
+ the ADU->MP3 conversion process (step 7), without reordering. (Note
+ also the pseudo-code in appendix B.2.)
+
+7. MIME registration
+
+ MIME media type name: audio
+
+ MIME subtype: mpa-robust
+
+ Required parameters: none
+
+ Optional parameters: none
+
+ Encoding considerations:
+ This type is defined only for transfer via RTP as specified in
+ "RFC 3119".
+
+ Security considerations:
+ See the "Security Considerations" section of
+ "RFC 3119".
+
+ Interoperability considerations:
+ This encoding is incompatible with both the "audio/mpa"
+ and "audio/mpeg" mime types.
+
+ Published specification:
+ The ISO/IEC MPEG-1 [3] and MPEG-2 [4] audio specifications,
+ and "RFC 3119".
+
+
+
+
+Finlayson Standards Track [Page 8]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ Applications which use this media type:
+ Audio streaming tools (transmitting and receiving)
+
+ Additional information: none
+
+ Person & email address to contact for further information:
+ Ross Finlayson
+ finlayson@live.com
+
+ Intended usage: COMMON
+
+ Author/Change controller:
+ Author: Ross Finlayson
+ Change controller: IETF AVT Working Group
+
+8. SDP usage
+
+ When conveying information by SDP [8], the encoding name SHALL be
+ "mp3" (the same as the MIME subtype). An example of the media
+ representation in SDP is:
+
+ m=audio 49000 RTP/AVP 121
+ a=rtpmap:121 mpa-robust/90000
+
+9. Security Considerations
+
+ If a session using this payload format is being encrypted, and
+ interleaving is being used, then the sender SHOULD ensure that any
+ change of encryption key coincides with a start of a new interleave
+ cycle. Apart from this, the security considerations for this payload
+ format are identical to those noted for RFC 2250 [2].
+
+10. Acknowledgements
+
+ The suggestion of adding an interleaving option (using the first bits
+ of the MPEG 'syncword' - which would otherwise be all-ones - as an
+ interleaving index) is due to Dave Singer and Stefan Gewinner. In
+ addition, Dave Singer provided valuable feedback that helped clarify
+ and improve the description of this payload format. Feedback from
+ Chris Sloan led to the addition of an "ADU descriptor" preceding each
+ ADU frame in the RTP packet.
+
+
+
+
+
+
+
+
+
+
+Finlayson Standards Track [Page 9]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+11. References
+
+ [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [2] Hoffman, D., Fernando, G., Goyal, V. and M. Civanlar, "RTP
+ Payload Format for MPEG1/MPEG2 Video", RFC 2250, January 1998.
+
+ [3] ISO/IEC International Standard 11172-3; "Coding of moving
+ pictures and associated audio for digital storage media up to
+ about 1,5 Mbits/s - Part 3: Audio", 1993.
+
+ [4] ISO/IEC International Standard 13818-3; "Generic coding of moving
+ pictures and associated audio information - Part 3: Audio", 1998.
+
+ [5] Handley, M., "Guidelines for Writers of RTP Payload Format
+ Specifications", BCP 36, RFC 2736, December 1999.
+
+ [6] Schulzrinne, H., "RTP Profile for Audio and Video Conferences
+ with Minimal Control", RFC 1890, January 1996.
+
+ [7] Marshall Eubanks, personal communication, December 2000.
+
+ [8] Handley, M. and V. Jacobson, "SDP: Session Description Protocol",
+ RFC 2327, April 1998.
+
+11. Author's Address
+
+ Ross Finlayson,
+ Live Networks, Inc. (LIVE.COM)
+
+ EMail: finlayson@live.com
+ WWW: http://www.live.com/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Finlayson Standards Track [Page 10]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+Appendix A. Translating Between "MP3 Frames" and "ADU Frames"
+
+ The following 'pseudo code' describes how a sender using this payload
+ format can translate a sequence of regular "MP3 Frames" to "ADU
+ Frames", and how a receiver can perform the reverse translation: from
+ "ADU Frames" to "MP3 Frames".
+
+ We first define the following abstract data structures:
+
+ - "Segment": A record that represents either a "MP3 Frame" or an
+ "ADU Frame". It consists of the following fields:
+ - "header": the 4-byte MPEG header
+ - "headerSize": a constant (== 4)
+ - "sideInfo": the 'side info' structure, *including* the optional
+ 2-byte CRC field, if present
+ - "sideInfoSize": the size (in bytes) of the above structure
+ - "frameData": the remaining data in this frame
+ - "frameDataSize": the size (in bytes) of the above data
+ - "backpointer": the size (in bytes) of the backpointer for this
+ frame
+ - "aduDataSize": the size (in bytes) of the ADU associated with
+ this frame. (If the frame is already an "ADU Frame", then
+ aduDataSize == frameDataSize)
+ - "mp3FrameSize": the total size (in bytes) that this frame would
+ have if it were a regular "MP3 Frame". (If it is already a
+ "MP3 Frame", then mp3FrameSize == headerSize + sideInfoSize +
+ frameDataSize) Note that this size can be derived completely
+ from "header".
+
+ - "SegmentQueue": A FIFO queue of "Segment"s, with operations
+ - void enqueue(Segment)
+ - Segment dequeue()
+ - Boolean isEmpty()
+ - Segment head()
+ - Segment tail()
+ - Segment previous(Segment): returns the segment prior to a
+ given one
+ - Segment next(Segment): returns the segment after a given one
+ - unsigned totalDataSize(): returns the sum of the
+ "frameDataSize" fields of each entry in the queue
+
+
+
+
+
+
+
+
+
+
+
+Finlayson Standards Track [Page 11]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+A.1 Converting a sequence of "MP3 Frames" to a sequence of "ADU Frames":
+
+SegmentQueue pendingMP3Frames; // initially empty
+while (1) {
+ // Enqueue new MP3 Frames, until we have enough data to generate
+ // the ADU for a frame:
+ do {
+ int totalDataSizeBefore
+ = pendingMP3Frames.totalDataSize();
+
+ Segment newFrame = 'the next MP3 Frame';
+ pendingMP3Frames.enqueue(newFrame);
+
+ int totalDataSizeAfter
+ = pendingMP3Frames.totalDataSize();
+ } while (totalDataSizeBefore < newFrame.backpointer ||
+ totalDataSizeAfter < newFrame.aduDataSize);
+
+ // We now have enough data to generate the ADU for the most
+ // recently enqueued frame (i.e., the tail of the queue).
+ // (The earlier frames in the queue - if any - must be
+ // discarded, as we don't have enough data to generate
+ // their ADUs.)
+ Segment tailFrame = pendingMP3Frames.tail();
+
+ // Output the header and side info:
+ output(tailFrame.header);
+ output(tailFrame.sideInfo);
+
+ // Go back to the frame that contains the start of our ADU data:
+ int offset = 0;
+ Segment curFrame = tailFrame;
+ int prevBytes = tailFrame.backpointer;
+ while (prevBytes > 0) {
+ curFrame = pendingMP3Frames.previous(curFrame);
+ int dataHere = curFrame.frameDataSize;
+ if (dataHere < prevBytes) {
+ prevBytes -= dataHere;
+ } else {
+ offset = dataHere - prevBytes;
+ break;
+ }
+ }
+
+ // Dequeue any frames that we no longer need:
+ while (pendingMP3Frames.head() != curFrame) {
+ pendingMP3Frames.dequeue();
+ }
+
+
+
+Finlayson Standards Track [Page 12]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ // Output, from the remaining frames, the ADU data that we want:
+ int bytesToUse = tailFrame.aduDataSize;
+ while (bytesToUse > 0) {
+ int dataHere = curFrame.frameDataSize - offset;
+ int bytesUsedHere
+ = dataHere < bytesToUse ? dataHere : bytesToUse;
+
+ output("bytesUsedHere" bytes from curFrame.frameData,
+ starting from "offset");
+
+ bytesToUse -= bytesUsedHere;
+ offset = 0;
+ curFrame = pendingMP3Frames.next(curFrame);
+ }
+}
+
+A.2 Converting a sequence of "ADU Frames" to a sequence of "MP3 Frames":
+
+SegmentQueue pendingADUFrames; // initially empty
+while (1) {
+ while (needToGetAnADU()) {
+ Segment newADU = 'the next ADU Frame';
+ pendingADUFrames.enqueue(newADU);
+
+ insertDummyADUsIfNecessary();
+ }
+
+ generateFrameFromHeadADU();
+}
+
+Boolean needToGetAnADU() {
+ // Checks whether we need to enqueue one or more new ADUs before
+ // we have enough data to generate a frame for the head ADU.
+ Boolean needToEnqueue = True;
+
+ if (!pendingADUFrames.isEmpty()) {
+ Segment curADU = pendingADUFrames.head();
+ int endOfHeadFrame = curADU.mp3FrameSize
+ - curADU.headerSize - curADU.sideInfoSize;
+ int frameOffset = 0;
+
+ while (1) {
+ int endOfData = frameOffset
+ - curADU.backpointer +
+ curADU.aduDataSize;
+ if (endOfData >= endOfHeadFrame) {
+ // We have enough data to generate a
+ // frame.
+
+
+
+Finlayson Standards Track [Page 13]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ needToEnqueue = False;
+ break;
+ }
+
+ frameOffset += curADU.mp3FrameSize
+ - curADU.headerSize
+ - curADU.sideInfoSize;
+ if (curADU == pendingADUFrames.tail()) break;
+ curADU = pendingADUFrames.next(curADU);
+ }
+ }
+
+ return needToEnqueue;
+}
+
+void generateFrameFromHeadADU() {
+ Segment curADU = pendingADUFrames.head();
+
+ // Output the header and side info:
+ output(curADU.header);
+ output(curADU.sideInfo);
+
+ // Begin by zeroing out the rest of the frame, in case the ADU
+ // data doesn't fill it in completely:
+ int endOfHeadFrame = curADU.mp3FrameSize
+ - curADU.headerSize - curADU.sideInfoSize;
+ output("endOfHeadFrame" zero bytes);
+
+ // Fill in the frame with appropriate ADU data from this and
+ // subsequent ADUs:
+ int frameOffset = 0;
+ int toOffset = 0;
+
+ while (toOffset < endOfHeadFrame) {
+ int startOfData = frameOffset - curADU.backpointer;
+ if (startOfData > endOfHeadFrame) {
+ break; // no more ADUs are needed
+ }
+ int endOfData = startOfData + curADU.aduDataSize;
+ if (endOfData > endOfHeadFrame) {
+ endOfData = endOfHeadFrame;
+ }
+
+ int fromOffset;
+ if (startOfData <= toOffset) {
+ fromOffset = toOffset - startOfData;
+ startOfData = toOffset;
+ if (endOfData < startOfData) {
+
+
+
+Finlayson Standards Track [Page 14]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ endOfData = startOfData;
+ }
+ } else {
+ fromOffset = 0;
+
+ // leave some zero bytes beforehand:
+ toOffset = startOfData;
+ }
+
+ int bytesUsedHere = endOfData - startOfData;
+ output(starting at offset "toOffset, "bytesUsedHere"
+ bytes from "&curADU.frameData[fromOffset]");
+ toOffset += bytesUsedHere;
+
+ frameOffset += curADU.mp3FrameSize
+ - curADU.headerSize - curADU.sideInfoSize;
+ curADU = pendingADUFrames.next(curADU);
+ }
+
+ pendingADUFrames.dequeue();
+}
+
+void insertDummyADUsIfNecessary() {
+ // The tail segment (ADU) is assumed to have been recently
+ // enqueued. If its backpointer would overlap the data
+ // of the previous ADU, then we need to insert one or more
+ // empty, 'dummy' ADUs ahead of it. (This situation should
+ // occur only if an intermediate ADU was missing - e.g., due
+ // to packet loss.)
+ while (1) {
+ Segment tailADU = pendingADUFrames.tail();
+ int prevADUend; // relative to the start of the tail ADU
+
+ if (pendingADUFrames.head() != tailADU) {
+ // there is a previous ADU
+ Segment prevADU
+ = pendingADUFrames.previous(tailADU);
+ prevADUend
+ = prevADU.mp3FrameSize +
+ prevADU.backpointer
+ - prevADU.headerSize
+ - curADU.sideInfoSize;
+ if (prevADU.aduDataSize > prevADUend) {
+ // this shouldn't happen if the previous
+ // ADU was well-formed
+ prevADUend = 0;
+ } else {
+ prevADUend -= prevADU.aduDataSize;
+
+
+
+Finlayson Standards Track [Page 15]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ }
+ } else {
+ prevADUend = 0;
+ }
+
+ if (tailADU.backpointer > prevADUend) {
+ // Insert a 'dummy' ADU in front of the tail.
+ // This ADU can have the same "header" (and thus
+ // "mp3FrameSize") as the tail ADU, but should
+ // have an "aduDataSize" of zero. The simplest
+ // way to do this is to copy the "sideInfo" from
+ // the tail ADU, and zero out the
+ // "main_data_begin" and all of the
+ // "part2_3_length" fields.
+ } else {
+ break; // no more dummy ADUs need to be inserted
+ }
+ }
+}
+
+Appendix B: Interleaving and Deinterleaving
+
+ The following 'pseudo code' describes how a sender can reorder a
+ sequence of "ADU Frames" according to an interleaving pattern (step
+ 2), and how a receiver can perform the reverse reordering (step 6).
+
+B.1 Interleaving a sequence of "ADU Frames":
+
+ We first define the following abstract data structures:
+
+ - "interleaveCycleSize": an integer in the range [1,256] -
+ "interleaveCycle": an array, of size "interleaveCycleSize",
+ containing some permutation of the integers from the set [0 ..
+ interleaveCycleSize-1]
+ e.g., if "interleaveCycleSize" == 8, "interleaveCycle" might
+ contain: 1,3,5,7,0,2,4,6
+ - "inverseInterleaveCycle": an array containing the inverse of the
+ permutation in "interleaveCycle" - i.e., such that
+ interleaveCycle[inverseInterleaveCycle[i]] == i
+ - "ii": the current Interleave Index (initially 0)
+ - "icc": the current Interleave Cycle Count (initially 0)
+ - "aduFrameBuffer": an array, of size "interleaveCycleSize", of ADU
+ Frames that are awaiting packetization
+
+while (1) {
+ int positionOfNextFrame = inverseInterleaveCycle[ii];
+ aduFrameBuffer[positionOfNextFrame] = the next ADU frame;
+ replace the high-order 11 bits of this frame's MPEG header
+
+
+
+Finlayson Standards Track [Page 16]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ with (ii,icc);
+ // Note: Be sure to leave the remaining 21 bits as is
+ if (++ii == interleaveCycleSize) {
+ // We've finished this cycle, so pass all
+ // pending frames to the packetizing step
+ for (int i = 0; i < interleaveCycleSize; ++i) {
+ pass aduFrameBuffer[i] to the packetizing step;
+ }
+
+ ii = 0;
+ icc = (icc+1)%8;
+ }
+}
+
+B.2 Deinterleaving a sequence of (interleaved) "ADU Frames":
+
+ We first define the following abstract data structures:
+
+ - "ii": the Interleave Index from the current incoming ADU frame
+ - "icc": the Interleave Cycle Count from the current incoming ADU
+ frame
+ - "iiLastSeen": the most recently seen Interleave Index (initially,
+ some integer *not* in the range [0,255])
+ - "iccLastSeen": the most recently seen Interleave Cycle Count
+ (initially, some integer *not* in the range [0,7])
+ - "aduFrameBuffer": an array, of size 32, of (pointers to) ADU
+ Frames that have just been depacketized (initially, all entries
+ are NULL)
+
+while (1) {
+ aduFrame = the next ADU frame from the depacketizing step;
+ (ii,icc) = "the high-order 11 bits of aduFrame's MPEG header";
+ "the high-order 11 bits of aduFrame's MPEG header" = 0xFFE;
+ // Note: Be sure to leave the remaining 21 bits as is
+
+ if (icc != iccLastSeen || ii == iiLastSeen) {
+ // We've started a new interleave cycle
+ // (or interleaving was not used). Release all
+ // pending ADU frames to the ADU->MP3 conversion step:
+ for (int i = 0; i < 32; ++i) {
+ if (aduFrameBuffer[i] != NULL) {
+ release aduFrameBuffer[i];
+ aduFrameBuffer[i] = NULL;
+ }
+ }
+ }
+
+ iiLastSeen = ii;
+
+
+
+Finlayson Standards Track [Page 17]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+ iccLastSeen = icc;
+ aduFrameBuffer[ii] = aduFrame;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Finlayson Standards Track [Page 18]
+
+RFC 3119 Loss-Tolerant RTP Payload Format for MP3 Audio June 2001
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Finlayson Standards Track [Page 19]
+