剑痴乎

  • 首页
  • 文章分类
    • 音视频
    • WebRTC
    • 编程之美
    • Linux
    • Windows
    • 生活点滴
    • 校园生活
  • 参考
    • API参考
    • 实用工具
    • 测试音视频
    • 文档
  • 留言板
  • 关于
剑痴乎
代码为剑,如痴如醉
  1. 首页
  2. WebRTC
  3. 正文

浅谈基于SFU实现一对一效果

2024年11月7日 20点热度 0人点赞 0条评论

基于SFU架构的视频会议系统中,Simulcast是最主流的带宽自适应方案。发布端(Publisher)同时编码并发送多路不同分辨率的流(通常为小、中、大三路),订阅端(Subscriber)则根据自身网络带宽、设备性能、窗口大小等因素,选择订阅最合适的单路流。这种设计发布端与订阅端互不干扰:

  • 发布端仅受自身上行带宽和编码负载影响
  • 订阅端仅受自身下行带宽,解码能力,显示窗口影响


但在实际生产环境中,某些核心场景却需要订阅端能够“反向影响”发布端,即实现backpressure(反压)机制。

反压需求场景

按需推流

当会议中所有订阅端都处于小窗口显示(如宫格数较多、缩略图模式)时,大家只会订阅小流。此时发布端若仍持续推送大流,就会造成巨大的上行带宽浪费和服务器转发压力。理想状态是:订阅端集体选择小流 → SFU 通知发布端自动降档,只推小流即可。

SFU模拟点对点(P2P)通话

用SFU统一实现1对1通话(便于后续扩展多人)。此时必须达到原生P2P(ICE直连)的体验。

  • 订阅端网络恶化时,不能仅靠切换Simulcast层(因为只有一层流),而应直接让发布端降低编码码率/分辨率
  • 订阅端网络恢复后,发布端也要快速回升

在传统Simulcast中做不到这样的“端到端拥塞控制”。

SFU如何实现订阅端反压

核心思路:在SFU内部为每个发布源(Source)和每个订阅接收器(Sink) 建立反馈通道,让订阅客户端的带宽估计结果能够传递到发布客户端。
下面是实现原理图:

  • 发布客户端 → RTP → SFU Source(发布源)
  • SFU Sink(订阅接收器)收到订阅端发来的 Transport-CC报文,进行下行带宽估计
  • Sink通过onFeedback接口将估计带宽值传递给对应的Source
  • Source封装REMB(Receiver Estimated Maximum Bitrate)RTCP报文,传回到发布客户端
  • 发布客户端收到REMB后,强制限制自身带宽估计值

这样就实现了订阅端 → SFU → 发布端的完整反压闭环。

REMB RTCP报文复用

WebRTC早期就内置了REMB RTCP,用在最早的接收端带宽估计中,接收端的带宽估计就是通过REMB反馈到发布端。虽然现在是Transport-CC + Sendside BWE,但REMB仍然被支持。这里可以看下REMB报文格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
//
//     0                   1                   2                   3
//     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//    |V=2|P| FMT=15  |   PT=206      |             length            |
//    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//  0 |                  SSRC of packet sender                        |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  4 |                       Unused = 0                              |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  8 |  Unique identifier 'R' 'E' 'M' 'B'                            |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 12 |  Num SSRC     | BR Exp    |  BR Mantissa                      |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 16 |   SSRC feedback                                               |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//    :  ...            

对于SFU,带宽反馈处理只需在 Source 侧调用:

1
2
3
4
5
6
7
8
9
10
11
// Sink带宽估计后调用
void Sink::OnBandwidthEstimate(DataRate estimate) {
    source_->OnFeedback(estimate);  // 通知对应的的Source
}
 
// Source收到后下发REMB
void Source::OnFeedback(DataRate bandwidth) {
    if (publisher_session_) {
        publisher_session_->SendRtcpREMB(bandwidth);
    }
}

发布客户端中WebRTC收到REMB后的处理如下:

C++
1
2
3
4
5
6
// Call when we receive a RTCP message with TMMBR or REMB.
void SendSideBandwidthEstimation::UpdateReceiverEstimate(Timestamp at_time,
                                                         DataRate bandwidth) {
  receiver_limit_ = bandwidth.IsZero() ? DataRate::PlusInfinity() : bandwidth;
  ApplyTargetLimits(at_time);
}

至此我们完成初步的反压实现。

遗留问题:弱网解除后带宽恢复速度慢

前面实现后还有个问题,就是订阅端弱网恢复后,恢复之前码率较慢。原因如下:

  • 订阅端之前带宽差 → SFU反馈低REMB → 发布端码率被压得很低
  • 订阅端网络恢复 → 其BWE想提升,但实际收到的码率仍然很低(受发布端限制)
  • 订阅端BWE探测不到更高带宽 → 继续反馈低REMB → 发布端无法提升 → 形成“死循环”

这就像“受制于人”,恢复速度远慢于原生的P2P实现。

这时候我们可以在SFU的Sink(下行)侧中,主动注入探测流量,也就是引入探测(Padding)包。让订阅端能够获得额外码率进行更大带宽探测,打破死循环,加快恢复到之前码率。

总结

通过以上机制,SFU不仅保留了Simulcast的灵活性,还具备了端到端拥塞控制能力,让视频会议在复杂网络环境下也能提供接近原生P2P的流畅体验。

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
标签: WebRTC 网络
最后更新:2026年3月14日

Jeff

管理员——代码为剑,如痴如醉

打赏 点赞
< 上一篇

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理。

文章目录
  • 反压需求场景
    • 按需推流
    • SFU模拟点对点(P2P)通话
  • SFU如何实现订阅端反压
    • REMB RTCP报文复用
  • 遗留问题:弱网解除后带宽恢复速度慢
  • 总结
相关文章
  • WebRTC音视频传输基础:NAT穿透
  • WebRTC研究:统计参数之往返时延
  • WebRTC研究:Transport-cc之RTP及RTCP
  • WebRTC研究:丢包判断
  • WebRTC研究:RTP中的序列号以及时间戳比较

COPYRIGHT © 2026 jianchihu.net. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang