对H264码流数据的NAL起始字节分析(档次、NALU类型)

来源:互联网 发布:mcu选型软件 编辑:程序博客网 时间:2024/05/02 00:53
这是一段H264码流,00 00 00 01这是对应forbidden_zero_bit的f(1),接着后面的nal_ref_idc的u(2),这个怎么解呀,有点晕。刚接触不久,nal_unit_type的u(5),后面的profile_idc的u(8)指的是那几个,是多少?
H264码流的NAL起始字节分析

满意回答

00 00 00 01是Start code后面的ox67为 0110 0111

forbidden_zero_bit 是禁止位,应该是第一位即f(1)=0,1为语法有错误

nal_ref_idc是参考级别,代表被其它帧参考情况,u(2)= 11 = 3最(0为无参考,详见规范)

nal_unit_type是该帧的类型,为剩下的5位,u(5)= 0 0111 = 7

 

NOTE:这是NALU类型,非Slice类型,这里只能判断NALU类型,不能继续判断是普通i还是p等slice类型

 

NALU类型:

目前类型有:

//H264定义的类型 values for nal_unit_type

typedef enum {

 NALU_TYPE_SLICE    = 1,

 NALU_TYPE_DPA      = 2,

 NALU_TYPE_DPB      = 3,

 NALU_TYPE_DPC      = 4,

 NALU_TYPE_IDR      = 5,

 NALU_TYPE_SEI      = 6,

 NALU_TYPE_SPS      = 7,

 NALU_TYPE_PPS      = 8,

 NALU_TYPE_AUD      = 9,

 NALU_TYPE_EOSEQ    = 10,

 NALU_TYPE_EOSTREAM = 11,

 NALU_TYPE_FILL     = 12,

#if (MVC_EXTENSION_ENABLE)

 NALU_TYPE_PREFIX   = 14,

 NALU_TYPE_SUB_SPS  = 15,

 NALU_TYPE_SLC_EXT  = 20,

 NALU_TYPE_VDRD     = 24  // View and Dependency Representation Delimiter NAL Unit

#endif

} NaluType;

可以看出是NALU_TYPE_SPS  即sequence parameter sets

 

H264档次: 

profile_idc的u(8)则是后面的“64”转化为十进制则是100,

66 Baseline

77 Main

88 Extended

100 High (FRExt)

110 High 10 (FRExt)

122 High 4:2:2 (FRExt)

144 High 4:4:4 (FRExt)

 

100是High (FRExt)



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


使用RTSP传输H264的时候,需要用到sdp协议描述,其中有两项:Sequence Parameter Sets (SPS) Picture Parameter Set (PPS)需要用到,那么这两项从哪里获取呢?答案是从H264码流中获取.H264码流中,都是以"0x00 0x00 0x01"或者"0x00 0x00 0x00 0x01"为开始码的,找到开始码之后,使用开始码之后的第一个字节的5位判断是否为7(sps)或者8(pps), 及data[4] & 0x1f == 7 || data[4] & 0x1f == 8.然后对获取的nal去掉开始码之后进行base64编码,得到的信息就可以用于sdp. spspps需要用逗号分隔开来.


if(( 0 == *(lpDataBuf+0) ) && 

( 0 == *(lpDataBuf+1) ) && 

( 0 == *(lpDataBuf+2) ) && 

( 1 == *(lpDataBuf+3) )  )

{

fNalType = (0x01f&(*(lpDataBuf+4))); //5位判断是否为

}

if( 7 == fNalType )/*SPS*/

00 00 00 01是一个nalu的起始标志。后面的第一个字节,67,是nalu的类型,type & 0x1f == 0x7表示这个nalu是sps,== 0x8表示是pps


先理解关键知识点,不知道有没有误导,H264的帧是以 NAL单元的单位来传送的,一个NAL单元包含一帧(I帧 或 P帧 或 B帧),这三种类型的帧可以百度。所谓的NAL单元就是去掉SPS、PPS的视频帧, I帧是关键帧,所有的解析都需要靠它,两个I帧之间被称为视频序列,I帧头部需要加入SPS和PPS,这两个之间需要0x00000001来分割, 0x00 0x00 0x00 0x01 + SPS的Base64解码形式 + 0x00 0x00 0x00 0x01 + PPS的解码形式 + 0x00 0x00 0x00 0x01 视频帧(IDR帧) 这样组成的一个buffer,FFMPEG的H264解码器才能成功解码。


I帧和IDR帧的区别:

1  在 H.264 中 帧并不具有随机访问的能力,这个功能由 IDR 承担。以前的标准中由 帧承担。

2  IDR 会导致 DPB (参考帧列表——这是关键所在)清空,而 不会。

3  IIDR帧其实都是I,都是使用帧内预测的。但是IDR帧的作用是立刻刷新,使错误不致传播,IDR帧开始,重新算一个新的序列开始编码。

4  IDR图像一定是I图像,但I图像不一定是IDR图像。一个序列中可以有很多的I图像,I图像之后的图像可以引用I图像之间的图像做运动参考。


0 0
原创粉丝点击