WebRTC服务质量(09)- Pacer机制(01) 流程概述

发布于:2025-02-11 ⋅ 阅读:(60) ⋅ 点赞:(0)

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 是一种数据发送调度机制。它的主要功能是根据网络带宽限制、网络拥塞控制的反馈以及媒体的发送策略,对数据包的发送进行适配和节奏调度,以避免网络拥塞、减少丢包并保证流媒体传输的平滑性。

二、核心概念:

2.1 Pacer 的作用:

  • 流量平滑:音频、视频等媒体数据包可能在生成时间上分布不均,通过 Pacer,可以将这些数据包的发送节奏调整成更均匀的形式,避免突发流量冲击网络。
  • 速率控制:Pacer 会根据传输码率(由拥塞控制算法提供,例如 Google 的 Congestion Control),动态调整包的发送速率,确保发送端不超过网络容量。
  • 优先级处理:Pacer 支持区分不同的流类型(例如音频、视频、FEC 冗余流等),为高优先级流(如音频)留出更多资源或者保证其更低的延迟。

2.2 Pacer 的工作流程:

  1. 音视频流媒体按照编码器的设定发送数据包。
  2. 数据包会先进入一个队列(Packet Queue)。
  3. Pacer 通过定时器或事件驱动机制,根据当前允许的发送速率(由拥塞控制模块动态提供)从队列中提取数据包发送。
  4. 如果发送速率受限,多余的包会继续留在队列中等待下一轮调度。

以下是简化的机制模型:

[Media Encoder] -> [Packet Queue] -> Pacer -> [Network Sender]

三、核心代码:

先想想,根据前面的概念阐述,如果要让你写,你怎么写呢?是不是重点实现以下几个模块:

  • packet_router.h/cpp:负责将数据包分发到具体的网络发送端。
  • packet_sender.h/cpp:实现了调度核心逻辑。
  • packet_queue.h/cpp:实现用于存储待发送数据包的队列。

现在具体看看webrtc如何做的。

3.1、Pacer对象创建:

  • PeerConnection当中创建Call对象;

    // 从上到下调用顺序如下:
    PeerConnectionFactory::CreatePeerConnectionOrError -->
    PeerConnectionFactory::CreateCall_w -->
    CallFactory::CreateCall --> 
    Call::Create
    
  • Call对象创建RtpTransportControllerSend:

    创建Call时候首先得创建Call::Config,便于以后创建Pacer对象时候作为参数;

    Call* Call::Create(const Call::Config& config,
                       Clock* clock,
                       rtc::scoped_refptr<SharedModuleThread> call_thread,
                       std::unique_ptr<ProcessThread> pacer_thread) {
         
      RTC_DCHECK(config.task_queue_factory);
      return new internal::Call(
          clock, config,
          std::make_unique<RtpTransportControllerSend>(
              clock, config.event_log, config.network_state_predictor_factory,
              config.network_controller_factory, config.bitrate_config,
              std::move(pacer_thread), config.task_queue_factory, config.trials),
          std::move(call_thread), config.task_queue_factory);
    }
    

    这儿的config.trials,会导致后面创建PacedSender对象的时候,处理模式为kPeriodic,也就是周期处理模式;

  • RtpTransportControllerSend创建PacerSender对象:

    RtpTransportControllerSend 是 WebRTC 中负责发送侧 RTP 流量控制的核心模块。它是 RTP 传输的控制器,负责管理和协调发送侧的各种功能,包括比特率管理(带宽估算 BWE)、节奏控制(Pacer)、网络状态预测和反馈处理等。我们先看看构造函数:

    RtpTransportControllerSend::RtpTransportControllerSend(
        Clock* clock,
        webrtc::RtcEventLog* event_log,
        NetworkStatePredictorFactoryInterface* predictor_factory,
        NetworkControllerFactoryInterface* controller_factory,
        const BitrateConstraints& bitrate_config,
        std::unique_ptr<ProcessThread> process_thread,
        TaskQueueFactory* task_queue_factory,
        const WebRtcKeyValueConfig* trials)
        : clock_(clock),
          event_log_(event_log),
          bitrate_configurator_(bitrate_config),
          process_thread_started_(false),
          process_thread_(std::move(process_thread)

网站公告

今日签到

点亮在社区的每一天
去签到