需要解决的问题
1、FEC Level Header for FEC Packets中的Protection Length 字段的大小是如何确定的?RFC5109中10.2节的例子中没有明确给出该字段值的计算方式。
2、RFC5109中10.3节的东西,还需要仔细阅读,因为WebRTC中,就是采用该方式传输的数据包。
3、ULP FEC的具体实现,需要阅读WebRTC源码
FEC总结比较好的文章
1、FEC 5109协议的翻译
https://blog.csdn.net/viyana/article/details/119083236#_1
2、FEC 5109的关键知识总结
https://www.pianshen.com/article/94831094807/
3、ULP FEC 在WeBRTC中的实现
深度分析WebRTC源码,源码更新时间为2019年7月25日,本节总结了ULPFEC在WebRTC中的实现,以及应用;下面以Video为例,从FEC掩码构建,FEC报文构建两个方面分析ULPFEC在WebRTC中的实现。
3.1 ULPFEC报文构建流程
在捕获到数据后,通过RTPSenderVideo::SendVideo发送数据。如果当前会话配置了red和ulpfec,则调用RTPSenderVideo::SendVideoPacketAsRedMaybeWithUlpfec,该函数主要完成五件事:
1)调用BuildRedPayload函数,将发送的数据生成RED包;
2)UlpfecGenerator::AddRtpPacketAndGenerateFec,使用媒体数据生成FEC包;
3)UlpfecGenerator::GetUlpfecPacketsAsRed,获取生成的FEC包;
4)LogAndSendToNetwork(red_packet),发送RED媒体数据包
5)LogAndSendToNetwork(std::move(rtp_packet)),发送FEC包
步骤2)中,会调用ForwardErrorCorrection::EncodeFec,其中该函数,主要完成了五件事:
a)ForwardErrorCorrection::NumFecPackets,通过保护因子计算FEC包个数
b)internal::GeneratePacketMasks,生成掩码,packet_masks_。
c)ForwardErrorCorrection::InsertZerosInPacketMasks,如果发生了丢包,调整packet_masks_
d)ForwardErrorCorrection::GenerateFecPayloads,生成FEC数据包
e)ForwardErrorCorrection::FinalizeFecHeaders,修正FEC头部
至此,FEC包的构造过程分析完毕。需要注意的是,虽然WebRTC中实现ULPFEC,但是使用的任然是均等保护,没用使用ULPFEC;另外,在WebRTC内部,保护RTP头部的FEC头部称之为Level 0,而保护RTP负载的的FEC Level部分称之为Level 1,这里和RFC5109中的定义略有不同,需要注意。
3.2 ULPFEC掩码表和掩码
FEC Level Header里面的mask
根据RFC5109定义,一个媒体数据包可以被多个FEC包保护,一个FEC包可以多保护多个媒体数据包。
假设m个媒体数据包需要n个FEC数据包保护,则可以定义一个如下图所示的二维的m * n零一矩阵来描述媒体数据包在fec包中的保护分布情况:
1)矩阵中元素m[i, j]置1表示第j个媒体数据包需要第i个FEC包保护。
2)从行角度来看,第i行元素表示第i个FEC包保护的媒体数据包的集合;
3)从列角度讲,第j列元素表示保护第j个媒体数据包的FEC包的集合。
由于该矩阵是零一矩阵,因此在存储上可以采用掩码来存储。这个掩码也就是FEC Level Header中所定义的mask掩码。
那么掩码中的0、1如何分布?现实世界中网络丢包分为随机丢包、突发丢包两种情况,FEC包需要能够针对这两种情况对媒体数据包进行保护。WebRTC预先构造两个掩码表kPacketMaskRandomTbl和kPacketMaskBurstyTbl,以模拟在随机情况和突发情况下媒体数据包在FEC包中的保护分配情况。
假设在随机丢包场景下,对于m * n的情况,我们只需要从kPacketMaskRandomTbl[m][n]就可以获取FEC包所需要的全部掩码,然后该掩码为基础,构造FEC数据包。注意这里的m指的是要保护的媒体包的个数,n指的是FEC包的个数。(可能是外国人的习惯问题,喜欢列在前,行在后面)
在这里需要注意:1、当保护的媒体包个数小于等于12时,使用WebRTC中定义的两个掩码表来获取掩码,如果保护的媒体包大于12时,需要通过代码计算掩码;
3.3 ULPFEC的实现
里面还保留了一套UnequalProtectionMask接口,这套接口里面有三种掩码模式:NoOverlap、Overlap、BiasFirstPacket
非对称保护思想是,FEC包对媒体数据包集合中的不同数据包实施不同的保护力度。某些场景下,一帧视频数据编码后生成的一系列RTP数据包,重要性不一样,比如开始几个RTP包包含PPS、SPS等信息,重要性会大一些。因此,在构造FEC包的掩码时,有均匀保护和非均匀保护两种策略。
均匀保护:所有RTP包重要性一样,FEC包对他们进行平等均匀保护。对于m * n,FEC包使用掩码MaskRandomTbl[m][n]。
非均匀保护:RTP包集合分重要数据包集合S1、普通数据包集合S2,分配较多个FEC包保护S1,较少个FEC包保护S2。WebRTC定义三种模式针对实现非均匀保护:
1)kModeNoOverlap:非叠加保护,保护S1的掩码和S2的掩码相互分离。
2)kModeOverlap:叠加保护,保护S1的掩码和S2的掩码叠加在一起。
3)kModeBiasFirstPacket:在均匀保护的基础上,所有FEC包都保护第一个包。
假设保护场景为(m, n),其中重要数据包为前k个,分配给重要数据包的FEC包个数为t,掩码表为mask_table。则三种场景下最终掩码的确定如下:
1)kModeNoOverlap:mask_table[k][t]和mask_table[m-k][n-t]的移位组合。
2)kModeOverlap: mask_table[k][t]和mask_table[m][n-t]的拼接。
3)kModeBiasFirstPacket:mask_table[m][n],再第一列全部置1。
不过目前webrtc的编码器使用单Slice编码,视频RTP报文重要程度无大差别,所以就没有使用这个功能。
————————————————
版权声明:本文为CSDN博主「CrystalShaw」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/CrystalShaw/article/details/102950002