本文涉及视频编解码最基础概念,从工程应用角度出发,帮助理解和编写源码。本文并不涉及深层次原理和算法。错误难免,逐渐完善。
本文为作者原创,转载请注明出处: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)得到,因此这种方式称为双向预测(或前面预测、双向参考)。
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帧之前的图像。
P帧:P帧(Predictive-coded picture, 预测编码图像帧)是帧间编码帧,利用之前的I帧或P帧进行预测编码。
B帧:B帧(Bi-directionally predicted picture, 双向预测编码图像帧)是帧间编码帧,利用之前和(或)之后的I帧或P帧进行双向预测编码。B帧不可以作为参考帧。
2.8 GOP
GOP(Group Of Pictures, 图像组)是一组连续的图像,由一个I帧和多个B/P帧组成,是编解码器存取的基本单位。GOP结构常用的两个参数M和N,M指定GOP中首个P帧和I帧之间的距离,N指定一个GOP的大小。例如M=1,N=15,GOP结构为:IPBBPBBPBBPBBPBGOP有两种:闭合式GOP和开放式GOP:
闭合式GOP:闭合式GOP只需要参考本GOP内的图像即可,不需参考前后GOP的数据。这种模式决定了,闭合式GOP的显示顺序总是以I帧开始以P帧结束
开放式GOP :开放式GOP中的B帧解码时可能要用到其前一个GOP或后一个GOP的某些帧。码流里面包含B帧的时候才会出现开放式GOP。
开放式GOP和闭合式GOP中I帧、P帧、B帧的依赖关系如下图所示:
2.9 DTS和PTS
DTS(Decoding Time Stamp, 解码时间戳),表示packet的解码时间。
PTS(Presentation Time Stamp, 显示时间戳),表示packet解码后数据的显示时间。
音频中DTS和PTS是相同的。视频中由于B帧需要双向预测,B帧依赖于其前和其后的帧,因此含B帧的视频解码顺序与显示顺序不同,即DTS与PTS不同。当然,不含B帧的视频,其DTS和PTS是相同的。下图以一个开放式GOP示意图为例,说明视频流的解码顺序和显示顺序
采集顺序指图像传感器采集原始信号得到图像帧的顺序。
编码顺序指编码器编码后图像帧的顺序。存储到磁盘的本地视频文件中图像帧的顺序与编码顺序相同。
传输顺序指编码后的流在网络中传输过程中图像帧的顺序。
解码顺序指解码器解码图像帧的顺序。
显示顺序指图像帧在显示器上显示的顺序。
采集顺序与显示顺序相同。编码顺序、传输顺序和解码顺序相同。
图中“B[1]”帧依赖于“I[0]”帧和“P[3]”帧,因此“P[3]”帧必须比“B[1]”帧先解码。这就导致了解码顺序和显示顺序的不一致,后显示的帧需要先解码。
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
4. 修改记录
2018-12-08 V1.0 初稿
来源:oschina
链接:https://my.oschina.net/u/4418449/blog/4260664