剑痴乎

剑痴乎
代码为剑,如痴如醉
  1. 首页
  2. WebRTC
  3. 正文

WebRTC研究:音频带内FEC

2020年10月24日 4321点热度 9人点赞 6条评论

在WebRTC中,对于音频丢包,目前有三种丢包恢复方案:

  • 带内FEC
  • 带外FEC
  • NACK

本文介绍其中最简单的带内FEC。带内FEC属于WebRTC中默认启用的功能,由Opus编解码器实现,经过我们测试,30%随机丢包率下语音聊天,仍有不错的质量。不过单一靠带内FEC是无法实现更高的抗丢包要求,例如突发丢包环境或者30%以上随机丢包率,这也是各个厂商的优化点。

Opus编解码器

Opus编解码器其实是一种混合音频编解码器,融合了SILK与CELT两种编解码器。

SILK编解码器

  • 由Skype开发
  • 使用线性预测
  • 适合语音

CELT编解码器

  • 由Xiph.Org开发
  • 使用改进的离散余弦变换
  • 适合音乐等音质要求高的

支持特性

  • FEC(Forward Error Correction):前向纠错。使用低码率编码前面音频包数据,作为冗余信息。
  • DTX(Discontinuous Transmission):非连续传输。在安静的情况时自动降低编码码率。
  • PLC(Packet Loss Concealment):丢包隐藏。在解码端实现。通过前面音频数据包和后面音频数据包的相关性来预测当前丢失的音频数据包,对丢失的音频数据包进行补偿,隐藏当前的丢包错误。

关于Opus中SILK与CELT为什么在一起的故事,大家可以看下声网社区分享的这一篇文章:
编解码器杂谈:浅析Opus

带内FEC原理

使用低码率编码前面的历史音频包数据,作为冗余信息插入当前音频包中,同时结合解码端的PLC处理,从而实现不错的丢包恢复效果。

假设当前音频包采样时间为T,采样间隔为Δ,那么某音频编码后数据如下:

1
Audio Encoded Data: | T | T - Δ |

携带T时刻编码数据,以及低码率编码的T - Δ时刻数据。

假设Δ为1,时间戳T从1开始,那么前6个包数据如下:

1
|1| | -> |2|1| -> |3|2| -> |4|3| -> |5|4| -> |6|5|

如果时刻4的包丢了,那么接收端可以从时刻5的数据包恢复时刻4数据。

如果出现突发连续丢包,例如时刻4,5的数据包都丢了,那么时刻4数据就无法还原了,此时就要通过PLC算法进行丢包恢复。当然,如果使用了带外FEC以及NACK,也可以配合带内FEC用于丢包恢复。

代码导读

带内FEC整个闭环处理比较简单:

  • 从Receiver Report中获取丢包率
  • 平滑处理丢包率
  • 平滑后的丢包率反馈给Opus编码器

AudioEncoderOpusImpl::OnReceivedUplinkPacketLossFraction负责相关处理。
接收通过RTCP反馈的丢包率,传给Opus编码器。

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void AudioEncoderOpusImpl::OnReceivedUplinkPacketLossFraction(
    float uplink_packet_loss_fraction) {
  if (audio_network_adaptor_) {
    audio_network_adaptor_->SetUplinkPacketLossFraction(
        uplink_packet_loss_fraction);
    ApplyAudioNetworkAdaptor();
  }
  // 对丢包率进行平滑处理
  packet_loss_fraction_smoother_->AddSample(uplink_packet_loss_fraction);
  float average_fraction_loss = packet_loss_fraction_smoother_->GetAverage();
  SetProjectedPacketLossRate(average_fraction_loss);
}
 
void AudioEncoderOpusImpl::SetProjectedPacketLossRate(float fraction) {
  // 允许的最大丢包率为20%
  fraction = std::min(std::max(fraction, 0.0f), kMaxPacketLossFraction);
  if (packet_loss_rate_ != fraction) {
    packet_loss_rate_ = fraction;
    // 传递丢包率到Opus编码器
    RTC_CHECK_EQ(
        0, WebRtcOpus_SetPacketLossRate(
               inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5)));
  }
}

SDP处理

这里我们看下使用Opus编码器时默认生成的SDP:

1
2
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1

可以看到useinbandfec=1字段,表示开启带内FEC,最后通过WebRtcOpus_EnableFec接口启用带内FEC功能。

优势与不足

由于带内FEC由编解码器实现,所以我们的工作量很少,可以很方便地将音频FEC的能力集成到我们的应用中。不过带内FEC中,音频包的冗余信息用的是低码率编码,所以还原后的音质会降低。

参考

[1] RTP Payload Format for the Opus Speech and Audio Codec.https://tools.ietf.org/html/rfc7587.

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

Jeff

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

打赏 点赞
< 上一篇
下一篇 >

文章评论

  • ewan

    大佬你好,请教下,你说的音频带外fec+nack的模式,是webrtc源生支持的吗

    2021年3月1日
    回复
    • Jeff

      @ewan 是的,不过WebRTC的实现很初级

      2021年3月1日
      回复
  • sshsu

    博主,想请教一个问题,关于webrtc的fec的rate的设置, 这个函数
    bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
    主要会根据当前帧的分辨率,码率和丢包率,从一个表中查到fec应该设的冗余度,但是在计算码率的时候使用了resolnFac对码率进行缩放,不太理解后面的思想,博主能看出来吗

    2021年8月21日
    回复
  • ppp

    WebRTC的音频带外 FEC 实现指的是哪些类呢?

    2022年6月8日
    回复
  • sola

    大佬,你好,请教一下这个默认值为什么最大只允许%20,提高会有什么负面作用吗, 比如%8 90 ? ,这边尝试写死 0.8 抗丢包能力会有大幅提升。

    2023年4月26日
    回复
    • Jeff

      @sola 同样编码码率情况下,提高这个值会导致音质降低,看你们怎么权衡了

      2023年5月17日
      回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复

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

    版权声明

    为支持原创,创作更好的文章,未经许可,禁止任何形式的转载与抄袭,如需转载请邮件私信!本人保留所有法定权利。违者必究!

    文章目录
    • Opus编解码器
    • 带内FEC原理
    • 代码导读
    • SDP处理
    • 优势与不足
    • 参考
    最近评论
    ztt 发布于 3 周前(04月05日) 你好,想看里面的视频和图片为什么没有显示呢?需要下flash吗还是什么。
    huowa222 发布于 4 周前(03月26日) 同问
    邱国禄 发布于 2 个月前(02月17日) Receive Delta以0.25ms为单位,reference time以64ms为单位,kDe...
    啊非 发布于 4 个月前(12月30日) 大神,请教一个问题: constexpr int kBaseScaleFactor = Tran...
    啊非 发布于 4 个月前(12月30日) reference time:3字节,表示参考时间,以64ms为单位,但是 代码里面是 Trans...
    相关文章
    • WebRTC资讯:H265支持进展
    • WebRTC研究:Audio level
    • Mac平台WebRTC编译
    • WebRTC研究:RTP时间戳的产生
    • WebRTC研究:统计参数之丢包率

    COPYRIGHT © 2024 jianchihu.net. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang