天天看點

H264視訊碼流格式淺析

針對H264碼流格式說明,網上已經有很多介紹了,最近也在看這個,這裡根據自己了解,做個記錄。

1、H264的功能分為兩層:視訊編碼層(VLC,Video Coding Layer)和網絡提取層(NAL, Network Abstraction Layer)。VLC資料即

編碼處理的輸出,它表示被壓縮編碼後的視訊資料序列。在VCL資料傳輸或存儲之前,這些編碼的VCL資料先被映射或封裝進NAL單

元。每個NAL單元包括一個原始位元組序列負荷(RBSP, Raw Byte Sequence Payload)、一組對應于視訊編碼的NAL頭資訊。

這裡說明下RBSP,EBSP,SODB。

SODB:(String of Data Bits)最原始的編碼資料,無任何附加資料。

RBSP:在SODB的基礎上增加了rbsp_stop_ont_bit(bit值為1)并用0按位元組補位對齊。

EBSP:(Encapsulation Byte Sequence Packets)在RBSP的基礎上增加了防止僞起始碼位元組(0x03)。

RBSP的基本結構是在原始編碼資料的後面添加了結尾比特。一個bit”1”,若幹比特”0”,以便位元組對齊。

NAL單元序列如下:

圖1

每個NAL單元包括NAL頭+RBSP。

典型的RBSP單元如下:

現在來具體的說明下NAL頭和RBSP。

NAL頭結構為:

+—————+

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

+-+-+-+-+-+-+-+-+

|F|NRI| Type |

+—————+

NAL頭說明:

針對Type的說明為:

然後我們根據一個實際的H264檔案内容看下:

我們可以看到NAL的單元有SPS、PPS、SEI、IDR_SLICE等。NAL單元裡面的頭也顯示了,頭結構裡面的nal_unit_type表示了RBSP是什麼類型。這裡要說明一點NAL_Size的大小是不包括startcode大小的。

接下來說明下起始碼即剛剛上面提到的startcode。

起始碼:如果NALU對應的Slice為一幀的開始,則用4位元組表示,即0x00000001;否則用3個位元組表示,即0x000001。

另外這裡要用到上面提到的EBSP。為了使NALU的主體不包括起始碼,在編碼的時候每遇到兩個位元組(連續)的0,就插入一個位元組0x03,以便和起始碼相差別,解碼時,則将相應的0x03删除掉。是以有時候NAL單元有可能是NAL頭+EBSP組成。

NALU主體 編碼時插入0x03

0x000000 >>>>>> 0x00000300

0x000001 >>>>>> 0x00000301

0x000002 >>>>>> 0x00000302

0x000003 >>>>>> 0x00000303

接下來對應剛剛的H264,其檔案資料表示如下:

前面兩個0x00000001對應PPS和SPS,第三個0x000001對應SEI。

2、接下來說說SPS、PPS和SEI。

SPS和PPS是用來初始化解碼器的,沒這些資料,視訊資料是無法解析出來的。另外如果我們分析單獨的H264檔案,可以發現有的檔案每個IDR幀前面都有PPS和SPS,有的隻是開頭才有。針對SPS和PPS,一般來說:

1)、如果是在直播的話,每個IDR幀前面都應該加上SPS和PPS,因為有的觀衆會中途進來觀看。

2)、如果是本地穩定檔案,可以在開頭加上SPS和PPS,或者都加上,這個根據具體需要來。

另外說明下SEI,有的H264檔案有SEI,有的則沒有,這說明SEI對檔案的播放并無太大影響。

繼續閱讀