H264碼流結(jié)構(gòu)
無(wú)論是解析視頻文件或這通過(guò)網(wǎng)絡(luò)傳輸, 其實(shí)都是一串字節(jié)序列. H264碼流就是按照一定的規(guī)則組織排列的字節(jié)串.
直觀理解的角度
按照從大到小分為: 視頻序列, 圖像幀, 片,宏塊,子塊
碼流功能的角度
從碼流功能的角度可以分為兩層:NAL層和VCL層
- NAL網(wǎng)絡(luò)提取層:負(fù)責(zé)以網(wǎng)絡(luò)所要求的恰當(dāng)?shù)姆绞綄?duì)數(shù)據(jù)進(jìn)行打包和傳送
- VCL視頻編碼層:包括核心壓縮引擎和塊颁湖,宏塊和片的語(yǔ)法級(jí)別定義,設(shè)計(jì)目標(biāo)是盡可能地獨(dú)立于網(wǎng)絡(luò)進(jìn)行高效的編碼
碼流解析的角度
可以理解為有一個(gè)一個(gè)的NALU單元組成.
一個(gè)NALU單元分成兩部分: NAL頭和RBSP(Raw ByteSequence Payload)原始字節(jié)序列載荷.
前面提到的一幀圖像(I幀, P幀, B幀)就是一個(gè)NALU單元, NALU單元除了代表圖像外還能包含其他類型的數(shù)據(jù),如PPS和SPS, 詳細(xì)的內(nèi)容在下節(jié)列出來(lái).
前面提到的VCL層, 或者說(shuō)VCL數(shù)據(jù),是指視頻編碼生成的壓縮比特流片段,被稱為SODB(String of Data Bits),
SODB是RBSP的原始幀, 即RBSP包含了SODB數(shù)據(jù)
NALU
一個(gè)NALU由 固定長(zhǎng)度的Header和RBSP組成
HEADER
NAL Header的結(jié)構(gòu)如下:
- forbidden_zero_bit
在網(wǎng)絡(luò)傳輸中發(fā)生錯(cuò)誤時(shí),會(huì)被置為1欠橘,告訴接收方丟掉該單元;否則為0 - nal_ref_idc
用于表示當(dāng)前NALU的重要性啥供,值越大忘伞,越重要.
解碼器在解碼處理不過(guò)來(lái)的時(shí)候,可以丟掉重要性為0的NALU. -
nal_unit_type
表示NALU數(shù)據(jù)的類型,有以下幾種:
72.png
其中比較注意的應(yīng)該是以下幾個(gè):
- 1-4:I/P/B幀,如果nal_ref_idc 為0 則表示I幀,不為0則為P/B幀
- 5:IDR幀,I幀的一種微峰,告訴解碼器舷丹,之前依賴的解碼參數(shù)集合(接下來(lái)要出現(xiàn)的SPS\PPS等)可以被刷新了。
- 6:SEI蜓肆,英文全稱Supplemental Enhancement Information颜凯,翻譯為“補(bǔ)充增強(qiáng)信息”,提供了向視頻碼流中加入額外信息的方法仗扬。
- 7:SPS症概,全稱Sequence Paramater Set,翻譯為“序列參數(shù)集”早芭。SPS中保存了一組編碼視頻序列(Coded Video Sequence)的全局參數(shù)彼城。因此該類型保存的是和編碼序列相關(guān)的參數(shù)。
- 8: PPS退个,全稱Picture Paramater Set募壕,翻譯為“圖像參數(shù)集”。該類型保存了整體圖像相關(guān)的參數(shù)帜乞。
- 9:AU分隔符司抱,AU全稱Access Unit,它是一個(gè)或者多個(gè)NALU的集合黎烈,代表了一個(gè)完整的幀习柠。
其中SPS,PPS 需要在I幀前出現(xiàn),不然解碼器沒(méi)法解碼.而SPS,PPS出現(xiàn)的頻率也跟不同應(yīng)用場(chǎng)景有關(guān),對(duì)于一個(gè)本地h264流,可能只要在第一個(gè)I幀前面出現(xiàn)一次就可以,但對(duì)于直播流,每個(gè)I幀前面都應(yīng)該插入sps或pps,因?yàn)橹辈r(shí)客戶端進(jìn)入的時(shí)間是不確定的.
RBSP
RBSP的結(jié)構(gòu)如下:
這部分還沒(méi)研究匀谣,似乎目前解析時(shí)ffmpeg都給實(shí)現(xiàn)了.
每個(gè)NALU前有一個(gè)起始碼 0x00 00 01(或者0x00 00 00 01), 作為NALU的分割符
下面是一個(gè)H264碼流:
分析其中比較有代表性的3幀:
- 00 00 00 01 67
00 00 00 01是一個(gè)NALU 開(kāi)始,67 是Header, 二進(jìn)制為0110 0111, nal_unit_type 為00111, 即7為SPS幀 - 00 00 00 01 68
68 二進(jìn)制為0110 1000, nal_unit_type 為00111, 即8為SPS幀 - 00 00 00 01 65
65 二進(jìn)制為0110 0101,nal_unit_type 為00101, 即5為IDR幀
H264 更詳細(xì)的分層結(jié)構(gòu)
關(guān)于多slice這塊目前還沒(méi)弄清楚资溃,后面弄清楚了再修改.