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

webrtc代码走读(十)-QOS-Sender Side BWE原理

1、背景介绍

为什么 Sender Side BWE 是 WebRTC 的核心

BWE(Bandwidth Estimation,带宽估计)是 WebRTC 视频引擎中决定通讯质量的关键模块。其核心作用是:在保证网络不拥塞的前提下,动态计算发送端可承载的最大视频码率,直接避免因码率超出网络承载能力导致的画面卡顿、花屏等问题。

1.1 BWE 算法的演进历程

BWE 算法的发展本质是“从被动响应到主动预测”的升级,具体分为三个阶段:

阶段核心逻辑优缺点代表算法
早期版本基于丢包的被动评估:逐步增加发送量,直到检测到丢包才降低码率优点:实现简单;缺点:丢包已代表网络拥塞,属于“事后补救”,延迟高基础丢包反馈算法
中期版本基于延迟的主动预测:通过接收端时延变化预判拥塞,提前调整码率优点:比丢包更灵敏,可避免拥塞发生;缺点:依赖接收端计算,反馈链路长KalmanFilter(接收端计算)
最新版本发送端本地化计算:将延迟分析逻辑迁移到发送端,减少反馈开销优点:响应速度更快,减少网络往返延迟;缺点:对发送端算力有轻微要求Trendline(发送端计算)
1.2 GCC vs Sender Side BWE

WebRTC 历史上存在两种主流拥塞控制算法,开发中需明确区分,避免代码混淆:

对比维度GCC(Google Congest Control)Sender Side BWE
码控计算模块位置接收端发送端
RTP 头部扩展字段AbsSendTime(绝对发送时间)TransportSequenceNumber(传输序列号)
接收端关键对象RemoteBitrateEstimatorAbsSendTimeRemoteEstimatorProxy
网络延时滤波器Kalman FilterTrendline Filter
接收端反馈 RTCP 报文REMB(Receiver Estimated Maximum Bitrate)TransportCC(Transport Congestion Control)
适用 WebRTC 版本M55 之前M55 之后(当前主流版本)

2 Sender Side BWE 的三大核心逻辑

Sender Side BWE 通过“多维度评估+动态融合”确定最终码率,核心逻辑分为三部分:REMB 兼容逻辑、基于丢包的拥塞控制、基于延迟的拥塞控制,最终取三者最小值作为发送码率(min(base, remb, bwe))。

2.1 REMB Bitrate:向下兼容逻辑

REMB(Receiver Estimated Maximum Bitrate)是 GCC 算法中接收端反馈的“建议最大码率”。在 Sender Side BWE 中,REMB 仅作为向下兼容老版本的备用逻辑,不参与主流计算。

  • 作用:当接收端为 M55 之前的老版本时,发送端仍能通过 REMB 报文获取码率建议,避免版本不兼容导致的通讯失败。
  • 优先级:最低,仅当基于延迟和丢包的计算结果无效时才使用。
2.2 基于丢包的拥塞控制:通过丢包率直接调整码率

核心思想

丢包率直接反映网络拥塞程度:

  • 丢包率极低(<2%):网络空闲,可提升码率;
  • 丢包率高(>10%):网络拥塞,需降低码率;
  • 丢包率中等(2%~10%):网络处于临界状态,维持当前码率。

关键公式与阈值

WebRTC 中通过以下逻辑计算丢包调整后的码率:

if 丢包率 fL(tk) < 0.02(2%):码率 = 当前码率 × 1.08 + 1000bps(8%增长+保底1kbps,避免低码率时停滞)
elif 丢包率 fL(tk) > 0.1(10%):码率 = 当前码率 × (512 - 丢包率×256) / 512(约等于码率 × (1 - 0.5×丢包率))
else:码率保持不变
  • 阈值说明:low_loss_threshold_ = 0.02f(2%)、high_loss_threshold_ = 0.1f(10%),为 WebRTC 内置默认值,开发中可通过 BitrateController 接口修改。
2.3 基于延迟的拥塞控制:预测拥塞的核心逻辑

基于延迟的拥塞控制是 Sender Side BWE 的核心,通过分析“包组到达时间的延迟趋势”预判网络状态,分为四个关键步骤:包组延迟评估(InterArrival)→ 滤波器趋势判断(TrendlineEstimator)→ 过载检测(OveruseDetector)→ 码率调节(AimdRateControl)

2.3.1 步骤1:包组延迟评估(InterArrival)—— 为什么要按“组”计算延迟?

  • 问题本质:视频帧可能被拆分为多个 RTP 包(如 1 帧 1080P 视频可能拆分为 10 个 RTP 包),若单个包计算延迟,会因“同一帧内包的发送间隔极短”导致延迟计算失真。
  • 解决方案:按“帧”分组(即“包组”),计算两组包的延迟差,核心参数如下:
参数定义计算公式示例
delta_timestamp两组包的发送时间差T2(第二组最后一个包的发送时间) - T1(第一组最后一个包的发送时间)若两组包分属不同帧,发送间隔为 40ms(25fps 帧率),则 delta_timestamp = 40ms
delta_arrival两组包的到达时间差t2(第二组最后一个包的到达时间) - t1(第一组最后一个包的到达时间)若网络延迟稳定,delta_arrival ≈ delta_timestamp;若网络拥塞,delta_arrival > delta_timestamp
delta_size两组包的大小差第二组包的总字节数 - 第一组包的总字节数若第一组 10KB,第二组 12KB,则 delta_size = 2KB

步骤2:Trendline 滤波趋势判断—— 如何量化延迟趋势?

Trendline 滤波器的核心是:通过“累积延迟”和“平滑延迟”计算延迟增长斜率,斜率越大,说明网络拥塞越严重。

关键计算步骤(附公式与注释)

  1. 单个包组的延迟增长值
    delay_i = delta_arrival - delta_timestamp

    • 含义:若 delay_i > 0,说明当前组的到达延迟比上一组高,网络开始堆积数据;若 delay_i < 0,说明网络延迟降低。
  2. 累积延迟
    acc_delay_i = acc_delay_{i-1} + delay_i

    • 含义:叠加历史延迟增长值,反映延迟的长期趋势。
  3. 平滑延迟(避免瞬时波动影响)
    smo_delay_i = alpha × smo_delay_{i-1} + (1 - alpha) × acc_delay_i

    • 参数:alpha = 0.9(WebRTC 内置,平衡平滑度与响应速度);
    • 作用:过滤瞬时延迟抖动,避免因单个包的网络波动误判拥塞。
  4. 趋势斜率计算

    • 分子(numerator):sum( (trans_k - trans_avg) × (smo_delay_k - smo_delay_avg) )
      • trans_k:第 k 组包的传输持续时间(从组内第一个包到达至最后一个包到达的时间);
      • trans_avg:所有组 trans_k 的平均值;
      • smo_delay_avg:所有组 smo_delay_k 的平均值。
    • 分母(denominator):sum( (trans_k - trans_avg)^2 )
    • 最终趋势值:trendline_i = numerator / denominator
      • 含义:trendline_i > 0 表示延迟呈上升趋势(网络拥塞);trendline_i < 0 表示延迟呈下降趋势(网络空闲)。

步骤3:过载检测(OveruseDetector)—— 如何判断网络状态?

通过 Trendline 计算的 trendline_i,结合动态阈值 gamma_1,判断网络处于“过载(overuse)”“正常(normal)”还是“未充分利用(underuse)”,核心是一个有限状态机

状态机迁移逻辑(伪代码)

// 输入:当前包组的趋势值 trendline_i,周期内包组个数 N
m_i = trendline_i × N  // 周期内总趋势值,放大趋势差异if m_i > gamma_1(动态阈值,由网络抖动自适应调整):// 延迟增长过快,网络过载current_state = overuse// 过载时,需记录过载持续时间,避免瞬时波动误判overuse_time += delta_Tif overuse_time > overuse_threshold:// 过载持续超过阈值,触发码率下降trigger_rate_decrease()
elif m_i < -gamma_1:// 延迟下降,网络未充分利用current_state = underusetrigger_rate_increase()  // 触发码率上升
else:// 延迟稳定,网络正常current_state = normalmaintain_current_rate()  // 维持当前码率

步骤4:AIMD 码率调节(AimdRateControl)—— 如何调整码率?

AIMD(Additive Increase Multiplicative Decrease,和式增加,积式减少)是 TCP 拥塞控制的经典思想,WebRTC 对其进行了适配,核心逻辑根据网络状态动态调整码率。

关键调节规则(附公式)
网络状态调节策略公式/说明示例
未充分利用(underuse)分阶段增长:
1. 会话初期(慢启动):倍数增长
2. 稳定期:线性增长
1. 慢启动:new_bitrate = current_bitrate × 1.08(8%倍数增长)
2. 稳定期:new_bitrate = current_bitrate + (RTT 周期内可传输码率)
若当前码率 1Mbps,慢启动后变为 1.08Mbps;稳定期若 RTT 为 100ms,可增加 1Mbps × 0.1 = 100kbps
过载(overuse)乘法下降:基于过去 500ms 内的最大确认码率new_bitrate = max_acked_bitrate_500ms × 0.85(降低 15%)若过去 500ms 最大确认码率为 1Mbps,下降后为 850kbps
正常(normal)维持当前码率new_bitrate = current_bitrate-

3、WebRTC 源码实现解析

以下基于 WebRTC M100+ 版本源码,梳理 Sender Side BWE 的核心函数调用链。

  • src/modules/congestion_controller/send_side_congestion_controller.cc
  • src/modules/bitrate_controller/send_side_bandwidth_estimation.cc
  • src/modules/congestion_controller/delay_based_bwe/delay_based_bwe.cc
3.1 核心函数调用链总览

Sender Side BWE 的触发入口是“接收端 RTCP 反馈报文的处理”,整体调用链如下:

// 1. 接收 RTCP 报文(TransportCC 或 RR)
BaseChannel::ProcessPacket → WebRtcVideoChannel::OnRtcpReceived → Call::DeliverRtcp → VideoSendStreamImpl::DeliverRtcp
// 2. 解析 RTCP 报文,触发拥塞控制回调
→ ModuleRtpRtcpImpl::IncomingRtcpPacket → RTCPReceiver::IncomingPacket → RTCPReceiver::TriggerCallbacksFromRtcpPacket
// 3. 分支1:基于延迟的拥塞控制(核心)
→ SendSideCongestionController::OnTransportFeedback → DelayBasedBwe::IncomingPacketFeedbackVector → BitrateControllerImpl::OnDelayBasedBweResult
// 3. 分支2:基于丢包的拥塞控制
→ BitrateControllerImpl::RtcpBandwidthObserverImpl::OnReceivedRtcpReceiverReport → BitrateControllerImpl::OnReceivedRtcpReceiverReport
// 4. 融合所有评估结果,确定最终码率
→ SendSideBandwidthEstimation::UpdateEstimate → SendSideBandwidthEstimation::CapBitrateToThresholds
// 5. 将码率更新到发送端各模块( pacing、FEC、编码器)
→ SendSideCongestionController::MaybeTriggerOnNetworkChanged
3.2 关键函数源码

基于延迟的拥塞控制:DelayBasedBwe::IncomingPacketFeedbackVector

/*** @brief 接收端反馈的包组到达信息,更新延迟统计并计算 BWE 值* @param packet_feedbacks:接收端反馈的包组列表(包含每个包的发送时间、到达时间、序列号)* @param now_ms:当前时间(毫秒)* @return void* @note 该函数是基于延迟拥塞控制的入口,负责将反馈信息传递给 InterArrival 和 TrendlineEstimator*/
void DelayBasedBwe::IncomingPacketFeedbackVector(const std::vector<PacketFeedback>& packet_feedbacks,int64_t now_ms) {// 遍历每个包的反馈信息,按包组分组(同一帧的包为一组)for (const auto& feedback : packet_feedbacks) {// 1. 检查包是否属于新的包组(通过序列号判断,同一帧的包序列号连续)if (!inter_arrival_->IsPacketInOrder(feedback.sequence_number)) {// 包乱序,跳过(乱序会导致延迟计算失真)continue;}// 2. 计算当前包组的延迟参数(delta_timestamp、delta_arrival、delta_size)std::optional<InterArrival::Result> result = inter_arrival_->ComputeDeltas(feedback.send_time_ms,  // 包的发送时间feedback.arrival_time_ms,  // 包的到达时间feedback.payload_size,  // 包的 payload 大小feedback.sequence_number,  // 包的序列号now_ms);// 3. 若成功计算出包组延迟参数,更新 Trendline 滤波器if (result) {// 调用 TrendlineEstimator 计算延迟趋势trendline_estimator_->Update(result->delta_send_time_ms,  // delta_timestampresult->delta_arrival_time_ms,  // delta_arrivalresult->delta_payload_size,  // delta_sizenow_ms);// 4. 调用 OveruseDetector 判断网络是否过载OveruseDetector::State overuse_state = overuse_detector_->Detect(trendline_estimator_->trendline_slope(),  // 延迟趋势斜率result->delta_arrival_time_ms,now_ms);// 5. 根据过载状态,通过 AIMD 调节码率aimd_rate_control_->Update(overuse_state,  // 网络过载状态trendline_estimator_->time_since_last_update_ms(),now_ms);}}// 6. 将计算出的 BWE 值(基于延迟)传递给 BitrateControllerint64_t target_bitrate_bps = aimd_rate_control_->GetTargetBitrate();OnDelayBasedBweResult(target_bitrate_bps, now_ms);
}

基于丢包的拥塞控制:SendSideBandwidthEstimation::UpdateEstimate

/*** @brief 基于丢包率更新码率估计,是丢包拥塞控制的核心逻辑* @param now_ms:当前时间(毫秒)* @return void* @note 该函数结合丢包率、历史码率、反馈超时等因素,计算丢包调整后的码率*/
void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) {uint32_t new_bitrate = current_bitrate_bps_;  // 初始化为当前码率// 1. 会话启动初期(前 2 秒)且无丢包:优先使用基于延迟的 BWE 值(快速启动)if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms)) {// 取“基于延迟的 BWE”和“当前码率”的最大值(快速提升码率)new_bitrate = std::max(bwe_incoming_, new_bitrate);new_bitrate = std::max(delay_based_bitrate_bps_, new_bitrate);if (new_bitrate != current_bitrate_bps_) {min_bitrate_history_.clear();  // 清空历史最小码率(启动期无需参考历史)min_bitrate_history_.push_back(std::make_pair(now_ms, current_bitrate_bps_));CapBitrateToThresholds(now_ms, new_bitrate);  // 限制码率在 [min, max] 范围内return;}}// 2. 更新历史最小码率(用于后续码率增长计算)UpdateMinHistory(now_ms);// 3. 无任何反馈(如接收端离线):维持当前码率if (last_packet_report_ms_ == -1) {CapBitrateToThresholds(now_ms, current_bitrate_bps_);return;}// 4. 检查反馈是否超时(反馈间隔是否过长)int64_t time_since_packet_report_ms = now_ms - last_packet_report_ms_;int64_t time_since_feedback_ms = now_ms - last_feedback_ms_;// 5. 反馈未超时:基于丢包率调整码率if (time_since_packet_report_ms < 1.2 * kFeedbackIntervalMs) {// 转换丢包率(RTCP RR 报文中的丢包率是 0~255 的整数,需转为 0~1 的浮点数)float loss = last_fraction_loss_ / 256.0f;// 仅当码率高于阈值时,才基于丢包率调整(过滤非拥塞导致的丢包,如网络抖动)if (current_bitrate_bps_ < bitrate_threshold_bps_ || loss <= low_loss_threshold_) {// 情况1:丢包率 < 2% 或码率过低:码率增长 8% + 1kbps(避免低码率停滞)new_bitrate = static_cast<uint32_t>(min_bitrate_history_.front().second * 1.08 + 0.5);  // 8% 增长,四舍五入new_bitrate += 1000;  // 额外加 1kbps,低码率场景(如 10kbps)效果明显} else if (current_bitrate_bps_ > bitrate_threshold_bps_) {if (loss <= high_loss_threshold_) {// 情况2:丢包率 2%~10%:维持当前码率new_bitrate = current_bitrate_bps_;} else {// 情况3:丢包率 >10%:降低码率(每 kBweDecreaseIntervalMs + RTT 周期仅降一次)if (!has_decreased_since_last_fraction_loss_ &&(now_ms - time_last_decrease_ms_) >= (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) {time_last_decrease_ms_ = now_ms;  // 记录上次降低时间,避免频繁降码率// 码率降低公式:newRate = 当前码率 × (512 - 丢包率×256) / 512 ≈ 当前码率 × (1 - 0.5×丢包率)new_bitrate = static_cast<uint32_t>((current_bitrate_bps_ * static_cast<double>(512 - last_fraction_loss_)) / 512.0);has_decreased_since_last_fraction_loss_ = true;  // 标记已降低,避免重复操作}}}} // 6. 反馈超时(接收端长时间未反馈):降低码率(应对网络断连风险)else if (time_since_feedback_ms > kFeedbackTimeoutIntervals * kFeedbackIntervalMs &&(last_timeout_ms_ == -1 || now_ms - last_timeout_ms_ > kTimeoutIntervalMs)) {if (in_timeout_experiment_) {LOG(LS_WARNING) << "Feedback timed out (" << time_since_feedback_ms << " ms), reducing bitrate.";new_bitrate *= 0.8;  // 超时后码率降低 20%// 重置丢包统计(避免超时后重复处理旧丢包)lost_packets_since_last_loss_update_Q8_ = 0;expected_packets_since_last_loss_update_ = 0;last_timeout_ms_ = now_ms;  // 记录上次超时时间}}// 7. 限制码率在 [min_bitrate_configured_, max_bitrate_configured_] 范围内CapBitrateToThresholds(now_ms, new_bitrate);
}

*融合所有评估结果:SendSideBandwidthEstimation::CapBitrateToThresholds

/*** @brief 融合“基于延迟的 BWE”“基于丢包的 BWE”“REMB”,并限制码率在配置范围内* @param now_ms:当前时间(毫秒)* @param bitrate_bps:待调整的码率(输入值)* @return void* @note 该函数是 Sender Side BWE 的“最终决策层”,输出最终发送码率*/
void SendSideBandwidthEstimation::CapBitrateToThresholds(int64_t now_ms,uint32_t bitrate_bps) {// 1. 若 REMB 有效(兼容老版本),码率不能超过 REMB 值if (bwe_incoming_ > 0 && bitrate_bps > bwe_incoming_) {bitrate_bps = bwe_incoming_;}// 2. 若基于延迟的 BWE 有效,码率不能超过延迟 BWE 值(核心限制)if (delay_based_bitrate_bps_ > 0 && bitrate_bps > delay_based_bitrate_bps_) {bitrate_bps = delay_based_bitrate_bps_;}// 3. 码率不能超过配置的最大码率(开发者可通过 API 设置,如 setMaxBitrate)if (bitrate_bps > max_bitrate_configured_) {bitrate_bps = max_bitrate_configured_;}// 4. 码率不能低于配置的最小码率(避免画面质量过低)if (bitrate_bps < min_bitrate_configured_) {// 每隔 kLowBitrateLogPeriodMs 打印一次警告日志(避免日志刷屏)if (last_low_bitrate_log_ms_ == -1 ||now_ms - last_low_bitrate_log_ms_ > kLowBitrateLogPeriodMs) {LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate_bps / 1000<< " kbps is below configured min bitrate "<< min_bitrate_configured_ / 1000 << " kbps.";last_low_bitrate_log_ms_ = now_ms;}bitrate_bps = min_bitrate_configured_;}// 5. 若码率变化或丢包率变化,记录 RTC 事件日志(用于调试)if (bitrate_bps != current_bitrate_bps_ ||last_fraction_loss_ != last_logged_fraction_loss_ ||now_ms - last_rtc_event_log_ms_ > kRtcEventLogPeriodMs) {event_log_->LogLossBasedBweUpdate(bitrate_bps, last_fraction_loss_,expected_packets_since_last_loss_update_);last_logged_fraction_loss_ = last_fraction_loss_;last_rtc_event_log_ms_ = now_ms;}// 6. 更新当前码率(最终结果)current_bitrate_bps_ = bitrate_bps;
}

码率更新到发送端模块:SendSideCongestionController::MaybeTriggerOnNetworkChanged

/*** @brief 将最终码率更新到发送端各核心模块( pacing、FEC、编码器)* @return void* @note 该函数是 Sender Side BWE 的“执行层”,确保码率调整生效*/
void SendSideCongestionController::MaybeTriggerOnNetworkChanged() {uint32_t bitrate_bps;       // 最终码率(bps)uint8_t fraction_loss;      // 丢包率(0~255)int64_t rtt;                // 网络往返延迟(ms)// 1. 从 BitrateController 获取最新的网络参数(码率、丢包率、RTT)bool estimate_changed = bitrate_controller_->GetNetworkParameters(&bitrate_bps, &fraction_loss, &rtt);// 2. 若码率变化,更新 Pacer(发送 pacing 模块,控制发送速率避免突发)if (estimate_changed) {pacer_->SetEstimatedBitrate(bitrate_bps);  // 调整 pacing 速率probe_controller_->SetEstimatedBitrate(bitrate_bps);  // 调整带宽探测速率retransmission_rate_limiter_->SetMaxRate(bitrate_bps);  // 调整重传速率上限}// 3. 处理网络断连或发送队列满的情况:码率设为 0(暂停发送)bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps;// 4. 若网络参数(码率、丢包率、RTT)变化,通知观察者(如编码器、FEC 模块)if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) {int64_t probing_interval_ms;{rtc::CritScope cs(&bwe_lock_);  // 加锁,线程安全// 获取 BWE 周期(用于后续带宽探测)probing_interval_ms = delay_based_bwe_->GetExpectedBwePeriodMs();}{rtc::CritScope cs(&observer_lock_);  // 加锁,线程安全if (observer_) {// 通知观察者:网络参数变化,需调整编码码率、FEC 冗余度等observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt,probing_interval_ms);// 示例:观察者可能是 VideoEncoder,此时会调用 SetRates(bitrate_bps) 调整编码码率}}}
}

4、开发应用实践:如何基于 Sender Side BWE 优化 WebRTC 应用

4.1 关键配置参数调整(提升通讯质量)

在实际开发中,可通过 WebRTC 的 API 调整以下参数,优化 Sender Side BWE 效果:

参数作用推荐配置API 示例(C++)
最小码率(min_bitrate)避免码率过低导致画面模糊视频通话:300kbps(480P);直播:1Mbps(720P)webrtc::VideoSendStream::Config config; config.min_bitrate_bps = 300000;
最大码率(max_bitrate)避免码率过高导致拥塞基于网络环境:WiFi 设为 8Mbps(1080P);4G 设为 4Mbpsconfig.max_bitrate_bps = 8000000;
BWE 启动期(start_phase_duration)会话初期快速提升码率的时间默认 2000ms(2秒),可根据需求调整为 3000mssend_side_bwe_.SetStartPhaseDurationMs(3000);
丢包率阈值(low_loss_threshold/high_loss_threshold)调整丢包触发码率变化的敏感度弱网环境可降低 high_loss_threshold 至 0.08(8%)send_side_bwe_.SetLossThresholds(0.02f, 0.08f);
4.2 常见问题与解决方案
问题现象可能原因解决方案
会话初期画面卡顿BWE 启动期码率提升过慢1. 延长启动期(SetStartPhaseDurationMs(3000));2. 增大启动期码率增长倍数(需修改 AIMD 源码)
弱网环境下码率频繁波动延迟抖动导致 OveruseDetector 误判1. 增大 Trendline 滤波器的 alpha 值(如 0.95);2. 提高过载检测的阈值 gamma_1
码率始终低于配置的最小码率网络拥塞严重,BWE 计算结果过低1. 检查是否配置了正确的最小码率;2. 优化视频编码参数(如降低分辨率、提高压缩率)
4.3 调试工具与日志分析

开发中可通过以下工具分析 Sender Side BWE 的运行状态:

  1. RTC 事件日志:通过 event_log_->LogLossBasedBweUpdate 记录码率、丢包率变化,可使用 WebRTC 提供的 rtc_event_log_analyzer 工具可视化分析;
  2. Wireshark 抓包:过滤 TransportCC(RTCP 类型 205)或 REMB(RTCP 类型 206)报文,查看接收端反馈的延迟和丢包信息;
  3. WebRTC 内置 metrics:通过 webrtc::Metrics 模块获取 bwe_delay_based_bitratebwe_loss_based_bitrate 等指标,实时监控 BWE 计算结果。
http://www.dtcms.com/a/540051.html

相关文章:

  • 102-Spring AI Alibaba RAG Pgvector 示例
  • 【刷机分享】解决K20Pro刷入PixelOS后“网络连接”受限问题(附详细ADB命令)
  • Rust 语言入门基础教程:从环境搭建到 Cargo 工具链
  • 【Linux】HTTPS协议
  • node.js 和npm 搭建项目基本流程
  • 【STM32】PWR电源控制
  • 做网页局域网站点配置wordpress仿简书主题
  • 《Linux篇》进程控制——进程创建(写时拷贝)、进程终止(退出码,exit,_exit)
  • 【MATLAB 数据分析学习指南】
  • Android PDF 操作 - AndroidPdfViewer 显示 PDF 异常清单(数据为 null、数据为空、PDF 文件损坏、非 PDF 文件)
  • 界面控件DevExpress WPF v25.2预览 - 模板工具包全新升级
  • 【音视频】H264中的SPS和PPS
  • ThinkPHP6 集成TCP长连接 GatewayWorker
  • TMap的查询
  • SpringCloud--Sleuth 解析
  • 【C++:继承和多态】多态加餐:面试常考——多态的常见问题11问
  • 零基础新手小白快速了解掌握服务集群与自动化运维(十五)Redis模块-哨兵集群
  • 今日Cortex-M3/M4研究总结
  • 2014吉林省赛题解 | CCUT应用OJ题解——Sign in
  • 涿州网站建设推广浙江建筑信息网站
  • 前端性能优化实战指南:从首屏加载到用户体验的全面提升
  • 【OPENGL ES 3.0 学习笔记】第十一天:glDrawArrays和glDrawElements
  • Linux入门1(2/2)
  • ubuntu24安装mysql遇到的坑----解决Mysql报错缺少libaio.so.1
  • 【星光不负 码向未来 | 万字解析:基于ArkUI声明式UI与分布式数据服务构建生产级跨设备音乐播放器】
  • UniApp 在手机端(Android)打开选择文件和文件写入
  • HarmonyOS分布式媒体播放器——跨设备音视频无缝流转
  • 【金融行业案例】基于Vaadin全栈Java框架重构内部系统,全面提升开发效率与用户体验
  • 小型网站开发要多少钱苏州专业做网站的公司哪家好
  • RocketMQ 生产环境性能调优实战:从 0 到 1 打造高可用消息队列系统