1. fec参数定义
struct FecProtectionParams {
//fec冗余度 ,(fec_rate/255 * n) n个媒体包生成的fec包数量
int fec_rate;
//支持的最大帧数量,当达到这么多数据帧的情况下必须生成一个fec包 ,这个参数可以不用考虑就是一个优化项
int max_fec_frames;
// 针对随机丢包和突发丢包的不同生成策略表,就是那一个fec包保护那一个媒体包
FecMaskType fec_mask_type;
};
用这参数配置fec编码器,fec就会生成相应冗余度的fec包
2.fec参数(冗余度)动态更改, (用于填充 FecProtectionParams. fec_rate)
基于当前码率,丢包率
// Table for Protection factor (code rate) of delta frames, for the XOR FEC.
// Input is the packet loss and an effective rate (bits/frame).
// Output is array kFecRateTable[k], where k = rate_i*129 + loss_j;
// loss_j = 0,1,..128, and rate_i varies over some range.
// TODO(brandtr): Consider replacing this big static table with a closed-form
// expression instead.
static const int kFecRateTableSize = 6450;
static const unsigned char kFecRateTable[kFecRateTableSize] = {
//码率区间1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
39, 39, 39, 39, 39, 39, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51,
//码率区间2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
30, 30, 30, 56, 56, 56, 56, 56, 56, 56, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
78, 78, 78, 78, 78, 78, 78, 78, 78,
...
kFecRateTable这相当一个二维表, 当前的码率计算第一维的索引。丢包率计算第二维索引。
就是: kFecRateTable[rate][lost],丢包率支持的最大值=128.
例如上面的码率区间2,由rate计算的。
lost=0, 冗余度=0;
lost=18, 冗余度=8;
lost=128,冗余度=78;
3. fec Mask值的获取。(FecProtectionParams.fec_mask_type 根据这个类型获取的).
webrtc中,根据上一步的 FecProtectionParams. fec_rate计算出来的 M个媒体包使用N(M*FecProtectionParams. fec_rate/255)个Fec包保护.
而这个 N个Fec包如何保护M个媒体包,这就用到了mask表 PacketMaskTable类封装的mask的获取。
下面看一下随机丢包的保护策略。 由于ulpfec一次最多支持48个媒体包,所以表定义为48.
const uint8_t** kPacketMaskRandomTbl[48] = {
kPacketMaskRandom1,
kPacketMaskRandom2,
kPacketMaskRandom3,
kPacketMaskRandom4,
kPacketMaskRandom5,
kPacketMaskRandom6,
kPacketMaskRandom7,
媒体包数量M=1 , 使用kPacketMaskRandom1保护策略。
媒体包数量M=2 , 使用kPacketMaskRandom2保护策略。
媒体包数量M=3 , 使用kPacketMaskRandom3保护策略。
const uint8_t* kPacketMaskRandom1[1] = {
kMaskRandom1_1
};
const uint8_t* kPacketMaskRandom2[2] = {
kMaskRandom2_1,
kMaskRandom2_2
};
const uint8_t* kPacketMaskRandom3[3] = {
kMaskRandom3_1,
kMaskRandom3_2,
kMaskRandom3_3
};
kMaskRandom3——1: 3个媒体报由1个FEC包保护 (M=3,N=1)
kMaskRandom3——2: (M=3,N=2)
kMaskRandom3——3: (M=3,N=3)
const uint8_t kMaskRandom3_2[4] = {
0xc0, 0x00,
0xa0, 0x00
};
0xc0 : 1100 0000 第一FEC包保护 1,2媒体包
0xa0 : 1010 0000 第二FEC包保护 1,3媒体包