WebRTC-nack机制详解

1.NACK的含义

丢包重传(NACK)是抵抗网络错误的重要手段。NACK在接收端检测到数据丢包后,发送NACK报文到发送端;发送端根据NACK报文中的序列号,在发送缓冲区找到对应的数据包,重新发送到接收端。NACK需要发送端,发送缓冲区的支持。

WebRTC中支持音频和视频的NACK重传。我们这里只分析nack机制,不分析jitterbuffer或者neteq的更多实现。

2.WebRTC中NACK请求发送的条件

这里以视频为例。

下面是webrtc中接收端触发nack的条件,我们看下nack_module.cc文件中OnReceivedPacket的实现。

void NackModule::OnReceivedPacket(const VCMPacket& packet) {
  rtc::CritScope lock(&crit_);
  if (!running_)
    return;
  //获取包的seqnum
  uint16_t seq_num = packet.seqNum;
  // TODO(philipel): When the packet includes information whether it is
  //                 retransmitted or not, use that value instead. For
  //                 now set it to true, which will cause the reordering
  //                 statistics to never be updated.
  bool is_retransmitted = true;
  //判断第一帧是不是关键帧
  bool is_keyframe = packet.isFirstPacket && packet.frameType == kVideoFrameKey;
//拿到第一个包的时候判断,把第一个包的seqnum赋值给最新的last_seq_num,如果是关键帧的话,插入到关键帧列表中,同时把initialized_设置为true
  if (!initialized_) {
    last_seq_num_ = seq_num;
    if (is_keyframe)
      keyframe_list_.insert(seq_num);
    initialized_ = true;
    return;
  }

  if (seq_num == last_seq_num_)
    return;
//判断有无乱序,乱序了,如来1,2,3,6包,然后来4包,就乱序了,就把4从nack_list中去掉,不再通知发送端重新发送4了
  if (AheadOf(last_seq_num_, seq_num)) {
    // An out of order packet has been received.
    //把重新收到的包从nack_list中移除掉
    nack_list_.erase(seq_num);
    if (!is_retransmitted)
      UpdateReorderingStatistics(seq_num);
    return;
  } else {
  //没有乱序,如1,2,3,6包,就把(3+1,6)之间的包加入到nack_list中
    AddPacketsToNack(last_seq_num_ + 1, seq_num);
    last_seq_num_ = seq_num;

    // Keep track of new keyframes.
    if (is_keyframe)
      keyframe_list_.insert(seq_num);

    // And remove old ones so we don't accumulate keyframes.
    auto it = keyframe_list_.lower_bound(seq_num - kMaxPacketAge);
    if (it != keyframe_list_.begin())
      keyframe_list_.erase(keyframe_list_.begin(), it);

    // Are there any nacks that are waiting for this seq_num.
    //从nack_list 中取出需要发送 NACK 的序号列表, 如果某个 seq 请求次数超过 kMaxNackRetries = 10次则会从nack_list 中删除.
    std::vector<uin
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值