【FFmpeg学习】H264 视频编码格式详细总结
一、音視頻的一些名詞解釋
1. 碼率
指視頻文件在單位時間內使用的數據流量,也叫碼流率。碼率越大,說明單位時間內取樣率越大,數據流精度就越高,這樣表現出來的的效果就是:視頻畫面更清晰畫質更高。
一般以秒為單位,如:128 kbps,表示每秒通過網絡傳送的數據量為 128k bit.
2. 幀率
指視頻每秒鐘包含多少張畫面,一般單位為fps。
幀率越高,表示單位時間內圖像幀的個數,普通的視頻文件一般在25fps - 30fps之間,表示每秒鐘25-30張圖像,而一般涉及到游戲等幀率會比較高一些,一般>60fps。在其他的參數一定的情況下,幀率越高,視頻或游戲的流暢度更好,反之,幀率越低,視頻或游戲的流暢度越次,低于15fps的時候人眼一般都會比較感覺到明顯的卡頓
3.分辨率
分辨率就是(矩形)圖片的長度和寬度,即圖片的尺寸。分辨率影響圖像大小,與圖像大小成正比:分辨率越高,圖像越大;分辨率越低,圖像越小。
二、H264 視頻編碼格式
為什么要做編碼壓縮:
對于視頻數據而言,視頻編碼的最主要目的是數據壓縮。這是因為動態圖像的像素形式表示數據量極為巨大,存儲空間和傳輸帶寬完全無法滿足保存和傳輸的需求。例如,圖像的每個像素的三個顏色分量RGB各需要一個字節表示,那么每一個像素至少需要3字節,分辨率1280×720的圖像的大小為2.76M字節。
如果對于同樣分辨率的視頻,如果幀率為25幀/秒,那么傳輸所需的碼率將達到553Mb/s!如果對于更高清的視頻,如1080P、4k、8k視頻,其傳輸碼率更是驚人。這樣的數據量,無論是存儲還是傳輸都無法承受。因此,對視頻數據進行壓縮稱為了必然之選。
視頻信息為什么可以被壓縮
視頻信息之所以存在大量可以被壓縮的空間,是因為其中本身就存在大量的數據冗余。其主要類型有:
1.?視頻壓縮編碼的基本技術
1). 預測編碼
預測編碼可以用于處理視頻中的時間和空間域的冗余。視頻處理中的預測編碼主要分為兩大類:幀內預測和幀間預測。
- 幀內預測:預測值與實際值位于同一幀內,用于消除圖像的空間冗余;幀內預測的特點是壓縮率相對較低,然而可以獨立解碼,不依賴其他幀的數據;通常視頻中的關鍵幀都采用幀內預測。
- 幀間預測:幀間預測的實際值位于當前幀,預測值位于參考幀,用于消除圖像的時間冗余;幀間預測的壓縮率高于幀內預測,然而不能獨立解碼,必須在獲取參考幀數據之后才能重建當前幀。
通常在視頻碼流中,I幀全部使用幀內編碼,P幀/B幀中的數據可能使用幀內或者幀間編碼。
2). 變換編碼
目前主流的視頻編碼算法均屬于有損編碼,通過對視頻造成有限而可以容忍的損失,獲取相對更高的編碼效率。而造成信息損失的部分即在于變換量化這一部分。在進行量化之前,首先需要將圖像信息從空間域通過變換編碼變換至頻
2. H.264 視頻編碼結構
?H.264編解碼主要分為五部分:幀間和幀內預測(Estimation)、變換(Transform)和反變換、量化(Quantization)和反量化、環路濾波(Loop Filter)、熵編碼(Entropy Coding)。
在H.264進行編碼的過程中,每一幀的H圖像被分為一個或多個切片(slice)進行編碼。每一個切片包含多個宏塊(MB,Macroblock)。宏塊是H.264標準中基本的編碼單元,其基本結構包含一個包含16×16個亮度像素塊和兩個8×8色度像素塊,以及其他一些宏塊頭信息。在對一個宏塊進行編碼時,每一個宏塊會分割成多種不同大小的子塊進行預測。
幀內預測采用的塊大小可能為16×16或者4×4,幀間預測/運動補償采用的塊可能有7種不同的形狀:16×16、16×8、8×16、8×8、8×4、4×8和4×4。相比于早期標準只能按照宏塊或者半個宏塊進行運動補償,H.264所采用的這種更加細分的宏塊分割方法提供了更高的預測精度和編碼效率。在變換編碼方面,針對預測殘差數據進行的變換塊大小為4×4或8×8(僅在FRExt版本支持)。相比于僅支持8×8大小的變換塊的早期版本,H.264避免了變換逆變換中經常出現的失配問題。
?
在H.264 中,分為: 序列、圖像、片、宏塊、子宏塊五個層次
一幀圖片經過 H.264 編碼器之后,就被編碼為一個或多個切片(slice),而裝載著這些切片(slice)的載體,就是 NALU。
什么是 NALU 呢?
H.264 原始碼流(又稱為裸流),是有一個接一個的NALU組成的,而它的功能分為兩層:?視頻編碼層(VCL, Video Coding Layer)和網絡提取層(NAL, Network Abstraction Layer)。VCL 數據即編碼處理的輸出,它表示被壓縮編碼后的視頻數據序列,網絡提取層(NAL, Network Abstraction Layer)將VCL封裝,成為一個個NALU。?NALU的結構是:NAL頭+RBSP
切片的主要作用是用作宏塊(Macroblock)的載體。
切片之所以被創造出來,主要目的是為限制誤碼的擴散和傳輸。
如何限制誤碼的擴散和傳輸?
每個切片(slice)都應該是互相獨立被傳輸的,某片的預測(片(slice)內預測和片(slice)間預測)不能以其它片中的宏塊(Macroblock)為參考圖像。
?
?切片可分為 切片頭和切片數據【如上】,一個切片的數據又被分成若干個宏塊【如下】。
分片數據中則是宏塊,其實宏塊存儲像素數據的地方。
宏塊是視頻信息的主要承載者,因為它包含著每一個像素的亮度和色度信息。視頻解碼最主要的工作則是提供高效的方式從碼流中獲得宏塊中的像素陣列。
組成部分:一個宏塊由一個16×16亮度像素和附加的一個8×8 Cb和一個 8×8 Cr 彩色像素塊組成。每個圖象中,若干宏塊被排列成片的形式。
從上圖中,可以看到,宏塊中包含了宏塊類型、預測類型、Coded Block Pattern、Quantization Parameter、像素的亮度和色度數據集等等信息。
對于切片(slice)來講,分為以下幾種類型:
I片:只包 I宏塊,I 宏塊利用從當前片中已解碼的像素作為參考進行幀內預測(不能取其它片中的已解碼像素作為參考進行幀內預測)。
P片:可包 P和I宏塊,P 宏塊利用前面已編碼圖象作為參考圖象進行幀內預測,一個幀內編碼的宏塊可進一步作宏塊的分割:即 16×16、16×8、8×16 或 8×8 亮度像素塊(以及附帶的彩色像素);如果選了 8×8 的子宏塊,則可再分成各種子宏塊的分割,其尺寸為 8×8、8×4、4×8 或 4×4 亮度像素塊(以及附帶的彩色像素)。
B片:可包 B和I宏塊,B 宏塊則利用雙向的參考圖象(當前和 來的已編碼圖象幀)進行幀內預測。
SP片(切換P):用于不同編碼流之間的切換,包含 P 和/或 I 宏塊
SI片:擴展檔次中必須具有的切換,它包 了一種特殊類型的編碼宏塊,叫做 SI 宏塊,SI 也是擴展檔次中的必備功能。
NALU 整體結構可以呼之欲出了,以下就引用 H.264 文檔當中的一幅圖了
3. I幀、B幀、P幀
DTS、PTS、GOP
- DTS :?解碼時間戳
- PTS:?顯示時間戳
- GOP :?一組完整的IBP幀畫面
GOP 是畫面組,一個 GOP 是一組連續的畫面。下圖GOP(Group of Picture)所示:
?GOP 一般有兩個數字,如 M = 3,N = 12,M 制定 I 幀與 P 幀之間的距離,N 指定兩個 I 幀之間的距離。那么現在的 GOP 結構是:
I BBP BBP BBP BB I增大圖片組能有效的減少編碼后的視頻體積,但是也會降低視頻質量,至于怎么取舍,得看需求了。
從上圖,可以看到,DTS和PTS的順序是不一致的,并且每組GOP中開頭都是I幀,然后后面都是B、P幀,如果開頭的I幀圖像質量比較差時,也會影響到一個GOP中后續B、P幀的圖像質量.
- I幀(intra picture) : 幀內編碼幀,自身可以通過視頻解壓算法解壓成一張單獨的完整的圖片;
- B幀(bidirectional) : 雙向預測內插編碼幀,參考前面和后面兩幀的數據加上本幀的變化而得出的本幀數據
- P幀 : 前向預測編碼幀,參考前面而得出的本幀數據.
總結
以上是生活随笔為你收集整理的【FFmpeg学习】H264 视频编码格式详细总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [jQuery] Zepto的点透问题如
- 下一篇: [html] js放在html的<bo