WebRTC服务质量(12)- Pacer机制(04) 向Pacer中插入数据

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中插入数据

一、前言:

我们之前讲述了Pacer的运行机制,以及如何在发送时候控制码率,本节我们看下如何往Pacer里头填数据。

二、调用栈:

我们先看下调用堆栈(我在发送视频的时候打的断点):

看到主要经历了几个步骤:

  • VideoStreamEncoder收到数据之后进行编码;
  • 调用底层实体Vp8编码器进行编码;
  • 然后转给RtpSenderVideo模块进行发送;
  • RtpSenderVideo又会转给Pacer模块,最终通过PacingController::EnqueuePacketInternal 将数据插入到Pacer队列中;
  • 之后pacer线程就会不断调用前面介绍的ProcessPackets方法,不断取出数据,按照media_budget所规定的数据量进行发送。

三、关键代码走读:

3.1、EnqueuePacket:

cpp 复制代码
// 将编码后需要发送的数据,不断加入到pacer的队列当中
void PacingController::EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) {
  // 根据packet_type找到它的优先级
  const int priority = GetPriorityForType(*packet->packet_type());
  // 将这个packet以及所处的优先级传给EnqueuePacketInternal
  EnqueuePacketInternal(std::move(packet), priority);
}

Pacer队列优先级如下:

发送的时候就是根据这个优先级进行发送的。可以看出,核心逻辑是不管卡不卡,保证音频先出去,大不了当作打电话了。因为重传包也有可能有音频,并且重传包肯定是比较早的包,也先发送出去。

3.2、EnqueuePacketInternal:

函数作用:将传入的 RTP 包插入内部的队列 packet_queue_ 中,同时进行一些附加操作,比如流量探测(prober_)、时间戳处理、预算更新等。

cpp 复制代码
void PacingController::EnqueuePacketInternal(
    std::unique_ptr<RtpPacketToSend> packet,
    int priority) {
  // 流量探测
  prober_.OnIncomingPacket(packet->payload_size());

  // 获取当前时间戳,作为包入队列的时间参考。
  Timestamp now = CurrentTime();
  if (packet->capture_time_ms() < 0) {
    packet->set_capture_time_ms(now.ms());
  }
  // 动态模式我们一般不使用,一般使用周期模式
  if (mode_ == ProcessMode::kDynamic && packet_queue_.Empty() &&
      media_debt_ == DataSize::Zero()) {
    last_process_time_ = CurrentTime();
  }
  // 将 RTP 包插入内部的队列 packet_queue_ 中。同时附带以下信息:
  packet_queue_.Push(priority, now, packet_counter_++, std::move(packet));
}

可以看出:

  • 我们主要是更新下流量探测模块相关参数,然后获取个当前的时间戳,将数据包插入队列当中了。
  • 采集时间小于0就设置为当前时间now.

四、总结:

本文主要讲了Pacer模块的数据是如何插入的,关键要记住:

  1. EnqueuePacket 是外部接口,将传入的 RTP 包封装后调用内部函数处理。
  2. EnqueuePacketInternal是内部核心逻辑,负责:
    • 将 RTP 包按优先级和时间戳入队列;
    • 管理动态发送预算;
    • 更新流量探测器。
  3. Pacer 的最终目标是控制 RTP 包的发送节奏,确保带宽利用率的同时避免网络过载,同时按优先级调度多种类型的数据包。
相关推荐
腾科IT教育1 分钟前
网络安全与网络空间安全:概念、产业与防护建议
网络·安全·web安全·网络安全·网络空间安全
0Kilobyte1 分钟前
自建拨号服务器上网
网络
SoStraw2 小时前
webrpc 常见问题 FAQ:无公网 IP、Token、传文件,以及和 frp / WebRTC 的差别
tcp/ip·webrtc·frp·token·faq·webrpc·无公网ip
zhao32668575110 小时前
静态IP代理固定IP与动态IP的根本差异,账号操作安全性如何体现
网络·网络协议·tcp/ip
杀生丸学AI16 小时前
【稀疏重建】StructSplat:基于非校准稀疏视图的可泛化3DGS
深度学习·3d·音视频·transformer·三维重建·空间智能
小柯南敲键盘16 小时前
跨境电商图片翻译工具推荐:批量AI翻译+视频字幕+智能抠图
人工智能·python·音视频
淼澄研学16 小时前
Kimi API黑产倒卖技术解析与Python合规接入指南
开发语言·网络·python
SendTomo17 小时前
P2P文件传输工具对比:SendTomo vs send.wang
javascript·网络协议·webrtc·html5·p2p
qyyyyy57018 小时前
英文技术标准和协议规范怎么读?RFC、接口规范与安全标准 PDF 翻译流程
网络协议·网络安全·机器翻译·csrf·技术美术
无锡耐特森18 小时前
Profinet转ModbusTCP协议网关:数字化工厂跨协议互联
网络