音視頻學(xué)習(xí)從零到整(1)
音視頻學(xué)習(xí)從零到整(2)
音視頻學(xué)習(xí)從零到整(3)
音視頻學(xué)習(xí)從零到整(4)
音視頻學(xué)習(xí)從零到整(5)
音視頻學(xué)習(xí)從零到整(6)
音視頻學(xué)習(xí)從零到整(7)
一.H264結(jié)構(gòu)圖
H264視頻壓縮后會(huì)成為一個(gè)序列幀.幀里包含圖像,圖像分為很多片.每個(gè)片可以分為宏塊.每個(gè)宏塊由許多子塊組成.這就是H264結(jié)構(gòu)圖.非常的情緒簡單.
H264結(jié)構(gòu)中,一個(gè)視頻圖像編碼后的數(shù)據(jù)叫做一幀跃赚,一幀由一個(gè)片(slice)或多個(gè)片組成州藕,一個(gè)片由一個(gè)或多個(gè)宏塊(MB)組成扩氢,一個(gè)宏塊由16x16的yuv數(shù)據(jù)組成。宏塊作為H264編碼的基本單位效五。
場和幀:視頻的一場或一幀可用來產(chǎn)生一個(gè)編碼圖像。在電視中,為減少大面積閃爍現(xiàn)象蝎宇,把一幀分成兩個(gè)隔行的場。
-
片:每個(gè)圖象中祷安,若干宏塊被排列成片的形式姥芥。片分為I片、B片汇鞭、P片和其他一些片凉唐。
I片只包含I宏塊庸追,P片可包含P和I宏塊,而B片可包含B和I宏塊熊榛。
I宏塊利用從當(dāng)前片中已解碼的像素作為參考進(jìn)行幀內(nèi)預(yù)測锚国。
P宏塊利用前面已編碼圖象作為參考圖象進(jìn)行幀內(nèi)預(yù)測。
B宏塊則利用雙向的參考圖象(前一幀和后一幀)進(jìn)行幀內(nèi)預(yù)測玄坦。
片的目的是為了限制誤碼的擴(kuò)散和傳輸血筑,使編碼片相互間是獨(dú)立的。
某片的預(yù)測不能以其它片中的宏塊為參考圖像煎楣,
這樣某一片中的預(yù)測誤差才不會(huì)傳播到其它片中去
宏塊:一個(gè)編碼圖像通常劃分成若干宏塊組成豺总,一個(gè)宏塊由一個(gè)16×16亮度像素和附加的一個(gè)8×8 Cb和一個(gè)8×8 Cr彩色像素塊組成。
二. H264編碼分層
H264編碼分層,分為了2層.
-
NAL層: (Network Abstraction Layer,視頻數(shù)據(jù)網(wǎng)絡(luò)抽象層)
- 它的作用是H264只要在網(wǎng)絡(luò)上傳輸,在傳輸?shù)倪^程每個(gè)包以太網(wǎng)是1500字節(jié). 而H264的幀往往會(huì)大于1500字節(jié)的.所以就要進(jìn)行拆包. 將一個(gè)幀拆成多個(gè)包進(jìn)行傳輸.所有的拆包或者組包都是通過NAL層去處理的.
VCL層:(Video Coding Layer,視頻數(shù)據(jù)編碼層) 它的作用就是對視頻原始數(shù)據(jù)進(jìn)行壓縮.
三.碼流的基本概念
SODB:(String of Data Bits,原始數(shù)據(jù)比特流),長度不一定是8的倍數(shù).它是由VCL層產(chǎn)生的.因?yàn)榉?的倍數(shù)所以處理比較麻煩.
RBSP:(Raw Byte Sequence Payload,SODB+trailing bits).算法是在SODB最后一位補(bǔ)1.不按字節(jié)對齊補(bǔ)0. 如果補(bǔ)齊0,不知道在哪里結(jié)束.所以補(bǔ)1.如果不夠8位則按位補(bǔ)0.
EBSP:(Encapsulate Byte Sequence Payload).就是生成壓縮流之后,我們還要在每個(gè)幀之前加一個(gè)起始位.起始位一般是十六進(jìn)制的0001.但是在整個(gè)編碼后的數(shù)據(jù)里,可能會(huì)出來連續(xù)的2個(gè)0x00.那這樣就與起始位產(chǎn)生了沖突.那怎么處理了? H264規(guī)范里說明如果處理2個(gè)連續(xù)的0x00,就額外增加一個(gè)0x03 .這樣就能預(yù)防壓縮后的數(shù)據(jù)與起始位產(chǎn)生沖突.
每個(gè)NAL前有一個(gè)起始碼 0x00 00 01(或者0x00 00 00 01)择懂,解碼器檢測每個(gè)起始碼喻喳,作為一個(gè)NAL的起始標(biāo)識(shí),當(dāng)檢測到下一個(gè)起始碼時(shí)困曙,當(dāng)前NAL結(jié)束表伦。
同時(shí)H.264規(guī)定,當(dāng)檢測到0x00 00 01時(shí)慷丽,也可以表征當(dāng)前NAL的結(jié)束蹦哼。那么NAL中數(shù)據(jù)出現(xiàn)0x000001或0x000000時(shí)怎么辦?H.264引入了防止競爭機(jī)制要糊,如果編碼器檢測到NAL數(shù)據(jù)存在0x000001或0x000000時(shí)纲熏,編碼器會(huì)在最后個(gè)字節(jié)前插入一個(gè)新的字節(jié)0x03,這樣:
解碼器檢測到0x000003時(shí)锄俄,把03拋棄局劲,恢復(fù)原始數(shù)據(jù)(脫殼操作)。解碼器在解碼時(shí)奶赠,首先逐個(gè)字節(jié)讀取NAL的數(shù)據(jù)鱼填,統(tǒng)計(jì)NAL的長度,然后再開始解碼毅戈。
- NALU: NAL Header(1B)+EBSP.NALU就是在EBSP的基礎(chǔ)上加1B的網(wǎng)絡(luò)頭.
四. 詳解NAL Unit
NAL 單元是由一個(gè)NALU頭部+一個(gè)切片.切片又可以細(xì)分成"切片頭+切片數(shù)據(jù)".我們之間了解過一個(gè)H254的幀是由多個(gè)切片構(gòu)成的.因?yàn)橐粠瑪?shù)據(jù)一次有可能傳不完.
切片與宏塊的關(guān)系(Slice & MacroBlock)
每個(gè)切片都包括切片頭+切片數(shù)據(jù). 那每個(gè)切片數(shù)據(jù)包括了很多宏塊.每個(gè)宏塊包括了宏塊的類型,宏塊的預(yù)測,殘差數(shù)據(jù).
圖解H264切片
在一副壓縮的H264的幀里,可以包含多個(gè)切片.至少有一個(gè)切換.
H264碼流分層結(jié)構(gòu)圖.
- A Annex格式數(shù)據(jù),就是起始碼+Nal Unit 數(shù)據(jù)
- NAL Unit: NALU 頭+NALU數(shù)據(jù)
- NALU 主體,是由切片組成.切片包括切片頭+切片數(shù)據(jù)
- Slice數(shù)據(jù): 宏塊組成
- PCM類: 宏塊類型+pcm數(shù)據(jù),或者宏塊類型+宏塊模式+殘差數(shù)據(jù)
- Residual: 殘差塊.
這個(gè)圖比較重要.大家可以多看看.