音視頻學習(二)-- H.264編碼原理

一、前言

上一篇文章《音視頻學習(一)-- 基礎知識準備》我們對音視頻的基礎知識有了一個大概的了解,這篇我們來深入了解一下視頻的編碼技術。

1、為什么要對視頻編碼

假設一個 1 小時的未壓縮的電影(1920 * 1080),像素數據格式為 RGB24,按照每秒 25 幀來計算:
3600 * 25 * 1920 * 1080 * 3 = 559.872GByte
500G 的電影顯然太大了,下載耗時也占地方,在線看也很慢,畢竟我們平時看的一般也就幾個 G 而已。所以我們要對視頻進行 壓縮,而 編碼 就是 壓縮 的過程。

2、如何編碼

幀率(FPS)代表每秒顯示的幀數(顯示的畫面數),也可以用頻率的單位 Hz 來衡量。由于人眼的視覺暫留現象,當幀率到達一定數值后,人眼就會感覺畫面是連續運動的了。一秒鐘達到 16 幀以上,大腦就會認為是連貫的了,動畫片和電影一般是 25 幀。


上面的翻頁動畫可以看出有很多高度重復的畫面,比如背景,這時候我們就可以對其進行壓縮。壓縮的過程其實就是去除冗余信息的過程。

  • 視頻信息中的冗余
    視頻信息中通常包含的冗余有三種:空間冗余時間冗余統計冗余。處理這三種冗余信息通常采用不同的方式:
    (1)空間冗余: 采用幀內預測編碼壓縮;
    (2)時間冗余: 采用運動搜索和運動補償壓縮;
    (3)統計冗余: 采用熵編碼壓縮。

編碼又分為 軟編碼 和 硬編碼

  • 軟編碼:使用CPU進行編碼
    特點:實現直接、簡單,參數調整方便,升級易,但 CPU 負載重,性能較硬編碼低,低碼率下質量通常比硬編碼要好一點。

  • 硬編碼:使用非 CPU 進行編碼,如顯卡GPU
    特點:性能高,低碼率下通常質量低于硬編碼器,但部分產品在 GPU 硬件平臺移植了優秀的軟編碼算法,質量基本等同于軟編碼。

對視頻進行編碼有很多種技術手段,H.264 視頻壓縮算法目前是所有視頻壓縮技術中使用最廣泛的。下面我們認識一下 H.264

二、H.264

1、簡介

國際上制定視頻編解碼技術的組織有兩個,一個是“國際電聯(ITU-T)”,它制定的標準有 H.261、H.263、H.263+ 等,另一個是“國際標準化組織(ISO)”它制定的標準有 MPEG-1、MPEG-2、MPEG-4 等。而 H.264 則是由兩個組織聯合組建的聯合視頻組(JVT)共同制定的新數字視頻編碼標準,所以它既是 ITU-TH.264,又是 ISO/IECMPEG-4 高級視頻編碼(Advanced Video Coding,AVC)的第 10 部分。

  • 優勢:
    H.264 最大的優勢是具有很高的數據壓縮比率,在同等圖像質量的條件下,H.264 的壓縮比是 MPEG-22 倍以上,是 MPEG-41.5~2 倍。

2、VCL 與 NAL 分層

H.264 原始碼流(裸流)是由一個接一個 NALU 組成,它的功能分為兩層,VCL(視頻編碼層)和 NAL(網絡提取層)。

  • VCL: 視像編碼層(Video Coding Layer, 簡稱VCL),包括核心壓縮引擎和塊,宏塊和片的語法級別定義,設計目標是盡可能地獨立于網絡進行高效的編碼,對視頻原始數據進行壓縮。
  • NAL: 網絡抽象層(Network Abstraction Layer,簡稱NAL)。在以太網每個包大小是 1500 字節,而一幀往往會大于這個值,所以就需要用于按照一定格式,對 VCL 視像編碼層輸出的數據拆成多個包傳輸,并提供包頭(header)等信息,以在不同速率的網絡上傳輸或進行存儲,所有的拆包和組包都是 NAL 層去處理的。覆蓋了所有片級以上的語法級別。

VCL 數據傳輸或者存儲之前,會被映射到一個 NALU 中,H264 數據包含一個個 NALU。如下圖:

一個NALU = 一組對應于視頻編碼的NALU頭部信息 + 一個原始字節序列負荷(RBSP,Raw Byte Sequence Payload)

H.264 碼流第一個 NALUSPS,第二個 NALUPPS,第三個 NALUIDR(即時解碼器刷新)

  • SPS:
    序列參數集 SPS(Sequence Parameter Sets),存儲的是一個序列的信息,包括有多少幀等
  • PPS:
    圖像參數集 PPS(Picture Parameter Sets ),存儲的一幀的信息。
    解碼的時候必須獲取到 SPSPPS 的信息,才能對后面的數據進行解碼。
image

3、幀、片 與 宏塊

(1)幀

I幀(關鍵幀)

I 幀也叫關鍵幀,采用的是 幀內壓縮技術

  • I 幀概念理解:
    我們拍攝視頻時,1 秒內拍攝的內容很少會有大幅度的變化,但是攝像頭一秒鐘會抓取幾十幀,比如電影就是 125 幀,這樣一組幀內的變化很小,為了壓縮數據,沒必要都存下來,我們只把第一幀完整的保存下來作為關鍵幀即可。
    I 幀很關鍵,后面解碼數據都要依賴于這個 I 幀。

P幀(向前參考幀)

P 幀也叫向前參考幀,采用的是 幀間壓縮技術
P幀只會保存跟前一幀不一樣的數據, 壓縮時只參考前一個幀。
視頻的第一幀會被作為關鍵幀完整保存下來,后面的幀會向前依賴,也就是第二幀依賴于第一個幀,后面所有的幀只存儲于前一幀的差異,這樣就能將數據大大的減少,從而達到一個高壓縮率的效果。

B幀(雙向參考幀)

B 幀也叫雙向參考幀,采用的是 幀間壓縮技術
壓縮時既參考前一幀也參考后一幀,這樣就使得它的壓縮率更高,存儲的數據量更小。如果B幀的數量越多,你的壓縮率就越高.這是B幀的優點,但是B幀最大的缺點是,如果是實時互動的直播,那時與B幀就要參考后面的幀才能解碼,那在網絡中就要等待后面的幀傳輸過來.這就與網絡有關了.如果網絡狀態很好的話,解碼會比較快,如果網絡不好時解碼會稍微慢一些.丟包時還需要重傳.對實時互動的直播,一般不會使用B幀.
如果在泛娛樂的直播中,可以接受一定度的延時,需要比較高的壓縮比就可以使用B幀.
如果我們在實時互動的直播,我們需要提高時效性,這時就不能使用B幀了.

(2)GOF(Group of Frame)或 GOP(Group of Picture)

我們管一組幀叫做 GOF 或者 GOP。一組幀就是一個 I 幀到下一個 I 幀之間的數據。下面這張圖清楚地展示了一組 GOP 內三種幀的解碼順序和顯示順序,可以發現不管是解碼還是顯示都是先從 I 幀開始的。

幀順序.jpeg

(3)片(slice)

片的主要作用是用作宏塊的載體。設置片的目的是為了限制誤碼的擴散和傳輸,編碼片是項目獨立的,一個片的預測不能以其他片中的宏塊為參考圖像。保證了某一片的預測誤差不會傳播到別的片。
我們可以理解為一張圖片可以包含一個或多個片,而每一個片包含整數個宏塊,即每片至少一個宏塊,最多時每片包整個圖像的宏塊。
切片可以細分為“切片頭+切片數據”,因為一幀數據一次有可能傳不完,所以需要記錄頭信息。

(4)宏塊(Macroblock)

宏塊是視頻信息的主要承載者,因為它包含著每一個像素的亮度和色度信息。視頻解碼最主要的工作則是提供高效的方式從碼流中獲得宏塊中的像素陣列。
組成部分:一個宏塊由一個 16×16 亮度像素和附加的一個 8×8 Cb 和一個 8×8 Cr 彩色像素塊組成。每個圖象中,若干宏塊被排列成片的形式。
宏塊中包含了宏塊類型、預測類型、Coded Block Pattern、Quantization Parameter、像素的亮度和色度數據集等等信息。

(5)幀、片 與 宏塊的關系

我們知道一幀代表的就是一張圖像。其中
1 幀 = n 個片
1 片 = n 個宏塊
1 宏塊 = 16x16yuv 數據

image

image

從上圖可看到一個序列的第一個圖像叫做 IDR 圖像(立即刷新圖像),IDR 圖像都是 I 圖像。H.264 引入 IDR 圖像是為了解碼的重同步,當解碼器解碼到 IDR 圖像時,立即將參考幀隊列清空,將已解碼的數據全部輸出或拋棄,重新查找參數集,開始一個新的序列。這樣,如果在前一個序列的傳輸中發生重大錯誤,如嚴重的丟包,或其他原因引起數據錯位,在這里可以獲得重新同步。IDR 圖像之后的圖像永遠不會引用 IDR 圖像之前的圖像的數據來解碼。

下圖是 h264 的一個完整的碼流分層結構:

4、預測編碼的原理

了解 H264 編碼之前,我們先了解一個概念,那就是 預測編碼

  • 預測編碼:
    對于存在前后相關性的信息,預測編碼 是一種非常簡便且有效的方法。此時預測編碼輸出的不再是原始的信號值,而是信號的預測值與實際值的差。這樣設計是因為相鄰信號存在大量相同或相近的現象,通過計算其差值可減少大量保存與傳輸原始信息的數據體積。
    下面用代碼來舉個例子說明一下預測編碼的原理,假設有下面的10 個數字:
2 , 2 , 2 , 7 , 2 , 2 , 2 , 2 , 2 , 13

我們也可以用下面的方式來表示:

prediction = 2;
Difference = { (5, 3), (11, 9) };

上面表示的是目標信號的預測值為2,在第 511 個元素的位置存在殘差,差值分別為 39
通過預測編碼,不僅降低了表示像素信息所需要的比特數,還可以保留視頻圖像的畫面質量。

預測編碼 并非H.264最先采用的技術。在早期的壓縮編碼技術中便采用了 預測數據+殘差 的方法來表示待編碼的像素。然而在這些標準中預測編碼僅僅用于 幀間預測 來去除空間冗余,對于幀內編碼仍然采用直接DCT+熵編碼的方法,壓縮效率難以滿足多媒體領域的新需求。H.264 標準深入分析了 I 幀中空間域的信息相關性,采用了多種預測編碼模式,進一步壓縮了I幀中的空間冗余信息,極大提升了 I 幀的編碼效率,為H.264 的壓縮比取得突破奠定了基礎。

(1)幀內預測壓縮

幀內預測壓縮 解決的是空域數據冗余問題.
什么是空域數據,就是這幅圖里數據在寬高空間內包含了很多顏色,光亮.人的肉眼很難察覺的數據. 對于這些數據,我們可以認作冗余.直接壓縮掉的.

(2)幀間預測壓縮

幀間預測壓縮 解決的是時域數據冗余問題。
在我們之前舉例說明過,攝像頭在一段時間內所捕捉的數據沒有較大的變化,我們針對這一時間內的相同的數據壓縮掉,這叫時域數據壓縮。

以上的總結參考了并部分摘抄了以下文章,非常感謝以下作者的分享!:
1、雷霄驊的視頻課《基于FFmpeg+SDL的視頻播放器的制作-第1節-大綱和視音頻基礎知識》(PS:致敬音視頻大神雷神雷曉華先生,謝謝你生前為我們留下來的無私分享成果)
2、云導播的《H.264/AVC 的分層結構與畫面劃分》
3、合肥懶皮的《H264系列十三 句法元素的分層結構》
4、Abson在簡書的《深入淺出理解視頻編碼H264結構》
5、取次花叢懶回顧的《【H.264/AVC視頻編解碼技術詳解】二十三、幀間預測編碼(1):幀間預測編碼的基本原理》

轉載請備注原文出處,不得用于商業傳播——凡幾多

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 為什么需要視頻編碼呢?比如當前屏幕是1280*720一秒30張圖片.那么我們一秒的視頻數據是1280 * 7...
    Leon_520閱讀 2,033評論 0 6
  • 在保證視頻圖像質量的前提下,HEVC通過增加一定的計算復雜度,可以實現碼流在H.264/AVC的基礎上降低50%。...
    加劉景長閱讀 7,986評論 0 6
  • ### YUV顏色空間 視頻是由一幀一幀的數據連接而成,而一幀視頻數據其實就是一張圖片。 yuv是一種圖片儲存格式...
    天使君閱讀 3,380評論 0 4
  • 在目前,無論在各個行只要和視頻相關的,我們都可以看見H264相關的身影,H264作為目前使用最廣泛的視頻壓縮標準,...
    DramaScript閱讀 21,692評論 7 56
  • 本文參考畢厚杰老師《新一代視頻壓縮編碼標準-----H.264/AVC》一書以及雷霄驊博客《視音頻編解碼技術零基礎...
    繁天涯閱讀 2,290評論 0 2