webrtc弱网-ReceiveSideCongestionController类源码分析及算法原理

ReceiveSideCongestionController是WebRTC接收端拥塞控制的核心枢纽,承担双模式带宽估计的关键职责。它通过智能算法切换机制,动态选择发送端BWE(基于TransportSequenceNumber的延迟反馈)或接收端BWE(基于AbsoluteSendTime/TOF的本地估计)模式。针对音频流强制使用发送端BWE确保低延迟,视频流则自适应选择最优路径。该组件集成RembThrottler进行码率限制,通过RemoteEstimatorProxy生成TransportFeedback,并采用精细的线程安全设计保护共享状态。最终通过REMB和TransportFeedback RTCP消息将网络状态反馈给发送端,实现端到端的拥塞控制闭环,确保实时通信的质量和稳定性。

一. 核心功能

接收端拥塞控制器是WebRTC中负责接收方带宽估计的关键组件,主要功能包括:

  • 双模式带宽估计:支持发送端BWE和接收端BWE两种模式

  • 反馈管理:通过TransportFeedback和REMB消息向发送端反馈网络状态

  • 动态算法选择:根据RTP扩展头自动选择最优的带宽估计算法

  • 码率控制:限制最大接收码率,避免网络拥塞

二. 核心算法原理

发送端BWE (Sender-side BWE)

复制代码
详细见:https://blog.csdn.net/talkRTC/article/details/150635619?spm=1001.2014.3001.5501
// 基于TransportSequenceNumber的带宽估计
// 接收端记录包到达时间,通过TransportFeedback消息反馈给发送端
// 发送端基于这些信息进行带宽估计

接收端BWE (Receiver-side BWE)

复制代码
// 两种估计算法:
// 1. AbsoluteSendTime算法:基于绝对发送时间扩展头
// 2. SingleStream算法:基于传输时间偏移
// 算法根据数据包中的扩展头动态切换

算法原理图

  1. 两种估计算法对比
特性 AbsoluteSendTime算法 SingleStream(TOF)算法
时间基准 绝对发送时间戳 传输时间偏移
精度 高(24位, 约15μs) 中等
同步要求 需要时钟同步 相对时间,不要求严格同步
适用场景 视频会议、实时通信 传统RTP流
  1. 包分组处理
复制代码
// 包组划分原则:
// - 发送时间间隔 > 5ms 作为组边界
// - 每组包含多个连续包
// 计算组间延迟变化:
组间延迟梯度 = (到达时间差 - 发送时间差) / 发送时间差
  1. 过载检测机制
复制代码
基于Kalman滤波的延迟变化检测:
状态变量: [延迟梯度, 延迟变化率]
观测值: 实际测量的延迟梯度
检测逻辑:
  - 延迟梯度 > 阈值 + 方差: 过载
  - 延迟梯度 < -阈值: 欠载  
  - 其他: 正常

工作时序图

AST算法核心流程

复制代码
// 1. 时间戳转换
absolute_send_time = 从RTP扩展头提取
send_time_24bits = (absolute_send_time * 1000) >> 18

// 2. 包组检测
if (current_send_time - prev_send_time > 5ms) {
    // 新包组开始
    form_new_packet_group();
}

// 3. 延迟计算
inter_arrival = current_arrival - prev_arrival
inter_send = current_send - prev_send  
delay_gradient = inter_arrival - inter_send

// 4. 状态判断
if (delay_gradient > threshold + noise_var) {
    state = OVERUSE;
} else if (delay_gradient < -threshold) {
    state = UNDERUSE;
} else {
    state = NORMAL;
}

三. 关键数据结构

复制代码
class ReceiveSideCongestionController {
private:
    Clock& clock_;                          // 系统时钟
    RembThrottler remb_throttler_;          // REMB码率限制器
    RemoteEstimatorProxy remote_estimator_proxy_; // 远程估计代理
    
    mutable Mutex mutex_;                   // 线程安全锁
    std::unique_ptr<RemoteBitrateEstimator> rbe_; // 远程带宽估计器
    bool using_absolute_send_time_;         // 当前使用的算法标志
    uint32_t packets_since_absolute_send_time_; // AST算法包计数器
};

四. 核心方法详解

4.1 构造函数

复制代码
ReceiveSideCongestionController::ReceiveSideCongestionController(
    Clock* clock,
    RemoteEstimatorProxy::TransportFeedbackSender feedback_sender,
    RembThrottler::RembSender remb_sender,
    NetworkStateEstimator* network_state_estimator)
    : clock_(*clock),
      remb_throttler_(std::move(remb_sender), clock),
      remote_estimator_proxy_(std::move(feedback_sender), network_state_estimator),
      rbe_(new RemoteBitrateEstimatorSingleStream(&remb_throttler_, clock)),
      using_absolute_send_time_(false),
      packets_since_absolute_send_time_(0) {}

功能:初始化所有组件,默认使用SingleStream算法

4.2 包处理入口

复制代码
void ReceiveSideCongestionController::OnReceivedPacket(
    const RtpPacketReceived& packet, MediaType media_type) {
    bool has_transport_sequence_number = 
        packet.HasExtension<TransportSequenceNumber>() ||
        packet.HasExtension<TransportSequenceNumberV2>();
        
    if (media_type == MediaType::AUDIO && !has_transport_sequence_number) {
        // 音频流且无传输序列号,不支持接收端BWE
        return;
    }

    if (has_transport_sequence_number) {
        // 发送端BWE模式:转发包信息给远程估计代理
        remote_estimator_proxy_.IncomingPacket(packet);
    } else {
        // 接收端BWE模式:本地进行带宽估计
        MutexLock lock(&mutex_);
        PickEstimator(packet.HasExtension<AbsoluteSendTime>());
        rbe_->IncomingPacket(packet);
    }
}

4.3 算法选择器

复制代码
void ReceiveSideCongestionController::PickEstimator(bool has_absolute_send_time) {
    if (has_absolute_send_time) {
        // 发现AST扩展头,立即切换到AST算法
        if (!using_absolute_send_time_) {
            RTC_LOG(LS_INFO) << "切换到绝对发送时间RBE算法";
            using_absolute_send_time_ = true;
            rbe_ = std::make_unique<RemoteBitrateEstimatorAbsSendTime>(
                &remb_throttler_, &clock_);
        }
        packets_since_absolute_send_time_ = 0;
    } else {
        // 没有AST扩展头,等待一定包数后切回TOF算法
        if (using_absolute_send_time_) {
            ++packets_since_absolute_send_time_;
            if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
                RTC_LOG(LS_INFO) << "切换到传输时间偏移RBE算法";
                using_absolute_send_time_ = false;
                rbe_ = std::make_unique<RemoteBitrateEstimatorSingleStream>(
                    &remb_throttler_, &clock_);
            }
        }
    }
}

4.4 周期处理

复制代码
TimeDelta ReceiveSideCongestionController::MaybeProcess() {
    Timestamp now = clock_.CurrentTime();
    mutex_.Lock();
    TimeDelta time_until_rbe = rbe_->Process();           // 处理接收端BWE
    mutex_.Unlock();
    TimeDelta time_until_rep = remote_estimator_proxy_.Process(now); // 处理发送端BWE反馈
    TimeDelta time_until = std::min(time_until_rbe, time_until_rep);
    return std::max(time_until, TimeDelta::Zero());       // 返回下次处理时间
}

五. 设计亮点

5.1 智能算法切换

复制代码
// 基于数据包特征自动选择最优算法
// AST算法优先,在没有AST时回退到TOF算法
// 切换阈值kTimeOffsetSwitchThreshold=30包,避免频繁切换

算法原理图:

5.2 双模式支持

复制代码
// 统一处理发送端BWE和接收端BWE
// 根据TransportSequenceNumber存在性自动路由
// 音频流特殊处理:仅支持发送端BWE

算法原理图

5.3 线程安全设计

复制代码
// 使用Mutex保护共享状态
// RTC_GUARDED_BY(mutex_)注解明确线程约束
// 细粒度锁:仅保护接收端BWE相关状态

六. 典型工作流程

6.1 视频流处理(接收端BWE)

复制代码
1. 收到视频RTP包 → 检查扩展头
2. 有AbsoluteSendTime → 选择AST算法
3. 调用rbe_->IncomingPacket()进行本地估计
4. 定期MaybeProcess()生成REMB反馈
5. 通过remb_throttler_发送码率限制

6.2 音频流处理

复制代码
1. 收到音频RTP包
2. 必须有TransportSequenceNumber,否则跳过
3. 仅支持发送端BWE模式

这个设计体现了WebRTC拥塞控制的核心理念:灵活性自适应性,能够根据网络条件和流类型自动选择最优的带宽估计策略。

相关推荐
21号 13 小时前
9.Redis 集群(重在理解)
数据库·redis·算法
python百炼成钢5 小时前
3.Linux 网络相关
linux·运维·网络·stm32·单片机
2503_930123935 小时前
Kubernetes (四)网络插件详解:Flannel 与 Calico 的原理、数据流向与实战对比
网络·容器·kubernetes
hadage2335 小时前
--- 数据结构 AVL树 ---
数据结构·算法
liu****5 小时前
8.list的使用
数据结构·c++·算法·list
阿拉丁的梦5 小时前
后期材质-屏幕冲击径向模糊
算法·材质
星哥说事5 小时前
网络安全设备:入侵检测系统(IDS)、入侵防御系统(IPS)的配置与使用
网络·安全·web安全
问道飞鱼5 小时前
【HTTP知识】HTTP OPTIONS 预检请求深度解析与优化策略
网络·网络协议·http·option·预检
weixin_429630266 小时前
实验二-决策树-葡萄酒
算法·决策树·机器学习