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日 3141hotness 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
    Leave a Reply to Justin 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