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對檔案的播放並無太大影響。
SEI(Supplemental Enhancement Information):輔助增強資訊。這裡面可以存放一些影片簡介,版權資訊或者作者自己新增的一些資訊。
參考文章:
http://www.cnblogs.com/skyseraph/archive/2012/04/01/2429384.html
http://blog.csdn.net/mandagod/article/details/51174680