WebRTC服务质量(01)- Qos概述
WebRTC服务质量(02)- RTP协议
WebRTC服务质量(03)- RTCP协议
WebRTC服务质量(04)- 重传机制(01) RTX NACK概述
WebRTC服务质量(05)- 重传机制(02) NACK判断丢包
WebRTC服务质量(06)- 重传机制(03) NACK找到真正的丢包
WebRTC服务质量(07)- 重传机制(04) 接收NACK消息
WebRTC服务质量(08)- 重传机制(05) RTX机制
WebRTC服务质量(09)- Pacer机制(01) 流程概述
WebRTC服务质量(10)- Pacer机制(02) RoundRobinPacketQueue
WebRTC服务质量(11)- Pacer机制(03) IntervalBudget
WebRTC服务质量(12)- Pacer机制(04) 向Pacer中插入数据
一、前言:
RoundRobinPacketQueue
是Pacer模块当中一个非常重要的循环队列模块,主要目的是在多流场景中,根据每个流的 优先级 以及流内的 RTP 包的 入队顺序、类型 和其他因素,动态决定数据包的发送顺序。
二、类关系图:
2.1、类图:
关键部分加了注释,便于理解:
- 多流支持: 每个流按 SSRC(Synchronization Source Identifier,同步信源标识符)进行区分,每个流维护独立的优先级队列。
- 多级优先级调度: 不同流间按优先级调度(基于
StreamPrioKey
),单个流内的包按严格的队列顺序管理。 - 静态与动态属性结合: 例如,属性包括每个包的优先级(
priority
)、入队时间(enqueue_time
)、重传标志、带宽开销等。 - 分组调度: 使用轮询(Round-Robin)机制,从不同流根据流的权重和优先级选取包发送,提高音频、视频和反馈等多种类型数据的实时性。
2.2、重要成员关系:
- stream_priorities当中存放StreamPrioKey和ssrc对应关系;
- streams当中存放ssrc和Stream的对应关系;
- 这样就建立了StreamPrioKey和Stream之间的关系;
- 反过来,也可以通过Stream当中的priority_it找到stream_priorities当中的某一项;
小结下:重要成员变量的功能
成员变量 | 功能 |
---|---|
streams_ |
保存所有流,键是流的 ssrc ,每条流存有独立队列和优先级信息。 |
stream_priorities_ |
将所有流按照 StreamPrioKey 排列,用于实现流间优先级调度。 |
enqueue_times_ |
一个多重集合,保存所有包的入队时间,便于快速找到最早入队的包时间。 |
size_packets_ 和 size_ |
分别记录队列中包的个数和总字节数,动态调整。 |
transport_overhead_per_packet_ |
计算包传输的额外开销(如包头)。 |
time_last_updated_ |
用于统计队列的更新时间,辅助计算入队和等待时间等。 |
三、重要函数:
3.1、Push
Push
会根据包的优先级、流的权重、总队列大小,以及包的类型等,将包插入到对应的流(Stream
)队列,并更新其他与队列状态关联的元数据。总体思路如下:
处理一个新包时:
- 确定该包所属的流,如果不存在该流,则创建一个
Stream
对象。 - 将包包装成为
QueuedPacket
并插入到流的优先级队列。 - 更新流的优先级键
StreamPrioKey
,并在stream_priorities_
中重新排序。 - 更新队列元数据(如队列包大小、队列时间等)。
void RoundRobinPacketQueue::Push(int priority,
Timestamp enqueue_time,
uint64_t enqueue_order,
std::unique_ptr<RtpPacketToSend> packet) {
RTC_DCHECK(packet->packet_type().has_value());
if (size_packets_ == 0) {
// Single packet fast-path.
single_packet_queue_.emplace(
QueuedPacket(priority, enqueue_time, enqueue_order,
enqueue_times_.end(), std::move(packet)