H.264 編碼中, I 幀、B 幀、P 幀、IDR 幀的區別

H.264簡介


H.264是新一代的編碼標準,以高壓縮高質量和支持多種網絡的流媒體傳輸著稱。算法

在H.264協議裏定義了三種幀,完整編碼的幀叫 I 幀,參考以前的 I 幀生成的只包含差別部分編碼的幀叫 P 幀,還有一種參考先後的幀編碼的幀叫 B 幀。緩存


H.264採用的核心算法是幀內壓縮和幀間壓縮,幀內壓縮是生成 I 幀的算法,幀間壓縮是生成 B 幀和 P 幀的算法。
微信


序列的說明


在H.264中圖像以序列爲單位進行組織,一個序列是一段圖像編碼後的數據流,以 I 幀開始,到下一個 I 幀結束。
網絡


一個序列的第一個圖像叫作 IDR 圖像(當即刷新圖像),IDR 圖像都是 I 幀圖像。app


H.264 引入 IDR 圖像是爲了解碼的重同步,當解碼器解碼到 IDR 圖像時,當即將參考幀隊列清空,將已解碼的數據所有輸出或拋棄,從新查找參數集,開始一個新的序列編輯器


這樣,若是前一個序列出現重大錯誤,在這裏能夠得到從新同步的機會。IDR 圖像以後的圖像永遠不會使用 IDR 以前的圖像的數據來解碼。性能


一個序列就是一段內容差別不太大的圖像編碼後生成的一串數據流。
學習


當運動變化比較少時,一個序列能夠很長,由於運動變化少就表明圖像畫面的內容變更很小,因此就能夠編一個 I 幀,而後一直 P 幀、B 幀了。測試


當運動變化多時,可能一個序列就比較短了,好比就包含一個 I 幀和 三、4個P幀。
flex


3 種幀的說明


I幀

I 幀:幀內編碼幀 ,I 幀表示關鍵幀,你能夠理解爲這一幀畫面的完整保留;解碼時只須要本幀數據就能夠完成(由於包含完整畫面)。


P幀 

P 幀:前向預測編碼幀。P 幀表示的是這一幀跟以前的一個關鍵幀(或P 幀)的差異,解碼時須要用以前緩存的畫面疊加上本幀定義的差異,生成最終畫面。


P幀的預測與重構:P 幀是以 I 幀爲參考幀,在 I 幀中找出 P 幀「某點」的預測值和運動矢量,取預測差值和運動矢量一塊兒傳送。


在接收端根據運動矢量從 I 幀中找出 P 幀「某點」的預測值並與差值相加以獲得 P 幀「某點」樣值,從而可獲得完整的 P 幀。


B幀

B 幀:雙向預測內插編碼幀。B 幀是雙向差異幀,也就是 B 幀記錄的是本幀與先後幀的差異(具體比較複雜,有 4 種狀況,但我這樣說簡單些)。


換言之,要解碼 B 幀,不只要取得以前的緩存畫面,還要解碼以後的畫面,經過先後畫面的與本幀數據的疊加取得最終的畫面。B 幀壓縮率高,可是解碼時 CPU 會比較累。


B 幀的預測與重構:B 幀之前面的 I 或 P 幀和後面的 P 幀爲參考幀,「找出」B 幀「某點」的預測值和兩個運動矢量,並取預測差值和運動矢量傳送


接收端根據運動矢量在兩個參考幀中「找出(算出)」預測值並與差值求和,獲得 B幀「某點」樣值,從而可獲得完整的 B 幀。


注:I、B、P 各幀是根據壓縮算法的須要,是人爲定義的,它們都是實實在在的物理幀。通常來講,I 幀的壓縮率是7(跟JPG差很少),P 幀是20,B 幀能夠達到50。


可見使用 B 幀能節省大量空間,節省出來的空間能夠用來保存多一些 I 幀,這樣在相同碼率下,能夠提供更好的畫質。


下面舉例說明:




在如上圖中,GOP (Group of Pictures) 長度爲 13,S0~S7 表示 8 個視點,T0~T12 爲 GOP 的 13 個時刻。每一個 GOP 包含幀數爲視點數 GOP 長度的乘積。在該圖中一個 GOP 中,包含 94 個 B 幀。B 幀佔一個 GOP 總幀數的 90.38%。


GOP 越長,B 幀所佔比例更高,編碼的率失真性能越高。下圖測試序列 Race1 在不一樣 GOP 下的率失真性能對比。




壓縮算法的說明


h264的壓縮方法:
(1)分組:把幾幀圖像分爲一組(GOP,也就是一個序列),爲防止運動變化,幀數不宜取多。
(2)定義幀:將每組內各幀圖像定義爲三種類型,即 I 幀、B 幀和 P 幀;
(3)預測幀:以I幀作爲基礎幀,以 I 幀預測 P 幀,再由 I 幀和 P 幀預測 B 幀;
(4)數據傳輸:最後將 I 幀數據與預測的差值信息進行存儲和傳輸。


幀內(Intraframe)壓縮也稱爲空間壓縮(Spatial compression)當壓縮一幀圖像時,僅考慮本幀的數據而不考慮相鄰幀之間的冗餘信息,這實際上與靜態圖像壓縮相似。幀內通常採用有損壓縮算法,因爲幀內壓縮是編碼一個完整的圖像,因此能夠獨立的解碼、顯示。幀內壓縮通常達不到很高的壓縮,跟編碼 jpeg 差很少。

  
幀間(Interframe)壓縮的原理是:相鄰幾幀的數據有很大的相關性,或者說先後兩幀信息變化很小的特色。也即連續的視頻其相鄰幀之間具備冗餘信息,根據這一特性,壓縮相鄰幀之間的冗餘量就能夠進一步提升壓縮量,減少壓縮比。幀間壓縮也稱爲時間壓縮(Temporal compression),它經過比較時間軸上不一樣幀之間的數據進行壓縮。


幀間壓縮通常是無損的。幀差值(Frame differencing)算法是一種典型的時間壓縮法,它經過比較本幀與相鄰幀之間的差別,僅記錄本幀與其相鄰幀的差值,這樣能夠大大減小數據量。


I 幀與 IDR 幀的區別


IDR(Instantaneous Decoding Refresh)--即時解碼刷新。


I 和 IDR 幀都是使用幀內預測的。它們都是同一個東西而已,在編碼和解碼中爲了方便,要首個 I 幀和其餘 I 幀區別開,因此才把第一個首個 I 幀叫 IDR,這樣就方便控制編碼和解碼流程。


IDR 幀的做用是馬上刷新,使錯誤不致傳播,從IDR幀開始,從新算一個新的序列開始編碼。而 I 幀不具備隨機訪問的能力,這個功能是由 IDR 承擔。IDR 會致使DPB(參考幀列表——這是關鍵所在)清空,而 I 不會。


IDR 圖像必定是 I 圖像,但I圖像不必定是 IDR 圖像。一個序列中能夠有不少的I圖像,I 圖像以後的圖像能夠引用 I 圖像之間的圖像作運動參考。


一個序列中能夠有不少的 I 圖像,I 圖像以後的圖象能夠引用I圖像之間的圖像作運動參考。


對於 IDR 幀來講,在 IDR 幀以後的全部幀都不能引用任何 IDR 幀以前的幀的內容,與此相反,對於普通的 I 幀來講,位於其以後的 B- 和 P- 幀能夠引用位於普通 I- 幀以前的 I- 幀。


從隨機存取的視頻流中,播放器永遠能夠從一個 IDR 幀播放,由於在它以後沒有任何幀引用以前的幀。可是,不能在一個沒有 IDR 幀的視頻中從任意點開始播放,由於後面的幀老是會引用前面的幀。

舉個例子,在一段視頻中,存在如下幀:I P B P B P B B PP B…

若是這段視頻應用了多重參照幀,那麼藍色的 P 幀在參照他前面的 I 幀(紅色)的同時,還可能會參照 I 幀以前的 P (綠色),因爲 I 幀先後的場景可能會有很大的反差甚至根本不一樣。


因此此時 P 幀參考I幀以前的幀不但會沒有意義,反而會形成不少問題。因此一種新型的幀被引入,那就是 IDR 幀。


若是這段視頻應用了多重參考幀的同時採用了 IDR 幀,那麼幀的順序就會變成這樣:I P B P B P B B P IDR P B…


因爲 IDR 幀禁止後面的幀向本身前面的幀參照,因此這回那個藍色的 P 幀就不會參照綠色的 P 幀了。


文章來源:https://blog.csdn.net/qq_29350001/article/details/73770702

做者:聚優致成


-- END --


進技術交流羣,掃碼添加個人微信:Byte-Flow



獲取視頻教程和源碼



推薦:

Android OpenGL 渲染圖像讀取哪家強?

字節流動 OpenGL ES 技術交流羣來啦

FFmpeg + OpenGL ES 實現 3D 全景播放器

FFmpeg + OpenGLES 實現視頻解碼播放和視頻濾鏡

一文掌握 YUV 圖像的基本處理

Android OpenGL ES 從入門到精通系統性學習教程

OpenGL ES 實現動態(水波紋)漣漪效果


以爲不錯,點個在看唄~


本文分享自微信公衆號 - 字節流動(google_developer)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索