webrtc弱网-FrameDropper 源码分析与算法原理

在webrtc弱网整个链路中,存在这么一个模块,当网络发送不及时或拥塞时,会采取丢帧策略。来满足当前的带宽。这个模块就是FrameDropper类。

一、核心功能

FrameDropper 是 WebRTC 视频编码模块中的帧丢弃控制器,通过漏桶算法变体实现动态帧丢弃策略,防止在带宽不足时视频数据堆积。主要功能包括:

  1. 根据目标比特率和实际帧大小动态计算丢帧比例

  2. 平滑处理关键帧和大帧的突发流量

  3. 避免长时间连续丢帧影响观看体验

二、核心算法原理
1. 漏桶模型 (Leaky Bucket)
float accumulator_;        // 当前桶内数据量(kbits)
float accumulator_max_;    // 桶容量 = target_bitrate_ * kLeakyBucketSizeSeconds
float target_bitrate_;     // 当前目标比特率(kbps)
  • 填充(Fill):当编码器输出帧时,按帧大小填充桶

  • 泄漏(Leak):按帧率持续漏出数据:accumulator_ -= target_bitrate_ / framerate

2. 关键帧/大帧特殊处理
int large_frame_accumulation_count_;       // 大帧分块计数
float large_frame_accumulation_chunk_size_;// 每块大小
  • 关键帧:强制分块处理,块数 = max(0.5*fps, 5)

  • 超大Delta帧(>3倍平均帧大小):分块处理

3. 丢帧决策算法
bool DropFrame(absl::optional<int64_t> last_drop_frame_ms);
  • 丢帧比例计算:通过指数平滑滤波更新

    rtc::ExpFilter drop_ratio_;  // 基值0.9,初始值0.96
  • 两种丢帧模式

    • 高丢帧率(≥0.5):连续丢帧直到满足 drop_count_ ≥ 1/(1-ratio)

    • 低丢帧率(<0.5):丢帧间隔 1/ratio 帧

4. 动态参数调整
void SetRates(float bitrate, float incoming_frame_rate);
  • 比特率变化时等比缩放桶内数据:accumulator_ *= new_bitrate / old_bitrate

  • 更新帧率相关参数:large_frame_accumulation_spread_ = max(0.5*fps, 5)

三、关键数据结构
1. 指数滤波器 (ExpFilter)
rtc::ExpFilter key_frame_ratio_;           // 关键帧比例滤波(α=0.99)
rtc::ExpFilter delta_frame_size_avg_kbits_;// 帧大小滤波(α=0.9)
rtc::ExpFilter drop_ratio_;                // 丢帧比例滤波(α=0.9)

滤波公式:new_val = α * old_val + (1-α) * sample

2. 大帧处理参数
float large_frame_accumulation_spread_;    // 分块数 = max(0.5*fps, 5)
const int kLargeDeltaFactor = 3;           // 大帧阈值系数
四、核心方法详解
1. Fill() - 帧数据填充
void Fill(size_t framesize_bytes, bool delta_frame)

处理流程:

  1. 关键帧:强制分块处理,更新关键帧比例

  2. 超大Delta帧:满足 size > 3*avg_size 时分块

  3. 普通帧:直接更新桶和帧大小平均值

  4. 分块处理时:当前帧大小记为0,后续通过Leak()分次添加

2. Leak() - 漏桶泄漏
void Leak(uint32_t input_framerate)

处理流程:

  1. 计算每帧理论比特值:target_bitrate_ / fps

  2. 大帧分块处理:每次泄漏扣除分块大小

  3. 更新丢帧比例:UpdateRatio()

3. UpdateRatio() - 动态调整丢帧率
void UpdateRatio()

决策逻辑:

  • 桶溢出时(accumulator_ > max):

    • 设置 drop_next_ = true

    • 提升丢帧率:drop_ratio_.Apply(1.0f, 1.0f)

  • 桶未溢出:降低丢帧率:drop_ratio_.Apply(1.0f, 0.0f)

4. DropFrame() - 丢帧决策
bool DropFrame(...)

决策矩阵:

丢帧率策略
≥0.5连续丢帧直到满足 N=1/(1-ratio)
(0, 0.5)每 1/ratio 帧丢1帧
0不丢帧
五、设计亮点
  1. 大帧分块处理
    避免单一大帧导致桶溢出引发连续丢帧:

    if (framesize_kbits > kLargeDeltaFactor * avg_size) 
        large_frame_accumulation_count_ = spread;
  2. 桶容量动态缩放
    比特率降低时等比缩小桶内数据:

    accumulator_ = bitrate / target_bitrate_ * accumulator_;
  3. 丢帧平滑控制
    通过指数滤波避免丢帧率剧烈波动:

    drop_ratio_.UpdateBase(0.9f);  // 平滑因子
  4. 最大连续丢帧限制
    防止长时间黑屏:

    const float kDefaultMaxDropDurationSecs = 4.0f;
    int max_limit = fps * max_drop_duration_secs_;
六、典型工作流程

该模块通过动态平衡帧率、帧大小和带宽关系,在拥塞时智能丢弃非关键帧,保障视频流畅传输。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值