📄 rfc2733.txt
字号:
value. The CC value is computed via the protection operation. The
CSRC list is never present, independent of the value of the CC field.
The extension is never present, independent of the value of the X
bit. The marker bit is computed via the protection operation.
The sequence number has the standard definition: it MUST be one
higher than the sequence number in the previously transmitted FEC
packet. The timestamp MUST be set to the value of the media RTP clock
at the instant the FEC packet is transmitted. This results in the TS
value in FEC packets to be monotonically increasing, independent of
the FEC scheme.
The payload type for the FEC packet is determined through dynamic,
out of band means. According to RFC 1889 [3], RTP participants which
cannot recognize a payload type must discard it. This provides
backwards compatibility. The FEC mechanisms can then be used in a
multicast group with mixed FEC-capable and FEC-incapable receivers.
6.2 FEC Header
This header is 12 bytes. The format of the header is shown in Figure
2, and consists of an SN base field, length recovery field, E field,
PT recovery field, mask field and TS recovery field.
Rosenberg & Schulzrinne Standards Track [Page 7]
RFC 2733 Generic FEC December 1999
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SN base | length recovery |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|E| PT recovery | mask |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| TS recovery |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 2: Parity Header Format
The length recovery field is used to determine the length of any
recovered packets. It is computed via the protection operation
applied to the unsigned network-ordered 16 bit representation of the
sums of the lengths (in bytes) of the media payload, CSRC list,
extension and padding of media packets associated with this FEC
packet (in other words, the CSRC list, extension, and padding, if
present, are "counted" as part of the payload). This allows the FEC
procedure to be applied even when the lengths of the media packets
are not identical. For example, assume an FEC packet is being
generated by xor'ing two media packets together. The length of the
two media packets are 3 (0b011) and 5 (0b101) bytes, respectively.
The length recovery field is then encoded as 0b011 xor 0b101 = 0b110.
The E bit indicates a header extension. Implementations conforming to
this version of the specification MUST set this bit to zero.
The PT recovery field is obtained via the protection operation
applied to the payload type values of the media packets associated
with the FEC packet.
The mask field is 24 bits. If bit i in the mask is set to 1, then the
media packet with sequence number N + i is associated with this FEC
packet, where N is the SN Base field in the FEC packet header. The
least significant bit corresponds to i=0, and the most significant to
i=23.
The SN base field MUST be set to the minimum sequence number of those
media packets protected by FEC. This allows for the FEC operation to
extend over any string of at most 24 packets.
The TS recovery field is computed via the protection operation
applied to the timestamps of the media packets associated with this
FEC packet. This allows the timestamp to be completely recovered.
The payload of the FEC packet is the protection operation applied to
the concatenation of the CSRC list, RTP extension, media payload, and
padding of the media packets associated with the FEC packet.
Rosenberg & Schulzrinne Standards Track [Page 8]
RFC 2733 Generic FEC December 1999
Note that it's possible for the FEC packet to be slightly larger than
the media packets it protects (due to the presence of the FEC
header). This could cause difficulties if this results in the FEC
packet exceeding the Maximum Transmission Unit size for the path
along which it is sent.
7 Protection Operation
The protection operation involves concatenating specific fields from
the RTP header of the media packet, appending the payload, padding
with zeroes, and then computing the xor across the resulting bit
strings. The resulting bit string is used to generate the FEC packet.
The following procedure MAY be followed for the protection operation.
Other procedures MAY be followed, but the end result MUST be
identical to the one described here. For each media packet to be
protected, a bit string is generated by concatenating the following
fields together in the order specifed:
o Padding Bit (1 bit)
o Extension Bit (1 bit)
o CC bits (4 bits)
o Marker bit (1 bit)
o Payload Type (7 bits)
o Timestamp (32 bits)
o Unsigned network-ordered 16 bit representation of the sum of
the lengths (in bytes) of the CSRC List, length of the padding,
length of the extension, and length of the media payload (16
bits)
o if CC is nonzero, the CSRC List (variable length)
o if X is 1, the Header Extension (variable length)
o the payload (variable length)
o Padding, if present (variable length)
Note that the Padding Bit (first entry above) forms the most
significant bit of the bit string.
Rosenberg & Schulzrinne Standards Track [Page 9]
RFC 2733 Generic FEC December 1999
If the lengths of the bit strings are not equal, each bit string that
is shorter than the length of the longest, MUST be padded to the
length of the longest. Any value for the pad may be used. The pad
MUST be added at the end of the bit string.
The parity operation is then applied across the bit strings. The
result is the bit string used to build the FEC packet. Call this the
FEC bit string.
The first (most significant) bit in the FEC bit string is written
into the Padding Bit of the FEC packet. The second bit in the FEC bit
string is written into the Extension bit of the FEC packet. The next
four bits of the FEC bit string are written into the CC field of the
FEC packet. The next bit of the FEC bit string is written into the
marker bit of the FEC packet. The next 7 bits of the FEC bit string
are written into the PT recovery field in the FEC packet header. The
next 32 bits of the FEC bit string are written into the TS recovery
field in the packet header. The next 16 bits are written into the
length recovery field in the FEC packet header. The remaining bits
are set to be the payload of the FEC packet.
8 Recovery Procedures
The FEC packets allow end systems to recover from the loss of media
packets. All of the header fields of the missing packets, including
CSRC lists, extensions, padding bits, marker and payload type, are
recoverable. This section describes the procedure for performing
this recovery.
Recovery requires two distinct operations. The first determines which
packets (media and FEC) must be combined in order to recover a
missing packet. Once this is done, the second step is to actually
reconstruct the data. The second step MUST be performed as described
below. The first step MAY be based on any algorithm chosen by the
implementer. Different algorithms result in a tradeoff between
complexity and the ability to recover missing packets if at all
possible.
8.1 Reconstruction
Let T be the list of packets (FEC and media) which can be combined to
recover some media packet xi. The procedure is as follows:
1. For the media packets in T, compute the bit string as
described in the protection operation of the previous
section.
Rosenberg & Schulzrinne Standards Track [Page 10]
RFC 2733 Generic FEC December 1999
2. For the FEC packet in T, compute the bit string in the same
fashion, except use the PT Recovery instead of Payload Type,
TS Recovery instead of Timestamp, and always set the CSRC
list, extension, and padding to null.
3. If any of the bit strings generated from the media packets
are shorter than the bit string generated from the FEC
packet, pad them to be the same length as the bit string
generated from the FEC. The padding MUST be added at the
end of the bit string, and MAY be of any value.
4. Perform the exclusive or (parity) operation across the bit
strings, resulting in a recovery bit string.
5. Create a new packet with the standard 12 byte RTP header
and no payload.
6. Set the version of the new packet to 2.
7. Set the Padding bit in the new packet to the first bit in
the recovery bit string.
8. Set the Extension bit in the new packet to the second bit
in the recovery bit string.
9. Set the CC field to the next four bits in the recovery bit
string.
10. Set the marker bit in the new packet to the next bit in the
recovery bit string.
11. Set the payload type in the new packet to the next 7 bits
in the recovery bit string.
12. Set the SN field in the new packet to xi.
13. Set the TS field in the new packet to the next 32 bits in
the recovery bit string.
14. Take the next 16 bits of the recovery bit string. Whatever
unsigned integer this represents (assuming network-order),
take that many bytes from the recovery bit string and
append them to the new packet. This represents the CSRC
list, extension, payload, and padding.
Rosenberg & Schulzrinne Standards Track [Page 11]
RFC 2733 Generic FEC December 1999
15. Set the SSRC of the new packet to the SSRC of the media
stream it's protecting.
This procedure will completely recover both the header and payload of
an RTP packet.
8.2 Determination of When to Recover
The previous section discussed how to recover a media packet with
sequence number xi when all of the packets needed to recover it were
available. The decision about whether to attempt recovery of some
media packet xi, and how to determine if sufficient data is available
to recover it, is left to the implementer. However, this section
provides a simple algorithm which MAY be used for this purpose.
The algorithm is described below in C code. The code assumes that
several functions exist. recover_packet() takes the sequence number
of a packet, and an FEC packet. Using the FEC packet and data packets
received previously, the data packet with the given sequence number
is recovered. add_fec_to_pending_list() adds the given FEC packet to
a linked list of FEC packets which have not yet been used for
recovery. wait_for_packet() waits for a packet, FEC or data, from the
network. remove_from_pending_list() removes the FEC packet from the
pending list. The structure packet contains a boolean variable fec
which is true when the packet is FEC, false if it's media. When its
an FEC packet, the mask and snbase field contain those values from
the FEC packet header. When it's a media packet, the sn variable
contains the sequence number of the packet. The global array A
indicates which media packets have been received, and which have not.
It is indexed by the sequence number of the packet.
The function fec_recovery implements the algorithm. It waits for
packets, and when it receives an FEC packet, calls recover_with_fec()
to attempt to use it to recover. If no recovery is possible, the FEC
packet is stored for later attempts. If the received packet was a
media packet, its presence is noted, and any old FEC packets are
checked to see if recovery is now possible. Recovered packets are
treated as if they were received, triggering further attempts at
recovery.
A real implementation will need to use a circular buffer instead of
the simple array (A in the code) in order to avoid running off the
end of the buffer. In addition, the code below does not attempt to
free up FEC packets that are old and were never used. Normally, such
discarding is done based on time constraints introduced by the
playout buffer. If an FEC data protects packets whose play time has
elapsed, the FEC is no longer needed.
Rosenberg & Schulzrinne Standards Track [Page 12]
RFC 2733 Generic FEC December 1999
typedef struct packet_s {
BOOLEAN fec; /* FEC or media */
int sn; /* SN of the packet, for media only */
BOOLEAN mask[24]; /* Mask, FEC only */
int snbase; /* SN Base, FEC only */
struct packet_s *next;
} packet;
BOOLEAN A[65535];
packet *pending_list;
packet *recover_with_fec(packet *fec_pkt) {
packet *data_pkt;
int pkts_present, /* number of packets from the mask that are
present */
pkts_needed, /* number of packets needed is the number of ones
in the mask minus 1 */
pkt_to_recover, /* sn of the packet we are recovering */
i;
pkts_present = 0;
/* The number of packets needed is the number of ones in the mask
minus 1. The code below increments pkts_needed by the number
of ones in the mask, so we initialize this to -1 so that the
final count is correct */
pkts_needed = -1;
/* Go through all 24 bits in the mask, and check if we have
all but one of the media packets */
for(i = 0; i < 24; i++) {
/* If the packet is here and in the mask, increment counter */
if(A[i+fec_pkt->snbase] && fec_pkt->mask[i]) pkts_present++;
/* Count the number of packets needed as well */
if(fec_pkt->mask[i]) pkts_needed++;
Rosenberg & Schulzrinne Standards Track [Page 13]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -