文章目录
H264数据
H264 帧的组成
H.264定义的结构中,一个视频图像编码后的数据为一帧:
- 帧(Frame):一帧由一个或多个片(Slice)组成
- 片(Slice):一个片是由一个或多个宏块(MB)组成的(宏块是H264编码的基本单位)
- 宏块(MB:Macro Block):一个宏块是由16x16的yuv数据组成的
帧类型
在H.264的协议中,定义了三类帧,分别是I帧、B帧和P帧。
I帧
定义
帧内编码帧 ,I帧表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)
特点
- 它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输;
- 解码时仅用I帧的数据就可重构完整图像;
- I帧描述了图像背景和运动主体的详情;
- I帧不需要参考其他画面而生成;
- I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);
- I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧;
- I帧不需要考虑运动矢量; 8)I帧所占数据的信息量比较大。
P帧
Preview Prediction
在视频画面播放过程中,若I帧丢失了,则后面的P帧也就随着解不出来,就会出现视频画面黑屏的现象;若P帧丢失了,则视频画面会出现花屏、马赛克等现象。
定义
P帧:前向预测编码帧。
P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)
P帧的预测与重构
P帧是以I帧为参考帧,在I帧中找出P帧“某点”的预测值和运动矢量,取预测差值和运动矢量一起传送。在接收端根据运动矢量从I帧中找出P帧“某点”的预测值并与差值相加以得到P帧“某点”样值,从而可得到完整的P帧。
特点
- P帧是I帧后面相隔1~2帧的编码帧;
- P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差);
- 解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;
- P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;
- P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;
- 由于P帧是参考帧,它可能造成解码错误的扩散;
- 由于是差值传送,P帧的压缩比较高。
B帧
而B帧和P帧对应的就是之前说的不对全部图像做编码的帧。B帧和P帧的差别在于,P帧是参考之前的I帧生成的,B帧是参考前后的图像帧生成的。
定义
B帧:双向预测内插编码帧。
B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况,但我这样说简单些),换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。
B帧的预测与重构
B帧以前面的I或P帧和后面的P帧为参考帧,“找出”B帧“某点”的预测值和两个运动矢量,并取预测差值和运动矢量传送。接收端根据运动矢量在两个参考帧中“找出(算出)”预测值并与差值求和,得到B帧“某点”样值,从而可得到完整的B帧。
特点
- B帧是由前面的I或P帧和后面的P帧来进行预测的;
- B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量;
- B帧是双向预测编码帧;
- B帧压缩比最高,因为它只反映丙参考帧间运动主体的变化情况,预测比较准确;
- B帧不是参考帧,不会造成解码错误的扩散。
注:
I、B、P各帧是根据压缩算法的需要,是人为定义的,它们都是实实在在的物理帧。一般来说,I帧的压缩率是7(跟JPG差不多),P帧是20,B帧可以达到50。可见使用B帧能节省大量空间,节省出来的空间可以用来保存多一些I帧,这样在相同码率下,可以提供更好的画质。
GOP(画面组)
本质:一组可以播放的视频帧组
一个GOP(Group Of Picture)就是一组连续的画面。
GOP结构一般有两个数字:
- 其中一个是GOP的长度(即两个I帧之间的B帧和P帧数),
- 另一个数字为I帧和P帧之间的间隔距离(即B帧数)。
在一个GOP内I帧解码不依赖任何的其它帧,P帧解码则依赖前面的I帧或P帧,B帧解码依赖前面的I帧或P帧及其后最近的一个P帧。
注意:在码率不变的前提下,GOP值越大,P、B帧的数量会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference越大,B帧的数量越多,同理也更容易获得较好的图像质量。但是通过提高GOP值来提高图像质量是有限度的。H264编码器在遇到场景切换的情况时,会自动强制插入一个I帧,此时实际的GOP值被缩短了。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大。同时,由于P、B帧的复杂度大于I帧,所以过多的P、B帧会影响编码效率,使编码效率降低。另外,过长的GOP还会影响Seek操作的响应速度,由于P、B帧是由前面的I或P帧预测得到的,所以Seek操作需要直接定位,解码某一个P或B帧时,需要先解码得到本GOP内的I帧及之前的N个预测帧才可以,GOP值越长,需要解码的预测帧就越多,seek响应的时间也越长。
IDR 帧
GOP中的I帧又分为普通I帧和IDR帧,IDR帧就是GOP的第一个I帧,这样区分视为了方便控制编码和解码的流程。 IDR帧一定是I帧,但是I帧不一定是IDR帧。
IDR帧因为附带SPS、PPS等信息,解码器在收到 IDR 帧时,需要做的工作就是:
- 把所有的 PPS 和 SPS 参数进行更新。
可以看出来IDR帧的作用
是让解码器立刻刷新相关数据信息,避免出现较大的解码错误问题。
引入IDR帧机制是为了解码的重同步,当解码器解码到 IDR帧时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现错误,在这里可以获得重新同步的机会。IDR帧之后的帧永远不会使用IDR帧之前的数据来解码。
H264压缩方式
H264的压缩方式
H264 的核心压缩算法是帧内压缩和帧间压缩:
- 帧内压缩是生成I帧的算法;
- 帧间压缩是生成B帧和P帧的算法。
帧内(Intraframe)压缩的原理是:
当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间的冗余信息,一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩率一般不高。
帧间(Interframe)压缩的原理是:
相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。
H264压缩方式说明
H.264压缩视频数据时的具体方式如下:
1). 分组,也就是将一系列变换不大的图像归为一个组,即一个GOP;
2). 定义帧,将每组的图像帧归分为I帧、P帧和B帧三种类型;
3). 预测帧, 以I帧做为基础帧,以I帧预测P帧,再由I帧和P帧预测B帧;
4). 数据传输, 最后将I帧数据与预测的差值信息进行存储和传输。
H264分层结构
H264的主要目标是为了有高的视频压缩比和良好的网络亲和性,H264将系统框架分为两个层面,分别是视频编码层面(VCL)和网络抽象层面(NAL)
视频编码层 VCL |
---|
网络抽象层面 NAL |
VCL
VCL层:包括核心压缩引擎和块,宏块和片的语法级别定义,设计目标是尽可能地独立于网络进行高效的编码;
NAL
NAL层:负责将VCL产生的比特字符串适配到各种各样的网络和多元环境中,覆盖了所有片级以上的语法级别。
NALU(NAL Unit)
H.264原始码流(裸流)是由一个接一个NALU组成,
NALU通常由
StartCode | NALU Header | NALU Payload |
---|
三部分组成,其中 Start Code 用于标示这是一个NALU 单元的开始,必须是"00 00 00 01" 或"00 00 01"。
Start Code
Start Code 用于标示这是一个NALU 单元的开始,必须是”00 00 00 01” 或”00 00 01”。
NAL Header
NAL Header由三部分组成,forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)。
forbidden_bit
禁止位,初始为0,当网络发现NAL单元有比特错误时可设置该比特为1,以便接受方纠错或丢掉该单元。
nal_reference_bit
NAL重要性,值越大,越重要,解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU。
nal_unit_type(帧类型)
常见帧类型判断
00 00 00 01 67
00 00 00 01 是 StartCode
67 是header
type = 7 =>SPS 即关键帧
一般来说 type = 7 + type = 8才可创建一个解码器
00 00 00 01 21
00 00 00 01 是 StartCode
21 是header
type = 1 => 非IDR的片 即 p帧或b帧
00 00 00 01 41
RBSP(Raw Byte Sequence Payload))
SPS
SPS是序列参数集,包含的是针对一连续编码视频序列的参数,如标识符 seq_parameter_set_id、帧数及 POC 的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等等。
PPS
PPS是图像参数集,对应的是一个序列中某一幅图像或者某几幅图像,其参数如标识符 pic_parameter_set_id、可选的 seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等等。
总结
IDR帧和I帧
I帧和P帧
NAL、SPS和PPS
NAL层由多个单元NALU组成,NALU由了NALU头(00 00 00 01或者00 00 01)、sps(序列参数集)、pps(图像参数集合)、slice、sei、IDR帧、I帧(在图像运动变化较少时,I帧后面是7个P帧,如果图像运动变化大时,一个序列就短了,I帧后面可能是3个或者4个P帧)、P帧、B帧等数据。