Easy Tech:什么是I帧、P帧和B帧?
I幀、P幀和B幀(I-frames、P-frames and B-frames)的概念是視頻壓縮領(lǐng)域的基礎(chǔ)。這三種幀類型在特定情況下用于提高編解碼器的壓縮效率、壓縮流的視頻質(zhì)量,以及使得流去應(yīng)對(duì)傳輸和存儲(chǔ)時(shí)候的錯(cuò)誤和故障。
翻譯 | Alex
技術(shù)審校 | 趙軍
本文來自O(shè)TTVerse,作者為Krishna Rao Vijayanagar。
?
I幀、P幀和B幀?Easy-Tech?#002#
?
在本篇文章中,我們將學(xué)習(xí)I幀、P幀和B幀的工作原理以及它們的用途。
好,我們先從現(xiàn)代視頻壓縮中最基本的概念開始——幀內(nèi)預(yù)測(cè)和幀間預(yù)測(cè)。
?
幀內(nèi)預(yù)測(cè)和幀間預(yù)測(cè)
?
在本篇文章中,我并不會(huì)深入講解幀內(nèi)預(yù)測(cè)和幀間預(yù)測(cè)(Intra and Inter-prediction)的技術(shù)細(xì)節(jié),但是我會(huì)告訴你它們?yōu)楹未嬖谝约坝惺裁从锰帯?/p>
以下方圖片為例。圖片顯示了兩個(gè)視頻幀(彼此相鄰),有一個(gè)黑色像素的矩形塊在其中移動(dòng)。在第一幀中,該塊位于圖像的左側(cè),而在第二幀中,它已經(jīng)移到了右側(cè)。?
如果我想用現(xiàn)代視頻編碼器(如H.264或HEVC)壓縮幀2,我會(huì)這樣做:
1.將視頻分解為多個(gè)像素塊(宏塊),并逐一壓縮。
2.為了壓縮每個(gè)宏塊,首先在當(dāng)前幀和前后幀中搜索,找到與我們想要壓縮的宏塊相似的宏塊。
3.記錄最佳匹配的宏塊的位置(位于哪一幀以及在該幀中的位置)。然后,兩個(gè)宏塊之間的差異被壓縮,并和位置信息一起被發(fā)送給解碼器。
請(qǐng)看下方圖片。如果要壓縮幀2中的宏塊(已用紅色方框標(biāo)記),你認(rèn)為最佳方法是什么?該怎么做?
?
?
1.首先,我可以查看幀1,并找到相匹配的宏塊。它似乎移動(dòng)了一個(gè)幀寬(我知道要少一些)的距離,并與幀2中像素塊的高度大約相同。好的,運(yùn)動(dòng)矢量出現(xiàn)了。
2.我在同一幀內(nèi)搜索,并很快發(fā)現(xiàn),位于紅色方框標(biāo)記的宏塊與上方的宏塊相同。所以,我可以讓解碼器復(fù)制這一宏塊,而不必再去其他幀搜索。這樣一來,運(yùn)動(dòng)矢量便是最小的(如果存在的話)。
現(xiàn)在我們來看下一個(gè)示例。如果想要壓縮幀2中包含藍(lán)色球體的宏塊,我們?cè)撛趺醋瞿?#xff1f;
在同一幀內(nèi)搜索,還是在前面的編碼幀中搜索?
?
?
1.首先,我查看了幀1并找到了相匹配的球體,它似乎移動(dòng)了一個(gè)幀寬(我知道要少一些)的距離,并向上移動(dòng)了一些。這讓我們得到了運(yùn)動(dòng)矢量。另外,包含兩個(gè)球體的宏塊之間的差異似乎非常小(猜測(cè)的)。
2.然后我在同一幀內(nèi)搜索,馬上意識(shí)到相同幀里面并沒有包含球體的其他宏塊。看來這次運(yùn)氣不太好,沒有在同一幀內(nèi)找到匹配的宏塊。
從上面那些示例中,我們都學(xué)到了什么?
1.編碼器搜索匹配宏塊以減少需要傳輸?shù)臄?shù)據(jù)的大小,整個(gè)過程通過運(yùn)動(dòng)估計(jì)和補(bǔ)償來完成,這使得編碼器可以在另一幀內(nèi)發(fā)現(xiàn)宏塊的水平和垂直位移。
2.編碼器可以在同一幀內(nèi)(幀內(nèi)預(yù)測(cè))和相鄰幀內(nèi)(幀間預(yù)測(cè))搜到匹配的宏塊。
3.它比較每個(gè)宏塊的幀間和幀內(nèi)預(yù)測(cè)結(jié)果,并選出最佳結(jié)果。這個(gè)過程被稱為“模式選擇”,我認(rèn)為這是視頻編碼器最核心的部分。
現(xiàn)在,看完對(duì)幀內(nèi)預(yù)測(cè)和幀間預(yù)測(cè)的快速介紹,讓我們來學(xué)習(xí)I幀、P幀和B幀吧!
?
什么是I幀?
?
I幀或關(guān)鍵幀或幀內(nèi)幀(I-frame or Key-Frame or Intra-frame)僅由幀內(nèi)預(yù)測(cè)的宏塊組成。
I幀中的每個(gè)宏塊只能在同一幀內(nèi)匹配其他宏塊,這意味著,它只能利用幀內(nèi)“空間冗余”來進(jìn)行壓縮。空間冗余是一個(gè)術(shù)語,用來指單個(gè)幀的像素之間的相似性。
I幀在不同的視頻編解碼器中以不同的形式出現(xiàn),如IDR、CRA或者BLA。這些不同類型的I幀本質(zhì)相同:都不存在時(shí)域預(yù)測(cè)。
I幀有很多用處,在我們學(xué)習(xí)P幀和B幀之后,我們?cè)賮硌芯俊?/p>
?
什么是P幀?
?
P幀代表預(yù)測(cè)幀,除了空域預(yù)測(cè)以外,它還可以通過時(shí)域預(yù)測(cè)來進(jìn)行壓縮。P幀參考前面的幀進(jìn)行運(yùn)動(dòng)估計(jì)。P幀中的每個(gè)宏塊都可以被:
- 時(shí)域預(yù)測(cè)
- 空域預(yù)測(cè)
- 跳過(skipped)(是指讓解碼器復(fù)制前一幀內(nèi)的位于相同位置的宏塊——0運(yùn)動(dòng)向量)
?
?
我制作了一張插圖來說明其中的重點(diǎn)。上圖中顯示了I幀和P幀。如前面討論,P幀參考前面的I幀或者P幀。圖中,幀的編碼、解碼順序與它們呈現(xiàn)在用戶面前的順序一致。這是因?yàn)镻幀只參考前面的圖像來進(jìn)行編碼。
?
什么是B幀?
?
B幀可以參考在其前后出現(xiàn)的幀。B幀中的B就代表雙向(Bi-Directional)。如果你的視頻編解碼器使用基于宏塊的壓縮(如H.264/AVC所做的一樣),那么B幀中的每個(gè)宏塊都可以:
- 后向預(yù)測(cè)(使用未來的幀)
- 前向預(yù)測(cè)(使用過去的幀)
- 無幀間預(yù)測(cè),僅幀內(nèi)預(yù)測(cè)
- 完全跳過(幀內(nèi)或幀間預(yù)測(cè))
由于B幀可以參考和插入在它之前和之后發(fā)生的兩個(gè)(或更多)幀(在時(shí)間維度上),所以它可以顯著降低幀的大小,同時(shí)保持視頻質(zhì)量。B幀能夠利用空間冗余和時(shí)間冗余(未來的幀和過去的幀),這使得它在視頻壓縮中非常有用。
但是,B幀是資源密集型——無論是從編碼側(cè)還是解碼側(cè)看,讓我們來看看原因。
想要理解B幀的作用,我們需要先理解呈現(xiàn)/顯示順序和解碼順序的概念。
以I幀和P幀為例。如果你只使用這兩種類型的幀,那么每一幀要么參考自身(I 幀),要么參考前一幀(P 幀)。因此,幀可以以相同的順序進(jìn)出編碼器。這里,呈現(xiàn)順序(或顯示順序)與編碼、解碼順序相同。
?
?
但如果某一幀要參考未來顯示的一幀,你要怎么做呢?這是我們?cè)谑褂肂幀壓縮時(shí)經(jīng)常遇到的情況。下圖中顯示了一個(gè)GOP(group of pictures)結(jié)構(gòu),GOP是一組連續(xù)的畫面,在每一個(gè)mini-GOP中,都使用了兩個(gè)B幀和一個(gè)P幀,也就是IBBPBBP。
?
?
解碼器端也是如此操作。
按照解碼順序,解碼器先解碼幀1(I幀),然后是幀2(P幀)。但它卻無法顯示幀2,因?yàn)樵诮獯a順序中的實(shí)際上是幀4!所以,解碼器需要將幀2(按解碼順序)放入緩沖區(qū),然后等待顯示它的時(shí)機(jī)。
所以,編碼器和解碼器需要在內(nèi)存中維護(hù)兩個(gè)“順序”或“序列”:一個(gè)將幀放置在正確的顯示順序中,另一個(gè)用于將幀按照編碼和解碼所需順序放置。
由于重新排序的要求,B幀會(huì)影響解碼器緩沖區(qū)的大小,并增加延遲。
這就是為什么許多系統(tǒng)在壓縮一個(gè)B幀時(shí),對(duì)可用作參考的幀數(shù)做出嚴(yán)格的限制的原因。按照同樣的思路,H.264/AVC的Baseline profile因?yàn)槊闇?zhǔn)低端設(shè)備的,所以不允許使用B幀或Slice。
?
參考B幀和非參考B幀
?
我們?cè)谏衔闹袑W(xué)過,B幀可以參考兩幀或者多幀,通常,(根據(jù)其位置)一幀在前,一幀在后。我們也已知道,I幀不參考任何幀,P幀只參考前面的幀。那么問題來了——任何幀都能使用B幀作為它的參考幀嗎?
答案是肯定的。
- 如果B幀可以作為參考幀,它就被稱為參考B幀。
- 如果B幀不用作參考幀,它便被稱為非參考B幀。
在比特流中標(biāo)明參考B幀和非參考B幀非常重要,因?yàn)榻獯a器需要在DBP(Decoded Picture Buffer,解碼圖像緩存)中存儲(chǔ)參考幀。
如果某一幀被標(biāo)記為非參考B幀,但卻將其用作參考幀,那么解碼器很可能崩潰。因?yàn)榻獯a器大概率在解碼和顯示之后就已經(jīng)刪除此幀。
與非參考B幀相比,大部分解碼器在量化參考B幀時(shí)會(huì)獲得更好的質(zhì)量,從而減少傳播損失。
?
在視頻壓縮/流化中使用I、P和B幀
?
在理解了I幀、P幀和B幀的工作原理之后,我們來解決一個(gè)重要問題:為什么要使用它們?
在下面內(nèi)容中,我們會(huì)學(xué)習(xí)I幀、P幀和B幀在視頻壓縮中最重要的用例。
?
在哪里使用I幀?
?
我們?cè)谇懊娴牟糠至私獾?#xff0c;I幀可以被獨(dú)立地編碼、解碼,這使得它在視頻壓縮中得到廣泛應(yīng)用。
?
刷新視頻質(zhì)量
?
I幀的插入通常表示GOP(或視頻片段)的結(jié)束。I幀壓縮不依靠前一幀編碼,從而可以刷新視頻質(zhì)量。正因?yàn)镮幀在保持視頻質(zhì)量方面有如此重要的作用,所以通常情況下,編碼器會(huì)在大小和質(zhì)量方面偏向I幀。在編碼高質(zhì)量的I幀后,編碼器便可以使用該I幀作為參考圖像來壓縮P幀和B幀。
那I幀只能用于刷新視頻質(zhì)量嗎?不僅如此。
?
恢復(fù)比特流錯(cuò)誤
?
我們之前說過,I幀可以被獨(dú)立地編碼和解碼。這意味著I幀可用于恢復(fù)視頻文件或視頻流中的災(zāi)難性故障。
我們來看看是它是如何做到的。
如果P幀和參考B幀遭到破壞,其他所有依賴于它們的幀就不能完整解碼,這會(huì)直接導(dǎo)致視頻故障。視頻通常無法從此類問題中恢復(fù)。然而,當(dāng)被破壞的視頻流到達(dá)I幀,因?yàn)镮幀被獨(dú)立地編碼解碼,所以視頻問題可以從I幀恢復(fù)。
這種I幀通常被稱為IDR幀(Instantaneous Decoder Refresh,即時(shí)解碼刷新),并且這種不參考I幀之前圖像的行為被稱為閉合GOP(Closed GOP)。
IDR幀通常在ABR流中表示視頻的某個(gè)新片段。由IDR幀開始,平臺(tái)可以確保新片段能夠獨(dú)立于其他片段被解碼。即使由于傳輸問題導(dǎo)致一些片段損壞或丟失,這一特性也能保證視頻可以繼續(xù)播放。
?
Trick Modes(快進(jìn)快退)
?
最后,關(guān)鍵幀對(duì)于Trick Modes來說至關(guān)重要!
如果想在一個(gè)視頻中快進(jìn)快退,則在視頻開始時(shí)需要一個(gè)I幀,對(duì)吧?
假設(shè)你搜索到的是P幀或者B幀,但解碼器已經(jīng)從內(nèi)存中刪除了參考幀,你該怎么重建它們呢?視頻播放器很自然地會(huì)找到一個(gè)起始點(diǎn)(I幀)并成功解碼,然后從這一點(diǎn)開始播放。
這又引出另一個(gè)有趣的事情。
如果你的關(guān)鍵幀在視頻中相隔時(shí)間很長(zhǎng),假設(shè)它們之間間隔20秒,那么你的用戶只能以20秒為增量進(jìn)行快進(jìn)快退,這樣的體驗(yàn)非常糟糕!
如果關(guān)鍵幀放置太多,那么雖然快進(jìn)快退體驗(yàn)會(huì)很棒,但這時(shí)候視頻就太大了,可能導(dǎo)致網(wǎng)路緩沖等問題。
所以設(shè)計(jì)出最佳的GOP和mini-GOP結(jié)構(gòu)真的是一項(xiàng)平衡的藝術(shù)。
?
在哪里使用P幀和B幀?
?
人們經(jīng)常會(huì)問:在哪里、什么時(shí)候以及如何使用P幀和B幀?
如果你已經(jīng)理解上文中所描述的P幀和B幀的工作原理,那么你就知道P幀和B幀可以在減少視頻大小的同時(shí),保證視頻質(zhì)量。這就是它們的主要用途!在合適的位置插入P幀和B幀可以減小視頻文件尺寸或者比特率,并且仍能保持一定的視頻質(zhì)量水平。
基于你所使用的GOP和mini-GOP結(jié)構(gòu),使用相關(guān)QP值壓縮P幀和B幀(被參考或者不被參考),你就可以達(dá)到目標(biāo)比特率或視頻質(zhì)量。
?
?小 結(jié)
?
我希望這篇關(guān)于I幀、P幀和B幀的文章能夠幫助你增加關(guān)于視頻壓縮的知識(shí)。想要更深入地理解它們,你可以下載靜態(tài)編譯好的 FFmpeg 版本,并在 FFmpeg 中使用 GOP、no-b-frame 相關(guān)設(shè)置來查看視頻的大小及其質(zhì)量如何變化。
本文已獲得作者Krishna Rao Vijayanagar授權(quán)發(fā)布,特此感謝。
原文鏈接:https://ottverse.com/i-p-b-frames-idr-keyframes-differences-usecases/
掃描圖中二維碼了解大會(huì)更多信息
總結(jié)
以上是生活随笔為你收集整理的Easy Tech:什么是I帧、P帧和B帧?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大话ion系列(一)
- 下一篇: 基于线性预测的语音编码原理解析