【H264】壓縮編碼原理


一、前言

H264 視頻壓縮算法現在無疑是所有視頻壓縮技術中使用最廣泛,最流行的。隨着 x264/openh264 以及 FFmpeg 等開源庫的推出,大多數使用者無需再對 H264 的細節做過多的研究,這大降低了人們使用 H264 的成本。

但為了用好 H264,我們還是要對 H264 壓縮編碼的基本原理弄清楚才行。今天我們就來看看 H264 壓縮編碼的基本原理。


二、H264概述

FFmpeg_H264_H2.png


H264 編碼器采用的是變換和預測的混合編碼法。由上圖所示,輸入的幀或場 Fn 以宏塊為單位被編碼器處理。首先,按幀內或幀間預測編碼的方法進行處理。

如果采用幀內預測編碼,其預測值 PRED(圖中用 P 表示)是由當前片中前面已編碼的參考圖像經運動補償( MC)后得出,其中參考圖像用 F’n-1 表示。為了提高預測精度,從而提高壓縮比,實際的參考圖像可在過去或未來(指顯示次序上)已編碼解碼重建和濾波的幀中進行選擇。

預測值 PRED 和當前塊相減后,產生一個殘差塊 Dn,經塊變換、量化后產生一組量化后的變換系數 X,再經熵編碼,與解碼所需的一些邊信息(如預測模式量化參數、運動矢量等)一起組成一個壓縮后的碼流,經 NAL(網絡自適應層)供傳輸和存儲用。


H264壓縮方法

H264 壓縮技術主要采用了以下幾種方法對視頻數據進行壓縮:

  • 幀內預測壓縮,解決的是空域數據冗余問題。
  • 幀間預測壓縮(運動估計與補償),解決的是時域數據冗徐問題。
  • 整數離散余弦變換(DCT),將空間上的相關性變為頻域上無關的數據,然后進行量化。
  • CABAC 熵編碼, 對量化后的系數進一步的壓縮。

三、H264編碼原理

下面我們就簡單的描述一下 H264 壓縮編碼數據的過程。通過攝像頭采集到的視頻幀(按每秒 30 幀算),被送到 H264 編碼器的緩沖區中。編碼器先要為每一幅圖片划分宏塊。


3.1 划分宏塊

宏塊是編碼標准的基本處理單元,通常它的大小也為 16x16 像素。16X16 的宏塊上可以划分出更小的子塊。子塊的大小可以是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4。

H264 默認是使用 16X16 大小的區域作為一個宏塊,也可以划分成 8X8 大小的宏塊。

H264_Encode_A.jpg


划分好宏塊后,計算宏塊的象素值

H264_Encode_B.jpg


以此類推,計算一幅圖像中每個宏塊的像素值,所有宏塊都處理完后如下面的樣子。

H264_Encode_C.jpg


3.2 划分子塊

H264 對比較平坦的圖像使用 16X16 大小的宏塊。但為了更高的壓縮率,還可以在 16X16 的宏塊上更划分出更小的子塊。

子塊的大小可以是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4,非常的靈活。

H264_Encode_D.jpg


上幅圖中,紅框內的 16X16 宏塊中大部分是藍色背景,而三只鷹的部分圖像被划在了該宏塊內。為了更好的處理三只鷹的部分圖像,H264就在 16X16 的宏塊內又划分出了多個子塊。

H264_Encode_E.jpg


這樣再經過幀內壓縮,可以得到更高效的數據。

下圖是分別使用 MPEG-2 和 H264 對上面宏塊進行壓縮后的結果。其中左半部分為 MPEG-2 子塊划分后壓縮的結果,右半部分為 H264 的子塊划壓縮后的結果,可以看出 H264 的划分方法更具優勢。

H264_Encode_F.jpg


每張圖片的宏塊划分好后,就可以對 H264 編碼器緩存中的所有圖片進行分組了。


3.3 幀分組

對於視頻數據主要有兩類數據冗余,一類是時間上的數據冗余,另一類是空間上的數據冗余。.其中時間上的數據冗余是最大的。下面我們就先來說說視頻數據時間上的冗余問題。

為什么說時間上的冗余是最大的呢?假設攝像頭每秒抓取30幀,這30幀的數據大部分情況下都是相關聯的。也有可能不止30幀的的數據,可能幾十幀,上百幀的數據都是關聯特別密切的。

對於這些關聯特別密切的幀,其實我們只需要保存一幀的數據,其它幀都可以通過這一幀再按某種規則預測出來,所以說視頻數據在時間上的冗余是最多的。


為了達到相關幀通過預測的方法來壓縮數據,就需要將視頻幀進行分組。那么如何判定某些幀關系密切,可以划為一組呢?

我們來看一下例子,下面是捕獲的一組運動的台球的視頻幀,台球從右上角滾到了左下角。

H264_Encode_G.jpg


H264_Encode_H.jpg


通過宏塊掃描與宏塊搜索可以發現這兩個幀的關聯度是非常高的。進而發現這一組幀的關聯度都是非常高的。因此,上面這幾幀就可以划分為一組,即 H264 中的 序列(GOP)。其算法是:在相鄰幾幅圖像畫面中,一般有差別的像素只有 10% 以內的點,亮度差值變化不超過 2%,而色度差值的變化只有 1% 以內,我們認為這樣的圖可以分到一組。

在這樣一組幀中,經過編碼后,我們只保留第一帖的完整數據,其它幀都通過參考上一幀計算出來。我們稱第一幀為 IDR/I幀,其它幀我們稱為 P/B幀,這樣編碼后的數據幀組我們稱為 GOP

所以如果場景一直沒什么變化,則一系列視頻幀中 I 幀的數量會很少。如果場景變換很復雜,一直在場景變換大的場景切換時就會有 I 幀出現。


3.4 運動估計與運動補償(幀間預測)

在 H264 編碼器中將幀分組后,就要計算幀組內物體的運動矢量了。還以上面運動的台球視頻幀為例,我們來看一下它是如何計算運動矢量的。

H264 編碼器首先按順序從緩沖區頭部取出兩幀視頻數據,然后進行宏塊掃描。當發現其中一幅圖片中有物體時,就在另一幅圖的鄰近位置(搜索窗口中)進行搜索。如果此時在另一幅圖中找到該物體,那么就可以計算出物體的運動矢量了。

H264_Encode_I.jpg


通過上圖中台球位置相差,就可以計算出台圖運行的方向和距離。H264 依次把每一幀中球移動的距離和方向都記錄下來就成了下面的樣子:

H264_Encode_J.jpg


運動矢量計算出來后,將相同部分(也就是綠色部分)減去,就得到了補償數據。我們最終只需要將補償數據進行壓縮保存,以后在解碼時就可以恢復原圖了。壓縮補償后的數據只需要記錄很少的一點數據。如下所示:

H264_Encode_Z.png


我們把運動矢量與補償稱為幀間壓縮技術,它解決的是視頻幀在時間上的數據冗余。在這一步我們獲取了 P/B 幀。

除了幀間壓縮,幀內也要進行數據壓縮,幀內數據壓縮解決的是空間上的數據冗余。下面我們就來介紹一下幀內壓縮技術。


3.5 幀內預測

人眼對圖象都有一個識別度,對低頻的亮度很敏感,對高頻的亮度不太敏感。所以基於一些研究,可以將一幅圖像中人眼不敏感的數據去除掉。這樣就提出了幀內預測技術。

H264 的幀內壓縮與 JPEG 很相似。一幅圖像被划分好宏塊后,對每個宏塊可以進行 9 種模式的預測。找出與原圖最接近的一種預測模式。

幀內預測后的圖像與原始圖像的對比如下:

H264_Encode_K.jpg


然后,將原始圖像與幀內預測后的圖像相減得殘差值

H264_Encode_L.jpg


再將我們之前得到的預測模式信息一起保存起來,這樣我們就可以在解碼時恢復原圖了。效果如下:

H264_Encode_M.jpg


經過幀內與幀間的壓縮后,雖然數據有大幅減少,但還有優化的空間。這一步主要是壓縮出 I 幀。


3.6 對殘差數據做DCT轉換

可以將殘差數據做整數離散余弦變換,去掉數據的相關性,進一步壓縮數據

如下圖所示,左側為原數據的宏塊,右側為計算出的殘差數據的宏塊。

H264_Encode_N.jpg


將殘差數據宏塊數字化后如下圖所示:

H264_Encode_O.jpg


將殘差數據宏塊進行 DCT 轉換。

H264_Encode_P.jpg


去掉相關聯的數據后,我們可以看出數據被進一步壓縮了。做完 DCT 后,還不夠,還要進行 CABAC 進行無損壓縮。


3.7 CABAC 壓縮

上面的幀內壓縮是屬於有損壓縮技術。也就是說圖像被壓縮后,無法完全復原。而 CABAC 屬於無損壓縮技術。

無損壓縮技術大家最熟悉的可能就是哈夫曼編碼了,給高頻的詞一個短碼,給低頻詞一個長碼從而達到數據壓縮的目的。

MPEG-2 中使用的 VLC 就是這種算法,我們以 A-Z 作為例子,A 屬於高頻數據,Z 屬於低頻數據。看看它是如何做的。

H264_Encode_Q.jpg


CABAC 也是給高頻數據短碼,給低頻數據長碼。同時還會根據上下文相關性進行壓縮,這種方式又比 VLC 高效很多。其效果如下:

img


現在將 A-Z 換成視頻幀,它就成了下面的樣子。

H264_Encode_V.jpg


從上面這張圖中明顯可以看出采用 CACBA 的無損壓縮方案要比 VLC 高效的多。


四、小結

至此,我們就將 H264 的編碼原理講完了。本篇文章主要講了以下以點內容:

  • 簡單介紹了 H264 中的一些基本概念。如 I/P/B 幀, GOP。
  • 詳細講解了 H264 編碼的基本原理,包括:
    • 宏塊的划分,以及子塊的划分。
    • 幀分組,將相似的幾幀划分為一組,即 H264 中的 序列(GOP)
    • 運動估計與運動補償(幀間預測),獲取 P/B 幀。
    • 幀內預測,獲取 I 幀。
    • 對殘差數據做 DCT 轉換。
    • CABAC 壓縮。

參考:

H264視頻壓縮算法

H264系列--壓縮編碼技術



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM