相关概念
I/P/B帧
H264定义的三种视频帧类型。
- I帧(Intra-frame):也称关键帧,采用帧内压缩技术,解码时不依赖其他的帧。I帧用于给后续的P帧和B帧提预测参考,一般视频的第一帧就是I帧。
- P帧(Predicted-frame):预测帧,或叫前向预测帧,记录与前一个I帧或P帧的差别,解码时需要依赖前一个帧。(P帧没有完整的画面数据,只有与前一帧的差别)
- B帧(Bi-directional frame):双向参考帧,记录与前后的I帧或P帧的差别,解码时需要参考前后两个帧。(B帧解码时依赖后面的帧,这就导致后面的帧要先解码,解码时间和显示时间不一样)。
![](https://www.midlane.top/wiki/download/attachments/49677194/v2-b87c2f78a2430ee24be17bc6fa17ee07_1440w.png?version=1&modificationDate=1676285752012&api=v2)
相邻两个I帧构成一个GOP(Group of Pictures)。GOP是从MPEG-1开始就有的概念,一般来说一个GOP内部的图像解码不依赖其他的GOP,并且GOP的第一帧一定是I帧,如果这个I帧丢失,那么这整个GOP内的图像都会解码失败,造成画面卡顿(如果只是P帧或B帧丢了,那么一般是画面花屏)。
除了I帧,H264帧还有IDR帧的概念。IDR帧表示解码器立即刷新(Instantaneous Decoder Refresh),IDR帧都是I帧,解码器收到IDR帧后,会立即清空缓存,将积压的未解码的P帧和B帧全部清除,重新开始新一轮GOP的解码。IDR帧后面的帧解码时绝对不会依赖IDR前面的帧。(作为对比,H264中的P帧B帧有可能依赖上一个普通I帧之前的帧)
片和宏块
H264编码的基本单位是宏块(MB),所有关于帧内预测、运动补偿、离散余弦变换和量化的操作都是针对宏块的。一个宏块由一个16x16的亮度像素块和两个8x8的色度像素块组成。宏块还可以划分成子块,以实现更加精细的预测效果以及提升数据压缩率。
H264并不会一次对一整幅图像进行宏块划分和编码,而是会先将图像拆分成若干个片(Slice),再对片进行编码和输出。片是比帧小、但比宏块大的单位,一帧图像可以拆分成一个或若干个片,每个片包含至少一个宏块。
I/P/B帧的概念也可以应用到片和宏块上,比如宏块有三种类型:I宏块、P宏块、B宏块。I宏块只能利用从当前片中已解码的像素作为参考进行帧内预测;P宏块可以利用前面已解码的图像作为参考图像进行帧内预测;B宏块利用双向的参考图像(当前和未来的已编码图像)进行帧内预测。
片一共有5种类型,包括I片、P片、B片,以及SP片和SI片。I片只能包含I宏块,P片可以包含P和I宏块,B片可以包含B和I宏块。SP片用于不同编码流之间的切换,包含P和/或I宏块。SI片包含了一种特殊类型的宏块,叫做SI宏块,也用于流之间的切换。当视频流的内容相同,但编码参数不同时使用SP,当视频流内容相关很大时,使用SI。SP和SI只用于扩展档次。
档次和级
H.264 规定了三种档次,每个档次支持一组特定的编码功能,并支持一类特定的应用。
- 基本档次(Baseline Profile):利用 I 片和 P 片支持帧内和帧间编码,支持利用基于上下文的自适应的变长编码进行的熵编码( CAVLC)。主要用于可视电话、会议电视、无线通信等实时视频通信;
- 主要档次(Main Profile):支持隔行视频,采用 B 片的帧间编码和采用加权预测的帧内编码;支持利用基于上下文的自适应的算术编码( CABAC)。主要用于数字广播电视与数字视频存储;
- 扩展档次(Profile X):支持码流之间有效的切换( SP 和 SI 片)、改进误码性能(数据分割),但不支持隔行视频和 CABAC。扩展档次提升了基本档次的容错能力,主要用于无线视频服务和移动流媒体。
![](/wiki/download/attachments/49677196/image2023-2-14_17-0-46.png?version=1&modificationDate=1676365247420&api=v2&effects=drop-shadow)
帧内预测
帧内预测区分亮度块和色度块。
对于亮度块,帧内预测的宏块大小为4x4或16x16,其中4x4的宏块用于图像的细节部分,16x16的宏块用于图像的平坦区域。4x4亮度块有9种预测模式,16x16的亮度块有4种预测模式。除此外,还有一种帧内编码模式称为I_PCM编码模式,这种模式直接传输图像像素值,不经过预测和变换。
![](/wiki/download/attachments/49677196/image2023-2-14_17-16-54.png?version=1&modificationDate=1676366215269&api=v2)
![](/wiki/download/attachments/49677196/image2023-2-14_17-17-8.png?version=1&modificationDate=1676366228723&api=v2)
![](/wiki/download/attachments/49677196/image2023-2-14_17-17-29.png?version=1&modificationDate=1676366250174&api=v2)
对于色度块,宏块大小为8x8,只有4种预测模式,与16x16亮度块的4种预测模式类似,只不过编号不同。两种色度成份通常使用同一种预测模式。
帧间预测
帧间预测将每个16x16像素的宏块进行树状划分,如下图所示:
![](/wiki/download/attachments/49677196/image2023-2-14_17-31-27.png?version=1&modificationDate=1676367087450&api=v2)
16x16的像素块一共有4种划分方式:一个16x16,两个16x8,两个8x16,四个8x8。对于8x8模式,还可以再划分成一个8x8,两个4x8,两个8x4,四个4x4。
每个分割的子块都有一个独立的运动补偿,这就大大提高了各宏块之间的关联性。
宏块的色度分量(Cr和Cb)尺寸为相应亮度的一半(水平和垂直各一半),采用和亮度块同样的分割方式进行预测。
量化
关注量化步长QP即可,QP值越大,编码压缩率越高,图像精度越差。使用使用时QP一般是一个范围值,不会限定死,maxQP和minQP决定了图像的上下限。
熵编码
基本档次和扩展档次使用CAVLC编码,主要档次使用CABAC编码。