一. 核心功能
QualityScaler 是 WebRTC 中用于动态调整视频编码质量的模块,主要功能包括:
-
QP 监控:持续监测编码器输出的量化参数(QP)
-
丢帧率分析:跟踪媒体优化和编码器导致的丢帧情况
-
自适应决策:根据 QP 和丢帧率触发分辨率/帧率调整
-
异步任务调度:通过延迟任务实现周期性质量检测
-
平滑处理:使用指数平滑算法减少 QP 波动影响
二. 核心算法原理
-
双阈值决策机制:
-
当 QP > 高阈值时:触发降级(降低分辨率/帧率)
-
当 QP ≤ 低阈值时:触发升级(提高分辨率/帧率)
-
-
丢帧率保护:当总丢帧率 ≥ 60% 时强制降级
-
指数平滑滤波:
class QpSmoother { rtc::ExpFilter smoother_; // 指数平滑滤波器 void Add(float sample) { smoother_.Apply(time_delta, sample); } }
-
动态采样周期调整:
-
初始快速检测(快速启动阶段)
-
根据历史结果动态调整检测间隔
-
公式:
delay = sampling_period_ms_ * scale_factor_
-
三. 关键数据结构
// QP 阈值结构体
struct QpThresholds {
int low; // 低阈值(升级边界)
int high; // 高阈值(降级边界)
};
// 质量检测结果
enum class CheckQpResult {
kInsufficientSamples, // 样本不足
kNormalQp, // QP正常
kHighQp, // QP过高(需降级)
kLowQp // QP过低(需升级)
};
// 平滑滤波器
class QpSmoother {
rtc::ExpFilter smoother_; // 指数平滑实现
int64_t last_sample_ms_; // 最后采样时间
};
四. 核心方法详解
-
质量检测入口:
void StartNextCheckQpTask() { pending_qp_task_ = std::make_unique<CheckQpTask>(this); pending_qp_task_->StartDelayedTask(); // 启动延迟检测任务 }
-
QP检测逻辑:
CheckQpResult CheckQp() const { // 1. 检查样本数量是否足够(默认至少60帧) if (frames < min_frames_needed_) return kInsufficientSamples; // 2. 检查丢帧率是否超标(≥60%) if (drop_rate >= kFramedropPercentThreshold) return kHighQp; // 3. 检查QP是否超过阈值 if (*avg_qp_high > thresholds_.high) return kHighQp; if (*avg_qp_low <= thresholds_.low) return kLowQp; return kNormalQp; }
-
平滑处理实现:
void QpSmoother::Add(float sample, int64_t time_sent_us) { int64_t now_ms = time_sent_us / 1000; // 应用指数平滑:新值 = α*当前值 + (1-α)*历史值 smoother_.Apply(now_ms - last_sample_ms_, sample); last_sample_ms_ = now_ms; }
五. 设计亮点
-
动态任务调度:
-
使用
CheckQpTask
实现自循环检测 -
根据历史结果动态调整检测频率
-
快速启动模式(fast_rampup_)加速初始检测
-
-
双通道平滑滤波:
qp_smoother_high_.reset(new QpSmoother(config_.alpha_high)); // 高阈值通道 qp_smoother_low_.reset(new QpSmoother(config_.alpha_low)); // 低阈值通道
使用不同的平滑系数分别处理高低阈值
-
字段试验支持:
QualityScalerSettings settings(field_trials); // 从字段试验获取参数 sampling_period_ms_ = settings.SamplingPeriodMs().value_or(kMeasureMs);
允许通过字段试验动态配置算法参数
-
丢帧分类统计:
void ReportDroppedFrameByMediaOpt(); // 媒体优化导致的丢帧 void ReportDroppedFrameByEncoder(); // 编码器导致的丢帧
六. 典型工作流程

注释精要
-
关键参数:
// 默认检测周期(ms) static const int kMeasureMs = 2000; // 丢帧率阈值(%) static const int kFramedropPercentThreshold = 60; // 最小决策帧数(2秒数据) static const size_t kMinFramesNeededToScale = 2 * 30;
-
核心类说明:
// QP平滑处理器:使用指数平滑算法消除瞬时波动 class QpSmoother { // α值决定平滑强度:α越大,新值权重越高 explicit QpSmoother(float alpha); }; // 异步检测任务:实现周期性的质量评估 class CheckQpTask { void StartDelayedTask(); // 启动延迟检测 };
-
自适应触发逻辑:
void QualityScaler::CheckQp() { // 优先检查丢帧率:超过60%立即降级 if (*drop_rate >= 60) return kHighQp; // 双通道平滑QP检测 if (high_smoothed_qp > high_thresh) return kHighQp; if (low_smoothed_qp <= low_thresh) return kLowQp; }
该模块通过智能的QP分析和动态的任务调度,实现了视频质量的自适应调整,在带宽波动环境下保持视频流畅性和清晰度的平衡。