本文描述了用rs码在rtp传输中实现fec的方法
概念:
媒体包: 荷载为视音频数据的包。
Fec包: 荷载为校验数据的包。(没有丢包的情况下可以忽略)。
1,纠错算法采用reed_solomon(RS)纠错算法,用开源的jerasure库实现。
2,rtp媒体包长度规定为
1408 bytes(包括rtp固定头和扩展头和数据),因为
RS
算法对
数据块有整除方面的要求,这个值是RS算法内部计算所得,这个值也可以是960 1024,
1088 ,1152 ,1216,1344,1408,1472 ……。(64的倍数=w*sizeof(long))(w=8)
3,所有rtp包都增加扩展头,扩展头大小为4 bytes,扩展头的前2个字节里面记录了实际数据的长度。后2个字节为0,
因为
RS算法编码的时候要求数据块大小都是一致的,必要的是会填充0。
4,10个媒体包生成2个Fec包。
5 ,Fec包的大小是
1408
+12+4+4,比媒体包要大20个字节,因为fec包荷载的数据是 对媒体包整包的校验。
6,Fec包的payload type为127,这样对于不识别的包一般会丢掉,不影响其他播放器 播放流。Fec包rtp头的时间戳是最后一个保护包的时间戳,Fec包的rtp头的包序号 递增,其他rtp头域和被保护的包相同,Fec包的荷载包括Fec头和Fec数据组成。Fec 头为4个字节,前2个字节 为 SN基数,表示保护的rtp包的最小序列号。后1 个字节为mask,表示保护了多少个一般为10 再后面一个字节表示本组的第几个fec包,
7,图示
媒体包格式:
RTP固定头12pytes |
扩展头4bytes |
媒体数据( |
Fec包格式:
RTP固定头12pytes |
扩展头4bytes |
FEC头4bytes |
FEC校验数据,长度等于媒体包总长度( |
8,发包方法:
发包的时候本地要有10个包的缓存不要释放,根据这个10个包计算2个校验包后再释放内存。如果媒体包小于1408则填充0,后再计算校验值,但是发送的时候不用发送后面填充的0,把10个包发送完毕后接着发送这个2个校验包。
9,接收方法:
收rtp包的时候保持10个包的缓存不要释放,等收到Fec包的时候,根据rtp头的序号判断这10个包是否连续,如果不连续,则根据后面到来的fec包试图恢复缺失的包。如果收到的媒体包都是连续的,则丢弃fec包。
说明:
该方案可以保证没有校验功能的播放器也可以播放rtp流。
该方案参考了https://blog.csdn.net/killmice/article/details/8522436
基于Budge和Mackenzie于1997年提交的一个早期FEC草案