H.264的句法和語義 H.264 的句法和語義
在編碼器輸出的碼流中,數(shù)據(jù)的基本單位是句法元素,每個句法元素由若干比特組成,它表示某個特定的物理意義,例如:宏塊類型、量化參數(shù)等。句法表征句法元素的組織結(jié)構(gòu),語義闡述句法元素的具體含義。所有的視頻編碼標(biāo)準(zhǔn)都是通過定義句法和語義來規(guī)范編解碼器的工作流程。
句法元素的分層結(jié)構(gòu)
編碼器輸出的比特碼流中,每個比特都隸屬某個句法元素,也就是說,碼流是由一個個句法元素依次銜接組成的,碼流中除了句法元素并不存在專門用于控制或同步的內(nèi)容。在H.264 定義的碼流中,句法元素被組織成有層次的結(jié)構(gòu),分別描述各個層次的信息。
句法元素的分層結(jié)構(gòu)有助于更有效地節(jié)省碼流。例如,在一個圖像中,經(jīng)常會在各個片之間有
相同的數(shù)據(jù),如果每個片都同時(shí)攜帶這些數(shù)據(jù),勢必會造成碼流的浪費(fèi)。更為有效的做法是將該圖
像的公共信息抽取出來,形成圖像一級的句法元素,而在片級只攜帶該片自身獨(dú)有的句法元素。在
H.264 中,句法元素共被組織成 序列、圖像、片、宏塊、子宏塊五個層次。
H.264 的分層結(jié)構(gòu)是經(jīng)過精心設(shè)計(jì)的,與以往的視頻編碼標(biāo)準(zhǔn)相比有很大的改進(jìn),這些改進(jìn)主
要針對傳輸中的錯誤掩藏,在有誤碼發(fā)生時(shí)可以提高圖像重建的性能。在以往的標(biāo)準(zhǔn)中,分層的組
織結(jié)構(gòu)如圖7.2,它們?nèi)缤琓CP/IP 協(xié)議的結(jié)構(gòu),每一層都有頭部,然后在每層的數(shù)據(jù)部分包含該層
的數(shù)據(jù)。
在這樣的結(jié)構(gòu)中,每一層的頭部和它的數(shù)據(jù)部分形成管理與被管理的強(qiáng)依賴關(guān)系,頭部的句法
元素是該層數(shù)據(jù)的核心,而一旦頭部丟失,數(shù)據(jù)部分的信息幾乎不可能再被正確解碼出來。尤其在
序列層及圖像層,由于網(wǎng)絡(luò)中MTU(最大傳輸單元)大小的限制,不可能將整個層的句法元素全部
放入同一個分組中,這個時(shí)候如果頭部所在的分組丟失,該層其他分組即使能被正確接收也無法解
碼,造成資源浪費(fèi)。(應(yīng)該可以這樣理解,也就是說,一個圖像層作為一個單元被交付給IP層,但是被分割成了幾個分組,如果圖像層的頭部信息的分組丟失,那么這個圖像層的所有片都無法被解碼)
H.264 中,分層結(jié)構(gòu)最大的不同是取消了序列層和圖像層,并將原本屬于序列和圖像頭部的
大部分句法元素游離出來形成序列和圖像兩級參數(shù)集,其余的部分則放入片層。參數(shù)集是一個獨(dú)立
的數(shù)據(jù)單位,不依賴于參數(shù)集外的其他句法元素。圖7.3 描述了參數(shù)集與參數(shù)集外句法元素的關(guān)系,
在圖中我們可以看到,參數(shù)集只是在片層句法元素需要的時(shí)候被引用,而且,一個參數(shù)集并不對應(yīng)
某個特定的圖像或序列,同一個序列參數(shù)集可以被多個序列中的圖像參數(shù)集引用,同理,同一個圖
像參數(shù)集也可以被多個圖像引用。只在編碼器認(rèn)為需要更新參數(shù)集的內(nèi)容時(shí),才會發(fā)送出新的參數(shù)
集。在這種機(jī)制下,由于參數(shù)集是獨(dú)立的,可以被多次重發(fā)或者采用特殊技術(shù)加以保護(hù)。
在圖7.3 的描述中,參數(shù)集與參數(shù)集外部的句法元素處于不同信道中,這是H.264 的一個建議,
我們可以使用更安全但成本更昂貴的通道來傳輸參數(shù)集,而使用成本低但不夠可靠的信道傳輸其他
句法元素,只需要保證片層中的某個句法元素需要引用某個參數(shù)集時(shí),那個參數(shù)集已經(jīng)到達(dá)解碼器,
也就是參數(shù)集在時(shí)間上必須先被傳送。當(dāng)然,在條件不允許的情況下,我們也可以采用妥協(xié)的辦法:
在同一個物理信道中傳輸所有的句法元素,但專門為參數(shù)集采用安全可靠的通信協(xié)議,如TCP。當(dāng)
然,H.264 也允許我們?yōu)榘▍?shù)集在內(nèi)的所有句法元素指定同樣的通信協(xié)議,但這時(shí)所有參數(shù)集
必須被多次重發(fā),以保證解碼器最終至少能接收到一個。在參數(shù)集和片使用同個物理信道的情況下,
圖7.3 中的信道1 和信道2 應(yīng)該被理解為邏輯上的信道,因?yàn)閺倪壿嬌峡?,參?shù)集與其它句法元素
還是處于各自彼此獨(dú)立的信道中。
H.264 在片層增加了新的句法元素指明所引用的參數(shù)集的編號,同時(shí)因?yàn)槿∠藞D像層,片成
為了信道2 中最上層的獨(dú)立的數(shù)據(jù)單位,每個片必須自己攜帶關(guān)于所屬圖像的編號、大小等基本信
息,這些信息在同一圖像的每個片中都必須是一致的。在編碼時(shí),H.264 的規(guī)范要求將參數(shù)集、片
這些獨(dú)立的數(shù)據(jù)單位盡可能各自完整地放入一個分組中被傳送。
從表面上看來,H.264 關(guān)于參數(shù)集和片層的結(jié)構(gòu)增加了編碼后數(shù)據(jù)的冗余度(比如參數(shù)集必須
多次重發(fā),又如每個片都必須攜帶一部分相同的關(guān)于整個圖像的信息,而這些數(shù)據(jù)完全是重復(fù)的),
降低了編碼效率,但這些技術(shù)的采用使得通信的魯棒性大大增強(qiáng),當(dāng)數(shù)據(jù)傳輸中出現(xiàn)丟包,能夠?qū)?div style="height:15px;">
使錯誤限制在最小范圍,防止錯誤的擴(kuò)散,解碼后對錯誤的掩藏和恢復(fù)也能起到很好的作用。 一個
片的丟失將不會影響其它片的解碼,還可以通過該片前后的片來恢復(fù)該片的數(shù)據(jù)。
H.264 片層以下的句法元素的結(jié)構(gòu)大體上和以往標(biāo)準(zhǔn)類似,但在相當(dāng)多的細(xì)節(jié)上有所改進(jìn),所
有的改進(jìn)的目的不外乎兩個:在錯誤發(fā)生時(shí)防止錯誤擴(kuò)散、減少冗余信息提高編碼效率。這兩者往
往是矛盾的,H.264 在這兩者上的取舍顯得頗具匠心。
圖7.3 所示的碼流的結(jié)構(gòu)是一種簡化的模型,這個模型已經(jīng)能夠正確工作,但還不夠完善,不
適合復(fù)雜的場合。在復(fù)雜的通信環(huán)境中,除了片和參數(shù)集外還需要其他的數(shù)據(jù)單位來提供額外的信
息。圖7.4 描述了在復(fù)雜通信中的碼流中可能出現(xiàn)的數(shù)據(jù)單位。如前文所述,參數(shù)集可以被抽取出
來使用其它信道。
(更正:看來一個片不適合作為一個分組,可能太小了。應(yīng)該是以這里的數(shù)據(jù)單元為一個分組的?)
在圖7.4 中我們看到,一個序列的第一個圖像叫做IDR 圖像(立即刷新圖像),IDR 圖像都是I
圖像。H.264 引入IDR 圖像是為了解碼的重同步,當(dāng)解碼器解碼到IDR 圖像時(shí),立即將參考幀隊(duì)列
清空,將已解碼的數(shù)據(jù)全部輸出或拋棄,重新查找參數(shù)集,開始一個新的序列。這樣,如果在前一
個序列的傳輸中發(fā)生重大錯誤,如嚴(yán)重的丟包,或其他原因引起數(shù)據(jù)錯位,在這里可以獲得重新同
步。IDR 圖像之后的圖像永遠(yuǎn)不會引用IDR 圖像之前的圖像的數(shù)據(jù)來解碼。
要注意IDR 圖像和I 圖像的區(qū)別,IDR 圖像一定是I 圖像,但I(xiàn) 圖像不一定是IDR 圖像。一個
序列中可以有很多的I 圖像,I 圖像之后的圖像可以引用I 圖像之間的圖像做運(yùn)動參考。
在圖7.4 中,除了參數(shù)集與片外還有其它的數(shù)據(jù)單位,這些數(shù)據(jù)單位可以提供額外的數(shù)據(jù)或同
步信息,這些數(shù)據(jù)單位也是一系列句法元素的集合。它們在解碼過程中不是必需的,但卻可以適當(dāng)
提高同步性能或定義圖像的復(fù)雜特征。
插入:關(guān)于I,P片的概念
宏塊、片
一個編碼圖像通常劃分成若干宏塊組成,一個宏塊由一個16×16 亮度像素和附加的一個8×8 Cb和一個8×8 Cr 彩色像素塊組成。每個圖象中,若干宏塊被排列成片的形式。
I 片只包含I 宏塊,P 片可包含P 和I 宏塊,而B 片可包含B 和I 宏塊。
I 宏塊利用從當(dāng)前片中已解碼的像素作為參考進(jìn)行幀內(nèi)預(yù)測(不能取其它片中的已解碼像素作為參考進(jìn)行幀內(nèi)預(yù)測)。
P 宏塊利用前面已編碼圖象作為參考圖象進(jìn)行幀內(nèi)預(yù)測,一個幀內(nèi)編碼的宏塊可進(jìn)一步作宏塊的分割:即16×16、16×8、8×16 或8×8 亮度像素塊(以及附帶的彩色像素);如果選了8×8 的子宏塊,則可再分成各種子宏塊的分割,其尺寸為8×8、8×4、4×8 或4×4 亮度像素塊(以及附帶的彩色像素)。
B 宏塊則利用雙向的參考圖象(當(dāng)前和未來的已編碼圖象幀)進(jìn)行幀內(nèi)預(yù)測。
檔次和級
H.264 規(guī)定了三種檔次,每個檔次支持一組特定的編碼功能,并支持一類特定的應(yīng)用。
1)基本檔次:利用I 片和P 片支持幀內(nèi)和幀間編碼,支持利用基于上下文的自適應(yīng)的變長編碼
進(jìn)行的熵編碼(CAVLC)。主要用于可視電話、會議電視、無線通信等實(shí)時(shí)視頻通信;
2)主要檔次:支持隔行視頻,采用B 片的幀間編碼和采用加權(quán)預(yù)測的幀內(nèi)編碼;支持利用基于
上下文的自適應(yīng)的算術(shù)編碼(CABAC)。主要用于數(shù)字廣播電視與數(shù)字視頻存儲;
3)擴(kuò)展檔次:支持碼流之間有效的切換(SP 和SI 片)、改進(jìn)誤碼性能(數(shù)據(jù)分割),但不支持
隔行視頻和CABAC。
以下是解碼時(shí)的知識,現(xiàn)在先不用考慮。
句法的表示方法
句法元素與變量
編碼器將數(shù)據(jù)編碼為句法元素然后依次發(fā)送。在解碼器端,通常要將句法元素作求值計(jì)算,得
出一些中間數(shù)據(jù),這些中間數(shù)據(jù)就是H.264 定義的變量。如圖7.5:
圖7.5 從句法元素解出變量
圖中,pic_width_in_mbs_minus1 是解碼器直接從碼流中提取的句法元素,這個句法元素表征圖
像的寬度,以宏塊為單位。我們看到,為了提高編碼效率,H.264 將圖像實(shí)際的寬度減去1 后再傳
送。
PicWidthInMbs = pic_width_in_mbs_minus1 + 1
PicWidthInSamplesL = PicWidthInMbs * 16
PicWidthInSamplesC = PicWidthInMbs * 8
以上變量PicWidthInMbs 表示圖像以宏塊為單位的寬, 變量PicWidthInSamplesL 、
PicWidthInSamplesC 分別表示圖像的亮度、色度分量以像素為單位的寬。H.264 定義這些變量是因
為在后續(xù)句法元素的提取算法或圖像的重建中需要用到它們的值。在H.264 中,句法元素的名稱是
由小寫字母和一系列的下劃線組成,而變量名稱是大小寫字母組成,中間沒有下劃線。(根據(jù)句法元素可以求解句法變量)
句法
...
語義
NAL層語義
在網(wǎng)絡(luò)傳輸?shù)沫h(huán)境下,編碼器將每個NAL 各自獨(dú)立、完整地放入一個分組,由于分組都有頭部,
解碼器可以很方便地檢測出NAL 的分界,依次取出NAL 進(jìn)行解碼。為了節(jié)省碼流,H.264 沒有另
外在NAL 的頭部設(shè)立表示起始的句法元素,我們從表7.1 可以看到這點(diǎn)。但是如果編碼數(shù)據(jù)是儲存
在介質(zhì)(如DVD 光盤)上,由于NAL 是依次緊密排列,解碼器將無法在數(shù)據(jù)流中分辨每個NAL
的起始和終止,所以必須要有另外的機(jī)制來解決這個問題。
針對這個問題,H.264 草案的附錄B 中指明了一種簡單又高效的方案。當(dāng)數(shù)據(jù)流是存儲在介質(zhì)
上時(shí),在每個NAL 前添加起始碼:
0x000001
在某些類型的介質(zhì)上,為了尋址的方便,要求數(shù)據(jù)流在長度上對齊,或必須是某個常數(shù)的倍數(shù)。考
慮到這種情況,H.264 建議在起始碼前添加若干字節(jié)的0 來填充,直到該NAL 的長度符合要求。
在這樣的機(jī)制下,解碼器在碼流中檢測起始碼,作為一個NAL 的起始標(biāo)識,當(dāng)檢測到下一個
起始碼時(shí)當(dāng)前NAL 結(jié)束。H.264 規(guī)定當(dāng)檢測到0x000000 時(shí)也可以表征當(dāng)前NAL 的結(jié)束,這是因?yàn)?div style="height:15px;">