【秒懂音影片開發】23_H.264編碼
本文主要介紹一種非常流行的影片編碼:H.264。
計算一下:10秒鐘1080p(1920×1080)、30fps的YUV420P原始影片,需要佔用多大的存儲空間?
- (10 * 30) * (1920 * 1080) * 1.5 = 933120000位元組 ≈ 889.89MB
- 可以看得出來,原始影片的體積是非常巨大的
由於網路頻寬和硬碟存儲空間都是非常有限的,因此,需要先使用影片編碼技術(比如H.264編碼)對原始影片進行壓縮,然後再進行存儲和分發。H.264編碼的壓縮比可以達到至少是100:1。
簡介
H.264,又稱為MPEG-4 Part 10,Advanced Video Coding。
- 譯為:MPEG-4第10部分,高級影片編碼
- 簡稱:MPEG-4 AVC
H.264是迄今為止影片錄製、壓縮和分發的最常用格式。截至2019年9月,已有91%的影片開發人員使用了該格式。H.264提供了明顯優於以前任何標準的壓縮性能。H.264因其是藍光碟的其中一種編解碼標準而著名,所有藍光碟播放器都必須能解碼H.264。
編碼器
H.264標準允許製造廠商自由地開發具有競爭力的創新產品,它並沒有定義一個編碼器,而是定義了編碼器應該產生的輸出碼流。
x264是一款免費的高性能的H.264開源編碼器。x264編碼器在FFmpeg中的名稱是libx264。
AVCodec *codec = avcodec_find_encoder_by_name("libx264");
解碼器
H.264標準中定義了一個解碼方法,但是製造廠商可以自由地開發可選的具有競爭力的、新的解碼器,前提是他們能夠獲得與標準中採用的方法同樣的結果。
FFmpeg默認已經內置了一個H.264的解碼器,名稱是h264。
AVCodec *codec1 = avcodec_find_decoder_by_name("h264");
// 或者
AVCodec *codec2 = avcodec_find_decoder(AV_CODEC_ID_H264);
編碼過程與原理
H.264的編程過程比較複雜,本文只介紹大體的框架和脈絡,具體細節就不展開了。
大體可以歸納為以下幾個主要步驟:
- 劃分幀類型
- 幀內/幀間編碼
- 變換 + 量化
- 濾波
- 熵編碼
劃分幀類型
有統計結果表明:在連續的幾幀影像中,一般只有10%以內的像素有差別,亮度的差值變化不超過2%,而色度的差值變化只在1%以內。
GOP
於是可以將一串連續的相似的幀歸到一個影像群組(Group Of Pictures,GOP)。
GOP中的幀可以分為3種類型:
- I幀(I Picture、I Frame、Intra Coded Picture),譯為:幀內編碼影像,也叫做關鍵幀(Keyframe)
- 是影片的第一幀,也是GOP的第一幀,一個GOP只有一個I幀
- 編碼
- 對整幀影像數據進行編碼
- 解碼
- 僅用當前I幀的編碼數據就可以解碼出完整的影像
- 是一種自帶全部資訊的獨立幀,無需參考其他影像便可獨立進行解碼,可以簡單理解為一張靜態影像
- P幀(I Picture、I Frame、Predictive Coded Picture),譯為:預測編碼影像
- 編碼
- 並不會對整幀影像數據進行編碼
- 以前面的I幀或P幀作為參考幀,只編碼當前P幀與參考幀的差異數據
- 解碼
- 需要先解碼出前面的參考幀,再結合差異數據解碼出當前P幀完整的影像
- 編碼
- B幀(B Picture、B Frame、Bipredictive Coded Picture),譯為:前後預測編碼影像
- 編碼
- 並不會對整幀影像數據進行編碼
- 同時以前面、後面的I幀或P幀作為參考幀,只編碼當前B幀與前後參考幀的差異數據
- 因為可參考的幀變多了,所以只需要存儲更少的差異數據
- 解碼
- 需要先解碼出前後的參考幀,再結合差異數據解碼出當前B幀完整的影像
- 編碼
不難看出,編碼後的數據大小:I幀 > P幀 > B幀。
在較早的影片編碼標準(例如MPEG-2)中,P幀只能使用一個參考幀,而一些現代影片編碼標準(比如H.264),允許使用多個參考幀。
GOP的長度
GOP的長度表示GOP的幀數。GOP的長度需要控制在合理範圍,以平衡影片品質、影片大小(網路頻寬)和seek效果(拖動、快進的響應速度)等。
-
加大GOP長度有利於減小影片文件大小,但也不宜設置過大,太大則會導致GOP後部幀的畫面失真,影響影片品質
-
由於P、B幀的複雜度大於I幀,GOP值過大,過多的P、B幀會影響編碼效率,使編碼效率降低
-
如果設置過小的GOP值,影片文件會比較大,則需要提高影片的輸出碼率,以確保畫面品質不會降低,故會增加網路頻寬
-
GOP長度也是影響影片seek響應速度的關鍵因素,seek時播放器需要定位到離指定位置最近的前一個I幀,如果GOP太大意味著距離指定位置可能越遠(需要解碼的參考幀就越多)、seek響應的時間(緩衝時間)也越長
GOP的類型
GOP又可以分為開放(Open)、封閉(Closed)兩種。
- Open
- 前一個GOP的B幀可以參考下一個GOP的I幀
- Closed
- 前一個GOP的B幀不能參考下一個GOP的I幀
- GOP不能以B幀結尾
需要注意的是:
-
由於P幀、B幀都對前面的參考幀(P幀、I幀)有依賴性,因此,一旦前面的參考幀出現數據錯誤,就會導致後面的P幀、B幀也出現數據錯誤,而且這種錯誤還會繼續向後傳播
-
對於普通的I幀,其後的P幀和B幀可以參考該普通I幀之前的其他I幀
在Closed GOP中,有一種特殊的I幀,叫做IDR幀(Instantaneous Decoder Refresh,譯為:即時解碼刷新)。
- 當遇到IDR幀時,會清空參考幀隊列
- 如果前一個序列出現重大錯誤,在這裡可以獲得重新同步的機會,使錯誤不會繼續往下傳播
- 一個IDR幀之後的所有幀,永遠都不會參考該IDR幀之前的幀
- 影片播放時,播放器一般都支援隨機seek(拖動)到指定位置,而播放器直接選擇到指定位置附近的IDR幀進行播放最為便捷,因為可以明確知道該IDR幀之後的所有幀都不會參考其之前的其他I幀,從而避免較為複雜的反向解析
幀內/幀間編碼
I幀採用的是幀內(Intra Frame)編碼,處理的是空間冗餘。
P幀、B幀採用的是幀間(Inter Frame)編碼,處理的是時間冗餘。
劃分宏塊
在進行編碼之前,首先要將一張完整的幀切割成多個宏塊(Macroblock),H.264中的宏塊大小通常是16×16。
宏塊可以進一步拆分為多個更小的變換塊(Transform blocks)、預測塊(Prediction blocks)。
-
變換塊的尺寸有:16×16、8×8、4×4
-
預測塊的尺寸有:16×16、16×8、8×16、8×8、8×4、4×8、4×4
幀內編碼
幀內編碼,也稱幀內預測。以4×4的預測塊為例,共有9種可選的預測模式。
利用幀內預測技術,可以得到預測幀,最終只需要保留預測模式資訊、以及預測幀與原始幀的殘差值。
編碼器會選取最佳預測模式,使預測幀更加接近原始幀,減少相互間的差異,提高編碼的壓縮效率。
幀間編碼
幀間編碼,也稱幀間預測,用到了運動補償(Motion compensation)技術。
編碼器利用塊匹配演算法,嘗試在先前已編碼的幀(稱為參考幀)上搜索與正在編碼的塊相似的塊。如果編碼器搜索成功,則可以使用稱為運動矢量的向量對塊進行編碼,該向量指向匹配塊在參考幀處的位置。
在大多數情況下,編碼器將成功執行,但是找到的塊可能與它正在編碼的塊不完全匹配。這就是編碼器將計算它們之間差異的原因。這些殘差值稱為預測誤差,需要進行變換並將其發送給解碼器。
綜上所述,如果編碼器在參考幀上成功找到匹配塊,它將獲得指向匹配塊的運動矢量和預測誤差。使用這兩個元素,解碼器將能夠恢復該塊的原始像素。
如果一切順利,該演算法將能夠找到一個幾乎沒有預測誤差的匹配塊,因此,一旦進行變換,運動矢量加上預測誤差的總大小將小於原始編碼的大小。
如果塊匹配演算法未能找到合適的匹配,則預測誤差將是可觀的。因此,運動矢量的總大小加上預測誤差將大於原始編碼。在這種情況下,編碼器將產生異常,並為該特定塊發送原始編碼。
變換與量化
接下來對殘差值進行DCT變換(Discrete Cosine Transform,譯為離散餘弦變換)。
規格
H.264的主要規格有:
- Baseline Profile(BP)
- 支援I/P幀,只支援無交錯(Progressive)和CAVLC
- 一般用於低階或需要額外容錯的應用,比如影片通話、手機影片等即時通訊領域
- Extended Profile(XP)
- 在Baseline的基礎上增加了額外的功能,支援流之間的切換,改進誤碼性能
- 支援I/P/B/SP/SI幀,只支援無交錯(Progressive)和CAVLC
- 適合於影片流在網路上的傳輸場合,比如影片點播
- Main Profile(MP)
- 提供I/P/B幀,支援無交錯(Progressive)和交錯(Interlaced),支援CAVLC和CABAC
- 用於主流消費類電子產品規格如低解碼(相對而言)的MP4、隨身的影片播放器、PSP和iPod等
- High Profile(HiP)
- 最常用的規格
- 在Main的基礎上增加了8×8內部預測、自定義量化、無損影片編碼和更多的YUV格式(如4:4:4)
- High 4:2:2 Profile(Hi422P)
- High 4:4:4 Predictive Profile(Hi444PP)
- High 4:2:2 Intra Profile
- High 4:4:4 Intra Profile
- 用於廣播及影片碟片存儲(藍光影片),高清電視的應用