H.264中I帧、B帧、P帧、NALU类型,块,宏块,片,图像的关系

参考:http://blog.csdn.net/ivy_reny/article/details/47144121

http://blog.csdn.net/wanggp_2007/article/details/4842839

http://blog.sina.com.cn/s/blog_4ad7c2540101me90.html

块==》宏块(MB)==》片(Slice)==》片组==》图像(picture)

1.宏块(Macro Block):是H.264编码的基本单位,一个编码图像首先要划分成多个块(4x4 像素)才能进行处理,显然宏块应该是整数个块组成,通常宏块大小为16x16个像素。

宏块分为I、P、B宏块:

I宏块只能利用当前片中已解码的像素作为参考进行帧内预测;

P宏块可以利用前面已解码的图像作为参考图像进行帧内预测;

B宏块则是利用前后向的参考图形进行帧内预测

2.(Slice):一帧视频图像可编码成一个或者多个片,每片包含整数个宏块,即每片至少一个宏块,最多时包含整个图像的宏块。

     片的目的:为了限制误码的扩散和传输,使编码片相互间保持独立。

片共有5种类型:I片(只包含I宏块)、P片(P和I宏块)、B片(B和I宏块)、SP片(用于不同编码流之间的切换)和SI片(特殊类型的编码宏块)。

以下是片的句法结构:片头规定了片的类型、属于哪个图像、有关的参考图像等;片的数据包含了一系列宏块和不编码数据。

3.片组,是一个编码图像中若干宏块的一个子集,包含一个或若干个片。

一般一个片组中,每片的宏块是按扫描次序进行编码的,除非使用任意片次序(Arbitrary Slice Order, ASO)一个编码帧中的片之后可以跟随任一解码图像的片。

4.序列

参照一段时间内图像的统计结果表明,在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内。所以对于一段变化不大图像画面,我们可以先编码出一个完整的图像帧A,随后的B帧就不编码全部图像,只写入与A帧的差别,这样B帧的大小就只有完整帧的1/10或更小!B帧之后的C帧如果变化不大,我们可以继续以参考B的方式编码C帧,这样循环下去。这段图像我们称为一个序列(序列就是有相同特点的一段数据),当某个图像与之前的图像变化很大,无法参考前面的帧来生成,那我们就结束上一个序列,开始下一段序列,也就是对这个图像生成一个完整帧A1,随后的图像就参考A1生成,只写入与A1的差别内容
    在H264协议里定义了三种帧,完整编码的帧叫I帧,参考之前的I帧生成的只包含差异部分编码的帧叫P帧,还有一种参考前后的帧编码的帧叫B帧。
   H264采用的核心算法是帧内压缩和帧间压缩,帧内压缩是生成I帧的算法,帧间压缩是生成B帧和P帧的算法

在H264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流, 以I帧开始,到下一个I帧结束。

一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像。H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。
    一个序列就是一段内容差异不太大的图像编码后生成的一串数据流。当运动变化比较少时,一个序列可以很长,因为运动变化少就代表图像画面的内容变动很小,所以就可以编一个I帧,然后一直P帧、B帧了。当运动变化多时,可能一个序列就比较短了,比如就包含一个I帧和3、4个P帧。

压缩算法的说明
h264的压缩方法:
1.分组:把几帧图像分为一组(GOP,也就是一个序列),为防止运动变化,帧数不宜取多。
2.定义帧:将每组内各帧图像定义为三种类型,即I帧、B帧和P帧;
3.预测帧:以I帧做为基础帧,以I帧预测P帧,再由I帧和P帧预测B帧;
4.数据传输:最后将I帧数据与预测的差值信息进行存储和传输。
    帧内(Intraframe)压缩也称为空间压缩(Spatial compression)。当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间的冗余信息,这实际上与静态图像压缩类似。帧内一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩一般达不到很高的压缩,跟编码jpeg差不多。  
    帧间(Interframe)压缩的原理是:相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。也即连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。帧间压缩也称为时间压缩(Temporal compression),它通过比较时间轴上不同帧之间的数据进行压缩。帧间压缩一般是无损的。帧差值(Frame differencing)算法是一种典型的时间压缩法,它通过比较本帧与相邻帧之间的差异,仅记录本帧与其相邻帧的差值,这样可以大大减少数据量。
       顺便说下有损(Lossy )压缩和无损(Lossy less)压缩。无损压缩也即压缩前和解压缩后的数据完全一致。多数的无损压缩都采用RLE行程编码算法。有损压缩意味着解压缩后的数据与压缩前的数据不一致。在压缩的过程中要丢失一些人眼和人耳所不敏感的图像或音频信息,而且丢失的信息不可恢复。几乎所有高压缩的算法都采用有损压缩,这样才能达到低数据率的目标。丢失的数据率与压缩比有关,压缩比越小,丢失的数据越多,解压缩后的效果一般越差。此外,某些有损压缩算法采用多次重复压缩的方式,这样还会引起额外的数据丢失。

===================================================================================================

i帧 i frame,即内部画面 intra picture,通常是GOP的第一个帧(即IDR)
I帧是最大去除图像空间冗余信息而压缩得到的帧,自带全部信息,不参考其他帧可独立解码,称为帧内编码帧
所有视频至少包含一个I帧,且作为文件的第一个帧,文件里的其他的I帧用来改善视频质量,但增加了文件大小
一般而言,每秒视频至少需要1个I帧,每秒里增加I帧可以改善质量,但增加网络带宽和网络负载
视频播放过程中,若I帧丢失,则随后的P帧也就无法解析,所以出现黑屏现象,若P帧丢失,则出现花屏、马赛克现象

P帧,前向搜索帧/前向预测帧,以I帧预测P帧

B帧,双向搜索帧/双向内插帧,由I帧、P帧预测B帧


P帧压缩:根据本帧与相邻的前一帧(I帧或P帧)的不同点来压缩本帧数据
P帧重构:以前面相邻I帧为参考帧,计算P帧某点的预测值和运动矢量得到P帧某点样值
B帧压缩:根据本帧与相邻的前一帧的差值、本帧与相邻的后一帧的差值来压缩本帧数据
B帧重构:以相邻的前面相邻帧(I或P)、后面相邻帧(P)为参考,找出B帧某点的预测值和两个运动矢量得到B帧某点样值

I帧编码减少空间域冗余,P、B帧编码减少时间域冗余

NTSC = national television system committee 应用于美国、日本、加拿大、墨西哥等
PAL  = phase alternating line 应用于中国、香港、中东、欧洲
GOP  = group of pictures  其最大可含帧数量 18(NTSC)/15(PAL)
GOP是有固定模式的一系列I、P、B帧组成
常用结构由15帧(PAL)组成,具有以下形式IBBPBBPBBPBBPBB,简称GOP(4,2),指的是该图像组除了1个I帧外,包含4个P帧,且
任何相邻I、P之间或相邻P、P之间存在2个B帧

IDR  = instantaneous decoding refresh 即时解码刷新  IDR一定是I帧,但I帧不一定是IDR
为了区分帧序列的首个I帧和其他I帧,才定义首个I帧为IDR,解码器只可以从IDR开始解码,IDR表示一组新的帧序列GOP
在IDR帧之后的所有帧都不能引用该IDR之前的帧数据,在普通I帧之后的B、P帧可以引用该普通I帧之前的I帧
ID会导致DPB(decord picture buff 参考帧列表)清空,导致PPS、SPS参数更新

H264从结构上分为 视频编码层VCL(video coding layer)和网路抽象层NAL(network abstract layer)

VCL包括codec编解码功能(基于宏块模型)、运动补偿预测处理、循环过滤器处理

NAL把VCL的输出封装成NALU(网络抽象层单元),以适应基于包的网络传输或面向包的多路复用环境

NALU的第1个字节是NUAL类型字节,其格式如下

|0 |1 |2 |3 |4 |5 |6 |7 |

|F |NRI|Type              |

F:       1 bit  forbidden_zero_bit H.264规范声明值设置为1表示语法违例

NRI:  2 bit  nal_ref_idc 表示NALU的优先级。0--3,取值越大,该NALU越重要,需要优先保护

                                      00值表示该NALU不用于帧间图像预测重构参考图像,可以丢弃不用冒参考图像完整性风险。

                                      如果NALU是参考帧slice、PPS、SPS时,该值必须大于0

Type: 5 bit  nal_unit_type 表示NALU载荷类型,类型值定义如下

                                         0:未定义

                                         1:非IDR图像不采用数据划分片段

                                         2:非IDR图像采用数据划分片段A部分

                                         3:非IDR图像采用数据划分片段B部分

                                         4:非IDR图像采用数据划分片段C部分

                                         5:IDR图像片段

                                         6:补充增强信息 SEI

                                         7:序列参数集 SPS

                                         8:图像参数集 PPS

                                         9:分隔符

                                         10:序列结束符

                                         11:流结束符

                                         12:填充数据

                                         13:序列参数集扩展

                                         14:带前缀的NALU

                                         15:子序列参数集

                                         16-18:保留

                                         19:不采用数据划分的辅助编码图像片段

                                         20:编码片段扩展

                                         21-23:保留

                                         24-31:未定义

h264数据帧的NALU前面带有 00 00 00 01或 00 00 01 分隔符,一般VCL输出首帧数据为PPS、SPS,接着是IDR帧

00 00 00 01 67 SPS 00 00 00 01 68 PPS 00 00 00 01 65 IDR ... ...

分隔符作为NALU的开始边界和结束边界,解码器使用分隔符逐个字节匹配数据流,计算NALU的长度,然后开始解码

h264 序列、帧、slice关系

从大到小依次为:序列、帧(I、P、B帧)、片组、片(I、P、B、SP、SI片)、NALU、宏块、亚宏块、块、像素

序列

图像以序列为单位进行组织,GOP,序列就是一段连续图像帧且画面之间变化不大。

统计一段时间内图像的结果表明,相邻几幅图像,一般像素存在差别的点只有10%以内,亮度差值变化不超过2%,

色度差值变化只有1%以内。所以一段连续的图像画面之间变化不大,可以把第1帧编码为完整图像帧,第2帧只编

码其与前面一帧的差别,这样第2帧只是前一帧的1/10或更小,依次对第2帧之后的图像帧做同样处理,这样的一段

图像就是一个序列。当某个帧与前面的帧图像变化很大,无法参考前面帧生成时,就要开始一个新序列。

帧      :有1个或多个片组,如果不采用FMO(灵活宏块排序)机制,则一帧只有一个片组

片组  :包含1个片(slice)或多个片

片      :slice,由宏块组成,如果不采用DP(数据分割)机制,1个片只包含1个NALU,

               否则1个片由3个NALU组成,nal_unit_type值等于2、3、4的NALU属于同一个片

               分片的目的是限制误码的扩撒和传输,使片间保持独立,[ [slice header] [slice data] ]

               [slice header] 说明了片类型、属于哪个帧、参考帧等

               [slice data] 里是整数个宏块

宏块   :编码处理的基本单元,由多个块组成,通常宏块大小为16X16像素,分为I、B、P宏块

块       :一个编码图像要划分成多个块才能进行处理,一个块是4X4像素

图像解码过程是按照slice进行解码,然后按照片组将解码宏块重组成图像

猜你喜欢

转载自blog.csdn.net/xiaolei251990/article/details/82787911