在上一篇文章《关于“视频”,你可能不知道的那些事儿》中,我们得到了一个概念:一段未经任何处理的 1080P 的 60 帧率视频每秒钟需要超过 300MB 的体积空间。直接封装到容器中不太现实,这个时候就需要对视频进行压缩了。类似于 H.264 这样的编码标准就是为视频压缩而服务的,而现代编码标准中的视频压缩技术又可以分为帧内压缩和帧间压缩两种。这里仅仅做一个非常快速的介绍,想要详细学习编码有关的知识(简直是无底洞 Orz),可以在高手云集的 Doom9 论坛继续遨游。
同样地,如果你想系统地了解 H.264 编码与视频压缩的内容,我会向你推荐《The H.264 Advanced Video Compression Standard》这本书,比看我的博文好多了:
视频压缩的原理
视频基本上由以每秒一定数量的播放帧(frame)组成,每个帧都是一个图像。
帧内压缩与帧间压缩
顺着上面的思路,如果可以将视频里面的每一帧进行压缩,就可以达到减小视频总体积的效果。根据当前帧压缩时所参考的对象,又有 帧内压缩(空间预测) 与 帧间压缩(时间预测) 的区别。帧内压缩类似于图片压缩,跟这一帧的前面(或后面)一帧(或几帧)无关,由当前帧中,已编码的部分来推测当前待编码的这一部分数据是什么。而帧间压缩是,由这一帧的前(或后)一帧(或几帧)来推测当前待压缩的这一部分数据是什么。
H.264 预测原理
视频的每一帧可以分成多个宏块(Macroblock),下图显示了三个宏块的预测源,一个 I 宏块,一个 P 宏块和一个 B 宏块。
- 帧内预测:使用来自当前帧中的相邻样本的帧内预测来预测 I 宏块(I MB)。
- 帧间预测:从先前编码的帧中的样本预测 P 宏块(P MB),它们可以在当前图像显示顺序之前 或 之后,即都是 “过去” 或都是 “未来” 帧。 而 B 宏块(B MB)中的每个分区是从一个或两个先前编码的帧中的样本预测的,例如一个 “过去” 帧 和 一个 “未来” 帧。
我们以 4x4 亮度块为例来解释帧内预测(其实还有 8x8 与 16x16 等等):
右图显示了一个 4×4 亮度块,它是左图中突出显示的宏块的一部分并需要预测。
宏块上面和左边的样本,在下图中标记为 A-M ,之前已被编码和重建,因此可在编码器和解码器中使用形成预测参考,而 a-p 则是需要进行预测的像素亮度值。
具体的帧内预测的方式有许多种,可以从下面的图示和表格中看出它们所采取的不同策略,箭头表示每种模式下的预测方向,计算方式有根据样本加权平均等等,这里就不描述细节了。
而帧间预测的原理,则是用到了 I 帧,P 帧和 B 帧的概念。其中 I 帧是关键桢(Intra),保留了完整的信息,可以使用前面提到的帧内预测,解码时只需要本帧数据就可以完成。如果将 I 帧与下一帧进行比较,发现二者之间只是变化了一些宏块(如下图所示),那么下一帧就是可前向预测的 P 帧(Predictive)。对于 P 帧中没有变化的宏块,编码时直接照抄 I 帧即可;而对于有变化的宏块,只要在编码时记录下变化的信息,解码时预测回去即可。
B 帧是双向预测帧(Bi-directional interpolated prediction),记录的是本帧与前后帧的差别(具体比较复杂,有4种情况),通过前后画面的与本帧数据的叠加取得最终的画面。B 帧的压缩率高,但是解码时 CPU 会比较累。我们的视频就是由 I 帧,P 帧和 B 帧组成的,通过这种压缩方式,可能连 10 分钟的视频体积都不一定有 300M 呢。
问题在于,使用帧间预测时,如果视频中的细节变化比较复杂,信息量很大,在解码时 P 帧和 B 帧就很难较好地还原,导致严重失真。最后提一下 Group of Picture (GOP),指的是每一组 IPB 帧的序列一共有多少帧率,或者说 I 帧出现的周期:
CBR, VBR 与 CRF
- CBR(Constant Bit Rate)固定码率:文件大小可预期,编码压力小,推荐用于直播。
- VBR(Variable Bit Rate)可变码率:相比于 CBR 更智能一些,简单场景码率低,复杂场景码率高。此外你可以选择 2-Pass 模式,以对码率做出更高的限制。第一遍分析视频复杂度,按帧分配复杂度,第二遍才开始渲染,因此 2-Pass 会导致更长的任务时间。 (AVR 是码率波动更小的 VBR。)
- CRF(Constant Rate Factor)固定质量:给定质量值,给不同的场景分配不同码率,但是 CRF 以画质要求为目标,所以视频的最终码率和体积都是不可控的。(CQP 是 CRF 的低级版本。)
x264 编码器预设用于直播与上传
显卡对视频编码帮助不是很大,主要还是看 CPU 性能,但是对于一些旧 CPU,编码已经几乎将 CPU 占满,如果还需要开启直播,有时则需要妥协... 如果只是做视频的话,还是果断选择 X264 CPU 编码器吧。CPU 的差距就好像深度学习领域使用 GPU 的差距,所以如果是使用笔记本的 U 做视频压制,请考虑好散热和用时。
如果你的视频源素材不需要压制(没有使用专业设备录制出的视频一般到不了二压线),自然只要做好剪辑特效等后期就可以上传了。另外其实 B 站的二压效果也很不错,如果你使用 CRF 模式对视频进行编码,得到一个码率超过二压线的视频,而你自己又不想本地压制,则可以让 B 站帮你进行压制,只是这样投稿到发布预览的时间又变长了。
下面的软件参数配置部分截图自极客湾的视频,它们的机器配置是 i9-9900K. 另外我推荐去小丸之家查看 小白哔哩哔哩免二压完全压制手册(第七版-2018新直传大更新版) ,里面有许多常见问题的解答。
MediaCoder
Adobe Premiere Pro
Final Cut Pro + Compressor
Open Broadcaster Software
小丸工具箱与 MeGUI
高级使用:AVS 脚本个性化压制
访问 Avisynth wiki 学习,毕竟预设也不是万能的。
参考文献
- Iain E. Richardson. The H.264 Advanced Video Compression Standard. Wiley
- “视频”是怎么来的?H.264、码率这些词又是什么意思?