本文档为封装在RTP中的媒体数据的通用前向纠错(FEC)指定了有效负载格式。它基于异或(奇偶校验)操作。本文档中描述的有效负载格式允许终端系统使用不同的保护长度和级别来应用保护,此外还使用不同的保护组大小来适应不同的媒体和信道特性。它能够根据丢包情况完全恢复受保护的数据包或部分恢复有效负载的关键部分。该方案与不支持FEC的主机完全兼容,因此不实现FEC的多播组中的接收机只需忽略保护数据即可工作。本规范淘汰了RFC 2733和RFC 3009。本文件中规定的FEC与RFC 2733和RFC 3009不向后兼容。
实时应用程序的性质意味着它们通常比正常的数据传输有更严格的延迟要求(即要求低延迟)。结果,对于这样的应用程序,重传丢失的分组通常不是有效的选择。在这些情况下,通过前向纠错(FEC)来尝试从数据包丢失中恢复信息是一种更好的方法。FEC是用于保护分组交换网络上的分组丢失的主要方法之一[9,10]。特别是传统纠错码的使用,如奇偶校验码、Reed-Solomon码和Hamming码,得到了广泛的应用。要应用这些机制,需要协议支持。RFC 2733[9]和RFC 3009[11]定义了这样的FEC协议之一。然而,在上述两个RFC中,RTP报头中的一些字段(P、X和CC字段)的指定方式与RTP中的设计方式不一致[1]。这防止了RTP包的有效性检查与有效负载无关。
本文扩展了FEC2733和RFC3009中定义的FEC,以包括对有效负载数据的不等错误保护。它以前面的两个RFC为特例指定了一个通用算法,该规范还修复了前面两个RFC与RFC2733和RFC3009的不一致性,并将废弃这两个RFC。请注意,本文档中指定的有效负载与RFC 2733和RFC 3009不向后兼容。由于本文档中指定的有效负载由不同于RFC3009的MIMES规定的有效负载,因此在容量交换中,不存在不同版本的奇偶校验FEC的错误识别问题。对于这里以及RFC 2733和RFC 3009中指定的奇偶校验FEC,有效负载数据是不变的,并且发送附加FEC数据以保护有效负载数据。因此,有效负载数据的通信将在不同奇偶校验FEC版本的主机和未实现奇偶校验FEC的主机之间无问题地流动。具有来自发送主机的不兼容FEC的接收主机将无法从附加FEC数据中获益,因此建议在可能的情况下更新实现RFC 2733和RFC 3009的现有主机以遵循此规范。
本文为RTP[1]定义了一种有效负载格式,该格式允许实时媒体的一般前向纠错。在此上下文中,通用意味着FEC协议(1)独立于被保护的媒体的性质,无论是音频、视频还是其他(2) 足够灵活,可支持多种FEC配置(3) 自适应设计使得FEC技术可以很容易地修改,而不需要带外信令;以及(4)支持用于传输FEC分组的多种不同机制。
此外,在许多情况下,网络连接的带宽是非常有限的资源。另一方面,大多数传统的FEC方案并不是为有限带宽资源的最佳利用而设计的。一个常用的改进是不等错误保护,它为数据流的不同部分提供不同级别的保护,这些部分的重要性不同。不等差错保护方案通常可以更有效地利用带宽,从而更好地保护数据流免受丢失。正确的协议支持是实现这些不等错误保护机制的关键。大多数不等差错保护方案的应用要求了解数据流不同部分的重要性。因此,大多数这样的方案是根据受保护介质的结构为特定类型的介质设计的,因此不是通用的。
本文定义了FEC算法和协议,用于实时媒体中具有不等差错保护的通用前向纠错。这里定义的特定算法称为不均匀级别保护(Uneven Level Protection-ULP)。有效负载数据受一个或多个保护级别的保护。较低的保护级别可以通过使用较小的组大小(与较高的保护级别相比)来生成FEC分组来提供更大的保护。正如我们将在下面讨论的,音频/视频应用程序通常会受益于不等的错误保护方案,该方案对每个数据包的开始部分(如ULP)提供更多的保护。一般来说,距离数据包开头较近的数据比数据包后面较远的数据更重要,并且往往携带更多的信息。
众所周知,在许多多媒体流中,数据的更重要部分总是在数据包的开头。这是编解码器设计中的常见做法,因为数据包的开头更接近报头处的重新同步标记,因此更有可能被正确解码。此外,几乎所有的媒体格式在包的开头都有帧头,帧头是包中最重要的部分。
对于视频流,大多数现代格式具有可选的数据分区模式,以提高容错能力,其中视频宏块头数据、运动矢量数据和离散余弦变换(DCT)系数数据被分离到各自的分区中。例如,在ITU-T H.263版本3中,有附录V的可选数据分区语法。在MPEG-4视觉简单配置文件中,有可选的数据分区模式。启用这些模式时,视频宏块(MB)头和运动矢量分区(对视频重建的质量更重要)在视频分组的开始处的分区中传输,而剩余DCT系数分区(不太重要)在靠近分组的结束处的分区中传输。因为数据是按重要性降序排列的,所以在传输中对数据包的开始部分提供更多的保护是有益的。
对于音频流,由许多新的音频编解码器生成的比特流还包含具有不同重要性类别的数据。然后,这些不同的类按重要性降序传输。在这些情况下,对数据包的开头应用更多的保护也将是有益的。即使对于意义一致的音频流,也可以对部分恢复的音频数据包应用各种时间移位和拉伸技术。
音频/视频应用程序通常会受益于本文档中指定的FEC算法。利用ULP,可以潜在地进一步提高媒体有效负载的保护效率。本文件规定了将通用FEC应用于RTP媒体有效载荷的协议和算法。
本文件中使用了以下术语:
Media Payload: The raw, unprotected user data that are transmitted from the sender. The media payload is placed inside of an RTP packet.
媒体有效负载:从发送方传输的未受保护的原始用户数据。媒体有效负载被放置在RTP包中。
Media Header: The RTP header for the packet containing the media payload.
媒体头:包含媒体负载的数据包的RTP头。
FEC Packet: The FEC algorithms at the transmitter take the media packets as an input. They output both the media packets that they are passed, and newly generated packets called FEC packets, which contain redundant media data used for error correction. The FEC packets are formatted according to the rules specified in this document.
FEC包:发射机的FEC算法将媒体包作为输入。它们输出所传递的媒体包和新生成的FEC包,FEC包包含用于纠错的冗余媒体数据。FEC数据包按照本文档中指定的规则进行格式化。
FEC Header: The header information contained in an FEC packet.
FEC头:FEC包中包含的头信息。
FEC Level Header: The header information contained in an FEC packet for each level.
FEC级报头:包含在每个级别的FEC数据包中的报头信息。
FEC Payload: The payload of an FEC packet. It may be divided into multiple levels.
FEC有效负载:FEC数据包的有效负载。它可以分为多个层次。
Associated: A FEC packet is said to be “associated” with one or more media packets (or vice versa) when those media packets are used to generate the FEC packet (by use of the exclusive-or operation). It refers to only those packets used to generate the level 0 FEC payload, if not explicitly stated otherwise.
关联:当使用一个或多个媒体分组来生成FEC分组时(通过使用异或操作),FEC分组被称为与一个或多个媒体分组“关联”(反之亦然)。如果没有明确地另外说明的话,它仅指用于生成0级FEC有效负载的那些包。
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 [2].
本文件中的关键词“必须”、“不得”、“必须”、“应”、“不应”、“应”、“不应”、“建议”、“可”和“可选”应按照RFC 2119[2]的规定进行解释。
当RTP会话中的发送方想要保护它用通用奇偶校验FEC发送的媒体流时,使用这里描述的有效负载格式。此格式支持的FEC基于简单的异或(exclusive or,XOR)平价运算,发送方从需要保护的媒体流中获取数据包,并确定这些数据包的保护级别和每个级别的保护长度。如下面第7节所述,将数据分组在一起。XOR操作应用于整个有效负载以生成FEC信息。遵循这里定义的过程的结果是,RTP包将包含FEC信息。这些RTP包可在接收方用于恢复分组或分组的一部分,使用恢复的部分生成FEC信息。
FEC的有效负载格式包含信息如下:发送方通知接收方到底哪些RTP包受到FEC包的保护,以及每个级别的保护级别和长度。具体地,每个FEC分组包含用于每个保护级别k的偏移掩码m(k)。如果掩码m(k)中的位i被设置为1,则媒体分组号N+i由该FEC分组在k级保护。N被称为基础序列号,并且也在FEC包中发送。在k级受保护的数据量由L(k)表示,L(k)也在FEC包中发送。保护长度、偏移掩码、有效负载类型和序列号基完全识别应用于生成FEC包的奇偶校验码,开销很小。第7.4节描述了一组规则,定义了如何为不同的保护级别设置掩码,第10节给出了示例。
本文件还描述了在频带内传输所有保护操作参数的程序。这使得发送者有很大的灵活性;发送方可以使保护适应当前的网络条件,并且确保接收方仍然可以使用FEC进行恢复。
在接收方,FEC和原始媒体都被接收。如果没有媒体包丢失,则可以忽略FEC包。在丢失的情况下,FEC分组可以与其他接收到的媒体组合以恢复丢失的媒体分组的全部或部分。
为简洁起见,我们将函数f(x,y,…)定义为应用于数据块x,y,。。。这个函数的输出是另一个块,称为奇偶校验块。为简单起见,我们假设奇偶校验块是按输入块的位异或计算的。具体程序见第8节。
使用奇偶校验码保护数据块是通过在一组数据块上生成一个或多个奇偶校验块来实现的。为了最有效,奇偶校验块必须由数据块的线性独立组合生成。这种特殊的组合称为奇偶校验码。有效负载格式使用异或奇偶校验码。
例如,考虑在两个数据块上生成单个奇偶校验块的奇偶校验码。如果原始媒体分组是a、b、c、d,则发送方生成的分组是:
a b c d <--媒体流
f(a,b) f(c,d) <--FEC流
时间向右增加。在本例中,纠错方案(我们交替使用术语scheme和代码)引入了50%的开销。但是如果b丢失了,可以用a和f(a,b)来恢复b。
指出除了异或奇偶校验码之外,还有许多其他类型的前向纠错码也可用于保护有效负载。一个值得注意的例子是里德-所罗门代码(Reed-Solomon code),还有许多其他代码[12]。然而,这里使用异或奇偶校验码是因为它在协议设计和实现方面的有效性和简单性。这对于在资源有限的节点中实现特别重要。
从上面的简单示例中可以看出,对数据的保护取决于组的大小。在上面的示例中,组大小是2。因此,如果三个包(两个有效负载包和一个FEC包)中的任何一个丢失,则仍然可以恢复原始有效负载数据。
一般来说,FEC保护操作是带宽和保护强度之间的权衡。作为源媒体分组的一部分生成的FEC分组越多,对丢失的保护就越强,但是组合流消耗的带宽就越大。
与大多数媒体有效负载中的常见情况一样,并非包的所有部分都具有相同的重要性。利用该特性,可以通过使用不等差错保护(即,对分组的不同部分应用不同的保护)潜在地实现信道带宽的更有效利用。更多的带宽用于保护更重要的部分,而较少的带宽用于不太重要的部分。
分组被分成重要性降低的部分,并且对每个部分应用不同强度的保护-这些部分被称为“级别”。保护操作在每个级别上独立应用。单个FEC包可以携带多个级别的奇偶校验数据。这种算法被称为不均匀保护,或ULP。
ULP的保护如下图1所示。在本例中,两个ULP FEC分组保护四个有效负载分组。
ULP FEC数据包#1只有一个级别,用于保护数据包A和B。它不是对A和B的整个数据包应用奇偶校验操作,而是只保护两个数据包的一段数据。在会话期间可以动态选择和更改的长度称为保护长度。
ULP FEC数据包#2有两个保护级别。0级保护与ULP FEC数据包#1相同,只是它在数据包C和D上运行。1级保护使用对来自数据包A、B、C和D的数据应用奇偶校验操作。请注意,级别1保护在级别0的不同数据包集上运行,并且具有与级别0不同的保护长度,其他任何级别也是如此。所有信息都通过本文件中指定的协议在频带内传输。
正如我们在引言中所讨论的,媒体流通常在包的开头有更重要的部分。通常,在靠近数据包开头的级别上有较强的保护,而在较远的级别上有较弱的保护是有用的。ULP算法提供了这样的FEC保护。
ULP FEC不仅对数据包的开头提供了更多的保护(这一点更为重要),而且还尽可能避免了效率较低的情况,即数据包的前一部分不可恢复,而后一部分可以恢复(并且常常必须丢弃)。
媒体包的格式不受FEC的影响。如果FEC作为一个单独的流发送,那么媒体包就如同没有FEC一样发送。
这种方法的优点是,不支持FEC的接收器可以解释媒体包。这种与不支持FEC的接收器的兼容性在多播场景中特别有用。使用FEC方案的开销仅存在于FEC分组中,并且可以通过跟踪FEC的使用量来容易地监视和调整。
通过将一个FEC报头和一个或多个级别的FEC报头和有效负载放入RTP有效负载中来构造FEC包,如图2所示:
FEC分组的RTP报头仅在FEC以与受保护的有效负载流(如第14节中定义的)分开的流发送时使用。因此,下面的大部分讨论仅适用于该场景。FEC分组的RTP报头中的所有字段根据RFC 3550[1]使用,其中一些字段在下面进一步说明。
标记:此字段不用于此有效负载类型,应设置为0。
同步源(SSRC):SSRC值应与其保护的媒体流的SSRC值相同。
序列号(SN):序列号具有标准定义-它必须比上一个传输的FEC数据包中的序列号高一个。
时间戳(TS):时间戳必须设置为FEC数据包传输时媒体RTP时钟的值。因此,FEC分组中的TS值总是单调增加的。
有效负载类型:FEC分组的有效负载类型通过动态带外方式确定。根据RFC3550[1],不能识别有效负载类型的RTP参与者必须丢弃它。这提供了向后兼容性。FEC机制随后可用于多播组中,该多播组中,有些接收器具有FEC能力,有些不具有FEC能力,特别是当FEC保护作为冗余编码发送时(参见第14节)。在这种情况下,FEC保护有效负载类型将无法被无FEC能力的接收器识别,并且因此将被忽略。
FEC报头是10个八位字节。头的格式如图3所示,由扩展标志(E位)、长掩码标志(L位)、P恢复字段、X恢复字段、CC恢复字段、M恢复字段、PT恢复字段、SN基字段、TS恢复字段和长度恢复字段组成。
E位是保留的扩展标志,用于指示本规范的任何未来扩展。它应该被设置为0,并且应该被接收器忽略。
L位表示是否使用长掩码。未设置L位时,掩码长度为16位。设置L位时,掩码的长度为48位。
P恢复字段、X恢复字段、CC恢复字段、M恢复字段和PT恢复字段通过由本FEC包所保护的所有媒体数据包的RTP头部的P/X/CC/M/PT flag位经XOR操作后得到。
SN基字段必须设置为FEC保护的(所有级别)媒体包的最低序列号(考虑环绕)。这允许FEC操作在L字段设置为0时扩展到最多16个分组的任何字符串上,或者在L字段设置为1时扩展到48个分组,依此类推。
TS恢复字段通过由本FEC包所保护的所有媒体数据包的RTP头部中的Timestamp字段经XOR操作后得到。这样就可以完全恢复时间戳。
长度恢复字段由本FEC包所保护的所有媒体数据包的负载长度(包括CSRC、RTP头部扩展、负载和padding的长度之和,以16位无符号网络序表示)经XOR操作后得到。这使得即使在受保护的媒体分组的长度不相同时也可以应用FEC过程。例如,假设通过将两个媒体包异或在一起生成FEC包。两个媒体包的有效负载长度分别为3(0b011)和5(0b101)字节。然后将长度恢复字段编码为0b011 xor 0b101=0b110。
FEC级报头是4或8个八位字节(取决于FEC报头中的L位)。标题的格式如图4所示。
FEC级报头由保护长度字段和掩码字段组成。保护长度字段为16位长。掩码字段的长度为16位(未设置L位时)或48位(设置L位时)。
FEC级报头中的掩码字段指示哪些包与当前级的FEC包相关联。它是16位或48位,具体取决于L位的值。如果掩码中的位i被设置为1,则序列号为N+i的媒体分组与该FEC分组相关联,其中N是FEC分组报头中的SN基字段。掩码的最高有效位对应于i=0,当L位设置为0时,最低有效位对应于i=15,或当L位设置为1时,i=47。
掩码字段的设置应遵循以下规则:
A. 一个媒体包在高于0级的每个保护级别上只能被保护一次。一个媒体包在0级可以被不同的包保护多次,只要这些包的0级保护长度相等。
B. 对于要在p级保护的媒体包,在任何FEC包中它也必须在p-1级保护。请注意,媒体包的保护级别p可以位于FEC包中,FEC包与包含同一媒体包的保护级别p-1的FEC包不同。
C. 如果ULP FEC数据包包含p级保护,则它还必须包含p-1级保护。请注意,p级保护的有效负载数据包的组合可能不同于p-1级的有效负载数据包的组合。
规则(a)的基本原理是多重保护增加了恢复实施的复杂性。在更高的级别上,多重保护带来的好处越来越小,因此它的应用仅限于级别0以简化实现。规则(b)的基本原理是保护偏移量(对于每个相关的数据包)在协议中没有显式地发信号。有了这个限制,可以很容易地从电平的保护长度中扣除偏移量。规则(c)的基本原理是没有明确指出保护级别。此规则设置为隐式指定级别。
保护组合的一个示例如下图5所示。这是与图1所示相同的示例,同样的示例在第10.2节中也有更详细的说明,以说明如何设置标题中的字段。
在本例中,ULP FEC数据包#1仅具有0级保护。ULP FEC数据包#2具有0级和1级保护。从表中可以看出,有效负载数据包A在0级受ULP FEC数据包#1保护,在1级受ULP FEC数据包#2保护,依此类推。此外,从表中可以容易地看出,ULP FEC分组#2保护0级有效负载分组C和D,保护1级有效负载分组A-D,依此类推。有关更多详细信息的其他示例,请参阅第10节“示例”。
每个级别的ULP FEC分组的有效载荷是应用于媒体有效载荷的保护操作(XOR)和在该级别上填充与ULP FEC分组相关联的媒体分组。有关保护操作的详细信息,请参见第8节。
ULP FEC包的大小由为保护操作选择的保护长度确定。在上面的示例中,ULP FEC分组#1具有长度L0(加上报头开销)。具有两个级别的ULP FEC包#2的长度为L0+L1(加上报头开销)。它比它保护的一些数据包(本例中的数据包B和C)长,比它保护的一些数据包(本例中的数据包A和D)短。
注意,FEC包(非ULP和ULP)可能大于其保护的最长媒体包,因为来自报头的开销和/或如果为ULP选择了较大的保护长度。如果这导致FEC分组超过其发送路径的最大传输单元大小,则这可能导致困难。
FEC分组由从受保护媒体RTP分组的数据生成的“FEC比特串”形成。更具体地说,FEC比特串是受保护媒体RTP分组的“受保护比特串”的逐位异或。
保护操作可遵循以下程序。可以使用其他程序,但最终结果必须与此处描述的相同。
在FEC报头的情况下,为要在FEC级别0保护的每个媒体分组生成受保护比特串(长度为80比特)。它是通过按指定顺序将以下字段串联在一起形成的:
在通过对受保护的位串应用奇偶校验操作形成FEC位串之后,根据FEC位串生成FEC报头,如下所示:
跳过FEC位串中的第一个(最高有效)2位。FEC比特串中的下一个比特被写入FEC分组中FEC报头的P恢复比特。FEC位串中的下一位被写入FEC报头的E恢复位。FEC位串的下4位被写入FEC报头的CC recovery字段。下一位被写入FEC报头的M恢复位。FEC位串的下7位被写入FEC报头中的PT recovery字段。接下来的16位被跳过。FEC位串的下32位被写入FEC报头中的TS recovery字段。接下来的16位被写入包报头中的长度恢复字段。
对于FEC有效负载的生成,受保护的比特串只是受保护的RTP分组。因此,FEC位串是这些受保护的媒体RTP分组的按位异或。需要为每个级别生成这样的FEC比特串,因为对于每个级别,受保护的有效负载分组的组可能不同。如果受保护的RTP数据包的长度不相等,则每个较短的数据包必须通过在末尾添加八位字节0来填充到最长数据包的长度。
对于保护级别n(n=0,1,…),在级别n ULP报头之后,只有Ln个八位字节的数据被设置为FEC级别n有效负载数据。数据是从FEC位串中的第(Sn+13)个八位字节开始的Ln个八位字节的数据,其中:
Sn = sum(Li : 0 <= i < n).
Li是级别i的保护长度,S0被定义为0。省略前12个八位字节的原因是FEC头已经保护了信息。
FEC包允许终端系统从媒体包的丢失中恢复。本节介绍执行此恢复的过程。
恢复需要两个不同的操作。第一种方法确定为了恢复丢失的数据包,必须组合哪些数据包(媒体和FEC)。完成后,第二步是实际重建数据。第二步必须如下所述执行。第一步可以基于实现者选择的任何算法。如果可能的话,不同的算法会在复杂性和恢复丢失数据包的能力之间进行权衡。
丢失的有效载荷分组可以全部或部分地恢复,这取决于由于不等错误保护的性质(当使用它时)而导致的数据丢失情况。包的部分恢复可以通过检查从FEC报头检索的包的恢复长度与恢复的有效负载数据的实际长度来检测。
让T是包的列表(FEC和媒体),该列表可以组合在一起恢复一些xi在0级别的媒体包席。程序如下:
此过程将RTP数据包的报头恢复到SSRC字段。
让T是可以组合在一定保护级别上恢复一些媒体分组席的分组(FEC和媒体)列表。程序如下:
在下面考虑的前两个示例(第10.1节和第10.2节)中,我们假设FEC流通过第14.1节中描述的单独RTP会话发送。对于这些示例,我们假设要从ssrc2发送四个媒体包A、B、C和D,它们的序列号分别为8、9、10和11,时间戳分别为3、5、7和9。数据包A和C使用有效负载类型11,数据包B和D使用有效负载类型18。数据包A具有200字节的有效负载、数据包B 140、数据包C 100和数据包D 340。数据包A和C具有其标记位集。
第三个示例(第10.3节)是说明FEC数据何时作为冗余数据与有效负载分组一起发送。
我们可以用一个FEC包在一个层次上保护四个有效负载包的完整长度。这提供了与RFC2733类似的保护。方案如图6所示。
从这四个包生成FEC包。我们假设有效负载类型127用于指示FEC分组。生成的RTP头如图7所示。
一个更复杂的例子是在两个层次上使用FEC。0级FEC将为有效负载包的开始部分提供更大的保护。1级FEC将对其余的包应用额外的保护。如图10所示。在本例中,L0=70,L1=90。
这将导致两个FEC数据包-#1和#2。
生成的ULP FEC数据包#1将具有如图11所示的RTP报头。ULP FEC数据包#1的FEC报头将如图12所示。#1的0级ULP报头将如图13所示。
生成的FEC数据包#2将具有如图14所示的RTP报头。FEC数据包#2的FEC报头将如图15所示。#2的0级ULP报头将如图16所示。#2的1级ULP报头将如图17所示。
这个例子说明了在与有效载荷相同的流中作为冗余编码发送的FEC。我们假设要从ssrc2发送五个媒体包A、B、C、D和E,它们的序列号分别为8、9、10、11和12,时间戳分别为3、5、7、9和11。所有媒体数据都用主编码(而FEC作为冗余编码仅保护主编码)进行编码,并使用有效负载类型11。数据包A具有200字节的有效负载、数据包B140、数据包C100、数据包D340和数据包E160。数据包A和C具有其标记位集。
我们使用的FEC方案将具有一个级别,如第10.1节中的图6所示。保护长度L0=340个八位字节。
冗余编码分组与有效负载类型100一起使用。假设FEC的有效负载类型为127。前四个RED包,从RED#1到RED#4,分别包含一个单独的媒体包A、B、C或D。生成保护前四个媒体分组中的媒体数据的FEC数据。第五个包,RED#5,包含作为冗余编码的FEC数据以及媒体包E。
RED Packet #1: Media Packet A
RED Packet #2: Media Packet B
RED Packet #3: Media Packet C
RED Packet #4: Media Packet D
RED Packet #5: FEC Packet, Media Packet E
RED包#1到#4的结构如图18所示。RED包#1的RTP报头如图19所示,所有其他的RED包格式相似,具有相应的序列号和时间戳。RED包的主要编码块头如图20所示。
FEC数据不是直接从RED包生成的,而是从包含媒体分组数据的虚拟RTP分组生成的。这些虚拟RTP包可以很容易地从包含冗余编码和不包含冗余编码的RED包生成。从RED包到虚拟RTP包的转换简单地通过(1)移除任何RED包头和冗余编码数据,以及(2)用主编码的PT替换RTP头中的PT来完成。
注:在RFC 2198指定的冗余编码的有效载荷格式中,只要在RED包中携带主编码,就丢失标记位(M字段)。因此,无论是否使用FEC,都无法恢复标记位(M字段)。
如上所述,RED包5将包含FEC数据(保护媒体包A、B、C和D)以及媒体包E的数据。RED包5的结构如图21所示。
包含FEC的RED包的RTP报头与图19所示相同,具有相应的序列号和时间戳。
在RED包#5中,FEC包数据块的冗余编码块报头如下图22所示。它后面是FEC包数据,在这种情况下,它包括一个FEC报头(如图8所示的10个八位字节)、ULP 0级报头(如图9所示的4个八位字节),以及ULP 0级数据(为0级设置了340个八位字节)。随后是包含媒体分组E的数据的主编码块。
在安全通信中使用FEC加加密有两种方法:一种方法是在已经加密的有效负载上应用FEC,另一种方法是在加密之前应用FEC。第一种情况是在媒体数据加密后的传输过程中,非可信节点需要FEC。第二种情况是媒体数据在通过安全传输传输之前受到FEC的保护。
由于该FEC的受保护有效载荷是RTP分组,因此在加密有效载荷上应用FEC主要适用于安全RTP(SRTP)[13]的情况。因为FEC在负载上应用XOR,所以FEC包在密码上应该和原始负载一样安全。在这种情况下,FEC分组的附加加密是不必要的。
在下面的讨论中,假设FEC在加密之前应用于有效载荷。FEC的使用对加密密钥的使用和更改有影响。由于FEC包确实由单独的流组成,因此在加密的使用上有许多组合。其中包括:
其中的前三个协议要求所有应用层信令协议都知道FEC的使用情况,从而在媒体和FEC流上分别交换密钥和协商加密使用情况。在最后一种情况下,不需要这种额外的机制。前两种情况呈现分层冲突,因为ULP FEC数据包应该与其他RTP数据包没有区别。仅加密一个流也可能使某些已知的明文攻击成为可能。基于这些原因,使用加密的应用程序应该加密两个流,即最后两个选项。
此外,由于加密可能被某些密码的媒体有效载荷和FEC数据之间的已知关系所削弱,因此当媒体有效载荷和FEC数据在单独的流中发送时,必须对每个流使用不同的加密密钥。注意,当SRTP[13]用于RTP会话的安全性时,SRTP规范要求每个RTP会话使用不同的密钥。
加密密钥的更改是另一个需要解决的关键问题。考虑两个数据包A和B连同保护它们的FEC包一起发送的情况。用于加密a和b的密钥不同,那么应该使用哪个密钥来解码FEC数据包?通常,需要缓存旧密钥,以便当媒体流的密钥改变时,可以使用旧密钥,直到确定ULP FEC分组的密钥也改变为止。此外,新密钥应用于加密由新旧密钥加密的有效载荷分组的组合生成的FEC分组。发送方和接收方需要定义如何执行加密以及如何使用密钥。
改变FEC数据和包会对重建操作产生很大的影响。通过改变FEC数据中的一些位的攻击可以对有效载荷包的计算和恢复产生显著影响。例如,更改长度恢复字段可能导致恢复过长的数据包。此外,恢复的计算复杂性可以容易地受到至少一个数量级的影响。根据应用场景,在执行恢复操作之前对接收的有效负载和FEC数据执行健全性检查以及在使用它们之前确定从恢复操作恢复的数据的有效性可能是有帮助的。
使用FEC的另一个问题是它对网络拥塞的影响。在许多情况下,网络中的数据包丢失是由拥塞引起的。在这种情况下,当遇到越来越多的网络损失时,应该避免添加FEC。如果它被广泛使用,这可能会导致拥堵加剧,并最终导致拥堵崩溃。这些应用可以包括更强的保护,同时减少有效载荷分组的带宽。在任何情况下,实施不得随着网络损耗的增加而显著增加使用中的带宽总量(包括有效负载和FEC)。
传输RTP数据的一般拥塞控制考虑适用;见RTP[1]和任何适用的RTP配置文件(如RTP/AVP[14])。如果使用尽力而为服务,另一个要求是此有效负载格式的用户必须监视数据包丢失,以确保数据包丢失率在可接受的参数范围内。如果跨相同网络路径且经历相同网络条件的TCP流将实现在合理时间尺度上测量的不小于RTP流实现的平均吞吐量,则分组丢失被认为是可接受的。可以通过实现拥塞控制机制来适应传输速率(或为分层多播会话预订的层的数目),或者如果丢失率高得不可接受,则通过安排接收机离开会话来满足该条件。
如本节所述,IANA注册了四种新的媒体子类型。此注册使用注册模板[3]和RFC 3555[4]完成。
类型名称:音频
子类型名称:ulpfec
所需参数:
速率:RTP时间戳速率,用于标记FEC数据包在单独流中的传输时间。在将其作为冗余数据发送到另一个流的情况下,速率应与用于保护的主要编码相同。在单独的流中使用时,速率应大于1000 Hz,以便为RTCP操作提供足够的分辨率。所选速率可以是高于1000 Hz的任何值,但建议与此流保护的媒体速率相匹配。
可选参数:
onelevelonly:指定是否只使用一级FEC保护。允许值为0和1。如果信号为1,则流中只能使用一级FEC保护。如果用信号表示为0,则可以使用多个级别的FEC保护。如果省略,则默认值为0。
编码注意事项:这种格式是有框架的(见模板文件[3]的第4.8节),包含二进制数据。
安全注意事项:这些媒体类型注册的安全注意事项与有效负载的安全注意事项相同,详见RFC 5109。
互操作性注意事项:无
发布规范:RFC 5109
使用这种媒体类型的应用程序:通过向媒体流发送额外数据来提高丢失恢复能力的多媒体应用程序。
附加信息:无
联系人和电子邮件地址以获取更多信息: Adam Li [email protected]
IETF音频/视频传输工作组
预期用途:普通
使用限制:此媒体类型取决于RTP帧,因此仅定义为通过RTP传输[1]。其他帧协议中的传输不应定义为RTP的健壮性机制。
Author:
Adam Li [email protected]
Change controller:
IETF Audio/Video Transport Working Group delegated from the IESG.
类型名称:视频
子类型名称:ulpfec
所需参数:
速率:RTP时间戳速率,用于标记FEC数据包在单独流中的传输时间。在将其作为冗余数据发送到另一个流的情况下,速率应与用于保护的主要编码相同。当在单独的流中使用时,速率应大于1000 Hz,以便为RTCP操作提供足够的分辨率。所选速率可以是高于1000 Hz的任何值,但建议与此流保护的媒体速率相匹配。
可选参数:
onelevelonly:指定是否只使用一级FEC保护。允许值为0和1。如果信号为1,则流中只能使用一级FEC保护。如果用信号表示0,则可以使用多个级别的FEC保护。如果省略,则默认值为0。
编码注意事项:这种格式是有框架的(见模板文件[3]的第4.8节),包含二进制数据。
安全注意事项:这些媒体类型注册的安全注意事项与有效负载的安全注意事项相同,详见RFC 5109。
互操作性注意事项:无
发布规范:RFC 5109
使用这种媒体类型的应用程序:通过向媒体流发送额外数据来提高丢失恢复能力的多媒体应用程序。
附加信息:无
联系人和电子邮件地址以获取更多信息: Adam Li [email protected]
IETF音频/视频传输工作组
预期用途:普通
使用限制:此媒体类型取决于RTP帧,因此仅定义为通过RTP传输[1]。其他帧协议中的传输不应定义为RTP的健壮性机制。
Author:
Adam Li [email protected]
Change controller: IETF Audio/Video Transport Working Group
delegated from the IESG.
类型名称:文本
子类型名称:ulpfec
所需参数:
速率:RTP时间戳速率,用于标记FEC数据包在单独流中的传输时间。在将其作为冗余数据发送到另一个流的情况下,速率应与用于保护的主要编码相同。当在单独的流中使用时,速率应大于1000 Hz,以便为RTCP操作提供足够的分辨率。所选速率可以是高于1000 Hz的任何值,但建议与此流保护的媒体速率相匹配。
可选参数:
onelevelonly:指定是否只使用一级FEC保护。允许值为0和1。如果信号为1,则流中只能使用一级FEC保护。如果用信号表示为0,则可以使用多个级别的FEC保护。如果省略,则默认值为0。
编码注意事项:这种格式是有框架的(见模板文件[3]的第4.8节),包含二进制数据。
安全注意事项:这些媒体类型注册的安全注意事项与有效负载的安全注意事项相同,详见RFC 5109。
互操作性注意事项:无
发布规范:RFC 5109
使用这种媒体类型的应用程序:通过向媒体流发送额外数据来提高丢失恢复能力的多媒体应用程序。
附加信息:无
联系人和电子邮件地址以获取更多信息: Adam Li [email protected]
IETF音频/视频传输工作组
预期用途:普通
使用限制:此媒体类型取决于RTP帧,因此仅定义为通过RTP传输[1]。其他帧协议中的传输不应定义为RTP的健壮性机制。
Author:
Adam Li [email protected]
Change controller: IETF Audio/Video Transport Working Group
delegated from the IESG.
类型名称:应用程序
子类型名称:ulpfec
所需参数:
速率:RTP时间戳速率,用于标记FEC数据包在单独流中的传输时间。在将其作为冗余数据发送到另一个流的情况下,速率应该与用于保护的主要编码相同。当在单独的流中使用时,速率应该大于1000 Hz,以便为RTCP操作提供足够的分辨率。所选速率可以是高于1000 Hz的任何值,但建议与此流保护的媒体速率相匹配。
可选参数:
onelevelonly:指定是否只使用一级FEC保护。允许值为0和1。如果信号为1,则流中只能使用一级FEC保护。如果用信号表示为0,则可以使用多个级别的FEC保护。如果省略,则默认值为0。
编码注意事项:这种格式是有框架的(见模板文件[3]的第4.8节),包含二进制数据。
安全注意事项:这些媒体类型注册的安全注意事项与有效负载的安全注意事项相同,详见RFC 5109。
互操作性注意事项:无
发布规范:RFC 5109
使用这种媒体类型的应用程序:通过向媒体流发送额外数据来提高丢失恢复能力的多媒体应用程序。
附加信息:无
联系人和电子邮件地址以获取更多信息: Adam Li [email protected]
IETF音频/视频传输工作组
预期用途:普通
使用限制:此媒体类型取决于RTP帧,因此仅定义为通过RTP传输[1]。其他帧协议中的传输不应定义为RTP的健壮性机制。
Author:
Adam Li [email protected]
Change controller: IETF Audio/Video Transport Working Group
delegated from the IESG.
FEC包可以与受保护的有效载荷一起主要以两种方式之一发送到接收器:作为单独的流,或者作为冗余编码在同一流中。必须在带外指示配置选项。本节还描述了如何使用RFC2327[8]中指定的会话描述协议(SDP)来实现这一点。
当FEC分组在单独的流中发送时,必须传送若干信息:
FEC没有静态有效负载类型分配,因此必须使用动态有效负载类型号。FEC流的SSRC必须设置为受保护有效负载流的SSRC。FEC流与其对应流的关联通过SDP[5]中的行分组和FEC语义[6]或其他外部手段来完成。
遵循RFC 3550[1]第5.2节中讨论的原则,FEC流及其相关有效负载流的复用通常由目的地传输地址(网络地址和端口号)提供,对于每个RTP会话而言,目的地传输地址是不同的。在一个RTP会话中将FEC与有效负载一起发送,并且仅通过SSRC或有效负载类型进行复用,排除了:(1) 对有效载荷和FEC保护数据使用不同的网络路径或网络资源分配(2) 如果需要,接收媒体的子集,特别是对于不理解FEC的主机;以及(3)对不同媒体使用不同过程的接收器实现。此外,将FEC与有效负载数据流复用将影响原始有效负载流的时序和序列号空间,这通常是不希望的。因此,FEC流和有效负载流应该通过两个独立的RTP会话发送,并且应该避免将它们按有效负载类型复用到单个RTP会话中。此外,FEC和有效负载不能被SSRC复用到单个RTP会话中,因为它们总是具有相同的SSRC。
与任何媒体流一样,FEC流的端口号和有效负载类型号在SDP中以m线传输。FEC没有静态有效负载类型分配,因此必须使用动态有效负载类型号。与数字的绑定由rtpmap属性表示。此绑定中使用的名称是“ulpfec”。FEC流所在的地址在其对应的c行中传送。
FEC流和它所保护的有效负载流之间的关联关系通过使用FEC语义(RFC 4756)[6]的SDP(RFC 3388)[5]中的媒体线分组来传送。FEC流和受保护的有效负载流形成FEC组。
以下是多播会话中FEC应用的示例SDP:
此SDP中存在两个a=组行表示存在两个FEC组。如“a=group:fec12”行所示,第一FEC组由流1(使用PCM的音频流[14])和流2(保护FEC流)组成。FEC流被发送到同一个多播组,并且与音频具有相同的生存时间(TTL),但是在一个更高的端口号2上。如“a=group:fec34”行所示,第二FEC组由流3(视频流)和流4(保护FEC流)组成。FEC流被发送到不同的多播地址,但是具有与有效负载视频流相同的端口号(30004)。
当FEC流以冗余编码格式作为辅助编解码器发送时,必须通过SDP发出信号。为此,使用RFC 2198[7]中定义的过程来表示冗余编码的使用。FEC有效负载类型以与任何其他次要编解码器相同的方式指示。FEC必须只保护主编解码器,FEC引擎的负载来自由主编解码器数据创建的虚拟RTP包。虚拟RTP分组可以非常容易地从RFC 2198分组转换为简单的RTP分组,执行步骤如下:(1)移除所有附加报头和冗余编码数据,以及(2)用主编解码器的有效载荷类型替换RTP报头中的有效载荷类型。
注:在RFC 2198指定的冗余编码的有效载荷格式中,只要在RED包中携带主编码,就丢失标记位(M字段)。因此,无论是否使用FEC,都无法恢复标记位(M字段)。
因为FEC数据(包括ULP报头)在与受保护净荷相同的分组中发送,所以FEC数据通过捆绑在相同流中与受保护净荷相关联。
当FEC流以冗余编码格式作为辅助编解码器发送时,这可以通过SDP发出信号。为此,使用RFC 2198[7]中定义的过程来表示冗余编码的使用。FEC有效负载类型以与任何其他次要编解码器相同的方式指示。rtpmap属性必须用于指示FEC包的动态有效负载类型号。FEC必须只保护主编解码器。
例如:
m=audio 12345 RTP/AVP 121 0 5 100
a=rtpmap:121 red/8000/1
a=rtpmap:100 ulpfec/8000
a=fmtp:121 0/5/100
该SDP指示存在单个音频流,其可以由PCM(媒体格式0)、DVI(媒体格式5)、冗余编码(由媒体格式121指示,其通过rtpmap属性绑定到red)或FEC(媒体格式100,其通过rtpmap属性绑定到ulpfec)组成。尽管FEC格式被指定为该流的可能编码,但是FEC不能为该流自身发送。仅当根据RFC 2198必须在此列出非主要编解码器时,才需要在m行中显示它。fmtp属性表示可以使用冗余编码格式,DVI作为二级编码,FEC作为三级编码。
当SDP用于提供/应答(offer / answer)[15]交换时,需要考虑一些因素。
“onelevelonly”参数是声明性的。对于声明为sendonly的流,该值指示是否只发送一级FEC。对于声明为recvonly或sendrecv的流,该值指示接收方接受接收的内容。
当FEC作为一个单独的流发送,并在SDP(RFC 3388)[5]中使用FEC语义(RFC 4756)[6]通过媒体线分组发信号时,提供方必须同时实现RFC 3388和RFC 4756。RFC 3388和RFC 4756中的提供/应答规则应遵循以下附加考虑。对于具有FEC的所有要约,应答者可以通过将端口设置为0来拒绝单独的FEC会话,并移除将该FEC会话与受保护的RTP会话分组的“a=group”属性。如果应答者接受FEC的使用,那么应答者只需通过在应答中包含相同的分组来接受FEC RTP会话和要约中的分组。注意,拒绝FEC RTP会话并不妨碍在没有FEC的情况下接受和使用媒体会话。
当FEC流以冗余编码格式(RFC 2198)[7]作为辅助编解码器发送时,供应方可以按照第14.2节的规定指示FEC流。应答者可以通过移除FEC流的有效负载类型来拒绝FEC流。要接受FEC的使用,应答者必须在应答中包含FEC有效负载类型。注意,在冗余有效负载格式[7]与FEC一起用作唯一的辅助编解码器的情况下,当FEC流被拒绝时,冗余编码有效负载类型也应被移除。
本文描述了一种用于前向纠错的通用协议,该协议支持多种短块奇偶校验FEC算法,如简单奇偶校验码和交织奇偶校验码。该方案仅限于在48个包的距离上交织奇偶校验码。此FEC算法与不支持FEC的主机完全兼容。由于媒体有效载荷没有改变并且保护作为附加信息发送,因此不知道本文档中指定的通用FEC的接收器可以简单地忽略附加FEC信息并处理主媒体有效载荷。这种互操作性对于与现有主机的兼容性尤其重要,而且在许多不同主机需要同时相互通信的场景中,例如在多播期间。
本文档中规定的通用FEC算法也是一种通用保护算法,具有以下特点:(1)它与被保护媒体的性质无关,无论该媒体是音频、视频还是其他媒体(2) 它足够灵活,可以支持多种FEC机制和设置(3) 它的自适应设计使得FEC参数可以很容易地修改,而不需要借助带外信令;以及(4)它支持许多不同的机制来传输FEC分组。
这里指定的FEC还为用户提供了不等的错误保护能力。其他一些算法也可以通过其他方式提供不等的错误保护能力。例如,AVT工作组在“用于渐进式多媒体流的擦除弹性传输的RTP有效负载格式”中提出了一种不等擦除保护(UXP)方案。UXP方案通过将要保护的有效负载流与使用Reed-Solomon操作获得的额外冗余信息交织,对媒体有效负载应用不等错误保护。
通过改变受保护媒体负载的结构,UXP方案牺牲了与不支持UXP的终端的向后兼容性。这使得在需要向后兼容性时应用UXP更加困难。然而,在ULP的情况下,媒体有效载荷保持不变,并且始终可以由终端使用。如果接收终端不支持ULP,则可以忽略额外的保护。
同时,也因为在UXP中媒体有效负载的结构被改变,UXP提供了独立于原始媒体有效负载结构和应用的保护而改变分组大小的独特能力,并且仅受协议开销约束。当需要在传输级别更改媒体的数据包大小时,此属性非常有用。
由于在UXP中使用交织,在编码和解码端都会引入延迟。对于UXP,传输块中的所有数据需要在编码开始之前到达,并且在传输块可以被解码之前必须接收到合理数量的分组。ULP方案在编码端引入了较小的延迟。在解码端,可以立即传送正确接收的数据包。只有在发生数据包丢失时,才会在ULP中引入延迟
由于UXP是一种交织方案,在受UXP保护的数据中发生的不可恢复的错误通常会导致有效负载流中出现许多损坏的漏洞。另一方面,在ULP中,由于位流中的数据包丢失而导致的不可恢复的错误通常在数据包的末尾出现为连续的丢失片段。取决于媒体有效负载流的编码,许多应用程序可能会发现,与具有多个损坏的孔的包相比,从仅在末端丢失连续片段的包中解析和提取数据更容易,特别是当孔与独立可解码的片段边界不一致时。
ULP使用的异或(XOR)奇偶校验操作比Reed-Solomon代码所需的更复杂的操作更简单、更快。这使得ULP更适合于计算成本受限的应用。
如上所述,ULP和UXP方案都对RTP媒体流应用不同的错误保护,但是每种方案都使用不同的技术。两种方案都有各自独特的特点,每种方案都可以应用于不同需求的场景。
[1] Schulzrinne, H., Casner, S., Frederick, R., and V. Jacobson,
“RTP: A Transport Protocol for Real-Time Applications”, STD 64,
RFC 3550, July 2003.
[2] Bradner, S., “Key words for use in RFCs to Indicate Requirement
Levels”, BCP 14, RFC 2119, March 1997.
[3] Freed, N. and J. Klensin, “Media Type Specifications and
Registration Procedures”, BCP 13, RFC 4288, December 2005.
[4] Casner, S., “Media Type Registration of RTP Payload Formats”,
RFC 4855, February 2007.
[5] Camarillo, G., Eriksson, G., Holler, J., and H. Schulzrinne,
“Grouping of Media Lines in the Session Description Protocol
(SDP)”, RFC 3388, December 2002.
[6] Li, A., “Forward Error Correction Grouping Semantics in Session
Description Protocol”, RFC 4756, November 2006.
[7] Perkins, C., Kouvelas, I., Hodson, O., Hardman, V., Handley, M.,
Bolot, J., Vega-Garcia, A., and S. Fosse-Parisis, “RTP Payload
for Redundant Audio Data”, RFC 2198, September 1997.
[8] Handley, M., Jacobson, V., and C. Perkins, “SDP: Session
Description Protocol”, RFC 4566, July 2006.
[9] Rosenberg, J. and H. Schulzrinne, “An RTP Payload Format for
Generic Forward Error Correction”, RFC 2733, December 1999.
[10] Perkins, C. and O. Hodson, “Options for Repair of Streaming
Media”, RFC 2354, June 1998.
[11] Rosenberg, J. and H. Schulzrinne, “Registration of parityfec
MIME types”, RFC 3009, November 2000.
[12] Luby, M., Vicisano, L., Gemmell, J., Rizzo, L., Handley, M., and
J. Crowcroft, “Forward Error Correction (FEC) Building Block”,
RFC 3452, December 2002.
[13] Baugher, M., McGrew, D., Naslund, M., Carrara, E., and K.
Norrman, “The Secure Real-time Transport Protocol (SRTP)”, RFC
3711, March 2004.
[14] Schulzrinne, H. and S. Casner, “RTP Profile for Audio and Video
Conferences with Minimal Control”, STD 65, RFC 3551, July 2003.
[15] Rosenberg, J. and H. Schulzrinne, “An Offer/Answer Model with
Session Description Protocol (SDP)”, RFC 3264, June 2002.