Skip to content

译文说明

本文由 Hy4 preview 机器翻译自韩文原文,仅供参考。技术细节请以韩文原文为准。

卡顿为何发生在画面黑场区间之后 ​

只要 VBR 编码的码率塌陷区间骗过了播放器的 ABR 判断,卡顿反而会出现在画面重新变亮之后。

先说观测到的现象 ​

这是实际运营中的直播频道发生过的事。那是一场 4 小时的活动,按 CDN 边缘节点统计的最高带宽约为 824.47 Mbps。编码器、打包器、CDN、网络各方面都没有资源异常。但运营期间的监控指标中,却观测到只有卡顿曲线出现瞬时飙升的区间。

按顺序过了一遍检查清单,全部干净。

检查项结果
CDN 边缘节点 5xx、超时比例无变化
源站 CPU、内存、带宽余量充足
源站响应时间分布(p50 / p99)与平时一致
分片生成间隔、清单更新延迟正常
网络区间丢包无显著数值
编码器输入丢帧无

注意:出现这种组合,就意味着分发链路没有问题。那么剩下的只有两处:内容本身,以及播放器的判断逻辑。

把时间轴叠在一起看 ​

我把打包器输出的编码质量按时间轴提取出来,与原始视频并排放在一起。

1080p rendition 输出码率在原始视频黑场区间塌陷后恢复、卡顿尖峰紧随其后出现的时差图

关键有两点。

  1. VBR 输出码率先急剧下降,随后又急剧上升。
  2. 码率偏低的约 7 秒区间,与原始视频约 8 秒的黑场区间完全重合。

而且卡顿尖峰并非出现在码率下降时,而是出现在码率重新回升之后。正是这个时间差揭示了该现象的本质。

VBR 的正常行为如何变成陷阱 ​

VBR 会根据画面复杂度分配不同的比特。画面运动多、细节多时就多用比特,画面静止或偏暗时就少用。黑场区间对编码器而言是最容易压缩的画面,因为 residual 几乎没有。于是码率会跌到谷底。

这不是缺陷,恰恰是 VBR 正常工作的证据。问题在于这一现象会在 ABR 阶梯的所有层级上同时发生。

rendition目标码率运动区间实测黑场区间实测(估算)
1080p8 Mbps约 8 Mbps1 Mbps 以下
720p4 Mbps约 4 Mbps1 Mbps 以下
480p2 Mbps约 2 Mbps1 Mbps 以下
360p1 Mbps约 1 Mbps1 Mbps 以下

参考:在黑场区间,所有画质等级的实际码率会挤到一起。如果 1080p 和 360p 都在 1 Mbps 以下,那么那一刻的阶梯就不是台阶,而是一块平地。

播放器侧的行为 ​

ABR 逻辑大致是这样工作的。

추정 대역폭 = 방금 받은 세그먼트 크기(bit) / 다운로드에 걸린 시간(s)

if (추정 대역폭 > 상위 rendition 선언 비트레이트 x safety factor) {
    상위 rendition으로 전환
}

这里漏掉了一个事实:作为分子的分片大小会随内容复杂度变化。我们以一个带宽为 1 Mbps 的用户为例来计算。

[움직임 구간, 360p 시청 중]
  세그먼트: 6초 x 1 Mbps = 약 0.75 MB
  다운로드 시간: 0.75 MB / (1 Mbps) = 약 6초
  추정 대역폭 = 1 Mbps          -> 360p 유지, 정확한 판단

[암전 구간, 360p 시청 중]
  세그먼트: 6초 x 0.3 Mbps = 약 0.22 MB   (VBR이 비트를 덜 씀)
  다운로드 시간: 0.22 MB / (1 Mbps) = 약 1.8초
  추정 대역폭 = 6초 분량을 1.8초에 받았으니 약 3.3 Mbps로 계산됨
                                -> "네트워크가 좋아졌다" 판단
                                -> 720p 또는 1080p로 상향

[암전 종료, 1080p 시청 중]
  세그먼트: 6초 x 8 Mbps = 약 6 MB
  다운로드 시간: 6 MB / (1 Mbps) = 약 48초
  6초 분량을 48초에 받는 중 => 버퍼 고갈 => 버퍼링 발생

参考:用户的实际带宽从 1 Mbps 起一个字节都没变。但播放器却判断带宽变宽了 3 倍。根源不在网络,而在于这个估算式并不知道分子发生了抖动。

而且,由于「做出向上切换的决定」与「为此付出代价的时刻」之间存在时间差,卡顿总是出现在画面重新变亮之后。这正是只看指标去找原因发生时点、结果却挖错区间的原因。

那么编码侧要改什么 ​

推荐的方向是转向 CBR 系。各选项对比如下。

方式比特分配ABR 准确度存储/传输效率直播适配度
VBR随复杂度自由波动低(分子会抖动)最好低
capped VBR会波动但上限固定中(下限仍会塌陷)好中
CBR把区间平均固定到目标值,不足则补 padding高低(简单画面会浪费比特)高

静态画面上浪费的比特看似可惜,但在直播 ABR 中,「声明的码率与实际一致」这份保证,比节省带宽更有价值。阶梯各层级的实测码率互不重叠,正是 ABR 成立的前提条件。

注意:只改成 capped VBR 只能解决一半。制造问题的不是上限,而是下限塌陷。如果没有最小码率下限(min bitrate)或 padding,黑场区间里阶梯仍会变成平地。

播放器侧可以缓解的手段 ​

有时无法改动编码,所以这里也整理了缓解手段。

  • 估算带宽时不要只用单个分片,而是对多个分片取移动平均或调和平均。目的是让 7 秒级别的异常值无法推翻判断。
  • 为向上切换增加缓冲区水位条件。即便估算带宽充足,只要缓冲区低于目标值就不升。
  • 为向上切换设置冷却时间。下行立即、上行保守的非对称策略,在直播中几乎总是正确的。
  • 除分片大小外,同时把清单声明的 BANDWIDTH 值作为向上判断标准的下限。只信实测数据的话,这次的案例就会原样踩中。

同一时间段一起响起的告警 ​

顺带一提,这个区间里还有另外两类告警同时触发,但两者都属于正常行为。它们会干扰排查顺序,属于噪声,所以一并记在这里。

  • 分片 404 激增:DASH MPD 的 SegmentTemplate 结构里,$Time$ 值与 SegmentTimeline 的 t 字段相绑定。播放器按计算出的时间戳发起请求时,可能会提前请求尚未生成的时间戳,这时就会出现 404。而源站实际生成的分片请求全部以 200 记录在日志中。在 DASH 直播中,少量 404 属于正常范围。
  • 403 激增:规模约为每分钟 150 次,全部来自不在 IP allowlist 中的来源。这是策略按预期生效的结果。

参考:3 个指标同时跳变,看起来像是同一个原因造成的,但实际上往往是 2 个无关的正常行为加 1 个真实问题。预先定义好每条告警的正常范围基线,是缩短故障响应时间最便宜的办法。

原理梳理 ​

  • VBR:码率随画面复杂度变化的编码方式。相对平均质量而言效率最高。
  • CBR:把区间平均码率固定到目标值的编码方式。在简单画面上会浪费比特,但输出可预测。
  • ABR:客户端依据观测到的下载性能选取 rendition 的方式。关键在于观测值是 세그먼트 크기 / 다운로드 시간。

压缩成一句话:ABR 测量的不是网络,而是「内容大小除以时间」。所以当内容大小因内容自身原因而抖动时,ABR 会误以为是网络发生了抖动。直播中使用 CBR 的理由不是画质一致性,而是为了不对 ABR 说谎。

小结 ​

  • 如果分发链路(CDN、源站、网络)全部正常、却只有卡顿指标跳变,就该去看内容特性和播放器的判断逻辑。
  • 在原始视频约 8 秒的黑场区间里,VBR 输出码率发生了塌陷(约 7 秒),ABR 阶梯的所有层级都降到用户带宽 1 Mbps 以下,台阶变成了平地。
  • 播放器把变短的下载时间误判为带宽改善,从而升到更高层级的 rendition;当画面重新变亮、1080p 恢复到 8 Mbps 的那一刻,缓冲区被耗尽。所以卡顿不出现在黑场区间,而出现在其紧随之后。
  • 根本解决方法是转向 CBR。只用 capped VBR 只能管住上限,下限塌陷依然存在。
  • 播放器侧的缓解办法包括:基于多分片平均的带宽估算、结合缓冲区水位条件、向上切换冷却、以及参考清单声明的码率。

基于 VitePress 构建 · 部署于腾讯云 EdgeOne Pages