視頻編碼最重要目的就是為了進(jìn)行數(shù)據(jù)壓縮寥裂,以此來降低數(shù)據(jù)傳輸和存儲的成本哈垢,用一個簡單的例子來說明視頻編碼的重要性早龟。我們計算一段 10
秒鐘1080p
(1920*1080)惫霸、30fps
的 yuv420p
像素格式(每個像素占用1.5
字節(jié))原始視頻的體積:
1920 * 1080 * 30 * 10 * 1.5 = 933120000 字節(jié) ≈ 889.89MB
僅僅是一段 10
秒鐘的1080p
原始視頻的體積就達(dá)到了 889.89MB
,如果傳輸沒有壓縮的視頻數(shù)據(jù)葱弟,1 秒鐘需要約 88.99MB
的帶寬壹店,顯然這是一個很大的數(shù)據(jù)量,應(yīng)用于現(xiàn)在的網(wǎng)絡(luò)芝加,網(wǎng)絡(luò)壓力會很大茫打。但是有了視頻編碼的存在,大幅的減少了視頻流所需要的比特,讓現(xiàn)在的網(wǎng)絡(luò)可以無壓力的播放老赤,甚至在某些低碼率的情況下,我們依然可以看到高清的視頻制市。當(dāng)前視頻編碼標(biāo)準(zhǔn)很多抬旺,最主流的還是 H.264 編碼。
一祥楣、H.264簡介
國際上制定視頻編解碼技術(shù)的組織有兩個开财,一個是“國際電聯(lián)(ITU-T)”,它制定的標(biāo)準(zhǔn)有 H.261误褪、H.263责鳍、H.263+ 等,另一個是“國際標(biāo)準(zhǔn)化組織(ISO)”它制定的標(biāo)準(zhǔn)有 MPEG-1兽间、MPEG-2历葛、MPEG-4 等。而 H.264 則是由兩個組織聯(lián)合組建的聯(lián)合視頻組(JVT)共同制定的新數(shù)字視頻編碼標(biāo)準(zhǔn)嘀略,所以它既是 ITU-T 的 H.264恤溶,又是 ISO/IEC 的 MPEG-4 高級視頻編碼(Advanced Video Coding,AVC)的第 10 部分帜羊。
H.264 是迄今為止視頻錄制咒程、壓縮和分發(fā)的最常用格式。截至 2019 年 9 月讼育,已有 91% 的視頻開發(fā)人員使用了該格式帐姻。H.264 提供了明顯優(yōu)于以前任何標(biāo)準(zhǔn)的壓縮性能,在同樣的畫質(zhì)下奶段,擁有更高的壓縮率(低碼率)饥瓷,同時擁有更好的網(wǎng)絡(luò)親和性,可適用于各種傳輸網(wǎng)絡(luò)忧饭。H.264 因其是藍(lán)光盤的其中一種編解碼標(biāo)準(zhǔn)而著名扛伍,所有藍(lán)光盤播放器都必須能解碼 H.264。
二词裤、編碼過程及原理
H.264 的編程過程比較復(fù)雜刺洒,本文只介紹大體的框架和脈絡(luò),具體細(xì)節(jié)就不展開了吼砂。大體可以歸納為以下幾個主要步驟(如下圖):劃分幀類型逆航、幀內(nèi)/幀間編碼、變換 + 量化渔肩、濾波因俐、熵編碼。
1、劃分幀類型
視頻壓縮主要是壓縮視頻冗余數(shù)據(jù)抹剩,對于視頻數(shù)據(jù)主要有兩類冗余數(shù)據(jù)撑帖,一類是空間上的冗余,一類是時間上的冗余澳眷。其中時間上的冗余是最大的胡嘿。為什么說時間上的冗余是最大的呢?我們使用 YuvEye 查看視頻的每一幀會發(fā)現(xiàn)钳踊,有很多連續(xù)的幀是相似的(如下圖的 3853~3864 幀是非常相似的)衷敌,連續(xù)相似的幀有可能有幾十幀,也有可能有幾百幀拓瞪。對于這些連續(xù)相似的幀缴罗,其實我們只需要保存一幀數(shù)據(jù),其他幀可以通過這一幀按照某種規(guī)則預(yù)測出來祭埂,所以說視頻數(shù)據(jù)在時間上的冗余是最多的面氓。
有統(tǒng)計結(jié)果表明,在連續(xù)的幾幀圖像中沟堡,一般只有10%以內(nèi)的像素有差別侧但,亮度的差值變化不超過2%,而色度的差值變化只在1%以內(nèi)航罗。為了達(dá)到連續(xù)相似的相關(guān)幀通過預(yù)測的方法來壓縮數(shù)據(jù)禀横,就需要將視頻幀進(jìn)行分組。那么如何對相似幀進(jìn)行分組呢粥血?H.264 編碼器會按順序柏锄,每次取出兩幅相鄰的幀進(jìn)行宏塊比較,計算兩幀的相似度复亏。通過宏塊掃描與宏塊搜索可以發(fā)現(xiàn)這兩個幀的關(guān)聯(lián)度是非常高的趾娃。進(jìn)而發(fā)現(xiàn)這一組幀的關(guān)聯(lián)度都是非常高的,這些幀就可以劃分到一個圖像群組缔御,我們簡稱 GOP(Group Of Pictures)抬闷。
接下來就要對 GOP 中的每一幀確定一個類型,H.264 協(xié)議中定義了 I 幀
耕突、P 幀
和 B 幀
共 3 種類型:
I 幀
(I Picture笤成、I Frame、Intra Coded Picture)眷茁,譯為:幀內(nèi)編碼圖像炕泳,也叫做關(guān)鍵幀(Keyframe),是視頻的第一幀上祈,也是 GOP 的第一幀培遵,一個 GOP 只有一個I 幀
浙芙。I 幀
是一種自帶全部信息的完整獨立幀,不會依賴其他幀的信息籽腕,也就是自我進(jìn)行參考的幀嗡呼,可以簡單理解為一張靜態(tài)圖像。在編碼時對整幀圖像數(shù)據(jù)進(jìn)行編碼节仿。在解碼時僅用當(dāng)前I 幀
的編碼數(shù)據(jù)就可以解碼出完整的圖像晤锥。
P 幀
(P Picture、P Frame廊宪、Predictive Coded Picture),譯為:預(yù)測編碼圖像女轿。編碼時并不會對整幀圖像數(shù)據(jù)進(jìn)行編碼箭启,以前面的 I 幀
或 P 幀
作為參考幀,只編碼當(dāng)前 P 幀
與參考幀的差異數(shù)據(jù)蛉迹。解碼時需要先解碼出前面的參考幀傅寡,再結(jié)合差異數(shù)據(jù)解碼出當(dāng)前 P 幀
完整的圖像。在較早的視頻編碼標(biāo)準(zhǔn)(例如MPEG-2)中北救,P 幀
只能使用一個參考幀荐操,而一些現(xiàn)代視頻編碼標(biāo)準(zhǔn)(比如 H.264),允許使用多個參考幀珍策。
B 幀
(B Picture托启、B Frame、Bipredictive Coded Picture)攘宙,譯為:前后預(yù)測編碼圖像屯耸。
編碼時并不會對整幀圖像數(shù)據(jù)進(jìn)行編碼,同時以前面蹭劈、后面的 I 幀
或 P 幀
作為參考幀疗绣,只編碼當(dāng)前 B 幀
與前后參考幀的差異數(shù)據(jù),因為可參考的幀變多了铺韧,所以只需要存儲更少的差異數(shù)據(jù)多矮。解碼時需要先解碼出前后的參考幀,再結(jié)合差異數(shù)據(jù)解碼出當(dāng)前 B 幀
完整的圖像哈打。
不難看出塔逃,編碼后的數(shù)據(jù)大小:I 幀
> P 幀
> B 幀
前酿。
1.1患雏、幀的編解碼順序
以下圖為例,在播放時站在用戶角度看到的幀的順序是 I0->B2->B3->P1->B5->B6->P4->B8->B9->I7->B11->B12->P10
罢维。編碼時同樣首先編碼 I0
幀淹仑,按照顯示順序接下來應(yīng)該編碼 B2
幀丙挽,但是由于 B2
幀需要參考后面的 P1
幀,所以要優(yōu)先編碼 P1
幀匀借,接下來才能編碼 B2
幀颜阐,然后是 B3
幀,再后面就是 P4
幀吓肋、B5
幀凳怨、B6
幀,緊接著由于 B8
幀和 B9
幀需要參考 GOP #1 的 I7
幀是鬼,在 B8
幀和 B9
幀編碼之前要先編碼 I7
幀肤舞,總結(jié)下來編碼的順序是 I0->P1->B2->B3->P4->B5->B6->I7->B8->B9->P10->B11->B12
。解碼順序和編碼順序是一樣的均蜜。
1.2李剖、GOP 長度
GOP 的長度表示 GOP 的幀數(shù)。GOP 的長度需要控制在合理范圍囤耳,以平衡視頻質(zhì)量篙顺、視頻大小(網(wǎng)絡(luò)帶寬)和seek 效果(拖動充择、快進(jìn)的響應(yīng)速度)等德玫。加大 GOP 長度有利于減小視頻文件大小,但也不宜設(shè)置過大椎麦,太大則會導(dǎo)致 GOP 后部幀的畫面失真宰僧,影響視頻質(zhì)量。由于 P 幀
铃剔、B 幀
的復(fù)雜度大于 I 幀
,GOP 值過大键兜,過多的P 幀
凤类、B 幀
會影響編碼效率,使編碼效率降低普气。如果設(shè)置過小的 GOP 值谜疤,視頻文件會比較大,則需要提高視頻的輸出碼率现诀,以確保畫面質(zhì)量不會降低夷磕,故會增加網(wǎng)絡(luò)帶寬。GOP 長度也是影響視頻 seek 響應(yīng)速度的關(guān)鍵因素仔沿,seek 時播放器需要定位到離指定位置最近的前一個I 幀
坐桩,如果 GOP 太大意味著距離指定位置可能越遠(yuǎn)(需要解碼的參考幀就越多)、seek 響應(yīng)的時間(緩沖時間)也越長封锉。
1.3绵跷、GOP 類型
GOP 又可以分為 Open(開放)膘螟、Closed(封閉)兩種。Open 類型:前一個 GOP 的 B 幀
可以參考下一個 GOP 的 I 幀
碾局。Closed 類型:前一個 GOP 的 B 幀
不能參考下一個 GOP 的 I 幀
荆残,并且 GOP 不能以 B 幀
結(jié)尾。
需要注意的是净当,由于 P 幀
内斯、B 幀
都對前面的參考幀(P 幀
、I 幀
)有依賴性像啼,因此俘闯,一旦前面的參考幀出現(xiàn)數(shù)據(jù)錯誤,就會導(dǎo)致后面的 P 幀
忽冻、B 幀
也出現(xiàn)數(shù)據(jù)錯誤备徐,而且這種錯誤還會繼續(xù)向后傳播。對于普通的 I 幀
甚颂,其后的P 幀
和B 幀
可以參考該普通 I 幀
之前的其他 I 幀
。
在 Closed GOP 中秀菱,有一種特殊的 I 幀
振诬,叫做 IDR 幀
(Instantaneous Decoder Refresh,譯為:即時解碼刷新)衍菱。在編碼解碼中為了方便赶么,將 GOP 中首個 I 幀
要和其他I幀區(qū)別開,把第一個 I 幀
叫 IDR 幀
脊串,這樣方便控制編碼和解碼流程辫呻,所以 IDR 幀
一定是 I 幀
,但 I 幀
不一定是 IDR 幀
琼锋。當(dāng)遇到 IDR 幀
時放闺,會清空參考幀隊列。如果前一個序列出現(xiàn)重大錯誤缕坎,在這里可以獲得重新同步的機(jī)會怖侦,使錯誤不會繼續(xù)往下傳播。一個 IDR 幀
之后的所有幀谜叹,永遠(yuǎn)都不會參考該 IDR 幀之前的幀匾寝。視頻播放時,播放器一般都支持隨機(jī) seek(拖動)到指定位置荷腊,而播放器直接選擇到指定位置附近的 IDR 幀
進(jìn)行播放最為便捷艳悔,因為可以明確知道該 IDR 幀
之后的所有幀都不會參考其之前的其他 I 幀
,從而避免較為復(fù)雜的反向解析女仰。
2猜年、幀內(nèi)/幀間編碼
I 幀
采用的是幀內(nèi)(Intra Frame)編碼抡锈,處理的是空間冗余。P 幀
码倦、B 幀
采用的是幀間(Inter Frame)編碼企孩,處理的是時間冗余。
2.1袁稽、劃分宏塊
在進(jìn)行編碼之前勿璃,編碼器會通過算法將一張完整的幀切割成多個宏塊(Macroblock),然后逐塊進(jìn)行后續(xù)的壓縮處理推汽。H.264 中的宏塊大小通常是 16x16
补疑,宏塊是 H.264 中最大的塊。宏塊可以進(jìn)一步拆分為多個更小的變換塊(Transform blocks)歹撒、預(yù)測塊(Prediction blocks)莲组。變換塊的尺寸有:16x16
、8x8
暖夭、4x4
锹杈。預(yù)測塊的尺寸有:16×16
、16×8
迈着、8×16
竭望、8×8
、8×4
裕菠、4×8
咬清、4×4
。
2.2奴潘、幀內(nèi)編碼
幀內(nèi)編碼旧烧,也稱幀內(nèi)預(yù)測。 假設(shè)當(dāng)前的塊不在圖像邊緣画髓,我們可以用上方相鄰塊邊界鄰近值作為基礎(chǔ)值掘剪,也就是上面一行中的每一個值,都垂直向下做拷貝雀扶,構(gòu)建出和源 YUV 塊一樣大小的預(yù)測塊杖小,這種構(gòu)建預(yù)測塊的方式,我們叫做垂直預(yù)測模式愚墓,屬于幀內(nèi)預(yù)測模式的一種予权。緊接著,以 4x4
的預(yù)測塊為例浪册,用源 YUV 的數(shù)據(jù)和預(yù)測 YUV 的數(shù)據(jù)做差值扫腺,得到殘差塊,這樣我們在碼流中村象,就直接傳輸當(dāng)前 4x4
塊的預(yù)測模式的標(biāo)志位和殘差數(shù)據(jù)就行笆环,這樣極大地節(jié)省了碼流攒至。編碼器會選取最佳預(yù)測模式,使預(yù)測幀更加接近原始幀躁劣,減少相互間的差異迫吐,提高編碼的壓縮效率。
與垂直預(yù)測模式相似的账忘,還有水平預(yù)測模式志膀、均值預(yù)測模式(也就是 4x4
的均值填充整個 4x4
)等 9 種可選的預(yù)測模式,:
2.3鳖擒、幀間編碼
幀間編碼溉浙,也稱幀間預(yù)測,用到了運動補(bǔ)償(Motion compensation)技術(shù)蒋荚。編碼器利用塊匹配算法戳稽,嘗試在先前已編碼的幀(稱為參考幀)上搜索與正在編碼的塊相似的塊。如果編碼器搜索成功期升,則可以使用稱為運動矢量的向量對塊進(jìn)行編碼惊奇,該向量指向匹配塊在參考幀處的位置。在大多數(shù)情況下播赁,編碼器將成功執(zhí)行赊时,但是找到的塊可能與它正在編碼的塊不完全匹配,這時編碼器將計算它們之間殘差值行拢。這些殘差值稱為預(yù)測誤差,需要進(jìn)行變換并將其發(fā)送給編碼器诞吱。綜上所述舟奠,如果編碼器在參考幀上成功找到匹配塊,它將獲得指向匹配塊的運動矢量和預(yù)測誤差房维。使用這兩個元素以及幀間預(yù)測模式標(biāo)志位沼瘫,解碼器將能夠恢復(fù)該塊的原始像素。如果一切順利咙俩,該算法將能夠找到一個幾乎沒有預(yù)測誤差的匹配塊耿戚,因此,一旦進(jìn)行變換阿趁,運動矢量加上預(yù)測誤差的總大小將小于原始編碼的大小膜蛔。如果塊匹配算法未能找到合適的匹配,則預(yù)測誤差將是可觀的脖阵。因此皂股,運動矢量的總大小加上預(yù)測誤差將大于原始編碼。在這種情況下命黔,編碼器將產(chǎn)生異常呜呐,并為該特定塊發(fā)送原始編碼就斤。
3、變換 + 量化
把經(jīng)過預(yù)測后得到的殘差值經(jīng)過 DCT 變換(Discrete Cosine Transform蘑辑,譯為離散余弦變換)洋机,目的是把直流和低頻(相對平坦,圖像或塊中大部分占比)能量集中在左上洋魂,高頻(細(xì)節(jié)绷旗,圖像或塊中少部分占比)能量集中在右下。DCT 本身雖然沒有壓縮作用忧设,僅僅是去掉了數(shù)據(jù)的相關(guān)性刁标,卻為后面進(jìn)一步壓縮數(shù)據(jù)時的取舍,奠定了必不可少的基礎(chǔ)址晕。
變換后直流分量 DC 都集中在左上角膀懈,是整塊像素的求和的均值。由于人眼對高頻信號不敏感谨垃,我們可以定義這樣一個變量 QP = 5启搂,將變換塊中所有的值都除以 QP,這樣做進(jìn)一步節(jié)省傳輸碼流位寬刘陶,同時主要去掉了高頻分量的值胳赌,在解碼端只需要將變換塊中所有的值在乘 QP 就可以基本還原低頻分量。
我們將 QP 運算的過程稱為量化匙隔,可見量化值越大疑苫,丟掉的高頻信息就越多渠驼,再加上編碼器中都是用整形變量代表像素值胀蛮,所以量化值最大還原的低頻信息也會越不準(zhǔn)確掏熬,即造成的失真就越大萌业,塊效應(yīng)也會越大祈秕,視頻編碼的質(zhì)量損失主要來源于此啄清。
4饶米、濾波
---- 后續(xù)更新 ----
5玄捕、熵編碼
熵的大小與信源的概率模型有著密切的關(guān)系喂柒,各個符號出現(xiàn)的概率不同不瓶,信源的熵也不同。當(dāng)信源中各事件是等概率分布時灾杰,熵具有極大值蚊丐。信源的熵與其可能達(dá)到的最大值之間的差值反映了該信源所含有的冗余度。信源的冗余度越小艳吠,即每個符號所獨立攜帶的信息量越大吠撮,那么傳送相同的信息量所需要的序列長度越短,符號位越少。因此泥兰,數(shù)據(jù)壓縮的一個基本的途徑是去除信源的符號之間的相關(guān)性弄屡,盡可能地使序列成為無記憶的,即前一符號的出現(xiàn)不影響以后任何一個符號出現(xiàn)的概率鞋诗。
利用信源的統(tǒng)計特性進(jìn)行碼率壓縮的編碼就稱為熵編碼膀捷,也叫統(tǒng)計編碼。熵編碼是無損壓縮編碼方法削彬,它生成的碼流可以經(jīng)解碼無失真地恢復(fù)出原數(shù)據(jù)全庸。熵編碼是建立在隨機(jī)過程的統(tǒng)計特性基礎(chǔ)上的。
視頻編碼常用的有兩種:變長編碼(哈夫曼編碼)融痛、算術(shù)編碼壶笼。
H.264 最后將結(jié)果進(jìn)行熵編碼,分為上下文自適應(yīng)的變長編碼(Context-based Adaptive Variable-Length Coding雁刷,CAVLC)與上下文自適應(yīng)的二進(jìn)制算術(shù)編碼(Context-based Adaptive Binary Arithmetic Coding覆劈,CABAC)。
三沛励、H.264 的主要規(guī)格
1责语、Baseline Profile(BP)
支持 I / P 幀
,只支持無交錯(Progressive)和 CAVLC目派;
一般用于低階或需要額外容錯的應(yīng)用坤候,比如視頻通話、手機(jī)視頻等即時通信領(lǐng)域企蹭。
2白筹、Extended Profile(XP)
在 Baseline 的基礎(chǔ)上增加了額外的功能,支持流之間的切換谅摄,改進(jìn)誤碼性能遍蟋;
支持 I / P / B / SP / SI 幀
,只支持無交錯(Progressive)和 CAVLC螟凭;
適合于視頻流在網(wǎng)絡(luò)上的傳輸場合,比如視頻點播它呀。
3螺男、Main Profile(MP)
提供 I / P / B 幀
,支持無交錯(Progressive)和交錯(Interlaced)纵穿,支持 CAVLC 和 CABAC下隧;
用于主流消費類電子產(chǎn)品規(guī)格如低解碼(相對而言)的 MP4、便攜的視頻播放器谓媒、PSP 和 iPod 等淆院。
4、High Profile(HiP)
最常用的規(guī)格句惯,在 Main 的基礎(chǔ)上增加了 8x8
內(nèi)部預(yù)測土辩、自定義量化支救、無損視頻編碼和更多的 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启涯;
用于廣播及視頻碟片存儲(藍(lán)光影片)贬堵,高清電視的應(yīng)用。