WebRTC中的前向纠错编码 - Red Packet

本文深入解析WebRTC中FEC(前向纠错编码)的工作原理及其在网络丢包情况下的作用。通过介绍RedPacket的生成和结构,阐述FEC如何减少重传次数、降低延迟并改善视频质量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WebRTC 的FEC(前向纠错编码) 是其QoS的重要组成部分, 用于网络丢包的时候恢复原始数据包, 减少重传次数, 减少延时, 改善视频质量. 它是RFC 5109标准的实现. 下文, 我们将深入剖析其原理.

Redundant Coding

要理解WebRTC中的FEC, 首先需要先了解Red Packet. 所谓Red Packet, 就是Redundant Coding 产生的包. 其定义非常简单, 下面来看Block Header的格式:

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F| block PT | timestamp offset | block length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

其定义如下: 
F: 1 bit, 1 表示后面跟着其他的Block Header, 0 表示这个Block Header就是最后一个. 
Block PT: 7 bits, 是这个block payload的 payload type 
Timestamp Offset: 14 bits, 无符号数, 是RTP 的Timestamp 到这个Data block的时间偏移 
Block Lenth: 10 bits, 是Data Block 长度.

另一种Primary Data Header, 之需要1byte

|F| Block PT|

用来描述最后的一个Data Block, 其TimeStamp 就是RTP Header的Timestap. 
WebRTC的Red Packet, 编码时, 用一个rtp packet 产生 1个red packet, 所以使用了 Primary Data Header来描述的

如何协商 数据和Rad Channel 的绑定关系呢?

m=audio 12345 RTP/AVP 121 0 5
a=rtpmap:121 red/8000/1

这段SDP 表示, RTP 音频 Session, 它的Payload Type 是121, 0, 5, Codec Red payload type 是121.

下面来看一个例子:

0 12 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC=0 |M| PT | sequence number of primary |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp of primary encoding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1| block PT=7 | timestamp offset | block length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0| block PT=5 | |
+-+-+-+-+-+-+-+-+ +
|                                     |
+ LPC encoded redundant data (PT=7) +
| (14 bytes) |
+ +---------------+
| | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
+ +
| |
+ +
| |
+ +
| DVI4 encoded primary data (PT=5) |
+ (84 bytes, not to scale) +
/ /
+ +
| |
+ +
| |
+ +---------------+
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

WebRTC中的实现:

//  生成Rad Packet 
RedPacket* ProducerFec::BuildRedPacket(const uint8_t* data_buffer,
                                       size_t payload_length,
                                       size_t rtp_header_length,
                                       int red_pl_type) {
  RedPacket* red_packet = new RedPacket(
      payload_length + kREDForFECHeaderLength + rtp_header_length);
  int pl_type = data_buffer[1] & 0x7f;
  red_packet->CreateHeader(data_buffer, rtp_header_length,
                           red_pl_type, pl_type);
  red_packet->AssignPayload(data_buffer + rtp_header_length, payload_length);
  return red_packet;
}
// 生成RedPacket Header
void RedPacket::CreateHeader(const uint8_t* rtp_header, size_t header_length,int red_pl_type, int pl_type) {
   memcpy(data_, rtp_header, header_length);
  // Replace payload type.
  data_[1] &= 0x80;
  data_[1] += red_pl_type;
  // Add RED header
  // f-bit always 0
  data_[header_length] = static_cast(pl_type);
  header_length_ = header_length + kREDForFECHeaderLength;
}
// 填上Payload
void RedPacket::AssignPayload(const uint8_t* payload, size_t length) {
   memcpy(data_ + header_length_, payload, length);
}

Reference: 
1. rfc2198 - RTP Payload for Redundant Audio Data 
2. rfc5109 - RTP Payload Format for Generic Forward Error Correction

### WebRTC中的NACK机制及其实现细节 在网络状况不佳的情况下,为了提高媒体传输的质量和可靠性,WebRTC采用了多种技术手段。其中一种重要的纠错方法是负确认(Negative Acknowledgement, NACK)。当接收端检测到丢失的数据包时,会向发送方请求重新发送这些数据包。 #### 工作原理 在实时通信过程中,如果接收者未能接收到某些RTP数据包,则会在本地缓存中记录下缺失序列号的信息,并通过RTCP反馈报文告知发送者哪些具体的包已经丢失[^1]。随后,发送节点依据此信息决定是否以及何时重发相应的RTP负载。 这种基于丢包恢复的技术特别适用于具有突发性损失特性的网络环境,因为它允许快速响应并修正短期内的错误情况而不必等待整个流结束之后再处理。对于视频通话而言,及时补回少量错过的图像帧可以显著改善用户体验;而对于语音交流来说,即使是在较差连接条件下也能保持较好的音质清晰度[^3]。 #### 实现要点 - **延迟控制**:为了避免过度频繁地触发重传操作而导致额外开销甚至恶化拥塞状态,通常会对NACK消息的应用设置一定的阈值条件,比如仅针对连续丢失超过一定数量以上的包才发起请求。 - **优先级管理**:考虑到不同类型的多媒体内容可能有着不同的重要性和紧迫程度,在实际部署中往往还需要考虑如何合理分配有限资源给最需要被修复的部分。例如,关键帧相比于普通预测编码单元更值得优先保障其完整性。 - **与其他机制配合使用**:除了单独依靠NACK之外,还可以将其同纠错(FEC)等其他鲁棒化措施结合起来应用,从而形成更为全面有效的QoS策略体系。特别是新版WebRTC已经开始引入RED方式作为增强型音频保护方案的一部分。 ```python def nack_handler(missing_packets): """ 处理接收到的NACK指令,准备并发送必要的重传数据包 参数: missing_packets (list): 缺失的数据包包ID列表 返回: None """ for packet_id in missing_packets: # 查找对应的原始数据包副本 original_packet = find_original(packet_id) if original_packet is not None: send_retransmission(original_packet) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值