Skip to content

Latest commit

 

History

History

audio_video

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

H.264视频码流解析

H.264原始码流(又称为“裸流”)是由一个一个的NALU组成的。他们的结构如下图所示。

|NALU|NALU|NALU|....

其中每个NALU之间通过startcode(起始码)进行分隔,起始码分成两种:0x000001(3Byte)或者0x00000001(4Byte)。如果NALU对应的Slice为一帧的开始就用0x00000001,否则就用0x000001。 H.264码流解析的步骤就是首先从码流中搜索0x000001和0x00000001,分离出NALU;然后再分析NALU的各个字段。本文的程序即实现了上述的两个步骤。

一、 移除H264的NAL防竞争码(0x03)

H264附录B指明一种简单高效的方案解决解码器分辨每个NAL的起始位置和终止位置-当数据流存储在介质中时,在每个NAL前添加:0x000001

在某些类型的存储介质中,为了寻址方便,要求数据流在长度上对齐,或必须是某个常数的倍数。考虑到这种情况,H264建议在起始码前添加若干字节的0来填充,直到该NAL的长度符合要求。

在这样的机制下,解码器在码流中检测起始码,作为一个NAL的起始标志,当检测到下一个起始码时当前NAL结束。H264规定当检测到0x000000时也可以表征当前NAL的结束,这是因为连着的3个字节的0中任何一个字节的0要么属于起始码,要么是起始码前面的0。

但是如果NAL内部出现了0x000001或0x000000的序列怎么办?解决办法如下:

0x000000------------->0x00000300

0x000001-------------->0x00000301

0x000002-------------->0x00000302

0x000003-------------->0x00000303

就是在0000后面加上03;

有人问:如果原序列中本来就有个0x00000303呢?会不会导致歧义?

答案肯定是不会的,假设原序列:0x00 00 03 03 ....

那么经过转换之后变成: 0x00 00 03 03 03.....

解码之后:0x00 00 03 03

解码之后的数据和原序列一样。所以不用担心产生歧义。 移除H264的NAL防竞争码(0x03)