H264帧格式解析
H264帧基础知识
GOP

一组GOP也就是一组图像,存在一个I帧,多个P帧和B帧。P/B帧是由I帧预测的,那么I帧质量差,会影响一整个GOP中后续的P、B帧质量。P、B帧的解码复杂,影响解码效率。其次过长的GOP会影响Seek操作的速度。
帧介绍
IDR帧与I帧
在I帧中,所有宏块都采用帧内预测的方式,因此解码时仅用I帧的数据就可重构完整图像,不需要参考其他画面而生成。
H.264中规定了两种类型的I帧:普通I帧(normal Iframes)和IDR帧(InstantaneousDecoding Refresh, 即时解码刷新)。 IDR帧实质也是I帧,使用帧内预测。IDR帧的作用是立即刷新,会导致DPB(Decoded Picture Buffer参考帧列表)清空,而I帧不会。所以IDR帧承担了随机访问功能,一个新的IDR帧开始,可以重新算一个新的Gop开始编码,播放器永远可以从一个IDR帧播放,因为在它之后没有任何帧引用之前的帧。如果一个视频中没有IDR帧,这个视频是不能随机访问的。所有位于IDR帧后的B帧和P帧都不能参考IDR帧以前的帧,而普通I帧后的B帧和P帧仍然可以参考I帧之前的其他帧。IDR帧阻断了误差的积累,而I帧并没有阻断误差的积累。
一个GOP序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像,但I帧不一定都是IDR帧,只有GOP序列的第1个I帧是IDR帧。
I帧
I帧:帧内编码帧 ,I帧表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)
- 它是一个帧内压缩编码帧,压缩比约为7。它将全帧图像信息进行JPEG压缩编码及传输;
- 解码时仅用I帧的数据就可重构完整图像;
- I帧描述了图像背景和运动主体的详情;
- I帧不需要参考其他画面而生成;
- I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);
- I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧;
- I帧不需要考虑运动矢量;
- I帧所占数据的信息量比较大。
疑问:按照GOP、IDR帧、I帧的解释,如果一个GOP出现除去第一个IDR帧之外的I帧,是不存在的,那这样的话,就不存在非IDR的I帧了,可是为什么还要说明非IDR的I帧呢。
解答:H264编码存在多种编码方式CBR、VBR、CVBR、ABR等等,VBR编码模式下图像内容变化差异很大时,会动态调整I帧的数量,因此GOP的概念需要修正:两个IDR帧之间的间隔为一组GOP,一组GOP中可以出现非IDR的I帧。
P帧
P帧:前向预测编码帧。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面,P帧没有完整画面数据,只有与前一帧的画面差异的数据。
-
P帧的压缩率20;
-
P帧是I帧后面相隔1~2帧的编码帧;
-
P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差);
-
解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;
-
P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;
-
P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;
-
由于P帧是参考帧,它可能造成解码错误的扩散;
-
由于是差值传送,P帧的压缩比较高。
B帧
B帧:双向预测内插编码帧。B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,约为50,但是解码时会更加耗性能。
- B帧是由前面的I或P帧和后面的P帧来进行预测的;
- B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量;
- B帧是双向预测编码帧;
- B帧压缩比最高,因为它只反映丙参考帧间运动主体的变化情况,预测比较准确;
- B帧不是参考帧,不会造成解码错误的扩散。
H264 profile level:
- BP-Baseline Profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;
- EP-Extended profile:进阶画质。支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC;
- MP-Main profile:主流画质。提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced),也支持CAVLC 和CABAC 的支持;
- HP-High profile:高级画质。在main Profile 的基础上增加了8x8内部预测、自定义量化、无损视频编码和更多的YUV 格式。
H264码率控制
VBR:Variable BitRate,动态比特率,其码率可以随着图像的复杂程度的不同而变化,因此其编码效率比较高,Motion发生时,马赛克很少。码率控制算法根据图像内容确定使用的比特率,图像内容比较简单则分配较少的码率(似乎码字更合适),图像内容复杂则分配较多的码字,这样既保证了质量,又兼顾带宽限制。这种算法优先考虑图像质量。
ABR:Average BitRate,平均比特率 是VBR的一种插值参数。ABR在指定的文件大小内,以每50帧 (30帧约1秒)为一段,低频和不敏感频率使用相对低的流量,高频和大动态表现时使用高流量,可以做为VBR和CBR的一种折衷选择。
CBR:Constant BitRate,是以恒定比特率方式进行编码,有Motion发生时,由于码率恒定,只能通过增大QP来减少码字大小,图像质量变差,当场景静止时,图像质量又变好,因此图像质量不稳定。优点是压缩速度快,缺点是每秒流量都相同容易导致空间浪费。
CVBR:Constrained Variable it Rate,VBR的一种改进,兼顾了CBR和VBR的优点:在图像内容静止时,节省带宽,有Motion发生时,利用前期节省的带宽来尽可能的提高图像质量,达到同时兼顾带宽和图像质量的目的。这种方法通常会让用户输入最大码率和最小码率,静止时,码率稳定在最小码率,运动时,码率大于最小码率,但是又不超过最大码率。
H264帧结构

NALU-header
NALU Header 由 8 bit 组成,其中最后的 5 bit 表示 NAL Unit Type

| NAL Unit Type | NAL Unit Content |
|---|---|
| 1 | 非 IDR 图像,且不采用数据划分的片段。 |
| 5 | IDR 图像。 |
| 6 | 补充增强信息(SEI)。 |
| 7 | 序列参数集(SPS)。 |
| 8 | 图像参数集(PPS)。 |
| 11 | 流结束符。 |
SEI payload type 计算方式
当开始解析类型为 SEI 的 NAL 时,在 RBSP 中持续读取 8 bit,直到非 0xff 为止,然后把读取的数值累加,累加值即为 SEI payload type。SEI RBSP 结构图如下:

CC