1. 程式人生 > >H.264中I幀、B幀、P幀、NALU型別,塊,巨集塊,片,影象的關係

H.264中I幀、B幀、P幀、NALU型別,塊,巨集塊,片,影象的關係

參考:http://blog.csdn.net/ivy_reny/article/details/47144121

http://blog.csdn.net/wanggp_2007/article/details/4842839

http://blog.sina.com.cn/s/blog_4ad7c2540101me90.html

 

塊==》巨集塊(MB)==》片(Slice)==》片組==》影象(picture)

 

1.巨集塊(Macro Block):是H.264編碼的基本單位,一個編碼影象首先要劃分成多個塊(4x4 畫素)才能進行處理,顯然巨集塊應該是整數個塊組成,通常巨集塊大小為16x16個畫素。

巨集塊分為I、P、B巨集塊:

I巨集塊只能利用當前片中已解碼的畫素作為參考進行幀內預測;

P巨集塊可以利用前面已解碼的影象作為參考影象進行幀內預測;

B巨集塊則是利用前後向的參考圖形進行幀內預測

 

2.(Slice):一幀視訊影象可編碼成一個或者多個片,每片包含整數個巨集塊,即每片至少一個巨集塊,最多時包含整個影象的巨集塊。

     片的目的:為了限制誤碼的擴散和傳輸,使編碼片相互間保持獨立。

片共有5種類型:I片(只包含I巨集塊)、P片(P和I巨集塊)、B片(B和I巨集塊)、SP片(用於不同編碼流之間的切換)和SI片(特殊型別的編碼巨集塊)。

以下是片的句法結構:片頭規定了片的型別、屬於哪個影象、有關的參考影象等;片的資料包含了一系列巨集塊和不編碼資料。

 

3.片組,是一個編碼影象中若干巨集塊的一個子集,包含一個或若干個片。

一般一個片組中,每片的巨集塊是按掃描次序進行編碼的,除非使用任意片次序(Arbitrary Slice Order, ASO)一個編碼幀中的片之後可以跟隨任一解碼影象的片。

4.序列

參照一段時間內影象的統計結果表明,在相鄰幾幅影象畫面中,一般有差別的畫素只有10%以內的點,亮度差值變化不超過2%,而色度差值的變化只有1%以內。所以對於一段變化不大影象畫面,我們可以先編碼出一個完整的影象幀A,隨後的B幀就不編碼全部影象,只寫入與A幀的差別,這樣B幀的大小就只有完整幀的1/10或更小!B幀之後的C幀如果變化不大,我們可以繼續以參考B的方式編碼C幀,這樣迴圈下去。這段影象我們稱為一個序列(序列就是有相同特點的一段資料

),當某個影象與之前的影象變化很大,無法參考前面的幀來生成,那我們就結束上一個序列,開始下一段序列,也就是對這個影象生成一個完整幀A1,隨後的影象就參考A1生成,只寫入與A1的差別內容
    在H264協議裡定義了三種幀,完整編碼的幀叫I幀,參考之前的I幀生成的只包含差異部分編碼的幀叫P幀,還有一種參考前後的幀編碼的幀叫B幀。
   H264採用的核心演算法是幀內壓縮和幀間壓縮,幀內壓縮是生成I幀的演算法,幀間壓縮是生成B幀和P幀的演算法

在H264中影象以序列為單位進行組織,一個序列是一段影象編碼後的資料流, 以I幀開始,到下一個I幀結束。

一個序列的第一個影象叫做 IDR 影象(立即重新整理影象),IDR 影象都是 I 幀影象。H.264 引入 IDR 影象是為了解碼的重同步,當解碼器解碼到 IDR 影象時,立即將參考幀佇列清空,將已解碼的資料全部輸出或拋棄,重新查詢引數集,開始一個新的序列。這樣,如果前一個序列出現重大錯誤,在這裡可以獲得重新同步的機會。IDR影象之後的影象永遠不會使用IDR之前的影象的資料來解碼。
    一個序列就是一段內容差異不太大的影象編碼後生成的一串資料流。當運動變化比較少時,一個序列可以很長,因為運動變化少就代表影象畫面的內容變動很小,所以就可以編一個I幀,然後一直P幀、B幀了。當運動變化多時,可能一個序列就比較短了,比如就包含一個I幀和3、4個P幀。

壓縮演算法的說明
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)演算法是一種典型的時間壓縮法,它通過比較本幀與相鄰幀之間的差異,僅記錄本幀與其相鄰幀的差值,這樣可以大大減少資料量。
       順便說下有損(Lossy )壓縮和無損(Lossy less)壓縮。無失真壓縮也即壓縮前和解壓縮後的資料完全一致。多數的無失真壓縮都採用RLE行程編碼演算法。有失真壓縮意味著解壓縮後的資料與壓縮前的資料不一致。在壓縮的過程中要丟失一些人眼和人耳所不敏感的影象或音訊資訊,而且丟失的資訊不可恢復。幾乎所有高壓縮的演算法都採用有失真壓縮,這樣才能達到低資料率的目標。丟失的資料率與壓縮比有關,壓縮比越小,丟失的資料越多,解壓縮後的效果一般越差。此外,某些有失真壓縮演算法採用多次重複壓縮的方式,這樣還會引起額外的資料丟失。

===================================================================================================

i幀 i frame,即內部畫面 intra picture,通常是GOP的第一個幀(即IDR)
I幀是最大去除影象空間冗餘資訊而壓縮得到的幀,自帶全部資訊,不參考其他幀可獨立解碼,稱為幀內編碼幀
所有視訊至少包含一個I幀,且作為檔案的第一個幀,檔案裡的其他的I幀用來改善視訊質量,但增加了檔案大小
一般而言,每秒視訊至少需要1個I幀,每秒裡增加I幀可以改善質量,但增加網路頻寬和網路負載
視訊播放過程中,若I幀丟失,則隨後的P幀也就無法解析,所以出現黑屏現象,若P幀丟失,則出現花屏、馬賽克現象

P幀,前向搜尋幀/前向預測幀,以I幀預測P幀

B幀,雙向搜尋幀/雙向內插幀,由I幀、P幀預測B幀


P幀壓縮:根據本幀與相鄰的前一幀(I幀或P幀)的不同點來壓縮本幀資料
P幀重構:以前面相鄰I幀為參考幀,計算P幀某點的預測值和運動向量得到P幀某點樣值
B幀壓縮:根據本幀與相鄰的前一幀的差值、本幀與相鄰的後一幀的差值來壓縮本幀資料
B幀重構:以相鄰的前面相鄰幀(I或P)、後面相鄰幀(P)為參考,找出B幀某點的預測值和兩個運動向量得到B幀某點樣值

I幀編碼減少空間域冗餘,P、B幀編碼減少時間域冗餘

NTSC = national television system committee 應用於美國、日本、加拿大、墨西哥等
PAL  = phase alternating line 應用於中國、香港、中東、歐洲
GOP  = group of pictures  其最大可含幀數量 18(NTSC)/15(PAL)
GOP是有固定模式的一系列I、P、B幀組成
常用結構由15幀(PAL)組成,具有以下形式IBBPBBPBBPBBPBB,簡稱GOP(4,2),指的是該影象組除了1個I幀外,包含4個P幀,且
任何相鄰I、P之間或相鄰P、P之間存在2個B幀

IDR  = instantaneous decoding refresh 即時解碼重新整理  IDR一定是I幀,但I幀不一定是IDR
為了區分幀序列的首個I幀和其他I幀,才定義首個I幀為IDR,解碼器只可以從IDR開始解碼,IDR表示一組新的幀序列GOP
在IDR幀之後的所有幀都不能引用該IDR之前的幀資料,在普通I幀之後的B、P幀可以引用該普通I幀之前的I幀
ID會導致DPB(decord picture buff 參考幀列表)清空,導致PPS、SPS引數更新

 

H264從結構上分為 視訊編碼層VCL(video coding layer)和網路抽象層NAL(network abstract layer)

VCL包括codec編解碼功能(基於巨集塊模型)、運動補償預測處理、迴圈過濾器處理

NAL把VCL的輸出封裝成NALU(網路抽象層單元),以適應基於包的網路傳輸或面向包的多路複用環境

 

NALU的第1個位元組是NUAL型別位元組,其格式如下

|0 |1 |2 |3 |4 |5 |6 |7 |

|F |NRI|Type              |

F:       1 bit  forbidden_zero_bit H.264規範宣告值設定為1表示語法違例

NRI:  2 bit  nal_ref_idc 表示NALU的優先順序。0--3,取值越大,該NALU越重要,需要優先保護

                                      00值表示該NALU不用於幀間影象預測重構參考影象,可以丟棄不用冒參考影象完整性風險。

                                      如果NALU是參考幀slice、PPS、SPS時,該值必須大於0

Type: 5 bit  nal_unit_type 表示NALU載荷型別,型別值定義如下

                                         0:未定義

                                         1:非IDR影象不採用資料劃分片段

                                         2:非IDR影象採用資料劃分片段A部分

                                         3:非IDR影象採用資料劃分片段B部分

                                         4:非IDR影象採用資料劃分片段C部分

                                         5:IDR影象片段

                                         6:補充增強資訊 SEI

                                         7:序列引數集 SPS

                                         8:影象引數集 PPS

                                         9:分隔符

                                         10:序列結束符

                                         11:流結束符

                                         12:填充資料

                                         13:序列引數集擴充套件

                                         14:帶字首的NALU

                                         15:子序列引數集

                                         16-18:保留

                                         19:不採用資料劃分的輔助編碼影象片段

                                         20:編碼片段擴充套件

                                         21-23:保留

                                         24-31:未定義

h264資料幀的NALU前面帶有 00 00 00 01或 00 00 01 分隔符,一般VCL輸出首幀資料為PPS、SPS,接著是IDR幀

00 00 00 01 67 SPS 00 00 00 01 68 PPS 00 00 00 01 65 IDR ... ...

分隔符作為NALU的開始邊界和結束邊界,解碼器使用分隔符逐個位元組匹配資料流,計算NALU的長度,然後開始解碼

 

h264 序列、幀、slice關係

從大到小依次為:序列、幀(I、P、B幀)、片組、片(I、P、B、SP、SI片)、NALU、巨集塊、亞巨集塊、塊、畫素

 

序列

影象以序列為單位進行組織,GOP,序列就是一段連續影象幀且畫面之間變化不大。

統計一段時間內影象的結果表明,相鄰幾幅影象,一般畫素存在差別的點只有10%以內,亮度差值變化不超過2%,

色度差值變化只有1%以內。所以一段連續的影象畫面之間變化不大,可以把第1幀編碼為完整影象幀,第2幀只編

碼其與前面一幀的差別,這樣第2幀只是前一幀的1/10或更小,依次對第2幀之後的影象幀做同樣處理,這樣的一段

影象就是一個序列。當某個幀與前面的幀影象變化很大,無法參考前面幀生成時,就要開始一個新序列。

 

幀      :有1個或多個片組,如果不採用FMO(靈活巨集塊排序)機制,則一幀只有一個片組

片組  :包含1個片(slice)或多個片

片      :slice,由巨集塊組成,如果不採用DP(資料分割)機制,1個片只包含1個NALU,

               否則1個片由3個NALU組成,nal_unit_type值等於2、3、4的NALU屬於同一個片

               分片的目的是限制誤碼的擴撒和傳輸,使片間保持獨立,[ [slice header] [slice data] ]

               [slice header] 說明了片型別、屬於哪個幀、參考幀等

               [slice data] 裡是整數個巨集塊

巨集塊   :編碼處理的基本單元,由多個塊組成,通常巨集塊大小為16X16畫素,分為I、B、P巨集塊

塊       :一個編碼影象要劃分成多個塊才能進行處理,一個塊是4X4畫素

影象解碼過程是按照slice進行解碼,然後按照片組將解碼巨集塊重組成影象