在排查 WebRTC 丢包问题时,我们会接触到一些视频帧相关的名词,如 GOP、I-帧、P-帧、B-帧等。如果是之前对视频编解码不是特别了解的同学(比如笔者)可能会有些疑惑。因此本文尝试将这些名词逐一解释,方便大家查阅。
我们都知道,当多张连续图像以一定的速率(比如每秒 24 张)播放,即可形成视频。但视频传输却并不是单纯地发送连续图像这么简单。假设一张图像分辨率为 1280×720,且每个 ARGB 像素点大小为 32bits,则单张图像大小约为 29.5Mbits;如果每秒需要传输 24 张,则大约需要占用约 708Mbits/s 的带宽。显然这样的带宽占用是不现实的。
由此便引申出了视频编码技术,比如常见的 H.264、VP8 等编码格式。这些技术的基本思想都是类似的。我们可以将一张完整的图像分为很多小的图像块(Macroblock)。如下图 1 所示,人在挥手时身体并没有动,那么身体部分的图像块即是冗余信息,没必要每次都传输;可以只传输挥手的那部分,接收方再将其与之前的某些参考图像 diff 即可得到最新的图像:
图中的 Intraframe 即我们常说的 I-帧,而 Interframe 则包含了 P-帧和 B-帧。
GOP 结构
由一个 I-帧和若干个 P-帧和 B-帧组成的连续帧序列则称为一个 GOP(Group of Pictures)。编码器会将视频编码为多个连续的 GOP,以下便是一个典型的 GOP 结构图:
I-帧即帧内编码,是一种不需要其他参考帧即可编码的视频帧。一个视频文件总是以 I-帧开头,并拥有一定间隔的 I-帧序列。I-帧有时也被称为关键帧(Keyframe),我们可以通过 I-帧随机访问该文件中的(几乎)任意位置,实现快退和快进;也可以通过读取 I-帧序列实现视频预览,比如下图便是 Google Photos 编辑视频的拖动条:
当然,由于 I-帧每次都对整个图像进行编码,它所占的体积(磁盘或带宽)也是最大的。
P-帧(Predicted)属于帧间预测的一种,它需要之前的 I-帧或 P-帧作为参考帧进行编码。P-帧会分析出参考帧中总是不变的部分,只有变化的部分会被编码,因此 P-帧比 I-帧的体积要小得多。当然,由于 P-帧需要参考帧,所以它对传输错误的容忍度较低。
B-帧(Bi-directional Predicted)也属于帧间预测,它需要同时使用之前的 I-帧或 P-帧和之后的 I-帧或 P-帧进行编码,记录的是前后参考帧之间的差别,压缩比更高。但 B-帧显然增加了编码复杂度,且对延迟要求较高,所以在实时通话领域通常不使用 B-帧。
DTS 和 PTS
由于 B-帧需要未来的参考帧才能解码,于是便有了 DTS(Decode Timestamp,解码时间戳)和 PTS(Presentation Timestamp,显示时间戳)的概念。
编码器在编码时需要提供 DTS 和 PTS;而解码器在解码时会根据 DTS 顺序解码,再根据 PTS 顺序播放。当然,编码器是按照 DTS 顺序进行编码的,视频帧也是按照 DTS 顺序传输的。
以上述 GOP 结构图为例,PTS 顺序为图中的 1-9 顺序,对应的 DTS 顺序如下:
I B P B P B P B I
PTS: 1 2 3 4 5 6 7 8 9
DTS: 1 3 2 5 4 7 6 9 8
即在解码 B-帧之前,先根据 DTS 解码它需要的所有参考帧,再根据 PTS 组帧播放。不过我们在实时通话领域通常不使用 B-帧,所以 DTS 通常等于 PTS。
以上便是 WebRTC 中常见的视频帧名词了,理解这些名词有助于我们后续理解 WebRTC 的 NACK、PIL 和 FIR 等丢包处理机制。当然,本文也仅仅涉及了视频编码的基础内容,更多编码相关的内容已经超出了笔者目前的能力范围,感兴趣的读者可以自行深入。
- 引用自文章 Things You Wanted to Know About Compression but Were Afraid to Ask
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。