在上一節中通過一個小程序,可以提取NAL Unit所包含的的字節數據。H.264碼流中的每一個NAL Unit的作用並不是相同的,而是根據不同的類型起不同的作用。下面將對NAL Unit中的數據進行解析。
一、NAL Unit結構
一個NAL Unit都是由一個NAL Header和一個NAL Body組成。對於基本版本的H.264標准(不考慮SVC和MVC擴展),一個NAL Header的長度固定為1,即8bit。這8bit的含義分別為:
- forbidden_zero_bit:每一個NAL Header的第一個bit,規定必須為0;
- nal_ref_idc:第2和3位,主要表示NAL的優先級。當該值為正時,表示當前NAL Unit中包含了SPS、PPS和作為參考幀的Slice等重要數據。
- nal_unit_type:表示NAL Unit的類型,包括VCL層和非VCL層的多種數據類型。常見的nal_unit_type取值有:7表示SPS,8表示PPS,5表示IDR幀,1表示非IDR幀等。

查詢H.264文檔7.3節,可以看到NAL Unit語法結構:
7.4節介紹了每一個語法結構的內容和作用

二、NAL Unit的有效負載數據及其封裝
在NAL Header之后,NAL Unit的其余部分,即NAL Body包含了有效負載數據的封裝。從NAL Body到實際的語法元素的碼流共3層封裝:
第一層:EBSP——擴展字節序列載荷
EBSP全稱為Extended Byte String Payload,等同於NAL Body的數據本身。在EBSP中包含了一個特殊的字節0x03,表示防止競爭校驗字節:
emulation_prevention_three_byte:設置該值的目的是為了防止NAL Body內部出現於NAL Unit起始碼0x 00 00 01或0x 00 00 00 01沖突。
當內部的連續4字節數據出現了下列情況時:
0x 00 00 00
0x 00 00 01
0x 00 00 02
0x 00 00 03
在兩個0字節之后會插入值為3的一個字節,形成下列情況:
0x 00 00 03 00
0x 00 00 03 01
0x 00 00 03 02
0x 00 00 03 03
在進行解析時需要將附加的03字節去掉,得到RBSP數據。
第二層:RBSP——原始字節序列載荷
RBSP全稱為Raw Byte Sequence Payload,相當於NAL Body去掉emulation_prevention_three_byte之后的數據,是對原始的語法元素碼流進一步處理后產生的數據。
作用:字節對齊。
每一個NAL Unit都是緊密排列的,如果出現一個UAL unit字節沒對齊,后面的就都對不齊,那就需要時刻進行數據位的對齊操作, 會對接收端和解碼端造成極大的負擔。
在語法元素編碼后,並不一定占滿了所有的比特,最后可能會空出幾位來。為了補全一位數據,RBSP在末尾添加了rbsp_trailing_bits()部分,其主要目的是字節對齊。
每個rbsp_trailing_bits()包括一個1bit和若干個0bit,0bit的個數不定,以實現字節的對齊。
例如:一個字節中前三位編碼了語法元素1 0 1,后面還剩5位,需要補上1 0 0 0 0,湊成一個字節。
完整的一個字節為 1 0 1 1 0 0 0 0。
第三層:SODB——數據字節流
SODB全稱為String Of Data Bits,表示H.264的語法元素編碼完成后的實際的原始二進制碼流。SODB通常不能保證字節對其。
