前面幾篇文章主要介紹了YUV,RGB的像素處理以及簡單介紹了一下JPEG的壓縮原理,接下來開始介紹視頻碼流的決議代碼,
一、什么是NALU
H264裸流由一個個NALU組成,它們的結構如下圖所示,

所以這里有必要介紹一下NALU是什么
NALU (Network Abstraction Layer Unit) 翻譯過來就是網路抽象層單元,在 H.264/AVC 視頻編碼標準中,所有的碼流資料,最終都被封裝成了一個一個的 NALU(Network Abstract Layer Unit)就是網路抽象層單元,
既然是視頻流,那么NALU里面存放的必然有視頻資料,除此之外,還有一些其他的資訊,比如說時間戳,幀率,畫面是否翻轉等等資訊,這些資料以每個NALU為一個單元,可以進行網路傳輸(推流),或者本地解碼(播放),
二、H264常用的封裝形式
H264流行的封裝形式有兩種,分別為AnnexB和AVCC,對于這兩種格式,與硬體編解碼的支持廠家有關,比如Android硬解碼只支持AnnexB,Apple的VideoBox只支持AVCC格式,本文先對AnnexB做出展開性討論,
三、AnnexB封裝格式淺析
在第一小節說了H264是由一個個NALU組成的,在AnnexB封裝格式中,為了區分前后的NALU,每個NALU資料的頭部都設定了起始碼(Startcode)以便于分隔,資料的具體格式為0x00 00 01(占3個位元組)或0x00 00 00 01(占4個位元組),下面來查看一下一段H264裸流的二進制檔案

其中0x00 00 00 01就代表著起始碼,后面的資料就是每個NALU里面的資料,每個NALU通過起始碼來標記這個NALU的開始,嗯,就是這么簡單,可能這時候有問題了,如果NALU資料里面也出現了0x00 00 01這種資料,該怎么區分呢,稍安勿躁,下一小節會繼續解釋,
四、防競爭位元組
剛剛說了,如果在NALU資料中出現了0x00 00 01這種資料,會導致讀取程式將一個NALU誤分隔為多個NALU,為了防止這種情況發生,AnnexB引入了防競爭位元組的概念,具體的實作如下:
0x 00 00 00 ====> 0x00 00 03 00
0x 00 00 01 ====> 0x00 00 03 01
0x 00 00 02 ====> 0x00 00 03 02 (0x000002作保留用,暫時也用不到)
0x 00 00 03 ====> 0x00 00 03 03 (避免原始資料中出現0x00 00 03,沖突)
也就是在0x00 00的后面插入一個03,這樣就不會引起讀取程式的誤會了,不會再和起始碼(0x00 00 01, 0x00 00 00 01)重復而發生沖突,
注意:在解包后進行解碼時,要將防競爭位元組去掉,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/273620.html
標籤:其他
