webrtc弱网-OveruseFrameDetector源码分析与算法原理
一、核心功能
CPU负载检测:监控视频帧的捕获、编码、发送全流程耗时,实时计算CPU使用率
自适应决策:基于CPU使用率阈值触发视频质量调整(降级/升级)
多策略支持:提供新旧两套CPU负载估计算法,支持实验性参数配置
指标上报:通过CpuOveruseMetricsObserver接口反馈性能数据
二、核心算法原理
负载估算算法:
旧算法(SendProcessingUsage1):
// 基于指数滤波的帧处理时间/帧间隔时间比率 usage_percent = 100 * filtered_processing_ms / filtered_frame_diff_ms
新算法(SendProcessingUsage2):
// 基于时间常数的指数平滑:load <-- x/d * (1-exp(-d/T)) + exp(-d/T)*load double tau = options_.filter_time_ms * 0.001; double e = diff_time / tau; double c = (e < 0.0001) ? (1-e/2)/tau : -expm1(-e)/diff_time; load_estimate_ = c * encode_time + exp(-e) * load_estimate_;
过载决策逻辑:
// 过载条件:连续高阈值检测 bool OveruseFrameDetector::IsOverusing(int usage_percent) {return (usage_percent >= options_.high_threshold) && (++checks_above_threshold_ >= options_.high_threshold_consecutive_count); }// 低载条件:低于阈值 + 冷却时间 bool IsUnderusing(int usage_percent, int64_t time_now) {return (usage_percent < options_.low_threshold) && (time_now > last_rampup_time_ms_ + current_rampup_delay_ms_); }
三、关键数据结构
struct CpuOveruseOptions { // 核心配置参数int high_encode_usage_threshold_percent = 85; // 过载阈值(85%)int low_encode_usage_threshold_percent = 42; // 低载阈值(高阈值的1/2)int frame_timeout_interval_ms = 1500; // 帧超时判定时间int min_frame_samples = 120; // 最小采样帧数 };struct FrameTiming { // 帧时序追踪(旧算法)int64_t capture_time_us; // 原始捕获时间uint32_t timestamp; // 帧时间戳int64_t capture_us; // 首次进入系统时间int64_t last_send_us; // 发送完成时间 };// 状态机标识(测试注入器) enum class State { kNormal, kOveruse, kUnderuse };
四、核心方法详解
帧生命周期管理:
void FrameCaptured(bool is_preprocess, uint32_t timestamp, const VideoFrame& frame, int64_t time_when_first_seen_us) {// 重置条件:分辨率变化(1280x720->640x480)或帧超时(>1500ms)if (FrameSizeChanged(...) || FrameTimeoutDetected(...)) ResetAll(...);// 记录帧进入系统的时间点usage_->FrameCaptured(..., time_when_first_seen_us, last_capture_time_us_);last_capture_time_us_ = time_when_first_seen_us; }void FrameSent(..., absl::optional<int> encode_duration_us) {// 计算实际编码耗时(支持外部传入或内部计算)duration_us = usage_->FrameSent(..., capture_time_us, encode_duration_us);// 上报编码耗时指标if (duration_us) EncodedFrameTimeMeasured(*duration_us / 1000); }
动态调整机制:
void CheckForOveruse(OveruseFrameDetectorObserverInterface* observer) {// 过载处理:指数退避延迟算法if (IsOverusing(*usage_percent_)) {current_rampup_delay_ms_ *= kRampUpBackoffFactor; // 延迟翻倍(最大240s)observer->AdaptDown(); // 触发降级决策} // 低载处理:快速恢复机制else if (IsUnderusing(*usage_percent_, now_ms)) {in_quick_rampup_ = true;observer->AdaptUp(); // 触发升级决策} }
五、设计亮点
双算法热切换:
// 根据filter_time_ms配置自动选择算法 std::unique_ptr<ProcessingUsage> CreateProcessingUsage(...) {return (options.filter_time_ms > 0) ? std::make_unique<SendProcessingUsage2>(options) :std::make_unique<SendProcessingUsage1>(options); }
测试注入器模式:
// 通过字段试验模拟过载场景(WebRTC-ForceSimulatedOveruseIntervalMs) OverdoseInjector::Value() {switch(state_) {case State::kOveruse: return 250; // 强制返回250%使用率case State::kUnderuse: return 5; // 强制返回5%使用率default: return usage_->Value();} }
抗抖动设计:
帧间隔时间上限约束:
max_sample_diff_ms_ = (1000/fps)*1.35
最小采样帧数限制:
min_frame_samples=120
连续阈值检测机制:
high_threshold_consecutive_count=2
六、典型工作流程
注释精要
// 帧捕获处理(核心逻辑) void OveruseFrameDetector::FrameCaptured(...) {// 重置条件检查:分辨率变化或帧超时if (FrameSizeChanged(frame.width() * frame.height()) || FrameTimeoutDetected(time_when_first_seen_us)) {ResetAll(frame.width() * frame.height()); // 重置统计状态}// 区分预处理器/编码器场景if(is_preprocess) {frame_timing_.push_back(FrameTiming(frame.timestamp_us(), timestamp, ...));} else { frame_timing_.push_back(FrameTiming(frame.timestamp_us(), frame.timestamp(), ...));} }// 过载检测算法(策略核心) void OveruseFrameDetector::CheckForOveruse(...) {// 过载处理:指数退避延迟if (IsOverusing(*usage_percent_)) {if (now_ms - last_rampup_time_ms_ < kStandardRampUpDelayMs) {current_rampup_delay_ms_ *= kRampUpBackoffFactor; // 延迟翻倍if (current_rampup_delay_ms_ > kMaxRampUpDelayMs) // 上限240scurrent_rampup_delay_ms_ = kMaxRampUpDelayMs;}observer->AdaptDown(); // 触发降级} // 低载处理:快速恢复else if (IsUnderusing(*usage_percent_, now_ms)) {last_rampup_time_ms_ = now_ms;in_quick_rampup_ = true; // 启用快速恢复模式observer->AdaptUp(); // 触发升级} }
该设计通过多算法支持、动态阈值调整和状态机管理,实现了高效的CPU负载感知和视频质量自适应控制,在WebRTC中为实时视频通信提供了关键QoS保障能力。