📄 rfc3119.txt
字号:
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -