JCHub

  • Home
  • Category
    • A/V
    • WebRTC
    • Beauty of Programming
    • Linux
    • Windows
    • Moments of Life
    • Campus Life
  • Reference
    • API Reference
    • Utilities
    • AV Test
    • Doc
  • Message Board
  • About
JCHub
Code as My Sword, Lost in Obsession
  1. Main page
  2. WebRTC
  3. Main content

WebRTC研究:丢包判断

2019年9月2日 3134hotness 11likes 3comments

使用RTP协议封装数据时,我们可以通过RTP报头的序列号连续性判断是否丢包。但由于RTP报头序列号只有两字节表示,值范围[0,65535],存在回绕问题(参考之前文章:WebRTC研究:RTP中的序列号以及时间戳比较,建议先阅读一遍此文章)。所以判断序列号连续性时得考虑回绕问题。下面我们就结合WebRTC这相关源码,讲下如何有效地根据序列号进行丢包判断。

首先看下这块代码,代码位于jitter_buffer.cc中:

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
25
26
27
28
bool VCMJitterBuffer::UpdateNackList(uint16_t sequence_number) {
  // Make sure we don't add packets which are already too old to be decoded.
  if (!last_decoded_state_.in_initial_state()) {
    latest_received_sequence_number_ = LatestSequenceNumber(
        latest_received_sequence_number_, last_decoded_state_.sequence_num());
  }
  if (IsNewerSequenceNumber(sequence_number,
                            latest_received_sequence_number_)) {
    // Push any missing sequence numbers to the NACK list.
    for (uint16_t i = latest_received_sequence_number_ + 1;
         IsNewerSequenceNumber(sequence_number, i); ++i) {
      missing_sequence_numbers_.insert(missing_sequence_numbers_.end(), i);
    }
    if (TooLargeNackList() && !HandleTooLargeNackList()) {
      RTC_LOG(LS_WARNING) << "Requesting key frame due to too large NACK list.";
      return false;
    }
    if (MissingTooOldPacket(sequence_number) &&
        !HandleTooOldPackets(sequence_number)) {
      RTC_LOG(LS_WARNING)
          << "Requesting key frame due to missing too old packets";
      return false;
    }
  } else {
    missing_sequence_numbers_.erase(sequence_number);
  }
  return true;
}

IsNewerSequenceNumber函数以及latest_received_sequence_number_介绍在之前文章说过,读者可参考前面给的文字链接。上述代码丢包判断用到的相关定义如下:

  • IsNewerSequenceNumber:判断是否是最新的序列号
  • sequence_number:当前收到的包序列号
  • latest_received_sequence_number_:上一次收到的最新RTP包序列号
  • missing_sequence_numbers_:存储丢包序列号

丢包判断流程如下:

  • 首先IsNewerSequenceNumber传入当前收到的包序列号sequence_number以及之前收到的最新RTP包序列号latest_received_sequence_number_,判断当前RTP包是否是新的数据包,而不是重传包或者乱序包
  • 在for循环中,从latest_received_sequence_number_ + 1开始判断(因为如果丢包了,两个包序列号间隔大于1),满足IsNewerSequenceNumber(sequence_number, i)则说明i为丢失的RTP包序列号,插入missing_sequence_numbers_中,接着++i继续判断,否则退出

通过如上方法,我们就可以获取那些丢失的包序列号,是不是很简单。

This article is licensed with Creative Commons Attribution-NonCommercial-No Derivatives 4.0 International License
Tag: WebRTC 网络 音视频
Last updated:2021年3月16日

Jeff

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

Tip the author Like
< Last article
Next article >

Comments

  • Justin

    有问题请教大佬-qq1447382485

    2020年3月30日
    Reply
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    Cancel

    This site uses Akismet to reduce spam. Learn how your comment data is processed.

    Related Posts
    • WebRTC研究:Transport-cc之RTP及RTCP
    • WebRTC音视频传输基础:NAT穿透
    • WebRTC研究:RTP中的序列号以及时间戳比较
    • 浅谈基于SFU实现一对一效果
    • WebRTC研究:统计参数之往返时延
    Categories

    COPYRIGHT © 2026 jianchihu.net. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang