1. 程式人生 > >H264視訊碼流格式淺析

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