由于研究生入了视频安全这个坑,目前主要研究的是H.264/AVC标准,因此决定对自学H.264过程中的知识进行总结并写入博客记录。当然由于水平有限,有些地方理解可能有误,所以敬请读者指出(如果有人看的话哈哈)。本文作为第一篇博客,主要对H.264/AVC相关的基本概念进行介绍。
H.264/AVC简介
H.264是2003年3月正式发布的视频编码标准,又称为先进视频编码(Advanced Video Coding, AVC),旨在在拥有更高的压缩率的情况下依然能够提供良好视频质量,现已在数字电视广播、实时视频通信、网络流媒体等领域中广泛应用。
视频编码的最主要目的是数据压缩。例如,图像的每个像素的RGB三个分量各需要一个字节表示,那么每一个像素至少需要3字节,分辨率1280×720的图像的大小为2.76MB,如果帧率为25帧/秒,那么视频的码率将达到69.12MB/s,现有的存储空间和传输带宽难以满足这样的需求,因此原始视频必须进行编码压缩。而视频信息之所以可以被压缩,是因为其本身存在大量的数据冗余。其主要类型有:
- 时间冗余:视频相邻的两帧之间内容相似,存在运动关系(帧间预测编码)。
- 空间冗余:视频的某一帧内部的相邻像素存在相似性(帧内预测编码)。
- 编码冗余:视频中不同数据出现的概率不同(熵编码)。
- 视觉冗余:观众的视觉系统对视频中不同的部分敏感度不同(变换编码)。
针对这些不同类型的冗余信息,在各种视频编码的标准算法中都有不同的技术专门应对,以通过不同的角度提高压缩的比率。
H.264/AVC基本概念
H.264是按照层次组织数据的,其层次结构大致如图所示。
- 宏块(macroblock):一帧图像通常划分成若干宏块,一个宏块由一个亮度像素块和附加的两个色度像素块组成。H.264中,亮度块为16x16大小的像素块,而两个色度图像像素块的大小依据其图像的采样格式而定,如:对于YUV420采样图像,色度块为8x8大小的像素块。视频编码算法以宏块为单位,逐个宏块进行编码,组织成连续的视频码流。宏块可以进一步进行16x8/8x16/8x8的分割,其中8x8子宏块又可以进一步进行8x4/4x8/4x4的分割。
- 片/条带(slice):每帧的数据可以分为若干个片,包括I/P/B三种片,一般每个片中包含一个或者几个宏块,I slice只含I宏块,P slice可以包含I/P宏块,B slice可以包含I/B宏块。对视频流进行分片处理,既可以方便通信传输,也可以提高视频流的容错能力,因为H.264规定,帧内编码块只能在同一个片中进行帧内预测,这样如果由于传输错误使一个片中的数据丢失,所能影响到的只是同一片中的宏块解码,不会影响到同一帧图像中其他片中的宏块解码。
- 帧(frame)和场(field):帧代表一幅静止的图像,一帧包括两个场,即顶场和底场,顶场是奇数行的数据,底场是偶数行的数据。H.264中主要包括三种类型的帧,即I帧、P帧和B帧。通常I帧的压缩率较低,作为后续帧的重要参考帧,而P帧和B帧由于使用了帧间预测使得压缩率较高,因此视频的压缩率主要取决于P帧和B帧。
- I帧:主要包含I宏块,其只依靠自身的数据进行帧内预测编码,不依赖于其他帧的数据。有一种特殊的I帧叫IDR(Instantaneous Decoding Refresh 即时解码刷新)帧,作用是立刻刷新,在IDR帧之后的所有帧都不能引用在IDR帧之前的帧,从而减少错误传播。由此可知,我们视频播放时常见的在“任意点”播放实际上就是定位到附近的IDR帧进行播放的,而非严格意义上的任意播放。
- P帧:主要包含I宏块和P宏块,P宏块需要利用在它前面的P帧或者I帧进行帧间预测编码,I宏块与I帧中的相似。
- B帧:主要包含I宏块和B宏块,B宏块数据需要利用在它前面和后面的I帧或P帧进行帧间预测编码。由于B帧的编解码打乱了视频图像的自然顺序,因此不用做参考帧。
- GOP(Group of Picture图像组):一个视频序列包含若干个GOP,一个GOP包含若干幅图像,图像可以是I/P/B帧中的任意类型。其中一个GOP的第一帧必定是I帧。
- 帧内预测:编码时,利用同一帧内的其他像素的数据对当前像素数据进行预测,然后用当前像素的真实值减去预测值得到残差,供后续编码使用。残差相对于原始数据通常小很多,可以减少编码的数据量。
- 帧间预测:帧间预测有两个重要概念:运动估计和运动补偿。运动估计是寻找当前编码块在已编码编码图像(称为参考帧)中的最佳对应块,并计算出两者的偏移(即运动矢量)。运动补偿就是根据运动矢量和帧间预测方法,求得当前块的估计值的过程。它旨在说明当前图像的每一个像素如何由其参考图像得到的。同样的,帧间预测编码的也是残差数据。
- 变换编码:对信号进行某种函数变换,使其从一种空间转换到另一空间,然后利用信号在另一空间的特性进行压缩。例如把视频信号从空域转换到频域,使得图像的低频系数集中于左上角,频率向右下角递增。H.264中主要用到离散余弦变换(DCT)和哈达玛(Hadamard)变换,其中DCT变换使用的是整数DCT变换。
- 量化:量化即令每个输出除以一个数(量化步长)然后取整,得到较小的量化输出,从而减少编码的数据量,属于有损压缩。
- 熵编码:根据统计特性设计的无损编码算法,能够十分有效地对数据进行压缩,H.264中主要使用了指数哥伦布编码(Exp-Golomb Code)、上下文自适应的变长编码(CAVLC)和上下文自适应的二进制算术编码(CABAC)。