h264 NALU的获取与分析

本文详细介绍了如何从H264数据流中提取NALU,包括NALU的起始标志、类型及其在SPS、PPS、I帧等关键帧的识别,以及不同帧类型的特性。通过实例和类型列表,帮助理解H.264编码的基本结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、如何从H264数据流中获取NALU

0x00000001或0x000001是一个nalu的起始标志,遇到下一个此标志时为该nalu的结尾。起始标志的后面第一个字节(type)里包含有nalu的类型,type & 0x1F即为该nalu的类型(nal_unit_type),具体类型分析详见下节。

2、H264帧分类

一、PPS与SPS

nal_unit_type=7时,nalu为SPS;nal_unit_type=8时,nalu为PPS。

SPS(Sequence Parameter Set)序列参数集,PPS(Picture Parameter Set)图像参数集。SPS和PPS串,包含了初始化H.264解码器所须要的信息参数,包括编码所用的profile,level,图像的宽和高,deblock滤波器等。若是对获取的nalu去掉开始码以后进行base64编码,获得的信息就能够用于sdp(SPS和PPS须要用逗号分隔开来)。下图为一个完整的sdp,sprop-parameter-sets为SPS和PPS的base64码,逗号前的为SPS,逗号后的为PPS:
 

2、I帧

nal_unit_type=5是,nalu为I帧。

I帧全名叫“IDR图像的编码条带”,俗称关键帧,也叫帧内编码帧 ,你能够理解为这一帧画面的完整保留;解码时只须要本帧数据就能够完成(由于包含完整画面)。

I帧特色:

1)它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输;

2)解码时仅用I帧的数据就可重构完整图像;

3)I帧描述了图像背景和运动主体的详情;

4)I帧不须要参考其余画面而生成;

5)I帧是P帧和B帧的参考帧(其质量直接影响到同组中之后各帧的质量);

6)I帧是帧组GOP (Group of Pictures)的基础帧(第一帧),在一组中只有一个I帧;

7)I帧不须要考虑运动矢量;

8)I帧所占数据的信息量比较大。

三、nal_unit_type=1时,nalu为“非IDR图像的编码条带”,为P或B帧。

P帧:前向预测编码帧。P帧表示的是这一帧跟以前的一个关键帧(或P帧)的差异,解码时须要用以前缓存的画面叠加上本帧定义的差异,生成最终画面。(也就是差异帧,P帧没有完整画面数据,只有与前一帧的画面差异的数据)

P帧的预测与重构:P帧是以I帧为参考帧,在I帧中找出P帧“某点”的预测值和运动矢量,取预测差值和运动矢量一块儿传送。在接收端根据运动矢量从I帧中找出P帧“某点”的预测值并与差值相加以获得P帧“某点”样值,从而可获得完整的P帧。

P帧特色:

1)P帧是I帧后面相隔1~2帧的编码帧;

2)P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测偏差);

3)解码时必须将I帧中的预测值与预测偏差求和后才能重构完整的P帧图像;

4)P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;

5)P帧能够是其后面P帧的参考帧,也能够是其先后的B帧的参考帧;

6)因为P帧是参考帧,它可能形成解码错误的扩散;

7)因为是差值传送,P帧的压缩比较高。

B帧:双向预测内插编码帧。B帧是双向差异帧,也就是B帧记录的是本帧与先后帧的差异(具体比较复杂,有4种状况,但我这样说简单些),换言之,要解码B帧,不只要取得以前的缓存画面,还要解码以后的画面,经过先后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,可是解码时CPU会比较累。

B帧的预测与重构

B帧之前面的I或P帧和后面的P帧为参考帧,“找出”B帧“某点”的预测值和两个运动矢量,并取预测差值和运动矢量传送。接收端根据运动矢量在两个参考帧中“找出(算出)”预测值并与差值求和,获得B帧“某点”样值,从而可获得完整的B帧。

B帧特色

1)B帧是由前面的I或P帧和后面的P帧来进行预测的;

2)B帧传送的是它与前面的I或P帧和后面的P帧之间的预测偏差及运动矢量;

3)B帧是双向预测编码帧;

4)B帧压缩比最高,由于它只反映了参考帧间运动主体的变化状况,预测比较准确;

5)B帧不是参考帧,不会形成解码错误的扩散。

注:I、B、P各帧是根据压缩算法的须要,是人为定义的,它们都是实实在在的物理帧。通常来讲,I帧的压缩率是7(跟JPG差很少),P帧是20,B帧能够达到50。可见使用B帧能节省大量空间,节省出来的空间能够用来保存多一些I帧,这样在相同码率下,能够提供更好的画质。

3、h264 NALU分析示例

下图为用UE打开的一个h264文件:

该段数据中共有4个nalu,红色标注部分为4个nalu的起始位置,开头均为0x00000001四个字节,根据起始的第五个字节分析,段1:0x06 & 0x1f = 6,nalu为辅助加强信息 (SEI);段2:0x67 & 0x1f = 7,nalu为SPS;段3:0x68 & 0x1f = 8,nalu为PPS;段4:0x65 & 0x1f = 5,nalu为I帧。

4、附录

nal_unit_type类型列表:

nal_unit_typeNAL 单元和 RBSP 语法结构的内容备注
0未指定
1一个非IDR图像的编码条带
slice_layer_without_partitioning_rbsp( )
2编码条带数据分割块A
slice_data_partition_a_layer_rbsp( )
3编码条带数据分割块B
slice_data_partition_b_layer_rbsp( )
4编码条带数据分割块C
slice_data_partition_c_layer_rbsp( )
5IDR图像的编码条带
slice_layer_without_partitioning_rbsp( )
I帧
6辅助加强信息 (SEI)
sei_rbsp( )
7序列参数集
seq_parameter_set_rbsp( )
SPS
8图像参数集
pic_parameter_set_rbsp( )
PPS
9访问单元分隔符
access_unit_delimiter_rbsp( )
10序列结尾
end_of_seq_rbsp( )
11流结尾
end_of_stream_rbsp( )
12填充数据
filler_data_rbsp( )
13序列参数集扩展
seq_parameter_set_extension_rbsp( )
14...18保留
19未分割的辅助编码图像的编码条带
slice_layer_without_partitioning_rbsp( )
20...23保留
24...31未指定

下面是h264标准中定义的nalu类型宏:

#define NALU_TYPE_SLICE 1

#define NALU_TYPE_DPA 2

#define NALU_TYPE_DPB 3

#define NALU_TYPE_DPC 4

#define NALU_TYPE_IDR 5

#define NALU_TYPE_SEI 6

#define NALU_TYPE_SPS 7

#define NALU_TYPE_PPS 8

#define NALU_TYPE_AUD 9

#define NALU_TYPE_EOSEQ 10

#define NALU_TYPE_EOSTREAM 11

#define NALU_TYPE_FILL 12

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值