当前位置: 首页 > news >正文

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

一、核心功能
  • CPU负载检测:监控视频帧的捕获、编码、发送全流程耗时,实时计算CPU使用率

  • 自适应决策:基于CPU使用率阈值触发视频质量调整(降级/升级)

  • 多策略支持:提供新旧两套CPU负载估计算法,支持实验性参数配置

  • 指标上报:通过CpuOveruseMetricsObserver接口反馈性能数据

二、核心算法原理
  1. 负载估算算法

    • 旧算法(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_;
  2. 过载决策逻辑

    // 过载条件:连续高阈值检测
    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 };
四、核心方法详解
  1. 帧生命周期管理

    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);
    }
  2. 动态调整机制

    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(); // 触发升级决策}
    }
五、设计亮点
  1. 双算法热切换

    // 根据filter_time_ms配置自动选择算法
    std::unique_ptr<ProcessingUsage> CreateProcessingUsage(...) {return (options.filter_time_ms > 0) ? std::make_unique<SendProcessingUsage2>(options) :std::make_unique<SendProcessingUsage1>(options);
    }
  2. 测试注入器模式

    // 通过字段试验模拟过载场景(WebRTC-ForceSimulatedOveruseIntervalMs)
    OverdoseInjector::Value() {switch(state_) {case State::kOveruse: return 250; // 强制返回250%使用率case State::kUnderuse: return 5;  // 强制返回5%使用率default: return usage_->Value();}
    }
  3. 抗抖动设计

    • 帧间隔时间上限约束: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保障能力。

http://www.lryc.cn/news/611938.html

相关文章:

  • Template 显式实例化 隐式实例化
  • C++之vector类的代码及其逻辑详解 (下)
  • java学习 leetcode24交换链表节点 200岛屿数量 +一些开发任务
  • win10/11网络防火墙阻止网络连接?【图文详解】防火墙阻止连接网络的解决方法
  • 最新教程 | CentOS 7 下 MySQL 8 离线部署完整手册(含自动部署脚本)
  • 【MyBatis新手避坑】详解 `Could not find resource ...Mapper.xml` 错误
  • 从博客到播客:文本转音频的全流程技术点
  • C++ - 仿 RabbitMQ 实现消息队列--网络通信协议设计
  • DOM的XML命名空间革命:从混乱到有序的蜕变
  • IP与MAC地址的区别解析
  • OpenAI重磅推出开源模型!gpt-oss-120b与20b全面解析
  • OpenAI/gpt-oss开源模型部署与使用全指南
  • OpenAI 开源GPT OSS系列模型
  • 小实验--震动点灯
  • GPT-OSS 与 Ollama 完整安装使用教程
  • 【JavaEE】(8) 网络原理 HTTP/HTTPS
  • NWinfo(硬件信息检测工具)v1.4.20绿色免费版,U盘随走随检,结果即刻导出
  • DM数据库的安全版本SYSDBA无法修改其他用户密码?
  • 基于串口实现可扩展的硬件函数 RPC 框架(附完整 Verilog 源码)
  • HarmonyOS应用开发环境搭建以及快速入门介绍
  • 【大模型系列】gpt-oss系列模型初探
  • 前端UI组件库
  • WMS及UI渲染底层原理学习
  • ROG 掌机 X:便携游戏新宠,开启微观生存冒险
  • JAVA 程序员cursor 和idea 结合编程
  • OpenAI最新开源:GPT-OSS原理与实践
  • 需求如何映射到开发计划中
  • 江协科技STM32 15-1 FLASH闪存
  • Unity模型显示在UI上
  • IDS知识点