一、H264 概述
H.264,通常也被稱之為H.264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC)
1. H.264視頻編解碼的意義
H.264的出現就是為了創建比以前的視頻壓縮標准更高效的壓縮標准,使用更好高效的視頻壓縮算法來壓縮視頻的占用空間,提高存儲和傳輸的效率,在獲得有效的壓縮效果的同時,使得壓縮過程引起的失真最小。MPEG-4 AVC和H.264 是目前較為主流的編碼標准。主要定義了兩方面的內容:視頻數據壓縮形式的編碼表示和用重建視頻信息的語法來描述編碼方法。目的是為了保證兼容的編碼器能夠成功的交互工作,同時也允許制造廠商自由的開發具有競爭力的創新產品。制造廠商只需要注意的事情就是能夠獲得和標准中采用的方法同樣的結果。
2. H.264編解碼的理論依據
提到H.264編解碼,我們先簡單說一下視頻壓縮算法。視頻壓縮算法是通過去除時間、空間的冗余來實現的。在一段時間內,相鄰的圖像的像素、亮度與色溫的差別很小,我們沒比要對每一個圖像進行完成的編碼,而是可以選取這段時間的第一張圖(也就是第一幀)作為完整的編碼,而后面一段時間的圖像只需要記錄與第一張圖(第一幀)在像素、亮度、色溫等方面的差別數據即可。通過去除不同類型的冗余,可以明顯的壓縮數據,代價就是一部分信息失真。
H.264編解碼在整個視頻數據處理過程中,屬於視頻數據處理的編解碼層,具體的可以查看本人總結的編解碼流程圖中的解碼部分:Thinking-in-AV/音視頻編解碼/音視頻解碼流程概覽.png。編碼部分將流程反過來進行理解即可。
二、H.264相關概念
1. H.264 的基本單位
在H.264定義的結構中,一個視頻圖像編碼后的數據叫做一幀。 一幀是由一個或多個片(slice)組成的,一個片是由一個或多個宏塊(MB)組成的(宏塊是H264編碼的基本單位),一個宏塊是由16x16的yuv數據組成的。
2. 幀類型
在H.264的協議中,定義了三類幀,分別是I幀、B幀和P幀。其中I幀就是之前我們所說的一個完整的圖像幀,而B幀和P幀對應的就是之前說的不對全部圖像做編碼的幀。B幀和P幀的差別在於,P幀是參考之前的I幀生成的,B幀是參考前后的圖像幀生成的。
在視頻畫面播放過程中,若I幀丟失了,則后面的P幀也就隨着解不出來,就會出現視頻畫面黑屏的現象;若P幀丟失了,則視頻畫面會出現花屏、馬賽克等現象。
3. GOP(畫面組)
一個GOP(Group Of Picture)就是一組連續的畫面。GOP結構一般有兩個數字,其中一個是GOP的長度(即兩個I幀之間的B幀和P幀數),另一個數字為I幀和P幀之間的間隔距離(即B幀數)。在一個GOP內I幀解碼不依賴任何的其它幀,P幀解碼則依賴前面的I幀或P幀,B幀解碼依賴前面的I幀或P幀及其后最近的一個P幀。
注意:在碼率不變的前提下,GOP值越大,P、B幀的數量會越多,平均每個I、P、B幀所占用的字節數就越多,也就更容易獲取較好的圖像質量;Reference越大,B幀的數量越多,同理也更容易獲得較好的圖像質量。但是通過提高GOP值來提高圖像質量是有限度的。H264編碼器在遇到場景切換的情況時,會自動強制插入一個I幀,此時實際的GOP值被縮短了。另一方面,在一個GOP中,P、B幀是由I幀預測得到的,當I幀的圖像質量比較差時,會影響到一個GOP中后續P、B幀的圖像質量,直到下一個GOP開始才有可能得以恢復,所以GOP值也不宜設置過大。同時,由於P、B幀的復雜度大於I幀,所以過多的P、B幀會影響編碼效率,使編碼效率降低。另外,過長的GOP還會影響Seek操作的響應速度,由於P、B幀是由前面的I或P幀預測得到的,所以Seek操作需要直接定位,解碼某一個P或B幀時,需要先解碼得到本GOP內的I幀及之前的N個預測幀才可以,GOP值越長,需要解碼的預測幀就越多,seek響應的時間也越長。
4. IDR 幀
GOP中的I幀又分為普通I幀和IDR幀,IDR幀就是GOP的第一個I幀,這樣區分視為了方便控制編碼和解碼的流程。 IDR幀一定是I幀,但是I幀不一定是IDR幀。
IDR幀因為附帶SPS、PPS等信息,解碼器在收到 IDR 幀時,需要做的工作就是:把所有的 PPS 和 SPS 參數進行更新。
可以看出來IDR幀的作用是讓解碼器立刻刷新相關數據信息,避免出現較大的解碼錯誤問題。
引入IDR幀機制是為了解碼的重同步,當解碼器解碼到 IDR幀時,立即將參考幀隊列清空,將已解碼的數據全部輸出或拋棄,重新查找參數集,開始一個新的序列。這樣,如果前一個序列出現錯誤,在這里可以獲得重新同步的機會。IDR幀之后的幀永遠不會使用IDR幀之前的數據來解碼。
三、H.264 壓縮方式
1. H.264 壓縮算法
H264 的核心壓縮算法是幀內壓縮和幀間壓縮,幀內壓縮是生成I幀的算法,幀間壓縮是生成B幀和P幀的算法。
幀內(Intraframe)壓縮的原理是:當壓縮一幀圖像時,僅考慮本幀的數據而不考慮相鄰幀之間的冗余信息,一般采用有損壓縮算法,由於幀內壓縮是編碼一個完整的圖像,所以可以獨立的解碼、顯示。幀內壓縮率一般不高。
幀間(Interframe)壓縮的原理是:相鄰幾幀的數據有很大的相關性,或者說前后兩幀信息變化很小的特點。連續的視頻其相鄰幀之間具有冗余信息,根據這一特性,壓縮相鄰幀之間的冗余量就可以進一步提高壓縮量,減小壓縮比。
而幀間壓縮也稱為時間壓縮(Temporalcompression),它通過比較時間軸上不同幀之間的數據進行壓縮。幀間壓縮是無損的,它通過比較本幀與相鄰幀之間的差異,僅記錄本幀與其相鄰幀的差值,這樣可以大大減少數據量。
2. H.264壓縮方式說明
H.264壓縮視頻數據時的具體方式如下:
a). 分組,也就是將一系列變換不大的圖像歸為一個組,即一個GOP;
b). 定義幀,將每組的圖像幀歸分為I幀、P幀和B幀三種類型;
c). 預測幀, 以I幀做為基礎幀,以I幀預測P幀,再由I幀和P幀預測B幀;
d). 數據傳輸, 最后將I幀數據與預測的差值信息進行存儲和傳輸。
四、H.264 分層結構
H.264的主要目標是為了有高的視頻壓縮比和良好的網絡親和性,H264將系統框架分為兩個層面,分別是視頻編碼層面(VCL)和網絡抽象層面(NAL)。
1. VLC層(Video Coding Layer)
VLC層:包括核心壓縮引擎和塊,宏塊和片的語法級別定義,設計目標是盡可能地獨立於網絡進行高效的編碼;
2. NAL層(Network Abstraction Layer)
NAL層:負責將VCL產生的比特字符串適配到各種各樣的網絡和多元環境中,覆蓋了所有片級以上的語法級別。
3. NALU (NAL Unit)
H.264原始碼流(裸流)是由一個接一個NALU組成,結構如下圖,一個NALU = 一組對應於視頻編碼的NALU頭部信息 + 一個原始字節序列負荷(RBSP,Raw Byte Sequence Payload)。
一個原始的H.264 NALU 單元常由 [StartCode] [NALU Header] [NALU Payload] 三部分組成。
3.1 Start Code
Start Code 用於標示這是一個NALU 單元的開始,必須是”00 00 00 01” 或”00 00 01”。
3.2. NAL Header
NAL Header由三部分組成,forbidden_bit(1bit),nal_reference_bit(2bits)(優先級),nal_unit_type(5bits)(類型)。
3.3 RBSP(Raw Byte Sequence Payload))
下圖是RBSP的序列的樣例及相關類型參數的描述表:
SPS是序列參數集,包含的是針對一連續編碼視頻序列的參數,如標識符 seq_parameter_set_id、幀數及 POC 的約束、參考幀數目、解碼圖像尺寸和幀場編碼模式選擇標識等等。
PPS是圖像參數集,對應的是一個序列中某一幅圖像或者某幾幅圖像,其參數如標識符 pic_parameter_set_id、可選的 seq_parameter_set_id、熵編碼模式選擇標識、片組數目、初始量化參數和去方塊濾波系數調整標識等等。
參數集是一個獨立的數據單位,不依賴於參數集之外的其他句法元素。一個參數集不對應某一個特定的圖像或者序列,同一個序列參數集可以被一個或者多個圖像參數集引用。同理,一個圖像參數集也可以被一個或者多個圖像引用。只有在編碼器認為需要更新參數集的內容時,才會發出新的參數集。
五、H.264 局限性
隨着數字視頻應用產業鏈的快速發展,視頻應用向以下幾個方向發展的趨勢愈加明顯:
(1) 高清晰度(HigherDefinition):數字視頻的應用格式從720P向1080P全面升級,而且現在4K的數字視頻格式也已經成為常見。
(2) 高幀率(Higherframe rate ):數字視頻幀率從30fps向60fps、120fps甚至240fps的應用場景升級;
(3) 高壓縮率(HigherCompression rate ):傳輸帶寬和存儲空間一直是視頻應用中最為關鍵的資源,因此,在有限的空間和管道中獲得最佳的視頻體驗一直是用戶的不懈追求。
但是面對視頻應用不斷向高清晰度、高幀率、高壓縮率方向發展的趨勢,當前主流的視頻壓縮標准協議H.264的局限性不斷凸顯。主要體現在:
(1) 宏塊個數的爆發式增長,會導致用於編碼宏塊的預測模式、運動矢量、參考幀索引和量化級等宏塊級參數信息所占用的碼字過多,用於編碼殘差部分的碼字明顯減少。
(2) 由於分辨率的大大增加,單個宏塊所表示的圖像內容的信息大大減少,這將導致相鄰的4 x 4或8 x 8塊變換后的低頻系數相似程度也大大提高,導致出現大量的冗余。
(3) 由於分辨率的大大增加,表示同一個運動的運動矢量的幅值將大大增加,H.264中采用一個運動矢量預測值,對運動矢量差編碼使用的是哥倫布指數編碼,該編碼方式的特點是數值越小使用的比特數越少。因此,隨着運動矢量幅值的大幅增加,H.264中用來對運動矢量進行預測以及編碼的方法壓縮率將逐漸降低。
(4) H.264的一些關鍵算法例如采用CAVLC和CABAC兩種基於上下文的熵編碼方法、deblock濾波等都要求串行編碼,並行度比較低。針對GPU/DSP/FPGA/ASIC等並行化程度非常高的CPU,H.264的這種串行化處理越來越成為制約運算性能的瓶頸。
於是面向更高清晰度、更高幀率、更高壓縮率視頻應用的HEVC(H.265)協議標准應運而生。H.265在H.264標准2~4倍的復雜度基礎上,將壓縮效率提升一倍以上。
(注意:實際使用過程中,不能忽視265專利費用這個重要的問題。專利問題參考:H.265成超級提款機 一場圍繞專利授權的戰爭已經爆發)