视频编解码基础概念
本文涉及视频编解码最基础概念,从工程应用角度出发,帮助理解和编写源码。本文并不涉及深层次原理和算法。错误难免,逐渐完善。
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10285829.html
1. 概述
音视频领域早期采用模拟化技术,属于电子电路领域。目前已发展为数字化技术,属于计算机技术领域。数字化的主要好处有:可靠性高、能够消除传输及存储损耗,便于计算机处理及网络传输等。音视频处理本质上就是对计算机数据的处理。
图像信息经采集后生成的原始视频,数据量非常大,对于某些采集后直接本地播放的应用(例如医用内窥镜),不需要考虑视频压缩技术。但现实中更多的应用场合(例如广播电视、网络摄像机等),涉及视频的传输与存储,传输网络与存储设备无法容忍原始视频的巨大数据量,必须将原始视频数据经过编码压缩后,再进行传输与存储。
本文仅关注视频编解码基础原理,不关注音频。
2. 视频压缩原理
2.1 熵与冗余
引自参考资料[1]第 1.5 节
在所有的实际节目素材中,存在着两种类型的信号分量:即异常的、不可预见的信号分量和可以预见的信号分量。异常分量称为熵,它是信号中的真正信息。其余部分称为冗余,因为它不是必需的信息。冗余可以是空间性的,如在图像的大片区域中,邻近像素几乎具有相同的数值。冗余也可以是时间性的,例如连续图像之间的相似部分。在所有的压缩系统编码器中都是将熵与冗余相分离,只有熵被编码和传输,而解码器则从编码器发送的信号中计算出冗余。
2.2 帧内编码
帧内编码是空间域编码,利用图像空间性冗余度进行图像压缩,处理的是一幅独立的图像,不会跨越多幅图像。空间域编码依赖于一幅图像中相邻像素间的相似性和图案区的主要空间域频率。
JPEG 标准用于静止图像(即图片),只使用了空间域压缩,只使用帧内编码。
2.3 帧间编码
帧间编码是时间域编码,是利用一组连续图像间的时间性冗余度进行图像压缩。如果某帧图像已被解码器解码获取,那么解码器只须利用两帧图像的差异即可得到此图像的下一帧图像。比如运动平缓的几帧图像的相似性大,差异性小,而运动剧烈的几幅图像则相似性小,差异性大,当得到一帧完整的图像后,可以利用与后一帧图像的差异值推算得到后一帧图像,这样就实现了数据量的压缩。时间域编码依赖于连续图像帧间的相似性,尽可能利用已接收处理的图像信息来“预测”生成当前图像。
MPEG 标准用于运动图像(即视频),会使用空间域编码和时间域编码,因此是帧内编码和帧间编码结合使用。
2.4 运动矢量
一组连续图像记录了目标的运动。运动矢量用于衡量两帧图像间目标的运动程度,运动矢量由水平位移量和垂直位移量二者构成。
2.5 运动补偿
目标的运动降低了图像间的相似性,增加了差异数据量。而运动补偿则通过运动矢量来降低图像间的差异数据量。
下图为运动补偿的示意图。当某一目标运动时,其位置会变化但形状颜色等基本不变。编码器则可利用运动矢量来减低图像差值,解码器根据图像差值中的运动矢量移动目标到合适的位置即可。假设图中是理想情况,目标除移动位置外其他任何属性无任何变化,则两幅图像间的差值仅包含运动矢量这一数据量。显然运动补偿可以显著减少图像差值数据量。
2.6 双向预测
先看示意图:
连续的三幅图像中,目标块有垂直位置上的移动,背景块无位置移动。我们考虑如何取得当前帧图像(画面 N):
画面 N 中,目标向上移动后,露出背景块。
画面 N-1 中,因为背景块被目标块遮挡住了,因此没有背景块相关信息。
画面 N+1 中,完整包含背景块的数据,因此画面 N 可以从画面 N+1 中取得背景块。
如何可以得到画面 N 呢?解码器可以先解码得到画面 N-1 和画面 N+1,通过画面 N-1 中的目标块数据结合运动矢量即可得到画面 N 中的目标块数据,通过画面 N+1 中的背景块数据则可得到画面 N 中的背景块数据。三幅画面的解码顺序为:N-1, N+1, N。三幅画面的显示顺序为:N-1, N, N+1。画面 N 通过其前一幅画面 N-1 和后一幅画面 N+1 推算(预测,predicted)得到,因此这种方式称为双向预测(或前向预测、双向参考),这里的画面 N 其实就是一个 B 帧。
2.7 视频流中的帧类型:I 帧/IDR 帧/P 帧/B 帧
I 帧:I 帧(Intra-coded picture, 帧内编码帧,常称为关键帧)包含一幅完整的图像信息,属于帧内编码图像,不含运动矢量,在解码时不需要参考其他帧图像。因此在 I 帧图像处可以切换频道,而不会导致图像丢失或无法解码。I 帧图像用于阻止误差的累积和扩散。在闭合式 GOP 中,每个 GOP 的第一个帧一定是 I 帧,且当前 GOP 的数据不会参考前后 GOP 的数据。
IDR 帧:IDR 帧(Instantaneous Decoding Refresh picture, 即时解码刷新帧)是一种特殊的 I 帧。当解码器解码到 IDR 帧时,会将 DPB(Decoded Picture Buffer,指前后向参考帧列表)清空,将已解码的数据全部输出或抛弃,然后开始一次全新的解码序列。IDR 帧之后的图像不会参考 IDR 帧之前的图像,因此 IDR 帧可以阻止视频流中的错误传播,同时 IDR 帧也是解码器、播放器的一个安全访问点。
P 帧:P 帧(Predictive-coded picture, 预测编码图像帧)是帧间编码帧,利用之前的 I 帧或 P 帧进行预测编码。
B 帧:B 帧(Bi-directionally predicted picture, 双向预测编码图像帧)是帧间编码帧,利用之前和(或)之后的 I 帧或 P 帧进行双向预测编码。B 帧不可以作为参考帧。B 帧具有更高的压缩率,但需要更多的缓冲时间以及更高的 CPU 占用率,因此 B 帧适合本地存储以及视频点播,而不适用对实时性要求较高的直播系统。
2.8 视频流中的帧组结构:GOP
GOP(Group Of Pictures, 图像组)是一组连续的图像,由一个 I 帧和多个 B/P 帧组成,是编解码器存取的基本单位。GOP 结构常用的两个参数 M 和 N,M 指定 GOP 中两个 anchor frame(anchor frame 指可被其他帧参考的帧,即 I 帧或 P 帧)之间的距离,N 指定一个 GOP 的大小。例如 M=3,N=15,GOP 结构为:IBBPBBPBBPBBPBB
TODO: GOP 中是否每两个 anchor frame 的间隔是相同的?推测:未必相同。实际上分析不少视频文件,规律并不一致。此处没有彻底弄清楚,待进一步积累素材、分析与确认。
GOP 有两种:闭合式 GOP 和开放式 GOP:
闭合式 GOP:闭合式 GOP 只需要参考本 GOP 内的图像即可,不需参考前后 GOP 的数据。这种模式决定了,闭合式 GOP 的显示顺序总是以 I 帧开始以 P 帧结束
TODO: 闭合式 GOP 是否一定是以 P 帧结束?推测:可能未必有此定义。有看到某些视频文件 GOP 以 B 帧结束。
开放式 GOP:开放式 GOP 中的 B 帧解码时可能要用到其前一个 GOP 或后一个 GOP 的某些帧。码流里面包含 B 帧的时候才会出现开放式 GOP。
TODO: 开放式 GOP 是否规定是以 B 帧开始,P 帧结束?推测:可能未必有此定义。是否以 B 帧开始?网上资料说法不一。是否以 P 帧结束?有看到某些视频文件 GOP 以 B 帧结束。
在开放式 GOP 中,普通 I 帧和 IDR 帧功能是有差别的,需要明确区分两种帧类型。在闭合式 GOP 中,普通 I 帧和 IDR 帧功能没有差别,可以不作区分。
开放式 GOP 和闭合式 GOP 中 I 帧、P 帧、B 帧的依赖关系如下图所示:
2.9 视频流中的帧顺序:DTS 和 PTS
DTS(Decoding Time Stamp, 解码时间戳),表示压缩帧的解码时刻。PTS(Presentation Time Stamp, 显示时间戳),表示将压缩帧解码后得到的原始帧的显示时刻。音频中 DTS 和 PTS 是相同的。视频中由于 B 帧需要双向预测,B 帧依赖于其前和其后的帧,因此含 B 帧的视频解码顺序与显示顺序不同,其 DTS 和 PTS 不同。当然,不含 B 帧的视频,其 DTS 和 PTS 是相同的。下图以一个开放式 GOP 示意图为例,说明视频流的解码顺序和显示顺序:
图中 [0]、[1] 等表示 GOP 中帧的采集/显示顺序序号,每个方格表示一帧图像(原始帧或编码帧),原始帧与编码帧一一对应。采集顺序指图像传感器采集原始信号得到图像帧的顺序。编码顺序指编码器编码后图像帧的顺序。存储到磁盘的本地视频文件中图像帧的顺序与编码顺序相同。传输顺序指编码后的流在网络中传输过程中图像帧的顺序。解码顺序指解码器解码图像帧的顺序。显示顺序指图像帧在显示器上显示的顺序。采集顺序与显示顺序相同。编码顺序、传输顺序和解码顺序相同。
以图中“B[1]”帧为例进行说明,“B[1]”帧解码时需要参考“I[0]”帧和“P[3]”帧,因此“P[3]”帧必须比“B[1]”帧先解码。这就导致了解码顺序和显示顺序的不一致,后显示的帧需要先解码。采集的时候图像还没有 I、P、B 类型,也没有 DTS 和 PTS,编码后才有这些信息。DTS 和 PTS 是解码器使用的,编码器编码生成的视频流(裸流)是不含 DTS 和 PTS 的,但是解码器可以根据视频流的内容(例如 H.264 语法结构)计算生成 DTS 和 PTS,这个 DTS 和 PTS 一般会被放在视频封装格式里。
3. 参考资料
[1] 泰克 Tektronic, MPEG 基础和协议分析指南
[2] 视频直播的理论知识,https://www.jianshu.com/p/04b5b1e4ff27
[3] open GOP & close GOP, https://www.jianshu.com/p/d30c051b4106
[4] I 帧/B 帧/P 帧/GOP, https://blog.csdn.net/abcsunl/article/details/68190136
[5] FFmpeg 音视频同步原理与实现, https://www.jianshu.com/p/3578e794f6b5
[6] FFmpeg 音视频同步, https://www.jianshu.com/p/27279255f67e
[7] The GOP Inter Prediction of H.264 AVC, https://www.sciencedirect.com/science/article/pii/S1319157819301867
[8] WiKi Group of pictures, https://en.wikipedia.org/wiki/Group_of_pictures
[9] Open and Closed GOPs – All You Need to Know, https://streaminglearningcenter.com/articles/open-and-closed-gops-all-you-need-to-know.html
4. 修改记录
2018-12-08 V1.0 初稿
2020-11-24 V1.0 修正 GOP 中 M 参数描述错误。修正笔误
2024-12-19 V1.1 修正解码和显示顺序图例。修正笔误