本文主要介紹一種非常流行的視訊編碼:H.264。
計算一下:10秒鐘1080p(1920x1080)、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中的巨集塊大小通常是16x16。
巨集塊可以進一步拆分為多個更小的變換塊(Transform blocks)、預測塊(Prediction blocks)。
-
變換塊的尺寸有:16x16、8x8、4x4
-
預測塊的尺寸有:16×16、16×8、8×16、8×8、8×4、4×8、4×4
幀內編碼
幀內編碼,也稱幀內預測。以4x4的預測塊為例,共有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的基礎上增加了8x8內部預測、自定義量化、無損視訊編碼和更多的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
- 用於廣播及視訊碟片儲存(藍光影片),高清電視的應用