流媒体弱网优化之路(FEC+mediasoup)——mediasoup的Nack优化以及FEC引入

本文详细介绍了在流媒体传输中针对弱网环境的优化策略,主要涉及mediasoup的Nack优化和FEC(前向纠错)的引入。首先,通过调整Nack的重传间隔和次数,降低了卡顿率。然后,针对10%丢包场景,引入FlexFEC方案,进一步提高了抗丢包能力,实现了无感知优化。测试结果显示,优化后卡顿率显著下降,提升了用户体验。

流媒体弱网优化之路(FEC+mediasoup)——mediasoup的Nack优化以及FEC引入

——
我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost

目标:可以让大家熟悉各类Qos能力、带宽估计能力,提供每个环节关键参数调节接口并实现一个json全配置,提供全面的可视化算法观察能力。

欢迎大家使用
——


一、mediasoup上行情况

  最近对mediasoup进行了一部分的上行弱网优化工作,在这里对之前的优化工作做一些总结和分析。按照惯例,在开始讲关键内容前先把mediasoup上行数据传输以及控制手段进行简单的介绍。
在这里插入图片描述
  例如上述的图中展示的数据流向。发送端中完整地使用了webrtc中的tcc带宽估计以及Nack模块。当数据包传输时,可以识别网络的带宽突变,同时也具备一定的丢包重传能力。

二、纯Nack优化的效果

2.1 方案

  事实上,这远远达不到我们生产开发中的要求。在实际的测试中,我们拉流的播放端在不扩大缓存(增大延迟)、慢放的情况下,10%的丢包就已经出现比较明显的卡顿情况。这类卡顿造成的原因主要来自于下行数据包的延迟到达或者丢失。因此,我们前段时间做的Nack优化提出了——在保证数据包完整到达的同时还要保证足够快地补偿给对端 弱网优化之路(NACK)——纯NACK方案的优化探索
  根据我们的Nack优化思路,我们把 RTC/NackGenerator.cpp 部分函数的代码修改成了这样:

  /* Static. */

  constexpr size_t MaxPacketAge{
   
    10000u };
  constexpr size_t MaxNackPackets{
   
    1000u };
  constexpr uint32_t DefaultRtt{
   
    100u };
  // constexpr uint8_t MaxNackRetries{ 10u };
  // constexpr uint64_t TimerInterval{ 40u };

  // =================== nack test ===================
  constexpr uint8_t MaxNackRetries{
   
    20u };
  constexpr uint64_t TimerInterval{
   
    20u };
  // =================== nack test ===================  

...

  // =================== nack test ===================
  double NackGenerator::CalculateRttLimit2SendNack(int tryTimes) {
   
   
    return tryTimes < 3 ?  (double)(tryTimes*0.4) + 1 : 2;
  }
  // =================== nack test ===================
  std::vector<uint16_t> NackGenerator::GetNackBatch(NackFilter filter)
  {
   
   
    MS_TRACE();

    uint64_t nowMs = DepLibUV::GetTimeMs();
    std::vector<uint16_t> nackBatch;

    auto it = this->nackList.begin();

    while (it != this->nackList.end())
    {
   
   
      NackInfo& nackInfo = it->second;
      uint16_t seq       = nackInfo.seq;

      // clang-format off
      if (
          filter == NackFilter::SEQ &&
          nackInfo.sentAtMs == 0 &&
          (
              nackInfo.sendAtSeq == this->lastSeq ||
              SeqManager<uint16_t>::IsSeqHigherThan(this->lastSeq, nackInfo.sendAtSeq)
              )
              )
        // clang-format on
        {
   
   
        nackBatch.emplace_back(seq);
        nackInfo.retries++;
        auto oldMs = nackInfo.sentAtMs;
        nackInfo.sentAtMs = nowMs;

        if (oldMs == 0) {
   
   
          oldMs = nowMs;
        }

        if (nackInfo.retries >= MaxNackRetries)
        {
   
   
          MS_WARN_TAG(
              rtx,
              "sequence number removed from the NACK list due to max retries [filter:seq, seq:%" PRIu16
              "]"
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值