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研究:统计参数之抖动

2021年3月14日 5219hotness 17likes 8comments

当我们调试WebRTC web客户端时,经常会打开chrome://webrtc-internals/这个页面,在这里我们可以看到音视频流的各种统计。今天我们就来看下其中的一个统计参数:抖动(jitter)。

什么是抖动

在网络传输中,每个包从发送端到接收端的时延都是不相同的,而jitter就是用来衡量这种不同。一般在发送端,数据包发送时间间隔是相同的,也就是均匀发送数据,但是传输过程中由于各种情况,例如拥塞,丢包,网络错误等,接收端收到的数据包间隔就会不一样,可能一会大,一会小,导致时延发生变化,这个时延的变化程度就是所谓的抖动,接收端如果不做任何处理,就会影响用户体验。例如对于视频来说,会导致帧率变化,视频播放就不平滑,有卡顿感。如下图片是抖动的一个形象描述。
jitter
WebRTC内部通过NetEQ与JitterBuffer进行音视频的抖动处理,消除抖动造成的影响,这些会在我的后续文章介绍。

抖动计算

根据RFC3550,假设RTP包i,RTP报头记录的时间戳为Si(单位为采样率),到达接收端的时间为Ri(单位同样为采样率),对于包i,j,我们定义一个变量\(D\),描述两个包时间的差异,由接收时间差减去发送时间差:
\[D(i,j) = (Rj - Ri) - (Sj - Si) = (Rj - Sj) - (Ri - Si)\tag{1}\]
抖动\(J\)按如下公式定义:
\[J(i) = J(i-1) + (|D(i-1,i)| - J(i-1))/16\tag{2}\]
上述公式中i-1指的是前一个收到的包,不是按RTP序列号计数的。增益参数1/16是为了消除噪声影响,使抖动收敛在较合理范围内,避免突发数据的影响。

由公式可知,如果接受端收到的包间隔跟发送端发送间隔一样,那么抖动为0。

代码导读

WebRTC统计参数中的抖动计算代码位于StreamStatisticianImpl::UpdateJitter中,看下如何计算。
1)计算接收时间差,也就是\(Ri - R_{i-1}\):

1
2
3
4
5
  // 计算接收时间差
  int64_t receive_diff_ms = receive_time_ms - last_receive_time_ms_;
  // 接收时间差:ms时间单位转换为采样率描述的时间单位
  uint32_t receive_diff_rtp = static_cast<uint32_t>(
      (receive_diff_ms * packet.payload_type_frequency()) / 1000);

2)计算\(|D(i-1,i)|\),其中发送时间为RTP报头记录的时间戳:

1
2
3
4
5
  // D:接收时间差 - 发送时间差
  int32_t time_diff_samples =
      receive_diff_rtp - (packet.Timestamp() - last_received_timestamp_);
 
  time_diff_samples = std::abs(time_diff_samples);

3)由公式(2),使用jitter_diff表示\(|D(i-1,i)|-J(i-1)\):
\[jitter\_diff = time\_diff\_samples - J(i-1)\tag{3}\]
\[J(i) = J(i-1) + jitter\_diff/16\tag{4}\]
所以相关代码如下:

1
2
3
4
5
6
7
8
9
10
11
  // lib_jingle sometimes deliver crazy jumps in TS for the same stream.
  // If this happens, don't update jitter value. Use 5 secs video frequency
  // as the threshold.
  // 由于一般视频的时钟采样率为90kHz,5S用采样率单位表示刚好是450000
  if (time_diff_samples < 450000) {
    // 根据公式(3)计算jitter_diff:q4后缀表示左移4位,也就是乘以16
    // 两边同乘以16,也就是<<4,这样做是为了避免计算使用float表示
    int32_t jitter_diff_q4 = (time_diff_samples << 4) - jitter_q4_;
    // 根据公式(4)更新jitter_q4_:(jitter_diff_q4 + 8)是为了四舍五入
    jitter_q4_ += ((jitter_diff_q4 + 8) >> 4);
  }

至此我们得到了jitter_diff_q4,单位为采样率,如果需要转换为毫秒时间单位,需要如下计算:
1)由于jitter_diff_q4放大了16倍,首先需要还原回去:

1
jitter = jitter_q4_ >> 4;

2)转换为毫秒单位:

1
2
// 一般视频的时钟采样频率clockrate_hz为:90kHz
jitter_ms = jitter / (clockrate_hz / 1000);

这样我们就得到了以毫秒表示的抖动统计参数,chrome://webrtc-internals/中抖动的单位是秒。

参考

[1] Jitter.https://en.wikipedia.org/wiki/Jitter.
[2] RFC3550.https://tools.ietf.org/html/rfc3550.

This article is licensed with Creative Commons Attribution-NonCommercial-No Derivatives 4.0 International License
Tag: WebRTC
Last updated:2022年3月27日

Jeff

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

Tip the author Like
< Last article
Next article >

Comments

  • MarkCao

    谢谢Jeff,讲解的很清晰,受教了。
    另外文中有一处笔误:“到达接收端的时间为Si(根据上下文应该是Ri)(单位同样为采样率)“。

    2021年6月11日
    Reply
    • Jeff

      @MarkCao 已纠正

      2021年6月11日
      Reply
  • MarkCao

    补充一点自己的理解:RTP包的时间戳timestamp虽然是用64位表示,但是webrtc中只用了32位表示,即整数和小数部分个16位,即4个字节。这也就是计算jitter_diff时使用Q4格式来避免浮点计算的原因。

    2021年6月11日
    Reply
  • xman

    公式写错了吧,应该是J(i)=J(i−1)+( 16*|D(i−1,i)| −J(i−1) ) / 16

    2023年2月11日
    Reply
  • hello123#

    // 两边同乘以16,也就是<<4,这样做是为了避免计算使用float表示
    int32_t jitter_diff_q4 = (time_diff_samples << 4) - jitter_q4_; 这个段代码,为什么 jitter_q4没有<<4呢

    2024年2月20日
    Reply
    • hello123#

      @hello123# 理解了 不用回复了 谢谢

      2024年2月20日
      Reply
      • mj

        @hello123# 能不能讲一下呢,我也没理解

        2024年6月27日
        Reply
      • mj

        @hello123# 突然懂了

        2024年6月27日
        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
    • 浅谈基于SFU实现一对一效果
    • WebRTC资讯:H265支持进展
    • Protected: WebRTC硬件编解码器出错无缝切换软编软解
    • WebRTC研究:Audio level
    • Mac平台WebRTC编译
    Categories

    COPYRIGHT © 2026 jianchihu.net. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang