📄 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 1999typedef 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 + -