webrtc 音频模块FEC模块

FecControllerPlrBased 模块是 WebRTC 音频网络适配器(Audio Network Adaptor, ANA)中的一个控制模块。它的核心职责是根据网络丢包率(Packet Loss Rate, PLR)和上行带宽动态决定是否启用前向纠错(FEC)。

FEC 是一种通过发送冗余数据来对抗网络丢包的技术,但它会占用额外的带宽。因此,需要在"抗丢包能力"和"带宽消耗"之间取得平衡。这个类就是用来做这个权衡决策的。

该模块通过这种动态、滞后的策略,确保了在网络波动时音频质量的稳定性,同时避免了不必要的带宽浪费。

一、滞后阈值(Hysteresis)

为了防止 FEC 状态在"开启"和"关闭"之间频繁震荡(Flapping),该类使用了两条不同的阈值曲线,形成一种滞后机制:

1, fec_enabling_threshold (开启阈值):

• 当当前丢包率 高于 这条曲线时,决定开启 FEC。

• 这条曲线通常较高,意味着只有当网络状况较差(丢包多)且带宽允许时,才愿意付出带宽代价去开启 FEC。

2, fec_disabling_threshold (关闭阈值):

• 当当前丢包率 低于 这条曲线时,决定关闭 FEC。

• 这条曲线通常较低,意味着只有当网络状况明显好转(丢包很少)时,才关闭 FEC 以节省带宽。

3,说明

复制代码
packet-loss ^   |  |
            |   |  |   FEC ON (区域)
            |    \  \   
            | FEC \  \_______ fec_enabling_threshold (高阈值)
            | OFF  \_________ fec_disabling_threshold (低阈值)
            |-----------------> bandwidth

• 如果当前状态是 FEC OFF,必须等到丢包率超过上方的 enabling 曲线才会切换为 ON。

• 如果当前状态是 FEC ON,必须等到丢包率降到下方的 disabling 曲线以下才会切换为 OFF。

• 在两条曲线之间的区域,保持当前状态不变。

二、关键成员变量

2.1 config:

• 存储配置信息,包括初始状态、两条阈值曲线以及平滑滤波器的时间常数。

cpp 复制代码
struct Config {
  // |fec_enabling_threshold| defines a curve, above which FEC should be
  // enabled. |fec_disabling_threshold| defines a curve, under which FEC
  // should be disabled. See below
  //
  // packet-loss ^   |  |
  //             |   |  |   FEC
  //             |    \  \   ON
  //             | FEC \  \_______ fec_enabling_threshold
  //             | OFF  \_________ fec_disabling_threshold
  //             |-----------------> bandwidth
  Config(bool initial_fec_enabled,
         const ThresholdCurve& fec_enabling_threshold,
         const ThresholdCurve& fec_disabling_threshold,
         int time_constant_ms);
  bool initial_fec_enabled;
  ThresholdCurve fec_enabling_threshold;
  ThresholdCurve fec_disabling_threshold;
  int time_constant_ms;
};

2.2 fec_enabled_

• 当前 FEC 的状态标志(true/false)。

• 当前的估计上行带宽。阈值曲线是带宽的函数,因为带宽越高,我们越能承受 FEC 带来的额外开销。

2.4 packet_loss_smoother_ (SmoothingFilter)

• 平滑滤波器。网络报告的丢包率通常是瞬时且波动的。直接使用原始丢包率会导致决策不稳定。

• 这个滤波器对丢包率进行指数加权移动平均(EWMA),提供一个更平滑、更稳定的丢包率估值用于决策。

• time_constant_ms 决定了平滑的程度:时间常数越大,反应越慢但越稳定;时间常数越小,反应越快但易受噪声影响。

三, 主要方法

3.1 UpdateNetworkMetrics(const NetworkMetrics& network_metrics):

• 输入更新。从 ANA 的其他部分接收最新的网络统计数据。

• 提取上行带宽 (uplink_bandwidth_bps)。

• 提取原始丢包率,并通过 packet_loss_smoother_ 进行平滑处理,得到用于决策的有效丢包率。

3.2 MakeDecision(AudioEncoderRuntimeConfig* config):

• 核心决策逻辑。这是 Controller 接口的实现,每帧或定期被调用。

• 它会根据当前的平滑丢包率和带宽,查询两条阈值曲线。

• 调用 FecEnablingDecision 或 FecDisablingDecision 来判断是否应该改变 fec_enabled_ 的状态。

• 最终将决策结果写入 config->enable_fec,从而指导音频编码器是否生成 FEC 数据。

3.3 FecEnablingDecision / FecDisablingDecision:

• 私有辅助函数,分别执行具体的比较逻辑:

1, FecEnablingDecision: 如果 !fec_enabled_ 且 smoothed_packet_loss > GetThreshold(bandwidth, enabling_curve),则返回 true。

2, FecDisablingDecision: 如果 fec_enabled_ 且 smoothed_packet_loss < GetThreshold(bandwidth, disabling_curve),则返回 true。

四、工作流程

  1. 初始化: 创建实例,设定初始 FEC 状态和阈值曲线。

  2. 监控: 每次收到网络指标更新 (UpdateNetworkMetrics),更新带宽估计,并平滑最新的丢包率样本。

  3. 决策: 在 MakeDecision 中:

• 根据当前带宽,从 fec_enabling_threshold 曲线计算出"开启临界丢包率"。

• 根据当前带宽,从 fec_disabling_threshold 曲线计算出"关闭临界丢包率"。

• 如果当前 FEC 是关闭的,且平滑丢包率 > 开启临界值 -> 开启 FEC。

• 如果当前 FEC 是开启的,且平滑丢包率 < 关闭临界值 -> 关闭 FEC。

• 否则,保持现状。

  1. 执行: 将结果传递给音频编码器,编码器据此调整输出包的格式(是否包含冗余帧)。

五,为什么需要基于带宽的曲线?

FEC 会增加比特率。

• 低带宽时:即使丢包率稍高,也可能无法承受 FEC 带来的额外负载,否则会导致拥塞加剧。因此,低带宽下的开启阈值会设得很高(很难开启 FEC)。

• 高带宽时:有足够的余量容纳冗余数据,因此可以更早地开启 FEC 以保护音质。此时开启阈值会降低。

相关推荐
show4331 小时前
2026视频处理小程序技术选型指南:链接解析+OCR+ASR+AI配音多引擎对比
小程序·ocr·音视频
昨日之日20062 小时前
LTX-2.5:更清晰、更可控、同步音画、多镜头连贯的AI视频神器
人工智能·音视频
記億揺晃着的那天3 小时前
NAS 内网域名访问为什么需要浏览器授权
网络·nginx·js·nas
chunmiao30324 小时前
DeepSeek V4-Pro 正式版上线,API 8月17日起分时调价
网络·安全
迪康Defender6 小时前
AI 重构终端安全运营:智能分析中枢 AI Insight 模块架构与落地场景深度解析
运维·网络·人工智能·其他·安全·重构·架构
0x536 小时前
Java网络编程(二)
java·服务器·网络
点云-激光雷达-Slam-三维牙齿7 小时前
批量音频转文本 ASR 目前中文识别效果最好的qwen3 模型
音视频
小柯南敲键盘7 小时前
跨马翻译:跨境电商批量图片翻译与视频字幕一站式工具
人工智能·python·音视频
西安景驰电子8 小时前
《PTP精确时间协议系列》第一篇:从原理到应用,全面解读IEEE 1588
linux·运维·服务器·开发语言·网络·windows·php
weixin_446260859 小时前
AVA-Encoder:面向智能体原生视频表征学习框架
学习·音视频