音視頻開發(fā)之旅(56) -H264/AVC基本結(jié)構(gòu)

從這篇開始栅螟,我們進(jìn)入H264的學(xué)習(xí)實(shí)踐,主要分三個(gè)階段

  1. 學(xué)習(xí)H264基本結(jié)構(gòu)和碼流協(xié)議步绸;2. 了解具體編碼壓縮技術(shù)吃媒;3. 分析了解相關(guān)開源庫 x264和h264bitstream赘那。

這篇我們來一起學(xué)習(xí)H264的基本結(jié)構(gòu)

目錄

  1. H264/AVC的目標(biāo)和方案
  2. H264分層結(jié)構(gòu)- VCL和NAL
  3. NALU HEAD解析
  4. NALU payload
  5. I/P/B幀的特點(diǎn)
  6. 切片Slice和宏塊
  7. 資料
  8. 收獲

一、H264/AVC的目標(biāo)和方案

音視頻編碼的標(biāo)準(zhǔn)由標(biāo)準(zhǔn)發(fā)展組織制定漾月,主要兩大組織:ISO(國際標(biāo)準(zhǔn)化組織和國際電工委員會(huì))和ITU-T(國際電信聯(lián)盟的電信標(biāo)準(zhǔn)化部門)

MPEG-1胃珍、MPEG-2蜓陌、MPEG-4 part2吩蔑、有ISO制定
H.261烛芬、H.262、H.263有ITU-T制定
H264/MPEG-4 part10 以及HEVC(h265) 有ISO和ITU-T等聯(lián)合制定

H.264 的主要目標(biāo):

1)高的視頻壓縮比仆潮,當(dāng)初提出的指標(biāo)是比H.263遣臼,MPEG-4,約為它們的2 倍鹏浅,現(xiàn)在都已基本實(shí)現(xiàn)屏歹;
2)良好的網(wǎng)絡(luò)親和性蝙眶,即可適用于各種傳輸網(wǎng)絡(luò)。
為此械馆,H.264 的功能分為兩層,即視頻編碼層(VCL)和網(wǎng)絡(luò)提取層(NAL)武通。
VCL 數(shù)據(jù)即編碼處理的輸出霹崎,它表示被壓縮編碼后的視頻數(shù)據(jù)序列。
在VCL 數(shù)據(jù)傳輸或存儲(chǔ)之前,這些編碼的VCL 數(shù)據(jù),先被映射或封裝進(jìn)NAL 單元中吟税。

*** h264編碼的主要流程**


壓縮技術(shù)
H264/MPEG-4 part10 是運(yùn)用比較廣泛的編碼標(biāo)準(zhǔn)協(xié)議
為了實(shí)現(xiàn)目標(biāo)偎球,H264在H263的基礎(chǔ)上增加了如下壓縮技術(shù)

1. 雙向運(yùn)動(dòng)補(bǔ)償
2. 以小塊進(jìn)行的可變塊運(yùn)動(dòng)補(bǔ)償
3. 四分之一像素運(yùn)動(dòng)補(bǔ)償
4. 環(huán)路濾波器
5. 變長編碼
6. 加權(quán)預(yù)測
7. 可伸縮視頻編碼
8. 多視點(diǎn)編碼等

二蚊俺、H264分層結(jié)構(gòu)- VCL和NAL

上一小節(jié),我們?yōu)榱藢?shí)現(xiàn)H264的兩個(gè)目標(biāo),H264功能上進(jìn)行了分層默赂,視頻編碼層(VCL, Video Coding Layer)網(wǎng)絡(luò)提取層(NAL, Network Abstraction Layer)
其中括勺,VCL(Video Coding Layer)視頻編碼層缆八,包括核心壓縮引擎和塊曲掰、宏塊和片的語法級(jí)別定義,設(shè)計(jì)目標(biāo)是盡可能地獨(dú)立于網(wǎng)絡(luò)進(jìn)行高效的編碼奈辰,負(fù)責(zé)有效表示視頻數(shù)據(jù)的內(nèi)容栏妖。
而 NAL(Network Abstraction Layer)網(wǎng)絡(luò)提取層,負(fù)責(zé)將 VCL 產(chǎn)生的比特字符串適配到各種各樣的網(wǎng)絡(luò)和多元環(huán)境中奖恰,覆蓋了所有片級(jí)以上的語法級(jí)別吊趾; 一個(gè)NALU 單元常由 [NALU Header] + [NALU Payload] 部分組成,
NAL對(duì)VCL進(jìn)行了封裝包裹

圖片來自:VCL & NAL (H.264/AVC)

三瑟啃、NALU HEAD解析

為了分析H264论泛,我們先通過如下命令 提取視頻

保留編碼格式:ffmpeg -i test.mp4 -vcodec copy -an test_copy.h264

強(qiáng)制格式:ffmpeg -i test.mp4 -vcodec libx264 -an test.h264

然后用010Editor打開提取的h264文件,如下所示:


H264 分成兩種流格式翰守,一種是 Annex-B 格式(上圖看到的就是這種格式)孵奶,一種是 RTP 包流的格式。
Annex-B 格式是默認(rèn)的輸出格式蜡峰。數(shù)據(jù)單元的分割使用[StartCode] (0x000001或0x00000001 )作為起始碼了袁。

NALU 單元常由 [NALU Header] [NALU Payload] 組成,

NALU Header是緊隨StartCode后的一個(gè)字節(jié)湿颅,按照位劃分三塊载绿。

其中第1位,表示禁止位油航,為1禁止使用該NALU單元崭庸,為0可以使用。
第2-3位是參考級(jí)別(NRI谊囚,NAL ref idc)表示重要性怕享,值越大說明越重要。比如在做丟幀處理時(shí)镰踏,就是通過這兩位來判斷該幀是否被依賴函筋,進(jìn)而決定是否可以被丟棄。
后面的5位表示NLAU的類型奠伪,其值的含義具體見下表

圖片來自:https://zhuanlan.zhihu.com/p/71928833
我們可以看到NAL類型分為兩類跌帐,VCL和非VCL。其中 包含圖像數(shù)據(jù)的unit屬于VCL NAL units; SPS绊率、PPS谨敛、和SEI 屬于Non-VCL NAL Units;

下面我們分別看下 我們的h264截圖中的 06、67滤否、68代表什么意思脸狸?

0x06 --二進(jìn)制化--》00000110 --取后五位--》000 00110 值位6 ,查看上表藐俺,發(fā)現(xiàn)是SEI即補(bǔ)充增強(qiáng)信息單元肥惭,可以向視頻碼流中加入額外信息的方法

0x67 --二進(jìn)制化--》01100111 --取后五位--》000 00111 值位7 盯仪,查看上表,發(fā)現(xiàn)是SPS 即序列參數(shù)集蜜葱,保存了一組編碼視頻序列(Coded Video Sequence)的全局參數(shù)

0x68 --二進(jìn)制化--》01101000 --取后五位--》000 01000 值位8 全景,查看上表,發(fā)現(xiàn)是PPS 即圖像參數(shù)集牵囤,該類型保存了整體圖像相關(guān)的參數(shù)爸黄。

除了上面這些,更多的是00 00 00 01 41揭鳞,或者00 00 00 01 01那么41炕贵、01又是什么吶?

0x41 --二進(jìn)制化--》01000001 --取后五位--》000 00001 值位1 野崇,查看上表称开,發(fā)現(xiàn)是非IDR幀,可以是 I/P/B幀

其中IDR是一種I幀乓梨,告訴解碼器鳖轰,之前依賴的解碼參數(shù)集合可以被刷新了

0x01 --二進(jìn)制化--》00000001 --取后五位--》000 00001 值位1 ,查看上表扶镀,發(fā)現(xiàn)是非IDR幀蕴侣,可以是 I/P/B幀 ,相比41臭觉,這個(gè)幀的重要性很低昆雀,可以丟棄

四、NALU payload

NALU的主體涉及到三個(gè)重要的名詞蝠筑,分別為EBSP狞膘、RBSP和SODB。其中EBSP完全等價(jià)于NALU主體什乙,而且它們?nèi)齻€(gè)的結(jié)構(gòu)關(guān)系為:
EBSP包含RBSP挽封,RBSP包含SODB。

** SODB: String Of Data Bits** 原始數(shù)據(jù)比特流稳强,就是最原始的編碼/壓縮得到的數(shù)據(jù)

RBSP: Raw Byte Sequence Payload,又稱原始字節(jié)序列載荷和悦。和SODB關(guān)系如下:
RBSP = SODB + RBSP Trailing Bits(RBSP尾部補(bǔ)齊字節(jié))
引入RBSP Trailing Bits做8位字節(jié)補(bǔ)齊退疫。

EBSP: Encapsulated Byte Sequence Payload: 擴(kuò)展字節(jié)序列載荷

如果RBSP種也包括了StartCode(0x0000010x00000001怎么辦呢?所以鸽素,就有了防止競爭字節(jié)(0x03

編碼時(shí)褒繁,掃描RBSP,如果遇到連續(xù)兩個(gè)0x00字節(jié)馍忽,就在后面添加防止競爭字節(jié)(0x03棒坏;解碼時(shí)燕差,同樣掃描EBSP,進(jìn)行逆向操作即可坝冕。

圖片來自:視頻和視頻幀:H264編碼格式整理

圖片來自:H264/AVC 句法和語義詳解(三):NALU詳解二(EBSP徒探、RBSP與SODB

五、I/P/B幀的特點(diǎn)

通過第三小節(jié)我們通過 NAL的Type表了解到喂窟。5代表IDR幀测暗、1代表非IDR幀。這一小節(jié)磨澡,我們就來了解下視頻的I/P/B幀碗啄。


I幀:幀內(nèi)編碼幀 intra picture,關(guān)鍵幀稳摄,I 幀通常是每個(gè) GOP的第一個(gè)幀稚字,進(jìn)行幀內(nèi)預(yù)測壓縮,作為P/B幀的參考幀厦酬。
I幀的特點(diǎn)如下:

    它是一個(gè)全幀壓縮編碼幀胆描。它將全幀圖像信息進(jìn)行JPEG壓縮編碼及傳輸; 
    解碼時(shí)僅用I幀的數(shù)據(jù)就可重構(gòu)完整圖像; 
    I幀描述了圖像背景和運(yùn)動(dòng)主體的詳情; 
    I幀不需要參考其他畫面而生成; 
    I幀是P幀和B幀的參考幀(其質(zhì)量直接影響到同組中以后各幀的質(zhì)量); 
    I幀是幀組GOP的基礎(chǔ)幀(第一幀),在一組中只有一個(gè)I幀; 
    I幀不需要考慮運(yùn)動(dòng)矢量; 
    I幀所占數(shù)據(jù)的信息量比較大。 

P幀: 前向預(yù)測編碼幀 predictive-frame弃锐,主要進(jìn)行幀間編碼袄友,參考前面的I/P幀,去除時(shí)間冗余信息霹菊,P幀沒有完整畫面數(shù)據(jù)剧蚣,只有與前面I/P的畫面差別的數(shù)據(jù)。解碼時(shí)需要用之前緩存I/P幀疊加上本幀的差異數(shù)據(jù)旋廷,生成最終畫面
P幀的特點(diǎn)如下:

    P幀是I幀后面相隔1~2幀的編碼幀; 
    P幀采用運(yùn)動(dòng)補(bǔ)償?shù)姆椒▊魉退c前面的I或P幀的差值及運(yùn)動(dòng)矢量(預(yù)測誤差); 
    解碼時(shí)必須將I幀中的預(yù)測值與預(yù)測誤差求和后才能重構(gòu)完整的P幀圖像; 
    P幀屬于前向預(yù)測的幀間編碼鸠按。它只參考前面最靠近它的I幀或P幀; 
    P幀可以是其后面P幀的參考幀,也可以是其前后的B幀的參考幀; 
    由于P幀是參考幀,它可能造成解碼錯(cuò)誤的擴(kuò)散; 
    由于是差值傳送,P幀的壓縮比較高。 

B幀: 雙向預(yù)測幀 bi-directional interpolated prediction frame饶碘,考慮前面的I/P幀以及后面的P幀之間的時(shí)間冗余信息來壓縮傳輸數(shù)據(jù)量的編碼圖像目尖;要解碼B幀,不僅要取得之前的緩存畫面扎运,還要解碼之后的畫面瑟曲,通過前后畫面的與本幀數(shù)據(jù)的疊加取得最終的畫面。B幀壓縮率高豪治,但是解碼時(shí)CPU消耗多些洞拨。
B幀特點(diǎn)如下:

    B幀是由前面的I或P幀和后面的P幀來進(jìn)行預(yù)測的; 
    B幀傳送的是它與前面的I或P幀和后面的P幀之間的預(yù)測誤差及運(yùn)動(dòng)矢量; 
    B幀是雙向預(yù)測編碼幀; 
    B幀壓縮比最高,因?yàn)樗环从潮麉⒖紟g運(yùn)動(dòng)主體的變化情況,預(yù)測比較準(zhǔn)確; 
    B幀不是參考幀,不會(huì)造成解碼錯(cuò)誤的擴(kuò)散。

GOP:兩個(gè)I幀之間是一個(gè)圖像序列负拟,主要用作形容一個(gè) i 幀 到下一個(gè) i 幀之間的間隔了多少個(gè)幀烦衣,一個(gè)序列的第一個(gè)圖像是 IDR 圖像(立即刷新圖像),IDR 圖像都是 I 幀圖像。
增大GOP圖片組能有效的減少編碼后的視頻體積花吟,但是也會(huì)降低視頻質(zhì)量秸歧。
GOP 越長,B 幀所占比例更高衅澈,編碼的率失真性能越高键菱。

使用H.264 Video ES Viewer工具打開一個(gè)test.264文件 查看每個(gè)NAL的類型以及VCL數(shù)數(shù)據(jù)大小以及幀類型。

六矾麻、切片Slice和宏塊

GOP纱耻、幀、片险耀、宏之間的關(guān)系

片的主要作用是用作宏塊(Macroblock)的載體, 目的是為限制誤碼的擴(kuò)散和傳輸弄喘。
如何限制誤碼的擴(kuò)散和傳輸?
每個(gè)片(slice)都應(yīng)該是互相獨(dú)立被傳輸?shù)乃ξ称念A(yù)測(片內(nèi)預(yù)測和片間預(yù)測)不能以其它片中的宏塊(Macroblock)為參考圖像蘑志。

每個(gè)分片也包含著頭和數(shù)據(jù)兩部分:

分片頭中包含著分片類型、宏塊類型贬派、幀的數(shù)量急但、分片屬于那個(gè)圖像以及對(duì)應(yīng)的幀的設(shè)置和參數(shù)等信息。
分片數(shù)據(jù)中則是宏塊搞乏,這里就是我們要找的存儲(chǔ)像素(YUV)數(shù)據(jù)的地方

什么是宏塊

宏塊是視頻信息的主要承載者波桩,因?yàn)樗恳粋€(gè)像素的亮度和色度信息。視頻解碼最主要的工作則是提供高效的方式從碼流中獲得宏塊中的像素陣列请敦。

組成部分:一個(gè)宏塊由一個(gè)16×16亮度像素和附加的一個(gè)8×8 Cb和一個(gè) 8×8 Cr 彩色像素塊組成镐躲。每個(gè)圖象中,若干宏塊被排列成片的形式侍筛。

** 常用的宏塊類型:**
I宏塊:采用幀內(nèi)預(yù)測宏塊萤皂,可能位于I/P/B幀(因?yàn)樵赑和B幀中也是可以進(jìn)行幀內(nèi)預(yù)測的)
P宏塊:采用單向幀間預(yù)測,只存在于P幀
B宏塊:采用雙向幀間預(yù)測匣椰,只存在于B幀

** 切片(slice)類型跟宏塊類型的關(guān)系**

I片:只包 I宏塊裆熙,I 宏塊利用從當(dāng)前片中已解碼的像素作為參考進(jìn)行幀內(nèi)預(yù)測(不能取其它片中的已解碼像素作為參考進(jìn)行幀內(nèi)預(yù)測)。
P片:可包 P和I宏塊禽笑,P 宏塊利用前面已編碼圖象作為參考圖象進(jìn)行幀內(nèi)預(yù)測入录,一個(gè)幀內(nèi)編碼的宏塊可進(jìn)一步作宏塊的分割:即 16×16、16×8佳镜、8×16 或 8×8 亮度像素塊(以及附帶的彩色像素);如果選了 8×8 的子宏塊僚稿,則可再分成各種子宏塊的分割,其尺寸為 8×8邀杏、8×4贫奠、4×8 或 4×4 亮度像素塊(以及附帶的彩色像素)。
B片:可包 B和I宏塊望蜡,B 宏塊則利用雙向的參考圖象(當(dāng)前和 來的已編碼圖象幀)進(jìn)行幀內(nèi)預(yù)測唤崭。
SP片(切換P):用于不同編碼流之間的切換,包含 P 和/或 I 宏塊
SI片:擴(kuò)展檔次中必須具有的切換脖律,它包 了一種特殊類型的編碼宏塊谢肾,叫做 SI 宏塊,SI 也是擴(kuò)展檔次中的必備功能小泉。

我們通過H264Visa工具來查看h264的 NALU芦疏、Slice、marcoblock微姊、以及YUV數(shù)據(jù)如下:


七酸茴、資料

本篇的內(nèi)容很多來下面的參考資料的學(xué)習(xí),結(jié)合自己的理解進(jìn)行整理和描述兢交,以及通過碼流分析工具進(jìn)行查看分析薪捍。 感謝如下作者的輸出。

  1. 圖書 《視頻編碼全角度詳解》
  2. 圖書 《新一代視頻壓縮編碼標(biāo)準(zhǔn) — H.264/AVC》
  3. 李超-H264基本原理
  4. 深入淺出理解視頻編碼H264結(jié)構(gòu)
  5. 視頻和視頻幀:H264編碼格式整理
  6. H264編碼總結(jié)
  7. VCL & NAL (H.264/AVC)

八配喳、收獲

通過本篇的學(xué)習(xí)

  1. 了解H264的結(jié)構(gòu) VCL和NAL的分層
  2. 了解NALU HEAD對(duì)應(yīng)的一個(gè)字節(jié)代表的含義和類型酪穿,SPS、PPS晴裹、SEI被济、IDR、非IDR等涧团,以及了解I/P/B幀的特性
  3. 了解NALU PayLoad的結(jié)構(gòu)
  4. 了解對(duì)幀分片和宏塊的定義和目的只磷。
  5. 通過碼流分析工具結(jié)合實(shí)踐更好的理解。

感謝你的閱讀
下一篇我們分析學(xué)習(xí)H264的編碼技術(shù)之幀內(nèi)預(yù)測少欺,歡迎關(guān)注公眾號(hào)“音視頻開發(fā)之旅”喳瓣,一起學(xué)習(xí)成長。
歡迎交流

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末赞别,一起剝皮案震驚了整個(gè)濱河市畏陕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仿滔,老刑警劉巖惠毁,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異崎页,居然都是意外死亡鞠绰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門飒焦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜈膨,“玉大人屿笼,你說我怎么就攤上這事∥涛。” “怎么了驴一?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長灶壶。 經(jīng)常有香客問我肝断,道長,這世上最難降的妖魔是什么驰凛? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任胸懈,我火速辦了婚禮,結(jié)果婚禮上恰响,老公的妹妹穿的比我還像新娘趣钱。我一直安慰自己,他們只是感情好胚宦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布羔挡。 她就那樣靜靜地躺著,像睡著了一般间唉。 火紅的嫁衣襯著肌膚如雪绞灼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天呈野,我揣著相機(jī)與錄音低矮,去河邊找鬼。 笑死被冒,一個(gè)胖子當(dāng)著我的面吹牛军掂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昨悼,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼蝗锥,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了率触?” 一聲冷哼從身側(cè)響起终议,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎葱蝗,沒想到半個(gè)月后穴张,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡两曼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年皂甘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悼凑。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡偿枕,死狀恐怖璧瞬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情渐夸,我是刑警寧澤彪蓬,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站捺萌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏膘茎。R本人自食惡果不足惜桃纯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望披坏。 院中可真熱鬧态坦,春花似錦、人聲如沸棒拂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帚屉。三九已至谜诫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間攻旦,已是汗流浹背喻旷。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牢屋,地道東北人且预。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像烙无,于是被迫代替她去往敵國和親锋谐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容