原文:https://blog.csdn.net/hbuxiaofei/article/details/50502330
****1卿樱、H264 NAL頭漩氨。****
NAL全稱(chēng)Network Abstract Layer相寇,即網(wǎng)絡(luò)抽象層貌踏。在H.264/AVC視頻編碼標(biāo)準(zhǔn)中白翻,整個(gè)系統(tǒng)框架被分為了兩個(gè)層面:視頻編碼層面(VCL)和網(wǎng)絡(luò)抽象層面(NAL)猜年。其中根欧,前者負(fù)責(zé)有效表示視頻數(shù)據(jù)的內(nèi)容羽杰,而后者則負(fù)責(zé)格式化數(shù)據(jù)并提供頭信息渡紫,以保證數(shù)據(jù)適合各種信道和存儲(chǔ)介質(zhì)上的傳輸。NAL單元是NAL的基本語(yǔ)法結(jié)構(gòu)考赛,它包含一個(gè)字節(jié)的頭信息和一系列來(lái)自VCL的稱(chēng)為原始字節(jié)序列載荷(RBSP)的字節(jié)流惕澎。
如果NALU對(duì)應(yīng)的Slice為一幀的開(kāi)始,則用4字節(jié)表示欲虚,即0x00000001集灌;否則用3字節(jié)表示,0x000001复哆。
NAL Header : forbidden_bit 欣喧, nal_reference_bit (優(yōu)先級(jí)) 2bit , nal_unit_type (類(lèi)型) 5bit 梯找。 標(biāo)識(shí)NAL單元中的RBSP數(shù)據(jù)類(lèi)型唆阿,其中,nal_unit_type為1锈锤, 2驯鳖, 3, 4久免, 5的NAL單元稱(chēng)為VCL的NAL單元浅辙,其他類(lèi)型的NAL單元為非VCL的NAL單元。
0:未規(guī)定
1:非IDR圖像中不采用數(shù)據(jù)劃分的片段
2:非IDR圖像中A類(lèi)數(shù)據(jù)劃分片段
3:非IDR圖像中B類(lèi)數(shù)據(jù)劃分片段
4:非IDR圖像中C類(lèi)數(shù)據(jù)劃分片段
5:IDR圖像的片段
6:補(bǔ)充增強(qiáng)信息(SEI)
7:序列參數(shù)集(SPS)
8:圖像參數(shù)集(PPS)
9:分割符
10:序列結(jié)束符
11:流結(jié)束符
12:填充數(shù)據(jù)
13:序列參數(shù)集擴(kuò)展
14:帶前綴的NAL單元
15:子序列參數(shù)集
16 – 18:保留
19:不采用數(shù)據(jù)劃分的輔助編碼圖像片段
20:編碼片段擴(kuò)展
21 – 23:保留
24 – 31:未規(guī)定
NAL的頭占用了一個(gè)字節(jié)阎姥,按照比特自高至低排列可以表示如下:
0AABBBBB
其中记舆,AA用于表示該NAL是否可以丟棄(有無(wú)被其后的NAL參考),00b表示沒(méi)有參考作用呼巴,可丟棄泽腮,如B slice、SEI等衣赶,非零——包括01b诊赊、10b、11b——表示該NAL不可丟棄府瞄,如SPS碧磅、PPS、I Slice、P Slice等续崖。常用的 NAL 頭 的取值如:
0x67: SPS
0x68: PPS
0x65: IDR
0x61: non-IDR Slice
0x01: B Slice
0x06: SEI
0x09: AU Delimiter
由于NAL的語(yǔ)法中沒(méi)有給出長(zhǎng)度信息敲街,實(shí)際的傳輸、存儲(chǔ)系統(tǒng)需要增加額外的頭實(shí)現(xiàn)各個(gè)NAL單元的定界严望。
其中,AVI文件和MPEG TS廣播流采取的是字節(jié)流的語(yǔ)法格式逻恐,即在NAL單元之前增加0x00000001的同步碼像吻,則從AVI文件或MPEG TS PES包中讀出的一個(gè)H.264視頻幀以下面的形式存在:
00 00 00 01 06 ... 00 00 00 01 67 ... 00 00 00 01 68 ... 00 00 00 01 65 ...
SEI信息 SPS PPS IDR Slice
而對(duì)于MP4文件,NAL單元之前沒(méi)有同步碼复隆,卻有若干字節(jié)的長(zhǎng)度碼拨匆,來(lái)表示NAL單元的長(zhǎng)度,這個(gè)長(zhǎng)度碼所占用的字節(jié)數(shù)由MP4文件頭給出挽拂;此外惭每,從MP4讀出來(lái)的視頻幀不包含PPS和SPS,這些信息位于MP4的文件頭中亏栈,解析器必須在打開(kāi)文件的時(shí)候就獲取它們台腥。從MP4文件讀出的一個(gè)H.264幀往往是下面的形式(假設(shè)長(zhǎng)度碼為2字節(jié)):
00 19 06 [... 25 字節(jié)...] 24 aa 65 [... 9386 字節(jié)...]
SEI信息 IDR Slice
2、幀分割绒北。 在實(shí)際的H264數(shù)據(jù)幀中黎侈,往往幀前面帶有00 00 00 01 或 00 00 01分隔符,一般來(lái)說(shuō)編碼器編出的首幀數(shù)據(jù)為PPS與SPS闷游,接著為I幀……
如下圖:
[圖片上傳失敗...(image-3914e4-1623751823950)]
3峻汉、如何判斷幀類(lèi)型(是圖像參考幀還是I、P幀等)脐往?
NALU類(lèi)型是我們判斷幀類(lèi)型的利器休吠,從官方文檔中得出如下圖:
[圖片上傳失敗...(image-6c3738-1623751823950)]
我們還是接著看最上面圖的碼流對(duì)應(yīng)的數(shù)據(jù)來(lái)層層分析,以00 00 00 01分割之后的下一個(gè)字節(jié)就是NALU類(lèi)型业簿,將其轉(zhuǎn)為二進(jìn)制數(shù)據(jù)后瘤礁,解讀順序?yàn)閺淖笸宜悖缦? (1)第1位禁止位辖源,值為1表示語(yǔ)法出錯(cuò)
(2)第2~3位為參考級(jí)別
(3)第4~8為是nal單元類(lèi)型
例如上面00000001后有67,68以及65
其中0x67的二進(jìn)制碼為: 0110 0111
4-8為00111蔚携,轉(zhuǎn)為十進(jìn)制7,參考第二幅圖:7對(duì)應(yīng)序列參數(shù)集SPS
其中0x68的二進(jìn)制碼為: 0110 1000
4-8為01000克饶,轉(zhuǎn)為十進(jìn)制8酝蜒,參考第二幅圖:8對(duì)應(yīng)圖像參數(shù)集PPS
其中0x65的二進(jìn)制碼為: 0110 0101
4-8為00101,轉(zhuǎn)為十進(jìn)制5矾湃,參考第二幅圖:5對(duì)應(yīng)IDR圖像中的片(I幀)
所以判斷是否為I幀的算法為: (NALU類(lèi)型 & 0001 1111) = 5 即 NALU類(lèi)型 & 31 = 5
比如0x65 & 31 = 5
參見(jiàn):http://blog.csdn.net/jefry_xdz/article/details/8461343