H264基礎簡介

前言

H264是屬於視頻的編碼層的標準格式,視頻編碼顯然是爲了壓縮大小。 咱們看下一個徹底沒壓縮的視頻數據大小。假設視頻是高清(1280 * 720),每秒30幀,也就是每秒的數據html

1280 * 720 *30 / 8(字節) /1024(KB)/1024(MB) = 3.11MBios

那麼90分鐘的電影就要16.7GB,這個數據量顯然在當前網絡下是不現實的。緩存

視頻壓縮的原理就是去除視頻冗餘部分,下面列舉下網絡

1,時間冗餘
時間冗餘是序列圖像(電視圖像、動畫)和語音數據中所常常包含的冗餘。
圖像序列中的兩幅相鄰的圖像,後一幅圖像與前一幅圖像之間有較大的相關性,這反映爲時間冗餘。同理,在語言中,因爲人在說話時發音的音頻是一連續的漸變過程,而不是一個徹底的在時間上獨立的過程,於是存在時間冗餘。dom

2,空間冗餘 空間冗餘是圖像數據中常常存在的一種冗餘。 在同一幅圖像中,規則物體和規則背景(所謂規則是指表面顏色分佈是有序的而不是雜亂無章的)的表面物理特性具備相關性,這些相關性的光成像結構在數字化圖像中就表現爲數據冗餘。學習

3,知識冗餘 有許多圖像的理解與某些基礎知識有至關大的相關性, 例如:人臉的圖像有固定的結構。好比,嘴的上方有鼻子。鼻子的上方有眼睛,鼻子位於正臉圖像的中線上等等。這類規律性的結構可由先驗知識相背景知識獲得,咱們稱此類冗餘爲知識冗餘。動畫

4,結構冗餘 有些圖像從大域上看存在着很是強的紋理結構,例如布紋圖像和草蓆圖像,咱們說它們在結構上存在冗餘。編碼

5,視覺冗餘 人類視覺系統對於圖像場的任何變化,並非都能感知的。例如,對於圖像的編碼和解碼處理時,因爲壓縮或量比截斷引入了噪聲而使圖像發生了一些變化,若是這些變化不能爲視覺所感知,則仍認爲圖像足夠好。事實上人類視覺系統通常的分辨能力約爲26灰度等級,而通常圖像量化採用28灰度等級,這類冗餘咱們稱爲視覺冗餘。 一般狀況下,人類視覺系統對亮度變化敏感,而對色度的變化相對不敏感;在高亮度區,人眼對亮度變化敏感度降低。 對物體邊緣敏感,內部區域相對不敏感;對總體結構敏感,而對內部細節相對不敏感。設計

6,信息熵冗餘 信息熵是指一組數據所攜帶的信息量。它通常定義爲:H = -∑pi×log2pi。其中N爲碼元個數,pi爲碼元yi發生的機率。由定義,爲使單位數據量d接近於或等於H,應設d=∑pi×b(yi),其中b(yi)是分配給碼元yi的比特數,理論上應取-log2pi。實際上在應用中很難估計出{Po,P1,…,PN—1}。所以通常取b(yo)=b(y1)=…=b(yN—1),例如,英文字母編碼碼元長爲7比特,即b(yo)=b(y1)=…=b(yN—1)=7,這樣所得的d必然大於H,由此帶來的冗餘稱爲信息墒冗餘或編碼冗餘。code

H264原始碼流結構

組成: H264功能分爲兩層,VCL(視頻編碼層)和 NAL(網絡提取層).

  1. VCL:包括核心壓縮引擎和塊,宏塊和片的語法級別定義,設計目標是儘量地獨立於網絡進行高效的編碼。
  2. NAL:負責將VCL產生的比特字符串適配到各類各樣的網絡和多元環境中,覆蓋了全部片級以上的語法級別。

VCL數據傳輸或者存儲以前,會被映射到一個NALU中,H264數據包含一個個NALU。以下圖

NALU

一個NALU = 一組對應於視頻編碼的NALU頭部信息 + 一個原始字節序列負荷(RBSP,Raw Byte Sequence Payload).

NALU結構

一個原始的NALU單元結構以下 [StartCode][NALU Header][NALU Payload]三部分。

StartCode,是一個NALU單元開始,必須是00 00 00 01 或者00 00 01。

1. NAL Header

NAL Header

頭信息協議如上圖。

例如: 1 00 00 00 01 06: SEI信息
2 00 00 00 01 67: 0x67&0x1f = 0x07 :SPS 3 00 00 00 01 68: 0x68&0x1f = 0x08 :PPS 4 00 00 00 01 65: 0x65&0x1f = 0x05: IDR Slice

  1. RBSP

RBSP序列舉例

下面是RBSP序列的描述

RBSP序列

H264的碼流分層結構

下面咱們挨個來看每層的結構.

  1. Slice(片)

能夠看到NALU的主體是slice。 slice是H264提出的新概念,編碼圖片後切分高效整合而成。 一個圖片有一個或者多個slice。經過NALU裝載網絡傳輸。

設置片的目的是爲了限制誤碼的擴散和傳輸,編碼片是項目獨立的,一個片的預測不能以其餘片中的宏塊爲參考圖像。保證了某一片的預測偏差不會傳播到別的片。

一個slice一樣包含Slice Header + Slice Data

slice有如下五種類型

(1) I -slice: slice的所有MB(宏塊)都採用intra-prediction(幀內預測)的方式來編碼; (2) P-slice: slice中的MB(宏塊)使用intra-prediction(幀內預測)和inter-prediction(幀間預測)的方式來編碼,但每個inter-prediction block最多隻能使用一個移動向量; (3) B-slice:與P-slice相似,但每個inter-prediction block可使用二個移動向量。B-slice的‘B’是指Bi-predictive(雙向預測),除了可由前一張和後一張影像的I(或P、B)-slice外,也能從前二張不一樣影像的I(或P、B)-slice來作inter- prediction。 (4) SP-slice:即所謂的Switching P slice,爲P-slice的一種特殊類型,用來串接兩個不一樣bitrate的bitstream; (5) SI-slice: 即所謂的Switching I slice,爲I-slice的一種特殊類型,除了用來串接兩個不一樣content的bitstream外,也可用來執行隨機存取(random access)來達到網絡VCR的功能

  1. 宏塊(Macroblock,MB) 從上面結構圖中能夠看到片中包含宏塊。那什麼是宏塊呢?

宏塊是視頻信息的主要承載者。一個編碼圖像一般劃分爲多個宏塊組成.包含着每個像素的亮度和色度信息。視頻解碼最主要的工做則是提供高效的方式從碼流中得到宏塊中像素陣列。

一個宏塊 = 一個16*16的亮度像素 + 一個8×8Cb + 一個8×8Cr彩色像素塊組成。(YCbCr 是屬於 YUV 家族的一員,在YCbCr 中 Y 是指亮度份量,Cb 指藍色色度份量,而 Cr 指紅色色度份量)

宏塊分類:

I宏塊: 幀內預測

P宏塊: 利用前幀做爲參考進行幀內預測,一個幀內編碼的宏塊可進一步做宏塊的分割

B宏塊: 雙向參考圖像(前幀和後幀)進行幀內預測

簡單總結下幀和片和宏塊的概念 1幀 = 1個或n個片 1片 = n個宏塊 1宏塊 = 16x16yuv數據

以下圖所示

宏塊的結構以下圖所示

slice結構

mb_type 肯定該 MB 是幀內或幀間(P 或 B)編碼模式,肯定該 MB 分割的尺寸 mb_pred 肯定幀內預測模式(幀內宏塊)肯定表 0 或表 1 參考圖 像,和每一宏塊分割的差分編碼的運動矢量(幀間宏塊,除 8×8 宏塊分割的幀內 MB) sub_mb_pred (只對 8×8MB 分割的幀內 MB)肯定每一子宏塊的子宏 塊分割,每一宏塊分割的表 0 和/或表 1 的參考圖象;每一 宏塊子分割的差分編碼運動矢量。 coded_block_pattern 指出哪一個 8×8 塊(亮度和彩色)包 編碼變換系數 mb_qp_delta 量化參數的改變值 esidual 預測後對應於殘差圖象取樣的編碼變換系數

I,P,B,IDR幀,DTS和PTS,GOP

I幀: 幀內編碼幀,I幀一般是每一個GOP的第一幀,適度壓縮,相似於圖片jpg壓縮同樣的原理。大約能夠獲得6:1的壓縮比。

P幀: 前向預測編碼幀,經過圖像序列前面已經編碼幀的時間冗餘信息壓縮,稱爲預測幀,大約能夠獲得20:1的壓縮比

B幀:雙向預測內插編碼幀,經過前幀和後幀的時間冗餘信息壓縮,也叫雙向預測幀。大約能夠獲得50:1的壓縮比

IDR幀: I幀的一種特殊幀,一個序列的第一個圖像叫作 IDR 圖像(當即刷新圖像)

當解碼器解碼到 IDR 圖像時,當即將參考幀隊列清空,將已解碼的數據所有輸出或拋棄,從新查找參數集,開始一個新的序列。這樣能夠避免前一個序列出現重大錯誤的問題。

DTS: (Decode Time Stamp) 用於視頻的解碼序列 PTS: (Presentation Time Stamp)用於視頻的顯示序列。

正由於有B幀這樣的雙向預測幀的存在,某一幀的解碼序列和實際的顯示序列是不同的。以下圖所示

DTS和PTS

GOP: (Group of Picture)兩個I幀之間造成的一組圖片,就是GOP。通常爲編碼器設置參數的時候,必須設置gop_size的值,表示兩個I幀之間的幀數目,相對來講GOP_size設置越小,畫面質量越好。可是相應的容量越大。

因爲解碼必須先獲取到I幀,才能得到第一張圖像,因此直播秒開的原理就是在CDN緩存一個GOP圖片組,這樣迅速解碼出第一幀圖。

參考資料:

  1. 從零瞭解H264結構

  2. H.264學習筆記

關於H264的介紹網絡上已經有不少,本文主要是用作筆記記錄。

相關文章
相關標籤/搜索