一脸侥、前言
上一篇文章《音視頻學習(一)-- 基礎(chǔ)知識準備》我們對音視頻的基礎(chǔ)知識有了一個大概的了解,這篇我們來深入了解一下視頻的編碼技術(shù)碗短。
1伤提、為什么要對視頻編碼
假設(shè)一個 1 小時的未壓縮的電影(1920 * 1080),像素數(shù)據(jù)格式為 RGB24株搔,按照每秒 25 幀來計算:
3600 * 25 * 1920 * 1080 * 3 = 559.872GByte
500 多 G 的電影顯然太大了剖淀,下載耗時也占地方,在線看也很慢纤房,畢竟我們平時看的一般也就幾個 G 而已纵隔。所以我們要對視頻進行 壓縮,而 編碼 就是 壓縮 的過程炮姨。
2捌刮、如何編碼
幀率(FPS)代表每秒顯示的幀數(shù)(顯示的畫面數(shù)),也可以用頻率的單位 Hz 來衡量舒岸。由于人眼的視覺暫留現(xiàn)象绅作,當幀率到達一定數(shù)值后,人眼就會感覺畫面是連續(xù)運動的了蛾派。一秒鐘達到 16 幀以上俄认,大腦就會認為是連貫的了,動畫片和電影一般是 25 幀碍脏。
上面的翻頁動畫可以看出有很多高度重復的畫面梭依,比如背景,這時候我們就可以對其進行壓縮典尾。壓縮的過程其實就是去除冗余信息的過程。
- 視頻信息中的冗余
視頻信息中通常包含的冗余有三種:空間冗余糊探、時間冗余和統(tǒng)計冗余钾埂。處理這三種冗余信息通常采用不同的方式:
(1)空間冗余: 采用幀內(nèi)預測編碼壓縮;
(2)時間冗余: 采用運動搜索和運動補償壓縮科平;
(3)統(tǒng)計冗余: 采用熵編碼壓縮褥紫。
編碼又分為 軟編碼 和 硬編碼:
軟編碼:使用CPU進行編碼
特點:實現(xiàn)直接、簡單瞪慧,參數(shù)調(diào)整方便髓考,升級易,但 CPU 負載重弃酌,性能較硬編碼低氨菇,低碼率下質(zhì)量通常比硬編碼要好一點儡炼。硬編碼:使用非 CPU 進行編碼,如顯卡GPU查蓉。
特點:性能高乌询,低碼率下通常質(zhì)量低于硬編碼器,但部分產(chǎn)品在 GPU 硬件平臺移植了優(yōu)秀的軟編碼算法豌研,質(zhì)量基本等同于軟編碼妹田。
對視頻進行編碼有很多種技術(shù)手段,H.264 視頻壓縮算法目前是所有視頻壓縮技術(shù)中使用最廣泛的鹃共。下面我們認識一下 H.264鬼佣。
二、H.264
1霜浴、簡介
國際上制定視頻編解碼技術(shù)的組織有兩個晶衷,一個是“國際電聯(lián)(ITU-T)”,它制定的標準有 H.261坷随、H.263房铭、H.263+ 等,另一個是“國際標準化組織(ISO)”它制定的標準有 MPEG-1温眉、MPEG-2缸匪、MPEG-4 等。而 H.264 則是由兩個組織聯(lián)合組建的聯(lián)合視頻組(JVT)共同制定的新數(shù)字視頻編碼標準类溢,所以它既是 ITU-T 的 H.264凌蔬,又是 ISO/IEC 的 MPEG-4 高級視頻編碼(Advanced Video Coding,AVC)的第 10 部分闯冷。
- 優(yōu)勢:
H.264 最大的優(yōu)勢是具有很高的數(shù)據(jù)壓縮比率砂心,在同等圖像質(zhì)量的條件下,H.264 的壓縮比是 MPEG-2 的 2 倍以上蛇耀,是 MPEG-4 的 1.5~2 倍辩诞。
2、VCL 與 NAL 分層
H.264 原始碼流(裸流)是由一個接一個 NALU 組成纺涤,它的功能分為兩層译暂,VCL(視頻編碼層)和 NAL(網(wǎng)絡提取層)。
- VCL: 視像編碼層(Video Coding Layer撩炊, 簡稱VCL)外永,包括核心壓縮引擎和塊,宏塊和片的語法級別定義拧咳,設(shè)計目標是盡可能地獨立于網(wǎng)絡進行高效的編碼伯顶,對視頻原始數(shù)據(jù)進行壓縮。
- NAL: 網(wǎng)絡抽象層(Network Abstraction Layer,簡稱NAL)祭衩。在以太網(wǎng)每個包大小是 1500 字節(jié)灶体,而一幀往往會大于這個值,所以就需要用于按照一定格式汪厨,對 VCL 視像編碼層輸出的數(shù)據(jù)拆成多個包傳輸赃春,并提供包頭(header)等信息,以在不同速率的網(wǎng)絡上傳輸或進行存儲劫乱,所有的拆包和組包都是 NAL 層去處理的织中。覆蓋了所有片級以上的語法級別。
VCL 數(shù)據(jù)傳輸或者存儲之前衷戈,會被映射到一個 NALU 中狭吼,H264 數(shù)據(jù)包含一個個 NALU。如下圖:
一個NALU = 一組對應于視頻編碼的NALU頭部信息 + 一個原始字節(jié)序列負荷(RBSP,Raw Byte Sequence Payload)
H.264 碼流第一個 NALU 是 SPS殖妇,第二個 NALU 是 PPS刁笙,第三個 NALU 是 IDR(即時解碼器刷新)
- SPS:
序列參數(shù)集 SPS(Sequence Parameter Sets),存儲的是一個序列的信息谦趣,包括有多少幀等- PPS:
圖像參數(shù)集 PPS(Picture Parameter Sets )疲吸,存儲的一幀的信息。
解碼的時候必須獲取到 SPS 和 PPS 的信息前鹅,才能對后面的數(shù)據(jù)進行解碼摘悴。
3、幀舰绘、片 與 宏塊
(1)幀
I幀(關(guān)鍵幀)
I 幀也叫關(guān)鍵幀蹂喻,采用的是 幀內(nèi)壓縮技術(shù)。
- I 幀概念理解:
我們拍攝視頻時捂寿,1 秒內(nèi)拍攝的內(nèi)容很少會有大幅度的變化口四,但是攝像頭一秒鐘會抓取幾十幀,比如電影就是 1 秒 25 幀秦陋,這樣一組幀內(nèi)的變化很小蔓彩,為了壓縮數(shù)據(jù),沒必要都存下來驳概,我們只把第一幀完整的保存下來作為關(guān)鍵幀即可粪小。
I 幀很關(guān)鍵,后面解碼數(shù)據(jù)都要依賴于這個 I 幀抡句。
P幀(向前參考幀)
P 幀也叫向前參考幀,采用的是 幀間壓縮技術(shù)杠愧。
P幀只會保存跟前一幀不一樣的數(shù)據(jù)待榔, 壓縮時只參考前一個幀。
視頻的第一幀會被作為關(guān)鍵幀完整保存下來,后面的幀會向前依賴锐锣,也就是第二幀依賴于第一個幀腌闯,后面所有的幀只存儲于前一幀的差異,這樣就能將數(shù)據(jù)大大的減少雕憔,從而達到一個高壓縮率的效果姿骏。
B幀(雙向參考幀)
B 幀也叫雙向參考幀,采用的是 幀間壓縮技術(shù)斤彼。
壓縮時既參考前一幀也參考后一幀分瘦,這樣就使得它的壓縮率更高,存儲的數(shù)據(jù)量更小琉苇。如果B幀的數(shù)量越多,你的壓縮率就越高.這是B幀的優(yōu)點,但是B幀最大的缺點是,如果是實時互動的直播,那時與B幀就要參考后面的幀才能解碼,那在網(wǎng)絡中就要等待后面的幀傳輸過來.這就與網(wǎng)絡有關(guān)了.如果網(wǎng)絡狀態(tài)很好的話,解碼會比較快,如果網(wǎng)絡不好時解碼會稍微慢一些.丟包時還需要重傳.對實時互動的直播,一般不會使用B幀.
如果在泛娛樂的直播中,可以接受一定度的延時,需要比較高的壓縮比就可以使用B幀.
如果我們在實時互動的直播,我們需要提高時效性,這時就不能使用B幀了.
(2)GOF(Group of Frame)或 GOP(Group of Picture)
我們管一組幀叫做 GOF 或者 GOP嘲玫。一組幀就是一個 I 幀到下一個 I 幀之間的數(shù)據(jù)。下面這張圖清楚地展示了一組 GOP 內(nèi)三種幀的解碼順序和顯示順序并扇,可以發(fā)現(xiàn)不管是解碼還是顯示都是先從 I 幀開始的去团。
(3)片(slice)
片的主要作用是用作宏塊的載體。設(shè)置片的目的是為了限制誤碼的擴散和傳輸穷蛹,編碼片是項目獨立的土陪,一個片的預測不能以其他片中的宏塊為參考圖像。保證了某一片的預測誤差不會傳播到別的片肴熏。
我們可以理解為一張圖片可以包含一個或多個片鬼雀,而每一個片包含整數(shù)個宏塊,即每片至少一個宏塊扮超,最多時每片包整個圖像的宏塊取刃。
切片可以細分為“切片頭+切片數(shù)據(jù)”,因為一幀數(shù)據(jù)一次有可能傳不完出刷,所以需要記錄頭信息璧疗。
(4)宏塊(Macroblock)
宏塊是視頻信息的主要承載者,因為它包含著每一個像素的亮度和色度信息馁龟。視頻解碼最主要的工作則是提供高效的方式從碼流中獲得宏塊中的像素陣列崩侠。
組成部分:一個宏塊由一個 16×16 亮度像素和附加的一個 8×8 Cb 和一個 8×8 Cr 彩色像素塊組成。每個圖象中坷檩,若干宏塊被排列成片的形式却音。
宏塊中包含了宏塊類型、預測類型矢炼、Coded Block Pattern系瓢、Quantization Parameter、像素的亮度和色度數(shù)據(jù)集等等信息句灌。
(5)幀夷陋、片 與 宏塊的關(guān)系
我們知道一幀代表的就是一張圖像欠拾。其中
1 幀 = n 個片
1 片 = n 個宏塊
1 宏塊 = 16x16yuv 數(shù)據(jù)
從上圖可看到一個序列的第一個圖像叫做 IDR 圖像(立即刷新圖像),IDR 圖像都是 I 圖像骗绕。H.264 引入 IDR 圖像是為了解碼的重同步藐窄,當解碼器解碼到 IDR 圖像時,立即將參考幀隊列清空酬土,將已解碼的數(shù)據(jù)全部輸出或拋棄荆忍,重新查找參數(shù)集,開始一個新的序列撤缴。這樣刹枉,如果在前一個序列的傳輸中發(fā)生重大錯誤,如嚴重的丟包腹泌,或其他原因引起數(shù)據(jù)錯位嘶卧,在這里可以獲得重新同步。IDR 圖像之后的圖像永遠不會引用 IDR 圖像之前的圖像的數(shù)據(jù)來解碼凉袱。
下圖是 h264 的一個完整的碼流分層結(jié)構(gòu):
4芥吟、預測編碼的原理
了解 H264 編碼之前,我們先了解一個概念专甩,那就是 預測編碼钟鸵。
- 預測編碼:
對于存在前后相關(guān)性的信息,預測編碼 是一種非常簡便且有效的方法涤躲。此時預測編碼輸出的不再是原始的信號值棺耍,而是信號的預測值與實際值的差。這樣設(shè)計是因為相鄰信號存在大量相同或相近的現(xiàn)象种樱,通過計算其差值可減少大量保存與傳輸原始信息的數(shù)據(jù)體積蒙袍。
下面用代碼來舉個例子說明一下預測編碼的原理,假設(shè)有下面的10 個數(shù)字:
2 , 2 , 2 , 7 , 2 , 2 , 2 , 2 , 2 , 13
我們也可以用下面的方式來表示:
prediction = 2;
Difference = { (5, 3), (11, 9) };
上面表示的是目標信號的預測值為2嫩挤,在第 5 和 11 個元素的位置存在殘差害幅,差值分別為 3 和 9。
通過預測編碼岂昭,不僅降低了表示像素信息所需要的比特數(shù)以现,還可以保留視頻圖像的畫面質(zhì)量。
預測編碼 并非H.264最先采用的技術(shù)约啊。在早期的壓縮編碼技術(shù)中便采用了 預測數(shù)據(jù)+殘差 的方法來表示待編碼的像素邑遏。然而在這些標準中預測編碼僅僅用于 幀間預測 來去除空間冗余,對于幀內(nèi)編碼仍然采用直接DCT+熵編碼的方法恰矩,壓縮效率難以滿足多媒體領(lǐng)域的新需求记盒。H.264 標準深入分析了 I 幀中空間域的信息相關(guān)性,采用了多種預測編碼模式外傅,進一步壓縮了I幀中的空間冗余信息孽鸡,極大提升了 I 幀的編碼效率蹂午,為H.264 的壓縮比取得突破奠定了基礎(chǔ)。
(1)幀內(nèi)預測壓縮
幀內(nèi)預測壓縮 解決的是空域數(shù)據(jù)冗余問題.
什么是空域數(shù)據(jù),就是這幅圖里數(shù)據(jù)在寬高空間內(nèi)包含了很多顏色,光亮.人的肉眼很難察覺的數(shù)據(jù). 對于這些數(shù)據(jù),我們可以認作冗余.直接壓縮掉的.
(2)幀間預測壓縮
幀間預測壓縮 解決的是時域數(shù)據(jù)冗余問題彬碱。
在我們之前舉例說明過,攝像頭在一段時間內(nèi)所捕捉的數(shù)據(jù)沒有較大的變化,我們針對這一時間內(nèi)的相同的數(shù)據(jù)壓縮掉奥洼,這叫時域數(shù)據(jù)壓縮巷疼。
以上的總結(jié)參考了并部分摘抄了以下文章,非常感謝以下作者的分享A榻薄:
1嚼沿、雷霄驊的視頻課《基于FFmpeg+SDL的視頻播放器的制作-第1節(jié)-大綱和視音頻基礎(chǔ)知識》(PS:致敬音視頻大神雷神雷曉華先生,謝謝你生前為我們留下來的無私分享成果)
2瓷患、云導播的《H.264/AVC 的分層結(jié)構(gòu)與畫面劃分》
3骡尽、合肥懶皮的《H264系列十三 句法元素的分層結(jié)構(gòu)》
4、Abson在簡書的《深入淺出理解視頻編碼H264結(jié)構(gòu)》
5擅编、取次花叢懶回顧的《【H.264/AVC視頻編解碼技術(shù)詳解】二十三攀细、幀間預測編碼(1):幀間預測編碼的基本原理》
轉(zhuǎn)載請備注原文出處,不得用于商業(yè)傳播——凡幾多