最近入门音视频技术,一直在学习H264编解码标准,了解了不少关于H264的相关知识,对于网上各种类型的资料,始终没有找到一篇适合的知识梳理资料。可能是查找方式不对,所以花费了比较多的时间。经过一段时间的熟悉后结合网上各类大神的指导资料和自己的理解决定自己整理一下关于H264编解码标准的知识。以后方便自己查阅,也让更多刚入门的人提供一个参考资料,由于是初次涉及,所以有些地方可能有理解不全面或有误,望各位前辈大神多多指导,不胜感激;
主要的参考资料在已贴在后面,大家可以详细了解;
0、序言
首先要弄明白编码的目的,有目的的学习效率会更好。编码是为了将数据进行压缩,这样在传输的过程中就不会使资源被浪费,用一个简单的例子来说明编码的必要性:
当你此刻显示器正在播放一个视频,分辨率是1280*720,帧率是25,那么一秒所产生正常的数据大小为:
1280*720(位像素)*25(张) / 8(1字节8位)(结果:B) / 1024(结果:KB) / 1024 (结果:MB) = 2.75MB
显然一秒这么大的数据你是无法接受的,所以如果不将数据进行压缩,那么只能一首凉凉表达此刻的感受了;
1、前言
H264里面很多文章梳理,具体标准定义就不多赘述了,但是有些概念一定要弄明白,这样在后面我就是因为有些概念模糊所以在理解某些知识点十分吃力,例如序列、GOP等等,我会逐一在后面描述到。
H264在视频采集到输出中属于编解码层次的数据,如图1所示,是在采集数据后做编码压缩时通过编码标准编码后所呈现的数据。
图1
2、H264相关概念
2.1序列
H264编码标准中所遵循的理论依据个人理解成:参照一段时间内相邻的图像中,像素、亮度与色温的差别很小。所以当面对一段时间内图像我们没必要去对每一幅图像进行完整一帧的编码,而是可以选取这段时间的第一帧图像作为完整编码,而下一幅图像可以记录与第一帧完整编码图像像素、亮度与色温等的差别即可,以此类推循环下去。
什么叫序列呢?上述的这段时间内图像变化不大的图像集我们就可以称之为一个序列。序列可以理解为有相同特点的一段数据。但是如果某个图像与之前的图像变换很大,很难参考之前的帧来生成新的帧,那么久结束删一个序列,开始下一段序列。重复上一序列的做法,生成新的一段序列。
2.2、帧类型
H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16x16的yuv数据组成。宏块作为H264编码的基本单位。
在H264协议内定义了三种帧,分别是I帧、B帧与P帧。I帧就是之前所说的一个完整的图像帧,而B、帧与P帧所对应的就是之前说的不编码全部图像的帧。P帧与B帧的差别就是P帧是参考之前的I帧而生成的,而B帧是参考前后图像帧编码生成的。
2.3、GOP(画面组)
GOP我个人也理解为跟序列差不多意思,就是一段时间内变化不大的图像集。GOP结构一般有两个数字,如M=3,N=12。M指定I帧和P帧之间的距离,N指定两个I帧之间的距离。上面的M=3,N=12,GOP结构为:IBBPBBPBBPBBI。在一个GOP内I frame解码不依赖任何的其它帧,p frame解码则依赖前面的I frame或P frame,B frame解码依赖前最近的一个I frame或P frame 及其后最近的一个P frame。
2.4、IDR帧(关键帧)
在编码解码中为了方便,将GOP中首个I帧要和其他I帧区别开,把第一个I帧叫IDR,这样方便控制编码和解码流程,所以IDR帧一定是I帧,但I帧不一定是IDR帧;IDR帧的作用是立刻刷新,使错误不致传播,从IDR帧开始算新的序列开始编码。I帧有被跨帧参考的可能,IDR不会。
I帧不用参考任何帧,但是之后的P帧和B帧是有可能参考这个I帧之前的帧的。IDR就不允许这样,例如:
IDR1 P4 B2 B3
P7
B5 B6